diff --git a/debuggers/openocd/AUTHORS b/debuggers/openocd/AUTHORS new file mode 100644 index 00000000..2a989f37 --- /dev/null +++ b/debuggers/openocd/AUTHORS @@ -0,0 +1,12 @@ +Dominic Rath +Magnus Lundin +Michael Fischer +Spencer Oliver +Carsten Schlote +Øyvind Harboe +Duane Ellis +Michael Schwingen +Rick Altherr +David Brownell +Vincint Palatin +Zachary T Welch diff --git a/debuggers/openocd/BUGS b/debuggers/openocd/BUGS new file mode 100644 index 00000000..4381c87b --- /dev/null +++ b/debuggers/openocd/BUGS @@ -0,0 +1,74 @@ +// This file is part of the Doxygen Developer Manual +/** @page bugs Bug Reporting + +Please report bugs by subscribing to the OpenOCD mailing list and +posting a message with your report: + + openocd-devel@lists.sourceforge.net + +Also, please check the Trac bug database to see if a ticket for +the bug has already been opened. You might be asked to open +such a ticket, or to update an existing ticket with more data. + + https://sourceforge.net/apps/trac/openocd/ + +To minimize work for OpenOCD developers, you should try to include +all of the information listed below. If you feel that some of the +items below are unnecessary for a clear bug report, you may leave +them out; likewise, feel free to include additional information +that may be important. + +- Target PCB/board description +- Configuration scripts +- OpenOCD command line +- List of commands issued or GDB operations performed +- Expected result +- Actual result +- Logs using debug_level 3 (or with '-d 3' on the command line) +- If the report is for a regression: + - Include logs for both working and broken versions. + - Find the precise version that caused the regression by binary search. + You can use "git bisect" to expedite this binary search: + http://www.kernel.org/pub/software/scm/git/docs/git-bisect.html + +If possible, please develop and attach a patch that helps to expose or +solve the reported problem. See the HACKING file for information +about that process. + +Attach all files directly to your posting. The mailing list knows to +transform attachments to links, but attachments must be less than 300KB +in total. + +@section bugscrashdump Obtaining Crash Backtraces + +If OpenOCD is crashing, there are two very effective things you can do to +improve your chances of getting help on the development mailing list. + +Try to reproduce the problem using the dummy JTAG interface to allow other developers to replicate +your problem robustly and use GDB to get a trace:@par +@code +% OPENOCDSRC/configure --enable-dummy ... +% openocd -f interface/dummy.cfg -f target/xxx.cfg +=> SEGFAULT +% gdb --args openocd .... +(gdb) run +(gdb) bt +=> here a stack trace is dumped. +@endcode + +@section bugsintreedebug Running and Debugging In-Tree + +To run or debug the in-tree executable (not recommended), you must +use libtool to set up the correct shared library paths: +@code + libtool gdb --args openocd .... +@endcode +or the more pedantic (and forward-compatible): +@code + libtool --mode=execute gdb --args openocd .... +@endcode + + */ +/** @file +This file contains the @ref bugs page. +*/ diff --git a/debuggers/openocd/COPYING b/debuggers/openocd/COPYING new file mode 100644 index 00000000..dd186c2d --- /dev/null +++ b/debuggers/openocd/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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/debuggers/openocd/ChangeLog b/debuggers/openocd/ChangeLog new file mode 100644 index 00000000..e01a96ea --- /dev/null +++ b/debuggers/openocd/ChangeLog @@ -0,0 +1,18242 @@ +2013-05-05 Freddie Chopin + + * : The openocd-0.7.0 release. Change-Id: I08157f47ac056e6d2089119dd2d6cbab11b521e8 Signed-off-by: + Freddie Chopin + +2013-04-28 Freddie Chopin + + * : doc: Update list of interfaces, targets and boards Change-Id: If9481e061f09a37f9ee3c461a1a0ce4d382a9a0d Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/1366 Tested-by: jenkins Reviewed-by: + Spencer Oliver + +2013-05-02 Spencer Oliver + + * : cfg: remove whitespace Change-Id: I20edbb50efc03711195102f4c6dc8bcfaf043d44 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1374 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2013-04-28 Freddie Chopin + + * : Restore -dev suffix Change-Id: I26f49e02d228b59533237607fa8307ecc627409e Signed-off-by: + Freddie Chopin + +2013-02-01 Spencer Oliver + + * : target: rename cortex_a8 to cortex_a Rename cortex_a8 target to use a more correct cortex_a name. This + also adds a deprecated_name var so that older scripts issue a + warning to update the target name. cfg files have also been updated to the new target name. Change-Id: I0eb1429c9281321efeb444b27a662a941a2ab67f Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1130 Tested-by: jenkins Reviewed-by: + Freddie Chopin + +2013-04-20 Freddie Chopin + + * : Mention "lpc4300" (with "lpc1800" alias) flash drivers in manual Change-Id: I0bb28910b2c07b1ca5bd644e0d88b931d585d3e7 Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/1352 Tested-by: jenkins + +2013-04-22 Christopher Kilgour + + * : kinetis: fix "SF1" parts to limit FlexRAM usage Ensure FlexRAM usage is limited to half the FlexRAM size when + programming. Assume the FlexNVM sector size is equal to half the + FlexRAM. Fix sector erase checking which had an error introduced + when the kinetis_ftfx_command( ) signature was changed. Change-Id: I88edd9c7d4a4ba474cad7b00052feaeedfa8ced8 Signed-off-by: + Christopher Kilgour Reviewed-on: + http://openocd.zylin.com/1358 Tested-by: jenkins Reviewed-by: + Freddie Chopin + +2013-04-23 Spencer Oliver + + * : arm: fix arm reg regression Seems commit fc2abe63fd3cea7497da7be2955d333bd3f800b9 caused a + regression in that the arm reg cmd no longer worked. The issue was + caused because we changed the value of ARM_MODE_THREAD which was + being checked in arm_init_arch_info. Change-Id: Id571d4ab336d1b0e2b93363147af245d24b65ca5 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1362 Tested-by: jenkins Reviewed-by: Luca + Bruno Reviewed-by: Freddie Chopin + + +2013-04-23 Hsiangkai Wang + + * : gdb server: Fix bug. Parse 'M' packet error. The format of 'M' packet is 'M addr,length:XX...'. The data follows + ':' immediately. No need to '+2' to SEPARATOR in unhexify(), because + SEPARATOR points to data correctly. Change-Id: I15b5758b540816cc727752e7bf68cd45e623f603 Signed-off-by: + Hsiangkai Wang Reviewed-on: + http://openocd.zylin.com/1360 Tested-by: jenkins Reviewed-by: + Spencer Oliver Reviewed-by: Freddie Chopin + + +2013-04-21 Freddie Chopin + + * : Restore -dev suffix Change-Id: I3662c5993766a76d6dd62b919c56cc059c4e50d4 Signed-off-by: + Freddie Chopin + +2013-04-20 Freddie Chopin + + * : Add "lpc1800" alias for "lpc4300" flash driver Change-Id: I6d2bb9105cc778bd1d21580022529d684c3b21b0 Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/1351 Tested-by: jenkins + +2013-04-20 Freddie Chopin + + * : Improve HACKING Reword info about creating SSH key - it's not required to add it to + Github account. Mention adding created SSH key to Gerrit account - + without this step it's not possible to access Gerrit in further + steps. Change-Id: Ibd81521fbe47d4b4beae0b77cdc9d939fd3ee20c Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/1350 Tested-by: jenkins Reviewed-by: Paul + Fertser + +2013-04-19 R. Steve McKown + + * : Support newer OSBDM firmware OSBDM: add new VID:PID implemented in OSJTAG/OSBDM firmware + somewhere between versions 30.13 and 31.21. PFLASH programming + works with this patch, tested on a Freescale Kinetis TWR-K20D72M + using its onboard OSBDM JTAG adapter. Note: flash program testing required hacking kinetis_write() to + force longword programming, as the FTFL program section commands + formulated by kinetis_write() currently fail on this board's + PK20DX256VLL7 processor. Change-Id: Ib7b92ff2fe9ebf6158fb1489f554a19e96cd9651 Signed-off-by: + R. Steve McKown Reviewed-on: + http://openocd.zylin.com/1348 Tested-by: jenkins Reviewed-by: + Freddie Chopin + +2013-04-03 Salvador Arroyo + + * : mips: m4k alternate pracc code. Patch 4 Now all the functions with only fetch accesses are modified. The + same delay between scans has been added to + mips32_pracc_fastdata_xfer(), it should work at the same scan rates + as the other pracc functions, but it needs higher scan_delays to + work. Change-Id: Ifb31d8ea6de9d22674385782913d221a2494dbbf Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/1196 Tested-by: jenkins Reviewed-by: + Freddie Chopin + +2013-03-03 Salvador Arroyo + + * : mips: m4k alternate pracc code. Patch 2 Each pracc function defines a variable ctx of type struct + pracc_queue_info. To simplify the code tree auxiliary functions are + defined: pracc_queue_init(), pracc_add() and pracc_queue_free(). + The second parameter in pracc_add() is the store address if the + instruction is a store at dmseg, otherwise it should be 0. The code + is executed by mips32_pracc_queue_exec(). If ejtag_info->mode is 0 + mips32_pracc_exec() is called and it should work like with current + code. To generate the delay between scans the number of clock ticks + are calculated with the help of jtag_get_speed_khz(). Due to delays + in the execution of each single ftdi instruction the number of ticks + are higher as it should be, specially at higher scan rates. + mips32_pracc_read_u32() should now work with the new code. Change-Id: I471590a4fc89b56af10bd46c48767b4c64de154f Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/1194 Tested-by: jenkins Reviewed-by: + Freddie Chopin + +2013-04-20 Freddie Chopin + + * : Improve clone command in README Without the explicit dir at the end the repository will be cloned to + "code". Change-Id: Icd8b55b4ba74f23b214c3844e2fb785377768119 Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/1349 Reviewed-by: Øyvind Harboe + Tested-by: jenkins + +2013-04-17 Ben Nahill + + * : topic: STM32W support added to em357 driver The em357 driver only supported one page configuration (192k in 96 + 2048k) pages. This is fine for em357 chips since that's the size + they have, but ST's STM32W chips (pretty much the same) have + different flash configurations available (64, 128, 192, 256k). I + can't find anywhere that would indicate the size of the chip + anywhere in memory so the selection must be manual, using the 'size' + parameter. For backwards compatibility, any size not known to be in + use defaults to the 192k configuration. I don't have any em357 + devices to test, but I also found that I had to re-assert the FPEC + clock enable before performing an erase. This is a single line and + shouldn't break any configurations. My testing so far has only been with a 64k device with 8k of RAM. Change-Id: Ic0ac400a9696efaa09d1407dd4a4d456bc2c318b Signed-off-by: + Ben Nahill Reviewed-on: + http://openocd.zylin.com/1336 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2013-04-11 Spencer Oliver + + * : stlink: fix connect under reset issues We need to make sure that srst is asserted before we attempt to + switch into jtag or swd mode otherwise we receive a error (-9) - + invalid device id. Change-Id: I625166c751cfba8e8a5290f40122bb9afc9dbb39 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1315 Tested-by: jenkins + +2013-03-19 Andreas Fritiofson + + * : ft2232: remove ft2232_large_scan memory leak This is a very long outstanding issue see: + + http://lists.berlios.de/pipermail/openocd-development/2011-June/019404.htmlAs this driver is deprecated the fix is added to purely to reduce + the warnings reported by clang. Change-Id: I3a16a704e0e8db27efda50fdcfdd35abf5ebed0f Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1278 Tested-by: jenkins + +2013-03-28 Spencer Oliver + + * : jimtcl: update embedded jimtcl Update to latest jimtcl commit + 2c1eba991e21a6f0b531fb0f83e21f9e6ee7c515. This fixes issues when + building on certain versions of Mac OSX. Change-Id: I551477752d7913c84e6deb60b889d0c14bd200a0 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1311 Tested-by: jenkins Reviewed-by: + Xiaofan + +2013-04-15 Peter Dietzsch + + * : flash: Added support for at91sam4sd32c Change-Id: I7223980602d7595a3dd7a3ceaac3f58d4f73f88d Signed-off-by: + Peter Dietzsch Reviewed-on: + http://openocd.zylin.com/1332 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2013-03-18 Michel JAOUEN + + * : arm_adi_v5: fix for csw nonsecure access. Add command to fix CSW_SPROT in register AP_CSW. This solves dap + apmem access in non secure access. Change-Id: I7cfcb6434d75f5cfd4a2630a059901cdeea010ce Signed-off-by: + Michel JAOUEN Reviewed-on: + http://openocd.zylin.com/1276 Tested-by: jenkins Reviewed-by: mike + brown Reviewed-by: Spencer Oliver + +2013-02-24 Salvador Arroyo + + * : mips: change in restoring debug working register In current devel code there are 3 functions (related to m4k code) + that need to restore register 8 from pracc stack: + mips32_pracc_read_u32() mips32_cp0_read() + mips32_pracc_write_mem_generic() And mips32_pracc_read_mem() needs to restore regs 8 and 9 from pracc + stack. Values in this registers should be the same as read by + mips32_pracc_read_regs() when entering debug mode and can be + modified by mips32_pracc_write_regs() when leaving debug mode. + There is no need to read their values from the processor registers + every time. The fields reg8 and reg9 are added to struct mips_ejtag to store + these register values and the call to mips32_save_context() is + shifted in mips_m4k_debug_entry() in order to store them before any + other function needs to restore these registers. For the same + reason in function mips_m4k_step() the call to + mips_m4k_set_breakpoint(), if needed, should be made after calling + mips_m4k_debug_entry(). For single word write the number of pracc + accesses are now 9 or 8, from 13 or 12 in current code, single word + read takes now 10 instead of 12. This patch is really the first in a set of patches for an alternate + m4k pracc code much faster that current code. At least for me with + pic32mx works fine. Change-Id: Ibd9df5e8b9f78ce05a180949ba6a561c761b61d6 Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/1146 Tested-by: jenkins Reviewed-by: + Spencer Oliver + +2013-02-23 Salvador Arroyo + + * : pic32mx: 0 wait state option By default pic32mx starts after any reset with 1 wait state for RAM + access/exec. It can be changed to 0 wait states by clearing the + BMXWSDRM bit (bit 6) in BMXCON register. With 0 wait states near + doubles the execution speed. CRC check sum can be done much faster + increasing verify_image speed. Fast data transfer also works with a + bit higher scan rate, up to 1500 Khz. This option can be set at any + time with mww 0xbf882004 0x40 or cleared with mww 0xbf882008 0x40. + Some numbers for FTDI/HS with current devel code and a elf file: Core clock / wait states verify_image speed + ------------------------------------|------------------------------ 4 Mhz / 1 21 KiB/s 4 Mhz / 0 36 KiB/s 8 Mhz / 1 37 KiB/s 8 Mhz / 0 57 KiB/s Change-Id: I4092ad0f3753f72f77108718d0ed3a3ab84e3b23 Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/1141 Tested-by: jenkins Reviewed-by: + Spencer Oliver Reviewed-by: Xiaofan + + +2013-02-27 Henrik Nilsson + + * : Added support for ARMv7-M in arm io. Added support for ARMv7-M targets in arm_nandwrite and arm_nandread. Change-Id: Iab1d78d401f735e191c6a8519f3619035a300fae Signed-off-by: + Henrik Nilsson Reviewed-on: + http://openocd.zylin.com/1188 Tested-by: jenkins Reviewed-by: + Freddie Chopin + +2013-03-18 mike brown + + * : arm_adi_v5: fix mem_ap_read_buf_u32() JTAG nastiness.. Moved JTAG code out of transport-neutral file (arm_adi_v5.c) into + transport specific file (adi_v5_jtag.c). Added ap_block_read to + dap_ops interface (arm_adi_v5.h) to support the move. Change-Id: I796d3984f138aad052b97c77ac9c12ffd1158f74 Signed-off-by: + mike brown Reviewed-on: + http://openocd.zylin.com/1277 Tested-by: jenkins Reviewed-by: Michel + JAOUEN Reviewed-by: Spencer Oliver + + +2013-03-19 Spencer Oliver + + * : ti_icdi: add icdi_usb_query result check Change-Id: I0b40586677a77ee6ae46fe120a677616bde22d1e Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1279 Tested-by: jenkins Reviewed-by: + Xiaofan Reviewed-by: Andreas Fritiofson + + +2013-03-14 Spencer Oliver + + * : docs: remove unnecessary whitespace Change-Id: I11bad3de145d941b61e9bd4920bc3281ece91ab3 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1245 Tested-by: jenkins Reviewed-by: + Freddie Chopin + +2013-03-23 Thomas Schmid + + * : at91sam3: Wrong PLLA frequency calculations The command 'at91sam3 info' ignores PLLA DIV values >1. This patch + fixes it. Tested on a SAM3S4C chip. Change-Id: I051f41bb3dcefe1ac785fbcb48477a807daa16a2 Signed-off-by: + Thomas Schmid Reviewed-on: + http://openocd.zylin.com/1307 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2013-03-15 Spencer Oliver + + * : target: fix broken Cortex-R4 support This regression was caused due to the recent addition of R4 support + and the removal of the bulk_write_memory handler. Change-Id: Ide692737f235c0e9906becb6f3502ba52c5907aa Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1246 Tested-by: jenkins + +2013-03-08 Andreas Fritiofson + + * : target: Add default implementation of bulk_write_memory Remove dummy implementations from all targets except arm7_9 and + mips, which are the only ones with real implementations. Replace + with a single default implementation simply calling + target_write_memory(). Change-Id: I9228104240bc0b50661be20bc7909713ccda2164 Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/1213 Tested-by: jenkins Reviewed-by: + Øyvind Harboe Reviewed-by: Spencer Oliver + + +2012-10-12 Evan Hunter + + * : adi_v5: search for Debug and Memory AP support Adds dap_find_ap() function. Change-Id: I6643025624009b12d4936de67a605da52c07be49 Signed-off-by: + Evan Hunter Reviewed-on: + http://openocd.zylin.com/909 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-06-05 Stefan Mahr + + * : jtag: add support for some probes that are mostly compatible + with opendous This patch adds support for usbprog-jtag and usbvlab that are mostly + compatible to opendous except for IN and OUT endpoints and usb + transfer mode. Change-Id: I44557c2449fe7473295038efa6ae4fc8d80ec7bf Signed-off-by: + Stefan Mahr Reviewed-on: + http://openocd.zylin.com/687 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2013-03-12 Stefan Mahr + + * : jtag: parport: avoid freeing read-only memory section If command parport_cable is not executed, parport_cable points to + const char array in read-only memory as default. On exit free() will + try to free this read-only memory. This patch uses strdup to + allocate memory when defining default setting. Change-Id: I290e707ac6a37e9dc1b45c85ca51d8bd6aac6761 Signed-off-by: + Stefan Mahr Reviewed-on: + http://openocd.zylin.com/1223 Tested-by: jenkins Reviewed-by: + Spencer Oliver + +2013-03-10 Andreas Fritiofson + + * : target: Remove read_memory_imp Change-Id: Idc6ef3b075ccbb5945df8fea746011cb17175d8f Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/1219 Tested-by: jenkins Reviewed-by: + Spencer Oliver + +2013-03-10 Andreas Fritiofson + + * : target: Remove soft_reset_halt_imp Change-Id: I12c907584ef73de570eba2dcfeb8477cabc6098f Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/1217 Tested-by: jenkins Reviewed-by: + Spencer Oliver + +2012-12-27 Rodrigo Melo + + * : interface: opendous_ftdi config file added This config file add support to the opendous cable based on the chip + ft2232H, using the ft2232 interface driver. Change-Id: I8171a0c475af8d61e081844ee86466a392138fb0 Signed-off-by: + Rodrigo Melo Reviewed-on: + http://openocd.zylin.com/1096 Tested-by: jenkins Reviewed-by: + Spencer Oliver + +2012-10-08 Drasko DRASKOVIC + + * : doc: Added MIPS target document This document explains MIPS EJTAG operations implementations within + OpenOCD. Change-Id: Ieaf01f8bc5a97d7b0f2c847bac5fbb2ccf8ba088 Signed-off-by: + Drasko DRASKOVIC Reviewed-on: + http://openocd.zylin.com/904 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2013-03-02 Alex Austin + + * : Kinetis: Symbolic names for Addresses and Commands Change-Id: I2165b66c37bd1608139b5dd00f48124161e13ef0 Signed-off-by: + Alex Austin Reviewed-on: + http://openocd.zylin.com/1191 Tested-by: jenkins Reviewed-by: + Christopher Kilgour Reviewed-by: Spencer + Oliver + +2013-03-06 Spencer Oliver + + * : tcl: add flash programming helper This adds a program proc that simplifies using OpenOCD as a + standalone programmer. Change-Id: I6ece492cd878c170b734e8bb2e09fe8c4557d5a6 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1199 Tested-by: jenkins Reviewed-by: Jörg + Fischer Reviewed-by: Andreas Fritiofson + Reviewed-by: Øyvind Harboe + + +2013-03-07 Spencer Oliver + + * : gdb: use stdio functions to convert parameters This reduces the number of gdb conversion routines we have to + maintain. Change-Id: Ia43d6cac86cbe4f76fe0875b9d9c16ac340296db Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1128 Tested-by: jenkins Reviewed-by: + Andreas Fritiofson Reviewed-by: + Freddie Chopin + +2013-03-07 Spencer Oliver + + * : docs: use doxygen keywords for formatting Rather than use bold fonts etc, use the correct keywords so doxygen + formats better. Change-Id: Id9d63f0fc3465665376d7a536c4d6da71998f40e Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1210 Tested-by: jenkins Reviewed-by: + Øyvind Harboe + +2013-02-27 Spencer Oliver + + * : flash: fix stm32 failed probe using incorrect flash size This fixes an issue if the device is manually probed after the + initial probe fails due to being unable to read flash size register. + In this situation the driver assumes the user has overridden the + flash size when infact this may not be the case. It also seems on the older stm32f1 devices the flash register is not + readable when locked, this does not seem to apply to the newer parts + - f0, f3, f4. Change-Id: I125f872fcb2d962ca6705f97b62d957e2b31303b Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1187 Tested-by: jenkins Reviewed-by: Johan + Almquist Reviewed-by: Freddie Chopin + + +2013-02-25 Spencer Oliver + + * : ti-icdi: catch failed icdi_send_cmd warnings detected by clang. Change-Id: I1532bcc12a8ab7446646dfb2a7afa8894ff03679 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1180 Tested-by: jenkins Reviewed-by: + Xiaofan Reviewed-by: Freddie Chopin + + +2013-02-25 Spencer Oliver + + * : target: use common target_name to access target::cmd_name member Change-Id: I203b89ef25a072c3b00b504483d5f2a83477fad6 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1182 Tested-by: jenkins Reviewed-by: + Mathias Küster Reviewed-by: Andreas Fritiofson + + +2013-02-27 Mathias K + + * : Change reset configuration. This patch change the default reset config from SYSRESETREQ to the + working VECTRESET. Change-Id: I21a9a74b9c0c68cfa3a6e6dac9b123acc98a93cb Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/1186 Tested-by: jenkins Reviewed-by: + Spencer Oliver + +2013-02-25 Mathias K + + * : Add the target name to debug output for better understanding and + error identification. Change-Id: I1054debea6cd3a6548aadeae2d84000a0039814e Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/1178 Tested-by: jenkins Reviewed-by: + Spencer Oliver + +2013-01-31 Spencer Oliver + + * : gdbserver: use common hexify/unhexify routines Change-Id: I9989b625666e9c60ec9867cf6f4d94f41c998c3f Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1105 Tested-by: jenkins Reviewed-by: + Mathias Küster Reviewed-by: Øyvind Harboe + + +2013-02-07 Spencer Oliver + + * : target: hla correctly use target events Because we were always running using target state TARGET_RUNNING + target algorithm's were a bit verbose compared to other targets. This brings the hla target inline with the other targets. Change-Id: I3a257fdc878b87660fac8b5eca22b421eee5b349 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1134 Tested-by: jenkins + +2013-02-19 Johan Almquist + + * : stm32: add support for stm32l1x 256k high density single bank + devices Added support for new ST devices in the stm32lx portfolio, with + device id 0x427. These have 256k flash, but in a single bank + compared to device id 0x436 which is a dual bank flash. Change-Id: Iafdfe990f24bd04b0d6e00385ee70690f3bf8d5f Signed-off-by: + Johan Almquist Reviewed-on: + http://openocd.zylin.com/1140 Tested-by: jenkins Reviewed-by: + Spencer Oliver + +2013-02-05 Spencer Oliver + + * : stm32: enable flash bank size override It has been seen on some stm32 targets that the flash size register + that is probed by the driver may contain an invalid size. This change enables the user to override the probed value. Change-Id: I09359e59a96f9133d3d939670957d32a830a944e Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1132 Tested-by: jenkins Reviewed-by: Johan + Almquist + +2013-02-01 Spencer Oliver + + * : armv7m: use ARM_MODE_THREAD core mode for algoorithm's This makes sure we are using privileged mode when executing any + loaders. Change-Id: I18bf32ec92e1c76a66ab25e3712652bc3650b332 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1108 Tested-by: jenkins Reviewed-by: + Andreas Fritiofson + +2013-01-09 Spencer Oliver + + * : armv7m: use generic arm read/write_core_reg Change-Id: I0c15acc1278d2972269d294078495e6b069c830b Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/969 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2012-11-08 Spencer Oliver + + * : armv7m: remove unused armv7m_regtype This simplifies the armv7m_core_reg structure ready for the move to + using the generic struct arm_reg. Change-Id: I8edb9d77cc54965d49cd2e754568ebcea4cf6964 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/967 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2013-01-28 Spencer Oliver + + * : helper: hexify correctly handle signed chars The current implementation of hexify was not correctly handling + signed chars. This function is currently used by the ti-icdi driver and as such + was causing random write issues. As a note perhaps a better long term fix would be to change to using + uint8_t buffers rather than char. This will require changes to the + ti-icdi driver aswell. Change-Id: I572e69ff2b99227a7d412de056458c0393794b03 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1124 Tested-by: jenkins Reviewed-by: + Øyvind Harboe + +2013-01-03 Spencer Oliver + + * : rtos: do not use LOG_OUTPUT LOG_OUTPUT is not intended for general output so use the correct + LOG_* functions instead. Change-Id: I48d0fe765637024dbafc68f2ea08219d3ff42754 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1104 Tested-by: jenkins Reviewed-by: + Freddie Chopin + +2013-01-16 Spencer Oliver + + * : jtag: only change state if necessary All the other drivers will only change the state if required. This + brings all the other drivers inline with this behaviour. The original issue relates to problems on xscale commit + 7989000e0969c1ccf69acbc3ce649a020bc1ee66 Change-Id: Ifc90ec2eef68a70a14f37c00931a07982bfa200c Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1114 Tested-by: jenkins Reviewed-by: + Freddie Chopin + +2013-01-25 Spencer Oliver + + * : hla: enable DWT component and fix watchpoints The makes sure the DWT component is always enabled so that + watchpoints work as expected. This does need merging into the existing cortex_m logic, however at + the moment this is non trivial. Change-Id: Ic6cccd1badb51f70a2ca8ea9ab6923788a94c1bf Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1122 Tested-by: jenkins Reviewed-by: + Freddie Chopin + +2012-12-07 Spencer Oliver + + * : flash: reduce stm32lx loader timeout Waiting 20secs is a bit much excessive, we could probably reduce to + 5. Change-Id: Iffb97adb99c2541a075fe78dbc88a53ddf340214 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1009 Tested-by: jenkins + +2012-12-30 Spencer Oliver + + * : docs: update stm32f1x/stm32f2x driver info As we use the two ST flash drivers for multiple stm32 variants + update the docs as to which targets use which driver. Change-Id: I84943ff45482a22b3d3dd8491bb4242d79415939 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/990 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2013-01-04 Spencer Oliver + + * : flash: add stm32f2x flash lock/unlock cmds Change-Id: I35344cc47fa4f0a49c034455c5abf479faa0344a Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/988 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2013-01-18 Roman D + + * : flash: EFM32 GG/LG page size detection fix Fixed flash page size detection according to EFM32 GG/LG errata. + MEM_INFO_PAGE_SIZE register containts invalid value in devices with + revision number lower than 18 and should not be used. Change-Id: Idb2832246efcbbec2fd98a5c458f72a36df386fb Signed-off-by: + Roman D Reviewed-on: http://openocd.zylin.com/1116 + Tested-by: jenkins Reviewed-by: Spencer Oliver + + +2013-01-10 Roman D + + * : flash: EFM32 flash implementation Limited (no page unprotect, no block writes) implementation of EFM32 + flash support. Verified with EFM32 development kit and STLink V2 + adapter using SWD. Change-Id: I3db2054d9aa628a1fe4814430425db3c9959c71c Signed-off-by: + Roman D Reviewed-on: http://openocd.zylin.com/1106 + Tested-by: jenkins Reviewed-by: Spencer Oliver + + +2013-01-02 Spencer Oliver + + * : hla: support setting DCB_DEMCR on resume This is only minimal support to enable use to catch a Hard Fault in + the stm32l flash bootloader. Change-Id: I21d6a11893e2f1d173ebff1a651d6f52bf6eec32 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1103 Reviewed-by: Peter Stuge + Tested-by: jenkins + +2012-11-20 Spencer Oliver + + * : flash: use correct stm32f1x option read mask Make sure we do not mask out the BFB2 boot bank bit, as this is used + on the larger XL devices. Change-Id: Iacfdf874140e409e0c4ca9b9aee8f5c2f90dc9be Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/991 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2012-11-20 Spencer Oliver + + * : stm32f1x: preserve user option byte data The user is able to use 2bytes of the options byte data for whatever + purpose they wish. Make sure we preserve this during an option + erase/write. Change-Id: Ibf951b11c59a148e671b1eb47fdc9b4f49ccae15 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/983 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2012-12-29 Andreas Fritiofson + + * : doc: Clarify the topic field in the commit comment template Change-Id: Iea1f3b665b011ca3748800048039d3f6b33d7756 Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/1101 Reviewed-by: Øyvind Harboe + Reviewed-by: Tomasz CEDRO + Reviewed-by: Spencer Oliver Tested-by: + Spencer Oliver + +2012-12-06 Spencer Oliver + + * : cfg: increase stm32l-discovery working area This part has 16k ram so make it all available. Change-Id: Ifeb7bc850bfe4f68d0affb8f6a0931b4327e7257 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1006 Tested-by: jenkins Reviewed-by: + Andreas Fritiofson + +2012-12-04 Spencer Oliver + + * : cfg: enable stlink stm32l HSI Switch to using the internal HSI when a reset init is called, this + also matches the std stm32l cfg. Read (verify) speed is increased from 17 to 120 KiB/s. Change-Id: Ic94ba85949ffdefa17b7be45eef14e30f941d107 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/1004 Tested-by: jenkins Reviewed-by: + Andreas Fritiofson + +2012-11-20 Spencer Oliver + + * : flash: format stm32f2x driver defines Change-Id: Ie903996368a8d4313df87839d5ba3f2a102796a3 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/987 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2012-11-15 Spencer Oliver + + * : stlink: add generic open error routine Change-Id: I1cd18896ab2a37255471a2d160befed8dd8fb544 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/979 Tested-by: jenkins + +2012-11-22 Spencer Oliver + + * : gdb: fix correct shutdown when using pipes 50d5441e2a615fb2c44b41a777e4373901f7a2e6 commit added a regression + when using pipes with GDB, OpenOCD would appear to hang when exiting + GDB. This fixes that behaviour so we shutdown correctly. Change-Id: I9b337c2bdd41b1966de1c7631118257afcbfa6bd Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/993 Tested-by: jenkins + +2012-11-08 Spencer Oliver + + * : doc: replace luminary with TI urls's Change-Id: Ic8a768f5a498e78b96421c6137238593c159fd72 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/970 Tested-by: jenkins + +2012-11-12 Spencer Oliver + + * : icdi: add TI icdi interface This is the new proprietary interface replacing the older FTDI based + adapters. It is currently fitted to the ek-lm4f232 and Stellaris + LaunchPad. Change-Id: I794ad79e31ff61ec8e9f49530aca9308025c0b60 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/922 Tested-by: jenkins + +2012-10-25 Spencer Oliver + + * : hla: fix watchpoints not being set Watchpoints were not being enabled when the hl adapter target was + resumed. This effects both stlink and icdi interfaces. Change-Id: Ia9f8a9415be97a467cd099b63b6bc9f7f37d0c0d Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/931 Tested-by: jenkins + +2012-10-24 Spencer Oliver + + * : stlink: rename stlink cmd names As part of the switch to using the hla for the stlink interface we + rename the cmds to a more generic name. Update scripts to match new names. Also add handlers for deprecated names. Change-Id: I6f00743da746e3aa13ce06acfdc93c8049545e07 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/921 Tested-by: jenkins + +2012-10-24 Spencer Oliver + + * : stlink: print version info Print stlink info always rather than just when debug log enabled. Change-Id: I2a29ef046925200e1c94624280c0b252fab5219a Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/925 Tested-by: jenkins + +2012-11-15 Muranaka Masaki + + * : flash: fm3 mb9bfxx7 mb9bfxx8 support Patch submitted by Trac #55 Change-Id: I08b0d79d24fe9108ca0bbfbc9b45c60359b6d180 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/981 Tested-by: jenkins + +2012-12-10 Kamal Dasu + + * : mips_m4k: Fixed mips_m4k_resume code for smp targets Fix for bug introduced in in mips smp support code in the resume + logic that is checking for wrong return value. Change-Id: Ice3e0069f936b556fecc338ccc12ddba38deeaf6 Signed-off-by: + Kamal Dasu Reviewed-on: + http://openocd.zylin.com/1048 Tested-by: jenkins Reviewed-by: + Spencer Oliver + +2012-11-26 Spencer Oliver + + * : jtag: fix reset_config copy/paste error As the other arg checks do not OR, it is assumed this is a + copy/paste error from the original code author. Change-Id: I7dfc7396254a6f558887def951c57dfd4a0e6c2c Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/997 Tested-by: jenkins Reviewed-by: Paul + Fertser Reviewed-by: Freddie Chopin + + +2012-11-13 Spencer Oliver + + * : jtag: enable connect under reset Currently if the target supports srst_nogate we wait until target + assert_reset until we get a chance to assert the srst. However + sometimes we will not get this far if the target has already failed + the jtag_examine_chain. This has been tested on targets that support this behaviour (STM32 + and STR9). Change-Id: Ibcf7584b137b472f31ba6ddd5cd99d848c5508d1 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/971 Tested-by: jenkins Reviewed-by: Paul + Fertser Reviewed-by: Freddie Chopin + + +2012-11-02 Evan Hunter + + * : cortex_a: Fix target entry state route. If target is disabled at init, then is examined using 'arp_examine', + it can get to cortex_a8_poll with the target state being unknown. Change-Id: Ifffb345bf971d275d2eb1912648b29f0a75f6ccc Signed-off-by: + Evan Hunter Reviewed-on: + http://openocd.zylin.com/954 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-10-17 Kamal Dasu + + * : mips_ejtag: Adding EJTAG 4.x and 5.x as valid versions This is a minor change to log EJTAG version 4.x and 5.x as valid + versions when debug log is enabled. Change-Id: Ie20458d033c6d22842cb4a31b56765d4ba2ff123 Signed-off-by: + Kamal Dasu Reviewed-on: + http://openocd.zylin.com/936 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-11-30 Aymeric Vincent + + * : Make NetBSD a recognized system Change-Id: I7fcb540553da7833a8b6a82335a7296539a8f491 Signed-off-by: + Aymeric Vincent Reviewed-on: + http://openocd.zylin.com/998 Reviewed-by: Peter Stuge + Tested-by: jenkins + +2012-11-15 Spencer Oliver + + * : stlink: format src defines Change-Id: I7c3fd6e84681e007f1983ad9b8c85369cf9f3ba1 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/978 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2012-11-11 Salvador Arroyo + + * : mips: patch mips32_pracc_exec_write() No function writes to MIPS32_PRACC_PARAM_IN addresses and probably + has no much sense. Any attempt to write to those addresses should + be an error. Change-Id: Iebea5fa9954e2cd56ad34976dd7d25009c6e6388 Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/975 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-11-03 Salvador Arroyo + + * : mips: optimize mips32_pracc_write_regs() code. All the the loads are done with lui and ori instructions, there is + no need to save any register, they will be overwritten. Like in the + previous patch, for speed optimization in write code, same + instructions can be saved if the lower half word or the upper half + word is 0. If the lower half word is 0, it can be loaded with only + a lui instruction. If the higher half word is 0 it can be done with + an ori instruction with register 0. This code saves 10 pracc + accesses at a minimum, and 40 at a maximum, obviously if register 2 + to 31 are 0 or a half word is 0 Current code needs 91 pracc + accesses. Change-Id: I892c5b440191d0c7a474c96845d41c373b7fc637 Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/957 Reviewed-by: Spencer Oliver + Tested-by: jenkins + +2012-11-02 Salvador Arroyo + + * : mips: optimize read code for speed Really nothing new that not explained in previous patches. The code + is expanded as needed, there are no loops in pracc code. For the + first value pracc accesses are reduced from 39 to 16 and for + aditional values from 10 to 3. dump_image should work around 3x + faster. Change-Id: I37c9b13395c09eb52a91f10cdb6cbaedef8ab98b Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/955 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-11-01 Salvador Arroyo + + * : mips: optimize CP0 read/write code MIPS32_PRACC_BASE_ADDR is defined as 0xFF200000. Now is possible to + load the base address with a lui instruction and only one pracc + access. Offsets to the pracc code addresses are defined to simplify + the code and probably make it a bit more readable or self-explained. Change-Id: I853dd2d7fad52745931cc6e6be68c0ae156d897e Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/951 Reviewed-by: Spencer Oliver + Tested-by: jenkins + +2012-10-30 Salvador Arroyo + + * : mips: optimize mips_ejtag_step_disable() code The code is a bit large compared to mips_ejtag_step_enable(). With + the mips32 xori instruction the code can be reused. The number of + pracc accesses are reduced from 18 to 7. Change-Id: If3974ebd64da4461c22b089796646990e68e1b72 Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/944 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-11-15 Spencer Oliver + + * : doc: update to new sourceforge git url The new sourceforge platform also supports http access, so use that + rather then repo.or.cz. Change-Id: Ica89d9475847a2095c179b240053145795549802 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/982 Tested-by: jenkins + +2012-11-10 Matthias Blaicher + + * : rtos: Fix error in reading the current thread in ChibiOS/RT Commit c4ab127b4069e20e introduces a copy&paste error which affects + the detection of the current thread. As a result, the stack of the current thread won't be detected + correctly in most cases. Change-Id: Ib46b8f64be8053d7e9103f427c66796963214419 Signed-off-by: + Matthias Blaicher Reviewed-on: + http://openocd.zylin.com/974 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-10-22 Karl Kurbjun + + * : ARM v4/v5 target files: mrc and mcr help information is + incorrect. The order of the mrc/mcr command matches the ARM Architecture + Reference Manual. This patch corrects the help information for + mrc/mcr. Change-Id: I1f0e6a628a3644124591a6aa291b8a58cfd93b44 Signed-off-by: + Karl Kurbjun Reviewed-on: + http://openocd.zylin.com/914 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-10-08 Peter Horn + + * : cortex_m: Fix single stepping will not return to debug mode + sometimes This occurs when stepping past a breakpoint on a even address with + maskisr option set to auto With -d3 the following log message appears in this case: "Debug : Interrupt handlers didn't complete within time, leaving target running" Cause : Given a breakpoint is set on the lower half word and the PC + is on the upper half word. When another breakpoint is now set on the + current PC then resuming the core will not result in a break on the + newly set breakpoint. This has been observed on a STM32F1x, STM32F2x + (CM3) but not on a STM32F0x (CM0). It's not clear if this is a + STM32F1/F2 only or a general CM3 problem. Change-Id: I384813f3bfdf935373b5e23cdb2d7f243c70cc00 Signed-off-by: + Peter Horn Reviewed-on: + http://openocd.zylin.com/864 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-10-25 Gianluca Renzi + + * : Generic LPC1850 board w/ SPIFI flash. This config file is intended as an example of how to use the + lpcspifi flash driver, but it should be functional for most LPC1850 + boards utilizing SPIFI flash. Change-Id: I855854282336701fd210134497ce014017f3aaec Signed-off-by: + Gianluca Renzi Reviewed-on: + http://openocd.zylin.com/929 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-11-05 Spencer Oliver + + * : cortex_m: fix define formatting Change-Id: Ibdec882b2afc7e16f2361f86715463e030a54964 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/963 Tested-by: jenkins + +2012-11-05 Matthias Blaicher + + * : rtos: Add FPU detection to ChibiOS/RT The stacking of ChibiOS/RT depends on the usage of an FPU. If the + FPU is enabled the FPU registers are also saved on context switch. This patch adds automatic detection of FPU for armv7m targets. Note: With this patch, openocd will only output an error message warning that the FPU is enabled. For further FPU support, the correct stacking information also needs to be added. Change-Id: I0984cbd9180f247ba2fa610e74a6413cc54239ea Signed-off-by: + Matthias Blaicher Reviewed-on: + http://openocd.zylin.com/961 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-09-19 Sergey Borshch + + * : fix memory leaks if add_connection() fails, memory allocated in + copy_command_context() is lost. Signed-off-by: Sergey Borshch + Change-Id: I91a2757f29612038031eb8953100faa3b850d3a6 Reviewed-on: + http://openocd.zylin.com/836 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-10-28 Peter Stuge + + * : mpsse: Always perform a general reset of the MPSSE in + mpsse_open() Per AN_135 FTDI MPSSE Basics Version 1.1, section 4.2 step 7. + + http://www.ftdichip.com/Support/Documents/AppNotes/AN_135_MPSSE_Basics.pdfThis allows to stop and restart OpenOCD reliably, without needing to + power cycle the interface. Change-Id: Ibeafe5ecfe7b2f6f82712cbc85116904407ddb36 Signed-off-by: + Peter Stuge Reviewed-on: + http://openocd.zylin.com/939 Tested-by: jenkins + +2012-10-28 Peter Stuge + + * : ftdi/flyswatter2.cfg: Fix the signal layout Change-Id: If6612af25fa3562f49e9c8ccff01b6ef0af5ceb0 Signed-off-by: + Peter Stuge Reviewed-on: + http://openocd.zylin.com/938 Tested-by: jenkins + +2012-10-26 Spencer Oliver + + * : gdb: fix broken qCRC packet handling The rtos layer was incorrectly handling a qCRC packet as a qC + packet. Make sure we check for the qCRC packet and return unhandled + so the gdb server gets a chance to handle it. This packet is used in the gdb compare-sections cmd. Change-Id: I21f8e5fa7225fccd13d65cf9e40186895065a7e3 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/933 Tested-by: jenkins Reviewed-by: + Matthias Blaicher Reviewed-by: Peter Stuge + + +2012-10-18 Edgar Grimberg + + * : ioutil: make the file compile on MacOS The meminfo command cannot exist if the malloc.h header is not + present. Cannot get the mac address without sys/ioctl.h and + SIOCGIFHWADDR defined Change-Id: Ifc0fb98c3a60c53ad2e19473e08b34c460529d0b Signed-off-by: + Edgar Grimberg Reviewed-on: + http://openocd.zylin.com/912 Tested-by: jenkins Reviewed-by: Øyvind + Harboe Reviewed-by: Peter Stuge + + +2012-10-23 Matthias Blaicher + + * : rtos: fix gdb qC command answer rtos->current_thread is of type int64_t. All other commands already + respect this. Change-Id: I9951946ff2a09c53cd78c6ab882c80cdd2ab7ac6 Signed-off-by: + Matthias Blaicher Reviewed-on: + http://openocd.zylin.com/917 Reviewed-by: Spencer Oliver + Tested-by: jenkins Reviewed-by: Peter Stuge + + +2012-10-27 Matthias Blaicher + + * : rtos: Fix wrong allocation in linux_get_symbol_list_to_lookup linux_get_symbol_list_to_lookup allocates to few memory. On 64 bit + systems the error did not show due to char* being twice its size, + leaving accidentally enough space. This patch makes linux_get_symbol_list_to_lookup behave identical to + all other RTOS. Change-Id: I290ea241fb20b65585c8be14609a92fdbd2a307d Signed-off-by: + Matthias Blaicher Reviewed-on: + http://openocd.zylin.com/934 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-10-18 Spencer Oliver + + * : docs: mention extended-remote support Change-Id: Idd7cc0364856082cbbfee5015e49cd7d237d68ef Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/913 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-10-11 Spencer Oliver + + * : gdb: fix extended-remote restart Seems versions of gdb > 6.8 require an W stop reply after receiving + a kill packet. Without this we receive the following error from gdb: + gdb/thread.c:72: internal-error: inferior_thread: Assertion `tp' + failed. Change-Id: I86765a321f0429c9b517fe13ded0ee2dbd4b2f87 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/911 Tested-by: jenkins Reviewed-by: Joel + Bodenmann Reviewed-by: Freddie Chopin + + +2012-10-06 Freddie Chopin + + * : Fix serious bug in LPC2xxx/LPC17xx flash algorithm. Flash algorithm for LPC17xx/LPC2xxx was trying to "reuse" previously + allocated working area on next flashing which is not possible - + working areas are freed automatically on reset. This caused all but + first flashing attempts to fail. As there is no point in storing + pointer to working area, it was converted to local variable. Change-Id: I939946325ff9eecc4861c0f51ab0f73871a3d7b9 Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/860 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-10-05 Matthias Blaicher + + * : rtos: Add ChibiOS/RT support This patch adds ChibiOS/RT support. This patch requires at least + ChibiOS/RT development version starting from SVN revision 4734. Note, that the Thread structures depend not only on the target but + also on the ChibiOS configuration at build time. To correct this + ChibiOS includes a new "memory signature" which specifies the + offsets. Special thanks go to Peter Stuge and Spencer Oliver for their + continous input and feedback to this patch. Change-Id: I842bf7ba6c2309a4efe93d29ea6cd0784a8b22a3 Signed-off-by: + Matthias Blaicher Reviewed-on: + http://openocd.zylin.com/901 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-09-27 Spencer Oliver + + * : flash: update stellaris flash data to latest dev package 9453 Change-Id: I16107a093d4ed7342583f5c32ad16aa98f81d122 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/856 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-05-17 Paul Fertser + + * : rtos: support FreeRTOS over stlink Since stlink is a special case it presents the same CPU core under a + different name, so copy the configuration to account for that. Change-Id: I9febf79b388301bde6211d185b5b8161cdadb9ff Signed-off-by: + Paul Fertser Reviewed-on: + http://openocd.zylin.com/652 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-09-30 Andreas Fritiofson + + * : dsp5680xx_flash: Remove unused flash bank structure Change-Id: I947b6730b3741a71303e440daefa4fcf583cb9cf Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/867 Reviewed-by: Freddie Chopin + Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-09-30 Andreas Fritiofson + + * : flash/nor/stellaris: Remove unnecessary write_algorithm check The pointer must be non-null here since we returned if allocation + failed. Change-Id: I9b75099ed3b3870c815d1df5760ed1f3fe1d20d6 Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/866 Reviewed-by: Freddie Chopin + Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-10-04 Spencer Oliver + + * : readme: update missing configure args Change-Id: I495a4557f161290f8f99788de27958f7dc08d6f6 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/900 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-10-04 Peter Stuge + + * : rtos: Rewrite rtos_qsymbol() and fix auto-detect false positive Matthias Blaicher submitted a patch at + http://openocd.zylin.com/#/c/891/ to fix the false positive; when no + RTOS was detected OpenOCD used the last RTOS in the list. While reviewing the code affected by Matthias' patch a rewrite + seemed appropriate, to make the code readable. Matthias has abandoned his change and this change also fixes the + false positive. Change-Id: Ic3327ccd036da52ba0a7e21ef93018205e74149c Signed-off-by: + Peter Stuge Reviewed-on: + http://openocd.zylin.com/895 Reviewed-by: Matthias Blaicher + Tested-by: jenkins + +2012-10-04 Peter Stuge + + * : rtos: Rewrite rtos_create() for readability The new code is almost functionally equivalent to the old; besides + error handling the only difference is that the code is now readable. Many thanks to Matthias Blaicher for pointing out an iteration error + in the rtos_try_next() change, which also affected this change. Change-Id: If38b87439e9de2303b220b3a7e3200ceaa8391da Signed-off-by: + Peter Stuge Reviewed-on: + http://openocd.zylin.com/893 Tested-by: jenkins Reviewed-by: + Matthias Blaicher + +2012-10-04 Spencer Oliver + + * : build: fix broken ftd2xx bus blaster If configure is executed without --enable-ft2232_ftd2xx then the bus + blaster or presto will fail to build with unresolved external + ftd2xx_status_string. Make sure we run the ftd2xx build test if + --enable-usb_blaster_ftd2xx is enabled. Change-Id: I09d270d6fcd083d77f6785b8969d9acb3dfef11d Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/892 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-09-26 Spencer Oliver + + * : cfg: cortino tested and working Change-Id: I13534742c76ebbb05b47bf98768c997068da747a Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/851 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-09-26 Spencer Oliver + + * : cfg: ftdi icdi enable srst open drain config Change-Id: I21a115121f167dc88cd9bf2d1ca1ac9f3e1110d7 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/848 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-09-25 Spencer Oliver + + * : cfg: lm3s811ek config tested and working Change-Id: I5402b5521d6e1ef0a569f5cad02c003681f5444b Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/847 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-09-25 Spencer Oliver + + * : cfg: stm32-performance stick config tested and working Change-Id: I9852d11e369e501af240a2b8e9f74306aee4e4a0 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/845 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-09-28 Spencer Oliver + + * : docs: enable local structs in doxygen output Change-Id: I9c811d49690524f1ce5372326de67ec4ac7b09f4 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/858 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-09-26 Spencer Oliver + + * : cfg: add ti ek-lm3s9d92 config Change-Id: Ib09ca3e57de363a24d704b184ba8546bad08f56f Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/853 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-09-27 Spencer Oliver + + * : sysfsgpio: remove ignoring return value build warning fixes following gcc warning: error: ignoring return value of write, + declared with attribute warn_unused_result Change-Id: I96ea6649078449208a77690caea2cb237c388e6e Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/854 Tested-by: jenkins Reviewed-by: Marc + Reilly Reviewed-by: Freddie Chopin + + +2012-09-26 Spencer Oliver + + * : cfg: add STM32F3-DISCOVERY board support Change-Id: I4a02e0504fc04ffc1238d9bb77ec05c1f781e7e8 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/810 Reviewed-by: Freddie Chopin + Tested-by: jenkins + +2012-09-26 Spencer Oliver + + * : cfg: fix incorrect str9-comstick reset config The str9-comstick uses a direct srst connection rather than via any + buffer. As a result this fixes issues with the newer ftdi driver. Change-Id: I0968e8459997a6a2b7bf0c46e89662cd57b4f496 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/842 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson Reviewed-by: Freddie + Chopin + +2012-09-24 Spencer Oliver + + * : ftdi: correct ftdi_initialize error text Change-Id: If230c0b5b3a18fd273106b743404079d0cbc9ddc Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/840 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson Reviewed-by: Freddie + Chopin + +2012-09-27 Spencer Oliver + + * : cfg: fix incorrect stm32f3 TAPID Change-Id: Id66d4e03a77c47a49086ee753bed01b3944064e1 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/855 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-08-22 Spencer Oliver + + * : jtag: remove libftdi enum-compare warning See Trac #52 for details. Change-Id: Idb509ead2b51bfcceeb00d0224a4d1c395b28a04 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/801 Tested-by: jenkins Reviewed-by: Olivier + Schonken Reviewed-by: Freddie Chopin + + +2012-08-16 George Harris + + * : Added SPIFI flash driver, algorithms, and docs Added a flash driver designed to allow program/erase of + memory-mapped SPI flash chips for LPC43xx/LPC18xx family micros. + This driver includes three algorithms - erase, write, and SPIFI + peripheral initialization (to allow memory-mapped access after a + reset). The driver has been added to the flash driver table + (drivers.c), and the OpenOCD documentation has been updated to + include the flash driver configuration command. Change-Id: I79f4ff8f1f07de4e5f2fe4f8c23aeb903f868514 Signed-off-by: + George Harris Reviewed-on: + http://openocd.zylin.com/783 Tested-by: jenkins Reviewed-by: + Aurelien Jacobs Reviewed-by: Freddie Chopin + + +2012-08-20 Marc Reilly + + * : drivers: new jtag bitbang driver using sysfs gpio This driver implements a bitbang jtag interface using gpio lines + exported via sysfs. The aim of this driver implementation is to use system GPIOs but to + avoid the need for an additional kernel driver. A config suitable for RaspberryPi is included. Change-Id: Ib2acf720247a219768d1cbfeebd88057ed2d7b8b Signed-off-by: + Marc Reilly Reviewed-on: + http://openocd.zylin.com/762 Reviewed-by: Spencer Oliver + Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-09-07 Freddie Chopin + + * : The openocd-0.6.0 release. Change-Id: I72eeabfc704d2a979ac0b4492771690631d2300f Signed-off-by: + Freddie Chopin + +2012-09-02 Chuen Chou + + * : flash: fix sam3 page read/write address computation error In at91sam3.c for Atmel SAM3 flash support, there are arithmetic + errors in the functions sam3_page_read() and sam3_page_write(). + Address locations are computed incorrectly due to an extra addition + operation. This leads to memory locations being skipped during flash + writes and reads. Smaller programs are written successfully into flash, with memory + gaps, while larger programs of legitimate size fail because the + skipped memory is not utilized and therefore unavailable. The changes address this condition, and have been tested with an + Atmel SAM3X-EK evaluation board. Change-Id: I9ea3b9ed0130b71cbc32b2294e31a6a2bc71b47a Signed-off-by: + Chuen Chou Reviewed-on: + http://openocd.zylin.com/806 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-09-05 Spencer Oliver + + * : docs: add user mailing list and irc info Change-Id: I7000b5ab2967f8dc4cea8983978fce824ea1f98e Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/807 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-08-29 Freddie Chopin + + * : Restore -dev tag. Signed-off-by: Freddie Chopin + +2012-08-25 Salvador Arroyo + + * : Pic32mx: make row programming work with any offset In function pic32mx_write_block() if the parameter offset is not a + multiple of row size the row offset (offset % row_size) will be + ignored by the flash controller, shifting the code to the beginning + of the row. Word programming gets it right. Change-Id: I134913e3d533688f791bbcb0c6e8983524197f3c Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/796 Tested-by: jenkins Reviewed-by: Spencer + Oliver Reviewed-by: Freddie Chopin + + +2012-08-28 Spencer Oliver + + * : stlink: fix typo Change-Id: I5fe7b695b00faef966e7621614bbd60b6e694a4f Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/800 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Freddie Chopin + + +2012-08-23 Andreas Fritiofson + + * : ftdi: fix overflow if last field of a scan is empty The last bit of a scan is clocked during TAP movement so it's + necessary for the last field to have at least one bit. Strip + trailing empty fields and make sure the TAP is not affected if + there's nothing to scan. Clients probably shouldn't add empty fields + so add a debug message to be able to track and fix them. Change-Id: I27552568bc11146570b9b99ed8a1ae81b5fb2c50 Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/794 Reviewed-by: Spencer Oliver + Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-08-28 Spencer Oliver + + * : adapter: remove superfluous line breaks Change-Id: I8e68b9d6f571ef7715a2f4cad0aa78fe4e3b48e8 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/798 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-08-17 Freddie Chopin + + * : Update NEWS Added some missing items to NEWS file prior to final 0.6.0 release. Change-Id: I69255c85fa8f4b6f06eae7c56f78072e3ec2d6f8 Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/784 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-08-17 Freddie Chopin + + * : Add another scripts search path for Windows builds Add single "scripts" folder to search path for Windows OpenOCD + builds that don't use cygwin bin/openocd.exe + scripts/interface/dummy.cfg scripts/target/at91eb40a.cfg Do some refactoring of current code (thx to Andreas). Change-Id: Idbb08d1368b06f25da44f4f9ab1511db992b1724 Signed-off-by: + Freddie Chopin Signed-off-by: Andreas + Fritiofson Reviewed-on: + http://openocd.zylin.com/785 Tested-by: jenkins + +2012-07-07 Christopher Kilgour + + * : kinetis: ensure flash writes are not truncated The number if longwords or "sections" (Freescale term) written for a + Kinetis flash write (4, 8, or 16 bytes depending on the part + density/granularity) are now rounded up to ensure there are no + truncations when the desired write is not a multiple of the minimum + write size. Change-Id: I8db40a8769d8ac5393a46cbf4e5ff0df82faf916 Signed-off-by: + Christopher Kilgour Reviewed-on: + http://openocd.zylin.com/738 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-08-22 Salvador Arroyo + + * : Patch: Make pic32mx unlock work at higher scan frequencies For example in a pic32mx220, pic32mx unlock don't work if + adapter_khz is set to 5000 or more. A short delay after asserting reset fix the problem. Change-Id: I62e493edfcea585c36c8de77a969cebac7227b96 Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/790 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-08-23 Spencer Oliver + + * : stlink: stlink_interface_init_target use hex prefix Change-Id: I782da74687bcf111c1f04c53b2c1120d6a034441 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/791 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-08-05 Salvador Arroyo + + * : Severe bug in Pracc code The function wait_for_pracc_rw() fails if Pracc bit is 0. The + variable ejtag_ctrl is loaded with the content of the control + register in the first scan. In the second scan Pracc bit is scanned + out as 0, letting the proccesor go. The result is unpredictable. All the strange data corruption when scanning at certain + frequencies, or the strange delays needed when entering or leaving + fasdata area are retated to this bug. Now the code works at any scan frequency, tested up to 15000Khz and + indepently of processor speed, tested at 31.25Khz and 4/8Mhz. Change-Id: Iedfd81d06d6af4bc738a521f720e42323025b268 Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/769 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-08-14 Andreas Fritiofson + + * : cfi: fix type-punning warnings in cfi_spansion_write_block Retest the condition when needed, instead of abusing the + common_magic field as a flag. There are only two options here. + Either it's an armv7m or it's another arm. is_arm(...) will return + true even for armv7m, so it's imperative to check in the right + order. Change-Id: Ic227f19f7babf1b0b0fe075f9a3abc4eabc7d5f1 Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/779 Tested-by: jenkins Reviewed-by: Spencer + Oliver Reviewed-by: Freddie Chopin + + +2012-08-13 Spencer Oliver + + * : target: catch dap_lookup read error Issue found by clang-3.1 Change-Id: I2e922ec83117e75db5bec1e82edaa75a9e6e7464 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/778 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-08-13 Spencer Oliver + + * : tcl: fix potential memory leaks Reorder to allocate all memory after COMMAND_PARSE_NUMBER call. + This removes a clang warning about un-released memory Change-Id: I8dbeb664a6467077157015bd879bc0aefc5e8614 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/776 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-08-10 Spencer Oliver + + * : flash: fix FC_FLEX_RAM class code path If the flash class was defined as FC_FLEX_RAM then this would always + drop through to the default handler. This bug was found by clang, so untested. Change-Id: I2d9fe6415dd216728a145519400f7b9ef1bd3c3a Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/773 Tested-by: jenkins Reviewed-by: Freddie + Chopin Reviewed-by: Mathias Küster + + +2012-08-07 Aurelien Jacobs + + * : ftdi: Olimex ARM-USB-TINY validated Flashing a CFI flash and debugging with gdb work fine. Change-Id: Ib2578ee6f41c1003968198439033d00d805122f7 Signed-off-by: + Aurelien Jacobs Reviewed-on: + http://openocd.zylin.com/770 Tested-by: jenkins Reviewed-by: Spencer + Oliver Reviewed-by: Freddie Chopin + + +2012-08-14 Spencer Oliver + + * : cfg: remove duplicate Olimex ARM-USB-OCD config This file is already included as olimex-arm-usb-ocd.cfg. Change-Id: I0e66977c58e74ac93a0dc3a0c88a5e5af4992f8b Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/780 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-08-02 Freddie Chopin + + * : Restore "-dev" tag. Change-Id: Ibb7669ea73872d75a5c2f32f2264e57b1d0f20c7 Signed-off-by: + Freddie Chopin + +2012-08-02 Spencer Oliver + + * : target: add valid smp target check Check that the target is valid before calling any target functions. Change-Id: I538fccc79d5ec89976e14beab02cb20490b299bb Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/766 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-08-02 Freddie Chopin + + * : Add missing files (header and .txt) for release. make distcheck is used to make packages with OpenOCD release, this + command uses information from Makefile.am files to know which files + should be included in the package and which can be left only in + repository. This patch makes a few headers from recent JTAG drivers + and one txt file with info about target tcl config files included in + released packages. Change-Id: I91202290633a30f53624a8c7d9a0ebf72c40772b Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/767 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-06-08 Alexander Osipenko + + * : arm946e: cp15 command returns value to the script Not just print it. This enables scripts to analyze valuable config options of arm946e-s + cores, do internal BIST memory tests and more. Be careful to flush caches before disabling it. Do not forget that + BIST test overwrites memory. - cp15 rewritten from COMMAND_HANDLER to jim_handler. Change-Id: I734da0be6db0a3127c2daa94ed75efef94da8ceb Signed-off-by: + Alexander Osipenko Reviewed-on: + http://openocd.zylin.com/694 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-07-31 Alexander Osipenko + + * : arm946e: don't use global variables for context Global variables 'dc' 'ic' had been used in the code to keep + target's state of D-cache and I-cache on debug entry. This may lead to incorrect operation in configurations with multiple + cores and unequal cache states. Fix: move cache state to the appropriate bits of the + 'cp15_control_reg' field (already present but unused). Vaule of + cp15 control register stored here on arm946e_post_debug_entry(), and + analyzed later in arm946e_write_memory(). Change-Id: I71ef82be00c21d6fffb3726cec4974d1ece70dfe Signed-off-by: + Alexander Osipenko Reviewed-on: + http://openocd.zylin.com/692 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-07-25 Joerg Fischer + + * : cfg: Add Hitex LPC1768-Stick using ftdi driver Add cfg files for Hitex LPC1768 Stick Website: + http://www.hitex.com/?id=1602 This board has a FTDI2232D as JTAG interface, using the same layout + as the Hitex STM32-PerformanceStick but with different USB PID. Main MCU is a LPC1768 from NXP. The interface config uses the ftdi driver instead of ft2232. The + corresponding ft2232 layout would be "stm32stick". Change-Id: I1fd15588c5af35f7d51777d1ad958cc1dc72c6f7 Signed-off-by: + Joerg Fischer Reviewed-on: + http://openocd.zylin.com/763 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-07-19 Freddie Chopin + + * : cfg: Add config file variants using the ftdi driver instead of + ft2232 part 4 - files that are currently untested Change-Id: Ic4a08fdefc99e7a9d50885c888c3fca60ffa39bd Signed-off-by: + Andreas Fritiofson Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/750 Tested-by: jenkins + +2012-07-20 Freddie Chopin + + * : cfg: Add config file variants using the ftdi driver instead of + ft2232 part 2 - files that are currently untested but assumed to work, as + other configs using the same layout work fine Change-Id: Ifaa1904227ebdc394362ccaf3ad3c5384a716657 Signed-off-by: + Andreas Fritiofson Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/754 Tested-by: jenkins + +2012-07-19 Spencer Oliver + + * : telnet: cleanup comments seems comments were mangled during the last cleanup. Change-Id: If759f62032705c7baffd3973e9717eb7e8a5d17c Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/752 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-06-07 Salvador Arroyo + + * : Bugfixes in mips32_pracc.c When testing a pic32mx220f032b with different values for adapter_khz + and cpu clocks i was getting a lot of corrupted data from the chip. + From time to time openocd fails with segmentation faults or is + aborted due to memory corruption. Change-Id: I134743f75c477b3d55dc74ae4474598e153b4a4a Signed-off-by: + Salvador Arroyo Reviewed-on: + http://openocd.zylin.com/690 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson Reviewed-by: Freddie + Chopin + +2012-07-17 Andreas Fritiofson + + * : flash: reduce code duplication in stm32 flash probe Remove a lot of the repetitive code in stm32f1x flash probe by + converting the large if-selector to a switch, moving the common + checks outside it and concentrating the failure handling to a single + point. Do the same with stm32f2x and stm32lx for consistency. Change-Id: Ic0ecfb1533c49f5d2108cda5fd20c8372d7c71ef Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/746 Tested-by: jenkins Reviewed-by: Spencer + Oliver Reviewed-by: Freddie Chopin + + +2012-07-12 Spencer Oliver + + * : flash: handle zero when reading stm32 flash size reg Some variants read 0 for the flash size register, rather than + failing lets assume we have max flash fitted. Change-Id: Ie1fb4e73606f49268a6fd5921c3aef75bc4790d3 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/744 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson Reviewed-by: Freddie + Chopin + +2012-07-12 Spencer Oliver + + * : flash: add stm32l Revision X support Revision X is not mentioned in the latest RM0038 rev5, however it + has been confirmed correct by ST using ST-LINK Utilty. Change-Id: I65210e512ea25818a1d0d3b223502ebd7535b29d Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/742 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson Reviewed-by: Freddie + Chopin + +2012-07-11 Andreas Fritiofson + + * : cfg: remove deprecated stm32 target configs These were deprecated in commit 69ac20a. Signed-off-by: Andreas Fritiofson + Change-Id: I047872f8cd61b42aaca6588ab75566219e4a3f5d Reviewed-on: + http://openocd.zylin.com/741 Tested-by: jenkins Reviewed-by: Freddie + Chopin Reviewed-by: Spencer Oliver + + +2012-07-11 Andreas Fritiofson + + * : flash: don't write to FLASH_CR in stm32x_write_block It's unnecessary and prevents reusing this function to fix option + byte writes. Also try to disable flash writing after an error. Change-Id: Ib5a7b768a1523e6b8da1555126fef4c1e60ab083 Signed-off-by: + Szymon Modzelewski Signed-off-by: Andreas + Fritiofson Reviewed-on: + http://openocd.zylin.com/479 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-07-20 Alex Austin + + * : Revert "When calling openocd from a shell like this:" This reverts commit e8641695c634109ebf5f1149923971770da1d28a Original premise was wrong. Proper command is "shutdown", not + "exit". Change-Id: I07f5fe0dda9c24abe53628da986bfda0e406bb4a Signed-off-by: + Alex Austin Reviewed-on: + http://openocd.zylin.com/757 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-07-17 Freddie Chopin + + * : Add config file for Lattice LC4032ZE CPLD (ispMACH 4000ZE + family) Change-Id: Iefec12b30ff737317c454b472200fd7e7edde619 Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/748 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-01-30 Andreas Fritiofson + + * : Add FTDI JTAG driver using MPSSE layer Based on ft2232.c but uses the MPSSE layer for low-level access, + greatly simplifying the JTAG logic. Remove all libftdi/FTD2XX code + and all layout specific code. Layout specifications are instead + handled in Tcl. Use a signal abstraction to enable Tcl configuration files to define + outputs for one or several FTDI GPIO. These outputs can then be + controlled using the ftdi_set_signal command. Special signal names + are reserved for nTRST, nSRST and LED (for blink) so that they, if + defined, will be used for their customary purpose. Depending on the type of buffer attached to the FTDI GPIO, the + outputs have to be controlled differently. In order to support + tristateable signals such as nSRST, both a data GPIO and an + output-enable GPIO can be specified for each signal. The following + output buffer configurations are supported: * Push-pull with one FTDI output as (non-)inverted data line * Open drain with one FTDI output as (non-)inverted output-enable * Tristate with one FTDI output as (non-)inverted data line and + another FTDI output as (non-)inverted output-enable * Unbuffered, using the FTDI GPIO as a tristate output directly by switching data and direction as necessary The data and output-enables are specified as 16-bit bitmasks, + corresponding to the concatenation of the high and low FTDI GPIO + registers. To specify an unbuffered output, use the same bitmask for + both data and output-enable. The adapter configuration file must also specify default values for + the FTDI data and direction GPIO registers, and the channel being + used (if different from 0). Change-Id: I287a41d4c696cf5fc74eb10d5e63578b0dc7f826 Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/452 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-06-27 Spencer Oliver + + * : target: Cortex-M use consistent arm dap access Purely cosmetic but use the same style as Cortex-A target, this + makes searching refs easier. Change-Id: I732ad9701f561e2312c5d191f5aaffd3a2f2393d Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/731 Reviewed-by: Freddie Chopin + Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2012-07-04 Spencer Oliver + + * : flash: add stm32f3x support add support for the new stm32f3x family from stmicro: + http://www.st.com/stm32f3 Change-Id: Icd1db95bb2767d9c0ecef24deefa92b4fdaa4f14 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/735 Tested-by: jenkins Reviewed-by: Freddie + Chopin Reviewed-by: Andreas Fritiofson + + +2012-06-27 Spencer Oliver + + * : target: detect correct Cortex-M tar auto increment size The ADIv5 spec guarentees that tar_autoincr_block will be 10bits. + Make this the default for Cortex-M family until we detect a + Cortex-M3/M4, we then change autoincrement to 12bits. Change-Id: Ie8c89134aa036879bdd8a3c312cee9715dbc6913 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/730 Tested-by: jenkins Reviewed-by: simon + qian Reviewed-by: Freddie Chopin + + +2012-02-18 Stian Skjelsad + + * : When calling openocd from a shell like this: openocd -f board/sheevaplug.cfg -c init -c exit the calling shell will believe that openocd exited with an error due + to exitval will be non-zero This is not tested against incomming telnet Change-Id: I63d15715a7b46f39a7de261a45039f8c3cad7a98 Signed-off-by: + Stian Skjelstad Reviewed-on: + http://openocd.zylin.com/470 Tested-by: jenkins Reviewed-by: Spencer + Oliver Reviewed-by: Bill Traynor + Reviewed-by: Mathias Küster + Reviewed-by: Freddie Chopin + + +2012-05-24 Vandra Akos + + * : target/target.c, jim_target_md refractored - Added a few lines of comment before the function explaining the + usage and the output generated by the command - Added a few lines of comment in the body explaining what is + happening to improve code readability - Renamed a few variables to improve readability: * a -> addr * b -> dwidth * c -> count - Added a new variable, named byte to contain the number of bytes + to read, instead of overwriting the count parameter, to avoid + confusion between the two values. Change-Id: I5828ec0f5aadaa39becec7b84f198756bb2c3d41 Signed-off-by: + Vandra Akos Reviewed-on: + http://openocd.zylin.com/665 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-05-29 Mike Crowe + + * : topic: flash: description/id added for ATSAM3SD8C New flash description for ATSAM3SD8C used on SAM3S-EK2 development + boards. Name used is "at91sam3sd8c" and chipid is 0x29ab0a60. + Mirrors description of other similar parts. Change-Id: I7fc4b82e7969451645ab067223663f08b76d866b Signed-off-by: + Mike Crowe Reviewed-on: + http://openocd.zylin.com/684 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-06-04 Olivier Schonken + + * : Changed SAM4S Erase for effective Sector erase In the previous iteration, the page counter for erases would not be + updated with the erase size. This patch keeps the page counter + synced with the sector counter. Signed-off-by: Olivier Schonken + Change-Id: I95e56a3257b2ad8301c9f28167b842fa6466334f Reviewed-on: + http://openocd.zylin.com/686 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-05-23 Christopher Kilgour + + * : kinetis: update support for all program flash granularities Updates the Kinetis NOR flash support to handle all known block and + sector sizes. Previously only 2kiB sectors were hard-coded, now all + four known combinations non-volatile sector sizes are supported. The premise of separating Kinetis Program Flash (PFLASH) from + FlexNVM is also introduced. This means each "block" of flash (in + Freescale terms) is treated as a bank in OpenOCD. Correspondingly, + the existing board configuration for the TWR-K60M512 eval system is + updated to recognize two banks instead of one. A board config for the TWR-K60F120M is also added. Bank and sector erase and programming has been checked with both of + the mentioned eval boards. Change-Id: Iae2d10ebf8f548d0a3698df5430bbbe1ccadc58a Signed-off-by: + Christopher Kilgour Reviewed-on: + http://openocd.zylin.com/663 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Jan Dakinevich + Reviewed-by: Spencer Oliver + + +2012-05-28 Alexander Osipenko + + * : JLink: added jlink_usb_io() function jlink_usb_io() function added for basic communication, since + jlink_usb_message() is more specific to JTAG transactions. To verify the patch issue "jlink config" command. Change-Id: Id7d10bd5e8985d4c77f2e0ca47fb6033db2877bf Signed-off-by: + Alexander Osipenko Reviewed-on: + http://openocd.zylin.com/679 Tested-by: jenkins Reviewed-by: Xiaofan + Reviewed-by: Spencer Oliver + + +2012-05-29 Liviu Ionescu + + * : docs: J-Link commands added to the manual The J-Link related commands and configuration commands were added to + the "8.2 Interface Drivers" section of the manual. (previously they + were enumerated as comments). The 'jlink pid' was marked as Config + all other as Command. A draft of a compatibility note was added, + but probably a table would be more appropriate. Change-Id: Ifbe230706815196aaad4e3729ed5089d5088b769 Signed-off-by: + Liviu Ionescu Reviewed-on: + http://openocd.zylin.com/680 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-06-22 Mirela Tauciuc + + * : AT91SAM7 Flash: fixed redundant assignation warning Change-Id: Iffacdce9ce90c4ea7e0c8647860a0056b952f387 Signed-off-by: + Mirela Tauciuc Reviewed-on: + http://openocd.zylin.com/691 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2012-05-29 Spencer Oliver + + * : docs: update interface support in README Change-Id: Id4b982ee426dedc85b643a71c1cdba67d0dd0ffd Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/682 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-05-25 Spencer Oliver + + * : build: remove src file execute permission Change-Id: I42a250cdfcd03424a63cd1a255f9cf4a3c6e3ccd Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/671 Reviewed-by: Xiaofan + + +2012-05-23 Spencer Oliver + + * : target: fix segfault in arm7_9 8/16bit read Seems I5347352e7595686634bd0de13fcf6de6e55027b0 introduced an issue + when reading 8/16 bit data - the in buffer was always set to 32bits. Change-Id: Ife2bb6a20fcb3ec0e486655512164f25ae9196b4 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/660 Tested-by: jenkins Reviewed-by: Mathias + Küster + +2012-05-09 Mathias K + + * : board: Add Sony Ericsson J100I Phone This patch add the Sony Ericsson J100I Phone to the board + configurations. Change-Id: I083ddf067c8ecdfdda0404fe9e9df980dbb86fe8 Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/631 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-05-22 Bill Traynor + + * : jtag: fix osbdm.c typo Fixing up tiny spelling error of "receive" vs. "recieve". Change-Id: Ib143d7fdb24ac1f2b7bd4ae90cadaf2e12760ff7 Signed-off-by: + Bill Traynor Reviewed-on: + http://openocd.zylin.com/659 Tested-by: jenkins Reviewed-by: Xiaofan + Reviewed-by: Peter Stuge + +2012-05-22 Spencer Oliver + + * : jtag: remove opendous clang warnings Change-Id: I0285c99507931e7d13aad36f4fc559c29a52faca Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/655 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-05-21 Spencer Oliver + + * : target: target.h typo and comment cleanup Change-Id: Ib751803754672bf556f4f65bd3f5621f6bbb7f0c Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/654 Tested-by: jenkins Reviewed-by: Bill + Traynor + +2012-05-14 Spencer Oliver + + * : target: enable TARGET_EVENT_RESUME_* events Change-Id: I7d8378f9f34c6674db8c8b29d1a961389578e921 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/640 Reviewed-by: Freddie Chopin + Tested-by: jenkins Reviewed-by: Bill + Traynor + +2012-05-10 Spencer Oliver + + * : target: remove duplicate target events Change-Id: Iba9ae441f3e6d48a7dfafe59ed093fef56a34723 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/633 Reviewed-by: Freddie Chopin + Tested-by: jenkins Reviewed-by: Bill + Traynor + +2012-05-15 Bill Traynor + + * : UserGuide: Updated list of supported interfaces, boards, and + targets. User Guide: Chapter 6 'Config File Guidelines'. The directory + listings of interfaces, boards, and targets has been brought up to + date. Change-Id: I53f218a94cb81c5e90298b367259e833192af5f3 Signed-off-by: + Bill Traynor Reviewed-on: + http://openocd.zylin.com/646 Tested-by: jenkins Reviewed-by: Xiaofan + Reviewed-by: Spencer Oliver + + +2012-05-14 Spencer Oliver + + * : NEWS: add headline items Change-Id: Ie78b0a171af76cf647deef501245caf54209d9f8 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/639 Tested-by: jenkins Reviewed-by: Freddie + Chopin Reviewed-by: Xiaofan + + +2012-05-17 Spencer Oliver + + * : stlink: add myself to copyright header Change-Id: I39e23b38ee630b80bccb5ff6b5819efa0fcb120a Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/651 Tested-by: jenkins Reviewed-by: Xiaofan + + +2012-05-15 Spencer Oliver + + * : contrib: enable cortex-m0 and cortex-m4 libdcc support Change-Id: Ib8ff645d1e5b8baca02de8ea95b629d88b203969 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/644 Tested-by: jenkins + +2012-05-17 Alexander Osipenko + + * : remote_bitbang: missed closing brace in macro + REMOTE_BITBANG_RAISE_ERROR Change-Id: I591308bd98810ef6361106c207c55b83c3a83890 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/647 Tested-by: jenkins Reviewed-by: Xiaofan + + +2012-05-14 Spencer Oliver + + * : docs: add initial target rtos support info Change-Id: Idd39ce17922602aedd4626496ed8f5422bb76e07 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/641 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-05-11 Spencer Oliver + + * : stlink: add armv7m stlink handling This enables us to better handle some of the low level functions + that the stlink does not support. It also enables us to share a few + more of the standard cortex_m3 functions if necessary. Change-Id: I7a2c57450122012ec189245d8879d8967913e00e Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/637 Tested-by: jenkins + +2012-05-03 Spencer Oliver + + * : flash: fix protect check for pic32mx1x/2x family Change-Id: Ib2692d8b79e52cd40f429008047494aa7f552984 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/612 Tested-by: jenkins Reviewed-by: Xiaofan + + +2012-05-08 Spencer Oliver + + * : stlink: fix stlink api2 single step This makes the newer v2 api behave as per the v1 api, eg. single + stepping masks all interrupts. A better long term solution is to use same behaviour as a cortex-m3 + target, see CORTEX_M3_ISRMASK_AUTO. Change-Id: Iaf9f9adf225cf274faaac938050bb996582aa98f Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/621 Tested-by: jenkins + +2012-05-04 Spencer Oliver + + * : stlink: stlink/v1 use v2 api if supported The api v2 is supported on the stlink/v1 if it has a least v11 + firmware. Change-Id: Idfdb5a7f5a5881326017451ae9b6004eeaa46a96 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/616 Tested-by: jenkins Reviewed-by: Freddie + Chopin Reviewed-by: Xiaofan + + +2012-05-01 Freddie Chopin + + * : Use hardware reset and connect under reset on boards with + ST-LINK/V2, as now it is supported. Change-Id: Id3b2ca9a2270974a5f453323f9057ecece400c94 Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/609 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-05-01 Spencer Oliver + + * : stlink: support connecting under reset Some targets support connecting while the target's srst is asserted. + Tested on stm32 family. Change-Id: I1197dd721a1e1cbf95ee77dfd8e1082b165b22a9 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/607 Tested-by: jenkins + +2012-05-08 Aurelien Jacobs + + * : cfi: fix write_bank segfault with spansion flash on armv7m cfi_spansion_write_block() passes an arm_algorithm struct to + target_run_algorithm() which in turn calls armv7m_start_algorithm() + which expect an armv7m_algorithm struct. As armv7m_algorithm is + bigger than arm_algorithm, when armv7m_start_algorithm() writes in + the struct, it overrun the buffer, writting junk on the stack, which + latter on generates a segfault. This patch ensure we use a properly sized armv7m_algorithm struct + when the target is an armv7m. Change-Id: I4ab67c15ae4bb72454414a81b92a4231dcdb2239 Signed-off-by: + Aurelien Jacobs Reviewed-on: + http://openocd.zylin.com/623 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-05-03 Spencer Oliver + + * : cfi: check supported arch check that the cfi driver supports the current target arch. Change-Id: I8a95908684de67bf1657d1956f2573662a641cc1 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/614 Tested-by: jenkins Reviewed-by: + Aurelien Jacobs + +2012-05-01 Spencer Oliver + + * : build: add missing erase_check loader src Change-Id: I1534c1ea1606fda9eb6ffa6a11a708f8c8a3d46a Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/605 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-05-11 Spencer Oliver + + * : contrib: fix Neo1973 udev permission typo Change-Id: I6d5ad0cc28e0cb52104ead9e974b8b1ed92d9cdc Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/636 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-04-30 Spencer Oliver + + * : cfg: increase stm32f0discovery board working area Change-Id: Iea166ee27fc60bbfdeb851fdcf71509f3984f72f Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/602 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-05-08 Bill Traynor + + * : cfg: Deleted duplicate busblaster.cfg and renamed original. The busblaster.cfg was contributed on April 23, 2012 and is a + duplicate of dp_busblaster.cfg that was contributed on Oct. 23, + 2011. Therefore, deleting the second version. Also, renaming the + original dp_busblaster.cfg to simply busblaster.cfg, as this name is + more concise. Change-Id: Iccb1f10f53dbbb248b1ff4c6295eaf67c32247c1 Signed-off-by: + Bill Traynor Reviewed-on: + http://openocd.zylin.com/622 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-05-07 Bill Traynor + + * : cfg: add default pid/vid pair to beaglebone board cfg. The newer versions of BeagleBone boards use the default vid/pid pair + for FT2232 debugging. Please see the following README: + http://beagleboard.org/static/beaglebone/latest/README.htm On + revision A3/A4 boards, the VID/PID were chosen to match the TI + XDS100v2 (0x0403/0xA6D0). On A5 and newer revisions when we've given + the authors of CCS the chance to update their software, the generic + FTDI VID/PID (0x0403/0x6010) will be used to simplify installation + of drivers for systems already having those drivers. Change-Id: I44228eb2029162f23d084eb05bcfef39e615668d Signed-off-by: + Bill Traynor Reviewed-on: + http://openocd.zylin.com/619 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-04-27 Spencer Oliver + + * : build: remove clang unused variable increments warnings Change-Id: Ib755474aa46f7233495fae1947bc27cd0b2d6b4f Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/599 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-04-27 Spencer Oliver + + * : cfg: allow stm32discovery parameter override This enable the user or board config to override the parameters + passed to stm32_stlink.cfg. Required to fix a incorrect working area bug with the + stm32vldiscovery. Change-Id: I40a4f7913ff37d577d44b1f23befccf0317080a1 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/597 Tested-by: jenkins Reviewed-by: Freddie + Chopin + +2012-04-19 Spencer Oliver + + * : stlink: support srst reset This adds the ability to support srst reset for the stlink/v2. + stlink/v1 will fallback to using SYSRESETREQ which is a full reset - + including peripherals. To enable the use of the srst add the following to your cfg: + reset_config srst_only Change-Id: I570de607c5f370fd6a4abf47360686c9be07bcdd Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/581 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Freddie Chopin + + +2012-04-19 Spencer Oliver + + * : stlink: add hardware srst functions to stlink/v2 Change-Id: Ib82b6a1116b9f396f1933cc5526733334254fd62 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/579 Tested-by: jenkins Reviewed-by: Freddie + Chopin Reviewed-by: Mathias Küster + + +2012-04-19 Spencer Oliver + + * : stlink: default to latest api available Change-Id: Ic04128f4020055587bb87250f41e5c804d9c2b01 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/577 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Freddie Chopin + + +2012-04-05 Spencer Oliver + + * : stlink: support stlink api result The stlink api does support results for some functions - add + support. Change-Id: I39cb495408c46af8bc343b198a1e0bd4c7aee6d8 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/560 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Freddie Chopin + + +2012-03-18 Olivier Schonken + + * : topic: Added support for the SAM4S variants Atmel introduced 6 new Cortex-M4 processors on 2011-10-26 SAM4S16C - + 1024KB flash LQFP100/BGA100 SAM4S16B - 1024KB flash LQFP64/QFN64 + SAM4S16A - 1024KB flash LQFP48/QFN48 SAM4S8C - 512KB flash + LQFP100/BGA100 SAM4S8B - 512KB flash LQFP64/QFN64 SAM4S8A - 512KB + flash LQFP48/QFN48 The SAM4S processors still suffer from the "6 waitstates needed to + program device" errata. Other relevant changes are: 1. Address of flash memory starts at 0x400000. 2. EWP (Erase page and write page) only works for the first two 8KB + "sectors" 3. Because of the EWP not working for all the sectors, normal page + writes have to be used. The default_flash_blank_check is used to + check if lockregions should be erased. 4. The EA (Erase All) command takes 7.3s to complete. (Previous + timeout was 500 ms) 5. There are 128 lockable regions of 8KB each. Implemented default blank checking, and page erase for load_image + scenarios. This is to compensate for the EWP flash commands only + working on the first 2 8KB sectors. Change-Id: I7c5a52b177f7849a107611fd0f635fc416cfb724 Signed-off-by: + Olivier Schonken Reviewed-on: + http://openocd.zylin.com/528 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-04-24 Linus Tolke + + * : topic: Ignored TAGS files. Allow use of TAGS. Change-Id: I5e71e8986671642b49cc9a62d37cc8c0dfa37181 Signed-off-by: + Linus Tolke Reviewed-on: + http://openocd.zylin.com/595 Reviewed-by: Peter Stuge + Tested-by: jenkins + +2012-04-22 Bill Traynor + + * : UserGuide: Fixing link to USBprog tool. In section '2.8 USB Other' updated the link to the USBprog tool: + http://shop.embedded-projects.net/ Change-Id: I7fa453934ac6a7889e01b22b7e0cb07f42ee168d Signed-off-by: + Bill Traynor Reviewed-on: + http://openocd.zylin.com/591 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-04-22 Bill Traynor + + * : UserGuide: Fixed link to Wiggler2 project. In section '2.9 IBM PC Parallel Printer Port based' fixed link to + the Wiggler2 project and removed the alternate URL text to retain + style consistency with the other URLs in the document: + http://www.ccac.rwth-aachen.de/~michaels/index.php/hardware/armjtag Change-Id: I879db1c6eaf683ca6475a0f466f987087c9d60d0 Signed-off-by: + Bill Traynor Reviewed-on: + http://openocd.zylin.com/593 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-04-22 Bill Traynor + + * : UserGuide: Fixing two typos. In Section 2.7 USB ST-LINK based made these two changes: "they only + works with" to "they only work with" "following method's" to + "following methods" Change-Id: Idfe6c11c3fa6f2157d01697cd7f480a9d495c8e2 Signed-off-by: + Bill Traynor Reviewed-on: + http://openocd.zylin.com/590 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-04-15 Uwe Hermann + + * : Split olimex_stm32_h107.cfg. Use one board file per eval board, so that the filename matches the + exact board the user has / wants to use. Merging different boards + into one file is confusing. Change-Id: I7c50233924a87a913723d7215c4851039c2971bc Signed-off-by: + Uwe Hermann Reviewed-on: + http://openocd.zylin.com/566 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-04-19 Bill Traynor + + * : UserGuide: Update Section 2.3 USB FT2232 Based Updated the link for the usbjtag project to the correct URL: + + http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.htmlAdded a NOTE to indicate the axm0432_jtag as no longer being + available from the axman.com page. Change-Id: I70727303dad58d9dc0c5f9b7cce219288b762042 Signed-off-by: + Bill Traynor Reviewed-on: + http://openocd.zylin.com/583 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-04-19 Bill Traynor + + * : UserGuide: Fixed link to USB-JTAG project. Updated the URL to Kolja Waschk's USB-Blaster compatible adapter: + http://ixo-jtag.sourceforge.net/ Change-Id: If9d2875b5ba5d3bfaaf524cd253a5fab53e05371 Signed-off-by: + Bill Traynor Reviewed-on: + http://openocd.zylin.com/585 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-04-18 Bill Traynor + + * : HACKING: Fix instruction for git pull --rebase When following the Patch Guidelines step by step, an error occurs at + step 6. "git pull --rebase origin/master" results in the error: fatal: 'origin/master' does not appear to be a git repository Removing the / seems to fix this. Change-Id: I4e2fa23c60654abeaebd3b25a8c8375aa07b0abd Signed-off-by: + Bill Traynor Signed-off-by: Peter Stuge + Reviewed-on: http://openocd.zylin.com/574 + Reviewed-by: David Anders Tested-by: jenkins + +2012-04-18 David Anders + + * : pandaboard: add initial TCL support for pandaboard-es add initial TCL support for the pandaboard-es which is based on the + omap4460 from Texas Instruments. Change-Id: Ic63588721487feb95e7cb3d41cfaab0d2f181766 Signed-off-by: + David Anders Reviewed-on: + http://openocd.zylin.com/573 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-04-18 Spencer Oliver + + * : cfg: add stm32f0discovery board config Change-Id: I4fccdbd4e0a3bc70cd425c910ad1007519098e20 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/570 Reviewed-by: Peter Stuge + Tested-by: jenkins + +2012-04-05 Spencer Oliver + + * : stlink: correctly format printed hex addresses Change-Id: I4a139989927249bb5e9dcc4804965c85c37cc09b Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/559 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2012-04-04 Stephane Bonnet + + * : ft2232: Support for Digilent HS1 USB adapter * Added support to the FT2232 driver for the FT2232H-based Digilent HS1 adapter. Change-Id: Iab6cc15f299badaf115615b5d4d785ecb2273c27 Signed-off-by: + Stephane Bonnet Reviewed-on: + http://openocd.zylin.com/558 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-03-27 Wjatscheslaw Stoljarski (Slawa) + + * : cfg: add imx53loco board config Add board config for iMX53QSB (loco) Change-Id: I8659dcd71a56d5fe855eaf62be0a415198b558c5 Signed-off-by: + Wjatscheslaw Stoljarski (Slawa) + Reviewed-on: + http://openocd.zylin.com/542 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-04-04 Simon Widmer + + * : Support for KaRo TX25 CPU Module on a StarterkitV base board This patch adds support for the KaRo TX25 module on a StarterkitV + base board. For board details, check + http://www.karo-electronics.com/tx25.html Change-Id: I2c80c5467bc476955b55196728aa3c37c8185e6c Author: Simon + Widmer Signed-off-by: Mark Vels + Reviewed-on: + http://openocd.zylin.com/557 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-04-04 Spencer Oliver + + * : doxygen: remove warnings Change-Id: I020845a8df7b67f3b6c1a233b3ee07a5d14fa685 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/556 Tested-by: jenkins + +2012-04-02 Salvador + + * : Minor bug fixes in Mips32 code Now the the "Fast" version for memory blank check in pic32mx.c can + be called: default_flash_blank_check() instead of the "fallback" + default_flash_mem_blank_check(). The command "verify_image", without working area, now don't show: checksum mismatch - attempting binary compare when there are no + real errors in flash. Change-Id: I256e8ae949289634e1de5c1c2861e4c4c4b7fdce Signed-off-by: + Salvador Reviewed-on: + http://openocd.zylin.com/549 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-03-30 Spencer Oliver + + * : docs: remove unused primer ref we already have a link to the patch primer in the main index. Change-Id: Ib90ade76a17f5d99da8fe481d8f87c68eca38f1c Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/546 Tested-by: jenkins + +2012-04-02 Uwe Hermann + + * : Initial config for the Voltcraft DSO-3062C. This is a digital oscilloscope which uses a Samsung S3C2440 + internally. http://randomprojects.org/wiki/Voltcraft_DSO-3062C Signed-off-by: Uwe Hermann Change-Id: + I5e28c3a8f30665a162e34c831294e4e658a16ebb Reviewed-on: + http://openocd.zylin.com/548 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-03-20 Spencer Oliver + + * : jimtcl: update to version 0.73 Change-Id: I9c943abb3ec5148b9cb24d0823f7787066948201 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/536 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2012-03-15 Mathias K + + * : stm32: Update register read/write to the register definition. This patch fix the register index on read/write register. Change-Id: I7b52a927a48259d6f497ac0f474aff7ff1529e9a Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/525 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-03-30 Spencer Oliver + + * : build: correctly quote m4 parameters Change-Id: I8fbef892caa78dba5324a8bc28d2a4a4854b1f48 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/544 Tested-by: jenkins + +2012-03-26 Spencer Oliver + + * : cfg: add STM32F4x and STM3241G-EVAL config files This adds support for the STM32F4 target and the STM3241G Eval + Board, in both standalone and using the onboard STLINK. Change-Id: I62f8908b5880568b2b36c78a78f94c40861ff335 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/540 Tested-by: jenkins + +2012-03-06 Olivier Schonken + + * : Added tcl config scripts for SAM3A/X targets and devboard The SAM3A/X processors that were released thus far is either a + SAM3A/X(4) - 256K, or a SAM3A/X(8) - 512K device. Thus the config + files are per variant, and not per device. Signed-off-by: Olivier Schonken Change-Id: I84d26d044e810eb428b1d6287907ea3bf8364c73 Signed-off-by: + Olivier Schonken Reviewed-on: + http://openocd.zylin.com/522 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-03-20 Spencer Oliver + + * : tools: update release scripts to use configure.ac we have already updated autoconf to use configure.ac instead of + configure.in, so update release.sh to use the new name. Change-Id: I2dc2beaf2f85058c4627183bc093052677ccba1b Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/537 Tested-by: jenkins + +2012-03-08 Chris Morgan + + * : Create a init_board procedure for the ea dev board. Signed-off-by: Chris Morgan Change-Id: + I082b0d3092c7f3b2ee6b68af64d48c78b31f1dbf Reviewed-on: + http://openocd.zylin.com/510 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-03-17 Salvador + + * : Bug in src/target/mips32_pracc.c The bug shows up with the command "mdw addres count" and only if + count>1024 (count>0x400). The first 1024 values shows as expected, + but the rest of the values are wrong. Name of variable bytesread" + is changed to "wordsread" to reflect what really does. Change-Id: Iad79393e72da2637551c5ae6e829e3873605c520 Signed-off-by: + Salvador Reviewed-on: + http://openocd.zylin.com/527 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-03-15 Mathias K + + * : gdb_server: Simple close the connection and not exit openocd. This patch let openocd running and only close the gdb connection on + error. Change-Id: Ifb88e16834b51207cc4c82210eab904ed8d30b71 Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/523 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-03-14 Paul Fertser + + * : rtos: add sanity checking for FreeRTOS's quantity of priorities On operating systems with opportunistic malloc() (e.g. default + setting in GNU/Linux) malloc can sometimes allocate a huge memory + region but later the process will get killed on the first attempt to + use this memory, so checking for malloc's return value is not enough + to prevent a crash. This patch is compile-tested only. Change-Id: I5e21663115c8e9a0ca9f3d71f7ba4bd09e5c3bb1 Signed-off-by: + Paul Fertser Reviewed-on: + http://openocd.zylin.com/521 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-02-24 Alexandre Pereira da Silva + + * : stlink: fix alignment build warning The {read,write}_mem32 interface functions was asking a 32 bits + buffer but they don't need 32 bits alignment. This will change the + interface to a 8 bits buffer to remove the alignment mismatch + warning. This was causing build errors on platforms with strict + aliasing rules. Change-Id: I338be8df5686f07a64ddb4f17c1bb494af583999 Signed-off-by: + Alexandre Pereira da Silva Reviewed-on: + http://openocd.zylin.com/483 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-03-13 Mathias K + + * : armv7m: Add a dummy register at the end of the register list. Signed-off-by: Mathias K Change-Id: + I0bfad091bd8adabd949fc0a74ef3a08a514eb307 Reviewed-on: + http://openocd.zylin.com/519 Reviewed-by: Peter Stuge + Tested-by: jenkins + +2012-03-12 Mathias K + + * : stm32: determine all cpu types and use common examine This patch determine all cpu types and not only the cortex M3 and + the stm32 target use the common target examine function from the + cortex_m sources. Change-Id: If689dd994b3855284b927fc4b206f420cf32b6c7 Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/511 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-03-08 Mathias K + + * : Automatically prepend v1 mass storage protocol. This patch prepend the v1 mass storage protocol to the command + buffer and simplify the usb read/write handling. Change-Id: I709602600e93cd1eb5848fa9f4d15659ba85eb35 Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/506 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-03-12 Spencer Oliver + + * : cfg: correct pic32mx config typo's Change-Id: Ibe5b6b0efefc7cfc75d789eb7e9c7ee239526ae2 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/508 Tested-by: jenkins + +2012-02-28 Jan Dakinevich + + * : jtag: basic support for P&E Micro OSBDM (aka OSJTAG) adapter This driver provides support for the P&E Micro OSBDM adapter + (sometimes named as OSJTAG), mounted on the Freescale TWRK60N512 + bord. Thus, it provides a quick start when working with this board. + The driver doesn't use BDM commands, but work with OSBDM adapter + using only JTAG commands. Change-Id: Ibc3779538e666e07651d3136431e5d44344f3b07 Signed-off-by: + Jan Dakinevich Reviewed-on: + http://openocd.zylin.com/492 Tested-by: jenkins Reviewed-by: Tomas + Frydrych Reviewed-by: Spencer Oliver + + +2012-03-08 Spencer Oliver + + * : docs: add stm32 dual bank example Change-Id: I1dfe134e2c7694fc978d14b4b21bdf9c82ca4b16 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/507 Tested-by: jenkins + +2012-03-05 Øyvind Harboe + + * : flash: retire unused eCos flash driver even the AT91EB40a's flash is covered by CFI and nobody ever + submitted any other drivers based on eCos code. It's just possible + that this idea was missing documentation and "marketing", but it's + in git if somebody wants to resurrect it. Change-Id: I66449aa6e0997301f9d67f28098789bfc891d6e9 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/502 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2012-02-25 Szymon Modzelewski + + * : flash: stm32f1x: add a couple missing stm32x_get_flash_reg Change-Id: I163de2c1bd962e7ea9ca6c741c1c62224c210677 Signed-off-by: + Szymon Modzelewski Reviewed-on: + http://openocd.zylin.com/486 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson Reviewed-by: Spencer + Oliver + +2012-02-29 Spencer Oliver + + * : stlink: fix incorrect pc console output target_call_event_callbacks needs to be called after debug entry + otherwise we will get a console pc mismatch. Change-Id: I278137736d5e85ca9662c306f6ac81336d8eb6cf Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/499 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2012-02-28 Attila Kinali + + * : SAM3: Remove unused reference to SUPC registers The SUPC (Supply Controller) registers are on different base + addresses on different SAM3 chips: SAM3U: 0x400e1210 SAM3N: + 0x400e1410 SAM3S: 0x400e1410 This creates a problem with the sam3_reg_list array which is const, + but would need to be changed at runtime to account for this + variability. As this register is not used anywhere, it's simplest to + just remove it. Change-Id: I987eb371648d826aa6d5e9de18d38c7bb66d6fca Signed-off-by: + Attila Kinali Reviewed-on: + http://openocd.zylin.com/495 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-02-28 Attila Kinali + + * : SAM3S: correct flash sector sizes. Lock region count and sector sizes did not match datasheet. (see + 6500C-ATARM-8FE11 "SAM3S Series Datasheet", Table 7-1) Change-Id: Ic511802f96ed03856467a24a6736349205a0576a Signed-off-by: + Attila Kinali Reviewed-on: + http://openocd.zylin.com/493 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-02-21 Szymon Modzelewski + + * : stlink-v1: fix memory writes implement stlink_usb_send and use it to fix stlink_usb_write_mem using two calls to stlink_usb_recv is inappropriate since each call + issues a SG command on stlink-v1, resulting in errors Change-Id: I24ef9f2dda284e041dc4a532b59968a77eebe702 Signed-off-by: + Szymon Modzelewski Reviewed-on: + http://openocd.zylin.com/498 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-02-21 Szymon Modzelewski + + * : stlink-v1: code cleanup This patch moves the bulk of the stlink read/write code into the + stlink_usb_xfer set of functions and implements stlink_usb_recv in + terms of the generic stlink_usb_xfer stlink_usb_xfer will be needed to implement stlink_usb_send without + code duplication stlink_usb_xfer: -sends the stlink command -performs a read or write + (as requested) -checks the status (v1 only) Change-Id: I0137d52620bd4883d46c9977a9e73f67622000a1 Signed-off-by: + Szymon Modzelewski Reviewed-on: + http://openocd.zylin.com/477 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-02-17 Spencer Oliver + + * : flash: add stm32lx High Density Devices Change-Id: Ieed9de4b078e1ebf659054a758b4f69acdf5b83e Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/466 Tested-by: jenkins + +2012-02-21 Szymon Modzelewski + + * : stlink-v1: fix memory writes implement stlink_usb_send and use it to fix stlink_usb_write_mem using two calls to stlink_usb_recv is inappropriate since each call + issues a SG command on stlink-v1, resulting in errors Change-Id: I52ff9ee8f5d9ae0d47356477468eb98952205c99 Signed-off-by: + Szymon Modzelewski Reviewed-on: + http://openocd.zylin.com/478 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Spencer Oliver + + +2012-02-24 Neil Jensen + + * : cfg: Beaglebone/AM335x refactor Split out functions specific to the AM335x SOC into the target + directory and simplified the board config file. This should allow + one to quickly create new configs for boards based on the TI + processor family. Change-Id: I0c3db97950dfa832f1f1918fc10c180f068bba74 Signed-off-by: + Neil Jensen Reviewed-on: + http://openocd.zylin.com/489 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-02-21 Spencer Oliver + + * : jtag: use correct tap -ignore-version mask when -ignore-version is used we should mask of the upper 4bits not + 8bits. Change-Id: I9ffe24c2aeeb414677357a647609fdf018890194 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/473 Tested-by: jenkins + +2012-02-16 Spencer Oliver + + * : flash: add stm32f2x async flash loader This enable the stm32f2x flash driver to use the asynchronous + algorithm support. Speed increase is as follows: before - wrote 1048576 bytes from file + stm32f4x.bin in 30.453804s (33.625 KiB/s) after - wrote 1048576 + bytes from file stm32f4x.bin in 23.679497s (43.244 KiB/s) This also fixes a bug that was in the old flash loader. The old + loader waited while bit16 of the status reg was 0, the new loader + waits until this bit is 0 as stated in the flash spec. Bizarrely + this bug did not effect programming on any tested parts. Change-Id: I3efc94d42cbe81283673a8f4203700638080af6e Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/460 Tested-by: jenkins + +2012-02-10 Spencer Oliver + + * : target: add target async algorithm support Currently the stm32f1x flash driver uses an asynchronous algorithm + as part of the block flash programming. This greatly speeds up flash + programming as the target is always running. Moving the async code to the target enable other targets to use this + added functionality. Change-Id: I8e53f094c2ef7848a7f86ddb9a35b6edbfc8454a Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/402 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2012-02-18 Neil Jensen + + * : cfg: Beaglebone Support Added support for the Beaglebone board based on the am335x processor + family. After much trial and error, I was able to configure the + Icepick-D and connect to the processor, halt execution, and run a + sample program. This is a unified config file (it doesn't use any + include statements) and further work needs to be done to split out + the icepick-d configuration to be more generic. Change-Id: Ia1b8e9f01f56bd4f8c575ba3d0160c248583a15e Signed-off-by: + Neil Jensen Reviewed-on: + http://openocd.zylin.com/471 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-02-13 Andreas Fritiofson + + * : target: rewrite working area allocator The existing allocator couldn't reuse a freed allocation if the + sizes didn't match exactly. That led to problems when for example a + flash write routine had allocated all of the working area to speed + up operation. A subsequent verify pass couldn't allocate space for + the checksum algorithm even though all previous allocations had been + freed. This allocator is marginally more complex, but solves the above + problem by splitting larger free areas to fulfill smaller requests + and by merging released areas into adjacent free areas. An initial free area, covering the entire specified address range, + is set up on first allocation, and all allocations are split off + from (and ultimately merged into) that one. It can also easily be + adapted to support several disjoint working areas for the same + target, by setting up several initial free areas and slightly + modifying the merge code. Change-Id: I6faaf9801312bb19a4fa4474694a0cd1c6e0ab54 Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/445 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-02-21 Spencer Oliver + + * : stlink: support expected-id 0 This brings the stlink driver inline with the rest of OpenOCD. If the user configures the tap as -expected-id 0 then the IDCODE + will be treated as a wildcard and ignored. Change-Id: I99160c69b2b40f5b1f608bb59ab6630894502fd8 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/476 Tested-by: jenkins Reviewed-by: Mathias + Küster + +2012-02-18 Stian Skjelsad + + * : Sometime in the past, nand_fileio_finish started to return + ERROR_OK (with the value of zero) on success. Change-Id: Ifb743c1617e2a6071a87c901fae8165969efcdbf Signed-off-by: + Stian Skjelstad Reviewed-on: + http://openocd.zylin.com/468 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-02-17 Jonathan Dumaresq + + * : Fix Typo in cfg file Change-Id: Id91ef70988212185f9ec653cbf5dc4e1defb1b9e Signed-off-by: + Jonathan Dumaresq Reviewed-on: + http://openocd.zylin.com/464 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-02-14 Spencer Oliver + + * : stlink: add arm semi-hosting support Change-Id: Ib275d451a9201580f08ced090e50cf45eb3ab3e2 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/459 Tested-by: jenkins + +2012-02-14 Spencer Oliver + + * : docs: fix texinfo warnings A period or comma must follow the closing brace of an @xref. Change-Id: I272f1e7fac8f1fee4844f485b0b8e2e4e9cf352d Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/456 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2012-02-07 Jonathan Dumaresq + + * : Add stm32f0x target Change-Id: I4abfef4459b7e2780d17bdd7623fd1ef797cc8ea Signed-off-by: + Jonathan Dumaresq Reviewed-on: + http://openocd.zylin.com/437 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-02-16 Mathias K + + * : Add bootloader mode. This patch add the bootloader define. Change-Id: I280a8a35c3514910dd381de3ab8ad59c9bd74ca1 Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/455 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-02-13 Spencer Oliver + + * : docs: correct small typo Change-Id: I5e8bea591274b4032d3e04c4be7e9110138d5bc2 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/447 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-02-04 James Robinson + + * : topic: Add support for i.MX28EVK Added the file imx28.cfg to the target directory Added the file + imx28evk.cfg to the board directory Change-Id: I02a74a03f3773892f830d13660ffdded34f3261d Signed-off-by: + James Robinson Reviewed-on: + http://openocd.zylin.com/428 Tested-by: jenkins Reviewed-by: Øyvind + Harboe Reviewed-by: Spencer Oliver + + +2012-02-10 Spencer Oliver + + * : cfg: add revb ek-lm3s811 board config Add board config for older (revb) ek-lm3s811 Change-Id: I75aca1714de3e88b60d00fa0f99f2c4b076b569c Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/444 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-02-10 Spencer Oliver + + * : cfg: add stm32ldiscovery board config Change-Id: I392fdc4c588783fda1c7d4d6413b86ae9aa3f6b9 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/442 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2012-02-03 Freddie Chopin + + * : Add init_board procedure executed after init_targets This adds init_board procedure that behaves exactly the same as + init_targets - it can be overriden by "next level" scripts. This + procedure is executed after init_targets, allowing common stuff + (jtag chain, memory, flash, ...) to be configured in target script + (via init_target) and leaving rest (like additional memory, reset + configuration, reset-init handlers, ...) to be done in init_board. This makes init_targets scheme more complete and easier to use - + current board scripts will not need new init_targets, because + everything can be "packed" in init_boards. Moreover it solves the + problem of variables being set in init_targets (executed after + init), which were not accessible by "linear" scripts (parsed before + init). All that has to be done is to enclose all code in board + config file in init_board procedure. Change-Id: I0736b1ff9873a687966407d62b58ccf29a8e597b Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/427 Reviewed-by: Chris Morgan + Tested-by: jenkins Reviewed-by: Peter Stuge + + +2012-02-06 Spencer Oliver + + * : cfg: add stm32vldiscovery board config Change-Id: I6343d1e61153ba71c71f8a473171972abb8e400d Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/432 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Andreas Fritiofson + + +2012-02-01 Freddie Chopin + + * : Export _TARGETNAME from generic LPC2xxx script Make _TARGETNAME variable global so it could be used by scripts + sourcing it. Change-Id: Iaf1c3b53875734658b1b8f136c9bb958988b56bf Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/421 Tested-by: jenkins Reviewed-by: Chris + Morgan Reviewed-by: Øyvind Harboe + + +2012-02-05 Spencer Oliver + + * : build: cleanup src/target directory Change-Id: Ia055b6d2b5f6449a38afd0539a8c66e7d7e0c059 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/430 Tested-by: jenkins + +2012-02-02 Spencer Oliver + + * : checkpatch: remove __packed and __aligned checks These checks are specific to linux kernel. Change-Id: Ia9b837b5609922a897822f1d55f96f04c0f1f838 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/424 Tested-by: jenkins + +2012-02-02 Spencer Oliver + + * : checkpatch: increase line length to 120 Change-Id: I963385d0a4880f2b1e55208c8dfe65c1870ac6e1 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/422 Tested-by: jenkins + +2012-01-31 Spencer Oliver + + * : build: cleanup src/flash/nand directory Change-Id: I21bb466a35168cf04743f5baafac9fef50d01707 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/419 Tested-by: jenkins + +2012-01-30 Spencer Oliver + + * : build: cleanup src/rtos directory Change-Id: I24bc62d12409dbfc20a0a986acf6b3f2c913e36d Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/416 Tested-by: jenkins + +2012-01-30 Spencer Oliver + + * : checkpatch: remove volatile check We may enable this again - but at the moment is causing extra issues + with reformatting the codebase. Change-Id: I5a2aaaa32ad784e011dff3079ff45501452c1819 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/414 + +2012-01-30 Spencer Oliver + + * : build: cleanup src/server directory Change-Id: I6410df28c5999f5cbee2d3bcaa02469a29ea4c15 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/412 Tested-by: jenkins + +2012-01-27 Spencer Oliver + + * : build: cleanup src/xsvf directory Change-Id: I5325980b240fba841d8cce81985f4da369ad9052 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/410 Tested-by: jenkins + +2012-01-27 Spencer Oliver + + * : build: cleanup src/pld directory Change-Id: I9edb027c76e5d7fe21d557a11e6a9691fa581e86 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/408 Tested-by: jenkins + +2012-02-05 Spencer Oliver + + * : build: update uncrustify config This config has been updated for 0.59 Change-Id: If0dc87dd5de052c1228743a196a3198dbd4bc279 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/406 Tested-by: jenkins + +2012-01-25 Andreas Fritiofson + + * : stm32f1x: fix bug in flash loader and restrict instruction set + to armv6-m Correct the offset to the read pointer when clearing it on error. Also restrict the instruction set to armv6-m so the flash driver can + be used on Cortex-M0 parts with the same flash controller. Change-Id: I380f9dabcc41fb6e4d43a7e02f355e2381913f39 Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/399 Tested-by: jenkins Reviewed-by: Freddie + Chopin Reviewed-by: Jonathan Dumaresq + Reviewed-by: Spencer Oliver + + +2012-01-23 Mathias K + + * : STLINK: add stlink v1 configuration Change-Id: I6b9de16879ff928d60e3c4a64731449275291cc2 Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/397 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-01-25 Mathias K + + * : STLINK: swd transport renamed and jtag+swim transport added This patch add jtag support to the stlink driver add two new + transport types, JTAG and SWIM. Change-Id: I7089d74250330be5c6a01c24066307641df7d11e Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/393 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-01-25 Spencer Oliver + + * : flash: fix stellaris class regression for some reason the following commit was incorrect + 769064de4bd8fc59804c37a418b83fcdba6fd36f Only the Sandstorm and Fury class should write this register. Change-Id: Ie18f1da6e9b59fb99cca47aa93c7f2fee447ccea Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/400 Tested-by: jenkins + +2011-12-02 Fujitsu FM3 Application Team + + * : flash: cleanup/reformat fm3 flash driver Signed-off-by: Fujitsu FM3 Application Team + Change-Id: + Iaf0bacfa5438a0213a65a3d60e7d461965a5a1ac Reviewed-on: + http://openocd.zylin.com/249 Reviewed-by: Øyvind Harboe + Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-01-17 Timo Ketola + + * : i.MX25: Set OOB size (MXC NFC) SPAS register (OOB size) is left wrong after reset with respect to + 2KiB page NAND chip. That will lead to ECC errors after 'reset + halt'. Change-Id: If5a4685cb8d6be35879453951611ef1059da219c Signed-off-by: + Timo Ketola Reviewed-on: + http://openocd.zylin.com/384 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-01-20 Spencer Oliver + + * : cfg: add missing Stellaris Blizzard info Change-Id: I1d6fb9a2ec8d87267a266f68c01ce032450e45d5 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/392 Tested-by: jenkins + +2012-01-17 Spencer Oliver + + * : flash: cleanup stellaris device class detection read the target class during probe and save for later use. Change-Id: Ib3ad20edc7d206b7f434bdcc6b947e6a5f06dd1f Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/388 Tested-by: jenkins + +2012-01-13 Spencer Oliver + + * : stlink: enable cortex special reg writes Change-Id: I5aa02e8de6dd5ac5a6ca628ba4068decb200c689 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/378 Tested-by: jenkins + +2012-01-19 Spencer Oliver + + * : flash: print bank usage on failure This makes use of the newly introduced usage field in the flash bank + structure. Also remove the assertion if usage field is null and lets print a + DEBUG_LOG message instead. Change-Id: I384bf0e2c444fcc99deef73aec9ef01149a91c76 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/391 Tested-by: jenkins + +2012-01-17 Timo Ketola + + * : doc: Update patch procedure Change-Id: I3e50357b4ddaf483712bbac68b6427b31529f666 Signed-off-by: + Timo Ketola Reviewed-on: + http://openocd.zylin.com/387 Tested-by: jenkins Reviewed-by: Øyvind + Harboe Reviewed-by: Spencer Oliver + + +2012-01-16 Spencer Oliver + + * : cmd: add missing usage vars we should have caught them all - hopefully. Change-Id: I35435317fccaf5ad0216244d69f76db6857bb582 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/381 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2012-01-06 Michel JAOUEN + + * : u8500: linux rtos config Change-Id: I21a9dcc5fb260095aed2217e467b74ebecb39afb Signed-off-by: + Michel JAOUEN Reviewed-on: + http://openocd.zylin.com/349 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2012-01-03 Michel JAOUEN + + * : rtos : create qsymbol interface and add str_to_hex interface Change-Id: I1b26f7efd3ad4a060f772dd12408e77a03d93cea Signed-off-by: + Michel JAOUEN Reviewed-on: + http://openocd.zylin.com/347 Tested-by: jenkins Reviewed-by: Evan + Hunter Reviewed-by: Øyvind Harboe + + +2012-01-03 Michel JAOUEN + + * : rtos : ps command Change-Id: I1b00b6d72f425826c33b0df7dd63114ce642ce93 Signed-off-by: + Michel JAOUEN Reviewed-on: + http://openocd.zylin.com/345 Tested-by: jenkins Reviewed-by: Evan + Hunter Reviewed-by: Øyvind Harboe + + +2012-01-03 Michel JAOUEN + + * : rtos : current_threadid move to rtos context Change-Id: I49d9d6d64c418be601d8723cb3eea9c3716ecb6b Signed-off-by: + Michel JAOUEN Reviewed-on: + http://openocd.zylin.com/343 Tested-by: jenkins Reviewed-by: Evan + Hunter Reviewed-by: Øyvind Harboe + + +2012-01-03 Michel JAOUEN + + * : rtos : remove unused parameter Change-Id: I98c9f28a0085bd4713b694181ab544777091eac6 Signed-off-by: + Michel JAOUEN Reviewed-on: + http://openocd.zylin.com/341 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2012-01-12 Mathias K + + * : stlink: handle wrong initialization file if no layout was + specified This patch remove the hardcoded default layout and return an error + if no layout was specified in the configuration file. Change-Id: I0e7833faa2dc194e727122840bcbdacd321cc4fd Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/369 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-01-12 Mathias K + + * : stlink: add read/write 8bit memory This patch add layout api funtions and implementation to read/write + 8bit memory. Change-Id: I8d145eb07e5afa9ce1830578e57d80a80d21e7dc Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/366 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2012-01-12 Spencer Oliver + + * : stlink: correctly signal stlink_interface_open failure give the user a error msg on open failure. Change-Id: If4a57bac7f3e1746c2a05c7a96747a38da188041 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/368 Tested-by: jenkins Reviewed-by: Mathias + Küster + +2012-01-09 Spencer Oliver + + * : flash: detect stm32f4x device id errata This allows us to detect a device arrata where the device id + returned is incorrect. This issue only effects stm32f4x Rev A silicon. Change-Id: Ic9f4985f9abf562f97322dcf484199f0a4eb01bb Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/354 Tested-by: jenkins + +2012-01-09 Spencer Oliver + + * : stlink: add dummy speed handlers Change-Id: I0445be7867637728145941b06225dc0acc5380e8 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/355 Tested-by: jenkins + +2012-01-10 Mathias K + + * : optimize: replace while loop by memcpy There is no need to use a while loop here. This patch simple copy + the last bytes with the system function. Change-Id: Ibda72dca449746efeba5a1af2e45c5990f9cf347 Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/364 Tested-by: jenkins Reviewed-by: Øyvind + Harboe Reviewed-by: Spencer Oliver + + +2012-01-10 Bruno FLEURETTE + + * : flash: pre-check flash unlock for stm32f2x add checking of the current flash lock status before performing the + unlock sequence (which would fail in an unlocked state) Change-Id: I693294c9cd2f59e69cb5bf3338120052fd680b1e Signed-off-by: + Bruno FLEURETTE Signed-off-by: Øyvind + Harboe Reviewed-on: + http://openocd.zylin.com/363 Reviewed-by: Øyvind Harboe + Reviewed-by: Spencer Oliver + Tested-by: jenkins Reviewed-by: Mathias + Küster + +2012-01-09 Spencer Oliver + + * : target: fix missing semihosting return path bug nicely caught by clang. Change-Id: I7abf0fdd76666fb3eb1c83e3edfd01e0da485ffe Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/359 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2012-01-04 Spencer Oliver + + * : flash: use stm32f2x flash size register Use the flash size register to calculate flash info. Change-Id: Ia230db8a08d440710c030a9e5001f20561c9f420 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/337 Tested-by: jenkins Reviewed-by: Mathias + Küster + +2012-01-04 Spencer Oliver + + * : contrib: add stlink udev rules Change-Id: I3f11de8abfaf8821311a7aa0fd237006de3c2792 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/333 Tested-by: jenkins Reviewed-by: Mathias + Küster + +2012-01-03 Spencer Oliver + + * : cfg: use consistent chipname Change-Id: I41e0788f830d5ece13e6231a99d5b4013c9c678f Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/331 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Freddie Chopin + + +2012-01-07 Øyvind Harboe + + * : rtos: fix bug in error handling checking for != ERROR_FAIL is broken. Change-Id: Id7085afac653bb9c38d08928227a9ea402d8e6e9 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/351 Tested-by: jenkins Reviewed-by: Michel + JAOUEN Reviewed-by: Øyvind Harboe + + +2011-12-16 Mathias K + + * : Change return value on error. On wrong parameters a error is signalized to the calling function. Change-Id: I484443fdb39938e20382edc9246d5ec546a5c960 Signed-off-by: + Mathias K Signed-off-by: Øyvind Harboe + Reviewed-on: http://openocd.zylin.com/282 + Tested-by: jenkins Reviewed-by: Øyvind Harboe + + +2011-12-28 Øyvind Harboe + + * : flash: introduce .usage field for nand and nor flash driver + structure Change-Id: I47e7ec8fa8c70d2addc3aa52d7c97e9e1e7bb662 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/301 Tested-by: jenkins Reviewed-by: Øyvind + Harboe Reviewed-by: Spencer Oliver + + +2011-12-24 Mathias K + + * : command: print BUG warning when usage is missing These error messages will prompt patches to be submitted for missing + .usage or empty fields. All of the below must be resolved before + next release. The Jim defined commands are excluded from this checklist because + the help text can be set later than during command registration. strlen(.usage) == 0 means that the command expects no arguments. Updates to this patch in Gerrit to fix problems below are most + welcome. Anyone can push updated versions of a patch to Gerrit. If + there are no further updates to this patch within a week, it will be + pushed to the master branch to prompt more fixes. These were caught by launching OpenOCD. Error: BUG: command 'command' does not have the '.usage' field + filled out Error: BUG: command 'script' does not have the '.usage' + field filled out Error: BUG: command 'power_restore' does not have + the '.usage' field filled out Error: BUG: command 'srst_deasserted' + does not have the '.usage' field filled out Error: BUG: command + 'measure_clk' does not have the '.usage' field filled out Error: + BUG: command 'exit' does not have the '.usage' field filled out + Error: BUG: command 'shutdown' does not have the '.usage' field + filled out Error: BUG: command 'gdb_sync' does not have the '.usage' + field filled out Error: BUG: command 'interface_list' does not have + the '.usage' field filled out Error: BUG: command 'target' does not + have the '.usage' field filled out Error: BUG: command 'target init' + does not have the '.usage' field filled out Error: BUG: command + 'flash' does not have the '.usage' field filled out Error: BUG: + command 'flash init' does not have the '.usage' field filled out + Error: BUG: command 'flash banks' does not have the '.usage' field + filled out Error: BUG: command 'nand' does not have the '.usage' + field filled out Error: BUG: command 'nand drivers' does not have + the '.usage' field filled out Error: BUG: command 'nand init' does + not have the '.usage' field filled out Error: BUG: command 'pld' + does not have the '.usage' field filled out Error: BUG: command 'pld + init' does not have the '.usage' field filled out Error: BUG: + command 'mflash' does not have the '.usage' field filled out Error: + BUG: command 'mflash init' does not have the '.usage' field filled + out Error: BUG: command 'dummy' does not have the '.usage' field + filled out Error: BUG: command 'dummy foo' does not have the + '.usage' field filled out Error: BUG: command 'scan_chain' does not + have the '.usage' field filled out Error: BUG: command 'jtag' does + not have the '.usage' field filled out Error: BUG: command 'jtag + init' does not have the '.usage' field filled out Error: BUG: + command 'arm' does not have the '.usage' field filled out Error: + BUG: command 'arm reg' does not have the '.usage' field filled out + Error: BUG: command 'etm' does not have the '.usage' field filled + out Error: BUG: command 'arm7_9' does not have the '.usage' field + filled out Error: BUG: command 'at91eb40a.cpu' does not have the + '.usage' field filled out Error: BUG: command 'at91eb40a.cpu arm' + does not have the '.usage' field filled out Error: BUG: command 'arm + reg' does not have the '.usage' field filled out Error: BUG: command + 'at91eb40a.cpu etm' does not have the '.usage' field filled out + Error: BUG: command 'at91eb40a.cpu arm7_9' does not have the + '.usage' field filled out Error: BUG: command 'target_request' does + not have the '.usage' field filled out ^C oyvind@fierce:~/openocd$ + openocd -c "interface dummy" -f board/at91eb40a.cfg 2>&1 | grep -w + BUG Error: BUG: command 'command' does not have the '.usage' field + filled out Error: BUG: command 'script' does not have the '.usage' + field filled out Error: BUG: command 'power_restore' does not have + the '.usage' field filled out Error: BUG: command 'srst_deasserted' + does not have the '.usage' field filled out Error: BUG: command + 'measure_clk' does not have the '.usage' field filled out Error: + BUG: command 'exit' does not have the '.usage' field filled out + Error: BUG: command 'shutdown' does not have the '.usage' field + filled out Error: BUG: command 'gdb_sync' does not have the '.usage' + field filled out Error: BUG: command 'interface_list' does not have + the '.usage' field filled out Error: BUG: command 'target' does not + have the '.usage' field filled out Error: BUG: command 'target init' + does not have the '.usage' field filled out Error: BUG: command + 'flash' does not have the '.usage' field filled out Error: BUG: + command 'flash init' does not have the '.usage' field filled out + Error: BUG: command 'flash banks' does not have the '.usage' field + filled out Error: BUG: command 'nand' does not have the '.usage' + field filled out Error: BUG: command 'nand drivers' does not have + the '.usage' field filled out Error: BUG: command 'nand init' does + not have the '.usage' field filled out Error: BUG: command 'pld' + does not have the '.usage' field filled out Error: BUG: command 'pld + init' does not have the '.usage' field filled out Error: BUG: + command 'mflash' does not have the '.usage' field filled out Error: + BUG: command 'mflash init' does not have the '.usage' field filled + out Error: BUG: command 'dummy' does not have the '.usage' field + filled out Error: BUG: command 'dummy foo' does not have the + '.usage' field filled out Error: BUG: command 'scan_chain' does not + have the '.usage' field filled out Error: BUG: command 'jtag' does + not have the '.usage' field filled out Error: BUG: command 'jtag + init' does not have the '.usage' field filled out Error: BUG: + command 'arm' does not have the '.usage' field filled out Error: + BUG: command 'arm reg' does not have the '.usage' field filled out + Error: BUG: command 'etm' does not have the '.usage' field filled + out Error: BUG: command 'arm7_9' does not have the '.usage' field + filled out Error: BUG: command 'at91eb40a.cpu' does not have the + '.usage' field filled out Error: BUG: command 'at91eb40a.cpu arm' + does not have the '.usage' field filled out Error: BUG: command 'arm + reg' does not have the '.usage' field filled out Error: BUG: command + 'at91eb40a.cpu etm' does not have the '.usage' field filled out + Error: BUG: command 'at91eb40a.cpu arm7_9' does not have the + '.usage' field filled out Error: BUG: command 'target_request' does + not have the '.usage' field filled out Change-Id: I2c3e529530a15d2295a1950ffc59e8f2fc661012 Signed-off-by: + Øyvind Harboe Signed-off-by: Mathias K + Reviewed-on: http://openocd.zylin.com/299 + Tested-by: jenkins Reviewed-by: Øyvind Harboe + Reviewed-by: Spencer Oliver + + +2011-12-17 Mathias K + + * : Add STM32F2X/STLINK target config file. Change-Id: I02161fa05da993b5b966c31a706667d1bd91935d Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/287 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-12-17 Mathias K + + * : STM32 ST-LINK target initial release STM32 ST-LINK target added. Change-Id: Ibe2b7a3c0d5a8cf73d8680d6019adbdb62d68fa2 Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/279 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-12-15 Mathias K + + * : Make jim functions public accessible. Change this 2 functions to make it accessible for other tcl + interfaces. Change-Id: Idee07fcc779941b037a05a40c021e3fb0b1a4a7a Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/277 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-12-01 Mathias K + + * : add private data pointer to the tap interface This will give us the ability to add special data structures and new + interfaces without rewriting the complete jtag engine. Change-Id: I21a6e1daa96c5f4d111bbb734c7c1fbc2eaee227 Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/244 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-12-23 Spencer Oliver + + * : build: fix mingw build issues 8901fca0270fec41b12c30c7dbd806d460548c5b broke the build under + mingw, this fixes that. Change-Id: I22b91e220dac3b68cc576b65a9f1b8711e64263a Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/298 Tested-by: jenkins Reviewed-by: Freddie + Chopin Reviewed-by: Øyvind Harboe + + +2011-12-14 Erik Ahlén + + * : Documentation for mxc NAND flash controller Change-Id: I9e552491e8b4737c01e4f8ae2b9a582b6ff2bc5d Signed-off-by: + Erik Ahlén Reviewed-on: + http://openocd.zylin.com/273 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Spencer Oliver + + +2011-12-13 Erik Ahlén + + * : Added command to enable/disable/query BI-swap for MXC NAND Change-Id: Ifa3eb739afe0760a974b57c5a17cc3bf7704ba79 Signed-off-by: + Erik Ahlén Reviewed-on: + http://openocd.zylin.com/270 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Spencer Oliver + + +2011-12-13 Erik Ahlén + + * : Added board type as a parameter to mx2 NFC as they have + different base addresses. Change-Id: I7bc326e9a8d9f6817f046a7faeebede567c53dd2 Signed-off-by: + Erik Ahlén Reviewed-on: + http://openocd.zylin.com/268 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Spencer Oliver + + +2011-12-20 Ulf Samuelsson + + * : Olimex-ARM-USB-OCD-H: Add udev rule Change-Id: Ifc9a1f7fa9445e05560c335b5bba3a33caeccc51 Signed-off-by: + Ulf Samuelsson Reviewed-on: + http://openocd.zylin.com/288 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Spencer Oliver + + +2011-12-21 Ulf Samuelsson + + * : git should ignore patches from format-patch Change-Id: Iafce872fa7559180834532ba80941dec3db7d079 Signed-off-by: + Ulf Samuelsson Reviewed-on: + http://openocd.zylin.com/295 Tested-by: jenkins Reviewed-by: Mathias + Küster Reviewed-by: Øyvind Harboe + + +2011-12-13 Øyvind Harboe + + * : jtag: make caller always allocate buffer simplifies the API and there is only one remaining user at this + point. Is the implementation busted where the check does not actually + happen now? Change-Id: I776a43766f5576a08df320f6fe41a2750d101bde Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/264 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-12-13 Øyvind Harboe + + * : jtag: retire jtag_alloc_in_value32 API not needed, reduce area of interface and sharp edges to API. Change-Id: I5347352e7595686634bd0de13fcf6de6e55027b0 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/262 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-12-12 Spencer Oliver + + * : build: libusb use AC_CHECK_HEADER use AC_CHECK_HEADER rather than AC_CHECK_HEADERS so that we do not + generate a unrequired HAVE_LIBUSB_1_0_LIBUSB_H define. Change-Id: I23a93d3813716dce797ca1514fdcb84533454c31 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/259 Tested-by: jenkins Reviewed-by: Mathias + Küster + +2011-12-12 Spencer Oliver + + * : build: correctly quote m4 parameters Change-Id: If7ccb52c107cb4ad7629ffcf237f9003f60e63d0 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/257 Tested-by: jenkins + +2011-12-13 Erik Ahlén + + * : Indentation and white space fixes. Change-Id: Iffbaefea4f3d5e9b56b3c36496b44969d7c07e82 Signed-off-by: + Erik Ahlén Reviewed-on: + http://openocd.zylin.com/266 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-12-16 Spencer Oliver + + * : checkpatch: fix false indent trigger we have changed the indent to 4 to match OpenOCD coding style. Change-Id: I4870a3410eb20fc2f6df6a3e5891d4d4e598131a Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/285 Tested-by: jenkins + +2011-12-15 Erik Ahlén + + * : Change checkpatch.pl tab expanding to 4 characters. The C coding style guide says that tab width is 4 characters but + checkpatch.pl expands tabs to 8 characters which produces false + negatives. Change-Id: Ibdabbb55269b7cf6bcd38042cccb8bd235e42ce2 Signed-off-by: + Erik Ahlén Reviewed-on: + http://openocd.zylin.com/275 Tested-by: jenkins Reviewed-by: Øyvind + Harboe Reviewed-by: Spencer Oliver + + +2011-12-13 Øyvind Harboe + + * : zy1000: fix crash in JTAG over TCP/IP disable asynchronous callbacks and reads as minidriver requires + reads and callbacks to be synchronous. Could possibly be fixed by some design work. Change-Id: I7ca79a551085b2e8ba6928e1762d1baed6e95d4b Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/260 Tested-by: jenkins Reviewed-by: Øyvind + Harboe Tested-by: Øyvind Harboe + + +2011-12-07 Øyvind Harboe + + * : HACKING: add explanation why we want cool-off times as long as a + week or two Change-Id: I281e9145f43bc7ac173e02c4e209834f0deaae2b Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/254 Tested-by: jenkins Reviewed-by: Spencer + Oliver Reviewed-by: Mathias Küster + Reviewed-by: Øyvind Harboe + + +2011-12-02 Antonio Borneo + + * : TCL/SPEAr: default one DDR chip Handle default case of single DDR chip Propagate global variable for + multi DDR chip Change-Id: I315380f91ee7fcc2976437aa5836d88a7964fc9d Signed-off-by: + Antonio Borneo Reviewed-on: + http://openocd.zylin.com/251 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-12-03 rodrigo_l_rosa + + * : HACKING - checkpatch before pushing makes life quicker Change-Id: I4c3cde2aae7bdea138413e373ac986be3efd54de Signed-off-by: + rodrigo_l_rosa Reviewed-on: + http://openocd.zylin.com/252 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-12-01 Spencer Oliver + + * : gdb_server: use strndup to allocate debug messages Lets be consistent and use strndup to allocate the debug buffer. Change-Id: I535ad270ebfeae6e09d28372ab3749c822971223 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/245 Tested-by: jenkins Reviewed-by: Øyvind + Harboe Reviewed-by: Andreas Fritiofson + + +2011-12-02 Peter Stuge + + * : Fix remaining incorrect reference to target/at91sam3uXX.cfg Commit 1794e5ee5452c83b5bef6d0a5a8a3f23d647e9c6 renamed the file to + have all lowercase characters according to most references to the + file, but the commit didn't change the existing reference to the old + filename. Change-Id: I380e52e947a8091d48cf010e3919bf2caed7fdff Signed-off-by: + Peter Stuge Reviewed-on: + http://openocd.zylin.com/248 Tested-by: jenkins + +2011-12-01 Spencer Oliver + + * : binarybuffer: use strndup to allocate string Change-Id: I65d8f37b18d5b5a798406b956f50ab7bb550e172 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/246 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2011-11-29 Mathias K + + * : target init sanity check Add a test if the pointer to the target_init function in the target + struct is set before the function pointer is used. Change-Id: Ie4ea542f64f35efce8c5bce2ced9b881bf283ec1 Signed-off-by: + Mathias K Reviewed-on: + http://openocd.zylin.com/241 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-11-22 Evan Hunter + + * : Fix unused variables error in amt_jtagaccel Change-Id: Ic64cf4e3b5cf8c1ea75a13577728b0cb0d70068e Signed-off-by: + Evan Hunter Reviewed-on: + http://openocd.zylin.com/237 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-11-19 rodrigo_l_rosa + + * : dsp5680xx - flash module clk to freescale cfg value the flash module clock was set according to a spreadsheet from + freescale, now it's set according to the configuration file used by + the Freescale Flash Programmer. both work, but i think it's better + to use the one used by a software that's made by Freescale (should + be correct...) Change-Id: I382197a3eb43dd47ff4b9b83d5e05008d5613fc6 Signed-off-by: + Rodrigo L. Rosa Reviewed-on: + http://openocd.zylin.com/223 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-04 rodrigo_l_rosa + + * : dsp5680xx - fix jtag debug request failure handling if JTAG debug request fails then halting with a reset should be + attempted. the failure was ignored previously. Change-Id: Ibec08e2e97f962d164a110c21aaa80bfc17b7f1a Signed-off-by: + Rodrigo L. Rosa Reviewed-on: + http://openocd.zylin.com/221 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-11-15 rodrigo_l_rosa + + * : dsp5680xx - fix - flashing algorithm check now the flash algorithm running on the 568013 checks the + buffer_empty bit (instead of the command_finished bit) before trying + to write a new word to the flash mem. this should speed up the + flashing procedure. since it is open loop, this change may reduce + the risk of failure. flashing will fail if JTAG speed is such that + the flash module cannot keep up. also, the USTAT register is only read once, as suggested in the flow + chart provided by freescale (per. ref. manual @ 6-11) the last step of the flow chart, exiting after commands are + complete, is not implemented. the algorithm will stay waiting for + more data. it is up to the PC side to *not* send more data. Change-Id: I47fe4b50de7da85f80868f5986a89a7e2152616c Signed-off-by: + Rodrigo L. Rosa Reviewed-on: + http://openocd.zylin.com/219 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-09-02 rodrigo_l_rosa + + * : dsp5680xx - fix jtag status mask Change-Id: I17a0f22cbeb20e4f6ea4065236243f93d826ccf0 Signed-off-by: + Rodrigo L. Rosa Reviewed-on: + http://openocd.zylin.com/217 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-09-02 rodrigo_l_rosa + + * : dsp5680xx - error codes added logging of target error codes to enable automatic error + handling from tcl. the plan is to use a computer to execute a + series of tcl commands, the changes allow simple parsing of return + messages to detect errors. Change-Id: Ia98d3bd036e1b6065b475ffff6c1d30baeaf7417 Signed-off-by: + Rodrigo L. Rosa Reviewed-on: + http://openocd.zylin.com/215 Tested-by: jenkins Tested-by: Øyvind + Harboe Reviewed-by: Øyvind Harboe + + +2011-11-23 Antonio Borneo + + * : TCL/SPEAr: fix name of included file Fix error introduced in recent commit. Correct the name of the + board file. Change-Id: I46bca8329812fb24bc4f8d316be9e7cba9b56496 Signed-off-by: + Antonio Borneo Reviewed-on: + http://openocd.zylin.com/234 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-18 Antonio Borneo + + * : TCL: Add board file for EVALSPEAr300 Initial support for SPEAr300 chip and for evaluation board named + EVALSPEAr300. Currently supports only those parts in common with + SPEAr310. Change-Id: I8075aa721cf3dfaac561ee51e5df4ce9a2992e3e Signed-off-by: + Antonio Borneo Reviewed-on: + http://openocd.zylin.com/230 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-21 Antonio Borneo + + * : TCL/SPEAr: move DDR activation in common code DDR controller activation should not be in DDR chip specific code, + but in generic DDR controller part. Change-Id: If1b178228352b48b0097d7b9b300005fb5bb4fb6 Signed-off-by: + Antonio Borneo Reviewed-on: + http://openocd.zylin.com/228 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-01-21 Antonio Borneo + + * : TCL/SPEAr: move device generic code The initialization of RAS enable and clock is required by all + SPEAr3xx devices Change-Id: Iea4cd0902e4da219475d7f35b4c25fc87ec6b902 Signed-off-by: + Antonio Borneo Reviewed-on: + http://openocd.zylin.com/226 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2010-11-27 Antonio Borneo + + * : TCL/SPEAr: Add reference to ST Application Note ST-AN was mentioned but there was no reference Change-Id: Ie065f8faba94d63cf391a994ec895692d499394e Signed-off-by: + Antonio Borneo Reviewed-on: + http://openocd.zylin.com/224 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-15 Spencer Oliver + + * : usbprog: fix shadowed declaration warning see Trac #38 Change-Id: If86fda797391f10d745384794b68e60380ef0b21 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/204 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2011-11-16 Mauro Gamba + + * : libusb-1.0 support The configuration script check for libusb-1.0 availability first and + only if not found check for libusb-0. So if both libraries are + installed on the system the build script will use libusb-1.0 It's + possible to force compiling with libusb-0 with the --enable-libusb0 + switch. If the driver support only libusb0 the script check anly + for it. Change-Id: I7eb045d4e2bd553abefad53f3f4023ff46b0f5f6 Signed-off-by: + Mauro Gamba Reviewed-on: + http://openocd.zylin.com/33 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-18 Spencer Oliver + + * : Revert "build: fix gcc 4.6.2 warnings" This reverts commit 0ef5a90d93c5a026bcf70132e60e957ae339d1e1 Causes older versions of gcc to break - need to look into a better + fix. This passed through the jenkins build as we originally did not build + this module - we do now. Change-Id: Iafeac8442b2249269ff45a52ccd3e2870920f635 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/214 Tested-by: jenkins + +2011-11-14 Robert Pasz + + * : presto: fix tms_sequence short issue fix issue when using tms_sequence short see Trac #31 Change-Id: I22a9cd2af59eae4d8a276dae60b6a99d05af53bb Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/201 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2011-11-14 Philip Nye + + * : gdb: fix multi core gdb issue gdb_memory_map() correctly calculates the target specific number of + flash banks, but then uses the total number (all targets) instead of + the target specific number to construct its GDB response, causing a + crash. Change-Id: I3f8639b3e90303a59753ebe140ce4fff96fd5db0 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/199 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2011-11-14 Spencer Oliver + + * : flash: match stm32f2x loader src name Change-Id: I60523f809f2d9ec9c9283e0456746ce9a63576a7 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/196 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2011-11-17 Felix Ruess + + * : config: do not use deprecated stm32.cfg Change-Id: Id72d2d7f874043331ecb5586a3797d017606129e Signed-off-by: + Spencer Oliver Signed-off-by: Felix Ruess + Reviewed-on: http://openocd.zylin.com/212 + Tested-by: jenkins + +2011-11-16 Andreas Fritiofson + + * : bitq: make private functions static Change-Id: I3fabbdbda4ba8ba6557d79b97444fe06f1710b58 Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/209 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-16 Andreas Fritiofson + + * : bitq: remove the remaining static variables in_mask and in_idx are just another encoding of the same state + information that is already kept in bitq_in_state.bit_pos so derive + them from that instead of maintaining them separately. Change-Id: I4ac6bbe923698a8c1090a785b8babcbb90f82931 Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/207 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-15 Andreas Fritiofson + + * : bitq: remove a static variable in_buff is only ever set to field->in_value and that pointer is + still available when the parsing is restarted so it could just as + well be used directly, removing the need for the static variable. Change-Id: I3dd7a8315ed5c5bdc3bfb74044f89492bca9816c Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/206 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-13 Tomas Frydrych + + * : kinetis flash: use longword write when writing into pflash Check whether the destination is in the program flash or NVM + regions, in the former case, use the normal longword mechanism, not + the fast NVM write. Change-Id: I7366b7c8919928ee690252df83b99701776aee82 Signed-off-by: + Tomas Frydrych Reviewed-on: + http://openocd.zylin.com/194 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-10-17 Aurelien Jacobs + + * : at91sam7: ensure probed flash bank has a name (fix a segfault) Before this commit, openocd used to segfault when probing flash of + an at91sam7x512 (which contains 2 banks of flash). This was due to + the way it systematically insert a new flash bank without setting + its name. Then, when get_flash_bank_by_name_noprobe() is called, it + is doing a strcmp() on the non-initialized bank->name. This commit prevents allocation of second probed bank if it is + already allocated (for example, if it is set in a target config + file). If a new bank really needs to be allocated, it ensures that a + default name is set. Change-Id: I38d15bef1fda2ec746efad37171975136cf7b371 Signed-off-by: + Aurelien Jacobs Reviewed-on: + http://openocd.zylin.com/171 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-10 Øyvind Harboe + + * : image: remove assignments to local variables that is never read Change-Id: I1a5e968f165e060fd4aa7c023ad870a9e21bb5dd Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/191 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-07 Øyvind Harboe + + * : svf: fix warnings Change-Id: Ib7f67612db3a865f9acc5ae349455da7ddcd3348 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/177 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-09 Spencer Oliver + + * : docs: remove berlios related info Change-Id: I9593eb165fce51411f20fa068e324b3fd882cdb3 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/190 Tested-by: jenkins + +2011-10-22 Kyle Manna + + * : contrib: Add udev rules for TI xds100v2 debugger This corrects permissions on the FTDI chip on the xds100v2 debugger + enabling normal users to access it. Change-Id: I0f6618692ebdee6284eee28f9e612e68782c4d78 Signed-off-by: + Kyle Manna Reviewed-on: + http://openocd.zylin.com/188 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-08 Øyvind Harboe + + * : buspirate: add missing error propagation found by clang. Change-Id: I80ea8e6afc8dcc1aa7edb6f63af0d94f6781b81c Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/182 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-08 Øyvind Harboe + + * : em357: fix warning by removing unused local variables Change-Id: I9def63d36ed4fa8bf9cdeeedc18b1b25d0e487d6 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/184 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-03 Spencer Oliver + + * : flash: update luminary device table add support for checking target against the device CLASS rather then + just the PARTNO. This change also adds the new LM4F family (Blizzard). Change-Id: Ia9d1e33f1f1c2817c0039a2232ecf932fae072f9 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/161 Reviewed-by: Øyvind Harboe + + +2011-10-17 Aurelien Jacobs + + * : at91sam7: add a new target config file for at91sam7x512 The main difference with at91sam7x256 is the declaration of the + second bank of flash. Change-Id: I87a20dcbb639b797799139ccf46cc73934fa3b9e Signed-off-by: + Aurelien Jacobs Reviewed-on: + http://openocd.zylin.com/173 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-07 Øyvind Harboe + + * : xsvf: add missing error propagation Change-Id: Ibc70deb980d6d18ceb376b72d9104e6180b16acf Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/176 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-10-31 Øyvind Harboe + + * : str9x: explain compiler that a local variable will always be + initialized Change-Id: I9ddb2793b4cdbf6acea6f69973531491e4ebcc5b Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/145 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-07 Øyvind Harboe + + * : str7x: fix error propagation stick to convention of "retval" being used as error value to be + propagated and use "flash_flags" local variable for flash flags read + from how. Change-Id: I63f1f2248b4f4538d6cd7634ae277f7c0aadc346 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/178 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-07 Øyvind Harboe + + * : ecos: add missing error propagation Change-Id: Ib34815c9cf654517f22486a7c8001fdb7471338c Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/174 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-10-31 Øyvind Harboe + + * : warning fix: add self-consitency check to remove warning verify promise of code that more code can be pasted with an assert + at the end condition of the code passage that builds string. Change-Id: I76a4e5f91b9142fff932e1493cb43c29eb6a0f80 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/143 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-11-04 Spencer Oliver + + * : tools: fix permissions Change-Id: I9419138dd2972304daf215594ca917ac8eb7fcda Signed-off-by: + Spencer Oliver + +2011-11-03 Øyvind Harboe + + * : etm: fix warning by removing assignment that is immediately + overwritten Change-Id: Ia3a83d3c1fc3a1707d69017fce6cf142a81babc4 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/165 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-01 Øyvind Harboe + + * : dsp5680xx: add missing and broken error propagation found by clang. Change-Id: Ie7e2ecad71bf0838ece93727e4778ad368b890ef Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/156 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-03 Øyvind Harboe + + * : avr32_regs: add missing error propagation Change-Id: Ie8b141dd534d73eccfc045069d5f628bd1eea88e Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/166 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-02 Øyvind Harboe + + * : HACKING: all you need is http access Change-Id: I191c1da5126c4c9ea1ff8826576b6b24feaf9881 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/157 Tested-by: jenkins Reviewed-by: Øyvind + Harboe Reviewed-by: Spencer Oliver + + +2011-11-03 Spencer Oliver + + * : tools: add checkpatch script Change-Id: I3579028fc1c6ee8bea58c82e5f0eecba7794d7cb Signed-off-by: + Spencer Oliver + +2011-11-01 Spencer Oliver + + * : cfg: add Stellaris LM4F232 Evaluation Kit config Change-Id: Ica754897bef6573a0738ed1afdfe1dfda07292fd Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/151 Tested-by: jenkins Reviewed-by: Andreas + Fritiofson + +2011-11-01 Mark Vels + + * : tx27stk5: add board init support for KaRo TX27 CPU module This patch adds support for a KaRo TX27 CPU module on a StarterkitV + base board. The register settings have been extracted from a + RedBoot distribution that is distributed along with the hardware by + KaRo. This setup has been tested with a JTAGKey. The testing has been + focussed on loading a program into memory and start execution. + Although the flash seems to be correctly detected, no effort has + been put in testing the NAND programming yet. Change-Id: Ib17763f1e3ecacd0eb9b5fdc32f8cba7a5e59be5 Signed-off-by: + Mark Vels Reviewed-on: + http://openocd.zylin.com/158 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-01 Øyvind Harboe + + * : cortex_a: add missing error propagation found by clang. Change-Id: I50eac219d7540fd48d3285f3f213cb659492d0c0 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/153 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-01 Øyvind Harboe + + * : arm11: print next address to debug fixes clang warning. Basically the next address pointer is not used + for anything in the fn, except to be examined in debug. Change-Id: I253519b8e49e54490bbe7da8ec3d2dd31f49052a Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/155 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-11-01 Øyvind Harboe + + * : target: fix null pointer exception check if no target is selected and return error. Change-Id: Ie8abb63c708d09572b45e88fc6766af108715077 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/148 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-10-31 Spencer Oliver + + * : target: rename cortex_m3.[ch] to cortex_m.[ch] This rename is in preparation for cortex_m4 support. Change-Id: Ic08c298ec6ed2aabc2c39db67191f68b3a51f550 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/147 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-31 Øyvind Harboe + + * : warnings: null pointer check fix rewrite broken null pointer check code by reducing scope of + variable. Change-Id: I8254f6849b187e5c9cd083053cdc11973c6fe339 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/142 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-10-27 Øyvind Harboe + + * : bugfixes: tinker a bit with the targets command return error when target can not be found instead of ERROR_OK, split + fn. Change-Id: Iba5232d3862a490d0995c3bfece23685bd6856e3 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/131 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-10-30 Uwe Hermann + + * : interface configs: Fix whitespace and other issues. Change-Id: I98825c7fb9bdee75b69b06005ed12a3f64ec4db4 Signed-off-by: + Uwe Hermann Reviewed-on: + http://openocd.zylin.com/139 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2011-10-29 Øyvind Harboe + + * : clang: fix warning by adding assert that shows that a variable + is used Change-Id: I26e0ba9f1ae9d43c9a14c42c4225746782dc4d66 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/134 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-27 Øyvind Harboe + + * : bugfixes: numerous bugs in error propagation found by clang Change-Id: I784068325b422d1918e28c08544bc5a1332d712f Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/130 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-26 Jim Norris + + * : Remove use of undefined variable. Change-Id: Id8fd345438c360b2a42857525f05360ce2794d21 Signed-off-by: + Jim Norris Reviewed-on: + http://openocd.zylin.com/127 Reviewed-by: Peter Stuge + Tested-by: jenkins + +2011-10-25 Jim Norris + + * : Add configuration for ATMEL SAM3N-EK board. Change-Id: I525f6c346cace4e54f47659c5a7aceb29ee4baf2 Signed-off-by: + Jim Norris Reviewed-on: + http://openocd.zylin.com/125 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-25 Marti Bolivar + + * : stm3220g_eval.cfg: fix CHIPNAME. The STM3220G-EVAL board has an STM32F207IGH6. ("...H6", not + "...T6"). Change-Id: Iaf3dae6830c5c0685a1dcd1588d391434bc51be7 Signed-off-by: + Marti Bolivar Reviewed-on: + http://openocd.zylin.com/120 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-10-25 Andreas Fritiofson + + * : armv7a: make local functions static Also fix a spelling error and remove the declaration for a + non-existent function from the header. Change-Id: I13177e2d81aa167c05c1cc766f06924211e6d735 Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/118 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-22 Freddie Chopin + + * : Fix "Evaluate 'script' in the global scope" This fixes commit Evaluate 'script' in the global scope. It caused + Windows builds behave differently than before because path was + evaluated twice and backslashes from Windows' paths got unescaped + and effectively wiped out. Configs could only be passed with "-f + ../dir/config.cfg" or "-f ..\\dir\\config.cfg" instead of usual "-f + dir/config.cfg" (or using backslash) as previously. Change-Id: I13b4abac6dbe6d770cc11a4e61c9421ef340da83 Author: Steve + Bennett Signed-off-by: Freddie Chopin + Reviewed-on: http://openocd.zylin.com/40 + Tested-by: jenkins Reviewed-by: Xiaofan + Reviewed-by: Spencer Oliver + +2011-10-23 Antonio Borneo + + * : SERVER: fix clang warning The fix is inline with the Linux coding style that forbids + assignment in if condition Change-Id: I0b9d0b419d9c8b7a8c755e048d5faf72d1658ba2 Signed-off-by: + Antonio Borneo Reviewed-on: + http://openocd.zylin.com/87 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-23 Antonio Borneo + + * : NOR/CORE: fix clang warning The fix is inline with the Linux coding style that forbids + assignment in if condition Change-Id: I10338a249bcfeff87d8596f7e17f209e26b41678 Signed-off-by: + Antonio Borneo Reviewed-on: + http://openocd.zylin.com/86 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-23 Antonio Borneo + + * : FLASH/CFI: fix clang warnings Total of 5 warnings: 3x "Dead store": removed dead assignment to + variable; 1x "Dereference of null pointer": this is not an error, + but a limited visibility of clang, since pointer erase_region_info is initialized inside cfi_fixup_non_cfi(); 1x "Branch condition + evaluates to a garbage value": this is a real coding bug that could + issue SIGSEGV, since "goto cleanup" can be executed before + initialization of "source". Change-Id: Id3c323c82bb15cbd3bb8fc04b23541f11145f109 Signed-off-by: + Antonio Borneo Reviewed-on: + http://openocd.zylin.com/84 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-22 Øyvind Harboe + + * : fm3: fix warning for superfluous assignment Change-Id: I4f8e8c2e676a2728ddc6227daf9ca6a7ceb3d505 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/46 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-22 Øyvind Harboe + + * : tms470: remove dead assignment warning Change-Id: I21e7ac47f80d93c9c0d7b169f8848b929c664b20 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/45 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-21 Øyvind Harboe + + * : clang: fix warning w/assert so that clang knows that there will + be no division by zero Change-Id: I98ac62a22f21043bb535a667a4f1f1537ccde2a4 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/42 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-23 Edgar Grimberg + + * : tms470: removed unnecessary operations This should silence a warning. Change-Id: Id91a9ebacae836083b1db2654a8e7bf24b2300e9 Signed-off-by: + Edgar Grimberg Reviewed-on: + http://openocd.zylin.com/52 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-22 Øyvind Harboe + + * : buspirate: ignore return value and fix warning Perhaps we could do one better and propagate the error? Change-Id: Idc45f516c26f09de4ee01fe05e8d3475f4b80db3 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/43 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-22 Øyvind Harboe + + * : server: remove warning due to dead assignment Change-Id: Idb08aef0c11b3fae92286e8fcea61ab09ab09e74 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/44 Reviewed-by: Peter Stuge + Tested-by: jenkins + +2011-10-20 Andreas Fritiofson + + * : rtos: remove broken code for handling the deprecated qP packet Change-Id: Icca522c1e2a2877abb20665b171c61079b1d8f48 Signed-off-by: + Andreas Fritiofson Reviewed-on: + http://openocd.zylin.com/37 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2011-10-19 Freddie Chopin + + * : Unused variables Fix a few errors with set and unused variables detected by GCC 4.7.0 Change-Id: I59b748e18e514ee9f0cde7883b4ed5116198bd4a Signed-off-by: + Freddie Chopin Reviewed-on: + http://openocd.zylin.com/36 Tested-by: jenkins Reviewed-by: Spencer + Oliver + +2011-10-19 Uwe Hermann + + * : TMPA900/910 MCUs are always little endian. Signed-off-by: Uwe Hermann Change-Id: + I8839f2cf0faf1b5ba9f99901c5ee028b199fabd2 Reviewed-on: + http://openocd.zylin.com/35 Tested-by: jenkins Reviewed-by: Peter + Stuge + +2011-09-19 Matt Reimer + + * : xscale: fix bug in xscale_receive() The code in xscale_receive() that tries to skip invalid reads (i.e. + reads that don't have the DBG_SR[0] 'valid' bit set) seems to be + wrong, as it only looks at the first word's valid flag rather than + each word's own valid flag. Am I reading the code correctly? If so, + the attached patch should fix it. If this looks correct, I'll generate a proper patch and commit + message. Matt Change-Id: I74ebe2ad7a36d340a9dd3b8487578b6ea7f3cf1e Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/32 Tested-by: jenkins Reviewed-by: Øyvind + Harboe + +2011-10-17 Spencer Oliver + + * : luminary: add peripheral reset script some luminary device classes require a reset script to emulate a + hardware reset. Change-Id: Id505c92451244b48b0238c2130aebab2df8d208b Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/30 Reviewed-by: Øyvind Harboe + Tested-by: Øyvind Harboe + + +2011-10-02 Karl Kurbjun + + * : ICEPick-C: Add support for warm reset through JTAG controller + and provide finer detail functions. This sets up simple functions that can later be used to provide + additional ICEPick Operations. Change-Id: I313b8679267696fad87d23f3692963e513f2fe21 Signed-off-by: + Spencer Oliver Reviewed-on: + http://openocd.zylin.com/22 Tested-by: Øyvind Harboe + Reviewed-by: Øyvind Harboe + + +2011-10-14 Øyvind Harboe + + * : target_request: add target_got_message() that can be used to + improve DCC performance API change to allow implementing a back-off algorithm for polling + hardware. Change-Id: I6cbe8b4534c8dfeb8442305171ea96b5481c1f17 Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/26 Reviewed-by: Øyvind Harboe + Tested-by: Øyvind Harboe + + +2011-10-14 Jim Norris + + * : Add some more detail for setting up Gerrit account. 1) Add a couple more steps when setting up the Gerrit account. Change-Id: I5d81feac4650d4d28653d14cfc0baf14270424c1 Signed-off-by: + Jim Norris Reviewed-on: http://openocd.zylin.com/28 + Reviewed-by: Peter Stuge Tested-by: Peter Stuge + + +2011-10-14 Spencer Oliver + + * : flash: fix lpc2000 driver typo Change-Id: I3a759ed98a27fd186c12355b846d5e97dba86c5b Signed-off-by: + Spencer Oliver + +2011-10-14 Uwe Hermann + + * : Add a board file for the Glyn Tonga2. This is a Toshiba TMPA900CMXBG (ARM9) based SO-DIMM CPU module with + 64MB DDR SDRAM, 256MB NAND flash, and on-board Ethernet. The board file provides a tonga2_init function which sets up the + PLL/clocks and memory (SDRAM and SRAM), which allows writing a + boot-loader into RAM via JTAG. Change-Id: I60522b97997bdf50e1f25aebab910d93a98522fb Signed-off-by: + Uwe Hermann Reviewed-on: + http://openocd.zylin.com/19 Reviewed-by: Spencer Oliver + Tested-by: Spencer Oliver + + +2011-10-03 Michel Jaouen + + * : breakpoint : smp software breakpoint issue Change-Id: Iefe78bad71d4fdb38ae412ab8fe2f6282836c22e Signed-off-by: + Øyvind Harboe Reviewed-on: + http://openocd.zylin.com/14 Tested-by: Spencer Oliver + Reviewed-by: Spencer Oliver + + +2011-10-12 Øyvind Harboe + + * : docs: update HACKING to point to Gerrit Change-Id: If79e86c731ac06aaefca1aebde40e7cb3de68e4d Signed-off-by: + Øyvind Harboe + +2011-10-12 Spencer Oliver + + * : docs: update project url's Change-Id: I54fc3aff722ed25143aad85e58d19b72fcecbba0 Signed-off-by: + Spencer Oliver + +2011-10-11 Spencer Oliver + + * : replace berlios url's with sourceforge url's Change-Id: I1c9957bb64df87cee7c5e832f21453eb8934a5fb Signed-off-by: + Spencer Oliver + +2011-07-31 Andreas Fritiofson + + * : stm32f1x: use async algorithm in flash programming routine Let the target algorithm be running in the background and buffer + data continuously through a FIFO. This reduces or removes the effect + of latency because only a very small number of queue executions + needs to be done per buffer fill. Previously, the many repeated + target state changes, register accesses (really inefficient) and + algorithm uploads caused the flash programming to be latency bound + in many cases. Now it should scale better with increased throughput. Signed-off-by: Andreas Fritiofson + +2011-07-15 Andreas Fritiofson + + * : cortex_m3: use armv7m's async algorithm implementation Signed-off-by: Andreas Fritiofson + +2011-07-15 Andreas Fritiofson + + * : target: add async algorithm entries to the target type On supported targets, this may be used to start a long running + algorithm in the background so the target may be interacted with + during execution and later wait for its completion. The most obvious use case is a double buffered flash algorithm that + can upload the next block of data while the algorithm is flashing + the current. Signed-off-by: Andreas Fritiofson + +2011-09-16 Simon Barner + + * : arm-jtag-ew: Formatting + +2011-09-16 Simon Barner + + * : arm-jtag-ew: Emit a warning if interface firmware version != 1.6 + +2011-09-16 Simon Barner + + * : arm-jtag-ew: Provide armjtagew_speed_div() in order to fix + interactive use of `adapter_khz' + +2011-09-16 Simon Barner + + * : arm-jtag-ew: Fix setting interface speed (1/2) CMD_SET_TCK_FREQUENCY message length is 5, not 4 - Ticket: #34 + +2011-09-16 Clément Burin des Roziers + + * : STM32L: Added flash driver and target Added the flash driver for the STM32L family, which highly differ + from the STM32F family. Added the TCL target file for JTAG access. + +2011-09-19 Michel Jaouen + + * : u8500 : config for L2 cache + +2011-09-29 Steve Bennett + + * : jim-nvp is moving from jimtcl to openocd The jim-nvp code is specific to openocd, so it belongs in openocd, + not in the core jimtcl. Signed-off-by: Steve Bennett + +2011-09-21 Mathias K + + * : add target events, run algorithm and default r/w buffer api Target events are added to get better gdb support. The run algorithm + functionality are implemented to support feature fast flash write + functionality. The new r/w buffer api is now used to support the + special memory address handling. The output of the md command was + fixed. + +2011-09-17 Mathias K + + * : kinetis cpu flash driver Initial release of the freescale kinetis cpu flash driver. + +2011-09-12 Mathias K + + * : kinetis auto mass erase on secured devices This is a proof of concept to get access to the debug port of a + secured kinetis cpu. On full flash erase the cpu is automatically + secured and the debug port is not accessible. To get this to work + the srst line is needed and the necessary configuration should be + added to the configuration file. + +2011-09-01 Uwe Bonnes + + * : Add definition for the STEVAL-PCC010 board with the STM32F207 + +2011-08-31 Martin Schmölzer + + * : ULINK driver: Remove typedefs in ulink.c Signed-off-by: Martin Schmölzer + + +2011-08-31 Martin Schmölzer + + * : ULINK driver: Remove typedefs in OpenULINK firmware USB + descriptor structures Signed-off-by: Martin Schmölzer + + +2011-08-31 Rodrigo L. Rosa + + * : static for some functions made two functions into static, since they are not required by + anything external + +2011-08-31 Øyvind Harboe + + * : commit 353362651fc28c1f1d823659cde36dd31d1aede6 Author: Martin + Schmoelzer Date: Tue Aug + 23 17:22:53 2011 +0200 + +2011-08-04 Martin Schmoelzer + + * : ULINK driver: Add '-lm' linker flag when building this driver + (required for correct calculation of JTAG TCK speed setting) Signed-off-by: Martin Schmölzer + + +2011-07-04 Martin Schmölzer + + * : ULINK driver: Implement variable TCK frequency in OpenULINK + firmware Also, speed up jtag_clock_tck() significantly (150 kHz -> 375 kHz) Signed-off-by: Martin Schmölzer + + +2011-08-23 Martin Schmoelzer + + * : ULINK driver: Implement JTAG_PATHMOVE command Signed-off-by: Martin Schmölzer + + +2011-07-04 Martin Schmölzer + + * : ULINK driver: Implement command to manually force downloading + firmware image from arbitrary location Signed-off-by: Martin Schmölzer + + +2011-07-04 Martin Schmölzer + + * : ULINK driver: Properly propagate return values in + ulink_execute_queue() Signed-off-by: Martin Schmölzer + + +2011-08-31 simonqian.openocd + + * : vsllink driver compile fails with'vsllink_debug_buffer' defined + but not used USB communication is handled by code under versaloon directory. So + _DEBUG_USB_COMMS_ should not be used in vsllink.c. Attachment is + the patch. + +2011-08-30 Rodrigo L. Rosa + + * : fix enter debug mode for locking added an alternative way to enter debug mode, which does not require + restarting the chip. this will not always work, but in general it + will (failure 0.3%), and failure is not a dramatic issue, simply + have to use the full sequence. the user can only access "halt", + which uses the full sequence, so the user should not have any + problems. restarting the chip requires reconfiguring the flash + module. the doc is very poor, so i'd rather have the two methods, + and live with the 0.3%. + +2011-08-30 Rodrigo L. Rosa + + * : fix debug mode,lock,unlock got new info regarding setting the chip to debug mode, and + locking/unlocking flash memory. the newer implementation is a bit + slower, but always works. the previous implementation would + randomly (as once every 25k-70k times) get the chip into a state + where the freescale tool would be necessary. this is fixed now. added functions to play around with the jtag state machine. they are + not the happiest, but are necessary to be able to execute the + halting/locking/unlocking sequences. Conflicts: src/target/dsp5680xx.c + +2011-08-30 Rodrigo L. Rosa + + * : optional crc for flash writing crc check was always performed on newly flashed data, now it is + optional flash mem can be locked by writing a specific word to a + specific address in flash. to verify flash, target must be halted, + and this will (when the new halt sequence is implemented) require + reseting the chip. if the target is reset after writing the lock + words, then it will lock, hence the CRC will fail because it is not + possible to read stuff from the target. also added a function that resets the jtag state machine. this is + not used yet, but will be soon. it is implemented to allow strict + control over JTAG state machine, necessary to implement to halt and + unlocking sequences. + +2011-08-15 Rodrigo L. Rosa + + * : dsp568013 disable polling by default + +2011-08-26 Evan Hunter + + * : Fix off by one bug in FreeRTOS + +2011-08-24 Jonathan Dumaresq + + * : This will add the Value Line HD of stm32 devices. This has been tested on STM32F100VE + +2011-07-18 Evan + + * : Add suspended task list to FreeRTOS support + +2011-08-22 Jim Paris + + * : Fix redbee config files Currently the board/redbee-*.cfg files incorrectly include the + interface definition. Move the interfaces to interface/, and create + a single board/redbee.cfg that is common to both boards. Intended + usage is now: openocd -f interface/redbee-econotag.cfg -f + board/redbee.cfg + +2011-08-20 olivier Schonken + + * : Fix Sam3u flash bank 1 issue + +2011-08-17 Jie Zhang + + * : remove white space before TAB + +2011-07-12 SimonQian + + * : versaloon driver update Signed-off-by: Spencer Oliver + +2011-08-16 Spencer Oliver + + * : build: rename configure.in to configure.ac configure.ac is the correct name to use with modern autotools. Signed-off-by: Spencer Oliver + +2011-08-15 Jie Zhang + + * : show git commit number even when cross-compiling AC_CHECK_FILE will die when cross-compiling. So don't use it to test + the existence of guess-rev.sh. Signed-off-by: Spencer Oliver + +2011-08-10 Stefan Mahr + + * : mips: fix potential alignment error + +2011-08-10 Stefan Mahr + + * : target: add helper functions to get/set u16 or u32 array from/to + buffer + +2011-08-10 Jie Zhang + + * : remove useless pxref to SMP subsection + +2011-08-11 Steve Bennett + + * : Evaluate 'script' in the global scope Scripts sourced via 'script' should evaluate in the global scope to + make it easy to set and reference global variables. Signed-off-by: Steve Bennett + +2011-08-05 Rodrigo L. Rosa + + * : renamed for clarity i had started my code from dsp5683xx, i renamed a bunch of stuff to + names i consider to be better. i believe no one is using this code, + so nobody should be affected. (it's not too late to do this change) + +2011-07-17 Andreas Fritiofson + + * : rlink: simplify and optimize queue fill level checks Add a helper function for running the queue if it would overflow + otherwise. Use it to simplify the queue fill level checks and + optimize in a few cases that would previously run the queue + prematurely. Signed-off-by: Andreas Fritiofson + +2011-07-16 Andreas Fritiofson + + * : rlink: remove duplicated code After the reply_index handling is fixed, there's no need to special + case the out scan. Signed-off-by: Andreas Fritiofson + +2011-07-16 Andreas Fritiofson + + * : rlink: more indentation fixes Remove unnecessary block scopes to reduce indentation level. Signed-off-by: Andreas Fritiofson + +2011-07-25 Drasko DRASKOVIC + + * : mips32 : Fixed memory byte access Function mips_m4k_write_memory() does endianess byte swap, but this + procedure break one byte access (temporary array overwrites content + in buffer). As a fix, this endianess swap and buffer affecting is + preformed only on hword and word accesses (not on byte access). + +2011-07-07 Drasko DRASKOVIC + + * : mips32: Added CP0 coprocessor R/W routines This patch adds MIPS32 CP0 coprocessor R/W routines, as well as + adequate commands to use these routines via telnet interface. Now is becomes possible to affect CP0 internal registers and + configure CPU directly from OpenOCD. + +2011-07-05 Drasko DRASKOVIC + + * : mips32: Removed Unnecessary JTAG Queue Flush jtag_execute_queue() is executed as a part of + mips_ejtag_drscan_32(). No need for this to be done before - + removed for optimisation. + +2011-08-09 Rodrigo L. Rosa + + * : fix return error msj retval was not correctly propagated + +2011-08-09 Øyvind Harboe + + * : Revert "dsp5680xx: disable for now, it generates warnings" This reverts commit d567df02b9f3e7d2e7e78b3c2907ecad9aa4bbd4. + +2011-07-19 Rodrigo L. Rosa + + * : dsp5680xx fix FM clk before doing anything with the flash module (FM) the clock divider + must be set. if erase_check was the first thing done with the FM + after reset then an error would be generated because the clk divider + was not set. now erase_check sets the clk divider. + +2011-08-09 Jean-Christophe PLAGNIOL-VILLARD + + * : Archive and recreate NEWS file. Archive released NEWS file as NEWS-0.5.0. Create new NEWS file from + release script template. + +2011-08-09 Jean-Christophe PLAGNIOL-VILLARD + + * : The openocd 0.5.0 release. Remove '-dev' version tag: 0.5.0-dev -> 0.5.0 + +2011-08-03 Luca Bruno + + * : Automatically generate ChangeLog from git log for release + tarball make dist should use git2cl to generate ChangeLog from git history, + populating the placeholder file in released tarball. Signed-off-by: Luca Bruno Signed-off-by: Spencer + Oliver + +2011-08-01 Jie Zhang + + * : etb: fix incorrect previous patchset This corrects two issues found with openocd. + d7f71e7fe9645fa8c3f88cf6fc9ad438aa6708f3 removed some code that was + being used. The above then caused even more code to get removed by commit + 1cfb2287a67c1f78b76583b2e5ed83ca3560b0d5. Signed-off-by: Spencer Oliver + +2011-07-28 Spencer Oliver + + * : docs: remove obsolete luminary target info The lm3s variant is not required as this is handled in the target + script - see tcl/target/stellaris.cfg. Signed-off-by: Spencer Oliver + +2011-07-28 Spencer Oliver + + * : cfg: update scripts to use new stm32 driver names Signed-off-by: Spencer Oliver + +2011-07-28 Spencer Oliver + + * : flash: update stm32 driver names Use consistent names for the stm32 family flash drivers, eg. stm32x + -> stm32f1x stm32f2xxx -> stm32f2x this makes it easier to add support for newer stm32 families. Signed-off-by: Spencer Oliver + +2011-07-27 Spencer Oliver + + * : doc: add Fujitsu FM3 flash driver info Signed-off-by: Spencer Oliver + +2011-07-21 Jie Zhang + + * : Update doc about Jim since it's not a single .C file and a + single .H file any more Signed-off-by: Spencer Oliver + +2011-07-18 Michael Hunold + + * : CPU name in TMPA900 config file should obviously be TMPA900 (not + TMPA910). Signed-off-by: Spencer Oliver + +2011-07-18 Spencer Oliver + + * : jimtcl: update to support --disable-install-jim Update jimtcl version to commit + 6233a6c5d39928f1bfafa8f41cb1ddf0c5a83de0 This enable to to build + jimtcl as a submodule but not install it. Signed-off-by: Spencer Oliver + +2011-07-09 Luca Bruno + + * : Do not append git info to version string when building from + released tarball When building official releases from tarball, git commit info is not + available in the building environment. Thus, automake should not try + to append the git commit to the version string. Signed-off-by: Luca Bruno Signed-off-by: Spencer + Oliver + +2011-07-12 Spencer Oliver + + * : busblaster: Fix warnings when building against D2XX The default is -Werror, so warnings become errors. Signed-off-by: Spencer Oliver + +2011-07-12 Steve Bennett + + * : ftdi: update for latest libftdi 1.0.4 For libftd2xx1.0.4, which uses a different directory structure than + libftd2xx0.4.16 Without this fix the build fails with version 1.0.4 + of the driver. Note that this does not fix --with-ftd2xx-lib=shared Signed-off-by: Steve Bennett Signed-off-by: + Spencer Oliver + +2011-07-04 Drasko DRASKOVIC + + * : mips_m4k and arm7_9 : Fix soft bkpt endianess for 16-bit + instructions The patch fix comparison of target data on the host by using + target_buffer_get_u16() to transform current_instr to _host_ + endianess before comparison. + +2011-07-04 Spencer Oliver + + * : Revert "cortex_m3: add auto maskisr" This reverts commit ff640f197a9a343b2f3ed10e9174e35282334e8c. Original patch reverted as Author's name was incorrectly set. + +2011-06-29 Spencer Oliver + + * : jimtcl: update to 0.71 based release The actual release is 411e92fea9621630eb350e0c2bb43543e553b84f as we + had a few issues relating to its use within openocd. Signed-off-by: Spencer Oliver + +2011-06-28 Øyvind Harboe + + * : mips4k: fix big-endian hosts and host alignment problems the code was making assumptions about the endianness of the host. + +2011-06-28 Spencer Oliver + + * : cortex_m3: add auto maskisr This patch extends the cortex_m3 maskisr command by a new option + 'auto'. The 'auto' option handles interrupts during stepping in a + way they are processed but don't disturb the program flow during + debugging. Before one had to choose to either enable or disable interrupts. The + former steps into interrupt handlers when they trigger. This + disturbs the flow during debugging, making it hard to follow some + piece of code when interrupts occur often. When interrupts are disabled, the flow isn't disturbed but code + relying on interrupt handlers to be processed will stop working. For + example a delay function counting the number of timer interrupts + will never complete, RTOS task switching will not occur and output + I/O queues of interrupt driven I/O will stall or overflow. Using the 'maskisr' command also typically requires gdb hooks to be + supplied by the user to switch interrupts off during the step and to + enable them again afterward. The new 'auto' option of the 'maskisr' command solves the above + problems. When set, the step command allows pending interrupt + handlers to be executed before the step, then the step is taken with + interrupts disabled and finally interrupts are enabled again. This + way interrupt processing stays in the background without disturbing + the flow of debugging. No gdb hooks are required. The 'auto' option + is the default, since it's believed that handling interrupts in this + way is suitable for most users. The principle used for interrupt handling could probably be used for + other targets too. Signed-off-by: Spencer Oliver + +2011-06-27 Spencer Oliver + + * : build: cleanup jimtcl generated configure.gnu We use configure.gnu to pass options to the jimtcl submodule. Make + sure a distclean removes any generated files Signed-off-by: Spencer Oliver + +2011-06-20 Martin Schmölzer + + * : Add OpenULINK driver files generated by SDCC to .gitignore + +2011-06-20 Martin Schmölzer + + * : Include ULINK driver in src/jtag/drivers/Makefile.am A new variable "nobase_dist_pkglib_DATA" is introduced to install + the OpenULINK firmware image to + $PREFIX/lib/openocd/OpenULINK/ulink_firmware.hex Also, the variable "EXTRA_DIST" is used to include the OpenULINK + firmware source in the OpenOCD source distribution. + +2011-06-20 Martin Schmölzer + + * : Include ULINK driver in configure.in + +2011-06-20 Martin Schmölzer + + * : Include ULINK driver in src/jtag/interfaces.c + +2011-06-20 Martin Schmölzer + + * : Add source code for new ULINK driver + +2011-06-17 Spencer Oliver + + * : build: do not included generated files in distribution We have to use this method as automake seems to ignore nodist_ on + libs. Signed-off-by: Spencer Oliver + +2011-06-17 Spencer Oliver + + * : build: pass correct flags to jimtcl during make distcheck This is only for the case of a make distcheck. During a normal + release build these flags will be created by configure.gnu Signed-off-by: Spencer Oliver + +2011-06-16 Tomek CEDRO + + * : ADAPTER: Fixed transport selection mechanism to support + transports other than jtag (if defined). + +2011-06-15 Dale Lukas Peterson + + * : Added Olimex STM32 {H,P}107.cfg board + +2011-06-12 Øyvind Harboe + + * : HACKING: add tip on how to write comments + +2011-06-10 Rodrigo L. Rosa + + * : doxy more + +2011-06-10 Rodrigo L. Rosa + + * : fix protection behavior + +2011-06-10 Rodrigo L. Rosa + + * : flash speed improved + +2011-06-10 Rodrigo L. Rosa + + * : cleanup flash module command + +2011-06-10 Rodrigo L. Rosa + + * : fix read speed improved by queueing commands + +2011-06-10 Rodrigo L. Rosa + + * : Added minimodule (ftdi) interface + +2011-06-06 Laurent Charpentier + + * : Added configuration file for stm32f2xxx. + +2011-06-03 Freddie Chopin + + * : Fix "unused variable" warnings (errors) detected with GCC 4.7.0 + - leftover changes + +2011-06-02 Rodrigo L. Rosa + + * : crc check on flashed data + +2011-06-03 Freddie Chopin + + * : Fix "unused variable" warnings (errors) detected with GCC 4.7.0 + - dubious fixes + +2011-06-02 Bear + + * : uptech2410 + +2011-05-31 Stefan Mahr + + * : mips: fixup fastdata fixup fastdata + +2011-05-31 Laurent Charpentier + + * : bootstrap: fix argument handling - no argument => run submodule init - "nosubmoudle" => do not run submodule - other values => error message + +2011-05-29 Stefan Mahr + + * : mips: fix swapping if running on big endian host + +2011-05-28 Damjan Marion + + * : Fixed values for Samung NAND chips + +2011-05-23 Damjan Marion + + * : Reorganize NAND flash table - added manufacturer field - name moved to the end for better text alignment + +2011-05-23 Alan Bowman + + * : Report actual current thread + +2011-05-24 Stefan Mahr + + * : add support for spansion flash on mindspeed c300 eval board Signed-off-by: Stefan Mahr + +2011-05-23 Spencer Oliver + + * : Fix build issue under cygwin cygwin does not define sleep, so use our internal win32 version. + caused by commit 9d4aec6bda90ad39a140747ea270c6a09dd26440 Signed-off-by: Spencer Oliver + +2011-05-03 Jie Zhang + + * : Get register value if it's invalid in cache. + +2011-05-17 Rodrigo L. Rosa + + * : flash support (only full erase/write) for 568013 and 568037 + +2011-05-11 Alan Bowman + + * : Correct stacking direction and use of address offset + +2011-05-04 Øyvind Harboe + + * : beagleboard: add support for various icepick versions The beagleboard icepick jtag tap id's vary. + +2011-04-27 Alexandre Pereira da Silva + + * : Add support for the lpc2460 target + +2011-05-03 Jie Zhang + + * : Remove useless MIPS code in avr32_ap7k.c. + +2011-04-28 Øyvind Harboe + + * : ecos: add 64 bit types for sprintf/sscanf + +2011-04-19 Michel Jaouen + + * : gdb_server : 'R' command replied by OK + +2011-04-19 Michel Jaouen + + * : smp : infra for smp minimum support + +2011-04-24 SimonQian + + * : add STM32F2 revY + +2011-04-21 Damjan Marion + + * : buspirate: fix building on some OSes + +2011-04-12 Alexandre Pereira da Silva + + * : Fix non cfi x16 nor flash connected to x8 bus. The ids in the + table should be masked before comparison. + +2011-04-12 Alexandre Pereira da Silva + + * : Make the LPC32xx slc nand driver the default + +2011-04-14 Broadcom Corporation (Evan Hunter) + + * : RTOS Thread awareness support wip - works on Cortex-M3 with ThreadX and FreeRTOS Compared to original patch a few nits were fixed: - remove stricmp usage - unsigned compare fix - printf formatting fixes - fixed a bug with overrunning a memory buffer allocated with + malloc. + +2011-04-13 Luca Ellero + + * : Replace byte-access to memory with faster word-access Freescale iMX53 doesn't seem to like unaligned accesses to his + memory mapped registers. Anyway this patch makes + dump_image/load_image 4X faster for every access through APB. Signed-off-by: Luca Ellero + +2011-04-13 Luca Ellero + + * : Add preliminary support for Freescale iMX53 Signed-off-by: Luca Ellero + +2011-04-12 Michel JAOUEN + + * : cortex_a :apb mem read/write working with mmu_on Conflicts: src/target/cortex_a.c + +2011-04-12 Michel JAOUEN + + * : cortex_a : use dap ref from armv4_5common + +2011-04-09 Jean-Christophe PLAGNIOL-VILLARD + + * : at91: add chip register definition and generic init support for - pio - pmc - rstc - wdt - sdramc - smc Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Cc: Nicolas Ferre + Cc: Patrice Vilchez + +2011-04-09 Jean-Christophe PLAGNIOL-VILLARD + + * : add at91sam9261-ek support Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Cc: Nicolas Ferre + Cc: Patrice Vilchez + +2011-04-09 Jean-Christophe PLAGNIOL-VILLARD + + * : jlink: jlink_debug_buffer use inline function when + _DEBUG_USB_COMMS_ not define Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Cc: Nicolas Ferre + Cc: Patrice Vilchez + +2011-04-03 Ali Lown + + * : Add support for LED to USB Blaster code. + +2011-04-05 Michel JAOUEN + + * : cortex_a : implement jtag console for cortex_a + +2011-04-04 Drasko DRASKOVIC + + * : Corrected waiting on PrAcc in wait_for_pracc_rw(). Added + necessary check that PrAcc is "1" before FASTDATA access. + +2011-04-02 Øyvind Harboe + + * : pandaboard: use new -dbgbase option to workaround broken ROM + table Signed-off-by: Øyvind Harboe + +2011-04-01 Michel JAOUEN + + * : cortex_a: fix gaffe in first implementation of -dbgbase + +2011-04-01 Øyvind Harboe + + * : mips: fix gaffe in previous commit accidentally invoked return jtag_execute_queue() in the middle of a + fn. Hmm.... I would have expected gcc or at least lint to catch + this. Signed-off-by: Øyvind Harboe + +2011-03-31 Phil + + * : Added s19 to (fast_)load_image documentation to match the online + help. + +2011-03-31 Øyvind Harboe + + * : types: write memory now uses const Signed-off-by: Øyvind Harboe + +2011-03-31 Øyvind Harboe + + * : startup: fix bugs in cleanup upon errors during startup Importantly adapter cleanup will now happen upon startup failure. Signed-off-by: Øyvind Harboe + +2011-03-31 Øyvind Harboe + + * : mips: mips_ejtag_get_impcode error propagation added Signed-off-by: Øyvind Harboe + +2011-03-31 Øyvind Harboe + + * : mips: fix error handling for jtag_execute_queue() Signed-off-by: Øyvind Harboe + +2011-03-30 Øyvind Harboe + + * : cortex-a: use -dbgbase option Signed-off-by: Øyvind Harboe + +2011-03-28 Olivier Schonken + + * : at91sam3: Modified cidr comparisson to ignore version bits production processor versions increment, thus the version bits + should be ignored for future proofing. e.g. Engineering sample + version == 0x00, production version 0x01 + +2011-03-29 Alexandre Pereira da Silva + + * : Clarify LPC32XX address cycles message Hi, This is a more descriptive message about LPC32XX error, when the + nand chip needs 5 address cycles. Thanks. + +2011-03-28 Andrew Lyon + + * : bugfix for step
mips_m4k The patch below fixes step
on mips_m4k. Spencer Oliver : The current code is used on all other arch's - is there a underlying + issue with those aswell ? + +2011-03-22 Øyvind Harboe + + * : cortex_a: rename cortex_a8.c/h to cortex_a.c/h Signed-off-by: Øyvind Harboe + +2011-03-21 Øyvind Harboe + + * : cortex a9: merge cortex a9 and a8 code better to keep this in a single file. Signed-off-by: Øyvind Harboe + +2011-03-21 Øyvind Harboe + + * : zy1000: fix bug in ir scan handling set cur_instr to BYPASS as optimisation code will rely on checking + the cached value. Signed-off-by: Øyvind Harboe + +2011-03-20 Øyvind Harboe + + * : dsp563xx_once: fix warning and potential bug I don't think dsp563xx_once_read_register() would ever be called + with len==0, but it would have been broken in that case. Signed-off-by: Øyvind Harboe + +2011-03-03 Mathias K + + * : target: allow targets to override memory alignment Targets can implement read/write_buffer to handle alignment. + +2011-03-17 Uwe Hermann + + * : Fix a bunch of typos. Fix a bunch of typos. Most are in code comments, so nothing should break. UNKOWN_COMMAND + and CMD_UNKOWN are not used elsewhere, so correcting the spelling + should also not break anything. + +2011-03-15 Øyvind Harboe + + * : dsp563xx: fix bug in x buffer handling found by inspection. Signed-off-by: Øyvind Harboe + +2011-03-03 Øyvind Harboe + + * : zy1000: fix JTAG over TCP/IP performance problem only flush write queue just before waiting for more data, rather + than when fetching more data from the buffer. Signed-off-by: Øyvind Harboe + +2011-03-03 Øyvind Harboe + + * : jtag: clean up jtag_sleep, handle short sleeps correctly via + usleep short sleeps are handled via usleep, longer sleeps we round up to + nearest ms. There was a bug in jtag_sleep() in that it would round *down* to + nearest ms, thus making all <1ms sleeps 0. Found by inspection + rather than symptom. Signed-off-by: Øyvind Harboe + +2011-03-10 Aaron Carroll + + * : omap4430: add Blaze config Signed-off-by: Aaron Carroll + +2011-03-07 Jean-Christophe PLAGNIOL-VILLARD + + * : jlink: add Emulator configuration support Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Cc: Nicolas Ferre + Cc: Patrice Vilchez + +2011-03-07 Jean-Christophe PLAGNIOL-VILLARD + + * : jlink: use tap buffer as 2k as said in the datasheet Section 3.3.2 Organization of buffers All buffers are big enough to hold 2 KByte of data. this will double the speed of download Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Cc: Nicolas Ferre + Cc: Patrice Vilchez + +2011-03-03 Mathias K + + * : ft2232: fix log message and change log output to debug + +2011-03-02 Jean-Christophe PLAGNIOL-VILLARD + + * : at91: add at91sam9g10 support Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Cc: Nicolas Ferre + Cc: Patrice Vilchez + +2011-03-02 Jean-Christophe PLAGNIOL-VILLARD + + * : at91: add at91sam9263 support Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Cc: Nicolas Ferre + Cc: Patrice Vilchez + +2011-03-02 Jean-Christophe PLAGNIOL-VILLARD + + * : at91sam9: factorise cpu support all at91sam9 are nearly the same except sram and soc name Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Cc: Nicolas Ferre + Cc: Patrice Vilchez + +2011-02-28 Jean-Christophe PLAGNIOL-VILLARD + + * : jlink: switch commands to subcommands Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + + +2011-02-28 Jean-Christophe PLAGNIOL-VILLARD + + * : jlink: add new PID and VID The default pid of the segger is 0x0101 But when you change the USB + Address it will also pid = ( usb_address > 0x4) ? 0x0101 : (0x101 + usb_address) Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + + +2011-02-24 Øyvind Harboe + + * : log: debug level is between silent and debug output levels It wasn't previously possible to silence the output. Signed-off-by: Øyvind Harboe + +2011-02-24 Mathias K + + * : ft2232: fix possible read buffer overflow This patch fix a possible read buffer overflow in + ft2232_execute_queue. Also the correct read queue size for libftdi + and libftd2xx was added and and tested. In function ft2232_write a + uninitialized value was initialized because we don't know if this + value was set in the ftdi api call. + +2011-02-21 Jean-Christophe PLAGNIOL-VILLARD + + * : add at91rm9200-ek board support tested with jlink sam-ice v5 while loading barebox (gdb) load Loading section .text, size 0x2f190 lma 0x21f00000 + Loading section .rodata, size 0x931c lma 0x21f2f190 Loading section + .data, size 0x29e8 lma 0x21f384ac Loading section .barebox_cmd, size + 0x78c lma 0x21f3ae94 Loading section .barebox_initcalls, size 0x80 + lma 0x21f3b620 Start address 0x21f00000, load size 243360 Transfer + rate: 26 KB/sec, 13520 bytes/write. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Cc: Nicolas Ferre + Cc: Patrice Vilchez + +2011-02-20 Mathias K + + * : dsp563xx: rudimentary gdb support This patch add rudimentary gdb support. The gdb register list order + is corrected. All registers are now 32bit width. Events are send to + signalize gdb the current target status. Resume and step function + was corrected to consider a modified pc register. Read/write memory + now support L memory type, this means a memory with alternating y/x + memory words. The memspace variable, used by gdb, is now observed + before a default memory access is initiated. Dummy functions for + breakpoint and watchpoint are added. + +2011-02-18 SimonQian + + * : fix compile error under MinGW + +2011-02-14 Luca Ellero + + * : arm_adi_v5: add/move apsel member in struct adiv5_dap This patch tries to make some order in "apsel" mess. "dap apsel" + command was quite useless (and broken) by itself. With this patch + we can use it to select between AHB or APB memory access (previous + patch 05ab8bdb813acdcd74afa71d6656c2df816cb230 was somehow broken). - moves member apsel (in struct adiv5_dap) to ap_current - adds apsel member this strange choice is made trying to keep coherence in "dap apsel" + command and to keep compatibility with other code (for example + cortex_a8). Signed-off-by: Luca Ellero + +2011-02-17 Mathias K + + * : dsp563xx_once: Correct wrong return value on jtag communication + errors This patch change the return value on a jtag communication error to + TARGET_UNKNOWN because this function should return the current + target status and not a error code from the underlying api call. + Also the validity of the jtag_status is extended to all static bits + in this value. + +2011-02-15 Bjarne Steinsbo + + * : lpc32xx: Flash driver Based on the lpc3180 driver, but released as a separate driver for + two reasons: 1) I don't have an lpc3180 to test it against, so it might + unintentionally break compatibility. 2) It's using a different OOB layout than lpc3180. Rewritten so that it no longer borrows code from the NXP CDL + library. Instead borrowing code from the u-boot port to lpc32xx, + written by Kevin Wells. Tested on lpc3250 (Hitex LPC3250-Stick). OOB layout is compatible + with LPCLinux. + +2011-02-15 Mathias K + + * : - add bulk memory write function - execute jtag queue at the end of + the memory transfer + +2011-02-13 Mathias K + + * : ft2232: add functions for ft2232 set data bits high/low byte + command reduce duplication. No change in behavior. + +2011-02-12 Luca Ellero + + * : arm_adi_v5: add wrapping transfer functions with selection of ap Signed-off-by: Luca Ellero + +2011-02-12 Luca Ellero + + * : cortex_a9: check if MMU is enabled on APB read/write memory Signed-off-by: Luca Ellero + +2011-02-12 Luca Ellero + + * : cortex_a9: trivial fixes Signed-off-by: Luca Ellero + +2011-02-09 Luca Ellero + + * : cortex_a9: implement read/write memory through APB-AP This patch adds read/write capability to memory addresses not + accessible through AHB-AP (for example "boot ROM code"). To select AHB or APB, a "dap apsel" command must be issued: dap + apsel 0 -> following memory accesses are through AHB dap apsel 1 -> + following memory accesses are through APB NOTE: at the moment APB memory accesses are very slow, compared to AHB accesses. Work has to be done to get it faster (for example LDR/STR instead od LDRB/STRB) Signed-off-by: Luca Ellero + +2011-02-08 Michal Demin + + * : buspirate: Fix command parsing, fix errors to have more sense. Signed-off-by: Michal Demin + +2011-02-07 Luca Ellero + + * : omap4430: Add JRC TAPID for PandaBoard REV EA1 (PEAP platforms) PandaBoard REV EA1 (Panda Early Adopter Program) has a different ID. + This patch add alternate REV EA1 TAP id to configuration file Signed-off-by: Luca Ellero + +2011-02-08 Luca Ellero + + * : cortex_a8/a9: fix some comments Signed-off-by: Luca Ellero + +2011-01-31 Øyvind Harboe + + * : stm32x: add support for STM32F20x ready for wider testing and comments on basic erase + programming. Signed-off-by: Øyvind Harboe + +2011-02-02 Mathias K + + * : 24bit buffer support Hello, this patch add 24bit support to the target buffer functions and + little/big endian functions. Regards, Mathias + +2011-02-02 Aaron Carroll + + * : cortex_m3: allow scripts to override reset If a handler for the reset-assert event it present, skip the usual + reset handling. This is needed, for example, for board-level + resets. Signed-off-by: Aaron Carroll + +2011-01-31 Øyvind Harboe + + * : cfi: use ARM32 machine code on all CPUs but Cortex M3 ARM11 broke with aa61a3b3d8b6acad19050987835ec05f3d298bdb as the + code only checked for arm 7/9. CFI probably needs work for non-ARM targets but perhaps not adding + working area memory to e.g. MIPS will give the default slow CFI + support. Signed-off-by: Øyvind Harboe + +2011-01-24 Aaron Carroll + + * : cortex_a9: add source files for Cortex A9 support. add target and build support for A9 Signed-off-by: Aaron Carroll + +2011-01-24 Aaron Carroll + + * : Add '-coreid' target option to support multiple cores per TAP. ARM Cortex-A9 multi-core chips expose a single TAP/DAP which + connects to both cores. The '-coreid' option selects which core the + target should connect to. Note that at present, OpenOCD can connect to either core, but not + both simulatenously, until ADI contexts can be shared. Signed-off-by: Aaron Carroll + +2011-01-28 Aaron Carroll + + * : openocd.texi: minor fixes in Reset Configuration Signed-off-by: Aaron Carroll + +2011-01-26 Mathias K + + * : - add xds100v2 configuaration file Signed-off-by: Spencer Oliver + +2011-01-26 Mathias K + + * : add basic TI xds100v2 support Signed-off-by: Spencer Oliver + +2011-01-18 Eric Wetzel + + * : stellaris: automatically generate and update device IDs Added a Perl script to contrib that uses the header files in + StellarisWare complete Firmware Development Package provided by + TI/Luminary to generate a new list of device IDs Used Perl script and revision 6734 of TI/Luminary StellarisWare to + update device IDs + +2011-01-13 Santeri Salko + + * : str9xpec: Find flash controller from the chain. Find the flash controller by position since it is before the core, + not after it. This fixes the problem that str9xpec enable_turbo (or any other + str9xpec command) did not work. (See my post in + http://forum.sparkfun.com/viewtopic.php?f=18&t=25542) Signed-off-by: Santeri Salko + +2011-01-13 simon qian + + * : transport: fix LOG_DEBUG gaffe LOG_DEBUG() arguments are only evaluated when DEBUG logging is + enabled, do not use arguments that have side effects like foo++. Signed-off-by: Øyvind Harboe + +2011-01-05 Eric Wetzel + + * : nit: more LOG_* \n fixes Remove extra \n from LOG_DEBUG, LOG_INFO, and LOG_WARNING messages Remove LOG_INFO_N LOG_INFO_N was only used once and had a \n at the + end Change LOG_USER_N calls that end with \n to LOG_USER + +2011-01-08 David Brownell + + * : present CM3 Trace agenda + +2011-01-06 Spencer Oliver + + * : cfi: use safer arch detection Signed-off-by: Spencer Oliver + +2011-01-05 Jonathan Dumaresq + + * : Add the support for the armv7m arch. Signed-off-by: Jonathan Dumaresq + +2011-01-05 Eric Wetzel + + * : nit: do not add \n at end of LOG_ERROR Fixed in many other places, and submitted in response to Øyvind's + invitation. + +2010-12-24 Spencer Oliver + + * : target: change working area free data type We only use the struct working_area member 'free' as a true/false + type so might as well use a bool data type. Signed-off-by: Spencer Oliver + +2011-01-03 Øyvind Harboe + + * : error handling: the error number is not part of the user + interface Do not propagate error number to user. This is for internal + programming purposes only. Error messages to the user is reported as + text via LOG_ERROR(). Signed-off-by: Øyvind Harboe + +2011-01-02 Michael Schwingen + + * : cfi_protect is not implemented on Spansion flashes (many do not + even have protection bits). Demote from error to warning, so that + common board code can use "flash write_image erase unlock" + regardless of the flash type. Signed-off-by: Michael Schwingen + +2011-01-02 Jon Povey + + * : svf: implement sleep for RUNTEST min_time Signed-off-by: Jon Povey min_time was effectively ignored, I needed it to program a Lattice + MachXO which uses a RUNTEST to wait for an erase operation, amongst + other things. With this patch pauses happen and I can program the device with an + SVF generated in LSC ispVM (with "Rev D Standard" checked to + suppress nonstandard LOOP statements) + +2010-12-31 Antonio Borneo + + * : NAND/S3CXXXX: remove private "target" copy Remove "target" form private data, and use common one in struct + nand_block. Signed-off-by: Antonio Borneo + +2010-12-31 Antonio Borneo + + * : NAND/NUC910: remove private "target" copy Remove "target" form private data, and use common one in struct + nand_block. Signed-off-by: Antonio Borneo + +2010-12-31 Antonio Borneo + + * : NAND/MX2: remove private "target" copy Remove "target" form private data, and use common one in struct + nand_block. Signed-off-by: Antonio Borneo + +2010-12-31 Antonio Borneo + + * : NAND/DAVINCI: remove private "target" copy Remove "target" form private data, and use common one in struct + nand_block. Signed-off-by: Antonio Borneo + +2010-12-31 Antonio Borneo + + * : NAND/TCL: prepare for common "target" reference Every NAND driver keeps private copy of "target" structure. Prepare + infostructure to move private "target" copy in common/shared struct + nand_device. Signed-off-by: Antonio Borneo + +2010-12-31 Antonio Borneo + + * : NAND/CORE: Comment use of alive_sleep() Signed-off-by: Antonio Borneo + +2010-12-31 Antonio Borneo + + * : flash/nand: review NAND driver interface From struct nand_flash_controller : - remove unused field register_commands; - remove field controller_ready, exported but never referenced. Remove dead code pointed by controller_ready. Signed-off-by: Antonio Borneo + +2010-12-29 Andrew MacIsaac + + * : Compilation Warnings on OS X 10.5 I received a number of "-Wshadow" related warnings (treated as + errors) while trying to build on OS X Leopard. In addition, there + were two miscellaneous other warnings in the flash drivers. + Attached are two patches which correct these issues and the commit + messages to accompany them. My system has the following configuration (taken from uname -a): Darwin 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT + 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386 === Werror_patch.txt Commit Message === compilation: fixes for + -Wshadow warnings on OS X These changes fix -Wshadow compilation warnings on OS X 10.5.8 Compiled with the following configure command: ../configure --prefix=/usr/local --enable-maintainer-mode + --enable-jlink --enable-ft2232_libftdi === flash_patch.txt Commit Message === compilation: fixes for flash + driver warnings on OS X These changes fix two compilation warnings on OS X 10.5.8: ../../../../src/flash/nor/at91sam3.c:2767: warning: redundant + redeclaration of 'at91sam3_flash' + ../../../../src/flash/nor/at91sam3.c:101: warning: previous + declaration of 'at91sam3_flash' was here and ../../../../src/flash/nor/stmsmi.c:205: warning: format not a string + literal and no format arguments Compiled with the following configure command: ../configure --prefix=/usr/local --enable-maintainer-mode + --enable-jlink --enable-ft2232_libftdi === Andrew + +2010-12-29 Øyvind Harboe + + * : warnings: use more 'const' for char * Signed-off-by: Øyvind Harboe + +2010-12-24 David Brownell + + * : initial SWD transport (SWD infrastructure #2) This piggy backs on JTAG so it's not yet pretty, but that seems + unavoidable so far given today's OpenOCD internals. SWD init and data transfer are unfinished and untested, but that + should cause no regressions, and will be addressed by the time + drivers start using this infrastructure. Checking in whould get the + code working better sooner, and turn up any structural/architectural + issues while they're easier to fix. The debug adapter drivers will provide simple SWD driver structs + with methods that kick in as needed (instead of JTAG). So far just + one adapter driver has been updated (not yet ready to use or + circulate). The biggest issues are probably - fault handling, where the ARM Debug Interface V5 pipelining needs work in both JTAG and SWD modes and - missing rewrite of block I/O code to work on both of our + Cortex-ready transports (Current code is hard-wired to JTAG); + relates also to the pipelining issue. - omitted support to activate/deactivate SWO/SWV trace (this is technically trivial, but configuring what to trace is NOT. Signed-off-by: David Brownell ---- doc/openocd.texi | 17 ++ src/jtag/core.c | 3 src/jtag/interface.h | 4 src/jtag/jtag.h | 2 src/jtag/swd.h | 114 +++++++++++++++++++ src/jtag/tcl.c | 2 src/target/adi_v5_swd.c | 281 + ++++++++++++++++++++++++++++++++++++++++++++++-- + src/target/arm_adi_v5.c | 8 + src/target/arm_adi_v5.h | 3 9 files changed, 425 insertions(+), 9 deletions(-) + +2010-12-23 Spencer Oliver + + * : flash: print flash bank name on flash info cmd The flash bank name is a required element in adding flash banks, + however other than looking at the config file there is no way of + getting the name used in openocd. Signed-off-by: Spencer Oliver + +2010-12-23 Spencer Oliver + + * : stm32: update option bytes for stm32xl family add supoort for xl family boot bank option. The option byte + handling will be cleaned up in a later patch. Signed-off-by: Spencer Oliver + +2010-12-22 Spencer Oliver + + * : stm32: add dual flash bank support This patch adds the initial dual flash bank support for devices such + as the stm32xl family. Signed-off-by: Spencer Oliver + +2010-12-21 Øyvind Harboe + + * : lpc2148: redo to the new target configuration scheme Define a proc which PCBs can easily override. Also demonstrates how to add multiple TAP exepcted-id's using + arguments. Added 0x3f0f0f0f as expected TAP-id. Old LPC2148 silicon I happened + to have on my desk? Signed-off-by: Øyvind Harboe + +2010-12-22 Øyvind Harboe + + * : bootstrap: by default the submodules are initialized use "nosubmodule" to skip setting up submodules. Signed-off-by: Øyvind Harboe + +2010-12-19 Tormod Volden + + * : tcl/interface/flashlink.cfg: Fix broken ST URL + +2010-12-19 Tormod Volden + + * : tcl/board: Fix ST URLs in stm32* eval board configuration files ST recently rewamped (screwed up) their web site and broke all + links. Also match the chip names with those on the web site product + descriptions. + +2010-12-16 Michael Trensch + + * : Add support for Hilscher netX controllers + +2010-12-19 Antonio Borneo + + * : TCL: fix non TCL comments End of line comments fixed with ';' before '#'. Added few + additional 'space' to keep indentation in multi-line comments. Signed-off-by: Antonio Borneo + +2010-12-14 John Devereux + + * : Fix for compilation failure amt_jtagaccel.c Hi, I think there are errors in amt_jtagaccel.c I attach a small patch that I needed to make it compile. + +2010-12-14 Øyvind Harboe + + * : stm32: fix unprotect the unprotect fn in stm32 needs to unprotect more sectors than was + requested aligned to some boundary. Print warning when this happens. Signed-off-by: Øyvind Harboe + +2010-12-10 Spencer Oliver + + * : contrib: add source to the cfi flash loaders Signed-off-by: Spencer Oliver + +2010-12-08 Spencer Oliver + + * : stm32: add STM32E-EVAL external memory config script Signed-off-by: Spencer Oliver + +2010-12-08 Spencer Oliver + + * : cfi: allow optional buffer write support Some flash's do not support buffer writes, so we now check they are + supported before trying to use them. Signed-off-by: Spencer Oliver + +2010-12-08 Spencer Oliver + + * : cfi: prefix string hex output Add hex prefix so we know output is not decimal. Signed-off-by: Spencer Oliver + +2010-12-08 Spencer Oliver + + * : cfi: whitespace and long line cleanup Signed-off-by: Spencer Oliver + +2010-12-04 Freddie Chopin + + * : remove srst_pulls_trst from LPC2xxx target scripts LPC2xxx do not require reset_config srst_pulls_trst. This can cause + various "strange" problems when flashing the chip, because "reset + halt" actually allows the chip to run for some short period of time + and execute some code. Signed-off-by: Freddie Chopin + +2010-12-06 Øyvind Harboe + + * : jtag: getting the JTAG speed can fail If the JTAG speed has not been set, then it has no defined value, + add code to propagate the error. No change to actual behavior as no new failure paths have been + introduced. This is a no-op patch to make subsequent patches + smaller. Signed-off-by: Øyvind Harboe + +2010-12-03 Rolf Meeser + + * : lpc2478 target config: CCLK as (mandatory) parameter + +2010-12-03 Rolf Meeser + + * : Add board config for Embedded Artists LPC2478-32 + +2010-12-03 Rolf Meeser + + * : Fix sector layout for 504-KiB LPC2000 devices + +2010-12-02 Spencer Oliver + + * : luminary: remove unused config cmds. Due to commit e40aee2954d2beabe1d8c530d9ff1e564fb01f48 we now honour + the targets 'reset_config' setting. Previously we ignored the srst + setting for luminary targets. Luminary targets have never supported using srst to reset into debug + mode so remove the option from the target configs files. Signed-off-by: Spencer Oliver + +2010-12-02 Spencer Oliver + + * : config: fix luminary jtag config When this config was updated in commit + e3773e3e3d1f1ee0dbb0b69e8babe8419784d1c1 the old jtag declaration + was not removed. Signed-off-by: Spencer Oliver + +2010-12-01 Øyvind Harboe + + * : profile: use 100Hz as a default sampling frequency it's a lie that is somewhere in the vicinity of the truth. Certainly + 64MHz confuses gprof and produces zero output and no error messages. Signed-off-by: Øyvind Harboe + +2010-12-01 Rolf Meeser + + * : lpc2900.c: Add support for new device LPC2926 + +2010-11-29 Piotr Esden-Tempski + + * : Some cosmetic fixes to the Lisa/L layout support functions. + +2010-11-29 Piotr Esden-Tempski + + * : Updated Floss-JTAG config file to support v0.3 and newer. Also + added noeeprom version of the config file for older versions of + Floss-JTAG. + +2010-11-26 Spencer Oliver + + * : build: correct configure help message As we default to building jimtcl the help text should show that. No + change in functionality or configure args required. Signed-off-by: Spencer Oliver + +2010-11-22 Antonio Borneo + + * : FLASH/NOR: rename from spearsmi to stmsmi STMicroelectronics controller SMI is not SPEAr specific. Rename it + and change name to every symbol in the code. Signed-off-by: Antonio Borneo + +2010-11-18 Antonio Borneo + + * : NOR/SPEARSMI: fix segfault If flash chip is not listed in the table, or if no flash is + connected, pointer must be properly initialized. Signed-off-by: Antonio Borneo + +2010-11-22 Øyvind Harboe + + * : flash: iterating over an address range now handles multiple + banks e.g. flash erase_address now works across an address range that + spans multiple flash chips. Signed-off-by: Øyvind Harboe + +2010-11-19 Spencer Oliver + + * : build: remove AC_CONFIG_AUX_DIR macro This was used during testing and should have been removed. Signed-off-by: Spencer Oliver + +2010-11-19 Spencer Oliver + + * : build: fix subconfigure parameter issue When passing CFLAGS for example through to the jimtcl subconfigure + the quotes were not being preserved. Signed-off-by: Spencer Oliver + +2010-11-19 Spencer Oliver + + * : build: prepend --with-jim-ext=nvp to jimtcl configure This allows us to add options to jimtcl configure. The default + autoconf AC_CONFIG_SUBDIRS does not currently support this. Signed-off-by: Spencer Oliver + +2010-11-12 Spencer Oliver + + * : build: add common.mk Rather than specifying common makefile variables move them all to a + common.mk. Signed-off-by: Spencer Oliver + +2010-11-17 Antonio Borneo + + * : FLASH/NOR: Remove useless file str9xpec.h Signed-off-by: Antonio Borneo + +2010-11-17 Antonio Borneo + + * : FLASH/NOR: Remove useless file str7x.h Signed-off-by: Antonio Borneo + +2010-11-17 Antonio Borneo + + * : FLASH/NOR: Remove useless file stellaris.h Signed-off-by: Antonio Borneo + +2010-11-17 Antonio Borneo + + * : FLASH/NOR: Remove useless file lpc288x.h Signed-off-by: Antonio Borneo + +2010-11-17 Antonio Borneo + + * : FLASH/NOR: Remove useless file avrf.h Signed-off-by: Antonio Borneo + +2010-11-17 Antonio Borneo + + * : FLASH/NOR: Remove useless file at91sam7.h Signed-off-by: Antonio Borneo + +2010-11-17 Antonio Borneo + + * : FLASH/NOR: Remove useless file spearsmi.h Signed-off-by: Antonio Borneo + +2010-11-11 Antonio Borneo + + * : TCL/SPEAr: Added Serial flash in board file Signed-off-by: Antonio Borneo + +2010-11-11 Øyvind Harboe + + * : httpd: retire this server this never panned out and there are enough mistakes in the code that + probably nobody used this. Use the tcl server and implement a standalone http app instead works + fine. Signed-off-by: Øyvind Harboe + +2010-11-13 Øyvind Harboe + + * : gdb: fix occasional crash when flash probe failed Signed-off-by: Øyvind Harboe + +2010-11-09 Øyvind Harboe + + * : cortex_m3: report detected error condition in poll If the CPU crashed at some point, poll will discover this. Previously the poll fn would clear the error and print a warning, + rather than propagating the error. The new behavior is to report the error back up, but still clear the + error. Signed-off-by: Øyvind Harboe + +2010-11-08 Antonio Borneo + + * : TCL scripts: replace "puts" with "echo" Signed-off-by: Antonio Borneo + +2010-11-08 Antonio Borneo + + * : JIM: Add "-n" option to "echo" With the new JIMTCL, "puts" only writes to stdout. To write on + telnet port too, "echo" must be used. This patch gives to "echo" + similar commandline option of "puts". Signed-off-by: Antonio Borneo + +2010-11-08 Øyvind Harboe + + * : stm32: return error when failing to read add missing error handling. Output warning when assuming maximum flash size in the family when + failing to read. Signed-off-by: Øyvind Harboe + +2010-11-08 Øyvind Harboe + + * : stm32: sharpen error handling for timeouts delete lots of crud by handling this all in one spot. Signed-off-by: Øyvind Harboe + +2010-11-04 Antonio Borneo + + * : TCL scripts: add support for ST SPEAr310 Initial support for ST SPEAr310 and for the evaluation board + EVALSPEAr310 Rev. 2.0. Scripts are split in generic for SPEAr3xx + family and specific for SPEAr310. This should easily allow adding + new members of the family. Signed-off-by: Antonio Borneo + +2010-10-29 Marek Vasut + + * : CortexA8: Introduce Freescale i.MX51 variant This patch introduces support for Cortex A8 based Freescale i.MX51 + CPU. This CPU has the Debug Access Port located at a different + address (0x60008000) than TI OMAP3 series of CPUs. i.MX51 configuration file based on OMAP3 configuration file and an + email from Alan Carvalho de Assis . Signed-off-by: Marek Vasut + +2010-10-31 Marek Vasut + + * : ADIv5: Implement function to lookup CoreSight component This patch implements "dap_lookup_cs_component()", which allows to + lookup CS component by it's identification. Signed-off-by: Marek Vasut + +2010-11-04 ddraskovic + + * : arm964e: Add support for ARM946E target. So far most of the people have been using existing ARM966E in the + place of ARM946E, because they have practically the same scan + chains. However, ARM946E has caches, which further complicates JATG handling + via scan-chain. this was preventing single-stepping for ARM946E when + SW breakpoints are used. This patch thus introduces : 1) Correct cache handling on memory write 2) Possibility to flush whole cache and turn it off during debug, or + just to flush affected lines (faster and better) 3) Correct SW breakpoint handling and correct single-stepping 4) Corrects the bug on CP15 read and write, so CP15 values are now + correctly R/W + +2010-10-15 Øyvind Harboe + + * : jimtcl: 0.63 release as a git module. Signed-off-by: Øyvind Harboe + +2010-10-28 Spencer Oliver + + * : src: add loader src description - add comment where to find the various loaders src files. Signed-off-by: Spencer Oliver + +2010-10-28 Øyvind Harboe + + * : imx31pdk: use rclk w/1MHz fallback measure_clk indicates ca. 3-4MHz, so 1MHz should be safe. Added self_test proc used to test that rclk worked. Signed-off-by: Øyvind Harboe + +2010-10-24 Peter Stuge + + * : Make systesetreq typos read sysresetreq instead Signed-off-by: Peter Stuge + +2010-10-22 Michal Demin + + * : buspirate: change handling of communication speed setting + + create serial port open function Signed-off-by: Michal Demin + +2010-10-12 Antonio Borneo + + * : TARGET: review handle_load_image_command() Collect variable definitions. Report syntax error to command + dispatcher. Propagate error when unable to open file. Signed-off-by: Antonio Borneo + +2010-10-10 David Brownell + + * : swj-dp.tcl (SWD infrastructure #1) Provide new helper proc that can set up either an SWD or JTAG DAP + based on the transport which is in use -- mostly for SWJ-DP. Also update some SWJ-DP based chips/targets to use it. The goal is + making SWD-vs-JTAG transparent in most places. SWJ-DP based chips + really need this flexible configuration to cope with debug adapters + that support different transports, without needing new target + configs for each transport or adapter. For JTAG-DP, callers will use "jtag newtap" directly, as today; only + one chip-level transport option exists. For SW-DP (e.g. LPC1[13]xx or EFM32, they'll use "swd newdap" + directly (part of an upcoming SWD transport patch). Again, only one + transport option exists, so hard-wiring is appropriate there. Signed-off-by: David Brownell + +2010-10-05 Spencer Oliver + + * : build: remove warn_unused_result errors Remove any build errors for strtol when building release version of + openocd. Signed-off-by: Spencer Oliver + +2010-10-04 Spencer Oliver + + * : gdbserver: fix gdb_port memory leak Signed-off-by: Spencer Oliver + +2010-09-05 Øyvind Harboe + + * : zy1000: add : port number syntax for tftp filing system Allows using non-standard port number. Default to port 69. Signed-off-by: Øyvind Harboe + +2010-09-27 Øyvind Harboe + + * : server: add support for pipes -p/--pipe is now deprecated. Use '-c "gdb_port pipe;log_output + openocd.log"' instead. Warning logged. Signed-off-by: Øyvind Harboe + +2010-09-27 Øyvind Harboe + + * : server: read/write now goes through connection fn's depending on whether the connection is over a socket or pipe, the + read is done differently. pipes can return -1 when writing 0 bytes, make 0 byte writes a + successful no-op. 0 byte writes falls out naturally of tcl server + code. Signed-off-by: Øyvind Harboe + +2010-09-26 Øyvind Harboe + + * : server: rely on ctrl-c to stop openocd there was special support to support pressing 'x' to quit openocd. + ctrl-c is sufficient. The main server loop is already complicated + enough. Signed-off-by: Øyvind Harboe + +2010-09-27 Luca Bruno + + * : Update ep93xx and at91rm9200 drivers ep93xx and at91rm9200 are conditionally built only on arm and were + not updated to reflect changes in command registration handler. + This patch makes them properly compile again, fixing a build failure + experienced on Debian armel. Signed-off-by: Luca Bruno Signed-off-by: Zachary + T Welch + +2010-09-28 Øyvind Harboe + + * : fileio: refactor struct fileio to be an opaque structure Signed-off-by: Øyvind Harboe + +2010-09-27 Øyvind Harboe + + * : flash: fix error handling memory leaks and missing check on memory allocation. Signed-off-by: Øyvind Harboe + +2010-09-24 Zachary T Welch + + * : Fix omap3_dbginit to write to physical memory. Setting the OMAP3530 DBGEN bit must be done in physical memory, so + update omap3_dbginit callback to use the new 'mww phys' command + syntax. + +2010-09-26 Øyvind Harboe + + * : gdb: fix blank line at top snuck in at some point... Signed-off-by: Øyvind Harboe + +2010-09-20 Øyvind Harboe + + * : flash: fix error handling sensible error must be reported at failure site Signed-off-by: Øyvind Harboe + +2010-09-21 Antonio Borneo + + * : TCL scripts: collect duplicated procedures TCL procedures mrw and mmw, originally in DaVinci target code, are + duplicated in other TCL scripts. Moved in a common helper file, and + added help/usage description. Signed-off-by: Antonio Borneo + +2010-09-20 Øyvind Harboe + + * : helper: fix flaky capture command capture of progress output would get polling results. This will + break in the example below where polling output would override the + tcl return value. capture {sleep 10000; set abc def} Signed-off-by: Øyvind Harboe + +2010-09-18 Øyvind Harboe + + * : logging: turn of stdout/stderr buffering with this buffering disabled fancier logging scripts will be able to + process each line as it is output. Signed-off-by: Øyvind Harboe + +2010-09-20 Øyvind Harboe + + * : jtag: build jtag first because it generates header files Signed-off-by: Øyvind Harboe + +2010-09-07 Øyvind Harboe + + * : zy1000: split out configure option for eCos and JTAG master Signed-off-by: Øyvind Harboe + +2010-09-20 Øyvind Harboe + + * : tcl: remove incomplete unused tcl file Signed-off-by: Øyvind Harboe + +2010-09-19 Mike Dunn + + * : xscale: check that wp length does not exceed address Hi everyone, A while back I sent in a patch that adds support for watchpoint + lengths greater than four on xscale. It's been working well, until + the other day, when it caused an unexpected debug exception. + Looking into this I realized there is a case where it breaks: when + the length arg is greater than the base address. This is a + consequence of the way the hardware works. Don't see a work-around, + so I added code to xscale_add_watchpoint() to check for and disallow + this combination. Some more detail... xscale watchpoint hardware does not support a + length directly. Instead, a mask value can be specified (not to be + confused with the optional mask arg to the wp command, which xscale + does not support). Any bits set in the mask are ignored when the + watchpoint hardware compares the access address to the watchpoint + address. So as long as the length is a power of two, setting the + mask to length-1 effectively specifies the length. Or so I thought, + until I realized that if the length exceeds the base address, *all* + bits of the base address are ignored by the comaparator, and the + watchpoint range effectively becomes 0 .. length. Questions, comments, criticisms gratefully received. Thanks, Mike Signed-off-by: Mike Dunn + +2010-09-18 Karl Kurbjun + + * : AM/DM37x: Unify configuration scripts and add support for TI + Beagleboard xM. + +2010-09-13 Øyvind Harboe + + * : breakpoints: fix error handling do not try to interpret "retval" into a string, just amend a bit + about the context of the already reported error. Signed-off-by: Øyvind Harboe + +2010-09-13 Mike Dunn + + * : xscale: fix sw breakpoints for thumb; set bp immediately Hi everyone, Version 2 of this patch. Code added to breakpoints.c was removed + from previous patch, and item 3 added, per discussion with Øyvind + regarding error reporting. Item 4 added, which I just noticed. I tried to use a software breakpoint in thumb code on the xscale for + the first time recently, and was surprised to find that it didn't + work. The result was this patch, which does four things: 1): fix trivial cut-n-paste error that caused thumb breakpoints to + not work 2): call xscale_set_breakpoint() from + xscale_add_breakpoint() 3): log error on data abort in + xscale_write_memory() 4): fixed incorrect error code returned by + xscale_set_breakpoint() when no breakpoint register is available; + added comment Item 2 not only makes the xscale breakpoint code consistent with + other targets, but also alerts the user immediately if an error + occurs when writing the breakpoint instruction to target memory + (previously, xscale_set_breakpoint() was not called until execution + resumed). Also, calling xscale_breakpoint_set() as part of the call + chain starting with handle_bp_command() and propagating the return + status back up the chain avoids the situation where OpenOCD "thinks" + the breakpoint is set when in reality an error ocurred. Item 3 provides a helpful message for a common reason for failure to + set sw breakpoint. This was thoroughly tested, mindful of the fact that breakpoint + management is somewhat dicey during single-stepping. Comments and criticisms of course gratefully received. Mike Signed-off-by: Mike Dunn Signed-off-by: + Øyvind Harboe + +2010-09-12 Øyvind Harboe + + * : helper: add stacktrace command that returns error stacktrace Ability to access the stacktrace from a script is quite handy. Signed-off-by: Øyvind Harboe + +2010-09-10 Øyvind Harboe + + * : version command: make it scriptable you can now set a variable in a script like set version [version]. Also version takes an optional argument "git" to show git version of + source. If git is not installed during the build, then this will + yield an error that is ignored during the build and "version git" + returns an empty string. Signed-off-by: Øyvind Harboe + +2010-09-10 Øyvind Harboe + + * : cfi: random crash in cfi_probe() fixed for non_cfi cfi chips free() was invoked on rodata. The mystery is why this bug has survived for so long. Signed-off-by: Øyvind Harboe + +2010-09-08 Mike Dunn + + * : xscale: mark xscale registers invalid on debug entry Hi everyone, This simple patch fixes a problem I noticed on the xscale where + incorrect values are sometimes reported by the reg command. The + problem can occur when requesting the value of registers in the + xscale-specific register cache. With a couple of exceptions, none + of the registers in the xscale register cache are automatically + retrieved on debug entry. This is probably fine, as they are + unlikely to be needed on a regular basis during a typical debug + session, and they can be retrieved when explicitly requested by name + using the reg command. The problem is that once this is done, the + register remains marked as valid for the remainder of the OpenOCD + session, and the reg command will henceforth always report the same + value because it is obtained from the cache and is never again + retrieved from the debug handler on the target. The fix is to mark all registers in the xscale register cache as + invalid on debug entry (before the two exceptions are retrieved), + thus forcing retrieval (when requested) from the target across + resumptions in execution, and avoiding the reporting of stale + values. Small addition change by Øyvind: change 'i' to unsigned to fix + compiler warning for xscale_debug_entry() fn. Signed-off-by: Mike Dunn Signed-off-by: + Øyvind Harboe + +2010-09-07 Øyvind Harboe + + * : warning: fix silly -O3 warning Some versions of GCC don't pick up that local variables are set in + all code paths. Signed-off-by: Øyvind Harboe + +2010-08-31 Wookey + + * : Numonyx M29W160ET patch Someone called David Carne popped up on IRC and offered a fix (as + he's not on this list so can;t post here). I am just passing it on. + (thanx David) 10:54 < davidc__> Basically; the Numonyx M29W160ET has an incorrect + CFI PRI block; it describes the erase blocks backwards 10:54 < davidc__> the linked patch has a fixup for that part + [really trivial]: + +2010-08-24 Spencer Oliver + + * : flash: increase stellaris flash loader buffer This speeds up programming for targets with more working area, Signed-off-by: Spencer Oliver + +2010-08-27 David Brownell + + * : bitq: unshadow pause() bitq.c: In function ‘bitq_scan_field’: bitq.c:224: error: + declaration of ‘pause’ shadows a global declaration + /usr/include/unistd.h:429: error: shadowed declaration is here Signed-off-by: David Brownell + +2010-08-17 Øyvind Harboe + + * : mcb1700: Keil MCB1700 w/1768 config script Ca. 93kBytes/s flashing speed @ 10MHz JTAG clock Signed-off-by: Øyvind Harboe + +2010-08-16 David Brownell + + * : two NEWS updates Mention AVR32 AP7000 support. Clarify ARM semihosting update was + for V7M (not ARM9 etc). Signed-off-by: David Brownell + +2010-08-15 Oleksandr Tymoshenko + + * : avr32: basic target script + +2010-08-15 Oleksandr Tymoshenko + + * : avr32: work-in-progress committed so as to ease cooperation and to let it be improved over + time. So far it supports: - halt/resume - registers inspection - memory inspection/modification I'm still getting up to speed with OpenOCD internals and AVR32 so + code is a little bit messy and I'd appreciate any feedback. + +2010-08-13 Catalin Patulea + + * : Fix typo in documentation of usb_blaster_vid_pid command + +2010-08-03 Piotr Esden-Tempski + + * : Added support for the Lisa/L jtag LEDs. + +2010-08-03 Piotr Esden-Tempski + + * : Added support for Lisa/L builtin JTAG interface. + +2010-08-10 Thomas Koeller + + * : jtag: fix handling of 'tap enable' error if a tap could not be _enabled_, the error message was 'failed to + disable tap'. Fixed that. Also, display the failing tap's name. Signed-off-by: Thomas Koeller + +2010-08-10 Thomas Koeller + + * : DM36x: Disable unused SYSCLKs Clear the enable bits for all clocks that are not set explicitly. + This is done to increase robustness by removing pre-existing state. Signed-off-by: Thomas Koeller + +2010-08-12 Fredrik Hederstierna + + * : str9x: faster flash erase of entire chip The patch improves flash erase for STR9x in case of a full bank + erase. Then the chip erase command is used instead which improves + speed significantly. Also I think it might help if e.g. STR912 enters some state where + flash banks are locked, and a chip erase command is the key for + unlocking the flash. + +2010-08-11 Øyvind Harboe + + * : board: added at91cap7a stk w/sdram config scripts The strange thing here with this board is that 16MHz kinda works, + but only 2MHz is really stable. Signed-off-by: Øyvind Harboe + +2010-08-11 Øyvind Harboe + + * : arm: add missing error reporting when an unknown core mode is read from the target, report error. Can + be communication failure. Signed-off-by: Øyvind Harboe + +2010-08-09 Ben Gardiner + + * : cfg: add omapl138 support and da850evm preliminary support This patch adds support for the omapl138 target and preliminary + support for the da850evm. The target cfg file is based on the + icepick routing done by the target/ti_dm6446.cfg file. I have performed limited testing with this setup. I am posting this + patch in the interest of sharing cfg files and in the hopes that the + experts on this list can correct errors I have made or point out + enhancements. The testing I have performed is debugging uboot with gdb where I + also use the following local.cfg and gdbinit files. Debugging + appears to work in so much as 'ni' works. local.cfg: gdb_memory_map disable gdbinit: target remote localhost:3333 set remote + hardware-breakpoint-limit 2 set remote hardware-watchpoint-limit 2 + monitor poll on Comments welcome. Best Regards, Ben Gardiner + +2010-08-08 Øyvind Harboe + + * : target: if polling fails, back off back-off algorithm for polling. Double polling interval up to 5000ms + when it fails. when polling succeeds, reset backoff. This avoids flooding logs(as much) when working with conditions + where the target polling will fail. Signed-off-by: Øyvind Harboe + +2010-08-02 Mike Dunn + + * : xscale documentation: vector table handling Hi everyone. I noticed some incorrect information in the user + manual regarding how the vector table is handled on the xscale, so + for your consideration, here's a short patch that corrects it, and + adds a little more detail I thought might be helpful. The documentation states that OpenOCD does not attempt to + synchronize the vector tables in memory with those stored in the + "mini instruction cache". In fact, on each resume it does copy from + memory to the cache all entries in the high and low tables that were + not previously defined using the 'xscale vector_table' command. (In + src/target/xscale.c, see xscale_update_vectors(), which is invoked + by xscale_resume().) I take advantage of this during Linux boot-up. + The extra detail describes in general terms how I do this. Corrections, comments are of course gratefully received. Thanks, Mike Signed-off-by: Mike Dunn + +2010-08-02 Øyvind Harboe + + * : zy1000: use correct base clock when calculating speed divisor revc uses 60MHz and revb 64MHz, use this in calculations. Signed-off-by: Øyvind Harboe + +2010-08-02 Øyvind Harboe + + * : lpc1768: even if rclk "works", it isn't necessarily the correct + clk rclk = 4MHz oon lpc1768, the correct JTAG clk is 666MHz(4MHz/6). Signed-off-by: Øyvind Harboe + +2010-08-02 Øyvind Harboe + + * : jtag: measure_clk debug proc It can be useful to get an approximate measurement of rtck frequency + for debugging purposes. Signed-off-by: Øyvind Harboe + +2010-08-01 Øyvind Harboe + + * : util: ms command to calculate length of operations This can be used to calculate approximate RTCK frequency for + instance. Signed-off-by: Øyvind Harboe + +2010-08-01 Peter Stuge + + * : Remove srst_pulls_trst from LPC2148 target srst_pulls_trst is only true on some (broken) LPC2148 boards, a fact + which is already documented in doc/openocd.texi, so it shouldn't be + set unconditionally in the target tcl. This patch was needed to reflash when an Abort exception occured + very early after reset, before OpenOCD tried to halt the CPU. + +2010-07-30 Øyvind Harboe + + * : lpc7168: make flash available upon reset init set user mode to avoid ROM being mapped at address 0 rather than + flash. Signed-off-by: Øyvind Harboe + +2010-07-10 Michal Demin + + * : Buspirate: fix shadow + +2010-07-19 Spencer Oliver + + * : flash: remove algorithm exit_point address for supported targets For the above targets the exit_point is optional when used with + run_algorithm, so remove it. This makes updating the algorithm less error prone. Signed-off-by: Spencer Oliver + +2010-07-19 Spencer Oliver + + * : armv7m: exit_point optional for armv7m_run_algorithm As the armv7m uses instruction breakpoints for algorithms we do not + really need to check the pc on exit. This now matches the behaviour of the arm4_5 codebase. Signed-off-by: Spencer Oliver + +2010-07-20 Øyvind Harboe + + * : arm11 error propagation fixes Signed-off-by: Øyvind Harboe + +2010-07-19 Øyvind Harboe + + * : arm_dpm: error propagation fixes found by inspection Signed-off-by: Øyvind Harboe + +2010-07-19 Øyvind Harboe + + * : arm: error propagation of arm_jtag_set_instr Signed-off-by: Øyvind Harboe + +2010-07-19 Øyvind Harboe + + * : arm_adi_v5: mem_ap_write error propagation Signed-off-by: Øyvind Harboe + +2010-07-19 Øyvind Harboe + + * : mem_ap_read_u32 error propagation Signed-off-by: Øyvind Harboe + +2010-07-19 Øyvind Harboe + + * : debug: debug entry error propagation Signed-off-by: Øyvind Harboe + +2010-07-19 Øyvind Harboe + + * : arm: add error propagation for enable/disable mmu caches Signed-off-by: Øyvind Harboe + +2010-07-19 David Brownell + + * : more careful luminary init Set up more of the Luminary-specific signals, and stop cloning a few + of the JTAG defaults. More comments too. Still leaves the "dap info 0" bugs unresolved (presumably coupled to + this particular adapter family) where TPIU, ITM, DWT, and other + debug modules wrongly display as extra NVICs. Signed-off-by: David Brownell + +2010-07-19 Spencer Oliver + + * : flash: add nuc910 nand driver This adds a nand driver support for the nuc910 target. Note that + ECC is not currently supported by this driver, although it is + supported by the peripheral. Signed-off-by: Spencer Oliver + +2010-07-16 Spencer Oliver + + * : cfg: update rsc-w910 script - Only enable the FMI (NAND) and DMA clocks. - Select NAND interface on the MFSEL. Signed-off-by: Spencer Oliver + +2010-07-18 Øyvind Harboe + + * : cortex a8: lots of error propagation fixes found by code inspection Signed-off-by: Øyvind Harboe + +2010-07-18 Øyvind Harboe + + * : cortex a8: add missing error handling for + cortex_a8_dap_write/read_coreregister_u32() Signed-off-by: Øyvind Harboe + +2010-07-18 Øyvind Harboe + + * : cortex a8: add missing error handling for + mem_ap_atomic_write_u32() Signed-off-by: Øyvind Harboe + +2010-07-18 David Brownell + + * : comments for Luminary ICDI layout Provide $defines for more of the signals involved in the Luminary + ICDI hardware, and comment some of what's going on. Signed-off-by: David Brownell + +2010-07-17 Øyvind Harboe + + * : debug-feature: jtagtcpip, improve jtag performance postpone callbacks until jtag execute queue time. Signed-off-by: Øyvind Harboe + +2010-07-16 David Brownell + + * : ARM ADI-V5: cleanup CID/PID addressing Use addition for offsetting, not masking. Shorten some lines. Make + "component_start" print-only (unused otherwise; don't save). Still doesn't resolve the issue where multiple components are + wrongly displaying as NVICs on some Cortex-M3 parts because many + PIDs appear to be zeroes ... maybe adapter related?? Signed-off-by: David Brownell + +2010-07-16 Øyvind Harboe + + * : fix warnings Signed-off-by: Øyvind Harboe + +2010-07-16 Øyvind Harboe + + * : debug feature: jtagtcpip, improve performance waiting for ZY1000 fifo to idle is now queued as an asynchronous + command. This radically improves performance when waitIdle() is + interspersed with writes as no readback is required over TCP/IP. Signed-off-by: Øyvind Harboe + +2010-07-13 David Brownell + + * : ARM ADI-V5: PIDs and CIDs are 8 bits Mask the upper bits after 32-bit reads. Alsoo revert the ugly changes to use PRIx32; just cast to unsized + integers when printing (two chars not eight). Signed-off-by: David Brownell + +2010-07-12 Spencer Oliver + + * : jtag: fix shadow issues in adapter_init Use global jtag_only rather than local static. Signed-off-by: Spencer Oliver + +2010-07-12 Spencer Oliver + + * : docs: fix transport typo Signed-off-by: Spencer Oliver + +2010-07-09 David Brownell + + * : transport selection tweaks * Bugfix and simplify legacy jtag-only defaulting * Make "dummy" declare its jtag-only nature * likewise update ft2232 * warn if selection is _required_ (multi-transport adapters), fixes the "only ft2232 works" bug for at least dummy, with other + drivers going the "legacy" path (submit patches). Signed-off-by: David Brownell + +2010-07-07 Øyvind Harboe + + * : transport: fix segfault in transport select String compare against addresses in range 0 or so due to not + checking if there was an active session first. Signed-off-by: Øyvind Harboe + +2010-07-05 sb-sf + + * : gdbserver: incorrect memory map for multiple targets (bug #24) The gdb server incorrectly reports the memory map if we have + multiple targets with multiple flash banks. Signed-off-by: Spencer Oliver + +2010-07-02 David Brownell + + * : Fix minor openocd.texi bug ::X Signed-off-by: David Brownell + + +2010-07-02 Spencer Oliver + + * : ft2232: revert ft2232_read_scan changes Revert change made in commit + dd88b461da1cb8642200dd5c96fb1ff384ca9f7b. Caused segfaults when + using ftdi driver under win32. Signed-off-by: Spencer Oliver + +2010-06-17 Marc Pignat + + * : ft2232: simplify ft2232_read_scan + +2010-06-25 Olaf Lüke + + * : at91sam3s* support Signed-off-by: Øyvind Harboe + +2010-06-23 Øyvind Harboe + + * : arm11: fix gaffe in no-ack transfers The code did not transfer the last word in no-ack transfers. The strange thing is that this did not lead to any observable + errors. This gaffe was introduced in commit 1f5883ea56cb058221f Signed-off-by: Øyvind Harboe + +2010-06-22 Øyvind Harboe + + * : am3517 evm: use physical write to memory while target is running Signed-off-by: Øyvind Harboe + +2010-06-22 Øyvind Harboe + + * : target: $_TARGET mdw now has a phys option just like the mdw command Signed-off-by: Øyvind Harboe + +2010-06-21 Edgar Grimberg + + * : xsvf: Fix shadow issues on Mac wait is declared in /usr/include/sys/wait.h Signed-off-by: Edgar Grimberg + +2010-06-21 Edgar Grimberg + + * : flash: fix shadow issues on Mac Wait is declared in /usr/include/sys/wait.h Signed-off-by: Edgar Grimberg + +2010-06-21 Øyvind Harboe + + * : gitignore: start list of emacs temp files to ignore Signed-off-by: Øyvind Harboe + +2010-06-21 Øyvind Harboe + + * : cortex a8: add error propagation for poll/resume Signed-off-by: Øyvind Harboe + +2010-06-21 Øyvind Harboe + + * : cortex a8: add error propagation for + mem_ap_read/write_atomic_u32 Error propagation avoids e.g. infinite loops waiting for target to + halt, etc. Signed-off-by: Øyvind Harboe + +2010-06-20 Antonio Borneo + + * : nand/mx2: review scope of symbols Add "static" qualifier to private variable. Signed-off-by: Antonio Borneo + +2010-06-20 Antonio Borneo + + * : openocd.c: review scope of symbols Add "static" qualifier to private data. Signed-off-by: Antonio Borneo + +2010-06-20 Antonio Borneo + + * : target/avrt: review unused symbols Remove unused functions: - mcu_write_dr_u16 - mcu_write_dr_u8 - mcu_write_ir_u16 - mcu_write_ir_u32 Signed-off-by: Antonio Borneo + +2010-06-20 Antonio Borneo + + * : target/feroceon: review scope of symbols Add "static" qualifier to private functions. Signed-off-by: Antonio Borneo + +2010-06-19 Antonio Borneo + + * : helper/jim-eventloop.h: review unused definitions Remove unused typedef and define Signed-off-by: Antonio Borneo + +2010-06-19 Antonio Borneo + + * : helper/jim-eventloop: review scope of symbols Add "static" qualifier to private functions. Remove private + prototypes from include file. Remove empty definition of + JIM_STATIC. Signed-off-by: Antonio Borneo + +2010-06-21 Øyvind Harboe + + * : jtag: do not use jtag_get_error() normal code should not call jtag_get_error(), but rather check the + return code from jtag_execute_queue(). Signed-off-by: Øyvind Harboe + +2010-06-21 Øyvind Harboe + + * : cortex a8: add missing error handling cortex examine was missing error handling. Signed-off-by: Øyvind Harboe + +2010-06-18 Øyvind Harboe + + * : cortex a8: fix segfault for unexamined targets print error message instead of segfaulting for unexamined targets. Signed-off-by: Øyvind Harboe + +2010-06-18 Antonio Borneo + + * : target/dsp563xx: review scope of symbols Add "static" qualifier to private functions. Remove private + prototypes from include file. Signed-off-by: Antonio Borneo + +2010-06-18 Andreas Fritiofson + + * : don't add confusing source info to Jim When an interactive command fails, the Jim stack trace prints + references to the line in "command.c" where the interpreter was + invoked. Since that location has no relation to the actual command + that failed, the information serves only to add confusion. By not adding the useless source info to Jim the noise can be + reduced, while still printing a useful trace for nested commands. Signed-off-by: Andreas Fritiofson + Signed-off-by: Øyvind Harboe + +2010-06-18 Antonio Borneo + + * : helper/jim: review scope of symbols Add "static" qualifier to private functions. Function Jim_InterpolateTokens() is private, but has not been + changed to "static". This function is called only once, so compiler + inlines it. After inline, there is a warning for variable + uninitialized. Signed-off-by: Antonio Borneo + Signed-off-by: Øyvind Harboe + +2010-06-17 Freddie Chopin + + * : mingw32: -Wshadow fixes in rlink.c (error: declaration of ‘byte’ shadows a global declaration; + + /usr/local/lib/gcc/i686-w64-mingw32/4.4.2/../../../../i686-w64-mingw32/include/rpcndr.h:50: error: shadowed declaration is here)Signed-off-by: Freddie Chopin + +2010-06-17 Freddie Chopin + + * : mingw32: -Wshadow fixes in jim.c (error: declaration of ‘boolean’ shadows a global + declaration; + + /usr/local/lib/gcc/i686-w64-mingw32/4.4.2/../../../../i686-w64-mingw32/include/rpcndr.h:52: error: shadowed declaration is here)Signed-off-by: Freddie Chopin + +2010-06-17 Antonio Borneo + + * : vsllink: fix -Wshadow warning Signed-off-by: Antonio Borneo + +2010-06-17 Øyvind Harboe + + * : zy1000: fix arm11 optimisation copy & paste error + added FIFO throttling to work around lockup bug + in FPGA. The arm11 optimisation was introduced post v0.4.0, so this is not a + regression compared to previous release. Signed-off-by: Øyvind Harboe + +2010-06-14 Antonio Borneo + + * : nor/at91sam3: replace helper membuf Helper ./src/helper/membuf.c is only used in at91sam3.c 1) Replace membuf with LOG_* 2) The original code in sam3_GetDetails() invalidates all the buffered output of sam3_GetInfo(). The new code skips sam3_GetInfo() if its output should not be printed. Signed-off-by: Antonio Borneo + +2010-06-16 Øyvind Harboe + + * : gdb: -Wshadow warning fixes Signed-off-by: Øyvind Harboe + +2010-06-16 Øyvind Harboe + + * : xsvf: -Wshadow warning fixes I think this fixed an error message where the error message would + show the *previous* uc code rather than the current unsupported uc + code. Signed-off-by: Øyvind Harboe + +2010-06-16 Øyvind Harboe + + * : mflash: -Wshadow warning fix Signed-off-by: Øyvind Harboe + +2010-06-16 Øyvind Harboe + + * : nand: when verify failed, it didn't return an error when the verify failed, it didn't return an error, which breaks e.g. + tcl scripts that rely on this for exceptions to work. Found by -Wshadow Signed-off-by: Øyvind Harboe + +2010-06-16 Øyvind Harboe + + * : str9xpec: -Wshadow warning fixes Signed-off-by: Øyvind Harboe + +2010-06-16 Øyvind Harboe + + * : oops... backup file snuck in, remove it. Signed-off-by: Øyvind Harboe + +2010-06-16 Øyvind Harboe + + * : stm32x: -Wshadow warning fixes Signed-off-by: Øyvind Harboe + +2010-06-15 Øyvind Harboe + + * : lpc2900: -Wshadow warning fixes Signed-off-by: Øyvind Harboe + +2010-06-15 Øyvind Harboe + + * : ecos flash: -Wshadow warning fixes Signed-off-by: Øyvind Harboe + +2010-06-15 Øyvind Harboe + + * : flash: -Wshadow warning fix Signed-off-by: Øyvind Harboe + +2010-06-15 Øyvind Harboe + + * : mips32_pracc: -Wshadow warning fixes Signed-off-by: Øyvind Harboe + +2010-06-15 Øyvind Harboe + + * : mips32: -Wshadow warning fixes Signed-off-by: Øyvind Harboe + +2010-06-15 Øyvind Harboe + + * : arm11_dbgtap: -Wshadow warning fixes Signed-off-by: Øyvind Harboe + +2010-06-15 Øyvind Harboe + + * : arm920t: -Wshadow warning fixes Signed-off-by: Øyvind Harboe + +2010-06-15 Øyvind Harboe + + * : adi_v5_jtag: -Wshadow warning fixes Signed-off-by: Øyvind Harboe + +2010-06-15 Øyvind Harboe + + * : arm_simulator: -Wshadow warning fixes Signed-off-by: Øyvind Harboe + +2010-06-15 Øyvind Harboe + + * : target: -Wshdaow warning fix Signed-off-by: Øyvind Harboe + +2010-06-15 Øyvind Harboe + + * : zy1000: -Wshadow warning fix Signed-off-by: Øyvind Harboe + +2010-06-15 Øyvind Harboe + + * : jim: -Wshadow warning fix Signed-off-by: Øyvind Harboe + +2010-06-14 Øyvind Harboe + + * : jim: -Wshadow fixes this batch of fixes should be pretty straightforward rename of + 'index' and an 'i' local variable shadowing. 'index' conflicts with a global name. Signed-off-by: Øyvind Harboe + +2010-06-14 michal smulski + + * : arm1136 scripts Here is a patch to fix a startup in C100 (arm1136). Basically make + sure that UART is configured before using it. Michal Signed-off-by: Øyvind Harboe + +2010-06-14 Øyvind Harboe + + * : cfi: add LOG_ERROR() in case of unsupported intel erase + algorithm found by code inspection. There are many other places in CFI where + LOG_ERROR() should be called similarly... Signed-off-by: Øyvind Harboe + +2010-06-14 Øyvind Harboe + + * : helper: fix -Wshadow warning in number parsing use obtuse local variable names in macros to avoid interfering with + global name space Signed-off-by: Øyvind Harboe + +2010-06-14 Øyvind Harboe + + * : target: fix retval gaffe in mwX commands failure to write to memory was not propagated. This is an interesting case of broken error handling: with + exceptions we wouldn't have had this at all, and I also wonder if + there is a GCC option to warn about these kinds of potential bugs. Signed-off-by: Øyvind Harboe + +2010-06-12 Antonio Borneo + + * : TARGET: removed unsed parameter Parameter "type" of function armv4_5_mmu_translate_va() is now not + used. Remove the parameter and the "enum" listing its values. Signed-off-by: Antonio Borneo + +2010-06-12 Antonio Borneo + + * : TARGET/ARM920T: fix return value Function arm920t_write_memory() default return value should be + ERROR_OK. All cases of local errors are handled immediately and not + further propagated. Signed-off-by: Antonio Borneo + +2010-06-11 Øyvind Harboe + + * : flash: add error handling to get_flash_by_addr/name autoprobing can fail and this error has to be reported up the call + stack. Signed-off-by: Øyvind Harboe + +2010-06-10 Øyvind Harboe + + * : cfi: fix error propagation any read/write operation to memory can fail. block write algorithm error propagation was broken in that it would + continue after an error was reported writing data to ram or the + algorithm failing. Signed-off-by: Øyvind Harboe + +2010-06-09 Øyvind Harboe + + * : flash: add error message if image is too big for flash replaced assert() w/error message if the image is too big. Signed-off-by: Øyvind Harboe + +2010-06-07 Øyvind Harboe + + * : zy1000: fix optimisation gaffe DCC optimisation was broken on targets w/multiple TAP's. Signed-off-by: Øyvind Harboe + +2010-05-05 Øyvind Harboe + + * : cfi: fix GDB keep alive bug Long running CFI writes could cause GDB timeout. Signed-off-by: Øyvind Harboe + +2010-06-07 Øyvind Harboe + + * : gdb-server: fix error reporting bugs GDB and OpenOCD has two different error number spaces and no mapping + exists between them. If a specific error number is to be reported to GDB then this has to + be done at the calling site, rather than as a generic routine that + tries to map "retval" to GDB error number speak. Signed-off-by: Øyvind Harboe + +2010-06-01 gcembed + + * : stm32 : change returned value of mass_erase function Hello, "stm32x mass_erase" return ERROR_OK even if something goes + wrong. Here is a summary of changes : * in stm32x_mass_erase : return ERROR_FLASH_OPERATION_FAILED when + error detected in FLASH_SR register; * in COMMAND_HANDLER(stm32x_handle_mass_erase_command) : return the + returned value of stm32x_mass_erase(). I don't know if there is reason to always return ERROR_OK ? Gaëtan + +2010-05-31 Jon Povey + + * : etm: print something when trace buffer empty ETM analyze produced no output when the trace buffer was empty. + This patch provides users with a clue. Signed-off-by: Jon Povey Signed-off-by: + Øyvind Harboe + +2010-05-24 Spencer Oliver + + * : flash: virtual driver update for get_flash_bank_by_name_noprobe Make sure we do not probe a flash when getting info. Signed-off-by: Spencer Oliver + +2010-05-24 Spencer Oliver + + * : cfg: add pic32 virtual banks make use of the new virtual bank flash driver. Signed-off-by: Spencer Oliver + +2010-05-26 Antonio Borneo + + * : NOR/CFI: fix memory leak; check malloc return value Every time command "flash probe #" is executed, memory structures + are re-allocated without preventive free() of former areas, causing + memory leak. Also, memory allocation does not check return value, + determining segmentation fault in case of out of memory. Signed-off-by: Antonio Borneo + Signed-off-by: Spencer Oliver + +2010-05-21 Freddie Chopin + + * : All LPC2xxx chips are little endian and that cannot be changed - + update config scripts Signed-off-by: Spencer Oliver + +2010-05-21 Freddie Chopin + + * : Update "flash bank" helper comments for LPC2xxx chips Signed-off-by: Spencer Oliver + +2010-05-21 Øyvind Harboe + + * : at91sam9260: use RCLK It might be possible to get this target going without RCLK, but it + would require more careful analysis and usage of the reset events. Enable fast memory accesses. Tested on an at91sam9260 custom board w/external DRAM and flash. Signed-off-by: Øyvind Harboe + +2010-05-21 Spencer Oliver + + * : arm_adi_v5: correct ahbap_debugport_init mem-ap id (bug #23) We request a id register read at the end of ahbap_debugport_init but + we never actually run the queue. In some cases this causes a + segfault. Signed-off-by: Spencer Oliver + +2010-05-20 gcembed + + * : nand : Add Freescale iMX27 nand flash controller support This patch add support of iMX27 nand flash controller. This is based + on driver for imx31 nand flash controller. OOB functionality is not + fully working. As in mx31 controller, mx2 NFC has a bug that swap + two bytes between SPARE and MAIN buffer. I used this driver for + several months and no problems appear. + +2010-05-18 Gary Carlson + + * : target: slow targets could cause GDB to time out This second half of the patch is proposed to clean up some GDB keep + alive issues on arm7_9 targets that start up with very slow clocks. + If an attempt is made to write to key registers on the processor + with a slow jtag speed, GDB timeout warnings appear on the console + (at least mine) when "reset halt" or "reset init" commands are + issued from the gdb client: *** BEFORE PATCH *** (gdb) monitor reset init fast memory access is disabled 2 kHz + keep_alive() was not invoked in the 1000ms timelimit. GDB alive + packet not sent! (1026). Workaround: increase "set remotetimeout" in + GDB JTAG tap: at91sam9g20.cpu tap/device found: 0x0792603f (mfg: + 0x01f, part: 0x7926, ver: 0x0) target state: halted target halted in + ARM state due to breakpoint, current mode: Supervisor cpsr: + 0x000000d3 pc: 0x00000000 MMU: disabled, D-Cache: disabled, I-Cache: + disabled keep_alive() was not invoked in the 1000ms timelimit. GDB + alive packet not sent! (1027). Workaround: increase "set + remotetimeout" in GDB keep_alive() was not invoked in the 1000ms + timelimit. GDB alive packet not sent! (1006). Workaround: increase + "set remotetimeout" in GDB keep_alive() was not invoked in the + 1000ms timelimit. GDB alive packet not sent! (1006). Workaround: + increase "set remotetimeout" in GDB keep_alive() was not invoked in + the 1000ms timelimit. GDB alive packet not sent! (1006). Workaround: + increase "set remotetimeout" in GDB keep_alive() was not invoked in + the 1000ms timelimit. GDB alive packet not sent! (1004). Workaround: + increase "set remotetimeout" in GDB RCLK - adaptive dcc downloads + are enabled fast memory access is enabled NAND flash device 'NAND + 256MiB 3,3V 8-bit' found (gdb) I added additional keep alive steps in areas that troubleshooting + revealed were causing problems. I only did this however for + non-fast write memory accesses. I don't think most people would be + using fast memory accesses to write to memory when the jtag and + system clocks are slow anyway. If you disagree with my feeling, think there is a more elegant way + to handle the problem, or think the patch will cause other + unforeseen problems with other targets, let me know. As you can see + below, the patch does eliminate the problem on my development + station and I suspect that it will benefit others. *** AFTER PATCH *** (gdb) monitor reset init fast memory access is disabled 2 kHz JTAG + tap: at91sam9g20.cpu tap/device found: 0x0792603f (mfg: 0x01f, part: + 0x7926, ver: 0x0) target state: halted target halted in ARM state + due to breakpoint, current mode: Supervisor cpsr: 0x000000d3 pc: + 0x00000000 MMU: disabled, D-Cache: disabled, I-Cache: disabled RCLK + - adaptive dcc downloads are enabled fast memory access is enabled + NAND flash device 'NAND 256MiB 3,3V 8-bit' found (gdb) Gary Carlson Gary Carlson, MSEE Principal Engineer Carlson-Minot Inc. + +2010-05-18 Øyvind Harboe + + * : zy1000: fix false positive warning about unitialized local + variable Signed-off-by: Øyvind Harboe + +2010-05-17 Jon Povey + + * : NAND/davinci: Fix segfault for hwecc4_infix reads Page reads using hwecc4_infix layout segfaulted for check_bad_blocks + because the read assumed a valid data buffer, which check_bad_blocks + does not use (it only passes a 6 byte buffer for the start of OOB). This version copes with undersized or missing data or oob buffers + and uses random read commands within the page to skip unwanted areas + of data/OOB for speed. NOTE: Running check_bad_blocks with this layout will be reading + infix OOB locations, not manufacturer bad block markers. This means + that if you check blocks written in infix layout they will appear + good, but manufacturer- marked bad blocks may also appear good. If + you want to scan for manufactuer-marked bad blocks, you need to + enable raw_access before running check_bad_blocks, or use the + non-infix layout. Signed-off-by: Jon Povey CC: David + Brownell + +2010-05-17 Spencer Oliver + + * : gdbserver: gdb cmds returning failure on success The gdb_memory_map cmd for example fell through and returned + ERROR_COMMAND_SYNTAX_ERROR on success - behaviour is now as + expected. Signed-off-by: Spencer Oliver + +2010-05-11 Antonio Borneo + + * : NOR/CFI: minor code cleanup Remove few LOG_DEBUG() messages, together with code and variables + required to build such messages. Signed-off-by: Antonio Borneo + +2010-05-11 Antonio Borneo + + * : NOR: add read() callback to struct flash_driver Final target is to force bus_width size during CFI flash read. In + this first step I need to replace default flash read with flash + specific implementation. This patch introduces: - flash_driver_read() layer; - default_flash_read(), backward compatible; - read() callback in struct flash_driver; - proper initialization in every flash_driver instance. Signed-off-by: Antonio Borneo + +2010-05-07 Antonio Borneo + + * : NOR: fix comment for Doxygen Either bus_width and chip_width are in bytes. Signed-off-by: Antonio Borneo + +2010-05-07 Antonio Borneo + + * : NOR/CFI: use bus_width for memory access in cfi_write() During cfi_write(), head and tail of destination area could be not + aligned to bus_width. Since write operation must be at bus_width + size, source buffer size is extended and buffer padded with current + values read from flash. Force using bus_width to read current value from flash. Do not use + cfi_add_byte() anymore, to allow removing this function later on. Signed-off-by: Antonio Borneo + +2010-04-20 Antonio Borneo + + * : NOR/CFI: identify memory accesses not using "bus_width". Since NOR flash devices does not handle "byte enable lanes", each + read/write access involves the whole "chip_width". When multiple + devices are in parallel, usually all chips are enabled during each + access. All such cases are compatible with flash accesses at + "bus_width" size. Access at "bus_width" size is mandatory for write access to avoid + transferring of garbage values to flash. During read access the + flash controller should take care, and discard unneeded bytes. + Anyway, it is good practice to use "bus_width" size also for read. Every memory access that does not respect "bus_width" size is marked + with a "FIXME" comment. Signed-off-by: Antonio Borneo + +2010-04-16 Antonio Borneo + + * : NOR/CFI: check "flash bank" command arguments Arguments chip_width and bus_width of command "flash bank" are not + fully checked. While bus_width is later on redundantly checked in + several other parts (e.g. in cfi_command_val()) and generates + run-time error, chip_width is never checked, nor related to actual + bus_width value. Added check to avoid: - (chip_width == 0), that would mean no memory chip at all, avoiding also division by zero e.g. in cfi_get_u8(); - (bus_width == 0), that would mean no bus at all; - unsupported cases of chip_width or bus_width value not power of 2; - unsupported case of chip width wider than bus. Signed-off-by: Antonio Borneo + +2010-05-14 Jun Ma + + * : missing pointer's declaration when enable macro + -D_DEBUG_GDB_IO_. reproducable when "./configure --enable-maintainer-mode + CFLAGS=-D_DEBUG_GDB_IO_" Signed-off-by: Jun Ma Signed-off-by: Øyvind + Harboe + +2010-05-13 Jon Povey + + * : NAND: fix off-by-one error in erase command argument range The last_block argument to nand_erase() is checked against + nand->num_blocks, but the highest valid block number is (total - 1), + the test for invalid should be ">=" rather than ">". Signed-off-by: Jon Povey Signed-off-by: + Øyvind Harboe + +2010-05-12 Spencer Oliver + + * : flash: require unique flash bank name Make sure the flash bank name is unique Signed-off-by: Spencer Oliver + +2010-05-12 Øyvind Harboe + + * : zy1000.cfg: gdb connect will fail first time without gdb-attach gdb-attach does a reset init to make sure that the CFI probe will + succeed upon first gdb connect. Signed-off-by: Øyvind Harboe + +2010-05-10 Karl Kurbjun + + * : Fujitsu MBM29SL800TE flash support Hi, This is my first post to the list. First, I would like to thank + everyone for their work on OpenOCD, it is a great tool to work with. + I have been using it to debug code on hardware for the Rockbox + project (www.rockbox.org). The target that I primarily work with has a Spansion/Fujitsu NOR + flash (MBM29SL800TE). I attached a patch that adds support for this + flash. I hope it can be included in the main repository. If there + is something that needs to be changed with the patch before + inclusion please let me know. -Karl Kurbjun + +2010-05-11 Marc Pignat + + * : Documentation : arm920t implements armv4 There is a small typo in the cpu list, arm920t is armv4. + +2010-05-10 Spencer Oliver + + * : armv7m: 20 second timeout/megabyte for CRC check There was a fixed 20 second timeout which is too little for large, + slow timeout checks. Signed-off-by: Spencer Oliver + +2010-05-07 Spencer Oliver + + * : cfg: add stm32eval board configs Increase working area for stm3210e_eval.cfg. Add new configs for + the following boards: STM321000B-EVAL, STM32100C-EVAL, + STM32100B-EVAL Signed-off-by: Spencer Oliver + +2010-05-05 Øyvind Harboe + + * : flash: stop caching protection state There are a million reasons why cached protection state might be + stale: power cycling of target, reset, code executing on the target, + etc. The "flash protect_check" command is now gone. This is *always* + executed when running a "flash info". As a bonus for more a more robust approach, lots of code could be + deleted. Signed-off-by: Øyvind Harboe + +2010-05-05 Øyvind Harboe + + * : cfi: fix error handling for protect fn No error was propagated. Signed-off-by: Øyvind Harboe + +2010-05-04 Øyvind Harboe + + * : gdb: connect will now fail if flash autoprobe fails This stops GDB from launching with an empty memory map, making gdb + load w/flashing fail for no obvious reason. The error message points in the direction of the gdb-attach event + that can be set up to issue a halt or "reset init" which will put + GDB in a well defined stated upon attach and thus have a robust + flash autoprobe. Signed-off-by: Øyvind Harboe + +2010-05-03 Matthias Bode + + * : Fixed bug in tcl-server No segmentationfault when sending commands to tcl-server. modified: src/server/server.c modified: src/server/tcl_server.c modified: src/server/tcl_server.h + +2010-05-04 Øyvind Harboe + + * : flash: more flash write_image bugfixes Remove/fix lots of bugs in handling of non-contigious sections and + out of order sections. Fix a gaffe introduced in previous commit to src/flash/nor/core.c Signed-off-by: Øyvind Harboe + +2010-05-05 Marc Pignat + + * : documentation typo Signed-off-by: Øyvind Harboe + +2010-05-04 Spencer Oliver + + * : str71x: fix previous commit fix build issue with 70226c221f5879bb6126ff3f2ec9ae64c68d80d6 commit Signed-off-by: Spencer Oliver + +2010-05-03 Øyvind Harboe + + * : str7x: fix bogus error messages Remove bogus error messages when trying to allocate a large chunk of + target memory and then falling back to a smaller one. Signed-off-by: Øyvind Harboe + +2010-05-04 Øyvind Harboe + + * : zy1000: wait for srst to deassert make wait for srst deassert more long latency friendly (JTAG over + TCP/IP), print actual time if it was more than 1ms. Signed-off-by: Øyvind Harboe + +2010-04-30 Tobias Ringström + + * : STM32 flash erase timeout fix The current timeout for STM32 flash block erase and flash mass erase + is 10 (ms), which is too tight, and fails around 50% of the time for + me. The data sheet for STM32F107VC specifies a maximum erase time + of 40 ms (for both operations). I'd also consider it a bug that the code does not detect a timeout, + but just assumes that the operation has completed. The attached + patch does not address this bug. The attached patch increases the timeouts from 10 to 100 ms. Please + apply. /Tobias + +2010-04-29 Øyvind Harboe + + * : flash: write_image would fail for certain images Fix a bug where write_image would fail if the sections in the image + were not in ascending order. This has previously been fixed in gdb + load. Solved by sorting the image sections before running flash + write_image erase unlock foo.elf. Signed-off-by: Øyvind Harboe + +2010-04-28 Øyvind Harboe + + * : nor: remove bogus output about padding sections padding of 0 bytes is actually no padding, do not output warning + about padding in that case. Signed-off-by: Øyvind Harboe + +2010-04-26 Marek Vasut + + * : Add VPACLink interface definition This patch adds definition file for the Voipac VPACLink JTAG + adaptor. The adaptor is combined JTAG/UART device. Signed-off-by: Marek Vasut + +2010-04-24 michal smulski + + * : telo: update configuration scripts to matched master branch Signed-off-by: Øyvind Harboe + +2010-04-20 michal smulski + + * : docs: improve load_image docs add docs for missing args. Signed-off-by: Øyvind Harboe + +2010-04-17 Andreas Fritiofson + + * : stm32x: allow flash probe on a running target If the flash has not yet been probed and GDB connects while the + target is running, the flash probe triggered by GDB's memory map + read will fail. In that case the returned memory map will be empty, + causing a subsequent load from within GDB to fail. There's not much + you can do from GDB to recover, other than a restart; a 'mon reset + init' and manual 'mon flash probe' won't help since GDB has already + made up its mind about the memory map. It seems there's no reason to require the target to be halted when + probing the flash. Remove the check to let a valid memory map be + provided to GDB even when connecting to a running target. Signed-off-by: Andreas Fritiofson + +2010-04-14 Antonio Borneo + + * : NOR/CFI: remove redundant code Arguments for "flash bank" command are already parsed and put in + "bank" struct. Removed code to parse them again. Signed-off-by: Antonio Borneo + +2010-04-13 Mike Dunn + + * : xscale: fix analyze_trace for trace data collected in wrap mode This patch fixes the xscale_analyze_trace() function. This function + was defective for a trace collected in 'fill' mode (hiccups with + repeated instructions) and completely broken when buffer overflowed + in 'wrap' mode. The reason for the latter case is that the + checkpoint registers were interpreted incorrectly when two + checkpoints are present in the trace (which will be true in 'wrap' + mode once the buffer fills). In this case, checkpoint1 register + will contain the older entry, and checkpoint0 the newer. The + original code assumed the opposite. I eventually gave up trying to + understand all the logic of the function, and rewrote it. I think + it's much cleaner and understandable now. I have been using and + testing this for a few weeks now. I'm confident it hasn't regressed + in any way. Also added capability to handle (as best as possible) the case where + an instruction can not be read from the loaded trace image; e.g., + partial image. This was a 'TODO' comment in the original + xscale_analyze_trace(). Outside of xcsale_analyze_trace(), these (related) changes were + made: - Remove pc_ok and current_pc elements from struct xscale_trace. + These elements and associated logic are useless clutter because the + very first entry placed in the trace buffer is always an indirect + jump to the address at which execution resumed. This type of trace + entry includes the literal address in the trace buffer, so the + initial address of the trace is immediately determined from the + trace buffer contents and does not need to be recorded when trace is + enabled. - Added num_checkpoints to struct xscale_trace_data, which is + necessary in order to correctly interpret the checkpoint register + contents. - In xscale_read_trace() - Fix potential array out-of-bounds condition. - Eliminate partial address entries when parsing trace (can occur + in wrap mode). - Count and record number of checkpoints in trace. - Added small, inlined utility function xscale_display_instruction() + to help make the code more concise and clear. TODO: - Save processor state (arm or thumb) in struct xscale_trace when + trace is enabled so that trace can be analyzed correctly (currently + assumes arm mode). - Add element to struct xscale_trace that records (when trace is + enabled) whether vector table is relocated high (to 0xffff0000) or + not, so that a branch to an exception vector is traced correctly + (curently assumes vectors at 0x0). + +2010-04-14 Anton Fedotov + + * : cortex-a8: more MMU support + virt2phys() can now convert virtual address to real + + read_memory() and write_memory() are renamed to read_phys_memory() + and write_phys_memory() + new read_memory() and write_memory() try + to resolve real address if mmu is enambled than perform real address + reading/writing + if address is bellow 0xc000000 than TTB0 is used + for page table dereference, if above - than TTB1. Linux style of + user/kernel address separation + if above fails (i.e address is unspecified) than mode is + checked whether it is Supervisor (than TTB1) or User (than TTB0) - Software breakpoints doesn't work. You should invoke + "gdb_breakpoint_override hard" before you start debugging + + cortex_a8_mmu(), cortex_a8_enable_mmu_caches(), + cortex_a8_disable_mmu_caches() are implemented Signed-off-by: Øyvind Harboe + +2010-04-11 Antonio Borneo + + * : NOR/TMS470: review scope of symbols Add "static" qualifier to private functions and data. Signed-off-by: Antonio Borneo + +2010-04-11 Antonio Borneo + + * : TARGET/MIPS32_PRACC: review scope of functions Add "static" qualifier to private functions. Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : HELPER/LOG: review unused symbols Remove unused functions: - log_catch - log_rethrow - log_try Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : NOR/CFI: review scope of functions Add "static" qualifier to private functions. Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : OPENOCD: review scope of functions Add "static" qualifier to private functions. Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : BINARYBUFFER: review scope of data and functions Add "static" qualifier to private data and functions. Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : NAND/TCL: review scope of functions Add "static" qualifier to private functions. Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : NAND/ARM_IO: review scope of functions Add "static" qualifier to private functions. Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : NAND/MX3: review scope of data Add "static" qualifier to private data. Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : NOR/AVRF: review scope of data Add "static" qualifier to private data. Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : NOR/DRIVERS: review scope of functions Add "static" qualifier to private functions. Remove unused "extern" + in src/ecosboard.c Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : TCL: review scope of functions Add "static" qualifier to private functions. Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : HELLO: review unused symbols Remove unused functions: - hello_register_commands Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : ADI_V5_JTAG: review scope of data Add "static" qualifier to private data. Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : ARM_JTAG: review scope of functions Add "static" qualifier to private functions. Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : ARMV4_5_MMU: review unused symbols Remove unused data: - armv4_5_mmu_page_type_names Remove prototype of not existing + function: - armv4mmu_translate_va Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : EMBEDDEDICE: review scope of functions Add "static" qualifier to private functions. Signed-off-by: Antonio Borneo + +2010-04-10 Antonio Borneo + + * : TARGET: review scope of functions Add "static" qualifier to private functions. Remove unused "extern" + in src/ecosboard.c Signed-off-by: Antonio Borneo + +2010-04-04 David Brownell + + * : Restore deleted '!' character I'm not sure what caused this significant character to get deleted. + it may be related to intermittent Editor or terminal flakes I've + been seeing lately (sigh). This fix is trivial. Signed-off-by: David Brownell + +2010-04-04 David Brownell + + * : simplify and unconfuse target_run_algorithm() For some reason there are *two* schemes for interposing logic into + the run_algorithm() code path... One is a standard procedural + wapper around the target method invocation. the other (superfluous) one hacked the method table by splicing a + second procedural wrapper into the method table. Remove it: * Rename its slightly-more-featureful wrapper so it becomes the standard procedural wrapper, leaving its added logic (where it should have been in the first place. Also add a paranoia check, to report targets that don't support algorithms without traversing a NULL pointer, and tweak its code structure a bit so it's easier to modify. * Get rid of the superfluous/conusing method table hacks. This is a net simplification, making it simpler to analyse what's + going on, and then interpose logic . ... by ensuring there's only + one natural place for it to live. ------------ Signed-off-by: David Brownell + +2010-03-28 Mike Dunn + + * : xscale: fix trace buffer functionality when resuming from a + breakpoint Problem: halt at a breakpoint, enable trace buffer ('xscale + trace_buffer enable fill'), then resume. Wait for debug exception + when trace buffer fills (if not sooner due to another breakpoint, + vector catch, etc). Instead, never halts. When halted explicitly + from OpenOCD and trace buffer dumped, it contains only one entry; a + branch to the address of the original breakpoint. If the above + steps are repeated, except that the breakpoint is removed before + resuming, the trace buffer fills and the debug exception is + generated, as expected. Cause: related to how a breakpoint is stepped over on resume. The + breakpoint is temporarily removed, and a hardware breakpoint is set + on the next instruction that will execute. xscale_debug_entry() is + called when that breakpoint hits. This function checks if the trace + buffer is enabled, and if so reads the trace buffer from the target + and then disables the trace (unless multiple trace buffers are + specified by the user when trace is enabled). Thus you only trace + one instruction before it is disabled. Solution: kind of a hack on top of a hack, but it's simple. + Anything better would involve some refactoring. This has been + tested and trace now works as intended, except that the very first + instruction is not part of the trace when resuming from a + breakpoint. TODO: still many issues with trace: doesn't work during + single-stepping (trace buffer is flushed each step), 'xscale + analyze_trace' works only marginally for a trace captured in 'fill' + mode, and not at all for a trace captured in 'wrap' mode. Signed-off-by: Øyvind Harboe + +2010-03-26 Antonio Borneo + + * : NOR TCL: fix usage message The command "flash bank" has updated syntax. Add the mandatory + parameter to the usage message that prints in case of + error. Signed-off-by: Antonio Borneo + +2010-03-04 Øyvind Harboe + + * : zy1000: dev tool first cut peek/poke over tcp/ip, used for debug/research purposes + only. Long term JTAG over TCP/IP might be an offshoot. The + performance is usable for development/testing purposes. Signed-off-by: Øyvind Harboe + +2010-03-25 Daniel Bäder + + * : change %x and %d to PRIx32 and PRId32 where needed for cygwin + +2010-03-24 Antonio Borneo + + * : telnet_server: review unused symbols Remove unused function Signed-off-by: Antonio Borneo + +2010-03-24 David Brownell + + * : FT2232 Messaaging fix The init cleanup patch overlooked a message which was wrongly + specific to the "usbjtag" layout. Fix. Signed-off-by: David Brownell + +2010-03-24 Antonio Borneo + + * : server: review scope of functions and data Add "static" qualifier to private functions and data. Signed-off-by: Antonio Borneo + +2010-03-20 Mike Dunn + + * : fix software breakpoints on xscale This patch fixes xscale software breakpoints by cleaning the dcache + and invalidating the icache after the bkpt instruction is inserted + or removed. The icache operation is necessary in order to flush the + fetch buffers, even if the icache is disabled (see section 4.2.7 of + the xscale core developer's manual). The dcache is presumed to be + enabled; no harm done if not. The dcache is also invalidated after + cleaning in order to safeguard against a future load of invalid + data, in the event that cache_clean_address points to memory that is + valid and in use. Also corrected a confusing typo I noticed in a comment. TODO (or not TODO...?): the xscale's 2K "mini dcache" is not + cleaned. This cache is not used unless the 'X' bit in the page + table entry is set. This is a proprietary xscale extension to the + ARM architecture. If a target's OS or executive makes use of this + for memory regions holding code, the breakpoint problem will + persist. Flushing the mini dcache requires that 2K of valid + cacheable memory (mapped with 'X' bit set) be designated by the user + for this purpose. The debug handler that gets downloaded to the + target will also need to be extended. + +2010-03-21 David Brownell + + * : ft2232 init mess cleanup In the ft2232 driver, initialization for many layouts punts to a + routine called usbjtag_init(), instead of a routine specific to each + layout. That routine is a mess built around a "what type layout am I" + core. That's a bad design ... in this case, especially so, since it + bypasses the layout-specific dispatch which was just done, and + obfuscates the initialization which is at least somewhat generic, + instead of being specific to the "usbjtag" layout. Split and document out the generic parts of usbjtag_init(), and make + the rest of those layouts have layout-specific init methods. Also, + rename usbjtag_reset() ... that also was not specific to the + "usbjtag" layout, and thus contributed to the previous code + structure confusion. (Eventually, all layout-specific code (and method tables) should + probably live in files specific to each layout. These changes will + facilitate those and other cleanups to this driver.) Signed-off-by: David Brownell + +2010-03-19 Øyvind Harboe + + * : jtag: make out_value const Tightens up the jtag_add_xxx_scan() API Signed-off-by: Øyvind Harboe + +2010-03-19 David Brownell + + * : FT2232 comment tweaks Note that the FT4232 chips have four channels not two, and Elaborate + on uses of the additional channels. Signed-off-by: David Brownell + +2010-03-19 Øyvind Harboe + + * : zy1000: fix bug in end state of DCC writes Introduced in latest commits, found by code inspection & GCC + warning. Signed-off-by: Øyvind Harboe + +2010-03-18 Øyvind Harboe + + * : jtag: remove jtag_get_end_state() usage Code inspection indicated what constant end states to use. Signed-off-by: Øyvind Harboe + +2010-03-18 Øyvind Harboe + + * : jtag: remove unecessary usage of jtag_get_end_state(). By code inspection. Signed-off-by: Øyvind Harboe + +2010-03-18 Mike Dunn + + * : Fix underlying problem with xscale icache and dcache commands Fix problem with the xscale icache and dcache commands. Both + commands were enabling or disabling the mmu, not the caches I didn't look any further after my earlier patch fixed the trivial + problem with command argument parsing. Turns out the underlying + code was broken. The resolution is straightforward when you look at the arguments to + xscale_enable_mmu_caches() and xscale_disable_mmu_caches(). I + finally took a deeper look after dumping the cp15 control register + (XSCALE_CTRL) and seeing that the cache bits weren't changing, but + the mmu bit was (which caused all manner of grief, as you can + imagine). This has been tested and works OK now. src/target/xscale.c | 17 +++++++++++------ 1 files changed, 11 insertions(+), 6 deletions(-) Signed-off-by: David Brownell + +2010-03-18 David Brownell + + * : commit 52a788e008ecf0ca6156f02de08a0f062d49a236 Author: David + Brownell Date: Thu Mar 18 + 11:56:17 2010 -0700 + +2010-03-18 Øyvind Harboe + + * : jtag: retire one instance of jtag_get_end_state() usage Less global variables.... Signed-off-by: Øyvind Harboe + +2010-03-18 Spencer Oliver + + * : DOCS: update flash bank examples - include the $_FLASHNAME in all flash bank examples. Signed-off-by: Spencer Oliver + +2010-03-17 Spencer Oliver + + * : MIPS: remove unused arg from mips_ejtag_set_instr This arg was never used and was just taken from the arm jtag code. Signed-off-by: Spencer Oliver + +2010-03-17 Øyvind Harboe + + * : linker error: fix problem with duplicate fn A fn was copied instead of moved to a new file. The linker can + discard exact copies of fn's without warning. This is a C++'ism. However on my Ubuntu 9.10 machine, it fails. Signed-off-by: Øyvind Harboe + +2010-03-17 Øyvind Harboe + + * : gdb: long running "monitor mww" now works w/gdb invoke keep_alive() to make sure that the default 2000ms timeout + does not trigger. Signed-off-by: Øyvind Harboe + +2010-03-17 Øyvind Harboe + + * : target: mdX/mwX on target were badly broken - incorrect parsing of arguments - mdX didn't display arguments correctly I don't think anyone ever used that code path :-) Did you know that "target mdw" and mdw are very different? for {set i 0} {$i < 256} {set i [expr $i+1]} {mwb [expr + 0x2000000+$i] $i} mdw 0x2000000 0x10 0x02000000: 03020100 07060504 0b0a0908 0f0e0d0c + 13121110 17161514 1b1a1918 1f1e1d1c 0x02000020: 23222120 27262524 + 2b2a2928 2f2e2d2c 33323130 37363534 3b3a3938 3f3e3d3c > zy1000.cpu mdb 0x2000000 0x20 0x02000000 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f ................ 0x02000010 10 11 12 13 14 + 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................ > zy1000.cpu mdh + 0x2000000 0x20 0x02000000 0100 0302 0504 0706 0908 0b0a 0d0c 0f0e + ................ 0x02000010 1110 1312 1514 1716 1918 1b1a 1d1c 1f1e + ................ 0x02000020 2120 2322 2524 2726 2928 2b2a 2d2c 2f2e + !"#$%&'()*+,-./ 0x02000030 3130 3332 3534 3736 3938 3b3a 3d3c 3f3e + 0123456789:;<=>? > zy1000.cpu mdw 0x2000000 0x20 0x02000000 03020100 + 07060504 0b0a0908 0f0e0d0c ................ 0x02000010 13121110 + 17161514 1b1a1918 1f1e1d1c ................ 0x02000020 23222120 + 27262524 2b2a2928 2f2e2d2c !"#$%&'()*+,-./ 0x02000030 33323130 + 37363534 3b3a3938 3f3e3d3c 0123456789:;<=>? 0x02000040 43424140 + 47464544 4b4a4948 4f4e4d4c @ABCDEFGHIJKLMNO 0x02000050 53525150 + 57565554 5b5a5958 5f5e5d5c PQRSTUVWXYZ[\]^_ 0x02000060 63626160 + 67666564 6b6a6968 6f6e6d6c `abcdefghijklmno 0x02000070 73727170 + 77767574 7b7a7978 7f7e7d7c pqrstuvwxyz{|}~. Signed-off-by: Øyvind Harboe + +2010-03-16 Spencer Oliver + + * : PIC32: add software reset support The PIC32MX does not support the ejtag software reset - it is + optional in the ejtag spec. We perform the equivalent using the microchip specific MTAP cmd's. Signed-off-by: Spencer Oliver + +2010-03-16 Øyvind Harboe + + * : gdb_server: improved gdb load performance by ack'ing memory writes immediately and reporting either at next + memory write or stepi/continue time. GDB will then send off a new + packet that is ready by the time the previous packet has been + written to target memory. On faster adapters this can be as much as 10% improvement. Signed-off-by: Øyvind Harboe + +2010-03-16 Øyvind Harboe + + * : arm7/9: remove unused post_restore_context Unused. If something should happen after context restore, then the + calling code can just do it afterwards. Signed-off-by: Øyvind Harboe + +2010-03-01 Øyvind Harboe + + * : bitbang: add jtag_add_tms_seq support Signed-off-by: Øyvind Harboe + +2010-03-16 Spencer Oliver + + * : PIC32: add Microchip Explorer16 cfg - add Microchip Explorer16 cfg using PIC32MX360F512L PIM. - remove reset config from PIC32 target cfg. Signed-off-by: Spencer Oliver + +2010-03-15 Bradey Honsinger + + * : image loading: fix problem with offsets > 0x80000000 Fixes bug that prevented users from specifying a base address of + 0x80000000 or higher in image commands (flash write_image, etm + image, xscale trace_image). image.base_address is an offset from the start address contained in + the image file (if there is one), or from 0 (for binary files). As a + signed 32-bit int, it couldn't be greater than 0x7fffffff, which is + a problem when trying to write a binary file to flash above that + address. Changing it to a 64-bit long long keeps it as a signed + offset, but allows it to cover the entire 32-bit address space. Signed-off-by: Øyvind Harboe + +2010-03-15 David Brownell + + * : rename jtag_nsrst_assert_width as adapter_nsrst_assert_width Globally rename "jtag_nsrst_assert_width" as + "adapter_nsrst_assert_width", and move it out of the "jtag" command + group ... it needs to be used with non-JTAG transports Includes a migration aid (in jtag/startup.tcl) so that old user + scripts won't break. That aid should Sunset in about a year. Signed-off-by: David Brownell + +2010-03-15 David Brownell + + * : rename jtag_khz as adapter_khz Globally rename "jtag_khz" as "adapter_khz", and move it out of the + "jtag" command group ... it needs to be used with non-JTAG + transports Includes a migration aid (in jtag/startup.tcl) so that old user + scripts won't break. That aid should Sunset in about a year. (We + may want to update it to include a nag message too.) Signed-off-by: David Brownell + +2010-03-15 Spencer Oliver + + * : PIC32MX: update cfg script The default config script will now dynamically setup the BMX + registers in the reset init script. This will also work if the user + overrides the default working area. Signed-off-by: Spencer Oliver + +2010-03-14 David Brownell + + * : FT2232: lookup and save layout just once Streamline use of the layout: have the "ft2232_layout" command look + it up and save the result, instead of having a few different chunks + of code looking it up later, and saving just its name (which is + already part of the layout). This - is cleaner - reports errors sooner - facilitates earlier adapter-specific setup - removes unused "default to "usbjtag" logic Signed-off-by: David Brownell + +2010-03-11 David Brownell + + * : versaloon cleanup patch Remove undesirable - backslashes at end-of-line; - initializations of BSS data to zero/NULL; - overlong lines (80+ characters) - whitespace issues - brackets around single-line statements And other minor issues reported by the Linux "checkpatch" utility Signed-off-by: David Brownell + +2010-03-08 Michal Demin + + * : Add support for Bus Pirate as a JTAG adapter. This includes a driver and matching config file. This support needs + to be enabled through the initial "configure" (use + "--enable-buspirate"). Signed-off-by: Michal Demin Signed-off-by: + David Brownell + +2010-03-10 Spencer Oliver + + * : MIPS: make fixed code arrays static const Signed-off-by: Spencer Oliver + +2010-03-08 Spencer Oliver + + * : PIC32: add flash algorithm support Add flash algorithm support for the PIC32MX. Still a few things + todo but this dramatically decreases the programing time, eg. approx + programming for 2.5k test file. - without fastload: 60secs - with fastload: 45secs - with fastload and algorithm: 2secs. Add new devices to supported list. Signed-off-by: Spencer Oliver + +2010-03-08 Spencer Oliver + + * : STR7: flash loader cleanup - make algorithm array static const. - increase algorithm buffer size to 32k. Signed-off-by: Spencer Oliver + +2010-03-08 Spencer Oliver + + * : ADUC702x: flash loader cleanup - make algorithm array static const. Signed-off-by: Spencer Oliver + +2010-03-08 David Brownell + + * : move a constant table to .rodata section The table of command registration functions shouldn't be in writable + memory, where stray pointers can clobber it. Also, it shouldn't be + initialized at runtime; that just consumes needless code space. Signed-off-by: David Brownell + +2010-03-08 Øyvind Harboe + + * : zy1000: embedded ice dcc tweak How many bits to shift out before/after enabled tap not in bypass is + calculated outside the loop. This is more of a demonstration of + principle and to clarify code than a performance optimisation as + such. Follows up a bit on the simplification work in jtag interface. Signed-off-by: Øyvind Harboe + +2010-03-04 Øyvind Harboe + + * : jtag: jtag_add_ir_scan() now takes a single field In the code a single field was all that was ever used. Makes + jtag_add_ir_scan() simpler and leaves more complicated stuff to + jtag_add_plain_ir_scan(). Signed-off-by: Øyvind Harboe + +2010-03-06 Antonio Borneo + + * : CFI: review print of Voltage values JEDEC standard reports Vpp integer part encoded as 4 bit HEX value. + To print it using decimal digits, %u is required. Other voltage + values are coded as BCD, so %x is appropriate. Code already prints one nibble at a time, so no need for field width + and precision in format string. Signed-off-by: Antonio Borneo + Signed-off-by: Øyvind Harboe + +2010-03-05 David Brownell + + * : README: update libftdi version The FT2232H really wants libftdi 0.17 or newer; some notable bugs + got fixed in that version. Signed-off-by: David Brownell + +2010-03-04 Øyvind Harboe + + * : minidriver: fix arm11 compilation problem Signed-off-by: Øyvind Harboe + +2010-03-03 David Brownell + + * : NOR: trim range in flash_driver_protect() When the beginning or end of the specified range of sectors already + has the requested protection status, don't ask the flash driver to + change those sectors. This will among other things turn command sequences like this into + the NOPs one would expect: flash protect_check 0 flash info 0 ... reports everything as unprotected ... flash protect 0 0 1 off That speeds things up (by whatever work was just avoided). Also, with Stellaris (which can't unprotect flash at page level) + this can eliminate some undesirable/false error reports. (And + finishes fixing a bug currently listed in our bug database...) Signed-off-by: David Brownell + +2010-03-03 David Brownell + + * : NOR: stellaris message tweaks Give a more accurate failure message when trying to unprotect; don't + complain about pages being write protected, just say that unprotect + is not supported by the hardware ... referencing the new "recover" + command, which is the way to achieve that. Likewise, when trying to protect, talk about "pages" (matching + hardware doc) not "sectors" (an concept that's alien to these + chips). Also make the helptext for the "recover" command mention that it + also erases the device. Signed-off-by: David Brownell + +2010-03-02 David Brownell + + * : ADIv5: use new DAP ops for AP read/write Make ADIv5 internals use the two new transport-neutral calls for + reading and writing DP registers; and do the same for external + callers. Also, bugfix some of their call sites to handle the fault + returns, instead of ignoring them. Remove most of the JTAG-specific calls, using their code as the + bodies of the JTAG-specific implementation for the new methods. NOTE that there's a remaining issue: mem_ap_read_buf_u32() makes + calls which are JTAG-specific. A later patch will need to remove + those, so JTAG-specific operations can be removed from this file, + and so that SWD support will be able to properly drop in as just a + transport layer to the ADIv5 infrastructure. (The way read results + are posted may need some more attention in the transport-neutrality + interface.) Signed-off-by: David Brownell + +2010-03-02 David Brownell + + * : ADIv5: use new dap_run() operation Make ADIv5 use one of the new transport-neutral interfaces: call + dap_run(), not jtagdp_transaction_endcheck(). Also, make that old interface private; and bugfix some of its call + sites to handle the fault returns, instead of ignoring them. Signed-off-by: David Brownell + +2010-03-02 David Brownell + + * : target_resume() doxygen Add doxygen for target_resume() ... referencing the still-unresolved + confusion about what the "debug_execution" parameter means (not all + CPU support code acts the same). The 'handle_breakpoints" param seems to have resolved the main issue + with its semantics, but it wasn't part of the function spec before. Signed-off-by: David Brownell + +2010-03-02 David Brownell + + * : ADIv5: use right ID for Cortex-M3 ETM Correct a mistake made copying the ID of the Cortex-M3 ETM module + from the TRM, so that "dap info" on a CM3 with an ETM will now + correctly describe ROM table entries for such modules. (They are + included on LPC17xx and some other cores.) Signed-off-by: David Brownell + +2010-03-01 Øyvind Harboe + + * : zy1000: faster jtag_add_ir_scan() Faster and simpler. Signed-off-by: Øyvind Harboe + +2010-03-01 Øyvind Harboe + + * : zy1000: add jtag_add_tms_seq support Signed-off-by: Øyvind Harboe + +2010-02-28 Spencer Oliver + + * : armv4_5: remove core_type check in mcr/mrc cmd core_type check is not required as the core function will be null + for cores that do not support the mcr/mrc functions. Signed-off-by: Spencer Oliver + +2010-02-28 Spencer Oliver + + * : stellaris: recover_command use usleep rather than sleep windows api does not define a posix sleep, use usleep that has an + openocd wrapper to the win32 native function. Signed-off-by: Spencer Oliver + +2010-02-26 Spencer Oliver + + * : semihosting: add armv7m semihosting support do_semihosting and arm_semihosting now check the core type and use + the generic arm structure. Signed-off-by: Spencer Oliver + +2010-02-26 Spencer Oliver + + * : CortexM3: move disassemble cmd to arm cmd group Rather than using a Cortex disassemble cmd, we now use the arm + generic version. Signed-off-by: Spencer Oliver + +2010-01-13 Spencer Oliver + + * : MIPS: add mips algorithm support - add mips support for target algorithms. - added handlers for target_checksum_memory and + target_blank_check_memory. - clean up long lines Signed-off-by: Spencer Oliver + +2010-02-28 Mariano Alvira + + * : Add board/redbee-usb.cfg The Redbee USB is a small form-factor usb stick from Redwire, LLC (www.redwirellc.com/store), built around a Freescale MC13224V + ARM7TDMI + 802.15.4 radio (plus antenna). It includes an FT2232H for debugging, with Channel B connected to + the mc13224v's JTAG interface (unusual) and Channel A connected to + UART1. Signed-off-by: David Brownell + +2010-02-27 Mariano Alvira + + * : Add target/mc13224v.cfg The MC13224V is a FreeScale ARM7TDMI based IEEE802.15.4 platform for + Zigbee and similar low-power wireless applications. Using PIP + (Platform In Package) technology, it integrates: an RF balun and + matching network; a buck converter (only an external inductor is + necessary); 96KB of SRAM; and 128KB of non-volatile memory. It has an integrated bootloader and can boot from a variety of + sources: external SPI or I2C non-volatile memory, an image loaded + over UART1, or the internal non-volatile memory. The image loaded + from one of these sources is executed directly from SRAM starting at + location 0x00400000. Open source development code at http://mc1322x.devl.org Signed-off-by: David Brownell + +2010-02-27 David Brownell + + * : ADIv5 DAP ops switching to JTAG or SWD modes Define two new DAP operations which use the new jtag_add_tms_seq() + calls to put the DAP's transport into either SWD or JTAG mode, when + the hardware allows. Tested with the Stellaris 'Recovering a "Locked" Device' procedure, + which loops five times over both of these. Signed-off-by: David Brownell + +2010-02-27 David Brownell + + * : interface: define TMS sequence command For support of SWD we need to be able to clock out special bit + sequences over TMS or SWDIO. Create this as a generic operation, + not yet called by anything, which is split as usual into: - upper level abstraction ... here, jtag_add_tms_seq(); - midlayer implementation logic hooking that to the lowlevel code; - lowlevel minidriver operation ... here, interface_add_tms_seq(); - message type for request queue, here JTAG_TMS. This is done slightly differently than other operations: there's a + flag saying whether the interface driver supports this request. (In + fact a flag *word* so upper layers can learn about other + capabilities too ... for example, supporting SWD operations.) That approach (flag) lets this method *eventually* be used to + eliminate pathmove() and statemove() support from most adapter + drivers, by moving all that logic into the mid-layer and increasing + uniformity between the various drivers. (Which will in turn reduce + subtle bugginess.) Signed-off-by: David Brownell + +2010-02-24 David Brownell + + * : ARM ADIv5 doxygen and cleanup Add doxygen for mem_ap_read_buf_u{8,16,32}() calls, and shrink a few + overlong lines. Signed-off-by: David Brownell + +2010-02-23 David Brownell + + * : ARM ADIv5: rename more JTAG-specific routines Highlight more of the internal JTAG-specific utilities, so it's + easier to identify code needing changes to become transport-neutral. Signed-off-by: David Brownell + +2010-02-09 Øyvind Harboe + + * : arm11: allow minidrivers to implement inner loop of memory + writes This allows minidrivers to e.g. hardware accelerate memory writes. Same trick as is used for arm7/9 dcc writes. Added error propagation for memory transfer failures in code + rearrangement. Also the JTAG end state is not updated until after the memory write + run is complete. Signed-off-by: Øyvind Harboe + +2010-02-21 David Brownell + + * : ft2232 table init cleanup Use labeled initializers in the table of layouts instead of + positional ones. This ls cleaner and less error prone, plus it + simplifies patches which add members to these structure. Signed-off-by: David Brownell + +2010-02-21 David Brownell + + * : ADIv5: relocate memacess_tck cycles When using an AP to access a memory (or a memory-mapped register), + some extra TCK (assuming JTAG) cycles should be added to ensure the + AP has enugh time to complete that access before trying to collect + the response. The previous code was adding these cycles *before* trying to access + (read or write) data to that address, not *after*. Fix by putting + the delays in the right location. Signed-off-by: David Brownell + +2010-02-21 David Brownell + + * : ARM: ADIv5, deadcode cleanup I have no idea what the scan_inout_check() was *expecting* to + achieve by issuing a read of the DP_RDBUFF register. But in any + case, that code was clearly never being called ("invalue" always + NULL) ... so remove it, and the associated comment. Also rename it as ap_write_check(), facilitating a cleanup of its + single call site by removing constant parameters. Signed-off-by: David Brownell + +2010-02-21 David Brownell + + * : ADIv5 clean up AP fault handling Pass up fault codes from various routines, so their callers can + clean up after failures, and remove the FIXME comments highlighting + those previously goofy code paths. dap_ap_{read,write}_reg_u32() dap_ap_write_reg() mem_ap_{read,write}_u32() mem_ap_{read,write}_atomic_u32() dap_setup_accessport() Make dap_ap_write_reg_u32() just wrap dap_ap_write_reg(), instead of + cloning its core code (and broken fault handling). Signed-off-by: David Brownell + +2010-02-21 David Brownell + + * : ARM: keep a handle to the PC Keep a handle to the PC in "struct arm", and use it. This register + is used a fair amount, so this is a net minor code shrink (other + than some line length fixes), but mostly it's to make things more + readable. For XScale, fix a dodgy sequence while stepping. It was + initializing a variable to a non-NULL value, then updating it to + handle the step-over-active-breakpoint case, and then later testing + for non-NULL to see if it should reverse that step-over-active + logic. It should have done like ARM7/ARM9 does: init to NULL. Signed-off-by: David Brownell + +2010-02-21 David Brownell + + * : ARM11: per-core options should not be global Address some FIXME comments by getting rid of globals, moving + per-core parameters in the existing per-core data structure. This will matter most whenever there are multiple ARM11 cores, e.g. + ARM11 MPcore chips, but in general is just cleanup. Signed-off-by: David Brownell + +2010-02-21 David Brownell + + * : Open the merge window for the 0.5.0 release cycle. Signed-off-by: David Brownell + +2010-02-21 David Brownell + + * : User's Guide mentions OS-specific installation Specifically the Linux issue of needing "udev" rules, and MS-Windows + needing driver configuration. Also, update the existing udev note to use the correct name of that + rules file in the source tree. Signed-off-by: David Brownell + +2010-02-20 David Brownell + + * : CSB337 board cleanup (quasi-regression) Get rid of new nasty warning: NOTE! Severe performance degradation without fast memory access + enabled... Signed-off-by: David Brownell + +2010-02-16 Marc Pignat + + * : atm920t : fix breakpoints and data cache handling Breakpoints did not work because the data cache was not flushed + properly. As a bonus add capability to write to memory marked as read only by + the MMU, which allows software breakpoints in such memory regions. + +2010-02-15 Øyvind Harboe + + * : gpl: fix GPL startup message Signed-off-by: Øyvind Harboe + +2010-02-14 Mathias Kuester + + * : fix crash with DSP563XX When a DSP563xx-aware GDB asks OpenOCD for target registers, the + result should be a GDB with register data ... not an OpenOCD crash. (Note that mainline GDB doesn't currently support this core, so for + now, this requires a GDB with FreeScale patches.) Signed-off-by: David Brownell + +2010-02-13 David Brownell + + * : Restore "-dev" version suffix (0.4.0-rc2-dev) Signed-off-by: David Brownell + +2010-02-11 Spencer Oliver + + * : STR9xpec: issue warning when unlocking device Issue warning to user when unlocking or writing the option bytes. + The new settings will not take effect until a target reset. Signed-off-by: Spencer Oliver + +2010-02-12 Øyvind Harboe + + * : arm720t: virt2phys callback added This is a copy and paste of arm926ejs. Not tested, but ready for + testing at least. There is a good chance that it will work if the + generic armv4_5 fn's are robust enough... Signed-off-by: Øyvind Harboe + +2010-02-11 Viktar Palstsiuk + + * : target library: configuration files for openocd tested with + Atmel SAM-ICE V6 JTAG. Signed-off-by: Øyvind Harboe + +2010-02-10 Øyvind Harboe + + * : arm11: fix another infinite loop bug reset init would get stuck in an infinite loop when e.g. khz was too + high. Added timeout. This is a copy of paste of a number of such + bugfixes in the arm11 code. Arm11 code reviewed for further such infinite loop bugs and I + couldn't find any more. Xing fingers it's the last one... Signed-off-by: Øyvind Harboe + +2010-02-09 Øyvind Harboe + + * : target: add todo in target_write_memory() about alignment target_write_buffer() does not align "buffer" in host memory passed + to target_write_memory(). Signed-off-by: Øyvind Harboe + +2010-02-06 David Brownell + + * : Re-title Developer's Guide The Doxygen output was previously titled "OpenOCD Reference Manual", + which was quite misleading ... the User's Guide is the reference + manual which folk should consult about how to use the software. Just rename it to match how it's been discussed previously, and to + bring out its intended audience: developers of this software. As a + rule, Doxygen is only for folk who work with the code it documents. Signed-off-by: David Brownell + +2010-02-05 Øyvind Harboe + + * : zy1000: complete zy1000_uart to jim command switch Signed-off-by: Øyvind Harboe + +2010-02-04 David Brownell + + * : Documentation: mention bug database Have the User's Guide and BUG handling notes both reference the fact + that we now have a bug database at SourceForge. Signed-off-by: David Brownell + +2010-02-04 Spencer Oliver + + * : CMD: duplicate cmd error msg When registering cmds we report duplicate attempts to register a cmd + as a LOG_ERROR. Some situations need this, such as when registering + dual flash banks. + + http://www.mail-archive.com/openocd-development@lists.berlios.de/msg11152.htmlSigned-off-by: Spencer Oliver + +2010-02-03 Spencer Oliver + + * : JTAG: fix bug when no interface connected - fix coredump when OpenOCD is started without a jtag interface + connected. Signed-off-by: Spencer Oliver + +2010-02-02 David Brownell + + * : NOR: User's Guide updates Remove long-obsolete text about "erase_check" affecting "flash info" + output. Move parts of that text to "protect_check", where it's + still relevant; and update the "flash info" description to mention + the issue. (This is still awkward. It might be best to make "protect_check" + mirror "erase_check" by dumping what it finds, so "flash info" + doesn't dump any potentially-stale cache info.) Signed-off-by: David Brownell + +2010-02-02 Edgar Grimberg + + * : flash/str7x: After reset init the flash is unlocked The default state of the STR7 flash after a reset init is unlocked. + The information in the flash driver now reflects this. The information about the lock status cannot be read from the flash + chip, so the user is informed that flash info might not contain + accurate information. [dbrownell@users.sourceforge.net: line length shrinkage] Signed-off-by: Edgar Grimberg + Signed-off-by: David Brownell + +2010-01-29 Edgar Grimberg + + * : Test cases ran on v0.4.0-rc1 Test cases ran on v0.4.0-rc1 for a number of targets: AT91FR40162 + LPC2148 SAM7 STR710 STR912 The goal of the testing session was to prove basic functionality of + OpenOCD for different targets. Signed-off-by: Edgar Grimberg + +2010-01-31 David Brownell + + * : ADIv5: more messaging cleanup, docs When the TAR cache was explicitly invalidated, don't bother printing + it; the actual hardware status is more informative. Provide some doxygen for the MEM-AP setup routine. Signed-off-by: David Brownell + +2010-01-21 Øyvind Harboe + + * : telnet: fix strage blank spaces at beginning of telnet lines Sometimes we saw two strange blank spaces at the beginning of the + telnet lines. progress ogress > This patch fixes this problem: progress progress > The code changes are *reasonably* clean, but perhaps it could be + made a bit more elegant, but I didn't want to change things after I + finished diagnosis/testing & submitting the patch. The problem was that logging can send the text and the newline + separately in two different requests and the telnet code would + incorrectly remove the prompt from the end of a line. Signed-off-by: Øyvind Harboe + +2010-01-30 David Brownell + + * : ADIv5 error checking for Tcl commands Reject invalid AP numbers (256+) as Tcl operation parameters. + Shrink one of the overlong lines. Add my copyright to the ADIv5 code (multiple contributions). Signed-off-by: David Brownell + +2010-01-29 David Brownell + + * : ADIv5: cleanup, rename swjdp_transaction_endcheck() Make messages reference "DAP" if they're actually + transport-agnostic, or "JTAG-DP" when they're JTAG-specific. Saying + SWJ-DP is often wrong (on most Cortex-A8 chips) and is confusing + even if correct (since we don't yet support SWD). Rename a JTAG-specific routine to jtagdp_transaction_endcheck() to + highlight that it's JTAG-specific, and that identify DAP clients + undesirably depending on JTAG. (They will all need to change for + SWD support.) Shrink a few overlong lines of code. Copy a comment from code + removed in a previous patch (for the ARMv7-M "dap baseaddr" + command). Signed-off-by: David Brownell + +2010-01-29 David Brownell + + * : NOR: cleanup driver decls Fix goofy struct indents. Function names *are* their addresses. Signed-off-by: David Brownell + +2010-01-28 David Brownell + + * : doc clarifications for server flags The "-f" is a shortcut for "-c" ... and providing any "-c" options + means the "openocd.cfg" file isn't implicitly used. Both the User's + Guide and the manual page were weak on these points, which has led + to some confusion. Also update the manual page to include highlights of the search path + mechanism, including the facts that it exists and that "-s" adds to + it. Stop saying only the current directory is involved; the OpenOCD + script library is quite significant. (Missing: complete manpage coverage of the search path, including a + FILES section listing all components and saying where the script + library is found.) Signed-off-by: David Brownell + +2010-01-28 Spencer Oliver + + * : ARM semihosting: win32 and cygwin fixes Cygwin would fail to reopen a previously written file if the mode is + not given. Simplified converting the open flags and made sure the win32 + O_BINARY bit is set. Added define for systems that do not support O_BINARY. Signed-off-by: Spencer Oliver + +2010-01-27 David Brownell + + * : Cortex-M3: report lockup, and recover ARMv7-M defines a "lockup" state that's entered in certain double + fault sequences which can't be recovered from without external help. + OpenOCD has previously ignored this. Issue a diagnostic saying the chip has locked up, and force exit + from this state by halting the core. It's not clear this is the + best way to handle lockup; but there should now be less confusion. Signed-off-by: David Brownell + +2010-01-27 David Brownell + + * : Cortex-A8: debug messaging tweaks Make that "TODO" message say what needs to be done. Say what part + of examining failed. Signed-off-by: David Brownell + +2010-01-26 David Brownell + + * : cygwin buildfix isspace() parameter must be an integer, else a 'char' gets used as + an array index (sigh). Signed-off-by: David Brownell + +2010-01-25 Edgar Grimberg + + * : core arm11: Silence logs at level 3 if there is no activity If the target and openocd are idling, the log should normally be + silent at level 3. (Given no verbose logging options.) Signed-off-by: Edgar Grimberg + Signed-off-by: David Brownell + +2010-01-22 David Brownell + + * : EmbeddedICE - fix Feroceon/Dragonite message The breakpoint/watchpoint message was wrong for Feroceon and + Dragonite, which have only one working watchpoint unit. Signed-off-by: David Brownell + +2010-01-22 David Brownell + + * : ARM11: fix breakpoints with GDB This fixes a bug whereby GDB's breakpoints weren't activated. The + root cause is a confused interface to resume(). Fix by almost + ignoring the "handle breakpoints" parameter; it only seems related + to the case of skipping breakpoint-at-PC. Update a few coments to clarify what's happening. Signed-off-by: David Brownell + +2010-01-21 David Brownell + + * : User's Guide secton on target hardware setup Highlight the needs to properly jumper development boards; to make + the OpenOCD configuration match the jumpering; and to have a usable + "reset-init" method when debugging early boot code. Specific mention of the "ATX Mode" that seems useful on many i.MX + boards, forcing NAND boot. Signed-off-by: David Brownell + +2010-01-21 Øyvind Harboe + + * : target: print reason why GDB halts If GDB halts unexpectedly, print reason: srst assert or power out + detected. If polling fails, then things are a bit trickier. We do not want to + spam telnet or the log with polling failed messages. Leave that + case be w/a comment in a code for now. Signed-off-by: Øyvind Harboe + +2010-01-21 Edgar Grimberg + + * : target: Fixed format problem for mdh Fixed format problem for mdh. It needs to display 4 chars. Signed-off-by: Edgar Grimberg + +2010-01-21 Øyvind Harboe + + * : ecos: add missing PRId8 definition Signed-off-by: Øyvind Harboe + +2010-01-20 David Brownell + + * : Cortex-M3 vector_catch testing support The "cm3-ftest.cfg" can be used to verify that OpenOCD handles + certain faults correctly: - Test #1: it ignores faults that it wasn't told to catch - Test #2: if vector_catch is told to catch, it catches The "fault.c" generates ASM code to trigger faults, while the config + script loads and runs pre-compiled code. This covers most, but not all, of the vector_catch options. Signed-off-by: David Brownell + +2010-01-20 David Brownell + + * : gdb_server: correctly report flash sector sizes Report each region of same-size sectors separately, instead of + incorrectly reporting that every sector has the same size. This is a longstanding bug on NOR flash chips with non-uniform + sector sizes. It was largely hidden by other bugs in flash + handling. When some of those were recently fixed, this one was + exposed as a regression on str710. [oyvind.harboe@zylin.com: update the loop to behave on str7 ] Signed-off-by: Øyvind Harboe + Signed-off-by: David Brownell + +2010-01-20 Øyvind Harboe + + * : testing: fix str710 test case now builds Make the test case easily adjustable in size. str710 has very + peculiar flash sector layout, nice for testing, but a larget + test_rom.elf is required. Signed-off-by: Øyvind Harboe + +2010-01-19 Spencer Oliver + + * : ARMV7M: handle bkpt instruction on resume/step Skip over a bkpt instruction if found on resume/step. Only software + breakpoints known to OpenOCD are currently handled. So this handles the special case of either a user added bkpt or + library added, eg. semi-hosting support. Signed-off-by: Spencer Oliver + +2010-01-19 David Brownell + + * : gdb_server -- subroutinize memory map logic Put the memory map logic into its own subroutine. This will make it + a bit easier to package bugfixes, and simplifies the query packet + handling. Signed-off-by: David Brownell + +2009-11-21 Andreas Fritiofson + + * : update win32 script search path The default script search path on Windows is out of date with the + current layout (from installation and documentation), which makes + the standard script library not be found after a normal ./configure && make && make install under msys/MinGW. The same should hold true for cygwin native builds + (not verified). Update search path to ../share/openocd/scripts not ../lib/openocd, + relative to the openocd executable. Signed-off-by: Andreas Fritiofson + Signed-off-by: David Brownell + +2010-01-18 Øyvind Harboe + + * : zy1000: flush jtag buffer before changing speed It is conceivable that there could be commands in the queue when a + speed change request comes in. Flush the hw queue before changing + speed. Not observed, found by inspection. Signed-off-by: Øyvind Harboe + +2010-01-19 Øyvind Harboe + + * : flash: add error messages upon incorrect arguments to flash + iteration According to OpenOCD error handling rules the error is logged at + where it occurs(same site where an exception would have been + thrown). Signed-off-by: Øyvind Harboe + +2010-01-18 Øyvind Harboe + + * : commands: allow scan_chain command to be executed during config Adding taps and then dumping them is quite reasonable thing to do in + a config script. Signed-off-by: Øyvind Harboe + +2010-01-16 richard vegh + + * : NAND: lpc3180 crashes on LPC3250 The LPC3180 NAND driver was crashing on some large page chips. Fix: - Crash and related functionality (don't memset too much OOB data) - Some debug messages - Command handling now works [dbrownell@users.sourceforge.net: whitespace/linelength/message + cleanup] Signed-off-by: David Brownell + +2010-01-15 David Brownell + + * : ARM DPM: disable some nyet-ready breakpoint code Until we manage breakpoints at runtime (patches not ready for 0.4) + the only way this code should touch them is to disable them at + server startup (a previous debug session may have left them active). Signed-off-by: David Brownell + +2010-01-14 David Brownell + + * : jtag.h whitespace/comment cleanup Signed-off-by: David Brownell + +2010-01-14 David Brownell + + * : ARM7/ARM9: improved reset support Teach most remaining ARM cores how to use the "reset-assert" event. Same model as elsewhere: iff a handler is provided for that event, + use that instead of trying to assert SRST (which may be unavailable, + or inappropriate since it resets too much). Else no change. Signed-off-by: David Brownell + +2010-01-14 Laurentiu Cocanu + + * : str9x.c: remove optimization when erasing the whole bank Using the erase bank command will cause a time out error. Replacing + this with the erase sector bank will provide a slower but safer and + stable method to erase the flash. Signed-off-by: Laurentiu Cocanu + Signed-off-by: Øyvind Harboe + +2010-01-14 Spencer Oliver + + * : GDB: change gdb_breakpoint_override to COMMAND_ANY - enable gdb_breakpoint_override to be used within config script. Signed-off-by: Spencer Oliver + +2010-01-13 David Brownell + + * : NOR: add optional "flash erase_address" sector padding Add a NOR flash mechanism where erase_address ranges can be padded + out to sector boundaries, triggering a diagnostic: > flash erase_address 0x0001f980 16 address range 0x0001f980 .. 0x0001f98f is not sector-aligned Command handler execution failed in procedure 'flash' called at file "command.c", line 647 called at file "command.c", line 361 > > flash erase_address pad 0x0001f980 16 Adding extra erase range, 0x0001f800 to 0x0001f97f Adding extra erase range, 0x0001f990 to 0x0001fbff erased address 0x0001f980 (length 16) in 0.095975s (0.163 kb/s) > This addresses what would otherwise be something of a functional + regression. An earlier version of the interface had a dangerous + problem: it would silently erase data outside the range it was told + to erase. Fixing that bug turned up some folk who relied on that + unsafe behavior. (The classic problem with interface bugs!) Now + they can get that behavior again. If they really need it, just + specify "pad". Signed-off-by: David Brownell + +2010-01-11 Øyvind Harboe + + * : arm7/9: enable check that DCC downloads have been enabled Signed-off-by: Øyvind Harboe + +2010-01-11 Øyvind Harboe + + * : target: add check_reset hook Allow targets to run checks post reset. Used to check that e.g. DCC + downloads have been enabled. Signed-off-by: Øyvind Harboe + +2010-01-11 Øyvind Harboe + + * : debug: make logging of commands terser one line / command instead of one line per argument. Signed-off-by: Øyvind Harboe + +2010-01-11 Vladimir Zapolskiy + + * : Added Openmoko USB JTAG interface config file. Added interface config file for JTAG/RS232 debug board originally + integrated to Neo 1973 and Neo FreeRunner phones. Adapter was + tested with i.MX31, S3C2410 and AT91SAM9260 processors. Signed-off-by: Vladimir Zapolskiy + +2010-01-11 Øyvind Harboe + + * : reset: better error messages Use correct tcl syntax to throw exception. the syntax is "return -code error" not "return -error" Signed-off-by: Øyvind Harboe + +2010-01-11 Øyvind Harboe + + * : zy1000: reset bugfix flush JTAG FIFO before reset. Fixes RCLK problems observed + w/lpc2148, but really fixes a wider range of problems. Signed-off-by: Øyvind Harboe + +2010-01-08 Øyvind Harboe + + * : shutdown: more graceful shutdown Shutdown is not an error condition, do not return error from main. Signed-off-by: Øyvind Harboe + +2010-01-10 David Brownell + + * : FreeBSD build fixes Based on notes from Tomek Cedro and Steve + Franks . In the User's Guide, sort the list of operating systems reported + through Tcl with $ocd_HOSTOS ... and include FreeBSD. Signed-off-by: David Brownell + +2010-01-09 David Brownell + + * : jtag/tcl help/usage fixups The usual: expand several helptexts to be more correct and to use + full sentences; make the usage messages use the same EBNF as the + User's Guide; use function names for their addresses. Also add a comment about that odd jtag_command_handlers_to_move[] + thing. Signed-off-by: David Brownell + +2010-01-09 David Brownell + + * : jtag: presto, parport help/usage updates Presto: add doxygen file comment. Parport: note a couple gaps in layout config. Both: use the uniform EBNF for usage, bugfix helptexts, use function + name as its address not "&name". Signed-off-by: David Brownell + +2010-01-09 David Brownell + + * : parport (mostly) doc fixes The "parport_port" commands generally don't *require* a port_number; + they're of the "apply any parameter, then print result" variety. + Update the User's Guide accordingly. Some of those commands are intended to be write-once: parport_port, + and parport_cable. Say so. Use proper EBNF for the parport_write_on_exit parameter. Parport address 0xc8b8 is evidently mutant. Say so in the + "parport.cfg" file, to avoid breaking anyone with that mutant + config. But update the User's Guide to include a sane example for + the LP2 port. Finally document the "presto_serial" command. Signed-off-by: David Brownell + +2010-01-09 David Brownell + + * : src/flash/nor: usage/help/doc updates Make "usage" messages use the same EBNF as the User's Guide; no + angle brackets. Improve and correct various helptexts. Don't use "&function"; a function's name is its address. Remove a + couple instances of pointless whitespace; shrink a few overlong + lines; fix some bad indents. Add TODO list entry re full support for NAND/NOR bank names. Signed-off-by: David Brownell + +2010-01-09 David Brownell + + * : src/server: usage/help/doc updates Make "usage" messages use the same EBNF as the User's Guide; no + angle brackets. Improve and correct various helptexts. Specifically for the port commands, clarify that the number is + optional, and omitting it causes the current number to be displayed. Don't use "&function"; a function's name is its address. Remove a + couple instances of pointless whitespace; shrink a few overlong + lines. Signed-off-by: David Brownell + +2010-01-08 David Brownell + + * : PLD: usage/help updates Make "usage" messages use the same EBNF as the User's Guide; no + angle brackets. Improve and correct various helptexts. Don't use "&function"; a function's name is its address. Remove a + couple instances of pointless whitespace, shrink a few overlong + lines. Signed-off-by: David Brownell + +2010-01-08 David Brownell + + * : Doc/examples: clarify usage messages Update/bugfix the "hello" example; emphasize using EBNF syntax, + matching the User's Guide. Correct the Texinfo style guide to say + EBNF, not BNF. Signed-off-by: David Brownell + +2010-01-08 David Brownell + + * : MFLASH: help/usage updates Make "usage" messages use the same EBNF as the User's Guide; no + angle brackets. Improve and correct various helptexts. Don't use "&function"; a function's name is its address. Remove a + couple instances of pointless whitespace. Signed-off-by: David Brownell + +2010-01-08 David Brownell + + * : NOR: add FIXMEs for writing ones It can invalidate ECC codes, and in general is not guaranteed to + work. (However on some chips it _appears_ to behave.) Just don't + do it; don't write in those cases. Signed-off-by: David Brownell + +2010-01-07 David Brownell + + * : ARM966: help/usage updates Usage syntax messages have the same EBNF as the User's Guide; there + should be no angle brackets in either place. Fix the User's Guide to say where the magic CP15 bits are defined; + and add comments in case someone provides mcr/mrc methods. Signed-off-by: David Brownell + +2010-01-07 David Brownell + + * : ARM720: help/usage updates Deprecate the "pass an instruction opcode" flavor of cp15 access in + favor of the "arm mcr ..." and "arm mrc ..." commands, which offer + fewer ways to break things. Use the same EBNF syntax in the code as for the user's guide. Update User's Guide to say where to find those magic values (which + table in the ARM920 TRM). Signed-off-by: David Brownell + +2010-01-07 David Brownell + + * : ARM11: help/usage updates Usage syntax messages have the same EBNF as the User's Guide; there + should be no angle brackets in either place. Uupdate some helptext to be more accurate. Fix the User's Guide in a few places to be more consistent (mostly + to use brackets not parentheses) and to recognize that parameter may + be entirely optional (in which case the command just displays + output, and changes nothing). Also reference NXP, not Philips, for + LPC chips. Don't use "&function"; functions are like arrays, their address is + their name. Signed-off-by: David Brownell + +2010-01-07 David Brownell + + * : ARMv7: help/usage updates Provide helptext which was sometimes missing; update some of it to + be more accurate. Usage syntax messages have the same EBNF as the User's Guide; there + should be no angle brackets in either place. Don't use "&function"; functions are like arrays, their address is + their name. Shrink some overlong lines, remove some empties. Add a couple comments about things that should change: those extra + TCK cycles for MEM-AP reads are in the wrong place (that might + explain some problems we've seen); the DAP command tables should be + shared, not copied. Signed-off-by: David Brownell + +2010-01-07 David Brownell + + * : target misc: help/usage updates Provide helptext which was sometimes missing; update some of it to + be more accurate. Usage syntax messages have the same EBNF as the User's Guide. Don't use "&function"; functions are like arrays, their address is + their name. Shrink some overlong lines; remove some empties. Signed-off-by: David Brownell + +2010-01-07 Spencer Oliver + + * : MIPS: change bulk_write_memory fallback msg to LOG_DEBUG Signed-off-by: Spencer Oliver + +2010-01-06 Spencer Oliver + + * : MIPS: fastdata bulk write fallback If fastdata access fails, then fallback to default + mips_m4k_write_memory Remove unnecessary fastdata loader verify + check Signed-off-by: Spencer Oliver + +2010-01-05 David Brownell + + * : don't require 'openocd.cfg' to start Starting the daemon with with just a bare "openocd" I saw: Can't find openocd.cfg That's not an error; don't treat it as if it were. There may be an + error later -- like, "no interface set up" -- but let messages only + report real errors, not fake ones. + +2010-01-05 David Brownell + + * : ARM: add comments re DAP assumptions I think some of these assumptions are not well-founded. Related, + that swjdp_transaction_endcheck() is a bit iffy. Signed-off-by: David Brownell + +2009-12-21 Spencer Oliver + + * : PIC32: enable ram execution add reset-init script to allow ram execution from reset, this is + required for ejtag fastdata access. Signed-off-by: Spencer Oliver + +2009-12-17 Spencer Oliver + + * : parport: output port as hex rather than dec Signed-off-by: Spencer Oliver + +2010-01-05 Øyvind Harboe + + * : gdb: fix regression in gdb_port command The gdb_port command can be invoked during normal execution to + report the port used for gdb, whereas it was listed as CONFIG stage + only, which caused an error when excuting it to return the reported + error. Also in line with the grander goal of making more commands available + during all "modes" (perhaps retiring config mode), there is no + particular reason to limit gdb_port to the config stage. Regression was introduced in: b3bf1d12b2fdfba1c1cbee3e1afbfbb27cbd1a26 aka v0.4.0-rc1-32-gb3bf1d1 Signed-off-by: Øyvind Harboe + +2010-01-04 David Brownell + + * : ARMv7-M: use AP_REG_* symbol Signed-off-by: David Brownell + +2010-01-03 David Brownell + + * : JTAG/drivers: ft2232 docs Add doxyegen description for this driver. Correct the helptext (configures *or* displays based on #params), + and usage (use the same BNF as the User's Guide). Remove superfluous #include Signed-off-by: David Brownell + +2010-01-03 David Brownell + + * : JTAG: Amontec JTAG accelerater "rtck" is back The command processing conversion a while back lost the "rtck" + enable/disable command; restore it. NOTE that having such a command is wrong; there's a standard way to + enable adaptive clocking ("speed 0"). Signed-off-by: David Brownell + +2010-01-03 David Brownell + + * : JTAG/drivers: amt_jtagaccel fixes + cleanup Build fixes: it failed abysmally with PPDEV enabled. Swapped a + build-time error with a FIXME comment in the affected macros. Cleanup: remove "&" before function pointers, and excess indent, for + the interface struct declaration. Signed-off-by: David Brownell + +2010-01-02 David Brownell + + * : ARM: dap info fix + tweaks Fix: don't print the BASE address except if it's a MEM-AP; that's an + unlikely error, but there's no point getting it wrong. Tweaks: + comments, capitalization. Signed-off-by: David Brownell + +2010-01-02 David Brownell + + * : ARM: ADIv5 symbol and comment cleanup Instead of magic numbers, use their AP_REG_* constants. Rename the + ROM address symbol as BASE to match ARM's documentation. Comment various other symbols in the header; add some missing ones. + Remove an unused struct. Add some doxygen for stuff including the + DAP structure and initialization. Signed-off-by: David Brownell + +2010-01-02 David Brownell + + * : streamline and document helptext mode displays Most commands are usable only at runtime; so don't bother saying + that, it's noise. Moreover, tokens like EXEC are cryptic. Be more + clear: highlight only the commands which may (also) be used during + the config stage, thus matching the docs more closely. There are - Configuration commands (per documentation) - And also some commands that valid at *any* time. Update the docs to note that "help" now shows this mode info. This also highlighted a few mistakes in command configuration, + mostly commands listed as "valid at any time" which shouldn't have + been. This just fixes ones I noted when sanity testing. Signed-off-by: David Brownell + +2010-01-01 Dean Glazeski + + * : Add the current command to the command information I wanted to make it so I can be ignorant of a commands invocation + string, so I tried to use CMD_CURRENT (aka cmd->current) which is + supposed to house a pointer to the current command.  It turns out + that this wasn't being set. This patch adds the current command structure to the command + invocation structure before sending it along to the command handler. Signed-off-by: David Brownell + +2009-12-31 David Brownell + + * : User's Guide: warn about the forum Namely, that developers don't hang out; it's a users-only club. Signed-off-by: David Brownell + +2009-12-31 Antonio Borneo + + * : ARM7_9: Fix segfaults Handlers for commands - arm7_9 semihosting - $_TARGETNAME arp_reset assert 1 didn't check if target has + already been examined, and could segfault when using the NULL + pointer "arm7_9->eice_cache". Signed-off-by: Antonio Borneo + Signed-off-by: David Brownell + +2009-12-31 Antonio Borneo + + * : ARM9TDMI: Fix segfault. The handler for "arm9tdmi vector_catch ..." did not check if target + has already been examined. Without this fix it segfaults when using + NULL pointer "arm7_9->eice_cache". Signed-off-by: Antonio Borneo + Signed-off-by: David Brownell + +2009-12-30 Øyvind Harboe + + * : zy1000: add zy1000_ prefix to uart command less polution of the general namespace(preventive action, no + problems reported). Signed-off-by: Øyvind Harboe + +2009-12-29 Øyvind Harboe + + * : zy1000: reconfigure FPGA upon reset instead of just the CPU Signed-off-by: Øyvind Harboe + +2009-12-25 Øyvind Harboe + + * : zy1000: less warnings use inline for static functions in header files to avoid warnings + about fn not being used. Signed-off-by: Øyvind Harboe + +2009-12-28 Piotr Esden-Tempski + + * : Added floss-jtag interface config file. + +2009-12-28 Freddie Chopin + + * : stm32x commands get "usage" Add .usage fields to stm32x command_registration, so that "help + stm32x" shows required parameters. Signed-off-by: Freddie Chopin Signed-off-by: + David Brownell + +2009-12-28 Piotr Esden-Tempski + + * : NOR: last_addr also needs correction when checking alignment Otherwise the new alignment checking algorithm thinks that the + address is not aligned, because it is way beyond the last sector. Signed-off-by: David Brownell + +2009-12-27 David Brownell + + * : NOR: make flash_write_unlock() pad to sector end Resolve a regression when using newish automagic "write_image" + modes, by always padding to the end of affected sectors. Also document some issues associated with those automagic options, + in the User's Guide and also some related code comments. We might need similar padding at the *beginning* of some sectors, + but this is a minimalist fix for the problems which have currently + been reported (plus doc updates). Signed-off-by: David Brownell + +2009-12-09 Dean Glazeski + + * : Olimex SAM9-L9260 board configuration update. This updates the board configuration for the SAM9-L9260 board with + the configuration for the on-board NAND and dataflash. Included are + commands for configuring the AT91SAM9 NAND flash driver. Signed-off-by: David Brownell + +2009-12-26 David Brownell + + * : User's Guide: update GDB info Advise leaving background polling enabled; fix broken URL; add + simple program startup example. + +2009-12-26 David Brownell + + * : NOR: Allocate the right amount of memory Switch to calloc() to simplify review and initialization. + +2009-12-26 Antonio Borneo + + * : PARPORT code cleanup: Align elements in array. Signed-off-by: Antonio Borneo + +2009-12-21 David Brownell + + * : v0.4.0-rc1 milestone Winter Solstice, 2009. Signed-off-by: David Brownell + +2009-12-21 David Brownell + + * : Packaging fix Don't forget to list target/arm_opcodes.h Signed-off-by: David Brownell + +2009-12-20 David Brownell + + * : Cortex-M3: cleanup Misc: - Introduce some "struct reg" temporaries, for clarity - Shorten lines - Add some missing whitespace - Clean up comments - Add notes about some fault handling issues - Most of these errata workarounds are for *OLD* chip revisions Signed-off-by: David Brownell + +2009-12-21 Antonio Borneo + + * : arm7_9: Support VINITHI signal Command "reset halt" checks if PC properly resets, issueing warning: + "PC was not 0. Does this target need srst_pulls_trst?". Checking PC + against 0 is not always correct. Removed PC value check, as suggested by Øyvind Harboe. Signed-off-by: Antonio Borneo + Signed-off-by: U-PROPRIET-28D9DF\PROPRIETAIRE + + +2009-12-09 Dean Glazeski + + * : AT91SAM9 NAND flash driver. This creates the TCL interface for configuring an AT91SAM9 NAND + flash controller and implements the necessary functions to correctly + work with a NAND flash device connected to the chip. This includes + updates to the driver list and the Makefile.am to support building + the driver and also houses the documentation update in openocd.texi. Signed-off-by: David Brownell + +2009-12-19 David Brownell + + * : ETM: add "etm trigger_debug" command In conjunction with manual register setup, this lets the ETM trigger + cause entry to debug state. It should make it easier to test and + bugfix the ETM code, by enabling non-trace usage and isolating bugs + specific to thef ETM support. (One current issue being that trace + data collection using the ETB doesn't yet behave.) For example, many ARM9 cores with an ETM should be able to implement + four more (simple) breakpoints and two more (simple) watchpoints + than the EmbeddedICE supports. Or, they should be able to support + complex breakpoints, incorporating ETM sequencer, counters, and/or + subroutine entry/exit criteria int criteria used to trigger debug + entry. Signed-off-by: David Brownell + +2009-12-19 David Brownell + + * : ETM: start cleaning up ETM_CTRL bit handling Provide better comments for the ETM_CTRL bits; use the correct bit + for half/full clock mode; and define a few more of the bits + available from the earliest ETM versions. The new bit defintions use ETM_CTRL_* names to match their register + (instead of ETM_PORT_* or ETMV1_*). For clarity, and better + matching to docs, they are defined with bitshifting not pre-computed + masks. Stop abusing typdefs for ETM_CTRL values; such values are not + limited to the enumerated set of individual bit values. Rename etm->portmode to etm->control ... and start morphing it into + a single generic shadow of ETM_CTRL. Eventually etm->tracemode + should vanish, so we can just write etm->control to ETM_CTRL. Restore an "if" that somehow got dropped. Signed-off-by: David Brownell + +2009-12-19 David Brownell + + * : NEWS: mention libftdi 0.17 + +2009-12-18 David Brownell + + * : Subject: flash fill[bwh] should use bulk i/o It's currently allocating a big buffer but writing it out in units + of sizeof(host's pointer) ... sub-optimal. Plus fix a couple minor coding style goofs. Signed-off-by: David Brownell + +2009-12-18 David Brownell + + * : XScale: better {read,write}_phys() We can actually do the right thing if the MMU is off; save the error + message for the phys-but-MMU-enabled path, which is what isn't yet + supported. Signed-off-by: David Brownell + +2009-12-18 David Brownell + + * : stellaris: update bulk flash writes Try to right-size the SRAM buffers, by not: - using them for very small writes - giving up when a large buffer isn't available - allocating buffers much larger than their data Also don't: - bother loading the code unless we allocate the writebuffer too - be so verbose with messaging: * be more concise * reduce importance (e.g. DEBUG not WARNING) * remove duplication The minimum buffer size is something of a guess. It's eight times + smaller than before, almost the same size as the code being + downloaded. It probably deserves some tuning. Also, note an erratum affecting flash protection on some chips; and + narrow many over-wide lines affected by the above changes. Signed-off-by: David Brownell + +2009-12-17 Dean Glazeski + + * : NAND read data page refactor. Added a new function to encapsulate reading a page of data from a + NAND device using either the read_block_data function of a NAND + controller or to use direct reading of data from the NAND device. This also adds some performance enhancements and uses the read_data + function if the read_block_data function fails safely (because it + can't allocate a buffer in the working area). [dbrownell@users.sourceforge.net: fix fault handling, whitespace] Signed-off-by: David Brownell + +2009-12-16 David Brownell + + * : Remove duplicate Olimex-"tiny" interface We already have tcl/interface/olimex-jtag-tiny.cfg and don't need a + clone of it. + +2009-12-16 David Brownell + + * : stellaris: comments Someday revisit various issues: Tempest parts support writing more + than one word at a time; for some target firmware it might be + necessary to save and restore flash IRQ configuration. (The safest + policy is likely to always reset after flash updates.) Plus swap some undesirable TAB characters with SPACE. Signed-off-by: David Brownell + +2009-12-16 David Brownell + + * : stellaris: remove needless code No point in reading and discarding a status value when fetching part + description data. Or having that needless "#if 0" code. Signed-off-by: David Brownell + +2009-12-16 David Brownell + + * : NOR: bugfix "flash fill[bwh] ..." helptext These commands don't have a "bank" parameter. Signed-off-by: David Brownell + +2009-12-15 Øyvind Harboe + + * : ecos: crisper implementation of timeval_ms() A crisper/faster implementation under eCos that makes profiling a + tad easier. Signed-off-by: Øyvind Harboe + +2009-12-15 David Brownell + + * : more tcl/{board,target} cleanup Remove more remnants of the old "jtag_device" syntax. Don't [format "%s.cpu" $_CHIPNAME] ... it's needless complexity. Remove various non-supported "-variant" target options; they're not + needed often at all. Flag some of the board files as needing to have and use target files + for the TAP and target declarations. Signed-off-by: David Brownell + +2009-12-14 David Brownell + + * : XScale: use all-ones for BYPASS, not five-ones PXA3xx has more than five bits in IR. Signed-off-by: David Brownell + +2009-12-15 Øyvind Harboe + + * : zy1000: keep up with command.h cleanup Signed-off-by: Øyvind Harboe + +2009-12-15 Øyvind Harboe + + * : imx31: move srst delay into config script reset init/run now works again. Signed-off-by: Øyvind Harboe + +2009-12-14 David Brownell + + * : ARM: disassemble STM correctly There is no "STMMIDA" instruction. There is however "STMDAMI". Signed-off-by: David Brownell + +2009-12-14 Yegor Yefremov + + * : Common target file for Stellaris chips Common target.cfg file for LM3S CPU family [dbrownell@users.sourceforge.net: rename, generalize more] Signed-off-by: Yegor Yefremov + Signed-off-by: David Brownell + +2009-12-14 David Brownell + + * : jtag: add '-ignore-version' option Add a "-ignore-version" to "jtag newtap" which makes the IDCODE + comparison logic optionally ignore version differences. Update the "scan_chain" command to illustrate this by showing the + "*" character instead of the (ignored) version nibble. Signed-off-by: David Brownell + +2009-12-13 David Brownell + + * : target: further shrink Jim-awareness Don't include from target.h ... not everything which + touches targets needs to be able to talk to Jim. Plus, most files + include this header by another path. Also, switch the affected files to use the classic sequence for + #included files: all first, then the + "local_headers.h". This helps prevent growth of problematic + layering, by minimizing entanglement. Signed-off-by: David Brownell + +2009-12-11 David Brownell + + * : ARM11: avoid pointless status returns For some routines that only returned ERROR_OK and where the caller + never checked ... don't bother. Remove some noise, and bugfix some + comments. Signed-off-by: David Brownell + +2009-12-11 Zachary T Welch + + * : fix 'write_image' usage information The 'flash write_image' command erroneously listed the bank number, + when it actually uses target addresses to do that lookup for the + user. + +2009-12-11 David Brownell + + * : ARM: disassembly fixes for LDC/STC/MRRC/MCRR Properly detect all of these, including the "2" variants; and bugfix + parameter display for LDC and STC. Signed-off-by: David Brownell + +2009-12-10 Spencer Oliver + + * : server: add server_preinit which is called before config file is + parsed. This fixes the issue under native win32 of the socket interface not + being enabled (via WSAStartup) before init is called from a script. Signed-off-by: Spencer Oliver + +2009-12-10 Øyvind Harboe + + * : gdb_server: use more local variables in inner loop of fetching + packetstiny refactoring to allow optimisation of inner loops Some profiling information for arm7 16MHz GDB load operation shows + gdb_get_packet_inner() near the very top. Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls Ts/call Ts/call name 52.91 2.27 2.27 + embeddedice_write_dcc 11.89 2.78 0.51 + gdb_get_packet_inner 8.86 3.16 0.38 + memcpy 3.26 3.30 0.14 + idle_thread_main(unsigned int) 3.03 3.43 0.13 + cyg_in_cksum Signed-off-by: Øyvind Harboe + +2009-12-10 Øyvind Harboe + + * : optimisation: tiny optimisation for embedded ice use two shift operations instead of three to set embedded ice + register. Signed-off-by: Øyvind Harboe + +2009-12-10 David Brownell + + * : anotyer cygwin compile fix Signed-off-by: David Brownell + +2009-12-09 David Brownell + + * : ARM: update arm_opcodes.h copyright I neglected to copy Magnus' copyright when I moved several + declarations from the ARMv7-M header. Signed-off-by: David Brownell + +2009-12-09 David Brownell + + * : Comment and doxygen fixes Signed-off-by: David Brownell + +2009-12-08 Rafael Campos Las Heras + + * : Fix compilation error with gcc 4.4.1 Signed-off-by: Rafael Campos Las Heras + +2009-12-08 David Brownell + + * : target: remove needless "extern"s Most of these happened to be in the target.h file. Some of those are associated with symbols that could be removed at + some point ... e.g. NVP_ASSERT/true and its sibling + NVP_DEASSERT/false. Signed-off-by: David Brownell + +2009-12-08 David Brownell + + * : ARM: cygwin complile fixes It's as if despite integers being 32-bits, GCC refuses to convert a + "uint32_t" to one of them. Signed-off-by: David Brownell + +2009-12-04 Øyvind Harboe + + * : minidriver: fix inline capability of minidriver Low latency low CPU processing power systems(embedded) will benefit + greatly from being able to inline certain jtag_add_xxx() fn's. The + trick is that this has to be done in such a way as to allow + implementing an OpenOCD API with a shared library(eventually) on a + PC hosted OpenOCD. Signed-off-by: Øyvind Harboe + +2009-12-05 Øyvind Harboe + + * : build: add build/src to include path This allows including generated include files. Signed-off-by: Øyvind Harboe + +2009-12-07 David Brownell + + * : ARM: list number of HW breakpoints/watchpoints When starting up, say how many hardware breakpoints and watchpoints + are available on various targets. This makes it easier to tell GDB how many of those resources exist. + Its remote protocol currently has no way to ask OpenOCD for that + information, so it must configured by hand (or not at all). Update the docs to mention this; remove obsolete "don't do this" + info. Presentation of GDB setup information is still a mess, but at + least it calls out the three components that need setup. Signed-off-by: David Brownell + +2009-12-07 David Brownell + + * : ARM: don't clone arm_arch_state() code Have various ARM cores delegate to arm_arch_state() to display basic + information, instead of duplicating that logic. This shrinks the code, makes them all report when semihosting is + active, and highlights which data are specific to this core. (Like + ARM720 not having separate instruction and data caches.) Signed-off-by: David Brownell + +2009-12-07 David Brownell + + * : ARM: use not armv4_5.h Move most declarations in to and + update users. What's left in the older file is stuff that I think should be + removed ... the old register cache access stuff, which makes it + awkward to support microcontroller profile (Cortex-M) cores. The armv4_5_run_algorithm() declaration was moved too, even though + it's not yet as generic as it probably ought to be. Signed-off-by: David Brownell + +2009-12-07 David Brownell + + * : ARM: move opcode macros to Move the ARM opcode macros from , and a few Thumb2 + ones from , to more appropriate homes in a new + file. Removed duplicate opcodes from that v7m/Thumb2 set. Protected a few + macro argument references by adding missing parentheses. Tightening up some of the line lengths turned up a curious artifact: + the macros for the Thumb opcodes are all 32 bits wide, not 16 bits. + There's currently no explanation for why it's done that way... Signed-off-by: David Brownell + +2009-12-07 David Brownell + + * : ARM: disassemble two more v6+ instructions The SRS and RFE instructions speed exception entry/exit by making it + easy to save and restore PC and SPSR. This handles both ARM and + Thumb2 encodings. Fix minor PLD goofage; that "should never reach this point" can't + happen, so remove it. Signed-off-by: David Brownell + +2009-12-07 David Brownell + + * : OMAP2420: define reset-assert event Behave like OMAP3530: force global software reset. Given the patch + to teach ARM11 how to use these events, and use VCR to catch the + reset vector, this works better than either the current reset logic + or than using SRST. Signed-off-by: David Brownell + +2009-12-06 Zachary T Welch + + * : add 'flash list', rewrite 'flash banks' Rename the existing 'flash banks' implementation as 'flash list', + and replace the broken 'flash_banks' TCL wrapper with a new command + handler. Adds documentation for the new 'flash list' command in the user + guide. + +2009-12-06 Zachary T Welch + + * : fix NOR flash regression When factoring the bank setup command into flash_bank_add(), I + forgot to include a call to the new helper. + +2009-12-05 Mathias Kuester + + * : NOR: add 29LV400BC flash device Signed-off-by: David Brownell + +2009-12-05 Nicolas Pitre + + * : ARM semihosting: work with both low and high vectors Signed-off-by: Nicolas Pitre Signed-off-by: David + Brownell + +2009-12-04 Zachary T Welch + + * : move remaining nand helper files Move remaining NAND implementation files into src/flash/nand/. + +2009-12-04 Zachary T Welch + + * : split NAND driver handling into nand/driver.[ch] This work parallels the NOR directory, encapsulating the NAND + drivers into a separate file. This takes an extra step by + encapsulating the type of data structure used to manage the drivers, + allowing it to be changed from an array to a dynamic list in the + future. + +2009-12-04 David Brownell + + * : ARM: rename armv4_5_build_reg_cache() as arm_*() Signed-off-by: David Brownell + +2009-12-04 David Brownell + + * : ARM: misc generic cleanup Remove an undesirable use of the CPSR symbol ... it needs to vanish. + Flag mode-to-number stuff as obsolete; say why ... should also + vanish. Get rid of no-longer-used mode and state typedefs. Comment a few of the implicit ties to "classic ARM". Signed-off-by: David Brownell + +2009-12-04 David Brownell + + * : ARM: switch target_to_armv4_5() to target_to_arm() And remove that old symbol. Signed-off-by: David Brownell + +2009-12-04 David Brownell + + * : ARM: rename armv4_5_mode_* AS arm_mode_* Signed-off-by: David Brownell + +2009-12-04 David Brownell + + * : ARM: rename ARMV4_5_STATE_* as ARM_STATE_* Signed-off-by: David Brownell + +2009-12-04 David Brownell + + * : ARM11: basic watchpoint support Use the DPM watchpoint support; remove old incomplete stubs. Signed-off-by: David Brownell + +2009-12-04 Zachary T Welch + + * : reorder build order of src directory Descend into the library modules in order, from bottom-to-top. + +2009-12-04 Zachary T Welch + + * : split flash.h into into flash/nor/*.h Move the bulk of the flash.h file into flash/nor/core.h, leaving an + empty husk that will be removed in the next patch. The NOR driver structure is an implementation detail, so move it + into its own private header file along with + helper declaration for finding them by name. + +2009-12-04 Zachary T Welch + + * : split NOR and NAND flash headers Moves common flash errors to to decouple these two + mostly unrelated trees of code. + +2009-12-04 Zachary T Welch + + * : add flash/nor/drivers.c Encapsulates access to the flash_drivers array, providing a base of + operations for future dynamic driver module loading features. + +2009-12-04 David Brownell + + * : ARM: semihosting entry cleanup Clean up arm_semihosting() entry a bit, comment some issues and just + which SVC opcodes are getting intercepted. Microcontroller profile + cores will need a new entry, since they use BKPT instead (and don't + have either SVC mode or an SPSR register). Signed-off-by: David Brownell + +2009-12-04 David Brownell + + * : User's Guide: more semihosting info List it in the concept index, in the section about target software + changes a project might want to consider, and in the section about + debug messaging. Signed-off-by: David Brownell + +2009-12-03 Zachary T Welch + + * : add flash/nor/core.[ch] The newly moved flash TCL routines access the internals of the + module too much. Fix the layering issues by adding new core NOR + flash APIs: : - flash_driver_find_by_name() - self-descriptive : - flash_bank_add() - encapsulates adding banks to bank + list - flash_bank_list() - encapsulates retreiving bank list This allows the externs in flash/nor/imp.h to be removed, and these + mechanisms may now be re-used by other flash module code. + +2009-12-03 Zachary T Welch + + * : separate Jim from jtag/core.c After previous efforts, only one Jim routine remained in + jtag/core.c, and moving it to jtag/tcl.c painlessly finishes + separating these layers. The headers need separating, but the + implementation is clean. + +2009-12-03 Zachary T Welch + + * : check top-level command registrations When calling module_register_commands, the return value needs to be + checked for failures. Instead of duplicating code, use an array of + function pointers to the identical registration functions to iterate + over during startup. + +2009-12-04 David Brownell + + * : target: cygwin build fixes Signed-off-by: David Brownell + +2009-12-03 Nicolas Pitre + + * : basic ARM semihosting support Semihosting enables code running on an ARM target to use the I/O + facilities on the host computer. The target application must be + linked against a library that forwards operation requests by using + the SVC instruction that is trapped at the Supervisor Call vector by + the debugger. The "hosted" library version provided with + CodeSourcery's Sourcery G++ Lite for ARM EABI is one example. This is currently available for ARM9 processors, but any ARM variant + should be able to support this with little additional work. Tested using binaries compiled with Sourcery G++ Lite 2009q1-161 and + ARM RVCT 3.0. [dbrownell@users.sourceforge.net: doc tweaks, NEWS] Signed-off-by: Nicolas Pitre Signed-off-by: David + Brownell + +2009-11-16 Dean Glazeski + + * : Make ARM NAND I/O operations aware of last op Updates the ARM NAND I/O code to look at and update the op field of + arm_nand_data to reflect the last operation performed. It uses this + field to copy the correct code to the target in the case where the + struct is used for reads and writes. Signed-off-by: David Brownell + +2009-11-20 Dean Glazeski + + * : NAND page command refactoring. Created a new function that handles sending a command and the + address information for pages to a NAND device. [dbrownell@users.sourceforge.net: tweaked line lengths, name + 'oob_only'] Signed-off-by: David Brownell + +2009-12-03 David Brownell + + * : ARM DPM: share debug reason logic No point in both ARM11 and Cortex-A8 having private copies of the + logic sorting out e.g. DBG_REASON_WATCHPOINT. Add and use a shared routine for this ... there's actually a bunch + more debug entry logic that could be shared, this is just a start on + that. Note that this routine fixes a bug observed in the ARM11 + code, where some abort mode quirks were displayed as being an + unknown debug reason; and also silences needless ARM11 chatter. Likewise with private copies of DSCR ... add one to the DPM struct. + Save it as part of setting DBG_REASON_* so later patches can switch + over to using that copy. Signed-off-by: David Brownell + +2009-12-03 David Brownell + + * : ARM DPM: make DSCR bit defs sharable Move the symbols for these bits from "armv7a.h" to "arm_dpm.h", + where they can be seen and used not just by Cortex-A but also by the + ARM11 (armv6) code. Change them from bit numbers to bit masks ... this matches the usage + in ARM11 code, and also makes it easier to read. Rename DSCR_EXT_INT_EN as DSCR_ITR_EN to match the docs; it's + enabling ITR functionality, not external interrupts, so this changes + the name to be less misleading. (There *IS* a bit affecting + interrupts, and this isn't it.) Signed-off-by: David Brownell + +2009-12-03 Zachary T Welch + + * : fix double 'init' regression To prevent regression in the behavior of 'init', we allow it to run + in any mode. If provided with -c init and with -c noinit, then the + second init at startup caused a spurious mode failure. Let 'init' + handle it. + +2009-12-03 Øyvind Harboe + + * : zy1000: include files have moved about now compiles again after include files were moved about to reduce -I + usage and stop using quotes but rather angle brackets for include + files. Signed-off-by: Øyvind Harboe + +2009-12-03 Zachary T Welch + + * : change #include "../hello.h" to "hello.h" Before we can -I the top-level src/ directory alone, references to + "hello.h" must be updated. This is an internal header, so it does + not need angle brackets. + +2009-12-03 Zachary T Welch + + * : change #include "svf.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "svf.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "telnet_server.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "telnet_server.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "httpd.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "httpd.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "s3c24xx_regs.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "s3c24xx_regs.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "nand.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "nand.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "flash.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "flash.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "trace.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "trace.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "target.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "target.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "mips_ejtag.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "mips_ejtag.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "mips32.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "mips32.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "etm.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "etm.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "breakpoints.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "breakpoints.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "armv7m.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "armv7m.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "armv4_5_mmu.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "armv4_5_mmu.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "armv4_5.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "armv4_5.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "arm_dpm.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "arm_dpm.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "arm9tdmi.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "arm9tdmi.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "arm7tdmi.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "arm7tdmi.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "arm11.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "arm11.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "minidriver.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "minidriver.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "interface.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "interface.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "types.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "types.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "replacements.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "replacements.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "log.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "log.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "ioutil.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "ioutil.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "configuration.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "configuration.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-12-03 Zachary T Welch + + * : change #include "binarybuffer.h" to Changes from the flat namespace to heirarchical one. Instead of + writing: #include "binarybuffer.h" the following form should be used. #include The exception is from .c files in the same directory. + +2009-11-28 Zachary T Welch + + * : change autoconf #include in configure.in Updates "system.h" and "replacements.h" with and + respectively. + +2009-12-03 Nicolas Pitre + + * : feroceon.c should be part of ARM7_9_SRC The Feroceon and Dragonite cores are similar to the ARM926 and + ARM966 cores respectively. Signed-off-by: Nicolas Pitre + +2009-12-02 Zachary T Welch + + * : move jtag drivers to src/jtag/drivers Moves JTAG interface drivers to src/jtag/drivers/, Adds + src/jtag/drivers/Makefile.am. Builds libocdjtagdrivers.la. Flattens the rlink driver files into the drivers/ directory, adding + the 'rlink_' prefix or '.rlink' suffix as appropriate. + +2009-12-01 Zachary T Welch + + * : move nand drivers to src/flash/nand/ Moves NAND drivers to src/flash/nand/. Adds + src/flash/nand/Makefile.am. Builds libocdflashnand.la. + +2009-12-02 David Brownell + + * : ARM11: store a clean copy of DSCR Just store a clean copy of DSCR in the per-CPU struct, so we + trivially pass a pointer to a recent copy. This replaces the + previous "last_dscr" and cleans up most of the related calling + conventions ... but it doesn't remove the other DSCR copy. + +2009-12-02 David Brownell + + * : ARM11: don't expose RDTR Don't expose the RDTR register through the register cache any more. + If anyone wants Tcl scripts to be able to use DCC based + communication with app code in the target, this wouldn't do it. Bugfix: don't trust the Tcl-accessible version of DSCR to flag + whether RDTR needs to be restored when resuming. + +2009-12-02 David Brownell + + * : ARM11: remove arm11->target Don't need/want arm11->target; we have arm11->arm.target instead. + Also remove some unused watchpoint stuff. + +2009-12-02 Zachary T Welch + + * : fix configure problem when building w/o USB If building OpenOCD without any USB drivers, a warning would appear + because $build_usb is never set to a sane default. This fixes it. + +2009-12-02 Zachary T Welch + + * : fix 'target init' command registration The command handler registration was put at the top level, rather + than as a subcommand. Move it to where it belongs. + +2009-12-01 Zachary T Welch + + * : remove #if BUILD_HTTPD Add httpd_stubs.c to provide no-op implementations of httpd_start() + and httpd_stop(). Allows these routines to be called unconditionally and ensures the + libocdserver ABI remains unchanged regardless of whether this + feature was built-in or not. Prints a DEBUG message when the stub implementation is included. + +2009-12-01 Zachary T Welch + + * : remove #if logic for openocd_sleep_*lude Adds server_stubs.c to hold these routines, using automake logic to + ensure it gets included under the right conditions. + +2009-11-30 Zachary T Welch + + * : target: factor target_init() into pieces Moves body of target initialization loop into a helper function, + cleaning up its visual flow in the process. + +2009-11-30 Zachary T Welch + + * : flash: factor init to 'flash init' Split flash initialiation into 'flash init', called from 'init'. + +2009-11-30 Zachary T Welch + + * : nand: factor init to 'nand init' Split NAND initialization into 'nand init', which gets called from + the main 'init' command. + +2009-12-02 David Brownell + + * : ARMv7a/Cortex-A8: report watchpoint trigger insn Save and display the address of the instruction which triggered the + watchpoint. Because of pipelining, that's well behind the PC value + when debug entry completes. (Example in a subroutine that had been + returned from...) Remove unused A8 stuff, mostly watchpoint hooks from the header. Signed-off-by: David Brownell + +2009-12-02 Øyvind Harboe + + * : zy1000: keep up with startup refactoring work. keep up with server_init() introduction. Signed-off-by: Øyvind Harboe + +2009-12-01 David Brownell + + * : ARM: core DPM support for watchpoints This is a NOP unless the underlying core exposes two new methods, + and neither of the two cores using this (ARM11xx, Cortex-A8) do so + yet. This patch only updates those cores so they pass a flag saying + whether or not to update breakpoint and watchpoint status before + resuming; and removing some now-needless anti-segfault code from + ARM11. Cortex-A8 didn't have that code ... yes, it segfaulted when + setting watchpoints. NOTE: this uses a slightly different strategy for setting/clearing + breakpoints than the ARM7/ARM9/etc code uses. It leaves them alone + unless it's *got* to change something, to speed halt/resume cycles + (including single stepping). ALSO NOTE: this under-delivers for Cortex-A8, where regions with + size up to 2 GBytes can be watched ... it handles watchpoints which + ARM11 can also handle (size 1/2/4 bytes). Should get fixed later. Signed-off-by: David Brownell + +2009-12-01 David Brownell + + * : Tcl and doc: update to match new 'arm mcr ...' etc Make them match the C code. Signed-off-by: David Brownell + +2009-12-01 Øyvind Harboe + + * : zy1000: keep up with latest changes to command handling Keep up with Jim Tcl interpreter creation cleanup. Signed-off-by: Øyvind Harboe + +2009-12-01 David Brownell + + * : ARM11: remove previous mcr()/mrc() methods We don't need this code, now that the DPM code handles it. Signed-off-by: David Brownell + +2009-12-01 David Brownell + + * : ARM: implement mrc()/mcr() as DPM ops Instead of having separate ARM11 and Cortex-A8 implementations of + this code, have one shared implementation which just builds on the + existing "run instruction via R0" support. This enables followup patches to remove that now-unused code from + those two drivers. (Patches to move the "mrc" and "mcr" code into + "struct arm" are due too ... MIPS and other cores do not support + those ARM-specific concepts.) Signed-off-by: David Brownell + +2009-12-01 David Brownell + + * : ARMv7-A: stop using CP15 ops The ARMv7-A code uses read_cp15() to access fault registers. + Instead, use DPM operations directly, passing in the relevant MRC + instructions. This eliminates per-operation overhead (though it'll be hard to + observe, this is uncommon) and helps eliminate read_cp15(). Signed-off-by: David Brownell + +2009-11-30 Øyvind Harboe + + * : main: invoke jtag_interface_quit() explicitly There is no particular reason to invoke jtag_interface_quit() on the + atexit() handler, it just makes the code more obtuse and stops other + legitimate usage of atexit(). Signed-off-by: Øyvind Harboe + +2009-11-30 David Brownell + + * : XScale: restore_context() cleanup Clean up two aspects to this routine: bad naming, since it doesn't + restore the context, just the banked registers; and excess + indentation for the bulk of the code. Also make some of its call sites stash the function's return code; + someday they should use it for error checking. Signed-off-by: David Brownell + +2009-11-29 Zachary T Welch + + * : remove interp global variable! Finish removing references to the 'interp' global variable from the + command module, encapsulating all reference via command_context. Eliminates use of the global entirely, so it can be removed. + Hurrah! + +2009-11-29 Zachary T Welch + + * : do not extern 'interp' from command.c Adds 'interp' field to command_context, chasing the few remaining + references to the global variable outside of the command module. + +2009-11-29 Zachary T Welch + + * : jtag: avoid using interp global variable Adds 'interp' field to jtag_tap_event_action structure to avoid + using the global variable of same name. + +2009-11-29 Zachary T Welch + + * : make syntax errors respond with 'usage' The 'help' text will become more verbose, so its entire text will be + far more than desired when you only borked your syntax. The usage + still allows the commands to be looked up for more help. + +2009-11-29 Zachary T Welch + + * : improve command_done() API and docs command_done() does not need to return an error, but it needed + Doxygen comment. Provide some for copy_command_context as well. Note: this audit revealed some potential bugs with the command + context implementation. There was a reason that commands were added + at the end of the list. Shallow copying of command_context means + that the list is shared between them. And commands added at the + top-level before the pre-existing commands will not be available in + the shared context as they were before. Yikes! Fortunately, this does not seem to occur in general use, as + 'add_help_text' gets registered in startup.tcl and claims the first + slot in my own test cases. Thus, it seems that we have been masking + the issue for now, but it shows the need for further architectural + improvement in the core command module. + +2009-11-29 Zachary T Welch + + * : allow deferal of init Adds 'noinit' command to prevent OpenOCD from running 'init' at the + end up startup, allowing it to be given from telnet or TCL. This + provides the old behavior by default, and users can add this command + to their scripts to get the new behavior. + +2009-11-28 Zachary T Welch + + * : improve gdb_init() sequence Rework gdb_init to create flexible APIs (gdb_target_add_{one,all}) + and static helper (gdb_target_start) for starting GDB services. + Eliminates duplicated code and provides general mechanisms for + adding GDB services. The 'init' command is updated to call the new + API, and later patches can decouple its policy of adding all targets + therein. Provides the new capability to use both piped and TCP servers when + multiple targets are defined. The first target fills the pipe, and + others will be started on TCP ports (unless disabled, i.e. + gdb_port=0). + +2009-11-29 David Brownell + + * : XScale: clean up full_context() (#2) Streamline the loop by continuing as soon as we know there's no work + to be done; this lets us un-indent almost everything. Signed-off-by: David Brownell + +2009-11-29 David Brownell + + * : XScale: debug entry uses new register mapping Use the new mapping interfaces in the debug entry path. SPSR and + the banked registers now have smaller and faster accessors ... use + them. Signed-off-by: David Brownell + +2009-11-29 Marek Vasut + + * : XScale: initial PXA3xx support [dbrownell@users.sourceforge.net: user's guide; variant param is + optional] Signed-off-by: David Brownell + +2009-11-28 David Brownell + + * : bugfix: 'init' changes state, not main() Code other than main() may invoke "init". When it does so, + customized handlers may need to run ... so make sure the command + context state is updated before they do so. Signed-off-by: David Brownell + +2009-11-28 David Brownell + + * : Cortex-M3: don't chain "struct arm" commands Those commands presume support for the "classic" set of CPU modes + (FIQ, supervisor, IRQ, etc) ... which aren't supported by the + ARMv7-M or ARMv6-M architectures. They also presume a "struct arm" + base type, which this code doesn't use. We haven't cleaned up the register handling enough to be able to + share any of those "base" methods. Signed-off-by: David Brownell + +2009-11-25 Zachary T Welch + + * : add more stub handlers to testee target Prevent everything from crashing when exercising various commands. + +2009-11-25 Zachary T Welch + + * : split jim_target into multiple handlers The 'target' command group was implemented using its own command + dispatching, which can be eliminated by using the new chained + command registration mechanism. This patch splits the jim_target() + function into individual handlers, which makes them to be visible to + the help and usage commands. These one-trick handlers are much + easier to understand. + +2009-11-26 Zachary T Welch + + * : improve jtag_tap_configure Splits bulk of the jtag_tap_configure into jtag_tap_configure_event, + removing three or four levels of indentation in the process. The + resulting code was stylistically improved in other ways, but it + should be functionally identical. + +2009-11-26 Zachary T Welch + + * : begin moving JTAG jim handlers/helpers Moves the tertiary jim handlers and required static helpers to the + top of tcl.c, defining them in a new registration array that is + chained in both the top-level context and under the jtag command. + The top-level commands can be removed at some point in the future to + reduce clutter. + +2009-11-28 Zachary T Welch + + * : remove redundant 'rm' command handler Two 'rm' commands were implemented and registered. This removes the + version that would have never been called prior to refactoring the + command registration. + +2009-11-28 Zachary T Welch + + * : include mode information in help text. Extends the help output to list the valid modes for each commands. + Fixes a memory leak of the returned command_name() string. + +2009-11-27 Zachary T Welch + + * : add command private data setter/accessor Presently, commands registration taks a static handler data pointer. + This patch adds support for commands that require a dynamic pointer, + such as those registered in a dynamic context (e.g. subcommands for + a user-created 'foo.cpu' command). The command_set_handler_data + will update a command (group) to use a new context pointer, while + the CMD_DATA macro allows command handlers to access the value. Jim + handlers should find this value in interp->cmdPrivData. + +2009-11-27 Zachary T Welch + + * : remove unknown handler Updates command registration to provide top-level handlers for all + commands, rather than falling back onto the 'unknown' command. + Instead, that same handler is registered for placeholders, providing + the same functionality under the root verb command name instead. + This permits users to implement their own 'unknown' function, and it + resolves some mind-bending breakage related to function object + lookup while recursing. Changes 'ocd_bounce' to call 'ocd_command' and 'ocd_help' from the + wrapper directly, rather than bouncing through their wrappers. This + prevents endless recursion caused by the above changes, whereby the + 'command' wrapper's type check would blow the stack to hell and + gone. + +2009-11-27 Zachary T Welch + + * : add 'command type' introspective handler Adds the 'command' group handler, with the 'type' command producing + a string that tells whether the given command is 'native' (for + Jim-based command handlers), 'simple' (for simple built-in + commands), 'group' for command group placeholders, and 'unknown' if + not found in the command registration tables (e.g. core built-ins + functions). + +2009-11-28 David Brownell + + * : ARM11: fix dbgtap JTAG_DEBUG There is no DEBUG() macro; don't call one! Always at least *parse* + debug code, to help prevent such errors. Signed-off-by: David Brownell + +2009-11-28 David Brownell + + * : target: remove unused TARGET_EVENT_OLD_* symbols Just two *_OLD_* symbols left... Signed-off-by: David Brownell + +2009-11-27 David Brownell + + * : omap3530.cfg: use new "reset-assert" event Replaces previous "reset-assert-pre" workaround. Signed-off-by: David Brownell + +2009-11-27 David Brownell + + * : target: groundwork for "reset-assert" event This defines a "reset-assert" event and a supporting utility + routine, and documents both how targets should implement it and how + config scripts should use it. Core-specific updates are needed to + make this work. Signed-off-by: David Brownell + +2009-11-27 Zachary T Welch + + * : fix regression causing duplicated output The command refactoring caused subcommand handlers to produce + duplicate output when run. The problem was introduced by failing to + ensure all such invocations went through a top-level "catcher" + script, prefixing the command name with the 'ocd_' prefix and + consuming its results. The fix is to ensure such a top-level "catcher" script gets created + for each top-level command, regardless of whether it has a handler. + Indeed, this patch removes all command registrations for + sub-commands, which would not have worked in the new registration + scheme anyway. For now, dispatch of subcommands continues to be handled by the new + 'unknown' command handler, which gets fixed here to strip the 'ocd_' + prefix if searching for the top-level command name fails initially. + Some Jim commands may be registered with this prefix, and that + situation seems to require the current fallback approach. + Otherwise, that prefix could be stripped unconditionally and the + logic made a little simpler. The same problem must be handled by + the 'help' command handler too, so its lookup process works as + intended. Overall, the command dispatching remains more complicated than + desired, but this patch fixes the immediate regressions. + +2009-11-27 Zachary T Welch + + * : update minidummy interface driver command handling Changes the interface definition field reference from + register_commands to commands, which allows the module to compile. + +2009-11-27 Øyvind Harboe + + * : zy1000: keep up with changes to log_init() fn's and return value for log_init() changed to void. Signed-off-by: Øyvind Harboe + +2009-11-16 Dean Glazeski + + * : ARM NAND I/O header documentation update. Fixed the header file to properly specify the doxygen documentation + for the items defined in it. Signed-off-by: David Brownell + +2009-11-16 Dean Glazeski + + * : ARM NAND I/O refactor code copying. Created a function for copying code to the working area on a target. + The NAND write and read functions are updated to include use of this + function. Signed-off-by: David Brownell + +2009-11-17 Dean Glazeski + + * : NAND Flash documentation update. Updated doxygen comments for different interface structures for the + NAND interface. Signed-off-by: David Brownell + +2009-11-24 Uwe Hermann + + * : update bug reporting information The Berlios bug-tracker is disabled, bug reports go to the list. Signed-off-by: Zachary T Welch + +2009-11-24 Uwe Hermann + + * : fix typos in source files Correct some spelling errors in source comments and printed output. Signed-off-by: Zachary T Welch + +2009-11-26 Eric Wetzel + + * : fix 'flash protect' and 'flash erase_sector' Command upgrading introduced two off-by-one bugs in the flash + commands. This patch fixes the 'flash {protect,erase_sector}' + commands to check that they have been passed the correct number of + arguments. Ammended during commit to fix help text for 'erase_address' too. + +2009-11-25 David Brownell + + * : target: target_get_name() --> target_type_name() There are two names that may matter on a per-target basis. One is a + per-instance name (for example, "at91sam7s.cpu"). The other is the + name of its type (for example, "arm7tdmi"), which is shared among + multiple targets. Currently target_get_name() returns the type name, which is + misleading and is rarely appropriate for target diagnostics. Rename + that as target_type_name(). Signed-off-by: David Brownell + +2009-11-25 David Brownell + + * : ARM: minor armv4/armv5 cleanup Lines of 300+ characters are still bad; debug tweaks. Signed-off-by: David Brownell + +2009-11-25 David Brownell + + * : ARM7/9: shrink run_algorithm_inner() lines 300+ characters is unreasonable. So is half that. Signed-off-by: David Brownell + +2009-11-20 Zachary T Welch + + * : update NEWS with recent developments Mention changes to flash bank command syntax, 'nand verify' command, + command error handling and reporting, and help/usage command + upgrades. + +2009-11-23 Zachary T Welch + + * : support OPENOCD_DEBUG_LEVEL environment setting Detect the OPENOCD_DEBUG_LEVEL setting in log_init(), allowing the + very early startup phases to be debugged. + +2009-11-24 Zachary T Welch + + * : update command handler documentation Adds sections on command registration and chaining, giving an + overview to developers that want to use these features. + +2009-11-21 Zachary T Welch + + * : improve command handling examples Removes hello and foo commands from top-level registration. + Instead, the dummy interface driver and faux flash driver have been + augmented to register these commands as sub-commands. + +2009-11-24 Zachary T Welch + + * : encapsulate and re-use log capture, retval setup Factors log capture while running script commands, eliminating + duplicated code between script_command and jim_capture. Factors + setting a command's Jim "retval" into a new helper as well. Using these new helpers in the new unknown command handler's fixes + possible regressions caused by these bits being missing. + +2009-11-23 Zachary T Welch + + * : improve usage and help command output Rewrite formatting code in C, removing last remenants of TCL help + code. Sinificantly improves the readability by using smarter indent + and wrap. + +2009-11-24 Zachary T Welch + + * : httpd: use register_commands() Updates httpd_start() to use register_commands() for 'readform' and + 'writeform' commands. Adds server/httpd.h to export the new + signatures for this function (and httpd_stop), which allows removing + the obsoleted declarations inside openocd.c. + +2009-11-23 Zachary T Welch + + * : refactor command_new to use command_registration Save stack space: use a struct. Makes it easier to add new + parameters. + +2009-11-23 Zachary T Welch + + * : remove target_type register_command callback Uses chaining of command_registration structures to eliminate all + target_type register_callback routines. Exports the command_handler + registration arrays for those target types that are used by others. + +2009-11-23 Zachary T Welch + + * : trace: use register_commands() + +2009-11-23 Zachary T Welch + + * : target: use register_commands() + +2009-11-23 Zachary T Welch + + * : etm_dummy: use register_commands() + +2009-11-23 Zachary T Welch + + * : etb: use register_commands() + +2009-11-23 Zachary T Welch + + * : cortex_a8: use register_commands() + +2009-11-23 Zachary T Welch + + * : armv7a: use register_commands() + +2009-11-23 Zachary T Welch + + * : arm9tdmi: use register_commands() + +2009-11-23 Zachary T Welch + + * : arm926ejs: use register_commands() + +2009-11-23 Zachary T Welch + + * : arm7_9_common: use register_commands() + +2009-11-23 Zachary T Welch + + * : arm11: use register_commands() + +2009-11-22 Zachary T Welch + + * : remove flash_driver->register_callbacks Replace flash_driver callback with pointer to command_registration. + Eliminates all related routines and allows drivers to omit commands. + +2009-11-22 Zachary T Welch + + * : str9xpec: use register_commands() + +2009-11-22 Zachary T Welch + + * : str7x: use register_commands() + +2009-11-22 Zachary T Welch + + * : stellaris: use register_commands() + +2009-11-22 Zachary T Welch + + * : nand: use register_commands() Eliminates 'nand_cmd' global variable. + +2009-11-22 Zachary T Welch + + * : lpc3180_nand_controller: use register_commands() + +2009-11-22 Zachary T Welch + + * : lpc2000: use register_commands() + +2009-11-22 Zachary T Welch + + * : ecos: use register_commands() + +2009-11-22 Zachary T Welch + + * : avrf: use register_commands() + +2009-11-22 Zachary T Welch + + * : at91sam3: use register_commands() + +2009-11-20 Zachary T Welch + + * : vsllink: use register_commands() Use register_commands() with command registration array. + +2009-11-20 Zachary T Welch + + * : presto: use register_commands() Use register_commands() with command registration array. + +2009-11-20 Zachary T Welch + + * : jlink: use register_commands() Use register_commands() with command registration array. + +2009-11-20 Zachary T Welch + + * : ft2232: use register_commands() Use register_commands() with a command registration array. + +2009-11-20 Zachary T Welch + + * : arm-jtag-ew: use register_commands() Uses register_commands() with command registration array. + +2009-11-23 Zachary T Welch + + * : pld: use static registration instead of callback Remove register_callbacks from pld_device structure, using an array + of command_registration records instead. + +2009-11-22 Zachary T Welch + + * : {,x}svf: use register_commands() Use register_commands() for registering {,x}svf commands. + +2009-11-20 Zachary T Welch + + * : log: use register_commands() Use register_commands() for logging callbacks. Improve help and add + proper usage. + +2009-11-20 Zachary T Welch + + * : openocd: use register_commands() Use register_commands() for top-level version and init command. + +2009-11-21 Zachary T Welch + + * : hello: use register_commands() Use new register_commands() with command registration table. + +2009-11-22 Zachary T Welch + + * : add public API for locating commands Allow other modules to find a command, primarily for the purpose of + registering and unregistering subcommands. + +2009-11-21 Zachary T Welch + + * : add command registration chaining Adds the ability to chain registration structures. Modules can + define a command with the 'chain' and 'num_chain' fields defined in + their registration table, and the register_commands() function will + initialize these commands. If the registration record creates a new + command, then the chained commands are created under it; otherwise, + they are created in the same context as the other commands (i.e. the + parent argument). + +2009-11-20 Zachary T Welch + + * : command: use register_commands for handlers Use register_commands() to register low-level command handlers, + adding a builtin_command_handlers declaration that is easy to + understand. Splits help and usage information into their + appropriate fields. + +2009-11-20 Zachary T Welch + + * : add register_commands for batch registration The register_commands API takes multiple commands in one call, + allowing modules to declare and pass a much simpler (and more + explicit) array of command_registration records. + +2009-11-20 Zachary T Welch + + * : use COMMAND_REGISTER macro Replaces direct calls to register_command() with a macro, to allow + its parameters to be changed and callers updated in phases. + +2009-11-21 Zachary T Welch + + * : improve startup tcl scripts Fix a couple of layering violations missed in the last round. Add + missing comment headers. + +2009-11-24 David Brownell + + * : Cortex-A8: hook up DPM This replaces two versions of register access functions. One was + commented out, and seemed to have uncertain intent. The other was + fairly new, and helped motivate the DPM framework once I observed + that the ARM11 was doing the very same ops. Signed-off-by: David Brownell + +2009-11-24 David Brownell + + * : Cortex-A8: minor cleanup Make various functions static, add some comments, report vector + catch as a flavor of DBG_REASON_BREAKPOINT, get rid of + needless/undesirable ARMV4_5_CORE_REG_MODE, etc. Signed-off-by: David Brownell + +2009-11-24 Zachary T Welch + + * : fix doxygen build Update build rules to skip the PDF unless the TeX has been created. + Also, fixes a warning regarding pattern rules being a GNU make + trick. + +2009-11-19 Zachary T Welch + + * : jlink: remove superfluous indentation Rewrite logic to remove indentation in jlink_usb_open, in prep for + further surgery. + +2009-11-19 Zachary T Welch + + * : rlink: eliminate spurious indentation Rework rlink_init to use less indentation. Best viewed with diff + -w. + +2009-11-19 Zachary T Welch + + * : usbprog: use jtag_usb_open Rewrite usbprob_jtag_open to use jtag_usb_open helper. + +2009-11-19 Zachary T Welch + + * : add jtag/usb_common.[ch] files Begins to consolidate code used by several USB JTAG interfaces. + This first patch provides the required build system changes and a + common jtag_usb_open routine, which will replace the guts for + probing the busses and devices for possible VID/PID matches. The + following patches convert each driver to use it. + +2009-11-24 David Brownell + + * : ARM11: use standard run_algorithm() As with single stepping, the previous stuff was needed because the + ARM11 code wasn't using the standard ARM base type and register + access ... but now those mechanisms work, so we can switch out that + special-purpose glue, in favor of the more thoroughly tested/capable + "standard" code. Fixes a bug in the resume() implementation: it wasn't handling two + of its arguments correctly, preventing the "flash erase_check" + algorithm from working. (This code needs a *subsequent* update for + correct register handling, though... removing the confusion about + which "r2", for example, to use.) This should resolve some "FIXME" comments too, for Thumb and + processor mode support. It also gets rid of a nasty exit() call; + servers should only have *clean* shutdown paths. Signed-off-by: David Brownell + +2009-11-24 David Brownell + + * : ARM11: partial support for standard ARM register interfaces. This provides "standard" ARM register support -- with twenty or more + shadow registers on top of what this code now handles, but properly + associated with the various core modes -- parallel to the current + register code. That is, the current code is stilil managing the + "current" registers; the new code shadows them. You can see all the registers with "arm reg", modify the shadows + like "r8_fiq" or "sp_abt" with "reg", and see them get properly + written back when you step. (Just don't do that with any of the + registers managed by the "old" code ...) It also switches to using more standard code, relying on those + standard registers, in two places: (a) the poll status display, + which now shows core state (ARM/Thumb/...) and mode (Supervisor, + IRQ, etc); and (b) GDB register access. So it's not a full migration, there are warts -- every place that + touches the old register cache is a potential bug -- but it's a + small more-or-less-comprehensible step that's even somewhat useful. + Later patches complete the migration. Signed-off-by: David Brownell + +2009-11-24 David Brownell + + * : ARM11: implement provider for new DPM interface This is a very thin layer over some of the current ARM11 debug TAP + utilities. The layer isn't yet hooked up. Signed-off-by: David Brownell + +2009-11-24 David Brownell + + * : target: cope with *any* error setting a breakpoint It's wrong to map unrecognized failure codes to success. Signed-off-by: David Brownell + +2009-11-23 Jerry Ling + + * : mips: fix gaffe when removing dynamic array allocation Classic sizeof() gaffe. Signed-off-by: Øyvind Harboe + +2009-10-26 Øyvind Harboe + + * : arm926ejs: retire cp15 commands, handled by mrc/mcr. Signed-off-by: Øyvind Harboe + +2009-11-22 David Brownell + + * : ARM11: macro cleanup Make this code look more like the rest of the OpenOCD code. - Use calloc() directly, not NEW() ... and fix some potential memory leaks while we're at it. - Remove FNC_INFO ... it's a NOP that just clutters things, and it's trivial for developers to add tracing as needed. - Replace FNC_INFO_NOTIMPLEMENTED with LOG_WARNING calls; ditto. And stop having those call sites wrongly succeed! - Waste less space with the CHECK_RETVAL() macro. Signed-off-by: David Brownell + +2009-11-22 Øyvind Harboe + + * : mips: use const for code sequences This will allow data to be allocated in read only memory instead of + on the stack. Speeds things up and reduces stack usage. Signed-off-by: Øyvind Harboe + +2009-11-22 Øyvind Harboe + + * : arm926ejs: fix warnings buf_set_u32() operated on an uninitialized stack variable with + non-byte boundaries, which led to warnings about reading + uninitialized stack. Signed-off-by: Øyvind Harboe + +2009-11-22 David Brownell + + * : ARM: use arm_reg_current() Start using the arm_reg_current() call. This shrinks and speeds the + affected code. It can also prevent some coredumps coming from + invalid CPSR values ... the ARMV4_5_CORE_REG_MODE() macro returns + bogus registers if e.g. "Secure Monitor" mode isn't supported by the + current CPU. Signed-off-by: David Brownell + +2009-11-22 David Brownell + + * : target: make register flags "bool" Mostly for clarity, but it also saves code and data space. Signed-off-by: David Brownell + +2009-11-22 Øyvind Harboe + + * : flash: dynamically allocate working storage Allocate working memory rather than using stack. Signed-off-by: Øyvind Harboe + +2009-11-22 Øyvind Harboe + + * : todo: add tip on how to identify excessive stack usage Use dynamic allocations for working memory rather than stack. Signed-off-by: Øyvind Harboe + +2009-11-21 Øyvind Harboe + + * : embedded: reduce stack usage Allocate working structures on stack to avoid issues with path + lengths + reduce stack usage. Signed-off-by: Øyvind Harboe + +2009-11-21 Øyvind Harboe + + * : embedded: save stack and also do not recaluate the crc32_table upon every invocation. Signed-off-by: Øyvind Harboe + +2009-11-22 Øyvind Harboe + + * : build: fix breakage in building bin2char bin2char build relied on $(builddir) which is not defined for + arm-elf X builds at least. Signed-off-by: Øyvind Harboe + +2009-11-22 David Brownell + + * : ARM: define two register utilities Define arm_reg_current() ... returning handle to a given register, + and encapsulating the current mode's register shadowing. It's got + one current use, for reporting the current register set to GDB. + This will let later patches clean up much ARMV4_5_CORE_REG_MODE() + nastiness, saving a bit of code. Define and use arm_set_cpsr() ... initially it updates the cached + CPSR and sets up state used by arm_reg_current(), plus any SPSR + handle. (Later: can also set up for T and J bits.) Signed-off-by: David Brownell + +2009-11-22 David Brownell + + * : ARM11: remove disabled register hooks Minor cleanup of ARM11 register handling: remove disabled register + hooks. This should all be handled by shared code, and this stuff is + just clutter. Signed-off-by: David Brownell + +2009-11-21 Zachary T Welch + + * : allow jtag interfaces to lack commands Allow JTAG interface drivers to skip registering an + register_commands callback when it will just be empty. + +2009-11-20 David Brownell + + * : ARM: pass 'struct reg *' to register r/w routines Implementations need to access the register struct they modify; make + it easier and less error-prone to identify the instance. (This + removes over 10% of the ARMV4_5_CORE_REG_MODE nastiness...) Plus some minor fixes noted when making these updates: ARM7/ARM9 + accessor methods should be static; don't leave CPSR wrongly marked + "dirty"; note significant XScale omissions in register handling; and + have armv4_5_build_reg_cache() record its result. Rename "struct armv4_5_core_reg" as "struct arm_reg"; it's used for + more than those older architecture generations. Signed-off-by: David Brownell + +2009-11-20 Zachary T Welch + + * : maintain command lists in sorted order Use insertion sort to the command link lists. The only practical + effect of this is to order the output of the new 'help' command. + +2009-11-20 Zachary T Welch + + * : provide command context during cmd_init For the startup.tcl code to use built-in commands, the context must + be associated with the interpreter temporarily. This will be + required to add help text. + +2009-11-19 Zachary T Welch + + * : factor help script command into parts Creates a helper function, cmd_help, which displays the help string + for a single command. Presently, it is called from the loop in + help. The routine has been extended to allow indentation of command + groups, so an improved help command can improve the display of + information. + +2009-11-19 Zachary T Welch + + * : change command_find helper interface Avoid requiring double pointers where a single would suffice. + +2009-11-20 David Brownell + + * : target.cfg: TAP id for Hilscher netX 500 Based on email from "Martin Kaul ". Signed-off-by: David Brownell + +2009-11-19 David Brownell + + * : Cortex-A8: better context restore The previous version never wrote dirty registers for non-current CPU + modes ... fix that. Signed-off-by: David Brownell + +2009-11-19 David Brownell + + * : target: create/use register_cache_invalidate() Create a generic register_cache_invalidate(), and use it to replace + three all-but-identical core-specific routines: - armv4_5_invalidate_core_regs() - armv7m_invalidate_core_regs - mips32_invalidate_core_regs() too. Make cache->num_regs be unsigned, avoiding various errors. Net code shrink and simplification. Signed-off-by: David Brownell + +2009-11-18 Zachary T Welch + + * : document new flash syntax Updates the user documentation with the new syntax for defining + flash and nand banks. + +2009-11-17 Zachary T Welch + + * : add support for naming NAND banks Requires users to name their nand banks, allowing them to be used + instead of bank numbers in script commands. + +2009-11-18 Zachary T Welch + + * : update 'flash bank' usage in scripts Sets $_FLASHNAME to "$_CHIPNAME.flash" and passes it as the first + argument to 'flash bank'. + +2009-11-17 Zachary T Welch + + * : refactor handle_flash_bank_command Move variables to point of first use, reducing their scope. Add + driver_name temporary to help arguments be changed later. Eliminates the useless 'found' variable, changing the code to + terminate the loop immediate and return its success. + +2009-11-17 Zachary T Welch + + * : allow flash/nand banks commands to accept names Add get_flash_bank_by_name (and get_nand_device_by_name) helpers to + retrieves struct flash_bank * (struct nand_device *) given a driver + name and an (optional) driver-specific bank index. These are used to extend flash_command_get_bank_by_num (and + nand_command_get_device_by_num) to allow all flash (nand) commands + to reference defined banks by name, not just by number. To avoid some code duplication, add the flash/common.[ch] files to + hold functionality common to both types driver. The first two + methods are helpers for the above routines to find a bank specified + by a "name" or "name.index" string. get_flash_name_index() finds + the '.index' portion, while flash_driver_name_matches() performs the + string portion matching. + +2009-11-19 David Brownell + + * : ARM: streamline register init Combine register names with other per-register data into a single + template structure. This saves space, and makes it easier to change + how registers get handled (by shrinking the number of places that + care about cache indices). Signed-off-by: David Brownell + +2009-11-18 Dean Glazeski + + * : nand_fileio_parse_args parses wrong param for size This changes the size parameter from argv[2] to argv[3], which is + what it's supposed to be. Signed-off-by: Zachary T Welch + +2009-11-19 David Brownell + + * : ARMv7-A: use standard ARM core_mode symbols The only way ARMv7-A modes differ from ARMv4/ARMv5 flavors is that + v7-A is allowed to include "Secure monitor" support. That's now + handled by our standard top-level ARM code ... so phase out the + stuff that's specific to ARMv7-A. Signed-off-by: David Brownell + +2009-11-18 Zachary T Welch + + * : remove fast command and jim_global_long Removing the fast command eliminates the fast_and_dangerous global, + which was used only by arm7_9_common as an initializer. The command + is not called in the tree; instead, more explicit commands are used. The jim_global_long function was not used anywhere in the tree. + +2009-11-18 Zachary T Welch + + * : change all bool parsers to accept any value This patch changes the behavior of all boolean parsing callers to + accept any one of "true/enable/on/yes/1" or + "false/disable/off/no/0". Since one particular pair will be most appropriate in any given + situation, the specific macros should continue to be used in order + to display the most informative error messages possible. + +2009-11-18 Zachary T Welch + + * : use COMMAND_PARSE_ENABLE macro where appropriate Updates all command parsing of simple "enable" and "disable" + arguments. A few case in the tree use a tri-state or extended + arguments, which cannot use this simple macro. Simlifies the xscale icache/dcache command handler logic. + +2009-11-18 Zachary T Welch + + * : add COMMAND_PARSE_BOOL macro and friends Adds several macros similar to COMMAND_PARSE_NUMBER, but for parsing + boolean command arguments. Two flavors are provided to provide + drop-in compatibility with existing code, allow for the elimination + of a lot of code bloat while improving the error checking and + reporting. COMMAND_PARSE_ON_OFF parses "on"/"off" command parameters. + COMMAND_PARSE_ENABLE parses "enable"/"disable" command parameters. Both print the error and return an error out of the calling + function. + +2009-11-18 David Brownell + + * : Cortex-A8: xPSR handling updates When we read the CPSR on debug entry, update the CPSR cache in all + cases, not just when the current processor state is User or System. Plus minor cleanup of how the (too-many) other registers' cache + entries get updated. Signed-off-by: David Brownell + +2009-11-18 David Brownell + + * : ARM: simplify ARMv7-A register handling ARMv7-A doesn't need to duplicate all the standard ARM code for + register handling. - Switch Cortex-A8 to use the standard register code - Remove duplicated infrastructure from ARMv7-A - Have ARMv7-A arch_state() show CPSR, like other ARMs Add comments to show where the Cortex-A8 isn't actually doing the + right thing for register reads/writes, unless core happens to be in + the right mode to start with. (Looks like maybe there may be + generic confusion between saved/current PSR values in all the ARM + code ...) Make related ARMv7-A and Cortex-A8 symbols properly static. Signed-off-by: David Brownell + +2009-11-18 David Brownell + + * : ARM: add "core_type" field to "struct arm" It's used to flag cores with the "TrustZone" extension, and is used + in subsequent patches to set up support for the registers shadowed + by its new secure monitor mode. The ARM1176 and Cortex-A8 both support this new mode. Signed-off-by: David Brownell + +2009-11-17 Zachary T Welch + + * : pass startup_tcl to command_init Removes external linkage from helper module, making the startup code + a parameter to a new command context's initialization routine. + +2009-11-17 Zachary T Welch + + * : move startup.c to libopenocd Moves the creation of startup_tcl.c from src/helper/ to src/. + Prepares to split the startup.tcl file into its per-module parts. + +2009-11-17 Øyvind Harboe + + * : jtag-api: get rid of unecessary buf_set_u23() that make code + obtuse. Also, this is on the path to increasing the word size for bit + vectors from 8 to something wider(32? natural host machine width?) Signed-off-by: Øyvind Harboe + +2009-11-17 David Brownell + + * : ARM: add arm_mode_name() Add and use arm_mode_name() to map from PSR bits to user meaningful + names. It uses a new table which, later, can be used to hold other + mode-coupled data. Add definitions for the "Secure Monitor" mode, as seen on some ARM11 + cores (like ARM1176) and on Cortex-A8. The previous mode name + scheme didn't understand that mode. Remove the old mechanism ... there were two copies, caused by + Cortex-A8 needing to add "Secure Monitor" mode support. Signed-off-by: David Brownell + +2009-11-17 Zachary T Welch + + * : allow documentation to be configured Add --disable-doxygen-html and --enable-doxygen-pdf options to the + configure script, allowing user to change the defaults. These + update the proess of munging the Doxygen configuration file to use + the settings thusly provided. Add options in README. + +2009-11-17 Zachary T Welch + + * : update command_handler documentation Improve the developer manual and primer sections which talk about + writing command handlers. Notably, it documents the new CMD_* + macros. + +2009-11-16 Zachary T Welch + + * : add CMD_NAME variable in command_invocation Update CMD_NAME from its migratory home in CMD_ARGV[-1] to + cmd->name. Allows CMD_ARGV++ idiom to be used safely in command + handlers. + +2009-11-15 Zachary T Welch + + * : command_handler: change 'cmd_ctx' to CMD_CTX Convert all command handler 'cmd_ctx' parameter usage with CMD_CTX. + +2009-11-15 Zachary T Welch + + * : command_handler: change to 'argc' to CMD_ARGC This patch converts all instances of 'argc' in COMMAND_HANDLER + routines to use CMD_ARGC. + +2009-11-17 David Brownell + + * : target: simplify register get/set ops No need to indirect from registered integers to pointers. Just + stash the pointers directly in the register struct, and don't even + bother registering. This is a small code shrink, speeds register access just a smidgeon, + and gets rid of another rude exit() path. Signed-off-by: David Brownell + +2009-11-17 Øyvind Harboe + + * : zy1000: revC UART forwarding Name of serial device differs between revB/C. Signed-off-by: Øyvind Harboe + +2009-11-12 Øyvind Harboe + + * : zy1000: fix bug when running on non-arm CPU Shifting by more than 32 is undefined for 32 bit integers according + to the C standard. Robust solution is conditional code. Signed-off-by: Øyvind Harboe + +2009-11-17 David Brownell + + * : ARM9TDMI: remove now-needless "struct arm9tdmi" And move the rest of the vector_catch stuff into the C file; it's + not part of the module interface. Signed-off-by: David Brownell + +2009-11-17 David Brownell + + * : target: remove some more duplicate includes Signed-off-by: David Brownell + +2009-11-16 David Brownell + + * : Cortex-A8: no exit() calls, add missing v7-A init Eventually there should be a v7a init routine, but for now all that + is inlined here. Signed-off-by: David Brownell + +2009-11-16 David Brownell + + * : MIPS: no exit() calls Signed-off-by: David Brownell + +2009-11-16 David Brownell + + * : ARMv4/ARMv5: no exit() calls Signed-off-by: David Brownell + +2009-11-16 David Brownell + + * : Cortex-M3: don't exit() Get rid of undesirable and needless exit() calls from the Cortex-M3 + support. Signed-off-by: David Brownell + +2009-11-16 David Brownell + + * : ARM11: register (most) standard ARM commands Have ARM11 register the "standard" ARM commands. For now, only + disassembly really works. Signed-off-by: David Brownell + +2009-11-16 David Brownell + + * : JTAG: fix autoprobe failure. Fix bug noted by Øyvind: terminate the IR length autoscan when the + IR is too long, or otherwise broken. Signed-off-by: David Brownell + +2009-11-13 Zachary T Welch + + * : struct fileio: improve member types Add const keyword to file url and cast to free(). Make size an ssize_t and chase all format strings that use it. + +2009-11-15 Zachary T Welch + + * : use Jim_CmdProc in jim_register The jim_register command just needed to use the type defined by + jim.h. + +2009-11-15 Zachary T Welch + + * : make command line options const The getopt_long call allows a const struct option, so mark ours + const too. + +2009-11-16 David Brownell + + * : target: don't include "log.h" from "armv4_5.h" No point in multiple includes, and that file doesn't use its + functions any more. Signed-off-by: David Brownell + +2009-11-16 David Brownell + + * : JTAG: no LOG_WARNING() for taps without IDCODE Signed-off-by: David Brownell + +2009-11-16 David Brownell + + * : "types.h" doxygen fix Signed-off-by: David Brownell + +2009-11-16 Zachary T Welch + + * : move ARRAY_SIZE macro to types.h The ARRAY_SIZE macro was defined in several target files, so move it + to types.h. This patch also removes two other identical macros: DIM (from + jtag.h) and asizeof (from arm11.h). + +2009-11-16 Zachary T Welch + + * : remove TAP_SCAN_BYTES macro Use DIV_ROUND_UP(n, 8) instead of TAP_SCAN_BYTES macro. + +2009-11-16 Zachary T Welch + + * : move container_of to types.h The container_of macro is useful as a general solution. It belongs + in types.h, rather than target.h where it was introduced. Requires + the offsetof macro, which comes from (moved as well). + +2009-11-15 Zachary T Welch + + * : flash_command_get_bank_by_num: make COMMAND_HELPER Use COMMAND_HELPER macro to declare flash_command_get_bank_by_num. + This is required for COMMAND_PARSE_NUMBER macro. + +2009-11-07 Zachary T Welch + + * : Add 'nand verify' command Add the 'nand verify' command to perform a dump and fake-write + simultaneously, checking the read bits against those generated by + the write process. Appropriate user documentation for this command + has been added to the user guide as well. The algorithm presently makes a relatively naive comparison. Some + chips that use ECC may not verify correctly using this + implementation, but the new documentation provides details about + this limitation. + +2009-11-05 Zachary T Welch + + * : Use nand_fileio_* in write/dump commands. This patch eliminates duplicated code in the the NAND 'dump' and + 'write' by using the new static helper functions. These changes also fix a possible memory leak in nand dump command, + in the case that the dump file failed to open. Overall, the changes should be functionally equivalent, but the + resulting code will be easier to improve and extend further. + +2009-11-16 Zachary T Welch + + * : binarybuffer: add API documentation Adds Doxygen documentation for a number of the binarybuffer APIs, + including "unexpected" behavior exposed during review on the list. + +2009-11-14 Zachary T Welch + + * : improve buf_set_buf helper Use void * and unsigned types for buffer and their sizes. Allows it + to be used with more than uint8_t * without casts. + +2009-11-14 Zachary T Welch + + * : improve buf_cpy helper Use memcpy for bulk of copy, improve final byte handling. Improve + types by using void * for buffers and unsigned for size. + +2009-11-14 Zachary T Welch + + * : improve str_to_buf and buf_to_str helpers Improve types: use void * and unsigned. Move all variables to point + of first use. Move radix guessing logic to new str_radix_guess + helper. + +2009-11-14 Zachary T Welch + + * : binarybuffer: fix whitespace related issues Add inter-operator whitespace. Improve existing documentation. + +2009-11-16 David Brownell + + * : target: no implicit #includes of "register.h" Same deal: "register.h" got needlessly included all over the place + because of being in a few widely included headers. So take it out of the header files which included it, and put it in + files which use it ... reduce needless interdependencies. Also, don't need that extra "types.h" inclusion. Signed-off-by: David Brownell + +2009-11-16 David Brownell + + * : target: don't implicitly include "algorithm.h" Most files in the tree seem to have ended up including this, and + *quite* needlessly ... only code implementing or using downloadable + algorithms actually needs these declarations. So take it out of the header files which included it, and put it in + files which use it ... reduce needless interdependencies. Also: "algorithm.h" doesn't need to include "types.h" again; it + already comes from a different header. Signed-off-by: David Brownell + +2009-11-15 David Brownell + + * : ARM11: use now-generic memory utils Now the ARM11 cores can use the renamed arm_checksum_memory() and + arm_blank_check_memory() routines ... do so. Sanity checked with "flash erase_check" of both NOR banks on an + OMAP2420 ... the algorithm code dumped four lines of of "poll" + status after each of almost 520 blocks (yes, *very* annoying) but + gave plausible results after producing that spam. Signed-off-by: David Brownell + +2009-11-15 David Brownell + + * : ARM: memory utils aren't ARM7/ARM9 dependent The arm7_9_checksum_memory() and arm7_9_blank_check_memory() + routines are not actually specific to the ARM7 and ARM9 core + generations ... they can work for any core which can run algorithms + using basic ARM (not Thumb) instructions. Rename them; move the declarations to a more generic site; likewise + move the code (and tidy it a bit in the process). NOTE: the blank_check() method falsely returned a success status + (0) on one error path, when the algorithm failed. Fixed this bug. Signed-off-by: David Brownell + +2009-11-15 Zachary T Welch + + * : arm-jtag-ew,jlink: switch to COMMAND_HANDLER These drivers were overlooked during the recent upgrade. Convert + them, moving their registration routines to eliminate their + declarations. + +2009-11-14 Zachary T Welch + + * : remove unused arm_jtag_buf_to_* helpers Removes unused arm_jtag_buf_* helpers from arm_jtag.[ch]. These + could reappear if patches are provided to conver the tree to use + them, but this code should not be in the master tree until that + series is ready. + +2009-11-14 Zachary T Welch + + * : struct scan_field_s -> struct scan_field Remove obsolete suffix from struct scan_field. Somehow, these + definitions did not get updated but did not cause any errors. + +2009-11-14 David Brownell + + * : lpc2900.h -- remove from Makefile.am too Signed-off-by: David Brownell + +2009-11-14 David Brownell + + * : remove annoying $URL$ startup message It's completely unused; the obnoxious "DANGER!!!" comments don't + even explain what it was doing (shorthand SVN magic). Signed-off-by: David Brownell + +2009-11-14 Zachary T Welch + + * : add openocd.h for top-level declarations Create src/openocd.h to hold declarations previously made internally + by src/main.c and src/server/server.c. This ensures all functions + are verified to be in-sync at compile time (rather than at link), + making it easier to track down bugs. + +2009-11-13 David Brownell + + * : ARM11: ETM + ETB support Kick in ETM (and ETB) support for ARM11. Tested on OMAP 2420, so + update that configuration. (That's an ARM1136ejs, ETB, OpenGL + ES1.1, C55x DSP, etc.) Also update the other ARM11 ETM + ETB targets in the tree to set up + these modules. (Not tested.) Signed-off-by: David Brownell + +2009-11-13 David Brownell + + * : iMX2* + ETB targets: hook up ETM and ETB ARM9 cores with an ETB will have a matching ETM. Hook them both up + by default. Signed-off-by: David Brownell + +2009-11-13 David Brownell + + * : ETM: simplify ETM initialization code paths Return NULL from etm_build_reg_cache() not ERROR_OK; and share code + on that fault path. Let ETM code handle any tracking of its cache -- not callers. Signed-off-by: David Brownell + +2009-11-13 David Brownell + + * : target: remove unused "bitfield" infrastructure We have too many different registers, and too many version and + context dependent interpretations, for this type of bitfield + management to be scalable. (Anyone who really wants bitfield interpretation *can* do that in + Tcl code...) There are ... quite a few copies of the same ARM dummy registers. + There should eventually be one copy; this many is craziness. Signed-off-by: David Brownell + +2009-11-13 David Brownell + + * : ARM7/9: rm arm7_9_get_arch_pointers() Remove the last external user of arm7_9_get_arch_pointers(), and + that annoying downcast utility. Add an is_arm7_9() predicate. Stop returning specious success codes on various failure paths in + the ARM7/ARM9 commands which used that downcast utility. Signed-off-by: David Brownell + +2009-11-13 Zachary T Welch + + * : command_t -> struct command Remove misleading typedef and redundant suffix from struct command. + +2009-11-13 Zachary T Welch + + * : remove rlink structure typedefs Remove useless typedefs from the rlink driver. Improve whitespace. + +2009-11-13 Zachary T Welch + + * : nand_device_t -> struct nand_device Remove misleading typedef and redundant suffix from struct + nand_device. + +2009-11-13 Zachary T Welch + + * : reg_t -> struct reg Remove misleading typedef and redundant suffix from struct reg. + +2009-11-13 Zachary T Welch + + * : improve mips32_pracc_context Use struct mips32_pracc_context instead of a typedef. + +2009-11-13 Zachary T Welch + + * : armv4_5_common_t -> struct arm Remove misleading typedef and just use struct arm. + +2009-11-13 Zachary T Welch + + * : etb_t -> struct etb Remove misleading typedef and redundant suffix from struct etb. + +2009-11-13 Zachary T Welch + + * : image_elf_t -> struct image_elf Remove misleading typedef and redundant suffix from struct + image_elf. + +2009-11-13 Zachary T Welch + + * : cortex_m3_fp_comparator_t -> struct cortex_m3_fp_comparator Remove misleading typedef and redundant suffix from struct + cortex_m3_fp_comparator. + +2009-11-13 Zachary T Welch + + * : cortex_a8_brp_t -> struct cortex_a8_brp Remove misleading typedef and redundant suffix from struct + cortex_a8_brp. + +2009-11-13 Zachary T Welch + + * : xscale_trace_t -> struct xscale_trace Remove misleading typedef and redundant suffix from struct + xscale_trace. + +2009-11-13 Zachary T Welch + + * : target_event_action_t -> struct target_event_action Remove misleading typedef and redundant suffix from struct + target_event_action. + +2009-11-13 Zachary T Welch + + * : arm9tdmi_vector_t -> struct arm9tdmi_vector Remove misleading typedef and redundant suffix from struct + arm9tdmi_vector. Renames enum arm9tdmi_vector as enum arm9tdmi_vector_bit. + +2009-11-13 Zachary T Welch + + * : xscale_common_t -> struct xscale_common Remove misleading typedef and redundant suffix from struct + xscale_common. + +2009-11-13 Zachary T Welch + + * : trace_point_t -> struct trace_point Remove misleading typedef and redundant suffix from struct + trace_point. + +2009-11-13 Zachary T Welch + + * : target_timer_callback_t -> struct target_timer_callback Remove misleading typedef and redundant suffix from struct + target_timer_callback. + +2009-11-13 Zachary T Welch + + * : working_area_t -> struct working_area Remove misleading typedef and redundant suffix from struct + working_area. + +2009-11-13 Zachary T Welch + + * : reg_cache_t -> struct reg_cache Remove misleading typedef and redundant suffix from struct + reg_cache. + +2009-11-13 Zachary T Welch + + * : oocd_trace_t -> struct oocd_trace Remove misleading typedef and redundant suffix from struct + oocd_trace. + +2009-11-13 Zachary T Welch + + * : mips_ejtag_t -> struct mips_ejtag Remove misleading typedef and redundant suffix from struct + mips_ejtag. + +2009-11-13 Zachary T Welch + + * : mips32_common_t -> struct mips32_common Remove misleading typedef and redundant suffix from struct + mips32_common. + +2009-11-13 Zachary T Welch + + * : image_mot_t -> struct image_mot Remove misleading typedef and redundant suffix from struct + image_mot. + +2009-11-13 Zachary T Welch + + * : image_ihex_t -> struct image_ihex Remove misleading typedef and redundant suffix from struct + image_ihex. + +2009-11-13 Zachary T Welch + + * : image_section_t -> struct image_section Remove misleading typedef and redundant suffix from struct + image_section. + +2009-11-13 Zachary T Welch + + * : etm_capture_driver_t -> struct etm_capture_driver Remove misleading typedef and redundant suffix from struct + etm_capture_driver. + +2009-11-13 Zachary T Welch + + * : etb_reg_t -> struct etb_reg Remove misleading typedef and redundant suffix from struct etb_reg. + +2009-11-13 Zachary T Welch + + * : cortex_m3_common_t -> struct cortex_m3_common Remove misleading typedef and redundant suffix from struct + cortex_m3_common. + +2009-11-13 Zachary T Welch + + * : watchpoint_t -> struct watchpoint Remove misleading typedef and redundant suffix from struct + watchpoint. + +2009-11-13 Zachary T Welch + + * : mcu_jtag_t -> struct mcu_jtag Remove misleading typedef and redundant suffix from struct mcu_jtag. + +2009-11-13 Zachary T Welch + + * : armv7m_algorithm_t -> struct armv7m_algorithm Remove misleading typedef and redundant suffix from struct + armv7m_algorithm. + +2009-11-13 Zachary T Welch + + * : armv7a_core_reg_t -> struct armv7a_core_reg Remove misleading typedef and redundant suffix from struct + armv7a_core_reg. + +2009-11-13 Zachary T Welch + + * : armv7a_common_t -> struct armv7a_common Remove misleading typedef and redundant suffix from struct + armv7a_common. + +2009-11-13 Zachary T Welch + + * : armv4_5_cache_common_t -> struct armv4_5_cache_common Remove misleading typedef and redundant suffix from struct + armv4_5_cache_common. + +2009-11-13 Zachary T Welch + + * : armv4_5_core_reg_t -> struct armv4_5_core_reg Remove misleading typedef and redundant suffix from struct + armv4_5_core_reg. + +2009-11-13 Zachary T Welch + + * : arm_jtag_t -> struct arm_jtag Remove misleading typedef and redundant suffix from struct arm_jtag. + +2009-11-13 Zachary T Welch + + * : arm_load_store_instr_t -> struct arm_load_store_instr Remove misleading typedef and redundant suffix from struct + arm_load_store_instr. + +2009-11-13 Zachary T Welch + + * : arm_b_bl_bx_blx_instr_t -> struct arm_b_bl_bx_blx_instr Remove misleading typedef and redundant suffix from struct + arm_b_bl_bx_blx_instr. + +2009-11-13 Zachary T Welch + + * : swjdp_reg_t -> struct swjdp_reg Remove misleading typedef and redundant suffix from struct + swjdp_reg. + +2009-11-13 Zachary T Welch + + * : arm966e_common_t -> struct arm966e_common Remove misleading typedef and redundant suffix from struct + arm966e_common. + +2009-11-13 Zachary T Welch + + * : arm920t_tlb_entry_t -> struct arm920t_tlb_entry Remove misleading typedef and redundant suffix from struct + arm920t_tlb_entry. + +2009-11-13 Zachary T Welch + + * : arm7tdmi_common_t -> struct arm7tdmi_common Remove misleading typedef and redundant suffix from struct + arm7tdmi_common. + +2009-11-13 Zachary T Welch + + * : arm720t_common_t -> struct arm720t_common Remove misleading typedef and redundant suffix from struct + arm720t_common. + +2009-11-13 Zachary T Welch + + * : arm11_reg_state_t -> struct arm11_reg_state Remove misleading typedef and redundant suffix from struct + arm11_reg_state. + +2009-11-13 Zachary T Welch + + * : arm11_reg_defs_t -> struct arm11_reg_defs Remove misleading typedef and redundant suffix from struct + arm11_reg_defs. + +2009-11-13 Zachary T Welch + + * : mem_param_t -> struct mem_param Remove misleading typedef and redundant suffix from struct + mem_param. + +2009-11-13 Zachary T Welch + + * : arm11_register_history_t -> struct arm11_register_history Remove misleading typedef and redundant suffix from struct + arm11_register_history. + +2009-11-13 Zachary T Welch + + * : pld_device_t -> struct pld_device Remove misleading typedef and redundant suffix from struct + pld_device. + +2009-11-13 Zachary T Welch + + * : xilinx_bit_file_t -> struct xilinx_bit_file Remove misleading typedef and redundant suffix from struct + xilinx_bit_file. + +2009-11-13 Zachary T Welch + + * : connection_t -> struct connection Remove misleading typedef and redundant suffix from struct + connection. + +2009-11-13 Zachary T Welch + + * : tcl_connection_t -> struct tcl_connection Remove misleading typedef and redundant suffix from struct + tcl_connection. + +2009-11-13 Zachary T Welch + + * : telnet_service_t -> struct telnet_service Remove misleading typedef and redundant suffix from struct + telnet_service. + +2009-11-13 Zachary T Welch + + * : gdb_connection_t -> struct gdb_connection Remove misleading typedef and redundant suffix from struct + gdb_connection. + +2009-11-13 Zachary T Welch + + * : aduc702x_flash_bank_t -> struct aduc702x_flash_bank Remove misleading typedef and redundant suffix from struct + aduc702x_flash_bank. + +2009-11-13 Zachary T Welch + + * : pic32mx_mem_layout_t -> struct pic32mx_mem_layout Remove misleading typedef and redundant suffix from struct + pic32mx_mem_layout. + +2009-11-13 Zachary T Welch + + * : nand_block_t -> struct nand_block Remove misleading typedef and redundant suffix from struct + nand_block. + +2009-11-13 Zachary T Welch + + * : str9x_flash_bank_t -> struct str9x_flash_bank Remove misleading typedef and redundant suffix from struct + str9x_flash_bank. + +2009-11-13 Zachary T Welch + + * : str7x_flash_bank_t -> struct str7x_flash_bank Remove misleading typedef and redundant suffix from struct + str7x_flash_bank. + +2009-11-13 Zachary T Welch + + * : stm32x_flash_bank_t -> struct stm32x_flash_bank Remove misleading typedef and redundant suffix from struct + stm32x_flash_bank. + +2009-11-13 Zachary T Welch + + * : stellaris_flash_bank_t -> struct stellaris_flash_bank Remove misleading typedef and redundant suffix from struct + stellaris_flash_bank. + +2009-11-13 Zachary T Welch + + * : pic32mx_flash_bank_t -> struct pic32mx_flash_bank Remove misleading typedef and redundant suffix from struct + pic32mx_flash_bank. + +2009-11-13 Zachary T Welch + + * : ocl_priv_t -> struct ocl_priv Remove misleading typedef and redundant suffix from struct ocl_priv. + +2009-11-13 Zachary T Welch + + * : nand_manufacturer_t -> struct nand_manufacturer Remove misleading typedef and redundant suffix from struct + nand_manufacturer. + +2009-11-13 Zachary T Welch + + * : nand_flash_controller_t -> struct nand_flash_controller Remove misleading typedef and redundant suffix from struct + nand_flash_controller. + +2009-11-13 Zachary T Welch + + * : mflash_bank_t -> struct mflash_bank Remove misleading typedef and redundant suffix from struct + mflash_bank. + +2009-11-13 Zachary T Welch + + * : mflash_gpio_drv_t -> struct mflash_gpio_drv Remove misleading typedef and redundant suffix from struct + mflash_gpio_drv. + +2009-11-13 Zachary T Welch + + * : lpc3180_nand_controller_t -> struct lpc3180_nand_controller Remove misleading typedef and redundant suffix from struct + lpc3180_nand_controller. + +2009-11-13 Zachary T Welch + + * : lpc288x_flash_bank_t -> struct lpc288x_flash_bank Remove misleading typedef and redundant suffix from struct + lpc288x_flash_bank. + +2009-11-13 Zachary T Welch + + * : flash_driver_t -> struct flash_driver Remove misleading typedef and redundant suffix from struct + flash_driver. + +2009-11-13 Zachary T Welch + + * : faux_flash_bank_t -> struct faux_flash_bank Remove misleading typedef and redundant suffix from struct + faux_flash_bank. + +2009-11-13 Zachary T Welch + + * : cfi_fixup_t -> struct cfi_fixup Remove misleading typedef and redundant suffix from struct + cfi_fixup. + +2009-11-13 Zachary T Welch + + * : cfi_spansion_pri_ext_t -> struct cfi_spansion_pri_ext Remove misleading typedef and redundant suffix from struct + cfi_spansion_pri_ext. + +2009-11-13 Zachary T Welch + + * : cfi_intel_pri_ext_t -> struct cfi_intel_pri_ext Remove misleading typedef and redundant suffix from struct + cfi_intel_pri_ext. + +2009-11-13 Zachary T Welch + + * : avrf_flash_bank_t -> struct avrf_flash_bank Remove misleading typedef and redundant suffix from struct + avrf_flash_bank. + +2009-11-13 Zachary T Welch + + * : at91sam7_flash_bank_t -> struct at91sam7_flash_bank Remove misleading typedef and redundant suffix from struct + at91sam7_flash_bank. + +2009-11-13 Zachary T Welch + + * : jtag_command_container_t -> union jtag_command_container Remove misleading typedef from union jtag_container. + +2009-11-13 Zachary T Welch + + * : end_state_command_t -> struct end_state_command Remove misleading typedef from struct end_state_command. + +2009-11-13 Zachary T Welch + + * : stableclocks_command_t -> struct stableclocks_command Remove misleading typedef from struct stableclocks_command. + +2009-11-13 Zachary T Welch + + * : pathmove_command_t -> struct pathmove_command Remove misleading typedef from struct pathmove_command. + +2009-11-13 Zachary T Welch + + * : cmd_queue_page_t -> struct cmd_queue_page Remove misleading typedef from struct cmd_queue_page. + +2009-11-13 Zachary T Welch + + * : more vsllink typedef cleanup Remove useless typedef for struct insert_insignification_operation. + +2009-11-13 Zachary T Welch + + * : presto_t -> struct presto Remove useless typedef. + +2009-11-13 Zachary T Welch + + * : jlink_jtag_t -> struct jlink Remove misleading typedef and redundant suffix. + +2009-11-13 Zachary T Welch + + * : pending_scan_result_t -> struct pending_scan_result Remove misleading typedef from struct struct pending_scan_result. + Future patches need to remove these duplicated types and code. + +2009-11-13 Zachary T Welch + + * : use struct jtag_tap_event_action Remove useless typedef and redundant suffix from + jtag_tap_event_action. + +2009-11-13 Zachary T Welch + + * : jtag_interface_t -> struct jtag_interface Remove useless typedef and redundant suffix from struct + jtag_interface. + +2009-11-13 Zachary T Welch + + * : bitq_interface_t -> struct biq_interface Remove useless typedef and redundant suffix. + +2009-11-13 Zachary T Welch + + * : scan_field_t -> struct scan_field Remove useless structure typedef. + +2009-11-13 Zachary T Welch + + * : fileio_t -> struct fileio Remove useless structure typedef. + +2009-11-13 Zachary T Welch + + * : remove accidental artifact Somehow I managed to slip a temporary build file into the tree. + Remove it and update the .gitignore file so it doesn't happen again. + +2009-11-11 Zachary T Welch + + * : add src/hello.c to augment new command tutorial The hello module provides the 'hello' command, printing a greetings + to the command console. It can grow to serve as pedagogical example + of services that OpenOCD developers should use: a runnable style + guide. + +2009-11-10 Zachary T Welch + + * : command_handler_t: make args parameter const This patch prevents command handlers from modifying the strings + passed in the 'args' array. + +2009-11-10 Zachary T Welch + + * : command_handler_t: make argc unsigned The number of command arguments will always be 0 or more, so use the + right type in handlers. This has a cascading effect up through the + layers, but the new COMMAND_HANDLER macros prevented total chaos. + +2009-11-10 Zachary T Welch + + * : use CALL_COMMAND_HANDLER instead of direct calls By using CALL_COMMAND_HANDLER, parameters can be reordered, added, + or even removed in inherited signatures, without requiring + revisiting all of the various call sites. + +2009-11-10 Zachary T Welch + + * : nand: add NAND_DEVICE_COMMAND_HANDLER macro Abstracts the extended NAND command handling to allow the function + signature to be controlled by __COMMAND_HANDLER. + +2009-11-10 Zachary T Welch + + * : add FLASH_BANK_COMMAND_HANDLER macro The FLASH_BANK_COMMAND_HANDLER provides an extended command handler + using the __COMMAND_HANDLER macro, whereby changing that macro is + sufficient to update flash handlers with the new signature. It also + enforces uniform style and scope when implementing this handler. + +2009-11-10 Zachary T Welch + + * : arm_adi,armv7[am]: use COMMAND_HELPER for helpers Rewrites the dap_* command helpers to use the COMMAND_HELPER + paradigm. Uses CALL_COMMAND_HELPER to hide inherited calling + conventions. + +2009-11-09 Zachary T Welch + + * : use COMMAND_HANDLER macro to define all commands + +2009-11-10 Zachary T Welch + + * : add COMMAND_HANDLER and COMMAND_HELPER macros The COMMAND_HANDLER and COMMAND_HELPER macros allow commands to be + defined in a manner that decouples them from the exact order and + type of their parameters. Once converted, incremental changes to + the command handler type can be addressed in incremental patches + that do not need to touch the entire tree. These macros' implementation, __COMMAND_HANDLER, is used to define + the new command_handler_t type, and additional patches will use it + to derive new macros to define extended command types (e.g. flash, + nand, pld). The CALL_COMMAND_HANDLER provides a means of calling + helpers or nested handlers from withing a command handler. This patch uses C99 varadic macro expansion. Please report + compilers that cannot handle this code. + +2009-11-13 David Brownell + + * : Cortex-A8: fix indent The "remove (forward) declarations" patch goofed indentation on the + "cortexa8_target" struct; fix. Signed-off-by: David Brownell + +2009-11-12 David Brownell + + * : ETM: start support for ETMv2+ ARM11 and newer cores include updated ETM modules. Recognize their + version codes and some key config differences. Sanity checked on an + OMAP2, with an ETM11RV r0p1 (ETMv3.1). This still handles only scan chain 6, with at most 128 registers. + Newer cores (mostly, Cortex) will need to use the DAP instead. Note that the newer ETM modules don't quite fit the quirky config + model of the older ones ... having more port widths is easy, but the + modes aren't the same. That still needs to change. Fix a curious bug ... how did the register cache NOT get saved?? Signed-off-by: David Brownell + +2009-11-12 Jonas Horberg + + * : parport: add support for the jtag_khz command. Add the khz and speed_div functions to the parport interface driver. + Add the parport_toggling_time function that tells the parport driver + how long (in nanoseconds) it takes for the hardware to toggle TCK. [dbrownell@users.sourceforge.net: tweak doc for clarity, mention + multimeter, and whitespace fixes] Signed-off-by: David Brownell + +2009-11-11 David Brownell + + * : ETM: use new toplevel ETM handle Make ETM itself use the new toplevel ETM handle, instead of the + to-be-removed lower level one. As of this patch, nothing should be + using the old ARM7/ARM9-specific handle. Signed-off-by: David Brownell + +2009-11-11 David Brownell + + * : ETM: update arm[79]tdmi_examine() Make ARM7 and ARM9 cores use the new toplevel ETM handle to trigger + ETM setup, not the to-be-removed lower level one. Signed-off-by: David Brownell + +2009-11-10 Zachary T Welch + + * : fix 'jtag interface' behavior Without this patch, running "openocd -c 'jtag interface'" segfaults. + Now, it returns the string "undefined" when the interface is unset. + +2009-11-11 Zachary T Welch + + * : add help regardless of callback Add help for commands regardless of whether a handler is involved. + With this, all sorts of new commands can be found in 'help' text. + Hopefully, all of them have been documented.... Sadly, the lsort function appears to handle nested lists poorly, + such that sub-commands do not group with their parents. + +2009-11-11 Zachary T Welch + + * : add command_name helper The command_name function returns a malloced string for a given + command and its parents. This can be used to display a message to + the user, but it is used internally to handle registration and + syntax errors. This helps permit arbitrary command nesting. + +2009-11-11 Zachary T Welch + + * : remove obsolete doxygen comments Documenting command handler parameters is redundant and pointless. + +2009-11-10 Zachary T Welch + + * : cortex_a8: remove declarations, use static keyword + +2009-11-10 Zachary T Welch + + * : change argv to args in command handlers Subsequent patches expect all command handlers to use a uniform + parameter naming scheme. In the entire tree, these two files used + standard 'argv' instead of our non-standard 'args'. This patch opts + to reduces the noise required to unify the command handlers, using + dominant 'args' form. A future patch may be used to convert us back to the standard argv, + but that requires coordination with all developers to minimize + disruptions. + +2009-11-09 Zachary T Welch + + * : command.c: make private routines static This patch also improves the signature of run_command function. + +2009-11-09 Zachary T Welch + + * : time_support: improve use of types Update timeval_add_time to use long int; implement timeval_add with + it. Update timeval_ms to check gettimeofday return value, return + int64_t. + +2009-11-11 David Brownell + + * : ETM cleanup Various cleanups of ETM related code. - Saner error return paths - Simplify arm7_9 init ... no need for extra zeroing! - Shrink some lines - Tweak some diagnostics - Use shorter name for ETM struct type. - Don't exit() and similar. The diagnostics look forward to having this ETM code + work with more than just ARM7/ARM9. Signed-off-by: David Brownell + +2009-11-10 David Brownell + + * : ARM720: bugfix The "ARM720 uses the new inheritance/nesting scheme" patch wrongly + scrubbed a calloc() from arm720t_target_create(). Signed-off-by: David Brownell + +2009-11-10 David Brownell + + * : target.cfg: (re)move some bogus reset_config lines General rule, this is all board-specific and doesn't belong in + target config files. Some of these were just cosmetic. Signed-off-by: David Brownell + +2009-10-27 Michael Bruck + + * : arm11: add etmr/etmw registers to access ETM via DBGTAP scan + chain First cut of these commands. Øyvind tinkered a bit with the number + parsing to bring it up to speed + rebased it. Ready for testing. Signed-off-by: Øyvind Harboe + +2009-11-10 Øyvind Harboe + + * : telo.cfg: fix search paths Add the missing "target/" prefix for scripts in the target folder. Signed-off-by: Øyvind Harboe + +2009-11-10 David Brownell + + * : ARM920: implement basic MMU ops mmu() works; virt2phys() fails and logs an error. Signed-off-by: David Brownell + +2009-11-10 David Brownell + + * : Target: fix bad error messages And shrink a few too-long lines. Signed-off-by: David Brownell + +2009-11-10 Øyvind Harboe + + * : tcl: HostOs now picks up eCos as well during compile time Signed-off-by: Øyvind Harboe + +2009-11-09 Zachary T Welch + + * : command.c: make commands static Removes useless declarations, moving the handler functions to appear + before their use in the (much bigger) command registriation + function. + +2009-11-09 Zachary T Welch + + * : jtag: remove useless declarations Contrary to my previous assessment, some opportunities to remove + forward declarations were overlooked. Remove them by moving the + definitions of the command registration and interface structure to + the end of files. + +2009-11-09 Zachary T Welch + + * : {pic32m,stm32}x.c: remove useless declarations Remove useless forward declarations. Moves command registrations to + end of files. Moves flash structure definitions to end of files. Signed-off-by: Zachary T Welch + +2009-11-09 Zachary T Welch + + * : flash/.c: remove useless declarations Remove useless forward declarations. Moves flash structure + definitions to end of files. Signed-off-by: Zachary T Welch + +2009-11-09 Zachary T Welch + + * : flash/at91sam[37].c: remove useless declarations Remove useless forward declarations. Moves command registration to + end of file. Moves flash structure definitions to end of files. Changes a few references to global flash structure to local refs. Signed-off-by: Zachary T Welch + +2009-11-09 Zachary T Welch + + * : flash/*nand*.c: remove useless declarations Remove useless forward declarations. Moves command registration to + end of files. Moves flash structure definition to end of files. Signed-off-by: Zachary T Welch + +2009-11-09 David Brownell + + * : Revert "target: add target->type->has_mmu fn" This patch introduced a bug preventing flash writes from working on + Cortex-M3 targets like the STM32. Moreover, it's the wrong approach + for handling no-MMU targets. The right way to handle no-MMU targets is to provide accessors for + physical addresses, and use them everywhere; and any code which + tries to work with virtual-to-physical mappings should use a + identity mapping (which can be defaulted). And ... we can tell if a target has an MMU by seeing if it's got an + mmu() method. No such methood means no MMU. Signed-off-by: David Brownell + +2009-11-09 David Brownell + + * : User's Guide: Flash/NAND doc tweaks Rename the "Drivers, Options, and Commands" sections to be just + "Driver List" matching the earlier reference. Add an example of + parallel CFI flash. Signed-off-by: David Brownell + +2009-11-09 Zachary T Welch + + * : target.h: remove extern keyword and wrap Removes 'extern' keyword from function prototypes and wraps long + lines. + +2009-11-09 Zachary T Welch + + * : src/flash: remove 'extern' and wrap headers Removes 'extern' keywords from function prototypes in the flash + headers. Wraps long lines to fit into 80 columns. Adds multiple inclusion protection for s3c2xx_nand.h. + +2009-11-09 Zachary T Welch + + * : src/helper: wrap and clean headers. Remove all useless 'extern' keywords from function prototypes. + Wraps long lines for readability. + +2009-11-09 David Brownell + + * : EmbeddedICE: minor cleanups Add comments (Doxygen and normal), remove unused code, shrink some + overlong lines. Get rid of a forward decl. Signed-off-by: David Brownell + +2009-11-06 Zachary T Welch + + * : Add private header for ARM11 internals. Reduces confusion about location of associated routines and reduces + clutter in the arm11 header. Removes extra whitespace around the lines touched by these changes. + +2009-11-08 David Brownell + + * : ARM: minor simulator cleanup Make several functions be static. Shrink some of the overlong + lines. Use pure tab indents in some places that mixed in spaces. + This gives a minor object code shrink (about 2% on amd64). Signed-off-by: David Brownell + +2009-11-08 David Brownell + + * : target.cfg: remove "-work-area-virt 0" The semantics of "-work-area-virt 0" (or phys) changed with the + patch to require specifying physical or virtrual work area + addresses. Specifying zero was previously a NOP. Now it means that + address zero is valid. This patch addresses three related issues: - MMU-less processors should never specify work-area-virt; remove those specifications. Such processors include ARM7TDMI, Cortex-M3, and ARM966. - MMU-equipped processors *can* specify work-area-virt... but zero won't be appropriate, except in mischievous contexts (which hide null pointer exceptions). Remove those specs from those processors too. If any of those mappings is valid, someone will need to submit a patch adding it ... along with a comment saying what OS provides the mapping, and in which context. Example, say "works with Linux 2.6.30+, in kernel mode". (Note that ARM Linux doesn't map kernel memory to zero ...) - Clarify docs on that "-virt" and other work area stuff. Seems to me work-area-virt is quite problematic; not every operating + system provides such static mappings; if they do, they're not in + every MMU context... Signed-off-by: David Brownell + +2009-11-06 David Brownell + + * : commit a9abfa7d06dbcfded97b7fb41f50d3581c24fbae Author: David + Brownell Date: Fri Nov 6 + 14:57:21 2009 -0800 + +2009-11-05 Zachary T Welch + + * : Simplify nand indentation. Removes check covered by new nand_command_get_device_by_num helper. + Reverses logic of probe check to further reduce indentation. + +2009-11-06 Zachary T Welch + + * : Fix arm11 vcr command parsing. + +2009-11-05 David Brownell + + * : ARM: other code uses the new inheritance/nesting scheme Remove most remaining uses of target->arch_info from ARM + infrastructure, where it hasn't already been updated. Signed-off-by: David Brownell + +2009-11-05 David Brownell + + * : ARM7TDMI uses the new inheritance/nesting scheme Use target_to_arm7_9(), replacing needless pointer traversals. Also: remove now-useless contents of arm7tdmi struct; it's almost + ready to be removed. Signed-off-by: David Brownell + +2009-11-05 David Brownell + + * : XScale uses the new inheritance/nesting scheme Use target_to_xscale(), replacing needless pointer traversals and + simplifying a bunch of code. Signed-off-by: David Brownell + +2009-11-05 David Brownell + + * : ARM966 uses the new inheritance/nesting scheme Use target_to_arm966(), replacing needless pointer traversals. Signed-off-by: David Brownell + +2009-11-05 David Brownell + + * : FA526 uses the new inheritance/nesting scheme Replace needless pointer traversals, simplify. Signed-off-by: David Brownell + +2009-11-05 David Brownell + + * : Cortex-M3: use the new inheritance/nesting scheme Use new target_to_cm3() and target_to_armv7m() inlines, instead of a + series of x->arch_info conversions. Remove arch_info, since nothing + uses it. Also fix an omission: the Cortex-M3 commands didn't verify that + they were operating on that kind of target. Add comment about the + ARMv7M version of that omission. Signed-off-by: David Brownell + +2009-11-05 David Brownell + + * : ARM7TDMI: remove forward decls The forward decls are just code clutter; remove them, by moving + their references after definitions. This is another file which + never needed even one internal forward declaration. Also shrink a few overly-long lines with function declarations or + definitions; get rid of arm7tdmi_register_commands(), it's not + needed (just delegated); minor whitespace declutter. Signed-off-by: David Brownell + +2009-11-05 David Brownell + + * : FA526: remove exports and forward decls Unneeded exports cause confusion about the module interfaces. Make + most functions static. The forward decls are just code clutter; remove them, by moving + their references after definitions. This is another file which + never needed even one internal forward declaration. Signed-off-by: David Brownell + +2009-11-05 David Brownell + + * : ARM966: remove exports and forward decls Unneeded exports cause confusion about the module interfaces. Make + most functions static. The forward decls are just code clutter; remove them, by moving + their references after definitions. This is another file which + never needed even one internal forward declaration. Also remove needless arm966e_init_target(), in favor of the arm9tdmi + routine to which it delegates its work. This saved over 100 bytes of code on x86_32. Signed-off-by: David Brownell + +2009-11-05 David Brownell + + * : ARM920: remove exports and forward decls Unneeded exports cause confusion about the module interfaces. Make + most functions static. Add a short header comment. The forward decls are just code clutter; remove them, by moving + their references after definitions. This is another file which + never needed even one internal forward declaration. This saved almost 900 bytes of code on x86_32; it seems the compiler + can leverage its knowledge that these functions are not called from + the outside world... Signed-off-by: David Brownell + +2009-10-23 Zachary T Welch + + * : Improve str9x config command argument parsing. + +2009-10-22 Zachary T Welch + + * : Improve stm32x.c command argument parsing. + +2009-10-22 Zachary T Welch + + * : Improve pic32mx.c command argument parsing. + +2009-10-23 Zachary T Welch + + * : Improve lpc3180_nand_controller.c parsing. This fixes a memory leak in lpc3180_nand_device_command by + reordering the malloc to occur after all parsing has completed. + +2009-10-23 Zachary T Welch + + * : Improve lpc288x.c command argument parsing. + +2009-10-23 Zachary T Welch + + * : Improve cfi.c command argument parsing. + +2009-10-22 Zachary T Welch + + * : Improve orion_nand.c command argument parsing. + +2009-10-22 Zachary T Welch + + * : Improve at91sam7.c command argument parsing. + +2009-10-22 Zachary T Welch + + * : Improve nand.c command argument parsing. + +2009-10-23 Zachary T Welch + + * : Add Flash/NAND bank command argument helpers. This eliminates redundant code for parsing and retreiving the bank + specified from a script command argument. This patch was written to + replace existing functionality; however, the parsing logic can be + updated later to allow flash commands to accept bank names as well + as their numbers. + +2009-10-22 Zachary T Welch + + * : Improve etm command argument parsing. + +2009-10-24 Zachary T Welch + + * : Improve arm_adi_v5 command argument parsing. + +2009-10-24 Zachary T Welch + + * : Improve xscale command argument parsing. + +2009-10-24 Zachary T Welch + + * : Improve arm966e command argument parsing. + +2009-10-24 Zachary T Welch + + * : Improve arm920t command argument parsing. + +2009-10-22 Zachary T Welch + + * : Improve arm7_9_common command argument parsing. + +2009-10-24 Zachary T Welch + + * : Improve armv7a command argument parsing. + +2009-10-24 Zachary T Welch + + * : Improve xscale command argument parsing. + +2009-10-24 Zachary T Welch + + * : Update all server port command to use new helper. + +2009-10-22 Zachary T Welch + + * : Improve target.c command argument parsing. Passes cmd_ctx into parse_load_image_command_args for reporting the + parsing errors therein. + +2009-10-22 Zachary T Welch + + * : Improve debug_level command argument parsing. + +2009-10-22 Zachary T Welch + + * : Add stringify macros in src/helper/types.h. + +2009-10-27 Øyvind Harboe + + * : arm11: check if target is halted before executing mrc/mcr + commands. Signed-off-by: Øyvind Harboe + +2009-10-26 Øyvind Harboe + + * : target: check args to mrc/mcr. Signed-off-by: Øyvind Harboe + +2009-10-24 Øyvind Harboe + + * : TODO: Wrote up list of remaining tasks for target->type->mrc/mcr Signed-off-by: Øyvind Harboe + +2009-10-24 Øyvind Harboe + + * : cortex_a8: add mrc mcr interface. Signed-off-by: Øyvind Harboe + +2009-11-05 David Brownell + + * : watchpoint_add() cleanup Fail watchpoint_add() if it's the same address but the parameters + are different ... don't just assume having the same address means + the same watchpoint! (Note that overlapping watchpoints aren't + detected...) Handle unrecognized return codes more sanely; don't exit()! And + describe command params right. Signed-off-by: David Brownell + +2009-11-05 David Brownell + + * : Cortex-M3: minor cleanup There's no reason to read which interrupts are enabled from the + NVIC; that state isn't used. Plus, it's highly dynamic since + firmware can change it at any time; remove the support for those + state records. Remove duplicate definition of DWT_CTRL address; shrink a line. Signed-off-by: David Brownell + +2009-11-05 David Brownell + + * : ARMv7M: add docs, remove exports Add Doxygen for the exported ARMv7-M interfaces. Make the non-exported stuff static. Remove functions and data which + are now observably unused. Add comment about a small speedup that the run_algorithm() logic + could use. Shrink a few too-long lines. Signed-off-by: David Brownell + +2009-10-26 Øyvind Harboe + + * : Make default implementation of mdw/mmw phys return error 'not + implemented' + +2009-10-30 Øyvind Harboe + + * : debug interface: get rid of unused pre_debug fn Removing unused code makes it much less mysterius. Signed-off-by: Øyvind Harboe + +2009-11-04 David Brownell + + * : ft2232: cleanup Previous patch somehow made GCC lose some of its cookies; work + around, zero-init that struct. Clean up code from the previous patch. Signed-off-by: David Brownell + +2009-11-04 David Brownell + + * : PXA255: support Intel "Lubbock" platform Config for Intel's "Lubbock" PXA255 development board. Even more so + than the PXA255 itself, this is obsolete. AFAIK this was the first + generally available development platform for PXA255. Intel stopped + providing these after other devel boards became available. One interesting thing about this board from the OpenOCD perspective + is probably its flash configuration. Each bank is 32 bits wide, + built from two 16-bit StrataFlash chips wired in parallel. This + doubles throughput ... it reads/writes 32 bits in the time a single + chip takes to write just 16 bits. This conf mostly works, given XScale bugfixes, but has some issues + (notably: no access to the on-board SDRAM) flagged by FIXMEs. Signed-off-by: David Brownell + +2009-11-04 David Brownell + + * : Version 0.3.0 Remove -dev tag, remove -rc tag. Signed-off-by: David Brownell + +2009-11-04 David Brownell + + * : Doc: fix broken link Signed-off-by: David Brownell + +2009-11-04 David Brownell + + * : Other files: stop referring to ChangeLog too The ChangeLog idiom is redundant given any decent SCM. Time to + phase it out here. Signed-off-by: David Brownell + +2009-11-04 David Brownell + + * : Tweak release docs Contrast releases to git snapshot tarballs. Mention that releases + have some quality-improvement focus, with special non-"dev" version + IDs. Explain more about version IDs, using "openocd -v" to see + them, etc; Make release milestone info be less specific about timing, and + presume we have both a merge window and an RC stage. Rework the release process information to match reality a bit more + closely. Reference the version.sh script (in one place the wrong + script was referenced). Bugfix branches get special treatment, + while non-bugfix releases are more or less what *defines* being the + mainline branch. Signed-off-by: David Brownell + +2009-11-04 Øyvind Harboe + + * : configure: fix build problems with eCos Various include files require some other include files to be + included first. Copied solution from net/if.h. Signed-off-by: Øyvind Harboe + +2009-11-03 Øyvind Harboe + + * : target: 20 second timeout/megabyte for CRC check There was a fixed 20 second timeout which is too little for large, + slow timeout checks. Signed-off-by: Øyvind Harboe + +2009-11-02 Øyvind Harboe + + * : target: require working area for physical/virtual addresses to + be specified Fixed bug: if virtual address for working memory was not specified + and MMU was enabled, then address 0 would be used. Require working address to be specified for both MMU enabled and + disabled case. For some completely inexplicable reason this fixes the regression in + svn 2646 for flash write in arm926ejs target. The logs showed that + MMU was disabled in the case below: + https://lists.berlios.de/pipermail/openocd-development/2009-November/011882.htmlSigned-off-by: Øyvind Harboe + +2009-11-01 David Brownell + + * : User's Guide: more init info, autoprobing, etc Mention the autoprobing as a tool that may be useful when figuring + out how to set up; and add a section showing how to use that + mechanism (with an example). Strengthen the differences between config and run stage + descriptions; add a section for the latter. Mention Dragonite. Signed-off-by: David Brownell + +2009-11-01 Freddie Chopin + + * : remove "-ircapture 0x1 -irmask 0x1" from stm32.cfg Gets rid of the runtime warning "stm32.bs: nonstandard IR mask" [dbrownell@users.sourceforge.net: line lengths, note issue, section + ref] Signed-off-by: David Brownell + +2009-10-29 Freddie Chopin + + * : target.cfg: use $_TARGETNAME for flash This gets rid of runtime warnings from the use of numbers. STM32 + and LPC2103 were tested. Other LPC updates are the same, and so are + safe. The CFI updates match other tested changes now in the tree. Signed-off-by: David Brownell + +2009-10-30 David Brownell + + * : ARM926: fix arm926ejs_mmu() reading from bad pointer I'm suspecting this code can never have worked, since the original + commit (svn #335) in early 2008. Fix is just copy/paste from another (working) function. Signed-off-by: David Brownell + +2009-10-29 Michael Roth + + * : SVF: fix checking bit pattern against length The code works like follow (N = bit_len): N -1 %4 2<< -1 ~ (binary) -------------------------------------------------- 1 0 0 2 1 1111 1110 2 1 1 4 3 1111 1100 3 2 2 8 7 1111 1000 4 3 3 16 15 1111 0000 5 4 0 2 1 1111 1110 6 5 1 4 3 1111 1100 7 6 2 8 7 1111 1000 8 7 3 16 15 1111 0000 ... ... ... ... ... ... Addresses a bug reported by FangfangLi . [dbrownell@users.sourceforge.net: fix spelling bug too] Signed-off-by: Michael Roth Cc: FangfangLi + Signed-off-by: David Brownell + + +2009-10-29 David Brownell + + * : XSVF: bugfix handling state paths Implement XSVF support for detailed state path transitions, by + collecting sequences of XSTATE transitions into paths and then + calling pathmove(). It seems that the Xilinx tools want to force state-by-state + transitions instead of relying on the standardized SVF paths. Like + maybe there are XSVF tools not implementing SVF paths, which are all + that we support using svf_statemove(). So from IRPAUSE, instead of just issuing "XSTATE DRPAUSE" they will + issue XSTATES for each intermediate state: first IREXIT2, then + IRUPDATE, DRSELECT, DRCAPTURE, DREXIT1, and finally DRPAUSE. This + works now. Handling of paths that go *through* reset is a trifle dodgey, but it + should be safe. Tested-by: Wookey Signed-off-by: David Brownell + +2009-10-28 Zachary T Welch + + * : The openocd 0.3.0-rc0 release. Remove '-dev' version tag: 0.3.0-rc0-dev -> 0.3.0-rc0 + +2009-10-28 David Brownell + + * : ARM926: remove exports and forward decls Unneeded exports cause confusion about the module interfaces. Only + the Feroceon code builds on this, so only routines it reuses should + be public.. Make most remaining functions static, and fix some of + the line-too-long issues. The forward decls are just code clutter; move their references + later, after the normal declarations. Turns out we don't need even + one forward declaration in this file. Signed-off-by: David Brownell + +2009-10-22 Zachary T Welch + + * : Add script to test the release process. Runs the release.sh script in a freshly cloned repository, charting + one hypothetical future of OpenOCD's lineage. + +2009-10-20 Zachary T Welch + + * : Factor version munging capabilities out of release.sh. + +2009-10-24 Zachary T Welch + + * : Add git2cl from repo.or.cz as a submodule in tools/git2cl. + +2009-10-27 Nicolas Pitre + + * : ARM: fix single-step of Thumb unconditional branch Only type 1 branch instruction has a condition code, not type 2. + Currently they're both tagged with ARM_B which doesn't allow for the + distinction. Signed-off-by: Nicolas Pitre Signed-off-by: David + Brownell + +2009-10-27 Oleg Seiljus + + * : Signalyzer: H2 and H4 support This patch includes partial support for these new JTAG adapters. + More complete support will require updates to the libftdi code, for + EEPROM access. [dbrownell@users.sourceforge.net: fix whitespace, linelen, etc ] Signed-off-by: David Brownell + +2009-10-27 Nicolas Pitre + + * : ARM: fix Thumb mode handling when single-stepping register based + branch insns Currently, OpenOCD is always caching the PC value without the T bit. + This means that assignment to the PC register must clear that bit + and set the processor state to Thumb when it is set. And when the + PC register value is transferred to another register or stored into + memory then the T bit must be restored. Discussion: It is arguable if OpenOCd should have preserved the + original PC value which would have greatly simplified this code. + The processor state could then be obtained simply by getting at bit + 0 of the PC. This however would require special handling elsewhere + instead since the T bit is not always relevant (like when PC is used + with ALU insns or as an index with some addressing modes). It is + unclear which way would be simpler in the end. Signed-off-by: Nicolas Pitre Signed-off-by: David + Brownell + +2009-10-27 Nicolas Pitre + + * : ARM: call thumb_pass_branch_condition() only for actual branch + opcodes Calling it first with every opcodes and then testing if the opcode + was indeed a branch instruction is wasteful and rather strange. If + ever thumb_pass_branch_condition() has side effects (say, like + printing a debugging traces) then the result would be garbage for + most Thumb instructions which have no condition code. While at it, let's make the nearby code more readable by reducing + some of the redundant brace noise and reworking the error handling + construct. Signed-off-by: Nicolas Pitre Signed-off-by: David + Brownell + +2009-10-26 David Brownell + + * : JTAG: "jtag newtap ..." cleanup Get rid of needless variable, improve and shrink diagnostic. Signed-off-by: David Brownell + +2009-10-26 David Brownell + + * : omap3530: target reset/init improvements Now I can issue "reset halt" and have everything act smoothly; the + vector_catch hardware is obviously not kicking in, but the rest of + the reset sequence acts sanely. - TAP "setup" event enables the DAP, not omap3_dbginit (resolving a chicken/egg bug I noted a while back) - Remove stuff from omap3_dbginit which should never be used in event handlers - Cope better with slow clocking during reset Also, stop hard-wiring the target name: use the input params in the + standard way, and set up $_TARGETNAME as an output param. Signed-off-by: David Brownell + +2009-10-26 Spencer Oliver + + * : Fix incorrect line endings Signed-off-by: Spencer Oliver + +2009-10-26 Wookey + + * : balloon3 board base config This is the very basic board config for the balloon3 board cpu JTAG + channel. The rest of the config comprises another 14 .cfg files which I + suspect openocd doesn't really want all of. I'm still not sure how + to deal with this. I'll post another mail/patch to discuss. Signed-off-by: David Brownell + +2009-10-23 Øyvind Harboe + + * : Idea for adding watchpoint masks. + +2009-10-25 David Brownell + + * : minor fixes to TODO list + +2009-10-25 Øyvind Harboe + + * : check if mmu is enabled before using mmu code path + +2009-10-25 David Brownell + + * : JTAG: jtag_tap_init() bugfixes Stop allocating three bytes per IR bit, and cope somewhat better + with IR lengths over 32 bits. Signed-off-by: David Brownell + +2009-10-24 Øyvind Harboe + + * : vector_catch and watchpoint TODO items. + +2009-10-23 Øyvind Harboe + + * : Improve help for arm9 vector_catch. + +2009-10-23 Øyvind Harboe + + * : mcr/mrc interface work. Implemented for arm926ejs and arm720t. + mcr/mrc commands added. + +2009-10-23 David Brownell + + * : jtag: clean up TAP state name handling Some cosmetic cleanup, and switch to a single table mapping between + state names and symbols (vs two routines which only share that state + with difficulty). Get rid of TAP_NUM_STATES, and some related knowledge about how TAP + numbers are assigned. Later on, this will help us get rid of more + such hardwired knowlege. Signed-off-by: David Brownell + +2009-10-22 Nicolas Pitre + + * : Ferocion: fix corruption of r0 when resuming Thumb mode The wrong variable (pc instead of r0) was used. Furthermore, + someone did cover this error by stupidly silencing the compiler + warning that occurred before a dummy void reference to r0 was added + to the code. Signed-off-by: David Brownell + +2009-10-22 David Brownell + + * : ETM: rename registers, doc tweaks The register names are perversely not documented as zero-indexed, so + rename them to match that convention. Also switch to lowercase + suffixes and infix numbering, matching ETB and EmbeddedICE usage. Update docs to be a bit more accurate, especially regarding what the + "trigger" event can cause; and to split the issues into a few more + paragraphs, for clarity. Make "configure" helptext point out that "oocd_trace" is prototype + hardware, not anything "real". Signed-off-by: David Brownell + +2009-10-21 Øyvind Harboe + + * : mww_phys retired. Replaced by generic mww phys in target.c + +2009-10-21 Øyvind Harboe + + * : retire obsolete mXY_phys commands. Handled by generic memory + read/modify commands and target read/write physical memory + callbacks. + +2009-10-21 Øyvind Harboe + + * : add support for target_read/write_phys_memory callbacks. + +2009-10-21 Øyvind Harboe + + * : commit 69a6037ce6e76dca4117689208358231dffa0929 Author: Øyvind + Harboe Date: Wed Oct 21 13:10:32 2009 + +0200 + +2009-10-21 Øyvind Harboe + + * : Retire obsolete and superfluous implementations of virt2phys in + each target. This is done in a polymorphic implementation in + target.c + +2009-10-21 Øyvind Harboe + + * : Defined target_write_memory() to be able to handle implementing + breakpoints for read only ram(e.g. MMU write protected. + +2009-10-20 David Brownell + + * : XSVF: use svf_add_statemove() XSVF improvements: - Layer parts of XSVF directly over SVF, calling + svf_add_statemove() instead of expecting jtag_add_statemove() to + conform to the SVF/XSVF requirements (which it doesn't). This should improve XSTATE handling a lot; it removes most users + of jtag_add_statemove(), and the comments about how it should + really do what svf_add_statemove() does. - Update XSTATE logic to be a closer match to the XSVF spec. The + main open issue here is (still) that this implementation doesn't + know how to build and submit paths from single-state transitions ... + but now it will report that error case. - Update the User's Guide to mention the two utility scripts for working with XSVF, and to mention the five extension opcodes. Handling of state transition paths is, overall, still a mess. I + think they should all be specified as paths not unlike SVF uses, and + compiled to the bitstrings later ... so that we can actually make + sense of the paths. (And see the extra clocks, detours through RUN, + etc.) Signed-off-by: David Brownell + +2009-10-20 Øyvind Harboe + + * : Added the faux flash driver and target. Used for testing. + +2009-10-20 Øyvind Harboe + + * : More svn to git version string fixes. + +2009-10-19 David Brownell + + * : davinci: add watchdog reset method Lightly tested on dm365. Signed-off-by: David Brownell + +2009-10-19 David Brownell + + * : SVF/XSVF: comment and whitespace fixes SVF: comment the predefined/default paths; make them static const SVF, XSVF: whitespace fixes, mostly so copyrights display sanely Signed-off-by: David Brownell + +2009-10-19 Redirect 'Slash' NIL + + * : MinGW: always use "-D__USE_MINGW_ANSI_STDIO" This is unfortunately needed to make stdio work like OpenOCD expects + -- matching the ANSI-C standard, instead of MS-Windows. I tested it in both MinGW-W64 on Vista 64 and MinGW-W32 on XP, and I + don't see any adverse effects to enabling it for all MinGW versions. + +2009-10-19 David Brownell + + * : Doc: jtag_init must validate scan chain too Same requirement as like init_reset, and for the same reason: we + need to start with a known and working state. + +2009-10-19 David Brownell + + * : Ignore openocd.exe for "git status" + +2009-10-19 oyvind + + * : Sync with official Jim Tcl repository. + +2009-10-18 Dean Glazeski + + * : SDRAM and clock configuration for the SAM9-L9260 board from + Olimex + +2009-10-17 David Brownell + + * : Ignore two more generated files On Windows the name is "bin2char.exe". All operating systems now + have "xscale_handler.h". + +2009-10-17 Redirect \"Slash\" NIL + + * : jim-eventloop for MinGW-w64 Use JIM_WIDE_MODIFIER for the sscanf format, and apply it for + MINGW32 as well as other Windows environments. (Microsoft doesn't + conform to the C99 standard, and uses "%I64d" not "%lld" for "long + long".) NB: __MINGW32__ should work on both w32 and w64,. + +2009-10-16 David Brownell + + * : xscale: better fix for debug_handler.bin Generate a C struct with the data, and use that, instead of an + assembly language file. The assembly language causes issues on + Darwin and MS-Windows, which don't necessarily use GNU AS; or if + they do, don't necessarily use its ELF syntax. It's also better in two other ways: fewer global symbols; and the + init-time size check gets optimized away at compile time. (Unless + it fails, in which case bigger chunks of the file vanish.) Signed-off-by: David Brownell + +2009-10-14 David Brownell + + * : portability updates Based on some patches from for + preliminary Win64 compilation. More such updates are needed, but + they need work. Compile tested on 64 and 32 bit Linuxes, and + Cygwin. Signed-off-by: David Brownell + +2009-10-14 Wookey + + * : Fw: [PATCH] OpenRD board configuration Ofrwarded from Ron, who's not subscribed. ----- Forwarded message from Ron ----- From: Ron Date: Wed, 14 Oct 2009 04:50:17 +1030 To: + wookey@debian.org Subject: [PATCH] OpenRD board configuration + X-Spam-Status: No, score=-3.6 required=4.5 + tests=BAYES_00,RCVD_IN_DNSWL_LOW autolearn=ham version=3.2.5 This piggybacks on the 'sheevaplug' layout which uses the same + Kirkwood SoC. Signed-off-by: Ron Lee + +2009-10-14 Øyvind Harboe + + * : Work in progress on arm11 reset. Assert srst. + +2009-10-14 David Brownell + + * : Fix problems building xscale_debug.S + +2009-10-13 Lennert Buytenhek + + * : fix detection of PLD instructions Signed-off-by: Lennert Buytenhek + Signed-off-by: David Brownell + +2009-10-13 David Brownell + + * : cosmetic cleanup in TMS tables Cleanup comments and layout/whitespace in the TMS tables. Table + contents stayed the same (ignoring whitespace). Signed-off-by: David Brownell + +2009-10-11 Yauheni Kaliuta + + * : Do not replace virt2phys with the default one if it was assigned Signed-off-by: Yauheni Kaliuta + +2009-10-13 Øyvind Harboe + + * : Missing type for eCos. + +2009-10-13 Øyvind Harboe + + * : Delete commented out code. Add a bit of error checking. + +2009-10-13 Øyvind Harboe + + * : Propagate error from assert, deassert and halt on tcl target + object. + +2009-10-12 Øyvind Harboe + + * : More error propagation fixes. + +2009-10-12 Wookey + + * : Xilinx xcr3256.cfg basic config script + +2009-10-12 Øyvind Harboe + + * : Propagate wDTR/rDTR failure immediately, otherwise it's followed + up by timeout errors. + +2009-10-12 Øyvind Harboe + + * : burst writes work fine. clean up junk. + +2009-10-12 David Brownell + + * : simplify XScale debug handler installation Load the XScale debug handler from the read-only data section + instead of from a separate file that can get lost or garbaged. This + eliminates installation and versioning issues, and also speeds up + reset handling a bit. Plus some minor bits of cleanup related to loading that handler: + comments about just what this handler does, and check fault codes + while writing it into the mini-icache. The only behavioral changes should be cleaner failure modes after + errors during handler loading, and being a bit faster. NOTE: presumes GNU assembly syntax, with ".incbin"; and ELF, + because of the syntax of the ".size" directive. Signed-off-by: David Brownell + +2009-10-12 Øyvind Harboe + + * : Merge commit 'origin/master' + +2009-10-12 Øyvind Harboe + + * : Supply default reset_config statement to make target scripts + useful standalone and provide sensible default + +2009-10-11 David Brownell + + * : xscale.c cleanup Declare almost everything as static. Move stuff to remove most + forward references. Remove most forward declarations. Warn if the + unimplemented register functions get called. Signed-off-by: David Brownell + +2009-10-11 David Brownell + + * : xscale minor cleanup Add a header comment referencing useful XScale specs. Make most + data static, and the tables readonly. Scrub extra blank lines. + Return fault codes from one routine. Remove a needless NOP methood. (BUGFIX) When we update R0, mark R0 as dirty/valid ... not R15/PC! Signed-off-by: David Brownell + +2009-10-10 Wookey + + * : Fix reset delays and tinker with ID's + +2009-10-09 David Brownell + + * : add documentation about reset customization We added two overridable procedures; document them, and the two jtag + arp_* operations they necessarily expose. Update the comment about the jtag_init_reset() routine; it's been + obsolete for as long as it's had SRST support. Signed-off-by: David Brownell + +2009-10-09 Øyvind Harboe + + * : ARM11 error checking + +2009-10-09 Øyvind Harboe + + * : Added tip in documentation on how to translate quirky syntax + +2009-10-08 David Brownell + + * : add overridable Tcl "init_reset" This abstracts the "jtag arp_init-reset" call into a method called + from OpenOCD startup and reset processing. Platforms which have different requirements for how such hard resets + must be performed can now override "init_reset" instead of needing + to rebuild custom hacked versions of the server. Signed-off-by: David Brownell + +2009-10-08 Rabeeh Khoury + + * : Function to flash SheevaPlug u-boot sectors This function is used by the SheevaPlug installer to flash the erase + and re-flash the U-Boot environment in the NAND Flash. + +2009-10-08 David Brownell + + * : prevent abort via polling during jtag_reset Observed: openocd: core.c:318: jtag_checks: Assertion `jtag_trst == 0' + failed. The issue was that nothing disabled background polling during calls + from the TCL shell to "jtag_reset 1 1". Fix by moving the existing + poll-disable mechanism to the JTAG layer where it belongs, and then + augmenting it to always pay attention to TRST and SRST. Signed-off-by: David Brownell + +2009-10-08 David Brownell + + * : commit 4aacf01e194d09fb55dc759fc42ac42c8432c015 Author: Øyvind + Harboe Date: Thu Oct 8 15:43:51 2009 + +0200 + +2009-10-08 Øyvind Harboe + + * : Add .project to .gitignore + +2009-10-08 Øyvind Harboe + + * : Update copyright statements. Make it easier to sync with Jim Tcl + +2009-10-07 John Rigby + + * : iMX25 target support Signed-off-by: David Brownell + +2009-10-07 David Brownell + + * : commit 03c9e48f88fa8b681b77c6c35d6da0a0e838a7e8 Author: + dbrownell Date: + Thu Oct 8 00:13:50 2009 +0000 + +2009-10-07 dbrownell + + * : Force sane SRST and TRST initialization At least some FT2232 based adapters don't necessarily come up in the + expected state, with SRST and TRST disabled. Since other adapters + could suffer the same problem, let's avoid needing to patch every + driver and just force *all* adapters to initialize those values + properly at server startup. git-svn-id: svn://svn.berlios.de/openocd/trunk@2824 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-07 dbrownell + + * : Remove much #ifdeffery around _DEBUG_JTAG_IO_ usage. Have + DEBUG_JTAG_IO() always trigger necessary warnings. git-svn-id: svn://svn.berlios.de/openocd/trunk@2822 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-07 David Brownell + + * : commit f8c8d8bc72b2a87d2b2e3d583a052d8f0e5d22ea Author: + dbrownell Date: + Wed Oct 7 16:15:21 2009 +0000 + +2009-10-07 dbrownell + + * : Note bug in handling of variables through command line + parameters. git-svn-id: svn://svn.berlios.de/openocd/trunk@2819 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-07 oharboe + + * : first stab at imx35 reset init script git-svn-id: svn://svn.berlios.de/openocd/trunk@2817 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-07 oharboe + + * : add timeouts and fix syntax error handling of mrc/mcr commands. git-svn-id: svn://svn.berlios.de/openocd/trunk@2815 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-07 oharboe + + * : increase pause before reboot so web interface remains responsive + when issuing a reboot of zy1000 git-svn-id: svn://svn.berlios.de/openocd/trunk@2813 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-07 oharboe + + * : 1.55 snapshot git-svn-id: svn://svn.berlios.de/openocd/trunk@2810 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-06 David Brownell + + * : commit 0da2f750a1d437b50b21ac7ee766188a47b37fad Author: + dbrownell Date: + Tue Oct 6 22:56:52 2009 +0000 + +2009-10-06 dbrownell + + * : Dragonite has the same EICE affliction as feroceon. From: Nicolas Pitre git-svn-id: svn://svn.berlios.de/openocd/trunk@2807 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-06 David Brownell + + * : commit 39b57471bfd92ef0d9a3aceb69f40c1335f5b62f Author: oharboe + Date: Tue Oct 6 + 08:10:57 2009 +0000 + +2009-10-06 oharboe + + * : stop using targetnum git-svn-id: svn://svn.berlios.de/openocd/trunk@2804 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-05 David Brownell + + * : commit 64ec7f66a896fc4de6b472cffb6ef5740a76f61d Author: + dbrownell Date: + Mon Oct 5 23:45:14 2009 +0000 + +2009-10-05 David Brownell + + * : commit 7a57c316196f93c7e31b7d00eb9b52177ae874c6 Author: + dbrownell Date: + Mon Oct 5 08:23:33 2009 +0000 + +2009-10-05 dbrownell + + * : Add a new JTAG "setup" event; use for better DaVinci ICEpick + support. The model is that this fires after scanchain verification, when it's + safe to call "jtag tapenable $TAPNAME". So it will fire as part of + non-error paths of "init" and "reset" command processing. However + it will *NOT* trigger during "jtag_reset" processing, which skips + all scan chain verification, or after verification errors. ALSO: - switch DaVinci chips to use this new mechanism - log TAP activation/deactivation, since their IDCODEs aren't + verified - unify "enum jtag_event" scripted event notifications - remove duplicative JTAG_TAP_EVENT_POST_RESET git-svn-id: svn://svn.berlios.de/openocd/trunk@2800 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-05 dbrownell + + * : Update the NEWS file to cover more of the user-visible changes. git-svn-id: svn://svn.berlios.de/openocd/trunk@2798 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-02 mlu + + * : Updated reset event handling in omap3530 cfg git-svn-id: svn://svn.berlios.de/openocd/trunk@2796 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-02 mlu + + * : Make sure that DSCR_DTR_RX is not full before writing git-svn-id: svn://svn.berlios.de/openocd/trunk@2794 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-02 mlu + + * : Added asser_reset and deassert_reset for cortex_a8 git-svn-id: svn://svn.berlios.de/openocd/trunk@2792 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-10-02 dbrownell + + * : Minor ETB and ETM bugfixes and doc updates - ETB * report _actual_ hardware status, not just expected status * add a missing diagnostic on a potential ETB setup error * prefix any diagnostics with "ETB" - ETM * make "etm status" show ETM hardware status too, instead of just traceport status (which previously was fake, sigh) - Docs * flesh out "etm tracemode" docs a bit * clarify "etm status" ... previously it was traceport status * explain "etm trigger_percent" as a *traceport* option ETM+ETB tracing still isn't behaving, but now I can see that part of + the reason is that the ETB turns itself off almost immediately after + being enabled, and before collecting any data. git-svn-id: svn://svn.berlios.de/openocd/trunk@2790 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-30 zwelch + + * : Update release process documentation. - Improve and clarify the wording of the introduction. - Add section on version taggging. - Some other minor corrections. git-svn-id: svn://svn.berlios.de/openocd/trunk@2788 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-30 zwelch + + * : Add numeric version tag support to release script. The release process itself does not use this support yet, but it + allows packagers to automate the process of managing their own tags, + if they patch the source code before releasing binaries. The + release processes should be revised to incorporate this feature to + support -rc packages. git-svn-id: svn://svn.berlios.de/openocd/trunk@2786 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-30 zwelch + + * : Add workaround to release script to update source code URL + keyword. git-svn-id: svn://svn.berlios.de/openocd/trunk@2784 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-30 zwelch + + * : Fix release script bugs after experience from 0.2.0: - The NEWS step failed due to an empty commit comment. - The final release step would have failed, because the steps to + switch from the secure to insecure repository (and back again) + require both switch and a URL relocation steps git-svn-id: svn://svn.berlios.de/openocd/trunk@2782 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-30 mlu + + * : Add DSCR_DTR_RX_FULL bit define git-svn-id: svn://svn.berlios.de/openocd/trunk@2780 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-30 oharboe + + * : michal smulski reset now works git-svn-id: svn://svn.berlios.de/openocd/trunk@2778 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-29 dbrownell + + * : ARM11 command handling fixes - Commands were supposed to have been "arm11 memwrite ..." not "memwrite ..." - Get rid of obfuscatory macros - Re-alphabetize - Add docs for "arm11 vcr" git-svn-id: svn://svn.berlios.de/openocd/trunk@2776 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-29 dbrownell + + * : Doc updates: add section on target software changes, minor + fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2774 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-29 dbrownell + + * : ETB: cleanup needless symbol exports and forward decls. git-svn-id: svn://svn.berlios.de/openocd/trunk@2772 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-29 oharboe + + * : reentry assert git-svn-id: svn://svn.berlios.de/openocd/trunk@2770 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-29 oharboe + + * : added t/nsrst_assert_width commands git-svn-id: svn://svn.berlios.de/openocd/trunk@2768 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-28 oharboe + + * : spelling fix git-svn-id: svn://svn.berlios.de/openocd/trunk@2766 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-27 dbrownell + + * : Add list of JTAG adapter drivers with TAP_RESET statemove bug. git-svn-id: svn://svn.berlios.de/openocd/trunk@2764 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-27 dbrownell + + * : Don't provide invalid OMAP5912 IR capture value/mask attributes git-svn-id: svn://svn.berlios.de/openocd/trunk@2762 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-26 dbrownell + + * : Diagnostics tweaks for jtag_examine_chain() failure paths. git-svn-id: svn://svn.berlios.de/openocd/trunk@2760 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-26 dbrownell + + * : Streamline Capture-IR handling and integrity test. Change the handling of the "-ircapture" and "-irmask" parameters to + be slightly more sensible, given that the JTAG spec describes what + is required, and that we already require that conformance in one + place. IR scan returns some bitstring with LSBs "01". - First, provide and use default values that satisfy the IEEE spec. Existing TAP configs will override the defaults, but those parms are no longer required. - Second, warn if any TAP gets set up to violate the JTAG spec. It's likely a bug, but maybe not; else this should be an error. Improve the related diagnostics to say which TAP is affected. And associated minor fixes/cleanups to comments and diagnostics. git-svn-id: svn://svn.berlios.de/openocd/trunk@2758 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-25 oharboe + + * : Michael Hasselberg target configuration + files for Toshiba TX09 familiy git-svn-id: svn://svn.berlios.de/openocd/trunk@2756 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-24 oharboe + + * : When attaching GDB to OpenOCD, the target state is no longer + affected. Added gdb_sync feature that allows GDB to sync up to + target state. Issue "monitor gdb_sync" and the next stepi, will + return immediately with updated register values to GDB. git-svn-id: svn://svn.berlios.de/openocd/trunk@2754 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-23 dbrownell + + * : When setting up an ETM, cache its ETM_CONFIG register. Then + only expose the registers which are actually present. They could be + missing for two basic reasons: - This version might not support them at all; e.g. ETMv1.1 doesn't have some control/status registers. (My sample of ARM9 boards shows all with ETMv1.3 support, FWIW.) - The configuration on this chip may not populate as many registers as possible; e.g. only two data value comparators instead of eight. Includes a bugfix in the "etm info" command: only one of the two + registers is missing on older silicon, so show the first one before + bailing. Update ETM usage docs to explain that those registers need to be + written to configure what is traced, and that some ETM configs are + not yet handled. Also, give some examples of the kinds of + constrained trace which could be arranged. git-svn-id: svn://svn.berlios.de/openocd/trunk@2752 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-23 dbrownell + + * : Initial ETM cleanups. Most of these are cosmetic: - Add a header comment - Line up the ETM context struct, pack it a bit - Remove unused context_id (this doesn't support ETMv2 yet) - Make most functions static - Remove unused string table and other needless lines of code - Correct "tracemode" helptext Also provide and use an etm_reg_lookup() to find entries in the ETM + register cache. This will help cope with corrected contents of that + cache, which doesn't include entires for non-existent registers. git-svn-id: svn://svn.berlios.de/openocd/trunk@2750 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-22 ntfreak + + * : - fix build issue under win32 (cygwin/msys) from svn r2746 git-svn-id: svn://svn.berlios.de/openocd/trunk@2748 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-22 dbrownell + + * : Make it easier to erase or protect through to the end of a (NOR) + flash chip: allow passing "last" as an alias for the number of the + last sector. Improve several aspects of error checking while we're at it. From: Johnny Halfmoon git-svn-id: svn://svn.berlios.de/openocd/trunk@2746 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-21 dbrownell + + * : Remove annoying end-of-line whitespace from doc/* files. git-svn-id: svn://svn.berlios.de/openocd/trunk@2744 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-21 dbrownell + + * : Remove annoying end-of-line whitespace from most src/* files; + omitted src/httpd git-svn-id: svn://svn.berlios.de/openocd/trunk@2742 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-21 dbrownell + + * : Ensure that DaVinci chips can't start with a too-fast JTAG + clock. It can be sped up later, once it's known the PLLs are + active. Note that modern tools from TI all use adaptive clocking; and that + if that's done with OpenOCD, "too fast" is also a non-issue. git-svn-id: svn://svn.berlios.de/openocd/trunk@2740 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-20 dbrownell + + * : Enhancement: stm32 flash protection error message This patch modifies an error message which, in its original state, I + find somewhat unhelpful. So a small hint was added. Signed-off-by: Johnny Halfmoon git-svn-id: svn://svn.berlios.de/openocd/trunk@2738 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-20 dbrownell + + * : Debug message updates: - Shrink messaging during resets, primarily by getting rid of "nothing happened" noise that hides *useful* information. - Improve: the "no IDCODE" message by identifying which tap only supports BYPASS; and the TAP event strings. Related minor code updates: - Remove two needless tests when examining the chain: we know we have a TAP, and that all TAPs have names. - Clean up two loops, turning "while"s into "for"s which better show what's actually being done. git-svn-id: svn://svn.berlios.de/openocd/trunk@2736 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-19 mlu + + * : Added CPUDBG_WCR_BASE define git-svn-id: svn://svn.berlios.de/openocd/trunk@2734 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-19 mlu + + * : Reduced sleep time after reset git-svn-id: svn://svn.berlios.de/openocd/trunk@2732 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-19 dbrownell + + * : Minor behavior fixes for the two JTAG reset events (C/internal, + and Tcl/external): - Reorder so *both* paths (TCK/TMS or TRST) can enable TAPs with ICEpick ... first C code flags TAPs that got disabled, then call any Tcl code that might want to re-enable them. - Always call the C/internal handlers when JTAG operations can be issued; previously that wasn't done when TRST was used. Plus some small cleanups (whitespace, strings, better messaging + during debug and on some errors) to reset-related code. git-svn-id: svn://svn.berlios.de/openocd/trunk@2730 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-18 mlu + + * : Move Cortex A8 debug access initialisation from omap3530.cfg to + cortex_a8.c git-svn-id: svn://svn.berlios.de/openocd/trunk@2728 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-18 dbrownell + + * : Tweak TCL reset script ... mostly improving descriptions of the + various steps, but also calling [target names] only once. git-svn-id: svn://svn.berlios.de/openocd/trunk@2726 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-17 dbrownell + + * : Minor fixes to NAND code and docs Erase logic: - command invocation + treat "nand erase N" (no offset/length) as "erase whole chip + N" + catch a few more bogus parameter cases, like length == 0 + (sigh) - nand_erase() should be static - on error + say which block failed, and if it was a bad block + don't give up after the first error; try to erase the rest - on success, say which nand device was erased (name isn't unique) Device list ("nand list"): - say how many blocks there are - split summary into two lines - give example in the docs Doc tweaks: - Use @option{...} for DaVinci's supported hardware ECC options For the record, I've observed that _sometimes_ erasing bad blocks + causes failure reports, and that manufacturer bad block markers + aren't always erasable (even when erasing their blocks doesn't + trigger an error report). git-svn-id: svn://svn.berlios.de/openocd/trunk@2724 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-17 oharboe + + * : michal smulski fix regression in + jtag_add_pathmove() which broke arm11 in r1825. Other uses of + jtag_add_pathmove are svn + xsvf + xscale... git-svn-id: svn://svn.berlios.de/openocd/trunk@2722 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-17 oharboe + + * : srst_gates_jtag option. at91sam9260 needs retesting, and + possibly srst_gates_jtag added to reset_config. Could i.MX27 be a + case where srst does not pull trst, but really srst gates jtag + clock? git-svn-id: svn://svn.berlios.de/openocd/trunk@2720 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-17 dbrownell + + * : Doc update: mention how ARM's WFI instruction affects JTAG + clocking by gating the core clock, and workarounds. Most details + are with the "halt" command, which is one of the first places this + issue will be noticed. git-svn-id: svn://svn.berlios.de/openocd/trunk@2718 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-16 mlu + + * : Use a variable armv7a->debug_base instead of hardedcoded + OMAP3530_DEBUG_BASE git-svn-id: svn://svn.berlios.de/openocd/trunk@2716 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-15 mlu + + * : Define debug_base, debug_ap, memory_ap in armv7a_common_t git-svn-id: svn://svn.berlios.de/openocd/trunk@2714 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-15 mlu + + * : Definy symbolic values for VA to PA address translation + operations git-svn-id: svn://svn.berlios.de/openocd/trunk@2712 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-15 oharboe + + * : added embedded ice programming while srst is asserted todo item git-svn-id: svn://svn.berlios.de/openocd/trunk@2710 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-14 mlu + + * : Cache invalidation when writing to memory git-svn-id: svn://svn.berlios.de/openocd/trunk@2708 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-14 oharboe + + * : fix email address git-svn-id: svn://svn.berlios.de/openocd/trunk@2706 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-14 oharboe + + * : fix warning git-svn-id: svn://svn.berlios.de/openocd/trunk@2704 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-13 mlu + + * : More CortexA8 debug register definitions. git-svn-id: svn://svn.berlios.de/openocd/trunk@2702 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-12 oharboe + + * : Dirk Behme document post TAP reset + event git-svn-id: svn://svn.berlios.de/openocd/trunk@2700 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-12 oharboe + + * : David Brownell Cleanup some the downloaded + ARM target algorithm code: - Provide more complete disassembly of the DCC bulk write code - Make code blocks "static const", in case GCC doesn't - Fix some tabbing/layout issues - Make some arm7_9_common.h flags be "bool" not "int"; and compact the layout a bit (group most bools together) git-svn-id: svn://svn.berlios.de/openocd/trunk@2698 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-11 oharboe + + * : tap post reset event added. Allows omap3530 to send 100 runtest + idle tickle's after a TAP_RESET. git-svn-id: svn://svn.berlios.de/openocd/trunk@2696 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-11 oharboe + + * : Nicolas Pitre put feroceon target definition at + the end so to avoid a bunch of useless forward declarations. git-svn-id: svn://svn.berlios.de/openocd/trunk@2694 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-11 oharboe + + * : spelling mistake git-svn-id: svn://svn.berlios.de/openocd/trunk@2692 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-11 oharboe + + * : registering a target event twice caused infinite loop. Same bug + as in jtag/core.c copy & pasted. git-svn-id: svn://svn.berlios.de/openocd/trunk@2690 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-11 oharboe + + * : Alexei Babich cleanup git-svn-id: svn://svn.berlios.de/openocd/trunk@2688 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-10 oharboe + + * : eol-style:native git-svn-id: svn://svn.berlios.de/openocd/trunk@2686 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-10 oharboe + + * : Alexei Babich fix problems with unecessary + tailend byte accesses. Use 16 bit access on tailend of a memory read + if possible. git-svn-id: svn://svn.berlios.de/openocd/trunk@2684 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-09 oharboe + + * : Rolf Meeser This patch adds target + algorithm support for those flash devices that do not support DQ5 + polling. So far they could only be programmed with host algorithm, + but this was way too slow. git-svn-id: svn://svn.berlios.de/openocd/trunk@2682 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-09 oharboe + + * : David Brownell Optionally shave time off + the armv4_5 run_algorithm() code: let them terminate using software + breakpoints, avoiding roundtrips to manage hardware ones. Enable this by using BKPT to terminate execution instead of "branch + to here" loops. Then pass zero as the exit address, except when + running on an ARMv4 core. ARM7TDMI, ARM9TDMI, and derived cores now + set a flag saying they're ARMv4. Use that mechanism in arm_nandwrite(), for about 3% speedup on a + DaVinci ARM926 core; not huge, but it helps. Some other algorithms + could use this too (mostly flavors of flash operation). git-svn-id: svn://svn.berlios.de/openocd/trunk@2680 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-08 mlu + + * : Report correct core instruction state for ARMv/A targets git-svn-id: svn://svn.berlios.de/openocd/trunk@2678 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-08 oharboe + + * : David Brownell Provide an "armv7a + disassemble" command. Current omissions include VFP (except as + coprocessor instructions), Neon, and various Thumb2 opcodes that are + not available in ARMv7-M processors. git-svn-id: svn://svn.berlios.de/openocd/trunk@2676 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-07 mlu + + * : Improved handling of instruction set state, helps for debugging + Thumb state. git-svn-id: svn://svn.berlios.de/openocd/trunk@2674 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-04 oharboe + + * : use "armv4_5 core_state arm" instead of soft_reset_halt, fewer + side effects git-svn-id: svn://svn.berlios.de/openocd/trunk@2672 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-04 oharboe + + * : Dirk Behme Add default fall back + freqency. git-svn-id: svn://svn.berlios.de/openocd/trunk@2670 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-04 oharboe + + * : Matt Hsu This patch simply enables the halting + debug mode. By enabling this bit, the processor halts when a debug + event such as breakpoint occurs. git-svn-id: svn://svn.berlios.de/openocd/trunk@2668 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-04 oharboe + + * : Matt Hsu Tidy up the bit-offset operation for + DSCR register git-svn-id: svn://svn.berlios.de/openocd/trunk@2666 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-04 oharboe + + * : David Claffey get rid of reset recursion git-svn-id: svn://svn.berlios.de/openocd/trunk@2664 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-02 oharboe + + * : David Claffey tested with the Atheros + reference design "PB44" git-svn-id: svn://svn.berlios.de/openocd/trunk@2662 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-09-01 ntfreak + + * : - fixes the incorrect info msg displayed during stellaris flash + programming. git-svn-id: svn://svn.berlios.de/openocd/trunk@2660 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-31 duane + + * : Warning fix git-svn-id: svn://svn.berlios.de/openocd/trunk@2658 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-31 oharboe + + * : Ferdinand Postema config script for the + MMnet1001 module from Propox. git-svn-id: svn://svn.berlios.de/openocd/trunk@2656 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-30 oharboe + + * : Dirk Behme Fix typo in help text. It + has to be 'production_test' instead of 'production' here. git-svn-id: svn://svn.berlios.de/openocd/trunk@2654 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-30 oharboe + + * : David Brownell Remove duplicate check for + flash write status. Via code review by Steve Grubb +   Also minor fixes for the message from "fill": the byte count is + unsigned, not signed; and more importantly, print the real number of + bytes written git-svn-id: svn://svn.berlios.de/openocd/trunk@2652 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-30 oharboe + + * : David Brownell start phasing out integers + as target IDs git-svn-id: svn://svn.berlios.de/openocd/trunk@2650 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-28 oharboe + + * : David Brownell fix warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@2648 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-28 oharboe + + * : restore ICE watchpoint registers when the *last* software + breakpoint is removed git-svn-id: svn://svn.berlios.de/openocd/trunk@2646 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-28 oharboe + + * : David Brownell ARM disassembly support for + about five dozen non-Thumb instructions that were added after + ARMv5TE was defined: - ARMv5J "BXJ" (for Java/Jazelle) - ARMv6 "media" instructions (for OMAP2420, i.MX31, etc) Compile-tested. This might not set up the simulator right for the + ARMv6 single step support; only BXJ branches though, and docs to + support Jazelle branching are non-public (still, sigh). ARMv6 instructions known to be mis-handled by this disassembler + include: UMAAL, LDREX, STREX, CPS, SETEND, RFE, SRS, MCRR2, MRRC2 git-svn-id: svn://svn.berlios.de/openocd/trunk@2644 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-27 oharboe + + * : arm11 single stepping wip - at least we know the next PC now git-svn-id: svn://svn.berlios.de/openocd/trunk@2642 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-27 oharboe + + * : refactor arm simulator to allow arm11 code to use it as well - + no observable changes otherwise. git-svn-id: svn://svn.berlios.de/openocd/trunk@2640 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-26 oharboe + + * : Matt Hsu and Holger Hans Peter Freyther + cortex-a8: Wait for the CPU to be + halted/started With DCCR we are asking the CPU to halt, we should wait until the + CPU has halted before proceeding with the operation. git-svn-id: svn://svn.berlios.de/openocd/trunk@2638 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-26 oharboe + + * : Matt Hsu and Holger Hans Peter Freyther + Only dap_ap_select when we are going to do a + memory access in the fast reg case. git-svn-id: svn://svn.berlios.de/openocd/trunk@2636 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-26 oharboe + + * : Matt Hsu cortex_a8_exec_opcode is writing the + ARM instruction into the ITR register but it will only be executed + when the DSCR[13] bit is set. The documentation is a bit weird as it + classifies the DSCR as read-only but the pseudo code is writing to + it as well. This is working on a beagleboard. git-svn-id: svn://svn.berlios.de/openocd/trunk@2634 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-26 oharboe + + * : Matt Hsu and Holger Hans Peter Freyther + Before executing a new instruction wait for the + previous instruction to be finished. This comes from the pseudo code + of the cortex a8 trm. git-svn-id: svn://svn.berlios.de/openocd/trunk@2632 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-26 oharboe + + * : added missing check on jtag_execute git-svn-id: svn://svn.berlios.de/openocd/trunk@2630 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-26 oharboe + + * : reduce arm11 output noise git-svn-id: svn://svn.berlios.de/openocd/trunk@2628 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-26 oharboe + + * : David Brownell Clock updates/fixes for the + Stellaris flash driver: - Bugfixes: * internal osc: it's *12* MHz (not 15 MHz) on _current_ chips + except new Tempest parts where it's 16 MHz (and calibrated!) + or some old Sandstorm ones, where 15 MHz was valid * crystal config: + read and use the crystal config, don't assume 6 MHz + know when that field is 4 bits vs 5 * an RCC2 register may be overriding the original RCC + more clock source options + bigger dividers + fractional dividers on Tempest (NYET handled) * there's a 30 KHz osc on newer chips (for deep sleep) * there's a 32768 Hz osc on newer chips (for hibernation) - Cosmetic * say "rev A0" not "vA.0", to match vendor docs * don't always report master clock as an "estimate": + give the error bound if it's approximate, like "±30%" + else don't say anything * fix whitespace and caps in some messages * these are not AT91SAM chips!! Those clock issues might explain problems sometimes reported when + writing to Stellaris flash banks; they affect write timings. That 12-vs-15 MHz issue is problematic; there's no consolidated doc + showing which chips (and revs!) have which internal oscillator + speed. It's clear that only older silicon had the + faster-and-less-accurate flavor. What's less clear is which chips + are "old" like that. Lightly tested, on a DustDevil part. git-svn-id: svn://svn.berlios.de/openocd/trunk@2626 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-25 oharboe + + * : David Brownell Tweak disassembly commands: For ARMv4/ARMv5: - better command parameter error checking - don't require an instruction count; default to one - recognize thumb function addresses - make function static - shorten some too-long lines For Cortex-M3: - don't require an instruction count; default to one With the relevant doc updates. --- Nyet done: invoke the thumb2 + disassembler on v4/v5, to better handle branch instructions. git-svn-id: svn://svn.berlios.de/openocd/trunk@2624 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-25 oharboe + + * : David Brownell More jtag_add_reset() + cleanup: Unify the handling of the req_tlr_or_trst parameter. Basically, + JTAG TMS+TCK ops ("TLR") is always used ... unless TRST is a safe + option in this system configuration. git-svn-id: svn://svn.berlios.de/openocd/trunk@2622 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-25 oharboe + + * : David Brownell Accomodate targets which + don't support various target-specific reset operations. Maybe they + can't; or it's a "not yet" thing. Note that the assert/deassert operations can't yet trigger for OMAP3 + because resets currently include JTAG reset in all cases, resetting + the ICEpick and thus disabling the TAP for Cortex-A8. git-svn-id: svn://svn.berlios.de/openocd/trunk@2620 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-25 ntfreak + + * : - fix build warnings - add svn props to recently added files armv7a.[ch] git-svn-id: svn://svn.berlios.de/openocd/trunk@2618 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-25 oharboe + + * : strange.... the code build and links w/Linux GCC target but + fails w/arm-elf. The code was clearly broken as it was missing two + extern's in the .h file... git-svn-id: svn://svn.berlios.de/openocd/trunk@2616 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-25 oharboe + + * : Ferdinand Postema increase reset delay to + fix regression from 2600 to 2604 git-svn-id: svn://svn.berlios.de/openocd/trunk@2614 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-25 oharboe + + * : Audrius Urmanavičius Latest source + (R2606) does not compile under Windows+Cygwin - fails with error + about possibly uninitialized use of variable 'ch'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2612 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-25 oharboe + + * : use cortex_a8 instead of cortex_m3 git-svn-id: svn://svn.berlios.de/openocd/trunk@2610 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-25 oharboe + + * : David Brownell Subset of Cortex-A8 support from Magnus: create + an armv7a file and seed it with DAP access support using the current + ADIv5 code. (With tweaks and cleanup from Øyvind and Dave.) The ARMv7-AR architecture manual is not publicly available (even in + subset form like the ARMv7-M spec), so it's hard to distinguish + between the Cortex-A8 implementation and the ARMv7-A architecture. The register set presumably is architectural, and so it's stored + here; it's like earlier ARMs, with small additions. Ditto the + instruction set, though Thumb2 support is used (extending Thumb + support from ARMv6 with more 32-bit instructions) and there's this + ThumbEE thing too. There is a new "debug monitor" mode, not yet + fully addressed here, to support debugging in environments (like + motor control) where halting debug mode is inadvisable. git-svn-id: svn://svn.berlios.de/openocd/trunk@2608 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-24 oharboe + + * : Steve Grubb fix various and sundry leaks git-svn-id: svn://svn.berlios.de/openocd/trunk@2606 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-21 oharboe + + * : Pieter Conradie shuffle things + around to the right spots. Should have been done in previous commit. git-svn-id: svn://svn.berlios.de/openocd/trunk@2604 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-21 oharboe + + * : Pieter Conradie Scripts for Atmel + AT91SAM7S256 and AT91SAM9260 git-svn-id: svn://svn.berlios.de/openocd/trunk@2602 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-20 oharboe + + * : Piotr Ziecik This patch adds handling blank + characters between hex digits in SVF file, making OpenOCD compatible + with files generated by Altera Quatrus II 9.0. git-svn-id: svn://svn.berlios.de/openocd/trunk@2600 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-20 oharboe + + * : David Brownell More Thumb2 disassembly: ARMv7-M: A5.3.6 Load/store dual or exclusive, table branch GCC will generate the table branch instructions, usually with + inlined tables that will confuse this disassembler. LDREX and STREX + are not issued by GCC without inline assembly. This means all Thumb2 instructions implemented by Cortex-M3 can now + be disassembled. Cortex-A8 cores support more Thumb2 instructions, + but most of those aren't yet publicly documented. git-svn-id: svn://svn.berlios.de/openocd/trunk@2598 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-19 oharboe + + * : David Brownell Fix some command helptext: - spell "address" right - list bp/wp params as optional And make those source lines wrap at sane margins. git-svn-id: svn://svn.berlios.de/openocd/trunk@2596 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-18 ntfreak + + * : David Brownell [david-b@pacbell.net]: Simplify dumping of register lists by only printing cached values if + they are marked as valid. Most of the time, they are invalid; so + printing *any* value is just misleading. Note that for ARM7 and ARM9 most EmbeddedICE registers (except for + debug status) could be cached most of the time; and their register + cache isn't maintained properly (many accesses seem to bypass that + cache code). git-svn-id: svn://svn.berlios.de/openocd/trunk@2594 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-18 ntfreak + + * : - add cfg file for Amontec JTAGKey2 jtag interface git-svn-id: svn://svn.berlios.de/openocd/trunk@2592 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-18 ntfreak + + * : Jonas Horberg [jhorberg@sauer-danfoss.com] Change jtag_rclk + behaviour so it can be called before the interface init function git-svn-id: svn://svn.berlios.de/openocd/trunk@2590 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-18 oharboe + + * : David Brownell Add "cortex_m3 + vector_catch" command and docs. One minor issue with this is that + the core debug support uses this mechanism, then trashes its state + over reset. Users can Work around that (for now) by re-assigning + the desired config after reset. Also fixes "target halted due to target-not-halted" goof. When we + can't describe the reason using OpenOCD's limited vocabulary, say + "reason undefined" instead of saying it's not halted. git-svn-id: svn://svn.berlios.de/openocd/trunk@2588 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-18 oharboe + + * : David Brownell Several of the ARMv7M + registers are 8 bits or less; don't display them as 32 bits unless + that's their true size. (Removes some confusion. git-svn-id: svn://svn.berlios.de/openocd/trunk@2586 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-16 oharboe + + * : Xiaofan Chen Split LM3S811 config file into + target file and board file git-svn-id: svn://svn.berlios.de/openocd/trunk@2584 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-16 oharboe + + * : Xiaofan Chen Add config file for + TI-Luminary LM3S1968 chip and EK-LM3S1968 board git-svn-id: svn://svn.berlios.de/openocd/trunk@2582 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-16 oharboe + + * : added note w/reference to discussion on whether or not arm11 + code is broken or not. git-svn-id: svn://svn.berlios.de/openocd/trunk@2580 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-07 ntfreak + + * : David Brownell : Warn about anyone using + "jtag_speed" commands; that command is obsolete, and will someday be + removed. git-svn-id: svn://svn.berlios.de/openocd/trunk@2578 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-07 ntfreak + + * : Ferdinand Postema [ferdinand@postema.eu] - fix vector catch issues with certain ARM9 cores - AT91SAM9260 and + STR9 git-svn-id: svn://svn.berlios.de/openocd/trunk@2576 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-06 ntfreak + + * : Gary Carlson [gcarlson@carlson-minot.com]: - revert patch from rev1507 as it was causing reset issues with arm9 + cores git-svn-id: svn://svn.berlios.de/openocd/trunk@2574 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-08-06 zwelch + + * : michal smulski : Fix ARM11 half-word bulk memory read and write. git-svn-id: svn://svn.berlios.de/openocd/trunk@2572 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-27 oharboe + + * : Fix NPE in GDB_EVENT_END as logforwarding was not disabled early + enough git-svn-id: svn://svn.berlios.de/openocd/trunk@2570 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-26 oharboe + + * : David Brownell More testcase work: A5.3.11 Data processing (shifted register) The usual kinds of problems; the most noteworthy were that the "S"et + flags bit was mis-handled in these instructions. --- This is the + last patch from a quickie set of tests covering all encodings of the + instructions with 32-bit opcodes. There may be some corner cases + left, plus the instructions that aren't yet handled, but the Thumb2 + disassembler is no longer just "lightly" tested with GCC output ... + the new code paths have mostly been verified. git-svn-id: svn://svn.berlios.de/openocd/trunk@2568 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-26 oharboe + + * : David Brownell More fixes from test cases: A5.3.8 Load halfword, unallocated memory hints It's mostly the usual sort of bitmasking goofage and getting the + width specs right. In one case an older x86 GCC generated bad code + unless I structred a conditional differently (sigh). git-svn-id: svn://svn.berlios.de/openocd/trunk@2566 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-24 oharboe + + * : David Brownell More instruction decoding + fixes based on test cases, covering ARMv7-M arch manual: A5.3.1 Data processing (modified immediate) A5.3.3 Data processing (plain binary immediate) A5.3.4 Branches and miscellaneous control and other (immediate) encodings referenced there. Several of these + just tweak the new syntax ("Unified" ARM/Thumb: UAL) but there were + a few bugs too. git-svn-id: svn://svn.berlios.de/openocd/trunk@2564 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-24 oharboe + + * : Andreas Fritiofson I noticed + there are a few checks for (rt == 0xf) even though that case is + handled with an early return at the top of the function. git-svn-id: svn://svn.berlios.de/openocd/trunk@2562 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-23 oharboe + + * : David Brownell thumb2 disassembly for Load + byte, memory hints git-svn-id: svn://svn.berlios.de/openocd/trunk@2560 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-23 oharboe + + * : David Brownell fix warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@2558 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-22 oharboe + + * : Stefano Voulaz first cut + samsung_s3c2450 git-svn-id: svn://svn.berlios.de/openocd/trunk@2556 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-21 ntfreak + + * : David Brownell : Clean up treatment of registers in ARMv7-M and Cortex-M3. - At the arch level: * Just list registers and names; don't impose core-specific policy about how they are accessed. * Each register has a symbol. * Remove the register mode field (irrelevant to debugger) - At the core/implementation level: * Just map the registers to their relevant access methods; don't require the arch level to say how that should work (cores other than Cortex-M3 could do it differently). * Don't use undefined bits from register 20. * Use register IDs that are part of the ARMv7-M interface. In short, there's now a real distinction between the arch and core + layers. git-svn-id: svn://svn.berlios.de/openocd/trunk@2554 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-21 ntfreak + + * : David Brownell : Revert parts of the previous ARMv7-M register patch. It turns out + that part of the issue is a documentation problem for the Cortex-M3 + r1 parts. So for the rest, simpler fixes are possible (in followup + patch). git-svn-id: svn://svn.berlios.de/openocd/trunk@2552 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-19 oharboe + + * : aduc flash problems have been resolved git-svn-id: svn://svn.berlios.de/openocd/trunk@2550 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-16 oharboe + + * : added item to come up with slick new 32 bit jtag_add_xxx() API git-svn-id: svn://svn.berlios.de/openocd/trunk@2548 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-16 oharboe + + * : microscopic white space fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2546 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-16 zwelch + + * : Magnus Lundin , Oyvind Harboe + , David Brownell : Move the dap command handler implementations to arm_adi_v5.c, + leaving just thin wrappers in armv7m.c. There should be no change + in functionality here. (From Magnus.) Minor style cleanup: whitespace, line length, etc. Update spec + references to use docs which are currently available. (From Dave.) git-svn-id: svn://svn.berlios.de/openocd/trunk@2544 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-15 zwelch + + * : David Brownell : More 32-bit Thumb2 instruction decoding: A5.3.7 Load word git-svn-id: svn://svn.berlios.de/openocd/trunk@2542 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-15 zwelch + + * : David Brownell : More 32-bit instruction decoding: A5.3.11 Data processing (shifted register) git-svn-id: svn://svn.berlios.de/openocd/trunk@2540 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-15 zwelch + + * : David Brownell : More instructions decoded: A5.3.14 Multiply, and multiply accumulate A5.3.15 Long multiply, long multiply accumulate, divide The EABI requires *adjacent* register pairs, but the long multiply + ops can use any pair of registers; interesting. git-svn-id: svn://svn.berlios.de/openocd/trunk@2538 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-15 zwelch + + * : David Brownell : Print old-style Thumb NOP instructions as such. (GCC uses "mov r8, + r8" instead of the architected NOP which is new in Thumb2.) git-svn-id: svn://svn.berlios.de/openocd/trunk@2536 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-15 zwelch + + * : David Brownell : Make the Thumb2 disassembler handle more 32-bit instructions: A5.3.3 Data processing (plain binary immediate) These use mostly twelve bit literals, but there are also bitfield + and saturated add primitives. git-svn-id: svn://svn.berlios.de/openocd/trunk@2534 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-15 zwelch + + * : David Brownell : Make the Thumb2 disassembler handle a bunch of 32-bit instructions: A5.3.4 Branches and miscellaneous control Note that this shifts some responsabililty out of helper functions, + making the code and layout simpler for 32-bit decoders: they only + need to know how to format the instruction and its parameters. Also, technical note: with this patch, Thumb1 decoders could now + call the Thumb2 decoder if they wanted to get nicer treatment of the + exiting 32-bit B/BLX instructions. git-svn-id: svn://svn.berlios.de/openocd/trunk@2532 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-15 zwelch + + * : David Brownell : Initial support for disassembling Thumb2 code. This works only for + Cortex-M3 cores so far. Eventually other cores will also need + Thumb2 support ... but they don't yet support any kind of + disassembly. - Update the 16-bit Thumb decoder: * Understand CPS, REV*, SETEND, {U,S}XT{B,H} opcodes added by ARMv6. (It already seems to treat CPY as MOV.) * Understand CB, CBNZ, WFI, IT, and other opcodes added by in Thumb2. - A new Thumb2 instruction decode routine is provided. * This has a different signature: pass the target, not the instruction, so it can fetch a second halfword when needed. The instruction size is likewise returned to the caller. * 32-bit instructions are recognized but not yet decoded. - Start using the current "UAL" syntax in some cases. "SWI" is renamed as "SVC"; "LDMIA" as "LDM"; "STMIA" as "STM". - Define a new "cortex_m3 disassemble addr count" command to give access to this disassembly. Sanity checked against "objdump -d" output; a bunch of the new + instructions checked out fine. git-svn-id: svn://svn.berlios.de/openocd/trunk@2530 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-15 oharboe + + * : retire Eclipse settings, charset will be set elsewhere. git-svn-id: svn://svn.berlios.de/openocd/trunk@2528 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-14 oharboe + + * : David Brownell mention udev, and correct + D2XX speed mentions git-svn-id: svn://svn.berlios.de/openocd/trunk@2526 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-14 oharboe + + * : 1.54 snapshot git-svn-id: svn://svn.berlios.de/openocd/trunk@2523 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-14 zwelch + + * : Bump minor version and add tag: Bump minor package version + number: 0.2.0 -> 0.3.0 Add '-in-development' version tag: 0.3.0 -> + 0.3.0-in-development git-svn-id: svn://svn.berlios.de/openocd/trunk@2521 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-14 zwelch + + * : Improve the release script before 0.2.0: 1) Only archive NEWS file on major and minor relesae, not bug-fixes. 2) Switch back to correct development branch during final release + step. 3) Add do_svn_switch helper to ensure package variables are + reloaded. git-svn-id: svn://svn.berlios.de/openocd/trunk@2516 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-14 zwelch + + * : Make the parport-ppdev option enabled by default. This may + require giving --disable-parport-ppdev to configure on some + platform(s). git-svn-id: svn://svn.berlios.de/openocd/trunk@2514 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-12 oharboe + + * : Xiaofan Chen document my experiment with + MinGW cross build. git-svn-id: svn://svn.berlios.de/openocd/trunk@2512 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-12 oharboe + + * : Magnus Lundin Thc cortex_m3_poll function does not identify + that a target is running unless we transition from RESET. This patch correctly identifies a running target. Patch made a tad more palatable by David Brownell + git-svn-id: svn://svn.berlios.de/openocd/trunk@2510 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-12 oharboe + + * : David Brownell Mention how parallel clock + voting implementations of RTCK work, and reference TI's free VHDL + code. git-svn-id: svn://svn.berlios.de/openocd/trunk@2508 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-10 oharboe + + * : wrote up workaround for xscale/debug_handler.bin bug git-svn-id: svn://svn.berlios.de/openocd/trunk@2506 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-10 oharboe + + * : David Brownell split EK board support out + from the target CPU support . git-svn-id: svn://svn.berlios.de/openocd/trunk@2504 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-08 zwelch + + * : Add section to provide some documentation for cross-compiling. git-svn-id: svn://svn.berlios.de/openocd/trunk@2502 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-08 zwelch + + * : Add comments to top-level files to "excuse" their Doxygen + markup. git-svn-id: svn://svn.berlios.de/openocd/trunk@2500 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-08 oharboe + + * : fix formatting of xscale bug entry(learning every day) git-svn-id: svn://svn.berlios.de/openocd/trunk@2498 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-08 oharboe + + * : typo in comment git-svn-id: svn://svn.berlios.de/openocd/trunk@2496 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-08 oharboe + + * : i.MX27 reset problems fixed & update remaining reset problems + notes git-svn-id: svn://svn.berlios.de/openocd/trunk@2494 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-07 oharboe + + * : srst pulls trst according to Freescale docs for i.mx27 git-svn-id: svn://svn.berlios.de/openocd/trunk@2492 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-07 oharboe + + * : Use reference to mailing list for known arm926ejs bugs rather + fill The List with lots of details git-svn-id: svn://svn.berlios.de/openocd/trunk@2490 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-07 oharboe + + * : fix return value for "reset" and "runtest" command. Found by + code inspection. git-svn-id: svn://svn.berlios.de/openocd/trunk@2488 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-07 oharboe + + * : more arm926ejs bugs git-svn-id: svn://svn.berlios.de/openocd/trunk@2486 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-06 oharboe + + * : David Brownell Update docs to say that + "arm7_9 dbgrq enable" is the default on ARM9 cores, and update the + DaVinci config files so they no longer explicitly specify it. git-svn-id: svn://svn.berlios.de/openocd/trunk@2484 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-06 ntfreak + + * : - fix build when using a cross compiler - do not try and run any + host tools - add missing types.h when platform does not contain elf.h git-svn-id: svn://svn.berlios.de/openocd/trunk@2482 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-06 oharboe + + * : a bit more debug output for translation of invalid mode numbers git-svn-id: svn://svn.berlios.de/openocd/trunk@2480 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-06 oharboe + + * : Fix regression in "step" command introduced in 2190 git-svn-id: svn://svn.berlios.de/openocd/trunk@2478 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-06 zwelch + + * : Update Release Script documentation to reflect current + implementation. git-svn-id: svn://svn.berlios.de/openocd/trunk@2476 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-06 zwelch + + * : Add NEWS file for the 0.2.0 release. git-svn-id: svn://svn.berlios.de/openocd/trunk@2474 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-06 zwelch + + * : Ferdinand Postema : Updates to private TAP state tables in amtjtagaccel interface + driver. The first change is the neccesary one to correct a long-standing bug + that caused the IDCODE to be shifted by one bit too many. This was + caused by an incorrect path from state RESET to state DRSHIFT. The value of those 2 bytes were 0x8a and 0x04. This means that the + bitstream to do this transition is 0b 00100 01010 (send LSB first). + This will bring you from the reset state to the shift state; + however, you enter the shift-state twice, which explains why the + ID-CODE that will be read next will be shifted 1 bit. The fix + changes these to 0x05 and 0x00. This will send the bitstream 0b + 00101 (send LSB first). This will bring the TAP controller from the + RESET state to the DRSHIFT state directly, without entering the + DRSHIFT state twice. After checking the whole table, two other transitions were found + that could be optimized (5 bits in stead of 10 bits). Summary off all changes: From To Old values Old Bitstream New values New + Bitstream Remarks ---- ------- ---------- ------------- + ---------- ------------- ------- RESET DRSHIFT 0x8a 0x04 + 0b00100 01010 0x05 0x00 0b00101 1,2 IDLE DRSHIFT 0x85 + 0x08 0b01000 00101 0x04 0x00 0b00100 2 IDLE IRSHIFT + 0x8b 0x08 0b01000 01011 0x06 0x00 0b00110 2 [1] Fixes the IDCODE bug [2] Optimization git-svn-id: svn://svn.berlios.de/openocd/trunk@2472 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-06 oharboe + + * : 10ms timeout check on cp15 read/write git-svn-id: svn://svn.berlios.de/openocd/trunk@2470 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-06 zwelch + + * : Fix maintainer-clean target in doc directory. git-svn-id: svn://svn.berlios.de/openocd/trunk@2468 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-06 oharboe + + * : added known problem w/line number's being off in syntax errors + for target reset events git-svn-id: svn://svn.berlios.de/openocd/trunk@2466 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-06 oharboe + + * : human readable error message upon invalid arguments git-svn-id: svn://svn.berlios.de/openocd/trunk@2464 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-04 zwelch + + * : Major update to release process documentation: - Provide overview of OpenOCD versioning schema. - Outline responsibilities and authority of the release manager. - Explain the need for flexibility in the release schedule. - Add and refine the release process steps. - Include tutorials for using new release script. - Many more improvements, too numerous to list. git-svn-id: svn://svn.berlios.de/openocd/trunk@2462 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-02 oharboe + + * : Xiaofan Chen With this patch, OpenOCD can + talk to my Analog Device Eval-ADuC7060 eval board. git-svn-id: svn://svn.berlios.de/openocd/trunk@2459 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-02 zwelch + + * : Add AUTHORS for 0.2.0 release. git-svn-id: svn://svn.berlios.de/openocd/trunk@2457 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-02 zwelch + + * : Remove vim editor commands from TCL files. git-svn-id: svn://svn.berlios.de/openocd/trunk@2455 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-02 zwelch + + * : Commit first draft of release process documentation. git-svn-id: svn://svn.berlios.de/openocd/trunk@2453 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-02 oharboe + + * : zy1000 1.53 snapshot git-svn-id: svn://svn.berlios.de/openocd/trunk@2451 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-02 zwelch + + * : David Brownell : More minor improvements to README to help polish the 0.2.0 release: - Add note about Ubuntu 8.04 (in lieu of starting a README.Linux + file). - Fix introductory paragraph to Bulding OpenOCD - Remove some vestigial texinfo markup. git-svn-id: svn://svn.berlios.de/openocd/trunk@2448 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-02 zwelch + + * : David Brownell : Restore some whitespace that got clobbered by over-aggressive + whitepace eradication patches a while back. git-svn-id: svn://svn.berlios.de/openocd/trunk@2446 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-01 zwelch + + * : Add missing copyright header to target_type.h. git-svn-id: svn://svn.berlios.de/openocd/trunk@2444 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-01 zwelch + + * : Update TODO list to relect 0.2.0 release. git-svn-id: svn://svn.berlios.de/openocd/trunk@2442 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-07-01 ntfreak + + * : - add stm32 connectivity line tapid to stm32.cfg git-svn-id: svn://svn.berlios.de/openocd/trunk@2440 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-30 zwelch + + * : Remove at91sam3.h from flash.c; use extern like other drivers. git-svn-id: svn://svn.berlios.de/openocd/trunk@2438 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-30 zwelch + + * : Provide some useful information in README file, rather than + punting. Add some text to introduce the project to new users. Move packaging, configuration, and compilation of OpenOCD out of the + User's Guide and into README, where it can be used by users before + configuring and compiling the documentation. Improve notes about required Subversion repository build steps. Add + reference to the standard GNU INSTALL file. git-svn-id: svn://svn.berlios.de/openocd/trunk@2436 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-30 ntfreak + + * : - remove cygwin build warnings in at91sam3.c git-svn-id: svn://svn.berlios.de/openocd/trunk@2434 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-30 zwelch + + * : Remove executable bits from at91sam3 configuration files. git-svn-id: svn://svn.berlios.de/openocd/trunk@2432 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-30 zwelch + + * : Add svn:eol-style properties missed in last commit. git-svn-id: svn://svn.berlios.de/openocd/trunk@2430 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-30 zwelch + + * : David Brownell : Add "jtag names" command, mirroring "target names" but returning TAP + names instead of target names. This starts letting TAPs be + manipulated in scripts ... much like what works now for targets. It's a bit limited just yet, since "jtag cget $TAPNAME" doesn't + expose all TAP attributes. "$TARGETNAME cget" is more functional. git-svn-id: svn://svn.berlios.de/openocd/trunk@2428 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-30 zwelch + + * : Fix doxygen 'undocumented parameter' warnings in membuf.h. git-svn-id: svn://svn.berlios.de/openocd/trunk@2426 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-30 zwelch + + * : Fix doxygen warning in jtag.h caused by a changed parameter + name. git-svn-id: svn://svn.berlios.de/openocd/trunk@2424 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-30 zwelch + + * : Fix @file documentation blocks in new interfaces source files. git-svn-id: svn://svn.berlios.de/openocd/trunk@2422 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-30 zwelch + + * : Fix logger.pl script to avoid spurious empty line in some cases. git-svn-id: svn://svn.berlios.de/openocd/trunk@2420 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-29 zwelch + + * : David Brownell : Minor bugfix ... previous version was tested *with* ICEpick active. + The "-disable" can swap with "-enable"; but not with an empty + string. git-svn-id: svn://svn.berlios.de/openocd/trunk@2418 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-29 zwelch + + * : David Brownell : Improve the PXA255 target config: move all that board-specific + setup to the pxa255_sst board.cfg, to which it evidently belongs + (it's the only PXA255 board now included). Provide the PXA255 JTAG id from Intel docs, and add a comment about + how this chip is now EOL'd (last orders taken). Note that I still can't get my old PXA255 board to work. There's + something broken in the reset sequence, which is preventing the TAP + from coming up at all. Old mailing list posts suggest this is a + longstanding bug... git-svn-id: svn://svn.berlios.de/openocd/trunk@2416 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-29 zwelch + + * : David Brownell : Minor fixup to the User's Guide, primarily related to the handful of + commands defined in "startup.tcl"; "help" was not previously + documented. Also, be more consistent about "Config Command" definitions (and to + be explicit about that doc convention). git-svn-id: svn://svn.berlios.de/openocd/trunk@2414 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-28 oharboe + + * : David Brownell various missing commands git-svn-id: svn://svn.berlios.de/openocd/trunk@2412 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-28 duane + + * : A bit more log detail about connections comming and going git-svn-id: svn://svn.berlios.de/openocd/trunk@2410 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-27 duane + + * : Add Breakpoint/Watchpoint unique ID to help debug hardware debug + register leakage git-svn-id: svn://svn.berlios.de/openocd/trunk@2408 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-27 duane + + * : Switch to strotk() grr.... git-svn-id: svn://svn.berlios.de/openocd/trunk@2406 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-26 oharboe + + * : David Brownell Add a short chapter on + boundary scan support, which currently just documents the SVF and + XSVF commands. git-svn-id: svn://svn.berlios.de/openocd/trunk@2404 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-25 oharboe + + * : Oleksandr Tymoshenko simple watchpoint + support for MIPS32/EJTAG (no value comparation yet). git-svn-id: svn://svn.berlios.de/openocd/trunk@2402 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-24 oharboe + + * : David Brownell Fix formatting bug in + at91sam7 doc added with the at91sam3 support; and some formatting + issues with sam7 and stm32 keyword params. Tweak at91sam3 docs. Remove ninth nibble from flash bank addresses, + clarify "at91sam3 show" variants and that the flash bank layout is + not needed as a parameter (unlike with sam7); formatting fixes. git-svn-id: svn://svn.berlios.de/openocd/trunk@2400 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-24 zwelch + + * : Remove whitespace at end of lines, step 2. - Replace '\s*$' with ''. git-svn-id: svn://svn.berlios.de/openocd/trunk@2398 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-24 zwelch + + * : Remove whitespace that occurs before ')'. - Replace '[ \t]*[)]' with ')'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2396 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-24 zwelch + + * : - Fixes '[<>]' whitespace - Replace '\(\w\)\([<>]\)\(\w\)' with '\1 \2 \3'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2394 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-24 zwelch + + * : - Fixes '+' whitespace - Replace '\(\w\)\(+\)\(\w\)' with '\1 \2 \3'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2392 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-24 zwelch + + * : - Fixes '==' whitespace - Replace '\(\w\)\(==\)\(\w\)' with '\1 \2 \3'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2390 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-24 zwelch + + * : - Replace 'switch(' with 'switch ('. git-svn-id: svn://svn.berlios.de/openocd/trunk@2388 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-24 zwelch + + * : - Replace 'if(' with 'if ('. git-svn-id: svn://svn.berlios.de/openocd/trunk@2386 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-24 zwelch + + * : Fix end-of-line style properties on newly added files. git-svn-id: svn://svn.berlios.de/openocd/trunk@2384 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-24 duane + + * : Add quick target - full cygwin builds take a long long long + time, this shortens the edit/build/debug cycle git-svn-id: svn://svn.berlios.de/openocd/trunk@2382 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 zwelch + + * : Remove whitespace at end of lines, step 2. - Replace '\s*$' with ''. git-svn-id: svn://svn.berlios.de/openocd/trunk@2380 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 zwelch + + * : - Replace '){' with ') {'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2378 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 zwelch + + * : Remove whitespace that occurs after '('. - Replace '([ \t]*' with '('. git-svn-id: svn://svn.berlios.de/openocd/trunk@2376 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 zwelch + + * : - Fixes '[|]' whitespace - Replace ')\([|]\)(' with ') \1 ('. - Replace ')\([|]\)\(\w\)' with ') \1 \2'. - Replace '\(\w\)\([|]\)(' with '\1 \2 ('. - Replace '\(\w\)\([|]\)\(\w\)' with '\1 \2 \3'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2374 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 zwelch + + * : - Fixes '=' whitespace - Replace ')\(=\)\(\w\)' with ') \1 \2'. - Replace '\(\w\)\(=\)(' with '\1 \2 ('. - Replace '\(\w\)\(=\)\(\w\)' with '\1 \2 \3'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2372 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 zwelch + + * : - Fixes '<<' whitespace - Replace ')\(<<\)\(\w\)' with ') \1 \2'. - Replace '\(\w\)\(<<\)(' with '\1 \2 ('. - Replace '\(\w\)\(<<\)\(\w\)' with '\1 \2 \3'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2370 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 zwelch + + * : - Fixes '<=' whitespace - Replace '\(\w\)\(<=\)\(\w\)' with '\1 \2 \3'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2368 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 zwelch + + * : - Fixes '&&' whitespace - Replace ')\(&&\)(' with ') \1 ('. - Replace '\(\w\)\(&&\)(' with '\1 \2 ('. - Replace '\(\w\)\(&&\)\(\w\)' with '\1 \2 \3'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2366 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 zwelch + + * : - Fixes '[+]=' whitespace - Replace '\(\w\)\([+]=\)(' with '\1 \2 ('. - Replace '\(\w\)\([+]=\)\(\w\)' with '\1 \2 \3'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2364 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 zwelch + + * : - Fixes '-=' whitespace - Replace '\(\w\)\(-=\)(' with '\1 \2 ('. - Replace '\(\w\)\(-=\)\(\w\)' with '\1 \2 \3'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2362 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 zwelch + + * : - Replace 'for(' with 'for ('. git-svn-id: svn://svn.berlios.de/openocd/trunk@2360 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 zwelch + + * : - Replace 'while(' with 'while ('. git-svn-id: svn://svn.berlios.de/openocd/trunk@2358 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-23 oharboe + + * : update w/missing eCos definitions after latest round of compiler + formatting warnings fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2356 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-22 zwelch + + * : David Brownell : This should be my last significant update of the User's Guide for + this release. Mostly it's a rework of the config file chapter's + presentation of board and target config files. - Give the new path for scripts! - Move board-config material out of the target-config section - Add more board-config info, notably for reset-init events - Link out of the board-config section to NAND, NOR, and Reset + chapters - Emphasize target input vs. output naming conventions - Other textual improvements Plus some other updates, like adding my copyright (now that I've + basically rewritten much of this). git-svn-id: svn://svn.berlios.de/openocd/trunk@2354 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-22 oharboe + + * : David Brownell Make the Hitex + STM32-PerformanceStick board config behave better: source the STM32 + target config instead of using a private clone git-svn-id: svn://svn.berlios.de/openocd/trunk@2352 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 ntfreak + + * : - fix break caused by r2208 when using --pipe option - issue is gdb stdin buffer gets full before we redirect openocd + output git-svn-id: svn://svn.berlios.de/openocd/trunk@2350 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 zwelch + + * : Oleksandr Tymoshenko : Resume command works only if resume address is provided. git-svn-id: svn://svn.berlios.de/openocd/trunk@2348 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2346 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2344 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2342 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2340 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2338 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2336 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2334 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2332 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2330 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2328 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2326 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2324 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2322 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2320 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2318 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2316 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2314 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2312 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2310 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2308 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2306 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2304 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2302 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2300 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 printf() -Werror fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@2298 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-21 duane + + * : C99 Type updates, include inttypes.h - it is catagorically + required git-svn-id: svn://svn.berlios.de/openocd/trunk@2296 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-19 zwelch + + * : Remove editor preferences from source files. git-svn-id: svn://svn.berlios.de/openocd/trunk@2294 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-19 zwelch + + * : Paulius Zaleckas : This is minimal patch to support FA526 ARMv4 compatible core. Since + it is very similar to ARM920T I tried to reuse as much code as + possible. CPU and board configs will follow soon. git-svn-id: svn://svn.berlios.de/openocd/trunk@2292 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-19 oharboe + + * : fix jtag_add_callback() args. The first argument is nothing + special, it's just another generic argument. git-svn-id: svn://svn.berlios.de/openocd/trunk@2290 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-18 oharboe + + * : less warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@2288 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-18 zwelch + + * : Oyvind Harboe : Ecos uses sys/types.h not stdint.h. git-svn-id: svn://svn.berlios.de/openocd/trunk@2286 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-18 zwelch + + * : Update Style Guide documentation to explain basic type rules. git-svn-id: svn://svn.berlios.de/openocd/trunk@2284 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-18 zwelch + + * : Transform 'u64' to 'uint64_t' - Replace '\([^_]\)u64' with '\1uint64_t'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2282 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-18 zwelch + + * : Transform 'u32' to 'uint32_t' in src/flash. - Replace '\([^_]\)u32' with '\1uint32_t'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2280 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-18 zwelch + + * : Transform 'u32' to 'uint32_t' in src/target/arm* - Replace '\([^_]\)u32' with '\1uint32_t'. - Replace '^u32' with 'uint32_t'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2278 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-18 zwelch + + * : Transform 'u8' to 'uint8_t' - Replace '\([^_]\)u8' with '\1uint8_t'. - Replace '^u8' with 'uint8_t'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2276 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-18 zwelch + + * : Transform 'u8' to 'uint8_t' in src/target - Replace '\([^_]\)u8' with '\1uint8_t'. - Replace '^u8' with 'uint8_t'. git-svn-id: svn://svn.berlios.de/openocd/trunk@2274 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-18 zwelch + + * : David Brownell : Clean up the PLD files: - Get rid of some extraneous whitespace - Make various functions static - Wrap overlong lines git-svn-id: svn://svn.berlios.de/openocd/trunk@2272 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-18 zwelch + + * : David Brownell : Take a whack at providing some texinfo style docs. Mostly it's just + basic "how 2 write sane dox" stuff. git-svn-id: svn://svn.berlios.de/openocd/trunk@2270 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-17 oharboe + + * : dummy driver now works under eCos git-svn-id: svn://svn.berlios.de/openocd/trunk@2268 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-17 zwelch + + * : David Brownell : Fix for a goofy "board" config ... reuse target/pxa270.cfg instead + of using a private copy. git-svn-id: svn://svn.berlios.de/openocd/trunk@2266 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-17 zwelch + + * : David Brownell : Let jtag_call_event_callbacks() behave when the callback removes + itself. Oddly, this crashed on x86_32 but not x86_64. git-svn-id: svn://svn.berlios.de/openocd/trunk@2264 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-17 zwelch + + * : Fix compilation for Ubuntu 9.04 on x86-64 when using + --enable-httpd. git-svn-id: svn://svn.berlios.de/openocd/trunk@2262 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-17 zwelch + + * : Ensure range errors are reported only when errno indicates one + occurred. git-svn-id: svn://svn.berlios.de/openocd/trunk@2260 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-17 zwelch + + * : Add argument parsing errors in command.h, use in parse_type + routines. git-svn-id: svn://svn.berlios.de/openocd/trunk@2258 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-17 zwelch + + * : Convert core parse_type implementations to check for underflow + errors. git-svn-id: svn://svn.berlios.de/openocd/trunk@2256 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-17 zwelch + + * : Update parse_type macro definitions to allow re-use with signed + types. git-svn-id: svn://svn.berlios.de/openocd/trunk@2254 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-16 zwelch + + * : David Brownell : Fix a bug preventing ICEpick "enable that TAP" code from working: + the "runtest" command wrongly finished with a JTAG reset, discarding + the work the TAP enable handler just finished! Instead, JTAG should + stay in RUN/IDLE state. git-svn-id: svn://svn.berlios.de/openocd/trunk@2252 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-16 zwelch + + * : David Brownell : Tighten error handling on TAP enable/disable paths a bit: - Don't enable/disable unless it's necessary. Those event handlers could have nasty side effects... - Don't *succeed* enables/disables if there was no code which could have implemented that action. This prevents bugs like wrongly acting as if the scan chain changed. - Minor whitespace cleanup in enable/disable command code. The big problem is still the lack of code to verify scan chains were + actually updated as requested; this adds a comment on that. I + suspect the best we can do near term will be to verify IDCODE. git-svn-id: svn://svn.berlios.de/openocd/trunk@2250 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-16 zwelch + + * : David Brownell : Distributing FTDI's "ftd2xx" library with OpenOCD violates the + OpenOCD license (GNU GPLv2 with no exceptions). Make that clear where that build option is presented, and don't + describe the FTDI libraries as an option for any packager. (It's + fine for personal use, of course.) Plus some related clarifications: libftdi version 0.16 for the new + FT2232H chips (for RTCK and high speed USB); the Amontec drivers are + just ftd2xx variants. git-svn-id: svn://svn.berlios.de/openocd/trunk@2248 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-16 zwelch + + * : David Brownell : Doc update: say "jtag newtap ... -disable" records the state after + exiting the RESET state, matching the only implementation we're + working with so far (TI ICEpick-C). Matching code updates. Now we can be sure that the "enabled" flag + value is correct after JTAG resets. git-svn-id: svn://svn.berlios.de/openocd/trunk@2246 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-16 zwelch + + * : David Brownell : Minor jtag cleanup: - remove hidden assumption about JTAG event numbering - move function declarations to a header - some end'o'line whitespace - use "calloc" not "malloc + memset" git-svn-id: svn://svn.berlios.de/openocd/trunk@2244 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-15 zwelch + + * : David Brownell : Add another board ... OMAP2420 "H4" board. This won't be very + widely used with OpenOCD, but with mainline support in both U-Boot + and Linux it at least makes for a more complete set (and another + testcase). This is incomplete support in several respects. The ARM11 support + is not very deep yet; most registers aren't available, and the ETM + can't be hooked up. Plus, there's no script for OMAP-specific stuff + like setting up the SDRAM controller. Eventually the same NAND + controller driver should work with OMAP2 and OMAP3. git-svn-id: svn://svn.berlios.de/openocd/trunk@2242 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-13 zwelch + + * : David Brownell : OpenOCD doesn't actually *need* to be keeping all TCP ports active + ... creating security issues in some network configs. Instead, let config file specify e.g. "tcl_port 0" (or gdb_port, + telnet_port) to disable that particular remote access method. git-svn-id: svn://svn.berlios.de/openocd/trunk@2240 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-13 zwelch + + * : Improve handle_profile_command argument parsing: - Use parse_uint to ensure timeout value parses properly. git-svn-id: svn://svn.berlios.de/openocd/trunk@2238 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-13 zwelch + + * : Cleanup and improve handle_wp_command and handle_rwp_command: - Simplify argument parsing logic using switch statement. - Use parse_u32 to ensure all values parse properly. - Return syntax error when mode argument fails to parse. git-svn-id: svn://svn.berlios.de/openocd/trunk@2236 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-13 zwelch + + * : Improve handle_verify_image_command_internal command argument + handling: - Use parse_u32 to ensure address parses properly. git-svn-id: svn://svn.berlios.de/openocd/trunk@2234 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-13 zwelch + + * : Improve handle_load_image_command argument parsing: - Use parse_u32 to ensure base/min/max addresses parse properly. git-svn-id: svn://svn.berlios.de/openocd/trunk@2232 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-13 zwelch + + * : Improve handle_md_command argument handling: - Use parse_u32 and parse_uint for address and count, respectively. git-svn-id: svn://svn.berlios.de/openocd/trunk@2230 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-13 zwelch + + * : Cleanup and improve handle_halt_command: - Make argument check use parse_uint to ensure value parses + properly. - Move variable declarations to location of first use. git-svn-id: svn://svn.berlios.de/openocd/trunk@2228 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-13 zwelch + + * : Use parse_uint in handle_reg_command to ensure reg number parses + properly. git-svn-id: svn://svn.berlios.de/openocd/trunk@2226 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-12 zwelch + + * : David Brownell : Currently the "debug_level 3" command tracing ignores commands that + could return values to TCL scripts (by plugging in to a slightly + lower level of the interpreter stack). Fix that by abstracting the tracing command and starting to make + some of those previously-untraced commands use this new mechanism. git-svn-id: svn://svn.berlios.de/openocd/trunk@2224 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-12 zwelch + + * : David Brownell : Partial fix to the "long IR length" problems. - Current code could handle up to 32 bit IR lengths with full functionality, if it didn't just reject may of them out of hand. So only reject clear errors, where the IR mask (or capture instruction) needs more than IrLen bits. - Longer IR lengths can only be handled in BYPASS mode for now. Example: TI's DSPs use 38-bit IR lengths. So we can't issue their IDCODE instructions... A more complete fix would be able to issue longer instructions; or + minimally, would fail cleanly for the non-BYPASS case. Note that this *could* make some currently broken scripts fail, + since the previous code accepted garbage values so long as they + didn't use more than 16 bits. git-svn-id: svn://svn.berlios.de/openocd/trunk@2222 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-12 zwelch + + * : Further cleanup to MIPS target read/write memory function: - Move the mips32_..._read_mem calls to top-level of read_mem + function. - Change: Only perform mips_m4k_read_mem conversion when retval == + ERROR_OK. - Prevents pointless conversions of bogus read values after + failures. - Eliminate retval variable from mips_m4k_write_mem; return + directly. - Move declaration of retval variable to point of first use. - Remove the now redundant switch statements testing size: - argument sanitizing already covers these cases. git-svn-id: svn://svn.berlios.de/openocd/trunk@2220 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-12 zwelch + + * : Fix unitialized use of cur_speed in handle_jtag_khz_command: - Use the default KHz speed setting, in case interface is not + initialized. git-svn-id: svn://svn.berlios.de/openocd/trunk@2218 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-12 zwelch + + * : Improve handle_runtest_command: - Use parse_uint helper to ensure argument is parsed properly. git-svn-id: svn://svn.berlios.de/openocd/trunk@2216 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-12 zwelch + + * : Improve handle_irscan_command: - Use parse_u32 helper to ensure scan values are parsed properly. - Clear the fields buffer to ensure partial cleanup occur correctly. git-svn-id: svn://svn.berlios.de/openocd/trunk@2214 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-12 zwelch + + * : Use parse_uint helper to replace strtoul call in + jtag_tap_by_string. git-svn-id: svn://svn.berlios.de/openocd/trunk@2212 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-12 zwelch + + * : Simplify and improve amt_jtagaccel_handle_parport_port_command: - Show the port number to the user when asking for it or setting it. - Print an error if the amt_jtagaccel_port has already been set. - Use parse_u16 helper to ensure amt_jtagaccel_port string parses + correctly. git-svn-id: svn://svn.berlios.de/openocd/trunk@2210 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-12 zwelch + + * : Simplify and improve handle_debug_level_comamnd: - Bug fix: Return a syntax error if more than one argument is given. - Bug fix: Use new parse_uint helper ensure debug_level parses + correctly. - Change: Display the debug_level after it has been set. - Simplify bounds checking of debug_level. git-svn-id: svn://svn.berlios.de/openocd/trunk@2208 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-12 zwelch + + * : Add new parse_uinttype wrappers for strtoul in + src/helper/command.[ch]. - Used to improve command argument parsing of unsigned integers + values. git-svn-id: svn://svn.berlios.de/openocd/trunk@2206 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-11 zwelch + + * : David Brownell : Rework the "Simple Configuration Files" chapter so it's more of a + quick-start "how to set up your project" tutorial: - Say how to hook up the JTAG adapter. This will help new users, and in any case is worth spelling out somewhere. - Streamline the previous rather haphazard presentation, filling in some missing holes along the way: * Suggest "project directory" structure * Introduce new term, "user config" file (openocd.cfg) * Talk about more options for openocd.cfg contents * ... and about creating new config files * Add new topic, project-specific utilities (+examples) - Remove too-short, yet duplicative, chapter 19 Nudge packagers a bit more strongly to send patches (including + config files) upstream. git-svn-id: svn://svn.berlios.de/openocd/trunk@2204 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-11 ntfreak + + * : - fix bug introduced during r1962 - Original patch submitted by David Claffey [dnclaffey@gmail.com]. git-svn-id: svn://svn.berlios.de/openocd/trunk@2202 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-11 oharboe + + * : fix ordering of arguments to fwrite() git-svn-id: svn://svn.berlios.de/openocd/trunk@2197 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-11 zwelch + + * : Factor target_timer_callbacks_check_time into pieces: - Add target_timer_callback_periodic_restart and + target_call_timer_callback. - Clean up and simplify logic that determines whether to call each + callback. - Move variable declarations to location of first use. git-svn-id: svn://svn.berlios.de/openocd/trunk@2195 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-11 zwelch + + * : Simplify and fix target handle_rwp_command routine: - Return syntax error unless exactly one argument is passed. - Move variable declaration to point of first use. git-svn-id: svn://svn.berlios.de/openocd/trunk@2193 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-11 zwelch + + * : Simplify handle_resume_command: - Eliminate redundant calls to target_resume with addr temp + variable. - Place variables at location of first use. - Fix minor whitespace issues. git-svn-id: svn://svn.berlios.de/openocd/trunk@2191 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-11 zwelch + + * : Move jtag_get_flush_queue_count near jtag_execute_queue (fix its + docs). git-svn-id: svn://svn.berlios.de/openocd/trunk@2189 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-11 zwelch + + * : Group JTAG reset configuration and accessor APIs together in + header file. Remove unused reset_line_mode enumerated type. git-svn-id: svn://svn.berlios.de/openocd/trunk@2187 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-11 zwelch + + * : Out-of-line jtag_tap_next_enabled and simplify its logic. git-svn-id: svn://svn.berlios.de/openocd/trunk@2185 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-11 oharboe + + * : disable polling continuous polling during reset git-svn-id: svn://svn.berlios.de/openocd/trunk@2183 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-10 ntfreak + + * : - fix texi/pdf issue created in svn r2039 git-svn-id: svn://svn.berlios.de/openocd/trunk@2181 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-10 zwelch + + * : David Brownell : Tweak the csb337 code so that it doesn't enable alignment traps when + it completes the "reset init" sequence. It turns out that the + current CFI code reliably triggers such traps. git-svn-id: svn://svn.berlios.de/openocd/trunk@2179 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Improve use of automake conditionals for FTDI-based JTAG + drivers: - Remove once-used XXX_FTD2XX symbols; replace with XXX_DRIVER + symbols. - Enabled when either libftdi or FTD2xx driver should be built. - Eliminates redundant DRIVERSFILE assignment in JTAG automake + input. git-svn-id: svn://svn.berlios.de/openocd/trunk@2177 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Rename jtag_driver.c as driver.c to remove duplicate name + component. git-svn-id: svn://svn.berlios.de/openocd/trunk@2175 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 oharboe + + * : reset to eol native for now. guess-rev.sh was broken by eol + native, but it was a red herring that these two files were affected. git-svn-id: svn://svn.berlios.de/openocd/trunk@2173 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Encapsulate the core jtag interface pointer: - Add new jtag_config_khz to increase encapsulation of jtag->khz + call. - Add new jtag_get_speed_readable to encapsulate of jtag->speed_div + call. - Make definition of jtag static in core.c, remove extern from + tcl.c. git-svn-id: svn://svn.berlios.de/openocd/trunk@2171 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Continue encapsulation of JTAG event callback sub-API: - Move jtag_event_callbacks struct to core.c; it's an implementation + detail. - Move jtag_*_event_callbacks next to the definition of the new + function type. git-svn-id: svn://svn.berlios.de/openocd/trunk@2169 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Expose jtag_unregister_event_callback with related API + declarations. git-svn-id: svn://svn.berlios.de/openocd/trunk@2167 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Properly encapsulate core hasKHZ variable. git-svn-id: svn://svn.berlios.de/openocd/trunk@2165 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Add missing static keywords to a few variables in JTAG core + module. git-svn-id: svn://svn.berlios.de/openocd/trunk@2163 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Encapsulate jtag_reset_config using accessors: - Update handle_reset_config_command in tcl.c to use new helpers. - Replace direct accesses in JTAG interface and target drivers. git-svn-id: svn://svn.berlios.de/openocd/trunk@2161 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Add get and set accessors for jtag_speed: - Setter calls the interface driver callback to improve core + encapsulation. - Use getter in standard JTAG interface drivers and ZY1000 + minidriver. git-svn-id: svn://svn.berlios.de/openocd/trunk@2159 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Encapsulate the jtag_trst and jtag_srst variables: - Add accessor functions to return their value. - Use new SRST accessor in cortex_m3.c and mips_m4k.c git-svn-id: svn://svn.berlios.de/openocd/trunk@2157 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Remove superfluous extern of jtag_event_strings from jtag.h. git-svn-id: svn://svn.berlios.de/openocd/trunk@2155 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 oharboe + + * : removed native line end style - breaks cygwin git-svn-id: svn://svn.berlios.de/openocd/trunk@2153 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Remove accidental duplicate of hasKHz; fixes pre-init speed + setup. git-svn-id: svn://svn.berlios.de/openocd/trunk@2151 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Split main jtag.c file into two layers: - src/jtag/core.c: contains the low-level JTAG TAP and scanning + routines. - src/jtag/tcl.c: contains high-level JTAG TCL commands that use the + core. - Remove static keywords from routines in core.c, extern from tcl.c: - jtag, jtag_interface global variables - jtag_{examine,validate}_chain and jtag_tap_{init,free} functions - Added myself to the copyright header in both of these files. - Used 'svn cp' to add files, so versioning was preserved for both. git-svn-id: svn://svn.berlios.de/openocd/trunk@2149 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Move Doxygen documentation for IR/DR scan routines to header + file. - Move plain IR scan declaration closer to the other IR scan + declarations. git-svn-id: svn://svn.berlios.de/openocd/trunk@2147 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Remove non-existant jtag_tap_by_position API declaration. git-svn-id: svn://svn.berlios.de/openocd/trunk@2145 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Cleanup jtag_tap_by_abs_position: - Remove unused orig_n local variable. - Merge variable declaration with first use. - Update code to use current style guidelines. git-svn-id: svn://svn.berlios.de/openocd/trunk@2143 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Simplify and fix bug in jtag_tap_by_string: - Bug fix: Use unsigned type and strtoul when parsing for position + number. - Simplify logic by returning directly when a tap is found by name. - Reduce scope: declare temporary variables with first use. - Bring code up to current style guidelines. git-svn-id: svn://svn.berlios.de/openocd/trunk@2141 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Cleanup jtag_tap_count_enabled. git-svn-id: svn://svn.berlios.de/openocd/trunk@2139 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Reduce scope or eliminate temporary variables in + jtag_add_statemove: - Change types of tms_bits and tms_count to unsigned, eliminates a + cast. - Use moves[] only if needed; a single move can use goal_state + directly. - Declare loop induction variable inside its control statement. - Remove retval in favor of direct returns. git-svn-id: svn://svn.berlios.de/openocd/trunk@2137 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-09 zwelch + + * : Revert changes from r2134 that snuck into the commit. Mea + culpa. git-svn-id: svn://svn.berlios.de/openocd/trunk@2135 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 kc8apf + + * : Fix eol-style on guess-rev.sh git-svn-id: svn://svn.berlios.de/openocd/trunk@2133 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 oharboe + + * : Zach Welch wrote a fix for configure problems under Cygwin. + ltmain.sh is added to svn ignore git-svn-id: svn://svn.berlios.de/openocd/trunk@2131 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Factor interface list to its own command: - Add handle_interface_list_command, used by + handle_interface_command. - Display output of new list to command console. - Change first index of displayed drivers to 1; it's only cosmetic. git-svn-id: svn://svn.berlios.de/openocd/trunk@2129 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Simplify jtag_add_sleep: - Add todo for removing keep_alive: is this a layering violation? - Use jtag_set_error instead of accessing jtag_error directly. - Remove superfluous retval temporary variable and empty return. git-svn-id: svn://svn.berlios.de/openocd/trunk@2127 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Simplify jtag_add_clocks: - Use jtag_set_error instead of accessing jtag_error directly. - Improve error language and whitespace. git-svn-id: svn://svn.berlios.de/openocd/trunk@2125 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Simplify jtag_add_pathmove: - Use jtag_set_error instead of accessing jtag_error directly. - Eliminate superfluous retval temporary variable. - Reduce scope of loop induction variable. - Wrap to fit within 80 columns. git-svn-id: svn://svn.berlios.de/openocd/trunk@2123 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Simplify jtag_add_plain_dr_scan: - Use jtag_set_error instead of accessing jtag_error directly. - Wrap function arguments to fit everything in 80 columns. - Move retval variable to location of first use. git-svn-id: svn://svn.berlios.de/openocd/trunk@2121 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Simplify jtag_add_plain_ir_scan: - Use jtag_set_error instead of accessing jtag_error directly. - Wrap function arguments to fit everything in 80 columns. git-svn-id: svn://svn.berlios.de/openocd/trunk@2119 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Simplify jtag_execute_queue: - Add static inline jtag_error_clear helper to return and clear + jtag_error. - Use new helper to shrink body of function to two lines. git-svn-id: svn://svn.berlios.de/openocd/trunk@2117 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Cleanup handle_runtest_command: - Make command argument require exactly one argument; do not allow + extras. - Remove superfluous whitespace at end of function. - Wrap function arguments to fit in 80 columns. git-svn-id: svn://svn.berlios.de/openocd/trunk@2115 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Extend handle_jtag_n{s,t}rst_delay_command routines: - Add support to display the reset delays too, like the other + commands. - Always show the values, so users can see if they are being + redundant. git-svn-id: svn://svn.berlios.de/openocd/trunk@2113 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Update JTAG reset delay command handlers: - Fixes for error handling: - Return a syntax error instead of calling exit(-1). - Return error when more than one argument is provided too. - Remove useless braces and indent after the if/return statements. - Wrap function arguments to fit in 80 columns. git-svn-id: svn://svn.berlios.de/openocd/trunk@2111 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Simplify logic in handle_jtag_speed_command. git-svn-id: svn://svn.berlios.de/openocd/trunk@2109 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 oharboe + + * : David Brownell - Don't let disabled TAPs be set as the current target - Improve "targets" output: * Remove undesirable "chain position" number; we discourage + using them * TAP and Target column updates: + make them long enough for current usage + improve labels, removing guesswork + "TapName" label patches scan_chain output * Highlight the "current" target * Display "tap disabled" as a new pseudo-state * Update docs accordingly git-svn-id: svn://svn.berlios.de/openocd/trunk@2107 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Reorder configure script macros: - Check for a compiler before looking for libraries or header files. - Initialize automake before calling other AM_ macros. - Disable libtool shared libraries by default. - Remove checks for unused C++, Fortran, and Java compilers. - Remove redundant AC_CANONICAL_HOST; called by AC_PROG_LIBTOOL. git-svn-id: svn://svn.berlios.de/openocd/trunk@2105 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-08 zwelch + + * : Move minidummy source file, as was supposed to happen in last + commit. git-svn-id: svn://svn.berlios.de/openocd/trunk@2103 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 zwelch + + * : Fix reference warning in JTAG primer, add another external + reference. git-svn-id: svn://svn.berlios.de/openocd/trunk@2101 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 zwelch + + * : David Brownell : Clarify docs for the evb_lm3s811 layout: works in two modes, not + just one. git-svn-id: svn://svn.berlios.de/openocd/trunk@2099 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 zwelch + + * : David Brownell : Rework chapter 12 (CPU configuration) to use @deffn, match the code + more closely, and present things more clearly. Includes the *current* list of targets. git-svn-id: svn://svn.berlios.de/openocd/trunk@2097 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 oharboe + + * : retire endstate command git-svn-id: svn://svn.berlios.de/openocd/trunk@2095 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 zwelch + + * : Fix regressions in previous series of cleanp, caused by r2092. git-svn-id: svn://svn.berlios.de/openocd/trunk@2093 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 zwelch + + * : Factoring of jtag_examine_chain for maintainability: - Improve variable type: change device_count to unsigned. - Improves jtag_tap_count_enabled() API too (now returns unsigned). git-svn-id: svn://svn.berlios.de/openocd/trunk@2091 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 zwelch + + * : Factoring of jtag_examine_chain for maintainability: - Factor TAP ID matching into new helper function. - Simplifies the main jtag_examine_chain loop logic considerably. git-svn-id: svn://svn.berlios.de/openocd/trunk@2089 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 zwelch + + * : Factoring of jtag_examine_chain for maintainability: - Add helper to check for the terminating ID during + jtag_examine_chain. git-svn-id: svn://svn.berlios.de/openocd/trunk@2087 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 zwelch + + * : Factoring of jtag_examine_chain for maintainability: - Factor output of accepted/incorrect/expected TAP IDs into static + helper. git-svn-id: svn://svn.berlios.de/openocd/trunk@2085 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 zwelch + + * : Factoring of jtag_examine_chain for maintainability: - Factor JTAG chain examination into static helper function. git-svn-id: svn://svn.berlios.de/openocd/trunk@2083 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 zwelch + + * : Factoring of jtag_examine_chain for maintainability: - Reduce indent: invert logic test for unexpected TAP (no IDs). git-svn-id: svn://svn.berlios.de/openocd/trunk@2081 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 zwelch + + * : Factoring of jtag_examine_chain for maintainability: - Move definition of maximum JTAG chain size closer to its only + uses. git-svn-id: svn://svn.berlios.de/openocd/trunk@2079 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-07 zwelch + + * : Clean up handle_endstate_command(): - Merge declaration of state with first use. - Unindent and remove unnecessary 'else' block. git-svn-id: svn://svn.berlios.de/openocd/trunk@2077 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-05 oharboe + + * : remove hacks no longer required to build OpenOCD w/eCos git-svn-id: svn://svn.berlios.de/openocd/trunk@2074 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-05 oharboe + + * : remove unused include file: inttypes.h git-svn-id: svn://svn.berlios.de/openocd/trunk@2072 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-05 zwelch + + * : Eliminate MixedCaps symbol from public JTAG TAP API: - Purely mechanical transformations to the source files. - Rename 'jtag_NextEnabledTap' as 'jtag_tap_next_enabled.' git-svn-id: svn://svn.berlios.de/openocd/trunk@2069 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-05 zwelch + + * : Eliminate MixedCaps symbol from public JTAG TAP API: - Purely mechanical transformations to the source files. - Rename 'jtag_NumTotalTaps' as 'jtag_tap_count.' git-svn-id: svn://svn.berlios.de/openocd/trunk@2067 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-05 zwelch + + * : Eliminate MixedCaps symbol from public JTAG TAP API: - Purely mechanical transformations to the source files. - Rename 'jtag_TapByString' as 'jtag_tap_by_string.' git-svn-id: svn://svn.berlios.de/openocd/trunk@2065 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-05 zwelch + + * : Eliminate MixedCaps symbol from public JTAG TAP API: - Purely mechanical transformations to the source files. - Rename 'jtag_TapByPosition' as 'jtag_tap_by_position.' git-svn-id: svn://svn.berlios.de/openocd/trunk@2063 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-05 zwelch + + * : Eliminate MixedCaps symbol from public JTAG TAP API: - Purely mechanical transformations to the source files. - Rename 'jtag_all_taps' as '__jtag_all_taps.' - Frees original symbol name to rename the accessor function. git-svn-id: svn://svn.berlios.de/openocd/trunk@2061 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-05 zwelch + + * : Add accessors for reset delays; use them in jim command + handlers. git-svn-id: svn://svn.berlios.de/openocd/trunk@2059 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-04 zwelch + + * : Add jtag_get_flush_queue_count accessor to help future + factoring. git-svn-id: svn://svn.berlios.de/openocd/trunk@2057 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-04 zwelch + + * : Clean up the core JTAG TAP APIs: - Move jtag_tap_name to same location as other TAP functions; export + it. - Factor new jtag_tap_add() from jim_newtap_cmd(); appends TAP to + global list. - Move static chain position counter to global; use in + jtag_NumTotalTaps(). - Use jtag_AllTaps for reading tap list, instead of accessing global + directly. git-svn-id: svn://svn.berlios.de/openocd/trunk@2055 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-04 zwelch + + * : Add missing static keywords in JTAG source file. git-svn-id: svn://svn.berlios.de/openocd/trunk@2053 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-04 ntfreak + + * : - add support for different TAR autotincrement sizes as per ARM ADI + spec. - set TAR size to 12 bits for Cortex-M3. - Original patch submitted by Magnus Lundin [lundin@mlu.mine.nu]. git-svn-id: svn://svn.berlios.de/openocd/trunk@2051 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-04 oharboe + + * : Introduce jtag_get_end_state() fn to clarify code a bit. git-svn-id: svn://svn.berlios.de/openocd/trunk@2049 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-04 oharboe + + * : do not modify global end state from jtag_add_xxx() git-svn-id: svn://svn.berlios.de/openocd/trunk@2047 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-04 oharboe + + * : no longer use jtag_add_xxx() to set end state to TAP_DRPAUSE git-svn-id: svn://svn.berlios.de/openocd/trunk@2045 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-04 oharboe + + * : use assert() to catch TAP_INVALID passed to jtag_add_xxx() fn's. git-svn-id: svn://svn.berlios.de/openocd/trunk@2043 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-04 oharboe + + * : jtag_add_end_state() now returns the value of the global + variable and does not modify the global variable if passed + TAP_INVALID. This patch has no effect on the current code and is + just to prepare upcoming patches. git-svn-id: svn://svn.berlios.de/openocd/trunk@2041 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-04 zwelch + + * : David Brownell : Update the "General Commands" (a.k.a. "random stuff") chapter, and + associated chunks of other text: - Switch to @deffn and review everything that's documented - Improve descriptions of reset events, with reference to the setup.tcl code which issues them. - Move one zy1000-specific command to that driver's doc. - There is no "script" command; remove its doc. NOTE: Some things missing from this bit of work are: 1- Reviewing the code to catch various *missing* functions, mostly from "target.c" 2- Alphabetizing and organizing. This chapter is a real grab-bag with no evident focus or structural principle. 3- Hole-filling and bugfixing with respect to messaging/logging. Example, what principle could possibly justify the tcl command output going into the server output/log instead of just the telnet session? 4- Not just for this chapter ... but there should be a section with descriptions of all the supported image file formats, so every image command can just reference that section. git-svn-id: svn://svn.berlios.de/openocd/trunk@2039 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-04 zwelch + + * : David Brownell : Minor cleanup of FT2232: - make Olimex glue warn about Olimex issues instead of JTAGkey + issues; - make some data static+const; - don't export some internal symbols. git-svn-id: svn://svn.berlios.de/openocd/trunk@2037 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-04 zwelch + + * : David Brownell : Convert the Interface/Dongle Config chapter's section on drivers to + use the @deffn syntax, and integrate the presentation of the + driver-specific commands with the relevant driver. Alphabetize. Cross-checked against the code ... several adapters were not listed, + and a few commands weren't. (Maintainers for the versaloon and zy1000 drivers would be good + candidates to add the commands missing from those sections...) git-svn-id: svn://svn.berlios.de/openocd/trunk@2035 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 oharboe + + * : use assert() for obscure check on illegal arguments upon trst + being asserted while commands are queued git-svn-id: svn://svn.berlios.de/openocd/trunk@2033 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 oharboe + + * : catchup with jtag refactoring. git-svn-id: svn://svn.berlios.de/openocd/trunk@2031 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 zwelch + + * : Finish JTAG header file modularization; command factoring + follows. git-svn-id: svn://svn.berlios.de/openocd/trunk@2029 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 zwelch + + * : Move JTAG command APIs into new jtag/commands.h header file. git-svn-id: svn://svn.berlios.de/openocd/trunk@2027 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 zwelch + + * : Improve in-source documentation that was causing Doxygen + warnings. git-svn-id: svn://svn.berlios.de/openocd/trunk@2025 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 zwelch + + * : Improve logger script to expose warnings and errors in the + output. git-svn-id: svn://svn.berlios.de/openocd/trunk@2023 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 zwelch + + * : Add draft of Patching Primer in The Manual; update primer page. git-svn-id: svn://svn.berlios.de/openocd/trunk@2021 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 zwelch + + * : Enable or add doxygen comments to the public JTAG API. git-svn-id: svn://svn.berlios.de/openocd/trunk@2019 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 zwelch + + * : Remove vestigal tap_transition type from public jtag API. git-svn-id: svn://svn.berlios.de/openocd/trunk@2017 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 zwelch + + * : Expose tap_state_by_name TAP helper available in public API. git-svn-id: svn://svn.berlios.de/openocd/trunk@2015 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 zwelch + + * : David Brownell : Rework the TAP creation documentation. - Try to use "TAP" not "tap" everywhere; it's an acronym. - Update the associated "target config files" section: * reference the "TAP Creation" chapter for details * simplify: reference interesting multi-tap config files * let's not forget CPU configuration (*before* workspace setup) * streamline it a bit * move that workspace-vs-mmu issue to a better location - Clean up TAP creation doc mess * switch to @deffn * (re)organize the remaining stuff * reference the "Config File Guidelines" chapter - Tweak the "Target Configuration" chapter * rename as "CPU configuration"; unconfuse vs. target/*.cfg * bring out that it's not just there for GDB * move TAP events to the TAP chapter, where they belong + (bugfix) git-svn-id: svn://svn.berlios.de/openocd/trunk@2013 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 zwelch + + * : Add missed accessor for checking the current TMS table. git-svn-id: svn://svn.berlios.de/openocd/trunk@2011 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-03 zwelch + + * : Make tap_state_by_name available in new JTAG interface API + header. git-svn-id: svn://svn.berlios.de/openocd/trunk@2009 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-02 zwelch + + * : Finish removing '#ifdef HAVE_JTAG_MINIDRIVER_H' from jtag.h: - Wraps JTAG callback API functions: - Outlines jtag_add_callback() and jtag_add_callback4(). - Adds interface_ prefix to existing in-tree driver + implementation. - Declare the driver interfaces routines in miniheader.h file. This patch requires renaming the equivalent macros in out-of-tree + jtag_minidriver.h implementations. git-svn-id: svn://svn.berlios.de/openocd/trunk@2007 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-02 ntfreak + + * : - change signature for adi_jtag_dp_scan and adi_jtag_dp_scan_u32 to + use swjdp_common_t *swjdp instead of arm_jtag_t *jtag_info - change SWJDP_IR/DR_APACC to DAP_IR/DR_APACC to conform with + ARM_ADI docs. - add swjdp->memaccess_tck field and code for extra tck clocks + before accessing memory bus - Set default memaccess value to 8 for Cortex-M3. - Add dap memaccess command. - document all armv7 dap cmds. - Original patch submitted by Magnus Lundin [lundin@mlu.mine.nu]. git-svn-id: svn://svn.berlios.de/openocd/trunk@2005 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-02 oharboe + + * : remove unecessary #ifdef as file is only built when minidriver + is enabled. git-svn-id: svn://svn.berlios.de/openocd/trunk@2003 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-02 oharboe + + * : more missing eCos types git-svn-id: svn://svn.berlios.de/openocd/trunk@2001 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-02 zwelch + + * : Move interface_jtag_add_scan_check_alloc implementations to + their respective implementation files. git-svn-id: svn://svn.berlios.de/openocd/trunk@1999 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-02 oharboe + + * : Remove unused code, TAP_INVALID is never passed to drivers. git-svn-id: svn://svn.berlios.de/openocd/trunk@1997 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-02 zwelch + + * : More JTAG interface driver cleanup: - Moves references to global jtag interface to default core + implementation. - Missed this reference in the earlier "pointless" patch. Mea + culpa. Important: this has a side-effect. Previously, the error return + inside the interface routine short-circuited the remainder of that + function when 'init' has not been called. With this patch, the + command queue will be cleared in the case that 'init' has been + called. Since that case indicates a buggy script, this does not + seem to be a problem. git-svn-id: svn://svn.berlios.de/openocd/trunk@1995 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-02 zwelch + + * : More JTAG interface driver cleanup: - Make interface_jtag_execute_queue call new helper function. - Add default_interface_jtag_execute_queue to wrap jtag interface + access. This patch may look useless on its own, but it helps to isolate the + core JTAG variables from the interface_jtag_* routines, so the later + can be moved into jtag_driver.c in a pending patch. git-svn-id: svn://svn.berlios.de/openocd/trunk@1993 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-02 zwelch + + * : Encapsulate JTAG command interfaces for moving to + jtag_interface.h. git-svn-id: svn://svn.berlios.de/openocd/trunk@1991 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-02 zwelch + + * : Start clean-up of JTAG driver interface: - Factor jtag_add_scan_check to call new jtag_add_scan_check_alloc + helper. - Use conditional logic to define two versions of the helper. - These helpers will be moved to other files in future patches. git-svn-id: svn://svn.berlios.de/openocd/trunk@1989 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-01 zwelch + + * : David Brownell : Whitespace fixes in jtag.c ... mostly end-of-line crap. Flag + "jtag_device" command as obsolete in its helptext. git-svn-id: svn://svn.berlios.de/openocd/trunk@1987 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-01 zwelch + + * : David Brownell : This is the missing half of the r1974 patch: OSK5912 board support, + which was split out from the omap5912 target config. git-svn-id: svn://svn.berlios.de/openocd/trunk@1985 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-01 zwelch + + * : Encapsulate JTAG minidriver functions, plan for new header file. git-svn-id: svn://svn.berlios.de/openocd/trunk@1983 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-01 zwelch + + * : Scrub final vestiges of in_handler from mips target APIs. git-svn-id: svn://svn.berlios.de/openocd/trunk@1981 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-01 oharboe + + * : fix warning for a variable that GCC thought might be + uninitialized(which it can't be). git-svn-id: svn://svn.berlios.de/openocd/trunk@1979 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-01 zwelch + + * : David Brownell : Uplevel the arch commands to be a chapter; they really don't fit in + the "general commands" category. git-svn-id: svn://svn.berlios.de/openocd/trunk@1977 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-01 zwelch + + * : David Brownell : Various updates, mostly small/formatting changes: * Small content tweaks: - Re-title: "OpenOCD User's Guide". - For users, URLS for latest doc and SparkFun forum - Mention GIT-SVN * Fix some front-matter goofage, matching texinfo docs: - "paragraphintent" location matters - put release version/date description with the copyright * Fix some other stuff matching texinfo docs: - no tabs - tweak some refs and anchors * whitespace-at-end-o-line fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@1975 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-06-01 zwelch + + * : David Brownell : Whitespace fixes. git-svn-id: svn://svn.berlios.de/openocd/trunk@1973 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-31 zwelch + + * : Final step in isolating target_type_s structure: - Move definition of 'struct target_type_s' into new 'target_type.h' + file. - Forward delclaration remains in target.h, with comment pointing to + new file. - Replaces #define with #include in source files. git-svn-id: svn://svn.berlios.de/openocd/trunk@1971 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-31 zwelch + + * : First step in hiding target_type_s from public interface: - Add DEFINE_TARGET_TYPE_S symbol in files that need it defined. - Forward declare 'struct target_type_s' only, unless that symbol is + defined. git-svn-id: svn://svn.berlios.de/openocd/trunk@1969 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-31 zwelch + + * : Add target breakpoint and watchpoint wrapper: - replaces all calls to + target->type->{add,remove}_{break,watch}point. git-svn-id: svn://svn.berlios.de/openocd/trunk@1967 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-31 zwelch + + * : Add target_step wrapper: - replaces all calls to target->type->step. git-svn-id: svn://svn.berlios.de/openocd/trunk@1965 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-31 zwelch + + * : Add target_bulk_write_memory wrapper: - replaces all calls to target->type->bulk_write_memory. - add documentation in target_s to warn not to invoke callback + directly. git-svn-id: svn://svn.berlios.de/openocd/trunk@1963 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-31 zwelch + + * : Add target_run_algorithm wrapper: - replaces all calls to target->type->run_algorithm. - add documentation in target_s to warn not to invoke callback + directly. git-svn-id: svn://svn.berlios.de/openocd/trunk@1961 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-31 zwelch + + * : Add target_read_memory wrapper: - replaces all calls to target->type->read_memory. - add documentation in target_s to warn not to invoke callback + directly. git-svn-id: svn://svn.berlios.de/openocd/trunk@1959 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-31 zwelch + + * : Make nvp_target_event static; remove its external declaration. git-svn-id: svn://svn.berlios.de/openocd/trunk@1957 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-31 zwelch + + * : Peter Denison : The debugging code in jlink_tap_execute() called when + _DEBUG_USB_COMMS_ is defined was using the entire cached scan length + to print the results buffers, and not the correct length of each + individual buffer. git-svn-id: svn://svn.berlios.de/openocd/trunk@1955 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-30 zwelch + + * : Eliminate duplicated code in the handle_mw_command memory write + loop. - wordsize will always be 1, 2, or 4 due to preceeding switch + statement. - move call to keep_alive after successful writes, not upon failures git-svn-id: svn://svn.berlios.de/openocd/trunk@1953 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-30 zwelch + + * : Remove unused jlink_execute_end_state (unreferenced after + r1949). git-svn-id: svn://svn.berlios.de/openocd/trunk@1951 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-30 oharboe + + * : remove unused JTAG_END_STATE git-svn-id: svn://svn.berlios.de/openocd/trunk@1949 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-30 oharboe + + * : more reset_config texts git-svn-id: svn://svn.berlios.de/openocd/trunk@1947 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-30 zwelch + + * : David Brownell : Provide basic documentation on the ARM ETM and ETB trace commands. Fix minor goofs in registration of the ETM commands; and whitespace + issues in the proof-of-concept oocd_trace code. (Plus include a ref + to Dominic's email saying that it's just proof-of-concept code.) Note that I'm still not sure whether the ETM support works. But + documenting how it's expected to work should help sort out which + behaviors are bugs, which will help get bugs patched. ZW: whitespace changes were split out of this patch but will follow. git-svn-id: svn://svn.berlios.de/openocd/trunk@1945 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-29 zwelch + + * : Remove error_handler_t type definition; it was unused in the + tree. git-svn-id: svn://svn.berlios.de/openocd/trunk@1943 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-29 zwelch + + * : David Brownell : Provide basic documentation for some of the other flash drivers. avr ... looks incomplete, may work with one AVR8 microcontroller ecosflash ... can't find docs lpc288x ... an NXP part, driver seems lpc2888-specific ocl ... some arm7/arm9 thing, can't find docs pic32mx ... looks incomplete, for PIC32MX (MIPS 4K) devices tms470 ... for TI TMS470 parts Still seems to be mostly arm7tdmi... several of these have no users + in the current tree. git-svn-id: svn://svn.berlios.de/openocd/trunk@1941 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-28 zwelch + + * : David Brownell : Start converting the architecture-specific commands to @deffn + format, reviewing against the code. * armv4_5 disassemble ... now documented; although Jazelle code is not handled * It's "armv4_5 core_state" not "core_mode"; although Jazelle + state is not handled * arm7/9 "debug" commands ... now with other arm7_9 commands, no longer in a separate section * arm926ejs cp15 ... previous description was broken, it matched the code for arm920t instead * Have separate subsections for ARMv4/ARMv5, ARMv6, and ARMv7; the latter are new * Move core-specific descriptions into sub-subsections under those architectures; XScale and ARM11 descriptions are new The new XScale and ARM11 command descriptions surely need + elaboration and review. ARM CP15 operation descriptions in general + seem to be confused and incomplete. git-svn-id: svn://svn.berlios.de/openocd/trunk@1939 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-28 zwelch + + * : David Brownell : Start updating the NOR flash coverage to use @deffn syntax, so the + commands have more consistent presentation and formatting. This + reorganizes information and updates its presentation, except where + the information didn't really match the code. This patch updates most of the driver specific support, creating one + new (and alphabetized!) section just for driver-specific data, where + previously that data was split over up to three sections. Of note: - The at91sam7 docs were a bit out of date with respect to the + code. - The "str9xpec" stuff still deserves some work. For now, it sits in its own subsection; pretty messy. - Likewise the "mflash" stuff. That's a parallel infrastructure, and is now in a section of its own. - The "mass_erase" commands for the Cortex M3 chips got turned into footnotes. IMO, they should vanish sometime; they're + superfluous. - There are still a bunch of undocumented NOR drivers. Examples: avr(8), tms470, pic32mx, more. Plus there are a handful of minor tweaks to the NAND docs (to help + make the NOR and NAND presentations be parallel); the "Command + Index" has been renamed as the "Command and Driver Index"; reference + TI instead of Luminary Micro in several places. git-svn-id: svn://svn.berlios.de/openocd/trunk@1937 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-27 zwelch + + * : Fix potentialyl unaligned memory accesses in mflash driver. git-svn-id: svn://svn.berlios.de/openocd/trunk@1935 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-27 kc8apf + + * : Author: Nicolas Pitre - Silence errors about keep_alive() not being called frequently + enough unless a gdb session is active or debugging is enabled git-svn-id: svn://svn.berlios.de/openocd/trunk@1933 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-27 zwelch + + * : unsik Kim : Add large bank write/dump + support in mflash driver. git-svn-id: svn://svn.berlios.de/openocd/trunk@1931 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-27 zwelch + + * : unsik Kim : Remove unused mflash driver + 'prove' field. git-svn-id: svn://svn.berlios.de/openocd/trunk@1929 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-27 zwelch + + * : unsik Kim : Change prefix of mflash driver + routines to mg_. git-svn-id: svn://svn.berlios.de/openocd/trunk@1927 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-27 ntfreak + + * : - add support for cortino jtag interface git-svn-id: svn://svn.berlios.de/openocd/trunk@1925 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-27 zwelch + + * : Link new Primer pages into the main list of Primers. git-svn-id: svn://svn.berlios.de/openocd/trunk@1923 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-27 zwelch + + * : Add draft of Autotools Primer to The Manual. git-svn-id: svn://svn.berlios.de/openocd/trunk@1921 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-27 zwelch + + * : Move TCL script files -- Step 2 of 2: - Move src/tcl to tcl/. - Update top Makefile.am to use new path name. git-svn-id: svn://svn.berlios.de/openocd/trunk@1919 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-27 zwelch + + * : Add warning to generated Doxyfile to edit Doxyfile.in. git-svn-id: svn://svn.berlios.de/openocd/trunk@1917 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-26 zwelch + + * : SimonQian , reported by R.Doss: This patch fixes a segfault when TDO was not received in XXR + command: - allocate space for the value and mask anyway - clear the mask to zero to effectively skip the output comparison + step git-svn-id: svn://svn.berlios.de/openocd/trunk@1915 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-26 zwelch + + * : David Brownell : Update the "Reset Configuration" information in the User's guide: - Convert to @deffn syntax - Move tutorial text from command descriptions into new sections - Describe several different types of JTAG-visible reset - Expand descriptions of configuration tweaks for SRST and TRST - Link to the "reset" command, and vice versa - Bugfix the "reset_config" description (it didn't match the code) Plus, be more proscriptive: do it in board config files, except for + the oddball cases where that won't work. (Current target.cfg files + seem to have much goofage there; several seem board-specific.) git-svn-id: svn://svn.berlios.de/openocd/trunk@1913 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-25 kc8apf + + * : Author: Raúl Sánchez Siles - cfi flash_address coding style fix git-svn-id: svn://svn.berlios.de/openocd/trunk@1911 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-24 zwelch + + * : David Brownell : Make startup for the various server ports be quiet, unless debugging + is active: don't emit needless scarey messages. Update the + relevant documentation and its references: - For these port commands ... cover the default values; convert to @deffn syntax; include their use outside of the configuration stage; and alphabetize. Similar updates to the rest of that small chapter: - Highlight that there even *IS* a configuration stage, after which some command functionality is no longer available. - For GDB commands ... convert to @deffn syntax; alphabetize; include a missing command (!); add missing helptext (!) for one non-missing command; update relevant cross-references and index entries. git-svn-id: svn://svn.berlios.de/openocd/trunk@1909 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-24 zwelch + + * : David Brownell : minor davinci_nand bugfix Fix a bug that joined us at the last minute, when an efficient + alloca() call got swapped out for a more portable malloc(). Also log one error, to give a clue in case it appears "in the wild". git-svn-id: svn://svn.berlios.de/openocd/trunk@1907 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-24 zwelch + + * : Nicolas Pitre : Update sheevaplug interface + script: When the CPU is in the WFI state, the JTAG interface simply doesn't + respond at all and initial tap examination simply fails. Let's + simply do it again when we come around to assert nSRST. git-svn-id: svn://svn.berlios.de/openocd/trunk@1905 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-24 zwelch + + * : David Brownell : NAND support for DaVinci-family drivers, with HW ECC support. + Declare the NAND chip on the DM355 EVM board. Currently tested on DM355 for Linux interop using the standard large + page (2KB) chip in the EVM socket; "hwecc1" and "hwecc4" work fine. + (Using hwecc4 relies on patches that haven't quite made it through + the Linux-MTD bottlenecks yet.) Not yet tested: 1-bit on small-page (although it's hard to see how + that could fail); 4-bit on small page (picky layout issues); the + "hwecc_infix" mode (primarily for older boot ROMs; testing there is + blocked on having new bootloader code). git-svn-id: svn://svn.berlios.de/openocd/trunk@1903 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-24 zwelch + + * : Properly fix doxygen out-of-tree build process: - move Doxyfile to Doxyfile.in: type 'make Doxyfile' to recreate it - create Doxyfile from Doxyfile.in with make rule: - use sed substitution of $(srcdir) to location directories - delete all doxygen created files with 'make distclean' - include all required files (including logger.pl) in distribution git-svn-id: svn://svn.berlios.de/openocd/trunk@1901 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-24 zwelch + + * : Freddie Chopin : - add reset delay settings for LPC2103, LPC2124, and LPC2129. git-svn-id: svn://svn.berlios.de/openocd/trunk@1899 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-23 zwelch + + * : Update main page of doxygen developer documentation: - Rewrite copy to give a better introduction and overview. - Add subpages: The List, Style Guide, Patch Policies, and Bug + Reporting. git-svn-id: svn://svn.berlios.de/openocd/trunk@1897 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-23 zwelch + + * : Update user guide documentation: - Remove style guide from user guide; moved to doxygen manual. - Replace with improved introduction for developers and packagers. - Move introductory paragraph about the project under the About + page. git-svn-id: svn://svn.berlios.de/openocd/trunk@1895 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-23 zwelch + + * : Submitted by Magnus Lundin : - Remove FTDI driver tap_set_state call; performed by + jtag_add_reset. git-svn-id: svn://svn.berlios.de/openocd/trunk@1893 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-23 zwelch + + * : Fix make docs rule to work with out-of-tree builds. git-svn-id: svn://svn.berlios.de/openocd/trunk@1891 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-23 zwelch + + * : Submitted by Magnus Lundin : Updates to the J-Link interface driver to support more device + versions: - Add capability detection: - if capable, detect protocol version; otherwise, assume v2 + protocol. - if capable, detect buffer size; otherwise, assume minimal. - Disable command result queries for devices using v2 protocol. - Defined and use JTAG2 command with v2 protocol; JTAG3 is v3 + protocol. - Add TCL command to allow explicit setting of J-Link protocol + version. With approval, I revised the patch to make the following changes: - add static keywords to new jlink-specific variables - factor calculation of major_version to be more readable - remove braces around simple one-line statements in if/else clauses - remove (rather than #if 0) duplicate reset code; it is in SVN - use &function to be clearer when passing function pointers - add symbols for EMU_CMD_GET_CAPS bits; do not hard-code constants! - almost renamed jlink_handle_jlink_hw_jtag_command (seriously?!?!) - rewrote that function using a switch statement. - made version request processing easier to understand and modify - improve alternate endpoint detection: - make code easier to read by using temporary variables - eliminate extra level of indentation and redundant logging - use ternary conditional to select JTAG2 or JTAG3 command - reverse version test in jlink_usb_message to reduce indentation - this had the biggest effect in cleaning up this patch - use C99's ability to declare new/changed variables with less scope - add spaces around binary operators in new/changed code - revert other superfluous whitespace/comment style changes git-svn-id: svn://svn.berlios.de/openocd/trunk@1889 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-23 zwelch + + * : Change doxygen configuration to show code comments in + documentation. git-svn-id: svn://svn.berlios.de/openocd/trunk@1887 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-22 kc8apf + + * : Author: Raúl Sánchez Siles - Fix calculation of flash_address for x16 devices used as x8 git-svn-id: svn://svn.berlios.de/openocd/trunk@1885 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-22 kc8apf + + * : Author: David Brownell Remove un-implemented and dubious "nand copy" command. Doing this efficiently would mean doing the copying on the target + CPU, instead of back and forth through JTAG. If anyone ever needs + this functionality, that's what they should implement. Also, update on-line "help" for "nand dump" to display its two + optional flags; and for "nand write" to display a recently added + flag. git-svn-id: svn://svn.berlios.de/openocd/trunk@1883 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-22 zwelch + + * : Submitted by David Brownell : Improve support for the DM355 EVM board, and eventually other boards + based on DaVinci chips: - Provide generic "davinci.cfg" to hold utilities that can be + reused by different chips in this family. Start with PINMUX, PSC, + and PLL setup. - DM355 chip support updates: provide a dictionary with + chip-specific symbols, load those utilities. - Create a new dm355evm board file, with a reset-init event handler which uses those utilities to set up PLLs and clocks, configure + the pins, and improve the JTAG speed limit. Also a minor tweak: provide a virtual address for the work area, + matching what the very latest kernels do. It's probably unwise to + use OpenOCD while the MMU is active though. The DRAM isn't yet accessible, but NAND access is mostly ready. git-svn-id: svn://svn.berlios.de/openocd/trunk@1881 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-22 zwelch + + * : Submitted by David Brownell : Add a "NAND Commands" section to to the TEXI docs, covering the + basic commands except for those previously discussed as being due + for removal ("nand copy") or switching to use byte offsets not block + numbers. This uses the "@deffn..." syntax for defining commands, as somewhat + suggested by the TEXI documentation, and adds a new "Command Index". + We might prefer to merge those indexes for the near term, but I + think the "@deffn" approch is probably worth switching to. Updates a few other bits to clarify that "flash" doesn't just mean + NOR. And to fix one niggling falsity: the "reset-init" event *is* + used, and in fact it's quite important. git-svn-id: svn://svn.berlios.de/openocd/trunk@1879 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-21 oharboe + + * : fix warning. Use %p for pointers git-svn-id: svn://svn.berlios.de/openocd/trunk@1877 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-21 oharboe + + * : Dirk Behme Minor updates for OMAP3 + scripts git-svn-id: svn://svn.berlios.de/openocd/trunk@1875 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-21 zwelch + + * : David Brownell : This patch adds + annotations to the key command_*() helper functions, fixng the bugs + that turned up. Several of these bugs were from misuse of PRIi64; that's for 64-bit + integers, NOT for "long long" or "u64" (which work best with %lld). git-svn-id: svn://svn.berlios.de/openocd/trunk@1873 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-21 kc8apf + + * : Author: Thomas Kindler - Increase DTC status retry count to avoid problems with STM Primer git-svn-id: svn://svn.berlios.de/openocd/trunk@1871 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-21 kc8apf + + * : Author: Holger Schurig -Prevent freezing of target when doing a 'shutdown'. git-svn-id: svn://svn.berlios.de/openocd/trunk@1869 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-21 kc8apf + + * : Author: Michael Bruck -jtag.c, interface_jtag_add_dr_out(): - use pointer 'field' instead of scan->fields[field_count] - restructure the main loop to clearly separate the two + cases: TAP is not bypassed / TAP is bypassed (this is to + keep the function similar to interface_jtag_add_dr_scan()) - fix bug where only the first output field has its tap field set - add asserts to verify that target_tap points to the one + not bypassed TAP git-svn-id: svn://svn.berlios.de/openocd/trunk@1867 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-21 kc8apf + + * : Author: Michael Bruck -jtag.c, interface_jtag_add_ir_scan(): - use pointer 'field' instead of scan->fields[nth_tap] - add assertion to ensure that input data has correct size + for TAP's IR git-svn-id: svn://svn.berlios.de/openocd/trunk@1865 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-21 kc8apf + + * : Author: Michael Bruck - jtag.c: remove unused variable 'nth_tap' from DR scan + functions git-svn-id: svn://svn.berlios.de/openocd/trunk@1863 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-21 kc8apf + + * : Author: Michael Bruck - jtag.c: consolidate all memory allocations in scan functions + in one block, add out_fields pointer to set stage for further + changes git-svn-id: svn://svn.berlios.de/openocd/trunk@1861 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-21 kc8apf + + * : Author: Michael Bruck - add doxygen comments to scan commands in jtag.c - move jtag_add_dr_scan next to interface_jtag_add_dr_scan to + keep these function pairs together git-svn-id: svn://svn.berlios.de/openocd/trunk@1859 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-20 zwelch + + * : Add initial OpenOCD server documentation (Duane Ellis and + myself). git-svn-id: svn://svn.berlios.de/openocd/trunk@1857 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-20 zwelch + + * : Move TCL overview from source tree to doxygen manual. git-svn-id: svn://svn.berlios.de/openocd/trunk@1855 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-20 zwelch + + * : Move non-arm target overview from source tree to doxygen manual. git-svn-id: svn://svn.berlios.de/openocd/trunk@1853 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-20 oharboe + + * : Spencer Oliver use 7 tms out of reset git-svn-id: svn://svn.berlios.de/openocd/trunk@1851 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-20 kc8apf + + * : Author: Michael Bruck - simplify code in interface_jtag_add_plain_dr_scan() by adding + a local variable 'scan' to hold the scan_command_t git-svn-id: svn://svn.berlios.de/openocd/trunk@1849 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-20 kc8apf + + * : Author: Michael Bruck - simplify code in interface_jtag_add_dr_out() by adding a local + variable 'scan' to hold the scan_command_t git-svn-id: svn://svn.berlios.de/openocd/trunk@1847 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-20 kc8apf + + * : Author: Michael Bruck - simplify code in interface_jtag_add_dr_scan() by adding a + local variable 'scan' to hold the scan_command_t git-svn-id: svn://svn.berlios.de/openocd/trunk@1845 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-20 kc8apf + + * : Author: Michael Bruck - move scan_size in interface_jtag_add_ir_scan() into the scope + of the inner loop and change it to unsigned git-svn-id: svn://svn.berlios.de/openocd/trunk@1843 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-20 kc8apf + + * : Author: Michael Bruck - rename local variable x to num_taps in + interface_jtag_add_ir_scan git-svn-id: svn://svn.berlios.de/openocd/trunk@1841 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-19 zwelch + + * : Wookey : add user documentation for echo + command. git-svn-id: svn://svn.berlios.de/openocd/trunk@1839 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-19 oharboe + + * : fix warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@1837 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-19 oharboe + + * : David Brownell NAND: update ids, "nand + list" bugfix git-svn-id: svn://svn.berlios.de/openocd/trunk@1835 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 oharboe + + * : use tap_get_tms_path_len() instead of fix # of 7. Not tested if + this builds, but at least we're looking at a build error instead of + a runtime error. git-svn-id: svn://svn.berlios.de/openocd/trunk@1833 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 oharboe + + * : use tap_get_tms_path_len() instead of fix # of 7. git-svn-id: svn://svn.berlios.de/openocd/trunk@1831 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 oharboe + + * : updated w/jtag_add_end_state() note. git-svn-id: svn://svn.berlios.de/openocd/trunk@1829 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 kc8apf + + * : Enable non-7-cycle state table for FT2232 and JLink git-svn-id: svn://svn.berlios.de/openocd/trunk@1827 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 kc8apf + + * : FT2232 support for non-7-cycle state moves by Dick Hollenbeck + git-svn-id: svn://svn.berlios.de/openocd/trunk@1825 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 kc8apf + + * : Change last_comand_pointer to last_command_pointer by Michael + Bruck git-svn-id: svn://svn.berlios.de/openocd/trunk@1823 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 kc8apf + + * : Add jtag_queue_command() by Michael Bruck + [7/8] git-svn-id: svn://svn.berlios.de/openocd/trunk@1821 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 kc8apf + + * : Add jtag_queue_command() by Michael Bruck + [5/8] git-svn-id: svn://svn.berlios.de/openocd/trunk@1819 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 kc8apf + + * : Add jtag_queue_command() by Michael Bruck + [3/8] git-svn-id: svn://svn.berlios.de/openocd/trunk@1817 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 kc8apf + + * : Add jtag_queue_command() by Michael Bruck git-svn-id: svn://svn.berlios.de/openocd/trunk@1815 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 kc8apf + + * : PATCHES updates from David Brownell git-svn-id: svn://svn.berlios.de/openocd/trunk@1813 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 oharboe + + * : Remove unecessary(and poptentially harmful?) "" around arguments + passed in to "eval" in command.c git-svn-id: svn://svn.berlios.de/openocd/trunk@1811 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 oharboe + + * : Dean Glazeski fixed bug in checking of + clocked back data in arm7_9_execute_fast_sys_speed. Not reported. + There is a chance that this bug hid a deeper problem since it only + partially disabled the check(mask & value were equal). git-svn-id: svn://svn.berlios.de/openocd/trunk@1809 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 oharboe + + * : Michael Bruck ARM11 cleanup stale + dependencies with generic arm code; added comments and whitespace + fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@1807 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 kc8apf + + * : Fix logically inverted comment git-svn-id: svn://svn.berlios.de/openocd/trunk@1805 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-18 kc8apf + + * : ETM/ETB documentation from David Brownell git-svn-id: svn://svn.berlios.de/openocd/trunk@1803 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-17 oharboe + + * : fix array2mem/mem2array when used as a "method" on a target. git-svn-id: svn://svn.berlios.de/openocd/trunk@1801 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-16 oharboe + + * : fix naming of at91sam7 driver git-svn-id: svn://svn.berlios.de/openocd/trunk@1799 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-15 zwelch + + * : Initialize a more variables in jim.c to allow gcc-4.4 to build. + Fix provided by Benjamin Schmidt . git-svn-id: svn://svn.berlios.de/openocd/trunk@1797 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-15 oharboe + + * : fix -fno-common/Mac build problems. git-svn-id: svn://svn.berlios.de/openocd/trunk@1795 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-15 oharboe + + * : revert to 1775. 1790 causes SEGFAULT w/Cygwin. git-svn-id: svn://svn.berlios.de/openocd/trunk@1793 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-15 zwelch + + * : Add current draft of The List of Pending and Open Tasks. git-svn-id: svn://svn.berlios.de/openocd/trunk@1791 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-14 zwelch + + * : Several minor fixes for the new doxygen manual. git-svn-id: svn://svn.berlios.de/openocd/trunk@1789 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-14 oharboe + + * : use TAP_INVALID enum instead of -1 git-svn-id: svn://svn.berlios.de/openocd/trunk@1787 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-14 oharboe + + * : dump_image now works for addresses not divisible by 4 git-svn-id: svn://svn.berlios.de/openocd/trunk@1785 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-14 oharboe + + * : selftest wip git-svn-id: svn://svn.berlios.de/openocd/trunk@1783 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-13 zwelch + + * : Update configure script test for net/if.h to work on MacOS. git-svn-id: svn://svn.berlios.de/openocd/trunk@1781 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-13 zwelch + + * : Fix bootstrap script to support MacOS glibtoolize oddity. git-svn-id: svn://svn.berlios.de/openocd/trunk@1779 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-13 zwelch + + * : Add JTAG Primer to doxygen manual, contributed by Strontium. git-svn-id: svn://svn.berlios.de/openocd/trunk@1776 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-13 oharboe + + * : added verify_jtag command git-svn-id: svn://svn.berlios.de/openocd/trunk@1774 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-13 oharboe + + * : shuffled comments about for jtag_add_dr_out() fn. git-svn-id: svn://svn.berlios.de/openocd/trunk@1772 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-12 oharboe + + * : irscan now also works correctly in addition to not crashing :-) git-svn-id: svn://svn.berlios.de/openocd/trunk@1770 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-12 oharboe + + * : 4-bit ECC support for Marvell Kirkwood SOC git-svn-id: svn://svn.berlios.de/openocd/trunk@1768 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-12 oharboe + + * : move eCos type definition to types.h where it belongs. git-svn-id: svn://svn.berlios.de/openocd/trunk@1766 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-12 ntfreak + + * : - fix build issue when HAVE_ELF_H is not defined git-svn-id: svn://svn.berlios.de/openocd/trunk@1764 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-12 zwelch + + * : Include project doxygen configuration with distribution + tarballs. git-svn-id: svn://svn.berlios.de/openocd/trunk@1762 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-12 zwelch + + * : Make replacements.h private by including it from config.h + autoheader. git-svn-id: svn://svn.berlios.de/openocd/trunk@1760 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-12 zwelch + + * : Audit and reduce #include directives in jim source files. git-svn-id: svn://svn.berlios.de/openocd/trunk@1758 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-12 zwelch + + * : Remove config.h from types.h; all .c files are required to + include it. git-svn-id: svn://svn.berlios.de/openocd/trunk@1756 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-12 zwelch + + * : Update rlink_make_speed_table.pl script to add config.h to its + output. git-svn-id: svn://svn.berlios.de/openocd/trunk@1754 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-12 oharboe + + * : added jtag_alloc_in_value32 - not used in this commit. git-svn-id: svn://svn.berlios.de/openocd/trunk@1752 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-12 zwelch + + * : Include assert.h in system.h to promote tree-wide use of + assertions. git-svn-id: svn://svn.berlios.de/openocd/trunk@1750 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 oharboe + + * : now builds on 64 and 32 bit systems git-svn-id: svn://svn.berlios.de/openocd/trunk@1748 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Update jim helper files to use proper configure script support: - configure.in: Add AC_TYPE_LONG_LONG_INT to detect 'long long int' + support. - configure.in: Add AC_C_CONST to provide equivalent support as + jim.h. - jim*.c: include config.h when HAVE_CONFIG_H is defined. - jim*.{h,c}: use HAVE_LONG_LONG_INT definition from config.h. - jim.h: Remove hard-coded const and HAVE_LONG_LONG definitions. - jim.h: -DJIM_NO_CONST has been obsoleted; -Dconst is equivalent. git-svn-id: svn://svn.berlios.de/openocd/trunk@1744 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 oharboe + + * : USB performance regression fix git-svn-id: svn://svn.berlios.de/openocd/trunk@1742 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 oharboe + + * : switch to jtag_add_dr_scan() from the synchronous version - USB + performance fix git-svn-id: svn://svn.berlios.de/openocd/trunk@1740 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 oharboe + + * : switch to jtag_add_dr_scan_check() - USB performance fix git-svn-id: svn://svn.berlios.de/openocd/trunk@1738 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 oharboe + + * : change jtag_add_callback API to be able to support + check_value/mask git-svn-id: svn://svn.berlios.de/openocd/trunk@1735 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 oharboe + + * : switch to jtag_add_callback() - USB performance fix git-svn-id: svn://svn.berlios.de/openocd/trunk@1733 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 oharboe + + * : switch to jtag_add_callback() - USB performance fix git-svn-id: svn://svn.berlios.de/openocd/trunk@1731 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 oharboe + + * : switch to jtag_add_callback() - USB performance fix git-svn-id: svn://svn.berlios.de/openocd/trunk@1729 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 oharboe + + * : switch to jtag_add_callback() - USB performance fix git-svn-id: svn://svn.berlios.de/openocd/trunk@1727 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 oharboe + + * : switch to jtag_add_callback() - USB performance fix git-svn-id: svn://svn.berlios.de/openocd/trunk@1725 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 oharboe + + * : leave eCos include file issues alone for now. git-svn-id: svn://svn.berlios.de/openocd/trunk@1723 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 oharboe + + * : used by upcoming commits git-svn-id: svn://svn.berlios.de/openocd/trunk@1721 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Update Doxyfile configuration for doxygen 1.5.8: - Enable doxygen's C language optimizations. - Use dot command (from graphviz package) to generate visual graphs. git-svn-id: svn://svn.berlios.de/openocd/trunk@1719 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Remove redundant config.h from replacements.h, obtained from + types.h. git-svn-id: svn://svn.berlios.de/openocd/trunk@1717 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Audit and eliminate redundant #include directives in other + target files. git-svn-id: svn://svn.berlios.de/openocd/trunk@1715 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Audit and eliminate redundant #include directives in core target + files. git-svn-id: svn://svn.berlios.de/openocd/trunk@1713 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Audit and eliminate redundant #include directives in src/flash + headers. git-svn-id: svn://svn.berlios.de/openocd/trunk@1711 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Audit and eliminate redundant #include directives from + src/server. git-svn-id: svn://svn.berlios.de/openocd/trunk@1709 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Audit and eliminate redundant #include directives from src/jtag. git-svn-id: svn://svn.berlios.de/openocd/trunk@1707 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Simplify #include directives in ioutil.c, use new header checks. git-svn-id: svn://svn.berlios.de/openocd/trunk@1705 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Add --enable-malloc-logging configure option and update log.c to + match. git-svn-id: svn://svn.berlios.de/openocd/trunk@1703 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Finish portability support for AC_HEADER_STDBOOL configure + macro. git-svn-id: svn://svn.berlios.de/openocd/trunk@1701 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Add configure check for sys/types.h; include in our types.h. git-svn-id: svn://svn.berlios.de/openocd/trunk@1699 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-11 zwelch + + * : Use AC_HEADER_STDBOOL macro instead of + AC_CHEACK_HEADERS(stdbool.h). git-svn-id: svn://svn.berlios.de/openocd/trunk@1697 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-10 zwelch + + * : Extend autotools build to create shared library libopenocd with + libtool: - Add libtoolize step too bootstrap script; creates ltmain.sh + script. - Add AC_PROG_LIBTOOL to configure.in to add libtool support to + build. - Change Makefile.am library rules from static (_a) to libtool + (_la). - Install libopenocd.{la,so,a} in $(libdir); update openocd link + rules. - Extend MAINTAINERCLEANFILES in top-level Makefile.am to remove + ltmain.sh. git-svn-id: svn://svn.berlios.de/openocd/trunk@1695 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-10 zwelch + + * : Extend configure script to check for environ declaration in + stdlib.h. Patch contributed by Martin Thomas . git-svn-id: svn://svn.berlios.de/openocd/trunk@1693 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-10 zwelch + + * : Revive tclapi.c from r1650: * Remove superfluous #include directives. * Fix warnings and API usage to cure its bit rot. * Build into libhelper library (for now). Add tclapi.h to export + tclapi_register_commands(). Register tclapi commands in + openocd.c:setup_command_handler(). git-svn-id: svn://svn.berlios.de/openocd/trunk@1691 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-10 oharboe + + * : David Brownell whitespace fixes. Testing + out on one file first... git-svn-id: svn://svn.berlios.de/openocd/trunk@1689 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-10 oharboe + + * : Michael Bruck use more const git-svn-id: svn://svn.berlios.de/openocd/trunk@1687 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-09 oharboe + + * : Michael Bruck ARM11 C99 updates git-svn-id: svn://svn.berlios.de/openocd/trunk@1685 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 oharboe + + * : plugged bug w/irlen > 32 introduce in 1672 git-svn-id: svn://svn.berlios.de/openocd/trunk@1683 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 oharboe + + * : David Brownell DaVinci dm6446 git-svn-id: svn://svn.berlios.de/openocd/trunk@1680 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 oharboe + + * : Michael Fischer fix compile problems on + Mac git-svn-id: svn://svn.berlios.de/openocd/trunk@1678 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 oharboe + + * : stm32 profiling wip git-svn-id: svn://svn.berlios.de/openocd/trunk@1676 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 oharboe + + * : add flush_count jtag queue profiling feature git-svn-id: svn://svn.berlios.de/openocd/trunk@1674 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 oharboe + + * : in_handler in_check_mask and in_check_value now removed from + field. Last big patch in the series of JTAG API cleanup. git-svn-id: svn://svn.berlios.de/openocd/trunk@1672 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 oharboe + + * : use assert instead of adding code that always runs git-svn-id: svn://svn.berlios.de/openocd/trunk@1670 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 oharboe + + * : retire jtag_set_check_value git-svn-id: svn://svn.berlios.de/openocd/trunk@1668 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 oharboe + + * : retire jtag_set_check_value git-svn-id: svn://svn.berlios.de/openocd/trunk@1666 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 oharboe + + * : first jtag_check_value_mask usage. tested by using "arm7_9 + fast_memory_access enable" & "mdw 0 0x10" git-svn-id: svn://svn.berlios.de/openocd/trunk@1664 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 zwelch + + * : Fix typo from hurrying the last commit. Nothing to see here. git-svn-id: svn://svn.berlios.de/openocd/trunk@1662 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 zwelch + + * : Re-order and extend header file tests in configure script. git-svn-id: svn://svn.berlios.de/openocd/trunk@1660 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-08 zwelch + + * : Fix warnings in ioutil.c; improves loadFile inteface. git-svn-id: svn://svn.berlios.de/openocd/trunk@1658 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : ouch - typo in last commit git-svn-id: svn://svn.berlios.de/openocd/trunk@1656 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : in_handler removal typo fixed git-svn-id: svn://svn.berlios.de/openocd/trunk@1654 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : refactor to be able to remove more in_handler stuff git-svn-id: svn://svn.berlios.de/openocd/trunk@1652 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : fix c99 compile errors git-svn-id: svn://svn.berlios.de/openocd/trunk@1650 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : remove usage of in_handler git-svn-id: svn://svn.berlios.de/openocd/trunk@1648 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : remove in_handler usage git-svn-id: svn://svn.berlios.de/openocd/trunk@1646 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : remove in_handler usage git-svn-id: svn://svn.berlios.de/openocd/trunk@1644 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : remove in_handler usage git-svn-id: svn://svn.berlios.de/openocd/trunk@1642 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : remove in_handler usage git-svn-id: svn://svn.berlios.de/openocd/trunk@1640 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : jtag API error handling refactoring. git-svn-id: svn://svn.berlios.de/openocd/trunk@1638 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : remove in_handler usage git-svn-id: svn://svn.berlios.de/openocd/trunk@1636 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : fix line endings git-svn-id: svn://svn.berlios.de/openocd/trunk@1634 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : Deleted at9sam7_old driver. Nobody has complained about the new + one yet. git-svn-id: svn://svn.berlios.de/openocd/trunk@1632 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 oharboe + + * : another example of removing in_handler usage git-svn-id: svn://svn.berlios.de/openocd/trunk@1630 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 zwelch + + * : Fix most pointer cast alignment warnings in arm11.c; fix u16 + memory reads.. git-svn-id: svn://svn.berlios.de/openocd/trunk@1628 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-07 zwelch + + * : Fix stm32x and pic32mx flash pointer cast alignment warnings, + simplify their last word handling. git-svn-id: svn://svn.berlios.de/openocd/trunk@1626 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-06 zwelch + + * : Fix pointer cast alignment warnings in target/image.c. git-svn-id: svn://svn.berlios.de/openocd/trunk@1624 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-06 zwelch + + * : Fix pointer cast alignment issues in svf.c git-svn-id: svn://svn.berlios.de/openocd/trunk@1622 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-06 zwelch + + * : Fix pointer cast alignment warnings in jim.c. git-svn-id: svn://svn.berlios.de/openocd/trunk@1620 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-06 oharboe + + * : Dick Hollenbeck comments & 7 clock TMS reset + for good measure git-svn-id: svn://svn.berlios.de/openocd/trunk@1618 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-06 mlu + + * : Small changes that might improve stability. Implemented new + jtag sequences tap_get_tms_path and tap_get_tms_path_len git-svn-id: svn://svn.berlios.de/openocd/trunk@1616 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-06 oharboe + + * : Dick Hollenbeck simplifies XSTATE handling, + and protects against illegal state transitions that might be in an + SVF file. git-svn-id: svn://svn.berlios.de/openocd/trunk@1614 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-06 zwelch + + * : Fix enviorn configure test failure message (thanks to Anders + Montonen). git-svn-id: svn://svn.berlios.de/openocd/trunk@1612 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-06 zwelch + + * : Add autoconf check to determine where environ should be + declared. git-svn-id: svn://svn.berlios.de/openocd/trunk@1610 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-06 oharboe + + * : retire out_mask - not used anywhere git-svn-id: svn://svn.berlios.de/openocd/trunk@1608 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-05 oharboe + + * : made warning about keep_alive() not being invoked more helpful git-svn-id: svn://svn.berlios.de/openocd/trunk@1606 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-05 oharboe + + * : Gabor Juhos juhosg at openwrt.org MIPS: fix a shift value in + the MIPS32_R_INST macro git-svn-id: svn://svn.berlios.de/openocd/trunk@1604 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-04 oharboe + + * : Dirk Behme Add minimalist Cortex A8 + file git-svn-id: svn://svn.berlios.de/openocd/trunk@1602 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-04 oharboe + + * : Mariano Alvira fixes warning as error about a + signed vs. unsigned comparison by casting the local unsigned + variable as (long long). git-svn-id: svn://svn.berlios.de/openocd/trunk@1600 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-03 oharboe + + * : fix embedded builds git-svn-id: svn://svn.berlios.de/openocd/trunk@1598 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-03 zwelch + + * : Fix compilation when HAVE_UNISTD_H is not defined. git-svn-id: svn://svn.berlios.de/openocd/trunk@1596 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-03 oharboe + + * : Piotr Esden-Tempski Mac OS X compile fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@1594 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-02 zwelch + + * : Add configure check for usb.h; required by a USB drivers. git-svn-id: svn://svn.berlios.de/openocd/trunk@1592 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-02 oharboe + + * : Dick Hollenbeck moved stuff into openocd.c - + should never have been in main.c in the first place. DLL will now + build. git-svn-id: svn://svn.berlios.de/openocd/trunk@1590 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-01 zwelch + + * : Remove superflous spaces from new JTAG table to fix formatting. git-svn-id: svn://svn.berlios.de/openocd/trunk@1588 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-05-01 zwelch + + * : Dick Hollenbeck : move OPENOCD_VERSION to use + config.h git-svn-id: svn://svn.berlios.de/openocd/trunk@1586 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-30 zwelch + + * : Uwe Hermann : Make ICEbear look like other + targets git-svn-id: svn://svn.berlios.de/openocd/trunk@1584 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-30 oharboe + + * : list board's as well as target config files. git-svn-id: svn://svn.berlios.de/openocd/trunk@1581 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-30 zwelch + + * : Add static keywords to core target source file data and + functions. git-svn-id: svn://svn.berlios.de/openocd/trunk@1579 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-30 zwelch + + * : Fix signed/unsigned comparison. git-svn-id: svn://svn.berlios.de/openocd/trunk@1577 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-30 oharboe + + * : flash fillX now has a verify stage git-svn-id: svn://svn.berlios.de/openocd/trunk@1575 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-30 zwelch + + * : Michael Bruck : sys/select.h must preceed + windows.h. git-svn-id: svn://svn.berlios.de/openocd/trunk@1573 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-29 mlu + + * : Clear FLASH_SR error flags after flash errors to avoid reset + befor further flash operations. git-svn-id: svn://svn.berlios.de/openocd/trunk@1571 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-29 mlu + + * : More error logging for DAP errors git-svn-id: svn://svn.berlios.de/openocd/trunk@1569 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-29 oharboe + + * : comments and debug code git-svn-id: svn://svn.berlios.de/openocd/trunk@1567 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-29 zwelch + + * : Sten : add support for ICEbear + FDTI-based interface. git-svn-id: svn://svn.berlios.de/openocd/trunk@1565 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-29 zwelch + + * : Remove vestigial last_tms variable from jlink driver. git-svn-id: svn://svn.berlios.de/openocd/trunk@1563 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-29 zwelch + + * : Fix jlink for Debian/Ubuntu (by Ben Dooks + ). git-svn-id: svn://svn.berlios.de/openocd/trunk@1561 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-29 zwelch + + * : Add missing header files to fix C99 compatibility. git-svn-id: svn://svn.berlios.de/openocd/trunk@1559 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-28 oharboe + + * : Dick Hollenbeck and Jeff Williams + tap_get_tms_path_len() git-svn-id: svn://svn.berlios.de/openocd/trunk@1557 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-28 ntfreak + + * : - fix win32 build git-svn-id: svn://svn.berlios.de/openocd/trunk@1555 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-28 oharboe + + * : Zach Welch fix gw16012 with + --enable-parport_ppdev git-svn-id: svn://svn.berlios.de/openocd/trunk@1553 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-28 oharboe + + * : Michael Bruck macros for error handling git-svn-id: svn://svn.berlios.de/openocd/trunk@1551 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-28 oharboe + + * : eol-style native git-svn-id: svn://svn.berlios.de/openocd/trunk@1549 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-27 mlu + + * : Added dap baseaddr and dap apid commands git-svn-id: svn://svn.berlios.de/openocd/trunk@1547 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-27 oharboe + + * : SimonQian patch for error compiling + vsllink if --enable-verbose-jtag-io is set git-svn-id: svn://svn.berlios.de/openocd/trunk@1545 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-27 oharboe + + * : more error handling git-svn-id: svn://svn.berlios.de/openocd/trunk@1543 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-27 oharboe + + * : SimonQian AVR wip git-svn-id: svn://svn.berlios.de/openocd/trunk@1540 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-27 mlu + + * : Deleted depreciated files ( new versions are arm_adi_v5.c/h ) git-svn-id: svn://svn.berlios.de/openocd/trunk@1538 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-27 mlu + + * : Changed armv7m and cortexm3 to use nev arm_adi_v5 instead of + cortex_swjdp. Added support for accessport ROM table + identification, dap command. git-svn-id: svn://svn.berlios.de/openocd/trunk@1536 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-27 oharboe + + * : Philippe Vachon 64 bit host fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@1534 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-27 oharboe + + * : Zach Welch wrap _GNU_SOURCE defines git-svn-id: svn://svn.berlios.de/openocd/trunk@1532 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-26 oharboe + + * : R.Doss AT91SAM9260 git-svn-id: svn://svn.berlios.de/openocd/trunk@1530 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-25 mlu + + * : Corrected statement order git-svn-id: svn://svn.berlios.de/openocd/trunk@1528 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-25 mlu + + * : Break ft2232_execute_quie into smaller functions, follows + restructure of jlink.c git-svn-id: svn://svn.berlios.de/openocd/trunk@1526 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-24 oharboe + + * : Zach Welch add TAP_SCAN_BYTES macro (1 of + 2) git-svn-id: svn://svn.berlios.de/openocd/trunk@1524 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-24 oharboe + + * : Uwe Hermann Update udev file git-svn-id: svn://svn.berlios.de/openocd/trunk@1522 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-24 oharboe + + * : Nicolas Pitre update SheevaPlug interface cfg + file git-svn-id: svn://svn.berlios.de/openocd/trunk@1520 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-24 duane + + * : Remove warning git-svn-id: svn://svn.berlios.de/openocd/trunk@1518 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-23 oharboe + + * : stm32.cfg can expect one of 4 id's. git-svn-id: svn://svn.berlios.de/openocd/trunk@1516 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-23 oharboe + + * : Laurentiu Cocanu - fix typo git-svn-id: svn://svn.berlios.de/openocd/trunk@1514 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-22 oharboe + + * : Michael Bruck ARM11 various updates + fix + formatting. git-svn-id: svn://svn.berlios.de/openocd/trunk@1512 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-22 oharboe + + * : Michael Bruck spotted a typo in help messages git-svn-id: svn://svn.berlios.de/openocd/trunk@1510 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-22 oharboe + + * : Zach Welch set speed in init git-svn-id: svn://svn.berlios.de/openocd/trunk@1508 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-22 oharboe + + * : Zach Welch reorder enum tap_state git-svn-id: svn://svn.berlios.de/openocd/trunk@1506 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-22 kc8apf + + * : Shrink JLink buffer sizes to specified 2KB courtesy of Jeff + Williams and Zach Welch + git-svn-id: svn://svn.berlios.de/openocd/trunk@1504 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-22 kc8apf + + * : Fix use of wrong format conversion for size_t (%zu instead of + %u) git-svn-id: svn://svn.berlios.de/openocd/trunk@1502 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-22 kc8apf + + * : refactor jlink_execute_queue courtesy of Zach Welch + git-svn-id: svn://svn.berlios.de/openocd/trunk@1500 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-21 oharboe + + * : Zach Welch refactor git-svn-id: svn://svn.berlios.de/openocd/trunk@1498 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-21 oharboe + + * : Zach Welch add --enable-verbose* options git-svn-id: svn://svn.berlios.de/openocd/trunk@1496 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-21 oharboe + + * : Nico Coesel MIPS32 speedup patches git-svn-id: svn://svn.berlios.de/openocd/trunk@1494 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-21 oharboe + + * : Zach Welch factor jlink usb_bulk_*_ex + functions git-svn-id: svn://svn.berlios.de/openocd/trunk@1492 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-21 oharboe + + * : Zach Welch improve Linux ftd2xx + configure-time support git-svn-id: svn://svn.berlios.de/openocd/trunk@1490 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-21 ntfreak + + * : - remove environ warning under win32 build git-svn-id: svn://svn.berlios.de/openocd/trunk@1488 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-21 oharboe + + * : Zach Welch fix unused return value + warnings (2 of 4) git-svn-id: svn://svn.berlios.de/openocd/trunk@1486 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-21 oharboe + + * : Zach Welch fix str9x type-punned pointer git-svn-id: svn://svn.berlios.de/openocd/trunk@1484 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-21 oharboe + + * : Zach Welch fix unused return value + warnings (3 of 4) git-svn-id: svn://svn.berlios.de/openocd/trunk@1482 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-21 oharboe + + * : Michael Schwingen add non-CFI + SST flashs git-svn-id: svn://svn.berlios.de/openocd/trunk@1480 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-20 ntfreak + + * : - fix at91rm9200 warning. Thanks Zach Welch - add missing svn props from previous commit git-svn-id: svn://svn.berlios.de/openocd/trunk@1478 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-20 oharboe + + * : Zach Welch fix ft2232/presto warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@1476 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-19 oharboe + + * : Zach Welch use ARM4_5_MODE_ANY instead of + -1 git-svn-id: svn://svn.berlios.de/openocd/trunk@1474 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-19 oharboe + + * : Zach Welch fix -Werror warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@1472 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-19 mifi + + * : Added functionality to support jtag_khz for the jlink. git-svn-id: svn://svn.berlios.de/openocd/trunk@1470 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-19 oharboe + + * : Zach Welch add missing initializers in + nand.c git-svn-id: svn://svn.berlios.de/openocd/trunk@1468 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-19 oharboe + + * : Zach Welch fix signed/unsigned + comparisons git-svn-id: svn://svn.berlios.de/openocd/trunk@1466 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-19 oharboe + + * : Zach Welch use tap_state_t git-svn-id: svn://svn.berlios.de/openocd/trunk@1464 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-18 mifi + + * : The following patches was applied: - openocd-flash-static-keyword-v3.patch - openocd-lpc2000-fix-erase-obo.patch - openocd-jlink-fix-sign-ptr-warn.patch - openocd-wextra-etm.patch - openocd-wextra-jtag.patch - openocd-add-new-tap-symbols-v6.patch Many thanks to Zach Welch git-svn-id: svn://svn.berlios.de/openocd/trunk@1462 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-15 oharboe + + * : Piotr Esden-Tempski Corrected + olimex_stm32_h103 board config git-svn-id: svn://svn.berlios.de/openocd/trunk@1460 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-15 oharboe + + * : Freddie Chopin LPC2378 config file git-svn-id: svn://svn.berlios.de/openocd/trunk@1458 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-14 mlu + + * : Improved (for humans) error reporting for flash programming + errors. git-svn-id: svn://svn.berlios.de/openocd/trunk@1456 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-03 ntfreak + + * : - add openocd coding style to texi git-svn-id: svn://svn.berlios.de/openocd/trunk@1454 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-03 ntfreak + + * : - add svn props from previous commit git-svn-id: svn://svn.berlios.de/openocd/trunk@1452 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-03 oharboe + + * : Piotr Esden-Tempski added a board file for the + Olimex STM32-H103 eval board. git-svn-id: svn://svn.berlios.de/openocd/trunk@1450 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-03 oharboe + + * : Nicolas Pitre nico at cam.org list the new flag in the "nand + write" help line. git-svn-id: svn://svn.berlios.de/openocd/trunk@1448 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-02 oharboe + + * : Nicolas Pitre nico at cam.org The ECC data is automatically + computed and written to the OOB area when the oob_softecc option is + passed to the "nand write" command. git-svn-id: svn://svn.berlios.de/openocd/trunk@1446 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-02 oharboe + + * : Nicolas Pitre nico at cam.org software ECC computation for NAND + flash git-svn-id: svn://svn.berlios.de/openocd/trunk@1444 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-02 oharboe + + * : Nicolas Pitre nico at cam.org Allocating a 6-byte memory + location with malloc() is rather silly when this can be allocated on + the stack. git-svn-id: svn://svn.berlios.de/openocd/trunk@1442 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-02 oharboe + + * : Uwe Hermann URL references git-svn-id: svn://svn.berlios.de/openocd/trunk@1439 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-04-02 oharboe + + * : fix keyword expansion git-svn-id: svn://svn.berlios.de/openocd/trunk@1437 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-30 ntfreak + + * : - add missing usbprog config. patch from Uwe Hermann + + https://lists.berlios.de/pipermail/openocd-development/2009-March/005145.htmlgit-svn-id: svn://svn.berlios.de/openocd/trunk@1435 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-24 ntfreak + + * : - fix typo's in last commit git-svn-id: svn://svn.berlios.de/openocd/trunk@1433 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-24 ntfreak + + * : - update str9 and stm32 comstick configs - add missing svn props git-svn-id: svn://svn.berlios.de/openocd/trunk@1431 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-24 oharboe + + * : Uwe Hermann Add new board configs: Olimex + LPC-H2148, Keil MCB2140. Both boards use an LPC2148, no external + flash or RAM. git-svn-id: svn://svn.berlios.de/openocd/trunk@1429 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-23 oharboe + + * : Uwe Hermann eal _CPUTAPID entry for the + LPC2148. I don't know if they're the same for all LPC214x, this + number is from an Olimex LPC-H2148. The chip on that board is + LPC2148FBD64. Also fix a few cosmetic issues and comments in the file and add more + docs and pointers to the datasheet. git-svn-id: svn://svn.berlios.de/openocd/trunk@1427 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-23 oharboe + + * : Uwe Hermann typo git-svn-id: svn://svn.berlios.de/openocd/trunk@1425 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-20 ntfreak + + * : - add missing svn props from previous commit git-svn-id: svn://svn.berlios.de/openocd/trunk@1423 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-20 oharboe + + * : Alan Carvalho de Assis adds support to + i.MX35 processor. git-svn-id: svn://svn.berlios.de/openocd/trunk@1421 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-19 ntfreak + + * : - fix incorrect str9comstick cfg git-svn-id: svn://svn.berlios.de/openocd/trunk@1419 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-18 oharboe + + * : Hiroshi Ito typos git-svn-id: svn://svn.berlios.de/openocd/trunk@1417 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-17 ntfreak + + * : - remove build warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@1415 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-16 ntfreak + + * : - fix issue with cortex_m3 reset run. Thanks Perry Hung - + + https://lists.berlios.de/pipermail/openocd-development/2009-March/005028.htmlgit-svn-id: svn://svn.berlios.de/openocd/trunk@1413 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-12 oharboe + + * : Uwe Hermann typos git-svn-id: svn://svn.berlios.de/openocd/trunk@1411 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-11 duane + + * : Added eol-style props git-svn-id: svn://svn.berlios.de/openocd/trunk@1409 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-11 duane + + * : Added -endstate to irscan and drscan to support beagleboard + (omap3530) git-svn-id: svn://svn.berlios.de/openocd/trunk@1407 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-08 ntfreak + + * : - add svn props from previous commit git-svn-id: svn://svn.berlios.de/openocd/trunk@1405 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-08 duane + + * : Added VID/PID pair to olimex-jtag-tiny-a the non-a version + already has the vid pid git-svn-id: svn://svn.berlios.de/openocd/trunk@1403 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-07 duane + + * : Accept/create both A and Non-A ft2232 based descriptions git-svn-id: svn://svn.berlios.de/openocd/trunk@1401 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-05 oharboe + + * : Audrius Urmanavičius cleanup flash + fill git-svn-id: svn://svn.berlios.de/openocd/trunk@1399 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-04 oharboe + + * : Nicolas Pitre making reset+halt on the SheevaPlug + 100% reliable (needs patch in target.c to fix "halt 0"). git-svn-id: svn://svn.berlios.de/openocd/trunk@1397 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-02 ntfreak + + * : - add missing svn props from previous commit git-svn-id: svn://svn.berlios.de/openocd/trunk@1395 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-01 oharboe + + * : Kees Jongenburger rename + description field of the jtag-tiny.cfg git-svn-id: svn://svn.berlios.de/openocd/trunk@1393 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-01 oharboe + + * : Nicolas Pitre nico at cam.org SheevaPlug board configuration git-svn-id: svn://svn.berlios.de/openocd/trunk@1391 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-01 oharboe + + * : Nicolas Pitre nico at cam.org add Feroceon target config file git-svn-id: svn://svn.berlios.de/openocd/trunk@1389 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-01 oharboe + + * : Nicolas Pitre nico at cam.org support for NAND controllers + without explicit busy signal git-svn-id: svn://svn.berlios.de/openocd/trunk@1387 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-03-01 oharboe + + * : Nicolas Pitre nico at cam.org The code unconditionally writes + into the oob area all the time. git-svn-id: svn://svn.berlios.de/openocd/trunk@1385 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-02-26 ntfreak + + * : - stm32x flash driver - add support for stm32105/107 (connectivity + line) git-svn-id: svn://svn.berlios.de/openocd/trunk@1383 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-02-23 oharboe + + * : tinkered a bit with performance for Cortex flash programming. + Mainly make it easier to profile as a start. git-svn-id: svn://svn.berlios.de/openocd/trunk@1380 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-02-22 oharboe + + * : John Woods fix newtap gaffe + rename git-svn-id: svn://svn.berlios.de/openocd/trunk@1378 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-02-18 oharboe + + * : Holger Schurig incorporate some + comments from Rick git-svn-id: svn://svn.berlios.de/openocd/trunk@1376 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-02-17 oharboe + + * : zy1000 1.49 snapshot git-svn-id: svn://svn.berlios.de/openocd/trunk@1374 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-02-13 ntfreak + + * : - guess-rev.sh now works as expected when build_dir is not the same + as src_dir git-svn-id: svn://svn.berlios.de/openocd/trunk@1372 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-02-10 kc8apf + + * : Use C89/C99/C++ compliant boolean types git-svn-id: svn://svn.berlios.de/openocd/trunk@1370 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-02-09 ntfreak + + * : - fix native win32 build issues git-svn-id: svn://svn.berlios.de/openocd/trunk@1368 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-02-03 kc8apf + + * : - Cable driver helper API courtesy of Dick Hollenbeck + - Formatting changes from uncrustify git-svn-id: svn://svn.berlios.de/openocd/trunk@1366 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-02-03 kc8apf + + * : Add uncrustify config file and helper script git-svn-id: svn://svn.berlios.de/openocd/trunk@1364 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-26 oharboe + + * : update symbols to match source file git-svn-id: svn://svn.berlios.de/openocd/trunk@1362 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-23 kc8apf + + * : xvsf player fixes by Dick Hollenbeck git-svn-id: svn://svn.berlios.de/openocd/trunk@1360 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-23 kc8apf + + * : Search path fixes for MinGW builds. Courtesy of Dimitar + Dimitrov git-svn-id: svn://svn.berlios.de/openocd/trunk@1358 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-23 kc8apf + + * : vsllink support for stable clocks by Simon Qian + git-svn-id: svn://svn.berlios.de/openocd/trunk@1356 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-20 kc8apf + + * : Fix for incorrect filename in include for at91sam9260 in + unknown-board-atmel-at91sam9260.cfg git-svn-id: svn://svn.berlios.de/openocd/trunk@1353 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-20 ntfreak + + * : - add --enable-release to docs git-svn-id: svn://svn.berlios.de/openocd/trunk@1351 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-20 kc8apf + + * : Add axm0432 interface config courtesy of Alan Carvalho de Assis + git-svn-id: svn://svn.berlios.de/openocd/trunk@1349 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-20 kc8apf + + * : Fix 'make maintainer-clean' courtesy of Zach Welch + git-svn-id: svn://svn.berlios.de/openocd/trunk@1345 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-20 kc8apf + + * : Fix support for ADuC702x flash. Courtesy of Michael Ashton + git-svn-id: svn://svn.berlios.de/openocd/trunk@1343 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-19 ntfreak + + * : - remove unused includes, fixes build issues under FreeBSD git-svn-id: svn://svn.berlios.de/openocd/trunk@1341 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-19 kc8apf + + * : SVF player courtesy of Simon Qian git-svn-id: svn://svn.berlios.de/openocd/trunk@1339 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-17 kc8apf + + * : Fix guess-rev.sh where the builtin echo doesn't support -n git-svn-id: svn://svn.berlios.de/openocd/trunk@1337 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-16 ntfreak + + * : - make guess-rev.sh work with msys git-svn-id: svn://svn.berlios.de/openocd/trunk@1333 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-16 ntfreak + + * : - add missing bitq and rlink files to distribution git-svn-id: svn://svn.berlios.de/openocd/trunk@1331 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-15 ntfreak + + * : - add missing svn props from 1323 commit git-svn-id: svn://svn.berlios.de/openocd/trunk@1324 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-15 oharboe + + * : Alan Carvalho de Assis imx31pdk.cfg reset + init event git-svn-id: svn://svn.berlios.de/openocd/trunk@1322 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-14 oharboe + + * : wip git-svn-id: svn://svn.berlios.de/openocd/trunk@1320 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-14 oharboe + + * : Alan Carvalho de Assis cfg file to + initialize the iMX27ADS board. git-svn-id: svn://svn.berlios.de/openocd/trunk@1318 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-14 oharboe + + * : Alan Carvalho de Assis small fix to move us + in the right direction. git-svn-id: svn://svn.berlios.de/openocd/trunk@1316 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-13 ntfreak + + * : - fix mips issues with newer versions of gdb - we simply add more dummy registers git-svn-id: svn://svn.berlios.de/openocd/trunk@1314 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-09 oharboe + + * : wip git-svn-id: svn://svn.berlios.de/openocd/trunk@1312 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-09 oharboe + + * : allow issuing reset_config on the fly. Faster turnaround times + in testing. git-svn-id: svn://svn.berlios.de/openocd/trunk@1310 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-09 oharboe + + * : Dick Hollenbeck adds jtag_add_clocks() and + implements those in the bitbang and ft2232.c. nearly a full + rewrite of the xsvf.c. improved some messaging only affected by + _DEBUG_JTAG_IO_ git-svn-id: svn://svn.berlios.de/openocd/trunk@1308 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-08 ntfreak + + * : - a few more docs tweaks git-svn-id: svn://svn.berlios.de/openocd/trunk@1306 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-07 oharboe + + * : Dick Hollenbeck SVF to XSVF converter and + the XSVF dumper take #2 git-svn-id: svn://svn.berlios.de/openocd/trunk@1304 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-05 ntfreak + + * : - add missing svn props from r1299 commit git-svn-id: svn://svn.berlios.de/openocd/trunk@1302 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-05 oharboe + + * : John McCarthy formatting fix of debug output git-svn-id: svn://svn.berlios.de/openocd/trunk@1300 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-04 oharboe + + * : eol-style native git-svn-id: svn://svn.berlios.de/openocd/trunk@1298 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-02 oharboe + + * : John McCarthy pic32mx flash wip git-svn-id: svn://svn.berlios.de/openocd/trunk@1296 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2009-01-01 ntfreak + + * : - add gdb pipe support to native win32 (--pipe option) git-svn-id: svn://svn.berlios.de/openocd/trunk@1294 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-28 ntfreak + + * : - fix missing/incorrect svn file props git-svn-id: svn://svn.berlios.de/openocd/trunk@1292 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-27 duane + + * : Added another test build configuration git-svn-id: svn://svn.berlios.de/openocd/trunk@1290 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-27 duane + + * : Missed the svn add on earlier commit, duh git-svn-id: svn://svn.berlios.de/openocd/trunk@1288 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-27 duane + + * : Added note to user manual for packagers of OpenOCD git-svn-id: svn://svn.berlios.de/openocd/trunk@1286 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-27 duane + + * : Some systems report linux as host, others linux-gnu... grrr git-svn-id: svn://svn.berlios.de/openocd/trunk@1284 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-27 duane + + * : From Lou.openocd012@fixit.nospammail.net git-svn-id: svn://svn.berlios.de/openocd/trunk@1282 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-27 duane + + * : Added dongle VSLLINK - from Simon Qian git-svn-id: svn://svn.berlios.de/openocd/trunk@1280 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-27 duane + + * : From Dirk Behme - Further docu fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@1278 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-27 duane + + * : Renamed build.tests to build.test1 git-svn-id: svn://svn.berlios.de/openocd/trunk@1276 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-24 duane + + * : Typos found by miceal catudal git-svn-id: svn://svn.berlios.de/openocd/trunk@1274 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-23 oharboe + + * : httpd wip git-svn-id: svn://svn.berlios.de/openocd/trunk@1272 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-22 oharboe + + * : httpd wip git-svn-id: svn://svn.berlios.de/openocd/trunk@1269 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-22 oharboe + + * : Dirk Behme Add missing tap-enable and tap-disable events to documentation. git-svn-id: svn://svn.berlios.de/openocd/trunk@1267 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-22 oharboe + + * : bumped a LOG_INFO to LOG_DEBUG level to reduce excessive output + for normal execution git-svn-id: svn://svn.berlios.de/openocd/trunk@1265 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-19 oharboe + + * : Dick Hollenbeck - This patch adds JTAG state + tracking to dummy.c git-svn-id: svn://svn.berlios.de/openocd/trunk@1263 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-19 oharboe + + * : Dick Hollenbeck better comments git-svn-id: svn://svn.berlios.de/openocd/trunk@1261 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-19 oharboe + + * : Dick Hollenbeck convert macros to inline + fn's. git-svn-id: svn://svn.berlios.de/openocd/trunk@1259 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-17 oharboe + + * : check syntax for init/version git-svn-id: svn://svn.berlios.de/openocd/trunk@1257 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-17 oharboe + + * : houskeeping git-svn-id: svn://svn.berlios.de/openocd/trunk@1255 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-16 oharboe + + * : work in progress to hook up libmicrohttpd + tcl integration git-svn-id: svn://svn.berlios.de/openocd/trunk@1251 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-16 oharboe + + * : Dirk Behme Fix some typos in + documentation git-svn-id: svn://svn.berlios.de/openocd/trunk@1249 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-16 oharboe + + * : allow setting/reading gdb_port at any time git-svn-id: svn://svn.berlios.de/openocd/trunk@1247 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-15 ntfreak + + * : - add missing svn props from r1243 commit git-svn-id: svn://svn.berlios.de/openocd/trunk@1245 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-15 oharboe + + * : sync up to tap_xxx rename + add with-ioutil for standalone + openocd implemetnations git-svn-id: svn://svn.berlios.de/openocd/trunk@1243 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-15 oharboe + + * : fast_load profiling tool moved to target.c git-svn-id: svn://svn.berlios.de/openocd/trunk@1241 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-13 duane + + * : Updates and fixes from Kees Jongenburger git-svn-id: svn://svn.berlios.de/openocd/trunk@1239 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-13 kc8apf + + * : Add JTAG tap events for enable/disable git-svn-id: svn://svn.berlios.de/openocd/trunk@1237 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-13 kc8apf + + * : Change tap_state naming to be consistent with SVF documentation. Courtesy of Dick Hollenbeck git-svn-id: svn://svn.berlios.de/openocd/trunk@1232 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-12 kc8apf + + * : Allow -expected-id to be specified multiple times when creating + a jtag tap git-svn-id: svn://svn.berlios.de/openocd/trunk@1229 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-11 ntfreak + + * : - added Axiom AXM-0432 to texi - updated missing jtag dongle url's in texi - reformat and remove whitespace from last commit git-svn-id: svn://svn.berlios.de/openocd/trunk@1227 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-11 ntfreak + + * : - typo with flash bank help command - typo with flash erase_sector in texi git-svn-id: svn://svn.berlios.de/openocd/trunk@1225 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-10 duane + + * : More fixes thanks to Kees Jongenburger git-svn-id: svn://svn.berlios.de/openocd/trunk@1223 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-10 duane + + * : Fix from Kees Jongenburger git-svn-id: svn://svn.berlios.de/openocd/trunk@1221 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-06 duane + + * : Test of commit email from duane git-svn-id: svn://svn.berlios.de/openocd/trunk@1219 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-05 oharboe + + * : Karl Beldan - The ibcr count for hw + instruction breakpoint registers was decremented with soft + breakpoints and breakpoint length error. git-svn-id: svn://svn.berlios.de/openocd/trunk@1215 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-04 oharboe + + * : zy1000 1.48 snapshot git-svn-id: svn://svn.berlios.de/openocd/trunk@1213 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-04 oharboe + + * : delete obsolete code git-svn-id: svn://svn.berlios.de/openocd/trunk@1211 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-04 duane + + * : Fix for Hiroshi Ito discovery of mis-aligned memory allocation git-svn-id: svn://svn.berlios.de/openocd/trunk@1205 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-03 ntfreak + + * : - incorrect str9 irmask used in config files git-svn-id: svn://svn.berlios.de/openocd/trunk@1203 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-02 oharboe + + * : Kees Jongenburger - now compiles git-svn-id: svn://svn.berlios.de/openocd/trunk@1201 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-01 oharboe + + * : "Theodore A. Roth" fixes to distcheck git-svn-id: svn://svn.berlios.de/openocd/trunk@1199 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-01 oharboe + + * : update zy1000 to svn head jtag api git-svn-id: svn://svn.berlios.de/openocd/trunk@1197 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-12-01 oharboe + + * : wip git-svn-id: svn://svn.berlios.de/openocd/trunk@1195 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-30 duane + + * : Test checkin from commandline git-svn-id: svn://svn.berlios.de/openocd/trunk@1193 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-27 ntfreak + + * : - fix issue with luminary flash driver and tail bytes git-svn-id: svn://svn.berlios.de/openocd/trunk@1191 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-27 ntfreak + + * : - stm32x flash driver: add support for low density devices git-svn-id: svn://svn.berlios.de/openocd/trunk@1189 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-26 ntfreak + + * : - fixes segfault using the targets cmd if multiple targets defined git-svn-id: svn://svn.berlios.de/openocd/trunk@1187 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-26 oharboe + + * : friendlier error messages git-svn-id: svn://svn.berlios.de/openocd/trunk@1185 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-21 ntfreak + + * : - add new cortex_m3 maskisr cmd git-svn-id: svn://svn.berlios.de/openocd/trunk@1181 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-20 ntfreak + + * : - preserve cortex_m3 C_MASKINTS during resume/step git-svn-id: svn://svn.berlios.de/openocd/trunk@1179 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-19 oharboe + + * : jtag_get_device() now returns NULL and reports error instead of + invoking exit() git-svn-id: svn://svn.berlios.de/openocd/trunk@1176 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-18 oharboe + + * : big endian fix for GDB. Probably fixes a memory corruption(not + reported) as well. git-svn-id: svn://svn.berlios.de/openocd/trunk@1174 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-14 ntfreak + + * : - stops multiple calls to examine from allocating the breakpoint + arrays git-svn-id: svn://svn.berlios.de/openocd/trunk@1171 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-13 oharboe + + * : big endian software breakpoint bogus error messages fixed git-svn-id: svn://svn.berlios.de/openocd/trunk@1167 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-13 oharboe + + * : nios wip git-svn-id: svn://svn.berlios.de/openocd/trunk@1165 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-12 ntfreak + + * : - slight mips32 cleanup/reformat - add missing svn props git-svn-id: svn://svn.berlios.de/openocd/trunk@1159 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-11 oharboe + + * : Fixes (more or less) random SEGFAULT upon invoking + script_command(). git-svn-id: svn://svn.berlios.de/openocd/trunk@1156 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-10 oharboe + + * : broadcast mac address in UDP hello message git-svn-id: svn://svn.berlios.de/openocd/trunk@1152 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-10 oharboe + + * : minor cleanup git-svn-id: svn://svn.berlios.de/openocd/trunk@1149 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-07 oharboe + + * : ocd_flash_banks now returns empty list when no flash banks are + configured instead of failing. Allows more orthogonal + implementations of tcl code. git-svn-id: svn://svn.berlios.de/openocd/trunk@1147 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-07 oharboe + + * : ocd_flash_banks now returns empty list when no flash banks are + configured instead of failing. Allows more orthogonal + implementations of tcl code. git-svn-id: svn://svn.berlios.de/openocd/trunk@1144 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-06 ntfreak + + * : - remove build warnings - added svn props for newly added files git-svn-id: svn://svn.berlios.de/openocd/trunk@1142 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-06 oharboe + + * : s3c6410 chip git-svn-id: svn://svn.berlios.de/openocd/trunk@1140 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-05 oharboe + + * : 926ejs target uses rclk. Cleaned up jtag_khz output a bit. git-svn-id: svn://svn.berlios.de/openocd/trunk@1138 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-05 oharboe + + * : wip git-svn-id: svn://svn.berlios.de/openocd/trunk@1136 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-05 oharboe + + * : disable continous polling while srst is asserted and power + dropout is detected git-svn-id: svn://svn.berlios.de/openocd/trunk@1134 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-04 oharboe + + * : arm7_9_execute_sys_speed error propagation. Found by code + inspection, no observed problems as such. git-svn-id: svn://svn.berlios.de/openocd/trunk@1132 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-04 oharboe + + * : Added Tcl escaping to FAQ git-svn-id: svn://svn.berlios.de/openocd/trunk@1130 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-03 ntfreak + + * : - fix issue with jlink/libusb timeout under linux - add missing svn props git-svn-id: svn://svn.berlios.de/openocd/trunk@1128 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-03 oharboe + + * : Rick Altherr - fix warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@1126 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-02 oharboe + + * : invoke target_create() once git-svn-id: svn://svn.berlios.de/openocd/trunk@1124 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-02 oharboe + + * : Alan Carvalho de Assis imx27 config file git-svn-id: svn://svn.berlios.de/openocd/trunk@1122 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-02 oharboe + + * : Rick Altherr - fix flash write_bank output. git-svn-id: svn://svn.berlios.de/openocd/trunk@1120 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-11-02 oharboe + + * : no longer used git-svn-id: svn://svn.berlios.de/openocd/trunk@1118 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-31 oharboe + + * : Rick Altherr switch to new syntax for target + events git-svn-id: svn://svn.berlios.de/openocd/trunk@1116 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-30 oharboe + + * : Hongtao Zheng single step fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@1113 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-28 oharboe + + * : Kees Jongenburger update syntax git-svn-id: svn://svn.berlios.de/openocd/trunk@1111 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-28 oharboe + + * : Hongtao Zheng - fix a simulation error for "BX PC" git-svn-id: svn://svn.berlios.de/openocd/trunk@1109 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-27 oharboe + + * : Kees Jongenburger old" syntax + target command appears to be broken this patch addresses this issue git-svn-id: svn://svn.berlios.de/openocd/trunk@1107 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-27 oharboe + + * : Hongtao Zheng - add simulation because previous functions could + not halt for instructions that next pc equal to the current pc. git-svn-id: svn://svn.berlios.de/openocd/trunk@1105 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-27 oharboe + + * : added option to use ramdisk instead of flash jffs2 git-svn-id: svn://svn.berlios.de/openocd/trunk@1103 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-24 ntfreak + + * : - fix native mingw build if gettimeofday not defined. - reformat whitespace in startup.tcl git-svn-id: svn://svn.berlios.de/openocd/trunk@1101 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-23 oharboe + + * : fix working memory location git-svn-id: svn://svn.berlios.de/openocd/trunk@1098 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-23 oharboe + + * : only log BUG: (do not return error) in the case of unknown debug + reason(0xc) git-svn-id: svn://svn.berlios.de/openocd/trunk@1096 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-22 oharboe + + * : load and verify are now synonymous to load/verify_image git-svn-id: svn://svn.berlios.de/openocd/trunk@1092 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-22 oharboe + + * : produce syntax error git-svn-id: svn://svn.berlios.de/openocd/trunk@1090 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-22 oharboe + + * : Laurentiu Cocanu - more help text git-svn-id: svn://svn.berlios.de/openocd/trunk@1088 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-22 oharboe + + * : version number keyword expansion handling git-svn-id: svn://svn.berlios.de/openocd/trunk@1086 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-21 oharboe + + * : remove duplicate target git-svn-id: svn://svn.berlios.de/openocd/trunk@1084 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-17 ntfreak + + * : - add link in texi docs git-svn-id: svn://svn.berlios.de/openocd/trunk@1081 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-17 ntfreak + + * : - remove texi warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@1079 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-16 oharboe + + * : sleep command now prints out target debugmsgs w/anything like + usable performance git-svn-id: svn://svn.berlios.de/openocd/trunk@1076 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-16 oharboe + + * : Laurentiu Cocanu - integrated new tcl target command docs git-svn-id: svn://svn.berlios.de/openocd/trunk@1073 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-16 oharboe + + * : adding concept of production script git-svn-id: svn://svn.berlios.de/openocd/trunk@1071 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-16 oharboe + + * : added capture command to capture log output. Useful when wanting + to capture log output from tcl procedures that invoke openocd + commands git-svn-id: svn://svn.berlios.de/openocd/trunk@1069 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-16 oharboe + + * : unsik Kim - mflash support git-svn-id: svn://svn.berlios.de/openocd/trunk@1067 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-15 ntfreak + + * : - fix tcl_port typo in docs - remove build warning from openocd.c - add missing svn props git-svn-id: svn://svn.berlios.de/openocd/trunk@1065 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-15 oharboe + + * : 김운식 spotted a bug in target_write_u8 git-svn-id: svn://svn.berlios.de/openocd/trunk@1063 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-14 oharboe + + * : Laurentiu Cocanu - fix error handling git-svn-id: svn://svn.berlios.de/openocd/trunk@1061 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-14 oharboe + + * : Laurentiu Cocanu - more error handling fixes git-svn-id: svn://svn.berlios.de/openocd/trunk@1059 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-14 oharboe + + * : clarified jtag_ntrst_delay option git-svn-id: svn://svn.berlios.de/openocd/trunk@1056 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-14 oharboe + + * : testing of syntax error in reset and at startup git-svn-id: svn://svn.berlios.de/openocd/trunk@1054 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-14 oharboe + + * : added warning to use GDB 6.7 or newer git-svn-id: svn://svn.berlios.de/openocd/trunk@1052 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-14 oharboe + + * : John McCarthy two patches add a mips_m4k target + option (ejtag_reset) to cause a reset command to use the EJTAG + Peripheral and System Reset in addition to srst. This is for + targets like the wrt54gl which do not connect the srst to a system + reset (I believe it just goes to a GPIO). git-svn-id: svn://svn.berlios.de/openocd/trunk@1050 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-14 oharboe + + * : reset cleanup git-svn-id: svn://svn.berlios.de/openocd/trunk@1048 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-13 oharboe + + * : SEGFAULT gaffe in dummy register handling git-svn-id: svn://svn.berlios.de/openocd/trunk@1046 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-13 oharboe + + * : fix crash when connecting GDB to powered down target git-svn-id: svn://svn.berlios.de/openocd/trunk@1044 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-13 oharboe + + * : Fixed gaffes in reset script handling + improved error messages + a bit. The file and line # of the syntax error in a reset script is + now printed. git-svn-id: svn://svn.berlios.de/openocd/trunk@1042 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-12 oharboe + + * : Fix problems with DCC downloads routine crashing silently. git-svn-id: svn://svn.berlios.de/openocd/trunk@1040 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-10 oharboe + + * : John McCarthy openocd-usb.cfg added git-svn-id: svn://svn.berlios.de/openocd/trunk@1038 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-09 oharboe + + * : enumeration of threads for testing purposes. git-svn-id: svn://svn.berlios.de/openocd/trunk@1035 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-09 oharboe + + * : added busy sleep (for testing purposes) git-svn-id: svn://svn.berlios.de/openocd/trunk@1033 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-08 oharboe + + * : Richard Missenden exit now works during startup script git-svn-id: svn://svn.berlios.de/openocd/trunk@1031 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-08 oharboe + + * : John McCarthy adds support for DMA mode access + as supported by EJTAG 1.0/2.0 processors git-svn-id: svn://svn.berlios.de/openocd/trunk@1029 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-07 oharboe + + * : reduce patch problems by moving $xxx expansion into seperate fn git-svn-id: svn://svn.berlios.de/openocd/trunk@1027 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-07 oharboe + + * : Frederik Kriewitz Segmentation fault + fix. git-svn-id: svn://svn.berlios.de/openocd/trunk@1025 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-07 oharboe + + * : Georg Acher - arm11 wip. run algorithm + small + init bugfix. git-svn-id: svn://svn.berlios.de/openocd/trunk@1023 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-06 oharboe + + * : basic smoketest on lm3s3748.elf git-svn-id: svn://svn.berlios.de/openocd/trunk@1020 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-06 oharboe + + * : better keep_alive() handling git-svn-id: svn://svn.berlios.de/openocd/trunk@1018 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-05 oharboe + + * : Georg Acher corrected TDO sampling git-svn-id: svn://svn.berlios.de/openocd/trunk@1016 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-03 oharboe + + * : GDB alive fixes for verify_image git-svn-id: svn://svn.berlios.de/openocd/trunk@1014 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-10-01 oharboe + + * : fixed gaffe: disable interrupts reset init script git-svn-id: svn://svn.berlios.de/openocd/trunk@1012 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-29 ntfreak + + * : - at91sam7.c remove build warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@1010 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-26 oharboe + + * : I do not know why this is necessary, but it fixes strange effects (step/resume cause a NMI after reset) on LM3S6918 -- + Michael Schwingen git-svn-id: svn://svn.berlios.de/openocd/trunk@1008 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-26 oharboe + + * : wip git-svn-id: svn://svn.berlios.de/openocd/trunk@1006 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-25 ntfreak + + * : - update docs for aduc702x flash driver git-svn-id: svn://svn.berlios.de/openocd/trunk@996 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-24 oharboe + + * : fix noise in gdb console when single stepping. Remove printing + of log before processing halted event. git-svn-id: svn://svn.berlios.de/openocd/trunk@994 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-24 oharboe + + * : "marcel" , I have the ADuC702x flashdriver working again (see attachment). It + adds the option to erase and write the ADuC702x flash git-svn-id: svn://svn.berlios.de/openocd/trunk@992 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-21 oharboe + + * : Removed some obsolete stuff + Pushing things in the direction of + openocd.texi git-svn-id: svn://svn.berlios.de/openocd/trunk@990 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-21 oharboe + + * : put instructions on how to report bugs onto the users radar git-svn-id: svn://svn.berlios.de/openocd/trunk@988 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-12 oharboe + + * : follow up to keep_alive() fix. process target events before + returning from reset procedure. git-svn-id: svn://svn.berlios.de/openocd/trunk@986 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-12 oharboe + + * : Duane Ellis: target_process_reset is now implemented in tcl. + This allows better control from target configuration scripts. git-svn-id: svn://svn.berlios.de/openocd/trunk@984 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-08 oharboe + + * : typo fixed. git-svn-id: svn://svn.berlios.de/openocd/trunk@982 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-08 oharboe + + * : Duane Ellis, added clock command. git-svn-id: svn://svn.berlios.de/openocd/trunk@980 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-04 oharboe + + * : s3c2440 OpenMoko target script git-svn-id: svn://svn.berlios.de/openocd/trunk@978 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-01 oharboe + + * : Removed target->reset_mode, no longer used git-svn-id: svn://svn.berlios.de/openocd/trunk@976 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-09-01 oharboe + + * : retired, nothing came of it. git-svn-id: svn://svn.berlios.de/openocd/trunk@974 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-27 oharboe + + * : comment about slow RTCK git-svn-id: svn://svn.berlios.de/openocd/trunk@972 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-26 oharboe + + * : added 1000ms timeout git-svn-id: svn://svn.berlios.de/openocd/trunk@970 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-25 oharboe + + * : RCLK is not supported, return error instead of crashing. git-svn-id: svn://svn.berlios.de/openocd/trunk@968 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-25 oharboe + + * : fixed bug in arm11 examine code. git-svn-id: svn://svn.berlios.de/openocd/trunk@966 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-25 oharboe + + * : sync with Jim Tcl repository. git-svn-id: svn://svn.berlios.de/openocd/trunk@964 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-24 oharboe + + * : duan ellis target tcl work in progress converts a number of 'simple string lookup tables' into NVP + tables. These NVP tables will be used by various commands coming + in the next patch. git-svn-id: svn://svn.berlios.de/openocd/trunk@962 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-23 ntfreak + + * : - clear any existing breakpoints/watchpoints when restarting in gdb + extended remote mode git-svn-id: svn://svn.berlios.de/openocd/trunk@960 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-22 ntfreak + + * : - fix win32 build issues from previous jim patch git-svn-id: svn://svn.berlios.de/openocd/trunk@958 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-20 oharboe + + * : added gdb timeout handling + error propagation git-svn-id: svn://svn.berlios.de/openocd/trunk@956 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-20 oharboe + + * : lm3s3748 config file git-svn-id: svn://svn.berlios.de/openocd/trunk@954 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-20 oharboe + + * : sharpen error propagation a wee bit. git-svn-id: svn://svn.berlios.de/openocd/trunk@952 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-20 oharboe + + * : Daniel Gimpelevich fix reset halt on feroceon git-svn-id: svn://svn.berlios.de/openocd/trunk@950 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-20 oharboe + + * : duane ellis: fix warning git-svn-id: svn://svn.berlios.de/openocd/trunk@948 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-19 oharboe + + * : fixed warning git-svn-id: svn://svn.berlios.de/openocd/trunk@946 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-19 oharboe + + * : make target_wait_state() usable from other places, made + LOG_USER() output LOG_DEBUG() output. Avoids flooding logs in + certain cases and OpenOCD will output error message if the halt + fails. git-svn-id: svn://svn.berlios.de/openocd/trunk@944 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-19 oharboe + + * : search and replace usleep(1000) with alive_sleep(1) to avoid GDB + timeouts. git-svn-id: svn://svn.berlios.de/openocd/trunk@942 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-19 oharboe + + * : added some alive_sleep()'s git-svn-id: svn://svn.berlios.de/openocd/trunk@940 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-19 oharboe + + * : added alive_sleep() function to let GDB alive packets be sent git-svn-id: svn://svn.berlios.de/openocd/trunk@938 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-19 oharboe + + * : duane ellis: (A) a new concept called "Name Value Pair" or NVP, + in simple terms: Think: "String" and "Value". There can be many + strings - all related to a single value, for examle: "T", "t", "y", + "1", "yes", all can represent "truth", the reverse mapping is more + simplistic - the first matching number wins. (B) a new "getopt" like feature for Jim - that simplifies argument + parsing in complex functions, normally this would be used in + conjunction with either an NVP table of options, or a more simpler + Enumeration table. In contrast to the GNU "getopt" package, this + is more of a "object model or code oriented" solution then a pure + data structure used by GNU getopt, or the main stream Tcl/Tk option + processing. git-svn-id: svn://svn.berlios.de/openocd/trunk@936 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-19 oharboe + + * : fix comment w.r.t. start address for RAM git-svn-id: svn://svn.berlios.de/openocd/trunk@934 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-19 oharboe + + * : removed a couple of exit()'s from error handling. git-svn-id: svn://svn.berlios.de/openocd/trunk@932 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-19 oharboe + + * : Daniel Gimpelevich one + more parport device git-svn-id: svn://svn.berlios.de/openocd/trunk@930 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-18 oharboe + + * : more error propagation git-svn-id: svn://svn.berlios.de/openocd/trunk@928 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-18 oharboe + + * : openocd.texi is the authoratitive source for documentation. Wiki + is dead. git-svn-id: svn://svn.berlios.de/openocd/trunk@926 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-17 oharboe + + * : deleted superfluous sam7s256 which was identical to sam7x256 git-svn-id: svn://svn.berlios.de/openocd/trunk@924 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-15 oharboe + + * : removed obsolete command. git-svn-id: svn://svn.berlios.de/openocd/trunk@922 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-14 oharboe + + * : arm7/9 breakpoint cleanup. arm7_9 sw/hw commands retired. + openocd.texi is alerady updated. git-svn-id: svn://svn.berlios.de/openocd/trunk@920 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-14 oharboe + + * : documentation wip for upcoming patch. git-svn-id: svn://svn.berlios.de/openocd/trunk@918 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-13 oharboe + + * : force lpc2148 target into ARM state. git-svn-id: svn://svn.berlios.de/openocd/trunk@916 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-13 oharboe + + * : added global gdb breakpoint override configuration command git-svn-id: svn://svn.berlios.de/openocd/trunk@914 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-13 oharboe + + * : Clear all dangling breakpoints upon GDB connection. git-svn-id: svn://svn.berlios.de/openocd/trunk@912 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-13 oharboe + + * : return halted signal if step/continue fails git-svn-id: svn://svn.berlios.de/openocd/trunk@910 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-11 oharboe + + * : fix output from jtag_khz when only jtag_speed has been invoked git-svn-id: svn://svn.berlios.de/openocd/trunk@908 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-11 oharboe + + * : propagate error code in case of "reset" failing. git-svn-id: svn://svn.berlios.de/openocd/trunk@906 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-11 oharboe + + * : fix error message git-svn-id: svn://svn.berlios.de/openocd/trunk@904 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-08 ntfreak + + * : - fix build issues under win32 (mingw) git-svn-id: svn://svn.berlios.de/openocd/trunk@902 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-08 oharboe + + * : default reset in help text - run git-svn-id: svn://svn.berlios.de/openocd/trunk@900 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-07 oharboe + + * : David Kuehling - added jim-eventloop.c git-svn-id: svn://svn.berlios.de/openocd/trunk@898 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-07 ntfreak + + * : - correct BUILD_ECOSBOARD definition is server.c git-svn-id: svn://svn.berlios.de/openocd/trunk@896 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-06 ntfreak + + * : - added svn props for previously added file git-svn-id: svn://svn.berlios.de/openocd/trunk@894 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-05 oharboe + + * : GDB monitor commands now also get halted state upon e.g. "reset + halt". git-svn-id: svn://svn.berlios.de/openocd/trunk@892 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-05 oharboe + + * : Duane Ellis: fix warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@890 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-05 oharboe + + * : define resetting the target into the halted or running state as + an atomic operation. git-svn-id: svn://svn.berlios.de/openocd/trunk@888 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-08-04 oharboe + + * : TAP_TLR won't work in a pathmove sequence. OpenOCD shouldn't and + doesn't need to support this. git-svn-id: svn://svn.berlios.de/openocd/trunk@886 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-31 oharboe + + * : wait up to 1 second for halted state upon reset init/halt. git-svn-id: svn://svn.berlios.de/openocd/trunk@884 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-30 oharboe + + * : warning output upon connection problems. git-svn-id: svn://svn.berlios.de/openocd/trunk@882 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-28 ntfreak + + * : - added run_and_halt_time to deprecated/removed functions section git-svn-id: svn://svn.berlios.de/openocd/trunk@880 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-28 oharboe + + * : fixed gaffe mea culpa git-svn-id: svn://svn.berlios.de/openocd/trunk@878 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-27 oharboe + + * : working notes. git-svn-id: svn://svn.berlios.de/openocd/trunk@876 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-26 ntfreak + + * : - merged mips target into svn trunk git-svn-id: svn://svn.berlios.de/openocd/trunk@874 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-25 oharboe + + * : added yours sincerely for files where I feel that I've made + non-trivial contributions. git-svn-id: svn://svn.berlios.de/openocd/trunk@872 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-24 oharboe + + * : more error message cleanup. invalid args & syntax errors both + now print arguments of command. git-svn-id: svn://svn.berlios.de/openocd/trunk@870 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-24 oharboe + + * : retire daemon_startup git-svn-id: svn://svn.berlios.de/openocd/trunk@868 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-24 oharboe + + * : Better handling of OpenOCD command invocation result/context. git-svn-id: svn://svn.berlios.de/openocd/trunk@866 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-23 ntfreak + + * : - comment about dummy ack '+' char from gdb git-svn-id: svn://svn.berlios.de/openocd/trunk@864 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-23 ntfreak + + * : - fix typo git-svn-id: svn://svn.berlios.de/openocd/trunk@862 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-23 oharboe + + * : handle end of line comments to improve compatibility with event + scripts git-svn-id: svn://svn.berlios.de/openocd/trunk@860 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-22 ntfreak + + * : - fix bug with stm32 high density write protection git-svn-id: svn://svn.berlios.de/openocd/trunk@858 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-22 oharboe + + * : Spen: startup.tcl cross compile support git-svn-id: svn://svn.berlios.de/openocd/trunk@856 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-22 oharboe + + * : very slightly improved error message for not being able to find + scripts git-svn-id: svn://svn.berlios.de/openocd/trunk@854 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-21 oharboe + + * : Allows config scripts to override handling of 'R'(restart) GDB + packet. git-svn-id: svn://svn.berlios.de/openocd/trunk@852 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-21 oharboe + + * : update jtag_speed/khz docs a bit. git-svn-id: svn://svn.berlios.de/openocd/trunk@850 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-21 oharboe + + * : cross compile fix git-svn-id: svn://svn.berlios.de/openocd/trunk@848 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-21 oharboe + + * : Duane Ellis stm32 peripherals scripts git-svn-id: svn://svn.berlios.de/openocd/trunk@846 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-20 oharboe + + * : BUG: prefix to timeout for gdb keep alive packets. git-svn-id: svn://svn.berlios.de/openocd/trunk@844 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-20 oharboe + + * : Duane Ellis - script commands for stm32 git-svn-id: svn://svn.berlios.de/openocd/trunk@842 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-20 oharboe + + * : Duane Ellis improve error message in Jim when sourcing a file fails. + Previously it did not tell you the CWD Jim was using as its + reference point. (Helpful when script filenames are a relative + path) git-svn-id: svn://svn.berlios.de/openocd/trunk@840 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-19 oharboe + + * : throw exception upon syntax error. git-svn-id: svn://svn.berlios.de/openocd/trunk@838 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-19 oharboe + + * : clarify error message w.r.t. not being able to set breakpoint git-svn-id: svn://svn.berlios.de/openocd/trunk@836 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-18 oharboe + + * : This allows overriding builtin openocd commands. git-svn-id: svn://svn.berlios.de/openocd/trunk@834 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-18 oharboe + + * : "reset" without arguments now execute a "reset run". the reset mode argument to the target command is deprecated(ignored + w/error message). git-svn-id: svn://svn.berlios.de/openocd/trunk@832 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-18 ntfreak + + * : - fix incorrectly registered function openocd_array2mem - removed unused variables - reformatted lpc288x.[ch] - fixed helper/Makefile.am dependencies - add correct svn props to added files git-svn-id: svn://svn.berlios.de/openocd/trunk@829 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-18 oharboe + + * : keep_alive() fix for reset warnings. git-svn-id: svn://svn.berlios.de/openocd/trunk@827 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-18 oharboe + + * : Duane Ellis more interface files. git-svn-id: svn://svn.berlios.de/openocd/trunk@825 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-18 oharboe + + * : added missing "reset+load" sequence. git-svn-id: svn://svn.berlios.de/openocd/trunk@823 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-17 oharboe + + * : Charles Hardin ckhardin at gmail.com Instead of stashing the + context in a global variable, just use the "context" associated with + the interp structure being passed around And fixed the message referring to mem2array in the array2mem + function git-svn-id: svn://svn.berlios.de/openocd/trunk@821 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-17 oharboe + + * : Charles Hardin ckhardin at gmail.com There isn't a real value to the cfg_cmd_ctx since everything should + be run thru the initial context created at start. git-svn-id: svn://svn.berlios.de/openocd/trunk@819 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-17 ntfreak + + * : - reverted resume_target to old behaviour git-svn-id: svn://svn.berlios.de/openocd/trunk@817 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-16 oharboe + + * : Fixes to \ and / handling for OpenOCD git-svn-id: svn://svn.berlios.de/openocd/trunk@815 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-16 oharboe + + * : print out jim error message stack trace in expected order(look + at any C++ or Java debugger for instance). git-svn-id: svn://svn.berlios.de/openocd/trunk@813 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-16 oharboe + + * : print syntax for command upon syntax error. git-svn-id: svn://svn.berlios.de/openocd/trunk@811 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-15 oharboe + + * : feeble beginnings for tcl api rules. git-svn-id: svn://svn.berlios.de/openocd/trunk@809 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-14 oharboe + + * : Charles Hardin This evaluates the file at the correct level for the interpreter and + the sets and all the globals are then done as expected. added a const to find_file function to avoid typecasting git-svn-id: svn://svn.berlios.de/openocd/trunk@806 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-13 ntfreak + + * : - added svn props for newly added files git-svn-id: svn://svn.berlios.de/openocd/trunk@804 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-13 oharboe + + * : Duane Ellis fix to tcl puts git-svn-id: svn://svn.berlios.de/openocd/trunk@802 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-12 ntfreak + + * : - remove requirement for file2c.tcl git-svn-id: svn://svn.berlios.de/openocd/trunk@800 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-12 oharboe + + * : testing/*.tcl sample & test code git-svn-id: svn://svn.berlios.de/openocd/trunk@798 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-11 ntfreak + + * : - configure check added for tclsh - startup.c manually added to clean deps git-svn-id: svn://svn.berlios.de/openocd/trunk@796 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-11 oharboe + + * : Charles Hardin ckhardin at gmail.com This address the >32 bit problem with drscan also added a check for + bypass in the execute since this will manifest itself as a memory + corruption when this check helps to debug the problem alot easier git-svn-id: svn://svn.berlios.de/openocd/trunk@794 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-11 oharboe + + * : work in progress to improve help git-svn-id: svn://svn.berlios.de/openocd/trunk@792 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-11 oharboe + + * : .cfg files are now executed as Jim Tcl. Commands that terminate + script w/error message. git-svn-id: svn://svn.berlios.de/openocd/trunk@790 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-11 oharboe + + * : working notes. git-svn-id: svn://svn.berlios.de/openocd/trunk@788 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-10 oharboe + + * : Charles Hardin Add semantics to support memwrite(32,16,8) with an array2mem command + Move the global up in bits2bytes.tcl so the set puts the value in + the global context. Add memwrite procs to memory.tcl git-svn-id: svn://svn.berlios.de/openocd/trunk@786 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-10 oharboe + + * : fix quoting problem when handling OpenOCD commands. git-svn-id: svn://svn.berlios.de/openocd/trunk@784 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-10 oharboe + + * : very slight cleanup of flash banks handling. git-svn-id: svn://svn.berlios.de/openocd/trunk@782 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-09 ntfreak + + * : - adding missing install entry for luminary-libftdi.cfg git-svn-id: svn://svn.berlios.de/openocd/trunk@780 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-09 ntfreak + + * : - added luminary libftdi interface config git-svn-id: svn://svn.berlios.de/openocd/trunk@778 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-09 oharboe + + * : added flash_banks low level command. git-svn-id: svn://svn.berlios.de/openocd/trunk@776 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-08 oharboe + + * : tcl regression fixes. git-svn-id: svn://svn.berlios.de/openocd/trunk@774 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-08 ntfreak + + * : - removed target_process_events as only used in + handle_resume_command and events will be called anyway by poll git-svn-id: svn://svn.berlios.de/openocd/trunk@772 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-08 ntfreak + + * : - apply correct formatting to openocd.c - Thanks Charles Hardin git-svn-id: svn://svn.berlios.de/openocd/trunk@770 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-07 oharboe + + * : more tcl cleanup. git-svn-id: svn://svn.berlios.de/openocd/trunk@768 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-07 ntfreak + + * : - command_run_line will only search once for the command, and + execute if found git-svn-id: svn://svn.berlios.de/openocd/trunk@766 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-07 oharboe + + * : fix syntax error. git-svn-id: svn://svn.berlios.de/openocd/trunk@764 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-06 ntfreak + + * : - fix duplicate log entry git-svn-id: svn://svn.berlios.de/openocd/trunk@762 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-06 ntfreak + + * : - fixed build issues with win32 - fixed build warnings for last commit - set svn props for last commit git-svn-id: svn://svn.berlios.de/openocd/trunk@760 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-06 oharboe + + * : fix a few compilation problems. git-svn-id: svn://svn.berlios.de/openocd/trunk@758 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-06 oharboe + + * : Oopss. Forgot to list Duane Ellis as + the author of changes in 755. git-svn-id: svn://svn.berlios.de/openocd/trunk@756 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-05 ntfreak + + * : - added search for libdl - Thanks Charles Hardin git-svn-id: svn://svn.berlios.de/openocd/trunk@754 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-04 ntfreak + + * : - added event scripts for str73x and str75x targets git-svn-id: svn://svn.berlios.de/openocd/trunk@751 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-04 ntfreak + + * : - fixed line endings with commands.tcl - added svn props for newly added files git-svn-id: svn://svn.berlios.de/openocd/trunk@749 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-04 oharboe + + * : fix to peek command. git-svn-id: svn://svn.berlios.de/openocd/trunk@747 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-04 oharboe + + * : typo git-svn-id: svn://svn.berlios.de/openocd/trunk@745 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-04 oharboe + + * : added support for Tcl config scripts on the command line(use + .tcl extension). git-svn-id: svn://svn.berlios.de/openocd/trunk@743 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-04 oharboe + + * : ARM11 update. OpenOCD supports starting without being able to + talk to the hardware. git-svn-id: svn://svn.berlios.de/openocd/trunk@741 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-07-04 oharboe + + * : Jim Tcl support added git-svn-id: svn://svn.berlios.de/openocd/trunk@739 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-28 oharboe + + * : wip. git-svn-id: svn://svn.berlios.de/openocd/trunk@737 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-27 ntfreak + + * : - update docs for new target_script events git-svn-id: svn://svn.berlios.de/openocd/trunk@735 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-27 oharboe + + * : hooks to enable experimentation with scripting language support. + Reduces patch size, but has no effect on OpenOCD otherwise. git-svn-id: svn://svn.berlios.de/openocd/trunk@733 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-27 oharboe + + * : David Anders more target lib scripts contributed by git-svn-id: svn://svn.berlios.de/openocd/trunk@731 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-27 oharboe + + * : David Anders: fixes an issue with large block nand flash address + where the beginning of the OOB area is always selected instead of + the beginning of a page when needed git-svn-id: svn://svn.berlios.de/openocd/trunk@729 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-25 ntfreak + + * : - fix reset_halt issue with certain arm cores - address not set in + embedded ice reg - Thanks Jonas Hörberg git-svn-id: svn://svn.berlios.de/openocd/trunk@727 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-24 ntfreak + + * : - fix compile errors when _DEBUG_INSTRUCTION_EXECUTION_ is defined - Thanks Simon Qian git-svn-id: svn://svn.berlios.de/openocd/trunk@725 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-18 oharboe + + * : Pavel Chromy: - lower jtag speeds (higher divisor) was used, TDI was not changed + on falling TCK edge as it should - reset signal was release upon any TMS transition, making it + impossible to use reset halt - added khz() and speed_div() functions git-svn-id: svn://svn.berlios.de/openocd/trunk@716 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-18 oharboe + + * : Spen spotted a bug in warning for missing srst_pulls_trst git-svn-id: svn://svn.berlios.de/openocd/trunk@714 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-16 mifi + + * : - added target and event script for the eir-sam7se512 target git-svn-id: svn://svn.berlios.de/openocd/trunk@712 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-16 oharboe + + * : GDB timeout fix. If a script takes a long time and does not + produce any output, ping between every command. git-svn-id: svn://svn.berlios.de/openocd/trunk@710 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-11 ntfreak + + * : - probe incorrect for high density stm32 flash git-svn-id: svn://svn.berlios.de/openocd/trunk@708 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-06 ntfreak + + * : - stm32 erase will use mass_erase if all banks selected git-svn-id: svn://svn.berlios.de/openocd/trunk@706 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-05 ntfreak + + * : - erase bank using bank erase rather than each sector - Thanks Fredrik Hederstierna git-svn-id: svn://svn.berlios.de/openocd/trunk@704 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-04 oharboe + + * : Pavel Chromy: fix logging syntax error + formatting & removing + obsolete comments. git-svn-id: svn://svn.berlios.de/openocd/trunk@702 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-04 ntfreak + + * : - luminary, stm32 and str7 flash driver error cleanup git-svn-id: svn://svn.berlios.de/openocd/trunk@700 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-06-03 oharboe + + * : Fredrik Hederstierna: fix leak + clean up return codes git-svn-id: svn://svn.berlios.de/openocd/trunk@698 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-29 ntfreak + + * : - added checksum_memory and blank_check_memory for xscale git-svn-id: svn://svn.berlios.de/openocd/trunk@696 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-27 ntfreak + + * : - moved flash erase_check target code to target.c git-svn-id: svn://svn.berlios.de/openocd/trunk@694 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-27 ntfreak + + * : - fixed typo in wp command git-svn-id: svn://svn.berlios.de/openocd/trunk@692 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-26 mifi + + * : - added check for max. value of jtag_speed in ft2232_khz. git-svn-id: svn://svn.berlios.de/openocd/trunk@690 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-26 oharboe + + * : found out why str912 reset halt failed. git-svn-id: svn://svn.berlios.de/openocd/trunk@688 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-26 ntfreak + + * : - corrected error with stm32 page calculation git-svn-id: svn://svn.berlios.de/openocd/trunk@686 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-24 mifi + + * : - comment out usb_set_altinterface, because it is not working under + Mac OS X. And not needed for Windows. Hopefully it will not break a + Linux build. git-svn-id: svn://svn.berlios.de/openocd/trunk@684 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-24 ntfreak + + * : - added stellaris flash mass_erase command git-svn-id: svn://svn.berlios.de/openocd/trunk@682 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-24 mifi + + * : - swap processing of reset handling. First srst and than trst. git-svn-id: svn://svn.berlios.de/openocd/trunk@680 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-24 mifi + + * : - corrected copy/paste type and renamed jlink_usb_read_result to + jlink_usb_read_emu_result git-svn-id: svn://svn.berlios.de/openocd/trunk@678 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-24 ntfreak + + * : - jlink jlink_execute_queue returns result - added jlink_get_version_info function - reformatted spaces to tabs git-svn-id: svn://svn.berlios.de/openocd/trunk@676 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-23 ntfreak + + * : - add support for newer high density stm32 parts git-svn-id: svn://svn.berlios.de/openocd/trunk@674 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-21 ntfreak + + * : - remove error message on shutdown git-svn-id: svn://svn.berlios.de/openocd/trunk@672 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-21 oharboe + + * : moved srst_pulls_trst check into arm7_9_common.c. Not tested + yet, if it is broken it should "only" print bogus warnings or not + print a warning when it should have. git-svn-id: svn://svn.berlios.de/openocd/trunk@670 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-19 oharboe + + * : reverted change in 658 and simply removed the busted warning for + now. git-svn-id: svn://svn.berlios.de/openocd/trunk@668 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-19 oharboe + + * : print out an error if srst_pulls_trst is not specified for e.g. + at91fr40008. Could possibly show bogus false positives in log + without any other side effects. git-svn-id: svn://svn.berlios.de/openocd/trunk@666 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-19 oharboe + + * : fix mode output when illegal arm mode is detected. Now prints + illegal mode for index -1. git-svn-id: svn://svn.berlios.de/openocd/trunk@664 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-19 oharboe + + * : updated guidelines. git-svn-id: svn://svn.berlios.de/openocd/trunk@662 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-16 mifi + + * : - added smoketest result for r657 - some corrections for the reset config of at91r40008 git-svn-id: svn://svn.berlios.de/openocd/trunk@660 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-14 ntfreak + + * : - added jlink support, based on Jürgen Stuber patch git-svn-id: svn://svn.berlios.de/openocd/trunk@658 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-11 mifi + + * : - added patch from uwe hermann, thanks for the hint. git-svn-id: svn://svn.berlios.de/openocd/trunk@656 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-10 mifi + + * : - corrected rounding in ft2232_khz git-svn-id: svn://svn.berlios.de/openocd/trunk@654 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-10 mifi + + * : - smoketest for r651 git-svn-id: svn://svn.berlios.de/openocd/trunk@652 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-09 oharboe + + * : Michael Fischer spotted a problem in the reset routines for + srst_pulls_trst. It is a bit of a mystery why this was only visible + w/LPC2148. Embedded ICE registers are now set up after SRST pulls TRST. git-svn-id: svn://svn.berlios.de/openocd/trunk@650 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-07 oharboe + + * : print available memory in log_level 3 git-svn-id: svn://svn.berlios.de/openocd/trunk@648 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-07 oharboe + + * : Edgar Grimberg plugged a leak found w/Valgrind. git-svn-id: svn://svn.berlios.de/openocd/trunk@646 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-06 oharboe + + * : Edgar Grimberg found tiny memory leak git-svn-id: svn://svn.berlios.de/openocd/trunk@644 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-06 oharboe + + * : The target library is now the authorotative source of config + examples git-svn-id: svn://svn.berlios.de/openocd/trunk@642 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-03 drath + + * : - fixed xsvf_add_statemove() git-svn-id: svn://svn.berlios.de/openocd/trunk@640 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-02 ntfreak + + * : - added info about libftdi support under win32 git-svn-id: svn://svn.berlios.de/openocd/trunk@638 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-01 oharboe + + * : Tim Hudson worked on English language. git-svn-id: svn://svn.berlios.de/openocd/trunk@636 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-05-01 ntfreak + + * : - add missing svn props git-svn-id: svn://svn.berlios.de/openocd/trunk@634 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-30 oharboe + + * : now compiles again. git-svn-id: svn://svn.berlios.de/openocd/trunk@632 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-30 ntfreak + + * : - added new device to luminary flash driver - only use SYSRESETREQ on affected luminary parts git-svn-id: svn://svn.berlios.de/openocd/trunk@630 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-30 oharboe + + * : Edgar's added support for printing jtag_khz git-svn-id: svn://svn.berlios.de/openocd/trunk@628 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-29 oharboe + + * : Edgar Grimberg added a new rule for target scripts. Flash + + verify must succeed. git-svn-id: svn://svn.berlios.de/openocd/trunk@626 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-28 ntfreak + + * : - add cortex_m3 variant luminary to fix reset issue with asserting + SRST - + + https://lists.berlios.de/pipermail/openocd-development/2008-April/002022.html for detailsgit-svn-id: svn://svn.berlios.de/openocd/trunk@624 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-26 ntfreak + + * : - luminary flash now loader polls when finished git-svn-id: svn://svn.berlios.de/openocd/trunk@622 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-26 ntfreak + + * : - incorrect ram size for lm3s811 target script git-svn-id: svn://svn.berlios.de/openocd/trunk@620 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-26 oharboe + + * : wip instructions for building Cortex toolchain git-svn-id: svn://svn.berlios.de/openocd/trunk@618 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-24 oharboe + + * : Close dangling file handle git-svn-id: svn://svn.berlios.de/openocd/trunk@616 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-24 oharboe + + * : Edgar's new test cases. git-svn-id: svn://svn.berlios.de/openocd/trunk@614 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-23 oharboe + + * : Pavel Chromy's on chip flash loader git-svn-id: svn://svn.berlios.de/openocd/trunk@612 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-23 ntfreak + + * : - added svn props for newly added files git-svn-id: svn://svn.berlios.de/openocd/trunk@610 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-23 ntfreak + + * : - fix typo in openocd.texi git-svn-id: svn://svn.berlios.de/openocd/trunk@608 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-23 oharboe + + * : Tim Hudson: removed setting jtag_speed directly (which should + not be done). git-svn-id: svn://svn.berlios.de/openocd/trunk@606 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-23 oharboe + + * : added fast option. git-svn-id: svn://svn.berlios.de/openocd/trunk@604 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-22 oharboe + + * : wip on reporting bugs. git-svn-id: svn://svn.berlios.de/openocd/trunk@602 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-21 ntfreak + + * : - added stm32 stick and luminary eval boards interface configs - corrected target lm3s6965.cfg git-svn-id: svn://svn.berlios.de/openocd/trunk@600 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-20 ntfreak + + * : - set erase flag on sector git-svn-id: svn://svn.berlios.de/openocd/trunk@598 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-20 ntfreak + + * : - update docs for flash write_image command - remove info on flash auto_erase, added to removed commands section git-svn-id: svn://svn.berlios.de/openocd/trunk@596 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-19 mifi + + * : - added test results for r592 git-svn-id: svn://svn.berlios.de/openocd/trunk@594 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-18 drath + + * : - Flash auto-erase is disabled by default git-svn-id: svn://svn.berlios.de/openocd/trunk@592 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-18 oharboe + + * : Nicolas Pitre fixed regression. git-svn-id: svn://svn.berlios.de/openocd/trunk@590 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-16 oharboe + + * : fix for gaffe in 555 that stopped JTAG chain examine + validate + from running. git-svn-id: svn://svn.berlios.de/openocd/trunk@588 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-16 ntfreak + + * : - correct stm32stick config script git-svn-id: svn://svn.berlios.de/openocd/trunk@586 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-16 oharboe + + * : Edgar Grimberg added some missing scripts from the install git-svn-id: svn://svn.berlios.de/openocd/trunk@584 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-15 oharboe + + * : - sw_bkpts fails if the target is not halted. The side effect is + that sw_bkpts also fails if the target is an unknown state(i.e. not + examined yet). - feroceon embedded ICE registers are now set up after TRST has been + deasserted(not tested, but it was broken as is anyway). git-svn-id: svn://svn.berlios.de/openocd/trunk@582 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-15 oharboe + + * : target read/write is no longer attempted for target_xxx() + functions when the target has not been examined(fails w/error). git-svn-id: svn://svn.berlios.de/openocd/trunk@580 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-14 oharboe + + * : retired fast_memory_access. It's always fast now. git-svn-id: svn://svn.berlios.de/openocd/trunk@578 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-14 oharboe + + * : moved out stuff that wasn't already moved from openocd.pdf to + the target library. git-svn-id: svn://svn.berlios.de/openocd/trunk@576 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-14 oharboe + + * : TRST is asserted *before* target->type->assert_reset() is + invoked. Removed old code. git-svn-id: svn://svn.berlios.de/openocd/trunk@574 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-13 oharboe + + * : A dummy driver to test codepath w/no contact w/target. git-svn-id: svn://svn.berlios.de/openocd/trunk@572 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-13 oharboe + + * : allows launching OpenOCD w/telnet+gdb server w/the target + powered down. git-svn-id: svn://svn.berlios.de/openocd/trunk@570 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-11 oharboe + + * : found two more gaffes for reset wip git-svn-id: svn://svn.berlios.de/openocd/trunk@568 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-11 oharboe + + * : Reset wip. Just adding hooks. This is just to reduce the size of + the actual change, no change in behaviour. git-svn-id: svn://svn.berlios.de/openocd/trunk@566 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-11 oharboe + + * : Wip - split target setup and target examination git-svn-id: svn://svn.berlios.de/openocd/trunk@564 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-11 oharboe + + * : Improved XScale performance for embedded hosted OpenOCD git-svn-id: svn://svn.berlios.de/openocd/trunk@562 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-10 oharboe + + * : stop using variable sized arrays. That's something that belongs + to C++ and not C. git-svn-id: svn://svn.berlios.de/openocd/trunk@560 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-10 ntfreak + + * : - single core context used, removed debug context as thought + unnecessary. - DCRDR now used to access special core registers - info is + currently omitted from the cortex_m3 TRM ARM have told me this is + the preferred access method and the docs will be updated soon. - now checks for User Thread Mode and Thread mode when halted. - removed repeated function declarations from command.c - cortex_m3_prepare_reset_halt removed, updated + cortex_m3_assert_reset to suit git-svn-id: svn://svn.berlios.de/openocd/trunk@558 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-09 oharboe + + * : target lib wip git-svn-id: svn://svn.berlios.de/openocd/trunk@556 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-09 ntfreak + + * : - add missing svn props git-svn-id: svn://svn.berlios.de/openocd/trunk@554 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-09 oharboe + + * : - added "init" command. "init" and "reset" at end of startup script + is equivalent to daemon_startup(still supported). - print warning if srst and trst change state at the same time when + srst_and_trst is seperate - reset now performs a trst, examines and validates the jtag chain + before targets assert reset - if startup fails to examine and validate the jtag chain, try a + reset before trying again git-svn-id: svn://svn.berlios.de/openocd/trunk@552 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-08 oharboe + + * : Edwin Olson found bug & tested fix for flash write_image for + stellaris. git-svn-id: svn://svn.berlios.de/openocd/trunk@550 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-08 oharboe + + * : added a couple of LOG_ERROR() messages to improve logfile. git-svn-id: svn://svn.berlios.de/openocd/trunk@548 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-08 oharboe + + * : The endstate now reports the endstate of the queue instead of + reading endstate variable internal to the driver. git-svn-id: svn://svn.berlios.de/openocd/trunk@546 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-07 oharboe + + * : - only if "reset halt" or "reset init" are issued will the reset + vector be set up - If communication fails during assert between assert/deassert and + during assert, warnings are printed. The warning suggests using + srst_only if the clock locks up as that would allow the reset vector + to be set up before asserting reset. git-svn-id: svn://svn.berlios.de/openocd/trunk@544 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-06 oharboe + + * : avoid patch trouble by isolating troublesome line... git-svn-id: svn://svn.berlios.de/openocd/trunk@542 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-04 oharboe + + * : - the reset mode parameter is now DEPRECATED. It is implemented as + an optional parameter with default reset_init. This is to streamline + things w.r.t. the target library. git-svn-id: svn://svn.berlios.de/openocd/trunk@540 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-04 oharboe + + * : added query of reset speed git-svn-id: svn://svn.berlios.de/openocd/trunk@538 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-03 oharboe + + * : - Work on fixing erase check. Many implementations are plain broken. + Wrote a default flash erase check fn which uses CFI's target + algorithm w/fallback to memory reads. - "flash info" no longer prints erase status as it is stale. - "flash erase_check" now prints erase status. erase check can take + a *long* time. Work in progress - arm7/9 with seperate srst & trst now supports reset init/halt + after a power outage. arm7/9 no longer makes any assumptions about + state of target when reset is asserted. - fixes for srst & trst capable arm7/9 with reset init/halt - prepare_reset_halt retired. This code needs to be inside + assert_reset anyway - haven't been able to get stm32 write algorithm to work. Fallback + flash write does work. Haven't found a version of openocd trunk + where this works. - added target_free_all_working_areas_restore() which can let be of + restoring backups. This is needed when asserting reset as the target + must be assumed to be an unknown state. Added some comments to + working areas API - str9 reset script fixes - some guidelines - fixed dangling callbacks upon reset timeout git-svn-id: svn://svn.berlios.de/openocd/trunk@536 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-02 oharboe + + * : fix flash info - now reports erased state properly git-svn-id: svn://svn.berlios.de/openocd/trunk@534 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-04-02 oharboe + + * : optional count argument to mwX git-svn-id: svn://svn.berlios.de/openocd/trunk@532 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-31 oharboe + + * : Do not assert trst in srst_only case even if srst_pulls_trst. git-svn-id: svn://svn.berlios.de/openocd/trunk@530 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-31 oharboe + + * : Removed exit()'s. A reset is usually enough to work around + these, reducing cycle times to get config scripts right. git-svn-id: svn://svn.berlios.de/openocd/trunk@528 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-28 oharboe + + * : Edgar Grimberg: added needed delays git-svn-id: svn://svn.berlios.de/openocd/trunk@526 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-26 oharboe + + * : hooks for multithreading. Disable nagle git-svn-id: svn://svn.berlios.de/openocd/trunk@524 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-22 ntfreak + + * : - gdb server was incorrectly sending null terminator on + qXfer:features:read: packet - armv7m now sends correct gdb register packet git-svn-id: svn://svn.berlios.de/openocd/trunk@522 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-22 ntfreak + + * : - changed jtag_add_reset errors to warnings - removed extra jtag reset warnings from arm7_9 and cortex_m3 git-svn-id: svn://svn.berlios.de/openocd/trunk@520 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-21 mifi + + * : - added new test results git-svn-id: svn://svn.berlios.de/openocd/trunk@518 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-14 oharboe + + * : added profile command. It was added to simplify evaluation by + testers. git-svn-id: svn://svn.berlios.de/openocd/trunk@516 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-13 oharboe + + * : Michael Bruck: fixed warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@514 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-13 oharboe + + * : added jtag_khz for use with target library git-svn-id: svn://svn.berlios.de/openocd/trunk@512 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-13 oharboe + + * : print ms in debug_level 3 logs. Seconds is not enough. git-svn-id: svn://svn.berlios.de/openocd/trunk@510 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-13 oharboe + + * : marked infinite loop in code w/TODO and fixed warning. git-svn-id: svn://svn.berlios.de/openocd/trunk@508 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-12 oharboe + + * : xscale now passes w/bitbang in 505 git-svn-id: svn://svn.berlios.de/openocd/trunk@506 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-12 oharboe + + * : This moves common code into functions so as to make it clear + that all the jtag_add_xxx() are indeed intended to do the same + thing. git-svn-id: svn://svn.berlios.de/openocd/trunk@504 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-12 oharboe + + * : more info about latest working version git-svn-id: svn://svn.berlios.de/openocd/trunk@502 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-12 oharboe + + * : tinkered a bit with testing matrix. git-svn-id: svn://svn.berlios.de/openocd/trunk@500 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-11 oharboe + + * : With the recent changes the TRST needs to happen for every + reset. git-svn-id: svn://svn.berlios.de/openocd/trunk@498 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-11 oharboe + + * : - retired unused jtag events. The code was incorrect - hopefully clarified the difference between TRST and TMS reset. - added DEBUG() statements w.r.t. state changes - TRST released and moving out of TAP_TLR are completely different + events. Only TRST released has a DEBUG() statement git-svn-id: svn://svn.berlios.de/openocd/trunk@496 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-11 oharboe + + * : retire unused code. git-svn-id: svn://svn.berlios.de/openocd/trunk@494 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-11 oharboe + + * : - fixed jtag_add_reset(). It no longer causes jtag_execute_queue() + to fail for two of it's return codes. A little bit weird, but + compatible with existing codebase. - tightend up error handling. Since the jtag_xxx() is a queue that + is either executed as things are added(hw queue) or a software + queue, then errors can only be caught during jtag_execute_queue(). + No error code is therefore returned from the queuing fn's. git-svn-id: svn://svn.berlios.de/openocd/trunk@492 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-10 oharboe + + * : backed out changes from 483. git-svn-id: svn://svn.berlios.de/openocd/trunk@490 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-10 oharboe + + * : more target scripts wip. git-svn-id: svn://svn.berlios.de/openocd/trunk@488 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-10 oharboe + + * : Pavel Chromy: the attached patch refines PRESTO support and + makes it work with libftdi. git-svn-id: svn://svn.berlios.de/openocd/trunk@486 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-10 oharboe + + * : - fixed a problem with big endian XScale and GDB register packets. - hmm..... did I screw up? Was XScale and not gdb_server busted + here? My thinking was that OpenOCD has a canonical internal + representation of registers that match GDB's expectations git-svn-id: svn://svn.berlios.de/openocd/trunk@484 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-10 oharboe + + * : - Fixed various error handling when looking for memory leaks - Fixed memory leak in gdb_server.c - pushed "Error:" statements up into fn's that know something about + what went wrong - load_image now fails if target_write_memory() fails - only issue an asynchronous halt() upon connect of GDB. Synchronous + halt/reset doesn't really work as what's required to initialize the + target might involve a special monitor sequence for the target in + question - syntax error handling improved(fewer exit()'s) git-svn-id: svn://svn.berlios.de/openocd/trunk@482 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-10 oharboe + + * : added stm32.cfg to install list git-svn-id: svn://svn.berlios.de/openocd/trunk@480 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-09 ntfreak + + * : - add stm32 target script git-svn-id: svn://svn.berlios.de/openocd/trunk@478 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-08 oharboe + + * : typo. git-svn-id: svn://svn.berlios.de/openocd/trunk@476 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-07 oharboe + + * : Asynchronous output information from e.g. a halt is now + displayed again. git-svn-id: svn://svn.berlios.de/openocd/trunk@474 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-07 ntfreak + + * : - The elf loader incorrectly assumed that the program header always + follows the ELF header. (Thanks Michael Bruck) git-svn-id: svn://svn.berlios.de/openocd/trunk@472 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-07 oharboe + + * : Edgar Grimberg, fix arm926ejs_examine_debug_reason return value. git-svn-id: svn://svn.berlios.de/openocd/trunk@470 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-07 oharboe + + * : minor corrections for target scripts. git-svn-id: svn://svn.berlios.de/openocd/trunk@468 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-07 oharboe + + * : Pavel Chromy, the patch fixes an issue with PRESTO & FTD2XX + under Linux. git-svn-id: svn://svn.berlios.de/openocd/trunk@466 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-07 oharboe + + * : wi-9c target scripts git-svn-id: svn://svn.berlios.de/openocd/trunk@464 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-07 mifi + + * : - added str912/str710_program.script - added test infos from r459 git-svn-id: svn://svn.berlios.de/openocd/trunk@462 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-07 oharboe + + * : Cosmetic fixes from Uwe Hermann git-svn-id: svn://svn.berlios.de/openocd/trunk@460 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-06 oharboe + + * : retired git-svn-id: svn://svn.berlios.de/openocd/trunk@458 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-06 oharboe + + * : tms is never referenced, confusing old code left behind + probably. git-svn-id: svn://svn.berlios.de/openocd/trunk@456 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-06 oharboe + + * : Pavel Chromy: faster alloc_printf() git-svn-id: svn://svn.berlios.de/openocd/trunk@454 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-06 oharboe + + * : Michael Bruck: - force simulate_reset_on_next_halt when target state is initially + detected - print out method of debug entry - fix VCR activation (didn't work before) git-svn-id: svn://svn.berlios.de/openocd/trunk@452 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-06 oharboe + + * : make debug code w.r.t. incorrect args for bypass stricter. git-svn-id: svn://svn.berlios.de/openocd/trunk@450 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-05 oharboe + + * : - This speeds up dcc arm7_9 bulk write a little bit and exercises + the jtag_add_dr_out() codepath - added a check to jtag_add_pathmove() for legal path transitions - tweaked jtag.h docs a little bit - made some jtag bypass tests _DEBUG_JTAG_IO_ git-svn-id: svn://svn.berlios.de/openocd/trunk@448 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-05 oharboe + + * : Pavel Chromy: memory leak in at91sam7 flash driver, possible + incorrect pointer conversion in gpnvm command handling, + uninitialized buffer issue in handle_flash_info_command in flash.c, + some formatting. git-svn-id: svn://svn.berlios.de/openocd/trunk@446 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-05 oharboe + + * : telnet_port can now be invoked multiple times git-svn-id: svn://svn.berlios.de/openocd/trunk@444 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-04 oharboe + + * : Fixed GDB timeout crash - regression introduced back when + log_add/remove_callback was added. git-svn-id: svn://svn.berlios.de/openocd/trunk@442 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-04 oharboe + + * : Michael Bruck: fix warnings. git-svn-id: svn://svn.berlios.de/openocd/trunk@440 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-03 ntfreak + + * : - added svn prop svn:eol-style native git-svn-id: svn://svn.berlios.de/openocd/trunk@438 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-03 oharboe + + * : added fill_malloc test. Not quite sure what to do here yet, but + it would be good to have something... git-svn-id: svn://svn.berlios.de/openocd/trunk@436 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-03 oharboe + + * : some comments from Dominic git-svn-id: svn://svn.berlios.de/openocd/trunk@434 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-02 ntfreak + + * : - added svn prop svn:eol-style native git-svn-id: svn://svn.berlios.de/openocd/trunk@432 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-02 oharboe + + * : fixed FSF address. Uwe Hermann. git-svn-id: svn://svn.berlios.de/openocd/trunk@430 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-01 oharboe + + * : wrote up explaining why tests are done on committed code. git-svn-id: svn://svn.berlios.de/openocd/trunk@428 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-01 ntfreak + + * : - contrib directory added - libdcc added as example for dcc comms with openocd target_request + debugmsgs git-svn-id: svn://svn.berlios.de/openocd/trunk@426 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-01 oharboe + + * : fix memory corruption regression introduced in 335 git-svn-id: svn://svn.berlios.de/openocd/trunk@424 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-01 mifi + + * : - added example for testing the JTAG speed with a FT2232 device git-svn-id: svn://svn.berlios.de/openocd/trunk@422 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-01 mifi + + * : - updated svn:eol-style prop to native for AT91R40008 (Thanks to + Spen for the hint) git-svn-id: svn://svn.berlios.de/openocd/trunk@420 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-01 ntfreak + + * : - updated svn:eol-style prop to native git-svn-id: svn://svn.berlios.de/openocd/trunk@418 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-01 oharboe + + * : improve DCC bulk write performance by using jtag_add_shift() + + tweaked embedded ICE communication. git-svn-id: svn://svn.berlios.de/openocd/trunk@416 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-01 oharboe + + * : Now uses jtag_add_shift() via embeddedice_write_reg_inner(). git-svn-id: svn://svn.berlios.de/openocd/trunk@414 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-01 oharboe + + * : log_remove_callback git-svn-id: svn://svn.berlios.de/openocd/trunk@412 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-01 mifi + + * : - added str912 test example, and test result git-svn-id: svn://svn.berlios.de/openocd/trunk@410 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-01 mifi + + * : - added test result for str710, and test description git-svn-id: svn://svn.berlios.de/openocd/trunk@408 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-03-01 mifi + + * : - added STR710 example which I used for Eclipse debug testing git-svn-id: svn://svn.berlios.de/openocd/trunk@406 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-29 oharboe + + * : added an #error in case anybody tries to compile that broken + code. git-svn-id: svn://svn.berlios.de/openocd/trunk@404 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-29 ntfreak + + * : - fix bug with emulated cortex_m3 dcc channel git-svn-id: svn://svn.berlios.de/openocd/trunk@402 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-29 oharboe + + * : Tweaked logging output. TODO is retired(hopelessly out of date). git-svn-id: svn://svn.berlios.de/openocd/trunk@400 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-29 oharboe + + * : Pavel Chromy fix: the guess-rev.sh scripts to retrieve SVN + revision returns the result including new line causing PKGBLDREV + macro to not work git-svn-id: svn://svn.berlios.de/openocd/trunk@398 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-29 oharboe + + * : Uwe Hermann: Small cosmetic fixes in the license header to make + them all look the same, fix some typos, update README. git-svn-id: svn://svn.berlios.de/openocd/trunk@396 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-29 oharboe + + * : Uwe Hermann: mproves the manpage text a bit and adds the missing + -s and -c options. git-svn-id: svn://svn.berlios.de/openocd/trunk@394 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-29 oharboe + + * : formatting fixes from Pavel Chromy git-svn-id: svn://svn.berlios.de/openocd/trunk@392 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-29 oharboe + + * : - image.c and fileio.c now uses logging to propagate error strings. More precise, less code. - removed unused code in fileio.c - Windows should now find debug_handler.bin git-svn-id: svn://svn.berlios.de/openocd/trunk@390 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-29 oharboe + + * : do not write single chars to log file. git-svn-id: svn://svn.berlios.de/openocd/trunk@388 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-29 oharboe + + * : Summary: passing of variable argument list reduced, strings sent + to logging are now formatted just once - more efficient. As a + result, ugly string malloc+strcpy are not needed anymore. git-svn-id: svn://svn.berlios.de/openocd/trunk@386 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-29 oharboe + + * : Michael Bruck: - fix indentation of multi-level commands - make help command work with multi-level commands git-svn-id: svn://svn.berlios.de/openocd/trunk@384 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-28 oharboe + + * : fixed newline gaffe in OUTPUT() git-svn-id: svn://svn.berlios.de/openocd/trunk@382 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-28 oharboe + + * : Pavel Chromy spotted a leak git-svn-id: svn://svn.berlios.de/openocd/trunk@380 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-28 oharboe + + * : numerous fixes from Uwe Hermann git-svn-id: svn://svn.berlios.de/openocd/trunk@378 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-28 oharboe + + * : Pavel Chromy - cleanup error messages git-svn-id: svn://svn.berlios.de/openocd/trunk@376 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-28 oharboe + + * : Pavel Chromy cleaned up checks for halted, error messages, etc. git-svn-id: svn://svn.berlios.de/openocd/trunk@374 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-28 oharboe + + * : fix from Pavel Chromy this patch fixes an issue in jtag_init - shall not reset jtag to + NULL. This causes jtag interface (USB device) not to be closed + properly if jtag chain validation fails. Once the underlaying jtag interface is initialized, jtag pointer + shall be left untouched, even in case of an error, so that proper + cleanup can be done, see exit_handler in openocd.c git-svn-id: svn://svn.berlios.de/openocd/trunk@372 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-28 oharboe + + * : code to be used in upcoming minidriver work. git-svn-id: svn://svn.berlios.de/openocd/trunk@370 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-28 oharboe + + * : fix copyright. git-svn-id: svn://svn.berlios.de/openocd/trunk@368 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-28 oharboe + + * : lingering change for eCos flash driver git-svn-id: svn://svn.berlios.de/openocd/trunk@366 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-28 oharboe + + * : - Added TARGET_REQ_DEBUGCHAR target_request debugmsg. This provides a better impeadance match for debug output char fn's, + e.g. eCos. - Line endings are now added at the caller site of command_print*(). + command_print() still adds a line ending - echo of commands in scripts are now available via debug_level + instead of forced echo - Added a USER_SAMELINE() for printing without a lineend. git-svn-id: svn://svn.berlios.de/openocd/trunk@364 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-28 drath + + * : - fix line-endings git-svn-id: svn://svn.berlios.de/openocd/trunk@362 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-28 oharboe + + * : Uwe Hermann fixed some warnings. git-svn-id: svn://svn.berlios.de/openocd/trunk@360 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-27 drath + + * : - fix typo in ep93xx jtag driver to allow OpenOCD compilation on ARM + (thanks to Uwe Hermann for the patch) git-svn-id: svn://svn.berlios.de/openocd/trunk@358 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-27 oharboe + + * : Nicolas Pitre listed some more devices. git-svn-id: svn://svn.berlios.de/openocd/trunk@356 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-26 ntfreak + + * : - code reformat (Thanks Pavel Chromy) git-svn-id: svn://svn.berlios.de/openocd/trunk@354 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-26 oharboe + + * : oopss.. another jtag minidriver reset gaffe. git-svn-id: svn://svn.berlios.de/openocd/trunk@352 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-26 oharboe + + * : Next step in the JTAG minidriver. This should be fairly close to + the final thing, but I'm not calling it "done" quite yet. git-svn-id: svn://svn.berlios.de/openocd/trunk@350 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-25 ntfreak + + * : - remove build warnings git-svn-id: svn://svn.berlios.de/openocd/trunk@348 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-25 oharboe + + * : Pavel Chromy - multiple log listeners - added OUTPUT() to replace printf - fix formatting git-svn-id: svn://svn.berlios.de/openocd/trunk@346 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-25 oharboe + + * : Pavel Chromy style fixes. git-svn-id: svn://svn.berlios.de/openocd/trunk@344 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-25 oharboe + + * : - Fix target library path problem w/Windows git-svn-id: svn://svn.berlios.de/openocd/trunk@342 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-25 oharboe + + * : committed bugfix from Michael Bruck git-svn-id: svn://svn.berlios.de/openocd/trunk@340 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-25 oharboe + + * : - using ERROR_COMMAND_SYNTAX_ERROR to print syntax in a couple of + places - some more flash cleanup of checking halted state - moved output handler into options.c - very slightly tweaked server.c to make it a bit more compatible + with eCos - retired arch_state. Not quite sure how I managed to leave that out + last time. git-svn-id: svn://svn.berlios.de/openocd/trunk@338 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-25 oharboe + + * : Michael Bruck spotted an omission in svn 322 git-svn-id: svn://svn.berlios.de/openocd/trunk@336 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-24 oharboe + + * : move options handling to separate file to better support + embedded implementations of OpenOCD git-svn-id: svn://svn.berlios.de/openocd/trunk@334 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-24 oharboe + + * : - fixed target->type->poll() return value - added arch_state to show status of currently selected target - simplified target->type->arch_state() api. - clean up telnet output a bit - fixed GDB output for arch_state - removed a couple of unecessary exit()'s - cleaned up error propagation a bit in a few places git-svn-id: svn://svn.berlios.de/openocd/trunk@332 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-24 oharboe + + * : debug_level 3 now prints seconds since start of openocd git-svn-id: svn://svn.berlios.de/openocd/trunk@330 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-24 oharboe + + * : sharpend JTAG docs w.r.t. hw fifo implementations and retired + jtag_cancel_queue() which is inheritely incompatible with a hw fifo + concept. git-svn-id: svn://svn.berlios.de/openocd/trunk@328 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-24 oharboe + + * : cosmetic fixes to debug output + phasing out printf() in favour + of logging system. From Pavel Chromy git-svn-id: svn://svn.berlios.de/openocd/trunk@326 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-23 drath + + * : - fix for feroceon CP15 register access (thanks to Niolas Pitre for + this patch) git-svn-id: svn://svn.berlios.de/openocd/trunk@324 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-23 mifi + + * : - added a test document as a starting point - corrected URL information for the repro git-svn-id: svn://svn.berlios.de/openocd/trunk@322 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-22 mifi + + * : - added patch to remove count and time information from log_printf + in case of debug_level is not set to LOG_DEBUG git-svn-id: svn://svn.berlios.de/openocd/trunk@320 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-22 vpalatin + + * : - fix read/write size for small unaligned accesses (thanks Michael + Bruck) git-svn-id: svn://svn.berlios.de/openocd/trunk@318 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-22 mifi + + * : - added patch to make single-stepping more resilient (thanks to + Nicolas Pitre for the patch) git-svn-id: svn://svn.berlios.de/openocd/trunk@316 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-20 ntfreak + + * : - fix bug when using full paths to config files. Thanks Ted Roth git-svn-id: svn://svn.berlios.de/openocd/trunk@314 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-19 ntfreak + + * : - add search paths via new arg -s (-search). Thanks Ted Roth - updated docs for new command git-svn-id: svn://svn.berlios.de/openocd/trunk@312 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-19 ntfreak + + * : - Fixed bug in pathmove for XScale - added virtual address to working_area. - Improved error messages in a number of places - Added ERROR_COMMAND_SYNTAX_ERROR that commands can return to have + syntax printed - Added help for some config commands - Added verification of sw breakpoints with ERROR() message - Removed a couple of exit()'s and replaced with error message - cosmetic fix to armv4_5.c, easier to read - added polymorphic(with default) virt2phys and mmu enable query + function to target.h - added virt2phys command that uses target->type->virt2phys() fn + Thanks to Øyvind Harboe git-svn-id: svn://svn.berlios.de/openocd/trunk@310 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-18 drath + + * : - Fix problems with stuck telnet sessions. Thanks to Øyvind Harboe + for this patch. git-svn-id: svn://svn.berlios.de/openocd/trunk@308 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-18 ntfreak + + * : - arg list now correctly released on error. Thanks Øyvind Harboe git-svn-id: svn://svn.berlios.de/openocd/trunk@306 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-18 ntfreak + + * : - removed a raft of unecessary exit() calls. Issuing a reset will + solve these ails. - now uses jtag_state_pathmove() instead of making assumptions about + implementation of jtag_statemove(). - fixed a couple of bugs in timeout handling - removed megabytes of log output when communication is failing. - sleep is now 300ms as documented instead of 3000ms - fixed error path of bulk write - debug_handler can now be issued during normal operation + has help + text. Thanks Øyvind Harboe git-svn-id: svn://svn.berlios.de/openocd/trunk@304 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-18 ntfreak + + * : - Added a "User:" debug level. These are messages that are intended + for the user and are part of normal operation. - Faster DEBUG/INFO() when they are disabled - target_read/write_buffer() now uses 16 and 32 bit access for + single word aligned requests. Other requests are serviced as quickly + as possible. - *much* faster read/write GDB packets, removing timeout problems. - GDB read/write packets w/single word aligned 32/16 bit access now + use 32/16 bit word access. - working area can now be changed on the fly. Provides a way to move + working area about as MMU is enabled/disabled. - cleaned up error messages for verify_image. Thanks Øyvind Harboe git-svn-id: svn://svn.berlios.de/openocd/trunk@302 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-16 ntfreak + + * : - solve lots of problems with stuck GDB connections, making it + impossible to connect to GDB, handle timeout of acknowledgement, + etc. - "monitor halt/resume" now works correctly - "monitor sleep 10000" no longer makes the GDB protocol lock up. + There is an error message and the protocol recovers nicely + afterwards. - it's now possible to connect to a target which needs a reset + before halt works. - handle failed memory access more gracefully. Connection is now + closed instead of OpenOCD quitting. - *much* improved handling of 2 second timeout on memory read + packets. Especially important w/mouseover evaluation of variables + in Eclipse. - fixed memory leak upon failed memory packet reply. - 'O' packets w/progress info is no longer sent out randomly. - faster packet reply code. - Thanks to Øyvind Harboe for this patch git-svn-id: svn://svn.berlios.de/openocd/trunk@300 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-16 ntfreak + + * : - fix issue with telnet prompt while gdb running git-svn-id: svn://svn.berlios.de/openocd/trunk@298 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-14 ntfreak + + * : - fix programming issue with lpc2101/2 git-svn-id: svn://svn.berlios.de/openocd/trunk@296 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-14 ntfreak + + * : - added check for revA silicon in stm32 flash driver git-svn-id: svn://svn.berlios.de/openocd/trunk@294 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-12 ntfreak + + * : - add autoprobe support to flash info command - auto_erase can now be called from script/config file git-svn-id: svn://svn.berlios.de/openocd/trunk@292 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-11 ntfreak + + * : - telnet prompt behaves correctly for new synchronous + halt/resume/reset commands - removed unused variables in tms470.c git-svn-id: svn://svn.berlios.de/openocd/trunk@290 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-10 ntfreak + + * : - stm32 flash driver now checks for correct target git-svn-id: svn://svn.berlios.de/openocd/trunk@288 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-10 mifi + + * : - added patch to change pathmove handling + + https://lists.berlios.de/pipermail/openocd-development/2008-January/000678.html(thanks to Øyvind for the patch) git-svn-id: svn://svn.berlios.de/openocd/trunk@286 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-07 ntfreak + + * : - added synchronous reset patch, Thanks Øyvind Harboe - added target_init_reset which calls target_process_reset after all + drivers have been initialised git-svn-id: svn://svn.berlios.de/openocd/trunk@284 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-06 mifi + + * : - added patch to solve problem with AT91SAM9260 (dirty register) + (thanks to Øyvind Harboe for the patch) git-svn-id: svn://svn.berlios.de/openocd/trunk@282 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-02-04 ntfreak + + * : Added patch to stop SEGFAULT with missing jtag config lines. + Thanks Øyvind Harboe + + https://lists.berlios.de/pipermail/openocd-development/2008-January/000731.htmlgit-svn-id: svn://svn.berlios.de/openocd/trunk@280 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-27 mifi + + * : - added autoprobe functionality - corrected blocksize handling from GDB "info mem" command (thanks + to Øyvind and Spen for these patches) git-svn-id: svn://svn.berlios.de/openocd/trunk@278 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-24 mifi + + * : - added patch to check some malloc problems. (thanks to Øyvind + Harboe for the patch) git-svn-id: svn://svn.berlios.de/openocd/trunk@276 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-23 mifi + + * : - added patch to fix crash in load_image on corrupt elf file or out + of memory. (thanks to Øyvind Harboe for the patch) git-svn-id: svn://svn.berlios.de/openocd/trunk@274 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-21 bodylove + + * : - Added example config and startup-script for a XScale IXP42x system git-svn-id: svn://svn.berlios.de/openocd/trunk@272 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-21 bodylove + + * : - Synced code with branch git-svn-id: svn://svn.berlios.de/openocd/trunk@270 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-21 bodylove + + * : - Eleminated leading tabs/white space git-svn-id: svn://svn.berlios.de/openocd/trunk@267 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-21 ntfreak + + * : - updated docs for cfi command, added missing ft2232_layout names git-svn-id: svn://svn.berlios.de/openocd/trunk@261 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-17 ntfreak + + * : - add support for cortex_m3 target_request debugmsgs - target request handler disabled by default until a target has been + registered git-svn-id: svn://svn.berlios.de/openocd/trunk@259 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-17 drath + + * : - fixed 'make distcheck' (thanks to Theodore A. Roth for this patch git-svn-id: svn://svn.berlios.de/openocd/trunk@257 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-14 drath + + * : - use correct SCAN_N check value (disabled by default) - add Øyvind Harboe to list of AUTHORS (thanks a lot to Øyvind for + his hard work) git-svn-id: svn://svn.berlios.de/openocd/trunk@255 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-10 ntfreak + + * : - fix gdb packet retransmission omission git-svn-id: svn://svn.berlios.de/openocd/trunk@253 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-10 ntfreak + + * : - added faster gdb packet handling (thanks to oyvind harboe for the + patch) - code reformat git-svn-id: svn://svn.berlios.de/openocd/trunk@251 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2008-01-09 ntfreak + + * : - rename flash_init and flash_erase to flash_init_drivers and + flash_erase_address_range - stops conflicts with redboot. Thanks + Øyvind Harboe - gdb connection not dropped if we fail to allocate memory in query + packets git-svn-id: svn://svn.berlios.de/openocd/trunk@249 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-29 ntfreak + + * : - add support for extended gdb packet R (restart), requires gdb to + be started with target extended-remote git-svn-id: svn://svn.berlios.de/openocd/trunk@247 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-21 mifi + + * : - corrected working_area of LPC2129 script - added LPC2148 script - corrected size of the working_area of the LPC2294 script git-svn-id: svn://svn.berlios.de/openocd/trunk@245 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-20 ntfreak + + * : - removed flash write_image - binary compare function has been moved + to verify_image command - minor code reformat and cleanup - updated docs to include new commands git-svn-id: svn://svn.berlios.de/openocd/trunk@243 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-18 ntfreak + + * : - added patch by Øyvind Harboe to Intel Hex Start Segment Address + Record (Type 3) - added support to parse Motorola Record Count (S5) git-svn-id: svn://svn.berlios.de/openocd/trunk@241 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-17 mifi + + * : - only some cosmetic changes, convert \r\n to unix git-svn-id: svn://svn.berlios.de/openocd/trunk@239 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-17 mifi + + * : - added patch to corrected argument of image_open in + handle_flash_write_image_command (thanks to oyvind Harboe for the + patch) git-svn-id: svn://svn.berlios.de/openocd/trunk@237 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-16 mifi + + * : - removed some compiler warnings - added patch to fix problem in cfi_intel_write_block. In case of cfi_info->write_algorithm is not NULL, target_code_size was not + set. (thanks to oyvind Harboe for the patch) git-svn-id: svn://svn.berlios.de/openocd/trunk@235 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-16 mifi + + * : - initialize num_sectors and sectors in handle_flash_bank_command. + (thanks to oyvind Harboe for this hint) git-svn-id: svn://svn.berlios.de/openocd/trunk@233 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-14 mifi + + * : - added the patch CFI-BE-Fixes-Blockwrite-Support.diff (thanks to + Carsten Schlote for the patch) git-svn-id: svn://svn.berlios.de/openocd/trunk@231 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-14 mifi + + * : Sorry, I have forgotten to add a description for the last + version, where I have added the clear_malloc and fill_malloc + functionality. But the default is the original malloc. git-svn-id: svn://svn.berlios.de/openocd/trunk@229 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-14 mifi + + * : - added patch from Dominic to unlock the ATMEL flash in + cfi_read_atmel_pri_ext - set cfi_info->write_algorithm and cfi_info->erase_check_algorithm + to NULL to get "flash erase_check" command working git-svn-id: svn://svn.berlios.de/openocd/trunk@227 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-10 bodylove + + * : - Stripped trailing spaces (patch preparation) git-svn-id: svn://svn.berlios.de/openocd/trunk@225 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-10 bodylove + + * : - Added PKGLIBDIR define to C options. Allows to store native code fragments at a central place git-svn-id: svn://svn.berlios.de/openocd/trunk@223 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-10 bodylove + + * : Changed openocd version info creation to be more useful. - Now displays subversion revision and svn URL git-svn-id: svn://svn.berlios.de/openocd/trunk@220 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-12-05 bodylove + + * : Merged rev 215 changes from /branches/xscale-ixp-be into trunk: - Obvious fixes to big endian type conversion macros - Fixed obvious typos for byte masks git-svn-id: svn://svn.berlios.de/openocd/trunk@217 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-11-23 ntfreak + + * : - added support for Hitex STM32 Performance Stick - added str9 and stm32 scripts to docs git-svn-id: svn://svn.berlios.de/openocd/trunk@213 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-10-26 ntfreak + + * : - corrected str91x bank1 programming issues - str91x protect_check fixed - bank number now correctly given to str91x flash_config command git-svn-id: svn://svn.berlios.de/openocd/trunk@211 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-10-08 ntfreak + + * : - cleaned up str7, str9 and stm32 flash drivers - str7 flash driver now checks correct busy bits depending on device - str9 flash driver now disables ITCM order as per st programming + manual - added str7 disable_jtag command - added gdb_detach command - updated arm966e cp15 support - fix crash on mingw build when enabling target_request debugmsgs git-svn-id: svn://svn.berlios.de/openocd/trunk@209 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-09-10 mlu + + * : - Fixed display of sector sizes in flash.c - Clean up, remove unused variables and code in armv7, cortex_m3 and + stellaris code - Move restore_context from cortex_m3 to armv7m - Updated halt handling for cortex_m3 git-svn-id: svn://svn.berlios.de/openocd/trunk@206 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-09-05 drath + + * : Patch by Michael Schwingen that - adds support for the Altium universal JTAG cable - adds support for "wiggler2" cable (basically a wiggler with added + LED, documentation coming soon) - adds LED support. The LED is turned on during data transfer - + works fine on Altium and wiggler2. - adds PORT_EXIT pattern that is written to port when exiting, in + order to turn off power on cables that get their power from parallel + port data lines - move port writes (with the system-specific ifdefs) to one central + function - increased image cache size to 2KB (might require more adaptive + cache handling, e.g. LRU) git-svn-id: svn://svn.berlios.de/openocd/trunk@204 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-08-21 drath + + * : - correctly initialize start address for XScale trace buffer decodes + in fill-once mode git-svn-id: svn://svn.berlios.de/openocd/trunk@202 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-08-20 mlu + + * : - Support for AT91SAM7xx512 chips git-svn-id: svn://svn.berlios.de/openocd/trunk@200 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-08-17 drath + + * : - renamed "xscale dump_trace_buffer" to "xscale dump_trace" and + added code for it git-svn-id: svn://svn.berlios.de/openocd/trunk@198 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-08-16 drath + + * : - fixed several bugs in flash writing code (thanks to Pavel Chromy) git-svn-id: svn://svn.berlios.de/openocd/trunk@196 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-08-14 drath + + * : - reworked presto.c to allow use of either FTD2XX or libftdi + (libftdi not functional yet). Configure option changed from + --enable-presto to --enable-presto_ftd2xx and + --enable-presto_libftdi - completed trace point support for use with ARM7/9 DCC - completed debug message output with support for HEX dumps (1, 2 or + 4 byte quantities) - fixed bug in delete_debug_msg_receiver (thanks to Pavel Chromy) - fixed bug in image_add_section (thanks to Pavel Chromy) - at91sam7 sector erase reworked (thanks to Pavel Chromy) - merge consecutive sections during flash image write to work around + possible section alignment issues with LPC2000 targets git-svn-id: svn://svn.berlios.de/openocd/trunk@194 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-08-10 drath + + * : - bumped version information git-svn-id: svn://svn.berlios.de/openocd/trunk@192 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-08-10 drath + + * : - renamed M5960 USB JTAG to "flyswatter" - make ep93xx and at91rm9200 bitbang JTAG interfaces dependant on + ARM host (thanks to Vincent Palatin) - various whitespace fixes - removed various warnings - add support for Debian GNU/kFreeBSD (thanks to Uwe Hermann) - fix OpenOCD compilation for various platforms (thanks to Uwe + Hermann and Vincent Palatin) - switched order of JTAG chain examination and validation (examine + first, then multiple validation tries even if examination failed) - added target_request subsystem to handle requests from the target + (debug messages and tracepoints implemented, future enhancements + might include semihosting, all ARM7/9 only for now) - added support for GDB vFlashXXX packets (thanks to Pavel Chromy) - added support for receiving data via ARM7/9 DCC - reworked flash writing. the 'flash write' command is now + deprecated and replaced by 'flash write_binary' (old syntax and + behaviour) and 'flash write_image' (write image files (bin, hex, + elf, s19) to a target). - added support for AMD/ST/SST 29F400B non-cfi flashes git-svn-id: svn://svn.berlios.de/openocd/trunk@190 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-07-31 drath + + * : - cleaned up cycle counting in ETM analysis - fixed broken OpenOCD version string git-svn-id: svn://svn.berlios.de/openocd/trunk@188 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-07-31 drath + + * : - calculate cycles since last executed instruction when + cycle-accurate tracing is enabled - increase memory pseudo-image cache size to 1024 byte for improved + trace analysis performance - added OpenOCD+trace as an ETM capture driver example + implementation - new usbprog driver (thanks to Benedikt Sauter) git-svn-id: svn://svn.berlios.de/openocd/trunk@186 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-07-26 ntfreak + + * : - corrected stm32x_handle_options_write_command, incorrect options + printed - added prepare_reset_halt handler for cortex_m3 git-svn-id: svn://svn.berlios.de/openocd/trunk@184 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-07-26 drath + + * : - documentation fixes (thanks to Uwe Hermann) - bootstrapping changes to accomodate packaging (thanks to Uwe + Hermann) git-svn-id: svn://svn.berlios.de/openocd/trunk@182 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-07-15 drath + + * : - added support for Asix Presto JTAG interface (thanks to Pavel + Chromy and Asix for making this addition possible) - added support for usbprog (thanks to Benedikt Sauter) - make OpenOCD listen for WM_QUIT messages on windows (thanks to + Pavel Chromy) - register at_exit handler to do necessary unregistering (thanks to + Pavel Chromy) - added dummy ETM capture driver to allow ETM to be registered + without a capture driver git-svn-id: svn://svn.berlios.de/openocd/trunk@180 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-06-24 ntfreak + + * : - ST STM32x cortex support added - ST STM32x flash support added - cleaned up armv7m and cortex-m3 support, removed luminary specific + code - cortex-m3 16bit read/write added (required for STM32x flash + programming) git-svn-id: svn://svn.berlios.de/openocd/trunk@177 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-06-16 ntfreak + + * : - str9xpec driver was using stricmp, changed to strcmp for posix + compatibility git-svn-id: svn://svn.berlios.de/openocd/trunk@175 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-06-15 drath + + * : - added support for pseudo image type "mem", currently only used for + etm analysis: "etm image mem" git-svn-id: svn://svn.berlios.de/openocd/trunk@173 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-06-14 drath + + * : - added stellaris.[ch] missing from Cortex-M3 merge git-svn-id: svn://svn.berlios.de/openocd/trunk@171 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-06-14 drath + + * : - added manpage for OpenOCD (thanks to Uwe Hermann) - fixed bug in ARM926EJ-S cache handling that caused cache linefills + to be disabled after first debug entry - added support for auto image type detection (thanks to Vincent + Palatin) - further work on ETM trace decoding (tested with a ETB interface + using an ETM in normal 16-bit port mode, still experimental) git-svn-id: svn://svn.berlios.de/openocd/trunk@169 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-05-30 drath + + * : - reworked image handling to support multiple sections (tested with + ihex file containing gaps) This checkin is still experimental, not + recommended for general use git-svn-id: svn://svn.berlios.de/openocd/trunk@159 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-05-29 drath + + * : - add missing image handling files git-svn-id: svn://svn.berlios.de/openocd/trunk@156 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-05-10 ntfreak + + * : -- corrected embedded ice definitions -- changed arm966e to use + standard arm9_7 reset handling git-svn-id: svn://svn.berlios.de/openocd/trunk@146 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-04-28 ntfreak + + * : - added support for Hitex comstick. git-svn-id: svn://svn.berlios.de/openocd/trunk@144 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-04-25 drath + + * : - added support for error handlers to JTAG scan commands + (jtag_[plain_][ir|dr]_scan) - catch apparently broken JTAG IR scan after ARM926EJ-S CP15 + operations - added "arm7_9 dump_etb" command git-svn-id: svn://svn.berlios.de/openocd/trunk@142 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-04-16 drath + + * : - allow multiple USB vendor and product ids when searching for + connected FT2232 based JTAG interfaces (thanks to Werner Almesberger + for this patch) git-svn-id: svn://svn.berlios.de/openocd/trunk@140 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-04-11 drath + + * : - disabled excessive debug output in jtag.h - output all of EmbeddedICE version register in error message - update OpenOCD's idea of the current core mode, and immediately + change core mode, on CPSR changes - added support for CFI cmdset 0002 (patch by Andrew Dyer, thanks a + lot) - enhanced CFI cmdset 0002 support to Atmel AT49 flashes (thanks to + Joerg Krein for providing test hardware) git-svn-id: svn://svn.berlios.de/openocd/trunk@138 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-03-29 drath + + * : - added "arm9tdmi vector_catch ['all'|'none'|'vec1 [vec2 [...]]']" + command - added missing arm926ej-s cp15 patch (thanks Vincent Palatin) git-svn-id: svn://svn.berlios.de/openocd/trunk@136 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-03-26 drath + + * : - fixed arm926 cp15 command bug (thanks to Vincent Palatin for this + patch) - fixed compiler warnings throughout the code (thanks to Vincent + Palatin for this patch) - added support for accessing ETB (embedded trace buffer) registers git-svn-id: svn://svn.berlios.de/openocd/trunk@134 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-03-15 drath + + * : - reworked file i/o. every fileaccess (target, flash, nand, in + future configuration, too) should now go through the fileio + subsystem - added support for reading IHEX files (through fileio) - load/dump_binary renamed to the more generic load/dump_image +
['bin'|'ihex'] - added NAND framework (preliminary) - added support for the LPC3180 SLC and MLC NAND controllers + (preliminary) - fix initialization for parport - gw16012 fixes/cleanups - added EmbeddedICE version 7 (preliminary, reported on two LPC23xx + devices so far) - added 'arm7_9 etm ' configuration command to enable + access to the ETM registers git-svn-id: svn://svn.berlios.de/openocd/trunk@132 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-02-03 drath + + * : - add missing parentheses around macro parameters (thanks to + Matthias Bauch for noticing this bug and providing a fix) git-svn-id: svn://svn.berlios.de/openocd/trunk@130 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-01-26 drath + + * : - disabled use of single-step bit for EmbeddedICE version 6 cores git-svn-id: svn://svn.berlios.de/openocd/trunk@128 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-01-25 drath + + * : - Added support for ARM926EJ-S based cores - Added contributors to AUTHORS file - Added link to Joern Kaipf's OOCD-Link git-svn-id: svn://svn.berlios.de/openocd/trunk@126 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2007-01-18 ntfreak + + * : - added support for ST flashlink cable git-svn-id: svn://svn.berlios.de/openocd/trunk@123 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-11-22 drath + + * : - checked in missing configure.in changes for GW16012 support git-svn-id: svn://svn.berlios.de/openocd/trunk@117 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-11-07 drath + + * : - added support for the oocd-link + (http://www.joernonline.de/dw/doku.php?id=en:projects:oocdlink) - fixed breakpoint handling (this changes the target_t interface) git-svn-id: svn://svn.berlios.de/openocd/trunk@113 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-10-23 drath + + * : - several small fixes (thanks to Magnus Lundin and Spencer Oliver) - added support for using Luminary Micro development board + 'evb_lm3s811' as a JTAG interface (thanks to Magnus Lundin) git-svn-id: svn://svn.berlios.de/openocd/trunk@106 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-10-12 drath + + * : - allow FT2232 devices to be opened by serial number instead of + device description ('ft2232_serial ' command) - redirect output from target event scripts (currently only reset) + to the daemon output (INFO:) - some minor fixes and enhancements git-svn-id: svn://svn.berlios.de/openocd/trunk@103 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-10-03 drath + + * : - fixed regression in gdb_server.c (Thanks to Michael Fischer for + finding these bugs) git-svn-id: svn://svn.berlios.de/openocd/trunk@101 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-09-12 drath + + * : - allow writes to second flash bank on STR71x devices (cleaned up + sector list building) - cleaned up str7x flash erase and protect code (use two accesses to + erase sectors in both banks) git-svn-id: svn://svn.berlios.de/openocd/trunk@98 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-09-07 drath + + * : - free working area used to store flash write buffer git-svn-id: svn://svn.berlios.de/openocd/trunk@96 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-09-04 drath + + * : - added debug output for D/I FSR and FAR (arm920t) - fixed bug that caused CPSR to be corrupted in Thumb mode git-svn-id: svn://svn.berlios.de/openocd/trunk@93 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-08-31 drath + + * : - added missing AT91RM9200 files - bumped OpenOCD version date git-svn-id: svn://svn.berlios.de/openocd/trunk@91 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-08-20 drath + + * : - made bp command more verbose - fixed bug that could result in register corruption on arm920t + targets git-svn-id: svn://svn.berlios.de/openocd/trunk@89 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-08-17 drath + + * : - renamed jtag_interface_t.support_statemove to + jtag_interface_t.support_pathmove (it is used to indicate + jtag_add_pathmove support) - fixed small bug in str7x.c that printed an address instead of the + target number in an error message - added support for Olimex ARM-USB-OCD. The new ft2232 layout is + called "olimex-jtag" git-svn-id: svn://svn.berlios.de/openocd/trunk@87 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-08-14 drath + + * : - updated configuration examples, installation instructions and + README (including list of supported JTAG interfaces) git-svn-id: svn://svn.berlios.de/openocd/trunk@85 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-08-11 drath + + * : - added support for FreeBSD ppi (parallel port access similar to + /dev/parport on linux) (thanks to Darius for this patch) - unified 'ftd2xx' and 'ftdi2232' into a single interface 'ft2232'. + The library used to access the hardware is choosen during configure + with --enable-ft2232_ftd2xx or --enable-ft2232-libftdi. git-svn-id: svn://svn.berlios.de/openocd/trunk@83 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-08-06 drath + + * : - fixed a minor problem with the GDB server that could drop the + first packet (non-fatal) - fixed some small memory leaks (thanks to Spencer Oliver) - verify chip- and buswidth of cfi flash configurations - added support for ARM966E based systems (tested only with ST micro + STR9, thanks to Spencer Oliver) git-svn-id: svn://svn.berlios.de/openocd/trunk@81 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-07-30 drath + + * : - added configurable delays after reset lines get deasserted. useful + if reset circuitry keeps lines asserted for too long. - additional debug output when opening the parallel port - fixed counting of available arm7/9 watchpoint units - 'flash write' now displays elapsed time git-svn-id: svn://svn.berlios.de/openocd/trunk@79 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-06-25 drath + + * : - fixed bug in Thumb sw breakpoint handling (thanks to Spen for this + patch) - fixed handling of services linked list (thanks to Spen for this + patch) git-svn-id: svn://svn.berlios.de/openocd/trunk@76 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-06-25 drath + + * : - added "version" command (patch from John Hartman, thanks) - fixed bug in telnet history handling (patch from John Hartman, + thanks) - OpenOCD version has been changed from SVN revision number to + date/time git-svn-id: svn://svn.berlios.de/openocd/trunk@74 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-06-16 drath + + * : - keep additional information for decoded instructions git-svn-id: svn://svn.berlios.de/openocd/trunk@69 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + +2006-06-05 drath + + * : - fixed some spelling errors (thanks to Andrew Dyer) git-svn-id: svn://svn.berlios.de/openocd/trunk@67 + b42882b7-edfa-0310-969c-e2dbd0fdcd60 + diff --git a/debuggers/openocd/Doxyfile.in b/debuggers/openocd/Doxyfile.in new file mode 100644 index 00000000..8632ee75 --- /dev/null +++ b/debuggers/openocd/Doxyfile.in @@ -0,0 +1,1517 @@ +# Doxyfile 1.5.8 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = OpenOCD + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, +# Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = YES + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = YES + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text " + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @srcdir@/doc/manual \ + @srcdir@/TODO \ + @srcdir@/BUGS \ + @srcdir@/HACKING \ + @srcdir@/src \ + @builddir@/config.h + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.h \ + *.c \ + *.txt + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = @doxygen_as_html@ + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to FRAME, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. Other possible values +# for this tag are: HIERARCHIES, which will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list; +# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which +# disables this behavior completely. For backwards compatibility with previous +# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE +# respectively. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = @doxygen_as_pdf@ + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = pdflatex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = YES + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = YES + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = *.h + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = HAVE_CONFIG_H + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Options related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/debuggers/openocd/HACKING b/debuggers/openocd/HACKING new file mode 100644 index 00000000..c2e841ab --- /dev/null +++ b/debuggers/openocd/HACKING @@ -0,0 +1,178 @@ +// This file is part of the Doxygen Developer Manual +/** @page patchguide Patch Guidelines + +\attention If you're behind a corporate wall with http only access to the +world, you can still use these instructions! + +\attention You can't send patches to the mailing list anymore at all. Nowadays +you are expected to send patches to the OpenOCD Gerrit GIT server for a +review. + +@section gerrit Submitting patches to the OpenOCD Gerrit server + +OpenOCD is to some extent a "self service" open source project, so to +contribute, you must follow the standard procedures to have the best +possible chance to get your changes accepted. + +The procedure to create a patch is essentially: + +- make the changes +- create a commit +- send the changes to the Gerrit server for review +- correct the patch and re-send it according to review feedback + +Your patch (or commit) should be a "good patch": focus it on a single +issue, and make it be easily reviewable. Don't make +it so large that it's hard to review; split large +patches into smaller ones. (That can also help +track down bugs later on.) All patches should +be "clean", which includes preserving the existing +coding style and updating documentation as needed. + +Say in the commit message if it's a bugfix (describe the bug) or a new +feature. Don't expect patches to merge immediately +for the next release. Be ready to rework patches +in response to feedback. + +Add yourself to the GPL copyright for non-trivial changes. + +@section stepbystep Step by step procedure + +-# Create a Gerrit account at: http://openocd.zylin.com + - On subsequent sign ins, use the full URL prefaced with 'http://' + For example: http://user_identifier.open_id_provider.com + -# Add a username to your profile. + After creating the Gerrit account and signing in, you will need to + add a username to your profile. To do this, go to 'Settings', and + add a username of your choice. + Your username will be required in step 3 and substituted wherever + the string 'USERNAME' is found. + -# Create an SSH public key following the directions on github: + https://help.github.com/articles/generating-ssh-keys . You can skip step 3 + (adding key to Github account) and 4 (testing) - these are useful only if + you actually use Github or want to test whether the new key works fine. + -# Add this new SSH key to your Gerrit account: + go to 'Settings' > 'SSH Public Keys', paste the contents of + ~/.ssh/id_rsa.pub into the text field (if it's not visible click on + 'Add Key ...' button) and confirm by clicking 'Add' button. +-# Clone the git repository, rather than just download the source: + @code + git clone git://git.code.sf.net/p/openocd/code openocd + @endcode + or if you have problems with the "git:" protocol, use + the slower http protocol: + @code + git clone http://git.code.sf.net/p/openocd/code openocd + @endcode +-# Set up Gerrit with your local repository. All this does it +to instruct git locally how to send off the changes. + -# Add a new remote to git using Gerrit username: +@code +git remote add review ssh://USERNAME@openocd.zylin.com:29418/openocd.git +git config remote.review.push HEAD:refs/publish/master +@endcode + Or with http only: +@code +git remote add review http://USERNAME@openocd.zylin.com/p/openocd.git +git config remote.review.push HEAD:refs/publish/master +@endcode + The http password is configured from your gerrit settings - http://openocd.zylin.com/#/settings/http-password. + \note If you want to simplify http access you can also add your http password to the url as follows: +@code +git remote add review http://USERNAME:PASSWORD@openocd.zylin.com/p/openocd.git +@endcode + -# You will need to install this hook, we will look into a better solution: +@code +scp -p -P 29418 USERNAME@openocd.zylin.com:hooks/commit-msg .git/hooks/ +@endcode + Or with http only: +@code +wget http://openocd.zylin.com/tools/hooks/commit-msg +mv commit-msg .git/hooks +chmod +x .git/hooks/commit-msg +@endcode + \note A script exists to simplify the two items above. execute: +@code +tools/initial.sh +@endcode +With @ being your Gerrit username. +-# Set up git with your name and email: +@code +git config --global user.name "John Smith" +git config --global user.email "john@smith.org" +@endcode +-# Work on your patches. Split the work into + multiple small patches that can be reviewed and + applied seperately and safely to the OpenOCD + repository. +@code +while(!done) { + work - edit files using your favorite editor. + run "git commit -s -a" to commit all changes. + run tools/checkpatch.sh to verify your patch style is ok. +} +@endcode + \note use "git add ." before commit to add new files. + + Comment template, notice the short first line w/topic. The topic field + should identify the main part or subsystem the patch touches. Check + git log for examples. +@code +topic: Short comment + +Longer comments over several lines, explaining (where applicable) the +reason for the patch and the general idea the solution is based on, +any major design decisions, etc... + +Signed-off-by: ... +@endcode +-# Next you need to make sure that your patches + are on top of the latest stuff on the server and + that there are no conflicts: +@code +git pull --rebase origin master +@endcode +-# Send the patches to the Gerrit server for review: +@code +git push review +@endcode +-# Forgot something, want to add more? Just make the changes and do: +@code +git commit --amend +git push review +@endcode + +Further reading: http://www.coreboot.org/Git + +@section timeline When can I expect my contribution to be committed? + +The code review is intended to take as long as a week or two to allow +maintainers and contributors who work on OpenOCD only in their spare +time oportunity to perform a review and raise objections. + +With Gerrit much of the urgency of getting things committed has been +removed as the work in progress is safely stored in Gerrit and +available if someone needs to build on your work before it is +submitted to the official repository. + +Another factor that contributes to the desire for longer cool-off +times (the time a patch lies around without any further changes or +comments), it means that the chances of quality regression on the +master branch will be much reduced. + +If a contributor pushes a patch, it is considered good form if another +contributor actually approves and submits that patch. + +It should be noted that a negative review in Gerrit ("-1" or "-2") may (but does +not have to) be disregarded if all conditions listed below are met: + +- the concerns raised in the review have been addressed (or explained), +- reviewer does not re-examine the change in a month, +- reviewer does not answer e-mails for another month. + +@section browsing Browsing Patches +All OpenOCD patches can be reviewed here. +*/ +/** @file +This file contains the @ref patchguide page. +*/ diff --git a/debuggers/openocd/INSTALL b/debuggers/openocd/INSTALL new file mode 100644 index 00000000..6e90e07d --- /dev/null +++ b/debuggers/openocd/INSTALL @@ -0,0 +1,370 @@ +Installation Instructions +************************* + +Copyright (C) 1994-1996, 1999-2002, 2004-2012 Free Software Foundation, +Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf limitation. Until the limitation is lifted, you can use +this workaround: + + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. diff --git a/debuggers/openocd/Makefile.am b/debuggers/openocd/Makefile.am new file mode 100644 index 00000000..722c3732 --- /dev/null +++ b/debuggers/openocd/Makefile.am @@ -0,0 +1,108 @@ +# not a GNU package. You can remove this line, if +# have all needed files, that a GNU package needs +AUTOMAKE_OPTIONS = gnu 1.6 + +# make sure we pass the correct jimtcl flags to distcheck +DISTCHECK_CONFIGURE_FLAGS = --disable-install-jim + +nobase_dist_pkgdata_DATA = \ + contrib/libdcc/dcc_stdio.c \ + contrib/libdcc/dcc_stdio.h \ + contrib/libdcc/example.c \ + contrib/libdcc/README \ + contrib/openocd.udev + +if INTERNAL_JIMTCL +SUBDIRS = jimtcl +else +SUBDIRS = +endif + +SUBDIRS += src doc + +EXTRA_DIST = \ + BUGS \ + HACKING \ + NEWTAPS \ + README.Win32 \ + Doxyfile.in \ + tools/logger.pl \ + contrib/loaders + +libtool: $(LIBTOOL_DEPS) + $(SHELL) ./config.status --recheck + +docs: pdf html doxygen + +Doxyfile: $(srcdir)/Doxyfile.in + @echo "Creating $@ from $<..." + @( \ + echo "### @@@ -= DO NOT EDIT THIS FILE =- @@@ ###" && \ + echo "### @@@ Make changes to Doxyfile.in @@@ ###" && \ + sed -e 's,@srcdir\@,$(srcdir),' \ + -e 's,@builddir\@,$(builddir),' \ + -e 's,@doxygen_as_html\@,$(doxygen_as_html),' \ + -e 's,@doxygen_as_pdf\@,$(doxygen_as_pdf),' $< \ + ) > $@ + +THE_MANUAL = doxygen/latex/refman.pdf + +doxygen:: + $(MAKE) Doxyfile + doxygen Doxyfile 2>&1 | perl $(srcdir)/tools/logger.pl > doxygen.log + @if [ -f doxygen/latex/refman.tex ]; then \ + echo "Creating $(THE_MANUAL)..."; \ + $(MAKE) $(THE_MANUAL); \ + else \ + echo "Skipping Doxygen PDF..."; \ + fi + +$(THE_MANUAL): %.pdf: %.tex + -cd $$(dirname $*) && pdflatex $$(basename $*) + -cd $$(dirname $*) && pdflatex $$(basename $*) + +TCL_PATH = tcl +# command to find paths of script files, relative to TCL_PATH +TCL_FILES = find $(srcdir)/$(TCL_PATH) -name '*.cfg' -o -name '*.tcl' -o -name '*.txt' | \ + sed -e 's,^$(srcdir)/$(TCL_PATH),,' + +dist-hook: + if test -d $(srcdir)/.git -a \( ! -e $(distdir)/ChangeLog -o -w $(distdir)/ChangeLog \) ; then \ + git --git-dir $(srcdir)/.git log | $(srcdir)/tools/git2cl/git2cl > $(distdir)/ChangeLog ; \ + fi + for i in $$($(TCL_FILES)); do \ + j="$(distdir)/$(TCL_PATH)/$$i" && \ + mkdir -p "$$(dirname $$j)" && \ + $(INSTALL_DATA) $(srcdir)/$(TCL_PATH)/$$i $$j; \ + done + +install-data-hook: + for i in $$($(TCL_FILES)); do \ + j="$(DESTDIR)$(pkgdatadir)/scripts/$$i" && \ + mkdir -p "$$(dirname $$j)" && \ + $(INSTALL_DATA) $(srcdir)/$(TCL_PATH)/$$i $$j; \ + done + +uninstall-hook: + rm -rf $(DESTDIR)$(pkgdatadir)/scripts + +distclean-local: + rm -rf Doxyfile doxygen + rm -f $(srcdir)/jimtcl/configure.gnu + +DISTCLEANFILES = doxygen.log + +MAINTAINERCLEANFILES = \ + $(srcdir)/INSTALL \ + $(srcdir)/configure \ + $(srcdir)/Makefile.in \ + $(srcdir)/depcomp \ + $(srcdir)/config.guess \ + $(srcdir)/config.sub \ + $(srcdir)/config.h.in \ + $(srcdir)/config.h.in~ \ + $(srcdir)/compile \ + $(srcdir)/ltmain.sh \ + $(srcdir)/missing \ + $(srcdir)/aclocal.m4 \ + $(srcdir)/install-sh diff --git a/debuggers/openocd/Makefile.in b/debuggers/openocd/Makefile.in new file mode 100644 index 00000000..d57e8cf5 --- /dev/null +++ b/debuggers/openocd/Makefile.in @@ -0,0 +1,934 @@ +# Makefile.in generated by automake 1.13.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/config.h.in $(nobase_dist_pkgdata_DATA) COPYING TODO \ + compile config.guess config.sub install-sh missing ltmain.sh +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config_subdir.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgdatadir)" +DATA = $(nobase_dist_pkgdata_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = src doc jimtcl +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip +GZIP_ENV = --best +DIST_TARGETS = dist-bzip2 dist-gzip dist-zip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +doxygen_as_html = @doxygen_as_html@ +doxygen_as_pdf = @doxygen_as_pdf@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# not a GNU package. You can remove this line, if +# have all needed files, that a GNU package needs +AUTOMAKE_OPTIONS = gnu 1.6 + +# make sure we pass the correct jimtcl flags to distcheck +DISTCHECK_CONFIGURE_FLAGS = --disable-install-jim +nobase_dist_pkgdata_DATA = \ + contrib/libdcc/dcc_stdio.c \ + contrib/libdcc/dcc_stdio.h \ + contrib/libdcc/example.c \ + contrib/libdcc/README \ + contrib/openocd.udev + +@INTERNAL_JIMTCL_FALSE@SUBDIRS = src doc +@INTERNAL_JIMTCL_TRUE@SUBDIRS = jimtcl src doc +EXTRA_DIST = \ + BUGS \ + HACKING \ + NEWTAPS \ + README.Win32 \ + Doxyfile.in \ + tools/logger.pl \ + contrib/loaders + +THE_MANUAL = doxygen/latex/refman.pdf +TCL_PATH = tcl +# command to find paths of script files, relative to TCL_PATH +TCL_FILES = find $(srcdir)/$(TCL_PATH) -name '*.cfg' -o -name '*.tcl' -o -name '*.txt' | \ + sed -e 's,^$(srcdir)/$(TCL_PATH),,' + +DISTCLEANFILES = doxygen.log +MAINTAINERCLEANFILES = \ + $(srcdir)/INSTALL \ + $(srcdir)/configure \ + $(srcdir)/Makefile.in \ + $(srcdir)/depcomp \ + $(srcdir)/config.guess \ + $(srcdir)/config.sub \ + $(srcdir)/config.h.in \ + $(srcdir)/config.h.in~ \ + $(srcdir)/compile \ + $(srcdir)/ltmain.sh \ + $(srcdir)/missing \ + $(srcdir)/aclocal.m4 \ + $(srcdir)/install-sh + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-nobase_dist_pkgdataDATA: $(nobase_dist_pkgdata_DATA) + @$(NORMAL_INSTALL) + @list='$(nobase_dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)/$$dir"; }; \ + echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(pkgdatadir)/$$dir'"; \ + $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(pkgdatadir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_dist_pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(nobase_dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(DATA) config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgdatadir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-local distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-nobase_dist_pkgdataDATA + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-nobase_dist_pkgdataDATA + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +.MAKE: $(am__recursive_targets) all install-am install-data-am \ + install-strip uninstall-am + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \ + dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-local distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-data-hook install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-nobase_dist_pkgdataDATA \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am uninstall-hook \ + uninstall-nobase_dist_pkgdataDATA + + +libtool: $(LIBTOOL_DEPS) + $(SHELL) ./config.status --recheck + +docs: pdf html doxygen + +Doxyfile: $(srcdir)/Doxyfile.in + @echo "Creating $@ from $<..." + @( \ + echo "### @@@ -= DO NOT EDIT THIS FILE =- @@@ ###" && \ + echo "### @@@ Make changes to Doxyfile.in @@@ ###" && \ + sed -e 's,@srcdir\@,$(srcdir),' \ + -e 's,@builddir\@,$(builddir),' \ + -e 's,@doxygen_as_html\@,$(doxygen_as_html),' \ + -e 's,@doxygen_as_pdf\@,$(doxygen_as_pdf),' $< \ + ) > $@ + +doxygen:: + $(MAKE) Doxyfile + doxygen Doxyfile 2>&1 | perl $(srcdir)/tools/logger.pl > doxygen.log + @if [ -f doxygen/latex/refman.tex ]; then \ + echo "Creating $(THE_MANUAL)..."; \ + $(MAKE) $(THE_MANUAL); \ + else \ + echo "Skipping Doxygen PDF..."; \ + fi + +$(THE_MANUAL): %.pdf: %.tex + -cd $$(dirname $*) && pdflatex $$(basename $*) + -cd $$(dirname $*) && pdflatex $$(basename $*) + +dist-hook: + if test -d $(srcdir)/.git -a \( ! -e $(distdir)/ChangeLog -o -w $(distdir)/ChangeLog \) ; then \ + git --git-dir $(srcdir)/.git log | $(srcdir)/tools/git2cl/git2cl > $(distdir)/ChangeLog ; \ + fi + for i in $$($(TCL_FILES)); do \ + j="$(distdir)/$(TCL_PATH)/$$i" && \ + mkdir -p "$$(dirname $$j)" && \ + $(INSTALL_DATA) $(srcdir)/$(TCL_PATH)/$$i $$j; \ + done + +install-data-hook: + for i in $$($(TCL_FILES)); do \ + j="$(DESTDIR)$(pkgdatadir)/scripts/$$i" && \ + mkdir -p "$$(dirname $$j)" && \ + $(INSTALL_DATA) $(srcdir)/$(TCL_PATH)/$$i $$j; \ + done + +uninstall-hook: + rm -rf $(DESTDIR)$(pkgdatadir)/scripts + +distclean-local: + rm -rf Doxyfile doxygen + rm -f $(srcdir)/jimtcl/configure.gnu + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/debuggers/openocd/NEWS b/debuggers/openocd/NEWS new file mode 100644 index 00000000..47a8fa66 --- /dev/null +++ b/debuggers/openocd/NEWS @@ -0,0 +1,43 @@ +This file includes highlights of the changes made in the +OpenOCD source archive release. See the +repository history for details about what changed, including +bugfixes and other issues not mentioned here. + +JTAG Layer: + New TI ICDI adapter support. + Support Latest OSBDM firmware. + Improved MIPS EJTAG Support. + +Boundary Scan: + +Target Layer: + New ARMv7R and Cortex-R4 support. + Added ChibiOS/RT support. + +Flash Layer: + New NXP LPC1850 support. + New NXP LPC4300 support. + New NXP SPIFI support. + New Energy Micro EFM32 support. + New ST STM32W support. + New ST STM32f2 write protection and lock/unlock support. + Ability to override STM32 flash bank size. + +Board, Target, and Interface Configuration Scripts: + Support Freescale i.MX6 series targets. + +Documentation: + New MIPS debugging info. + +Build and Release: + +For more details about what has changed since the last release, +see the git repository history. With gitweb, you can browse that +in various levels of detail. + +For older NEWS, see the NEWS files associated with each release +(i.e. NEWS-). + +For more information about contributing test reports, bug fixes, or new +features and device support, please read the new Developer Manual (or +the BUGS and PATCHES.txt files in the source archive). diff --git a/debuggers/openocd/NEWTAPS b/debuggers/openocd/NEWTAPS new file mode 100644 index 00000000..638fa005 --- /dev/null +++ b/debuggers/openocd/NEWTAPS @@ -0,0 +1,145 @@ +Reporting Unknown JTAG TAP IDS +------------------------------ + +If OpenOCD reports an UNKNOWN or Unexpected Tap ID please report it to +the development mailing list - However - keep reading. + +openocd-devel@lists.sourceforge.net. + +======================================== + +About "UNEXPECTED" tap ids. + + Before reporting an "UNEXPECTED TAP ID" - take a closer look. + Perhaps you have your OpenOCD configured the wrong way, maybe you + have the tap configured the wrong way? Or something else is wrong. + (Remember: OpenOCD does not stop if the tap is not present) + + This "tap id check" is there for a purpose. + The goal is to help get the *right* configuration. + +The idea is this: + + Every JTAG tap is suppose to have "a unique 32bit tap id" number. + They are suppose to be "sort of unique" but they are not. There are + no guarantees. + +Version Number Changes: + + Sometimes, the tap ID only differs by VERSION number. If so - it's + not a big deal. Please do report this information. We'd like to + know about it. + + For example + +Error: ERROR: Tap: s3c4510.cpu - Expected id: 0x3f0f0f0f, Got: 0x1f0f0f0f +Error: ERROR: expected: mfg: 0x787, part: 0xf0f0, ver: 0x3 +Error: ERROR: got: mfg: 0x787, part: 0xf0f0, ver: 0x1 + +======================================== + +Updating the Tap ID number your self + + Why do this? You just want the warning to go away. And don't want + to update your version/instance of OpenOCD. + + On simple systems, to fix this problem, in your "openocd.cfg" file, + override the tap id. Depending on the tap, add one of these 3 + commands: + + set CPUTAPID newvalue + or set BSTAPID newvalue + or set FLASHTAPID newvalue + or set ETMTAPID newvalue + + Where "newvalue" is the new value you are seeing. + + On complex systems, (with many taps and chips) you probably have a + custom configuration file. Its is more complicated, you're going to + have to read through the configuration files + +======================================== + +What to send: + +Cut & paste the output of OpenOCD that pointed you at this file. + +Please include the VERSION number of OpenOCD you are using. + +And please include the information below. + +======================================== + +A) The JTAG TAP ID code. + +This is always a 32bit hex number. + +Examples: + 0x1f0f0f0f - is an old ARM7TDMI + 0x3f0f0f0f - is a newer ARM7TDMI + 0x3ba00477 - is an ARM cortex M3 + +Some chips have multiple JTAG taps - be sure to list +each one individually - ORDER is important! + +======================================== +B) The maker of the part + +Examples: + Xilinx, Atmel, ST Micro Systems, Freescale + +======================================== +C) The family of parts it belongs to + +Examples: + "NXP LPC Series" + "Atmel SAM7 Series" + +======================================== + +D) The actual part number on the package + + For example: "S3C45101x01" + +======================================== + +E) What type of board it is. + +ie: a "commercial off the self eval board" that one can purchase (as +opposed to your private internal custom board) + +For example: ST Micro systems has Eval boards, so does Analog Devices + +Or - if it is inside something "hackers like to hack" that information +is helpful too. + +For example: A consumer GPS unit or a cellphone + +======================================== + +(F) The maker of the board + ie: Olimex, LogicPD, Freescale(eval board) + +======================================== + +(G) Identifying information on the board. + + Not good: "iar red ST eval board" + + Really good: "IAR STR912-SK evaluation board" + +======================================== + +(H) Are there other interesting (JTAG) chips on the board? + + ie: An FPGA or CPLD ... + +======================================== + +(I) What target config files need updating? + + In fact it's best if you submit a patch with those + updates. Most of the other information listed here + is just to help create a good patch. + +======================================== diff --git a/debuggers/openocd/README b/debuggers/openocd/README new file mode 100644 index 00000000..6a832174 --- /dev/null +++ b/debuggers/openocd/README @@ -0,0 +1,461 @@ +Welcome to OpenOCD! +=================== + +OpenOCD provides on-chip programming and debugging support with a +layered architecture of JTAG interface and TAP support, debug target +support (e.g. ARM, MIPS), and flash chip drivers (e.g. CFI, NAND, etc.). +Several network interfaces are available for interactiving with OpenOCD: +HTTP, telnet, TCL, and GDB. The GDB server enables OpenOCD to function +as a "remote target" for source-level debugging of embedded systems +using the GNU GDB program. + +This README file contains an overview of the following topics: +- how to find and build more OpenOCD documentation, +- the build process +- packaging tips. +- configuration options + +===================== +OpenOCD Documentation +===================== + +In addition to in-tree documentation, the latest documentation may be +viewed on-line at the following URLs: + + OpenOCD User's Guide: + http://openocd.sourceforge.net/doc/html/index.html + + OpenOCD Developer's Manual: + http://openocd.sourceforge.net/doc/doxygen/html/index.html + +These reflect the latest development versions, so the following section +introduces how to build the complete documentation from the package. + + +For more information, refer to these documents or contact the developers +by subscribing to the OpenOCD developer mailing list: + + openocd-devel@lists.sourceforge.net + +Building the OpenOCD Documentation +---------------------------------- + +The OpenOCD User's Guide can be produced in two different format: + + # If PDFVIEWER is set, this creates and views the PDF User Guide. + make pdf && ${PDFVIEWER} doc/openocd.pdf + + # If HTMLVIEWER is set, this creates and views the HTML User Guide. + make html && ${HTMLVIEWER} doc/openocd.html/index.html + +The OpenOCD Developer Manual contains information about the internal +architecture and other details about the code: + + # NB! make sure doxygen is installed, type doxygen --version + make doxygen + + # If HTMLVIEWER is set, this views the HTML Doxygen output. + ${HTMLVIEWER} doxygen/index.html + +The remaining sections describe how to configure the system such that +you can build the in-tree documentation. + +================== +Installing OpenOCD +================== + +On Linux, you may have permissions problems to address. The best way +to do this is to use the contrib/openocd.udev rules file. It probably +belongs somewhere in /etc/udev/rules.d, but consult your operating +system documentation to be sure. In particular, make sure that it +matches the syntax used by your operating system's version of udev. + +A Note to OpenOCD Users +----------------------- + +If you would rather be working "with" OpenOCD rather than "on" it, your +operating system or JTAG interface supplier may provide binaries for +you in a convenient-enough package. + +Such packages may be more stable than git mainline, where bleeding-edge +development takes place. These "Packagers" produce binary releases of +OpenOCD after the developers produces new "release" versions of the +source code. Previous versions of OpenOCD cannot be used to diagnose +problems with the current release, so users are encouraged to keep in +contact with their distribution package maintainers or interface vendors +to ensure suitable upgrades appear regularly. + +Users of these binary versions of OpenOCD must contact their Packager to +ask for support or newer versions of the binaries; the OpenOCD +developers do not support packages directly. + +A Note to OpenOCD Packagers +--------------------------- + +You are a PACKAGER of OpenOCD if you: + +- Sell dongles: and include pre-built binaries +- Supply tools: A complete development solution +- Supply IDEs: like Eclipse, or RHIDE, etc. +- Build packages: RPM files, or DEB files for a Linux Distro + +As a PACKAGER, you will experience first reports of most issues. +When you fix those problems for your users, your solution may help +prevent hundreds (if not thousands) of other questions from other users. + +If something does not work for you, please work to inform the OpenOCD +developers know how to improve the system or documentation to avoid +future problems, and follow-up to help us ensure the issue will be fully +resolved in our future releases. + +That said, the OpenOCD developers would also like you to follow a few +suggestions: + +- Send patches, including config files, upstream. +- Always build with printer ports enabled. +- Use libftdi + libusb for FT2232 support. + +Remember, the FTD2XX library cannot be used in binary distributions, due +to restrictions of the GPL v2. + +================ +Building OpenOCD +================ + +The INSTALL file contains generic instructions for running 'configure' +and compiling the OpenOCD source code. That file is provided by default +for all GNU automake packages. If you are not familiar with the GNU +autotools, then you should read those instructions first. + +The remainder of this document tries to provide some instructions for +those looking for a quick-install. + +OpenOCD Dependencies +-------------------- + +Presently, GCC is required to build OpenOCD. The developers have begun +to enforce strict code warnings (-Wall, -Werror, -Wextra, and more) and +use C99-specific features: inline functions, named initializers, mixing +declarations with code, and other tricks. While it may be possible to +use other compilers, they must be somewhat modern and could require +extending support to conditionally remove GCC-specific extensions. + +Also, you need to install the appropriate driver files, if you want to +build support for a USB or FTDI-based interface: + +- ft2232, jlink, rlink, vsllink, usbprog, arm-jtag-ew: + - libusb: required for portable communication with USB dongles +- ft2232 also requires: + - libftdi: http://www.intra2net.com/opensource/ftdi/ *OR* + - ftd2xx: http://www.ftdichip.com/Drivers/D2XX.htm, + or the Amontec version (from http://www.amontec.com), for + easier support of JTAGkey's vendor and product IDs. + +Many Linux distributions provide these packages through their automated +installation and update mechanisms; however, some Linux versions include +older versions of libftdi. In particular, using Ubuntu 8.04 has been +problematic, but newer versions of Ubuntu do not have this problem. + +Compiling OpenOCD +----------------- + +To build OpenOCD (on both Linux and Cygwin), use the following sequence +of commands: + + ./configure [with some options listed in the next section] + make + make install + +The 'configure' step generates the Makefiles required to build OpenOCD, +usually with one or more options provided to it. The first 'make' step +will build OpenOCD and place the final executable in ./src/. The +final (optional) step, ``make install'', places all of the files in the +required location. + +Cross-Compiling Options +----------------------- + +To cross-compile, you must specify both --build and --host options to +the 'configure' script. For example, you can configure OpenOCD to +cross-compile on a x86 Linux host to run on Windows (MinGW32), you could +use the following configuration options: + + ./configure --build=i686-pc-linux-gnu --host=i586-mingw32msvc ... + +Likewise, the following options allow OpenOCD to be cross-compiled for +an ARM target on the same x86 host: + + ./configure --build=i686-pc-linux-gnu --host=arm-elf ... + +Both must be specified to work around bugs in autoconf. + +Scripts for producing ARM cross-compilers can be found on the web with a +little searching. A script to produce an x86 Linux-hosted MinGW32 +cross-compiler can be downloaded from the following URL: + + http://www.mingw.org/wiki/LinuxCrossMinGW + +Configuration Options +--------------------- + +The configure script takes numerous options, specifying which JTAG +interfaces should be included (among other things). The following list +of options was extracted from the output of './configure --help'. Other +options may be available there: + + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + NOTE: This option is *required* for GIT builds! + It should *not* be used to build a release. + + --enable-dummy Enable building the dummy JTAG port driver + + --enable-parport Enable building the pc parallel port driver + --disable-parport-ppdev Disable use of ppdev (/dev/parportN) for parport + (for x86 only) + --enable-parport-giveio Enable use of giveio for parport (for CygWin only) + + --enable-ftdi Enable building support for the MPSSE mode of FTDI + based devices, using libusb-1.0 in asynchronous mode + + --enable-ft2232_libftdi Enable building support for FT2232 based devices + using the libftdi driver, opensource alternate of + FTD2XX + --enable-ft2232_ftd2xx Enable building support for FT2232 based devices + using the FTD2XX driver from ftdichip.com + + --enable-usb_blaster_libftdi + Enable building support for the Altera USB-Blaster + using the libftdi driver, opensource alternate of + FTD2XX + --enable-usb_blaster_ftd2xx + Enable building support for the Altera USB-Blaster + using the FTD2XX driver from ftdichip.com + + --enable-amtjtagaccel Enable building the Amontec JTAG-Accelerator driver + + --enable-zy1000-master Use ZY1000 JTAG master registers + --enable-zy1000 Enable ZY1000 interface + + --enable-ioutil Enable ioutil functions - useful for standalone + OpenOCD implementations + + --enable-ep93xx Enable building support for EP93xx based SBCs + + --enable-at91rm9200 Enable building support for AT91RM9200 based SBCs + + --enable-gw16012 Enable building support for the Gateworks GW16012 + JTAG Programmer + + --enable-presto_libftdi Enable building support for ASIX Presto Programmer + using the libftdi driver + --enable-presto_ftd2xx Enable building support for ASIX Presto Programmer + using the FTD2XX driver + + --enable-usbprog Enable building support for the usbprog JTAG + Programmer + + --enable-oocd_trace Enable building support for some prototype + OpenOCD+trace ETM capture hardware + + --enable-jlink Enable building support for the Segger J-Link JTAG + Programmer + + --enable-vsllink Enable building support for the Versaloon-Link JTAG + Programmer + + --enable-rlink Enable building support for the Raisonance RLink + JTAG Programmer + --enable-ulink Enable building support for the Keil ULINK JTAG + Programmer + --enable-arm-jtag-ew Enable building support for the Olimex ARM-JTAG-EW + Programmer + + --enable-buspirate Enable building support for the Buspirate + + --enable-stlink Enable building support for the ST-Link JTAG + Programmer + --enable-ti-icdi Enable building support for the TI/Stellaris ICDI + JTAG Programmer + + --enable-osbdm Enable building support for the OSBDM (JTAG only) + Programmer + + --enable-opendous Enable building support for the estick/opendous JTAG + Programmer + --enable-sysfsgpio Enable building support for programming driven via + sysfs gpios. + + --enable-minidriver-dummy + Enable the dummy minidriver. + + --disable-internal-jimtcl + Disable building internal jimtcl + --enable-libusb0 Use libusb-0.1 library for USB JTAG devices + --enable-remote-bitbang Enable building support for the Remote Bitbang jtag + driver + + --disable-doxygen-html Disable building Doxygen manual as HTML. + --enable-doxygen-pdf Enable building Doxygen manual as PDF. + +Miscellaneous Configure Options +------------------------------- + +The following additional options may also be useful: + + --disable-assert turn off assertions + + --enable-verbose Enable verbose JTAG I/O messages (for debugging). + --enable-verbose-jtag-io + Enable verbose JTAG I/O messages (for debugging). + --enable-verbose-usb-io Enable verbose USB I/O messages (for debugging) + --enable-verbose-usb-comms + Enable verbose USB communication messages (for + debugging) + --enable-malloc-logging Include free space in logging messages (requires + malloc.h). + + --disable-gccwarnings Disable extra gcc warnings during build. + --disable-wextra Disable extra compiler warnings + --disable-werror Do not treat warnings as errors + + --disable-option-checking + Ignore unrecognized --enable and --with options. + --disable-dependency-tracking speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=no] + --enable-static[=PKGS] build static libraries [default=yes] + +Parallel Port Dongles +--------------------- + +If you want to access the parallel port using the PPDEV interface you +have to specify both --enable-parport AND --enable-parport-ppdev, since the +the later option is an option to the parport driver (see +http://forum.sparkfun.com/viewtopic.php?t=3795 for more info). + +The same is true for the --enable-parport-giveio option, you +have to use both the --enable-parport AND the --enable-parport-giveio +option if you want to use giveio instead of ioperm parallel port access +method. + +FT2232C Based USB Dongles +------------------------- + +There are 2 methods of using the FTD2232, either (1) using the +FTDICHIP.COM closed source driver, or (2) the open (and free) driver +libftdi. + +Using LIBFTDI +------------- + +The libftdi source code can be download from the following website: + + http://www.intra2net.com/en/developer/libftdi/download.php + +For both Linux and Windows, both libusb and libftdi must be built and +installed. To use the newer FT2232H chips, supporting RTCK and USB high +speed (480 Mbps), use libftdi version 0.17 or newer. Many Linux +distributions provide suitable packages for these libraries. + +For Windows, libftdi is supported with versions 0.14 and later. + +With these prerequisites met, configure the libftdi solution like this: + + ./configure --prefix=/path/for/your/install --enable-ft2232_libftdi + +Then type ``make'', and perhaps ``make install''. + +Using FTDI's FTD2XX +------------------- + +The (closed source) FTDICHIP.COM solution is faster on MS-Windows. That +is the motivation for supporting it even though its licensing restricts +it to non-redistributable OpenOCD binaries, and it is not available for +all operating systems used with OpenOCD. You may, however, build such +copies for personal use. + +The FTDICHIP drivers come as either a (win32) ZIP file, or a (Linux) +TAR.GZ file. You must unpack them ``some where'' convenient. As of this +writing FTDICHIP does not supply means to install these files "in an +appropriate place." + +If your distribution does not package these, there are several +'./configure' options to solve this problem: + + --with-ftd2xx-win32-zipdir + Where (CYGWIN/MINGW) the zip file from ftdichip.com + was unpacked + --with-ftd2xx-linux-tardir + Where (Linux/Unix) the tar file from ftdichip.com + was unpacked + --with-ftd2xx-lib Use static or shared ftd2xx libs on default static + +If you are using the FTDICHIP.COM driver, download and unpack the +Windows or Linux FTD2xx drivers from the following location: + + http://www.ftdichip.com/Drivers/D2XX.htm + +Remember, this library is binary-only, while OpenOCD is licenced +according to GNU GPLv2 without any exceptions. That means that +_distributing_ copies of OpenOCD built with the FTDI code would violate +the OpenOCD licensing terms. + +Linux Notes +*********** + +The Linux tar.gz archive contains a directory named libftd2xx0.4.16 +(or similar). Assuming that you have extracted this archive in the same +directory as the OpenOCD package, you could configure with options like +the following: + + ./configure \ + --enable-ft2232_ftd2xx \ + --with-ft2xx-linux-tardir=../libftd2xx0.4.16 \ + ... other options ... + +Note that on Linux there is no good reason to use these FTDI binaries; +they are no faster (on Linux) than libftdi, and cause licensing issues. + +========================== +Obtaining OpenOCD From GIT +========================== + +You can download the current GIT version with a GIT client of your +choice from the main repository: + + git://git.code.sf.net/p/openocd/code + +You may prefer to use a mirror: + + http://repo.or.cz/r/openocd.git + git://repo.or.cz/openocd.git + +Using the GIT command line client, you might use the following command +to set up a local copy of the current repository (make sure there is no +directory called "openocd" in the current directory): + + git clone git://git.code.sf.net/p/openocd/code openocd + +Then you can update that at your convenience using + + git pull + +There is also a gitweb interface, which you can use either to browse +the repository or to download arbitrary snapshots using HTTP: + + http://repo.or.cz/w/openocd.git + +Snapshots are compressed tarballs of the source tree, about 1.3 MBytes +each at this writing. + + +Tips For Building From a GIT Repository +--------------------------------------- + +Building OpenOCD from a repository requires a recent version of the GNU +autotools (autoconf >= 2.59 and automake >= 1.9). + +1) Run './bootstrap' to create the 'configure' script and prepare + the build process for your host system. + +2) Run './configure --enable-maintainer-mode' with other options. diff --git a/debuggers/openocd/README.Win32 b/debuggers/openocd/README.Win32 new file mode 100644 index 00000000..6c690c9c --- /dev/null +++ b/debuggers/openocd/README.Win32 @@ -0,0 +1,98 @@ +Building OpenOCD for Windows +---------------------------- + +For building on Windows, you have to use CygWin. Make sure that your +PATH environment variable contains no other locations with Unix utilities +(like UnxUtils). Those tools can't handle the CygWin paths, resulting +in obscure dependency errors. This was an observation gathered from the +logs of one user; please correct us if this is wrong. + +The following URL is a good reference if you want to build OpenOCD +under CygWin: + + http://forum.sparkfun.com/viewtopic.php?t=11221 + +Alternatively you can build the Windows binary under Linux using +MinGW cross compiler. The following documents some tips of +using this cross build option. + +libusb-win32 +------------ + +You can choose to use the libusb-win32 binary distribution from +its SourceForge page. As of this writing, the latest version +is 0.1.12.2. This is the recommend version to use since it fixed +an issue with USB composite device and this is important for FTDI +based JTAG debuggers. + + http://sourceforge.net/projects/libusb-win32/ + +You need to download the libusb-win32-device-bin-0.1.12.2.tar.gz +package. Extract this file into a temp directory. + +Copy the file libusb-win32-device-bin-0.1.12.2\include\usb.h +to your MinGW include directory. + +Copy the library libusb-win32-device-bin-0.1.12.2\lib\gcc\libusb.a +to your MinGW library directory. + +Take note that different Linux distributions often have different MinGW +installation directory. Some of them also put the library and include +into a separate sys-root directory. + +When the libusb-win32 repository is more current than its release code, +you could build that instead. + +These are the instruction from the libusb-win32 Makefile: + +# If you're cross-compiling and your mingw32 tools are called +# i586-mingw32msvc-gcc and so on, then you can compile libusb-win32 +# by running +# make host_prefix=i586-mingw32msvc all + +libftdi +------- + +The author does not provide Windows binary. You can build it from a +released source tarball or the git tree. + +If you are using the git tree, the following are the instructions from +README.mingw. You will need to have the cmake utility installed. + +- Edit Toolchain-mingw32.cmake to point to the correct MinGW + installation. +- Create a build directory like "mkdir build-win32", e.g in ../libftdi/ +- cd into that directory and run + "cmake -DCMAKE_TOOLCHAIN_FILE=../Toolchain-mingw32.cmake .." +- Copy src/ftdi.h to your MinGW include directory. +- Copy build-win32/src/*.a to your MinGW lib directory. + +libftd2xx +--------- + +The Cygwin/Win32 ZIP file contains a directory named ftd2xx.win32. +After being extracted, the directory does not need further preparation. +Instead, its path must be provided to the --with-ftd2xx-win32-zipdir +configure option, as shown in the next section. + +OpenOCD +------- + +Now you can build OpenOCD under Linux using MinGW. You need to use +--build and --host configure options. + +To use libftdi: + + ./configure --build=i686-pc-linux-gnu --host=i586-mingw32msvc \ + --enable-ft2232_libftdi \ + ... other options ... + +To use ftd2xx: + + ./configure --build=i686-pc-linux-gnu --host=i586-mingw32msvc \ + --enable-ft2232_ftd2xx \ + --with-ftd2xx-win32-zipdir=/path/to/libftd2xx-win32 \ + ... other options ... + +If you are using the GIT repository, see the README file for additional +instructions about configuring and building OpenOCD. diff --git a/debuggers/openocd/TODO b/debuggers/openocd/TODO new file mode 100644 index 00000000..8aac1575 --- /dev/null +++ b/debuggers/openocd/TODO @@ -0,0 +1,380 @@ +// This file is part of the Doxygen Developer Manual +/** @page tasks Pending and Open Tasks + +This page lists pending and open tasks being considered or worked upon +by the OpenOCD community. + +@section thelist The List + +Most items are open for the taking, but please post to the mailing list +before spending much time working on anything lists here. The community +may have evolved an idea since it was added here. + +Feel free to send patches to add or clarify items on this list, too. + +@section thelisttcl TCL + +This section provides possible things to improve with OpenOCD's TCL support. + +- Fix problem with incorrect line numbers reported for a syntax + error in a reset init event. + +- organize the TCL configurations: + - provide more directory structure for boards/targets? + - factor configurations into layers (encapsulation and re-use) + +- Fix handling of variables between multiple command line "-c" and "-f" + parameters. Currently variables assigned through one such parameter + command/script are unset before the next one is invoked. + +- Isolate all TCL command support: + - Pure C CLI implementations using --disable-builtin-tcl. + - Allow developers to build new dongles using OpenOCD's JTAG core. + - At first, provide only low-level JTAG support; target layer and + above rely heavily on scripting event mechanisms. + - Allow full TCL support? add --with-tcl=/path/to/installed/tcl + - Move TCL support out of foo.[ch] and into foo_tcl.[ch] (other ideas?) + - See src/jtag/core.c and src/jtag/tcl.c for an example. + - allow some of these TCL command modules to be dynamically loadable? + +@section thelistjtag JTAG + +This section list issues that need to be resolved in the JTAG layer. + +@subsection thelistjtagcore JTAG Core + +The following tasks have been suggested for cleaning up the JTAG layer: + +- use tap_set_state everywhere to allow logging TAP state transitions +- Encapsulate cmd_queue_cur_state and related variable handling. +- add slick 32 bit versions of jtag_add_xxx_scan() that avoids +buf_set_u32() calls and other evidence of poor impedance match between +API and calling code. New API should cut down # of lines in calling +code by 100's and make things clearer. Also potentially be supported +directly in minidriver API for better embedded host performance. + +The following tasks have been suggested for adding new core JTAG support: + +- Improve autodetection of TAPs by supporting tcl escape procedures that + can configure discovered TAPs based on IDCODE value ... they could: + - Remove guessing for irlen + - Allow non-default irmask/ircapture values +- SPI/UART emulation: + - (ab)use bit-banging JTAG interfaces to emulate SPI/UART + - allow SPI to program flash, MCUs, etc. + +@subsection thelistjtaginterfaces JTAG Interfaces + +There are some known bugs to fix in JTAG adapter drivers: + +- For JTAG_STATEMOVE to TAP_RESET, all drivers must ignore the current + recorded state. The tap_get_state() call won't necessarily return + the correct value, especially at server startup. Fix is easy: in + that case, always issue five clocks with TMS high. + - amt_jtagaccel.c + - arm-jtag-ew.c + - bitbang.c + - bitq.c + - gw16012.c + - jlink.c + - usbprog.c + - vsllink.c + - rlink/rlink.c +- bug: USBprog is broken with new tms sequence; it needs 7-clock cycles. + Fix promised from Peter Denison openwrt at marshadder.org + Workaround: use "tms_sequence long" @par + https://lists.berlios.de/pipermail/openocd-development/2009-July/009426.html + +The following tasks have been suggested for improving OpenOCD's JTAG +interface support: + +- rework USB communication to be more robust. Two possible options are: + -# use libusb-1.0.1 with libusb-compat-0.1.1 (non-blocking I/O wrapper) + -# rewrite implementation to use non-blocking I/O +- J-Link driver: + - fix to work with long scan chains, such as R.Doss's svf test. +- FT2232 (libftdi): + - make performance comparable to alternatives (on Win32, D2XX is faster) + - make usability comparable to alternatives +- Autodetect USB based adapters; this should be easy on Linux. If there's + more than one, list the options; otherwise, just select that one. + +The following tasks have been suggested for adding new JTAG interfaces: + +- TCP driver: allow client/server for remote JTAG interface control. +This requires a client and a server. The server is built into the +normal OpenOCD and takes commands from the client and executes +them on the interface returning the result of TCP/IP. The client +is an OpenOCD which is built with a TCP/IP minidriver. The use +of a minidriver is required to capture all the jtag_add_xxx() +fn's at a high enough level and repackage these cmd's as +TCP/IP packets handled by the server. + +@section thelistswd Serial Wire Debug + +- implement Serial Wire Debug interface + +@section thelistbs Boundary Scan Support + +- add STAPL support? +- add BSDL support? + +A few possible options for the above: + -# Fake a TCL equivalent? + -# Integrate an existing library? + -# Write a new C implementation a la Jim? + +Once the above are completed: +- add support for programming flash using boundary scan techniques +- add integration with a modified gerber view program: + - provide means to view the PCB and select pins and traces + - allow use-cases such as the following: + - @b Stimulus + -# Double-click on a pin (or trace) with the mouse. + - @b Effects + -# The trace starts blinking, and + -# OpenOCD toggles the pin(s) 0/1. + +@section thelisttargets Target Support + +- Many common ARM cores could be autodetected using IDCODE +- general layer cleanup: @par + https://lists.berlios.de/pipermail/openocd-development/2009-May/006590.html +- regression: "reset halt" between 729(works) and 788(fails): @par +https://lists.berlios.de/pipermail/openocd-development/2009-July/009206.html +- registers + - add flush-value operation, call them all on resume/reset +- mcr/mrc target->type support + - missing from ARM920t, ARM966e, XScale. + It's possible that the current syntax is unable to support read-modify-write + operations(see arm966e). + - mcr/mrc - retire cp15 commands when there the mrc/mrc commands have been + tested from: arm926ejs, arm720t, cortex_a8 +- ARM7/9: + - clean up "arm9tdmi vector_catch". Available for some arm7 cores? @par +https://lists.berlios.de/pipermail/openocd-development/2009-October/011488.html +https://lists.berlios.de/pipermail/openocd-development/2009-October/011506.html + - add reset option to allow programming embedded ice while srst is asserted. + Some CPUs will gate the JTAG clock when srst is asserted and in this case, + it is necessary to program embedded ice and then assert srst afterwards. +- ARM926EJS: + - reset run/halt/step is not robust; needs testing to map out problems. +- ARM11 improvements (MB?) + - add support for asserting srst to reset the core. + - Single stepping works, but should automatically + use hardware stepping if available. + - mdb can return garbage data if read byte operation fails for + a memory region(16 & 32 byte access modes may be supported). Is this + a bug in the .MX31 PDK init script? Try on i.MX31 PDK: + mdw 0xb80005f0 0x8, mdh 0xb80005f0 0x10, mdb 0xb80005f0 0x20. mdb returns + garabage. + - implement missing functionality (grep FNC_INFO_NOTIMPLEMENTED ...) +- Thumb2 single stepping: ARM1156T2 needs simulator support +- Cortex A8 support (ML) + - add target implementation (ML) +- Cortex M3 support + - when stepping, only write dirtied registers (be faster) + - when connecting to halted core, fetch registers (startup is quirky) +- Generic ARM run_algorithm() interface + - tagged struct wrapping ARM instructions and metadata + - not revision-specific (current: ARMv4+ARMv5 -or- ARMv6 -or- ARMv7) + - usable with at least arm_nandwrite() and generic CFI drivers +- ETM + - don't show FIFOFULL registers if they're not supported + - use comparators to get more breakpoints and watchpoints + - add "etm drivers" command + - trace driver init() via examine() paths only, not setup()/reset +- MC1322x support (JW/DE?) + - integrate and test support from JW (and DE?) + - get working with a known good interface (i.e. not today's jlink) +- AT91SAM92xx: + - improvements for unknown-board-atmel-at91sam9260.cfg (RD) +- STR9x: (ZW) + - improvements to str912.cfg to be more general purpose +- AVR: (SQ) + - independently verify implementation + - incrementally improve working prototype in trunk. (SQ) + - work out how to debug this target + - AVR debugging protocol. +- FPGA: + - Altera Nios Soft-CPU support +- Coldfire (suggested by NC) + - can we draw from the BDM project? @par + http://bdm.sourceforge.net/ + + or the OSBDM package @par + http://forums.freescale.com/freescale/board/message?board.id=OSBDM08&thread.id=422 + +@section thelistsvf SVF/XSVF + +- develop SVF unit tests +- develop XSVF unit tests + +@section thelistflash Flash Support + +- finish documentation for the following flash drivers: + - avr + - pic32mx + - ocl + - str9xpec + +- Don't expect writing all-ones to be a safe way to write without + changing bit values. Minimally it loses on flash modules with + internal ECC, where it may change the ECC. + - NOR flash_write_unlock() does that between sectors + - there may be other cases too + +- Make sure all commands accept either a bank name or a bank number, + and be sure both identifiers show up in "flash banks" and "nand list". + Right now the user-friendly names are pretty much hidden... + +@subsection thelistflashcfi CFI + +- finish implementing bus width/chip width handling (suggested by NC) +- factor vendor-specific code into separate source files + - add new callback interface for vendor-specific code +- investigate/implement "thin wrapper" to use eCos CFI drivers (ØH) + +@section thelistdebug Debugger Support + +- add support for masks in watchpoints? @par + https://lists.berlios.de/pipermail/openocd-development/2009-October/011507.html +- breakpoints can get lost in some circumstances: @par + https://lists.berlios.de/pipermail/openocd-development/2009-June/008853.html +- add support for masks in watchpoints. The trick is that GDB does not + support a breakpoint mask in the remote protocol. One way to work around + this is to add a separate command "watchpoint_mask add/rem ", that + is run to register a list of masks that the gdb_server knows to use with + a particular watchpoint address. +- integrate Keil AGDI interface to OpenOCD? (submitted by Dario Vecchio) + +@section thelisttesting Testing Suite + +This section includes several related groups of ideas: +- @ref thelistunittests +- @ref thelistsmoketests +- @ref thelisttestreports +- @ref thelisttestgenerichw + +@subsection thelistunittests Unit Tests + +- add testing skeleton to provide frameworks for adding tests +- implement server unit tests +- implement JTAG core unit tests +- implement JTAG interface unit tests +- implement flash unit tests +- implement target unit tests + +@subsection thelistsmoketests Smoke Test Tools + +-# extend 'make check' with a smoketest app + - checks for OOCD_TEST_CONFIG, etc. in environment (or config file) + - if properly set, runs the smoke test with specified parameters + - openocd -f ${OOCD_TEST_CONFIG} + - implies a modular test suite (see below) + - should be able to run some minimal tests with dummy interface: + - compare results of baseline sanity checks with expected results + +-# builds a more complete test suite: + - existing testing/examples/ look like a great start + - all targets should be tested fully and for all capabilities + - we do NOT want a "lowest common denominator" test suite + - ... but can we start with one to get going? + - probably requires one test configuration file per board/target + - modularization can occur here, just like with targets/boards/chips + - coverage can increase over time, building up bundles of tests + +-# add new 'smoketest' Makefile target: + - calls 'make check' (and the smoketest app) + - gather inputs and output into a report file + +@subsection thelisttestreports Test Feedback Tools + +These ideas were first introduced here: @par + https://lists.berlios.de/pipermail/openocd-development/2009-May/006358.html + +- provide report submission scripts for e-mail and web forms +- add new Makefile targets to post the report: + - 'checkreportsend' -- send to list via e-mail (via sendmail) + - 'checkreportpost' -- send web form (via curl or other script) + +@subsection thelisttestgenerichw Generic Hardware Tester + +- implement VHDL to use for FPGA-based JTAG TAP testing device +- develop test suite that utilizes this testing device + +@section thelistautotools Autotools Build System + +- make entire configure process require less user consideration: + - automatically detect the features that are available, unless + options were specifically provided to configure + - provide a report of the drivers that will be build at the end of + running configure, so the users can verify which drivers will be + built during 'make' (and their options) . +- eliminate sources of confusion in @c bootstrap script: + -# Make @c bootstrap call 'configure --enable-maintainer-mode \'? + -# Add @c buildstrap script to assist with bootstrap and configure steps. +- automatically build tool-chains required for cross-compiling + - produce mingw32, arm-elf, others using in-tree scripts + - build all required target code from sources +- make JTAG and USB debug output a run-time configuration option + +@section thelistarchitecture Architectural Tasks + +The following architectural tasks need to be accomplished and should be +fairly easy to complete: + + +- use dynamic allocations for working memory. Scan & fix code +for excessive stack allocations. take linux/scripts/checkstack.pl and +see what the worst offenders are. Dynamic stack allocations are found +at the bottom of the list below. Example, on amd64: + + $ objdump -d | checkstack.pl | head -10 + 0x004311e3 image_open [openocd]: 13464 + 0x00431301 image_open [openocd]: 13464 + 0x004237a4 target_array2mem [openocd]: 4376 + 0x0042382b target_array2mem [openocd]: 4376 + 0x00423e74 target_mem2array [openocd]: 4360 + 0x00423ef9 target_mem2array [openocd]: 4360 + 0x00404aed handle_svf_command [openocd]: 2248 + 0x00404b7e handle_svf_command [openocd]: 2248 + 0x00413581 handle_flash_fill_command [openocd]: 2200 + 0x004135fa handle_flash_fill_command [openocd]: 2200 +- clean-up code to match style guides +- factor code to eliminate duplicated functionality +- rewrite code that uses casts to access 16-bit and larger types + from unaligned memory addresses +- libopenocd support: @par + https://lists.berlios.de/pipermail/openocd-development/2009-May/006405.html +- review and clean up interface/target/flash APIs + +The following strategic tasks will require ambition, knowledge, and time +to complete: + +- overhaul use of types to improve 32/64-bit portability + - types for both host and target word sizes? + - can we use GDB's CORE_TYPE support? +- Allow N:M:P mapping of servers, targets, and interfaces +- loadable module support for interface/target/flash drivers and commands + - support both static and dynamic modules. + - should probably use libltdl for dynamic library handing. + +@section thelistadmin Documentation Tasks + +- Develop milestone and release guidelines, processes, and scripts. +- Develop "style" guidelines (and scripts) for maintainers: + - reviewing patches + - committing to git +- Review Users' Guide for documentation errors or omissions + - "capture" and "ocd_find" commands + - "ocd_" prefix on various stuff +- Update Developer's Manual (doxygen output) + - Add documentation describing the architecture of each module + - Provide more Technical Primers to bootstrap contributor knowledge + +*/ +/** @file +This file contains the @ref thelist page. +*/ + diff --git a/debuggers/openocd/aclocal.m4 b/debuggers/openocd/aclocal.m4 new file mode 100644 index 00000000..26dbacbe --- /dev/null +++ b/debuggers/openocd/aclocal.m4 @@ -0,0 +1,9770 @@ +# generated automatically by aclocal 1.13.1 -*- Autoconf -*- + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS + +# longlong.m4 serial 17 +dnl Copyright (C) 1999-2007, 2009-2013 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_LONG_LONG_INT if 'long long int' works. +# This fixes a bug in Autoconf 2.61, and can be faster +# than what's in Autoconf 2.62 through 2.68. + +# Note: If the type 'long long int' exists but is only 32 bits large +# (as on some very old compilers), HAVE_LONG_LONG_INT will not be +# defined. In this case you can treat 'long long int' like 'long int'. + +AC_DEFUN([AC_TYPE_LONG_LONG_INT], +[ + AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) + AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], + [ac_cv_type_long_long_int=yes + if test "x${ac_cv_prog_cc_c99-no}" = xno; then + ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int + if test $ac_cv_type_long_long_int = yes; then + dnl Catch a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004. + dnl If cross compiling, assume the bug is not important, since + dnl nobody cross compiles for this platform as far as we know. + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[@%:@include + @%:@ifndef LLONG_MAX + @%:@ define HALF \ + (1LL << (sizeof (long long int) * CHAR_BIT - 2)) + @%:@ define LLONG_MAX (HALF - 1 + HALF) + @%:@endif]], + [[long long int n = 1; + int i; + for (i = 0; ; i++) + { + long long int m = n << i; + if (m >> i != n) + return 1; + if (LLONG_MAX / 2 < m) + break; + } + return 0;]])], + [], + [ac_cv_type_long_long_int=no], + [:]) + fi + fi]) + if test $ac_cv_type_long_long_int = yes; then + AC_DEFINE([HAVE_LONG_LONG_INT], [1], + [Define to 1 if the system has the type 'long long int'.]) + fi +]) + +# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works. +# This fixes a bug in Autoconf 2.61, and can be faster +# than what's in Autoconf 2.62 through 2.68. + +# Note: If the type 'unsigned long long int' exists but is only 32 bits +# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT +# will not be defined. In this case you can treat 'unsigned long long int' +# like 'unsigned long int'. + +AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], +[ + AC_CACHE_CHECK([for unsigned long long int], + [ac_cv_type_unsigned_long_long_int], + [ac_cv_type_unsigned_long_long_int=yes + if test "x${ac_cv_prog_cc_c99-no}" = xno; then + AC_LINK_IFELSE( + [_AC_TYPE_LONG_LONG_SNIPPET], + [], + [ac_cv_type_unsigned_long_long_int=no]) + fi]) + if test $ac_cv_type_unsigned_long_long_int = yes; then + AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1], + [Define to 1 if the system has the type 'unsigned long long int'.]) + fi +]) + +# Expands to a C program that can be used to test for simultaneous support +# of 'long long' and 'unsigned long long'. We don't want to say that +# 'long long' is available if 'unsigned long long' is not, or vice versa, +# because too many programs rely on the symmetry between signed and unsigned +# integer types (excluding 'bool'). +AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET], +[ + AC_LANG_PROGRAM( + [[/* For now, do not test the preprocessor; as of 2007 there are too many + implementations with broken preprocessors. Perhaps this can + be revisited in 2012. In the meantime, code should not expect + #if to work with literals wider than 32 bits. */ + /* Test literals. */ + long long int ll = 9223372036854775807ll; + long long int nll = -9223372036854775807LL; + unsigned long long int ull = 18446744073709551615ULL; + /* Test constant expressions. */ + typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + ? 1 : -1)]; + typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 + ? 1 : -1)]; + int i = 63;]], + [[/* Test availability of runtime routines for shift and division. */ + long long int llmax = 9223372036854775807ll; + unsigned long long int ullmax = 18446744073709551615ull; + return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) + | (llmax / ll) | (llmax % ll) + | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) + | (ullmax / ull) | (ullmax % ull));]]) +]) + +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) + +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) + +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3337 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.2' +macro_revision='1.3337' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) + +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) + +# Copyright (C) 2002-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.13' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.13.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.13.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless 'enable' is passed literally. +# For symmetry, 'disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], + [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], + am_maintainer_other[ make rules and dependencies not useful + (and sometimes confusing) to the casual installer])], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_CC_C_O +# -------------- +# Like AC_PROG_CC_C_O, but changed for automake. +AC_DEFUN([AM_PROG_CC_C_O], +[AC_REQUIRE([AC_PROG_CC_C_O])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +dnl Make sure AC_PROG_CC is never called again, or it will override our +dnl setting of CC. +m4_define([AC_PROG_CC], + [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of '-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/debuggers/openocd/common.mk b/debuggers/openocd/common.mk new file mode 100644 index 00000000..1cb0743e --- /dev/null +++ b/debuggers/openocd/common.mk @@ -0,0 +1,12 @@ + +# common flags used in openocd build +AM_CPPFLAGS = -I$(top_srcdir)/src \ + -I$(top_builddir)/src \ + -I$(top_srcdir)/src/helper \ + -DPKGDATADIR=\"$(pkgdatadir)\" \ + -DPKGLIBDIR=\"$(pkglibdir)\" + +if INTERNAL_JIMTCL +AM_CPPFLAGS += -I$(top_srcdir)/jimtcl \ + -I$(top_builddir)/jimtcl +endif diff --git a/debuggers/openocd/compile b/debuggers/openocd/compile new file mode 100755 index 00000000..531136b0 --- /dev/null +++ b/debuggers/openocd/compile @@ -0,0 +1,347 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-10-14.11; # UTC + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# 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, 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, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/debuggers/openocd/config.guess b/debuggers/openocd/config.guess new file mode 100755 index 00000000..1804e9fc --- /dev/null +++ b/debuggers/openocd/config.guess @@ -0,0 +1,1535 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012, 2013 Free Software Foundation, Inc. + +timestamp='2012-12-29' + +# This file 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 3 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, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, +2012, 2013 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/debuggers/openocd/config.h.in b/debuggers/openocd/config.h.in new file mode 100644 index 00000000..d359bd1f --- /dev/null +++ b/debuggers/openocd/config.h.in @@ -0,0 +1,320 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* 0 if you don't want the Amontec JTAG-Accelerator driver. */ +#undef BUILD_AMTJTAGACCEL + +/* 0 if you don't want the ARM-JTAG-EW JTAG driver. */ +#undef BUILD_ARMJTAGEW + +/* 0 if you don't want at91rm9200. */ +#undef BUILD_AT91RM9200 + +/* 0 if you don't want a bitbang interface. */ +#undef BUILD_BITBANG + +/* 0 if you don't want a bitq interface. */ +#undef BUILD_BITQ + +/* 0 if you don't want the Buspirate JTAG driver. */ +#undef BUILD_BUSPIRATE + +/* 0 if you don't want dummy driver. */ +#undef BUILD_DUMMY + +/* 0 if you don't want ep93xx. */ +#undef BUILD_EP93XX + +/* 0 if you don't want ftd2xx ft2232. */ +#undef BUILD_FT2232_FTD2XX + +/* Support FT2232H/FT4232HS with FTD2XX or libftdi. */ +#undef BUILD_FT2232_HIGHSPEED + +/* 0 if you don't want libftdi ft2232. */ +#undef BUILD_FT2232_LIBFTDI + +/* 0 if you don't want ftdi. */ +#undef BUILD_FTDI + +/* 0 if you don't want the Gateworks GW16012 driver. */ +#undef BUILD_GW16012 + +/* 0 if you don't want the High Level JTAG driver. */ +#undef BUILD_HLADAPTER + +/* 0 if you don't want the J-Link JTAG driver. */ +#undef BUILD_JLINK + +/* Use the dummy minidriver. */ +#undef BUILD_MINIDRIVER_DUMMY + +/* 0 if you don't want the OpenOCD+trace ETM capture driver. */ +#undef BUILD_OOCD_TRACE + +/* 0 if you don't want the estick/opendous JTAG driver. */ +#undef BUILD_OPENDOUS + +/* 0 if you don't want the OSBDM driver. */ +#undef BUILD_OSBDM + +/* 0 if you don't want parport. */ +#undef BUILD_PARPORT + +/* 0 if you don't want the ASIX PRESTO driver using FTD2XX. */ +#undef BUILD_PRESTO_FTD2XX + +/* 0 if you don't want the ASIX PRESTO driver using libftdi. */ +#undef BUILD_PRESTO_LIBFTDI + +/* 0 if you don't want the Remote Bitbang JTAG driver. */ +#undef BUILD_REMOTE_BITBANG + +/* 0 if you don't want the RLink JTAG driver. */ +#undef BUILD_RLINK + +/* 0 if you don't want SysfsGPIO driver. */ +#undef BUILD_SYSFSGPIO + +/* 0 if you don't want the ULINK JTAG driver. */ +#undef BUILD_ULINK + +/* 0 if you don't want the usbprog JTAG driver. */ +#undef BUILD_USBPROG + +/* 0 if you don't want ftd2xx usb_blaster. */ +#undef BUILD_USB_BLASTER_FTD2XX + +/* 0 if you don't want libftdi usb_blaster. */ +#undef BUILD_USB_BLASTER_LIBFTDI + +/* 0 if you don't want the Versaloon-Link JTAG driver. */ +#undef BUILD_VSLLINK + +/* 0 if you don't want ZY1000. */ +#undef BUILD_ZY1000 + +/* 0 if you don't want ZY1000 JTAG master registers. */ +#undef BUILD_ZY1000_MASTER + +/* Support FT232H with FTD2XX or libftdi. */ +#undef HAS_ENUM_FT232H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ELF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the header file. */ +#undef HAVE_IFADDRS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_JTAG_MINIDRIVER_H + +/* Define if you have libusb-1.0 */ +#undef HAVE_LIBUSB1 + +/* Define to 1 if the system has the type 'long long int'. */ +#undef HAVE_LONG_LONG_INT + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_TCP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_IF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_PTHREAD_H + +/* Define to 1 if stdbool.h conforms to C99. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strndup' function. */ +#undef HAVE_STRNDUP + +/* Define to 1 if you have the `strnlen' function. */ +#undef HAVE_STRNLEN + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_POLL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if the system has the type 'unsigned long long int'. */ +#undef HAVE_UNSIGNED_LONG_LONG_INT + +/* Define to 1 if you have the header file. */ +#undef HAVE_USB_H + +/* Define to 1 if you have the `usleep' function. */ +#undef HAVE_USLEEP + +/* Define to 1 if you have the `vasprintf' function. */ +#undef HAVE_VASPRINTF + +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + +/* 0 if not building for Cygwin. */ +#undef IS_CYGWIN + +/* 0 if not building for Darwin. */ +#undef IS_DARWIN + +/* 1 if building for MinGW. */ +#undef IS_MINGW + +/* 0 if not building for Win32. */ +#undef IS_WIN32 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Define to 1 if assertions should be disabled. */ +#undef NDEBUG + +/* Must declare 'environ' to use it. */ +#undef NEED_ENVIRON_EXTERN + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* 0 if you don't want parport to use giveio. */ +#undef PARPORT_USE_GIVEIO + +/* 0 if you don't want parport to use ppdev. */ +#undef PARPORT_USE_PPDEV + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Include malloc free space in logging */ +#undef _DEBUG_FREE_SPACE_ + +/* Print verbose JTAG I/O messages */ +#undef _DEBUG_JTAG_IO_ + +/* Print verbose USB communication messages */ +#undef _DEBUG_USB_COMMS_ + +/* Print verbose USB I/O messages */ +#undef _DEBUG_USB_IO_ + +/* Use GNU C library extensions (e.g. stdndup). */ +#undef _GNU_SOURCE + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + + +#include +#include +#include + diff --git a/debuggers/openocd/config.sub b/debuggers/openocd/config.sub new file mode 100755 index 00000000..802a224d --- /dev/null +++ b/debuggers/openocd/config.sub @@ -0,0 +1,1790 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012, 2013 Free Software Foundation, Inc. + +timestamp='2012-12-29' + +# This file 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 3 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, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, +2012, 2013 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/debuggers/openocd/config_subdir.m4 b/debuggers/openocd/config_subdir.m4 new file mode 100644 index 00000000..4102dfd3 --- /dev/null +++ b/debuggers/openocd/config_subdir.m4 @@ -0,0 +1,27 @@ +dnl +dnl If needed, define the m4_ifblank and m4_ifnblank macros from autoconf 2.64 +dnl This allows us to run with earlier Autoconfs as well. +ifdef([m4_ifblank],[],[ +m4_define([m4_ifblank], +[m4_if(m4_translit([[$1]], [ ][ ][ +]), [], [$2], [$3])])]) +dnl +ifdef([m4_ifnblank],[],[ +m4_define([m4_ifnblank], +[m4_if(m4_translit([[$1]], [ ][ ][ +]), [], [$3], [$2])])]) +dnl + +dnl AC_CONFIG_SUBDIRS does not allow configure options to be passed +dnl to subdirs, this function allows that by creating a configure.gnu +dnl script that prepends configure options and then calls the real +dnl configure script +AC_DEFUN([AX_CONFIG_SUBDIR_OPTION], +[ +AC_CONFIG_SUBDIRS([$1]) + +m4_ifblank([$2], [rm -f $srcdir/$1/configure.gnu], +[printf "#!/bin/sh +"\$"SHELL "../$srcdir/$1/configure" $2 \""\$"@"\" > "$srcdir/$1/configure.gnu" +]) +]) diff --git a/debuggers/openocd/configure b/debuggers/openocd/configure new file mode 100755 index 00000000..7fbd82fb --- /dev/null +++ b/debuggers/openocd/configure @@ -0,0 +1,18031 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for openocd 0.7.0. +# +# Report bugs to >. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and OpenOCD Mailing +$0: List about your +$0: system, including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='openocd' +PACKAGE_TARNAME='openocd' +PACKAGE_VERSION='0.7.0' +PACKAGE_STRING='openocd 0.7.0' +PACKAGE_BUGREPORT='OpenOCD Mailing List ' +PACKAGE_URL='' + +ac_unique_file="src/openocd.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +enable_option_checking=no +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +EXEEXT_FOR_BUILD +CFLAGS_FOR_BUILD +CC_FOR_BUILD +INTERNAL_JIMTCL_FALSE +INTERNAL_JIMTCL_TRUE +MINIDRIVER_DUMMY_FALSE +MINIDRIVER_DUMMY_TRUE +MINIDRIVER_FALSE +MINIDRIVER_TRUE +BITQ_FALSE +BITQ_TRUE +IS_DARWIN_FALSE +IS_DARWIN_TRUE +IS_WIN32_FALSE +IS_WIN32_TRUE +IS_MINGW_FALSE +IS_MINGW_TRUE +IS_CYGWIN_FALSE +IS_CYGWIN_TRUE +USE_LIBUSB1_FALSE +USE_LIBUSB1_TRUE +USE_LIBUSB0_FALSE +USE_LIBUSB0_TRUE +USB_NG_FALSE +USB_NG_TRUE +USB_FALSE +USB_TRUE +SYSFSGPIO_FALSE +SYSFSGPIO_TRUE +OPENDOUS_FALSE +OPENDOUS_TRUE +OSBDM_FALSE +OSBDM_TRUE +HLADAPTER_FALSE +HLADAPTER_TRUE +BUSPIRATE_FALSE +BUSPIRATE_TRUE +REMOTE_BITBANG_FALSE +REMOTE_BITBANG_TRUE +ARMJTAGEW_FALSE +ARMJTAGEW_TRUE +ULINK_FALSE +ULINK_TRUE +RLINK_FALSE +RLINK_TRUE +VSLLINK_FALSE +VSLLINK_TRUE +JLINK_FALSE +JLINK_TRUE +OOCD_TRACE_FALSE +OOCD_TRACE_TRUE +USBPROG_FALSE +USBPROG_TRUE +PRESTO_DRIVER_FALSE +PRESTO_DRIVER_TRUE +PRESTO_LIBFTDI_FALSE +PRESTO_LIBFTDI_TRUE +GW16012_FALSE +GW16012_TRUE +AMTJTAGACCEL_FALSE +AMTJTAGACCEL_TRUE +USB_BLASTER_DRIVER_FALSE +USB_BLASTER_DRIVER_TRUE +USB_BLASTER_LIBFTDI_FALSE +USB_BLASTER_LIBFTDI_TRUE +FTDI_DRIVER_FALSE +FTDI_DRIVER_TRUE +FT2232_DRIVER_FALSE +FT2232_DRIVER_TRUE +FT2232_LIBFTDI_FALSE +FT2232_LIBFTDI_TRUE +BITBANG_FALSE +BITBANG_TRUE +AT91RM9200_FALSE +AT91RM9200_TRUE +IOUTIL_FALSE +IOUTIL_TRUE +ZY1000_MASTER_FALSE +ZY1000_MASTER_TRUE +ZY1000_FALSE +ZY1000_TRUE +EP93XX_FALSE +EP93XX_TRUE +GIVEIO_FALSE +GIVEIO_TRUE +DUMMY_FALSE +DUMMY_TRUE +PARPORT_FALSE +PARPORT_TRUE +RELEASE_FALSE +RELEASE_TRUE +subdirs +doxygen_as_pdf +doxygen_as_html +LIBTOOL_DEPS +CPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +RANLIB +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_maintainer_mode +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_assert +with_ftd2xx +with_ftd2xx_win32_zipdir +with_ftd2xx_linux_tardir +with_ftd2xx_lib +enable_doxygen_html +enable_doxygen_pdf +enable_gccwarnings +enable_wextra +enable_werror +enable_verbose +enable_verbose_jtag_io +enable_verbose_usb_io +enable_verbose_usb_comms +enable_malloc_logging +enable_dummy +enable_parport +enable_parport_ppdev +enable_parport_giveio +enable_ft2232_libftdi +enable_ft2232_ftd2xx +enable_ftdi +enable_usb_blaster_libftdi +enable_usb_blaster_ftd2xx +enable_amtjtagaccel +enable_zy1000_master +enable_zy1000 +enable_ioutil +enable_ep93xx +enable_at91rm9200 +enable_gw16012 +enable_presto_libftdi +enable_presto_ftd2xx +enable_usbprog +enable_oocd_trace +enable_jlink +enable_vsllink +enable_rlink +enable_ulink +enable_arm_jtag_ew +enable_buspirate +enable_stlink +enable_ti_icdi +enable_osbdm +enable_opendous +enable_sysfsgpio +enable_minidriver_dummy +enable_internal_jimtcl +enable_libusb0 +enable_remote_bitbang +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' +ac_subdirs_all='jimtcl' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures openocd 0.7.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/openocd] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of openocd 0.7.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=no] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --disable-assert turn off assertions + --disable-doxygen-html Disable building Doxygen manual as HTML. + --enable-doxygen-pdf Enable building Doxygen manual as PDF. + --disable-gccwarnings Disable compiler warnings + --disable-wextra Disable extra compiler warnings + --disable-werror Do not treat warnings as errors + --enable-verbose Enable verbose JTAG I/O messages (for debugging). + --enable-verbose-jtag-io + Enable verbose JTAG I/O messages (for debugging). + --enable-verbose-usb-io Enable verbose USB I/O messages (for debugging) + --enable-verbose-usb-comms + Enable verbose USB communication messages (for + debugging) + --enable-malloc-logging Include free space in logging messages (requires + malloc.h). + --enable-dummy Enable building the dummy port driver + --enable-parport Enable building the pc parallel port driver + --disable-parport-ppdev Disable use of ppdev (/dev/parportN) for parport + (for x86 only) + --enable-parport-giveio Enable use of giveio for parport (for CygWin only) + --enable-ft2232_libftdi Enable building support for FT2232 based devices + using the libftdi driver, opensource alternate of + FTD2XX + --enable-ft2232_ftd2xx Enable building support for FT2232 based devices + using the FTD2XX driver from ftdichip.com + --enable-ftdi Enable building support for the MPSSE mode of FTDI + based devices, using libusb-1.0 in asynchronous mode + --enable-usb_blaster_libftdi + Enable building support for the Altera USB-Blaster + using the libftdi driver, opensource alternate of + FTD2XX + --enable-usb_blaster_ftd2xx + Enable building support for the Altera USB-Blaster + using the FTD2XX driver from ftdichip.com + --enable-amtjtagaccel Enable building the Amontec JTAG-Accelerator driver + --enable-zy1000-master Use ZY1000 JTAG master registers + --enable-zy1000 Enable ZY1000 interface + --enable-ioutil Enable ioutil functions - useful for standalone + OpenOCD implementations + --enable-ep93xx Enable building support for EP93xx based SBCs + --enable-at91rm9200 Enable building support for AT91RM9200 based SBCs + --enable-gw16012 Enable building support for the Gateworks GW16012 + JTAG Programmer + --enable-presto_libftdi Enable building support for ASIX Presto Programmer + using the libftdi driver + --enable-presto_ftd2xx Enable building support for ASIX Presto Programmer + using the FTD2XX driver + --enable-usbprog Enable building support for the usbprog JTAG + Programmer + --enable-oocd_trace Enable building support for some prototype + OpenOCD+trace ETM capture hardware + --enable-jlink Enable building support for the Segger J-Link JTAG + Programmer + --enable-vsllink Enable building support for the Versaloon-Link JTAG + Programmer + --enable-rlink Enable building support for the Raisonance RLink + JTAG Programmer + --enable-ulink Enable building support for the Keil ULINK JTAG + Programmer + --enable-arm-jtag-ew Enable building support for the Olimex ARM-JTAG-EW + Programmer + --enable-buspirate Enable building support for the Buspirate + --enable-stlink Enable building support for the ST-Link JTAG + Programmer + --enable-ti-icdi Enable building support for the TI ICDI JTAG + Programmer + --enable-osbdm Enable building support for the OSBDM (JTAG only) + Programmer + --enable-opendous Enable building support for the estick/opendous JTAG + Programmer + --enable-sysfsgpio Enable building support for programming driven via + sysfs gpios. + --enable-minidriver-dummy + Enable the dummy minidriver. + --disable-internal-jimtcl + Disable building internal jimtcl + --enable-libusb0 Use libusb-0.1 library for USB JTAG devices + --enable-remote-bitbang Enable building support for the Remote Bitbang jtag + driver + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + --with-ftd2xx= This option has been removed. + --with-ftd2xx-win32-zipdir + Where (CYGWIN/MINGW) the zip file from ftdichip.com + was unpacked (default=search) + --with-ftd2xx-linux-tardir + Where (Linux/Unix) the tar file from ftdichip.com + was unpacked (default=search) + --with-ftd2xx-lib Use static or shared ftd2xx libs (default=static) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to >. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +openocd configure 0.7.0 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------------------------------------------------- ## +## Report this to OpenOCD Mailing List ## +## ------------------------------------------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by openocd $as_me 0.7.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + +am__api_version='1.13' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='openocd' + VERSION='0.7.0' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + +ac_config_headers="$ac_config_headers config.h" + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 +$as_echo_n "checking for $CC option to accept ISO C99... " >&6; } +if ${ac_cv_prog_cc_c99+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +#include + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +#define debug(...) fprintf (stderr, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + your preprocessor is broken; +#endif +#if BIG_OK +#else + your preprocessor is broken; +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\0'; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static void +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str; + int number; + float fnumber; + + while (*format) + { + switch (*format++) + { + case 's': // string + str = va_arg (args_copy, const char *); + break; + case 'd': // int + number = va_arg (args_copy, int); + break; + case 'f': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); +} + +int +main () +{ + + // Check bool. + _Bool success = false; + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + test_varargs ("s, d' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' + || dynamic_array[ni.number - 1] != 543); + + ; + return 0; +} +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c99" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c99" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +$as_echo "$ac_cv_prog_cc_c99" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c99" != xno; then : + +fi + + +if test "x$CC" != xcc; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 +$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 +$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +fi +set dummy $CC; ac_cc=`$as_echo "$2" | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; +then + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; + then + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + + + + +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=no +fi + + + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.2' +macro_revision='1.3337' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5 +$as_echo_n "checking for unsigned long long int... " >&6; } +if ${ac_cv_type_unsigned_long_long_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_type_unsigned_long_long_int=yes + if test "x${ac_cv_prog_cc_c99-no}" = xno; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + /* For now, do not test the preprocessor; as of 2007 there are too many + implementations with broken preprocessors. Perhaps this can + be revisited in 2012. In the meantime, code should not expect + #if to work with literals wider than 32 bits. */ + /* Test literals. */ + long long int ll = 9223372036854775807ll; + long long int nll = -9223372036854775807LL; + unsigned long long int ull = 18446744073709551615ULL; + /* Test constant expressions. */ + typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + ? 1 : -1)]; + typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 + ? 1 : -1)]; + int i = 63; +int +main () +{ +/* Test availability of runtime routines for shift and division. */ + long long int llmax = 9223372036854775807ll; + unsigned long long int ullmax = 18446744073709551615ull; + return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) + | (llmax / ll) | (llmax % ll) + | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) + | (ullmax / ull) | (ullmax % ull)); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +else + ac_cv_type_unsigned_long_long_int=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5 +$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; } + if test $ac_cv_type_unsigned_long_long_int = yes; then + +$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h + + fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5 +$as_echo_n "checking for long long int... " >&6; } +if ${ac_cv_type_long_long_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_type_long_long_int=yes + if test "x${ac_cv_prog_cc_c99-no}" = xno; then + ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int + if test $ac_cv_type_long_long_int = yes; then + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #ifndef LLONG_MAX + # define HALF \ + (1LL << (sizeof (long long int) * CHAR_BIT - 2)) + # define LLONG_MAX (HALF - 1 + HALF) + #endif +int +main () +{ +long long int n = 1; + int i; + for (i = 0; ; i++) + { + long long int m = n << i; + if (m >> i != n) + return 1; + if (LLONG_MAX / 2 < m) + break; + } + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_type_long_long_int=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5 +$as_echo "$ac_cv_type_long_long_int" >&6; } + if test $ac_cv_type_long_long_int = yes; then + +$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h + + fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ioperm" >&5 +$as_echo_n "checking for library containing ioperm... " >&6; } +if ${ac_cv_search_ioperm+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ioperm (); +int +main () +{ +return ioperm (); + ; + return 0; +} +_ACEOF +for ac_lib in '' ioperm; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ioperm=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_ioperm+:} false; then : + break +fi +done +if ${ac_cv_search_ioperm+:} false; then : + +else + ac_cv_search_ioperm=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ioperm" >&5 +$as_echo "$ac_cv_search_ioperm" >&6; } +ac_res=$ac_cv_search_ioperm +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 +$as_echo_n "checking for library containing dlopen... " >&6; } +if ${ac_cv_search_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dlopen=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_dlopen+:} false; then : + break +fi +done +if ${ac_cv_search_dlopen+:} false; then : + +else + ac_cv_search_dlopen=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 +$as_echo "$ac_cv_search_dlopen" >&6; } +ac_res=$ac_cv_search_dlopen +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +for ac_header in sys/socket.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_socket_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_SOCKET_H 1 +_ACEOF + +fi + +done + +for ac_header in arpa/inet.h +do : + ac_fn_c_check_header_compile "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +" +if test "x$ac_cv_header_arpa_inet_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ARPA_INET_H 1 +_ACEOF + +fi + +done + +for ac_header in elf.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "elf.h" "ac_cv_header_elf_h" "$ac_includes_default" +if test "x$ac_cv_header_elf_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ELF_H 1 +_ACEOF + +fi + +done + +for ac_header in dirent.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "dirent.h" "ac_cv_header_dirent_h" "$ac_includes_default" +if test "x$ac_cv_header_dirent_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DIRENT_H 1 +_ACEOF + +fi + +done + +for ac_header in fcntl.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default" +if test "x$ac_cv_header_fcntl_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FCNTL_H 1 +_ACEOF + +fi + +done + +for ac_header in ifaddrs.h +do : + ac_fn_c_check_header_compile "$LINENO" "ifaddrs.h" "ac_cv_header_ifaddrs_h" "#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +" +if test "x$ac_cv_header_ifaddrs_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_IFADDRS_H 1 +_ACEOF + +fi + +done + +for ac_header in malloc.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "malloc.h" "ac_cv_header_malloc_h" "$ac_includes_default" +if test "x$ac_cv_header_malloc_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MALLOC_H 1 +_ACEOF + +fi + +done + +for ac_header in netdb.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "netdb.h" "ac_cv_header_netdb_h" "$ac_includes_default" +if test "x$ac_cv_header_netdb_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NETDB_H 1 +_ACEOF + +fi + +done + +for ac_header in netinet/in.h +do : + ac_fn_c_check_header_compile "$LINENO" "netinet/in.h" "ac_cv_header_netinet_in_h" "#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +" +if test "x$ac_cv_header_netinet_in_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NETINET_IN_H 1 +_ACEOF + +fi + +done + +for ac_header in netinet/tcp.h +do : + ac_fn_c_check_header_compile "$LINENO" "netinet/tcp.h" "ac_cv_header_netinet_tcp_h" "#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +" +if test "x$ac_cv_header_netinet_tcp_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NETINET_TCP_H 1 +_ACEOF + +fi + +done + +for ac_header in pthread.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" +if test "x$ac_cv_header_pthread_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PTHREAD_H 1 +_ACEOF + +fi + +done + +for ac_header in strings.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "strings.h" "ac_cv_header_strings_h" "$ac_includes_default" +if test "x$ac_cv_header_strings_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRINGS_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/ioctl.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_ioctl_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_IOCTL_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/param.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_param_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_PARAM_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/poll.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/poll.h" "ac_cv_header_sys_poll_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_poll_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_POLL_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/select.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/select.h" "ac_cv_header_sys_select_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_select_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_SELECT_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/stat.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/stat.h" "ac_cv_header_sys_stat_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_stat_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_STAT_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/time.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_time_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_TIME_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/types.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_types_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_TYPES_H 1 +_ACEOF + +fi + +done + +for ac_header in unistd.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" +if test "x$ac_cv_header_unistd_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_UNISTD_H 1 +_ACEOF + +fi + +done + +for ac_header in net/if.h +do : + ac_fn_c_check_header_compile "$LINENO" "net/if.h" "ac_cv_header_net_if_h" "#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +" +if test "x$ac_cv_header_net_if_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NET_IF_H 1 +_ACEOF + +fi + +done + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable assertions" >&5 +$as_echo_n "checking whether to enable assertions... " >&6; } + # Check whether --enable-assert was given. +if test "${enable_assert+set}" = set; then : + enableval=$enable_assert; ac_enable_assert=$enableval + if test "x$enableval" = xno; then : + +$as_echo "#define NDEBUG 1" >>confdefs.h + +elif test "x$enableval" != xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: invalid argument supplied to --enable-assert" >&5 +$as_echo "$as_me: WARNING: invalid argument supplied to --enable-assert" >&2;} + ac_enable_assert=yes +fi +else + ac_enable_assert=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_enable_assert" >&5 +$as_echo "$ac_enable_assert" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 +$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } +if ${ac_cv_header_stdbool_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #ifndef bool + "error: bool is not defined" + #endif + #ifndef false + "error: false is not defined" + #endif + #if false + "error: false is not 0" + #endif + #ifndef true + "error: true is not defined" + #endif + #if true != 1 + "error: true is not 1" + #endif + #ifndef __bool_true_false_are_defined + "error: __bool_true_false_are_defined is not defined" + #endif + + struct s { _Bool s: 1; _Bool t; } s; + + char a[true == 1 ? 1 : -1]; + char b[false == 0 ? 1 : -1]; + char c[__bool_true_false_are_defined == 1 ? 1 : -1]; + char d[(bool) 0.5 == true ? 1 : -1]; + /* See body of main program for 'e'. */ + char f[(_Bool) 0.0 == false ? 1 : -1]; + char g[true]; + char h[sizeof (_Bool)]; + char i[sizeof s.t]; + enum { j = false, k = true, l = false * true, m = true * 256 }; + /* The following fails for + HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ + _Bool n[m]; + char o[sizeof n == m * sizeof n[0] ? 1 : -1]; + char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; + /* Catch a bug in an HP-UX C compiler. See + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + */ + _Bool q = true; + _Bool *pq = &q; + +int +main () +{ + + bool e = &s; + *pq |= q; + *pq |= ! q; + /* Refer to every declared value, to avoid compiler optimizations. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + + !m + !n + !o + !p + !q + !pq); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdbool_h=yes +else + ac_cv_header_stdbool_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 +$as_echo "$ac_cv_header_stdbool_h" >&6; } + ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" +if test "x$ac_cv_type__Bool" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE__BOOL 1 +_ACEOF + + +fi + + +if test $ac_cv_header_stdbool_h = yes; then + +$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + +for ac_func in strndup +do : + ac_fn_c_check_func "$LINENO" "strndup" "ac_cv_func_strndup" +if test "x$ac_cv_func_strndup" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRNDUP 1 +_ACEOF + +fi +done + +for ac_func in strnlen +do : + ac_fn_c_check_func "$LINENO" "strnlen" "ac_cv_func_strnlen" +if test "x$ac_cv_func_strnlen" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRNLEN 1 +_ACEOF + +fi +done + +for ac_func in gettimeofday +do : + ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" +if test "x$ac_cv_func_gettimeofday" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETTIMEOFDAY 1 +_ACEOF + +fi +done + +for ac_func in usleep +do : + ac_fn_c_check_func "$LINENO" "usleep" "ac_cv_func_usleep" +if test "x$ac_cv_func_usleep" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_USLEEP 1 +_ACEOF + +fi +done + +for ac_func in vasprintf +do : + ac_fn_c_check_func "$LINENO" "vasprintf" "ac_cv_func_vasprintf" +if test "x$ac_cv_func_vasprintf" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VASPRINTF 1 +_ACEOF + +fi +done + + +build_bitbang=no +build_bitq=no +is_cygwin=no +is_mingw=no +is_win32=no +is_darwin=no + +# guess-rev.sh only exists in the repository, not in the released archives +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build a release" >&5 +$as_echo_n "checking whether to build a release... " >&6; } +if test -x $srcdir/guess-rev.sh ; then + build_release=no +else + build_release=yes +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_release" >&5 +$as_echo "$build_release" >&6; } + +# We are not *ALWAYS* being installed in the standard place. +# We may be installed in a "tool-build" specific location. +# Normally with other packages - as part of a tool distro. +# Thus - we should search that 'libdir' also. +# +# And - if we are being installed there - the odds are +# The libraries unique to what we are are there too. +# + +# Expand nd deal with NONE - just like configure will do later +OCDprefix=$prefix +OCDxprefix=$exec_prefix +test x"$OCDprefix" = xNONE && OCDprefix=$ac_default_prefix +# Let make expand exec_prefix. +test x"$OCDxprefix" = xNONE && OCDxprefix="$OCDprefix" + +# what matters is the "exec-prefix" +if test "$OCDxprefix" != "$ac_default_prefix" +then + # We are installing in a non-standard place + # Nonstandard --prefix and/or --exec-prefix + # We have an override of some sort. + # use build specific install library dir + + LDFLAGS="$LDFLAGS -L$OCDxprefix/lib" + # RPATH becomes an issue on Linux only + if test $host_os = linux-gnu || test $host_os = linux ; then + LDFLAGS="$LDFLAGS -Wl,-rpath,$OCDxprefix/lib" + fi + # The "INCDIR" is also usable + CFLAGS="$CFLAGS -I$includedir" +fi + + +# Check whether --with-ftd2xx was given. +if test "${with_ftd2xx+set}" = set; then : + withval=$with_ftd2xx; +# Option Given. +cat << __EOF__ + +The option: --with-ftd2xx= has been removed. +On Linux, the new option is: + + --with-ftd2xx-linux-tardir=/path/to/files + +Where is the path the the directory where the "tar.gz" file +from FTDICHIP.COM was unpacked, for example: + + --with-ftd2xx-linux-tardir=${HOME}/libftd2xx0.4.16 + +On Cygwin/MingW32, the new option is: + + --with-ftd2xx-win32-zipdir=/path/to/files + +Where is the path to the directory where the "zip" file from +FTDICHIP.COM was unpacked, for example: + + --with-ftd2xx-win32-zipdir=${HOME}/ftd2xx.cdm.files + +__EOF__ + + as_fn_error $? "Sorry Cannot continue" "$LINENO" 5 + +else + true +fi + + +#======================================== +# FTD2XXX support comes in 4 forms. +# (1) win32 - via a zip file +# (2) linux - via a tar file +# (3) linux/cygwin/mingw - via libftdi +# (4) darwin - installed under /usr/local +# +# In case (1) and (2) we need to know where the package was unpacked. + + +# Check whether --with-ftd2xx-win32-zipdir was given. +if test "${with_ftd2xx_win32_zipdir+set}" = set; then : + withval=$with_ftd2xx_win32_zipdir; + # option present + if test -d $with_ftd2xx_win32_zipdir + then + with_ftd2xx_win32_zipdir=`cd $with_ftd2xx_win32_zipdir && pwd` + { $as_echo "$as_me:${as_lineno-$LINENO}: Using: ftdichip.com library: $with_ftd2xx_win32_zipdir" >&5 +$as_echo "$as_me: Using: ftdichip.com library: $with_ftd2xx_win32_zipdir" >&6;} + else + as_fn_error $? "Parameter to --with-ftd2xx-win32-zipdir is not a dir: $with_ftd2xx_win32_zipdir" "$LINENO" 5 + fi + +else + true +fi + + + +# Check whether --with-ftd2xx-linux-tardir was given. +if test "${with_ftd2xx_linux_tardir+set}" = set; then : + withval=$with_ftd2xx_linux_tardir; + # Option present + if test $is_win32 = yes ; then + as_fn_error $? "The option: --with-ftd2xx-linux-tardir is only usable on linux" "$LINENO" 5 + fi + if test -d $with_ftd2xx_linux_tardir + then + with_ftd2xx_linux_tardir=`cd $with_ftd2xx_linux_tardir && pwd` + { $as_echo "$as_me:${as_lineno-$LINENO}: Using: ftdichip.com library: $with_ftd2xx_linux_tardir" >&5 +$as_echo "$as_me: Using: ftdichip.com library: $with_ftd2xx_linux_tardir" >&6;} + else + as_fn_error $? "Parameter to --with-ftd2xx-linux-tardir is not a dir: $with_ftd2xx_linux_tardir" "$LINENO" 5 + fi + +else + true +fi + + + +# Check whether --with-ftd2xx-lib was given. +if test "${with_ftd2xx_lib+set}" = set; then : + withval=$with_ftd2xx_lib; + case "$withval" in + static) + with_ftd2xx_lib=$withval + ;; + shared) + with_ftd2xx_lib=$withval + ;; + *) + as_fn_error $? "Option: --with-ftd2xx-lib=static or --with-ftd2xx-lib=shared not, $withval" "$LINENO" 5 + ;; + esac + +else + + # Default is static - it is simpler :-( + with_ftd2xx_lib=static + +fi + + +# Check whether --enable-doxygen-html was given. +if test "${enable_doxygen_html+set}" = set; then : + enableval=$enable_doxygen_html; doxygen_as_html=$enableval +else + doxygen_as_html=yes +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build Doxygen as HTML" >&5 +$as_echo_n "checking whether to build Doxygen as HTML... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $doxygen_as_html" >&5 +$as_echo "$doxygen_as_html" >&6; } + +# Check whether --enable-doxygen-pdf was given. +if test "${enable_doxygen_pdf+set}" = set; then : + enableval=$enable_doxygen_pdf; doxygen_as_pdf=$enableval +else + doxygen_as_pdf=no +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build Doxygen as PDF" >&5 +$as_echo_n "checking whether to build Doxygen as PDF... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $doxygen_as_pdf" >&5 +$as_echo "$doxygen_as_pdf" >&6; } + +# Check whether --enable-gccwarnings was given. +if test "${enable_gccwarnings+set}" = set; then : + enableval=$enable_gccwarnings; gcc_warnings=$enableval +else + gcc_warnings=yes +fi + + +# Check whether --enable-wextra was given. +if test "${enable_wextra+set}" = set; then : + enableval=$enable_wextra; gcc_wextra=$enableval +else + gcc_wextra=$gcc_warnings +fi + + +# Check whether --enable-werror was given. +if test "${enable_werror+set}" = set; then : + enableval=$enable_werror; gcc_werror=$enableval +else + gcc_werror=$gcc_warnings +fi + + +# set default verbose options, overridden by following options +debug_jtag_io=no +debug_usb_io=no +debug_usb_comms=no + +# Check whether --enable-verbose was given. +if test "${enable_verbose+set}" = set; then : + enableval=$enable_verbose; + debug_jtag_io=$enableval + debug_usb_io=$enableval + debug_usb_comms=$enableval + +fi + + +# Check whether --enable-verbose_jtag_io was given. +if test "${enable_verbose_jtag_io+set}" = set; then : + enableval=$enable_verbose_jtag_io; debug_jtag_io=$enableval +fi + + +# Check whether --enable-verbose_usb_io was given. +if test "${enable_verbose_usb_io+set}" = set; then : + enableval=$enable_verbose_usb_io; debug_usb_io=$enableval +fi + + +# Check whether --enable-verbose_usb_comms was given. +if test "${enable_verbose_usb_comms+set}" = set; then : + enableval=$enable_verbose_usb_comms; debug_usb_comms=$enableval +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable verbose JTAG I/O messages" >&5 +$as_echo_n "checking whether to enable verbose JTAG I/O messages... " >&6; }; +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $debug_jtag_io" >&5 +$as_echo "$debug_jtag_io" >&6; } +if test $debug_jtag_io = yes; then + +$as_echo "#define _DEBUG_JTAG_IO_ 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable verbose USB I/O messages" >&5 +$as_echo_n "checking whether to enable verbose USB I/O messages... " >&6; }; +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $debug_usb_io" >&5 +$as_echo "$debug_usb_io" >&6; } +if test $debug_usb_io = yes; then + +$as_echo "#define _DEBUG_USB_IO_ 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable verbose USB communication messages" >&5 +$as_echo_n "checking whether to enable verbose USB communication messages... " >&6; }; +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $debug_usb_comms" >&5 +$as_echo "$debug_usb_comms" >&6; } +if test $debug_usb_comms = yes; then + +$as_echo "#define _DEBUG_USB_COMMS_ 1" >>confdefs.h + +fi + +debug_malloc=no +# Check whether --enable-malloc_logging was given. +if test "${enable_malloc_logging+set}" = set; then : + enableval=$enable_malloc_logging; debug_malloc=$enableval +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable malloc free space logging" >&5 +$as_echo_n "checking whether to enable malloc free space logging... " >&6; }; +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $debug_malloc" >&5 +$as_echo "$debug_malloc" >&6; } +if test $debug_malloc = yes; then + +$as_echo "#define _DEBUG_FREE_SPACE_ 1" >>confdefs.h + +fi + +# Check whether --enable-dummy was given. +if test "${enable_dummy+set}" = set; then : + enableval=$enable_dummy; build_dummy=$enableval +else + build_dummy=no +fi + + +# Check whether --enable-parport was given. +if test "${enable_parport+set}" = set; then : + enableval=$enable_parport; build_parport=$enableval +else + build_parport=no +fi + + +# Check whether --enable-parport_ppdev was given. +if test "${enable_parport_ppdev+set}" = set; then : + enableval=$enable_parport_ppdev; parport_use_ppdev=$enableval +else + parport_use_ppdev=yes +fi + + +# Check whether --enable-parport_giveio was given. +if test "${enable_parport_giveio+set}" = set; then : + enableval=$enable_parport_giveio; parport_use_giveio=$enableval +else + parport_use_giveio= +fi + + +# Check whether --enable-ft2232_libftdi was given. +if test "${enable_ft2232_libftdi+set}" = set; then : + enableval=$enable_ft2232_libftdi; build_ft2232_libftdi=$enableval +else + build_ft2232_libftdi=no +fi + + +# Check whether --enable-ft2232_ftd2xx was given. +if test "${enable_ft2232_ftd2xx+set}" = set; then : + enableval=$enable_ft2232_ftd2xx; build_ft2232_ftd2xx=$enableval +else + build_ft2232_ftd2xx=no +fi + + +# Check whether --enable-ftdi was given. +if test "${enable_ftdi+set}" = set; then : + enableval=$enable_ftdi; build_ftdi=$enableval +else + build_ftdi=no +fi + + +# Check whether --enable-usb_blaster_libftdi was given. +if test "${enable_usb_blaster_libftdi+set}" = set; then : + enableval=$enable_usb_blaster_libftdi; build_usb_blaster_libftdi=$enableval +else + build_usb_blaster_libftdi=no +fi + + +# Check whether --enable-usb_blaster_ftd2xx was given. +if test "${enable_usb_blaster_ftd2xx+set}" = set; then : + enableval=$enable_usb_blaster_ftd2xx; build_usb_blaster_ftd2xx=$enableval +else + build_usb_blaster_ftd2xx=no +fi + + +# Check whether --enable-amtjtagaccel was given. +if test "${enable_amtjtagaccel+set}" = set; then : + enableval=$enable_amtjtagaccel; build_amtjtagaccel=$enableval +else + build_amtjtagaccel=no +fi + + +# Check whether --enable-zy1000_master was given. +if test "${enable_zy1000_master+set}" = set; then : + enableval=$enable_zy1000_master; build_zy1000_master=$enableval +else + build_zy1000_master=no +fi + + +# Check whether --enable-zy1000 was given. +if test "${enable_zy1000+set}" = set; then : + enableval=$enable_zy1000; build_zy1000=$enableval +else + build_zy1000=no +fi + + +# Check whether --enable-ioutil was given. +if test "${enable_ioutil+set}" = set; then : + enableval=$enable_ioutil; build_ioutil=$enableval +else + build_ioutil=no +fi + + +case "${host_cpu}" in + arm*) + # Check whether --enable-ep93xx was given. +if test "${enable_ep93xx+set}" = set; then : + enableval=$enable_ep93xx; build_ep93xx=$enableval +else + build_ep93xx=no +fi + + + # Check whether --enable-at91rm9200 was given. +if test "${enable_at91rm9200+set}" = set; then : + enableval=$enable_at91rm9200; build_at91rm9200=$enableval +else + build_at91rm9200=no +fi + + ;; + + *) + build_ep93xx=no + build_at91rm9200=no + ;; +esac + +# Check whether --enable-gw16012 was given. +if test "${enable_gw16012+set}" = set; then : + enableval=$enable_gw16012; build_gw16012=$enableval +else + build_gw16012=no +fi + + +# Check whether --enable-presto_libftdi was given. +if test "${enable_presto_libftdi+set}" = set; then : + enableval=$enable_presto_libftdi; build_presto_libftdi=$enableval +else + build_presto_libftdi=no +fi + + +# Check whether --enable-presto_ftd2xx was given. +if test "${enable_presto_ftd2xx+set}" = set; then : + enableval=$enable_presto_ftd2xx; build_presto_ftd2xx=$enableval +else + build_presto_ftd2xx=no +fi + + +# Check whether --enable-usbprog was given. +if test "${enable_usbprog+set}" = set; then : + enableval=$enable_usbprog; build_usbprog=$enableval +else + build_usbprog=no +fi + + +# Check whether --enable-oocd_trace was given. +if test "${enable_oocd_trace+set}" = set; then : + enableval=$enable_oocd_trace; build_oocd_trace=$enableval +else + build_oocd_trace=no +fi + + +# Check whether --enable-jlink was given. +if test "${enable_jlink+set}" = set; then : + enableval=$enable_jlink; build_jlink=$enableval +else + build_jlink=no +fi + + +# Check whether --enable-vsllink was given. +if test "${enable_vsllink+set}" = set; then : + enableval=$enable_vsllink; build_vsllink=$enableval +else + build_vsllink=no +fi + + +# Check whether --enable-rlink was given. +if test "${enable_rlink+set}" = set; then : + enableval=$enable_rlink; build_rlink=$enableval +else + build_rlink=no +fi + + +# Check whether --enable-ulink was given. +if test "${enable_ulink+set}" = set; then : + enableval=$enable_ulink; build_ulink=$enableval +else + build_ulink=no +fi + + +# Check whether --enable-arm-jtag-ew was given. +if test "${enable_arm_jtag_ew+set}" = set; then : + enableval=$enable_arm_jtag_ew; build_armjtagew=$enableval +else + build_armjtagew=no +fi + + +# Check whether --enable-buspirate was given. +if test "${enable_buspirate+set}" = set; then : + enableval=$enable_buspirate; build_buspirate=$enableval +else + build_buspirate=no +fi + + +# Check whether --enable-stlink was given. +if test "${enable_stlink+set}" = set; then : + enableval=$enable_stlink; build_hladapter_stlink=$enableval +else + build_hladapter_stlink=no +fi + + +# Check whether --enable-ti-icdi was given. +if test "${enable_ti_icdi+set}" = set; then : + enableval=$enable_ti_icdi; build_hladapter_icdi=$enableval +else + build_hladapter_icdi=no +fi + + +# Check whether --enable-osbdm was given. +if test "${enable_osbdm+set}" = set; then : + enableval=$enable_osbdm; build_osbdm=$enableval +else + build_osbdm=no +fi + + +# Check whether --enable-opendous was given. +if test "${enable_opendous+set}" = set; then : + enableval=$enable_opendous; build_opendous=$enableval +else + build_opendous=no +fi + + +# Check whether --enable-sysfsgpio was given. +if test "${enable_sysfsgpio+set}" = set; then : + enableval=$enable_sysfsgpio; build_sysfsgpio=$enableval +else + build_sysfsgpio=no +fi + + +# Check whether --enable-minidriver_dummy was given. +if test "${enable_minidriver_dummy+set}" = set; then : + enableval=$enable_minidriver_dummy; build_minidriver_dummy=$enableval +else + build_minidriver_dummy=no +fi + + +# Check whether --enable-internal-jimtcl was given. +if test "${enable_internal_jimtcl+set}" = set; then : + enableval=$enable_internal_jimtcl; use_internal_jimtcl=$enableval +else + use_internal_jimtcl=yes +fi + + +# Check whether --enable-libusb0 was given. +if test "${enable_libusb0+set}" = set; then : + enableval=$enable_libusb0; check_libusb0=$enableval +else + check_libusb0=no +fi + + +build_minidriver=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable ZY1000 minidriver" >&5 +$as_echo_n "checking whether to enable ZY1000 minidriver... " >&6; } +if test $build_zy1000 = yes; then + if test $build_minidriver = yes; then + as_fn_error $? "Multiple minidriver options have been enabled." "$LINENO" 5 + fi + +$as_echo "#define HAVE_JTAG_MINIDRIVER_H 1" >>confdefs.h + + build_minidriver=yes +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_zy1000" >&5 +$as_echo "$build_zy1000" >&6; } + +# Check whether --enable-remote-bitbang was given. +if test "${enable_remote_bitbang+set}" = set; then : + enableval=$enable_remote_bitbang; build_remote_bitbang=$enableval +else + build_remote_bitbang=no +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable dummy minidriver" >&5 +$as_echo_n "checking whether to enable dummy minidriver... " >&6; } +if test $build_minidriver_dummy = yes; then + if test $build_minidriver = yes; then + as_fn_error $? "Multiple minidriver options have been enabled." "$LINENO" 5 + fi + build_minidriver=yes + +$as_echo "#define BUILD_MINIDRIVER_DUMMY 1" >>confdefs.h + + +$as_echo "#define HAVE_JTAG_MINIDRIVER_H 1" >>confdefs.h + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_minidriver_dummy" >&5 +$as_echo "$build_minidriver_dummy" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether standard drivers can be built" >&5 +$as_echo_n "checking whether standard drivers can be built... " >&6; } +if test "$build_minidriver" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Using the minidriver disables all other drivers." >&5 +$as_echo "$as_me: WARNING: Using the minidriver disables all other drivers." >&2;} + sleep 2 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi + +case "${host_cpu}" in + i?86|x86*) + ;; + *) + if test x$parport_use_ppdev = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --disable-parport-ppdev is not supported by the host CPU" >&5 +$as_echo "$as_me: WARNING: --disable-parport-ppdev is not supported by the host CPU" >&2;} + fi + parport_use_ppdev=yes + ;; +esac + +case $host in + *-cygwin*) + is_win32=yes + parport_use_ppdev=no + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return __MINGW32__; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + is_mingw=yes +else + is_mingw=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $is_mingw = yes; then + +$as_echo "#define IS_MINGW 1" >>confdefs.h + + if test x$parport_use_giveio = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --disable-parport-giveio is not supported by MinGW32 hosts" >&5 +$as_echo "$as_me: WARNING: --disable-parport-giveio is not supported by MinGW32 hosts" >&2;} + fi + parport_use_giveio=yes + is_cygwin=no + else + is_cygwin=yes + +$as_echo "#define IS_CYGWIN 1" >>confdefs.h + + # sys/io.h needed under cygwin for parport access + if test $build_parport = yes; then + for ac_header in sys/io.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/io.h" "ac_cv_header_sys_io_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_io_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_IO_H 1 +_ACEOF + +else + as_fn_error $? "Please install the cygwin ioperm package" "$LINENO" 5 +fi + +done + + fi + fi + + +$as_echo "#define IS_WIN32 1" >>confdefs.h + + +$as_echo "#define IS_DARWIN 0" >>confdefs.h + + ;; + *-mingw*) + is_mingw=yes + is_win32=yes + parport_use_ppdev=no + + if test x$parport_use_giveio = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --disable-parport-giveio is not supported by MinGW32 hosts" >&5 +$as_echo "$as_me: WARNING: --disable-parport-giveio is not supported by MinGW32 hosts" >&2;} + fi + parport_use_giveio=yes + + if test x$build_buspirate = xyes; then + as_fn_error $? "buspirate currently not supported by MinGW32 hosts" "$LINENO" 5 + fi + + CFLAGS="$CFLAGS -D__USE_MINGW_ANSI_STDIO" + + +$as_echo "#define IS_MINGW 1" >>confdefs.h + + +$as_echo "#define IS_WIN32 1" >>confdefs.h + + +$as_echo "#define IS_DARWIN 0" >>confdefs.h + + ;; + *darwin*) + is_darwin=yes + + if test x$parport_use_giveio = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-parport-giveio cannot be used by Darwin hosts" >&5 +$as_echo "$as_me: WARNING: --enable-parport-giveio cannot be used by Darwin hosts" >&2;} + fi + parport_use_giveio=no + + +$as_echo "#define IS_CYGWIN 0" >>confdefs.h + + +$as_echo "#define IS_WIN32 0" >>confdefs.h + + +$as_echo "#define IS_DARWIN 1" >>confdefs.h + + ;; + *) + if test x$parport_use_giveio = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-parport-giveio cannot be used by $host hosts" >&5 +$as_echo "$as_me: WARNING: --enable-parport-giveio cannot be used by $host hosts" >&2;} + fi + parport_use_giveio=no + +$as_echo "#define IS_CYGWIN 0" >>confdefs.h + + +$as_echo "#define IS_WIN32 0" >>confdefs.h + + +$as_echo "#define IS_DARWIN 0" >>confdefs.h + + ;; +esac + +if test $build_parport = yes; then + build_bitbang=yes + +$as_echo "#define BUILD_PARPORT 1" >>confdefs.h + +else + +$as_echo "#define BUILD_PARPORT 0" >>confdefs.h + +fi + +if test $build_dummy = yes; then + build_bitbang=yes + +$as_echo "#define BUILD_DUMMY 1" >>confdefs.h + +else + +$as_echo "#define BUILD_DUMMY 0" >>confdefs.h + +fi + +if test $build_ep93xx = yes; then + build_bitbang=yes + +$as_echo "#define BUILD_EP93XX 1" >>confdefs.h + +else + +$as_echo "#define BUILD_EP93XX 0" >>confdefs.h + +fi + +if test $build_zy1000 = yes; then + +$as_echo "#define BUILD_ZY1000 1" >>confdefs.h + +else + +$as_echo "#define BUILD_ZY1000 0" >>confdefs.h + +fi + +if test $build_zy1000_master = yes; then + +$as_echo "#define BUILD_ZY1000_MASTER 1" >>confdefs.h + +else + +$as_echo "#define BUILD_ZY1000_MASTER 0" >>confdefs.h + +fi + +if test $build_at91rm9200 = yes; then + build_bitbang=yes + +$as_echo "#define BUILD_AT91RM9200 1" >>confdefs.h + +else + +$as_echo "#define BUILD_AT91RM9200 0" >>confdefs.h + +fi + +if test x$parport_use_ppdev = xyes; then + +$as_echo "#define PARPORT_USE_PPDEV 1" >>confdefs.h + +else + +$as_echo "#define PARPORT_USE_PPDEV 0" >>confdefs.h + +fi + +if test x$parport_use_giveio = xyes; then + +$as_echo "#define PARPORT_USE_GIVEIO 1" >>confdefs.h + +else + +$as_echo "#define PARPORT_USE_GIVEIO 0" >>confdefs.h + +fi + +if test $build_bitbang = yes; then + +$as_echo "#define BUILD_BITBANG 1" >>confdefs.h + +else + +$as_echo "#define BUILD_BITBANG 0" >>confdefs.h + +fi + +if test $build_ft2232_libftdi = yes; then + +$as_echo "#define BUILD_FT2232_LIBFTDI 1" >>confdefs.h + +else + +$as_echo "#define BUILD_FT2232_LIBFTDI 0" >>confdefs.h + +fi + +if test $build_ft2232_ftd2xx = yes; then + +$as_echo "#define BUILD_FT2232_FTD2XX 1" >>confdefs.h + +else + +$as_echo "#define BUILD_FT2232_FTD2XX 0" >>confdefs.h + +fi + +if test $build_ftdi = yes; then + +$as_echo "#define BUILD_FTDI 1" >>confdefs.h + +else + +$as_echo "#define BUILD_FTDI 0" >>confdefs.h + +fi + +if test $build_usb_blaster_libftdi = yes; then + build_bitbang=yes + +$as_echo "#define BUILD_USB_BLASTER_LIBFTDI 1" >>confdefs.h + +else + +$as_echo "#define BUILD_USB_BLASTER_LIBFTDI 0" >>confdefs.h + +fi + +if test $build_usb_blaster_ftd2xx = yes; then + build_bitbang=yes + +$as_echo "#define BUILD_USB_BLASTER_FTD2XX 1" >>confdefs.h + +else + +$as_echo "#define BUILD_USB_BLASTER_FTD2XX 0" >>confdefs.h + +fi + +if test $build_amtjtagaccel = yes; then + +$as_echo "#define BUILD_AMTJTAGACCEL 1" >>confdefs.h + +else + +$as_echo "#define BUILD_AMTJTAGACCEL 0" >>confdefs.h + +fi + +if test $build_gw16012 = yes; then + +$as_echo "#define BUILD_GW16012 1" >>confdefs.h + +else + +$as_echo "#define BUILD_GW16012 0" >>confdefs.h + +fi + +if test $build_presto_libftdi = yes; then + build_bitq=yes + +$as_echo "#define BUILD_PRESTO_LIBFTDI 1" >>confdefs.h + +else + +$as_echo "#define BUILD_PRESTO_LIBFTDI 0" >>confdefs.h + +fi + +if test $build_presto_ftd2xx = yes; then + build_bitq=yes + +$as_echo "#define BUILD_PRESTO_FTD2XX 1" >>confdefs.h + +else + +$as_echo "#define BUILD_PRESTO_FTD2XX 0" >>confdefs.h + +fi + +if test $build_bitq = yes; then + +$as_echo "#define BUILD_BITQ 1" >>confdefs.h + +else + +$as_echo "#define BUILD_BITQ 0" >>confdefs.h + +fi + +if test $build_usbprog = yes; then + +$as_echo "#define BUILD_USBPROG 1" >>confdefs.h + +else + +$as_echo "#define BUILD_USBPROG 0" >>confdefs.h + +fi + +if test $build_oocd_trace = yes; then + +$as_echo "#define BUILD_OOCD_TRACE 1" >>confdefs.h + +else + +$as_echo "#define BUILD_OOCD_TRACE 0" >>confdefs.h + +fi + +if test $build_jlink = yes; then + +$as_echo "#define BUILD_JLINK 1" >>confdefs.h + +else + +$as_echo "#define BUILD_JLINK 0" >>confdefs.h + +fi + +if test $build_vsllink = yes; then + +$as_echo "#define BUILD_VSLLINK 1" >>confdefs.h + +else + +$as_echo "#define BUILD_VSLLINK 0" >>confdefs.h + +fi + +if test $build_rlink = yes; then + +$as_echo "#define BUILD_RLINK 1" >>confdefs.h + +else + +$as_echo "#define BUILD_RLINK 0" >>confdefs.h + +fi + +if test $build_ulink = yes; then + +$as_echo "#define BUILD_ULINK 1" >>confdefs.h + +else + +$as_echo "#define BUILD_ULINK 0" >>confdefs.h + +fi + +if test $build_armjtagew = yes; then + +$as_echo "#define BUILD_ARMJTAGEW 1" >>confdefs.h + +else + +$as_echo "#define BUILD_ARMJTAGEW 0" >>confdefs.h + +fi + +if test $build_buspirate = yes; then + +$as_echo "#define BUILD_BUSPIRATE 1" >>confdefs.h + +else + +$as_echo "#define BUILD_BUSPIRATE 0" >>confdefs.h + +fi + +if test $build_hladapter_stlink = yes -o $build_hladapter_icdi = yes; then + +$as_echo "#define BUILD_HLADAPTER 1" >>confdefs.h + +else + +$as_echo "#define BUILD_HLADAPTER 0" >>confdefs.h + +fi + +if test $build_osbdm = yes; then + +$as_echo "#define BUILD_OSBDM 1" >>confdefs.h + +else + +$as_echo "#define BUILD_OSBDM 0" >>confdefs.h + +fi + +if test $build_opendous = yes; then + +$as_echo "#define BUILD_OPENDOUS 1" >>confdefs.h + +else + +$as_echo "#define BUILD_OPENDOUS 0" >>confdefs.h + +fi + +if test "$use_internal_jimtcl" = yes; then + if test -f "$srcdir/jimtcl/configure.ac"; then + + + +subdirs="$subdirs jimtcl" + + +printf "#!/bin/sh +"\$"SHELL "../$srcdir/jimtcl/configure" --disable-install-jim \""\$"@"\" > "$srcdir/jimtcl/configure.gnu" + + + else + as_fn_error $? "jimtcl not found, run git submodule init and git submodule update." "$LINENO" 5 + fi +fi + +if test $build_remote_bitbang = yes; then + build_bitbang=yes + +$as_echo "#define BUILD_REMOTE_BITBANG 1" >>confdefs.h + +else + +$as_echo "#define BUILD_REMOTE_BITBANG 0" >>confdefs.h + +fi + +if test $build_sysfsgpio = yes; then + build_bitbang=yes + +$as_echo "#define BUILD_SYSFSGPIO 1" >>confdefs.h + +else + +$as_echo "#define BUILD_SYSFSGPIO 0" >>confdefs.h + +fi +#-- Deal with MingW/Cygwin FTD2XX issues + +if test $is_win32 = yes; then +if test "${with_ftd2xx_linux_tardir+set}" = set +then + as_fn_error $? "The option: with_ftd2xx_linux_tardir is for LINUX only." "$LINENO" 5 +fi + +if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ftd2xx.lib exists (win32)" >&5 +$as_echo_n "checking for ftd2xx.lib exists (win32)... " >&6; } + + # if we are given a zipdir... + if test "${with_ftd2xx_win32_zipdir+set}" = set + then + # Set the CFLAGS for "ftd2xx.h" + f=$with_ftd2xx_win32_zipdir/ftd2xx.h + if test ! -f $f ; then + as_fn_error $? "File: $f cannot be found" "$LINENO" 5 + fi + CFLAGS="$CFLAGS -I$with_ftd2xx_win32_zipdir" + + # And calculate the LDFLAGS for the machine + case "$host_cpu" in + i?86|x86_32) + LDFLAGS="$LDFLAGS -L$with_ftd2xx_win32_zipdir/i386" + LIBS="$LIBS -lftd2xx" + f=$with_ftd2xx_win32_zipdir/i386/ftd2xx.lib + ;; + amd64|x86_64) + LDFLAGS="$LDFLAGS -L$with_ftd2xx_win32_zipdir/amd64" + LIBS="$LIBS -lftd2xx" + f=$with_ftd2xx_win32_zipdir/amd64/ftd2xx.lib + ;; + *) + as_fn_error $? "Unknown Win32 host cpu: $host_cpu" "$LINENO" 5 + ;; + esac + if test ! -f $f ; then + as_fn_error $? "Library: $f not found" "$LINENO" 5 + fi + else + LIBS="$LIBS -lftd2xx" + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ASSUMPTION: The (win32) FTDICHIP.COM files: ftd2xx.h and ftd2xx.lib are in a proper place" >&5 +$as_echo "$as_me: WARNING: ASSUMPTION: The (win32) FTDICHIP.COM files: ftd2xx.h and ftd2xx.lib are in a proper place" >&2;} + fi +fi +fi # win32 + +if test $is_darwin = yes ; then +if test "${with_ftd2xx_win32_zipdir+set}" = set +then + as_fn_error $? "The option: --with-ftd2xx-win32-zipdir is for win32 only" "$LINENO" 5 +fi +if test "${with_ftd2xx_linux_tardir+set}" = set +then + as_fn_error $? "The option: with_ftd2xx_linux_tardir is for LINUX only." "$LINENO" 5 +fi + +if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libftd2xx.a (darwin)" >&5 +$as_echo_n "checking for libftd2xx.a (darwin)... " >&6; } + + if test ! -f /usr/local/include/ftd2xx.h ; then + as_fn_error $? "ftd2xx library from FTDICHIP.com seems to be missing, cannot find: /usr/local/include/ftd2xx.h" "$LINENO" 5 + fi + + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -lftd2xx" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: -L/usr/local/lib -lftd2xx" >&5 +$as_echo "-L/usr/local/lib -lftd2xx" >&6; } +fi +fi # darwin + +if test $is_win32 = no && test $is_darwin = no ; then + +if test "${with_ftd2xx_win32_zipdir+set}" = set +then + as_fn_error $? "The option: --with-ftd2xx-win32-zipdir is for win32 only" "$LINENO" 5 +fi + +if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes ; then + # Must be linux + if test $host_os != linux-gnu && test $host_os != linux ; then + as_fn_error $? "The (linux) ftd2xx library from FTDICHIP.com is linux only. Try --enable-ft2232-libftdi instead" "$LINENO" 5 + fi + # Are we given a TAR directory? + if test "${with_ftd2xx_linux_tardir+set}" = set + then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking uninstalled ftd2xx distribution" >&5 +$as_echo_n "checking uninstalled ftd2xx distribution... " >&6; } + # The .H file is simple.. + FTD2XX_H=$with_ftd2xx_linux_tardir/ftd2xx.h + if test ! -f "${FTD2XX_H}"; then + as_fn_error $? "Option: --with-ftd2xx-linux-tardir appears wrong, cannot find: ${FTD2XX_H}" "$LINENO" 5 + fi + CFLAGS="$CFLAGS -I$with_ftd2xx_linux_tardir" + if test $with_ftd2xx_lib = shared; then + FTD2XX_LDFLAGS="-L$with_ftd2xx_linux_tardir" + FTD2XX_LIB="-lftd2xx" + else + # Test #1 - v1.0.x + case "$host_cpu" in + i?86|x86_32) + dir=build/i386;; + amd64|x86_64) + dir=build/x86_64;; + *) + dir=none;; + esac + if test -f "$with_ftd2xx_linux_tardir/$dir/libftd2xx.a"; then + FTD2XX_LDFLAGS="-L$with_ftd2xx_linux_tardir/$dir" + # Also needs -lrt + FTD2XX_LIB="-lftd2xx -lrt" + else + # Test Number2. + # Grr.. perhaps it exists as a version number? + FTD2XX_LIB="$with_ftd2xx_linux_tardir/static_lib/libftd2xx.a.*.*.*" + count=`ls ${FTD2XX_LIB} | wc -l` + if test $count -gt 1 ; then + as_fn_error $? "Multiple libftd2xx.a files found in: $with_ftd2xx_linux_tardir/static_lib sorry cannot handle this yet" "$LINENO" 5 + fi + if test $count -ne 1 ; then + as_fn_error $? "Not found: $f, option: --with-ftd2xx-linux-tardir appears to be wrong" "$LINENO" 5 + fi + # Because the "-l" rules do not understand version numbers... + # we will just stuff the absolute path onto the LIBS variable + FTD2XX_LIB="`ls ${FTD2XX_LIB}` -lpthread" + FTD2XX_LDFLAGS="" + fi + fi + LDFLAGS="${LDFLAGS} ${FTD2XX_LDFLAGS}" + LIBS="${FTD2XX_LIB} ${LIBS}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${FTD2XX_LDFLAGS} ${FTD2XX_LIB}" >&5 +$as_echo "${FTD2XX_LDFLAGS} ${FTD2XX_LIB}" >&6; } + else + ac_fn_c_check_header_mongrel "$LINENO" "ftd2xx.h" "ac_cv_header_ftd2xx_h" "$ac_includes_default" +if test "x$ac_cv_header_ftd2xx_h" = xyes; then : + +else + + as_fn_error $? "You seem to be missing the FTD2xx driver header file." "$LINENO" 5 + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing FT_GetLibraryVersion" >&5 +$as_echo_n "checking for library containing FT_GetLibraryVersion... " >&6; } +if ${ac_cv_search_FT_GetLibraryVersion+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char FT_GetLibraryVersion (); +int +main () +{ +return FT_GetLibraryVersion (); + ; + return 0; +} +_ACEOF +for ac_lib in '' ftd2xx; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_FT_GetLibraryVersion=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_FT_GetLibraryVersion+:} false; then : + break +fi +done +if ${ac_cv_search_FT_GetLibraryVersion+:} false; then : + +else + ac_cv_search_FT_GetLibraryVersion=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_FT_GetLibraryVersion" >&5 +$as_echo "$ac_cv_search_FT_GetLibraryVersion" >&6; } +ac_res=$ac_cv_search_FT_GetLibraryVersion +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + + as_fn_error $? "You appear to be missing the FTD2xx driver library." "$LINENO" 5 + +fi + + fi +fi +fi # linux + +if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes ; then + +# Before we go any further - make sure we can *BUILD* and *RUN* +# a simple app with the "ftd2xx.lib" file - in what ever form we where given +# We should be able to compile, link and run this test program now +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ftd2xx library works" >&5 +$as_echo_n "checking whether ftd2xx library works... " >&6; } + +# +# Save the LDFLAGS for later.. +LDFLAGS_SAVE=$LDFLAGS +CFLAGS_SAVE=$CFLAGS +_LDFLAGS=`eval echo $LDFLAGS` +_CFLAGS=`eval echo $CFLAGS` +LDFLAGS=$_LDFLAGS +CFLAGS=$_CFLAGS + +if test "$cross_compiling" = yes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Skipping as we are cross-compiling" >&5 +$as_echo "Skipping as we are cross-compiling" >&6; } + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include "confdefs.h" +#if IS_WIN32 +#include "windows.h" +#endif +#include +#include + +int +main () +{ + + DWORD x; + FT_GetLibraryVersion( &x ); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Success!" >&5 +$as_echo "Success!" >&6; } + +else + + as_fn_error $? "Cannot build & run test program using ftd2xx.lib" "$LINENO" 5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ftd2xx highspeed device support" >&5 +$as_echo_n "checking for ftd2xx highspeed device support... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include "confdefs.h" +#if IS_WIN32 +#include "windows.h" +#endif +#include +#include + +DWORD x = FT_DEVICE_4232H; + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + +$as_echo "#define BUILD_FT2232_HIGHSPEED 1" >>confdefs.h + + build_ft2232_highspeed=yes + +else + + build_ft2232_highspeed=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_ft2232_highspeed" >&5 +$as_echo "$build_ft2232_highspeed" >&6; } + + if test $build_ft2232_highspeed = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You need a newer FTD2XX driver (version 2.04.16 or later)." >&5 +$as_echo "$as_me: WARNING: You need a newer FTD2XX driver (version 2.04.16 or later)." >&2;} + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ftd2xx FT232H device support" >&5 +$as_echo_n "checking for ftd2xx FT232H device support... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include "confdefs.h" +#if IS_WIN32 +#include "windows.h" +#endif +#include +#include + +DWORD x = FT_DEVICE_232H; + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + +$as_echo "#define HAS_ENUM_FT232H 1" >>confdefs.h + + has_enum_ft232h=yes + +else + + has_enum_ft232h=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_enum_ft232h" >&5 +$as_echo "$has_enum_ft232h" >&6; } + + if test $has_enum_ft232h = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You need a newer FTD2XX driver (version 2.08.12 or later)." >&5 +$as_echo "$as_me: WARNING: You need a newer FTD2XX driver (version 2.08.12 or later)." >&2;} + fi + +LDFLAGS=$LDFLAGS_SAVE +CFLAGS=$CFLAGS_SAVE +fi + +if test $build_ft2232_libftdi = yes ; then + # We assume: the package is preinstalled in the proper place + # these present as 2 libraries.. + LIBS="$LIBS -lftdi -lusb" + # + # Try to build a small program. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking Build & Link with libftdi..." >&5 +$as_echo_n "checking Build & Link with libftdi...... " >&6; } + + LDFLAGS_SAVE=$LDFLAGS + CFLAGS_SAVE=$CFLAGS + _LDFLAGS=`eval echo $LDFLAGS` + _CFLAGS=`eval echo $CFLAGS` + LDFLAGS=$_LDFLAGS + CFLAGS=$_CFLAGS + + if test "$cross_compiling" = yes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Skipping as we are cross-compiling" >&5 +$as_echo "Skipping as we are cross-compiling" >&6; } + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main () +{ + + struct ftdi_context *p; + p = ftdi_new(); + if( p != NULL ){ + return 0; + } else { + fprintf( stderr, "calling ftdi_new() failed\n"); + return 1; + } + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Success" >&5 +$as_echo "Success" >&6; } + +else + + as_fn_error $? "Cannot build & run test program using libftdi" "$LINENO" 5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libftdi highspeed device support" >&5 +$as_echo_n "checking for libftdi highspeed device support... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main () +{ + +enum ftdi_chip_type x = TYPE_2232H; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + +$as_echo "#define BUILD_FT2232_HIGHSPEED 1" >>confdefs.h + + build_ft2232_highspeed=yes + +else + + build_ft2232_highspeed=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_ft2232_highspeed" >&5 +$as_echo "$build_ft2232_highspeed" >&6; } + + if test $build_ft2232_highspeed = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You need a newer libftdi version (0.16 or later)." >&5 +$as_echo "$as_me: WARNING: You need a newer libftdi version (0.16 or later)." >&2;} + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libftdi FT232H device support" >&5 +$as_echo_n "checking for libftdi FT232H device support... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main () +{ + +enum ftdi_chip_type x = TYPE_232H; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + +$as_echo "#define HAS_ENUM_FT232H 1" >>confdefs.h + + has_enum_ft232h=yes + +else + + has_enum_ft232h=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_enum_ft232h" >&5 +$as_echo "$has_enum_ft232h" >&6; } + + if test $has_enum_ft232h = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You need a newer libftdi version (0.20 or later)." >&5 +$as_echo "$as_me: WARNING: You need a newer libftdi version (0.20 or later)." >&2;} + fi + + # Restore the 'unexpanded ldflags' + LDFLAGS=$LDFLAGS_SAVE + CFLAGS=$CFLAGS_SAVE +fi + +# check for usb.h when a driver will require it +build_usb=no +if test $build_vsllink = yes -o $build_usbprog = yes -o \ + $build_rlink = yes -o $build_ulink = yes -o $build_armjtagew = yes +then + build_usb=yes +fi + +# Check for libusb1 ported drivers. +build_usb_ng=no +if test $build_jlink = yes -o $build_hladapter_stlink = yes -o $build_osbdm = yes -o \ + $build_opendous = yes -o $build_ftdi = yes -o $build_hladapter_icdi = yes +then + build_usb_ng=yes +fi + +# check for libusb library if necessary +use_libusb0=no +use_libusb1=no +if test $build_usb = yes -o $build_usb_ng = yes; then + if test $check_libusb0 = no -a $build_usb_ng = yes; then + ac_fn_c_check_header_mongrel "$LINENO" "libusb-1.0/libusb.h" "ac_cv_header_libusb_1_0_libusb_h" "$ac_includes_default" +if test "x$ac_cv_header_libusb_1_0_libusb_h" = xyes; then : + +$as_echo "#define HAVE_LIBUSB1 1" >>confdefs.h + check_libusb0=no use_libusb1=yes +else + check_libusb0=yes use_libusb1=no +fi + + + fi + + if test $check_libusb0 = yes -o $build_usb = yes; then + for ac_header in usb.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "usb.h" "ac_cv_header_usb_h" "$ac_includes_default" +if test "x$ac_cv_header_usb_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_USB_H 1 +_ACEOF + use_libusb0=yes +else + as_fn_error $? "libusb or libusb-1.0 are required to build some OpenOCD driver(s)" "$LINENO" 5 +fi + +done + + fi +fi + + if test $build_release = yes; then + RELEASE_TRUE= + RELEASE_FALSE='#' +else + RELEASE_TRUE='#' + RELEASE_FALSE= +fi + + if test $build_parport = yes; then + PARPORT_TRUE= + PARPORT_FALSE='#' +else + PARPORT_TRUE='#' + PARPORT_FALSE= +fi + + if test $build_dummy = yes; then + DUMMY_TRUE= + DUMMY_FALSE='#' +else + DUMMY_TRUE='#' + DUMMY_FALSE= +fi + + if test x$parport_use_giveio = xyes; then + GIVEIO_TRUE= + GIVEIO_FALSE='#' +else + GIVEIO_TRUE='#' + GIVEIO_FALSE= +fi + + if test $build_ep93xx = yes; then + EP93XX_TRUE= + EP93XX_FALSE='#' +else + EP93XX_TRUE='#' + EP93XX_FALSE= +fi + + if test $build_zy1000 = yes; then + ZY1000_TRUE= + ZY1000_FALSE='#' +else + ZY1000_TRUE='#' + ZY1000_FALSE= +fi + + if test $build_zy1000_master = yes; then + ZY1000_MASTER_TRUE= + ZY1000_MASTER_FALSE='#' +else + ZY1000_MASTER_TRUE='#' + ZY1000_MASTER_FALSE= +fi + + if test $build_ioutil = yes; then + IOUTIL_TRUE= + IOUTIL_FALSE='#' +else + IOUTIL_TRUE='#' + IOUTIL_FALSE= +fi + + if test $build_at91rm9200 = yes; then + AT91RM9200_TRUE= + AT91RM9200_FALSE='#' +else + AT91RM9200_TRUE='#' + AT91RM9200_FALSE= +fi + + if test $build_bitbang = yes; then + BITBANG_TRUE= + BITBANG_FALSE='#' +else + BITBANG_TRUE='#' + BITBANG_FALSE= +fi + + if test $build_ft2232_libftdi = yes; then + FT2232_LIBFTDI_TRUE= + FT2232_LIBFTDI_FALSE='#' +else + FT2232_LIBFTDI_TRUE='#' + FT2232_LIBFTDI_FALSE= +fi + + if test $build_ft2232_ftd2xx = yes -o $build_ft2232_libftdi = yes; then + FT2232_DRIVER_TRUE= + FT2232_DRIVER_FALSE='#' +else + FT2232_DRIVER_TRUE='#' + FT2232_DRIVER_FALSE= +fi + + if test $build_ftdi = yes; then + FTDI_DRIVER_TRUE= + FTDI_DRIVER_FALSE='#' +else + FTDI_DRIVER_TRUE='#' + FTDI_DRIVER_FALSE= +fi + + if test $build_usb_blaster_libftdi = yes; then + USB_BLASTER_LIBFTDI_TRUE= + USB_BLASTER_LIBFTDI_FALSE='#' +else + USB_BLASTER_LIBFTDI_TRUE='#' + USB_BLASTER_LIBFTDI_FALSE= +fi + + if test $build_usb_blaster_ftd2xx = yes -o $build_usb_blaster_libftdi = yes; then + USB_BLASTER_DRIVER_TRUE= + USB_BLASTER_DRIVER_FALSE='#' +else + USB_BLASTER_DRIVER_TRUE='#' + USB_BLASTER_DRIVER_FALSE= +fi + + if test $build_amtjtagaccel = yes; then + AMTJTAGACCEL_TRUE= + AMTJTAGACCEL_FALSE='#' +else + AMTJTAGACCEL_TRUE='#' + AMTJTAGACCEL_FALSE= +fi + + if test $build_gw16012 = yes; then + GW16012_TRUE= + GW16012_FALSE='#' +else + GW16012_TRUE='#' + GW16012_FALSE= +fi + + if test $build_presto_libftdi = yes; then + PRESTO_LIBFTDI_TRUE= + PRESTO_LIBFTDI_FALSE='#' +else + PRESTO_LIBFTDI_TRUE='#' + PRESTO_LIBFTDI_FALSE= +fi + + if test $build_presto_ftd2xx = yes -o $build_presto_libftdi = yes; then + PRESTO_DRIVER_TRUE= + PRESTO_DRIVER_FALSE='#' +else + PRESTO_DRIVER_TRUE='#' + PRESTO_DRIVER_FALSE= +fi + + if test $build_usbprog = yes; then + USBPROG_TRUE= + USBPROG_FALSE='#' +else + USBPROG_TRUE='#' + USBPROG_FALSE= +fi + + if test $build_oocd_trace = yes; then + OOCD_TRACE_TRUE= + OOCD_TRACE_FALSE='#' +else + OOCD_TRACE_TRUE='#' + OOCD_TRACE_FALSE= +fi + + if test $build_jlink = yes; then + JLINK_TRUE= + JLINK_FALSE='#' +else + JLINK_TRUE='#' + JLINK_FALSE= +fi + + if test $build_vsllink = yes; then + VSLLINK_TRUE= + VSLLINK_FALSE='#' +else + VSLLINK_TRUE='#' + VSLLINK_FALSE= +fi + + if test $build_rlink = yes; then + RLINK_TRUE= + RLINK_FALSE='#' +else + RLINK_TRUE='#' + RLINK_FALSE= +fi + + if test $build_ulink = yes; then + ULINK_TRUE= + ULINK_FALSE='#' +else + ULINK_TRUE='#' + ULINK_FALSE= +fi + + if test $build_armjtagew = yes; then + ARMJTAGEW_TRUE= + ARMJTAGEW_FALSE='#' +else + ARMJTAGEW_TRUE='#' + ARMJTAGEW_FALSE= +fi + + if test $build_remote_bitbang = yes; then + REMOTE_BITBANG_TRUE= + REMOTE_BITBANG_FALSE='#' +else + REMOTE_BITBANG_TRUE='#' + REMOTE_BITBANG_FALSE= +fi + + if test $build_buspirate = yes; then + BUSPIRATE_TRUE= + BUSPIRATE_FALSE='#' +else + BUSPIRATE_TRUE='#' + BUSPIRATE_FALSE= +fi + + if test $build_hladapter_stlink = yes -o $build_hladapter_icdi = yes; then + HLADAPTER_TRUE= + HLADAPTER_FALSE='#' +else + HLADAPTER_TRUE='#' + HLADAPTER_FALSE= +fi + + if test $build_osbdm = yes; then + OSBDM_TRUE= + OSBDM_FALSE='#' +else + OSBDM_TRUE='#' + OSBDM_FALSE= +fi + + if test $build_opendous = yes; then + OPENDOUS_TRUE= + OPENDOUS_FALSE='#' +else + OPENDOUS_TRUE='#' + OPENDOUS_FALSE= +fi + + if test $build_sysfsgpio = yes; then + SYSFSGPIO_TRUE= + SYSFSGPIO_FALSE='#' +else + SYSFSGPIO_TRUE='#' + SYSFSGPIO_FALSE= +fi + + if test $build_usb = yes; then + USB_TRUE= + USB_FALSE='#' +else + USB_TRUE='#' + USB_FALSE= +fi + + if test $build_usb_ng = yes; then + USB_NG_TRUE= + USB_NG_FALSE='#' +else + USB_NG_TRUE='#' + USB_NG_FALSE= +fi + + if test $use_libusb0 = yes; then + USE_LIBUSB0_TRUE= + USE_LIBUSB0_FALSE='#' +else + USE_LIBUSB0_TRUE='#' + USE_LIBUSB0_FALSE= +fi + + if test $use_libusb1 = yes; then + USE_LIBUSB1_TRUE= + USE_LIBUSB1_FALSE='#' +else + USE_LIBUSB1_TRUE='#' + USE_LIBUSB1_FALSE= +fi + + if test $is_cygwin = yes; then + IS_CYGWIN_TRUE= + IS_CYGWIN_FALSE='#' +else + IS_CYGWIN_TRUE='#' + IS_CYGWIN_FALSE= +fi + + if test $is_mingw = yes; then + IS_MINGW_TRUE= + IS_MINGW_FALSE='#' +else + IS_MINGW_TRUE='#' + IS_MINGW_FALSE= +fi + + if test $is_win32 = yes; then + IS_WIN32_TRUE= + IS_WIN32_FALSE='#' +else + IS_WIN32_TRUE='#' + IS_WIN32_FALSE= +fi + + if test $is_darwin = yes; then + IS_DARWIN_TRUE= + IS_DARWIN_FALSE='#' +else + IS_DARWIN_TRUE='#' + IS_DARWIN_FALSE= +fi + + if test $build_bitq = yes; then + BITQ_TRUE= + BITQ_FALSE='#' +else + BITQ_TRUE='#' + BITQ_FALSE= +fi + + + if test $build_minidriver = yes; then + MINIDRIVER_TRUE= + MINIDRIVER_FALSE='#' +else + MINIDRIVER_TRUE='#' + MINIDRIVER_FALSE= +fi + + if test $build_minidriver_dummy = yes; then + MINIDRIVER_DUMMY_TRUE= + MINIDRIVER_DUMMY_FALSE='#' +else + MINIDRIVER_DUMMY_TRUE='#' + MINIDRIVER_DUMMY_FALSE= +fi + + + if test $use_internal_jimtcl = yes; then + INTERNAL_JIMTCL_TRUE= + INTERNAL_JIMTCL_FALSE='#' +else + INTERNAL_JIMTCL_TRUE='#' + INTERNAL_JIMTCL_FALSE= +fi + + +# Look for environ alternatives. Possibility #1: is environ in unistd.h or stdlib.h? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for environ in unistd.h and stdlib.h" >&5 +$as_echo_n "checking for environ in unistd.h and stdlib.h... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define _GNU_SOURCE +#include +#include + +int +main () +{ +char **ep = environ; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + has_environ=yes + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + # Possibility #2: can environ be found in an available library? + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for extern environ" >&5 +$as_echo_n "checking for extern environ... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + extern char **environ; + +int +main () +{ +char **ep = environ; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + +$as_echo "#define NEED_ENVIRON_EXTERN 1" >>confdefs.h + + has_environ=yes + +else + + has_environ=no + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${has_environ}" >&5 +$as_echo "${has_environ}" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test "${has_environ}" != "yes" ; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Could not find 'environ' in unistd.h or available libraries. +See \`config.log' for more details" "$LINENO" 5; } +fi + + +$as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + +# set default gcc warnings +GCC_WARNINGS="-Wall -Wstrict-prototypes -Wformat-security -Wshadow" +if test "${gcc_wextra}" = yes; then + GCC_WARNINGS="${GCC_WARNINGS} -Wextra -Wno-unused-parameter" + GCC_WARNINGS="${GCC_WARNINGS} -Wbad-function-cast" + GCC_WARNINGS="${GCC_WARNINGS} -Wcast-align" + GCC_WARNINGS="${GCC_WARNINGS} -Wredundant-decls" +fi +if test "${gcc_werror}" = yes; then + GCC_WARNINGS="${GCC_WARNINGS} -Werror" +fi + +# overide default gcc cflags +if test $gcc_warnings = yes; then + CFLAGS="$CFLAGS $GCC_WARNINGS" +fi + +# Setup for compiling build tools +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a C compiler for build tools" >&5 +$as_echo_n "checking for a C compiler for build tools... " >&6; } +if test $cross_compiling = yes; then + for ac_prog in gcc cc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC_FOR_BUILD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC_FOR_BUILD"; then + ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC_FOR_BUILD="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD +if test -n "$CC_FOR_BUILD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +$as_echo "$CC_FOR_BUILD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC_FOR_BUILD" && break +done + + CFLAGS_FOR_BUILD="-g -O2 $GCC_WARNINGS" +else + CC_FOR_BUILD=$CC + CFLAGS_FOR_BUILD=$CFLAGS +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +$as_echo "$CC_FOR_BUILD" >&6; } + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executable build tools" >&5 +$as_echo_n "checking for suffix of executable build tools... " >&6; } +if test $cross_compiling = yes; then + cat >conftest.c <<\_______EOF +int main () +{ + exit (0); +} +_______EOF + for i in .exe ""; do + compile="$CC_FOR_BUILD conftest.c -o conftest$i" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$compile\""; } >&5 + (eval $compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if (./conftest) 2>&5; then + EXEEXT_FOR_BUILD=$i + break + fi + fi + done + rm -f conftest* + if test "${EXEEXT_FOR_BUILD+set}" != set; then + as_fn_error $? "Cannot determine suffix of executable build tools" "$LINENO" 5 + fi +else + EXEEXT_FOR_BUILD=$EXEEXT +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXEEXT_FOR_BUILD" >&5 +$as_echo "$EXEEXT_FOR_BUILD" >&6; } + + +ac_config_files="$ac_config_files Makefile src/Makefile src/helper/Makefile src/jtag/Makefile src/jtag/drivers/Makefile src/jtag/hla/Makefile src/transport/Makefile src/xsvf/Makefile src/svf/Makefile src/target/Makefile src/rtos/Makefile src/server/Makefile src/flash/Makefile src/flash/nor/Makefile src/flash/nand/Makefile src/pld/Makefile doc/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +if test -z "${RELEASE_TRUE}" && test -z "${RELEASE_FALSE}"; then + as_fn_error $? "conditional \"RELEASE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${PARPORT_TRUE}" && test -z "${PARPORT_FALSE}"; then + as_fn_error $? "conditional \"PARPORT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${DUMMY_TRUE}" && test -z "${DUMMY_FALSE}"; then + as_fn_error $? "conditional \"DUMMY\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GIVEIO_TRUE}" && test -z "${GIVEIO_FALSE}"; then + as_fn_error $? "conditional \"GIVEIO\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${EP93XX_TRUE}" && test -z "${EP93XX_FALSE}"; then + as_fn_error $? "conditional \"EP93XX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ZY1000_TRUE}" && test -z "${ZY1000_FALSE}"; then + as_fn_error $? "conditional \"ZY1000\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ZY1000_MASTER_TRUE}" && test -z "${ZY1000_MASTER_FALSE}"; then + as_fn_error $? "conditional \"ZY1000_MASTER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${IOUTIL_TRUE}" && test -z "${IOUTIL_FALSE}"; then + as_fn_error $? "conditional \"IOUTIL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AT91RM9200_TRUE}" && test -z "${AT91RM9200_FALSE}"; then + as_fn_error $? "conditional \"AT91RM9200\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BITBANG_TRUE}" && test -z "${BITBANG_FALSE}"; then + as_fn_error $? "conditional \"BITBANG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${FT2232_LIBFTDI_TRUE}" && test -z "${FT2232_LIBFTDI_FALSE}"; then + as_fn_error $? "conditional \"FT2232_LIBFTDI\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${FT2232_DRIVER_TRUE}" && test -z "${FT2232_DRIVER_FALSE}"; then + as_fn_error $? "conditional \"FT2232_DRIVER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${FTDI_DRIVER_TRUE}" && test -z "${FTDI_DRIVER_FALSE}"; then + as_fn_error $? "conditional \"FTDI_DRIVER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USB_BLASTER_LIBFTDI_TRUE}" && test -z "${USB_BLASTER_LIBFTDI_FALSE}"; then + as_fn_error $? "conditional \"USB_BLASTER_LIBFTDI\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USB_BLASTER_DRIVER_TRUE}" && test -z "${USB_BLASTER_DRIVER_FALSE}"; then + as_fn_error $? "conditional \"USB_BLASTER_DRIVER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMTJTAGACCEL_TRUE}" && test -z "${AMTJTAGACCEL_FALSE}"; then + as_fn_error $? "conditional \"AMTJTAGACCEL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GW16012_TRUE}" && test -z "${GW16012_FALSE}"; then + as_fn_error $? "conditional \"GW16012\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${PRESTO_LIBFTDI_TRUE}" && test -z "${PRESTO_LIBFTDI_FALSE}"; then + as_fn_error $? "conditional \"PRESTO_LIBFTDI\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${PRESTO_DRIVER_TRUE}" && test -z "${PRESTO_DRIVER_FALSE}"; then + as_fn_error $? "conditional \"PRESTO_DRIVER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USBPROG_TRUE}" && test -z "${USBPROG_FALSE}"; then + as_fn_error $? "conditional \"USBPROG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${OOCD_TRACE_TRUE}" && test -z "${OOCD_TRACE_FALSE}"; then + as_fn_error $? "conditional \"OOCD_TRACE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${JLINK_TRUE}" && test -z "${JLINK_FALSE}"; then + as_fn_error $? "conditional \"JLINK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${VSLLINK_TRUE}" && test -z "${VSLLINK_FALSE}"; then + as_fn_error $? "conditional \"VSLLINK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${RLINK_TRUE}" && test -z "${RLINK_FALSE}"; then + as_fn_error $? "conditional \"RLINK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ULINK_TRUE}" && test -z "${ULINK_FALSE}"; then + as_fn_error $? "conditional \"ULINK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ARMJTAGEW_TRUE}" && test -z "${ARMJTAGEW_FALSE}"; then + as_fn_error $? "conditional \"ARMJTAGEW\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${REMOTE_BITBANG_TRUE}" && test -z "${REMOTE_BITBANG_FALSE}"; then + as_fn_error $? "conditional \"REMOTE_BITBANG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUSPIRATE_TRUE}" && test -z "${BUSPIRATE_FALSE}"; then + as_fn_error $? "conditional \"BUSPIRATE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HLADAPTER_TRUE}" && test -z "${HLADAPTER_FALSE}"; then + as_fn_error $? "conditional \"HLADAPTER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${OSBDM_TRUE}" && test -z "${OSBDM_FALSE}"; then + as_fn_error $? "conditional \"OSBDM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${OPENDOUS_TRUE}" && test -z "${OPENDOUS_FALSE}"; then + as_fn_error $? "conditional \"OPENDOUS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${SYSFSGPIO_TRUE}" && test -z "${SYSFSGPIO_FALSE}"; then + as_fn_error $? "conditional \"SYSFSGPIO\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USB_TRUE}" && test -z "${USB_FALSE}"; then + as_fn_error $? "conditional \"USB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USB_NG_TRUE}" && test -z "${USB_NG_FALSE}"; then + as_fn_error $? "conditional \"USB_NG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_LIBUSB0_TRUE}" && test -z "${USE_LIBUSB0_FALSE}"; then + as_fn_error $? "conditional \"USE_LIBUSB0\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_LIBUSB1_TRUE}" && test -z "${USE_LIBUSB1_FALSE}"; then + as_fn_error $? "conditional \"USE_LIBUSB1\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${IS_CYGWIN_TRUE}" && test -z "${IS_CYGWIN_FALSE}"; then + as_fn_error $? "conditional \"IS_CYGWIN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${IS_MINGW_TRUE}" && test -z "${IS_MINGW_FALSE}"; then + as_fn_error $? "conditional \"IS_MINGW\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${IS_WIN32_TRUE}" && test -z "${IS_WIN32_FALSE}"; then + as_fn_error $? "conditional \"IS_WIN32\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${IS_DARWIN_TRUE}" && test -z "${IS_DARWIN_FALSE}"; then + as_fn_error $? "conditional \"IS_DARWIN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BITQ_TRUE}" && test -z "${BITQ_FALSE}"; then + as_fn_error $? "conditional \"BITQ\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MINIDRIVER_TRUE}" && test -z "${MINIDRIVER_FALSE}"; then + as_fn_error $? "conditional \"MINIDRIVER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MINIDRIVER_DUMMY_TRUE}" && test -z "${MINIDRIVER_DUMMY_FALSE}"; then + as_fn_error $? "conditional \"MINIDRIVER_DUMMY\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${INTERNAL_JIMTCL_TRUE}" && test -z "${INTERNAL_JIMTCL_FALSE}"; then + as_fn_error $? "conditional \"INTERNAL_JIMTCL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by openocd $as_me 0.7.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to >." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +openocd config.status 0.7.0 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "src/helper/Makefile") CONFIG_FILES="$CONFIG_FILES src/helper/Makefile" ;; + "src/jtag/Makefile") CONFIG_FILES="$CONFIG_FILES src/jtag/Makefile" ;; + "src/jtag/drivers/Makefile") CONFIG_FILES="$CONFIG_FILES src/jtag/drivers/Makefile" ;; + "src/jtag/hla/Makefile") CONFIG_FILES="$CONFIG_FILES src/jtag/hla/Makefile" ;; + "src/transport/Makefile") CONFIG_FILES="$CONFIG_FILES src/transport/Makefile" ;; + "src/xsvf/Makefile") CONFIG_FILES="$CONFIG_FILES src/xsvf/Makefile" ;; + "src/svf/Makefile") CONFIG_FILES="$CONFIG_FILES src/svf/Makefile" ;; + "src/target/Makefile") CONFIG_FILES="$CONFIG_FILES src/target/Makefile" ;; + "src/rtos/Makefile") CONFIG_FILES="$CONFIG_FILES src/rtos/Makefile" ;; + "src/server/Makefile") CONFIG_FILES="$CONFIG_FILES src/server/Makefile" ;; + "src/flash/Makefile") CONFIG_FILES="$CONFIG_FILES src/flash/Makefile" ;; + "src/flash/nor/Makefile") CONFIG_FILES="$CONFIG_FILES src/flash/nor/Makefile" ;; + "src/flash/nand/Makefile") CONFIG_FILES="$CONFIG_FILES src/flash/nand/Makefile" ;; + "src/pld/Makefile") CONFIG_FILES="$CONFIG_FILES src/pld/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="" + +# ### BEGIN LIBTOOL CONFIG + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi + +# +# CONFIG_SUBDIRS section. +# +if test "$no_recursion" != yes; then + + # Remove --cache-file, --srcdir, and --disable-option-checking arguments + # so they do not pile up. + ac_sub_configure_args= + ac_prev= + eval "set x $ac_configure_args" + shift + for ac_arg + do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case $ac_arg in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ + | --c=*) + ;; + --config-cache | -C) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + ;; + --disable-option-checking) + ;; + *) + case $ac_arg in + *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_sub_configure_args " '$ac_arg'" ;; + esac + done + + # Always prepend --prefix to ensure using the same prefix + # in subdir configurations. + ac_arg="--prefix=$prefix" + case $ac_arg in + *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" + + # Pass --silent + if test "$silent" = yes; then + ac_sub_configure_args="--silent $ac_sub_configure_args" + fi + + # Always prepend --disable-option-checking to silence warnings, since + # different subdirs can have different --enable and --with options. + ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args" + + ac_popdir=`pwd` + for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + test -d "$srcdir/$ac_dir" || continue + + ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)" + $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5 + $as_echo "$ac_msg" >&6 + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + cd "$ac_dir" + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f "$ac_srcdir/configure.gnu"; then + ac_sub_configure=$ac_srcdir/configure.gnu + elif test -f "$ac_srcdir/configure"; then + ac_sub_configure=$ac_srcdir/configure + elif test -f "$ac_srcdir/configure.in"; then + # This should be Cygnus configure. + ac_sub_configure=$ac_aux_dir/configure + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5 +$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + # Make the cache file name correct relative to the subdirectory. + case $cache_file in + [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; + *) # Relative name. + ac_sub_cache_file=$ac_top_build_prefix$cache_file ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 +$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} + # The eval makes quoting arguments work. + eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \ + --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" || + as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5 + fi + + cd "$ac_popdir" + done +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/debuggers/openocd/configure.ac b/debuggers/openocd/configure.ac new file mode 100644 index 00000000..6ec042db --- /dev/null +++ b/debuggers/openocd/configure.ac @@ -0,0 +1,1328 @@ +AC_PREREQ(2.60) +AC_INIT([openocd], [0.7.0], + [OpenOCD Mailing List ]) +AC_CONFIG_SRCDIR([src/openocd.c]) + +m4_include([config_subdir.m4])dnl + +AM_INIT_AUTOMAKE([-Wall -Wno-portability dist-bzip2 dist-zip]) +AM_MAINTAINER_MODE + +AC_CONFIG_HEADERS([config.h]) +AH_BOTTOM([ +#include +#include +#include +]) + +AC_LANG_C +AC_PROG_CC +AC_PROG_CC_C99 +AM_PROG_CC_C_O +AC_PROG_RANLIB + +dnl disable checks for C++, Fortran and GNU Java Compiler +m4_defun([_LT_AC_LANG_CXX_CONFIG], [:]) +m4_defun([_LT_AC_LANG_F77_CONFIG], [:]) +m4_defun([_LT_AC_LANG_GCJ_CONFIG], [:]) +AC_DISABLE_SHARED +AC_PROG_LIBTOOL +AC_SUBST([LIBTOOL_DEPS]) + +dnl configure checks required for Jim files (these are obsolete w/ C99) +AC_C_CONST +AC_TYPE_LONG_LONG_INT + +AC_SEARCH_LIBS([ioperm], [ioperm]) +AC_SEARCH_LIBS([dlopen], [dl]) + +AC_CHECK_HEADERS([sys/socket.h]) +AC_CHECK_HEADERS([arpa/inet.h], [], [], [dnl +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +]) +AC_CHECK_HEADERS([elf.h]) +AC_CHECK_HEADERS([dirent.h]) +AC_CHECK_HEADERS([fcntl.h]) +AC_CHECK_HEADERS([ifaddrs.h], [], [], [dnl +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +]) +AC_CHECK_HEADERS([malloc.h]) +AC_CHECK_HEADERS([netdb.h]) +AC_CHECK_HEADERS([netinet/in.h], [], [], [dnl +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +]) +AC_CHECK_HEADERS([netinet/tcp.h], [], [], [dnl +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +]) +AC_CHECK_HEADERS([pthread.h]) +AC_CHECK_HEADERS([strings.h]) +AC_CHECK_HEADERS([sys/ioctl.h]) +AC_CHECK_HEADERS([sys/param.h]) +AC_CHECK_HEADERS([sys/poll.h]) +AC_CHECK_HEADERS([sys/select.h]) +AC_CHECK_HEADERS([sys/stat.h]) +AC_CHECK_HEADERS([sys/time.h]) +AC_CHECK_HEADERS([sys/types.h]) +AC_CHECK_HEADERS([unistd.h]) +AC_CHECK_HEADERS([net/if.h], [], [], [dnl +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +]) + +AC_HEADER_ASSERT +AC_HEADER_STDBOOL +AC_HEADER_TIME + +AC_C_BIGENDIAN + +AC_CHECK_FUNCS([strndup]) +AC_CHECK_FUNCS([strnlen]) +AC_CHECK_FUNCS([gettimeofday]) +AC_CHECK_FUNCS([usleep]) +AC_CHECK_FUNCS([vasprintf]) + +build_bitbang=no +build_bitq=no +is_cygwin=no +is_mingw=no +is_win32=no +is_darwin=no + +# guess-rev.sh only exists in the repository, not in the released archives +AC_MSG_CHECKING([whether to build a release]) +if test -x $srcdir/guess-rev.sh ; then + build_release=no +else + build_release=yes +fi +AC_MSG_RESULT([$build_release]) + +# We are not *ALWAYS* being installed in the standard place. +# We may be installed in a "tool-build" specific location. +# Normally with other packages - as part of a tool distro. +# Thus - we should search that 'libdir' also. +# +# And - if we are being installed there - the odds are +# The libraries unique to what we are are there too. +# + +# Expand nd deal with NONE - just like configure will do later +OCDprefix=$prefix +OCDxprefix=$exec_prefix +test x"$OCDprefix" = xNONE && OCDprefix=$ac_default_prefix +# Let make expand exec_prefix. +test x"$OCDxprefix" = xNONE && OCDxprefix="$OCDprefix" + +# what matters is the "exec-prefix" +if test "$OCDxprefix" != "$ac_default_prefix" +then + # We are installing in a non-standard place + # Nonstandard --prefix and/or --exec-prefix + # We have an override of some sort. + # use build specific install library dir + + LDFLAGS="$LDFLAGS -L$OCDxprefix/lib" + # RPATH becomes an issue on Linux only + if test $host_os = linux-gnu || test $host_os = linux ; then + LDFLAGS="$LDFLAGS -Wl,-rpath,$OCDxprefix/lib" + fi + # The "INCDIR" is also usable + CFLAGS="$CFLAGS -I$includedir" +fi + +AC_ARG_WITH(ftd2xx, + AS_HELP_STRING([--with-ftd2xx=],[This option has been removed.]), + [ +# Option Given. +cat << __EOF__ + +The option: --with-ftd2xx= has been removed. +On Linux, the new option is: + + --with-ftd2xx-linux-tardir=/path/to/files + +Where is the path the the directory where the "tar.gz" file +from FTDICHIP.COM was unpacked, for example: + + --with-ftd2xx-linux-tardir=${HOME}/libftd2xx0.4.16 + +On Cygwin/MingW32, the new option is: + + --with-ftd2xx-win32-zipdir=/path/to/files + +Where is the path to the directory where the "zip" file from +FTDICHIP.COM was unpacked, for example: + + --with-ftd2xx-win32-zipdir=${HOME}/ftd2xx.cdm.files + +__EOF__ + + AC_MSG_ERROR([Sorry Cannot continue]) + ], [true]) + +#======================================== +# FTD2XXX support comes in 4 forms. +# (1) win32 - via a zip file +# (2) linux - via a tar file +# (3) linux/cygwin/mingw - via libftdi +# (4) darwin - installed under /usr/local +# +# In case (1) and (2) we need to know where the package was unpacked. + +AC_ARG_WITH(ftd2xx-win32-zipdir, + AS_HELP_STRING([--with-ftd2xx-win32-zipdir],[Where (CYGWIN/MINGW) the zip file from ftdichip.com was unpacked (default=search)]), + [ + # option present + if test -d $with_ftd2xx_win32_zipdir + then + with_ftd2xx_win32_zipdir=`cd $with_ftd2xx_win32_zipdir && pwd` + AC_MSG_NOTICE([Using: ftdichip.com library: $with_ftd2xx_win32_zipdir]) + else + AC_MSG_ERROR([Parameter to --with-ftd2xx-win32-zipdir is not a dir: $with_ftd2xx_win32_zipdir]) + fi + ], [true]) + +AC_ARG_WITH(ftd2xx-linux-tardir, + AS_HELP_STRING([--with-ftd2xx-linux-tardir], [Where (Linux/Unix) the tar file from ftdichip.com was unpacked (default=search)]), + [ + # Option present + if test $is_win32 = yes ; then + AC_MSG_ERROR([The option: --with-ftd2xx-linux-tardir is only usable on linux]) + fi + if test -d $with_ftd2xx_linux_tardir + then + with_ftd2xx_linux_tardir=`cd $with_ftd2xx_linux_tardir && pwd` + AC_MSG_NOTICE([Using: ftdichip.com library: $with_ftd2xx_linux_tardir]) + else + AC_MSG_ERROR([Parameter to --with-ftd2xx-linux-tardir is not a dir: $with_ftd2xx_linux_tardir]) + fi + ], [true]) + +AC_ARG_WITH(ftd2xx-lib, + AS_HELP_STRING([--with-ftd2xx-lib], + [Use static or shared ftd2xx libs (default=static)]), + [ + case "$withval" in + static) + with_ftd2xx_lib=$withval + ;; + shared) + with_ftd2xx_lib=$withval + ;; + *) + AC_MSG_ERROR([Option: --with-ftd2xx-lib=static or --with-ftd2xx-lib=shared not, $withval]) + ;; + esac + ], [ + # Default is static - it is simpler :-( + with_ftd2xx_lib=static + ]) + +AC_ARG_ENABLE([doxygen-html], + AS_HELP_STRING([--disable-doxygen-html], + [Disable building Doxygen manual as HTML.]), + [doxygen_as_html=$enableval], [doxygen_as_html=yes]) +AC_SUBST([doxygen_as_html]) +AC_MSG_CHECKING([whether to build Doxygen as HTML]) +AC_MSG_RESULT([$doxygen_as_html]) + +AC_ARG_ENABLE([doxygen-pdf], + AS_HELP_STRING([--enable-doxygen-pdf], + [Enable building Doxygen manual as PDF.]), + [doxygen_as_pdf=$enableval], [doxygen_as_pdf=no]) +AC_SUBST([doxygen_as_pdf]) +AC_MSG_CHECKING([whether to build Doxygen as PDF]) +AC_MSG_RESULT([$doxygen_as_pdf]) + +AC_ARG_ENABLE([gccwarnings], + AS_HELP_STRING([--disable-gccwarnings], [Disable compiler warnings]), + [gcc_warnings=$enableval], [gcc_warnings=yes]) + +AC_ARG_ENABLE([wextra], + AS_HELP_STRING([--disable-wextra], [Disable extra compiler warnings]), + [gcc_wextra=$enableval], [gcc_wextra=$gcc_warnings]) + +AC_ARG_ENABLE([werror], + AS_HELP_STRING([--disable-werror], [Do not treat warnings as errors]), + [gcc_werror=$enableval], [gcc_werror=$gcc_warnings]) + +# set default verbose options, overridden by following options +debug_jtag_io=no +debug_usb_io=no +debug_usb_comms=no + +AC_ARG_ENABLE([verbose], + AS_HELP_STRING([--enable-verbose], + [Enable verbose JTAG I/O messages (for debugging).]), + [ + debug_jtag_io=$enableval + debug_usb_io=$enableval + debug_usb_comms=$enableval + ], []) + +AC_ARG_ENABLE([verbose_jtag_io], + AS_HELP_STRING([--enable-verbose-jtag-io], + [Enable verbose JTAG I/O messages (for debugging).]), + [debug_jtag_io=$enableval], []) + +AC_ARG_ENABLE([verbose_usb_io], + AS_HELP_STRING([--enable-verbose-usb-io], + [Enable verbose USB I/O messages (for debugging)]), + [debug_usb_io=$enableval], []) + +AC_ARG_ENABLE([verbose_usb_comms], + AS_HELP_STRING([--enable-verbose-usb-comms], + [Enable verbose USB communication messages (for debugging)]), + [debug_usb_comms=$enableval], []) + +AC_MSG_CHECKING([whether to enable verbose JTAG I/O messages]); +AC_MSG_RESULT([$debug_jtag_io]) +if test $debug_jtag_io = yes; then + AC_DEFINE([_DEBUG_JTAG_IO_],[1], [Print verbose JTAG I/O messages]) +fi + +AC_MSG_CHECKING([whether to enable verbose USB I/O messages]); +AC_MSG_RESULT([$debug_usb_io]) +if test $debug_usb_io = yes; then + AC_DEFINE([_DEBUG_USB_IO_],[1], [Print verbose USB I/O messages]) +fi + +AC_MSG_CHECKING([whether to enable verbose USB communication messages]); +AC_MSG_RESULT([$debug_usb_comms]) +if test $debug_usb_comms = yes; then + AC_DEFINE([_DEBUG_USB_COMMS_],[1], [Print verbose USB communication messages]) +fi + +debug_malloc=no +AC_ARG_ENABLE([malloc_logging], + AS_HELP_STRING([--enable-malloc-logging], + [Include free space in logging messages (requires malloc.h).]), + [debug_malloc=$enableval], []) + +AC_MSG_CHECKING([whether to enable malloc free space logging]); +AC_MSG_RESULT([$debug_malloc]) +if test $debug_malloc = yes; then + AC_DEFINE([_DEBUG_FREE_SPACE_],[1], [Include malloc free space in logging]) +fi + +AC_ARG_ENABLE([dummy], + AS_HELP_STRING([--enable-dummy], [Enable building the dummy port driver]), + [build_dummy=$enableval], [build_dummy=no]) + +AC_ARG_ENABLE([parport], + AS_HELP_STRING([--enable-parport], [Enable building the pc parallel port driver]), + [build_parport=$enableval], [build_parport=no]) + +AC_ARG_ENABLE([parport_ppdev], + AS_HELP_STRING([--disable-parport-ppdev], + [Disable use of ppdev (/dev/parportN) for parport (for x86 only)]), + [parport_use_ppdev=$enableval], [parport_use_ppdev=yes]) + +AC_ARG_ENABLE([parport_giveio], + AS_HELP_STRING([--enable-parport-giveio], + [Enable use of giveio for parport (for CygWin only)]), + [parport_use_giveio=$enableval], [parport_use_giveio=]) + +AC_ARG_ENABLE([ft2232_libftdi], + AS_HELP_STRING([--enable-ft2232_libftdi], [Enable building support for FT2232 based devices using the libftdi driver, opensource alternate of FTD2XX]), + [build_ft2232_libftdi=$enableval], [build_ft2232_libftdi=no]) + +AC_ARG_ENABLE([ft2232_ftd2xx], + AS_HELP_STRING([--enable-ft2232_ftd2xx], [Enable building support for FT2232 based devices using the FTD2XX driver from ftdichip.com]), + [build_ft2232_ftd2xx=$enableval], [build_ft2232_ftd2xx=no]) + +AC_ARG_ENABLE([ftdi], + AS_HELP_STRING([--enable-ftdi], [Enable building support for the MPSSE mode of FTDI based devices, using libusb-1.0 in asynchronous mode]), + [build_ftdi=$enableval], [build_ftdi=no]) + +AC_ARG_ENABLE([usb_blaster_libftdi], + AS_HELP_STRING([--enable-usb_blaster_libftdi], [Enable building support for the Altera USB-Blaster using the libftdi driver, opensource alternate of FTD2XX]), + [build_usb_blaster_libftdi=$enableval], [build_usb_blaster_libftdi=no]) + +AC_ARG_ENABLE([usb_blaster_ftd2xx], + AS_HELP_STRING([--enable-usb_blaster_ftd2xx], [Enable building support for the Altera USB-Blaster using the FTD2XX driver from ftdichip.com]), + [build_usb_blaster_ftd2xx=$enableval], [build_usb_blaster_ftd2xx=no]) + +AC_ARG_ENABLE([amtjtagaccel], + AS_HELP_STRING([--enable-amtjtagaccel], [Enable building the Amontec JTAG-Accelerator driver]), + [build_amtjtagaccel=$enableval], [build_amtjtagaccel=no]) + +AC_ARG_ENABLE([zy1000_master], + AS_HELP_STRING([--enable-zy1000-master], [Use ZY1000 JTAG master registers]), + [build_zy1000_master=$enableval], [build_zy1000_master=no]) + +AC_ARG_ENABLE([zy1000], + AS_HELP_STRING([--enable-zy1000], [Enable ZY1000 interface]), + [build_zy1000=$enableval], [build_zy1000=no]) + +AC_ARG_ENABLE([ioutil], + AS_HELP_STRING([--enable-ioutil], [Enable ioutil functions - useful for standalone OpenOCD implementations]), + [build_ioutil=$enableval], [build_ioutil=no]) + +case "${host_cpu}" in + arm*) + AC_ARG_ENABLE([ep93xx], + AS_HELP_STRING([--enable-ep93xx], [Enable building support for EP93xx based SBCs]), + [build_ep93xx=$enableval], [build_ep93xx=no]) + + AC_ARG_ENABLE([at91rm9200], + AS_HELP_STRING([--enable-at91rm9200], [Enable building support for AT91RM9200 based SBCs]), + [build_at91rm9200=$enableval], [build_at91rm9200=no]) + ;; + + *) + build_ep93xx=no + build_at91rm9200=no + ;; +esac + +AC_ARG_ENABLE([gw16012], + AS_HELP_STRING([--enable-gw16012], [Enable building support for the Gateworks GW16012 JTAG Programmer]), + [build_gw16012=$enableval], [build_gw16012=no]) + +AC_ARG_ENABLE([presto_libftdi], + AS_HELP_STRING([--enable-presto_libftdi], [Enable building support for ASIX Presto Programmer using the libftdi driver]), + [build_presto_libftdi=$enableval], [build_presto_libftdi=no]) + +AC_ARG_ENABLE([presto_ftd2xx], + AS_HELP_STRING([--enable-presto_ftd2xx], [Enable building support for ASIX Presto Programmer using the FTD2XX driver]), + [build_presto_ftd2xx=$enableval], [build_presto_ftd2xx=no]) + +AC_ARG_ENABLE([usbprog], + AS_HELP_STRING([--enable-usbprog], [Enable building support for the usbprog JTAG Programmer]), + [build_usbprog=$enableval], [build_usbprog=no]) + +AC_ARG_ENABLE([oocd_trace], + AS_HELP_STRING([--enable-oocd_trace], + [Enable building support for some prototype OpenOCD+trace ETM capture hardware]), + [build_oocd_trace=$enableval], [build_oocd_trace=no]) + +AC_ARG_ENABLE([jlink], + AS_HELP_STRING([--enable-jlink], [Enable building support for the Segger J-Link JTAG Programmer]), + [build_jlink=$enableval], [build_jlink=no]) + +AC_ARG_ENABLE([vsllink], + AS_HELP_STRING([--enable-vsllink], [Enable building support for the Versaloon-Link JTAG Programmer]), + [build_vsllink=$enableval], [build_vsllink=no]) + +AC_ARG_ENABLE([rlink], + AS_HELP_STRING([--enable-rlink], [Enable building support for the Raisonance RLink JTAG Programmer]), + [build_rlink=$enableval], [build_rlink=no]) + +AC_ARG_ENABLE([ulink], + AS_HELP_STRING([--enable-ulink], [Enable building support for the Keil ULINK JTAG Programmer]), + [build_ulink=$enableval], [build_ulink=no]) + +AC_ARG_ENABLE([arm-jtag-ew], + AS_HELP_STRING([--enable-arm-jtag-ew], [Enable building support for the Olimex ARM-JTAG-EW Programmer]), + [build_armjtagew=$enableval], [build_armjtagew=no]) + +AC_ARG_ENABLE([buspirate], + AS_HELP_STRING([--enable-buspirate], [Enable building support for the Buspirate]), + [build_buspirate=$enableval], [build_buspirate=no]) + +AC_ARG_ENABLE([stlink], + AS_HELP_STRING([--enable-stlink], [Enable building support for the ST-Link JTAG Programmer]), + [build_hladapter_stlink=$enableval], [build_hladapter_stlink=no]) + +AC_ARG_ENABLE([ti-icdi], + AS_HELP_STRING([--enable-ti-icdi], [Enable building support for the TI ICDI JTAG Programmer]), + [build_hladapter_icdi=$enableval], [build_hladapter_icdi=no]) + +AC_ARG_ENABLE([osbdm], + AS_HELP_STRING([--enable-osbdm], [Enable building support for the OSBDM (JTAG only) Programmer]), + [build_osbdm=$enableval], [build_osbdm=no]) + +AC_ARG_ENABLE([opendous], + AS_HELP_STRING([--enable-opendous], [Enable building support for the estick/opendous JTAG Programmer]), + [build_opendous=$enableval], [build_opendous=no]) + +AC_ARG_ENABLE([sysfsgpio], + AS_HELP_STRING([--enable-sysfsgpio], [Enable building support for programming driven via sysfs gpios.]), + [build_sysfsgpio=$enableval], [build_sysfsgpio=no]) + +AC_ARG_ENABLE([minidriver_dummy], + AS_HELP_STRING([--enable-minidriver-dummy], [Enable the dummy minidriver.]), + [build_minidriver_dummy=$enableval], [build_minidriver_dummy=no]) + +AC_ARG_ENABLE([internal-jimtcl], + AS_HELP_STRING([--disable-internal-jimtcl], [Disable building internal jimtcl]), + [use_internal_jimtcl=$enableval], [use_internal_jimtcl=yes]) + +AC_ARG_ENABLE([libusb0], + AS_HELP_STRING([--enable-libusb0], [Use libusb-0.1 library for USB JTAG devices]), + [check_libusb0=$enableval], [check_libusb0=no]) + +build_minidriver=no +AC_MSG_CHECKING([whether to enable ZY1000 minidriver]) +if test $build_zy1000 = yes; then + if test $build_minidriver = yes; then + AC_MSG_ERROR([Multiple minidriver options have been enabled.]) + fi + AC_DEFINE([HAVE_JTAG_MINIDRIVER_H], [1], + [Define to 1 if you have the header file.]) + build_minidriver=yes +fi +AC_MSG_RESULT([$build_zy1000]) + +AC_ARG_ENABLE([remote-bitbang], + AS_HELP_STRING([--enable-remote-bitbang], [Enable building support for the Remote Bitbang jtag driver]), + [build_remote_bitbang=$enableval], [build_remote_bitbang=no]) + +AC_MSG_CHECKING([whether to enable dummy minidriver]) +if test $build_minidriver_dummy = yes; then + if test $build_minidriver = yes; then + AC_MSG_ERROR([Multiple minidriver options have been enabled.]) + fi + build_minidriver=yes + AC_DEFINE([BUILD_MINIDRIVER_DUMMY], [1], [Use the dummy minidriver.]) + AC_DEFINE([HAVE_JTAG_MINIDRIVER_H], [1], + [Define to 1 if you have the header file.]) +fi +AC_MSG_RESULT([$build_minidriver_dummy]) + +AC_MSG_CHECKING([whether standard drivers can be built]) +if test "$build_minidriver" = yes; then + AC_MSG_RESULT([no]) + AC_MSG_WARN([Using the minidriver disables all other drivers.]) + sleep 2 +else + AC_MSG_RESULT([yes]) +fi + +case "${host_cpu}" in + i?86|x86*) + ;; + *) + if test x$parport_use_ppdev = xno; then + AC_MSG_WARN([--disable-parport-ppdev is not supported by the host CPU]) + fi + parport_use_ppdev=yes + ;; +esac + +case $host in + *-cygwin*) + is_win32=yes + parport_use_ppdev=no + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[return __MINGW32__;]])], + [is_mingw=yes],[is_mingw=no]) + if test $is_mingw = yes; then + AC_DEFINE([IS_MINGW], [1], [1 if building for MinGW.]) + if test x$parport_use_giveio = xno; then + AC_MSG_WARN([--disable-parport-giveio is not supported by MinGW32 hosts]) + fi + parport_use_giveio=yes + is_cygwin=no + else + is_cygwin=yes + AC_DEFINE([IS_CYGWIN], [1], [1 if building for Cygwin.]) + # sys/io.h needed under cygwin for parport access + if test $build_parport = yes; then + AC_CHECK_HEADERS([sys/io.h],[],AC_MSG_ERROR([Please install the cygwin ioperm package])) + fi + fi + + AC_DEFINE([IS_WIN32], [1], [1 if building for Win32.]) + AC_DEFINE([IS_DARWIN], [0], [0 if not building for Darwin.]) + ;; + *-mingw*) + is_mingw=yes + is_win32=yes + parport_use_ppdev=no + + if test x$parport_use_giveio = xno; then + AC_MSG_WARN([--disable-parport-giveio is not supported by MinGW32 hosts]) + fi + parport_use_giveio=yes + + if test x$build_buspirate = xyes; then + AC_MSG_ERROR([buspirate currently not supported by MinGW32 hosts]) + fi + + CFLAGS="$CFLAGS -D__USE_MINGW_ANSI_STDIO" + + AC_DEFINE([IS_MINGW], [1], [1 if building for MinGW.]) + AC_DEFINE([IS_WIN32], [1], [1 if building for Win32.]) + AC_DEFINE([IS_DARWIN], [0], [0 if not building for Darwin.]) + ;; + *darwin*) + is_darwin=yes + + if test x$parport_use_giveio = xyes; then + AC_MSG_WARN([--enable-parport-giveio cannot be used by Darwin hosts]) + fi + parport_use_giveio=no + + AC_DEFINE([IS_CYGWIN], [0], [0 if not building for Cygwin.]) + AC_DEFINE([IS_WIN32], [0], [0 if not building for Win32.]) + AC_DEFINE([IS_DARWIN], [1], [1 if building for Darwin.]) + ;; + *) + if test x$parport_use_giveio = xyes; then + AC_MSG_WARN([--enable-parport-giveio cannot be used by ]$host[ hosts]) + fi + parport_use_giveio=no + AC_DEFINE([IS_CYGWIN], [0], [0 if not building for Cygwin.]) + AC_DEFINE([IS_WIN32], [0], [0 if not building for Win32.]) + AC_DEFINE([IS_DARWIN], [0], [0 if not building for Darwin.]) + ;; +esac + +if test $build_parport = yes; then + build_bitbang=yes + AC_DEFINE([BUILD_PARPORT], [1], [1 if you want parport.]) +else + AC_DEFINE([BUILD_PARPORT], [0], [0 if you don't want parport.]) +fi + +if test $build_dummy = yes; then + build_bitbang=yes + AC_DEFINE([BUILD_DUMMY], [1], [1 if you want dummy driver.]) +else + AC_DEFINE([BUILD_DUMMY], [0], [0 if you don't want dummy driver.]) +fi + +if test $build_ep93xx = yes; then + build_bitbang=yes + AC_DEFINE([BUILD_EP93XX], [1], [1 if you want ep93xx.]) +else + AC_DEFINE([BUILD_EP93XX], [0], [0 if you don't want ep93xx.]) +fi + +if test $build_zy1000 = yes; then + AC_DEFINE([BUILD_ZY1000], [1], [1 if you want ZY1000.]) +else + AC_DEFINE([BUILD_ZY1000], [0], [0 if you don't want ZY1000.]) +fi + +if test $build_zy1000_master = yes; then + AC_DEFINE([BUILD_ZY1000_MASTER], [1], [1 if you want ZY1000 JTAG master registers.]) +else + AC_DEFINE([BUILD_ZY1000_MASTER], [0], [0 if you don't want ZY1000 JTAG master registers.]) +fi + +if test $build_at91rm9200 = yes; then + build_bitbang=yes + AC_DEFINE([BUILD_AT91RM9200], [1], [1 if you want at91rm9200.]) +else + AC_DEFINE([BUILD_AT91RM9200], [0], [0 if you don't want at91rm9200.]) +fi + +if test x$parport_use_ppdev = xyes; then + AC_DEFINE([PARPORT_USE_PPDEV], [1], [1 if you want parport to use ppdev.]) +else + AC_DEFINE([PARPORT_USE_PPDEV], [0], [0 if you don't want parport to use ppdev.]) +fi + +if test x$parport_use_giveio = xyes; then + AC_DEFINE([PARPORT_USE_GIVEIO], [1], [1 if you want parport to use giveio.]) +else + AC_DEFINE([PARPORT_USE_GIVEIO], [0], [0 if you don't want parport to use giveio.]) +fi + +if test $build_bitbang = yes; then + AC_DEFINE([BUILD_BITBANG], [1], [1 if you want a bitbang interface.]) +else + AC_DEFINE([BUILD_BITBANG], [0], [0 if you don't want a bitbang interface.]) +fi + +if test $build_ft2232_libftdi = yes; then + AC_DEFINE([BUILD_FT2232_LIBFTDI], [1], [1 if you want libftdi ft2232.]) +else + AC_DEFINE([BUILD_FT2232_LIBFTDI], [0], [0 if you don't want libftdi ft2232.]) +fi + +if test $build_ft2232_ftd2xx = yes; then + AC_DEFINE([BUILD_FT2232_FTD2XX], [1], [1 if you want ftd2xx ft2232.]) +else + AC_DEFINE([BUILD_FT2232_FTD2XX], [0], [0 if you don't want ftd2xx ft2232.]) +fi + +if test $build_ftdi = yes; then + AC_DEFINE([BUILD_FTDI], [1], [1 if you want ftdi.]) +else + AC_DEFINE([BUILD_FTDI], [0], [0 if you don't want ftdi.]) +fi + +if test $build_usb_blaster_libftdi = yes; then + build_bitbang=yes + AC_DEFINE([BUILD_USB_BLASTER_LIBFTDI], [1], [1 if you want libftdi usb_blaster.]) +else + AC_DEFINE([BUILD_USB_BLASTER_LIBFTDI], [0], [0 if you don't want libftdi usb_blaster.]) +fi + +if test $build_usb_blaster_ftd2xx = yes; then + build_bitbang=yes + AC_DEFINE([BUILD_USB_BLASTER_FTD2XX], [1], [1 if you want ftd2xx usb_blaster.]) +else + AC_DEFINE([BUILD_USB_BLASTER_FTD2XX], [0], [0 if you don't want ftd2xx usb_blaster.]) +fi + +if test $build_amtjtagaccel = yes; then + AC_DEFINE([BUILD_AMTJTAGACCEL], [1], [1 if you want the Amontec JTAG-Accelerator driver.]) +else + AC_DEFINE([BUILD_AMTJTAGACCEL], [0], [0 if you don't want the Amontec JTAG-Accelerator driver.]) +fi + +if test $build_gw16012 = yes; then + AC_DEFINE([BUILD_GW16012], [1], [1 if you want the Gateworks GW16012 driver.]) +else + AC_DEFINE([BUILD_GW16012], [0], [0 if you don't want the Gateworks GW16012 driver.]) +fi + +if test $build_presto_libftdi = yes; then + build_bitq=yes + AC_DEFINE([BUILD_PRESTO_LIBFTDI], [1], [1 if you want the ASIX PRESTO driver using libftdi.]) +else + AC_DEFINE([BUILD_PRESTO_LIBFTDI], [0], [0 if you don't want the ASIX PRESTO driver using libftdi.]) +fi + +if test $build_presto_ftd2xx = yes; then + build_bitq=yes + AC_DEFINE([BUILD_PRESTO_FTD2XX], [1], [1 if you want the ASIX PRESTO driver using FTD2XX.]) +else + AC_DEFINE([BUILD_PRESTO_FTD2XX], [0], [0 if you don't want the ASIX PRESTO driver using FTD2XX.]) +fi + +if test $build_bitq = yes; then + AC_DEFINE([BUILD_BITQ], [1], [1 if you want a bitq interface.]) +else + AC_DEFINE([BUILD_BITQ], [0], [0 if you don't want a bitq interface.]) +fi + +if test $build_usbprog = yes; then + AC_DEFINE([BUILD_USBPROG], [1], [1 if you want the usbprog JTAG driver.]) +else + AC_DEFINE([BUILD_USBPROG], [0], [0 if you don't want the usbprog JTAG driver.]) +fi + +if test $build_oocd_trace = yes; then + AC_DEFINE([BUILD_OOCD_TRACE], [1], [1 if you want the OpenOCD+trace ETM capture driver.]) +else + AC_DEFINE([BUILD_OOCD_TRACE], [0], [0 if you don't want the OpenOCD+trace ETM capture driver.]) +fi + +if test $build_jlink = yes; then + AC_DEFINE([BUILD_JLINK], [1], [1 if you want the J-Link JTAG driver.]) +else + AC_DEFINE([BUILD_JLINK], [0], [0 if you don't want the J-Link JTAG driver.]) +fi + +if test $build_vsllink = yes; then + AC_DEFINE([BUILD_VSLLINK], [1], [1 if you want the Versaloon-Link JTAG driver.]) +else + AC_DEFINE([BUILD_VSLLINK], [0], [0 if you don't want the Versaloon-Link JTAG driver.]) +fi + +if test $build_rlink = yes; then + AC_DEFINE([BUILD_RLINK], [1], [1 if you want the RLink JTAG driver.]) +else + AC_DEFINE([BUILD_RLINK], [0], [0 if you don't want the RLink JTAG driver.]) +fi + +if test $build_ulink = yes; then + AC_DEFINE([BUILD_ULINK], [1], [1 if you want the ULINK JTAG driver.]) +else + AC_DEFINE([BUILD_ULINK], [0], [0 if you don't want the ULINK JTAG driver.]) +fi + +if test $build_armjtagew = yes; then + AC_DEFINE([BUILD_ARMJTAGEW], [1], [1 if you want the ARM-JTAG-EW JTAG driver.]) +else + AC_DEFINE([BUILD_ARMJTAGEW], [0], [0 if you don't want the ARM-JTAG-EW JTAG driver.]) +fi + +if test $build_buspirate = yes; then + AC_DEFINE([BUILD_BUSPIRATE], [1], [1 if you want the Buspirate JTAG driver.]) +else + AC_DEFINE([BUILD_BUSPIRATE], [0], [0 if you don't want the Buspirate JTAG driver.]) +fi + +if test $build_hladapter_stlink = yes -o $build_hladapter_icdi = yes; then + AC_DEFINE([BUILD_HLADAPTER], [1], [1 if you want the High Level JTAG driver.]) +else + AC_DEFINE([BUILD_HLADAPTER], [0], [0 if you don't want the High Level JTAG driver.]) +fi + +if test $build_osbdm = yes; then + AC_DEFINE([BUILD_OSBDM], [1], [1 if you want the OSBDM driver.]) +else + AC_DEFINE([BUILD_OSBDM], [0], [0 if you don't want the OSBDM driver.]) +fi + +if test $build_opendous = yes; then + AC_DEFINE([BUILD_OPENDOUS], [1], [1 if you want the estick/opendous JTAG driver.]) +else + AC_DEFINE([BUILD_OPENDOUS], [0], [0 if you don't want the estick/opendous JTAG driver.]) +fi + +if test "$use_internal_jimtcl" = yes; then + if test -f "$srcdir/jimtcl/configure.ac"; then + AX_CONFIG_SUBDIR_OPTION([jimtcl], [--disable-install-jim]) + else + AC_MSG_ERROR([jimtcl not found, run git submodule init and git submodule update.]) + fi +fi + +if test $build_remote_bitbang = yes; then + build_bitbang=yes + AC_DEFINE([BUILD_REMOTE_BITBANG], [1], [1 if you want the Remote Bitbang JTAG driver.]) +else + AC_DEFINE([BUILD_REMOTE_BITBANG], [0], [0 if you don't want the Remote Bitbang JTAG driver.]) +fi + +if test $build_sysfsgpio = yes; then + build_bitbang=yes + AC_DEFINE([BUILD_SYSFSGPIO], [1], [1 if you want the SysfsGPIO driver.]) +else + AC_DEFINE([BUILD_SYSFSGPIO], [0], [0 if you don't want SysfsGPIO driver.]) +fi +#-- Deal with MingW/Cygwin FTD2XX issues + +if test $is_win32 = yes; then +if test "${with_ftd2xx_linux_tardir+set}" = set +then + AC_MSG_ERROR([The option: with_ftd2xx_linux_tardir is for LINUX only.]) +fi + +if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes ; then + AC_MSG_CHECKING([for ftd2xx.lib exists (win32)]) + + # if we are given a zipdir... + if test "${with_ftd2xx_win32_zipdir+set}" = set + then + # Set the CFLAGS for "ftd2xx.h" + f=$with_ftd2xx_win32_zipdir/ftd2xx.h + if test ! -f $f ; then + AC_MSG_ERROR([File: $f cannot be found]) + fi + CFLAGS="$CFLAGS -I$with_ftd2xx_win32_zipdir" + + # And calculate the LDFLAGS for the machine + case "$host_cpu" in + i?86|x86_32) + LDFLAGS="$LDFLAGS -L$with_ftd2xx_win32_zipdir/i386" + LIBS="$LIBS -lftd2xx" + f=$with_ftd2xx_win32_zipdir/i386/ftd2xx.lib + ;; + amd64|x86_64) + LDFLAGS="$LDFLAGS -L$with_ftd2xx_win32_zipdir/amd64" + LIBS="$LIBS -lftd2xx" + f=$with_ftd2xx_win32_zipdir/amd64/ftd2xx.lib + ;; + *) + AC_MSG_ERROR([Unknown Win32 host cpu: $host_cpu]) + ;; + esac + if test ! -f $f ; then + AC_MSG_ERROR([Library: $f not found]) + fi + else + LIBS="$LIBS -lftd2xx" + AC_MSG_WARN([ASSUMPTION: The (win32) FTDICHIP.COM files: ftd2xx.h and ftd2xx.lib are in a proper place]) + fi +fi +fi # win32 + +if test $is_darwin = yes ; then +if test "${with_ftd2xx_win32_zipdir+set}" = set +then + AC_MSG_ERROR([The option: --with-ftd2xx-win32-zipdir is for win32 only]) +fi +if test "${with_ftd2xx_linux_tardir+set}" = set +then + AC_MSG_ERROR([The option: with_ftd2xx_linux_tardir is for LINUX only.]) +fi + +if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes ; then + AC_MSG_CHECKING([for libftd2xx.a (darwin)]) + + if test ! -f /usr/local/include/ftd2xx.h ; then + AC_MSG_ERROR([ftd2xx library from FTDICHIP.com seems to be missing, cannot find: /usr/local/include/ftd2xx.h]) + fi + + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -lftd2xx" + AC_MSG_RESULT([-L/usr/local/lib -lftd2xx]) +fi +fi # darwin + +if test $is_win32 = no && test $is_darwin = no ; then + +if test "${with_ftd2xx_win32_zipdir+set}" = set +then + AC_MSG_ERROR([The option: --with-ftd2xx-win32-zipdir is for win32 only]) +fi + +if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes ; then + # Must be linux + if test $host_os != linux-gnu && test $host_os != linux ; then + AC_MSG_ERROR([The (linux) ftd2xx library from FTDICHIP.com is linux only. Try --enable-ft2232-libftdi instead]) + fi + # Are we given a TAR directory? + if test "${with_ftd2xx_linux_tardir+set}" = set + then + AC_MSG_CHECKING([uninstalled ftd2xx distribution]) + # The .H file is simple.. + FTD2XX_H=$with_ftd2xx_linux_tardir/ftd2xx.h + if test ! -f "${FTD2XX_H}"; then + AC_MSG_ERROR([Option: --with-ftd2xx-linux-tardir appears wrong, cannot find: ${FTD2XX_H}]) + fi + CFLAGS="$CFLAGS -I$with_ftd2xx_linux_tardir" + if test $with_ftd2xx_lib = shared; then + FTD2XX_LDFLAGS="-L$with_ftd2xx_linux_tardir" + FTD2XX_LIB="-lftd2xx" + else + # Test #1 - v1.0.x + case "$host_cpu" in + i?86|x86_32) + dir=build/i386;; + amd64|x86_64) + dir=build/x86_64;; + *) + dir=none;; + esac + if test -f "$with_ftd2xx_linux_tardir/$dir/libftd2xx.a"; then + FTD2XX_LDFLAGS="-L$with_ftd2xx_linux_tardir/$dir" + # Also needs -lrt + FTD2XX_LIB="-lftd2xx -lrt" + else + # Test Number2. + # Grr.. perhaps it exists as a version number? + FTD2XX_LIB="$with_ftd2xx_linux_tardir/static_lib/libftd2xx.a.*.*.*" + count=`ls ${FTD2XX_LIB} | wc -l` + if test $count -gt 1 ; then + AC_MSG_ERROR([Multiple libftd2xx.a files found in: $with_ftd2xx_linux_tardir/static_lib sorry cannot handle this yet]) + fi + if test $count -ne 1 ; then + AC_MSG_ERROR([Not found: $f, option: --with-ftd2xx-linux-tardir appears to be wrong]) + fi + # Because the "-l" rules do not understand version numbers... + # we will just stuff the absolute path onto the LIBS variable + FTD2XX_LIB="`ls ${FTD2XX_LIB}` -lpthread" + FTD2XX_LDFLAGS="" + fi + fi + LDFLAGS="${LDFLAGS} ${FTD2XX_LDFLAGS}" + LIBS="${FTD2XX_LIB} ${LIBS}" + AC_MSG_RESULT([${FTD2XX_LDFLAGS} ${FTD2XX_LIB}]) + else + AC_CHECK_HEADER([ftd2xx.h],[],[ + AC_MSG_ERROR([You seem to be missing the FTD2xx driver header file.]) + ]) + AC_SEARCH_LIBS([FT_GetLibraryVersion],[ftd2xx],,[ + AC_MSG_ERROR([You appear to be missing the FTD2xx driver library.]) + ],[]) + fi +fi +fi # linux + +if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes ; then + +# Before we go any further - make sure we can *BUILD* and *RUN* +# a simple app with the "ftd2xx.lib" file - in what ever form we where given +# We should be able to compile, link and run this test program now +AC_MSG_CHECKING([whether ftd2xx library works]) + +# +# Save the LDFLAGS for later.. +LDFLAGS_SAVE=$LDFLAGS +CFLAGS_SAVE=$CFLAGS +_LDFLAGS=`eval echo $LDFLAGS` +_CFLAGS=`eval echo $CFLAGS` +LDFLAGS=$_LDFLAGS +CFLAGS=$_CFLAGS + +AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include "confdefs.h" +#if IS_WIN32 +#include "windows.h" +#endif +#include +#include + ]], [[ + DWORD x; + FT_GetLibraryVersion( &x ); + ]])], [ + AC_MSG_RESULT([Success!]) + ], [ + AC_MSG_ERROR([Cannot build & run test program using ftd2xx.lib]) + ], [ + AC_MSG_RESULT([Skipping as we are cross-compiling]) + ]) + +AC_MSG_CHECKING([for ftd2xx highspeed device support]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include "confdefs.h" +#if IS_WIN32 +#include "windows.h" +#endif +#include +#include + +DWORD x = FT_DEVICE_4232H; + ]], [])], [ + AC_DEFINE([BUILD_FT2232_HIGHSPEED], [1], + [Support FT2232H/FT4232HS with FTD2XX or libftdi.]) + build_ft2232_highspeed=yes + ], [ + build_ft2232_highspeed=no + ]) + AC_MSG_RESULT([$build_ft2232_highspeed]) + + if test $build_ft2232_highspeed = no; then + AC_MSG_WARN([You need a newer FTD2XX driver (version 2.04.16 or later).]) + fi + +AC_MSG_CHECKING([for ftd2xx FT232H device support]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include "confdefs.h" +#if IS_WIN32 +#include "windows.h" +#endif +#include +#include + +DWORD x = FT_DEVICE_232H; + ]], [])], [ + AC_DEFINE([HAS_ENUM_FT232H], [1], + [Support FT232H with FTD2XX or libftdi.]) + has_enum_ft232h=yes + ], [ + has_enum_ft232h=no + ]) + AC_MSG_RESULT([$has_enum_ft232h]) + + if test $has_enum_ft232h = no; then + AC_MSG_WARN([You need a newer FTD2XX driver (version 2.08.12 or later).]) + fi + +LDFLAGS=$LDFLAGS_SAVE +CFLAGS=$CFLAGS_SAVE +fi + +if test $build_ft2232_libftdi = yes ; then + # We assume: the package is preinstalled in the proper place + # these present as 2 libraries.. + LIBS="$LIBS -lftdi -lusb" + # + # Try to build a small program. + AC_MSG_CHECKING([Build & Link with libftdi...]) + + LDFLAGS_SAVE=$LDFLAGS + CFLAGS_SAVE=$CFLAGS + _LDFLAGS=`eval echo $LDFLAGS` + _CFLAGS=`eval echo $CFLAGS` + LDFLAGS=$_LDFLAGS + CFLAGS=$_CFLAGS + + AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include +#include + ]], [[ + struct ftdi_context *p; + p = ftdi_new(); + if( p != NULL ){ + return 0; + } else { + fprintf( stderr, "calling ftdi_new() failed\n"); + return 1; + } + ]])], [ + AC_MSG_RESULT([Success]) + ], [ + AC_MSG_ERROR([Cannot build & run test program using libftdi]) + ], [ + AC_MSG_RESULT([Skipping as we are cross-compiling]) + ]) + +AC_MSG_CHECKING([for libftdi highspeed device support]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include + ]], [[ +enum ftdi_chip_type x = TYPE_2232H; + ]])], [ + AC_DEFINE([BUILD_FT2232_HIGHSPEED], [1], + [Support FT2232H/FT4232HS with FTD2XX or libftdi.]) + build_ft2232_highspeed=yes + ], [ + build_ft2232_highspeed=no + ]) + AC_MSG_RESULT([$build_ft2232_highspeed]) + + if test $build_ft2232_highspeed = no; then + AC_MSG_WARN([You need a newer libftdi version (0.16 or later).]) + fi + +AC_MSG_CHECKING([for libftdi FT232H device support]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include + ]], [[ +enum ftdi_chip_type x = TYPE_232H; + ]])], [ + AC_DEFINE([HAS_ENUM_FT232H], [1], + [Support FT232H with FTD2XX or libftdi.]) + has_enum_ft232h=yes + ], [ + has_enum_ft232h=no + ]) + AC_MSG_RESULT([$has_enum_ft232h]) + + if test $has_enum_ft232h = no; then + AC_MSG_WARN([You need a newer libftdi version (0.20 or later).]) + fi + + # Restore the 'unexpanded ldflags' + LDFLAGS=$LDFLAGS_SAVE + CFLAGS=$CFLAGS_SAVE +fi + +# check for usb.h when a driver will require it +build_usb=no +if test $build_vsllink = yes -o $build_usbprog = yes -o \ + $build_rlink = yes -o $build_ulink = yes -o $build_armjtagew = yes +then + build_usb=yes +fi + +# Check for libusb1 ported drivers. +build_usb_ng=no +if test $build_jlink = yes -o $build_hladapter_stlink = yes -o $build_osbdm = yes -o \ + $build_opendous = yes -o $build_ftdi = yes -o $build_hladapter_icdi = yes +then + build_usb_ng=yes +fi + +# check for libusb library if necessary +use_libusb0=no +use_libusb1=no +if test $build_usb = yes -o $build_usb_ng = yes; then + if test $check_libusb0 = no -a $build_usb_ng = yes; then + AC_CHECK_HEADER([libusb-1.0/libusb.h], + [AC_DEFINE(HAVE_LIBUSB1, 1, [Define if you have libusb-1.0]) check_libusb0=no use_libusb1=yes ], + [ check_libusb0=yes use_libusb1=no ]) + fi + + if test $check_libusb0 = yes -o $build_usb = yes; then + AC_CHECK_HEADERS([usb.h], [use_libusb0=yes], + [AC_MSG_ERROR([libusb or libusb-1.0 are required to build some OpenOCD driver(s)])]) + fi +fi + +AM_CONDITIONAL([RELEASE], [test $build_release = yes]) +AM_CONDITIONAL([PARPORT], [test $build_parport = yes]) +AM_CONDITIONAL([DUMMY], [test $build_dummy = yes]) +AM_CONDITIONAL([GIVEIO], [test x$parport_use_giveio = xyes]) +AM_CONDITIONAL([EP93XX], [test $build_ep93xx = yes]) +AM_CONDITIONAL([ZY1000], [test $build_zy1000 = yes]) +AM_CONDITIONAL([ZY1000_MASTER], [test $build_zy1000_master = yes]) +AM_CONDITIONAL([IOUTIL], [test $build_ioutil = yes]) +AM_CONDITIONAL([AT91RM9200], [test $build_at91rm9200 = yes]) +AM_CONDITIONAL([BITBANG], [test $build_bitbang = yes]) +AM_CONDITIONAL([FT2232_LIBFTDI], [test $build_ft2232_libftdi = yes]) +AM_CONDITIONAL([FT2232_DRIVER], [test $build_ft2232_ftd2xx = yes -o $build_ft2232_libftdi = yes]) +AM_CONDITIONAL([FTDI_DRIVER], [test $build_ftdi = yes]) +AM_CONDITIONAL([USB_BLASTER_LIBFTDI], [test $build_usb_blaster_libftdi = yes]) +AM_CONDITIONAL([USB_BLASTER_DRIVER], [test $build_usb_blaster_ftd2xx = yes -o $build_usb_blaster_libftdi = yes]) +AM_CONDITIONAL([AMTJTAGACCEL], [test $build_amtjtagaccel = yes]) +AM_CONDITIONAL([GW16012], [test $build_gw16012 = yes]) +AM_CONDITIONAL([PRESTO_LIBFTDI], [test $build_presto_libftdi = yes]) +AM_CONDITIONAL([PRESTO_DRIVER], [test $build_presto_ftd2xx = yes -o $build_presto_libftdi = yes]) +AM_CONDITIONAL([USBPROG], [test $build_usbprog = yes]) +AM_CONDITIONAL([OOCD_TRACE], [test $build_oocd_trace = yes]) +AM_CONDITIONAL([JLINK], [test $build_jlink = yes]) +AM_CONDITIONAL([VSLLINK], [test $build_vsllink = yes]) +AM_CONDITIONAL([RLINK], [test $build_rlink = yes]) +AM_CONDITIONAL([ULINK], [test $build_ulink = yes]) +AM_CONDITIONAL([ARMJTAGEW], [test $build_armjtagew = yes]) +AM_CONDITIONAL([REMOTE_BITBANG], [test $build_remote_bitbang = yes]) +AM_CONDITIONAL([BUSPIRATE], [test $build_buspirate = yes]) +AM_CONDITIONAL([HLADAPTER], [test $build_hladapter_stlink = yes -o $build_hladapter_icdi = yes]) +AM_CONDITIONAL([OSBDM], [test $build_osbdm = yes]) +AM_CONDITIONAL([OPENDOUS], [test $build_opendous = yes]) +AM_CONDITIONAL([SYSFSGPIO], [test $build_sysfsgpio = yes]) +AM_CONDITIONAL([USB], [test $build_usb = yes]) +AM_CONDITIONAL([USB_NG], [test $build_usb_ng = yes]) +AM_CONDITIONAL([USE_LIBUSB0], [test $use_libusb0 = yes]) +AM_CONDITIONAL([USE_LIBUSB1], [test $use_libusb1 = yes]) +AM_CONDITIONAL([IS_CYGWIN], [test $is_cygwin = yes]) +AM_CONDITIONAL([IS_MINGW], [test $is_mingw = ye]s) +AM_CONDITIONAL([IS_WIN32], [test $is_win32 = ye]s) +AM_CONDITIONAL([IS_DARWIN], [test $is_darwin = ye]s) +AM_CONDITIONAL([BITQ], [test $build_bitq = yes]) + +AM_CONDITIONAL([MINIDRIVER], [test $build_minidriver = ye]s) +AM_CONDITIONAL([MINIDRIVER_DUMMY], [test $build_minidriver_dummy = yes]) + +AM_CONDITIONAL([INTERNAL_JIMTCL], [test $use_internal_jimtcl = yes]) + +# Look for environ alternatives. Possibility #1: is environ in unistd.h or stdlib.h? +AC_MSG_CHECKING([for environ in unistd.h and stdlib.h]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#define _GNU_SOURCE +#include +#include + ]], [[char **ep = environ;]] + )], [ + AC_MSG_RESULT([yes]) + has_environ=yes + ], [ + AC_MSG_RESULT([no]) + + # Possibility #2: can environ be found in an available library? + AC_MSG_CHECKING([for extern environ]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + extern char **environ; + ]], [[char **ep = environ;]] + )], [ + AC_DEFINE(NEED_ENVIRON_EXTERN, [1], [Must declare 'environ' to use it.]) + has_environ=yes + ], [ + has_environ=no + ]) + AC_MSG_RESULT([${has_environ}]) + ]) + +if test "${has_environ}" != "yes" ; then + AC_MSG_FAILURE([Could not find 'environ' in unistd.h or available libraries.]) +fi + +AC_DEFINE([_GNU_SOURCE],[1],[Use GNU C library extensions (e.g. stdndup).]) + +# set default gcc warnings +GCC_WARNINGS="-Wall -Wstrict-prototypes -Wformat-security -Wshadow" +if test "${gcc_wextra}" = yes; then + GCC_WARNINGS="${GCC_WARNINGS} -Wextra -Wno-unused-parameter" + GCC_WARNINGS="${GCC_WARNINGS} -Wbad-function-cast" + GCC_WARNINGS="${GCC_WARNINGS} -Wcast-align" + GCC_WARNINGS="${GCC_WARNINGS} -Wredundant-decls" +fi +if test "${gcc_werror}" = yes; then + GCC_WARNINGS="${GCC_WARNINGS} -Werror" +fi + +# overide default gcc cflags +if test $gcc_warnings = yes; then + CFLAGS="$CFLAGS $GCC_WARNINGS" +fi + +# Setup for compiling build tools +AC_MSG_CHECKING([for a C compiler for build tools]) +if test $cross_compiling = yes; then + AC_CHECK_PROGS(CC_FOR_BUILD, gcc cc) + CFLAGS_FOR_BUILD="-g -O2 $GCC_WARNINGS" +else + CC_FOR_BUILD=$CC + CFLAGS_FOR_BUILD=$CFLAGS +fi + +AC_MSG_RESULT([$CC_FOR_BUILD]) +AC_SUBST([CC_FOR_BUILD]) +AC_SUBST([CFLAGS_FOR_BUILD]) + +AC_MSG_CHECKING([for suffix of executable build tools]) +if test $cross_compiling = yes; then + cat >conftest.c <<\_______EOF +int main () +{ + exit (0); +} +_______EOF + for i in .exe ""; do + compile="$CC_FOR_BUILD conftest.c -o conftest$i" + if AC_TRY_EVAL(compile); then + if (./conftest) 2>&AC_FD_CC; then + EXEEXT_FOR_BUILD=$i + break + fi + fi + done + rm -f conftest* + if test "${EXEEXT_FOR_BUILD+set}" != set; then + AC_MSG_ERROR([Cannot determine suffix of executable build tools]) + fi +else + EXEEXT_FOR_BUILD=$EXEEXT +fi +AC_MSG_RESULT([$EXEEXT_FOR_BUILD]) +AC_SUBST([EXEEXT_FOR_BUILD]) + +AC_CONFIG_FILES([ + Makefile + src/Makefile + src/helper/Makefile + src/jtag/Makefile + src/jtag/drivers/Makefile + src/jtag/hla/Makefile + src/transport/Makefile + src/xsvf/Makefile + src/svf/Makefile + src/target/Makefile + src/rtos/Makefile + src/server/Makefile + src/flash/Makefile + src/flash/nor/Makefile + src/flash/nand/Makefile + src/pld/Makefile + doc/Makefile +]) +AC_OUTPUT diff --git a/debuggers/openocd/contrib/libdcc/README b/debuggers/openocd/contrib/libdcc/README new file mode 100644 index 00000000..d67ccce3 --- /dev/null +++ b/debuggers/openocd/contrib/libdcc/README @@ -0,0 +1,19 @@ +This code is an example of using the openocd debug message system. + +Before the message output is seen in the debug window, the functionality +will need enabling: + +From the gdb prompt: +monitor target_request debugmsgs enable +monitor trace point 1 + +From the Telnet prompt: +target_request debugmsgs enable +trace point 1 + +To see how many times the trace point was hit: +(monitor) trace point 1 + +Spen +spen@spen-soft.co.uk + diff --git a/debuggers/openocd/contrib/libdcc/dcc_stdio.c b/debuggers/openocd/contrib/libdcc/dcc_stdio.c new file mode 100644 index 00000000..356ddbda --- /dev/null +++ b/debuggers/openocd/contrib/libdcc/dcc_stdio.c @@ -0,0 +1,157 @@ +/*************************************************************************** + * Copyright (C) 2008 by Dominic Rath * + * Dominic.Rath@gmx.de * + * Copyright (C) 2008 by Spencer Oliver * + * spen@spen-soft.co.uk * + * Copyright (C) 2008 by Frederik Kriewtz * + * frederik@kriewitz.eu * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "dcc_stdio.h" + +#define TARGET_REQ_TRACEMSG 0x00 +#define TARGET_REQ_DEBUGMSG_ASCII 0x01 +#define TARGET_REQ_DEBUGMSG_HEXMSG(size) (0x01 | ((size & 0xff) << 8)) +#define TARGET_REQ_DEBUGCHAR 0x02 + +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_6SM__) + +/* we use the System Control Block DCRDR reg to simulate a arm7_9 dcc channel + * DCRDR[7:0] is used by target for status + * DCRDR[15:8] is used by target for write buffer + * DCRDR[23:16] is used for by host for status + * DCRDR[31:24] is used for by host for write buffer */ + +#define NVIC_DBG_DATA_R (*((volatile unsigned short *)0xE000EDF8)) + +#define BUSY 1 + +void dbg_write(unsigned long dcc_data) +{ + int len = 4; + + while (len--) + { + /* wait for data ready */ + while (NVIC_DBG_DATA_R & BUSY); + + /* write our data and set write flag - tell host there is data*/ + NVIC_DBG_DATA_R = (unsigned short)(((dcc_data & 0xff) << 8) | BUSY); + dcc_data >>= 8; + } +} + +#elif defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5T__) + +void dbg_write(unsigned long dcc_data) +{ + unsigned long dcc_status; + + do { + asm volatile("mrc p14, 0, %0, c0, c0" : "=r" (dcc_status)); + } while (dcc_status & 0x2); + + asm volatile("mcr p14, 0, %0, c1, c0" : : "r" (dcc_data)); +} + +#else + #error unsupported target +#endif + +void dbg_trace_point(unsigned long number) +{ + dbg_write(TARGET_REQ_TRACEMSG | (number << 8)); +} + +void dbg_write_u32(const unsigned long *val, long len) +{ + dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(4) | ((len & 0xffff) << 16)); + + while (len > 0) + { + dbg_write(*val); + + val++; + len--; + } +} + +void dbg_write_u16(const unsigned short *val, long len) +{ + unsigned long dcc_data; + + dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(2) | ((len & 0xffff) << 16)); + + while (len > 0) + { + dcc_data = val[0] + | ((len > 1) ? val[1] << 16: 0x0000); + + dbg_write(dcc_data); + + val += 2; + len -= 2; + } +} + +void dbg_write_u8(const unsigned char *val, long len) +{ + unsigned long dcc_data; + + dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(1) | ((len & 0xffff) << 16)); + + while (len > 0) + { + dcc_data = val[0] + | ((len > 1) ? val[1] << 8 : 0x00) + | ((len > 2) ? val[2] << 16 : 0x00) + | ((len > 3) ? val[3] << 24 : 0x00); + + dbg_write(dcc_data); + + val += 4; + len -= 4; + } +} + +void dbg_write_str(const char *msg) +{ + long len; + unsigned long dcc_data; + + for (len = 0; msg[len] && (len < 65536); len++); + + dbg_write(TARGET_REQ_DEBUGMSG_ASCII | ((len & 0xffff) << 16)); + + while (len > 0) + { + dcc_data = msg[0] + | ((len > 1) ? msg[1] << 8 : 0x00) + | ((len > 2) ? msg[2] << 16 : 0x00) + | ((len > 3) ? msg[3] << 24 : 0x00); + dbg_write(dcc_data); + + msg += 4; + len -= 4; + } +} + +void dbg_write_char(char msg) +{ + dbg_write(TARGET_REQ_DEBUGCHAR | ((msg & 0xff) << 16)); +} diff --git a/debuggers/openocd/contrib/libdcc/dcc_stdio.h b/debuggers/openocd/contrib/libdcc/dcc_stdio.h new file mode 100644 index 00000000..d16f2a78 --- /dev/null +++ b/debuggers/openocd/contrib/libdcc/dcc_stdio.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2008 by Dominic Rath * + * Dominic.Rath@gmx.de * + * Copyright (C) 2008 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef DCC_STDIO_H +#define DCC_STDIO_H + +void dbg_trace_point(unsigned long number); + +void dbg_write_u32(const unsigned long *val, long len); +void dbg_write_u16(const unsigned short *val, long len); +void dbg_write_u8(const unsigned char *val, long len); + +void dbg_write_str(const char *msg); +void dbg_write_char(char msg); + +#endif /* DCC_STDIO_H */ diff --git a/debuggers/openocd/contrib/libdcc/example.c b/debuggers/openocd/contrib/libdcc/example.c new file mode 100644 index 00000000..0814c9ce --- /dev/null +++ b/debuggers/openocd/contrib/libdcc/example.c @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2008 by Spencer Oliver * + * spen@spen-soft.co.uk * + * Copyright (C) 2008 by Frederik Kriewtz * + * frederik@kriewitz.eu * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "dcc_stdio.h" + +/* enable openocd debugmsg at the gdb prompt: + * monitor target_request debugmsgs enable + * + * create a trace point: + * monitor trace point 1 + * + * to show how often the trace point was hit: + * monitor trace point +*/ + +int main(void) +{ + dbg_write_str("hello world"); + + dbg_write_char('t'); + dbg_write_char('e'); + dbg_write_char('s'); + dbg_write_char('t'); + dbg_write_char('\n'); + + unsigned long test_u32 = 0x01234567; + dbg_write_u32(&test_u32, 1); + + static const unsigned short test_u16[] = {0x0123, 0x4567, 0x89AB, 0xCDEF, 0x0123, 0x4567, 0x89AB, 0xCDEF}; + dbg_write_u16(test_u16, 8); + + static const unsigned char test_u8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0XDD, 0xEE, 0xFF}; + dbg_write_u8(test_u8, 16); + + while(1) + { + dbg_trace_point(0); + } +} diff --git a/debuggers/openocd/contrib/loaders/README b/debuggers/openocd/contrib/loaders/README new file mode 100644 index 00000000..2b123cf6 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/README @@ -0,0 +1,33 @@ +Included in these directories are the src to the various ram loaders used +within openocd. + +** target checksum loaders ** + +checksum/armv4_5_crc.s : + - ARMv4 and ARMv5 checksum loader : see target/arm_crc_code.c:arm_crc_code + +checksum/armv7m_crc.s : + - ARMv7m checksum loader : see target/armv7m.c:cortex_m3_crc_code + +checksum/mips32.s : + - MIPS32 checksum loader : see target/mips32.c:mips_crc_code + +** target flash loaders ** + +flash/pic32mx.s : + - Microchip PIC32 flash loader : see flash/nor/pic32mx.c:pic32mx_flash_write_code + +flash/stellaris.s : + - TI Stellaris flash loader : see flash/nor/stellaris.c:stellaris_write_code + +flash/stm32x.s : + - ST STM32 flash loader : see flash/nor/stm32x.c:stm32x_flash_write_code + +flash/str7x.s : + - ST STR7 flash loader : see flash/nor/str7x.c:str7x_flash_write_code + +flash/str9x.s : + - ST STR9 flash loader : see flash/nor/str9x.c:str9x_flash_write_code + +Spencer Oliver +spen@spen-soft.co.uk diff --git a/debuggers/openocd/contrib/loaders/checksum/armv4_5_crc.s b/debuggers/openocd/contrib/loaders/checksum/armv4_5_crc.s new file mode 100644 index 00000000..950a8d0e --- /dev/null +++ b/debuggers/openocd/contrib/loaders/checksum/armv4_5_crc.s @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/* + r0 - address in - crc out + r1 - char count +*/ + + .text + .arm + +_start: +main: + mov r2, r0 + mov r0, #0xffffffff /* crc */ + mov r3, r1 + mov r4, #0 + b ncomp +nbyte: + ldrb r1, [r2, r4] + ldr r7, CRC32XOR + eor r0, r0, r1, asl #24 + mov r5, #0 +loop: + cmp r0, #0 + mov r6, r0, asl #1 + add r5, r5, #1 + mov r0, r6 + eorlt r0, r6, r7 + cmp r5, #8 + bne loop + add r4, r4, #1 +ncomp: + cmp r4, r3 + bne nbyte +end: + bkpt #0 + +CRC32XOR: .word 0x04c11db7 + + .end diff --git a/debuggers/openocd/contrib/loaders/checksum/armv7m_crc.s b/debuggers/openocd/contrib/loaders/checksum/armv7m_crc.s new file mode 100644 index 00000000..8dfc40ad --- /dev/null +++ b/debuggers/openocd/contrib/loaders/checksum/armv7m_crc.s @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/* + parameters: + r0 - address in - crc out + r1 - char count +*/ + + .text + .syntax unified + .cpu cortex-m0 + .thumb + .thumb_func + + .align 2 + +_start: +main: + mov r2, r0 + movs r0, #0 + mvns r0, r0 + ldr r6, CRC32XOR + mov r3, r1 + movs r4, #0 + b ncomp +nbyte: + ldrb r1, [r2, r4] + lsls r1, r1, #24 + eors r0, r0, r1 + movs r5, #0 +loop: + cmp r0, #0 + bge notset + lsls r0, r0, #1 + eors r0, r0, r6 + b cont +notset: + lsls r0, r0, #1 +cont: + adds r5, r5, #1 + cmp r5, #8 + bne loop + adds r4, r4, #1 +ncomp: + cmp r4, r3 + bne nbyte + bkpt #0 + + .align 2 + +CRC32XOR: .word 0x04c11db7 + + .end diff --git a/debuggers/openocd/contrib/loaders/checksum/mips32.s b/debuggers/openocd/contrib/loaders/checksum/mips32.s new file mode 100644 index 00000000..f8f08a23 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/checksum/mips32.s @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .global main + .text + .set noreorder + +/* params: + * $a0 address in + * $a1 byte count + * vars + * $a0 crc + * $a1 crc data byte + * temps: + * t3 v0 a3 a2 t0 v1 + */ + +.ent main +main: + addiu $t4, $a0, 0 /* address in */ + addiu $t2, $a1, 0 /* count */ + + addiu $a0, $zero, 0xffffffff /* a0 crc - result */ + + beq $zero, $zero, ncomp + addiu $t3, $zero, 0 /* clear bytes read */ + +nbyte: + lb $a1, ($t4) /* load byte from source address */ + addi $t4, $t4, 1 /* inc byte count */ + +crc: + sll $a1, $a1, 24 + lui $v0, 0x04c1 + xor $a0, $a0, $a1 + ori $a3, $v0, 0x1db7 + addu $a2, $zero, $zero /* clear bit count */ +loop: + sll $t0, $a0, 1 + addiu $a2, $a2, 1 /* inc bit count */ + slti $a0, $a0, 0 + xor $t1, $t0, $a3 + movn $t0, $t1, $a0 + slti $v1, $a2, 8 /* 8bits processed */ + bne $v1, $zero, loop + addu $a0, $t0, $zero + +ncomp: + bne $t2, $t3, nbyte /* all bytes processed */ + addiu $t3, $t3, 1 + +wait: + sdbbp + +.end main diff --git a/debuggers/openocd/contrib/loaders/erase_check/armv4_5_erase_check.s b/debuggers/openocd/contrib/loaders/erase_check/armv4_5_erase_check.s new file mode 100644 index 00000000..4688ee96 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/erase_check/armv4_5_erase_check.s @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/* + parameters: + r0 - address in + r1 - byte count + r2 - mask - result out +*/ + + .text + .arm + +loop: + ldrb r3, [r0], #1 + and r2, r2, r3 + subs r1, r1, #1 + bne loop +end: + bkpt #0 + +CRC32XOR: .word 0x04c11db7 + + .end diff --git a/debuggers/openocd/contrib/loaders/erase_check/armv7m_erase_check.s b/debuggers/openocd/contrib/loaders/erase_check/armv7m_erase_check.s new file mode 100644 index 00000000..358a1c83 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/erase_check/armv7m_erase_check.s @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/* + parameters: + r0 - address in + r1 - byte count + r2 - mask - result out +*/ + + .text + .syntax unified + .cpu cortex-m0 + .thumb + .thumb_func + + .align 2 + +loop: + ldrb r3, [r0] + adds r0, #1 + ands r2, r2, r3 + subs r1, r1, #1 + bne loop +end: + bkpt #0 + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_intel_16.s b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_intel_16.s new file mode 100644 index 00000000..52836006 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_intel_16.s @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2005, 2007 by Dominic Rath * + * Dominic.Rath@gmx.de * + * Copyright (C) 2010 Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .arm + .arch armv4 + + .section .init + +/* algorithm register usage: + * r0: source address (in RAM) + * r1: target address (in Flash) + * r2: count + * r3: flash write command + * r4: status byte (returned to host) + * r5: busy test pattern + * r6: error test pattern + */ + +loop: + ldrh r4, [r0], #2 + strh r3, [r1] + strh r4, [r1] +busy: + ldrh r4, [r1] + and r7, r4, r5 + cmp r7, r5 + bne busy + tst r4, r6 + bne done + subs r2, r2, #1 + beq done + add r1, r1, #2 + b loop +done: + b done + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_intel_32.s b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_intel_32.s new file mode 100644 index 00000000..fbab3159 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_intel_32.s @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2005, 2007 by Dominic Rath * + * Dominic.Rath@gmx.de * + * Copyright (C) 2010 Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .arm + .arch armv4 + + .section .init + +/* algorithm register usage: + * r0: source address (in RAM) + * r1: target address (in Flash) + * r2: count + * r3: flash write command + * r4: status byte (returned to host) + * r5: busy test pattern + * r6: error test pattern + */ + +loop: + ldr r4, [r0], #4 + str r3, [r1] + str r4, [r1] +busy: + ldr r4, [r1] + and r7, r4, r5 + cmp r7, r5 + bne busy + tst r4, r6 + bne done + subs r2, r2, #1 + beq done + add r1, r1, #4 + b loop +done: + b done + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_intel_8.s b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_intel_8.s new file mode 100644 index 00000000..64a2f8d6 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_intel_8.s @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2005, 2007 by Dominic Rath * + * Dominic.Rath@gmx.de * + * Copyright (C) 2010 Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .arm + .arch armv4 + + .section .init + +/* algorithm register usage: + * r0: source address (in RAM) + * r1: target address (in Flash) + * r2: count + * r3: flash write command + * r4: status byte (returned to host) + * r5: busy test pattern + * r6: error test pattern + */ + +loop: + ldrb r4, [r0], #1 + strb r3, [r1] + strb r4, [r1] +busy: + ldrb r4, [r1] + and r7, r4, r5 + cmp r7, r5 + bne busy + tst r4, r6 + bne done + subs r2, r2, #1 + beq done + add r1, r1, #1 + b loop +done: + b done + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_span_16.s b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_span_16.s new file mode 100644 index 00000000..d363fbda --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_span_16.s @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2005, 2007 by Dominic Rath * + * Dominic.Rath@gmx.de * + * Copyright (C) 2010 Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .arm + .arch armv4 + + .section .init + +/* input parameters - */ +/* R0 = source address */ +/* R1 = destination address */ +/* R2 = number of writes */ +/* R3 = flash write command */ +/* R4 = constant to mask DQ7 bits (also used for Dq5 with shift) */ +/* output parameters - */ +/* R5 = 0x80 ok 0x00 bad */ +/* temp registers - */ +/* R6 = value read from flash to test status */ +/* R7 = holding register */ +/* unlock registers - */ +/* R8 = unlock1_addr */ +/* R9 = unlock1_cmd */ +/* R10 = unlock2_addr */ +/* R11 = unlock2_cmd */ + +code: + ldrh r5, [r0], #2 + strh r9, [r8] + strh r11, [r10] + strh r3, [r8] + strh r5, [r1] + nop +busy: + ldrh r6, [r1] + eor r7, r5, r6 + ands r7, r4, r7 + beq cont /* b if DQ7 == Data7 */ + ands r6, r6, r4, lsr #2 + beq busy /* b if DQ5 low */ + ldrh r6, [r1] + eor r7, r5, r6 + ands r7, r4, r7 + beq cont /* b if DQ7 == Data7 */ + mov r5, #0 /* 0x0 - return 0x00, error */ + bne done +cont: + subs r2, r2, #1 /* 0x1 */ + moveq r5, #128 /* 0x80 */ + beq done + add r1, r1, #2 /* 0x2 */ + b code +done: + b done + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_span_16_dq7.s b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_span_16_dq7.s new file mode 100644 index 00000000..fb405387 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_span_16_dq7.s @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2005, 2007 by Dominic Rath * + * Dominic.Rath@gmx.de * + * Copyright (C) 2010 Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .arm + .arch armv4 + + .section .init + +/* input parameters - */ +/* R0 = source address */ +/* R1 = destination address */ +/* R2 = number of writes */ +/* R3 = flash write command */ +/* R4 = constant to mask DQ7 bits (also used for Dq5 with shift) */ +/* output parameters - */ +/* R5 = 0x80 ok 0x00 bad */ +/* temp registers - */ +/* R6 = value read from flash to test status */ +/* R7 = holding register */ +/* unlock registers - */ +/* R8 = unlock1_addr */ +/* R9 = unlock1_cmd */ +/* R10 = unlock2_addr */ +/* R11 = unlock2_cmd */ + +code: + ldrh r5, [r0], #2 + strh r9, [r8] + strh r11, [r10] + strh r3, [r8] + strh r5, [r1] + nop +busy: + ldrh r6, [r1] + eor r7, r5, r6 + ands r7, #0x80 + bne busy + subs r2, r2, #1 /* 0x1 */ + moveq r5, #128 /* 0x80 */ + beq done + add r1, r1, #2 /* 0x2 */ + b code +done: + b done + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_span_32.s b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_span_32.s new file mode 100644 index 00000000..5a7ab990 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_span_32.s @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2005, 2007 by Dominic Rath * + * Dominic.Rath@gmx.de * + * Copyright (C) 2010 Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .arm + .arch armv4 + + .section .init + +/* input parameters - */ +/* R0 = source address */ +/* R1 = destination address */ +/* R2 = number of writes */ +/* R3 = flash write command */ +/* R4 = constant to mask DQ7 bits (also used for Dq5 with shift) */ +/* output parameters - */ +/* R5 = 0x80 ok 0x00 bad */ +/* temp registers - */ +/* R6 = value read from flash to test status */ +/* R7 = holding register */ +/* unlock registers - */ +/* R8 = unlock1_addr */ +/* R9 = unlock1_cmd */ +/* R10 = unlock2_addr */ +/* R11 = unlock2_cmd */ + +code: + ldr r5, [r0], #4 + str r9, [r8] + str r11, [r10] + str r3, [r8] + str r5, [r1] + nop +busy: + ldr r6, [r1] + eor r7, r5, r6 + ands r7, r4, r7 + beq cont /* b if DQ7 == Data7 */ + ands r6, r6, r4, lsr #2 + beq busy /* b if DQ5 low */ + ldr r6, [r1] + eor r7, r5, r6 + ands r7, r4, r7 + beq cont /* b if DQ7 == Data7 */ + mov r5, #0 /* 0x0 - return 0x00, error */ + bne done +cont: + subs r2, r2, #1 /* 0x1 */ + moveq r5, #128 /* 0x80 */ + beq done + add r1, r1, #4 /* 0x4 */ + b code +done: + b done + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_span_8.s b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_span_8.s new file mode 100644 index 00000000..65d64da7 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/armv4_5_cfi_span_8.s @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2005, 2007 by Dominic Rath * + * Dominic.Rath@gmx.de * + * Copyright (C) 2010 Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .arm + .arch armv4 + + .section .init + +/* input parameters - */ +/* R0 = source address */ +/* R1 = destination address */ +/* R2 = number of writes */ +/* R3 = flash write command */ +/* R4 = constant to mask DQ7 bits (also used for Dq5 with shift) */ +/* output parameters - */ +/* R5 = 0x80 ok 0x00 bad */ +/* temp registers - */ +/* R6 = value read from flash to test status */ +/* R7 = holding register */ +/* unlock registers - */ +/* R8 = unlock1_addr */ +/* R9 = unlock1_cmd */ +/* R10 = unlock2_addr */ +/* R11 = unlock2_cmd */ + +code: + ldrb r5, [r0], #1 + strb r9, [r8] + strb r11, [r10] + strb r3, [r8] + strb r5, [r1] + nop +busy: + ldrb r6, [r1] + eor r7, r5, r6 + ands r7, r4, r7 + beq cont /* b if DQ7 == Data7 */ + ands r6, r6, r4, lsr #2 + beq busy /* b if DQ5 low */ + ldrb r6, [r1] + eor r7, r5, r6 + ands r7, r4, r7 + beq cont /* b if DQ7 == Data7 */ + mov r5, #0 /* 0x0 - return 0x00, error */ + bne done +cont: + subs r2, r2, #1 /* 0x1 */ + moveq r5, #128 /* 0x80 */ + beq done + add r1, r1, #1 /* 0x1 */ + b code +done: + b done + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/armv7m_cfi_span_16.s b/debuggers/openocd/contrib/loaders/flash/armv7m_cfi_span_16.s new file mode 100644 index 00000000..ee3aa579 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/armv7m_cfi_span_16.s @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright (C) 2005, 2007 by Dominic Rath * + * Dominic.Rath@gmx.de * + * Copyright (C) 2010 Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .syntax unified + .arch armv7-m + .thumb + .thumb_func + + .align 2 + +/* input parameters - */ +/* R0 = source address */ +/* R1 = destination address */ +/* R2 = number of writes */ +/* R3 = flash write command */ +/* R4 = constant to mask DQ7 bits (also used for Dq5 with shift) */ +/* output parameters - */ +/* R5 = 0x80 ok 0x00 bad */ +/* temp registers - */ +/* R6 = value read from flash to test status */ +/* R7 = holding register */ +/* unlock registers - */ +/* R8 = unlock1_addr */ +/* R9 = unlock1_cmd */ +/* R10 = unlock2_addr */ +/* R11 = unlock2_cmd */ + +code: + ldrh r5, [r0], #2 + strh r9, [r8] + strh r11, [r10] + strh r3, [r8] + strh r5, [r1] + nop +busy: + ldrh r6, [r1] + eor r7, r5, r6 + ands r7, r4, r7 + beq cont /* b if DQ7 == Data7 */ + ands r6, r6, r4, lsr #2 + beq busy /* b if DQ5 low */ + ldrh r6, [r1] + eor r7, r5, r6 + ands r7, r4, r7 + beq cont /* b if DQ7 == Data7 */ + mov r5, #0 /* 0x0 - return 0x00, error */ + bne done +cont: + subs r2, r2, #1 /* 0x1 */ + beq success + add r1, r1, #2 /* 0x2 */ + b code + +success: + mov r5, #128 /* 0x80 */ + b done + +done: + bkpt #0 + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/armv7m_io.s b/debuggers/openocd/contrib/loaders/flash/armv7m_io.s new file mode 100644 index 00000000..3bd90ca6 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/armv7m_io.s @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2013 by Henrik Nilsson * + * henrik.nilsson@bytequest.se * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .syntax unified + .arch armv7-m + .thumb + .thumb_func + + .align 4 + +/* Inputs: + * r0 buffer address + * r1 NAND data address (byte wide) + * r2 buffer length + */ +read: + ldrb r3, [r1] + strb r3, [r0], #1 + subs r2, r2, #1 + bne read + +done_read: + bkpt #0 + + .align 4 + +/* Inputs: + * r0 NAND data address (byte wide) + * r1 buffer address + * r2 buffer length + */ +write: + ldrb r3, [r1], #1 + strb r3, [r0] + subs r2, r2, #1 + bne write + +done_write: + bkpt #0 + + .end + diff --git a/debuggers/openocd/contrib/loaders/flash/efm32.S b/debuggers/openocd/contrib/loaders/flash/efm32.S new file mode 100644 index 00000000..900ddab4 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/efm32.S @@ -0,0 +1,114 @@ +/*************************************************************************** + * Copyright (C) 2011 by Andreas Fritiofson * + * andreas.fritiofson@gmail.com * + * Copyright (C) 2013 by Roman Dmitrienko * + * me@iamroman.org * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .syntax unified + .cpu cortex-m0 + .thumb + .thumb_func + + /* Params: + * r0 - flash base (in), status (out) + * r1 - count (word-32bit) + * r2 - workarea start + * r3 - workarea end + * r4 - target address + * Clobbered: + * r5 - rp + * r6 - wp, tmp + * r7 - tmp + */ + +/* offsets of registers from flash reg base */ +#define EFM32_MSC_WRITECTRL_OFFSET 0x008 +#define EFM32_MSC_WRITECMD_OFFSET 0x00c +#define EFM32_MSC_ADDRB_OFFSET 0x010 +#define EFM32_MSC_WDATA_OFFSET 0x018 +#define EFM32_MSC_STATUS_OFFSET 0x01c +#define EFM32_MSC_LOCK_OFFSET 0x03c + + /* unlock MSC */ + ldr r6, =#0x1b71 + str r6, [r0, #EFM32_MSC_LOCK_OFFSET] + /* set WREN to 1 */ + movs r6, #1 + str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] + +wait_fifo: + ldr r6, [r2, #0] /* read wp */ + cmp r6, #0 /* abort if wp == 0 */ + beq exit + ldr r5, [r2, #4] /* read rp */ + cmp r5, r6 /* wait until rp != wp */ + beq wait_fifo + + /* store address in MSC_ADDRB */ + str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] + /* set LADDRIM bit */ + movs r6, #1 + str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] + /* check status for INVADDR and/or LOCKED */ + ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] + movs r7, #6 + tst r6, r7 + bne error + + /* wait for WDATAREADY */ +wait_wdataready: + ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] + movs r7, #8 + tst r6, r7 + beq wait_wdataready + + /* load data to WDATA */ + ldr r6, [r5] + str r6, [r0, #EFM32_MSC_WDATA_OFFSET] + /* set WRITEONCE bit */ + movs r6, #8 + str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] + + adds r5, #4 /* rp++ */ + adds r4, #4 /* target_address++ */ + + /* wait until BUSY flag is reset */ +busy: + ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] + movs r7, #1 + tst r6, r7 + bne busy + + cmp r5, r3 /* wrap rp at end of buffer */ + bcc no_wrap + mov r5, r2 + adds r5, #8 +no_wrap: + str r5, [r2, #4] /* store rp */ + subs r1, r1, #1 /* decrement word count */ + cmp r1, #0 + beq exit /* loop if not done */ + b wait_fifo +error: + movs r0, #0 + str r0, [r2, #4] /* set rp = 0 on error */ +exit: + mov r0, r6 /* return status in r0 */ + bkpt #0 diff --git a/debuggers/openocd/contrib/loaders/flash/lpcspifi_erase.S b/debuggers/openocd/contrib/loaders/flash/lpcspifi_erase.S new file mode 100644 index 00000000..219f645b --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/lpcspifi_erase.S @@ -0,0 +1,176 @@ +/*************************************************************************** + * Copyright (C) 2012 by George Harris * + * george@luminairecoffee.com * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .syntax unified + .cpu cortex-m3 + .thumb + .thumb_func + +/* + * Params : + * r0 = start address, status (out) + * r1 = count + * r2 = erase command + * r3 = block size + */ + +#define SSP_BASE_HIGH 0x4008 +#define SSP_BASE_LOW 0x3000 +#define SSP_CR0_OFFSET 0x00 +#define SSP_CR1_OFFSET 0x04 +#define SSP_DATA_OFFSET 0x08 +#define SSP_CPSR_OFFSET 0x10 +#define SSP_SR_OFFSET 0x0c + +#define SSP_CLOCK_BASE_HIGH 0x4005 +#define SSP_CLOCK_BASE_LOW 0x0000 +#define SSP_BRANCH_CLOCK_BASE_HIGH 0x4005 +#define SSP_BRANCH_CLOCK_BASE_LOW 0x2000 +#define SSP_BASE_CLOCK_OFFSET 0x94 +#define SSP_BRANCH_CLOCK_OFFSET 0x700 + +#define IOCONFIG_BASE_HIGH 0x4008 +#define IOCONFIG_BASE_LOW 0x6000 +#define IOCONFIG_SCK_OFFSET 0x18c +#define IOCONFIG_HOLD_OFFSET 0x190 +#define IOCONFIG_WP_OFFSET 0x194 +#define IOCONFIG_MISO_OFFSET 0x198 +#define IOCONFIG_MOSI_OFFSET 0x19c +#define IOCONFIG_CS_OFFSET 0x1a0 + +#define IO_BASE_HIGH 0x400f +#define IO_BASE_LOW 0x4000 +#define IO_CS_OFFSET 0xab +#define IODIR_BASE_HIGH 0x400f +#define IODIR_BASE_LOW 0x6000 +#define IO_CS_DIR_OFFSET 0x14 + + +setup: /* Initialize SSP pins and module */ + mov.w r10, #IOCONFIG_BASE_LOW + movt r10, #IOCONFIG_BASE_HIGH + mov.w r8, #0xea + str.w r8, [r10, #IOCONFIG_SCK_OFFSET] /* Configure SCK pin function */ + mov.w r8, #0x40 + str.w r8, [r10, #IOCONFIG_HOLD_OFFSET] /* Configure /HOLD pin function */ + mov.w r8, #0x40 + str.w r8, [r10, #IOCONFIG_WP_OFFSET] /* Configure /WP pin function */ + mov.w r8, #0xed + str.w r8, [r10, #IOCONFIG_MISO_OFFSET] /* Configure MISO pin function */ + mov.w r8, #0xed + str.w r8, [r10, #IOCONFIG_MOSI_OFFSET] /* Configure MOSI pin function */ + mov.w r8, #0x44 + str.w r8, [r10, #IOCONFIG_CS_OFFSET] /* Configure CS pin function */ + + mov.w r10, #IODIR_BASE_LOW + movt r10, #IODIR_BASE_HIGH + mov.w r8, #0x800 + str r8, [r10, #IO_CS_DIR_OFFSET] /* Set CS as output */ + mov.w r10, #IO_BASE_LOW + movt r10, #IO_BASE_HIGH + mov.w r8, #0xff + str.w r8, [r10, #IO_CS_OFFSET] /* Set CS high */ + + mov.w r10, #SSP_CLOCK_BASE_LOW + movt r10, #SSP_CLOCK_BASE_HIGH + mov.w r8, #0x0000 + movt r8, #0x0100 + str.w r8, [r10, #SSP_BASE_CLOCK_OFFSET] /* Configure SSP0 base clock (use 12 MHz IRC) */ + + mov.w r10, #SSP_BRANCH_CLOCK_BASE_LOW + movt r10, #SSP_BRANCH_CLOCK_BASE_HIGH + mov.w r8, #0x01 + str.w r8, [r10, #SSP_BRANCH_CLOCK_OFFSET] /* Configure (enable) SSP0 branch clock */ + + mov.w r10, #SSP_BASE_LOW + movt r10, #SSP_BASE_HIGH + mov.w r8, #0x07 + str.w r8, [r10, #SSP_CR0_OFFSET] /* Set clock postscale */ + mov.w r8, #0x02 + str.w r8, [r10, #SSP_CPSR_OFFSET] /* Set clock prescale */ + str.w r8, [r10, #SSP_CR1_OFFSET] /* Enable SSP in SPI mode */ +write_enable: + bl cs_down + mov.w r9, #0x06 /* Send the write enable command */ + bl write_data + bl cs_up + + bl cs_down + mov.w r9, #0x05 /* Get status register */ + bl write_data + mov.w r9, #0x00 /* Dummy data to clock in status */ + bl write_data + bl cs_up + + tst r9, #0x02 /* If the WE bit isn't set, we have a problem. */ + beq error +erase: + bl cs_down + mov.w r9, r2 /* Send the erase command */ + bl write_data +write_address: + lsr r9, r0, #16 /* Send the current 24-bit write address, MSB first */ + bl write_data + lsr r9, r0, #8 + bl write_data + mov.w r9, r0 + bl write_data + bl cs_up +wait_flash_busy: /* Wait for the flash to finish the previous erase */ + bl cs_down + mov.w r9, #0x05 /* Get status register */ + bl write_data + mov.w r9, #0x00 /* Dummy data to clock in status */ + bl write_data + bl cs_up + tst r9, #0x01 /* If it isn't done, keep waiting */ + bne wait_flash_busy + + subs r1, r1, #1 /* decrement count */ + cbz r1, exit /* Exit if we have written everything */ + add r0, r3 /* Move the address up by the block size */ + b write_enable /* Start a new block erase */ +write_data: /* Send/receive 1 byte of data over SSP */ + mov.w r10, #SSP_BASE_LOW + movt r10, #SSP_BASE_HIGH + str.w r9, [r10, #SSP_DATA_OFFSET] /* Write supplied data to the SSP data reg */ +wait_transmit: + ldr r9, [r10, #SSP_SR_OFFSET] /* Check SSP status */ + tst r9, #0x0010 /* Check if BSY bit is set */ + bne wait_transmit /* If still transmitting, keep waiting */ + ldr r9, [r10, #SSP_DATA_OFFSET] /* Load received data */ + bx lr /* Exit subroutine */ +cs_up: + mov.w r8, #0xff + b cs_write +cs_down: + mov.w r8, #0x0000 +cs_write: + mov.w r10, #IO_BASE_LOW + movt r10, #IO_BASE_HIGH + str.w r8, [r10, #IO_CS_OFFSET] + bx lr +error: + movs r0, #0 +exit: + bkpt #0x00 + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/lpcspifi_init.S b/debuggers/openocd/contrib/loaders/flash/lpcspifi_init.S new file mode 100644 index 00000000..1b373a1b --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/lpcspifi_init.S @@ -0,0 +1,102 @@ +/*************************************************************************** + * Copyright (C) 2012 by George Harris * + * george@luminairecoffee.com * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/*************************************************************************** +* This is an algorithm for the LPC43xx family (and probably the LPC18xx * +* family as well, though they have not been tested) that will initialize * +* memory-mapped SPI flash accesses. Unfortunately NXP has published * +* neither the ROM source code that performs this initialization nor the * +* register descriptions necessary to do so, so this code is necessary to * +* call into the ROM SPIFI API. * +***************************************************************************/ + + .text + .syntax unified + .arch armv7-m + .thumb + .thumb_func + + .align 2 + +/* + * Params : + * r0 = spifi clock speed + */ + +#define IOCONFIG_BASE_HIGH 0x4008 +#define IOCONFIG_BASE_LOW 0x6000 +#define IOCONFIG_SCK_OFFSET 0x18c +#define IOCONFIG_HOLD_OFFSET 0x190 +#define IOCONFIG_WP_OFFSET 0x194 +#define IOCONFIG_MISO_OFFSET 0x198 +#define IOCONFIG_MOSI_OFFSET 0x19c +#define IOCONFIG_CS_OFFSET 0x1a0 + +#define SPIFI_ROM_TABLE_BASE_HIGH 0x1040 +#define SPIFI_ROM_TABLE_BASE_LOW 0x0118 + +code: + mov.w r8, r0 + sub sp, #0x84 + add r7, sp, #0x0 + /* Initialize SPIFI pins */ + mov.w r3, #IOCONFIG_BASE_LOW + movt r3, #IOCONFIG_BASE_HIGH + mov.w r2, #0xf3 + str.w r2, [r3, #IOCONFIG_SCK_OFFSET] + mov.w r3, #IOCONFIG_BASE_LOW + movt r3, #IOCONFIG_BASE_HIGH + mov.w r2, #IOCONFIG_BASE_LOW + movt r2, #IOCONFIG_BASE_HIGH + mov.w r1, #IOCONFIG_BASE_LOW + movt r1, #IOCONFIG_BASE_HIGH + mov.w r0, #IOCONFIG_BASE_LOW + movt r0, #IOCONFIG_BASE_HIGH + mov.w r4, #0xd3 + str.w r4, [r0, #IOCONFIG_MOSI_OFFSET] + mov r0, r4 + str.w r0, [r1, #IOCONFIG_MISO_OFFSET] + mov r1, r0 + str.w r1, [r2, #IOCONFIG_WP_OFFSET] + str.w r1, [r3, #IOCONFIG_HOLD_OFFSET] + mov.w r3, #IOCONFIG_BASE_LOW + movt r3, #IOCONFIG_BASE_HIGH + mov.w r2, #0x13 + str.w r2, [r3, #IOCONFIG_CS_OFFSET] + + /* Perform SPIFI init. See spifi_rom_api.h (in NXP lpc43xx driver package) for details */ + /* on initialization arguments. */ + movw r3, #SPIFI_ROM_TABLE_BASE_LOW /* The ROM API table is located @ 0x10400118, and */ + movt r3, #SPIFI_ROM_TABLE_BASE_HIGH /* the first pointer in the struct is to the init function. */ + ldr r3, [r3, #0x0] + ldr r4, [r3, #0x0] /* Grab the init function pointer from the table */ + /* Set up function arguments */ + movw r0, #0x3b4 + movt r0, #0x1000 /* Pointer to a SPIFI data struct that we don't care about */ + mov.w r1, #0x3 /* "csHigh". Not 100% sure what this does. */ + mov.w r2, #0xc0 /* The configuration word: S_RCVCLOCK | S_FULLCLK */ + mov.w r3, r8 /* SPIFI clock speed (12MHz) */ + blx r4 /* Call the init function */ + b done + +done: + bkpt #0 + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/lpcspifi_write.S b/debuggers/openocd/contrib/loaders/flash/lpcspifi_write.S new file mode 100644 index 00000000..4292a370 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/lpcspifi_write.S @@ -0,0 +1,210 @@ +/*************************************************************************** + * Copyright (C) 2012 by George Harris * + * george@luminairecoffee.com * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .syntax unified + .cpu cortex-m3 + .thumb + .thumb_func + +/* + * Params : + * r0 = workarea start, status (out) + * r1 = workarea end + * r2 = target address (offset from flash base) + * r3 = count (bytes) + * r4 = page size + * Clobbered: + * r7 - rp + * r8 - wp, tmp + * r9 - send/receive data + * r10 - temp + * r11 - current page end address + */ + +#define SSP_BASE_HIGH 0x4008 +#define SSP_BASE_LOW 0x3000 +#define SSP_CR0_OFFSET 0x00 +#define SSP_CR1_OFFSET 0x04 +#define SSP_DATA_OFFSET 0x08 +#define SSP_CPSR_OFFSET 0x10 +#define SSP_SR_OFFSET 0x0c + +#define SSP_CLOCK_BASE_HIGH 0x4005 +#define SSP_CLOCK_BASE_LOW 0x0000 +#define SSP_BRANCH_CLOCK_BASE_HIGH 0x4005 +#define SSP_BRANCH_CLOCK_BASE_LOW 0x2000 +#define SSP_BASE_CLOCK_OFFSET 0x94 +#define SSP_BRANCH_CLOCK_OFFSET 0x700 + +#define IOCONFIG_BASE_HIGH 0x4008 +#define IOCONFIG_BASE_LOW 0x6000 +#define IOCONFIG_SCK_OFFSET 0x18c +#define IOCONFIG_HOLD_OFFSET 0x190 +#define IOCONFIG_WP_OFFSET 0x194 +#define IOCONFIG_MISO_OFFSET 0x198 +#define IOCONFIG_MOSI_OFFSET 0x19c +#define IOCONFIG_CS_OFFSET 0x1a0 + +#define IO_BASE_HIGH 0x400f +#define IO_BASE_LOW 0x4000 +#define IO_CS_OFFSET 0xab +#define IODIR_BASE_HIGH 0x400f +#define IODIR_BASE_LOW 0x6000 +#define IO_CS_DIR_OFFSET 0x14 + + +setup: /* Initialize SSP pins and module */ + mov.w r10, #IOCONFIG_BASE_LOW + movt r10, #IOCONFIG_BASE_HIGH + mov.w r8, #0xea + str.w r8, [r10, #IOCONFIG_SCK_OFFSET] /* Configure SCK pin function */ + mov.w r8, #0x40 + str.w r8, [r10, #IOCONFIG_HOLD_OFFSET] /* Configure /HOLD pin function */ + mov.w r8, #0x40 + str.w r8, [r10, #IOCONFIG_WP_OFFSET] /* Configure /WP pin function */ + mov.w r8, #0xed + str.w r8, [r10, #IOCONFIG_MISO_OFFSET] /* Configure MISO pin function */ + mov.w r8, #0xed + str.w r8, [r10, #IOCONFIG_MOSI_OFFSET] /* Configure MOSI pin function */ + mov.w r8, #0x44 + str.w r8, [r10, #IOCONFIG_CS_OFFSET] /* Configure CS pin function */ + + mov.w r10, #IODIR_BASE_LOW + movt r10, #IODIR_BASE_HIGH + mov.w r8, #0x800 + str r8, [r10, #IO_CS_DIR_OFFSET] /* Set CS as output */ + mov.w r10, #IO_BASE_LOW + movt r10, #IO_BASE_HIGH + mov.w r8, #0xff + str.w r8, [r10, #IO_CS_OFFSET] /* Set CS high */ + + mov.w r10, #SSP_CLOCK_BASE_LOW + movt r10, #SSP_CLOCK_BASE_HIGH + mov.w r8, #0x0000 + movt r8, #0x0100 + str.w r8, [r10, #SSP_BASE_CLOCK_OFFSET] /* Configure SSP0 base clock (use 12 MHz IRC) */ + + mov.w r10, #SSP_BRANCH_CLOCK_BASE_LOW + movt r10, #SSP_BRANCH_CLOCK_BASE_HIGH + mov.w r8, #0x01 + str.w r8, [r10, #SSP_BRANCH_CLOCK_OFFSET] /* Configure (enable) SSP0 branch clock */ + + mov.w r10, #SSP_BASE_LOW + movt r10, #SSP_BASE_HIGH + mov.w r8, #0x07 + str.w r8, [r10, #SSP_CR0_OFFSET] /* Set clock postscale */ + mov.w r8, #0x02 + str.w r8, [r10, #SSP_CPSR_OFFSET] /* Set clock prescale */ + str.w r8, [r10, #SSP_CR1_OFFSET] /* Enable SSP in SPI mode */ + + mov.w r11, #0x00 +find_next_page_boundary: + add r11, r4 /* Increment to the next page */ + cmp r11, r2 + /* If we have not reached the next page boundary after the target address, keep going */ + bls find_next_page_boundary +write_enable: + bl cs_down + mov.w r9, #0x06 /* Send the write enable command */ + bl write_data + bl cs_up + + bl cs_down + mov.w r9, #0x05 /* Get status register */ + bl write_data + mov.w r9, #0x00 /* Dummy data to clock in status */ + bl write_data + bl cs_up + + tst r9, #0x02 /* If the WE bit isn't set, we have a problem. */ + beq error +page_program: + bl cs_down + mov.w r9, #0x02 /* Send the page program command */ + bl write_data +write_address: + lsr r9, r2, #16 /* Send the current 24-bit write address, MSB first */ + bl write_data + lsr r9, r2, #8 + bl write_data + mov.w r9, r2 + bl write_data +wait_fifo: + ldr r8, [r0] /* read the write pointer */ + cmp r8, #0 /* if it's zero, we're gonzo */ + beq exit + ldr r7, [r0, #4] /* read the read pointer */ + cmp r7, r8 /* wait until they are not equal */ + beq wait_fifo +write: + ldrb r9, [r7], #0x01 /* Load one byte from the FIFO, increment the read pointer by 1 */ + bl write_data /* send the byte to the flash chip */ + + cmp r7, r1 /* wrap the read pointer if it is at the end */ + it cs + addcs r7, r0, #8 /* skip loader args */ + str r7, [r0, #4] /* store the new read pointer */ + subs r3, r3, #1 /* decrement count */ + cbz r3, exit /* Exit if we have written everything */ + + add r2, #1 /* Increment flash address by 1 */ + cmp r11, r2 /* See if we have reached the end of a page */ + bne wait_fifo /* If not, keep writing bytes */ + bl cs_up /* Otherwise, end the command and keep going w/ the next page */ + add r11, r4 /* Move up the end-of-page address by the page size*/ +wait_flash_busy: /* Wait for the flash to finish the previous page write */ + bl cs_down + mov.w r9, #0x05 /* Get status register */ + bl write_data + mov.w r9, #0x00 /* Dummy data to clock in status */ + bl write_data + bl cs_up + tst r9, #0x01 /* If it isn't done, keep waiting */ + bne wait_flash_busy + b write_enable /* If it is done, start a new page write */ +write_data: /* Send/receive 1 byte of data over SSP */ + mov.w r10, #SSP_BASE_LOW + movt r10, #SSP_BASE_HIGH + str.w r9, [r10, #SSP_DATA_OFFSET] /* Write supplied data to the SSP data reg */ +wait_transmit: + ldr r9, [r10, #SSP_SR_OFFSET] /* Check SSP status */ + tst r9, #0x0010 /* Check if BSY bit is set */ + bne wait_transmit /* If still transmitting, keep waiting */ + ldr r9, [r10, #SSP_DATA_OFFSET] /* Load received data */ + bx lr /* Exit subroutine */ +cs_up: + mov.w r8, #0xff + b cs_write +cs_down: + mov.w r8, #0x0000 +cs_write: + mov.w r10, #IO_BASE_LOW + movt r10, #IO_BASE_HIGH + str.w r8, [r10, #IO_CS_OFFSET] + bx lr +error: + movs r0, #0 + str r0, [r2, #4] /* set rp = 0 on error */ +exit: + mov r0, r6 + bkpt #0x00 + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/pic32mx.s b/debuggers/openocd/contrib/loaders/flash/pic32mx.s new file mode 100644 index 00000000..d45ab111 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/pic32mx.s @@ -0,0 +1,132 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .arch m4k + .set noreorder + .set noat + +/* params: + * $a0 src adr - ram + result + * $a1 dest adr - flash + * $a2 count (32bit words) + * vars + * + * temps: + * $t0, $t1, $t2, $t3, $t4, $t5 + * $s0, $s1, $s3, $s4, $s5 + */ + + .type main, @function + .global main + +.ent main +main: + /* setup constants */ + lui $t0, 0xaa99 + ori $t0, 0x6655 /* NVMKEY1 */ + lui $t1, 0x5566 + ori $t1, 0x99AA /* NVMKEY2 */ + lui $t2, 0xBF80 + ori $t2, 0xF400 /* NVMCON */ + ori $t3, $zero, 0x4003 /* NVMCON row write cmd */ + ori $t4, $zero, 0x8000 /* NVMCON start cmd */ + +write_row: + /* can we perform a row write: 128 32bit words */ + sltiu $s3, $a2, 128 + bne $s3, $zero, write_word + ori $t5, $zero, 0x4000 /* NVMCON clear cmd */ + + /* perform row write 512 bytes */ + sw $a1, 32($t2) /* set NVMADDR with dest addr - real addr */ + sw $a0, 64($t2) /* set NVMSRCADDR with src addr - real addr */ + + bal progflash + addiu $a0, $a0, 512 + addiu $a1, $a1, 512 + beq $zero, $zero, write_row + addiu $a2, $a2, -128 + +write_word: + /* write 32bit words */ + lui $s5, 0xa000 + ori $s5, 0x0000 + or $a0, $a0, $s5 /* convert to virtual addr */ + + beq $zero, $zero, next_word + ori $t3, $zero, 0x4001 /* NVMCON word write cmd */ + +prog_word: + lw $s4, 0($a0) /* load data - from virtual addr */ + sw $s4, 48($t2) /* set NVMDATA with data */ + sw $a1, 32($t2) /* set NVMADDR with dest addr - real addr */ + + bal progflash + addiu $a0, $a0, 4 + addiu $a1, $a1, 4 + addiu $a2, $a2, -1 +next_word: + bne $a2, $zero, prog_word + nop + +done: + beq $zero, $zero, exit + addiu $a0, $zero, 0 + +error: + /* save result to $a0 */ + addiu $a0, $s1, 0 + +exit: + sdbbp +.end main + + .type progflash, @function + .global progflash + +.ent progflash +progflash: + sw $t3, 0($t2) /* set NVMWREN */ + sw $t0, 16($t2) /* write NVMKEY1 */ + sw $t1, 16($t2) /* write NVMKEY2 */ + sw $t4, 8($t2) /* start operation */ + +waitflash: + lw $s0, 0($t2) + and $s0, $s0, $t4 + bne $s0, $zero, waitflash + nop + + /* following is to comply with errata #34 + * 500ns delay required */ + nop + nop + nop + nop + /* check for errors */ + lw $s1, 0($t2) + andi $s1, $zero, 0x3000 + bne $s1, $zero, error + sw $t5, 4($t2) /* clear NVMWREN */ + jr $ra + nop + +.end progflash diff --git a/debuggers/openocd/contrib/loaders/flash/stellaris.s b/debuggers/openocd/contrib/loaders/flash/stellaris.s new file mode 100644 index 00000000..42494938 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/stellaris.s @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2006 by Magnus Lundin * + * lundin@mlu.mine.nu * + * * + * Copyright (C) 2008 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .syntax unified + .cpu cortex-m3 + .thumb + .thumb_func + +/* + * Params : + * r0 = workarea start + * r1 = workarea end + * r2 = target address + * r3 = count (32bit words) + * + * Clobbered: + * r4 = pFLASH_CTRL_BASE + * r5 = FLASHWRITECMD + * r7 - rp + * r8 - wp, tmp + */ + +write: + ldr r4, pFLASH_CTRL_BASE + ldr r5, FLASHWRITECMD + +wait_fifo: + ldr r8, [r0, #0] /* read wp */ + cmp r8, #0 /* abort if wp == 0 */ + beq exit + ldr r7, [r0, #4] /* read rp */ + cmp r7, r8 /* wait until rp != wp */ + beq wait_fifo + +mainloop: + str r2, [r4, #0] /* FMA - write address */ + add r2, r2, #4 /* increment target address */ + ldr r8, [r7], #4 + str r8, [r4, #4] /* FMD - write data */ + str r5, [r4, #8] /* FMC - enable write */ +busy: + ldr r8, [r4, #8] + tst r8, #1 + bne busy + + cmp r7, r1 /* wrap rp at end of buffer */ + it cs + addcs r7, r0, #8 /* skip loader args */ + str r7, [r0, #4] /* store rp */ + subs r3, r3, #1 /* decrement word count */ + cbz r3, exit /* loop if not done */ + b wait_fifo +exit: + bkpt #0 + +pFLASH_CTRL_BASE: .word 0x400FD000 +FLASHWRITECMD: .word 0xA4420001 diff --git a/debuggers/openocd/contrib/loaders/flash/stm32f1x.S b/debuggers/openocd/contrib/loaders/flash/stm32f1x.S new file mode 100644 index 00000000..6b6aa091 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/stm32f1x.S @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2011 by Andreas Fritiofson * + * andreas.fritiofson@gmail.com * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .syntax unified + .cpu cortex-m0 + .thumb + .thumb_func + .global write + + /* Params: + * r0 - flash base (in), status (out) + * r1 - count (halfword-16bit) + * r2 - workarea start + * r3 - workarea end + * r4 - target address + * Clobbered: + * r5 - rp + * r6 - wp, tmp + * r7 - tmp + */ + +#define STM32_FLASH_SR_OFFSET 0x0c /* offset of SR register from flash reg base */ + +wait_fifo: + ldr r6, [r2, #0] /* read wp */ + cmp r6, #0 /* abort if wp == 0 */ + beq exit + ldr r5, [r2, #4] /* read rp */ + cmp r5, r6 /* wait until rp != wp */ + beq wait_fifo + ldrh r6, [r5] /* "*target_address++ = *rp++" */ + strh r6, [r4] + adds r5, #2 + adds r4, #2 +busy: + ldr r6, [r0, #STM32_FLASH_SR_OFFSET] /* wait until BSY flag is reset */ + movs r7, #1 + tst r6, r7 + bne busy + movs r7, #0x14 /* check the error bits */ + tst r6, r7 + bne error + cmp r5, r3 /* wrap rp at end of buffer */ + bcc no_wrap + mov r5, r2 + adds r5, #8 +no_wrap: + str r5, [r2, #4] /* store rp */ + subs r1, r1, #1 /* decrement halfword count */ + cmp r1, #0 + beq exit /* loop if not done */ + b wait_fifo +error: + movs r0, #0 + str r0, [r2, #4] /* set rp = 0 on error */ +exit: + mov r0, r6 /* return status in r0 */ + bkpt #0 diff --git a/debuggers/openocd/contrib/loaders/flash/stm32f2x.S b/debuggers/openocd/contrib/loaders/flash/stm32f2x.S new file mode 100644 index 00000000..7ac5e3c0 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/stm32f2x.S @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * Copyright (C) 2011 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .syntax unified + .cpu cortex-m3 + .thumb + .thumb_func + +/* + * Params : + * r0 = workarea start, status (out) + * r1 = workarea end + * r2 = target address + * r3 = count (16bit words) + * r4 = flash base + * + * Clobbered: + * r6 - temp + * r7 - rp + * r8 - wp, tmp + */ + +#define STM32_FLASH_CR_OFFSET 0x10 /* offset of CR register in FLASH struct */ +#define STM32_FLASH_SR_OFFSET 0x0c /* offset of SR register in FLASH struct */ + +wait_fifo: + ldr r8, [r0, #0] /* read wp */ + cmp r8, #0 /* abort if wp == 0 */ + beq exit + ldr r7, [r0, #4] /* read rp */ + cmp r7, r8 /* wait until rp != wp */ + beq wait_fifo + + ldr r6, STM32_PROG16 + str r6, [r4, #STM32_FLASH_CR_OFFSET] + ldrh r6, [r7], #0x02 /* read one half-word from src, increment ptr */ + strh r6, [r2], #0x02 /* write one half-word from src, increment ptr */ +busy: + ldr r6, [r4, #STM32_FLASH_SR_OFFSET] + tst r6, #0x10000 /* BSY (bit16) == 1 => operation in progress */ + bne busy /* wait more... */ + tst r6, #0xf0 /* PGSERR | PGPERR | PGAERR | WRPERR */ + bne error /* fail... */ + + cmp r7, r1 /* wrap rp at end of buffer */ + it cs + addcs r7, r0, #8 /* skip loader args */ + str r7, [r0, #4] /* store rp */ + subs r3, r3, #1 /* decrement halfword count */ + cbz r3, exit /* loop if not done */ + b wait_fifo +error: + movs r1, #0 + str r1, [r0, #4] /* set rp = 0 on error */ +exit: + mov r0, r6 /* return status in r0 */ + bkpt #0x00 + +STM32_PROG16: .word 0x101 /* PG | PSIZE_16*/ diff --git a/debuggers/openocd/contrib/loaders/flash/stm32lx.S b/debuggers/openocd/contrib/loaders/flash/stm32lx.S new file mode 100644 index 00000000..6e8ccb08 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/stm32lx.S @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * Copyright (C) 2011 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * + * Copyright (C) 2011 Clement Burin des Roziers * + * clement.burin-des-roziers@hikob.com * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +// Build : arm-eabi-gcc -c stm32lx.S + .text + .syntax unified + .cpu cortex-m3 + .thumb + .thumb_func + .global write + +/* + r0 - destination address + r1 - source address + r2 - count +*/ + + // Set 0 to r3 + movs r3, #0 + // Go to compare + b.n test_done + +write_word: + // Load one word from address in r0, increment by 4 + ldr.w ip, [r1], #4 + // Store the word to address in r1, increment by 4 + str.w ip, [r0], #4 + // Increment r3 + adds r3, #1 + +test_done: + // Compare r3 and r2 + cmp r3, r2 + // Loop if not zero + bcc.n write_word + + // Set breakpoint to exit + bkpt #0x00 + diff --git a/debuggers/openocd/contrib/loaders/flash/str7x.s b/debuggers/openocd/contrib/loaders/flash/str7x.s new file mode 100644 index 00000000..b9eb4299 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/str7x.s @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .arm + .arch armv4t + + .section .init +/* + r0 source address + r1 address + r2 FLASH_CR0 + r3 dword count + r4 result + r5 busy mask +*/ + +write: + mov r4, #0x10000000 /* set DWPG bit */ + str r4, [r2, #0x0] /* FLASH_CR0 */ + str r1, [r2, #0x10] /* FLASH_AR */ + ldr r4, [r0], #4 /* load data */ + str r4, [r2, #0x8] /* FLASH_DR0 */ + ldr r4, [r0], #4 /* load data */ + str r4, [r2, #0xc] /* FLASH_DR1 */ + mov r4, #0x90000000 /* set DWPG and WMS bits */ + str r4, [r2, #0x0] /* FLASH_CR0 */ +busy: + ldr r4, [r2, #0x0] /* FLASH_CR0 */ + tst r4, r5 + bne busy + ldr r4, [r2, #0x14] /* FLASH_ER */ + tst r4, #0xff /* do we have errors */ + tsteq r4, #0x100 /* write protection set */ + bne exit + add r1, r1, #0x8 /* next 8 bytes */ + subs r3, r3, #1 /* decremment dword count */ + bne write +exit: + b exit + + .end diff --git a/debuggers/openocd/contrib/loaders/flash/str9x.s b/debuggers/openocd/contrib/loaders/flash/str9x.s new file mode 100644 index 00000000..35abbba5 --- /dev/null +++ b/debuggers/openocd/contrib/loaders/flash/str9x.s @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + .text + .arm + .arch armv5t + + .section .init +/* + r0 source address (in) + r1 target address (in) + r2 word count (in) + r3 result (out) +*/ + +write: + bic r4, r1, #3 /* word address */ + mov r3, #0x40 /* write command */ + strh r3, [r4, #0] + ldrh r3, [r0], #2 /* read data */ + strh r3, [r1], #2 /* write data */ + mov r3, #0x70 /* status command */ + strh r3, [r4, #0] +busy: + ldrb r3, [r4, #0] /* status */ + tst r3, #0x80 + beq busy + mov r5, #0x50 /* clear status command */ + strh r5, [r4, #0] + mov r5, #0xFF /* read array */ + strh r5, [r4, #0] + tst r3, #0x12 + bne exit + subs r2, r2, #1 /* decremment word count */ + bne write +exit: + bkpt #0 + + .end diff --git a/debuggers/openocd/contrib/openocd.udev b/debuggers/openocd/contrib/openocd.udev new file mode 100644 index 00000000..7065014a --- /dev/null +++ b/debuggers/openocd/contrib/openocd.udev @@ -0,0 +1,92 @@ +ACTION!="add|change", GOTO="openocd_rules_end" +SUBSYSTEM!="usb|tty", GOTO="openocd_rules_end" + +# Olimex ARM-USB-OCD +ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="0003", MODE="664", GROUP="plugdev" + +# Olimex ARM-USB-OCD-H +ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="002b", MODE="664", GROUP="plugdev" + +# Olimex ARM-USB-OCD-TINY +ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="0004", MODE="664", GROUP="plugdev" + +# Olimex ARM-JTAG-EW +ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="001e", MODE="664", GROUP="plugdev" + +# Olimex ARM-USB-OCD-TINY-H +ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="002a", MODE="664", GROUP="plugdev" + +# USBprog with OpenOCD firmware +ATTRS{idVendor}=="1781", ATTRS{idProduct}=="0c63", MODE="664", GROUP="plugdev" + +# Amontec JTAGkey and JTAGkey-tiny +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="cff8", MODE="664", GROUP="plugdev" + +# Amontec JTAGkey-HiSpeed +ATTRS{idVendor}=="0fbb", ATTRS{idProduct}=="1000", MODE="664", GROUP="plugdev" + +# Axiom AXM-0432 Link (Symphony SoundBite?) +# Calao Systems USB-A9260-C01 +# TinCanTools Flyswatter +# OOCD-Link +# Marvell Sheevaplug (early development versions) +# DLP Design DLP-USB1232H USB-to-UART/FIFO interface module +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="664", GROUP="plugdev" + +# Calao Systems USB-A9260-C02 +# Bus Pirate +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="664", GROUP="plugdev" + +# IAR J-Link USB +ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0101", MODE="664", GROUP="plugdev" + +# Raisonance RLink +ATTRS{idVendor}=="138e", ATTRS{idProduct}=="9000", MODE="664", GROUP="plugdev" + +# Hitex STR9-comStick +ATTRS{idVendor}=="0640", ATTRS{idProduct}=="002c", MODE="664", GROUP="plugdev" + +# Hitex STM32-PerformanceStick +ATTRS{idVendor}=="0640", ATTRS{idProduct}=="002d", MODE="664", GROUP="plugdev" + +# TI/Luminary Stellaris Evaluation Board FTDI (several) +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcd9", MODE="664", GROUP="plugdev" + +# TI/Luminary Stellaris In-Circuit Debug Interface FTDI (ICDI) Board +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcda", MODE="664", GROUP="plugdev" + +# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board +ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="664", GROUP="plugdev" + +# Xverve Signalyzer Tool (DT-USB-ST) +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bca0", MODE="664", GROUP="plugdev" + +# egnite Turtelizer 2 +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bdc8", MODE="664", GROUP="plugdev" + +# Marvell Sheevaplug +ATTRS{idVendor}=="9e88", ATTRS{idProduct}=="9e8f", MODE="664", GROUP="plugdev" + +# Section5 ICEbear +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="c140", MODE="664", GROUP="plugdev" +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="c141", MODE="664", GROUP="plugdev" + +# Hilscher NXHX Boards +ATTRS{idVendor}=="0640", ATTRS{idProduct}=="0028", MODE="664", GROUP="plugdev" + +# Debug Board for Neo1973 +ATTRS{idVendor}=="1457", ATTRS{idProduct}=="5118", MODE="664", GROUP="plugdev" + +# XDS100v2 +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="a6d0", MODE="664", GROUP="plugdev" + +# stlink v1 +ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3744", MODE="664", GROUP="plugdev" + +# stlink v2 +ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", MODE="664", GROUP="plugdev" + +# opendous and estick +ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204f", MODE="664", GROUP="plugdev" + +LABEL="openocd_rules_end" diff --git a/debuggers/openocd/depcomp b/debuggers/openocd/depcomp new file mode 100755 index 00000000..06b0882d --- /dev/null +++ b/debuggers/openocd/depcomp @@ -0,0 +1,790 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2012-10-18.11; # UTC + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. + +# 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, 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, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/debuggers/openocd/doc/INSTALL.txt b/debuggers/openocd/doc/INSTALL.txt new file mode 100644 index 00000000..c329be2c --- /dev/null +++ b/debuggers/openocd/doc/INSTALL.txt @@ -0,0 +1,204 @@ +TODO!!! this should be merged into openocd.texi!!! + + +Prerequisites +============= + +When building with support for FTDI FT2232 based devices, you need at least +one of the following libraries: + +- libftdi (http://www.intra2net.com/opensource/ftdi/) +- libftd2xx (http://www.ftdichip.com/Drivers/D2XX.htm) + +On Windows, you need either Cygwin or MinGW, but compilation for MinGW is also +possible using a Cygwin host. + +Basic Installation +================== + + OpenOCD is distributed without autotools generated files, i.e. without a +configure script. Run ./bootstrap in the openocd directory to have all +necessary files generated. + + You have to explicitly enable desired JTAG interfaces during configure: + +./configure --enable-parport --enable-ft2232-libftdi (OR --enable-ft2232-ftd2xx) \ + --enable-amtjtagaccel + + Under Windows/Cygwin, only the ftd2xx driver is supported for FT2232 based +devices. You have to specify the location of the FTDI driver package with the +--with-ftd2xx=/full/path/name option. + +Under Linux you can choose to build the parport driver with support for +/dev/parportN instead of the default access with direct port I/O using +--enable-parport_ppdev. This has the advantage of running OpenOCD without root +privileges at the expense of a slight performance decrease. This is also +available on FreeBSD using PPI, but the naming of the devices is different. + +Generic installation instructions +================================= + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes a while. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Type `make install' to install the programs and any data files and + documentation. + + 4. You can remove the program binaries and object files from the + source code directory by typing `make clean'. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/debuggers/openocd/doc/Makefile.am b/debuggers/openocd/doc/Makefile.am new file mode 100644 index 00000000..6759ed5e --- /dev/null +++ b/debuggers/openocd/doc/Makefile.am @@ -0,0 +1,20 @@ +info_TEXINFOS = openocd.texi +openocd_TEXINFOS = fdl.texi +man_MANS = openocd.1 +EXTRA_DIST = openocd.1 \ + INSTALL.txt + +dist-hook: + mkdir $(distdir)/manual + cp -p $(srcdir)/manual/*.txt $(distdir)/manual + for i in $$(cd $(srcdir)/manual/ && ls -d */); do \ + mkdir $(distdir)/manual/$$i; \ + cp -p $(srcdir)/manual/$$i/* $(distdir)/manual/$$i/; \ + done + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in \ + $(srcdir)/mdate-sh \ + $(srcdir)/stamp-vti \ + $(srcdir)/version.texi \ + $(srcdir)/texinfo.tex diff --git a/debuggers/openocd/doc/Makefile.in b/debuggers/openocd/doc/Makefile.in new file mode 100644 index 00000000..3004fa77 --- /dev/null +++ b/debuggers/openocd/doc/Makefile.in @@ -0,0 +1,809 @@ +# Makefile.in generated by automake 1.13.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = doc +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(openocd_TEXINFOS) mdate-sh $(srcdir)/version.texi \ + $(srcdir)/stamp-vti texinfo.tex +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config_subdir.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +AM_V_DVIPS = $(am__v_DVIPS_@AM_V@) +am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@) +am__v_DVIPS_0 = @echo " DVIPS " $@; +am__v_DVIPS_1 = +AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@) +am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@) +am__v_MAKEINFO_0 = @echo " MAKEINFO" $@; +am__v_MAKEINFO_1 = +AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@) +am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@) +am__v_INFOHTML_0 = @echo " INFOHTML" $@; +am__v_INFOHTML_1 = +AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@) +am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@) +am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@; +am__v_TEXI2DVI_1 = +AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@) +am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@) +am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@; +am__v_TEXI2PDF_1 = +AM_V_texinfo = $(am__v_texinfo_@AM_V@) +am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@) +am__v_texinfo_0 = -q +am__v_texinfo_1 = +AM_V_texidevnull = $(am__v_texidevnull_@AM_V@) +am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@) +am__v_texidevnull_0 = > /dev/null +am__v_texidevnull_1 = +INFO_DEPS = $(srcdir)/openocd.info +am__TEXINFO_TEX_DIR = $(srcdir) +DVIS = openocd.dvi +PDFS = openocd.pdf +PSS = openocd.ps +HTMLS = openocd.html +TEXINFOS = openocd.texi +TEXI2DVI = texi2dvi +TEXI2PDF = $(TEXI2DVI) --pdf --batch +MAKEINFOHTML = $(MAKEINFO) --html +AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) +DVIPS = dvips +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +doxygen_as_html = @doxygen_as_html@ +doxygen_as_pdf = @doxygen_as_pdf@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +info_TEXINFOS = openocd.texi +openocd_TEXINFOS = fdl.texi +man_MANS = openocd.1 +EXTRA_DIST = openocd.1 \ + INSTALL.txt + +MAINTAINERCLEANFILES = \ + $(srcdir)/Makefile.in \ + $(srcdir)/mdate-sh \ + $(srcdir)/stamp-vti \ + $(srcdir)/version.texi \ + $(srcdir)/texinfo.tex + +all: all-am + +.SUFFIXES: +.SUFFIXES: .dvi .html .info .pdf .ps .texi +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu doc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +.texi.info: + $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \ + am__cwd=`pwd` && $(am__cd) $(srcdir) && \ + rm -rf $$backupdir && mkdir $$backupdir && \ + if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ + for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ + if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ + done; \ + else :; fi && \ + cd "$$am__cwd"; \ + if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + -o $@ $<; \ + then \ + rc=0; \ + $(am__cd) $(srcdir); \ + else \ + rc=$$?; \ + $(am__cd) $(srcdir) && \ + $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ + fi; \ + rm -rf $$backupdir; exit $$rc + +.texi.dvi: + $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ + $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \ + $< + +.texi.pdf: + $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ + $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \ + $< + +.texi.html: + $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp) + $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + -o $(@:.html=.htp) $<; \ + then \ + rm -rf $@; \ + if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ + mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \ + else \ + if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ + rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \ + exit 1; \ + fi +$(srcdir)/openocd.info: openocd.texi $(srcdir)/version.texi $(openocd_TEXINFOS) +openocd.dvi: openocd.texi $(srcdir)/version.texi $(openocd_TEXINFOS) +openocd.pdf: openocd.texi $(srcdir)/version.texi $(openocd_TEXINFOS) +openocd.html: openocd.texi $(srcdir)/version.texi $(openocd_TEXINFOS) +$(srcdir)/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-vti +$(srcdir)/stamp-vti: openocd.texi $(top_srcdir)/configure + @(dir=.; test -f ./openocd.texi || dir=$(srcdir); \ + set `$(SHELL) $(srcdir)/mdate-sh $$dir/openocd.texi`; \ + echo "@set UPDATED $$1 $$2 $$3"; \ + echo "@set UPDATED-MONTH $$2 $$3"; \ + echo "@set EDITION $(VERSION)"; \ + echo "@set VERSION $(VERSION)") > vti.tmp + @cmp -s vti.tmp $(srcdir)/version.texi \ + || (echo "Updating $(srcdir)/version.texi"; \ + cp vti.tmp $(srcdir)/version.texi) + -@rm -f vti.tmp + @cp $(srcdir)/version.texi $@ + +mostlyclean-vti: + -rm -f vti.tmp + +maintainer-clean-vti: +@MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi +.dvi.ps: + $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(DVIPS) $(AM_V_texinfo) -o $@ $< + +uninstall-dvi-am: + @$(NORMAL_UNINSTALL) + @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \ + rm -f "$(DESTDIR)$(dvidir)/$$f"; \ + done + +uninstall-html-am: + @$(NORMAL_UNINSTALL) + @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \ + rm -rf "$(DESTDIR)$(htmldir)/$$f"; \ + done + +uninstall-info-am: + @$(PRE_UNINSTALL) + @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \ + if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \ + then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \ + done; \ + else :; fi + @$(NORMAL_UNINSTALL) + @list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \ + (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \ + echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \ + rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \ + else :; fi); \ + done + +uninstall-pdf-am: + @$(NORMAL_UNINSTALL) + @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \ + rm -f "$(DESTDIR)$(pdfdir)/$$f"; \ + done + +uninstall-ps-am: + @$(NORMAL_UNINSTALL) + @list='$(PSS)'; test -n "$(psdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \ + rm -f "$(DESTDIR)$(psdir)/$$f"; \ + done + +dist-info: $(INFO_DEPS) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + list='$(INFO_DEPS)'; \ + for base in $$list; do \ + case $$base in \ + $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \ + esac; \ + if test -f $$base; then d=.; else d=$(srcdir); fi; \ + base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \ + for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \ + if test -f $$file; then \ + relfile=`expr "$$file" : "$$d/\(.*\)"`; \ + test -f "$(distdir)/$$relfile" || \ + cp -p $$file "$(distdir)/$$relfile"; \ + else :; fi; \ + done; \ + done + +mostlyclean-aminfo: + -rm -rf openocd.t2d openocd.t2p + +clean-aminfo: + -test -z "openocd.dvi openocd.pdf openocd.ps openocd.html" \ + || rm -rf openocd.dvi openocd.pdf openocd.ps openocd.html + +maintainer-clean-aminfo: + @list='$(INFO_DEPS)'; for i in $$list; do \ + i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \ + echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \ + rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \ + done +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-info dist-hook +check-am: all-am +check: check-am +all-am: Makefile $(INFO_DEPS) $(MANS) +installdirs: + for dir in "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-aminfo clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: $(DVIS) + +html: html-am + +html-am: $(HTMLS) + +info: info-am + +info-am: $(INFO_DEPS) + +install-data-am: install-info-am install-man + +install-dvi: install-dvi-am + +install-dvi-am: $(DVIS) + @$(NORMAL_INSTALL) + @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \ + done +install-exec-am: + +install-html: install-html-am + +install-html-am: $(HTMLS) + @$(NORMAL_INSTALL) + @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ + $(am__strip_dir) \ + d2=$$d$$p; \ + if test -d "$$d2"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ + echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \ + $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ + else \ + list2="$$list2 $$d2"; \ + fi; \ + done; \ + test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ + done; } +install-info: install-info-am + +install-info-am: $(INFO_DEPS) + @$(NORMAL_INSTALL) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \ + fi; \ + for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + esac; \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \ + for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \ + $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \ + if test -f $$ifile; then \ + echo "$$ifile"; \ + else : ; fi; \ + done; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done + @$(POST_INSTALL) + @if $(am__can_run_installinfo); then \ + list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\ + install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\ + done; \ + else : ; fi +install-man: install-man1 + +install-pdf: install-pdf-am + +install-pdf-am: $(PDFS) + @$(NORMAL_INSTALL) + @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done +install-ps: install-ps-am + +install-ps-am: $(PSS) + @$(NORMAL_INSTALL) + @list='$(PSS)'; test -n "$(psdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-aminfo \ + maintainer-clean-generic maintainer-clean-vti + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \ + mostlyclean-libtool mostlyclean-vti + +pdf: pdf-am + +pdf-am: $(PDFS) + +ps: ps-am + +ps-am: $(PSS) + +uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \ + uninstall-man uninstall-pdf-am uninstall-ps-am + +uninstall-man: uninstall-man1 + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-aminfo clean-generic \ + clean-libtool cscopelist-am ctags-am dist-hook dist-info \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-aminfo \ + maintainer-clean-generic maintainer-clean-vti mostlyclean \ + mostlyclean-aminfo mostlyclean-generic mostlyclean-libtool \ + mostlyclean-vti pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am uninstall-dvi-am uninstall-html-am \ + uninstall-info-am uninstall-man uninstall-man1 \ + uninstall-pdf-am uninstall-ps-am + + +dist-hook: + mkdir $(distdir)/manual + cp -p $(srcdir)/manual/*.txt $(distdir)/manual + for i in $$(cd $(srcdir)/manual/ && ls -d */); do \ + mkdir $(distdir)/manual/$$i; \ + cp -p $(srcdir)/manual/$$i/* $(distdir)/manual/$$i/; \ + done + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/debuggers/openocd/doc/fdl.texi b/debuggers/openocd/doc/fdl.texi new file mode 100644 index 00000000..a18c33ea --- /dev/null +++ b/debuggers/openocd/doc/fdl.texi @@ -0,0 +1,452 @@ +@c -*-texinfo-*- +@node License +@appendix The GNU Free Documentation License. +@center Version 1.2, November 2002 + +@c This file is intended to be included within another document, +@c hence no sectioning command or @node. + +@display +Copyright @copyright{} 2000,2001,2002 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. +@end display + +@enumerate 0 +@item +PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document @dfn{free} in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of ``copyleft'', which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +@item +APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The ``Document'', below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as ``you''. You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not ``Transparent'' is called ``Opaque''. + +Examples of suitable formats for Transparent copies include plain +@sc{ascii} without markup, Texinfo input format, La@TeX{} input +format, @acronym{SGML} or @acronym{XML} using a publicly available +@acronym{DTD}, and standard-conforming simple @acronym{HTML}, +PostScript or @acronym{PDF} designed for human modification. Examples +of transparent image formats include @acronym{PNG}, @acronym{XCF} and +@acronym{JPG}. Opaque formats include proprietary formats that can be +read and edited only by proprietary word processors, @acronym{SGML} or +@acronym{XML} for which the @acronym{DTD} and/or processing tools are +not generally available, and the machine-generated @acronym{HTML}, +PostScript or @acronym{PDF} produced by some word processors for +output purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +A section ``Entitled XYZ'' means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as ``Acknowledgements'', +``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' +of such a section when you modify the Document means that it remains a +section ``Entitled XYZ'' according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +@item +VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + +@item +COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + +@item +MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +@enumerate A +@item +Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. + +@item +List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has fewer than five), +unless they release you from this requirement. + +@item +State on the Title page the name of the publisher of the +Modified Version, as the publisher. + +@item +Preserve all the copyright notices of the Document. + +@item +Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +@item +Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +@item +Preserve in that license notice the full lists of Invariant Sections +and required Cover Texts given in the Document's license notice. + +@item +Include an unaltered copy of this License. + +@item +Preserve the section Entitled ``History'', Preserve its Title, and add +to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled ``History'' in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +@item +Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise +the network locations given in the Document for previous versions +it was based on. These may be placed in the ``History'' section. +You may omit a network location for a work that was published at +least four years before the Document itself, or if the original +publisher of the version it refers to gives permission. + +@item +For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve +the Title of the section, and preserve in the section all the +substance and tone of each of the contributor acknowledgements and/or +dedications given therein. + +@item +Preserve all the Invariant Sections of the Document, +unaltered in their text and in their titles. Section numbers +or the equivalent are not considered part of the section titles. + +@item +Delete any section Entitled ``Endorsements''. Such a section +may not be included in the Modified Version. + +@item +Do not retitle any existing section to be Entitled ``Endorsements'' or +to conflict in title with any Invariant Section. + +@item +Preserve any Warranty Disclaimers. +@end enumerate + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled ``Endorsements'', provided it contains +nothing but endorsements of your Modified Version by various +parties---for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + +@item +COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled ``History'' +in the various original documents, forming one section Entitled +``History''; likewise combine any sections Entitled ``Acknowledgements'', +and any sections Entitled ``Dedications''. You must delete all +sections Entitled ``Endorsements.'' + +@item +COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + +@item +AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an ``aggregate'' if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + +@item +TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled ``Acknowledgements'', +``Dedications'', or ``History'', the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + +@item +TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document 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. + +@item +FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation 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. See +@uref{http://www.gnu.org/copyleft/}. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License ``or any later version'' applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. +@end enumerate + +@unnumberedsec ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +@smallexample +@group + Copyright (C) @var{year} @var{your name}. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. +@end group +@end smallexample + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the ``with@dots{}Texts.'' line with this: + +@smallexample +@group + with the Invariant Sections being @var{list their titles}, with + the Front-Cover Texts being @var{list}, and with the Back-Cover Texts + being @var{list}. +@end group +@end smallexample + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + +@c Local Variables: +@c ispell-local-pdict: "ispell-dict" +@c End: + diff --git a/debuggers/openocd/doc/manual/app.txt b/debuggers/openocd/doc/manual/app.txt new file mode 100644 index 00000000..989e6e67 --- /dev/null +++ b/debuggers/openocd/doc/manual/app.txt @@ -0,0 +1,9 @@ +/** @page appdocs OpenOCD Application APIs + +The top-level APIs in the OpenOCD library allow applications to integrate +all of the low-level functionality using a set of simple function calls. + +These function calls do not exist in a re-usable form, but +contributions to create and document them will be welcome. + + */ diff --git a/debuggers/openocd/doc/manual/flash.txt b/debuggers/openocd/doc/manual/flash.txt new file mode 100644 index 00000000..a9f6c2a5 --- /dev/null +++ b/debuggers/openocd/doc/manual/flash.txt @@ -0,0 +1,35 @@ +/** @page flashdocs OpenOCD Flash APIs + +OpenOCD provides its Flash APIs for developers to support different +types of flash devices, some of which are built-in to target devices +while others may be connected via standard memory interface (e.g. CFI, +FMI, etc.). + +The Flash module provides the following APIs: + + - @subpage flashcfi + - @subpage flashnand + - @subpage flashtarget + +This section needs to be expanded. + +*/ + + +/** @page flashcfi OpenOCD CFI Flash API + +This section needs to be expanded to describe OpenOCD's CFI Flash API. + +*/ + +/** @page flashnand OpenOCD NAND Flash API + +This section needs to be expanded to describe OpenOCD's NAND Flash API. + +*/ + +/** @page flashtarget OpenOCD Target Flash API + +This section needs to be expanded to describe OpenOCD's Target Flash API. + +*/ diff --git a/debuggers/openocd/doc/manual/helper.txt b/debuggers/openocd/doc/manual/helper.txt new file mode 100644 index 00000000..aa52355f --- /dev/null +++ b/debuggers/openocd/doc/manual/helper.txt @@ -0,0 +1,136 @@ +/** @page helperdocs OpenOCD Helper APIs + +OpenOCD uses several low-level APIs as the foundation for high-level APIs: + + - @subpage helperporting + - @subpage helperjim + - @subpage helpercommand + - @subpage helperlogging + - @subpage helperbuffers + +This section needs to be expanded. + + */ + +/** @page helperporting OpenOCD Types/Portability APIs + +This section needs to be expanded to describe OpenOCD's type and +portability API. + + */ + +/** @page helperjim OpenOCD Jim API + +The Jim API provides access to a small-footprint TCL implementation. + +Visit http://jim.berlios.de/ for more information on Jim. + +This section needs to be expanded to describe OpenOCD's Jim API. + + */ + +/** @page helpercommand OpenOCD Command API + +OpenOCD's command API allows modules to register callbacks that are then +available to the scripting services. It provides the mechanism for +these commands to be dispatched to the modlue using a standard +interfaces. It provides macros for defining functions that use and +extend this interface. + +@section helpercmdhandler Command Handlers + +Command handlers are functions with a particular signature, which can +be extended by modules for passing additional parameters to helpers or +another layer of handlers. + +@subsection helpercmdhandlerdef Defining and Calling Command Handlers + +These functions should be defined using the @c COMMAND_HANDLER macro. +These methods must be defined as static, as their principle entry point +should be the run_command dispatch mechanism. + +Command helper functions that require access to the full set of +parameters should be defined using the @c COMMAND_HELPER. These must be +declared static by you, as sometimes you might want to share a helper +among several files (e.g. @c s3c24xx_nand.h). + +Both types of routines must be called using the @c CALL_COMMAND_HANDLER macro. +Calls using this macro to normal handlers require the name of the command +handler (which can a name or function pointer). Calls to helpers and +derived handlers must pass those extra parameters specified by their +definitions; however, lexical capture is used for the core parameters. +This dirty trick is being used as a stop-gap measure while the API is +migrated to one that passes a pointer to a structure containing the +same ingredients. At that point, this macro will be removed and callers +will be able to use direct invocations. + +Thus, the following macros can be used to define and call command +handlers or helpers: + +- @c COMMAND_HANDLER - declare or define a command handler. +- @c COMMAND_HELPER - declare or define a derived command handler or helper. +- @c CALL_COMMAND_COMMAND - call a command handler/helper. + +@subsection helpercmdhandlermacros Command Handler Macros + +In addition, the following macros may be used in the context of +command handlers and helpers: +- @c CMD_CTX - the current @c command_context +- @c CMD_NAME - invoked command name +- @c CMD_ARGC - the number of command arguments +- @c CMD_ARGV - array of command argument strings + +@section helpercmdregister Command Registration + +In order to use a command handler, it must be registered with the +command subsystem. All commands are registered with command_registration +structures, specifying the name of the command, its handler, its allowed +mode(s) of execution, and strings that provide usage and help text. +A single handler may be registered using multiple names, but any name +may have only one handler associated with it. + +The @c register_commands() and @c register_commands() functions provide +registration, while the @c unregister_command() and +@c unregister_all_commands() functions will remove existing commands. +These may be called at any time, allowing the command set to change in +response to system actions. + +@subsection helpercmdjim Jim Command Registration + +The command_registration structure provides support for registering +native Jim command handlers (@c jim_handler) too. For these handlers, +the module can provide help and usage support; however, this mechanism +allows Jim handlers to be called as sub-commands of other commands. +These commands may be registered with a private data value (@c +jim_handler_data) that will be available when called, as with low-level +Jim command registration. + +A command may have a normal @c handler or a @c jim_handler, but not both. + +@subsection helpercmdregisterchains Command Chaining + +When using register_commands(), the array of commands may reference +other arrays. When the @c chain field is filled in a +command_registration record, the commands on in the chained list will +added in one of two places. If the record defines a new command, then +the chained commands are added under it; otherwise, the commands are +added in the same context as the other commands in the array. + +@section helpercmdprimer Command Development Primer + +This @ref primercommand provides details about the @c hello module, +showing how the pieces desrcribed on this page fit together. + + */ + +/** @page helperlogging OpenOCD Logging API + +This section needs to be expanded to describe OpenOCD's Logging API. + + */ + +/** @page helperbuffers OpenOCD Byte Buffer API + +This section needs to be expanded to describe OpenOCD's Byte Buffer API. + + */ diff --git a/debuggers/openocd/doc/manual/jtag.txt b/debuggers/openocd/doc/manual/jtag.txt new file mode 100644 index 00000000..8f0804ce --- /dev/null +++ b/debuggers/openocd/doc/manual/jtag.txt @@ -0,0 +1,73 @@ +/** @page jtagdocs JTAG APIs + +For new developers unfamiliar with the technology, @ref primerjtag provides +a brief introduction to the IEEE JTAG interface. + +The OpenOCD JTAG library API covers several functional areas. The jtag +@b core communicates through the @b minidriver API with either its full +@a driver implementation (src/jtag/jtag_driver.c) or a @a minidriver . +Internally, the @b command API is used by the JTAG driver for managing +asynchronous transactions. + +- @subpage jtagcore + - @b public API routines + - declared in @c src/jtag/jtag.h + - used by other modules + +- @subpage jtagtcl + - @b private TCL handling routines + - defined in @c src/jtag/tcl.c + - registers and handles Jim commands that configure and use the JTAG core + +- @subpage jtagcmd + - @b private command queue API + - declared in @c src/jtag/commands.h + - provides routines used internally by the full JTAG drivers. + +- @subpage jtagiface + - @b private interface driver API + - declared in @c src/jtag/interface.h + - used by the core, minidrivers, and the full interface device drivers. + - allows implementing new interface device drivers. + - includes the Cable/TAP API (commands starting with @c tap_) + +- @subpage jtagdriver + - @b private minidriver API + - declared in @c src/jtag/minidriver.h + - used @a only by the core and minidriver implementations: + - @c jtag_driver.c (in-tree OpenOCD drivers) + - @c zy1000/build/include/jtag_minidriver.h (ZY1000 minidriver) + - future implementations (on other embedded hosts) + - interface device drivers do @b not need this API. + + */ + +/** @page jtagcore JTAG Core API + +This section needs to be expanded. + + */ + +/** @page jtagtcl JTAG TCL API + +This section needs to be expanded. + + */ + +/** @page jtagcmd JTAG Command API + +This section needs to be expanded. + + */ + +/** @page jtagiface JTAG Interface API + +This section needs to be expanded. + + */ + +/** @page jtagdriver JTAG Minidriver API + +This section needs to be expanded. + + */ diff --git a/debuggers/openocd/doc/manual/main.txt b/debuggers/openocd/doc/manual/main.txt new file mode 100644 index 00000000..c14096b5 --- /dev/null +++ b/debuggers/openocd/doc/manual/main.txt @@ -0,0 +1,105 @@ +/** @mainpage OpenOCD Developer's Guide + +Welcome to the OpenOCD Developer's Guide -- the developer's resource for +learning about the internal architecture of the OpenOCD project. @par + +In addition, this document contains the tactical and strategic plans +and processes that have been developed by and for the OpenOCD community. + +Developers that want to contribute to OpenOCD should read the following +sections before starting work: + +- The List of @subpage thelist enumerates opportunities for improving or +extending the OpenOCD platform. If your ideas are on The List, you might +check the mailing list archives to find the status of your feature (or bug). +- The @subpage styleguide provides rules that developers should + follow when writing new code for OpenOCD. +- The @subpage patchguide provides policies that developers should + follow when submitting patches to the project. +- The @subpage bugs page contains the content of the BUGS file, which + provides instructions for submitting bug reports to the maintainers. +- The @subpage releases page describes the project's release process. + +@ref primer provide introductory materials for new developers on various +specific topics. + +Finally, the @ref oocd pages explain how the code has been organized +into layers of APIs, providing an overview of how they fit together. +These pages attempt to give developers a high-level perspective of the +various code modules provided by OpenOCD. + + */ + +/** @page primer OpenOCD Technical Primers + +This pages lists Technical Primers available for OpenOCD Developers. +They seek to provide information to pull novices up the learning curves +associated with the fundamental technologies used by OpenOCD. + +- @subpage primerdocs +- @subpage primerautotools +- @subpage primertcl +- @subpage primerjtag + +The above documents should bridge any "ancillary" gaps in contributor +knowledge, without having to learn the complete languages or technology. +They should provide enough information for experienced developers to +learn how to make "correct" changes when creating patches. + +Beyond the fundamentals, the following primers provide introductory +tutorials for OpenOCD's sub-systems. These complement the @ref oocd +pages that provide more high-level perspective on related topics. + +- @subpage primercommand + +In all cases, these Primers should use idiomatic conventions that the +community has agreed are the "right way of doing things". In this +respect, these documents typically assume some familiarity with the +information contained in one or more @ref styleguide, or they will +directly refer to specific style guides as supplemental reading. + +Contributions or suggestions for new Technical Primers are welcome. + + */ + +/** @page oocd OpenOCD Architecture + +The OpenOCD library consists of several APIs that build together to +provide the support functionality. The following list shows how these +modules are stacked in the current implementation (from bottom to top): + +- @subpage helperdocs + - @ref helperporting + - @ref helperjim + - @ref helpercommand + - @ref helperlogging +- @subpage jtagdocs + - @ref jtagcore + - @ref jtagtcl + - @ref jtagcmd + - @ref jtagiface + - @ref jtagdriver +- @subpage targetdocs + - @ref targetarm + - @ref targetnotarm + - @ref targetmips + - @ref targetregister + - @ref targetimage + - @ref targettrace +- @subpage flashdocs + - @ref flashcfi + - @ref flashnand + - @ref flashtarget +- @subpage serverdocs + - @ref servergdb + - @ref servertelnet + - @ref serverhttp +- @subpage appdocs + +Obviously, there are some nuances to the stack that are not shown by +this linear list of layers. + +The List of @ref thelist enumerates opportunities for improving or +extending the OpenOCD platform. + + */ diff --git a/debuggers/openocd/doc/manual/primer/autotools.txt b/debuggers/openocd/doc/manual/primer/autotools.txt new file mode 100644 index 00000000..28a4b5f6 --- /dev/null +++ b/debuggers/openocd/doc/manual/primer/autotools.txt @@ -0,0 +1,167 @@ +/** @page primerautotools OpenOCD Autotools Primer + +This page provides an overview to OpenOCD's use of the GNU autotool suite: +- @ref primerautoconf +- @ref primerautomake +- @ref primerlibtool + +Most developers do not need to concern themselves with these tools, as +the @ref primerbootstrap script runs these tools in the required sequence. + +@section primerbootstrap Autotools Bootstrap + +The @c bootstrap script should be used by developers to run the +autotools in the correct sequence. + +When run after a fresh checkout, this script generates the build files +required to compile the project, producing the project configure script. +After running @c configure, the @ref primermaintainermode settings will +handle most situations that require running these tools again. In some +cases, a fresh bootstrap may be still required. + +@subsection primerbootstrapcures Problems Solved By Bootstrap + +For example, the build system can fail in unexpected ways after running +git pull. Here, the make maintainer-clean +should be used to remove all of the files generated by the @c bootstrap +script and subsequent build processes. + +In this particular case, one may also need to remove stray files by hand +after running this command to ensure everything is rebuilt properly. +This step should be necessary only if the @c maintainer-clean was run +@b after altering the build system files with git. If it is run +@b before any updates, the build system should never leave artifacts +in the tree. + +Without such precautions, changes can be introduced that leave the tree +timestamps in an inconsistent state, producing strange compile errors +that are resolve after such diligence. + +@subsection primermaintainerclean Autotools Cleaning + +Normally, all files generated by the bootstrap script, configure +process, and build system should be removed after running make +maintainer-clean. Automatically generated files that remain +after this should be listed in @c MAINTAINERCLEANFILES, +@c DISTCLEANFILES, or @c CLEANFILES, depending on which stage of the +build process they are produced. + +@section primerautoconf Autoconf Configuration Script + +The @c autoconf program generates the @c configure script from +@c configure.in, using serious Perl voodoo. The resulting script is +included in the project distribution packages and run by users to +configure the build process for their system. + +@subsection primermaintainermode Maintainer Mode + +After a fresh checkout, @c bootstrap, and a simple @c configure, you may +experience errors when running @c make that some files cannot be found +(e.g. @c version.texi), and a second @c make will "mysteriously" solve +the problems. The isssue is well-known and expected, if unfortunate. + +The OpenOCD project requires that all developers building from the +git repository use the @c --enable-maintainer-mode option when +running the @c configure script. This option ensures that certain files +are created during the build process that would normally be packaged in +the distribution tarball. The @c bootstrap script will remind you of +this requirement when it runs. + +In addition to solving these problems, this option enables Makefile +rules (provided by automake) that allow the normal @c make process to +rebuild the autotools outputs, included the automake-generated Makefiles +themselves. This avoids the heavy-handed approach of running the +@c bootstrap script after changing one of these files. + +@section primerautomake Automake Makefiles + +The @c automake program generates @c Makefile.in files (from @c +Makefile.am files). These files are later processed by the configure +script produced by @c autoconf. + +@subsection primerautomakenewfiles Creating Makefile.am Files + +This section shows how to add a @c Makefile.am in a new directory (or +one that lacks one). +-# The new directory must be listed in the @c SUBDIRS variable in the +parent directory's Makefile.am: +@code +$ echo 'SUBDIRS += directory' >>../Makefile.am +@endcode +-# Create an bare-bones Makefile.am file in directory that needs it: +@code +$ echo "MAINTAINERCLEANFILES = Makefile.in" >Makefile.am +@endcode +-# The @c configure.in script must be updated, so it generates the required +Makefile when the @a configure script is run by the user: +@verbatim +AC_OUTPUT([ + ... + path/to/new/Makefile + ]) +@endverbatim + +Note: these instructions are @b not meant to be used literally, rather +they are shown for demonstration purposes. + +The default MAINTAINERCLEANFILES rule ensures that the +automake-generated @c Makefile.in file will be removed when developers +run make maintainer-clean. Additional rules may be added +after this; however, the project should bootstrap and tear down cleanly +after taking these minimal steps, with the new directory being visited +during the @c make sequence. + +@subsection primerautomaketweaks Updating Makefile.am Files + +Adding, removing, and renaming files from the project tree usually +requires updating the autotools inputs. This section will help describe +how to do this as questions arise. + +@section primerlibtool Libtool and Libraries + +The @c libtool program provides the means of generating libraries in a +portable and painless manner (relatively speaking). + +This section will contain an answer to "what does libtool give OpenOCD?" +and "what do developers need to consider in new code?" + +@section primerautotoolsmation Autotools Automation + +This section outlines three ways the autotools provides automation to +assist with testing and distribution: +- @ref primerautocheck -- automatic unit and smoke tests +- @ref primerautodistcheck -- automatic distribution and packaging tests + +@subsection primerautocheck make check + +The make check command will run the OpenOCD test suite, +once it has been integrated as such. This section will contain +information about how to extend the testing build system components to +implement new checks. + +@subsection primerautodistcheck make distcheck + +The make distcheck command produces an archive of the +project deliverables (using make dist) and verifies its +integrity for distribution by attemptng to use the package in the same +manner as a user. + +These checks includes the following steps: +-# Unpack the project archive into its expected directory. +-# Configure and build the project in a temporary out-of-tree directory. +-# Run make check to ensure the distributed code passes all tests. +-# Run make install into a temporary installation directory. +-# Check that make uninstall removes all files that were installed. +-# Check that make distclean removes all files created +during all other steps (except the first). + +If all of these steps complete successfully, the @c make process will +output a friendly message indicating the archive is ready to be +distributed. + + */ +/** @file + +This file contains the @ref primerautotools page. + + */ diff --git a/debuggers/openocd/doc/manual/primer/commands.txt b/debuggers/openocd/doc/manual/primer/commands.txt new file mode 100644 index 00000000..5f89d506 --- /dev/null +++ b/debuggers/openocd/doc/manual/primer/commands.txt @@ -0,0 +1,138 @@ +/** @page primercommand Command Development Primer + +This page provides a primer for writing commands by introducing @c hello +module. The full source code used in this example can be found in +hello.c, and the @ref primercmdcode section shows how to use it. + +A summary of this information can be found in @ref helpercommand . + +@section primercmdhandler Command Handlers + +Defining new commands and their helpers is easy. The following code +defines a simple command handler that delegates its argument parsing: +@code +COMMAND_HANDLER(handle_hello_command) +{ + const char *sep, *name; + int retval = CALL_COMMAND_HANDLER(handle_hello_args); + if (ERROR_OK == retval) + command_print(CMD_CTX, "Greetings%s%s!", sep, name); + return retval; +} +@endcode + +Here, the @c COMMAND_HANDLER macro establishes the function signature, +see in command.h by the @c __COMMAND_HANDLER macro. + +The COMMAND_HELPER macro function allows defining functions with an +extended version of the base signature. These helper functions can be +called (with the appropriate parameters), the @c CALL_COMMAND_HANDLER +macro to pass any e as parameters to the following helper function: + +The subsequent blocks of code are a normal C function that can do +anything, so only complex commands deserve should use comamnd helper +functions. In this respect, this example uses one to demonstrate how -- +not when -- they should be used. + +@code +static COMMAND_HELPER(handle_hello_args, const char **sep, const char **name) +{ + if (argc > 1) + { + LOG_ERROR("%s: too many arguments", CMD_NAME); + return ERROR_COMMAND_SYNTAX_ERROR; + } + if (1 == CMD_ARGC) + { + *sep = ", "; + *name = CMD_ARGV[0]; + } + else + *sep = *name = ""; + + return ERROR_OK; +} +@endcode + +Of course, you may also call other macros or functions, but that extends +beyond the scope of this tutorial on writing commands. + +@section primercmdreg Command Registration + +Before this new function can be used, it must be registered somehow. +For a new module, registering should be done in a new function for +the purpose, which must be called from @c openocd.c: +@code + +static const struct command_registration hello_command_handlers[] = { + { + .name = "hello", + .mode = COMMAND_ANY, + .handler = handle_hello_command, + .help = "print a warm greeting", + .usage = "[name]", + }, + { + .chain = foo_command_handlers, + } + COMMAND_REGISTRATION_DONE +}; + +int hello_register_commands(struct command_context_s *cmd_ctx) +{ + return register_commands(cmd_ctx, NULL, handle_command_handlers); +} +@endcode + +Note that the "usage" text should use the same EBNF that's found +in the User's Guide: literals in 'single quotes', sequences of +optional parameters in [square brackets], and alternatives in +(parentheses|with|vertical bars), and so forth. No angle brackets. + +That's it! The command should now be registered and available to scripts. + +@section primercmdchain Command Chaining + +This example also shows how to chain command handler registration, so +your modules can "inherit" commands provided by other (sub)modules. +Here, the hello module includes the foo commands in the same context +that the 'hello' command will be registered. + +If the @c chain field had been put in the 'hello' command, then the +@c foo module commands would be registered under it. Indeed, that +technique is used to define the 'foo bar' and 'foo baz' commands, +as well as for the example drivers that use these modules. + +The code for the 'foo' command handlers can be found in @c hello.c. + +@section primercmdcode Trying These Example Commands + +These commands have been inherited by the dummy interface, faux flash, +and testee target drivers. The easiest way to test these is by using the +dummy interface. + +Once OpenOCD has been built with this example code, the following command +demonstrates the abilities that the @c hello module provides: +@code +openocd -c 'interface dummy' \ + -c 'dummy hello' \ + -c 'dummy hello World' \ + -c 'dummy hello {John Doe}' \ + -c 'dummy hello John Doe' # error: too many arguments +@endcode + +If saved in @c hello.cfg, then running openocd -f hello.cfg +should produce the following output before displaying the help text and +exiting: +@code +Greetings! +Greetings, World! +Greetings, John Doe! +Error: hello: too many arguments +Runtime error, file "openocd.cfg", line 14: + hello: too many arguments +dummy hello [] + prints a warm welcome +@endcode + + */ diff --git a/debuggers/openocd/doc/manual/primer/docs.txt b/debuggers/openocd/doc/manual/primer/docs.txt new file mode 100644 index 00000000..504da790 --- /dev/null +++ b/debuggers/openocd/doc/manual/primer/docs.txt @@ -0,0 +1,124 @@ +/** @page primerdocs OpenOCD Documentation Primers + +This page provides an introduction to OpenOCD's documentation processes. + +OpenOCD presently produces several kinds of documentation: +- The User's Guide: + - Focuses on using the OpenOCD software. + - Details the installation, usage, and customization. + - Provides descriptions of public Jim/TCL script commands. + - Written using GNU texinfo. + - Created with 'make pdf' or 'make html'. + - See @subpage primertexinfo and @ref styletexinfo. +- The References: (as proposed) + - Focuses on using specific hardware with OpenOCD. + - Details the supported interfaces, chips, boards, and targets. + - Provides overview, usage, reference, and FAQ for each device. + - Written using LaTeX language with custom macros. + - Created with 'make references'. + - See @subpage primerlatex and @ref stylelatex. +- The Manual: + - Focuses on developing the OpenOCD software. + - Details the architecutre, driver interfaces, and processes. + - Provides "full" coverage of C source code (work-in-progress). + - Written using Doxygen C language conventions (i.e. in comments). + - Created with 'make doxygen'. + - See @subpage primerdoxygen and @ref styledoxygen. + +The following sections provide more information for anyone that wants to +contribute new or updated documentation to the OpenOCD project. + + */ +/** @page primertexinfo Texinfo Primer + +The OpenOCD User's Guide presently exists entirely within the +doc/openocd.texi document. That file contains documentation with +mark-up suitable for being parsed by the GNU Texinfo utilities +(http://www.gnu.org/software/texinfo/). + +When you add a new command, driver, or driver option, it needs to be +documented in the User's Guide. Use the existing documentation for +models, but feel free to make better use of Texinfo mechanisms. See +the Texinfo web site for the Texinfo manual and more information. + +OpenOCD style guidelines for Texinfo documentation can be found on the +@ref styletexinfo page. + + */ +/** @page primerlatex LaTeX Primer + +The OpenOCD project provides a number of reference guides using the +LaTeX typesetting language. + +- OpenOCD Quick Reference Sheets +- OpenOCD Hardware Reference Guides + +These documents have not yet been produced, so this Primer serves as +a placeholder to describe how they are created and can be extended. +The same holds true for the @ref stylelatex page. + + */ +/** @page primerdoxygen Doxygen Primer + +Doxygen-style comments are used to provide documentation in-line with +the OpenOCD source code. These comments are used to document functions, +variables, structs, enums, fields, and everything else that might need +to be documented for developers. Additional files containing comments +that supplement the code comments in order to provide complete developer +documentation. + +Even if you already know Doxygen, please read this Primer to learn +how OpenOCD developers already use Doxygen features in the project tree. +For more information about OpenOCD's required style for using Doxygen, +see the @ref styledoxygen page and look at existing documentation in the +@c doc/manual tree. + +@section primerdoxytext Doxygen Input Files + +Doxygen has been configured parse all of the C source code files (*.c +and *.h) in @c src/ in order to produce a complete reference of all +OpenOCD project symbols. In addition to the source code files, other +files will also be scanned for comment blocks; some are referenced +explicitly by the @c INPUT variable in the Doxygen configuration file. + +By default, the Doxygen configuration enables a "full" set of features, +including generation of dependency graphs (using the GraphViz package). +These features may be disabled by editing the @c Doxyfile.in file at the +top of the project tree; the configuration file includes comments that +provide detailed documentation for each option. + +To support out-of-tree building of the documentation, the @c Doxyfile.in +@c INPUT values will have all instances of the string @c "@srcdir@" +replaced with the current value of the make variable +$(srcdir). The Makefile uses a rule to convert +@c Doxyfile.in into the @c Doxyfile used by make doxygen. + +@section primerdoxyoocd OpenOCD Input Files + +OpenOCD uses the @c INPUT mechanism to include additional documentation to +provide The Manual for OpenOCD Developers. These extra files contain +high-level information intended to supplement the relatively low-level +documentation that gets extracted from the source code comments. + +OpenOCD's Doxygen configuration file will search for all @c .txt files +that can be found under the @c doc/manual directory in the project tree. +New files containing valid Doxygen markup that are placed in or under +that directory will be detected and included in The Manual automatically. + +@section primerdoxyman Doxygen Reference Manual + +The full documentation for Doxygen can be referenced on-line at the project +home page: http://www.doxygen.org/index.html. In HTML versions of this +document, an image with a link to this site appears in the page footer. + +*/ +/** @file + +This file contains the Doxygen source code for the @ref primerdocs. +The @ref primerdocs page also contains the following sections: + +- @ref primertexinfo +- @ref primerlatex +- @ref primerdoxygen + + */ diff --git a/debuggers/openocd/doc/manual/primer/jtag.txt b/debuggers/openocd/doc/manual/primer/jtag.txt new file mode 100644 index 00000000..997f53bf --- /dev/null +++ b/debuggers/openocd/doc/manual/primer/jtag.txt @@ -0,0 +1,170 @@ +/** @page primerjtag OpenOCD JTAG Primer + +JTAG is unnecessarily confusing, because JTAG is often confused with +boundary scan, which is just one of its possible functions. + +JTAG is simply a communication interface designed to allow communication +to functions contained on devices, for the designed purposes of +initialisation, programming, testing, debugging, and anything else you +want to use it for (as a chip designer). + +Think of JTAG as I2C for testing. It doesn't define what it can do, +just a logical interface that allows a uniform channel for communication. + +See @par + http://en.wikipedia.org/wiki/Joint_Test_Action_Group + +and @par + http://www.inaccessnetworks.com/projects/ianjtag/jtag-intro/jtag-state-machine-large.png + +The first page (among other things) shows a logical representation +describing how multiple devices are wired up using JTAG. JTAG does not +specify, data rates or interface levels (3.3V/1.8V, etc) each device can +support different data rates/interface logic levels. How to wire them +in a compatible way is an exercise for an engineer. + +Basically TMS controls which shift register is placed on the device, +between TDI and TDO. The second diagram shows the state transitions on +TMS which will select different shift registers. + +The first thing you need to do is reset the state machine, because when +you connect to a chip you do not know what state the controller is in,you need +to clock TMS as 1, at least 5 times. This will put you into "Test Logic +Reset" State. Knowing this, you can, once reset, then track what each +transition on TMS will do, and hence know what state the JTAG state +machine is in. + +There are 2 "types" of shift registers. The Instruction shift register +and the data shift register. The sizes of these are undefined, and can +change from chip to chip. The Instruction register is used to select +which Data register/data register function is used, and the data +register is used to read data from that function or write data to it. + +Each of the states control what happens to either the data register or +instruction register. + +For example, one of the data registers will be known as "bypass" this is +(usually) a single bit which has no function and is used to bypass the +chip. Assume we have 3 identical chips, wired up like the picture(wikipedia) +and each has a 3 bits instruction register, and there are 2 known +instructions (110 = bypass, 010 = "some other function") if we want to use +"some other function", on the second chip in the line, and not change +the other chips we would do the following transitions. + +From Test Logic Reset, TMS goes: + + 0 1 1 0 0 + +which puts every chip in the chain into the "Shift IR state" +Then (while holding TMS as 0) TDI goes: + + 0 1 1 0 1 0 0 1 1 + +which puts the following values in the instruction shift register for +each chip [110] [010] [110] + +The order is reversed, because we shift out the least significant bit +first. Then we transition TMS: + + 1 1 1 0 0 + +which puts us in the "Shift DR state". + +Now when we clock data onto TDI (again while holding TMS to 0) , the +data shifts through the data registers, and because of the instruction +registers we selected ("some other function" has 8 bits in its data +register), our total data register in the chain looks like this: + + 0 00000000 0 + +The first and last bit are in the "bypassed" chips, so values read from +them are irrelevant and data written to them is ignored. But we need to +write bits for those registers, because they are in the chain. + +If we wanted to write 0xF5 to the data register we would clock out of +TDI (holding TMS to 0): + + 0 1 0 1 0 1 1 1 1 0 + +Again, we are clocking the least-significant bit first. Then we would +clock TMS: + + 1 1 0 + +which updates the selected data register with the value 0xF5 and returns +us to run test idle. + +If we needed to read the data register before over-writing it with F5, +no sweat, that's already done, because the TDI/TDO are set up as a +circular shift register, so if you write enough bits to fill the shift +register, you will receive the "captured" contents of the data registers +simultaneously on TDO. + +That's JTAG in a nutshell. On top of this, you need to get specs for +target chips and work out what the various instruction registers/data +registers do, so you can actually do something useful. That's where it +gets interesting. But in and of itself, JTAG is actually very simple. + +@section primerjtag More Reading + +A separate primer contains information about @subpage primerjtagbs for +developers that want to extend OpenOCD for such purposes. + + */ +/** @page primerjtagbs JTAG Boundary Scan Primer + +The following page provides an introduction on JTAG that focuses on its +boundary scan capabilities: @par +http://www.engr.udayton.edu/faculty/jloomis/ece446/notes/jtag/jtag1.html + +OpenOCD does not presently have clear means of using JTAG for boundary +scan testing purposes; however, some developers have explored the +possibilities. The page contains information that may be useful to +those wishing to implement boundary scan capabilities in OpenOCD. + +@section primerbsdl The BSDL Language + +For more information on the Boundary Scan Description Language (BSDL), +the following page provides a good introduction: @par +http://www.radio-electronics.com/info/t_and_m/boundaryscan/bsdl.php + +@section primerbsdlvendors Vendor BSDL Files + +NXP LPC: @par +http://www.standardics.nxp.com/support/models/lpc2000/ + +Freescale PowerPC: @par +http://www.freescale.com/webapp/sps/site/overview.jsp?code=DRPPCBSDLFLS + +Freescale i.MX1 (too old): @par +http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=i.MX1&nodeId=0162468rH311432973ZrDR&fpsp=1&tab=Design_Tools_Tab + +Renesas R32C/117: @par +http://sg.renesas.com/fmwk.jsp?cnt=r32c116_7_8_root.jsp&fp=/products/mpumcu/m16c_family/r32c100_series/r32c116_7_8_group/ +- The device page does not come with BSDL file; you have to register to + download them. @par + http://www.corelis.com/support/BSDL.htm + +TI links theirs right off the generic page for each chip; +this may be the case for other vendors as well. For example: + +- DaVinci DM355 -- http://www.ti.com/litv/zip/sprm262b +- DaVinci DM6446 + - 2.1 silicon -- http://www.ti.com/litv/zip/sprm325a + - older silicon -- http://www.ti.com/litv/zip/sprm203 +- OMAP 3530 + - CBB package -- http://www.ti.com/litv/zip/sprm315b + - 515 ball s-PGBA, POP, 0.4mm pitch + - CUS package -- http://www.ti.com/litv/zip/sprm314a + - 515 ball s-PGBA, POP, 0.5mm pitch + - CBC package -- http://www.ti.com/litv/zip/sprm346 + - 423 ball s-PGBA, 0.65mm pitch + +Many other files are available in the "Semiconductor Manufacturer's BSDL +files" section of the following site: @par +http://www.freelabs.com/~whitis/electronics/jtag/ + + */ +/** @file +This file contains the @ref primerjtag and @ref primerjtagbs page. + */ diff --git a/debuggers/openocd/doc/manual/primer/tcl.txt b/debuggers/openocd/doc/manual/primer/tcl.txt new file mode 100644 index 00000000..9be4a05e --- /dev/null +++ b/debuggers/openocd/doc/manual/primer/tcl.txt @@ -0,0 +1,440 @@ +/** @page primertcl OpenOCD TCL Primer + +The @subpage scripting page provides additional TCL Primer material. + +@verbatim + +**************************************** +**************************************** + +This is a short introduction to 'un-scare' you about the language +known as TCL. It is structured as a guided tour through the files +written by me [Duane Ellis] - in early July 2008 for OpenOCD. + +Which uses the "JIM" embedded Tcl clone-ish language. + +Thing described here are *totally* TCL generic... not Jim specific. + +The goal of this document is to encourage you to add your own set of +chips to the TCL package - and most importantly you should know where +you should put them - so they end up in an organized way. + +--Duane Ellis. + duane@duaneellis.com + +**************************************** +**************************************** + +Adding "chip" support - Duane Ellis July 5 - 2008. + +The concept is this: + In your "openocd.cfg" file add something like this: + + source [find tcl/chip/VENDOR/FAMILY/NAME.tcl] + + For example... + source [find tcl/chip/atmel/at91/at91sam7x256.tcl] + + You'll notice that it makes use of: + + tcl/cpu/arm/.tcl. + + Yes, that is where you should put "core" specific things. + Be careful and learn the difference: + + THE "CORE" - is not the entire chip! + +Definition: + That "file" listed above is called a "CHIP FILE". + + It may be standalone, or may need to "source" other "helper" files. + + The reference [7/5/2008] is the at91sam7x256.tcl file. + +**************************************** +**************************************** +=== TCL TOUR === +Open: at91sam7x256.tcl +=== TCL TOUR === + +A walk through --- For those who are new to TCL. + +Examine the file: at91sam7x256.tcl + +It starts with: + source [find path/filename.tcl] + +In TCL - this is very important. + + Rule #1 Everything is a string. + Rule #2 If you think other wise See #1. +Reminds you of: + Rule #1: The wife is correct. + Rule #2: If you think otherwise, See #1 + +Any text contained inside of [square-brackets] +is just like `back-ticks` in BASH. + +Hence, the [find FILENAME] executes the command find with a single +parameter the filename. + +======================================== + +Next you see a series of: + +set NAME VALUE + +It is mostly "obvious" what is going on. + +Exception: The arrays. + + You would *THINK* Tcl supports arrays. + In fact, multi-dim arrays. That is false. + + For the index for"FLASH(0,CHIPSELECT)" is actually the string + "0,CHIPSELECT". This is problematic. In the normal world, you think + of array indexes as integers. + + For example these are different: + + set foo(0x0c) 123 + set foo(12) 444 + + Why? Because 0x0c {lowercase} is a string. + Don't forget UPPER CASE. + + You must be careful - always... always... use simple decimal + numbers. When in doubt use 'expr' the evaluator. These are all the + same. + + set x 0x0c + set foo([expr $x]) "twelve" + + set x 12 + set foo([expr $x]) "twelve" + + set x "2 * 6" + set foo([expr $x]) "twelve" + +************************************************** +*************************************************** +=== TCL TOUR === +Open the file: "bitsbytes.tcl" + +There is some tricky things going on. +=============== + +First, there is a "for" loop - at level 0 +{level 0 means: out side of a proc/function} + +This means it is evaluated when the file is parsed. + +== SIDEBAR: About The FOR command == +In TCL, "FOR" is a funny thing, it is not what you think it is. + +Syntactically - FOR is a just a command, it is not language +construct like for(;;) in C... + +The "for" command takes 4 parameters. + (1) The "initial command" to execute. + (2) the test "expression" + (3) the "next command" + (4) the "body command" of the FOR loop. + +Notice I used the words "command" and "expression" above. + +The FOR command: +1) executes the "initial command" +2) evaluates the expression if 0 it stops. +3) executes the "body command" +4) executes the "next command" +5) Goto Step 2. + +As show, each of these items are in {curly-braces}. This means they +are passed as they are - KEY-POINT: un evaluated to the FOR +command. Think of it like escaping the backticks in Bash so that the +"under-lying" command can evaluate the contents. In this case, the FOR +COMMAND. + +== END: SIDEBAR: About The FOR command == + +You'll see two lines: + +LINE1: + set vn [format "BIT%d" $x] + +Format is like "sprintf". Because of the [brackets], it becomes what +you think. But here's how: + +First - the line is parsed - for {braces}. In this case, there are +none. The, the parser looks for [brackets] and finds them. The, +parser then evaluates the contents of the [brackets], and replaces +them. It is alot this bash statement. + + EXPORT vn=`date` + +LINE 2 & 3 + set $vn [expr (1024 * $x)] + global $vn + +In line 1, we dynamically created a variable name. Here, we are +assigning it a value. Lastly Line 3 we force the variable to be +global, not "local" the the "for command body" + +=============== +The PROCS + +proc create_mask { MSB LSB } { + ... body .... +} + +Like "for" - PROC is really just a command that takes 3 parameters. +The (1) NAME of the function, a (2) LIST of parameters, and a (3) BODY + +Again, this is at "level 0" so it is a global function. (Yes, TCL +supports local functions, you put them inside of a function} + +You'll see in some cases, I nest [brackets] alot and in others I'm +lazy or wanted it to be more clear... it is a matter of choice. +=============== + + +************************************************** +*************************************************** +=== TCL TOUR === +Open the file: "memory.tcl" +=============== + +Here is where I setup some 'memory definitions' that various targets can use. + +For example - there is an "unknown" memory region. + +All memory regions must have 2 things: + + (1) N_ + (2) NAME( array ) + And the array must have some specific names: + ( , THING ) + Where: THING is one of: + CHIPSELECT + BASE + LEN + HUMAN + TYPE + RWX - the access ability. + WIDTH - the accessible width. + + ie: Some regions of memory are not 'word' + accessible. + +The function "address_info" - given an address should +tell you about the address. + + [as of this writing: 7/5/2008 I have done + only a little bit with this -Duane] + +=== +MAJOR FUNCTION: +== + +proc memread32 { ADDR } +proc memread16 { ADDR } +proc memread8 { ADDR } + +All read memory - and return the contents. + +[ FIXME: 7/5/2008 - I need to create "memwrite" functions] + +************************************************** +*************************************************** +=== TCL TOUR === +Open the file: "mmr_helpers.tcl" +=============== + +This file is used to display and work with "memory mapped registers" + +For example - 'show_mmr32_reg' is given the NAME of the register to +display. The assumption is - the NAME is a global variable holding the +address of that MMR. + +The code does some tricks. The [set [set NAME]] is the TCL way +of doing double variable interpolation - like makefiles... + +In a makefile or shell script you may have seen this: + + FOO_linux = "Penguins rule" + FOO_winXP = "Broken Glass" + FOO_mac = "I like cat names" + + # Pick one + BUILD = linux + #BUILD = winXP + #BUILD = mac + FOO = ${FOO_${BUILD}} + +The "double [set] square bracket" thing is the TCL way, nothing more. + +---- + +The IF statement - and "CATCH" . + +Notice this IF COMMAND - (not statement) is like this: +[7/5/2008 it is this way] + + if ![catch { command } msg ] { + ...something... + } else { + error [format string...] + } + +The "IF" command expects either 2 params, or 4 params. + + === Sidebar: About "commands" === + + Take a look at the internals of "jim.c" + Look for the function: Jim_IfCoreCommand() + And all those other "CoreCommands" + + You'll notice - they all have "argc" and "argv" + + Yea, the entire thing is done that way. + + IF is a command. SO is "FOR" and "WHILE" and "DO" and the + others. That is why I keep using the phase it is a "command" + + === END: Sidebar: About "commands" === + +Parameter 1 to the IF command is expected to be an expression. + +As such, I do not need to wrap it in {braces}. + +In this case, the "expression" is the result of the "CATCH" command. + +CATCH - is an error catcher. + +You give CATCH 1 or 2 parameters. + The first 1st parameter is the "code to execute" + The 2nd (optional) is where to put the error message. + + CATCH returns 0 on success, 1 for failure. + The "![catch command]" is self explaintory. + + +The 3rd parameter to IF must be exactly "else" or "elseif" [I lied +above, the IF command can take many parameters they just have to +be joined by exactly the words "else" or "elseif". + +The 4th parameter contains: + + "error [format STRING....]" + +This lets me modify the previous lower level error by tacking more +text onto the end of it. In this case, i want to add the MMR register +name to make my error message look better. + +--------- +Back to something inside show_mmr32_reg{}. + +You'll see something 'set fn show_${NAME}_helper' Here I am +constructing a 'function name' Then - I look it up to see if it +exists. {the function: "proc_exists" does this} + +And - if it does - I call the function. + +In "C" it is alot like using: 'sprintf()' to construct a function name +string, then using "dlopen()" and "dlsym()" to look it up - and get a +function pointer - and calling the function pointer. + +In this case - I execute a dynamic command. You can do some cool +tricks with interpretors. + +---------- + +Function: show_mmr32_bits() + +In this case, we use the special TCL command "upvar" which tcl's way +of passing things by reference. In this case, we want to reach up into +the callers lexical scope and find the array named "NAMES" + +The rest of the function is pretty straight forward. + +First - we figure out the longest name. +Then print 4 rows of 8bits - with names. + + +************************************************** +*************************************************** +=== TCL TOUR === +Open the file: "chips/atmel/at91/usarts.tcl" +=============== + +First - about the AT91SAM series - all of the usarts +are basically identical... + +Second - there can be many of them. + +In this case - I do some more TCL tricks to dynamically +create functions out of thin air. + +Some assumptions: + +The "CHIP" file has defined some variables in a proper form. + +ie: AT91C_BASE_US0 - for usart0, + AT91C_BASE_US1 - for usart1 + ... And so on ... + +Near the end of the file - look for a large "foreach" loop that +looks like this: + + foreach WHO { US0 US1 US2 US3 US4 .... } { + + } + +In this case, I'm trying to figure out what USARTs exist. + +Step 1 - is to determine if the NAME has been defined. +ie: Does AT91C_BASE_USx - where X is some number exist? + +The "info exists VARNAME" tells you if the variable exists. Then - +inside the IF statement... There is another loop. This loop is the +name of various "sub-registers" within the USART. + +Some more trick are played with the [set VAR] backtick evaluation stuff. +And we create two variables + +We calculate and create the global variable name for every subregister in the USART. +And - declare that variable as GLOBAL so the world can find it. + +Then - we dynamically create a function - based on the register name. + +Look carefully at how that is done. You'll notice the FUNCTION BODY is +a string - not something in {braces}. Why? This is because we need TCL +to evaluate the contents of that string "*NOW*" - when $vn exists not +later, when the function "show_FOO" is invoked. + +Lastly - we build a "str" of commands - and create a single function - +with the generated list of commands for the entire USART. + +With that little bit of code - I now have a bunch of functions like: + + show_US0, show_US1, show_US2, .... etc ... + + And show_US0_MR, show_US0_IMR ... etc... + +And - I have this for every USART... without having to create tons of +boiler plate yucky code. + +**************************************** +**************************************** +END of the Tcl Intro and Walk Through +**************************************** +**************************************** + +FUTURE PLANS + + Some "GPIO" functions... + +@endverbatim + + */ diff --git a/debuggers/openocd/doc/manual/release.txt b/debuggers/openocd/doc/manual/release.txt new file mode 100644 index 00000000..d1447569 --- /dev/null +++ b/debuggers/openocd/doc/manual/release.txt @@ -0,0 +1,465 @@ +/** @page releases Release Processes + +This page provides an introduction to the OpenOCD Release Processes: + +- @ref releasewhy - Explain the motivations for producing + releases on a regular basis. +- @ref releasewho - Describes the responsibilities and + authority required to produce official OpenOCD releases. +- @ref releasewhen - Provides guidelines for scheduling + activities for each release cycle. +- @ref releasehow - Outlines all of the steps for the + processes used to produce and release the package source archives. +- @ref releasescriptcmds - Introduces the automated @c release.sh script. + +@section releasewhy Why Produce Releases? + +The OpenOCD maintainers produce releases periodically for many +reasons. This section provides the key reasons for making releases on a +regular basis and why a set of release processes should be used +to produce them. + +At any time, source archives can be produced by running +make dist in the OpenOCD project tree. With the 0.2.0 +release, this command will package the tree into several popular archive +formats: openocd-\.{tar.gz,tar.bz2,zip}. If +produced properly, these files are suitable for release to the public. + +When properly versioned and released for users, these archives present +several important advantages compared to using the source repository +(including snapshots downloaded from that repository using gitweb): + +-# They allow others to package and distribute the code using + consistent version labels. Users won't normally need to care + whose package they use, just the version of OpenOCD. +-# They contain a working configure script and makefiles, which + were produced as part of creating the archive. +-# Because they have been formally released by the project, users + don't need to try a random work-in-process revision. Releasing + involves spending some time specifically on quality improvments, + including bugfixing source code and documentation. +-# They provide developers with the flexibility needed to address + larger issues, which sometimes involves temporary breakage. + +Hopefully, this shows several good reasons to produce regular releases, +but the release processes were developed with some additional design +goals in mind. Specifically, the releases processes should have the +following properties: + +-# Produce successive sets of archives cleanly and consistently. +-# Implementable as a script that automates the critical steps. +-# Prevent human operators from producing broken packages, when possible. +-# Allow scheduling and automation of building and publishing milestones. + +The current release processes are documented in the following sections. +They attempt to meet these design goals, but improvements may still +need to be made. + +@subsection version_labels Version Labels + +Users can display the OpenOCD version string in at least two +ways. The command line openocd -v invocation +displays it; as does the Tcl version command. + +Labels for released versions look like 0.3.0, or +0.3.0-rc1 for a preliminary release. +Non-released (developer) versions look like 0.3.0-dev, +or 0.3.0-rc1-dev. +In all cases, additional tags may be appended to those base +release version labels. + +The tools/release/version.sh script is used to +manipulate version IDs found in the source tree. + +@subsubsection releaseversions Release Versions and Tags + +The OpenOCD version string is composed of three numeric components +separated by two decimal points: @c x.y.z, where @c x is the @a major +version number, @c y is the @a minor number, and @c z is the @a micro. +For any bug-fix release, the micro version number will be non-zero +(z > 0). For a minor release, the micro version +number will be zero (z = 0). For a major releases, +the minor version will @a also be zero (y = 0, z = 0). + +After these required numeric components, release version strings +may contain tags such as as -rc1 or -rc2. +These 'rc' tags indicate "release candidate" versions of the package. +Like major/minor/micro numbers, these are updated +as part of the release process. + +The release process includes version number manipulations to the tree +being released, ensuring that all numbers are incremented (or rolled +over) at the right time and in the proper locations of the repository. +One of those manipulations creates a repository tag matching that +release's version label. + +@subsubsection releaseversionsdist Packager Versions + +Distributors of patched versions of OpenOCD are encouraged to extend the +version string with a unique version tag when producing external +releases, as this helps to identify your particular distribution series. +Knowing that a release has such patches can be essential to tracking +down and fixing bugs. + +Packager version tags should always be suffixes to the version +code from the OpenOCD project, signifying modifications to the +original code base. Each packager release should have a unique +version. + +For example, the following command will add a 'foo' tag to the +configure.ac script of a local copy of the source tree, giving +a version label like 0.3.0-foo: + +@code +tools/release/version.sh tag add foo +@endcode + +This command will modify the configure.ac script in your working copy +only. After running the @c bootstrap sequence, the tree can be patched +and used to produce your own derived versions. You might check that +change into a private branch of your git tree, along with the other +patches you are providing. + +You can also "bump" those tags (so "foo1" becomes "foo2" etc) +each time a derived package is released, incrementing the tag's +version to facilitate tracking the changes you have distributed. + +@code +tools/release/version.sh bump tag foo +@endcode + +Of course, any patches in your branches must be provided to +your customers, and be in conformance with the GPL. In most +cases you should also work to merge your improvements to the +mainline tree. + +@subsubsection version_tags Development Versions and Tags + +Everything except formal releases should have the tag -dev +in their version number. This helps developers identify reports +created from non-release versions, and it can be detected and +manipulated by the release script. Specifically, this tag will be +removed and re-added during the release process; it should never be +manipulated by developers in submitted patches. + +Versions built from developer trees may have additional tags. +Trees built from git snapshots have snapshot tags. +When built from a "live" git tree, tags specify +specific git revisions: + +0.3.0-rc1-dev-00015-gf37c9b8-dirty + +indicates a development tree based on git revison f37c9b8 +(a truncated version of a SHA1 hash) with some non-git +patches applied (the dirty tag). This information +can be useful when tracking down bugs. +(Note that at this writing, the tags do not directly +correspond to git describe output. The +hash ID can be used with git show, but +the relevant repository tag isn't 0.3.0-rc1-dev; +this might change in the future.) + +@section releasewho Release Manager + +OpenOCD archive releases will be produced by an individual filling the +role of Release Manager, hereafter abbreviated as RM. This +individual determines the schedule and executes the release processes +for the community. + +@subsection releasewhohow RM Authority + +Each release requires one individual to fulfill the RM role; however, +graceful transitions of this authority may take place at any time. The +current RM may transfer their authority to another contributor in a post +to the OpenOCD development mailing list. Such delegation of authority +must be approved by the individual that will receive it and the +community of maintainers. Initial arrangements with the new RM should +be made off-list, as not every contributor wants these responsibilities. + +@subsection releasewhowhat RM Responsibilities + +In addition to the actual process of producing the releases, the RM is +responsible for keeping the community informed of all progress through +the release cycle(s) being managed. The RM is responsible for managing +the changes to the package version, though the release tools should +manage the tasks of adding or removing any required development branch +tags and incrementing the version. + +These responsibilities matter most towards the end of the release +cycle, when the RM creates the first RC and all contributors enter +a quality-improvement mode. The RM works with other contributors +to make sure everyone knows what kinds of fixes should merge, the +status of major issues, and the release timetable. + +In particular, the RM has the final decision on whether a given +bug should block the release. + +@section releasewhen Release Schedule + +The OpenOCD release process must be carried out on a periodic basis, so +the project can realize the benefits presented in answer to the question, +@ref releasewhy. + +Starting with the 0.2.0 release, the OpenOCD project expects to produce +new releases every few months. +Bug fix releases could be provided more frequently. These release +schedule goals may be adjusted in the future, after the project +maintainers and distributors receive feedback and experience. + +More importantly, the statements made in this section do not create an +obligation by any member of the OpenOCD community to produce new +releases on regular schedule, now or in the future. + +@subsection releasewhenexample Sample Schedule + +The RM must pro-actively communicate with the community from the +beginning of the development cycle through the delivery of the new +release. This section presents guidelines for scheduling key points +where the community must be informed of changing conditions. + +If Tn is the time of release n, then the following schedule +might describe some key T0-to-T1 release cycle milestones. + +- T0 ... End of T0 release cycle. T1 cycle starts, with merge + window opening. Developers begin to merge queued work. +- ... several weeks of merge window ... +- RC1 ... Close mainline to new work. Produce RC1 + release, begin testing phase; developers are in "bugfix mode", + all other work is queued; send out planned endgame schedule. +- RC2 ... Produce RC2 and send schedule update to + mailing list, listing priorities for remaining fixes +- ... more RC milestones, until ready ... +- T1: End of T1 release cycle. T2 cycle starts, with merge + window opening. Developers begin to merge queued work. + +Note that until it happens, any date for T1 is just a goal. +Critical bugs prevent releases from happening. We are just +beginning to use this window-plus-RCs process, so the lengths +of the merge windows versus the RC phase is subject to change. +Most projects have RC phases of a month or more. + +Some additional supplemental communication will be desirable. The above +list omits the step-by-step instructions to daily release management. +Individuals performing release management need to have the ability to +interact proactively with the community as a whole, anticipating when +such interaction will be required and giving ample notification. + +The next section explains why the OpenOCD project allows significant +flexibility in the part of the development that precedes the release +process. + +@subsection releasewhenflex Schedule Flexibility + +The Release Manager should attempt to follow the guidelines in this +document, but the process of scheduling each release milestone should be +community driven at the start. Features that don't complete before +the merge window closes can be held (perhaps in some branch) until +the next merge window opens, rather than delaying the release cycle. + +The Release +Manager cannot schedule the work that will be done on the project, +when it will be submitted, reviewed, and deemed suitable to be committed. +That is, the RM cannot act as a priest in a cathedral; OpenOCD uses +the bazaar development model. The release schedule must adapt +continuously in response to changes in the rate of work. +Fewer releases may be +required if developers contribute less patches, and more releases may be +desirable if the project continues to grow and experience high rates of +community contribution. During each cycle, the RM should be tracking +the situation and gathering feedback from the community. + +@section releasehow Release Process: Step-by-Step + +The release process is not final; it may need more iterations +to work out bugs. +While there are release scripts, key steps require community +support; the Release Manager isn't the only participant. + +The following steps should be followed to produce each release: + +-# Produce final patches using a local clone of mainline. Nobody + except the RM should be committing anything. Everyone with commit + privileges needs to know and agree to this in advance! Even the RM + only commits a handful of updates as part of the release process + itself ... to files which are part of the version identification scheme + or release process; and to create the version tag; and then to open the + merge window for the next release cycle. + -# Finalize @c the NEWS file to describe the changes in the release + - This file is used to automatically post "blurbs" about the project. + - This material should have been produced during the development cycle, + by adding items for each @c NEWS-worthy contribution, when committed + during the merge window. (One part of closing the merge window, by + opening the RC phase of the release, is the commitment to hold all + further such contributions until the next merge window opens.) + - The RM should make sure nothing important was omitted, as part of + the RC1 cycle. From then on, no more updates to NEWS content should + be needed (except to seed the process for the next release, or maybe + if a significant and longstanding bug is fixed late in the RC phase). + -# Bump library version if our API changed (not yet required) + -# Update and commit the final package version in @c configure.ac: + (The tools/release/version.sh script might help ensure + the versions are named properly.): + -# Remove @c -dev tag. + -# Update any @c -rc tag: + - If producing the final release from an -rc series, remove it + - If producing the first RC in a series, add rc1 + - If producing the next RC in a series, bump the rc number + -# Commit that version change, with a good descriptive comment. + -# Create a git tag for the final commit, with a tag name matching + the version string in configure.ac (including -rcN + where relevant): +@verbatim +PACKAGE_VERSION="x.y.z" +PACKAGE_TAG="v${PACKAGE_VERSION}" +git tag -m "The openocd-${PACKAGE_VERSION} release." "${PACKAGE_TAG}" +@endverbatim + -# Do not push those changes to mainline yet; only builds using the + source archives you will be creating should ever be labeled as + official releases (with no "-dev" suffix). Since mainline is a + development tree, these will be pushed later, as part of opening + the merge window for the next release cycle (restoring the "-dev" + suffix for that next release.) Those version and tag updates are + the last ones to be included in the release being made. +-# Produce the release files, using the local clone of the source + tree which holds the release's tag and updated version in + @c configure.ac ... this is used only to produce the release, and + all files should already be properly checked out. + -# Run tools/release.sh package to produce the + source archives. This automatically bootstraps and + configures the process. + -# Run tools/release.sh stage to create an @c archives + directory with the release data, including MD5 and SHA1 + checksum files. + -# Sanity check at least one of those archives, by extracting and + configuring its contents, using them to build a copy of OpenOCD, + and verifying that the result prints the correct release version + in its startup banner. (For example, + "configure --enable-ft2232_libftdi --enable-parport" + then "make" and run "src/openocd -v" as a sanity check.) + -# Run make docs to create the + documentation which will be published. +-# Upload packages and post announcements of their availability: + -# Release packages into files section of project sites: + - SF.net: + -# Under "Project Admin", use the "File Manager" + -# Create a new folder under "openocd" named "${PACKAGE_VERSION}" + -# Upload the @c NEWS file and mark it as the release notes. + -# Upload the three source archive files, using the Web interface, + into that folder. Verify the upload worked OK by checking the + MD5 and SHA1 checksums computed by SourceForge against the + versions created as part of staging the release. + -# Also upload doc/openocd.pdf (the User's Guide) so the version + matching each release will be easily available. + -# Select each file in the release, and use the property panel + to set its type and select the right release notes. + - .tar.bz2: Linux, Mac + - .tar.gz: BSD, Solaris, Others + - .zip: Windows + - For openocd.pdf just associate it with the right release notes. + -# Create an SF.net project news update. + -# Depending on how paranoid you're feeling today, verify the images by + downloading them from the websites and making sure there are no + differences between the downloaded copies and your originals. + -# Publish User's and Developer's Guides to the project web sites: + -# Use SCP to update the SF.net web site with PDF and HTML for the + User's Guide, and HTML for the developer's guide ... you can + instantiate a shell.sourceforge.net instance and set up symlinks + from your home directory, to simplify this process. + -# Post announcement e-mail to the openocd-development list. + -# optionally: + -# Post an update on the OpenOCD blog. + -# Announce updates on freshmeat.net and other trackers. + -# Submit updates to news feeds (e.g. Digg, Reddit, etc.). +-# Resume normal development on mainline, by opening the merge window for + the next major or minor release cycle. (You might want to do this + before all the release bits are fully published.) + - Update the version label in the @c configure.ac file: + - Restore @c -dev version tag. + - For a new minor release cycle, increment the release's minor number + - For a new major release cycle, increment the release's major number + and zero its minor number + - Archive @c NEWS file as "doc/news/NEWS-${PACKAGE_VERSION}". + - Create a new @c NEWS file for the next release + - Commit those changes. + - Push all the updates to mainline. + - Last updates for the release, including the release tag (you + will need to "git push --tags"). + - Updates opening the merge window + - At this point, it's OK for commiters to start pushing changes + which have been held off until the next release. (Any bugfixes to + this release will be against a bug-fix release branch starting from + the commit you tagged as this release, not mainline.) + - Announce to the openocd-development list. Ideally, you will also + be able to say who is managing the next release cycle. + +To start a bug-fix release branch: +-# Create a new branch, starting from a major or + minor release tag +-# Restore @c -dev version tag. +-# Bump micro version number in configure.ac +-# Backport bugfix patches from mainline into that branch. + (Always be sure mainline has the fix first, so it's hard + to just lose a bugfix.) +-# Commit and push those patches. +-# When desired, release as above ... except note that the next + release of a bugfix branch is never a new major or minor release + +@subsection releasescriptcmds Release Script Commands + +The @c release.sh script automates some of the steps involved +in making releases, simplifying the Release Manager's work. + +The release script can be used for two tasks: +- Creating releases and starting a new release cycle: +@code +git checkout master +tools/release.sh --type=minor --final --start-rc release +@endcode +- Creating a development branch from a tagged release: +@code +git checkout 'v0.2.0' +tools/release.sh --type=micro branch +@endcode + +Both of these variations make automatic commits and tags in your +repository, so you should be sure to run it on a cloned copy before +proceding with a live release. + +@subsection releasescriptopts Release Script Options + +The @c release.sh script recognizes some command-line options that +affect its behavior: + +- The @c --start-rc indicates that the new development release cycle + should start with @c -rc0. Without this, the @c -rc tag will be omitted, + leading to non-monotonic versioning of the in-tree version numbers. +- The @c --final indicates that the release should drop the @c -rc tag, + to going from @c x.y.z-rcN-dev to x.y.z. + +@subsection releasescriptenv Release Script Environment + +The @c release.sh script recognizes some environment variables which +affect its behavior: + +- @c CONFIG_OPTS : Passed as options to the configure script. +- @c MAKE_OPTS : Passed as options to the 'make' processes. + +@section releasetutorial Release Tutorials + +This section should contain a brief tutorial for using the Release +Script to perform release tasks, but the new script needs to be +used for 0.3.0. + +@section releasetodo Release Script Shortcomings + +Improved automated packaging and distribution of OpenOCD requires more +patching of the configure script. The final release script should be +able to manage most steps of the processes. The steps requiring user +input could be guided by an "assistant" that walks the Release Manager +through the process from beginning to end, performing basic sanity +checks on their various inputs (e.g. the @c NEWS blurb). + + */ +/** @file +This file contains the @ref releases page. + */ diff --git a/debuggers/openocd/doc/manual/scripting.txt b/debuggers/openocd/doc/manual/scripting.txt new file mode 100644 index 00000000..783541ca --- /dev/null +++ b/debuggers/openocd/doc/manual/scripting.txt @@ -0,0 +1,80 @@ +/** @page scripting Scripting Overview + +@section scriptingisnt What scripting will not do + +The scripting support is intended for developers of OpenOCD. +It is not the intention that normal OpenOCD users will +use tcl scripting extensively, write lots of clever scripts, +or contribute back to OpenOCD. + +Target scripts can contain new procedures that end users may +tinker to their needs without really understanding tcl. + +Since end users are not expected to mess with the scripting +language, the choice of language is not terribly important +to those same end users. + +Jim Tcl was chosen as it was easy to integrate, works +great in an embedded environment and Øyvind Harboe +had experience with it. + +@section scriptinguses Uses of scripting + +Default implementation of procedures in tcl/procedures.tcl. + +- Polymorphic commands for target scripts. + - there will be added some commands in Tcl that the target + scripts can replace. + - produce \ \. Default implementation + is to ignore serial number and write a raw binary file + to beginning of first flash. Target script can dictate + file format and structure of serialnumber. Tcl allows + an argument to consist of e.g. a list so the structure of + the serial number is not limited to a single string. + - reset handling. Precise control of how srst, trst & + tms is handled. +- replace some parts of the current command line handler. + This is only to simplify the implementation of OpenOCD + and will have no externally visible consequences. + Tcl has an advantage in that it's syntax is backwards + compatible with the current OpenOCD syntax. +- external scripting. Low level tcl functions will be defined + that return machine readable output. These low level tcl + functions constitute the tcl api. flash_banks is such + a low level tcl proc. "flash banks" is an example of + a command that has human readable output. The human + readable output is expected to change inbetween versions + of OpenOCD. The output from flash_banks may not be + in the preferred form for the client. The client then + has two choices a) parse the output from flash_banks + or b) write a small piece of tcl to output the + flash_banks output to a more suitable form. The latter may + be simpler. + + +@section scriptingexternal External scripting + +The embedded Jim Tcl interpreter in OpenOCD is very limited +compared to any full scale PC hosted scripting language. + +The goal is to keep the internal Jim Tcl interpreter as +small as possible and allow any advanced scripting, +especially scripting that interacts with the host, +run on the host and talk to OpenOCD via the TCP/IP +scripting connection. + +Another problem with Jim Tcl is that there is no debugger +for it. + +With a bit of trickery it should be possible to run Jim +Tcl scripts under a Tcl interpreter on a PC. The advantage +would be that the Jim Tcl scripts could be debugged using +a standard PC Tcl debugger. + +The rough idea is to write an unknown proc that sends +unknown commands to OpenOCD. + +Basically a PC version of startup.tcl. Patches most +gratefully accepted! :-) + + */ diff --git a/debuggers/openocd/doc/manual/server.txt b/debuggers/openocd/doc/manual/server.txt new file mode 100644 index 00000000..3c2fbd0e --- /dev/null +++ b/debuggers/openocd/doc/manual/server.txt @@ -0,0 +1,316 @@ +/** @page serverdocs OpenOCD Server APIs + +OpenOCD provides support for implementing different types of servers. +Presently, the following servers have APIs that can be used. + + - @subpage servergdb + - @subpage servertelnet + - @subpage serverhttp + +@section serverdocsoverview Overview + +What follows is a development history, and describes some of the intent +of why certain features exist within OpenOCD along with the reasoning +behind them. + +This roadmap section was written May 2009 - about 9 to 12 months +after some of this work had started, it attempts to document some of +the reasons why certain features exist within OpenOCD at that time. + +@section serverdocsbg Background + +In early 2008, Oyvind Harboe and Duane Ellis had talked about how to +create a reasonable GUI for OpenOCD - something that is non-invasive, +simple to use and maintain, and does not tie OpenOCD to many other +packages. It would be wrong to "spider web" requirements into other +external external packages. That makes it difficult for developers to +write new code and creates a support nightmare. + +In many ways, people had talked about the need for some type of +high-level interface to OpenOCD, because they only had two choices: +- the ability to script: via an external program the actions of OpenOCD. +- the ablity to write a complex internal commands: native 'commands' + inside of OpenOCD was complicated. + +Fundamentally, the basic problem with both of those would be solved +with a script language: + +-# Internal: simple, small, and self-contained. +-# Cross Language: script friendly front-end +-# Cross Host: GUI Host interface +-# Cross Debugger: GUI-like interface + +What follows hopefully shows how the plans to solve these problems +materialized and help to explain the grand roadmap plan. + +@subsection serverdocsjim Why JimTCL? The Internal Script Language + +At the time, the existing "command context schema" was proving itself +insufficient. However, the problem was also considered from another +direction: should OpenOCD be first class and the script second class? +Which one rules? + +In the end, OpenOCD won, the conclusion was that simpler will be better. +Let the script language be "good enough"; it would not need numerous +features. Imagine debugging an embedded Perl module while debugging +OpenOCD. Yuck. OpenOCD already has a complex enough build system, why +make it worse? + +The goal was to add a simple language that would be moderately easy to +work with and be self-contained. JimTCL is a single C and single H +file, allowing OpenOCD to avoid the spider web of dependent packages. + +@section serverdocstcl TCL Server Port + +The TCL Server port was added in mid-2008. With embedded TCL, we can +write scripts internally to help things, or we can write "C" code that +interfaces well with TCL. + +From there, the developers wanted to create an external front-end that +would be @a very usable and that that @a any language could utilize, +allowing simple front-ends to be (a) cross-platform (b) languag +agnostic, and (c) easy to develop and use. + +Simple ASCII protocols are easy. For example, HTTP, FTP (control), and +SMTP are all text-based. All of these examples are widely and +well-known, and they do not require high-speed or high-volume. They +also support a high degree of interoperability with multiple systems. +They are not human-centric protocols; more correctly, they are rigid, +terse, simple ASCII protocols that are emensely parsable by a script. + +Thus, the TCL server -- a 'machine' type socket interface -- was added +with the hope was it would output simple "name-value" pair type +data. At the time, simple name/value pairs seemed reasonably easier to +do at the time, though Maybe it should output JSON; + +See here: + + http://www.mail-archive.com/openocd-development%40lists.berlios.de/msg00248.html + +The hope was that one could write a script in what ever language you want +and do things with it! + +@section serverdocsgui GUI Like Interfaces + +A lot has been said about various "widigit-foo-gui-library is so +wonderful". Please refer back to the domino and spider web problem of +dependencies. Sure, you may well know the WhatEver-GUI library, but +most others will not (including the next contributer to OpenOCD). +How do we solve that problem? + +For example, Cygwin can be painful, Cygwin GUI packages want X11 +to be present, crossing the barrier between MinGW and Cygwin is +painful, let alone getting the GUI front end to work on MacOS, and +Linux, yuck yuck yuck. Painful. very very painful. + +What works easier and is less work is what is already present in every +platform? The answer: A web browser. In other words, OpenOCD could +serve out embedded web pages via "localhost" to your browser. + +Long before OpenOCD had a TCL command line, Zylin AS built their ZY1000 +devince with a built-in HTTP server. Later, they were willing to both +contribute and integrate most of that work into the main tree. + +@subsection serverdocsother Other Options Considered + +What if a web browser is not acceptable ie: You want to write your own +front gadget in Eclipse, or KDevelop, or PerlTK, Ruby, or what ever +the latest and greatest Script De Jour is. + +- Option 1: Can we transport this extra data through the GDB server +protocol? In other words, can we extend the GDB server protocol? +No, Eclipse wants to talk to GDB directly and control the GDB port. + +- Option 2: SWIG front end (libopenocd): Would that work? + +That's painful - unless you design your api to be very simplistic - +every language has it's own set of wack-ness, parameter marshaling is +painful. + +What about "callbacks" and structures, and other mess. Imagine +debugging that system. When JimTCL was introduced Spencer Oliver had +quite a few well-put concerns (Summer 2008) about the idea of "TCL" +taking over OpenOCD. His concern is and was: how do you debug +something written in 2 different languages? A "SWIG" front-end is +unlikely to help that situation. + +@subsection serverdoccombined Combined: Socket & WebServer Benifits + +Seriously think about this question: What script language (or compiled +language) today cannot talk directly to a socket? Every thing in the +OpenOCD world can work a socket interface. Any host side tool can talk +to Localhost or remote host, however one might want to make it work. + +A socket interface is very simple. One could write a Java application +and serve it out via the embedded web server, could it - or something +like it talk to the built in TCL server? Yes, absolutely! We are on to +something here. + +@subsection serverdocplatforms Platform Permuntations + +Look at some permutations where OpenOCD can run; these "just work" if +the Socket Approach is used. + + +- Linux/Cygwin/MinGw/MacOSx/FreeBSD development Host Locally +- OpenOCD with some dongle on that host + + +- Linux/Cygwin/MingW/MacOS/FreeBSD development host +- DONGLE: tcpip based ARM-Linux perhaps at91rm9200 or ep93xx.c, running openocd. + + +- Windows cygwin/X desktop environment. +- Linux development host (via remote X11) +- Dongle: "eb93xx.c" based linux board + + +@subsection serverdocfuture Development Scale Out + +During 2008, Duane Ellis created some TCL scripts to display peripheral +register contents. For example, look at the sam7 TCL scripts, and the +stm32 TCL scripts. The hope was others would create more. + + +A good example of this is display/view the peripheral registers on +your embedded target. Lots of commercial embedded debug tools have +this, some can show the TIMER registers, the interrupt controller. + +What if the chip companies behind STM32, or PIC32, AT91SAM chips - +wanted to write something that makes working with their chip better, +easier, faster, etc. + +@a Question: How can we (the OpenOCD group) make that really fancy +stuff across multiple different host platforms? + +Remember: OpenOCD runs on: +-# Linux via USB, +-# ARM Linux - bit-banging GPIO pins +-# MacOSX +-# FreeBSD +-# Cygwin +-# MinGW32 +-# Ecos + +How can we get that to work? + +@subsection serverdocdebug What about Debugger Plugins? + +Really GDB is nice, it works, but it is not a good embedded debug tool. +OpenOCD cannot work in a GUI when one cannot get to its command line. +Some GDB front-end developers have pedantic designs that refuse any and +all access to the GDB command line (e.g. http://www.kdbg.org/todo.php). + +The TELNET interface to OpenOCD works, but the intent of that interface +is human interaction. It must remain available, developers depend +upon it, sometimes that is the only scheme available. + +As a small group of developers, supporting all the platforms and +targets in the debugger will be difficult, as there are enough problem +with the plethora of Adapters, Chips, and different target boards. +Yes, the TCL interface might be suitable, but it has not received much +love or attention. Perhaps it will after you read and understand this. + +One reason might be, this adds one more host side requirement to make +use of the feature. In other words, one could write a Python/TK +front-end, but it is only useable if you have Python/TK installed. +Maybe this can be done via Ecllipse, but not all developers use Ecplise. +Many devlopers use Emacs (possibly with GUD mode) or vim and will not +accept such an interface. The next developer reading this might be +using Insight (GDB-TK) - and somebody else - DDD.. + +There is no common host-side GDB front-end method. + +@section serverdocschallenge Front-End Scaling + +Maybe we are wrong - ie: OpenOCD + some TK tool + +Remember: OpenOCD is often (maybe 99.9%) of the time used with +GDB-REMOTE. There is always some front-end package - be it command-line +GDB under DDD, Eclipse, KDevelop, Emacs, or some other package +(e.g. IAR tools can talk to GDB servers). How can the OpenOCD +developers make that fancy target display GUI visible under 5 to 10 +different host-side GDB.. + +Sure - a man on a mission can make that work. The GUI might be +libopenocd + Perl/TK, or maybe an Eclipse Plug-in. +That is a development support nightmare for reasons described +above. We have enough support problems as it is with targets, adapters, +etc. + +@section serverdocshttpbg HTTP Server Background + +OpenOCD includes an HTTP server because most development environments +are likely contain a web browser. The web browser can talk to OpenOCD's +HTTP server and provide a high-level interfaces to the program. +Altogether, it provides a universally accessible GUI for OpenOCD. + +@section serverdocshtml Simple HTML Pages + +There is (or could be) a simple "Jim TCL" function to read a memory +location. If that can be tied into a TCL script that can modify the +HTTP text, then we have a simple script-based web server with a JTAG +engine under the hood. + +Imagine a web page - served from a small board with two buttons: +"LED_ON" and "LED_OFF", each click - turns the LED on or OFF, a very +simplistic idea. Little boards with web servers are great examples of +this: Ethernut is a good example and Contiki (not a board, an embedded +OS) is another example. + +One could create a simple: Click here to display memory or maybe +click here to display the UART REGISTER BLOCK; click again and see +each register explained in exquisit detail. + +For an STM32, one could create a simple HTML page, with simple +substitution text that the simple web server use to substitute the +HTML text JIMTCL_PEEK32( 0x12345678 ) with the value read from +memory. We end up with an HTML page that could list the contents of +every peripheral register on the target platform. + +That also is transportable, regardless of the OpenOCD host +platform: Linux/X86, Linux/ARM, FreeBSD, Cygwin, MingW, or MacOSX. +You could even port OpenOCD to an Android system and use it as a +bit-banging JTAG Adapter serving web pages. + +@subsection serverdocshtmladv Advanced HTML Pages + +Java or JavaScript could be used to talk back to the TCL port. One +could write a Java, AJAX, FLASH, or some other developer friendly +toolbox and get a real cross-platform GUI interface. Sure, the interface +is not native - but it is 100% cross-platform! + +OpenOCD current uses simple HTML pages; others might be an Adobe FLASH +expert, or a Java Expert. These possibilities could allow the pages +remain cross-platform but still provide a rich user-interface +experience. + +Don't forget it can also be very simple, exactly what one developer +can contribute, a set of very simple web pages. + +@subsection serverdocshtmlstatus HTTP/HTML Status + +As of May 2009, much of the HTML pages were contributed by Zylin AS, +hence they continue to retain some resemblance to the ZY1000 interface. + +Patches would be welcome to move these parts of the system forward. + + */ + +/** @page servergdb OpenOCD GDB Server API + +This section needs to be expanded. + + */ + +/** @page servertelnet OpenOCD Telnet Server API + +This section needs to be expanded. + + */ + +/** @page serverhttp OpenOCD http Server API + +This section needs to be expanded. + + */ diff --git a/debuggers/openocd/doc/manual/style.txt b/debuggers/openocd/doc/manual/style.txt new file mode 100644 index 00000000..54c1342e --- /dev/null +++ b/debuggers/openocd/doc/manual/style.txt @@ -0,0 +1,403 @@ +/** @page styleguide Style Guides + +The goals for each of these guides are: +- to produce correct code that appears clean, consistent, and readable, +- to allow developers to create patches that conform to a standard, and +- to eliminate these issues as points of future contention. + +Some of these rules may be ignored in the spirit of these stated goals; +however, such exceptions should be fairly rare. + +The following style guides describe a formatting, naming, and other +conventions that should be followed when writing or changing the OpenOCD +code: + +- @subpage styletcl +- @subpage stylec +- @subpage styleperl +- @subpage styleautotools + +In addition, the following style guides provide information for +providing documentation, either as part of the C code or stand-alone. + +- @subpage styledoxygen +- @subpage styletexinfo +- @subpage stylelatex + +Feedback would be welcome to improve the OpenOCD guidelines. + + */ +/** @page styletcl TCL Style Guide + +OpenOCD needs to expand its Jim/TCL Style Guide. + +Many of the guidelines listed on the @ref stylec page should apply to +OpenOCD's Jim/TCL code as well. + + */ +/** @page stylec C Style Guide + +This page contains guidelines for writing new C source code for the +OpenOCD project. + +@section styleformat Formatting Guide + +- remove any trailing white space at the end of lines. +- use TAB characters for indentation; do NOT use spaces. +- displayed TAB width is 4 characters. +- use Unix line endings ('\\n'); do NOT use DOS endings ('\\r\\n') +- limit adjacent empty lines to at most two (2). +- remove any trailing empty lines at the end of source files +- do not "comment out" code from the tree; instead, one should either: + -# remove it entirely (git can retrieve the old version), or + -# use an @c \#if/\#endif block. + +Finally, try to avoid lines of code that are longer than than 72-80 columns: + +- long lines frequently indicate other style problems: + - insufficient use of static functions, macros, or temporary variables + - poor flow-control structure; "inverted" logical tests +- a few lines may be wider than this limit (typically format strings), but: + - all C compilers will concatenate series of string constants. + - all long string constants should be split across multiple lines. + +@section stylenames Naming Rules + +- most identifiers must use lower-case letters (and digits) only. + - macros must use upper-case letters (and digits) only. + - OpenOCD identifiers should NEVER use @c MixedCaps. +- @c typedef names must end with the '_t' suffix. + - This should be reserved for types that should be passed by value. + - Do @b not mix the typedef keyword with @c struct. +- use underline characters between consecutive words in identifiers + (e.g. @c more_than_one_word). + +@section stylec99 C99 Rules + +- inline functions +- @c // comments -- in new code, prefer these for single-line comments +- trailing comma allowed in enum declarations +- designated initializers ( .field = value ) +- variables declarations should occur at the point of first use +- new block scopes for selection and iteration statements +- use malloc() to create dynamic arrays. Do @b not use @c alloca +or variable length arrays on the stack. non-MMU hosts(uClinux) and +pthreads require modest and predictable stack usage. + +@section styletypes Type Guidelines +- use native types (@c int or @c unsigned) if the type is not important + - if size matters, use the types from \ or \: + - @c int8_t, @c int16_t, @c int32_t, or @c int64_t: signed types of specified size + - @c uint8_t, @c uint16_t, @c uint32_t, or @c uint64_t: unsigned types of specified size + - do @b NOT redefine @c uN types from "types.h" + +@section stylefunc Functions + +- static inline functions should be prefered over macros: +@code +/** do NOT define macro-like functions like this... */ +#define CUBE(x) ((x) * (x) * (x)) +/** instead, define the same expression using a C99 inline function */ +static inline int cube(int x) { return x * x * x; } +@endcode +- Functions should be declared static unless required by other modules + - define static functions before first usage to avoid forward declarations. +- Functions should have no space between its name and its parameter list: +@code +int f(int x1, int x2) +{ + ... + int y = f(x1, x2 - x1); + ... +} +@endcode +- Separate assignment and logical test statements. In other words, you +should write statements like the following: +@code +// separate statements should be preferred +result = foo(); +if (ERROR_OK != result) + ... +@endcode +More directly, do @b not combine these kinds of statements: +@code +// Combined statements should be avoided +if (ERROR_OK != (result = foo())) + return result; +@endcode + + */ +/** @page styledoxygen Doxygen Style Guide + +The following sections provide guidelines for OpenOCD developers +who wish to write Doxygen comments in the code or this manual. +For an introduction to Doxygen documentation, +see the @ref primerdoxygen. + +@section styledoxyblocks Doxygen Block Selection + +Several different types of Doxygen comments can be used; often, +one style will be the most appropriate for a specific context. +The following guidelines provide developers with heuristics for +selecting an appropriate form and writing consistent documentation +comments. + +-# use @c /// to for one-line documentation of instances. +-# for documentation requiring multiple lines, use a "block" style: +@verbatim +/** + * @brief First sentence is short description. Remaining text becomes + * the full description block, where "empty" lines start new paragraphs. + * + * One can make text appear in @a italics, @b bold, @c monospace, or + * in blocks such as the one in which this example appears in the Style + * Guide. See the Doxygen Manual for the full list of commands. + * + * @param foo For a function, describe the parameters (e.g. @a foo). + * @returns The value(s) returned, or possible error conditions. + */ +@endverbatim + -# The block should start on the line following the opening @c /**. + -# The end of the block, \f$*/\f$, should also be on its own line. + -# Every line in the block should have a @c '*' in-line with its start: + - A leading space is required to align the @c '*' with the @c /** line. + - A single "empty" line should separate the function documentation + from the block of parameter and return value descriptions. + - Except to separate paragraphs of documentation, other extra + "empty" lines should be removed from the block. + -# Only single spaces should be used; do @b not add mid-line indentation. +-# If the total line length will be less than 72-80 columns, then + - The @c /**< form can be used on the same line. + - This style should be used sparingly; the best use is for fields: + @code int field; /**< field description */ @endcode + +@section styledoxyall Doxygen Style Guide + +The following guidelines apply to all Doxygen comment blocks: + +-# Use the @c '\@cmd' form for all doxygen commands (do @b not use @c '\\cmd'). +-# Use symbol names such that Doxygen automatically creates links: + -# @c function_name() can be used to reference functions + (e.g. flash_set_dirty()). + -# @c struct_name::member_name should be used to reference structure + fields in the documentation (e.g. @c flash_driver::name). + -# URLS get converted to markup automatically, without any extra effort. + -# new pages can be linked into the heirarchy by using the @c \@subpage + command somewhere the page(s) under which they should be linked: + -# use @c \@ref in other contexts to create links to pages and sections. +-# Use good Doxygen mark-up: + -# '\@a' (italics) should be used to reference parameters (e.g. foo). + -# '\@b' (bold) should be used to emphasizing single words. + -# '\@c' (monospace) should be used with file names and + code symbols, so they appear visually distinct from + surrounding text. + -# To mark-up multiple words, the HTML alternatives must be used. +-# Two spaces should be used when nesting lists; do @b not use '\\t' in lists. +-# Code examples provided in documentation must conform to the Style Guide. + +@section styledoxytext Doxygen Text Inputs + +In addition to the guidelines in the preceding sections, the following +additional style guidelines should be considered when writing +documentation as part of standalone text files: + +-# Text files must contain Doxygen at least one comment block: + -# Documentation should begin in the first column (except for nested lists). + -# Do NOT use the @c '*' convention that must be used in the source code. +-# Each file should contain at least one @c \@page block. + -# Each new page should be listed as a \@subpage in the \@page block + of the page that should serve as its parent. + -# Large pages should be structure in parts using meaningful \@section + and \@subsection commands. +-# Include a @c \@file block at the end of each Doxygen @c .txt file to + document its contents: + - Doxygen creates such pages for files automatically, but no content + will appear on them for those that only contain manual pages. + - The \@file block should provide useful meta-documentation to assist + techincal writers; typically, a list of the pages that it contains. + - For example, the @ref styleguide exists in @c doc/manual/style.txt, + which contains a reference back to itself. +-# The \@file and \@page commands should begin on the same line as + the start of the Doxygen comment: +@verbatim +/** @page pagename Page Title + +Documentation for the page. + + */ +/** @file + +This file contains the @ref pagename page. + + */ +@endverbatim + +For an example, the Doxygen source for this Style Guide can be found in +@c doc/manual/style.txt, alongside other parts of The Manual. + + */ +/** @page styletexinfo Texinfo Style Guide + +The User's Guide is there to provide two basic kinds of information. It +is a guide for how and why to use each feature or mechanism of OpenOCD. +It is also the reference manual for all commands and options involved +in using them, including interface, flash, target, and other drivers. +At this time, it is the only user-targetted documentation; everything +else is addressing OpenOCD developers. + +There are two key audiences for the User's Guide, both developer based. +The primary audience is developers using OpenOCD as a tool in their +work, or who may be starting to use it that way. A secondary audience +includes developers who are supporting those users by packaging or +customizing it for their hardware, installing it as part of some software +distribution, or by evolving OpenOCD itself. There is some crossover +between those audiences. We encourage contributions from users as the +fundamental way to evolve and improve OpenOCD. In particular, creating +a board or target specific configuration file is something that many +users will end up doing at some point, and we like to see such files +become part of the mainline release. + +General documentation rules to remember include: + +- Be concise and clear. It's work to remove those extra words and + sentences, but such "noise" doesn't help readers. +- Make it easy to skim and browse. "Tell what you're going to say, + then say it". Help readers decide whether to dig in now, or + leave it for later. +- Make sure the chapters flow well. Presentations should not jump + around, and should move easily from overview down to details. +- Avoid using the passive voice. +- Address the reader to clarify roles ("your config file", "the board you + are debugging", etc.); "the user" (etc) is artificial. +- Use good English grammar and spelling. Remember also that English + will not be the first language for many readers. Avoid complex or + idiomatic usage that could create needless barriers. +- Use examples to highlight fundamental ideas and common idioms. +- Don't overuse list constructs. This is not a slide presentation; + prefer paragraphs. + +When presenting features and mechanisms of OpenOCD: + +- Explain key concepts before presenting commands using them. +- Tie examples to common developer tasks. +- When giving instructions, you can \@enumerate each step both + to clearly delineate the steps, and to highlight that this is + not explanatory text. +- When you provide "how to use it" advice or tutorials, keep it + in separate sections from the reference material. +- Good indexing is something of a black art. Use \@cindex for important + concepts, but don't overuse it. In particular, rely on the \@deffn + indexing, and use \@cindex primarily with significant blocks of text + such as \@subsection. The \@dfn of a key term may merit indexing. +- Use \@xref (and \@anchor) with care. Hardcopy versions, from the PDF, + must make sense without clickable links (which don't work all that well + with Texinfo in any case). If you find you're using many links, + read that as a symptom that the presentation may be disjointed and + confusing. +- Avoid font tricks like \@b, but use \@option, \@file, \@dfn, \@emph + and related mechanisms where appropriate. + +For technical reference material: + +- It's OK to start sections with explanations and end them with + detailed lists of the relevant commands. +- Use the \@deffn style declarations to define all commands and drivers. + These will automatically appear in the relevant index, and those + declarations help promote consistent presentation and style. + - It's a "Command" if it can be used interactively. + - Else it's a "Config Command" if it must be used before the + configuration stage completes. + - For a "Driver", list its name. + - Use EBNF style regular expressions to define parameters: + brackets around zero-or-one choices, parentheses around + exactly-one choices. + - Use \@option, \@file, \@var and other mechanisms where appropriate. + - Say what output it displays, and what value it returns to callers. + - Explain clearly what the command does. Sometimes you will find + that it can't be explained clearly. That usually means the command + is poorly designed; replace it with something better, if you can. + - Be complete: document all commands, except as part of a strategy + to phase something in or out. + - Be correct: review the documentation against the code, and + vice versa. +- Alphabetize the \@defn declarations for all commands in each + section. +- Keep the per-command documentation focussed on exactly what that + command does, not motivation, advice, suggestions, or big examples. + When commands deserve such expanded text, it belongs elsewhere. + Solutions might be using a \@section explaining a cluster of related + commands, or acting as a mini-tutorial. +- Details for any given driver should be grouped together. + +The User's Guide is the first place most users will start reading, +after they begin using OpenOCD. Make that investment of their time +be as productive as possible. Needing to look at OpenOCD source code, +to figure out how to use it is a bad sign, though it's OK to need to +look at the User's guide to figure out what a config script is doing. + + */ +/** @page stylelatex LaTeX Style Guide + +This page needs to provide style guidelines for using LaTeX, the +typesetting language used by The References for OpenOCD Hardware. +Likewise, the @ref primerlatex for using this guide needs to be completed. + + */ +/** @page styleperl Perl Style Guide + +This page provides some style guidelines for using Perl, a scripting +language used by several small tools in the tree: + +-# Ensure all Perl scripts use the proper suffix (@c .pl for scripts, and + @c .pm for modules) +-# Pass files as script parameters or piped as input: + - Do NOT code paths to files in the tree, as this breaks out-of-tree builds. + - If you must, then you must also use an automake rule to create the script. +-# use @c '#!/usr/bin/perl' as the first line of Perl scripts. +-# always use strict and use warnings +-# invoke scripts indirectly in Makefiles or other scripts: +@code +perl script.pl +@endcode + +Maintainers must also be sure to follow additional guidelines: +-# Ensure that Perl scripts are committed as executables: + Use "chmod +x script.pl" + @a before using "git add script.pl" + + */ +/** @page styleautotools Autotools Style Guide + +This page contains style guidelines for the OpenOCD autotools scripts. + +The following guidelines apply to the @c configure.ac file: +- Better guidelines need to be developed, but until then... +- Use good judgement. + +The following guidelines apply to @c Makefile.am files: +-# When assigning variables with long lists of items: + -# Separate the values on each line to make the files "patch friendly": +@code +VAR = \ + value1 \ + value2 \ + ... + value9 \ + value10 +@endcode + */ +/** @file + +This file contains the @ref styleguide pages. The @ref styleguide pages +include the following Style Guides for their respective code and +documentation languages: + +- @ref styletcl +- @ref stylec +- @ref styledoxygen +- @ref styletexinfo +- @ref stylelatex +- @ref styleperl +- @ref styleautotools + + */ diff --git a/debuggers/openocd/doc/manual/target.txt b/debuggers/openocd/doc/manual/target.txt new file mode 100644 index 00000000..7e9767f8 --- /dev/null +++ b/debuggers/openocd/doc/manual/target.txt @@ -0,0 +1,46 @@ +/** @page targetdocs OpenOCD Target APIs + +OpenOCD provides its Target APIs to allow developers to provide trace and +debugging support for specific device targets. These primarily consist of +ARM cores, but other types have been supported. New targets should be +developed by following or using these APIs. + +The Target Support module contains APIs that cover several functional areas: + + - @subpage targetarm + - @subpage targetnotarm + - @subpage targetmips + - @subpage targetregister + - @subpage targetimage + - @subpage targettrace + +This section needs to be expanded. + +*/ + +/** @page targetarm OpenOCD ARM Targets + +This section needs to describe OpenOCD's ARM target support. + + */ + +/** @page targetregister OpenOCD Target Register API + +This section needs to describe OpenOCD's Target Register API, as +provided by 'src/target/register.h'. + + */ + +/** @page targetimage OpenOCD Target Image API + +This section needs to describe OpenOCD's Target Image API, as provided +by 'src/target/image.h'. + + */ + +/** @page targettrace OpenOCD Target Trace API + +This section needs to describe OpenOCD's Target Trace API, as provided +by 'src/target/trace.h'. + + */ diff --git a/debuggers/openocd/doc/manual/target/mips.txt b/debuggers/openocd/doc/manual/target/mips.txt new file mode 100644 index 00000000..32c40b98 --- /dev/null +++ b/debuggers/openocd/doc/manual/target/mips.txt @@ -0,0 +1,536 @@ +/** @page targetmips OpenOCD MIPS Targets + +@section ejatgmem EJTAG Memory Addresses + +An optional uncached and unmapped debug segment dseg (EJTAG area) appears in the address range +0xFFFF FFFF FF20 0000 to 0xFFFF FFFF FF3F FFFF. The dseg segment thereby appears in the kseg part of the +compatibility segment, and access to kseg is possible with the dseg segment. + +The dseg segment is subdivided into dmseg (EJTAG memory) segment and the drseg (EJTAG registers) segment. The +dmseg segment is used when the probe services the memory segment. The drseg segment is used when the +memory-mapped debug registers are accessed. Table 5-2 shows the subdivision and attributes for the segments. + +dseg is divided in : + + - dmseg (0xFFFF FFFF FF20 0000 to 0xFFFF FFFF FF2F FFFF) + - drseg (0xFFFF FFFF FF30 0000 to 0xFFFF FFFF FF3F FFFF) + +Because the dseg segment is serviced exclusively by the EJTAG features, there +are no physical address per se. Instead the lower 21 bits of the virtual address select +the appropriate reference in either EJTAG memory or registers. References are not mapped through the +TLB, nor do the accesses appear on the external system memory interface. + +Both of this memory segments are Uncached. + +On debug exception (break) CPU jumps to the beginning of dmseg. This some kind of memory shared +between CPU and EJTAG dongle. + +There CPU stops (correct terminology is : stalls, because it stops it's pipeline), and is waiting for some action of dongle. + +If the dongle gives it instruction, CPU executes it, augments it's PC to 0xFFFF FFFF FF20 0001 - but it again points to dmseg area, +so it stops waiting for next instruction. + +This will all become clear later, after reading following prerequisite chapters. + +@section impflags Important flags + +@subsection pnnw PNnW + +Indicates read or write of a pending processor access: + + - 0 : Read processor access, for a fetch/load access + - 1 : Write processor access, for a store access + +This value is defined only when a processor access is pending. + +Processor will do the action for us : it can for example read internal state (register values), +and send us back the information via EJTAG memory (dmseg), or it can take some data from dmseg and write it into the registers or RAM. + +Every time when it sees address (i.e. when this address is the part of the opcode it is executing, wether it is instruction or data fetch) +that falls into dmseg, processor stalls. That acutally meand that CPU stops it's pipeline and it is waitning for dongle to take some action. + +CPU is now either waiting for dongle to take some data from dmseg (if we requested for CPU do give us internal state, for example), +or it will wait for some data from dongle (if it needs following instruction because it did previous, or if the operand address of the currently executed opcode +falls somewhere (anywhere) in dmseg (0xff..ff20000 - 0xff..ff2fffff)). + +Bit PNnW describes character of CPU access to EJTAG memory (the memry where dongle puts/takes data) - CPU can either READ for it (PNnW == 0) or +WRITE to it (PNnW == 1). + +By reading PNnW bit OpenOCD will know if it has to send (PNnW == 0) or to take (PNnW == 1) data (from dmseg, via dongle). + +@subsection pracc PrAcc + +Indicates a pending processor access and controls finishing of a pending processor access. + +When read: + + - 0 : No pending processor access + - 1 : Pending processor access + +A write of 0 finishes a processor access if pending; +otherwise operation of the processor is UNDEFINED +if the bit is written to 0 when no processor access is +pending. A write of 1 is ignored. + +A successful FASTDATA access will clear this bit. + +As noted above, on any access to dmseg, processor will stall. It waits for dongle to do some action - either to take or put some data. +OpenOCD can figure out which action has to be taken by reading PrAcc bit. + +Once action from dongle has been done, i.e. after the data is taken/put, OpenOCD can signal to CPU to proceed with executing the instruction. +This can be the next instruction (if previous was finished before pending), or the same instruction - if for example CPU was waiting on dongle +to give it an operand, because it saw in the instruction opcode that operand address is somewhere in dmseg. That prowoked the CPU to stall (it tried operand fetch to dmseg and stopped), +and PNnW bit is 0 (CPU does read from dmseg), and PrAcc is 1 (CPU is pending on dmseg access). + +@subsection spracc SPrAcc + +Shifting in a zero value requests completion of the Fastdata access. + +The PrAcc bit in the EJTAG Control register is overwritten with zero when the access +succeeds. (The access succeeds if PrAcc is one and the operation address is in the legal dmseg segment +Fastdata area.) + +When successful, a one is shifted out. Shifting out a zero indicates a Fastdata access failure. +Shifting in a one does not complete the Fastdata access and the PrAcc bit is unchanged. Shifting out a +one indicates that the access would have been successful if allowed to complete and a zero indicates +the access would not have successfully completed. + +@section fdreg Fastdata Register (TAP Instruction FASTDATA) + +The width of the Fastdata register is 1 bit. + +During a Fastdata access, the Fastdata register is written and read, i.e., a bit is +shifted in and a bit is shifted out. + +Also during a Fastdata access, the Fastdata register value shifted in specifies whether the Fastdata +access should be completed or not. The value shifted out is a flag that indicates whether the Fastdata access was +successful or not (if completion was requested). + +@section ejtagacc EJTAG Access Implementation + +OpenOCD reads/writes data to JTAG via mips_m4k_read_memory() and mips_m4k_write_memory() functions defined in src/target/mips_m4k.c. +Internally, these functions call mips32_pracc_read_mem() and mips32_pracc_write_mem() defined in src/target/mips32_pracc.c + +Let's take for example function mips32_pracc_read_mem32() which describes CPU reads (fetches) from dmseg (EJTAG memory) : + +@code +static const uint32_t code[] = { + /* start: */ + MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */ + MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ + MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)), + MIPS32_SW(8,0,15), /* sw $8,($15) */ + MIPS32_SW(9,0,15), /* sw $9,($15) */ + MIPS32_SW(10,0,15), /* sw $10,($15) */ + MIPS32_SW(11,0,15), /* sw $11,($15) */ + + MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */ + MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)), + MIPS32_LW(9,0,8), /* $9 = mem[$8]; read addr */ + MIPS32_LW(10,4,8), /* $10 = mem[$8 + 4]; read count */ + MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $11 = MIPS32_PRACC_PARAM_OUT */ + MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)), + /* loop: */ + MIPS32_BEQ(0,10,8), /* beq 0, $10, end */ + MIPS32_NOP, + + MIPS32_LW(8,0,9), /* lw $8,0($9), Load $8 with the word @mem[$9] */ + MIPS32_SW(8,0,11), /* sw $8,0($11) */ + + MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */ + MIPS32_ADDI(9,9,4), /* $1 += 4 */ + MIPS32_ADDI(11,11,4), /* $11 += 4 */ + + MIPS32_B(NEG16(8)), /* b loop */ + MIPS32_NOP, + /* end: */ + MIPS32_LW(11,0,15), /* lw $11,($15) */ + MIPS32_LW(10,0,15), /* lw $10,($15) */ + MIPS32_LW(9,0,15), /* lw $9,($15) */ + MIPS32_LW(8,0,15), /* lw $8,($15) */ + MIPS32_B(NEG16(27)), /* b start */ + MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */ +}; +@endcode + +We have to pass this code to CPU via dongle via dmseg. + +After debug exception CPU will find itself stalling at the begining of the dmseg. It waits for the first instruction from dongle. +This is MIPS32_MTC0(15,31,0), so CPU saves C0 and continues to addr 0xFF20 0001, which falls also to dmseg, so it stalls. +Dongle proceeds giving to CPU one by one instruction in this manner. + +However, things are not so simple. If you take a look at the program, you will see that some instructions take operands. If it has to take +operand from the address in dmseg, CPU will stall witing for the dongle to do the action of passing the operand and signal this by putting PrAcc to 0. +If this operand is somewhere in RAM, CPU will not stall (it stalls only on dmseg), but it will just take it and proceed to nex instruction. But since PC for next instruction +points to dmseg, it will stall, so that dongle can pass next instruction. + +Some instuctions are jumps (if these are jumps in dmseg addr, CPU will jump and then stall. If this is jump to some address in RAM, CPU will jump and just proceed - +will not stall on addresses in RAM). + +To have information about CPU is currently (does it stalls wanting on operand or it jumped somewhere waiting for next instruction), +OpenOCD has to call TAP ADDRESS instruction, which will ask CPU to give us his address within EJTAG memory : + +@code +address = data = 0; +mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); +mips_ejtag_drscan_32(ejtag_info, &address); +@endcode + +And then, upon the results, we can conclude where it is in our code so far, so we can give it what it wants next : + +@code +if ((address >= MIPS32_PRACC_PARAM_IN) + && (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) +{ + offset = (address - MIPS32_PRACC_PARAM_IN) / 4; + data = ctx->local_iparam[offset]; +} +else if ((address >= MIPS32_PRACC_PARAM_OUT) + && (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) +{ + offset = (address - MIPS32_PRACC_PARAM_OUT) / 4; + data = ctx->local_oparam[offset]; +} +else if ((address >= MIPS32_PRACC_TEXT) + && (address <= MIPS32_PRACC_TEXT + ctx->code_len * 4)) +{ + offset = (address - MIPS32_PRACC_TEXT) / 4; + data = ctx->code[offset]; +} +else if (address == MIPS32_PRACC_STACK) +{ + /* save to our debug stack */ + data = ctx->stack[--ctx->stack_offset]; +} +else +{ + /* TODO: send JMP 0xFF200000 instruction. + Hopefully processor jump back to start of debug vector */ + data = 0; + LOG_ERROR("Error reading unexpected address 0x%8.8" PRIx32 "", address); + return ERROR_JTAG_DEVICE_ERROR; +} +@endcode + +i.e. if CPU is stalling on addresses in dmseg that are reserved for input parameters, we can conclude that it actually tried to take (read) +parametar from there, and saw that address of param falls in dmseg, so it stopped. Obviously, now dongle have to give to it operand. + +Similarly, mips32_pracc_exec_write() describes CPU writes into EJTAG memory (dmseg). +Obvioulsy, code is RO, and CPU can change only parameters : + +@code +mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA); +mips_ejtag_drscan_32(ctx->ejtag_info, &data); + +/* Clear access pending bit */ +ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC; +mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL); +mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl); + +//jtag_add_clocks(5); +jtag_execute_queue(); + +if ((address >= MIPS32_PRACC_PARAM_IN) + && (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) +{ + offset = (address - MIPS32_PRACC_PARAM_IN) / 4; + ctx->local_iparam[offset] = data; +} +else if ((address >= MIPS32_PRACC_PARAM_OUT) + && (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) +{ + offset = (address - MIPS32_PRACC_PARAM_OUT) / 4; + ctx->local_oparam[offset] = data; +} +else if (address == MIPS32_PRACC_STACK) +{ + /* save data onto our stack */ + ctx->stack[ctx->stack_offset++] = data; +} +else +{ + LOG_ERROR("Error writing unexpected address 0x%8.8" PRIx32 "", address); + return ERROR_JTAG_DEVICE_ERROR; +} +@endcode + +CPU loops here : + +@code +while (1) +{ + if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK) + return retval; + + address = data = 0; + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); + mips_ejtag_drscan_32(ejtag_info, &address); + + /* Check for read or write */ + if (ejtag_ctrl & EJTAG_CTRL_PRNW) + { + if ((retval = mips32_pracc_exec_write(&ctx, address)) != ERROR_OK) + return retval; + } + else + { + /* Check to see if its reading at the debug vector. The first pass through + * the module is always read at the vector, so the first one we allow. When + * the second read from the vector occurs we are done and just exit. */ + if ((address == MIPS32_PRACC_TEXT) && (pass++)) + { + break; + } + + if ((retval = mips32_pracc_exec_read(&ctx, address)) != ERROR_OK) + return retval; + } + + if (cycle == 0) + break; +} +@endcode + +and using presented R (mips32_pracc_exec_read()) and W (mips32_pracc_exec_write()) functions it reads in the code (RO) and reads and writes operands (RW). + +@section fdimpl OpenOCD FASTDATA Implementation + +OpenOCD FASTDATA write function, mips32_pracc_fastdata_xfer() is called from bulk_write_memory callback, which writes a count items of 4 bytes +to the memory of a target at the an address given. Because it operates only on whole words, this should be faster than target_write_memory(). + +In order to implement FASTDATA write, mips32_pracc_fastdata_xfer() uses the following handler : + +@code +uint32_t handler_code[] = { + /* caution when editing, table is modified below */ + /* r15 points to the start of this code */ + MIPS32_SW(8,MIPS32_FASTDATA_HANDLER_SIZE - 4,15), + MIPS32_SW(9,MIPS32_FASTDATA_HANDLER_SIZE - 8,15), + MIPS32_SW(10,MIPS32_FASTDATA_HANDLER_SIZE - 12,15), + MIPS32_SW(11,MIPS32_FASTDATA_HANDLER_SIZE - 16,15), + /* start of fastdata area in t0 */ + MIPS32_LUI(8,UPPER16(MIPS32_PRACC_FASTDATA_AREA)), + MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_FASTDATA_AREA)), + MIPS32_LW(9,0,8), /* start addr in t1 */ + MIPS32_LW(10,0,8), /* end addr to t2 */ + /* loop: */ + /* 8 */ MIPS32_LW(11,0,0), /* lw t3,[t8 | r9] */ + /* 9 */ MIPS32_SW(11,0,0), /* sw t3,[r9 | r8] */ + MIPS32_BNE(10,9,NEG16(3)), /* bne $t2,t1,loop */ + MIPS32_ADDI(9,9,4), /* addi t1,t1,4 */ + + MIPS32_LW(8,MIPS32_FASTDATA_HANDLER_SIZE - 4,15), + MIPS32_LW(9,MIPS32_FASTDATA_HANDLER_SIZE - 8,15), + MIPS32_LW(10,MIPS32_FASTDATA_HANDLER_SIZE - 12,15), + MIPS32_LW(11,MIPS32_FASTDATA_HANDLER_SIZE - 16,15), + + MIPS32_LUI(15,UPPER16(MIPS32_PRACC_TEXT)), + MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_TEXT)), + MIPS32_JR(15), /* jr start */ + MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */ +}; +@endcode + +In the begining and the end of the handler we have fuction prologue (save the regs that will be clobbered) and epilogue (restore regs), +and in the very end, after all the xfer have been done, we do jump to the MIPS32_PRACC_TEXT address, i.e. Debug Exception Vector location. +We will use this fact (that we came back to MIPS32_PRACC_TEXT) to verify later if all the handler is executed (because when in RAM, +processor do not stall - it executes all instructions untill one of them do not demand access to dmseg (if one of it's opernads is there)). + +This handler is put into the RAM and executed from there, and not instruction by instruction, like in previous simple write +(mips_m4k_write_memory()) and read (mips_m4k_read_memory()) functions. + +N.B. When it is executing this code in RAM, CPU will not stall on instructions, but execute all until it comes to the : + +@code +MIPS32_LW(9,0,8) /* start addr in t1 */ +@endcode + +and there it will stall - because it will see that one of the operands have to be fetched from dmseg (EJTAG memory, in this case FASTDATA memory segment). + +This handler is loaded in the RAM, ath the reserved location "work_area". This work_area is configured in OpenOCD configuration script and should be selected +in that way that it is not clobbered (overwritten) by data we want to write-in using FASTDATA. + +What is executed instruction by instruction which is passed by dongle (via EJATG memory) is small jump code, which jumps at the handler in RAM. +CPU stalls on dmseg when receiving these jmp_code instructions, but once it jumps in RAM, CPU do not stall anymore and executes bunch of handler instructions. +Untill it comes to the first instruction which has an operand in FASTDATA area. There it stalls and waits on action from probe. +It happens actually when CPU comes to this loop : + +@code +MIPS32_LW(9,0,8), /* start addr in t1 */ +MIPS32_LW(10,0,8), /* end addr to t2 */ + /* loop: */ +/* 8 */ MIPS32_LW(11,0,0), /* lw t3,[t8 | r9] */ +/* 9 */ MIPS32_SW(11,0,0), /* sw t3,[r9 | r8] */ +MIPS32_BNE(10,9,NEG16(3)), /* bne $t2,t1,loop */ +@endcode + +and then it stalls because operand in r8 points to FASTDATA area. + +OpenOCD first verifies that CPU came to this place by : + +@code +/* next fetch to dmseg should be in FASTDATA_AREA, check */ +address = 0; +mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); +mips_ejtag_drscan_32(ejtag_info, &address); + +if (address != MIPS32_PRACC_FASTDATA_AREA) + return ERROR_FAIL; +@endcode + +and then passes to CPU start and end address of the loop region for handler in RAM. + +In the loop in handler, CPU sees that it has to take and operand from FSTDATA area (to write it to the dst in RAM after), and so it stalls, putting PrAcc to "1". +OpenOCD fills the data via this loop : + +@code +for (i = 0; i < count; i++) +{ + /* Send the data out using fastdata (clears the access pending bit) */ + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA); + if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++)) != ERROR_OK) + return retval; +} +@endcode + +Each time when OpenOCD fills data to CPU (via dongle, via dmseg), CPU takes it and proceeds in executing the endler. However, since handler is in a assembly loop, +CPU comes to next instruction which also fetches data from FASTDATA area. So it stalls. +Then OpenOCD fills the data again, from it's (OpenOCD's) loop. And this game continues untill all the data has been filled. + +After the last data has beend given to CPU it sees that it reached the end address, so it proceeds with next instruction. However, rhis instruction do not point into dmseg, so +CPU executes bunch of handler instructions (all prologue) and in the end jumps to MIPS32_PRACC_TEXT address. + +On it's side, OpenOCD checks in CPU has jumped back to MIPS32_PRACC_TEXT, which is the confirmation that it correclty executed all the rest of the handler in RAM, +and that is not stuck somewhere in the RAM, or stalling on some acces in dmseg - that would be an error : + +@code +address = 0; +mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); +mips_ejtag_drscan_32(ejtag_info, &address); + +if (address != MIPS32_PRACC_TEXT) + LOG_ERROR("mini program did not return to start"); +@endcode + +@section fdejtagspec EJTAG spec on FASTDATA access + +The width of the Fastdata register is 1 bit. During a Fastdata access, the Fastdata register is written and read, i.e., a bit +is shifted in and a bit is shifted out. During a Fastdata access, the Fastdata register value shifted in specifies whether +the Fastdata access should be completed or not. The value shifted out is a flag that indicates whether the Fastdata +access was successful or not (if completion was requested). + +The FASTDATA access is used for efficient block transfers between dmseg (on the probe) and target memory (on the +processor). An "upload" is defined as a sequence of processor loads from target memory and stores to dmseg. A +"download" is a sequence of processor loads from dmseg and stores to target memory. The "Fastdata area" specifies +the legal range of dmseg addresses (0xFF20.0000 - 0xFF20.000F) that can be used for uploads and downloads. The +Data + Fastdata registers (selected with the FASTDATA instruction) allow efficient completion of pending Fastdata +area accesses. +During Fastdata uploads and downloads, the processor will stall on accesses to the Fastdata area. The PrAcc (processor +access pending bit) will be 1 indicating the probe is required to complete the access. Both upload and download +accesses are attempted by shifting in a zero SPrAcc value (to request access completion) and shifting out SPrAcc to +see if the attempt will be successful (i.e., there was an access pending and a legal Fastdata area address was used). +Downloads will also shift in the data to be used to satisfy the load from dmseg’s Fastdata area, while uploads will +shift out the data being stored to dmseg’s Fastdata area. +As noted above, two conditions must be true for the Fastdata access to succeed. These are: + + - PrAcc must be 1, i.e., there must be a pending processor access. + - The Fastdata operation must use a valid Fastdata area address in dmseg (0xFF20.0000 to 0xFF20.000F). + +Basically, because FASTDATA area in dmseg is 16 bytes, we transfer (0xFF20.0000 - 0xFF20.000F) +FASTDATA scan TAP instruction selects the Data and the Fastdata registers at once. + +They come in order : +TDI -> | Data register| -> | Fastdata register | -> TDO + +FASTDATA register is 1-bit width register. It takes in SPrAcc bit which should be shifted first, +followed by 32 bit of data. + +Scan width of FASTDTA is 33 bits in total : 33 bits are shifted in and 33 bits are shifted out. + +First bit that is shifted out is SPrAcc that comes out of Fastdata register and should give us status on FATSDATA write we want to do. + +@section fdcheck OpenOCD misses FASTDATA check + +Download flow (probe -> target block transfer) : + +1) Probe transfer target execution to a loop in target memory doing a fixed number of "loads" to fastdata area of dmseg (and stores to the target download destination.) + +2) Probe loops attempting to satisfy the loads "expected" from the target. + On FASTDATA access "successful" move on to next "load". + On FASTDATA access "failure" repeat until "successful" or timeout. + (A "failure" is an attempt to satisfy an access when none are pending.) + +Note: A failure may have a recoverable (and even expected) cause like slow target execution of the load loop. Other failures may be due to unexpected more troublesome causes like an exception while in debug mode or a target hang on a bad target memory access. + +Shifted out SPrAcc bit inform us that there was CPU access pendingand that it can be complete. + +Basically, we should do following procedure : + + - Download (dongle -> CPU) : +You shift "download" DATA and FASTDATA[SPrAcc] = 0 (33 bit scan) into the target. If the value of FASTDATA[SPrAcc] shifted out is "1" then an access was pending when you started the scan and it is now complete. + +If SPrAcc is 0 then no access was pending to the fastdata area. (Repeat attempt to complete the access you expect for this data word. Timeout if you think the access is "long overdue" as something unexpected has happened.) + + - Upload (CPU -> dongle) : +You shift "dummy" DATA and FASTDATA[SPrAcc] = 0 (33 bit scan) into the target. If the value of FASTDATA[SPrAcc] shifted out is "1" then an access was pending when you started the scan and it is now complete. The "upload" is the DATA shifted out of the target. + +If SPrAcc is 0 then no access was pending to the fastdata area. (Repeat attempt to complete the access you expect for this data word. Timeout if you think the access is "long overdue" as something unexpected has happened.) + +Basically, if checking first (before scan) if CPU is pending on FASTDATA access (PrAcc is "1"), like this + +@code +wait(ready); +do_scan(); +@endcode + +which is inefficient, we should do it like this : + +@code +BEGIN : + do_scan(); + if (!was_ready) + goto BEGIN; +@endcode + +by checking SPrAcc that we shifted out. + +If some FASTDATA write fails, OpenOCD will continue with it's loop (on the host side), but CPU will rest pending (on the target side) +waiting for correct FASTDATA write. + +Since OpenOCD goes ahead, it will eventually finish it's loop, and proceede to check if CPU took all the data. But since CPU did not took all the data, +it is still turns in handler's loop in RAM, stalling on Fastdata area so this check : + +@code +address = 0; +mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); +retval = mips_ejtag_drscan_32(ejtag_info, &address); +if (retval != ERROR_OK) + return retval; + +if (address != MIPS32_PRACC_TEXT) + LOG_ERROR("mini program did not return to start"); +@endcode + +fails, and that gives us enough information of the failure. + +In this case, we can lower the JTAG frquency and try again, bacuse most probable reason of this failure is that we tried FASTDATA upload before CPU arrived to rise PrAcc (i.e. before it was pending on access). +However, the reasons for failure might be numerous : reset, exceptions which can occur in debug mode, bus hangs, etc. + +If lowering the JTAG freq does not work either, we can fall back to more robust solution with patch posted below. + +To summarize, FASTDATA communication goes as following : + +-# CPU jumps to Debug Exception Vector Location 0xFF200200 in dmseg and it stalls, pending and waiting for EJTAG to give it first debug instruction and signall it by putting PrAcc to "0" +-# When PrAcc goes to "0" CPU execute one opcode sent by EJTAG via DATA reg. Then it pends on next access, waiting for PrAcc to be put to "0" again +-# Following this game, OpenOCD first loads handler code in RAM, and then sends the jmp_code - instruction by instruction via DATA reg, which redirects CPU to handler previously set up in RAM +-# Once in RAM CPU does not pend on any instruction, but it executes all handler instructions untill first "fetch" to Fastdata area - then it stops and pends. +-# So - when it comes to any instruction (opcode) in this handler in RAM which reads (or writes) to Fastdata area (0xF..F20.0000 to 0xF..F20.000F), CPU stops (i.e. stalls access). + I.e. it stops on this lw opcode and waits to FASTDATA TAP command from the probe. +-# CPU continues only if OpenOCD shifted in SPrAcc "0" (and if the PrAcc was "1"). It shifts-out "1" to tell us that it was OK (processor was stalled, so it can complete the access), + and that it continued execution of the handler in RAM. +-# If PrAcc was not "1" CPU will not continue (go to next instruction), but will shift-out "0" and keep stalling on the same instruction of my handler in RAM. +-# When Fastdata loop is finished, CPU executes all following hadler instructions in RAM (prologue). +-# In the end of my handler in RAM, I jumps back to begining of Debug Exception Vector Location 0xFF200200 in dmseg. +-# When it jumps back to 0xFF200200 in dmseg processor stops and pends, waiting for OpenOCD to send it instruction via DATA reg and signal it by putting PrAcc to "0". + +*/ diff --git a/debuggers/openocd/doc/manual/target/notarm.txt b/debuggers/openocd/doc/manual/target/notarm.txt new file mode 100644 index 00000000..5d5be78c --- /dev/null +++ b/debuggers/openocd/doc/manual/target/notarm.txt @@ -0,0 +1,71 @@ +/** @page targetnotarm OpenOCD Non-ARM Targets + +This page describes outstanding issues w.r.t. non-ARM targets. + +@section targetnotarmflash Flash drivers + +The flash drivers contain ARM32 code that is used +to execute code on the target. + +This needs to be handled in some CPU independent +manner. + +The ocl and ecos flash drivers compile the flash +driver code to run on the target on the developer +machine. + +The ocl and ecos flash drivers should be unified +and instructions should be written on how to +compile the target flash drivers. Perhaps +using automake? + + +eCos has CFI driver that could probably be compiled +for all targets. The trick is to figure out a +way to make the compiled flash drivers work +on all target memory maps + sort out all the +little details + +@section targetnotarm32v64 32 vs. 64 bit + +Currently OpenOCD only supports 32 bit targets. + +Adding 64 bit support would be nice but there +hasn't been any call for it in the openocd development +mailing list + +@section targetnotarmsupport Target Support + +target.h is relatively CPU agnostic and +the intention is to move in the direction of less +instruction set specific. + +Non-CPU targets are also supported, but there isn't +a lot of activity on it in the mailing list currently. +An example is FPGA programming support via JTAG, +but also flash chips can be programmed directly +using JTAG. + +@section targetnotarmphy non-JTAG physical layer + +JTAG is not the only physical protocol used to talk to +CPUs. + +OpenOCD does not today have targets that use non-JTAG. + +The actual physical layer is a relatively modest part +of the total OpenOCD system. + + +@section targetnotarmppc PowerPC + +there exists open source implementations of powerpc +target manipulation, but there hasn't been a lot +of activity in the mailing list. + +@section targetnotarmmips MIPS + +Currently OpenOCD has a MIPS target defined. This is the +first non-ARM example of a CPU target + + */ diff --git a/debuggers/openocd/doc/mdate-sh b/debuggers/openocd/doc/mdate-sh new file mode 100755 index 00000000..b3719cf7 --- /dev/null +++ b/debuggers/openocd/doc/mdate-sh @@ -0,0 +1,224 @@ +#!/bin/sh +# Get modification time of a file or directory and pretty-print it. + +scriptversion=2010-08-21.06; # UTC + +# Copyright (C) 1995-2013 Free Software Foundation, Inc. +# written by Ulrich Drepper , June 1995 +# +# 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, 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, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +fi + +case $1 in + '') + echo "$0: No file. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: mdate-sh [--help] [--version] FILE + +Pretty-print the modification day of FILE, in the format: +1 January 1970 + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "mdate-sh $scriptversion" + exit $? + ;; +esac + +error () +{ + echo "$0: $1" >&2 + exit 1 +} + + +# Prevent date giving response in another language. +LANG=C +export LANG +LC_ALL=C +export LC_ALL +LC_TIME=C +export LC_TIME + +# GNU ls changes its time format in response to the TIME_STYLE +# variable. Since we cannot assume 'unset' works, revert this +# variable to its documented default. +if test "${TIME_STYLE+set}" = set; then + TIME_STYLE=posix-long-iso + export TIME_STYLE +fi + +save_arg1=$1 + +# Find out how to get the extended ls output of a file or directory. +if ls -L /dev/null 1>/dev/null 2>&1; then + ls_command='ls -L -l -d' +else + ls_command='ls -l -d' +fi +# Avoid user/group names that might have spaces, when possible. +if ls -n /dev/null 1>/dev/null 2>&1; then + ls_command="$ls_command -n" +fi + +# A 'ls -l' line looks as follows on OS/2. +# drwxrwx--- 0 Aug 11 2001 foo +# This differs from Unix, which adds ownership information. +# drwxrwx--- 2 root root 4096 Aug 11 2001 foo +# +# To find the date, we split the line on spaces and iterate on words +# until we find a month. This cannot work with files whose owner is a +# user named "Jan", or "Feb", etc. However, it's unlikely that '/' +# will be owned by a user whose name is a month. So we first look at +# the extended ls output of the root directory to decide how many +# words should be skipped to get the date. + +# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. +set x`$ls_command /` + +# Find which argument is the month. +month= +command= +until test $month +do + test $# -gt 0 || error "failed parsing '$ls_command /' output" + shift + # Add another shift to the command. + command="$command shift;" + case $1 in + Jan) month=January; nummonth=1;; + Feb) month=February; nummonth=2;; + Mar) month=March; nummonth=3;; + Apr) month=April; nummonth=4;; + May) month=May; nummonth=5;; + Jun) month=June; nummonth=6;; + Jul) month=July; nummonth=7;; + Aug) month=August; nummonth=8;; + Sep) month=September; nummonth=9;; + Oct) month=October; nummonth=10;; + Nov) month=November; nummonth=11;; + Dec) month=December; nummonth=12;; + esac +done + +test -n "$month" || error "failed parsing '$ls_command /' output" + +# Get the extended ls output of the file or directory. +set dummy x`eval "$ls_command \"\\\$save_arg1\""` + +# Remove all preceding arguments +eval $command + +# Because of the dummy argument above, month is in $2. +# +# On a POSIX system, we should have +# +# $# = 5 +# $1 = file size +# $2 = month +# $3 = day +# $4 = year or time +# $5 = filename +# +# On Darwin 7.7.0 and 7.6.0, we have +# +# $# = 4 +# $1 = day +# $2 = month +# $3 = year or time +# $4 = filename + +# Get the month. +case $2 in + Jan) month=January; nummonth=1;; + Feb) month=February; nummonth=2;; + Mar) month=March; nummonth=3;; + Apr) month=April; nummonth=4;; + May) month=May; nummonth=5;; + Jun) month=June; nummonth=6;; + Jul) month=July; nummonth=7;; + Aug) month=August; nummonth=8;; + Sep) month=September; nummonth=9;; + Oct) month=October; nummonth=10;; + Nov) month=November; nummonth=11;; + Dec) month=December; nummonth=12;; +esac + +case $3 in + ???*) day=$1;; + *) day=$3; shift;; +esac + +# Here we have to deal with the problem that the ls output gives either +# the time of day or the year. +case $3 in + *:*) set `date`; eval year=\$$# + case $2 in + Jan) nummonthtod=1;; + Feb) nummonthtod=2;; + Mar) nummonthtod=3;; + Apr) nummonthtod=4;; + May) nummonthtod=5;; + Jun) nummonthtod=6;; + Jul) nummonthtod=7;; + Aug) nummonthtod=8;; + Sep) nummonthtod=9;; + Oct) nummonthtod=10;; + Nov) nummonthtod=11;; + Dec) nummonthtod=12;; + esac + # For the first six month of the year the time notation can also + # be used for files modified in the last year. + if (expr $nummonth \> $nummonthtod) > /dev/null; + then + year=`expr $year - 1` + fi;; + *) year=$3;; +esac + +# The result. +echo $day $month $year + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/debuggers/openocd/doc/openocd.1 b/debuggers/openocd/doc/openocd.1 new file mode 100644 index 00000000..4278486e --- /dev/null +++ b/debuggers/openocd/doc/openocd.1 @@ -0,0 +1,103 @@ +.TH "OPENOCD" "1" "November 24, 2009" +.SH "NAME" +openocd \- A free and open on\-chip debugging, in\-system programming and +boundary\-scan testing tool for ARM and MIPS systems +.SH "SYNOPSIS" +.B openocd \fR[\fB\-fsdlcphv\fR] [\fB\-\-file\fR ] [\fB\-\-search\fR ] [\fB\-\-debug\fR ] [\fB\-\-log_output\fR ] [\fB\-\-command\fR ] [\fB\-\-pipe\fR] [\fB\-\-help\fR] [\fB\-\-version\fR] +.SH "DESCRIPTION" +.B OpenOCD +is an on\-chip debugging, in\-system programming and boundary\-scan +testing tool for various ARM and MIPS systems. +.PP +The debugger uses an IEEE 1149\-1 compliant JTAG TAP bus master to access +on\-chip debug functionality available on ARM based microcontrollers or +system-on-chip solutions. For MIPS systems the EJTAG interface is supported. +.PP +User interaction is realized through a telnet command line interface, +a gdb (the GNU debugger) remote protocol server, and a simplified RPC +connection that can be used to interface with OpenOCD's Jim Tcl engine. +.PP +OpenOCD supports various different types of JTAG interfaces/programmers, +please check the \fIopenocd\fR info page for the complete list. +.SH "OPTIONS" +.TP +.B "\-f, \-\-file " +This is a shortcut for a \fB\-c "[script \fI\fB]"\fR +command, using a search path to load the configuration file +.IR . +In order to specify multiple config files, you can use multiple +.B \-\-file +arguments. If no such \fB\-c\fR +options are included, the first config file +.B openocd.cfg +in the search path will be used. +.TP +.B "\-s, \-\-search " +Add +.I +to the search path used for config files and scripts. +The search path begins with the current directory, +then includes these additional directories before other +components such as the standard OpenOCD script libraries. +.TP +.B "\-d, \-\-debug " +Set debug level. Possible values are: +.br +.RB " * " 0 " (errors)" +.br +.RB " * " 1 " (warnings)" +.br +.RB " * " 2 " (informational messages)" +.br +.RB " * " 3 " (debug messages)" +.br +The default level is +.BR 2 . +.TP +.B "\-l, \-\-log_output " +Redirect log output to the file +.IR . +Per default the log output is printed on +.BR stderr . +.TP +.B "\-c, \-\-command " +Add the command +.I +to a list of commands executed on server startup. +Note that you will need to explicitly invoke +.I init +if the command requires access to a target or flash. +.TP +.B "\-p, \-\-pipe" +Use pipes when talking to gdb. +.TP +.B "\-h, \-\-help" +Show a help text and exit. +.TP +.B "\-v, \-\-version" +Show version information and exit. +.SH "BUGS" +Please report any bugs on the mailing list at +.BR openocd\-devel@lists.sourceforge.net . +.SH "LICENCE" +.B OpenOCD +is covered by the GNU General Public License (GPL), version 2 or later. +.SH "SEE ALSO" +.BR jtag (1) +.PP +The full documentation for +.B openocd +is maintained as a Texinfo manual. If the +.BR info +(or +.BR pinfo ) +and +.BR openocd +programs are properly installed at your site, the command +.B info openocd +should give you access to the complete manual. +.SH "AUTHORS" +Please see the file AUTHORS. +.PP +This manual page was written by Uwe Hermann . +It is licensed under the terms of the GNU GPL (version 2 or later). diff --git a/debuggers/openocd/doc/openocd.info b/debuggers/openocd/doc/openocd.info new file mode 100644 index 00000000..c21cbd37 --- /dev/null +++ b/debuggers/openocd/doc/openocd.info @@ -0,0 +1,109 @@ +This is openocd.info, produced by makeinfo version 5.1 from +openocd.texi. + +This User's Guide documents release 0.7.0, dated 4 May 2013, of the Open +On-Chip Debugger (OpenOCD). + + * Copyright (C) 2008 The OpenOCD Project + * Copyright (C) 2007-2008 Spencer Oliver + * Copyright (C) 2008-2010 Oyvind Harboe + * Copyright (C) 2008 Duane Ellis + * Copyright (C) 2009-2010 David Brownell + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, with no Front-Cover Texts, + and with no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". +INFO-DIR-SECTION Development +START-INFO-DIR-ENTRY +* OpenOCD: (openocd). OpenOCD User's Guide +END-INFO-DIR-ENTRY + + +Indirect: +openocd.info-1: 990 +openocd.info-2: 301821 + +Tag Table: +(Indirect) +Node: Top990 +Node: About3496 +Node: Developers7842 +Node: Debug Adapter Hardware10510 +Node: About Jim-Tcl21044 +Node: Running23186 +Node: OpenOCD Project Setup28081 +Ref: OpenOCD Project Setup-Footnote-147973 +Ref: OpenOCD Project Setup-Footnote-248313 +Ref: OpenOCD Project Setup-Footnote-348581 +Node: Config File Guidelines48909 +Ref: theinitboardprocedure72069 +Ref: definecputargetsworkinginsmp78860 +Ref: theinittargetsprocedure83294 +Ref: translatingconfigurationfiles86553 +Ref: Config File Guidelines-Footnote-187780 +Node: Daemon Configuration87855 +Ref: configurationstage88177 +Ref: enteringtherunstage89029 +Ref: tcpipports91478 +Ref: gdbconfiguration93724 +Ref: gdbbreakpointoverride94039 +Ref: gdbflashprogram94414 +Ref: eventpolling95289 +Node: Debug Adapter Configuration97725 +Ref: jtagspeed125585 +Node: Reset Configuration128543 +Ref: srstandtrstissues131471 +Node: TAP Declaration143516 +Ref: enablinganddisablingtaps155076 +Ref: autoprobing157723 +Ref: TAP Declaration-Footnote-1160414 +Node: CPU Configuration160614 +Ref: targettypes164761 +Ref: targetconfiguration166765 +Ref: targetcurstate175679 +Ref: targetevents176920 +Node: Flash Commands181766 +Ref: norconfiguration183298 +Ref: flashprogrammingcommands185957 +Ref: flashprotect191530 +Ref: program191888 +Ref: flashdriverlist192139 +Ref: at91sam3196024 +Ref: Flash Commands-Footnote-1221282 +Ref: Flash Commands-Footnote-2221448 +Node: Flash Programming221613 +Node: NAND Flash Commands223061 +Ref: nandconfiguration226029 +Ref: nanddriverlist236404 +Node: PLD/FPGA Commands241099 +Node: General Commands243162 +Ref: debuglevel245109 +Ref: targetstatehandling246035 +Ref: resetcommand249687 +Ref: memoryaccess251957 +Ref: imageaccess253584 +Node: Architecture and Core Commands257966 +Ref: armhardwaretracing258436 +Ref: traceportdrivers266354 +Ref: arm9vectorcatch274250 +Ref: xscalevectorcatch282653 +Ref: softwaredebugmessagesandtracing288914 +Node: JTAG Commands292381 +Node: Boundary Scan Commands301821 +Node: TFTP304271 +Node: GDB and OpenOCD305145 +Ref: programmingusinggdb310040 +Ref: usingopenocdsmpwithgdb311483 +Node: Tcl Scripting API312914 +Node: FAQ315554 +Ref: faqrtck315664 +Ref: faqtaporder328202 +Node: Tcl Crash Course329965 +Node: License341963 +Node: OpenOCD Concept Index364373 +Node: Command and Driver Index382304 + +End Tag Table diff --git a/debuggers/openocd/doc/openocd.info-1 b/debuggers/openocd/doc/openocd.info-1 new file mode 100644 index 00000000..56f887d0 --- /dev/null +++ b/debuggers/openocd/doc/openocd.info-1 @@ -0,0 +1,6641 @@ +This is openocd.info, produced by makeinfo version 5.1 from +openocd.texi. + +This User's Guide documents release 0.7.0, dated 4 May 2013, of the Open +On-Chip Debugger (OpenOCD). + + * Copyright (C) 2008 The OpenOCD Project + * Copyright (C) 2007-2008 Spencer Oliver + * Copyright (C) 2008-2010 Oyvind Harboe + * Copyright (C) 2008 Duane Ellis + * Copyright (C) 2009-2010 David Brownell + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, with no Front-Cover Texts, + and with no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". +INFO-DIR-SECTION Development +START-INFO-DIR-ENTRY +* OpenOCD: (openocd). OpenOCD User's Guide +END-INFO-DIR-ENTRY + + +File: openocd.info, Node: Top, Next: About, Up: (dir) + +OpenOCD User's Guide +******************** + +This User's Guide documents release 0.7.0, dated 4 May 2013, of the Open +On-Chip Debugger (OpenOCD). + + * Copyright (C) 2008 The OpenOCD Project + * Copyright (C) 2007-2008 Spencer Oliver + * Copyright (C) 2008-2010 Oyvind Harboe + * Copyright (C) 2008 Duane Ellis + * Copyright (C) 2009-2010 David Brownell + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, with no Front-Cover Texts, + and with no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". + +* Menu: + +* About:: About OpenOCD +* Developers:: OpenOCD Developer Resources +* Debug Adapter Hardware:: Debug Adapter Hardware +* About Jim-Tcl:: About Jim-Tcl +* Running:: Running OpenOCD +* OpenOCD Project Setup:: OpenOCD Project Setup +* Config File Guidelines:: Config File Guidelines +* Daemon Configuration:: Daemon Configuration +* Debug Adapter Configuration:: Debug Adapter Configuration +* Reset Configuration:: Reset Configuration +* TAP Declaration:: TAP Declaration +* CPU Configuration:: CPU Configuration +* Flash Commands:: Flash Commands +* Flash Programming:: Flash Programming +* NAND Flash Commands:: NAND Flash Commands +* PLD/FPGA Commands:: PLD/FPGA Commands +* General Commands:: General Commands +* Architecture and Core Commands:: Architecture and Core Commands +* JTAG Commands:: JTAG Commands +* Boundary Scan Commands:: Boundary Scan Commands +* TFTP:: TFTP +* GDB and OpenOCD:: Using GDB and OpenOCD +* Tcl Scripting API:: Tcl Scripting API +* FAQ:: Frequently Asked Questions +* Tcl Crash Course:: Tcl Crash Course +* License:: GNU Free Documentation License + +* OpenOCD Concept Index:: Concept Index +* Command and Driver Index:: Command and Driver Index + + +File: openocd.info, Node: About, Next: Developers, Prev: Top, Up: Top + +About +***** + +OpenOCD was created by Dominic Rath as part of a diploma thesis written +at the University of Applied Sciences Augsburg +(). Since that time, the project has grown +into an active open-source project, supported by a diverse community of +software and hardware developers from around the world. + +What is OpenOCD? +================ + +The Open On-Chip Debugger (OpenOCD) aims to provide debugging, in-system +programming and boundary-scan testing for embedded target devices. + +It does so with the assistance of a "debug adapter", which is a small +hardware module which helps provide the right kind of electrical +signaling to the target being debugged. These are required since the +debug host (on which OpenOCD runs) won't usually have native support for +such signaling, or the connector needed to hook up to the target. + +Such debug adapters support one or more "transport" protocols, each of +which involves different electrical signaling (and uses different +messaging protocols on top of that signaling). There are many types of +debug adapter, and little uniformity in what they are called. (There +are also product naming differences.) + +These adapters are sometimes packaged as discrete dongles, which may +generically be called "hardware interface dongles". Some development +boards also integrate them directly, which may let the development board +can be directly connected to the debug host over USB (and sometimes also +to power it over USB). + +For example, a "JTAG Adapter" supports JTAG signaling, and is used to +communicate with JTAG (IEEE 1149.1) compliant TAPs on your target board. +A "TAP" is a "Test Access Port", a module which processes special +instructions and data. TAPs are daisy-chained within and between chips +and boards. JTAG supports debugging and boundary scan operations. + +There are also "SWD Adapters" that support Serial Wire Debug (SWD) +signaling to communicate with some newer ARM cores, as well as debug +adapters which support both JTAG and SWD transports. SWD only supports +debugging, whereas JTAG also supports boundary scan operations. + +For some chips, there are also "Programming Adapters" supporting special +transports used only to write code to flash memory, without support for +on-chip debugging or boundary scan. (At this writing, OpenOCD does not +support such non-debug adapters.) + +Dongles: OpenOCD currently supports many types of hardware dongles: USB +based, parallel port based, and other standalone boxes that run OpenOCD +internally. *Note Debug Adapter Hardware::. + +GDB Debug: It allows ARM7 (ARM7TDMI and ARM720t), ARM9 (ARM920T, +ARM922T, ARM926EJ-S, ARM966E-S), XScale (PXA25x, IXP42x) and Cortex-M3 +(Stellaris LM3, ST STM32 and Energy Micro EFM32) based cores to be +debugged via the GDB protocol. + +Flash Programing: Flash writing is supported for external CFI compatible +NOR flashes (Intel and AMD/Spansion command set) and several internal +flashes (LPC1700, LPC1800, LPC2000, LPC4300, AT91SAM7, AT91SAM3U, STR7x, +STR9x, LM3, STM32x and EFM32). Preliminary support for various NAND +flash controllers (LPC3180, Orion, S3C24xx, more) controller is +included. + +OpenOCD Web Site +================ + +The OpenOCD web site provides the latest public news from the community: + + + +Latest User's Guide: +==================== + +The user's guide you are now reading may not be the latest one +available. A version for more recent code may be available. Its HTML +form is published regularly at: + + + +PDF form is likewise published at: + + + +OpenOCD User's Forum +==================== + +There is an OpenOCD forum (phpBB) hosted by SparkFun, which might be +helpful to you. Note that if you want anything to come to the attention +of developers, you should post it to the OpenOCD Developer Mailing List +instead of this forum. + + + +OpenOCD User's Mailing List +=========================== + +The OpenOCD User Mailing List provides the primary means of +communication between users: + + + +OpenOCD IRC +=========== + +Support can also be found on irc: + + +File: openocd.info, Node: Developers, Next: Debug Adapter Hardware, Prev: About, Up: Top + +1 OpenOCD Developer Resources +***************************** + +If you are interested in improving the state of OpenOCD's debugging and +testing support, new contributions will be welcome. Motivated +developers can produce new target, flash or interface drivers, improve +the documentation, as well as more conventional bug fixes and +enhancements. + +The resources in this chapter are available for developers wishing to +explore or expand the OpenOCD source code. + +1.1 OpenOCD GIT Repository +========================== + +During the 0.3.x release cycle, OpenOCD switched from Subversion to a +GIT repository hosted at SourceForge. The repository URL is: + + + +or via http + + + +You may prefer to use a mirror and the HTTP protocol: + + + +With standard GIT tools, use 'git clone' to initialize a local +repository, and 'git pull' to update it. There are also gitweb pages +letting you browse the repository with a web browser, or download +arbitrary snapshots without needing a GIT client: + + + +The 'README' file contains the instructions for building the project +from the repository or a snapshot. + +Developers that want to contribute patches to the OpenOCD system are +strongly encouraged to work against mainline. Patches created against +older versions may require additional work from their submitter in order +to be updated for newer releases. + +1.2 Doxygen Developer Manual +============================ + +During the 0.2.x release cycle, the OpenOCD project began providing a +Doxygen reference manual. This document contains more technical +information about the software internals, development processes, and +similar documentation: + + + +This document is a work-in-progress, but contributions would be welcome +to fill in the gaps. All of the source files are provided in-tree, +listed in the Doxyfile configuration in the top of the source tree. + +1.3 OpenOCD Developer Mailing List +================================== + +The OpenOCD Developer Mailing List provides the primary means of +communication between developers: + + + +Discuss and submit patches to this list. The 'HACKING' file contains +basic information about how to prepare patches. + +1.4 OpenOCD Bug Database +======================== + +During the 0.4.x release cycle the OpenOCD project team began using Trac +for its bug database: + + + + +File: openocd.info, Node: Debug Adapter Hardware, Next: About Jim-Tcl, Prev: Developers, Up: Top + +2 Debug Adapter Hardware +************************ + +Defined: dongle: A small device that plugins into a computer and serves +as an adapter .... [snip] + +In the OpenOCD case, this generally refers to a small adapter that +attaches to your computer via USB or the Parallel Printer Port. One +exception is the Zylin ZY1000, packaged as a small box you attach via an +ethernet cable. The Zylin ZY1000 has the advantage that it does not +require any drivers to be installed on the developer PC. It also has a +built in web interface. It supports RTCK/RCLK or adaptive clocking and +has a built in relay to power cycle targets remotely. + +2.1 Choosing a Dongle +===================== + +There are several things you should keep in mind when choosing a dongle. + + 1. Transport Does it support the kind of communication that you need? + OpenOCD focusses mostly on JTAG. Your version may also support + other ways to communicate with target devices. + 2. Voltage What voltage is your target - 1.8, 2.8, 3.3, or 5V? Does + your dongle support it? You might need a level converter. + 3. Pinout What pinout does your target board use? Does your dongle + support it? You may be able to use jumper wires, or an "octopus" + connector, to convert pinouts. + 4. Connection Does your computer have the USB, printer, or Ethernet + port needed? + 5. RTCK Do you expect to use it with ARM chips and boards with RTCK + support? Also known as "adaptive clocking" + +2.2 Stand alone Systems +======================= + +ZY1000 See: + +Technically, not a dongle, but a standalone box. The ZY1000 has the +advantage that it does not require any drivers installed on the +developer PC. It also has a built in web interface. It supports +RTCK/RCLK or adaptive clocking and has a built in relay to power cycle +targets remotely. + +2.3 USB FT2232 Based +==================== + +There are many USB JTAG dongles on the market, many of them are based on +a chip from "Future Technology Devices International" (FTDI) known as +the FTDI FT2232; this is a USB full speed (12 Mbps) chip. See: + for more information. In summer 2009, USB +high speed (480 Mbps) versions of these FTDI chips are starting to +become available in JTAG adapters. Around 2012 a new variant appeared - +FT232H - this is a single-channel version of FT2232H. (Adapters using +those high speed FT2232H or FT232H chips may support adaptive clocking.) + +The FT2232 chips are flexible enough to support some other transport +options, such as SWD or the SPI variants used to program some chips. +They have two communications channels, and one can be used for a UART +adapter at the same time the other one is used to provide a debug +adapter. + +Also, some development boards integrate an FT2232 chip to serve as a +built-in low cost debug adapter and usb-to-serial solution. + + * usbjtag + Link + + * jtagkey + See: + * jtagkey2 + See: + * oocdlink + See: By Joern Kaipf + * signalyzer + See: + * Stellaris Eval Boards + See: - The Stellaris eval boards bundle + FT2232-based JTAG and SWD support, which can be used to debug the + Stellaris chips. Using separate JTAG adapters is optional. These + boards can also be used in a "pass through" mode as JTAG adapters + to other target boards, disabling the Stellaris chip. + * TI/Luminary ICDI + See: - TI/Luminary In-Circuit Debug Interface + (ICDI) Boards are included in Stellaris LM3S9B9x Evaluation Kits. + Like the non-detachable FT2232 support on the other Stellaris eval + boards, they can be used to debug other target boards. + * olimex-jtag + See: + * Flyswatter/Flyswatter2 + See: + * turtelizer2 + See: Turtelizer 2 + (http://www.ethernut.de/en/hardware/turtelizer/index.html), or + + * comstick + Link: + * stm32stick + Link + * axm0432_jtag + Axiom AXM-0432 Link - NOTE: This JTAG does + not appear to be available anymore as of April 2012. + * cortino + Link + * dlp-usb1232h + Link + * digilent-hs1 + Link + * opendous + Link FT2232H-based + (OpenHardware). + * JTAG-lock-pick Tiny 2 + Link FT232H-based + +2.4 USB-JTAG / Altera USB-Blaster compatibles +============================================= + +These devices also show up as FTDI devices, but are not +protocol-compatible with the FT2232 devices. They are, however, +protocol-compatible among themselves. USB-JTAG devices typically +consist of a FT245 followed by a CPLD that understands a particular +protocol, or emulate this protocol using some other hardware. + +They may appear under different USB VID/PID depending on the particular +product. The driver can be configured to search for any VID/PID pair +(see the section on driver commands). + + * USB-JTAG Kolja Waschk's USB Blaster-compatible adapter + Link: + * Altera USB-Blaster + Link: + +2.5 USB JLINK based +=================== + +There are several OEM versions of the Segger JLINK adapter. It is an +example of a micro controller based JTAG adapter, it uses an AT91SAM764 +internally. + + * ATMEL SAMICE Only works with ATMEL chips! + Link: + + * SEGGER JLINK + Link: + * IAR J-Link + Link: + + +2.6 USB RLINK based +=================== + +Raisonance has an adapter called RLink. It exists in a stripped-down +form on the STM32 Primer, permanently attached to the JTAG lines. It +also exists on the STM32 Primer2, but that is wired for SWD and not +JTAG, thus not supported. + + * Raisonance RLink + Link: + + * STM32 Primer + Link: + * STM32 Primer2 + Link: + +2.7 USB ST-LINK based +===================== + +ST Micro has an adapter called ST-LINK. They only work with ST Micro +chips, notably STM32 and STM8. + + * ST-LINK + This is available standalone and as part of some kits, eg. + STM32VLDISCOVERY. + Link: + * ST-LINK/V2 + This is available standalone and as part of some kits, eg. + STM32F4DISCOVERY. + Link: + +For info the original ST-LINK enumerates using the mass storage usb +class, however it's implementation is completely broken. The result is +this causes issues under linux. The simplest solution is to get linux +to ignore the ST-LINK using one of the following methods: + * modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i + * add "options usb-storage quirks=483:3744:i" to /etc/modprobe.conf + +2.8 USB TI/Stellaris ICDI based +=============================== + +Texas Instruments has an adapter called ICDI. It is not to be confused +with the FTDI based adapters that were originally fitted to their +evaluation boards. This is the adapter fitted to the Stellaris +LaunchPad. + +2.9 USB Other +============= + + * USBprog + Link: - which uses an Atmel + MEGA32 and a UBN9604 + + * USB - Presto + Link: + + * Versaloon-Link + Link: + + * ARM-JTAG-EW + Link: + + * Buspirate + Link: + + * opendous + Link: - which uses an + AT90USB162 + + * estick + Link: + + * Keil ULINK v1 + Link: + +2.10 IBM PC Parallel Printer Port Based +======================================= + +The two well known "JTAG Parallel Ports" cables are the Xilnx DLC5 and +the Macraigor Wiggler. There are many clones and variations of these on +the market. + +Note that parallel ports are becoming much less common, so if you have +the choice you should probably avoid these adapters in favor of +USB-based ones. + + * Wiggler - There are many clones of this. + Link: + + * DLC5 - From XILINX - There are many clones of this + Link: Search the web for: "XILINX DLC5" - it is no longer produced, + PDF schematics are easily found and it is easy to make. + + * Amontec - JTAG Accelerator + Link: + + * GW16402 + Link: + + + * Wiggler2 + Link: + + + * Wiggler_ntrst_inverted + Yet another variation - See the source code, src/jtag/parport.c + + * old_amt_wiggler + Unknown - probably not on the market today + + * arm-jtag + Link: Most likely + [another wiggler clone] + + * chameleon + Link: + + * Triton + Unknown. + + * Lattice + ispDownload from Lattice Semiconductor + + + * flashlink + From ST Microsystems; + Link: + + +2.11 Other... +============= + + * ep93xx + An EP93xx based Linux machine using the GPIO pins directly. + + * at91rm9200 + Like the EP93xx - but an ATMEL AT91RM9200 based solution using the + GPIO pins on the chip. + + +File: openocd.info, Node: About Jim-Tcl, Next: Running, Prev: Debug Adapter Hardware, Up: Top + +3 About Jim-Tcl +*************** + +OpenOCD uses a small "Tcl Interpreter" known as Jim-Tcl. This +programming language provides a simple and extensible command +interpreter. + +All commands presented in this Guide are extensions to Jim-Tcl. You can +use them as simple commands, without needing to learn much of anything +about Tcl. Alternatively, can write Tcl programs with them. + +You can learn more about Jim at its website, . +There is an active and responsive community, get on the mailing list if +you have any questions. Jim-Tcl maintainers also lurk on the OpenOCD +mailing list. + + * Jim vs. Tcl + Jim-Tcl is a stripped down version of the well known Tcl language, + which can be found here: . Jim-Tcl has far + fewer features. Jim-Tcl is several dozens of .C files and .H files + and implements the basic Tcl command set. In contrast: Tcl 8.6 is + a 4.2 MB .zip file containing 1540 files. + + * Missing Features + Our practice has been: Add/clone the real Tcl feature if/when + needed. We welcome Jim-Tcl improvements, not bloat. Also there + are a large number of optional Jim-Tcl features that are not + enabled in OpenOCD. + + * Scripts + OpenOCD configuration scripts are Jim-Tcl Scripts. OpenOCD's + command interpreter today is a mixture of (newer) Jim-Tcl commands, + and (older) the orginal command interpreter. + + * Commands + At the OpenOCD telnet command line (or via the GDB monitor command) + one can type a Tcl for() loop, set variables, etc. Some of the + commands documented in this guide are implemented as Tcl scripts, + from a 'startup.tcl' file internal to the server. + + * Historical Note + Jim-Tcl was introduced to OpenOCD in spring 2008. Fall 2010, + before OpenOCD 0.5 release OpenOCD switched to using Jim Tcl as a + git submodule, which greatly simplified upgrading Jim Tcl to + benefit from new features and bugfixes in Jim Tcl. + + * Need a crash course in Tcl? + *Note Tcl Crash Course::. + + +File: openocd.info, Node: Running, Next: OpenOCD Project Setup, Prev: About Jim-Tcl, Up: Top + +4 Running +********* + +Properly installing OpenOCD sets up your operating system to grant it +access to the debug adapters. On Linux, this usually involves +installing a file in '/etc/udev/rules.d,' so OpenOCD has permissions. +MS-Windows needs complex and confusing driver configuration for every +peripheral. Such issues are unique to each operating system, and are +not detailed in this User's Guide. + +Then later you will invoke the OpenOCD server, with various options to +tell it how each debug session should work. The '--help' option shows: +bash$ openocd --help + +--help | -h display this help +--version | -v display OpenOCD version +--file | -f use configuration file +--search | -s dir to search for config files and scripts +--debug | -d set debug level <0-3> +--log_output | -l redirect log output to file +--command | -c run + +If you don't give any '-f' or '-c' options, OpenOCD tries to read the +configuration file 'openocd.cfg'. To specify one or more different +configuration files, use '-f' options. For example: + + openocd -f config1.cfg -f config2.cfg -f config3.cfg + +Configuration files and scripts are searched for in + 1. the current directory, + 2. any search dir specified on the command line using the '-s' option, + 3. any search dir specified using the 'add_script_search_dir' command, + 4. '$HOME/.openocd' (not on Windows), + 5. the site wide script library '$pkgdatadir/site' and + 6. the OpenOCD-supplied script library '$pkgdatadir/scripts'. +The first found file with a matching file name will be used. + + Note: Don't try to use configuration script names or paths which + include the "#" character. That character begins Tcl comments. + +4.1 Simple setup, no customization +================================== + +In the best case, you can use two scripts from one of the script +libraries, hook up your JTAG adapter, and start the server ... and your +JTAG setup will just work "out of the box". Always try to start by +reusing those scripts, but assume you'll need more customization even if +this works. *Note OpenOCD Project Setup::. + +If you find a script for your JTAG adapter, and for your board or +target, you may be able to hook up your JTAG adapter then start the +server like: + + openocd -f interface/ADAPTER.cfg -f board/MYBOARD.cfg + +You might also need to configure which reset signals are present, using +'-c 'reset_config trst_and_srst'' or something similar. If all goes +well you'll see output something like + + Open On-Chip Debugger 0.4.0 (2010-01-14-15:06) + For bug reports, read + http://openocd.sourceforge.net/doc/doxygen/bugs.html + Info : JTAG tap: lm3s.cpu tap/device found: 0x3ba00477 + (mfg: 0x23b, part: 0xba00, ver: 0x3) + +Seeing that "tap/device found" message, and no warnings, means the JTAG +communication is working. That's a key milestone, but you'll probably +need more project-specific setup. + +4.2 What OpenOCD does as it starts +================================== + +OpenOCD starts by processing the configuration commands provided on the +command line or, if there were no '-c command' or '-f file.cfg' options +given, in 'openocd.cfg'. *Note Configuration Stage: configurationstage. +At the end of the configuration stage it verifies the JTAG scan chain +defined using those commands; your configuration should ensure that this +always succeeds. Normally, OpenOCD then starts running as a daemon. +Alternatively, commands may be used to terminate the configuration stage +early, perform work (such as updating some flash memory), and then shut +down without acting as a daemon. + +Once OpenOCD starts running as a daemon, it waits for connections from +clients (Telnet, GDB, Other) and processes the commands issued through +those channels. + +If you are having problems, you can enable internal debug messages via +the '-d' option. + +Also it is possible to interleave Jim-Tcl commands w/config scripts +using the '-c' command line switch. + +To enable debug output (when reporting problems or working on OpenOCD +itself), use the '-d' command line switch. This sets the 'debug_level' +to "3", outputting the most information, including debug messages. The +default setting is "2", outputting only informational messages, warnings +and errors. You can also change this setting from within a telnet or +gdb session using 'debug_level' (*note debug_level: debuglevel.). + +You can redirect all output from the daemon to a file using the '-l +' switch. + +Note! OpenOCD will launch the GDB & telnet server even if it can not +establish a connection with the target. In general, it is possible for +the JTAG controller to be unresponsive until the target is set up +correctly via e.g. GDB monitor commands in a GDB init script. + + +File: openocd.info, Node: OpenOCD Project Setup, Next: Config File Guidelines, Prev: Running, Up: Top + +5 OpenOCD Project Setup +*********************** + +To use OpenOCD with your development projects, you need to do more than +just connecting the JTAG adapter hardware (dongle) to your development +board and then starting the OpenOCD server. You also need to configure +that server so that it knows about that adapter and board, and helps +your work. You may also want to connect OpenOCD to GDB, possibly using +Eclipse or some other GUI. + +5.1 Hooking up the JTAG Adapter +=============================== + +Today's most common case is a dongle with a JTAG cable on one side (such +as a ribbon cable with a 10-pin or 20-pin IDC connector) and a USB cable +on the other. Instead of USB, some cables use Ethernet; older ones may +use a PC parallel port, or even a serial port. + + 1. _Start with power to your target board turned off_, and nothing + connected to your JTAG adapter. If you're particularly paranoid, + unplug power to the board. It's important to have the ground + signal properly set up, unless you are using a JTAG adapter which + provides galvanic isolation between the target board and the + debugging host. + + 2. _Be sure it's the right kind of JTAG connector._ If your dongle + has a 20-pin ARM connector, you need some kind of adapter (or + octopus, see below) to hook it up to boards using 14-pin or 10-pin + connectors ... or to 20-pin connectors which don't use ARM's + pinout. + + In the same vein, make sure the voltage levels are compatible. Not + all JTAG adapters have the level shifters needed to work with 1.2 + Volt boards. + + 3. _Be certain the cable is properly oriented_ or you might damage + your board. In most cases there are only two possible ways to + connect the cable. Connect the JTAG cable from your adapter to the + board. Be sure it's firmly connected. + + In the best case, the connector is keyed to physically prevent you + from inserting it wrong. This is most often done using a slot on + the board's male connector housing, which must match a key on the + JTAG cable's female connector. If there's no housing, then you + must look carefully and make sure pin 1 on the cable hooks up to + pin 1 on the board. Ribbon cables are frequently all grey except + for a wire on one edge, which is red. The red wire is pin 1. + + Sometimes dongles provide cables where one end is an "octopus" of + color coded single-wire connectors, instead of a connector block. + These are great when converting from one JTAG pinout to another, + but are tedious to set up. Use these with connector pinout + diagrams to help you match up the adapter signals to the right + board pins. + + 4. _Connect the adapter's other end_ once the JTAG cable is connected. + A USB, parallel, or serial port connector will go to the host which + you are using to run OpenOCD. For Ethernet, consult the + documentation and your network administrator. + + For USB based JTAG adapters you have an easy sanity check at this + point: does the host operating system see the JTAG adapter? If + that host is an MS-Windows host, you'll need to install a driver + before OpenOCD works. + + 5. _Connect the adapter's power supply, if needed._ This step is + primarily for non-USB adapters, but sometimes USB adapters need + extra power. + + 6. _Power up the target board._ Unless you just let the magic smoke + escape, you're now ready to set up the OpenOCD server so you can + use JTAG to work with that board. + +Talk with the OpenOCD server using telnet ('telnet localhost 4444' on +many systems) or GDB. *Note GDB and OpenOCD::. + +5.2 Project Directory +===================== + +There are many ways you can configure OpenOCD and start it up. + +A simple way to organize them all involves keeping a single directory +for your work with a given board. When you start OpenOCD from that +directory, it searches there first for configuration files, scripts, +files accessed through semihosting, and for code you upload to the +target board. It is also the natural place to write files, such as log +files and data you download from the board. + +5.3 Configuration Basics +======================== + +There are two basic ways of configuring OpenOCD, and a variety of ways +you can mix them. Think of the difference as just being how you start +the server: + + * Many '-f file' or '-c command' options on the command line + * No options, but a "user config file" in the current directory named + 'openocd.cfg' + +Here is an example 'openocd.cfg' file for a setup using a Signalyzer +FT2232-based JTAG adapter to talk to a board with an Atmel AT91SAM7X256 +microcontroller: + + source [find interface/signalyzer.cfg] + + # GDB can also flash my flash! + gdb_memory_map enable + gdb_flash_program enable + + source [find target/sam7x256.cfg] + +Here is the command line equivalent of that configuration: + + openocd -f interface/signalyzer.cfg \ + -c "gdb_memory_map enable" \ + -c "gdb_flash_program enable" \ + -f target/sam7x256.cfg + +You could wrap such long command lines in shell scripts, each supporting +a different development task. One might re-flash the board with a +specific firmware version. Another might set up a particular debugging +or run-time environment. + + Important: At this writing (October 2009) the command line method + has problems with how it treats variables. For example, after '-c + "set VAR value"', or doing the same in a script, the variable VAR + will have no value that can be tested in a later script. + +Here we will focus on the simpler solution: one user config file, +including basic configuration plus any TCL procedures to simplify your +work. + +5.4 User Config Files +===================== + +A user configuration file ties together all the parts of a project in +one place. One of the following will match your situation best: + + * Ideally almost everything comes from configuration files provided + by someone else. For example, OpenOCD distributes a 'scripts' + directory (probably in '/usr/share/openocd/scripts' on Linux). + Board and tool vendors can provide these too, as can individual + user sites; the '-s' command line option lets you say where to find + these files. (*Note Running::.) The AT91SAM7X256 example above + works this way. + + Three main types of non-user configuration file each have their own + subdirectory in the 'scripts' directory: + + 1. interface - one for each different debug adapter; + 2. board - one for each different board + 3. target - the chips which integrate CPUs and other JTAG TAPs + + Best case: include just two files, and they handle everything else. + The first is an interface config file. The second is + board-specific, and it sets up the JTAG TAPs and their GDB targets + (by deferring to some 'target.cfg' file), declares all flash + memory, and leaves you nothing to do except meet your deadline: + + source [find interface/olimex-jtag-tiny.cfg] + source [find board/csb337.cfg] + + Boards with a single microcontroller often won't need more than the + target config file, as in the AT91SAM7X256 example. That's because + there is no external memory (flash, DDR RAM), and the board + differences are encapsulated by application code. + + * Maybe you don't know yet what your board looks like to JTAG. Once + you know the 'interface.cfg' file to use, you may need help from + OpenOCD to discover what's on the board. Once you find the JTAG + TAPs, you can just search for appropriate target and board + configuration files ... or write your own, from the bottom up. + *Note Autoprobing: autoprobing. + + * You can often reuse some standard config files but need to write a + few new ones, probably a 'board.cfg' file. You will be using + commands described later in this User's Guide, and working with the + guidelines in the next chapter. + + For example, there may be configuration files for your JTAG adapter + and target chip, but you need a new board-specific config file + giving access to your particular flash chips. Or you might need to + write another target chip configuration file for a new chip built + around the Cortex M3 core. + + Note: When you write new configuration files, please submit + them for inclusion in the next OpenOCD release. For example, + a 'board/newboard.cfg' file will help the next users of that + board, and a 'target/newcpu.cfg' will help support users of + any board using that chip. + + * You may may need to write some C code. It may be as simple as a + supporting a new ft2232 or parport based adapter; a bit more + involved, like a NAND or NOR flash controller driver; or a big + piece of work like supporting a new chip architecture. + +Reuse the existing config files when you can. Look first in the +'scripts/boards' area, then 'scripts/targets'. You may find a board +configuration that's a good example to follow. + +When you write config files, separate the reusable parts (things every +user of that interface, chip, or board needs) from ones specific to your +environment and debugging approach. + + * For example, a 'gdb-attach' event handler that invokes the 'reset + init' command will interfere with debugging early boot code, which + performs some of the same actions that the 'reset-init' event + handler does. + + * Likewise, the 'arm9 vector_catch' command (or its siblings 'xscale + vector_catch' and 'cortex_m vector_catch') can be a timesaver + during some debug sessions, but don't make everyone use that + either. Keep those kinds of debugging aids in your user config + file, along with messaging and tracing setup. (*Note Software + Debug Messages and Tracing: softwaredebugmessagesandtracing.) + + * You might need to override some defaults. For example, you might + need to move, shrink, or back up the target's work area if your + application needs much SRAM. + + * TCP/IP port configuration is another example of something which is + environment-specific, and should only appear in a user config file. + *Note TCP/IP Ports: tcpipports. + +5.5 Project-Specific Utilities +============================== + +A few project-specific utility routines may well speed up your work. +Write them, and keep them in your project's user config file. + +For example, if you are making a boot loader work on a board, it's nice +to be able to debug the "after it's loaded to RAM" parts separately from +the finicky early code which sets up the DDR RAM controller and clocks. +A script like this one, or a more GDB-aware sibling, may help: + + proc ramboot { } { + # Reset, running the target's "reset-init" scripts + # to initialize clocks and the DDR RAM controller. + # Leave the CPU halted. + reset init + + # Load CONFIG_SKIP_LOWLEVEL_INIT version into DDR RAM. + load_image u-boot.bin 0x20000000 + + # Start running. + resume 0x20000000 + } + +Then once that code is working you will need to make it boot from NOR +flash; a different utility would help. Alternatively, some developers +write to flash using GDB. (You might use a similar script if you're +working with a flash based microcontroller application instead of a boot +loader.) + + proc newboot { } { + # Reset, leaving the CPU halted. The "reset-init" event + # proc gives faster access to the CPU and to NOR flash; + # "reset halt" would be slower. + reset init + + # Write standard version of U-Boot into the first two + # sectors of NOR flash ... the standard version should + # do the same lowlevel init as "reset-init". + flash protect 0 0 1 off + flash erase_sector 0 0 1 + flash write_bank 0 u-boot.bin 0x0 + flash protect 0 0 1 on + + # Reboot from scratch using that new boot loader. + reset run + } + +You may need more complicated utility procedures when booting from NAND. +That often involves an extra bootloader stage, running from on-chip SRAM +to perform DDR RAM setup so it can load the main bootloader code (which +won't fit into that SRAM). + +Other helper scripts might be used to write production system images, +involving considerably more than just a three stage bootloader. + +5.6 Target Software Changes +=========================== + +Sometimes you may want to make some small changes to the software you're +developing, to help make JTAG debugging work better. For example, in C +or assembly language code you might use '#ifdef JTAG_DEBUG' (or its +converse) around code handling issues like: + + * Watchdog Timers... Watchog timers are typically used to + automatically reset systems if some application task doesn't + periodically reset the timer. (The assumption is that the system + has locked up if the task can't run.) When a JTAG debugger halts + the system, that task won't be able to run and reset the timer ... + potentially causing resets in the middle of your debug sessions. + + It's rarely a good idea to disable such watchdogs, since their + usage needs to be debugged just like all other parts of your + firmware. That might however be your only option. + + Look instead for chip-specific ways to stop the watchdog from + counting while the system is in a debug halt state. It may be + simplest to set that non-counting mode in your debugger startup + scripts. You may however need a different approach when, for + example, a motor could be physically damaged by firmware remaining + inactive in a debug halt state. That might involve a type of + firmware mode where that "non-counting" mode is disabled at the + beginning then re-enabled at the end; a watchdog reset might fire + and complicate the debug session, but hardware (or people) would be + protected.(1) + + * ARM Semihosting... When linked with a special runtime library + provided with many toolchains(2), your target code can use I/O + facilities on the debug host. That library provides a small set of + system calls which are handled by OpenOCD. It can let the debugger + provide your system console and a file system, helping with early + debugging or providing a more capable environment for + sometimes-complex tasks like installing system firmware onto NAND + or SPI flash. + + * ARM Wait-For-Interrupt... Many ARM chips synchronize the JTAG + clock using the core clock. Low power states which stop that core + clock thus prevent JTAG access. Idle loops in tasking environments + often enter those low power states via the 'WFI' instruction (or + its coprocessor equivalent, before ARMv7). + + You may want to _disable that instruction_ in source code, or + otherwise prevent using that state, to ensure you can get JTAG + access at any time.(3) For example, the OpenOCD 'halt' command may + not work for an idle processor otherwise. + + * Delay after reset... Not all chips have good support for debugger + access right after reset; many LPC2xxx chips have issues here. + Similarly, applications that reconfigure pins used for JTAG access + as they start will also block debugger access. + + To work with boards like this, _enable a short delay loop_ the + first thing after reset, before "real" startup activities. For + example, one second's delay is usually more than enough time for a + JTAG debugger to attach, so that early code execution can be + debugged or firmware can be replaced. + + * Debug Communications Channel (DCC)... Some processors include + mechanisms to send messages over JTAG. Many ARM cores support + these, as do some cores from other vendors. (OpenOCD may be able + to use this DCC internally, speeding up some operations like + writing to memory.) + + Your application may want to deliver various debugging messages + over JTAG, by _linking with a small library of code_ provided with + OpenOCD and using the utilities there to send various kinds of + message. *Note Software Debug Messages and Tracing: + softwaredebugmessagesandtracing. + +5.7 Target Hardware Setup +========================= + +Chip vendors often provide software development boards which are highly +configurable, so that they can support all options that product boards +may require. _Make sure that any jumpers or switches match the system +configuration you are working with._ + +Common issues include: + + * JTAG setup ... Boards may support more than one JTAG + configuration. Examples include jumpers controlling pullups versus + pulldowns on the nTRST and/or nSRST signals, and choice of + connectors (e.g. which of two headers on the base board, or one + from a daughtercard). For some Texas Instruments boards, you may + need to jumper the EMU0 and EMU1 signals (which OpenOCD won't + currently control). + + * Boot Modes ... Complex chips often support multiple boot modes, + controlled by external jumpers. Make sure this is set up + correctly. For example many i.MX boards from NXP need to be + jumpered to "ATX mode" to start booting using the on-chip ROM, when + using second stage bootloader code stored in a NAND flash chip. + + Such explicit configuration is common, and not limited to booting + from NAND. You might also need to set jumpers to start booting + using code loaded from an MMC/SD card; external SPI flash; + Ethernet, UART, or USB links; NOR flash; OneNAND flash; some + external host; or various other sources. + + * Memory Addressing ... Boards which support multiple boot modes may + also have jumpers to configure memory addressing. One board, for + example, jumpers external chipselect 0 (used for booting) to + address either a large SRAM (which must be pre-loaded via JTAG), + NOR flash, or NAND flash. When it's jumpered to address NAND + flash, that board must also be told to start booting from on-chip + ROM. + + Your 'board.cfg' file may also need to be told this jumper + configuration, so that it can know whether to declare NOR flash + using 'flash bank' or instead declare NAND flash with 'nand + device'; and likewise which probe to perform in its 'reset-init' + handler. + + A closely related issue is bus width. Jumpers might need to + distinguish between 8 bit or 16 bit bus access for the flash used + to start booting. + + * Peripheral Access ... Development boards generally provide access + to every peripheral on the chip, sometimes in multiple modes (such + as by providing multiple audio codec chips). This interacts with + software configuration of pin multiplexing, where for example a + given pin may be routed either to the MMC/SD controller or the GPIO + controller. It also often interacts with configuration jumpers. + One jumper may be used to route signals to an MMC/SD card slot or + an expansion bus (which might in turn affect booting); others might + control which audio or video codecs are used. + +Plus you should of course have 'reset-init' event handlers which set up +the hardware to match that jumper configuration. That includes in +particular any oscillator or PLL used to clock the CPU, and any memory +controllers needed to access external memory and peripherals. Without +such handlers, you won't be able to access those resources without +working target firmware which can do that setup ... this can be awkward +when you're trying to debug that target firmware. Even if there's a ROM +bootloader which handles a few issues, it rarely provides full access to +all board-specific capabilities. + + ---------- Footnotes ---------- + + (1) Note that many systems support a "monitor mode" debug that is a +somewhat cleaner way to address such issues. You can think of it as +only halting part of the system, maybe just one task, instead of the +whole thing. At this writing, January 2010, OpenOCD based debugging +does not support monitor mode debug, only "halt mode" debug. + + (2) See chapter 8 "Semihosting" in ARM DUI 0203I +(http://infocenter.arm.com/help/topic/com.arm.doc.dui0203i/DUI0203I_rvct_developer_guide.pdf), +the "RealView Compilation Tools Developer Guide". The CodeSourcery EABI +toolchain also includes a semihosting library. + + (3) As a more polite alternative, some processors have special +debug-oriented registers which can be used to change various features +including how the low power states are clocked while debugging. The +STM32 DBGMCU_CR register is an example; at the cost of extra power +consumption, JTAG can be used during low power states. + + +File: openocd.info, Node: Config File Guidelines, Next: Daemon Configuration, Prev: OpenOCD Project Setup, Up: Top + +6 Config File Guidelines +************************ + +This chapter is aimed at any user who needs to write a config file, +including developers and integrators of OpenOCD and any user who needs +to get a new board working smoothly. It provides guidelines for +creating those files. + +You should find the following directories under $(INSTALLDIR)/scripts, +with files including the ones listed here. Use them as-is where you +can; or as models for new files. + * 'interface' ... These are for debug adapters. Files that + configure JTAG adapters go here. + $ ls interface -R + interface/: + altera-usb-blaster.cfg hilscher_nxhx50_re.cfg openocd-usb-hs.cfg + arm-jtag-ew.cfg hitex_str9-comstick.cfg openrd.cfg + at91rm9200.cfg icebear.cfg osbdm.cfg + axm0432.cfg jlink.cfg parport.cfg + busblaster.cfg jtagkey2.cfg parport_dlc5.cfg + buspirate.cfg jtagkey2p.cfg redbee-econotag.cfg + calao-usb-a9260-c01.cfg jtagkey.cfg redbee-usb.cfg + calao-usb-a9260-c02.cfg jtagkey-tiny.cfg rlink.cfg + calao-usb-a9260.cfg jtag-lock-pick_tiny_2.cfg sheevaplug.cfg + chameleon.cfg kt-link.cfg signalyzer.cfg + cortino.cfg lisa-l.cfg signalyzer-h2.cfg + digilent-hs1.cfg luminary.cfg signalyzer-h4.cfg + dlp-usb1232h.cfg luminary-icdi.cfg signalyzer-lite.cfg + dummy.cfg luminary-lm3s811.cfg stlink-v1.cfg + estick.cfg minimodule.cfg stlink-v2.cfg + flashlink.cfg neodb.cfg stm32-stick.cfg + flossjtag.cfg ngxtech.cfg sysfsgpio-raspberrypi.cfg + flossjtag-noeeprom.cfg olimex-arm-usb-ocd.cfg ti-icdi.cfg + flyswatter2.cfg olimex-arm-usb-ocd-h.cfg turtelizer2.cfg + flyswatter.cfg olimex-arm-usb-tiny-h.cfg ulink.cfg + ftdi olimex-jtag-tiny.cfg usb-jtag.cfg + hilscher_nxhx10_etm.cfg oocdlink.cfg usbprog.cfg + hilscher_nxhx500_etm.cfg opendous.cfg vpaclink.cfg + hilscher_nxhx500_re.cfg opendous_ftdi.cfg vsllink.cfg + hilscher_nxhx50_etm.cfg openocd-usb.cfg xds100v2.cfg + + interface/ftdi: + axm0432.cfg icebear.cfg oocdlink.cfg + calao-usb-a9260-c01.cfg jtagkey2.cfg opendous_ftdi.cfg + calao-usb-a9260-c02.cfg jtagkey2p.cfg openocd-usb.cfg + cortino.cfg jtagkey.cfg openocd-usb-hs.cfg + dlp-usb1232h.cfg jtag-lock-pick_tiny_2.cfg openrd.cfg + dp_busblaster.cfg kt-link.cfg redbee-econotag.cfg + flossjtag.cfg lisa-l.cfg redbee-usb.cfg + flossjtag-noeeprom.cfg luminary.cfg sheevaplug.cfg + flyswatter2.cfg luminary-icdi.cfg signalyzer.cfg + flyswatter.cfg luminary-lm3s811.cfg signalyzer-lite.cfg + hilscher_nxhx10_etm.cfg minimodule.cfg stm32-stick.cfg + hilscher_nxhx500_etm.cfg neodb.cfg turtelizer2-revB.cfg + hilscher_nxhx500_re.cfg ngxtech.cfg turtelizer2-revC.cfg + hilscher_nxhx50_etm.cfg olimex-arm-usb-ocd.cfg vpaclink.cfg + hilscher_nxhx50_re.cfg olimex-arm-usb-ocd-h.cfg xds100v2.cfg + hitex_lpc1768stick.cfg olimex-arm-usb-tiny-h.cfg + hitex_str9-comstick.cfg olimex-jtag-tiny.cfg + $ + * 'board' ... think Circuit Board, PWA, PCB, they go by many names. + Board files contain initialization items that are specific to a + board. They reuse target configuration files, since the same + microprocessor chips are used on many boards, but support for + external parts varies widely. For example, the SDRAM + initialization sequence for the board, or the type of external + flash and what address it uses. Any initialization sequence to + enable that external flash or SDRAM should be found in the board + file. Boards may also contain multiple targets: two CPUs; or a CPU + and an FPGA. + $ ls board + actux3.cfg lpc1850_spifi_generic.cfg + am3517evm.cfg lpc4350_spifi_generic.cfg + arm_evaluator7t.cfg lubbock.cfg + at91cap7a-stk-sdram.cfg mcb1700.cfg + at91eb40a.cfg microchip_explorer16.cfg + at91rm9200-dk.cfg mini2440.cfg + at91rm9200-ek.cfg mini6410.cfg + at91sam9261-ek.cfg netgear-dg834v3.cfg + at91sam9263-ek.cfg olimex_LPC2378STK.cfg + at91sam9g20-ek.cfg olimex_lpc_h2148.cfg + atmel_at91sam7s-ek.cfg olimex_sam7_ex256.cfg + atmel_at91sam9260-ek.cfg olimex_sam9_l9260.cfg + atmel_at91sam9rl-ek.cfg olimex_stm32_h103.cfg + atmel_sam3n_ek.cfg olimex_stm32_h107.cfg + atmel_sam3s_ek.cfg olimex_stm32_p107.cfg + atmel_sam3u_ek.cfg omap2420_h4.cfg + atmel_sam3x_ek.cfg open-bldc.cfg + atmel_sam4s_ek.cfg openrd.cfg + balloon3-cpu.cfg osk5912.cfg + colibri.cfg phone_se_j100i.cfg + crossbow_tech_imote2.cfg phytec_lpc3250.cfg + csb337.cfg pic-p32mx.cfg + csb732.cfg propox_mmnet1001.cfg + da850evm.cfg pxa255_sst.cfg + digi_connectcore_wi-9c.cfg redbee.cfg + diolan_lpc4350-db1.cfg rsc-w910.cfg + dm355evm.cfg sheevaplug.cfg + dm365evm.cfg smdk6410.cfg + dm6446evm.cfg spear300evb.cfg + efikamx.cfg spear300evb_mod.cfg + eir.cfg spear310evb20.cfg + ek-lm3s1968.cfg spear310evb20_mod.cfg + ek-lm3s3748.cfg spear320cpu.cfg + ek-lm3s6965.cfg spear320cpu_mod.cfg + ek-lm3s811.cfg steval_pcc010.cfg + ek-lm3s811-revb.cfg stm320518_eval_stlink.cfg + ek-lm3s8962.cfg stm32100b_eval.cfg + ek-lm3s9b9x.cfg stm3210b_eval.cfg + ek-lm3s9d92.cfg stm3210c_eval.cfg + ek-lm4f120xl.cfg stm3210e_eval.cfg + ek-lm4f232.cfg stm3220g_eval.cfg + embedded-artists_lpc2478-32.cfg stm3220g_eval_stlink.cfg + ethernut3.cfg stm3241g_eval.cfg + glyn_tonga2.cfg stm3241g_eval_stlink.cfg + hammer.cfg stm32f0discovery.cfg + hilscher_nxdb500sys.cfg stm32f3discovery.cfg + hilscher_nxeb500hmi.cfg stm32f4discovery.cfg + hilscher_nxhx10.cfg stm32ldiscovery.cfg + hilscher_nxhx500.cfg stm32vldiscovery.cfg + hilscher_nxhx50.cfg str910-eval.cfg + hilscher_nxsb100.cfg telo.cfg + hitex_lpc1768stick.cfg ti_am335xevm.cfg + hitex_lpc2929.cfg ti_beagleboard.cfg + hitex_stm32-performancestick.cfg ti_beagleboard_xm.cfg + hitex_str9-comstick.cfg ti_beaglebone.cfg + iar_lpc1768.cfg ti_blaze.cfg + iar_str912_sk.cfg ti_pandaboard.cfg + icnova_imx53_sodimm.cfg ti_pandaboard_es.cfg + icnova_sam9g45_sodimm.cfg topas910.cfg + imx27ads.cfg topasa900.cfg + imx27lnst.cfg twr-k60f120m.cfg + imx28evk.cfg twr-k60n512.cfg + imx31pdk.cfg tx25_stk5.cfg + imx35pdk.cfg tx27_stk5.cfg + imx53loco.cfg unknown_at91sam9260.cfg + keil_mcb1700.cfg uptech_2410.cfg + keil_mcb2140.cfg verdex.cfg + kwikstik.cfg voipac.cfg + linksys_nslu2.cfg voltcraft_dso-3062c.cfg + lisa-l.cfg x300t.cfg + logicpd_imx27.cfg zy1000.cfg + $ + * 'target' ... think chip. The "target" directory represents the + JTAG TAPs on a chip which OpenOCD should control, not a board. Two + common types of targets are ARM chips and FPGA or CPLD chips. When + a chip has multiple TAPs (maybe it has both ARM and DSP cores), the + target config file defines all of them. + $ ls target + aduc702x.cfg lpc1763.cfg + am335x.cfg lpc1764.cfg + amdm37x.cfg lpc1765.cfg + ar71xx.cfg lpc1766.cfg + at32ap7000.cfg lpc1767.cfg + at91r40008.cfg lpc1768.cfg + at91rm9200.cfg lpc1769.cfg + at91sam3ax_4x.cfg lpc1788.cfg + at91sam3ax_8x.cfg lpc17xx.cfg + at91sam3ax_xx.cfg lpc1850.cfg + at91sam3nXX.cfg lpc2103.cfg + at91sam3sXX.cfg lpc2124.cfg + at91sam3u1c.cfg lpc2129.cfg + at91sam3u1e.cfg lpc2148.cfg + at91sam3u2c.cfg lpc2294.cfg + at91sam3u2e.cfg lpc2378.cfg + at91sam3u4c.cfg lpc2460.cfg + at91sam3u4e.cfg lpc2478.cfg + at91sam3uxx.cfg lpc2900.cfg + at91sam3XXX.cfg lpc2xxx.cfg + at91sam4sd32x.cfg lpc3131.cfg + at91sam4sXX.cfg lpc3250.cfg + at91sam4XXX.cfg lpc4350.cfg + at91sam7se512.cfg lpc4350.cfg.orig + at91sam7sx.cfg mc13224v.cfg + at91sam7x256.cfg nuc910.cfg + at91sam7x512.cfg omap2420.cfg + at91sam9260.cfg omap3530.cfg + at91sam9260_ext_RAM_ext_flash.cfg omap4430.cfg + at91sam9261.cfg omap4460.cfg + at91sam9263.cfg omap5912.cfg + at91sam9.cfg omapl138.cfg + at91sam9g10.cfg pic32mx.cfg + at91sam9g20.cfg pxa255.cfg + at91sam9g45.cfg pxa270.cfg + at91sam9rl.cfg pxa3xx.cfg + atmega128.cfg readme.txt + avr32.cfg samsung_s3c2410.cfg + c100.cfg samsung_s3c2440.cfg + c100config.tcl samsung_s3c2450.cfg + c100helper.tcl samsung_s3c4510.cfg + c100regs.tcl samsung_s3c6410.cfg + cs351x.cfg sharp_lh79532.cfg + davinci.cfg smp8634.cfg + dragonite.cfg spear3xx.cfg + dsp56321.cfg stellaris.cfg + dsp568013.cfg stellaris_icdi.cfg + dsp568037.cfg stm32f0x_stlink.cfg + efm32_stlink.cfg stm32f1x.cfg + epc9301.cfg stm32f1x_stlink.cfg + faux.cfg stm32f2x.cfg + feroceon.cfg stm32f2x_stlink.cfg + fm3.cfg stm32f3x.cfg + hilscher_netx10.cfg stm32f3x_stlink.cfg + hilscher_netx500.cfg stm32f4x.cfg + hilscher_netx50.cfg stm32f4x_stlink.cfg + icepick.cfg stm32l.cfg + imx21.cfg stm32lx_dual_bank.cfg + imx25.cfg stm32lx_stlink.cfg + imx27.cfg stm32_stlink.cfg + imx28.cfg stm32w108_stlink.cfg + imx31.cfg stm32xl.cfg + imx35.cfg str710.cfg + imx51.cfg str730.cfg + imx53.cfg str750.cfg + imx6.cfg str912.cfg + imx.cfg swj-dp.tcl + is5114.cfg test_reset_syntax_error.cfg + ixp42x.cfg test_syntax_error.cfg + k40.cfg ti-ar7.cfg + k60.cfg ti_calypso.cfg + lpc1751.cfg ti_dm355.cfg + lpc1752.cfg ti_dm365.cfg + lpc1754.cfg ti_dm6446.cfg + lpc1756.cfg tmpa900.cfg + lpc1758.cfg tmpa910.cfg + lpc1759.cfg u8500.cfg + * _more_ ... browse for other library files which may be useful. + For example, there are various generic and CPU-specific utilities. + +The 'openocd.cfg' user config file may override features in any of the +above files by setting variables before sourcing the target file, or by +adding commands specific to their situation. + +6.1 Interface Config Files +========================== + +The user config file should be able to source one of these files with a +command like this: + + source [find interface/FOOBAR.cfg] + +A preconfigured interface file should exist for every debug adapter in +use today with OpenOCD. That said, perhaps some of these config files +have only been used by the developer who created it. + +A separate chapter gives information about how to set these up. *Note +Debug Adapter Configuration::. Read the OpenOCD source code (and +Developer's Guide) if you have a new kind of hardware interface and need +to provide a driver for it. + +6.2 Board Config Files +====================== + +The user config file should be able to source one of these files with a +command like this: + + source [find board/FOOBAR.cfg] + +The point of a board config file is to package everything about a given +board that user config files need to know. In summary the board files +should contain (if present) + + 1. One or more 'source [target/...cfg]' statements + 2. NOR flash configuration (*note NOR Configuration: + norconfiguration.) + 3. NAND flash configuration (*note NAND Configuration: + nandconfiguration.) + 4. Target 'reset' handlers for SDRAM and I/O configuration + 5. JTAG adapter reset configuration (*note Reset Configuration::) + 6. All things that are not "inside a chip" + +Generic things inside target chips belong in target config files, not +board config files. So for example a 'reset-init' event handler should +know board-specific oscillator and PLL parameters, which it passes to +target-specific utility code. + +The most complex task of a board config file is creating such a +'reset-init' event handler. Define those handlers last, after you +verify the rest of the board configuration works. + +6.2.1 Communication Between Config files +---------------------------------------- + +In addition to target-specific utility code, another way that board and +target config files communicate is by following a convention on how to +use certain variables. + +The full Tcl/Tk language supports "namespaces", but Jim-Tcl does not. +Thus the rule we follow in OpenOCD is this: Variables that begin with a +leading underscore are temporary in nature, and can be modified and used +at will within a target configuration file. + +Complex board config files can do the things like this, for a board with +three chips: + + # Chip #1: PXA270 for network side, big endian + set CHIPNAME network + set ENDIAN big + source [find target/pxa270.cfg] + # on return: _TARGETNAME = network.cpu + # other commands can refer to the "network.cpu" target. + $_TARGETNAME configure .... events for this CPU.. + + # Chip #2: PXA270 for video side, little endian + set CHIPNAME video + set ENDIAN little + source [find target/pxa270.cfg] + # on return: _TARGETNAME = video.cpu + # other commands can refer to the "video.cpu" target. + $_TARGETNAME configure .... events for this CPU.. + + # Chip #3: Xilinx FPGA for glue logic + set CHIPNAME xilinx + unset ENDIAN + source [find target/spartan3.cfg] + +That example is oversimplified because it doesn't show any flash memory, +or the 'reset-init' event handlers to initialize external DRAM or +(assuming it needs it) load a configuration into the FPGA. Such features +are usually needed for low-level work with many boards, where "low +level" implies that the board initialization software may not be +working. (That's a common reason to need JTAG tools. Another is to +enable working with microcontroller-based systems, which often have no +debugging support except a JTAG connector.) + +Target config files may also export utility functions to board and user +config files. Such functions should use name prefixes, to help avoid +naming collisions. + +Board files could also accept input variables from user config files. +For example, there might be a 'J4_JUMPER' setting used to identify what +kind of flash memory a development board is using, or how to set up +other clocks and peripherals. + +6.2.2 Variable Naming Convention +-------------------------------- + +Most boards have only one instance of a chip. However, it should be +easy to create a board with more than one such chip (as shown above). +Accordingly, we encourage these conventions for naming variables +associated with different 'target.cfg' files, to promote consistency and +so that board files can override target defaults. + +Inputs to target config files include: + + * 'CHIPNAME' ... This gives a name to the overall chip, and is used + as part of tap identifier dotted names. While the default is + normally provided by the chip manufacturer, board files may need to + distinguish between instances of a chip. + * 'ENDIAN' ... By default 'little' - although chips may hard-wire + 'big'. Chips that can't change endianness don't need to use this + variable. + * 'CPUTAPID' ... When OpenOCD examines the JTAG chain, it can be + told verify the chips against the JTAG IDCODE register. The target + file will hold one or more defaults, but sometimes the chip in a + board will use a different ID (perhaps a newer revision). + +Outputs from target config files include: + + * '_TARGETNAME' ... By convention, this variable is created by the + target configuration script. The board configuration file may make + use of this variable to configure things like a "reset init" + script, or other things specific to that board and that target. If + the chip has 2 targets, the names are '_TARGETNAME0', + '_TARGETNAME1', ... etc. + +6.2.3 The reset-init Event Handler +---------------------------------- + +Board config files run in the OpenOCD configuration stage; they can't +use TAPs or targets, since they haven't been fully set up yet. This +means you can't write memory or access chip registers; you can't even +verify that a flash chip is present. That's done later in event +handlers, of which the target 'reset-init' handler is one of the most +important. + +Except on microcontrollers, the basic job of 'reset-init' event handlers +is setting up flash and DRAM, as normally handled by boot loaders. +Microcontrollers rarely use boot loaders; they run right out of their +on-chip flash and SRAM memory. But they may want to use one of these +handlers too, if just for developer convenience. + + Note: Because this is so very board-specific, and chip-specific, no + examples are included here. Instead, look at the board config + files distributed with OpenOCD. If you have a boot loader, its + source code will help; so will configuration files for other JTAG + tools (*note Translating Configuration Files: + translatingconfigurationfiles.). + +Some of this code could probably be shared between different boards. +For example, setting up a DRAM controller often doesn't differ by much +except the bus width (16 bits or 32?) and memory timings, so a reusable +TCL procedure loaded by the 'target.cfg' file might take those as +parameters. Similarly with oscillator, PLL, and clock setup; and +disabling the watchdog. Structure the code cleanly, and provide +comments to help the next developer doing such work. (_You might be +that next person_ trying to reuse init code!) + +The last thing normally done in a 'reset-init' handler is probing +whatever flash memory was configured. For most chips that needs to be +done while the associated target is halted, either because JTAG memory +access uses the CPU or to prevent conflicting CPU access. + +6.2.4 JTAG Clock Rate +--------------------- + +Before your 'reset-init' handler has set up the PLLs and clocking, you +may need to run with a low JTAG clock rate. *Note JTAG Speed: +jtagspeed. Then you'd increase that rate after your handler has made it +possible to use the faster JTAG clock. When the initial low speed is +board-specific, for example because it depends on a board-specific +oscillator speed, then you should probably set it up in the board config +file; if it's target-specific, it belongs in the target config file. + +For most ARM-based processors the fastest JTAG clock(1) is one sixth of +the CPU clock; or one eighth for ARM11 cores. Consult chip +documentation to determine the peak JTAG clock rate, which might be less +than that. + + Warning: On most ARMs, JTAG clock detection is coupled to the core + clock, so software using a 'wait for interrupt' operation blocks + JTAG access. Adaptive clocking provides a partial workaround, but + a more complete solution just avoids using that instruction with + JTAG debuggers. + +If both the chip and the board support adaptive clocking, use the +'jtag_rclk' command, in case your board is used with JTAG adapter which +also supports it. Otherwise use 'adapter_khz'. Set the slow rate at +the beginning of the reset sequence, and the faster rate as soon as the +clocks are at full speed. + +6.2.5 The init_board procedure +------------------------------ + +The concept of 'init_board' procedure is very similar to 'init_targets' +(*Note The init_targets procedure: theinittargetsprocedure.) - it's a +replacement of "linear" configuration scripts. This procedure is meant +to be executed when OpenOCD enters run stage (*Note Entering the Run +Stage: enteringtherunstage,) after 'init_targets'. The idea to have +spearate 'init_targets' and 'init_board' procedures is to allow the +first one to configure everything target specific (internal flash, +internal RAM, etc.) and the second one to configure everything board +specific (reset signals, chip frequency, reset-init event handler, +external memory, etc.). Additionally "linear" board config file will +most likely fail when target config file uses 'init_targets' scheme +("linear" script is executed before 'init' and 'init_targets' - after), +so separating these two configuration stages is very convenient, as the +easiest way to overcome this problem is to convert board config file to +use 'init_board' procedure. Board config scripts don't need to override +'init_targets' defined in target config files when they only need to to +add some specifics. + +Just as 'init_targets', the 'init_board' procedure can be overriden by +"next level" script (which sources the original), allowing greater code +reuse. + + ### board_file.cfg ### + + # source target file that does most of the config in init_targets + source [find target/target.cfg] + + proc enable_fast_clock {} { + # enables fast on-board clock source + # configures the chip to use it + } + + # initialize only board specifics - reset, clock, adapter frequency + proc init_board {} { + reset_config trst_and_srst trst_pulls_srst + + $_TARGETNAME configure -event reset-init { + adapter_khz 1 + enable_fast_clock + adapter_khz 10000 + } + } + +6.3 Target Config Files +======================= + +Board config files communicate with target config files using naming +conventions as described above, and may source one or more target config +files like this: + + source [find target/FOOBAR.cfg] + +The point of a target config file is to package everything about a given +chip that board config files need to know. In summary the target files +should contain + + 1. Set defaults + 2. Add TAPs to the scan chain + 3. Add CPU targets (includes GDB support) + 4. CPU/Chip/CPU-Core specific features + 5. On-Chip flash + +As a rule of thumb, a target file sets up only one chip. For a +microcontroller, that will often include a single TAP, which is a CPU +needing a GDB target, and its on-chip flash. + +More complex chips may include multiple TAPs, and the target config file +may need to define them all before OpenOCD can talk to the chip. For +example, some phone chips have JTAG scan chains that include an ARM core +for operating system use, a DSP, another ARM core embedded in an image +processing engine, and other processing engines. + +6.3.1 Default Value Boiler Plate Code +------------------------------------- + +All target configuration files should start with code like this, letting +board config files express environment-specific differences in how +things should be set up. + + # Boards may override chip names, perhaps based on role, + # but the default should match what the vendor uses + if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME + } else { + set _CHIPNAME sam7x256 + } + + # ONLY use ENDIAN with targets that can change it. + if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN + } else { + set _ENDIAN little + } + + # TAP identifiers may change as chips mature, for example with + # new revision fields (the "3" here). Pick a good default; you + # can pass several such identifiers to the "jtag newtap" command. + if { [info exists CPUTAPID ] } { + set _CPUTAPID $CPUTAPID + } else { + set _CPUTAPID 0x3f0f0f0f + } + +_Remember:_ Board config files may include multiple target config files, +or the same target file multiple times (changing at least 'CHIPNAME'). + +Likewise, the target configuration file should define '_TARGETNAME' (or +'_TARGETNAME0' etc) and use it later on when defining debug targets: + + set _TARGETNAME $_CHIPNAME.cpu + target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME + +6.3.2 Adding TAPs to the Scan Chain +----------------------------------- + +After the "defaults" are set up, add the TAPs on each chip to the JTAG +scan chain. *Note TAP Declaration::, and the naming convention for +taps. + +In the simplest case the chip has only one TAP, probably for a CPU or +FPGA. The config file for the Atmel AT91SAM7X256 looks (in part) like +this: + + jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID + +A board with two such at91sam7 chips would be able to source such a +config file twice, with different values for 'CHIPNAME', so it adds a +different TAP each time. + +If there are nonzero '-expected-id' values, OpenOCD attempts to verify +the actual tap id against those values. It will issue error messages if +there is mismatch, which can help to pinpoint problems in OpenOCD +configurations. + + JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f + (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3) + ERROR: Tap: sam7x256.cpu - Expected id: 0x12345678, Got: 0x3f0f0f0f + ERROR: expected: mfg: 0x33c, part: 0x2345, ver: 0x1 + ERROR: got: mfg: 0x787, part: 0xf0f0, ver: 0x3 + +There are more complex examples too, with chips that have multiple TAPs. +Ones worth looking at include: + + * 'target/omap3530.cfg' - with disabled ARM and DSP, plus a JRC to + enable them + * 'target/str912.cfg' - with flash, CPU, and boundary scan + * 'target/ti_dm355.cfg' - with ETM, ARM, and JRC (this JRC is not + currently used) + +6.3.3 Add CPU targets +--------------------- + +After adding a TAP for a CPU, you should set it up so that GDB and other +commands can use it. *Note CPU Configuration::. For the at91sam7 +example above, the command can look like this; note that '$_ENDIAN' is +not needed, since OpenOCD defaults to little endian, and this chip +doesn't support changing that. + + set _TARGETNAME $_CHIPNAME.cpu + target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME + +Work areas are small RAM areas associated with CPU targets. They are +used by OpenOCD to speed up downloads, and to download small snippets of +code to program flash chips. If the chip includes a form of +"on-chip-ram" - and many do - define a work area if you can. Again +using the at91sam7 as an example, this can look like: + + $_TARGETNAME configure -work-area-phys 0x00200000 \ + -work-area-size 0x4000 -work-area-backup 0 + +6.3.4 Define CPU targets working in SMP +--------------------------------------- + +After setting targets, you can define a list of targets working in SMP. + + set _TARGETNAME_1 $_CHIPNAME.cpu1 + set _TARGETNAME_2 $_CHIPNAME.cpu2 + target create $_TARGETNAME_1 cortex_a -chain-position $_CHIPNAME.dap \ + -coreid 0 -dbgbase $_DAP_DBG1 + target create $_TARGETNAME_2 cortex_a -chain-position $_CHIPNAME.dap \ + -coreid 1 -dbgbase $_DAP_DBG2 + #define 2 targets working in smp. + target smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1 +In the above example on cortex_a, 2 cpus are working in SMP. In SMP only +one GDB instance is created and : + * a set of hardware breakpoint sets the same breakpoint on all + targets in the list. + * halt command triggers the halt of all targets in the list. + * resume command triggers the write context and the restart of all + targets in the list. + * following a breakpoint: the target stopped by the breakpoint is + displayed to the GDB session. + * dedicated GDB serial protocol packets are implemented for + switching/retrieving the target displayed by the GDB session *note + Using OpenOCD SMP with GDB: usingopenocdsmpwithgdb. + +The SMP behaviour can be disabled/enabled dynamically. On cortex_a +following command have been implemented. + * cortex_a smp_on : enable SMP mode, behaviour is as described above. + * cortex_a smp_off : disable SMP mode, the current target is the one + displayed in the GDB session, only this target is now controlled by + GDB session. This behaviour is useful during system boot up. + * cortex_a smp_gdb : display/fix the core id displayed in GDB session + see following example. + + >cortex_a smp_gdb + gdb coreid 0 -> -1 + #0 : coreid 0 is displayed to GDB , + #-> -1 : next resume triggers a real resume + > cortex_a smp_gdb 1 + gdb coreid 0 -> 1 + #0 :coreid 0 is displayed to GDB , + #->1 : next resume displays coreid 1 to GDB + > resume + > cortex_a smp_gdb + gdb coreid 1 -> 1 + #1 :coreid 1 is displayed to GDB , + #->1 : next resume displays coreid 1 to GDB + > cortex_a smp_gdb -1 + gdb coreid 1 -> -1 + #1 :coreid 1 is displayed to GDB, + #->-1 : next resume triggers a real resume + +6.3.5 Chip Reset Setup +---------------------- + +As a rule, you should put the 'reset_config' command into the board +file. Most things you think you know about a chip can be tweaked by the +board. + +Some chips have specific ways the TRST and SRST signals are managed. In +the unusual case that these are _chip specific_ and can never be changed +by board wiring, they could go here. For example, some chips can't +support JTAG debugging without both signals. + +Provide a 'reset-assert' event handler if you can. Such a handler uses +JTAG operations to reset the target, letting this target config be used +in systems which don't provide the optional SRST signal, or on systems +where you don't want to reset all targets at once. Such a handler might +write to chip registers to force a reset, use a JRC to do that +(preferable - the target may be wedged!), or force a watchdog timer to +trigger. (For Cortex-M targets, this is not necessary. The target +driver knows how to use trigger an NVIC reset when SRST is not +available.) + +Some chips need special attention during reset handling if they're going +to be used with JTAG. An example might be needing to send some commands +right after the target's TAP has been reset, providing a +'reset-deassert-post' event handler that writes a chip register to +report that JTAG debugging is being done. Another would be +reconfiguring the watchdog so that it stops counting while the core is +halted in the debugger. + +JTAG clocking constraints often change during reset, and in some cases +target config files (rather than board config files) are the right +places to handle some of those issues. For example, immediately after +reset most chips run using a slower clock than they will use later. +That means that after reset (and potentially, as OpenOCD first starts +up) they must use a slower JTAG clock rate than they will use later. +*Note JTAG Speed: jtagspeed. + + Important: When you are debugging code that runs right after chip + reset, getting these issues right is critical. In particular, if + you see intermittent failures when OpenOCD verifies the scan chain + after reset, look at how you are setting up JTAG clocking. + +6.3.6 The init_targets procedure +-------------------------------- + +Target config files can either be "linear" (script executed line-by-line +when parsed in configuration stage, *Note Configuration Stage: +configurationstage,) or they can contain a special procedure called +'init_targets', which will be executed when entering run stage (after +parsing all config files or after 'init' command, *Note Entering the Run +Stage: enteringtherunstage.) Such procedure can be overriden by "next +level" script (which sources the original). This concept faciliates +code reuse when basic target config files provide generic configuration +procedures and 'init_targets' procedure, which can then be sourced and +enchanced or changed in a "more specific" target config file. This is +not possible with "linear" config scripts, because sourcing them +executes every initialization commands they provide. + + ### generic_file.cfg ### + + proc setup_my_chip {chip_name flash_size ram_size} { + # basic initialization procedure ... + } + + proc init_targets {} { + # initializes generic chip with 4kB of flash and 1kB of RAM + setup_my_chip MY_GENERIC_CHIP 4096 1024 + } + + ### specific_file.cfg ### + + source [find target/generic_file.cfg] + + proc init_targets {} { + # initializes specific chip with 128kB of flash and 64kB of RAM + setup_my_chip MY_CHIP_WITH_128K_FLASH_64KB_RAM 131072 65536 + } + +The easiest way to convert "linear" config files to 'init_targets' +version is to enclose every line of "code" (i.e. not 'source' commands, +procedures, etc.) in this procedure. + +For an example of this scheme see LPC2000 target config files. + +The 'init_boards' procedure is a similar concept concerning board config +files (*Note The init_board procedure: theinitboardprocedure.) + +6.3.7 ARM Core Specific Hacks +----------------------------- + +If the chip has a DCC, enable it. If the chip is an ARM9 with some +special high speed download features - enable it. + +If present, the MMU, the MPU and the CACHE should be disabled. + +Some ARM cores are equipped with trace support, which permits +examination of the instruction and data bus activity. Trace activity is +controlled through an "Embedded Trace Module" (ETM) on one of the core's +scan chains. The ETM emits voluminous data through a "trace port". +(*Note ARM Hardware Tracing: armhardwaretracing.) If you are using an +external trace port, configure it in your board config file. If you are +using an on-chip "Embedded Trace Buffer" (ETB), configure it in your +target config file. + + etm config $_TARGETNAME 16 normal full etb + etb config $_TARGETNAME $_CHIPNAME.etb + +6.3.8 Internal Flash Configuration +---------------------------------- + +This applies ONLY TO MICROCONTROLLERS that have flash built in. + +Never ever in the "target configuration file" define any type of flash +that is external to the chip. (For example a BOOT flash on Chip Select +0.) Such flash information goes in a board file - not the TARGET (chip) +file. + +Examples: + * at91sam7x256 - has 256K flash YES enable it. + * str912 - has flash internal YES enable it. + * imx27 - uses boot flash on CS0 - it goes in the board file. + * pxa270 - again - CS0 flash - it goes in the board file. + +6.4 Translating Configuration Files +=================================== + +If you have a configuration file for another hardware debugger or +toolset (Abatron, BDI2000, BDI3000, CCS, Lauterbach, Segger, Macraigor, +etc.), translating it into OpenOCD syntax is often quite +straightforward. The most tricky part of creating a configuration +script is oftentimes the reset init sequence where e.g. PLLs, DRAM and +the like is set up. + +One trick that you can use when translating is to write small Tcl +procedures to translate the syntax into OpenOCD syntax. This can avoid +manual translation errors and make it easier to convert other scripts +later on. + +Example of transforming quirky arguments to a simple search and replace +job: + + # Lauterbach syntax(?) + # + # Data.Set c15:0x042f %long 0x40000015 + # + # OpenOCD syntax when using procedure below. + # + # setc15 0x01 0x00050078 + + proc setc15 {regs value} { + global TARGETNAME + + echo [format "set p15 0x%04x, 0x%08x" $regs $value] + + arm mcr 15 [expr ($regs>>12)&0x7] \ + [expr ($regs>>0)&0xf] [expr ($regs>>4)&0xf] \ + [expr ($regs>>8)&0x7] $value + } + + ---------- Footnotes ---------- + + (1) A FAQ gives +details. + + +File: openocd.info, Node: Daemon Configuration, Next: Debug Adapter Configuration, Prev: Config File Guidelines, Up: Top + +7 Daemon Configuration +********************** + +The commands here are commonly found in the openocd.cfg file and are +used to specify what TCP/IP ports are used, and how GDB should be +supported. + +7.1 Configuration Stage +======================= + +When the OpenOCD server process starts up, it enters a _configuration +stage_ which is the only time that certain commands, _configuration +commands_, may be issued. Normally, configuration commands are only +available inside startup scripts. + +In this manual, the definition of a configuration command is presented +as a _Config Command_, not as a _Command_ which may be issued +interactively. The runtime 'help' command also highlights configuration +commands, and those which may be issued at any time. + +Those configuration commands include declaration of TAPs, flash banks, +the interface used for JTAG communication, and other basic setup. The +server must leave the configuration stage before it may access or +activate TAPs. After it leaves this stage, configuration commands may +no longer be issued. + +7.2 Entering the Run Stage +========================== + +The first thing OpenOCD does after leaving the configuration stage is to +verify that it can talk to the scan chain (list of TAPs) which has been +configured. It will warn if it doesn't find TAPs it expects to find, or +finds TAPs that aren't supposed to be there. You should see no errors +at this point. If you see errors, resolve them by correcting the +commands you used to configure the server. Common errors include using +an initial JTAG speed that's too fast, and not providing the right +IDCODE values for the TAPs on the scan chain. + +Once OpenOCD has entered the run stage, a number of commands become +available. A number of these relate to the debug targets you may have +declared. For example, the 'mww' command will not be available until a +target has been successfuly instantiated. If you want to use those +commands, you may need to force entry to the run stage. + + -- Config Command: init + This command terminates the configuration stage and enters the run + stage. This helps when you need to have the startup scripts manage + tasks such as resetting the target, programming flash, etc. To + reset the CPU upon startup, add "init" and "reset" at the end of + the config script or at the end of the OpenOCD command line using + the '-c' command line switch. + + If this command does not appear in any startup/configuration file + OpenOCD executes the command for you after processing all + configuration files and/or command line options. + + NOTE: This command normally occurs at or near the end of your + openocd.cfg file to force OpenOCD to "initialize" and make the + targets ready. For example: If your openocd.cfg file needs to + read/write memory on your target, 'init' must occur before the + memory read/write commands. This includes 'nand probe'. + + -- Overridable Procedure: jtag_init + This is invoked at server startup to verify that it can talk to the + scan chain (list of TAPs) which has been configured. + + The default implementation first tries 'jtag arp_init', which uses + only a lightweight JTAG reset before examining the scan chain. If + that fails, it tries again, using a harder reset from the + overridable procedure 'init_reset'. + + Implementations must have verified the JTAG scan chain before they + return. This is done by calling 'jtag arp_init' (or 'jtag + arp_init-reset'). + +7.3 TCP/IP Ports +================ + +The OpenOCD server accepts remote commands in several syntaxes. Each +syntax uses a different TCP/IP port, which you may specify only during +configuration (before those ports are opened). + +For reasons including security, you may wish to prevent remote access +using one or more of these ports. In such cases, just specify the +relevant port number as zero. If you disable all access through TCP/IP, +you will need to use the command line '-pipe' option. + + -- Command: gdb_port [number] + Normally gdb listens to a TCP/IP port, but GDB can also communicate + via pipes(stdin/out or named pipes). The name "gdb_port" stuck + because it covers probably more than 90% of the normal use cases. + + No arguments reports GDB port. "pipe" means listen to stdin output + to stdout, an integer is base port number, "disable" disables the + gdb server. + + When using "pipe", also use log_output to redirect the log output + to a file so as not to flood the stdin/out pipes. + + The -p/-pipe option is deprecated and a warning is printed as it is + equivalent to passing in -c "gdb_port pipe; log_output + openocd.log". + + Any other string is interpreted as named pipe to listen to. Output + pipe is the same name as input pipe, but with 'o' appended, e.g. + /var/gdb, /var/gdbo. + + The GDB port for the first target will be the base port, the second + target will listen on gdb_port + 1, and so on. When not specified + during the configuration stage, the port NUMBER defaults to 3333. + + -- Command: tcl_port [number] + Specify or query the port used for a simplified RPC connection that + can be used by clients to issue TCL commands and get the output + from the Tcl engine. Intended as a machine interface. When not + specified during the configuration stage, the port NUMBER defaults + to 6666. + + -- Command: telnet_port [number] + Specify or query the port on which to listen for incoming telnet + connections. This port is intended for interaction with one human + through TCL commands. When not specified during the configuration + stage, the port NUMBER defaults to 4444. When specified as zero, + this port is not activated. + +7.4 GDB Configuration +===================== + +You can reconfigure some GDB behaviors if needed. The ones listed here +are static and global. *Note Target Configuration: targetconfiguration, +about configuring individual targets. *Note Target Events: +targetevents, about configuring target-specific event handling. + + -- Command: gdb_breakpoint_override ['hard'|'soft'|'disable'] + Force breakpoint type for gdb 'break' commands. This option + supports GDB GUIs which don't distinguish hard versus soft + breakpoints, if the default OpenOCD and GDB behaviour is not + sufficient. GDB normally uses hardware breakpoints if the memory + map has been set up for flash regions. + + -- Config Command: gdb_flash_program ('enable'|'disable') + Set to 'enable' to cause OpenOCD to program the flash memory when a + vFlash packet is received. The default behaviour is 'enable'. + + -- Config Command: gdb_memory_map ('enable'|'disable') + Set to 'enable' to cause OpenOCD to send the memory configuration + to GDB when requested. GDB will then know when to set hardware + breakpoints, and program flash using the GDB load command. + 'gdb_flash_program enable' must also be enabled for flash + programming to work. Default behaviour is 'enable'. *Note + gdb_flash_program: gdbflashprogram. + + -- Config Command: gdb_report_data_abort ('enable'|'disable') + Specifies whether data aborts cause an error to be reported by GDB + memory read packets. The default behaviour is 'disable'; use + 'enable' see these errors reported. + +7.5 Event Polling +================= + +Hardware debuggers are parts of asynchronous systems, where significant +events can happen at any time. The OpenOCD server needs to detect some +of these events, so it can report them to through TCL command line or to +GDB. + +Examples of such events include: + + * One of the targets can stop running ... maybe it triggers a code + breakpoint or data watchpoint, or halts itself. + * Messages may be sent over "debug message" channels ... many + targets support such messages sent over JTAG, for receipt by the + person debugging or tools. + * Loss of power ... some adapters can detect these events. + * Resets not issued through JTAG ... such reset sources can include + button presses or other system hardware, sometimes including the + target itself (perhaps through a watchdog). + * Debug instrumentation sometimes supports event triggering such as + "trace buffer full" (so it can quickly be emptied) or other signals + (to correlate with code behavior). + +None of those events are signaled through standard JTAG signals. +However, most conventions for JTAG connectors include voltage level and +system reset (SRST) signal detection. Some connectors also include +instrumentation signals, which can imply events when those signals are +inputs. + +In general, OpenOCD needs to periodically check for those events, either +by looking at the status of signals on the JTAG connector or by sending +synchronous "tell me your status" JTAG requests to the various active +targets. There is a command to manage and monitor that polling, which +is normally done in the background. + + -- Command: poll ['on'|'off'] + Poll the current target for its current state. (Also, *note target + curstate: targetcurstate.) If that target is in debug mode, + architecture specific information about the current state is + printed. An optional parameter allows background polling to be + enabled and disabled. + + You could use this from the TCL command shell, or from GDB using + 'monitor poll' command. Leave background polling enabled while + you're using GDB. + > poll + background polling: on + target state: halted + target halted in ARM state due to debug-request, \ + current mode: Supervisor + cpsr: 0x800000d3 pc: 0x11081bfc + MMU: disabled, D-Cache: disabled, I-Cache: enabled + > + + +File: openocd.info, Node: Debug Adapter Configuration, Next: Reset Configuration, Prev: Daemon Configuration, Up: Top + +8 Debug Adapter Configuration +***************************** + +Correctly installing OpenOCD includes making your operating system give +OpenOCD access to debug adapters. Once that has been done, Tcl commands +are used to select which one is used, and to configure how it is used. + + Note: Because OpenOCD started out with a focus purely on JTAG, you + may find places where it wrongly presumes JTAG is the only + transport protocol in use. Be aware that recent versions of + OpenOCD are removing that limitation. JTAG remains more functional + than most other transports. Other transports do not support + boundary scan operations, or may be specific to a given chip + vendor. Some might be usable only for programming flash memory, + instead of also for debugging. + +Debug Adapters/Interfaces/Dongles are normally configured through +commands in an interface configuration file which is sourced by your +'openocd.cfg' file, or through a command line '-f interface/....cfg' +option. + + source [find interface/olimex-jtag-tiny.cfg] + +These commands tell OpenOCD what type of JTAG adapter you have, and how +to talk to it. A few cases are so simple that you only need to say what +driver to use: + + # jlink interface + interface jlink + +Most adapters need a bit more configuration than that. + +8.1 Interface Configuration +=========================== + +The interface command tells OpenOCD what type of debug adapter you are +using. Depending on the type of adapter, you may need to use one or +more additional commands to further identify or configure the adapter. + + -- Config Command: interface name + Use the interface driver NAME to connect to the target. + + -- Command: interface_list + List the debug adapter drivers that have been built into the + running copy of OpenOCD. + -- Command: interface transports transport_name+ + Specifies the transports supported by this debug adapter. The + adapter driver builds-in similar knowledge; use this only when + external configuration (such as jumpering) changes what the + hardware can support. + + -- Command: adapter_name + Returns the name of the debug adapter driver being used. + +8.2 Interface Drivers +===================== + +Each of the interface drivers listed here must be explicitly enabled +when OpenOCD is configured, in order to be made available at run time. + + -- Interface Driver: amt_jtagaccel + Amontec Chameleon in its JTAG Accelerator configuration, connected + to a PC's EPP mode parallel port. This defines some + driver-specific commands: + + -- Config Command: parport_port number + Specifies either the address of the I/O port (default: 0x378 + for LPT1) or the number of the '/dev/parport' device. + + -- Config Command: rtck ['enable'|'disable'] + Displays status of RTCK option. Optionally sets that option + first. + + -- Interface Driver: arm-jtag-ew + Olimex ARM-JTAG-EW USB adapter This has one driver-specific + command: + + -- Command: armjtagew_info + Logs some status + + -- Interface Driver: at91rm9200 + Supports bitbanged JTAG from the local system, presuming that + system is an Atmel AT91rm9200 and a specific set of GPIOs is used. + + -- Interface Driver: dummy + A dummy software-only driver for debugging. + + -- Interface Driver: ep93xx + Cirrus Logic EP93xx based single-board computer bit-banging (in + development) + + -- Interface Driver: ft2232 + FTDI FT2232 (USB) based devices over one of the userspace + libraries. + + Note that this driver has several flaws and the 'ftdi' driver is + recommended as its replacement. + + These interfaces have several commands, used to configure the + driver before initializing the JTAG scan chain: + + -- Config Command: ft2232_device_desc description + Provides the USB device description (the _iProduct string_) of + the FTDI FT2232 device. If not specified, the FTDI default + value is used. This setting is only valid if compiled with + FTD2XX support. + + -- Config Command: ft2232_serial serial-number + Specifies the SERIAL-NUMBER of the FTDI FT2232 device to use, + in case the vendor provides unique IDs and more than one + FT2232 device is connected to the host. If not specified, + serial numbers are not considered. (Note that USB serial + numbers can be arbitrary Unicode strings, and are not + restricted to containing only decimal digits.) + + -- Config Command: ft2232_layout name + Each vendor's FT2232 device can use different GPIO signals to + control output-enables, reset signals, and LEDs. Currently + valid layout NAME values include: + - axm0432_jtag Axiom AXM-0432 + - comstick Hitex STR9 comstick + - cortino Hitex Cortino JTAG interface + - evb_lm3s811 TI/Luminary Micro EVB_LM3S811 as a JTAG + interface, either for the local Cortex-M3 (SRST only) or + in a passthrough mode (neither SRST nor TRST) This layout + can not support the SWO trace mechanism, and should be + used only for older boards (before rev C). + - luminary_icdi This layout should be used with most + TI/Luminary eval boards, including Rev C LM3S811 eval + boards and the eponymous ICDI boards, to debug either the + local Cortex-M3 or in passthrough mode to debug some + other target. It can support the SWO trace mechanism. + - flyswatter Tin Can Tools Flyswatter + - icebear ICEbear JTAG adapter from Section 5 + - jtagkey Amontec JTAGkey and JTAGkey-Tiny (and + compatibles) + - jtagkey2 Amontec JTAGkey2 (and compatibles) + - m5960 American Microsystems M5960 + - olimex-jtag Olimex ARM-USB-OCD and ARM-USB-Tiny + - oocdlink OOCDLink + - redbee-econotag Integrated with a Redbee development + board. + - redbee-usb Integrated with a Redbee USB-stick development + board. + - sheevaplug Marvell Sheevaplug development kit + - signalyzer Xverve Signalyzer + - stm32stick Hitex STM32 Performance Stick + - turtelizer2 egnite Software turtelizer2 + - usbjtag "USBJTAG-1" layout described in the OpenOCD + diploma thesis + + -- Config Command: ft2232_vid_pid [vid pid]+ + The vendor ID and product ID of the FTDI FT2232 device. If + not specified, the FTDI default values are used. Currently, + up to eight [VID, PID] pairs may be given, e.g. + ft2232_vid_pid 0x0403 0xcff8 0x15ba 0x0003 + + -- Config Command: ft2232_latency ms + On some systems using FT2232 based JTAG interfaces the FT_Read + function call in ft2232_read() fails to return the expected + number of bytes. This can be caused by USB communication + delays and has proved hard to reproduce and debug. Setting + the FT2232 latency timer to a larger value increases delays + for short USB packets but it also reduces the risk of timeouts + before receiving the expected number of bytes. The OpenOCD + default value is 2 and for some systems a value of 10 has + proved useful. + + -- Config Command: ft2232_channel channel + Used to select the channel of the ft2232 chip to use (between + 1 and 4). The default value is 1. + + For example, the interface config file for a Turtelizer JTAG + Adapter looks something like this: + + interface ft2232 + ft2232_device_desc "Turtelizer JTAG/RS232 Adapter" + ft2232_layout turtelizer2 + ft2232_vid_pid 0x0403 0xbdc8 + + -- Interface Driver: ftdi + This driver is for adapters using the MPSSE (Multi-Protocol + Synchronous Serial Engine) mode built into many FTDI chips, such as + the FT2232, FT4232 and FT232H. It is a complete rewrite to address + a large number of problems with the ft2232 interface driver. + + The driver is using libusb-1.0 in asynchronous mode to talk to the + FTDI device, bypassing intermediate libraries like libftdi of D2XX. + Performance-wise it is consistently faster than the ft2232 driver, + sometimes several times faster. + + A major improvement of this driver is that support for new FTDI + based adapters can be added competely through configuration files, + without the need to patch and rebuild OpenOCD. + + The driver uses a signal abstraction to enable Tcl configuration + files to define outputs for one or several FTDI GPIO. These outputs + can then be controlled using the 'ftdi_set_signal' command. + Special signal names are reserved for nTRST, nSRST and LED (for + blink) so that they, if defined, will be used for their customary + purpose. + + Depending on the type of buffer attached to the FTDI GPIO, the + outputs have to be controlled differently. In order to support + tristateable signals such as nSRST, both a data GPIO and an + output-enable GPIO can be specified for each signal. The following + output buffer configurations are supported: + + - Push-pull with one FTDI output as (non-)inverted data line + - Open drain with one FTDI output as (non-)inverted + output-enable + - Tristate with one FTDI output as (non-)inverted data line and + another FTDI output as (non-)inverted output-enable + - Unbuffered, using the FTDI GPIO as a tristate output directly + by switching data and direction as necessary + + These interfaces have several commands, used to configure the + driver before initializing the JTAG scan chain: + + -- Config Command: ftdi_vid_pid [vid pid]+ + The vendor ID and product ID of the adapter. If not + specified, the FTDI default values are used. Currently, up to + eight [VID, PID] pairs may be given, e.g. + ftdi_vid_pid 0x0403 0xcff8 0x15ba 0x0003 + + -- Config Command: ftdi_device_desc description + Provides the USB device description (the _iProduct string_) of + the adapter. If not specified, the device description is + ignored during device selection. + + -- Config Command: ftdi_serial serial-number + Specifies the SERIAL-NUMBER of the adapter to use, in case the + vendor provides unique IDs and more than one adapter is + connected to the host. If not specified, serial numbers are + not considered. (Note that USB serial numbers can be + arbitrary Unicode strings, and are not restricted to + containing only decimal digits.) + + -- Config Command: ftdi_channel channel + Selects the channel of the FTDI device to use for MPSSE + operations. Most adapters use the default, channel 0, but + there are exceptions. + + -- Config Command: ftdi_layout_init data direction + Specifies the initial values of the FTDI GPIO data and + direction registers. Each value is a 16-bit number + corresponding to the concatenation of the high and low FTDI + GPIO registers. The values should be selected based on the + schematics of the adapter, such that all signals are set to + safe levels with minimal impact on the target system. Avoid + floating inputs, conflicting outputs and initially asserted + reset signals. + + -- Config Command: ftdi_layout_signal name ['-data'|'-ndata' + data_mask] ['-oe'|'-noe' oe_mask] + Creates a signal with the specified NAME, controlled by one or + more FTDI GPIO pins via a range of possible buffer + connections. The masks are FTDI GPIO register bitmasks to + tell the driver the connection and type of the output buffer + driving the respective signal. DATA_MASK is the bitmask for + the pin(s) connected to the data input of the output buffer. + '-ndata' is used with inverting data inputs and '-data' with + non-inverting inputs. The '-oe' (or '-noe') option tells + where the output-enable (or not-output-enable) input to the + output buffer is connected. + + Both DATA_MASK and OE_MASK need not be specified. For + example, a simple open-collector transistor driver would be + specified with '-oe' only. In that case the signal can only + be set to drive low or to Hi-Z and the driver will complain if + the signal is set to drive high. Which means that if it's a + reset signal, 'reset_config' must be specified as + 'srst_open_drain', not 'srst_push_pull'. + + A special case is provided when '-data' and '-oe' is set to + the same bitmask. Then the FTDI pin is considered being + connected straight to the target without any buffer. The FTDI + pin is then switched between output and input as necessary to + provide the full set of low, high and Hi-Z characteristics. + In all other cases, the pins specified in a signal definition + are always driven by the FTDI. + + -- Command: ftdi_set_signal name '0'|'1'|'z' + Set a previously defined signal to the specified level. + - '0', drive low + - '1', drive high + - 'z', set to high-impedance + + For example adapter definitions, see the configuration files + shipped in the 'interface/ftdi' directory. + + -- Interface Driver: remote_bitbang + Drive JTAG from a remote process. This sets up a UNIX or TCP + socket connection with a remote process and sends ASCII encoded + bitbang requests to that process instead of directly driving JTAG. + + The remote_bitbang driver is useful for debugging software running + on processors which are being simulated. + + -- Config Command: remote_bitbang_port number + Specifies the TCP port of the remote process to connect to or + 0 to use UNIX sockets instead of TCP. + + -- Config Command: remote_bitbang_host hostname + Specifies the hostname of the remote process to connect to + using TCP, or the name of the UNIX socket to use if + remote_bitbang_port is 0. + + For example, to connect remotely via TCP to the host foobar you + might have something like: + + interface remote_bitbang + remote_bitbang_port 3335 + remote_bitbang_host foobar + + To connect to another process running locally via UNIX sockets with + socket named mysocket: + + interface remote_bitbang + remote_bitbang_port 0 + remote_bitbang_host mysocket + + -- Interface Driver: usb_blaster + USB JTAG/USB-Blaster compatibles over one of the userspace + libraries for FTDI chips. These interfaces have several commands, + used to configure the driver before initializing the JTAG scan + chain: + + -- Config Command: usb_blaster_device_desc description + Provides the USB device description (the _iProduct string_) of + the FTDI FT245 device. If not specified, the FTDI default + value is used. This setting is only valid if compiled with + FTD2XX support. + + -- Config Command: usb_blaster_vid_pid vid pid + The vendor ID and product ID of the FTDI FT245 device. If not + specified, default values are used. Currently, only one VID, + PID pair may be given, e.g. for Altera USB-Blaster (default): + usb_blaster_vid_pid 0x09FB 0x6001 + The following VID/PID is for Kolja Waschk's USB JTAG: + usb_blaster_vid_pid 0x16C0 0x06AD + + -- Command: usb_blaster ('pin6'|'pin8') ('0'|'1') + Sets the state of the unused GPIO pins on USB-Blasters (pins 6 + and 8 on the female JTAG header). These pins can be used as + SRST and/or TRST provided the appropriate connections are made + on the target board. + + For example, to use pin 6 as SRST (as with an AVR board): + $_TARGETNAME configure -event reset-assert \ + "usb_blaster pin6 1; wait 1; usb_blaster pin6 0" + + -- Interface Driver: gw16012 + Gateworks GW16012 JTAG programmer. This has one driver-specific + command: + + -- Config Command: parport_port [port_number] + Display either the address of the I/O port (default: 0x378 for + LPT1) or the number of the '/dev/parport' device. If a + parameter is provided, first switch to use that port. This is + a write-once setting. + + -- Interface Driver: jlink + Segger J-Link family of USB adapters. It currently supports only + the JTAG transport. + + Compatibility Note: Segger released many firmware versions for + the many harware versions they produced. OpenOCD was + extensively tested and intended to run on all of them, but + some combinations were reported as incompatible. As a general + recommendation, it is advisable to use the latest firmware + version available for each hardware version. However the + current V8 is a moving target, and Segger firmware versions + released after the OpenOCD was released may not be compatible. + In such cases it is recommended to revert to the last known + functional version. For 0.5.0, this is from "Feb 8 2012 + 14:30:39", packed with 4.42c. For 0.6.0, the last known + version is from "May 3 2012 18:36:22", packed with 4.46f. + + -- Command: jlink caps + Display the device firmware capabilities. + -- Command: jlink info + Display various device information, like hardware version, + firmware version, current bus status. + -- Command: jlink hw_jtag ['2'|'3'] + Set the JTAG protocol version to be used. Without argument, + show the actual JTAG protocol version. + -- Command: jlink config + Display the J-Link configuration. + -- Command: jlink config kickstart [val] + Set the Kickstart power on JTAG-pin 19. Without argument, + show the Kickstart configuration. + -- Command: jlink config mac_address ['ff:ff:ff:ff:ff:ff'] + Set the MAC address of the J-Link Pro. Without argument, show + the MAC address. + -- Command: jlink config ip ['A.B.C.D'('/E'|'F.G.H.I')] + Set the IP configuration of the J-Link Pro, where A.B.C.D is + the IP address, E the bit of the subnet mask and F.G.H.I the + subnet mask. Without arguments, show the IP configuration. + -- Command: jlink config usb_address ['0x00' to '0x03' or '0xff'] + Set the USB address; this will also change the product id. + Without argument, show the USB address. + -- Command: jlink config reset + Reset the current configuration. + -- Command: jlink config save + Save the current configuration to the internal persistent + storage. + -- Config: jlink pid val + Set the USB PID of the interface. As a configuration command, + it can be used only before 'init'. + + -- Interface Driver: parport + Supports PC parallel port bit-banging cables: Wigglers, PLD + download cable, and more. These interfaces have several commands, + used to configure the driver before initializing the JTAG scan + chain: + + -- Config Command: parport_cable name + Set the layout of the parallel port cable used to connect to + the target. This is a write-once setting. Currently valid + cable NAME values include: + + - altium Altium Universal JTAG cable. + - arm-jtag Same as original wiggler except SRST and TRST + connections reversed and TRST is also inverted. + - chameleon The Amontec Chameleon's CPLD when operated in + configuration mode. This is only used to program the + Chameleon itself, not a connected target. + - dlc5 The Xilinx Parallel cable III. + - flashlink The ST Parallel cable. + - lattice Lattice ispDOWNLOAD Cable + - old_amt_wiggler The Wiggler configuration that comes with + some versions of Amontec's Chameleon Programmer. The new + version available from the website uses the original + Wiggler layout ('WIGGLER') + - triton The parallel port adapter found on the "Karo + Triton 1 Development Board". This is also the layout + used by the HollyGates design (see + ). + - wiggler The original Wiggler layout, also supported by + several clones, such as the Olimex ARM-JTAG + - wiggler2 Same as original wiggler except an led is fitted + on D5. + - wiggler_ntrst_inverted Same as original wiggler except + TRST is inverted. + + -- Config Command: parport_port [port_number] + Display either the address of the I/O port (default: 0x378 for + LPT1) or the number of the '/dev/parport' device. If a + parameter is provided, first switch to use that port. This is + a write-once setting. + + When using PPDEV to access the parallel port, use the number + of the parallel port: 'parport_port 0' (the default). If + 'parport_port 0x378' is specified you may encounter a problem. + + -- Command: parport_toggling_time [nanoseconds] + Displays how many nanoseconds the hardware needs to toggle + TCK; the parport driver uses this value to obey the + 'adapter_khz' configuration. When the optional NANOSECONDS + parameter is given, that setting is changed before displaying + the current value. + + The default setting should work reasonably well on commodity + PC hardware. However, you may want to calibrate for your + specific hardware. + Tip: To measure the toggling time with a logic analyzer + or a digital storage oscilloscope, follow the procedure + below: + > parport_toggling_time 1000 + > adapter_khz 500 + This sets the maximum JTAG clock speed of the hardware, + but the actual speed probably deviates from the requested + 500 kHz. Now, measure the time between the two closest + spaced TCK transitions. You can use 'runtest 1000' or + something similar to generate a large set of samples. + Update the setting to match your measurement: + > parport_toggling_time + Now the clock speed will be a better match for + 'adapter_khz rate' commands given in OpenOCD scripts and + event handlers. + + You can do something similar with many digital + multimeters, but note that you'll probably need to run + the clock continuously for several seconds before it + decides what clock rate to show. Adjust the toggling + time up or down until the measured clock rate is a good + match for the adapter_khz rate you specified; be + conservative. + + -- Config Command: parport_write_on_exit ('on'|'off') + This will configure the parallel driver to write a known + cable-specific value to the parallel interface on exiting + OpenOCD. + + For example, the interface configuration file for a classic + "Wiggler" cable on LPT2 might look something like this: + + interface parport + parport_port 0x278 + parport_cable wiggler + + -- Interface Driver: presto + ASIX PRESTO USB JTAG programmer. + -- Config Command: presto_serial serial_string + Configures the USB serial number of the Presto device to use. + + -- Interface Driver: rlink + Raisonance RLink USB adapter + + -- Interface Driver: usbprog + usbprog is a freely programmable USB adapter. + + -- Interface Driver: vsllink + vsllink is part of Versaloon which is a versatile USB programmer. + + Note: This defines quite a few driver-specific commands, which + are not currently documented here. + + -- Interface Driver: hla + This is a driver that supports multiple High Level Adapters. This + type of adapter does not expose some of the lower level api's that + OpenOCD would normally use to access the target. + + Currently supported adapters include the ST STLINK and TI ICDI. + + -- Config Command: hla_device_desc description + Currently Not Supported. + + -- Config Command: hla_serial serial + Currently Not Supported. + + -- Config Command: hla_layout ('stlink'|'icdi') + Specifies the adapter layout to use. + + -- Config Command: hla_vid_pid vid pid + The vendor ID and product ID of the device. + + -- Config Command: stlink_api api_level + Manually sets the stlink api used, valid options are 1 or 2. + (STLINK Only). + + -- Interface Driver: opendous + opendous-jtag is a freely programmable USB adapter. + + -- Interface Driver: ulink + This is the Keil ULINK v1 JTAG debugger. + + -- Interface Driver: ZY1000 + This is the Zylin ZY1000 JTAG debugger. + + Note: This defines some driver-specific commands, which are not + currently documented here. + + -- Command: power ['on'|'off'] + Turn power switch to target on/off. No arguments: print status. + +8.3 Transport Configuration +=========================== + +As noted earlier, depending on the version of OpenOCD you use, and the +debug adapter you are using, several transports may be available to +communicate with debug targets (or perhaps to program flash memory). + -- Command: transport list + displays the names of the transports supported by this version of + OpenOCD. + + -- Command: transport select transport_name + Select which of the supported transports to use in this OpenOCD + session. The transport must be supported by the debug adapter + hardware and by the version of OPenOCD you are using (including the + adapter's driver). No arguments: returns name of session's + selected transport. + +8.3.1 JTAG Transport +-------------------- + +JTAG is the original transport supported by OpenOCD, and most of the +OpenOCD commands support it. JTAG transports expose a chain of one or +more Test Access Points (TAPs), each of which must be explicitly +declared. JTAG supports both debugging and boundary scan testing. +Flash programming support is built on top of debug support. + +8.3.2 SWD Transport +------------------- + +SWD (Serial Wire Debug) is an ARM-specific transport which exposes one +Debug Access Point (DAP, which must be explicitly declared. (SWD uses +fewer signal wires than JTAG.) SWD is debug-oriented, and does not +support boundary scan testing. Flash programming support is built on +top of debug support. (Some processors support both JTAG and SWD.) + -- Command: swd newdap ... + Declares a single DAP which uses SWD transport. Parameters are + currently the same as "jtag newtap" but this is expected to change. + -- Command: swd wcr trn prescale + Updates TRN (turnaraound delay) and prescaling.fields of the Wire + Control Register (WCR). No parameters: displays current settings. + +8.3.3 SPI Transport +------------------- + +The Serial Peripheral Interface (SPI) is a general purpose transport +which uses four wire signaling. Some processors use it as part of a +solution for flash programming. + +8.4 JTAG Speed +============== + +JTAG clock setup is part of system setup. It _does not belong with +interface setup_ since any interface only knows a few of the constraints +for the JTAG clock speed. Sometimes the JTAG speed is changed during +the target initialization process: (1) slow at reset, (2) program the +CPU clocks, (3) run fast. Both the "slow" and "fast" clock rates are +functions of the oscillators used, the chip, the board design, and +sometimes power management software that may be active. + +The speed used during reset, and the scan chain verification which +follows reset, can be adjusted using a 'reset-start' target event +handler. It can then be reconfigured to a faster speed by a +'reset-init' target event handler after it reprograms those CPU clocks, +or manually (if something else, such as a boot loader, sets up those +clocks). *Note Target Events: targetevents. When the initial low JTAG +speed is a chip characteristic, perhaps because of a required oscillator +speed, provide such a handler in the target config file. When that +speed is a function of a board-specific characteristic such as which +speed oscillator is used, it belongs in the board config file instead. +In both cases it's safest to also set the initial JTAG clock rate to +that same slow speed, so that OpenOCD never starts up using a clock +speed that's faster than the scan chain can support. + + jtag_rclk 3000 + $_TARGET.cpu configure -event reset-start { jtag_rclk 3000 } + +If your system supports adaptive clocking (RTCK), configuring JTAG to +use that is probably the most robust approach. However, it introduces +delays to synchronize clocks; so it may not be the fastest solution. + +NOTE: Script writers should consider using 'jtag_rclk' instead of +'adapter_khz', but only for (ARM) cores and boards which support +adaptive clocking. + + -- Command: adapter_khz max_speed_kHz + A non-zero speed is in KHZ. Hence: 3000 is 3mhz. JTAG interfaces + usually support a limited number of speeds. The speed actually + used won't be faster than the speed specified. + + Chip data sheets generally include a top JTAG clock rate. The + actual rate is often a function of a CPU core clock, and is + normally less than that peak rate. For example, most ARM cores + accept at most one sixth of the CPU clock. + + Speed 0 (khz) selects RTCK method. *Note FAQ RTCK: faqrtck. If + your system uses RTCK, you won't need to change the JTAG clocking + after setup. Not all interfaces, boards, or targets support + "rtck". If the interface device can not support it, an error is + returned when you try to use RTCK. + + -- Function: jtag_rclk fallback_speed_kHz + This Tcl proc (defined in 'startup.tcl') attempts to enable + RTCK/RCLK. If that fails (maybe the interface, board, or target + doesn't support it), falls back to the specified frequency. + # Fall back to 3mhz if RTCK is not supported + jtag_rclk 3000 + + +File: openocd.info, Node: Reset Configuration, Next: TAP Declaration, Prev: Debug Adapter Configuration, Up: Top + +9 Reset Configuration +********************* + +Every system configuration may require a different reset configuration. +This can also be quite confusing. Resets also interact with RESET-INIT +event handlers, which do things like setting up clocks and DRAM, and +JTAG clock rates. (*Note JTAG Speed: jtagspeed.) They can also +interact with JTAG routers. Please see the various board files for +examples. + + Note: To maintainers and integrators: Reset configuration touches + several things at once. Normally the board configuration file + should define it and assume that the JTAG adapter supports + everything that's wired up to the board's JTAG connector. + + However, the target configuration file could also make note of + something the silicon vendor has done inside the chip, which will + be true for most (or all) boards using that chip. And when the + JTAG adapter doesn't support everything, the user configuration + file will need to override parts of the reset configuration + provided by other files. + +9.1 Types of Reset +================== + +There are many kinds of reset possible through JTAG, but they may not +all work with a given board and adapter. That's part of why reset +configuration can be error prone. + + * _System Reset_ ... the _SRST_ hardware signal resets all chips + connected to the JTAG adapter, such as processors, power management + chips, and I/O controllers. Normally resets triggered with this + signal behave exactly like pressing a RESET button. + * _JTAG TAP Reset_ ... the _TRST_ hardware signal resets just the + TAP controllers connected to the JTAG adapter. Such resets should + not be visible to the rest of the system; resetting a device's TAP + controller just puts that controller into a known state. + * _Emulation Reset_ ... many devices can be reset through JTAG + commands. These resets are often distinguishable from system + resets, either explicitly (a "reset reason" register says so) or + implicitly (not all parts of the chip get reset). + * _Other Resets_ ... system-on-chip devices often support several + other types of reset. You may need to arrange that a watchdog + timer stops while debugging, preventing a watchdog reset. There + may be individual module resets. + +In the best case, OpenOCD can hold SRST, then reset the TAPs via TRST +and send commands through JTAG to halt the CPU at the reset vector +before the 1st instruction is executed. Then when it finally releases +the SRST signal, the system is halted under debugger control before any +code has executed. This is the behavior required to support the 'reset +halt' and 'reset init' commands; after 'reset init' a board-specific +script might do things like setting up DRAM. (*Note Reset Command: +resetcommand.) + +9.2 SRST and TRST Issues +======================== + +Because SRST and TRST are hardware signals, they can have a variety of +system-specific constraints. Some of the most common issues are: + + * _Signal not available_ ... Some boards don't wire SRST or TRST to + the JTAG connector. Some JTAG adapters don't support such signals + even if they are wired up. Use the 'reset_config' SIGNALS options + to say when either of those signals is not connected. When SRST is + not available, your code might not be able to rely on controllers + having been fully reset during code startup. Missing TRST is not a + problem, since JTAG-level resets can be triggered using with TMS + signaling. + + * _Signals shorted_ ... Sometimes a chip, board, or adapter will + connect SRST to TRST, instead of keeping them separate. Use the + 'reset_config' COMBINATION options to say when those signals aren't + properly independent. + + * _Timing_ ... Reset circuitry like a resistor/capacitor delay + circuit, reset supervisor, or on-chip features can extend the + effect of a JTAG adapter's reset for some time after the adapter + stops issuing the reset. For example, there may be chip or board + requirements that all reset pulses last for at least a certain + amount of time; and reset buttons commonly have hardware + debouncing. Use the 'adapter_nsrst_delay' and 'jtag_ntrst_delay' + commands to say when extra delays are needed. + + * _Drive type_ ... Reset lines often have a pullup resistor, letting + the JTAG interface treat them as open-drain signals. But that's + not a requirement, so the adapter may need to use push/pull output + drivers. Also, with weak pullups it may be advisable to drive + signals to both levels (push/pull) to minimize rise times. Use the + 'reset_config' TRST_TYPE and SRST_TYPE parameters to say how to + drive reset signals. + + * _Special initialization_ ... Targets sometimes need special JTAG + initialization sequences to handle chip-specific issues (not + limited to errata). For example, certain JTAG commands might need + to be issued while the system as a whole is in a reset state (SRST + active) but the JTAG scan chain is usable (TRST inactive). Many + systems treat combined assertion of SRST and TRST as a trigger for + a harder reset than SRST alone. Such custom reset handling is + discussed later in this chapter. + +There can also be other issues. Some devices don't fully conform to the +JTAG specifications. Trivial system-specific differences are common, +such as SRST and TRST using slightly different names. There are also +vendors who distribute key JTAG documentation for their chips only to +developers who have signed a Non-Disclosure Agreement (NDA). + +Sometimes there are chip-specific extensions like a requirement to use +the normally-optional TRST signal (precluding use of JTAG adapters which +don't pass TRST through), or needing extra steps to complete a TAP +reset. + +In short, SRST and especially TRST handling may be very finicky, needing +to cope with both architecture and board specific constraints. + +9.3 Commands for Handling Resets +================================ + + -- Command: adapter_nsrst_assert_width milliseconds + Minimum amount of time (in milliseconds) OpenOCD should wait after + asserting nSRST (active-low system reset) before allowing it to be + deasserted. + + -- Command: adapter_nsrst_delay milliseconds + How long (in milliseconds) OpenOCD should wait after deasserting + nSRST (active-low system reset) before starting new JTAG + operations. When a board has a reset button connected to SRST line + it will probably have hardware debouncing, implying you should use + this. + + -- Command: jtag_ntrst_assert_width milliseconds + Minimum amount of time (in milliseconds) OpenOCD should wait after + asserting nTRST (active-low JTAG TAP reset) before allowing it to + be deasserted. + + -- Command: jtag_ntrst_delay milliseconds + How long (in milliseconds) OpenOCD should wait after deasserting + nTRST (active-low JTAG TAP reset) before starting new JTAG + operations. + + -- Command: reset_config mode_flag ... + This command displays or modifies the reset configuration of your + combination of JTAG board and target in target configuration + scripts. + + Information earlier in this section describes the kind of problems + the command is intended to address (*note SRST and TRST Issues: + srstandtrstissues.). As a rule this command belongs only in board + config files, describing issues like _board doesn't connect TRST_; + or in user config files, addressing limitations derived from a + particular combination of interface and board. (An unlikely + example would be using a TRST-only adapter with a board that only + wires up SRST.) + + The MODE_FLAG options can be specified in any order, but only one + of each type - SIGNALS, COMBINATION, GATES, TRST_TYPE, SRST_TYPE + and CONNECT_TYPE - may be specified at a time. If you don't + provide a new value for a given type, its previous value (perhaps + the default) is unchanged. For example, this means that you don't + need to say anything at all about TRST just to declare that if the + JTAG adapter should want to drive SRST, it must explicitly be + driven high ('srst_push_pull'). + + * SIGNALS can specify which of the reset signals are connected. + For example, If the JTAG interface provides SRST, but the + board doesn't connect that signal properly, then OpenOCD can't + use it. Possible values are 'none' (the default), + 'trst_only', 'srst_only' and 'trst_and_srst'. + + Tip: If your board provides SRST and/or TRST through the + JTAG connector, you must declare that so those signals + can be used. + + * The COMBINATION is an optional value specifying broken reset + signal implementations. The default behaviour if no option + given is 'separate', indicating everything behaves normally. + 'srst_pulls_trst' states that the test logic is reset together + with the reset of the system (e.g. NXP LPC2000, "broken" + board layout), 'trst_pulls_srst' says that the system is reset + together with the test logic (only hypothetical, I haven't + seen hardware with such a bug, and can be worked around). + 'combined' implies both 'srst_pulls_trst' and + 'trst_pulls_srst'. + + * The GATES tokens control flags that describe some cases where + JTAG may be unvailable during reset. 'srst_gates_jtag' + (default) indicates that asserting SRST gates the JTAG clock. + This means that no communication can happen on JTAG while SRST + is asserted. Its converse is 'srst_nogate', indicating that + JTAG commands can safely be issued while SRST is active. + + * The CONNECT_TYPE tokens control flags that describe some cases + where SRST is asserted while connecting to the target. + 'srst_nogate' is required to use this option. + 'connect_deassert_srst' (default) indicates that SRST will not + be asserted while connecting to the target. Its converse is + 'connect_assert_srst', indicating that SRST will be asserted + before any target connection. Only some targets support this + feature, STM32 and STR9 are examples. This feature is useful + if you are unable to connect to your target due to incorrect + options byte config or illegal program execution. + + The optional TRST_TYPE and SRST_TYPE parameters allow the driver + mode of each reset line to be specified. These values only affect + JTAG interfaces with support for different driver modes, like the + Amontec JTAGkey and JTAG Accelerator. Also, they are necessarily + ignored if the relevant signal (TRST or SRST) is not connected. + + * Possible TRST_TYPE driver modes for the test reset signal + (TRST) are the default 'trst_push_pull', and + 'trst_open_drain'. Most boards connect this signal to a + pulldown, so the JTAG TAPs never leave reset unless they are + hooked up to a JTAG adapter. + + * Possible SRST_TYPE driver modes for the system reset signal + (SRST) are the default 'srst_open_drain', and + 'srst_push_pull'. Most boards connect this signal to a + pullup, and allow the signal to be pulled low by various + events including system powerup and pressing a reset button. + +9.4 Custom Reset Handling +========================= + +OpenOCD has several ways to help support the various reset mechanisms +provided by chip and board vendors. The commands shown in the previous +section give standard parameters. There are also _event handlers_ +associated with TAPs or Targets. Those handlers are Tcl procedures you +can provide, which are invoked at particular points in the reset +sequence. + +_When SRST is not an option_ you must set up a 'reset-assert' event +handler for your target. For example, some JTAG adapters don't include +the SRST signal; and some boards have multiple targets, and you won't +always want to reset everything at once. + +After configuring those mechanisms, you might still find your board +doesn't start up or reset correctly. For example, maybe it needs a +slightly different sequence of SRST and/or TRST manipulations, because +of quirks that the 'reset_config' mechanism doesn't address; or +asserting both might trigger a stronger reset, which needs special +attention. + +Experiment with lower level operations, such as 'jtag_reset' and the +'jtag arp_*' operations shown here, to find a sequence of operations +that works. *Note JTAG Commands::. When you find a working sequence, +it can be used to override 'jtag_init', which fires during OpenOCD +startup (*note Configuration Stage: configurationstage.); or +'init_reset', which fires during reset processing. + +You might also want to provide some project-specific reset schemes. For +example, on a multi-target board the standard 'reset' command would +reset all targets, but you may need the ability to reset only one target +at time and thus want to avoid using the board-wide SRST signal. + + -- Overridable Procedure: init_reset mode + This is invoked near the beginning of the 'reset' command, usually + to provide as much of a cold (power-up) reset as practical. By + default it is also invoked from 'jtag_init' if the scan chain does + not respond to pure JTAG operations. The MODE parameter is the + parameter given to the low level reset command ('halt', 'init', or + 'run'), 'setup', or potentially some other value. + + The default implementation just invokes 'jtag arp_init-reset'. + Replacements will normally build on low level JTAG operations such + as 'jtag_reset'. Operations here must not address individual TAPs + (or their associated targets) until the JTAG scan chain has first + been verified to work. + + Implementations must have verified the JTAG scan chain before they + return. This is done by calling 'jtag arp_init' (or 'jtag + arp_init-reset'). + + -- Command: jtag arp_init + This validates the scan chain using just the four standard JTAG + signals (TMS, TCK, TDI, TDO). It starts by issuing a JTAG-only + reset. Then it performs checks to verify that the scan chain + configuration matches the TAPs it can observe. Those checks + include checking IDCODE values for each active TAP, and verifying + the length of their instruction registers using TAP '-ircapture' + and '-irmask' values. If these tests all pass, TAP 'setup' events + are issued to all TAPs with handlers for that event. + + -- Command: jtag arp_init-reset + This uses TRST and SRST to try resetting everything on the JTAG + scan chain (and anything else connected to SRST). It then invokes + the logic of 'jtag arp_init'. + + +File: openocd.info, Node: TAP Declaration, Next: CPU Configuration, Prev: Reset Configuration, Up: Top + +10 TAP Declaration +****************** + +_Test Access Ports_ (TAPs) are the core of JTAG. TAPs serve many roles, +including: + + * Debug Target A CPU TAP can be used as a GDB debug target + * Flash Programing Some chips program the flash directly via JTAG. + Others do it indirectly, making a CPU do it. + * Program Download Using the same CPU support GDB uses, you can + initialize a DRAM controller, download code to DRAM, and then start + running that code. + * Boundary Scan Most chips support boundary scan, which helps test + for board assembly problems like solder bridges and missing + connections + +OpenOCD must know about the active TAPs on your board(s). Setting up +the TAPs is the core task of your configuration files. Once those TAPs +are set up, you can pass their names to code which sets up CPUs and +exports them as GDB targets, probes flash memory, performs low-level +JTAG operations, and more. + +10.1 Scan Chains +================ + +TAPs are part of a hardware "scan chain", which is daisy chain of TAPs. +They also need to be added to OpenOCD's software mirror of that hardware +list, giving each member a name and associating other data with it. +Simple scan chains, with a single TAP, are common in systems with a +single microcontroller or microprocessor. More complex chips may have +several TAPs internally. Very complex scan chains might have a dozen or +more TAPs: several in one chip, more in the next, and connecting to +other boards with their own chips and TAPs. + +You can display the list with the 'scan_chain' command. (Don't confuse +this with the list displayed by the 'targets' command, presented in the +next chapter. That only displays TAPs for CPUs which are configured as +debugging targets.) Here's what the scan chain might look like for a +chip more than one TAP: + + TapName Enabled IdCode Expected IrLen IrCap IrMask +-- ------------------ ------- ---------- ---------- ----- ----- ------ + 0 omap5912.dsp Y 0x03df1d81 0x03df1d81 38 0x01 0x03 + 1 omap5912.arm Y 0x0692602f 0x0692602f 4 0x01 0x0f + 2 omap5912.unknown Y 0x00000000 0x00000000 8 0x01 0x03 + +OpenOCD can detect some of that information, but not all of it. *Note +Autoprobing: autoprobing. Unfortunately those TAPs can't always be +autoconfigured, because not all devices provide good support for that. +JTAG doesn't require supporting IDCODE instructions, and chips with JTAG +routers may not link TAPs into the chain until they are told to do so. + +The configuration mechanism currently supported by OpenOCD requires +explicit configuration of all TAP devices using 'jtag newtap' commands, +as detailed later in this chapter. A command like this would declare +one tap and name it 'chip1.cpu': + + jtag newtap chip1 cpu -irlen 4 -expected-id 0x3ba00477 + +Each target configuration file lists the TAPs provided by a given chip. +Board configuration files combine all the targets on a board, and so +forth. Note that _the order in which TAPs are declared is very +important._ It must match the order in the JTAG scan chain, both inside +a single chip and between them. *Note FAQ TAP Order: faqtaporder. + +For example, the ST Microsystems STR912 chip has three separate TAPs(1). +To configure those taps, 'target/str912.cfg' includes commands something +like this: + + jtag newtap str912 flash ... params ... + jtag newtap str912 cpu ... params ... + jtag newtap str912 bs ... params ... + +Actual config files use a variable instead of literals like 'str912', to +support more than one chip of each type. *Note Config File +Guidelines::. + + -- Command: jtag names + Returns the names of all current TAPs in the scan chain. Use 'jtag + cget' or 'jtag tapisenabled' to examine attributes and state of + each TAP. + foreach t [jtag names] { + puts [format "TAP: %s\n" $t] + } + + -- Command: scan_chain + Displays the TAPs in the scan chain configuration, and their + status. The set of TAPs listed by this command is fixed by exiting + the OpenOCD configuration stage, but systems with a JTAG router can + enable or disable TAPs dynamically. + +10.2 TAP Names +============== + +When TAP objects are declared with 'jtag newtap', a "dotted.name" is +created for the TAP, combining the name of a module (usually a chip) and +a label for the TAP. For example: 'xilinx.tap', 'str912.flash', +'omap3530.jrc', 'dm6446.dsp', or 'stm32.cpu'. Many other commands use +that dotted.name to manipulate or refer to the TAP. For example, CPU +configuration uses the name, as does declaration of NAND or NOR flash +banks. + +The components of a dotted name should follow "C" symbol name rules: +start with an alphabetic character, then numbers and underscores are OK; +while others (including dots!) are not. + + Tip: In older code, JTAG TAPs were numbered from 0..N. This feature + is still present. However its use is highly discouraged, and + should not be relied on; it will be removed by mid-2010. Update + all of your scripts to use TAP names rather than numbers, by paying + attention to the runtime warnings they trigger. Using TAP numbers + in target configuration scripts prevents reusing those scripts on + boards with multiple targets. + +10.3 TAP Declaration Commands +============================= + + -- Command: jtag newtap chipname tapname configparams... + Declares a new TAP with the dotted name CHIPNAME.TAPNAME, and + configured according to the various CONFIGPARAMS. + + The CHIPNAME is a symbolic name for the chip. Conventionally + target config files use '$_CHIPNAME', defaulting to the model name + given by the chip vendor but overridable. + + The TAPNAME reflects the role of that TAP, and should follow this + convention: + + * 'bs' - For boundary scan if this is a seperate TAP; + * 'cpu' - The main CPU of the chip, alternatively 'arm' and + 'dsp' on chips with both ARM and DSP CPUs, 'arm1' and 'arm2' + on chips two ARMs, and so forth; + * 'etb' - For an embedded trace buffer (example: an ARM ETB11); + * 'flash' - If the chip has a flash TAP, like the str912; + * 'jrc' - For JTAG route controller (example: the ICEpick + modules on many Texas Instruments chips, like the OMAP3530 on + Beagleboards); + * 'tap' - Should be used only FPGA or CPLD like devices with a + single TAP; + * 'unknownN' - If you have no idea what the TAP is for (N is a + number); + * _when in doubt_ - Use the chip maker's name in their data + sheet. For example, the Freescale IMX31 has a SDMA (Smart + DMA) with a JTAG TAP; that TAP should be named 'sdma'. + + Every TAP requires at least the following CONFIGPARAMS: + + * '-irlen' NUMBER + The length in bits of the instruction register, such as 4 or 5 + bits. + + A TAP may also provide optional CONFIGPARAMS: + + * '-disable' (or '-enable') + Use the '-disable' parameter to flag a TAP which is not linked + in to the scan chain after a reset using either TRST or the + JTAG state machine's RESET state. You may use '-enable' to + highlight the default state (the TAP is linked in). *Note + Enabling and Disabling TAPs: enablinganddisablingtaps. + * '-expected-id' NUMBER + A non-zero NUMBER represents a 32-bit IDCODE which you expect + to find when the scan chain is examined. These codes are not + required by all JTAG devices. _Repeat the option_ as many + times as required if more than one ID code could appear (for + example, multiple versions). Specify NUMBER as zero to + suppress warnings about IDCODE values that were found but not + included in the list. + + Provide this value if at all possible, since it lets OpenOCD + tell when the scan chain it sees isn't right. These values + are provided in vendors' chip documentation, usually a + technical reference manual. Sometimes you may need to probe + the JTAG hardware to find these values. *Note Autoprobing: + autoprobing. + * '-ignore-version' + Specify this to ignore the JTAG version field in the + '-expected-id' option. When vendors put out multiple versions + of a chip, or use the same JTAG-level ID for several + largely-compatible chips, it may be more practical to ignore + the version field than to update config files to handle all of + the various chip IDs. The version field is defined as bit + 28-31 of the IDCODE. + * '-ircapture' NUMBER + The bit pattern loaded by the TAP into the JTAG shift register + on entry to the IRCAPTURE state, such as 0x01. JTAG requires + the two LSBs of this value to be 01. By default, '-ircapture' + and '-irmask' are set up to verify that two-bit value. You + may provide additional bits, if you know them, or indicate + that a TAP doesn't conform to the JTAG specification. + * '-irmask' NUMBER + A mask used with '-ircapture' to verify that instruction scans + work correctly. Such scans are not used by OpenOCD except to + verify that there seems to be no problems with JTAG scan chain + operations. + +10.4 Other TAP commands +======================= + + -- Command: jtag cget dotted.name '-event' name + -- Command: jtag configure dotted.name '-event' name string + At this writing this TAP attribute mechanism is used only for event + handling. (It is not a direct analogue of the 'cget'/'configure' + mechanism for debugger targets.) See the next section for + information about the available events. + + The 'configure' subcommand assigns an event handler, a TCL string + which is evaluated when the event is triggered. The 'cget' + subcommand returns that handler. + +10.5 TAP Events +=============== + +OpenOCD includes two event mechanisms. The one presented here applies +to all JTAG TAPs. The other applies to debugger targets, which are +associated with certain TAPs. + +The TAP events currently defined are: + + * post-reset + The TAP has just completed a JTAG reset. The tap may still be in + the JTAG RESET state. Handlers for these events might perform + initialization sequences such as issuing TCK cycles, TMS sequences + to ensure exit from the ARM SWD mode, and more. + + Because the scan chain has not yet been verified, handlers for + these events _should not issue commands which scan the JTAG IR or + DR registers_ of any particular target. NOTE: As this is written + (September 2009), nothing prevents such access. + * setup + The scan chain has been reset and verified. This handler may + enable TAPs as needed. + * tap-disable + The TAP needs to be disabled. This handler should implement 'jtag + tapdisable' by issuing the relevant JTAG commands. + * tap-enable + The TAP needs to be enabled. This handler should implement 'jtag + tapenable' by issuing the relevant JTAG commands. + +If you need some action after each JTAG reset, which isn't actually +specific to any TAP (since you can't yet trust the scan chain's contents +to be accurate), you might: + + jtag configure CHIP.jrc -event post-reset { + echo "JTAG Reset done" + ... non-scan jtag operations to be done after reset + } + +10.6 Enabling and Disabling TAPs +================================ + +In some systems, a "JTAG Route Controller" (JRC) is used to enable +and/or disable specific JTAG TAPs. Many ARM based chips from Texas +Instruments include an "ICEpick" module, which is a JRC. Such chips +include DaVinci and OMAP3 processors. + +A given TAP may not be visible until the JRC has been told to link it +into the scan chain; and if the JRC has been told to unlink that TAP, it +will no longer be visible. Such routers address problems that JTAG +"bypass mode" ignores, such as: + + * The scan chain can only go as fast as its slowest TAP. + * Having many TAPs slows instruction scans, since all TAPs receive + new instructions. + * TAPs in the scan chain must be powered up, which wastes power and + prevents debugging some power management mechanisms. + +The IEEE 1149.1 JTAG standard has no concept of a "disabled" tap, as +implied by the existence of JTAG routers. However, the upcoming IEEE +1149.7 framework (layered on top of JTAG) does include a kind of JTAG +router functionality. + +In OpenOCD, tap enabling/disabling is invoked by the Tcl commands shown +below, and is implemented using TAP event handlers. So for example, +when defining a TAP for a CPU connected to a JTAG router, your +'target.cfg' file should define TAP event handlers using code that looks +something like this: + + jtag configure CHIP.cpu -event tap-enable { + ... jtag operations using CHIP.jrc + } + jtag configure CHIP.cpu -event tap-disable { + ... jtag operations using CHIP.jrc + } + +Then you might want that CPU's TAP enabled almost all the time: + + jtag configure $CHIP.jrc -event setup "jtag tapenable $CHIP.cpu" + +Note how that particular setup event handler declaration uses quotes to +evaluate '$CHIP' when the event is configured. Using brackets { } would +cause it to be evaluated later, at runtime, when it might have a +different value. + + -- Command: jtag tapdisable dotted.name + If necessary, disables the tap by sending it a 'tap-disable' event. + Returns the string "1" if the tap specified by DOTTED.NAME is + enabled, and "0" if it is disabled. + + -- Command: jtag tapenable dotted.name + If necessary, enables the tap by sending it a 'tap-enable' event. + Returns the string "1" if the tap specified by DOTTED.NAME is + enabled, and "0" if it is disabled. + + -- Command: jtag tapisenabled dotted.name + Returns the string "1" if the tap specified by DOTTED.NAME is + enabled, and "0" if it is disabled. + + Note: Humans will find the 'scan_chain' command more helpful + for querying the state of the JTAG taps. + +10.7 Autoprobing +================ + +TAP configuration is the first thing that needs to be done after +interface and reset configuration. Sometimes it's hard finding out what +TAPs exist, or how they are identified. Vendor documentation is not +always easy to find and use. + +To help you get past such problems, OpenOCD has a limited _autoprobing_ +ability to look at the scan chain, doing a "blind interrogation" and +then reporting the TAPs it finds. To use this mechanism, start the +OpenOCD server with only data that configures your JTAG interface, and +arranges to come up with a slow clock (many devices don't support fast +JTAG clocks right when they come out of reset). + +For example, your 'openocd.cfg' file might have: + + source [find interface/olimex-arm-usb-tiny-h.cfg] + reset_config trst_and_srst + jtag_rclk 8 + +When you start the server without any TAPs configured, it will attempt +to autoconfigure the TAPs. There are two parts to this: + + 1. _TAP discovery_ ... After a JTAG reset (sometimes a system reset + may be needed too), each TAP's data registers will hold the + contents of either the IDCODE or BYPASS register. If JTAG + communication is working, OpenOCD will see each TAP, and report + what '-expected-id' to use with it. + 2. _IR Length discovery_ ... Unfortunately JTAG does not provide a + reliable way to find out the value of the '-irlen' parameter to use + with a TAP that is discovered. If OpenOCD can discover the length + of a TAP's instruction register, it will report it. Otherwise you + may need to consult vendor documentation, such as chip data sheets + or BSDL files. + +In many cases your board will have a simple scan chain with just a +single device. Here's what OpenOCD reported with one board that's a bit +more complex: + + clock speed 8 kHz + There are no enabled taps. AUTO PROBING MIGHT NOT WORK!! + AUTO auto0.tap - use "jtag newtap auto0 tap -expected-id 0x2b900f0f ..." + AUTO auto1.tap - use "jtag newtap auto1 tap -expected-id 0x07926001 ..." + AUTO auto2.tap - use "jtag newtap auto2 tap -expected-id 0x0b73b02f ..." + AUTO auto0.tap - use "... -irlen 4" + AUTO auto1.tap - use "... -irlen 4" + AUTO auto2.tap - use "... -irlen 6" + no gdb ports allocated as no target has been specified + +Given that information, you should be able to either find some existing +config files to use, or create your own. If you create your own, you +would configure from the bottom up: first a 'target.cfg' file with these +TAPs, any targets associated with them, and any on-chip resources; then +a 'board.cfg' with off-chip resources, clocking, and so forth. + + ---------- Footnotes ---------- + + (1) See the ST document titled: _STR91xFAxxx, Section 3.15 Jtag +Interface, Page: 28/102, Figure 3: JTAG chaining inside the STR91xFA_. + + + +File: openocd.info, Node: CPU Configuration, Next: Flash Commands, Prev: TAP Declaration, Up: Top + +11 CPU Configuration +******************** + +This chapter discusses how to set up GDB debug targets for CPUs. You +can also access these targets without GDB (*note Architecture and Core +Commands::, and *note Target State handling: targetstatehandling.) and +through various kinds of NAND and NOR flash commands. If you have +multiple CPUs you can have multiple such targets. + +We'll start by looking at how to examine the targets you have, then look +at how to add one more target and how to configure it. + +11.1 Target List +================ + +All targets that have been set up are part of a list, where each member +has a name. That name should normally be the same as the TAP name. You +can display the list with the 'targets' (plural!) command. This +display often has only one CPU; here's what it might look like with more +than one: + TargetName Type Endian TapName State +-- ------------------ ---------- ------ ------------------ ------------ + 0* at91rm9200.cpu arm920t little at91rm9200.cpu running + 1 MyTarget cortex_m little mychip.foo tap-disabled + +One member of that list is the "current target", which is implicitly +referenced by many commands. It's the one marked with a '*' near the +target name. In particular, memory addresses often refer to the address +space seen by that current target. Commands like 'mdw' (memory display +words) and 'flash erase_address' (erase NOR flash blocks) are examples; +and there are many more. + +Several commands let you examine the list of targets: + + -- Command: target count + _Note: target numbers are deprecated; don't use them. They will be + removed shortly after August 2010, including this command. Iterate + target using 'target names', not by counting._ + + Returns the number of targets, N. The highest numbered target is N + - 1. + set c [target count] + for { set x 0 } { $x < $c } { incr x } { + # Assuming you have created this function + print_target_details $x + } + + -- Command: target current + Returns the name of the current target. + + -- Command: target names + Lists the names of all current targets in the list. + foreach t [target names] { + puts [format "Target: %s\n" $t] + } + + -- Command: target number number + _Note: target numbers are deprecated; don't use them. They will be + removed shortly after August 2010, including this command._ + + The list of targets is numbered starting at zero. This command + returns the name of the target at index NUMBER. + set thename [target number $x] + puts [format "Target %d is: %s\n" $x $thename] + + -- Command: targets [name] + _Note: the name of this command is plural. Other target command + names are singular._ + + With no parameter, this command displays a table of all known + targets in a user friendly form. + + With a parameter, this command sets the current target to the given + target with the given NAME; this is only relevant on boards which + have more than one target. + +11.2 Target CPU Types and Variants +================================== + +Each target has a "CPU type", as shown in the output of the 'targets' +command. You need to specify that type when calling 'target create'. +The CPU type indicates more than just the instruction set. It also +indicates how that instruction set is implemented, what kind of debug +support it integrates, whether it has an MMU (and if so, what kind), +what core-specific commands may be available (*note Architecture and +Core Commands::), and more. + +For some CPU types, OpenOCD also defines "variants" which indicate +differences that affect their handling. For example, a particular +implementation bug might need to be worked around in some chip versions. + +It's easy to see what target types are supported, since there's a +command to list them. However, there is currently no way to list what +target variants are supported (other than by reading the OpenOCD source +code). + + -- Command: target types + Lists all supported target types. At this writing, the supported + CPU types and variants are: + + * 'arm11' - this is a generation of ARMv6 cores + * 'arm720t' - this is an ARMv4 core with an MMU + * 'arm7tdmi' - this is an ARMv4 core + * 'arm920t' - this is an ARMv4 core with an MMU + * 'arm926ejs' - this is an ARMv5 core with an MMU + * 'arm966e' - this is an ARMv5 core + * 'arm9tdmi' - this is an ARMv4 core + * 'avr' - implements Atmel's 8-bit AVR instruction set. + (Support for this is preliminary and incomplete.) + * 'cortex_a' - this is an ARMv7 core with an MMU + * 'cortex_m' - this is an ARMv7 core, supporting only the + compact Thumb2 instruction set. + * 'dragonite' - resembles arm966e + * 'dsp563xx' - implements Freescale's 24-bit DSP. (Support for + this is still incomplete.) + * 'fa526' - resembles arm920 (w/o Thumb) + * 'feroceon' - resembles arm926 + * 'mips_m4k' - a MIPS core. This supports one variant: + * 'xscale' - this is actually an architecture, not a CPU type. + It is based on the ARMv5 architecture. There are several + variants defined: + - 'ixp42x', 'ixp45x', 'ixp46x', 'pxa27x' ... instruction + register length is 7 bits + - 'pxa250', 'pxa255', 'pxa26x' ... instruction register + length is 5 bits + - 'pxa3xx' ... instruction register length is 11 bits + +To avoid being confused by the variety of ARM based cores, remember this +key point: _ARM is a technology licencing company_. (See: +.) The CPU name used by OpenOCD will reflect the +CPU design that was licenced, not a vendor brand which incorporates that +design. Name prefixes like arm7, arm9, arm11, and cortex reflect design +generations; while names like ARMv4, ARMv5, ARMv6, and ARMv7 reflect an +architecture version implemented by a CPU design. + +11.3 Target Configuration +========================= + +Before creating a "target", you must have added its TAP to the scan +chain. When you've added that TAP, you will have a 'dotted.name' which +is used to set up the CPU support. The chip-specific configuration file +will normally configure its CPU(s) right after it adds all of the chip's +TAPs to the scan chain. + +Although you can set up a target in one step, it's often clearer if you +use shorter commands and do it in two steps: create it, then configure +optional parts. All operations on the target after it's created will +use a new command, created as part of target creation. + +The two main things to configure after target creation are a work area, +which usually has target-specific defaults even if the board setup code +overrides them later; and event handlers (*note Target Events: +targetevents.), which tend to be much more board-specific. The key +steps you use might look something like this + + target create MyTarget cortex_m -chain-position mychip.cpu + $MyTarget configure -work-area-phys 0x08000 -work-area-size 8096 + $MyTarget configure -event reset-deassert-pre { jtag_rclk 5 } + $MyTarget configure -event reset-init { myboard_reinit } + +You should specify a working area if you can; typically it uses some +on-chip SRAM. Such a working area can speed up many things, including +bulk writes to target memory; flash operations like checking to see if +memory needs to be erased; GDB memory checksumming; and more. + + Warning: On more complex chips, the work area can become + inaccessible when application code (such as an operating system) + enables or disables the MMU. For example, the particular MMU + context used to acess the virtual address will probably matter ... + and that context might not have easy access to other addresses + needed. At this writing, OpenOCD doesn't have much MMU + intelligence. + +It's often very useful to define a 'reset-init' event handler. For +systems that are normally used with a boot loader, common tasks include +updating clocks and initializing memory controllers. That may be needed +to let you write the boot loader into flash, in order to "de-brick" your +board; or to load programs into external DDR memory without having run +the boot loader. + + -- Command: target create target_name type configparams... + This command creates a GDB debug target that refers to a specific + JTAG tap. It enters that target into a list, and creates a new + command ('TARGET_NAME') which is used for various purposes + including additional configuration. + + * TARGET_NAME ... is the name of the debug target. By + convention this should be the same as the _dotted.name_ of the + TAP associated with this target, which must be specified here + using the '-chain-position DOTTED.NAME' configparam. + + This name is also used to create the target object command, + referred to here as '$target_name', and in other places the + target needs to be identified. + * TYPE ... specifies the target type. *Note target types: + targettypes. + * CONFIGPARAMS ... all parameters accepted by '$target_name + configure' are permitted. If the target is big-endian, set it + here with '-endian big'. If the variant matters, set it here + with '-variant'. + + You _must_ set the '-chain-position DOTTED.NAME' here. + + -- Command: $target_name configure configparams... + The options accepted by this command may also be specified as + parameters to 'target create'. Their values can later be queried + one at a time by using the '$target_name cget' command. + + _Warning:_ changing some of these after setup is dangerous. For + example, moving a target from one TAP to another; and changing its + endianness or variant. + + * '-chain-position' DOTTED.NAME - names the TAP used to access + this target. + + * '-endian' ('big'|'little') - specifies whether the CPU uses + big or little endian conventions + + * '-event' EVENT_NAME EVENT_BODY - *Note Target Events: + targetevents. Note that this updates a list of named event + handlers. Calling this twice with two different event names + assigns two different handlers, but calling it twice with the + same event name assigns only one handler. + + * '-variant' NAME - specifies a variant of the target, which + OpenOCD needs to know about. + + * '-work-area-backup' ('0'|'1') - says whether the work area + gets backed up; by default, _it is not backed up._ When + possible, use a working_area that doesn't need to be backed + up, since performing a backup slows down operations. For + example, the beginning of an SRAM block is likely to be used + by most build systems, but the end is often unused. + + * '-work-area-size' SIZE - specify work are size, in bytes. The + same size applies regardless of whether its physical or + virtual address is being used. + + * '-work-area-phys' ADDRESS - set the work area base ADDRESS to + be used when no MMU is active. + + * '-work-area-virt' ADDRESS - set the work area base ADDRESS to + be used when an MMU is active. _Do not specify a value for + this except on targets with an MMU._ The value should normally + correspond to a static mapping for the '-work-area-phys' + address, set up by the current operating system. + + * '-rtos' RTOS_TYPE - enable rtos support for target, RTOS_TYPE + can be one of 'auto'|'eCos'|'ThreadX'| + 'FreeRTOS'|'linux'|'ChibiOS'. + +11.4 Other $target_name Commands +================================ + +The Tcl/Tk language has the concept of object commands, and OpenOCD +adopts that same model for targets. + +A good Tk example is a on screen button. Once a button is created a +button has a name (a path in Tk terms) and that name is useable as a +first class command. For example in Tk, one can create a button and +later configure it like this: + + # Create + button .foobar -background red -command { foo } + # Modify + .foobar configure -foreground blue + # Query + set x [.foobar cget -background] + # Report + puts [format "The button is %s" $x] + +In OpenOCD's terms, the "target" is an object just like a Tcl/Tk button, +and its object commands are invoked the same way. + + str912.cpu mww 0x1234 0x42 + omap3530.cpu mww 0x5555 123 + +The commands supported by OpenOCD target objects are: + + -- Command: $target_name arp_examine + -- Command: $target_name arp_halt + -- Command: $target_name arp_poll + -- Command: $target_name arp_reset + -- Command: $target_name arp_waitstate + Internal OpenOCD scripts (most notably 'startup.tcl') use these to + deal with specific reset cases. They are not otherwise documented + here. + + -- Command: $target_name array2mem arrayname width address count + -- Command: $target_name mem2array arrayname width address count + These provide an efficient script-oriented interface to memory. + The 'array2mem' primitive writes bytes, halfwords, or words; while + 'mem2array' reads them. In both cases, the TCL side uses an array, + and the target side uses raw memory. + + The efficiency comes from enabling the use of bulk JTAG data + transfer operations. The script orientation comes from working + with data values that are packaged for use by TCL scripts; 'mdw' + type primitives only print data they retrieve, and neither store + nor return those values. + + * ARRAYNAME ... is the name of an array variable + * WIDTH ... is 8/16/32 - indicating the memory access size + * ADDRESS ... is the target memory address + * COUNT ... is the number of elements to process + + -- Command: $target_name cget queryparm + Each configuration parameter accepted by '$target_name configure' + can be individually queried, to return its current value. The + QUERYPARM is a parameter name accepted by that command, such as + '-work-area-phys'. There are a few special cases: + + * '-event' EVENT_NAME - returns the handler for the event named + EVENT_NAME. This is a special case because setting a handler + requires two parameters. + * '-type' - returns the target type. This is a special case + because this is set using 'target create' and can't be changed + using '$target_name configure'. + + For example, if you wanted to summarize information about all the + targets you might use something like this: + + foreach name [target names] { + set y [$name cget -endian] + set z [$name cget -type] + puts [format "Chip %d is %s, Endian: %s, type: %s" \ + $x $name $y $z] + } + + -- Command: $target_name curstate + Displays the current target state: 'debug-running', 'halted', + 'reset', 'running', or 'unknown'. (Also, *note Event Polling: + eventpolling.) + + -- Command: $target_name eventlist + Displays a table listing all event handlers currently associated + with this target. *Note Target Events: targetevents. + + -- Command: $target_name invoke-event event_name + Invokes the handler for the event named EVENT_NAME. (This is + primarily intended for use by OpenOCD framework code, for example + by the reset code in 'startup.tcl'.) + + -- Command: $target_name mdw addr [count] + -- Command: $target_name mdh addr [count] + -- Command: $target_name mdb addr [count] + Display contents of address ADDR, as 32-bit words ('mdw'), 16-bit + halfwords ('mdh'), or 8-bit bytes ('mdb'). If COUNT is specified, + displays that many units. (If you want to manipulate the data + instead of displaying it, see the 'mem2array' primitives.) + + -- Command: $target_name mww addr word + -- Command: $target_name mwh addr halfword + -- Command: $target_name mwb addr byte + Writes the specified WORD (32 bits), HALFWORD (16 bits), or BYTE + (8-bit) pattern, at the specified address ADDR. + +11.5 Target Events +================== + +At various times, certain things can happen, or you want them to happen. +For example: + * What should happen when GDB connects? Should your target reset? + * When GDB tries to flash the target, do you need to enable the flash + via a special command? + * Is using SRST appropriate (and possible) on your system? Or + instead of that, do you need to issue JTAG commands to trigger + reset? SRST usually resets everything on the scan chain, which can + be inappropriate. + * During reset, do you need to write to certain memory locations to + set up system clocks or to reconfigure the SDRAM? How about + configuring the watchdog timer, or other peripherals, to stop + running while you hold the core stopped for debugging? + +All of the above items can be addressed by target event handlers. These +are set up by '$target_name configure -event' or 'target create ... +-event'. + +The programmer's model matches the '-command' option used in Tcl/Tk +buttons and events. The two examples below act the same, but one +creates and invokes a small procedure while the other inlines it. + + proc my_attach_proc { } { + echo "Reset..." + reset halt + } + mychip.cpu configure -event gdb-attach my_attach_proc + mychip.cpu configure -event gdb-attach { + echo "Reset..." + # To make flash probe and gdb load to flash work we need a reset init. + reset init + } + +The following target events are defined: + + * debug-halted + The target has halted for debug reasons (i.e.: breakpoint) + * debug-resumed + The target has resumed (i.e.: gdb said run) + * early-halted + Occurs early in the halt process + * examine-start + Before target examine is called. + * examine-end + After target examine is called with no errors. + * gdb-attach + When GDB connects. This is before any communication with the + target, so this can be used to set up the target so it is possible + to probe flash. Probing flash is necessary during gdb connect if + gdb load is to write the image to flash. Another use of the flash + memory map is for GDB to automatically hardware/software + breakpoints depending on whether the breakpoint is in RAM or read + only memory. + * gdb-detach + When GDB disconnects + * gdb-end + When the target has halted and GDB is not doing anything (see early + halt) + * gdb-flash-erase-start + Before the GDB flash process tries to erase the flash + * gdb-flash-erase-end + After the GDB flash process has finished erasing the flash + * gdb-flash-write-start + Before GDB writes to the flash + * gdb-flash-write-end + After GDB writes to the flash + * gdb-start + Before the target steps, gdb is trying to start/resume the target + * halted + The target has halted + * reset-assert-pre + Issued as part of 'reset' processing after 'reset_init' was + triggered but before either SRST alone is re-asserted on the scan + chain, or 'reset-assert' is triggered. + * reset-assert + Issued as part of 'reset' processing after 'reset-assert-pre' was + triggered. When such a handler is present, cores which support + this event will use it instead of asserting SRST. This support is + essential for debugging with JTAG interfaces which don't include an + SRST line (JTAG doesn't require SRST), and for selective reset on + scan chains that have multiple targets. + * reset-assert-post + Issued as part of 'reset' processing after 'reset-assert' has been + triggered. or the target asserted SRST on the entire scan chain. + * reset-deassert-pre + Issued as part of 'reset' processing after 'reset-assert-post' has + been triggered. + * reset-deassert-post + Issued as part of 'reset' processing after 'reset-deassert-pre' has + been triggered and (if the target is using it) after SRST has been + released on the scan chain. + * reset-end + Issued as the final step in 'reset' processing. + * reset-init + Used by reset init command for board-specific initialization. This + event fires after _reset-deassert-post_. + + This is where you would configure PLLs and clocking, set up DRAM so + you can download programs that don't fit in on-chip SRAM, set up + pin multiplexing, and so on. (You may be able to switch to a fast + JTAG clock rate here, after the target clocks are fully set up.) + * reset-start + Issued as part of 'reset' processing before 'reset_init' is called. + + This is the most robust place to use 'jtag_rclk' or 'adapter_khz' + to switch to a low JTAG clock rate, when reset disables PLLs needed + to use a fast clock. + * resume-start + Before any target is resumed + * resume-end + After all targets have resumed + * resumed + Target has resumed + + +File: openocd.info, Node: Flash Commands, Next: Flash Programming, Prev: CPU Configuration, Up: Top + +12 Flash Commands +***************** + +OpenOCD has different commands for NOR and NAND flash; the "flash" +command works with NOR flash, while the "nand" command works with NAND +flash. This partially reflects different hardware technologies: NOR +flash usually supports direct CPU instruction and data bus access, while +data from a NAND flash must be copied to memory before it can be used. +(SPI flash must also be copied to memory before use.) However, the +documentation also uses "flash" as a generic term; for example, "Put +flash configuration in board-specific files". + +Flash Steps: + 1. Configure via the command 'flash bank' + Do this in a board-specific configuration file, passing parameters + as needed by the driver. + 2. Operate on the flash via 'flash subcommand' + Often commands to manipulate the flash are typed by a human, or run + via a script in some automated way. Common tasks include writing a + boot loader, operating system, or other data. + 3. GDB Flashing + Flashing via GDB requires the flash be configured via "flash bank", + and the GDB flash features be enabled. *Note GDB Configuration: + gdbconfiguration. + +Many CPUs have the ablity to "boot" from the first flash bank. This +means that misprogramming that bank can "brick" a system, so that it +can't boot. JTAG tools, like OpenOCD, are often then used to "de-brick" +the board by (re)installing working boot firmware. + +12.1 Flash Configuration Commands +================================= + + -- Config Command: flash bank name driver base size chip_width + bus_width target [driver_options] + Configures a flash bank which provides persistent storage for + addresses from base to base + size - 1. These banks will often be + visible to GDB through the target's memory map. In some cases, + configuring a flash bank will activate extra commands; see the + driver-specific documentation. + + * NAME ... may be used to reference the flash bank in other + flash commands. A number is also available. + * DRIVER ... identifies the controller driver associated with + the flash bank being declared. This is usually 'cfi' for + external flash, or else the name of a microcontroller with + embedded flash memory. *Note Flash Driver List: + flashdriverlist. + * BASE ... Base address of the flash chip. + * SIZE ... Size of the chip, in bytes. For some drivers, this + value is detected from the hardware. + * CHIP_WIDTH ... Width of the flash chip, in bytes; ignored for + most microcontroller drivers. + * BUS_WIDTH ... Width of the data bus used to access the chip, + in bytes; ignored for most microcontroller drivers. + * TARGET ... Names the target used to issue commands to the + flash controller. + * DRIVER_OPTIONS ... drivers may support, or require, + additional parameters. See the driver-specific documentation + for more information. + Note: This command is not available after OpenOCD + initialization has completed. Use it in board specific + configuration files, not interactively. + + -- Command: flash banks + Prints a one-line summary of each device that was declared using + 'flash bank', numbered from zero. Note that this is the _plural_ + form; the _singular_ form is a very different command. + + -- Command: flash list + Retrieves a list of associative arrays for each device that was + declared using 'flash bank', numbered from zero. This returned + list can be manipulated easily from within scripts. + + -- Command: flash probe num + Identify the flash, or validate the parameters of the configured + flash. Operation depends on the flash type. The NUM parameter is + a value shown by 'flash banks'. Most flash commands will + implicitly _autoprobe_ the bank; flash drivers can distinguish + between probing and autoprobing, but most don't bother. + +12.2 Erasing, Reading, Writing to Flash +======================================= + +One feature distinguishing NOR flash from NAND or serial flash +technologies is that for read access, it acts exactly like any other +addressible memory. This means you can use normal memory read commands +like 'mdw' or 'dump_image' with it, with no special 'flash' subcommands. +*Note Memory access: memoryaccess, and *note Image access: imageaccess. + +Write access works differently. Flash memory normally needs to be +erased before it's written. Erasing a sector turns all of its bits to +ones, and writing can turn ones into zeroes. This is why there are +special commands for interactive erasing and writing, and why GDB needs +to know which parts of the address space hold NOR flash memory. + + Note: Most of these erase and write commands leverage the fact that + NOR flash chips consume target address space. They implicitly + refer to the current JTAG target, and map from an address in that + target's address space back to a flash bank. A few commands use + abstract addressing based on bank and sector numbers, and don't + depend on searching the current target and its address space. + Avoid confusing the two command models. + +Some flash chips implement software protection against accidental +writes, since such buggy writes could in some cases "brick" a system. +For such systems, erasing and writing may require sector protection to +be disabled first. Examples include CFI flash such as "Intel Advanced +Bootblock flash", and AT91SAM7 on-chip flash. *Note flash protect: +flashprotect. + + -- Command: flash erase_sector num first last + Erase sectors in bank NUM, starting at sector FIRST up to and + including LAST. Sector numbering starts at 0. Providing a LAST + sector of 'last' specifies "to the end of the flash bank". The NUM + parameter is a value shown by 'flash banks'. + + -- Command: flash erase_address ['pad'] ['unlock'] address length + Erase sectors starting at ADDRESS for LENGTH bytes. Unless 'pad' + is specified, address must begin a flash sector, and address + + length - 1 must end a sector. Specifying 'pad' erases extra data + at the beginning and/or end of the specified region, as needed to + erase only full sectors. The flash bank to use is inferred from + the ADDRESS, and the specified length must stay within that bank. + As a special case, when LENGTH is zero and ADDRESS is the start of + the bank, the whole flash is erased. If 'unlock' is specified, + then the flash is unprotected before erase starts. + + -- Command: flash fillw address word length + -- Command: flash fillh address halfword length + -- Command: flash fillb address byte length + Fills flash memory with the specified WORD (32 bits), HALFWORD (16 + bits), or BYTE (8-bit) pattern, starting at ADDRESS and continuing + for LENGTH units (word/halfword/byte). No erasure is done before + writing; when needed, that must be done before issuing this + command. Writes are done in blocks of up to 1024 bytes, and each + write is verified by reading back the data and comparing it to what + was written. The flash bank to use is inferred from the ADDRESS of + each block, and the specified length must stay within that bank. + + -- Command: flash write_bank num filename offset + Write the binary 'filename' to flash bank NUM, starting at OFFSET + bytes from the beginning of the bank. The NUM parameter is a value + shown by 'flash banks'. + + -- Command: flash write_image [erase] [unlock] filename [offset] [type] + Write the image 'filename' to the current target's flash bank(s). + A relocation OFFSET may be specified, in which case it is added to + the base address for each section in the image. The file [TYPE] + can be specified explicitly as 'bin' (binary), 'ihex' (Intel hex), + 'elf' (ELF file), 's19' (Motorola s19). 'mem', or 'builder'. The + relevant flash sectors will be erased prior to programming if the + 'erase' parameter is given. If 'unlock' is provided, then the + flash banks are unlocked before erase and program. The flash bank + to use is inferred from the address of each image section. + + Warning: Be careful using the 'erase' flag when the flash is + holding data you want to preserve. Portions of the flash + outside those described in the image's sections might be + erased with no notice. + * When a section of the image being written does not fill + out all the sectors it uses, the unwritten parts of those + sectors are necessarily also erased, because sectors + can't be partially erased. + * Data stored in sector "holes" between image sections are + also affected. For example, "'flash write_image erase + ...'" of an image with one byte at the beginning of a + flash bank and one byte at the end erases the entire bank + - not just the two sectors being written. + Also, when flash protection is important, you must re-apply it + after it has been removed by the 'unlock' flag. + +12.3 Other Flash commands +========================= + + -- Command: flash erase_check num + Check erase state of sectors in flash bank NUM, and display that + status. The NUM parameter is a value shown by 'flash banks'. + + -- Command: flash info num + Print info about flash bank NUM The NUM parameter is a value shown + by 'flash banks'. This command will first query the hardware, it + does not print cached and possibly stale information. + + -- Command: flash protect num first last ('on'|'off') + Enable ('on') or disable ('off') protection of flash sectors in + flash bank NUM, starting at sector FIRST and continuing up to and + including LAST. Providing a LAST sector of 'last' specifies "to + the end of the flash bank". The NUM parameter is a value shown by + 'flash banks'. + + -- Command: program filename [verify] [reset] [offset] + This is a helper script that simplifies using OpenOCD as a + standalone programmer. The only required parameter is 'filename', + the others are optional. *Note Flash Programming::. + +12.4 Flash Driver List +====================== + +As noted above, the 'flash bank' command requires a driver name, and +allows driver-specific options and behaviors. Some drivers also +activate driver-specific commands. + +12.4.1 External Flash +--------------------- + + -- Flash Driver: cfi + The "Common Flash Interface" (CFI) is the main standard for + external NOR flash chips, each of which connects to a specific + external chip select on the CPU. Frequently the first such chip is + used to boot the system. Your board's 'reset-init' handler might + need to configure additional chip selects using other commands + (like: 'mww' to configure a bus and its timings), or perhaps + configure a GPIO pin that controls the "write protect" pin on the + flash chip. The CFI driver can use a target-specific working area + to significantly speed up operation. + + The CFI driver can accept the following optional parameters, in any + order: + + * JEDEC_PROBE ... is used to detect certain non-CFI flash ROMs, + like AM29LV010 and similar types. + * X16_AS_X8 ... when a 16-bit flash is hooked up to an 8-bit + bus. + + To configure two adjacent banks of 16 MBytes each, both sixteen + bits (two bytes) wide on a sixteen bit bus: + + flash bank $_FLASHNAME cfi 0x00000000 0x01000000 2 2 $_TARGETNAME + flash bank $_FLASHNAME cfi 0x01000000 0x01000000 2 2 $_TARGETNAME + + To configure one bank of 32 MBytes built from two sixteen bit (two + byte) wide parts wired in parallel to create a thirty-two bit (four + byte) bus with doubled throughput: + + flash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME + + -- Flash Driver: lpcspifi + NXP's LPC43xx and LPC18xx families include a proprietary SPI Flash + Interface (SPIFI) peripheral that can drive and provide memory + mapped access to external SPI flash devices. + + The lpcspifi driver initializes this interface and provides program + and erase functionality for these serial flash devices. Use of + this driver requires a working area of at least 1kB to be + configured on the target device; more than this will significantly + reduce flash programming times. + + The setup command only requires the BASE parameter. All other + parameters are ignored, and the flash size and layout are + configured by the driver. + + flash bank $_FLASHNAME lpcspifi 0x14000000 0 0 0 $_TARGETNAME + + -- Flash Driver: stmsmi + Some devices form STMicroelectronics (e.g. STR75x MCU family, + SPEAr MPU family) include a proprietary "Serial Memory Interface" + (SMI) controller able to drive external SPI flash devices. + Depending on specific device and board configuration, up to 4 + external flash devices can be connected. + + SMI makes the flash content directly accessible in the CPU address + space; each external device is mapped in a memory bank. CPU can + directly read data, execute code and boot from SMI banks. Normal + OpenOCD commands like 'mdw' can be used to display the flash + content. + + The setup command only requires the BASE parameter in order to + identify the memory bank. All other parameters are ignored. + Additional information, like flash size, are detected + automatically. + + flash bank $_FLASHNAME stmsmi 0xf8000000 0 0 0 $_TARGETNAME + +12.4.2 Internal Flash (Microcontrollers) +---------------------------------------- + + -- Flash Driver: aduc702x + The ADUC702x analog microcontrollers from Analog Devices include + internal flash and use ARM7TDMI cores. The aduc702x flash driver + works with models ADUC7019 through ADUC7028. The setup command + only requires the TARGET argument since all devices in this family + have the same memory layout. + + flash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME + + -- Flash Driver: at91sam3 + All members of the AT91SAM3 microcontroller family from Atmel + include internal flash and use ARM's Cortex-M3 core. The driver + currently (6/22/09) recognizes the AT91SAM3U[1/2/4][C/E] chips. + Note that the driver was orginaly developed and tested using the + AT91SAM3U4E, using a SAM3U-EK eval board. Support for other chips + in the family was cribbed from the data sheet. _Note to future + readers/updaters: Please remove this worrysome comment after other + chips are confirmed._ + + The AT91SAM3U4[E/C] (256K) chips have two flash banks; most other + chips have one flash bank. In all cases the flash banks are at the + following fixed locations: + + # Flash bank 0 - all chips + flash bank $_FLASHNAME at91sam3 0x00080000 0 1 1 $_TARGETNAME + # Flash bank 1 - only 256K chips + flash bank $_FLASHNAME at91sam3 0x00100000 0 1 1 $_TARGETNAME + + Internally, the AT91SAM3 flash memory is organized as follows. + Unlike the AT91SAM7 chips, these are not used as parameters to the + 'flash bank' command: + + * _N-Banks:_ 256K chips have 2 banks, others have 1 bank. + * _Bank Size:_ 128K/64K Per flash bank + * _Sectors:_ 16 or 8 per bank + * _SectorSize:_ 8K Per Sector + * _PageSize:_ 256 bytes per page. Note that OpenOCD operates on + 'sector' sizes, not page sizes. + + The AT91SAM3 driver adds some additional commands: + + -- Command: at91sam3 gpnvm + -- Command: at91sam3 gpnvm clear number + -- Command: at91sam3 gpnvm set number + -- Command: at91sam3 gpnvm show ['all'|number] + With no parameters, 'show' or 'show all', shows the status of + all GPNVM bits. With 'show' NUMBER, displays that bit. + + With 'set' NUMBER or 'clear' NUMBER, modifies that GPNVM bit. + + -- Command: at91sam3 info + This command attempts to display information about the + AT91SAM3 chip. _First_ it read the 'CHIPID_CIDR' [address + 0x400e0740, see Section 28.2.1, page 505 of the AT91SAM3U + 29/may/2009 datasheet, document id: doc6430A] and decodes the + values. _Second_ it reads the various clock configuration + registers and attempts to display how it believes the chip is + configured. By default, the SLOWCLK is assumed to be 32768 + Hz, see the command 'at91sam3 slowclk'. + + -- Command: at91sam3 slowclk [value] + This command shows/sets the slow clock frequency used in the + 'at91sam3 info' command calculations above. + + -- Flash Driver: at91sam4 + All members of the AT91SAM4 microcontroller family from Atmel + include internal flash and use ARM's Cortex-M4 core. This driver + uses the same cmd names/syntax as *Note at91sam3::. + + -- Flash Driver: at91sam7 + All members of the AT91SAM7 microcontroller family from Atmel + include internal flash and use ARM7TDMI cores. The driver + automatically recognizes a number of these chips using the chip + identification register, and autoconfigures itself. + + flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME + + For chips which are not recognized by the controller driver, you + must provide additional parameters in the following order: + + * CHIP_MODEL ... label used with 'flash info' + * BANKS + * SECTORS_PER_BANK + * PAGES_PER_SECTOR + * PAGES_SIZE + * NUM_NVM_BITS + * FREQ_KHZ ... required if an external clock is provided, + optional (but recommended) when the oscillator frequency is + known + + It is recommended that you provide zeroes for all of those values + except the clock frequency, so that everything except that + frequency will be autoconfigured. Knowing the frequency helps + ensure correct timings for flash access. + + The flash controller handles erases automatically on a page + (128/256 byte) basis, so explicit erase commands are not necessary + for flash programming. However, there is an "EraseAll" command + that can erase an entire flash plane (of up to 256KB), and it will + be used automatically when you issue 'flash erase_sector' or 'flash + erase_address' commands. + + -- Command: at91sam7 gpnvm bitnum ('set'|'clear') + Set or clear a "General Purpose Non-Volatile Memory" (GPNVM) + bit for the processor. Each processor has a number of such + bits, used for controlling features such as brownout detection + (so they are not truly general purpose). + Note: This assumes that the first flash bank (number 0) + is associated with the appropriate at91sam7 target. + + -- Flash Driver: avr + The AVR 8-bit microcontrollers from Atmel integrate flash memory. + _The current implementation is incomplete._ + + -- Flash Driver: efm32 + All members of the EFM32 microcontroller family from Energy Micro + include internal flash and use ARM Cortex M3 cores. The driver + automatically recognizes a number of these chips using the chip + identification register, and autoconfigures itself. + flash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME + _The current implementation is incomplete. Unprotecting flash + pages is not supported._ + + -- Flash Driver: lpc2000 + Most members of the LPC1700, LPC1800, LPC2000 and LPC4300 + microcontroller families from NXP include internal flash and use + Cortex-M3 (LPC1700, LPC1800), Cortex-M4 (LPC4300) or ARM7TDMI + (LPC2000) cores. + + Note: There are LPC2000 devices which are not supported by the + LPC2000 driver: The LPC2888 is supported by the LPC288X + driver. The LPC29xx family is supported by the LPC2900 + driver. + + The LPC2000 driver defines two mandatory and one optional + parameters, which must appear in the following order: + + * VARIANT ... required, may be 'lpc2000_v1' (older LPC21xx and + LPC22xx) 'lpc2000_v2' (LPC213x, LPC214x, LPC210[123], LPC23xx + and LPC24xx) 'lpc1700' (LPC175x and LPC176x) or 'lpc4300' - + available also as 'lpc1800' alias (LPC18x[2357] and + LPC43x[2357]) + * CLOCK_KHZ ... the frequency, in kiloHertz, at which the core + is running + * 'calc_checksum' ... optional (but you probably want to + provide this!), telling the driver to calculate a valid + checksum for the exception vector table. + Note: If you don't provide 'calc_checksum' when you're + writing the vector table, the boot ROM will almost + certainly ignore your flash image. However, if you do + provide it, with most tool chains 'verify_image' will + fail. + + LPC flashes don't require the chip and bus width to be specified. + + flash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 $_TARGETNAME \ + lpc2000_v2 14765 calc_checksum + + -- Command: lpc2000 part_id bank + Displays the four byte part identifier associated with the + specified flash BANK. + + -- Flash Driver: lpc288x + The LPC2888 microcontroller from NXP needs slightly different flash + support from its lpc2000 siblings. The LPC288X driver defines one + mandatory parameter, the programming clock rate in Hz. LPC flashes + don't require the chip and bus width to be specified. + + flash bank $_FLASHNAME lpc288x 0 0 0 0 $_TARGETNAME 12000000 + + -- Flash Driver: lpc2900 + This driver supports the LPC29xx ARM968E based microcontroller + family from NXP. + + The predefined parameters BASE, SIZE, CHIP_WIDTH and BUS_WIDTH of + the 'flash bank' command are ignored. Flash size and sector layout + are auto-configured by the driver. The driver has one additional + mandatory parameter: The CPU clock rate (in kHz) at the time the + flash operations will take place. Most of the time this will not + be the crystal frequency, but a higher PLL frequency. The + 'reset-init' event handler in the board script is usually the place + where you start the PLL. + + The driver rejects flashless devices (currently the LPC2930). + + The EEPROM in LPC2900 devices is not mapped directly into the + address space. It must be handled much more like NAND flash + memory, and will therefore be handled by a separate + 'lpc2900_eeprom' driver (not yet available). + + Sector protection in terms of the LPC2900 is handled transparently. + Every time a sector needs to be erased or programmed, it is + automatically unprotected. What is shown as protection status in + the 'flash info' command, is actually the LPC2900 _sector + security_. This is a mechanism to prevent a sector from ever being + erased or programmed again. As this is an irreversible mechanism, + it is handled by a special command ('lpc2900 secure_sector'), and + not by the standard 'flash protect' command. + + Example for a 125 MHz clock frequency: + flash bank $_FLASHNAME lpc2900 0 0 0 0 $_TARGETNAME 125000 + + Some 'lpc2900'-specific commands are defined. In the following + command list, the BANK parameter is the bank number as obtained by + the 'flash banks' command. + + -- Command: lpc2900 signature bank + Calculates a 128-bit hash value, the _signature_, from the + whole flash content. This is a hardware feature of the flash + block, hence the calculation is very fast. You may use this + to verify the content of a programmed device against a known + signature. Example: + lpc2900 signature 0 + signature: 0x5f40cdc8:0xc64e592e:0x10490f89:0x32a0f317 + + -- Command: lpc2900 read_custom bank filename + Reads the 912 bytes of customer information from the flash + index sector, and saves it to a file in binary format. + Example: + lpc2900 read_custom 0 /path_to/customer_info.bin + + The index sector of the flash is a _write-only_ sector. It cannot + be erased! In order to guard against unintentional write access, + all following commands need to be preceeded by a successful call to + the 'password' command: + + -- Command: lpc2900 password bank password + You need to use this command right before each of the + following commands: 'lpc2900 write_custom', 'lpc2900 + secure_sector', 'lpc2900 secure_jtag'. + + The password string is fixed to "I_know_what_I_am_doing". + Example: + lpc2900 password 0 I_know_what_I_am_doing + Potentially dangerous operation allowed in next command! + + -- Command: lpc2900 write_custom bank filename type + Writes the content of the file into the customer info space of + the flash index sector. The filetype can be specified with + the TYPE field. Possible values for TYPE are: BIN (binary), + IHEX (Intel hex format), ELF (ELF binary) or S19 (Motorola + S-records). The file must contain a single section, and the + contained data length must be exactly 912 bytes. + Attention: This cannot be reverted! Be careful! + Example: + lpc2900 write_custom 0 /path_to/customer_info.bin bin + + -- Command: lpc2900 secure_sector bank first last + Secures the sector range from FIRST to LAST (including) + against further program and erase operations. The sector + security will be effective after the next power cycle. + Attention: This cannot be reverted! Be careful! + Secured sectors appear as _protected_ in the 'flash info' + command. Example: + lpc2900 secure_sector 0 1 1 + flash info 0 + #0 : lpc2900 at 0x20000000, size 0x000c0000, (...) + # 0: 0x00000000 (0x2000 8kB) not protected + # 1: 0x00002000 (0x2000 8kB) protected + # 2: 0x00004000 (0x2000 8kB) not protected + + -- Command: lpc2900 secure_jtag bank + Irreversibly disable the JTAG port. The new JTAG security + setting will be effective after the next power cycle. + Attention: This cannot be reverted! Be careful! + Examples: + lpc2900 secure_jtag 0 + + -- Flash Driver: ocl + _No idea what this is, other than using some arm7/arm9 core._ + + flash bank $_FLASHNAME ocl 0 0 0 0 $_TARGETNAME + + -- Flash Driver: pic32mx + The PIC32MX microcontrollers are based on the MIPS 4K cores, and + integrate flash memory. + + flash bank $_FLASHNAME pix32mx 0x1fc00000 0 0 0 $_TARGETNAME + flash bank $_FLASHNAME pix32mx 0x1d000000 0 0 0 $_TARGETNAME + + Some pic32mx-specific commands are defined: + -- Command: pic32mx pgm_word address value bank + Programs the specified 32-bit VALUE at the given ADDRESS in + the specified chip BANK. + -- Command: pic32mx unlock bank + Unlock and erase specified chip BANK. This will remove any + Code Protection. + + -- Flash Driver: stellaris + All members of the Stellaris LM3Sxxx microcontroller family from + Texas Instruments include internal flash and use ARM Cortex M3 + cores. The driver automatically recognizes a number of these chips + using the chip identification register, and autoconfigures itself. + (1) + + flash bank $_FLASHNAME stellaris 0 0 0 0 $_TARGETNAME + + -- Command: stellaris recover bank_id + Performs the _Recovering a "Locked" Device_ procedure to + restore the flash specified by BANK_ID and its associated + nonvolatile registers to their factory default values + (erased). This is the only way to remove flash protection or + re-enable debugging if that capability has been disabled. + + Note that the final "power cycle the chip" step in this + procedure must be performed by hand, since OpenOCD can't do + it. + Warning: if more than one Stellaris chip is connected, + the procedure is applied to all of them. + + -- Flash Driver: stm32f1x + All members of the STM32F0, STM32F1 and STM32F3 microcontroller + families from ST Microelectronics include internal flash and use + ARM Cortex-M0/M3/M4 cores. The driver automatically recognizes a + number of these chips using the chip identification register, and + autoconfigures itself. + + flash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME + + Note that some devices have been found that have a flash size + register that contains an invalid value, to workaround this issue + you can override the probed value used by the flash driver. + + flash bank $_FLASHNAME stm32f1x 0 0x20000 0 0 $_TARGETNAME + + If you have a target with dual flash banks then define the second + bank as per the following example. + flash bank $_FLASHNAME stm32f1x 0x08080000 0 0 0 $_TARGETNAME + + Some stm32f1x-specific commands (2) are defined: + + -- Command: stm32f1x lock num + Locks the entire stm32 device. The NUM parameter is a value + shown by 'flash banks'. + + -- Command: stm32f1x unlock num + Unlocks the entire stm32 device. The NUM parameter is a value + shown by 'flash banks'. + + -- Command: stm32f1x options_read num + Read and display the stm32 option bytes written by the + 'stm32f1x options_write' command. The NUM parameter is a + value shown by 'flash banks'. + + -- Command: stm32f1x options_write num ('SWWDG'|'HWWDG') + ('RSTSTNDBY'|'NORSTSTNDBY') ('RSTSTOP'|'NORSTSTOP') + Writes the stm32 option byte with the specified values. The + NUM parameter is a value shown by 'flash banks'. + + -- Flash Driver: stm32f2x + All members of the STM32F2 and STM32F4 microcontroller families + from ST Microelectronics include internal flash and use ARM + Cortex-M3/M4 cores. The driver automatically recognizes a number + of these chips using the chip identification register, and + autoconfigures itself. + + Note that some devices have been found that have a flash size + register that contains an invalid value, to workaround this issue + you can override the probed value used by the flash driver. + + flash bank $_FLASHNAME stm32f2x 0 0x20000 0 0 $_TARGETNAME + + Some stm32f2x-specific commands are defined: + + -- Command: stm32f2x lock num + Locks the entire stm32 device. The NUM parameter is a value + shown by 'flash banks'. + + -- Command: stm32f2x unlock num + Unlocks the entire stm32 device. The NUM parameter is a value + shown by 'flash banks'. + + -- Flash Driver: stm32lx + All members of the STM32L microcontroller families from ST + Microelectronics include internal flash and use ARM Cortex-M3 + cores. The driver automatically recognizes a number of these chips + using the chip identification register, and autoconfigures itself. + + Note that some devices have been found that have a flash size + register that contains an invalid value, to workaround this issue + you can override the probed value used by the flash driver. + + flash bank $_FLASHNAME stm32lx 0 0x20000 0 0 $_TARGETNAME + + -- Flash Driver: str7x + All members of the STR7 microcontroller family from ST + Microelectronics include internal flash and use ARM7TDMI cores. + The STR7X driver defines one mandatory parameter, VARIANT, which is + either 'STR71x', 'STR73x' or 'STR75x'. + + flash bank $_FLASHNAME str7x 0x40000000 0x00040000 0 0 $_TARGETNAME STR71x + + -- Command: str7x disable_jtag bank + Activate the Debug/Readout protection mechanism for the + specified flash bank. + + -- Flash Driver: str9x + Most members of the STR9 microcontroller family from ST + Microelectronics include internal flash and use ARM966E cores. The + str9 needs the flash controller to be configured using the 'str9x + flash_config' command prior to Flash programming. + + flash bank $_FLASHNAME str9x 0x40000000 0x00040000 0 0 $_TARGETNAME + str9x flash_config 0 4 2 0 0x80000 + + -- Command: str9x flash_config num bbsr nbbsr bbadr nbbadr + Configures the str9 flash controller. The NUM parameter is a + value shown by 'flash banks'. + + * BBSR - Boot Bank Size register + * NBBSR - Non Boot Bank Size register + * BBADR - Boot Bank Start Address register + * NBBADR - Boot Bank Start Address register + + -- Flash Driver: tms470 + Most members of the TMS470 microcontroller family from Texas + Instruments include internal flash and use ARM7TDMI cores. This + driver doesn't require the chip and bus width to be specified. + + Some tms470-specific commands are defined: + + -- Command: tms470 flash_keyset key0 key1 key2 key3 + Saves programming keys in a register, to enable flash erase + and write commands. + + -- Command: tms470 osc_mhz clock_mhz + Reports the clock speed, which is used to calculate timings. + + -- Command: tms470 plldis (0|1) + Disables (1) or enables (0) use of the PLL to speed up the + flash clock. + + -- Flash Driver: virtual + This is a special driver that maps a previously defined bank to + another address. All bank settings will be copied from the master + physical bank. + + The VIRTUAL driver defines one mandatory parameters, + + * MASTER_BANK The bank that this virtual address refers to. + + So in the following example addresses 0xbfc00000 and 0x9fc00000 + refer to the flash bank defined at address 0x1fc00000. Any cmds + executed on the virtual banks are actually performed on the + physical banks. + flash bank $_FLASHNAME pic32mx 0x1fc00000 0 0 0 $_TARGETNAME + flash bank vbank0 virtual 0xbfc00000 0 0 0 $_TARGETNAME $_FLASHNAME + flash bank vbank1 virtual 0x9fc00000 0 0 0 $_TARGETNAME $_FLASHNAME + + -- Flash Driver: fm3 + All members of the FM3 microcontroller family from Fujitsu include + internal flash and use ARM Cortex M3 cores. The FM3 driver uses + the TARGET parameter to select the correct bank config, it can + currently be one of the following: 'mb9bfxx1.cpu', 'mb9bfxx2.cpu', + 'mb9bfxx3.cpu', 'mb9bfxx4.cpu', 'mb9bfxx5.cpu' or 'mb9bfxx6.cpu'. + + flash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME + +12.4.3 str9xpec driver +---------------------- + +Here is some background info to help you better understand how this +driver works. OpenOCD has two flash drivers for the str9: + 1. Standard driver 'str9x' programmed via the str9 core. Normally + used for flash programming as it is faster than the 'str9xpec' + driver. + 2. Direct programming 'str9xpec' using the flash controller. This is + an ISC compilant (IEEE 1532) tap connected in series with the str9 + core. The str9 core does not need to be running to program using + this flash driver. Typical use for this driver is + locking/unlocking the target and programming the option bytes. + +Before we run any commands using the 'str9xpec' driver we must first +disable the str9 core. This example assumes the 'str9xpec' driver has +been configured for flash bank 0. + # assert srst, we do not want core running + # while accessing str9xpec flash driver + jtag_reset 0 1 + # turn off target polling + poll off + # disable str9 core + str9xpec enable_turbo 0 + # read option bytes + str9xpec options_read 0 + # re-enable str9 core + str9xpec disable_turbo 0 + poll on + reset halt +The above example will read the str9 option bytes. When performing a +unlock remember that you will not be able to halt the str9 - it has been +locked. Halting the core is not required for the 'str9xpec' driver as +mentioned above, just issue the commands above manually or from a telnet +prompt. + + -- Flash Driver: str9xpec + Only use this driver for locking/unlocking the device or + configuring the option bytes. Use the standard str9 driver for + programming. Before using the flash commands the turbo mode must + be enabled using the 'str9xpec enable_turbo' command. + + Several str9xpec-specific commands are defined: + + -- Command: str9xpec disable_turbo num + Restore the str9 into JTAG chain. + + -- Command: str9xpec enable_turbo num + Enable turbo mode, will simply remove the str9 from the chain + and talk directly to the embedded flash controller. + + -- Command: str9xpec lock num + Lock str9 device. The str9 will only respond to an unlock + command that will erase the device. + + -- Command: str9xpec part_id num + Prints the part identifier for bank NUM. + + -- Command: str9xpec options_cmap num ('bank0'|'bank1') + Configure str9 boot bank. + + -- Command: str9xpec options_lvdsel num ('vdd'|'vdd_vddq') + Configure str9 lvd source. + + -- Command: str9xpec options_lvdthd num ('2.4v'|'2.7v') + Configure str9 lvd threshold. + + -- Command: str9xpec options_lvdwarn bank ('vdd'|'vdd_vddq') + Configure str9 lvd reset warning source. + + -- Command: str9xpec options_read num + Read str9 option bytes. + + -- Command: str9xpec options_write num + Write str9 option bytes. + + -- Command: str9xpec unlock num + unlock str9 device. + +12.5 mFlash +=========== + +12.5.1 mFlash Configuration +--------------------------- + + -- Config Command: mflash bank soc base RST_pin target + Configures a mflash for SOC host bank at address BASE. The pin + number format depends on the host GPIO naming convention. + Currently, the mflash driver supports s3c2440 and pxa270. + + Example for s3c2440 mflash where RST PIN is GPIO B1: + + mflash bank $_FLASHNAME s3c2440 0x10000000 1b 0 + + Example for pxa270 mflash where RST PIN is GPIO 43: + + mflash bank $_FLASHNAME pxa270 0x08000000 43 0 + +12.5.2 mFlash commands +---------------------- + + -- Command: mflash config pll frequency + Configure mflash PLL. The FREQUENCY is the mflash input frequency, + in Hz. Issuing this command will erase mflash's whole internal + nand and write new pll. After this command, mflash needs + power-on-reset for normal operation. If pll was newly configured, + storage and boot(optional) info also need to be update. + + -- Command: mflash config boot + Configure bootable option. If bootable option is set, mflash offer + the first 8 sectors (4kB) for boot. + + -- Command: mflash config storage + Configure storage information. For the normal storage operation, + this information must be written. + + -- Command: mflash dump num filename offset size + Dump SIZE bytes, starting at OFFSET bytes from the beginning of the + bank NUM, to the file named FILENAME. + + -- Command: mflash probe + Probe mflash. + + -- Command: mflash write num filename offset + Write the binary file FILENAME to mflash bank NUM, starting at + OFFSET bytes from the beginning of the bank. + + ---------- Footnotes ---------- + + (1) Currently there is a 'stellaris mass_erase' command. That seems +pointless since the same effect can be had using the standard 'flash +erase_address' command. + + (2) Currently there is a 'stm32f1x mass_erase' command. That seems +pointless since the same effect can be had using the standard 'flash +erase_address' command. + + +File: openocd.info, Node: Flash Programming, Next: NAND Flash Commands, Prev: Flash Commands, Up: Top + +13 Flash Programming +******************** + +OpenOCD implements numerous ways to program the target flash, whether +internal or external. Programming can be acheived by either using GDB +*note Programming using GDB: programmingusinggdb, or using the cmds +given in *note Flash Programming Commands: flashprogrammingcommands. + + +To simplify using the flash cmds directly a jimtcl script is available +that handles the programming and verify stage. OpenOCD will +program/verify/reset the target and shutdown. + +The script is executed as follows and by default the following actions +will be peformed. + 1. 'init' is executed. + 2. 'reset init' is called to reset and halt the target, any 'reset + init' scripts are executed. + 3. 'flash write_image' is called to erase and write any flash using + the filename given. + 4. 'verify_image' is called if 'verify' parameter is given. + 5. 'reset run' is called if 'reset' parameter is given. + 6. OpenOCD is shutdown. + +An example of usage is given below. *Note program::. + + # program and verify using elf/hex/s19. verify and reset + # are optional parameters + openocd -f board/stm32f3discovery.cfg \ + -c "program filename.elf verify reset" + + # binary files need the flash address passing + openocd -f board/stm32f3discovery.cfg \ + -c "program filename.bin 0x08000000" + + +File: openocd.info, Node: NAND Flash Commands, Next: PLD/FPGA Commands, Prev: Flash Programming, Up: Top + +14 NAND Flash Commands +********************** + +Compared to NOR or SPI flash, NAND devices are inexpensive and high +density. Today's NAND chips, and multi-chip modules, commonly hold +multiple GigaBytes of data. + +NAND chips consist of a number of "erase blocks" of a given size (such +as 128 KBytes), each of which is divided into a number of pages (of +perhaps 512 or 2048 bytes each). Each page of a NAND flash has an "out +of band" (OOB) area to hold Error Correcting Code (ECC) and other +metadata, usually 16 bytes of OOB for every 512 bytes of page data. + +One key characteristic of NAND flash is that its error rate is higher +than that of NOR flash. In normal operation, that ECC is used to +correct and detect errors. However, NAND blocks can also wear out and +become unusable; those blocks are then marked "bad". NAND chips are +even shipped from the manufacturer with a few bad blocks. The highest +density chips use a technology (MLC) that wears out more quickly, so ECC +support is increasingly important as a way to detect blocks that have +begun to fail, and help to preserve data integrity with techniques such +as wear leveling. + +Software is used to manage the ECC. Some controllers don't support ECC +directly; in those cases, software ECC is used. Other controllers speed +up the ECC calculations with hardware. Single-bit error correction +hardware is routine. Controllers geared for newer MLC chips may correct +4 or more errors for every 512 bytes of data. + +You will need to make sure that any data you write using OpenOCD +includes the apppropriate kind of ECC. For example, that may mean +passing the 'oob_softecc' flag when writing NAND data, or ensuring that +the correct hardware ECC mode is used. + +The basic steps for using NAND devices include: + 1. Declare via the command 'nand device' + Do this in a board-specific configuration file, passing parameters + as needed by the controller. + 2. Configure each device using 'nand probe'. + Do this only after the associated target is set up, such as in its + reset-init script or in procures defined to access that device. + 3. Operate on the flash via 'nand subcommand' + Often commands to manipulate the flash are typed by a human, or run + via a script in some automated way. Common task include writing a + boot loader, operating system, or other data needed to initialize + or de-brick a board. + +NOTE: At the time this text was written, the largest NAND flash fully +supported by OpenOCD is 2 GiBytes (16 GiBits). This is because the +variables used to hold offsets and lengths are only 32 bits wide. +(Larger chips may work in some cases, unless an offset or length is +larger than 0xffffffff, the largest 32-bit unsigned integer.) Some +larger devices will work, since they are actually multi-chip modules +with two smaller chips and individual chipselect lines. + +14.1 NAND Configuration Commands +================================ + +NAND chips must be declared in configuration scripts, plus some +additional configuration that's done after OpenOCD has initialized. + + -- Config Command: nand device name driver target [configparams...] + Declares a NAND device, which can be read and written to after it + has been configured through 'nand probe'. In OpenOCD, devices are + single chips; this is unlike some operating systems, which may + manage multiple chips as if they were a single (larger) device. In + some cases, configuring a device will activate extra commands; see + the controller-specific documentation. + + NOTE: This command is not available after OpenOCD initialization + has completed. Use it in board specific configuration files, not + interactively. + + * NAME ... may be used to reference the NAND bank in most other + NAND commands. A number is also available. + * DRIVER ... identifies the NAND controller driver associated + with the NAND device being declared. *Note NAND Driver List: + nanddriverlist. + * TARGET ... names the target used when issuing commands to the + NAND controller. + * CONFIGPARAMS ... controllers may support, or require, + additional parameters. See the controller-specific + documentation for more information. + + -- Command: nand list + Prints a summary of each device declared using 'nand device', + numbered from zero. Note that un-probed devices show no details. + > nand list + #0: NAND 1GiB 3,3V 8-bit (Micron) pagesize: 2048, buswidth: 8, + blocksize: 131072, blocks: 8192 + #1: NAND 1GiB 3,3V 8-bit (Micron) pagesize: 2048, buswidth: 8, + blocksize: 131072, blocks: 8192 + > + + -- Command: nand probe num + Probes the specified device to determine key characteristics like + its page and block sizes, and how many blocks it has. The NUM + parameter is the value shown by 'nand list'. You must + (successfully) probe a device before you can use it with most other + NAND commands. + +14.2 Erasing, Reading, Writing to NAND Flash +============================================ + + -- Command: nand dump num filename offset length [oob_option] + Reads binary data from the NAND device and writes it to the file, + starting at the specified offset. The NUM parameter is the value + shown by 'nand list'. + + Use a complete path name for FILENAME, so you don't depend on the + directory used to start the OpenOCD server. + + The OFFSET and LENGTH must be exact multiples of the device's page + size. They describe a data region; the OOB data associated with + each such page may also be accessed. + + NOTE: At the time this text was written, no error correction was + done on the data that's read, unless raw access was disabled and + the underlying NAND controller driver had a 'read_page' method + which handled that error correction. + + By default, only page data is saved to the specified file. Use an + OOB_OPTION parameter to save OOB data: + * no oob_* parameter + Output file holds only page data; OOB is discarded. + * 'oob_raw' + Output file interleaves page data and OOB data; the file will + be longer than "length" by the size of the spare areas + associated with each data page. Note that this kind of "raw" + access is different from what's implied by 'nand raw_access', + which just controls whether a hardware-aware access method is + used. + * 'oob_only' + Output file has only raw OOB data, and will be smaller than + "length" since it will contain only the spare areas associated + with each data page. + + -- Command: nand erase num [offset length] + Erases blocks on the specified NAND device, starting at the + specified OFFSET and continuing for LENGTH bytes. Both of those + values must be exact multiples of the device's block size, and the + region they specify must fit entirely in the chip. If those + parameters are not specified, the whole NAND chip will be erased. + The NUM parameter is the value shown by 'nand list'. + + NOTE: This command will try to erase bad blocks, when told to do + so, which will probably invalidate the manufacturer's bad block + marker. For the remainder of the current server session, 'nand + info' will still report that the block "is" bad. + + -- Command: nand write num filename offset [option...] + Writes binary data from the file into the specified NAND device, + starting at the specified offset. Those pages should already have + been erased; you can't change zero bits to one bits. The NUM + parameter is the value shown by 'nand list'. + + Use a complete path name for FILENAME, so you don't depend on the + directory used to start the OpenOCD server. + + The OFFSET must be an exact multiple of the device's page size. + All data in the file will be written, assuming it doesn't run past + the end of the device. Only full pages are written, and any extra + space in the last page will be filled with 0xff bytes. (That + includes OOB data, if that's being written.) + + NOTE: At the time this text was written, bad blocks are ignored. + That is, this routine will not skip bad blocks, but will instead + try to write them. This can cause problems. + + Provide at most one OPTION parameter. With some NAND drivers, the + meanings of these parameters may change if 'nand raw_access' was + used to disable hardware ECC. + * no oob_* parameter + File has only page data, which is written. If raw acccess is + in use, the OOB area will not be written. Otherwise, if the + underlying NAND controller driver has a 'write_page' routine, + that routine may write the OOB with hardware-computed ECC + data. + * 'oob_only' + File has only raw OOB data, which is written to the OOB area. + Each page's data area stays untouched. This can be a + dangerous option, since it can invalidate the ECC data. You + may need to force raw access to use this mode. + * 'oob_raw' + File interleaves data and OOB data, both of which are written + If raw access is enabled, the data is written first, then the + un-altered OOB. Otherwise, if the underlying NAND controller + driver has a 'write_page' routine, that routine may modify the + OOB before it's written, to include hardware-computed ECC + data. + * 'oob_softecc' + File has only page data, which is written. The OOB area is + filled with 0xff, except for a standard 1-bit software ECC + code stored in conventional locations. You might need to + force raw access to use this mode, to prevent the underlying + driver from applying hardware ECC. + * 'oob_softecc_kw' + File has only page data, which is written. The OOB area is + filled with 0xff, except for a 4-bit software ECC specific to + the boot ROM in Marvell Kirkwood SoCs. You might need to + force raw access to use this mode, to prevent the underlying + driver from applying hardware ECC. + + -- Command: nand verify num filename offset [option...] + Verify the binary data in the file has been programmed to the + specified NAND device, starting at the specified offset. The NUM + parameter is the value shown by 'nand list'. + + Use a complete path name for FILENAME, so you don't depend on the + directory used to start the OpenOCD server. + + The OFFSET must be an exact multiple of the device's page size. + All data in the file will be read and compared to the contents of + the flash, assuming it doesn't run past the end of the device. As + with 'nand write', only full pages are verified, so any extra space + in the last page will be filled with 0xff bytes. + + The same OPTIONS accepted by 'nand write', and the file will be + processed similarly to produce the buffers that can be compared + against the contents produced from 'nand dump'. + + NOTE: This will not work when the underlying NAND controller + driver's 'write_page' routine must update the OOB with a + hardward-computed ECC before the data is written. This limitation + may be removed in a future release. + +14.3 Other NAND commands +======================== + + -- Command: nand check_bad_blocks num [offset length] + Checks for manufacturer bad block markers on the specified NAND + device. If no parameters are provided, checks the whole device; + otherwise, starts at the specified OFFSET and continues for LENGTH + bytes. Both of those values must be exact multiples of the + device's block size, and the region they specify must fit entirely + in the chip. The NUM parameter is the value shown by 'nand list'. + + NOTE: Before using this command you should force raw access with + 'nand raw_access enable' to ensure that the underlying driver will + not try to apply hardware ECC. + + -- Command: nand info num + The NUM parameter is the value shown by 'nand list'. This prints + the one-line summary from "nand list", plus for devices which have + been probed this also prints any known status for each block. + + -- Command: nand raw_access num ('enable'|'disable') + Sets or clears an flag affecting how page I/O is done. The NUM + parameter is the value shown by 'nand list'. + + This flag is cleared (disabled) by default, but changing that value + won't affect all NAND devices. The key factor is whether the + underlying driver provides 'read_page' or 'write_page' methods. If + it doesn't provide those methods, the setting of this flag is + irrelevant; all access is effectively "raw". + + When those methods exist, they are normally used when reading data + ('nand dump' or reading bad block markers) or writing it ('nand + write'). However, enabling raw access (setting the flag) prevents + use of those methods, bypassing hardware ECC logic. This can be a + dangerous option, since writing blocks with the wrong ECC data can + cause them to be marked as bad. + +14.4 NAND Driver List +===================== + +As noted above, the 'nand device' command allows driver-specific options +and behaviors. Some controllers also activate controller-specific +commands. + + -- NAND Driver: at91sam9 + This driver handles the NAND controllers found on AT91SAM9 family + chips from Atmel. It takes two extra parameters: address of the + NAND chip; address of the ECC controller. + nand device $NANDFLASH at91sam9 $CHIPNAME 0x40000000 0xfffffe800 + AT91SAM9 chips support single-bit ECC hardware. The 'write_page' + and 'read_page' methods are used to utilize the ECC hardware unless + they are disabled by using the 'nand raw_access' command. There + are four additional commands that are needed to fully configure the + AT91SAM9 NAND controller. Two are optional; most boards use the + same wiring for ALE/CLE: + -- Command: at91sam9 cle num addr_line + Configure the address line used for latching commands. The + NUM parameter is the value shown by 'nand list'. + -- Command: at91sam9 ale num addr_line + Configure the address line used for latching addresses. The + NUM parameter is the value shown by 'nand list'. + + For the next two commands, it is assumed that the pins have already + been properly configured for input or output. + -- Command: at91sam9 rdy_busy num pio_base_addr pin + Configure the RDY/nBUSY input from the NAND device. The NUM + parameter is the value shown by 'nand list'. PIO_BASE_ADDR is + the base address of the PIO controller and PIN is the pin + number. + -- Command: at91sam9 ce num pio_base_addr pin + Configure the chip enable input to the NAND device. The NUM + parameter is the value shown by 'nand list'. PIO_BASE_ADDR is + the base address of the PIO controller and PIN is the pin + number. + + -- NAND Driver: davinci + This driver handles the NAND controllers found on DaVinci family + chips from Texas Instruments. It takes three extra parameters: + address of the NAND chip; hardware ECC mode to use ('hwecc1', + 'hwecc4', 'hwecc4_infix'); address of the AEMIF controller on this + processor. + nand device davinci dm355.arm 0x02000000 hwecc4 0x01e10000 + All DaVinci processors support the single-bit ECC hardware, and + newer ones also support the four-bit ECC hardware. The + 'write_page' and 'read_page' methods are used to implement those + ECC modes, unless they are disabled using the 'nand raw_access' + command. + + -- NAND Driver: lpc3180 + These controllers require an extra 'nand device' parameter: the + clock rate used by the controller. + -- Command: lpc3180 select num [mlc|slc] + Configures use of the MLC or SLC controller mode. MLC implies + use of hardware ECC. The NUM parameter is the value shown by + 'nand list'. + + At this writing, this driver includes 'write_page' and 'read_page' + methods. Using 'nand raw_access' to disable those methods will + prevent use of hardware ECC in the MLC controller mode, but won't + change SLC behavior. + + -- NAND Driver: mx3 + This driver handles the NAND controller in i.MX31. The mxc driver + should work for this chip aswell. + + -- NAND Driver: mxc + This driver handles the NAND controller found in Freescale i.MX + chips. It has support for v1 (i.MX27 and i.MX31) and v2 (i.MX35). + The driver takes 3 extra arguments, chip ('mx27', 'mx31', 'mx35'), + ecc ('noecc', 'hwecc') and optionally if bad block information + should be swapped between main area and spare area ('biswap'), + defaults to off. + nand device mx35.nand mxc imx35.cpu mx35 hwecc biswap + -- Command: mxc biswap bank_num [enable|disable] + Turns on/off bad block information swaping from main area, + without parameter query status. + + -- NAND Driver: orion + These controllers require an extra 'nand device' parameter: the + address of the controller. + nand device orion 0xd8000000 + These controllers don't define any specialized commands. At this + writing, their drivers don't include 'write_page' or 'read_page' + methods, so 'nand raw_access' won't change any behavior. + + -- NAND Driver: s3c2410 + -- NAND Driver: s3c2412 + -- NAND Driver: s3c2440 + -- NAND Driver: s3c2443 + -- NAND Driver: s3c6400 + These S3C family controllers don't have any special 'nand device' + options, and don't define any specialized commands. At this + writing, their drivers don't include 'write_page' or 'read_page' + methods, so 'nand raw_access' won't change any behavior. + + +File: openocd.info, Node: PLD/FPGA Commands, Next: General Commands, Prev: NAND Flash Commands, Up: Top + +15 PLD/FPGA Commands +******************** + +Programmable Logic Devices (PLDs) and the more flexible Field +Programmable Gate Arrays (FPGAs) are both types of programmable +hardware. OpenOCD can support programming them. Although PLDs are +generally restrictive (cells are less functional, and there are no +special purpose cells for memory or computational tasks), they share the +same OpenOCD infrastructure. Accordingly, both are called PLDs here. + +15.1 PLD/FPGA Configuration and Commands +======================================== + +As it does for JTAG TAPs, debug targets, and flash chips (both NOR and +NAND), OpenOCD maintains a list of PLDs available for use in various +commands. Also, each such PLD requires a driver. + +They are referenced by the number shown by the 'pld devices' command, +and new PLDs are defined by 'pld device driver_name'. + + -- Config Command: pld device driver_name tap_name [driver_options] + Defines a new PLD device, supported by driver DRIVER_NAME, using + the TAP named TAP_NAME. The driver may make use of any + DRIVER_OPTIONS to configure its behavior. + + -- Command: pld devices + Lists the PLDs and their numbers. + + -- Command: pld load num filename + Loads the file 'filename' into the PLD identified by NUM. The file + format must be inferred by the driver. + +15.2 PLD/FPGA Drivers, Options, and Commands +============================================ + +Drivers may support PLD-specific options to the 'pld device' definition +command, and may also define commands usable only with that particular +type of PLD. + + -- FPGA Driver: virtex2 + Virtex-II is a family of FPGAs sold by Xilinx. It supports the + IEEE 1532 standard for In-System Configuration (ISC). No + driver-specific PLD definition options are used, and one + driver-specific command is defined. + + -- Command: virtex2 read_stat num + Reads and displays the Virtex-II status register (STAT) for + FPGA NUM. + + +File: openocd.info, Node: General Commands, Next: Architecture and Core Commands, Prev: PLD/FPGA Commands, Up: Top + +16 General Commands +******************* + +The commands documented in this chapter here are common commands that +you, as a human, may want to type and see the output of. Configuration +type commands are documented elsewhere. + +Intent: + * Source Of Commands + OpenOCD commands can occur in a configuration script (discussed + elsewhere) or typed manually by a human or supplied + programatically, or via one of several TCP/IP Ports. + + * From the human + A human should interact with the telnet interface (default port: + 4444) or via GDB (default port 3333). + + To issue commands from within a GDB session, use the 'monitor' + command, e.g. use 'monitor poll' to issue the 'poll' command. All + output is relayed through the GDB session. + + * Machine Interface The Tcl interface's intent is to be a machine + interface. The default Tcl port is 5555. + +16.1 Daemon Commands +==================== + + -- Command: exit + Exits the current telnet session. + + -- Command: help [string] + With no parameters, prints help text for all commands. Otherwise, + prints each helptext containing STRING. Not every command provides + helptext. + + Configuration commands, and commands valid at any time, are + explicitly noted in parenthesis. In most cases, no such + restriction is listed; this indicates commands which are only + available after the configuration stage has completed. + + -- Command: sleep msec ['busy'] + Wait for at least MSEC milliseconds before resuming. If 'busy' is + passed, busy-wait instead of sleeping. (This option is strongly + discouraged.) Useful in connection with script files ('script' + command and 'target_name' configuration). + + -- Command: shutdown + Close the OpenOCD daemon, disconnecting all clients (GDB, telnet, + other). + + -- Command: debug_level [n] + Display debug level. If N (from 0..3) is provided, then set it to + that level. This affects the kind of messages sent to the server + log. Level 0 is error messages only; level 1 adds warnings; level + 2 adds informational messages; and level 3 adds debugging messages. + The default is level 2, but that can be overridden on the command + line along with the location of that log file (which is normally + the server's standard output). *Note Running::. + + -- Command: echo [-n] message + Logs a message at "user" priority. Output MESSAGE to stdout. + Option "-n" suppresses trailing newline. + echo "Downloading kernel -- please wait" + + -- Command: log_output [filename] + Redirect logging to FILENAME; the initial log output channel is + stderr. + + -- Command: add_script_search_dir [directory] + Add DIRECTORY to the file/script search path. + +16.2 Target State handling +========================== + +In this section "target" refers to a CPU configured as shown earlier +(*note CPU Configuration::). These commands, like many, implicitly +refer to a current target which is used to perform the various +operations. The current target may be changed by using 'targets' +command with the name of the target which should become current. + + -- Command: reg [(number|name) [value]] + Access a single register by NUMBER or by its NAME. The target must + generally be halted before access to CPU core registers is allowed. + Depending on the hardware, some other registers may be accessible + while the target is running. + + _With no arguments_: list all available registers for the current + target, showing number, name, size, value, and cache status. For + valid entries, a value is shown; valid entries which are also dirty + (and will be written back later) are flagged as such. + + _With number/name_: display that register's value. + + _With both number/name and value_: set register's value. Writes + may be held in a writeback cache internal to OpenOCD, so that + setting the value marks the register as dirty instead of + immediately flushing that value. Resuming CPU execution (including + by single stepping) or otherwise activating the relevant module + will flush such values. + + Cores may have surprisingly many registers in their Debug and trace + infrastructure: + + > reg + ===== ARM registers + (0) r0 (/32): 0x0000D3C2 (dirty) + (1) r1 (/32): 0xFD61F31C + (2) r2 (/32) + ... + (164) ETM_contextid_comparator_mask (/32) + > + + -- Command: halt [ms] + -- Command: wait_halt [ms] + The 'halt' command first sends a halt request to the target, which + 'wait_halt' doesn't. Otherwise these behave the same: wait up to + MS milliseconds, or 5 seconds if there is no parameter, for the + target to halt (and enter debug mode). Using 0 as the MS parameter + prevents OpenOCD from waiting. + + Warning: On ARM cores, software using the _wait for interrupt_ + operation often blocks the JTAG access needed by a 'halt' + command. This is because that operation also puts the core + into a low power mode by gating the core clock; but the core + clock is needed to detect JTAG clock transitions. + + One partial workaround uses adaptive clocking: when the core + is interrupted the operation completes, then JTAG clocks are + accepted at least until the interrupt handler completes. + However, this workaround is often unusable since the + processor, board, and JTAG adapter must all support adaptive + JTAG clocking. Also, it can't work until an interrupt is + issued. + + A more complete workaround is to not use that operation while + you work with a JTAG debugger. Tasking environments generaly + have idle loops where the body is the _wait for interrupt_ + operation. (On older cores, it is a coprocessor action; newer + cores have a 'wfi' instruction.) Such loops can just remove + that operation, at the cost of higher power consumption + (because the CPU is needlessly clocked). + + -- Command: resume [address] + Resume the target at its current code position, or the optional + ADDRESS if it is provided. OpenOCD will wait 5 seconds for the + target to resume. + + -- Command: step [address] + Single-step the target at its current code position, or the + optional ADDRESS if it is provided. + + -- Command: reset + -- Command: reset run + -- Command: reset halt + -- Command: reset init + Perform as hard a reset as possible, using SRST if possible. _All + defined targets will be reset, and target events will fire during + the reset sequence._ + + The optional parameter specifies what should happen after the + reset. If there is no parameter, a 'reset run' is executed. The + other options will not work on all systems. *Note Reset + Configuration::. + + - run Let the target run + - halt Immediately halt the target + - init Immediately halt the target, and execute the reset-init + script + + -- Command: soft_reset_halt + Requesting target halt and executing a soft reset. This is often + used when a target cannot be reset and halted. The target, after + reset is released begins to execute code. OpenOCD attempts to stop + the CPU and then sets the program counter back to the reset vector. + Unfortunately the code that was executed may have left the hardware + in an unknown state. + +16.3 I/O Utilities +================== + +These commands are available when OpenOCD is built with +'--enable-ioutil'. They are mainly useful on embedded targets, notably +the ZY1000. Hosts with operating systems have complementary tools. + +_Note:_ there are several more such commands. + + -- Command: append_file filename [string]* + Appends the STRING parameters to the text file 'filename'. Each + string except the last one is followed by one space. The last + string is followed by a newline. + + -- Command: cat filename + Reads and displays the text file 'filename'. + + -- Command: cp src_filename dest_filename + Copies contents from the file 'src_filename' into 'dest_filename'. + + -- Command: ip + _No description provided._ + + -- Command: ls + _No description provided._ + + -- Command: mac + _No description provided._ + + -- Command: meminfo + Display available RAM memory on OpenOCD host. Used in OpenOCD + regression testing scripts. + + -- Command: peek + _No description provided._ + + -- Command: poke + _No description provided._ + + -- Command: rm filename + Unlinks the file 'filename'. + + -- Command: trunc filename + Removes all data in the file 'filename'. + +16.4 Memory access commands +=========================== + +These commands allow accesses of a specific size to the memory system. +Often these are used to configure the current target in some special +way. For example - one may need to write certain values to the SDRAM +controller to enable SDRAM. + + 1. Use the 'targets' (plural) command to change the current target. + 2. In system level scripts these commands are deprecated. Please use + their TARGET object siblings to avoid making assumptions about what + TAP is the current target, or about MMU configuration. + + -- Command: mdw [phys] addr [count] + -- Command: mdh [phys] addr [count] + -- Command: mdb [phys] addr [count] + Display contents of address ADDR, as 32-bit words ('mdw'), 16-bit + halfwords ('mdh'), or 8-bit bytes ('mdb'). When the current target + has an MMU which is present and active, ADDR is interpreted as a + virtual address. Otherwise, or if the optional PHYS flag is + specified, ADDR is interpreted as a physical address. If COUNT is + specified, displays that many units. (If you want to manipulate + the data instead of displaying it, see the 'mem2array' primitives.) + + -- Command: mww [phys] addr word + -- Command: mwh [phys] addr halfword + -- Command: mwb [phys] addr byte + Writes the specified WORD (32 bits), HALFWORD (16 bits), or BYTE + (8-bit) value, at the specified address ADDR. When the current + target has an MMU which is present and active, ADDR is interpreted + as a virtual address. Otherwise, or if the optional PHYS flag is + specified, ADDR is interpreted as a physical address. + +16.5 Image loading commands +=========================== + + -- Command: dump_image filename address size + Dump SIZE bytes of target memory starting at ADDRESS to the binary + file named FILENAME. + + -- Command: fast_load + Loads an image stored in memory by 'fast_load_image' to the current + target. Must be preceeded by fast_load_image. + + -- Command: fast_load_image filename address ['bin'|'ihex'|'elf'|'s19'] + Normally you should be using 'load_image' or GDB load. However, + for testing purposes or when I/O overhead is significant(OpenOCD + running on an embedded host), storing the image in memory and + uploading the image to the target can be a way to upload e.g. + multiple debug sessions when the binary does not change. Arguments + are the same as 'load_image', but the image is stored in OpenOCD + host memory, i.e. does not affect target. This approach is also + useful when profiling target programming performance as I/O and + target programming can easily be profiled separately. + + -- Command: load_image filename address [['bin'|'ihex'|'elf'|'s19'] + 'min_addr' 'max_length'] + Load image from file FILENAME to target memory offset by ADDRESS + from its load address. The file format may optionally be specified + ('bin', 'ihex', 'elf', or 's19'). In addition the following + arguments may be specifed: MIN_ADDR - ignore data below MIN_ADDR + (this is w.r.t. to the target's load address + ADDRESS) MAX_LENGTH + - maximum number of bytes to load. + proc load_image_bin {fname foffset address length } { + # Load data from fname filename at foffset offset to + # target at address. Load at most length bytes. + load_image $fname [expr $address - $foffset] bin $address $length + } + + -- Command: test_image filename [address ['bin'|'ihex'|'elf']] + Displays image section sizes and addresses as if FILENAME were + loaded into target memory starting at ADDRESS (defaults to zero). + The file format may optionally be specified ('bin', 'ihex', or + 'elf') + + -- Command: verify_image filename address ['bin'|'ihex'|'elf'] + Verify FILENAME against target memory starting at ADDRESS. The + file format may optionally be specified ('bin', 'ihex', or 'elf') + This will first attempt a comparison using a CRC checksum, if this + fails it will try a binary compare. + +16.6 Breakpoint and Watchpoint commands +======================================= + +CPUs often make debug modules accessible through JTAG, with hardware +support for a handful of code breakpoints and data watchpoints. In +addition, CPUs almost always support software breakpoints. + + -- Command: bp [address len ['hw']] + With no parameters, lists all active breakpoints. Else sets a + breakpoint on code execution starting at ADDRESS for LENGTH bytes. + This is a software breakpoint, unless 'hw' is specified in which + case it will be a hardware breakpoint. + + (*Note arm9 vector_catch: arm9vectorcatch, or *note xscale + vector_catch: xscalevectorcatch, for similar mechanisms that do not + consume hardware breakpoints.) + + -- Command: rbp address + Remove the breakpoint at ADDRESS. + + -- Command: rwp address + Remove data watchpoint on ADDRESS + + -- Command: wp [address len [('r'|'w'|'a') [value [mask]]]] + With no parameters, lists all active watchpoints. Else sets a data + watchpoint on data from ADDRESS for LENGTH bytes. The watch point + is an "access" watchpoint unless the 'r' or 'w' parameter is + provided, defining it as respectively a read or write watchpoint. + If a VALUE is provided, that value is used when determining if the + watchpoint should trigger. The value may be first be masked using + MASK to mark "don't care" fields. + +16.7 Misc Commands +================== + + -- Command: profile seconds filename + Profiling samples the CPU's program counter as quickly as possible, + which is useful for non-intrusive stochastic profiling. Saves up + to 10000 sampines in 'filename' using "gmon.out" format. + + -- Command: version + Displays a string identifying the version of this OpenOCD server. + + -- Command: virt2phys virtual_address + Requests the current target to map the specified VIRTUAL_ADDRESS to + its corresponding physical address, and displays the result. + + +File: openocd.info, Node: Architecture and Core Commands, Next: JTAG Commands, Prev: General Commands, Up: Top + +17 Architecture and Core Commands +********************************* + +Most CPUs have specialized JTAG operations to support debugging. +OpenOCD packages most such operations in its standard command framework. +Some of those operations don't fit well in that framework, so they are +exposed here as architecture or implementation (core) specific commands. + +17.1 ARM Hardware Tracing +========================= + +CPUs based on ARM cores may include standard tracing interfaces, based +on an "Embedded Trace Module" (ETM) which sends voluminous address and +data bus trace records to a "Trace Port". + + * Development-oriented boards will sometimes provide a high speed + trace connector for collecting that data, when the particular CPU + supports such an interface. (The standard connector is a 38-pin + Mictor, with both JTAG and trace port support.) Those trace + connectors are supported by higher end JTAG adapters and some logic + analyzer modules; frequently those modules can buffer several + megabytes of trace data. Configuring an ETM coupled to such an + external trace port belongs in the board-specific configuration + file. + * If the CPU doesn't provide an external interface, it probably has + an "Embedded Trace Buffer" (ETB) on the chip, which is a dedicated + SRAM. 4KBytes is one common ETB size. Configuring an ETM coupled + only to an ETB belongs in the CPU-specific (target) configuration + file, since it works the same on all boards. + +ETM support in OpenOCD doesn't seem to be widely used yet. + + Issues: ETM support may be buggy, and at least some 'etm config' + parameters should be detected by asking the ETM for them. + + ETM trigger events could also implement a kind of complex hardware + breakpoint, much more powerful than the simple watchpoint hardware + exported by EmbeddedICE modules. _Such breakpoints can be + triggered even when using the dummy trace port driver_. + + It seems like a GDB hookup should be possible, as well as tracing + only during specific states (perhaps _handling IRQ 23_ or _calls + foo()_). + + There should be GUI tools to manipulate saved trace data and help + analyse it in conjunction with the source code. It's unclear how + much of a common interface is shared with the current XScale trace + support, or should be shared with eventual Nexus-style trace module + support. + + At this writing (November 2009) only ARM7, ARM9, and ARM11 support + for ETM modules is available. The code should be able to work with + some newer cores; but not all of them support this original style + of JTAG access. + +17.1.1 ETM Configuration +------------------------ + +ETM setup is coupled with the trace port driver configuration. + + -- Config Command: etm config target width mode clocking driver + Declares the ETM associated with TARGET, and associates it with a + given trace port DRIVER. *Note Trace Port Drivers: + traceportdrivers. + + Several of the parameters must reflect the trace port capabilities, + which are a function of silicon capabilties (exposed later using + 'etm info') and of what hardware is connected to that port (such as + an external pod, or ETB). The WIDTH must be either 4, 8, or 16, + except with ETMv3.0 and newer modules which may also support 1, 2, + 24, 32, 48, and 64 bit widths. (With those versions, 'etm info' + also shows whether the selected port width and mode are supported.) + + The MODE must be 'normal', 'multiplexed', or 'demultiplexed'. The + CLOCKING must be 'half' or 'full'. + + Warning: With ETMv3.0 and newer, the bits set with the MODE + and CLOCKING parameters both control the mode. This modified + mode does not map to the values supported by previous ETM + modules, so this syntax is subject to change. + + Note: You can see the ETM registers using the 'reg' command. + Not all possible registers are present in every ETM. Most of + the registers are write-only, and are used to configure what + CPU activities are traced. + + -- Command: etm info + Displays information about the current target's ETM. This includes + resource counts from the 'ETM_CONFIG' register, as well as silicon + capabilities (except on rather old modules). from the + 'ETM_SYS_CONFIG' register. + + -- Command: etm status + Displays status of the current target's ETM and trace port driver: + is the ETM idle, or is it collecting data? Did trace data + overflow? Was it triggered? + + -- Command: etm tracemode [type context_id_bits cycle_accurate + branch_output] + Displays what data that ETM will collect. If arguments are + provided, first configures that data. When the configuration + changes, tracing is stopped and any buffered trace data is + invalidated. + + * TYPE ... describing how data accesses are traced, when they + pass any ViewData filtering that that was set up. The value + is one of 'none' (save nothing), 'data' (save data), 'address' + (save addresses), 'all' (save data and addresses) + * CONTEXT_ID_BITS ... 0, 8, 16, or 32 + * CYCLE_ACCURATE ... 'enable' or 'disable' cycle-accurate + instruction tracing. Before ETMv3, enabling this causes much + extra data to be recorded. + * BRANCH_OUTPUT ... 'enable' or 'disable'. Disable this unless + you need to try reconstructing the instruction trace stream + without an image of the code. + + -- Command: etm trigger_debug ('enable'|'disable') + Displays whether ETM triggering debug entry (like a breakpoint) is + enabled or disabled, after optionally modifying that configuration. + The default behaviour is 'disable'. Any change takes effect after + the next 'etm start'. + + By using script commands to configure ETM registers, you can make + the processor enter debug state automatically when certain + conditions, more complex than supported by the breakpoint hardware, + happen. + +17.1.2 ETM Trace Operation +-------------------------- + +After setting up the ETM, you can use it to collect data. That data can +be exported to files for later analysis. It can also be parsed with +OpenOCD, for basic sanity checking. + +To configure what is being traced, you will need to write various trace +registers using 'reg ETM_*' commands. For the definitions of these +registers, read ARM publication _IHI 0014, "Embedded Trace Macrocell, +Architecture Specification"_. Be aware that most of the relevant +registers are write-only, and that ETM resources are limited. There are +only a handful of address comparators, data comparators, counters, and +so on. + +Examples of scenarios you might arrange to trace include: + + * Code flow within a function, _excluding_ subroutines it calls. Use + address range comparators to enable tracing for instruction access + within that function's body. + * Code flow within a function, _including_ subroutines it calls. Use + the sequencer and address comparators to activate tracing on an + "entered function" state, then deactivate it by exiting that state + when the function's exit code is invoked. + * Code flow starting at the fifth invocation of a function, combining + one of the above models with a counter. + * CPU data accesses to the registers for a particular device, using + address range comparators and the ViewData logic. + * Such data accesses only during IRQ handling, combining the above + model with sequencer triggers which on entry and exit to the IRQ + handler. + * _... more_ + +At this writing, September 2009, there are no Tcl utility procedures to +help set up any common tracing scenarios. + + -- Command: etm analyze + Reads trace data into memory, if it wasn't already present. + Decodes and prints the data that was collected. + + -- Command: etm dump filename + Stores the captured trace data in 'filename'. + + -- Command: etm image filename [base_address] [type] + Opens an image file. + + -- Command: etm load filename + Loads captured trace data from 'filename'. + + -- Command: etm start + Starts trace data collection. + + -- Command: etm stop + Stops trace data collection. + +17.1.3 Trace Port Drivers +------------------------- + +To use an ETM trace port it must be associated with a driver. + + -- Trace Port Driver: dummy + Use the 'dummy' driver if you are configuring an ETM that's not + connected to anything (on-chip ETB or off-chip trace connector). + _This driver lets OpenOCD talk to the ETM, but it does not expose + any trace data collection._ + -- Config Command: etm_dummy config target + Associates the ETM for TARGET with a dummy driver. + + -- Trace Port Driver: etb + Use the 'etb' driver if you are configuring an ETM to use on-chip + ETB memory. + -- Config Command: etb config target etb_tap + Associates the ETM for TARGET with the ETB at ETB_TAP. You + can see the ETB registers using the 'reg' command. + -- Command: etb trigger_percent [percent] + This displays, or optionally changes, ETB behavior after the + ETM's configured _trigger_ event fires. It controls how much + more trace data is saved after the (single) trace trigger + becomes active. + + * The default corresponds to _trace around_ usage, + recording 50 percent data before the event and the rest + afterwards. + * The minimum value of PERCENT is 2 percent, recording + almost exclusively data before the trigger. Such extreme + _trace before_ usage can help figure out what caused that + event to happen. + * The maximum value of PERCENT is 100 percent, recording + data almost exclusively after the event. This extreme + _trace after_ usage might help sort out how the event + caused trouble. + + -- Trace Port Driver: oocd_trace + This driver isn't available unless OpenOCD was explicitly + configured with the '--enable-oocd_trace' option. You probably + don't want to configure it unless you've built the appropriate + prototype hardware; it's _proof-of-concept_ software. + + Use the 'oocd_trace' driver if you are configuring an ETM that's + connected to an off-chip trace connector. + + -- Config Command: oocd_trace config target tty + Associates the ETM for TARGET with a trace driver which + collects data through the serial port TTY. + + -- Command: oocd_trace resync + Re-synchronizes with the capture clock. + + -- Command: oocd_trace status + Reports whether the capture clock is locked or not. + +17.2 Generic ARM +================ + +These commands should be available on all ARM processors. They are +available in addition to other core-specific commands that may be +available. + + -- Command: arm core_state ['arm'|'thumb'] + Displays the core_state, optionally changing it to process either + 'arm' or 'thumb' instructions. The target may later be resumed in + the currently set core_state. (Processors may also support the + Jazelle state, but that is not currently supported in OpenOCD.) + + -- Command: arm disassemble address [count ['thumb']] + Disassembles COUNT instructions starting at ADDRESS. If COUNT is + not specified, a single instruction is disassembled. If 'thumb' is + specified, or the low bit of the address is set, Thumb2 (mixed + 16/32-bit) instructions are used; else ARM (32-bit) instructions + are used. (Processors may also support the Jazelle state, but + those instructions are not currently understood by OpenOCD.) + + Note that all Thumb instructions are Thumb2 instructions, so older + processors (without Thumb2 support) will still see correct + disassembly of Thumb code. Also, ThumbEE opcodes are the same as + Thumb2, with a handful of exceptions. ThumbEE disassembly + currently has no explicit support. + + -- Command: arm mcr pX op1 CRn CRm op2 value + Write VALUE to a coprocessor PX register passing parameters CRN, + CRM, opcodes OPC1 and OPC2, and using the MCR instruction. + (Parameter sequence matches the ARM instruction, but omits an ARM + register.) + + -- Command: arm mrc pX coproc op1 CRn CRm op2 + Read a coprocessor PX register passing parameters CRN, CRM, opcodes + OPC1 and OPC2, and the MRC instruction. Returns the result so it + can be manipulated by Jim scripts. (Parameter sequence matches the + ARM instruction, but omits an ARM register.) + + -- Command: arm reg + Display a table of all banked core registers, fetching the current + value from every core mode if necessary. + + -- Command: arm semihosting ['enable'|'disable'] + Display status of semihosting, after optionally changing that + status. + + Semihosting allows for code executing on an ARM target to use the + I/O facilities on the host computer i.e. the system where OpenOCD + is running. The target application must be linked against a + library implementing the ARM semihosting convention that forwards + operation requests by using a special SVC instruction that is + trapped at the Supervisor Call vector by OpenOCD. + +17.3 ARMv4 and ARMv5 Architecture +================================= + +The ARMv4 and ARMv5 architectures are widely used in embedded systems, +and introduced core parts of the instruction set in use today. That +includes the Thumb instruction set, introduced in the ARMv4T variant. + +17.3.1 ARM7 and ARM9 specific commands +-------------------------------------- + +These commands are specific to ARM7 and ARM9 cores, like ARM7TDMI, +ARM720T, ARM9TDMI, ARM920T or ARM926EJ-S. They are available in addition +to the ARM commands, and any other core-specific commands that may be +available. + + -- Command: arm7_9 dbgrq ['enable'|'disable'] + Displays the value of the flag controlling use of the the + EmbeddedIce DBGRQ signal to force entry into debug mode, instead of + breakpoints. If a boolean parameter is provided, first assigns + that flag. + + This should be safe for all but ARM7TDMI-S cores (like NXP LPC). + This feature is enabled by default on most ARM9 cores, including + ARM9TDMI, ARM920T, and ARM926EJ-S. + + -- Command: arm7_9 dcc_downloads ['enable'|'disable'] + Displays the value of the flag controlling use of the debug + communications channel (DCC) to write larger (>128 byte) amounts of + memory. If a boolean parameter is provided, first assigns that + flag. + + DCC downloads offer a huge speed increase, but might be unsafe, + especially with targets running at very low speeds. This command + was introduced with OpenOCD rev. 60, and requires a few bytes of + working area. + + -- Command: arm7_9 fast_memory_access ['enable'|'disable'] + Displays the value of the flag controlling use of memory writes and + reads that don't check completion of the operation. If a boolean + parameter is provided, first assigns that flag. + + This provides a huge speed increase, especially with USB JTAG + cables (FT2232), but might be unsafe if used with targets running + at very low speeds, like the 32kHz startup clock of an AT91RM9200. + +17.3.2 ARM720T specific commands +-------------------------------- + +These commands are available to ARM720T based CPUs, which are +implementations of the ARMv4T architecture based on the ARM7TDMI-S +integer core. They are available in addition to the ARM and ARM7/ARM9 +commands. + + -- Command: arm720t cp15 opcode [value] + _DEPRECATED - avoid using this. Use the 'arm mrc' or 'arm mcr' + commands instead._ + + Display cp15 register returned by the ARM instruction OPCODE; else + if a VALUE is provided, that value is written to that register. + The OPCODE should be the value of either an MRC or MCR instruction. + +17.3.3 ARM9 specific commands +----------------------------- + +ARM9-family cores are built around ARM9TDMI or ARM9E (including ARM9EJS) +integer processors. Such cores include the ARM920T, ARM926EJ-S, and +ARM966. + + -- Command: arm9 vector_catch ['all'|'none'|list] + Vector Catch hardware provides a sort of dedicated breakpoint for + hardware events such as reset, interrupt, and abort. You can use + this to conserve normal breakpoint resources, so long as you're not + concerned with code that branches directly to those hardware + vectors. + + This always finishes by listing the current configuration. If + parameters are provided, it first reconfigures the vector catch + hardware to intercept 'all' of the hardware vectors, 'none' of + them, or a list with one or more of the following: 'reset' 'undef' + 'swi' 'pabt' 'dabt' 'irq' 'fiq'. + +17.3.4 ARM920T specific commands +-------------------------------- + +These commands are available to ARM920T based CPUs, which are +implementations of the ARMv4T architecture built using the ARM9TDMI +integer core. They are available in addition to the ARM, ARM7/ARM9, and +ARM9 commands. + + -- Command: arm920t cache_info + Print information about the caches found. This allows to see + whether your target is an ARM920T (2x16kByte cache) or ARM922T + (2x8kByte cache). + + -- Command: arm920t cp15 regnum [value] + Display cp15 register REGNUM; else if a VALUE is provided, that + value is written to that register. This uses "physical access" and + the register number is as shown in bits 38..33 of table 9-9 in the + ARM920T TRM. (Not all registers can be written.) + + -- Command: arm920t cp15i opcode [value [address]] + _DEPRECATED - avoid using this. Use the 'arm mrc' or 'arm mcr' + commands instead._ + + Interpreted access using ARM instruction OPCODE, which should be + the value of either an MRC or MCR instruction (as shown tables + 9-11, 9-12, and 9-13 in the ARM920T TRM). If no VALUE is provided, + the result is displayed. Else if that value is written using the + specified ADDRESS, or using zero if no other address is provided. + + -- Command: arm920t read_cache filename + Dump the content of ICache and DCache to a file named 'filename'. + + -- Command: arm920t read_mmu filename + Dump the content of the ITLB and DTLB to a file named 'filename'. + +17.3.5 ARM926ej-s specific commands +----------------------------------- + +These commands are available to ARM926ej-s based CPUs, which are +implementations of the ARMv5TEJ architecture based on the ARM9EJ-S +integer core. They are available in addition to the ARM, ARM7/ARM9, and +ARM9 commands. + +The Feroceon cores also support these commands, although they are not +built from ARM926ej-s designs. + + -- Command: arm926ejs cache_info + Print information about the caches found. + +17.3.6 ARM966E specific commands +-------------------------------- + +These commands are available to ARM966 based CPUs, which are +implementations of the ARMv5TE architecture. They are available in +addition to the ARM, ARM7/ARM9, and ARM9 commands. + + -- Command: arm966e cp15 regnum [value] + Display cp15 register REGNUM; else if a VALUE is provided, that + value is written to that register. The six bit REGNUM values are + bits 37..32 from table 7-2 of the ARM966E-S TRM. There is no + current control over bits 31..30 from that table, as required for + BIST support. + +17.3.7 XScale specific commands +------------------------------- + +Some notes about the debug implementation on the XScale CPUs: + +The XScale CPU provides a special debug-only mini-instruction cache +(mini-IC) in which exception vectors and target-resident debug handler +code are placed by OpenOCD. In order to get access to the CPU, OpenOCD +must point vector 0 (the reset vector) to the entry of the debug +handler. However, this means that the complete first cacheline in the +mini-IC is marked valid, which makes the CPU fetch all exception +handlers from the mini-IC, ignoring the code in RAM. + +To address this situation, OpenOCD provides the 'xscale vector_table' +command, which allows the user to explicity write individual entries to +either the high or low vector table stored in the mini-IC. + +It is recommended to place a pc-relative indirect branch in the vector +table, and put the branch destination somewhere in memory. Doing so +makes sure the code in the vector table stays constant regardless of +code layout in memory: + _vectors: + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + .org 0x100 + .long real_reset_vector + .long real_ui_handler + .long real_swi_handler + .long real_pf_abort + .long real_data_abort + .long 0 /* unused */ + .long real_irq_handler + .long real_fiq_handler + +Alternatively, you may choose to keep some or all of the mini-IC vector +table entries synced with those written to memory by your system +software. The mini-IC can not be modified while the processor is +executing, but for each vector table entry not previously defined using +the 'xscale vector_table' command, OpenOCD will copy the value from +memory to the mini-IC every time execution resumes from a halt. This is +done for both high and low vector tables (although the table not in use +may not be mapped to valid memory, and in this case that copy operation +will silently fail). This means that you will need to briefly halt +execution at some strategic point during system start-up; e.g., after +the software has initialized the vector table, but before exceptions are +enabled. A breakpoint can be used to accomplish this once the +appropriate location in the start-up code has been identified. A +watchpoint over the vector table region is helpful in finding the +location if you're not sure. Note that the same situation exists any +time the vector table is modified by the system software. + +The debug handler must be placed somewhere in the address space using +the 'xscale debug_handler' command. The allowed locations for the debug +handler are either (0x800 - 0x1fef800) or (0xfe000800 - 0xfffff800). +The default value is 0xfe000800. + +XScale has resources to support two hardware breakpoints and two +watchpoints. However, the following restrictions on watchpoint +functionality apply: (1) the value and mask arguments to the 'wp' +command are not supported, (2) the watchpoint length must be a power of +two and not less than four, and can not be greater than the watchpoint +address, and (3) a watchpoint with a length greater than four consumes +all the watchpoint hardware resources. This means that at any one time, +you can have enabled either two watchpoints with a length of four, or +one watchpoint with a length greater than four. + +These commands are available to XScale based CPUs, which are +implementations of the ARMv5TE architecture. + + -- Command: xscale analyze_trace + Displays the contents of the trace buffer. + + -- Command: xscale cache_clean_address address + Changes the address used when cleaning the data cache. + + -- Command: xscale cache_info + Displays information about the CPU caches. + + -- Command: xscale cp15 regnum [value] + Display cp15 register REGNUM; else if a VALUE is provided, that + value is written to that register. + + -- Command: xscale debug_handler target address + Changes the address used for the specified target's debug handler. + + -- Command: xscale dcache ['enable'|'disable'] + Enables or disable the CPU's data cache. + + -- Command: xscale dump_trace filename + Dumps the raw contents of the trace buffer to 'filename'. + + -- Command: xscale icache ['enable'|'disable'] + Enables or disable the CPU's instruction cache. + + -- Command: xscale mmu ['enable'|'disable'] + Enables or disable the CPU's memory management unit. + + -- Command: xscale trace_buffer ['enable'|'disable' ['fill' [n] | + 'wrap']] + Displays the trace buffer status, after optionally enabling or + disabling the trace buffer and modifying how it is emptied. + + -- Command: xscale trace_image filename [offset [type]] + Opens a trace image from 'filename', optionally rebasing its + segment addresses by OFFSET. The image TYPE may be one of 'bin' + (binary), 'ihex' (Intel hex), 'elf' (ELF file), 's19' (Motorola + s19), 'mem', or 'builder'. + + -- Command: xscale vector_catch [mask] + Display a bitmask showing the hardware vectors to catch. If the + optional parameter is provided, first set the bitmask to that + value. + + The mask bits correspond with bit 16..23 in the DCSR: + 0x01 Trap Reset + 0x02 Trap Undefined Instructions + 0x04 Trap Software Interrupt + 0x08 Trap Prefetch Abort + 0x10 Trap Data Abort + 0x20 reserved + 0x40 Trap IRQ + 0x80 Trap FIQ + + -- Command: xscale vector_table [('low'|'high') index value] + + Set an entry in the mini-IC vector table. There are two tables: + one for low vectors (at 0x00000000), and one for high vectors + (0xFFFF0000), each holding the 8 exception vectors. INDEX can be + 1-7, because vector 0 points to the debug handler entry and can not + be overwritten. VALUE holds the 32-bit opcode that is placed in + the mini-IC. + + Without arguments, the current settings are displayed. + +17.4 ARMv6 Architecture +======================= + +17.4.1 ARM11 specific commands +------------------------------ + + -- Command: arm11 memwrite burst ['enable'|'disable'] + Displays the value of the memwrite burst-enable flag, which is + enabled by default. If a boolean parameter is provided, first + assigns that flag. Burst writes are only used for memory writes + larger than 1 word. They improve performance by assuming that the + CPU has read each data word over JTAG and completed its write + before the next word arrives, instead of polling for a status flag + to verify that completion. This is usually safe, because JTAG runs + much slower than the CPU. + + -- Command: arm11 memwrite error_fatal ['enable'|'disable'] + Displays the value of the memwrite error_fatal flag, which is + enabled by default. If a boolean parameter is provided, first + assigns that flag. When set, certain memory write errors cause + earlier transfer termination. + + -- Command: arm11 step_irq_enable ['enable'|'disable'] + Displays the value of the flag controlling whether IRQs are enabled + during single stepping; they are disabled by default. If a boolean + parameter is provided, first assigns that. + + -- Command: arm11 vcr [value] + Displays the value of the _Vector Catch Register (VCR)_, + coprocessor 14 register 7. If VALUE is defined, first assigns + that. + + Vector Catch hardware provides dedicated breakpoints for certain + hardware events. The specific bit values are core-specific (as in + fact is using coprocessor 14 register 7 itself) but all current + ARM11 cores _except the ARM1176_ use the same six bits. + +17.5 ARMv7 Architecture +======================= + +17.5.1 ARMv7 Debug Access Port (DAP) specific commands +------------------------------------------------------ + +These commands are specific to ARM architecture v7 Debug Access Port +(DAP), included on Cortex-M and Cortex-A systems. They are available in +addition to other core-specific commands that may be available. + + -- Command: dap apid [num] + Displays ID register from AP NUM, defaulting to the currently + selected AP. + + -- Command: dap apsel [num] + Select AP NUM, defaulting to 0. + + -- Command: dap baseaddr [num] + Displays debug base address from MEM-AP NUM, defaulting to the + currently selected AP. + + -- Command: dap info [num] + Displays the ROM table for MEM-AP NUM, defaulting to the currently + selected AP. + + -- Command: dap memaccess [value] + Displays the number of extra tck cycles in the JTAG idle to use for + MEM-AP memory bus access [0-255], giving additional time to respond + to reads. If VALUE is defined, first assigns that. + + -- Command: dap apcsw [0 / 1] + fix CSW_SPROT from register AP_REG_CSW on selected dap. Defaulting + to 0. + +17.5.2 Cortex-M specific commands +--------------------------------- + + -- Command: cortex_m maskisr ('auto'|'on'|'off') + Control masking (disabling) interrupts during target step/resume. + + The 'auto' option handles interrupts during stepping a way they get + served but don't disturb the program flow. The step command first + allows pending interrupt handlers to execute, then disables + interrupts and steps over the next instruction where the core was + halted. After the step interrupts are enabled again. If the + interrupt handlers don't complete within 500ms, the step command + leaves with the core running. + + Note that a free breakpoint is required for the 'auto' option. If + no breakpoint is available at the time of the step, then the step + is taken with interrupts enabled, i.e. the same way the 'off' + option does. + + Default is 'auto'. + + -- Command: cortex_m vector_catch ['all'|'none'|list] + Vector Catch hardware provides dedicated breakpoints for certain + hardware events. + + Parameters request interception of 'all' of these hardware event + vectors, 'none' of them, or one or more of the following: + 'hard_err' for a HardFault exception; 'mm_err' for a MemManage + exception; 'bus_err' for a BusFault exception; 'irq_err', + 'state_err', 'chk_err', or 'nocp_err' for various UsageFault + exceptions; or 'reset'. If NVIC setup code does not enable them, + MemManage, BusFault, and UsageFault exceptions are mapped to + HardFault. UsageFault checks for divide-by-zero and unaligned + access must also be explicitly enabled. + + This finishes by listing the current vector catch configuration. + + -- Command: cortex_m reset_config ('srst'|'sysresetreq'|'vectreset') + Control reset handling. The default 'srst' is to use srst if + fitted, otherwise fallback to 'vectreset'. + - 'srst' use hardware srst if fitted otherwise fallback to + 'vectreset'. + - 'sysresetreq' use NVIC SYSRESETREQ to reset system. + - 'vectreset' use NVIC VECTRESET to reset system. + Using 'vectreset' is a safe option for all current Cortex-M cores. + This however has the disadvantage of only resetting the core, all + peripherals are uneffected. A solution would be to use a + 'reset-init' event handler to manually reset the peripherals. + *Note Target Events: targetevents. + +17.6 Software Debug Messages and Tracing +======================================== + +OpenOCD can process certain requests from target software, when the +target uses appropriate libraries. The most powerful mechanism is +semihosting, but there is also a lighter weight mechanism using only the +DCC channel. + +Currently 'target_request debugmsgs' is supported only for 'arm7_9' and +'cortex_m' cores. These messages are received as part of target +polling, so you need to have 'poll on' active to receive them. They are +intrusive in that they will affect program execution times. If that is +a problem, *note ARM Hardware Tracing: armhardwaretracing. + +See 'libdcc' in the contrib dir for more details. In addition to +sending strings, characters, and arrays of various size integers from +the target, 'libdcc' also exports a software trace point mechanism. The +target being debugged may issue trace messages which include a 24-bit +"trace point" number. Trace point support includes two distinct +mechanisms, each supported by a command: + + * _History_ ... A circular buffer of trace points can be set up, and + then displayed at any time. This tracks where code has been, which + can be invaluable in finding out how some fault was triggered. + + The buffer may overflow, since it collects records continuously. + It may be useful to use some of the 24 bits to represent a + particular event, and other bits to hold data. + + * _Counting_ ... An array of counters can be set up, and then + displayed at any time. This can help establish code coverage and + identify hot spots. + + The array of counters is directly indexed by the trace point + number, so trace points with higher numbers are not counted. + +Linux-ARM kernels have a "Kernel low-level debugging via EmbeddedICE DCC +channel" option (CONFIG_DEBUG_ICEDCC, depends on CONFIG_DEBUG_LL) which +uses this mechanism to deliver messages before a serial console can be +activated. This is not the same format used by 'libdcc'. Other +software, such as the U-Boot boot loader, sometimes does the same thing. + + -- Command: target_request debugmsgs ['enable'|'disable'|'charmsg'] + Displays current handling of target DCC message requests. These + messages may be sent to the debugger while the target is running. + The optional 'enable' and 'charmsg' parameters both enable the + messages, while 'disable' disables them. + + With 'charmsg' the DCC words each contain one character, as used by + Linux with CONFIG_DEBUG_ICEDCC; otherwise the libdcc format is + used. + + -- Command: trace history ['clear'|count] + With no parameter, displays all the trace points that have + triggered in the order they triggered. With the parameter 'clear', + erases all current trace history records. With a COUNT parameter, + allocates space for that many history records. + + -- Command: trace point ['clear'|identifier] + With no parameter, displays all trace point identifiers and how + many times they have been triggered. With the parameter 'clear', + erases all current trace point counters. With a numeric IDENTIFIER + parameter, creates a new a trace point counter and associates it + with that identifier. + + _Important:_ The identifier and the trace point number are not + related except by this command. These trace point numbers always + start at zero (from server startup, or after 'trace point clear') + and count up from there. + + +File: openocd.info, Node: JTAG Commands, Next: Boundary Scan Commands, Prev: Architecture and Core Commands, Up: Top + +18 JTAG Commands +**************** + +Most general purpose JTAG commands have been presented earlier. (*Note +JTAG Speed: jtagspeed, *note Reset Configuration::, and *note TAP +Declaration::.) Lower level JTAG commands, as presented here, may be +needed to work with targets which require special attention during +operations such as reset or initialization. + +To use these commands you will need to understand some of the basics of +JTAG, including: + + * A JTAG scan chain consists of a sequence of individual TAP devices + such as a CPUs. + * Control operations involve moving each TAP through the same + standard state machine (in parallel) using their shared TMS and + clock signals. + * Data transfer involves shifting data through the chain of + instruction or data registers of each TAP, writing new register + values while the reading previous ones. + * Data register sizes are a function of the instruction active in a + given TAP, while instruction register sizes are fixed for each TAP. + All TAPs support a BYPASS instruction with a single bit data + register. + * The way OpenOCD differentiates between TAP devices is by shifting + different instructions into (and out of) their instruction + registers. + +18.1 Low Level JTAG Commands +============================ + +These commands are used by developers who need to access JTAG +instruction or data registers, possibly controlling the order of TAP +state transitions. If you're not debugging OpenOCD internals, or +bringing up a new JTAG adapter or a new type of TAP device (like a CPU +or JTAG router), you probably won't need to use these commands. In a +debug session that doesn't use JTAG for its transport protocol, these +commands are not available. + + -- Command: drscan tap [numbits value]+ ['-endstate' tap_state] + Loads the data register of TAP with a series of bit fields that + specify the entire register. Each field is NUMBITS bits long with + a numeric VALUE (hexadecimal encouraged). The return value holds + the original value of each of those fields. + + For example, a 38 bit number might be specified as one field of 32 + bits then one of 6 bits. _For portability, never pass fields which + are more than 32 bits long. Many OpenOCD implementations do not + support 64-bit (or larger) integer values._ + + All TAPs other than TAP must be in BYPASS mode. The single bit in + their data registers does not matter. + + When TAP_STATE is specified, the JTAG state machine is left in that + state. For example DRPAUSE might be specified, so that more + instructions can be issued before re-entering the RUN/IDLE state. + If the end state is not specified, the RUN/IDLE state is entered. + + Warning: OpenOCD does not record information about data + register lengths, so _it is important that you get the bit + field lengths right_. Remember that different JTAG + instructions refer to different data registers, which may have + different lengths. Moreover, those lengths may not be fixed; + the SCAN_N instruction can change the length of the register + accessed by the INTEST instruction (by connecting a different + scan chain). + + -- Command: flush_count + Returns the number of times the JTAG queue has been flushed. This + may be used for performance tuning. + + For example, flushing a queue over USB involves a minimum latency, + often several milliseconds, which does not change with the amount + of data which is written. You may be able to identify performance + problems by finding tasks which waste bandwidth by flushing small + transfers too often, instead of batching them into larger + operations. + + -- Command: irscan [tap instruction]+ ['-endstate' tap_state] + For each TAP listed, loads the instruction register with its + associated numeric INSTRUCTION. (The number of bits in that + instruction may be displayed using the 'scan_chain' command.) For + other TAPs, a BYPASS instruction is loaded. + + When TAP_STATE is specified, the JTAG state machine is left in that + state. For example IRPAUSE might be specified, so the data + register can be loaded before re-entering the RUN/IDLE state. If + the end state is not specified, the RUN/IDLE state is entered. + + Note: OpenOCD currently supports only a single field for + instruction register values, unlike data register values. For + TAPs where the instruction register length is more than 32 + bits, portable scripts currently must issue only BYPASS + instructions. + + -- Command: jtag_reset trst srst + Set values of reset signals. The TRST and SRST parameter values + may be '0', indicating that reset is inactive (pulled or driven + high), or '1', indicating it is active (pulled or driven low). The + 'reset_config' command should already have been used to configure + how the board and JTAG adapter treat these two signals, and to say + if either signal is even present. *Note Reset Configuration::. + + Note that TRST is specially handled. It actually signifies JTAG's + RESET state. So if the board doesn't support the optional TRST + signal, or it doesn't support it along with the specified SRST + value, JTAG reset is triggered with TMS and TCK signals instead of + the TRST signal. And no matter how that JTAG reset is triggered, + once the scan chain enters RESET with TRST inactive, TAP + 'post-reset' events are delivered to all TAPs with handlers for + that event. + + -- Command: pathmove start_state [next_state ...] + Start by moving to START_STATE, which must be one of the _stable_ + states. Unless it is the only state given, this will often be the + current state, so that no TCK transitions are needed. Then, in a + series of single state transitions (conforming to the JTAG state + machine) shift to each NEXT_STATE in sequence, one per TCK cycle. + The final state must also be stable. + + -- Command: runtest NUM_CYCLES + Move to the RUN/IDLE state, and execute at least NUM_CYCLES of the + JTAG clock (TCK). Instructions often need some time to execute + before they take effect. + + -- Command: verify_ircapture ('enable'|'disable') + Verify values captured during IRCAPTURE and returned during IR + scans. Default is enabled, but this can be overridden by + 'verify_jtag'. This flag is ignored when validating JTAG chain + configuration. + + -- Command: verify_jtag ('enable'|'disable') + Enables verification of DR and IR scans, to help detect programming + errors. For IR scans, 'verify_ircapture' must also be enabled. + Default is enabled. + +18.2 TAP state names +==================== + +The TAP_STATE names used by OpenOCD in the 'drscan', 'irscan', and +'pathmove' commands are the same as those used in SVF boundary scan +documents, except that SVF uses IDLE instead of RUN/IDLE. + + * RESET ... _stable_ (with TMS high); acts as if TRST were pulsed + * RUN/IDLE ... _stable_; don't assume this always means IDLE + * DRSELECT + * DRCAPTURE + * DRSHIFT ... _stable_; TDI/TDO shifting through the data register + * DREXIT1 + * DRPAUSE ... _stable_; data register ready for update or more + shifting + * DREXIT2 + * DRUPDATE + * IRSELECT + * IRCAPTURE + * IRSHIFT ... _stable_; TDI/TDO shifting through the instruction + register + * IREXIT1 + * IRPAUSE ... _stable_; instruction register ready for update or + more shifting + * IREXIT2 + * IRUPDATE + +Note that only six of those states are fully "stable" in the face of TMS +fixed (low except for RESET) and a free-running JTAG clock. For all the +others, the next TCK transition changes to a new state. + + * From DRSHIFT and IRSHIFT, clock transitions will produce side + effects by changing register contents. The values to be latched in + upcoming DRUPDATE or IRUPDATE states may not be as expected. + * RUN/IDLE, DRPAUSE, and IRPAUSE are reasonable choices after + 'drscan' or 'irscan' commands, since they are free of JTAG side + effects. + * RUN/IDLE may have side effects that appear at non-JTAG levels, such + as advancing the ARM9E-S instruction pipeline. Consult the + documentation for the TAP(s) you are working with. + diff --git a/debuggers/openocd/doc/openocd.info-2 b/debuggers/openocd/doc/openocd.info-2 new file mode 100644 index 00000000..ab4cbd4e --- /dev/null +++ b/debuggers/openocd/doc/openocd.info-2 @@ -0,0 +1,2250 @@ +This is openocd.info, produced by makeinfo version 5.1 from +openocd.texi. + +This User's Guide documents release 0.7.0, dated 4 May 2013, of the Open +On-Chip Debugger (OpenOCD). + + * Copyright (C) 2008 The OpenOCD Project + * Copyright (C) 2007-2008 Spencer Oliver + * Copyright (C) 2008-2010 Oyvind Harboe + * Copyright (C) 2008 Duane Ellis + * Copyright (C) 2009-2010 David Brownell + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, with no Front-Cover Texts, + and with no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". +INFO-DIR-SECTION Development +START-INFO-DIR-ENTRY +* OpenOCD: (openocd). OpenOCD User's Guide +END-INFO-DIR-ENTRY + + +File: openocd.info, Node: Boundary Scan Commands, Next: TFTP, Prev: JTAG Commands, Up: Top + +19 Boundary Scan Commands +************************* + +One of the original purposes of JTAG was to support boundary scan based +hardware testing. Although its primary focus is to support On-Chip +Debugging, OpenOCD also includes some boundary scan commands. + +19.1 SVF: Serial Vector Format +============================== + +The Serial Vector Format, better known as "SVF", is a way to represent +JTAG test patterns in text files. In a debug session using JTAG for its +transport protocol, OpenOCD supports running such test files. + + -- Command: svf filename ['quiet'] + This issues a JTAG reset (Test-Logic-Reset) and then runs the SVF + script from 'filename'. Unless the 'quiet' option is specified, + each command is logged before it is executed. + +19.2 XSVF: Xilinx Serial Vector Format +====================================== + +The Xilinx Serial Vector Format, better known as "XSVF", is a binary +representation of SVF which is optimized for use with Xilinx devices. +In a debug session using JTAG for its transport protocol, OpenOCD +supports running such test files. + + Important: Not all XSVF commands are supported. + + -- Command: xsvf (tapname|'plain') filename ['virt2'] ['quiet'] + This issues a JTAG reset (Test-Logic-Reset) and then runs the XSVF + script from 'filename'. When a TAPNAME is specified, the commands + are directed at that TAP. When 'virt2' is specified, the XRUNTEST + command counts are interpreted as TCK cycles instead of + microseconds. Unless the 'quiet' option is specified, messages are + logged for comments and some retries. + +The OpenOCD sources also include two utility scripts for working with +XSVF; they are not currently installed after building the software. You +may find them useful: + + * _svf2xsvf_ ... converts SVF files into the extended XSVF syntax + understood by the 'xsvf' command; see notes below. + * _xsvfdump_ ... converts XSVF files into a text output format; + understands the OpenOCD extensions. + +The input format accepts a handful of non-standard extensions. These +include three opcodes corresponding to SVF extensions from Lattice +Semiconductor (LCOUNT, LDELAY, LDSR), and two opcodes supporting a more +accurate translation of SVF (XTRST, XWAITSTATE). If _xsvfdump_ shows a +file is using those opcodes, it probably will not be usable with other +XSVF tools. + + +File: openocd.info, Node: TFTP, Next: GDB and OpenOCD, Prev: Boundary Scan Commands, Up: Top + +20 TFTP +******* + +If OpenOCD runs on an embedded host(as ZY1000 does), then TFTP can be +used to access files on PCs (either the developer's PC or some other +PC). + +The way this works on the ZY1000 is to prefix a filename by "/tftp/ip/" +and append the TFTP path on the TFTP server (tftpd). For example, + + load_image /tftp/10.0.0.96/c:\temp\abc.elf + +will load c:\temp\abc.elf from the developer pc (10.0.0.96) into memory +as if the file was hosted on the embedded host. + +In order to achieve decent performance, you must choose a TFTP server +that supports a packet size bigger than the default packet size (512 +bytes). There are numerous TFTP servers out there (free and commercial) +and you will have to do a bit of googling to find something that fits +your requirements. + + +File: openocd.info, Node: GDB and OpenOCD, Next: Tcl Scripting API, Prev: TFTP, Up: Top + +21 GDB and OpenOCD +****************** + +OpenOCD complies with the remote gdbserver protocol, and as such can be +used to debug remote targets. Setting up GDB to work with OpenOCD can +involve several components: + + * The OpenOCD server support for GDB may need to be configured. + *Note GDB Configuration: gdbconfiguration. + * GDB's support for OpenOCD may need configuration, as shown in this + chapter. + * If you have a GUI environment like Eclipse, that also will probably + need to be configured. + +Of course, the version of GDB you use will need to be one which has been +built to know about the target CPU you're using. It's probably part of +the tool chain you're using. For example, if you are doing +cross-development for ARM on an x86 PC, instead of using the native x86 +'gdb' command you might use 'arm-none-eabi-gdb' if that's the tool chain +used to compile your code. + +21.1 Connecting to GDB +====================== + +Use GDB 6.7 or newer with OpenOCD if you run into trouble. For instance +GDB 6.3 has a known bug that produces bogus memory access errors, which +has since been fixed; see + + +OpenOCD can communicate with GDB in two ways: + + 1. A socket (TCP/IP) connection is typically started as follows: + target remote localhost:3333 + This would cause GDB to connect to the gdbserver on the local pc + using port 3333. + + It is also possible to use the GDB extended remote protocol as + follows: + target extended-remote localhost:3333 + 2. A pipe connection is typically started as follows: + target remote | openocd -c "gdb_port pipe; log_output openocd.log" + This would cause GDB to run OpenOCD and communicate using pipes + (stdin/stdout). Using this method has the advantage of GDB + starting/stopping OpenOCD for the debug session. log_output sends + the log output to a file to ensure that the pipe is not saturated + when using higher debug level outputs. + +To list the available OpenOCD commands type 'monitor help' on the GDB +command line. + +21.2 Sample GDB session startup +=============================== + +With the remote protocol, GDB sessions start a little differently than +they do when you're debugging locally. Here's an examples showing how +to start a debug session with a small ARM program. In this case the +program was linked to be loaded into SRAM on a Cortex-M3. Most programs +would be written into flash (address 0) and run from there. + + $ arm-none-eabi-gdb example.elf + (gdb) target remote localhost:3333 + Remote debugging using localhost:3333 + ... + (gdb) monitor reset halt + ... + (gdb) load + Loading section .vectors, size 0x100 lma 0x20000000 + Loading section .text, size 0x5a0 lma 0x20000100 + Loading section .data, size 0x18 lma 0x200006a0 + Start address 0x2000061c, load size 1720 + Transfer rate: 22 KB/sec, 573 bytes/write. + (gdb) continue + Continuing. + ... + +You could then interrupt the GDB session to make the program break, type +'where' to show the stack, 'list' to show the code around the program +counter, 'step' through code, set breakpoints or watchpoints, and so on. + +21.3 Configuring GDB for OpenOCD +================================ + +OpenOCD supports the gdb 'qSupported' packet, this enables information +to be sent by the GDB remote server (i.e. OpenOCD) to GDB. Typical +information includes packet size and the device's memory map. You do +not need to configure the packet size by hand, and the relevant parts of +the memory map should be automatically set up when you declare (NOR) +flash banks. + +However, there are other things which GDB can't currently query. You +may need to set those up by hand. As OpenOCD starts up, you will often +see a line reporting something like: + + Info : lm3s.cpu: hardware has 6 breakpoints, 4 watchpoints + +You can pass that information to GDB with these commands: + + set remote hardware-breakpoint-limit 6 + set remote hardware-watchpoint-limit 4 + +With that particular hardware (Cortex-M3) the hardware breakpoints only +work for code running from flash memory. Most other ARM systems do not +have such restrictions. + +Another example of useful GDB configuration came from a user who found +that single stepping his Cortex-M3 didn't work well with IRQs and an +RTOS until he told GDB to disable the IRQs while stepping: + + define hook-step + mon cortex_m maskisr on + end + define hookpost-step + mon cortex_m maskisr off + end + +Rather than typing such commands interactively, you may prefer to save +them in a file and have GDB execute them as it starts, perhaps using a +'.gdbinit' in your project directory or starting GDB using 'gdb -x +filename'. + +21.4 Programming using GDB +========================== + +By default the target memory map is sent to GDB. This can be disabled by +the following OpenOCD configuration option: + gdb_memory_map disable +For this to function correctly a valid flash configuration must also be +set in OpenOCD. For faster performance you should also configure a valid +working area. + +Informing GDB of the memory map of the target will enable GDB to protect +any flash areas of the target and use hardware breakpoints by default. +This means that the OpenOCD option 'gdb_breakpoint_override' is not +required when using a memory map. *Note gdb_breakpoint_override: +gdbbreakpointoverride. + +To view the configured memory map in GDB, use the GDB command 'info mem' +All other unassigned addresses within GDB are treated as RAM. + +GDB 6.8 and higher set any memory area not in the memory map as +inaccessible. This can be changed to the old behaviour by using the +following GDB command + set mem inaccessible-by-default off + +If 'gdb_flash_program enable' is also used, GDB will be able to program +any flash memory using the vFlash interface. + +GDB will look at the target memory map when a load command is given, if +any areas to be programmed lie within the target flash area the vFlash +packets will be used. + +If the target needs configuring before GDB programming, an event script +can be executed: + $_TARGETNAME configure -event EVENTNAME BODY + +To verify any flash programming the GDB command 'compare-sections' can +be used. + +21.5 Using OpenOCD SMP with GDB +=============================== + +For SMP support following GDB serial protocol packet have been defined : + * j - smp status request + * J - smp set request + +OpenOCD implements : + * 'jc' packet for reading core id displayed by GDB connection. Reply + is 'XXXXXXXX' (8 hex digits giving core id) or 'E01' for target not + smp. + * 'JcXXXXXXXX' (8 hex digits) packet for setting core id displayed at + next GDB continue (core id -1 is reserved for returning to normal + resume mode). Reply 'E01' for target not smp or 'OK' on success. + +Handling of this packet within GDB can be done : + * by the creation of an internal variable (i.e '_core') by mean of + function allocate_computed_value allowing following GDB command. + set $_core 1 + #Jc01 packet is sent + print $_core + #jc packet is sent and result is affected in $ + + * by the usage of GDB maintenance command as described in following + example (2 cpus in SMP with core id 0 and 1 *note Define CPU + targets working in SMP: definecputargetsworkinginsmp.). + + # toggle0 : force display of coreid 0 + define toggle0 + maint packet Jc0 + continue + main packet Jc-1 + end + # toggle1 : force display of coreid 1 + define toggle1 + maint packet Jc1 + continue + main packet Jc-1 + end + + +File: openocd.info, Node: Tcl Scripting API, Next: FAQ, Prev: GDB and OpenOCD, Up: Top + +22 Tcl Scripting API +******************** + +22.1 API rules +============== + +The commands are stateless. E.g. the telnet command line has a concept +of currently active target, the Tcl API proc's take this sort of state +information as an argument to each proc. + +There are three main types of return values: single value, name value +pair list and lists. + +Name value pair. The proc 'foo' below returns a name/value pair list. + + + > set foo(me) Duane + > set foo(you) Oyvind + > set foo(mouse) Micky + > set foo(duck) Donald + +If one does this: + + > set foo + +The result is: + + me Duane you Oyvind mouse Micky duck Donald + +Thus, to get the names of the associative array is easy: + + foreach { name value } [set foo] { + puts "Name: $name, Value: $value" + } + +Lists returned must be relatively small. Otherwise a range should be +passed in to the proc in question. + +22.2 Internal low-level Commands +================================ + +By low-level, the intent is a human would not directly use these +commands. + +Low-level commands are (should be) prefixed with "ocd_", e.g. +'ocd_flash_banks' is the low level API upon which 'flash banks' is +implemented. + + * mem2array + + Read memory and return as a Tcl array for script processing + * array2mem + + Convert a Tcl array to memory locations and write the values + * ocd_flash_banks + ['driver options' ...] + + Return information about the flash banks + +OpenOCD commands can consist of two words, e.g. "flash banks". The +'startup.tcl' "unknown" proc will translate this into a Tcl proc called +"flash_banks". + +22.3 OpenOCD specific Global Variables +====================================== + +Real Tcl has ::tcl_platform(), and platform::identify, and many other +variables. JimTCL, as implemented in OpenOCD creates $ocd_HOSTOS which +holds one of the following values: + + * cygwin Running under Cygwin + * darwin Darwin (Mac-OS) is the underlying operating sytem. + * freebsd Running under FreeBSD + * linux Linux is the underlying operating sytem + * mingw32 Running under MingW32 + * winxx Built using Microsoft Visual Studio + * other Unknown, none of the above. + +Note: 'winxx' was choosen because today (March-2009) no distinction is +made between Win32 and Win64. + + Note: We should add support for a variable like Tcl variable + 'tcl_platform(platform)', it should be called 'jim_platform' + (because it is jim, not real tcl). + + +File: openocd.info, Node: FAQ, Next: Tcl Crash Course, Prev: Tcl Scripting API, Up: Top + +23 FAQ +****** + + 1. RTCK, also known as: Adaptive Clocking - What is it? + + In digital circuit design it is often refered to as "clock + synchronisation" the JTAG interface uses one clock (TCK or TCLK) + operating at some speed, your CPU target is operating at another. + The two clocks are not synchronised, they are "asynchronous" + + In order for the two to work together they must be synchronised + well enough to work; JTAG can't go ten times faster than the CPU, + for example. There are 2 basic options: + 1. Use a special "adaptive clocking" circuit to change the JTAG + clock rate to match what the CPU currently supports. + 2. The JTAG clock must be fixed at some speed that's enough + slower than the CPU clock that all TMS and TDI transitions can + be detected. + + Does this really matter? For some chips and some situations, this + is a non-issue, like a 500MHz ARM926 with a 5 MHz JTAG link; the + CPU has no difficulty keeping up with JTAG. Startup sequences are + often problematic though, as are other situations where the CPU + clock rate changes (perhaps to save power). + + For example, Atmel AT91SAM chips start operation from reset with a + 32kHz system clock. Boot firmware may activate the main oscillator + and PLL before switching to a faster clock (perhaps that 500 MHz + ARM926 scenario). If you're using JTAG to debug that startup + sequence, you must slow the JTAG clock to sometimes 1 to 4kHz. + After startup completes, JTAG can use a faster clock. + + Consider also debugging a 500MHz ARM926 hand held battery powered + device that enters a low power "deep sleep" mode, at 32kHz CPU + clock, between keystrokes unless it has work to do. When would + that 5 MHz JTAG clock be usable? + + Solution #1 - A special circuit + + In order to make use of this, your CPU, board, and JTAG adapter + must all support the RTCK feature. Not all of them support this; + keep reading! + + The RTCK ("Return TCK") signal in some ARM chips is used to help + with this problem. ARM has a good description of the problem + described at this link: + [checked + 28/nov/2008]. Link title: "How does the JTAG synchronisation logic + work? / how does adaptive clocking work?". + + The nice thing about adaptive clocking is that "battery powered + hand held device example" - the adaptiveness works perfectly all + the time. One can set a break point or halt the system in the deep + power down code, slow step out until the system speeds up. + + Note that adaptive clocking may also need to work at the board + level, when a board-level scan chain has multiple chips. Parallel + clock voting schemes are good way to implement this, both within + and between chips, and can easily be implemented with a CPLD. It's + not difficult to have logic fan a module's input TCK signal out to + each TAP in the scan chain, and then wait until each TAP's RTCK + comes back with the right polarity before changing the output RTCK + signal. Texas Instruments makes some clock voting logic available + for free (with no support) in VHDL form; see + + + Solution #2 - Always works - but may be slower + + Often this is a perfectly acceptable solution. + + In most simple terms: Often the JTAG clock must be 1/10 to 1/12 of + the target clock speed. But what that "magic division" is varies + depending on the chips on your board. ARM rule of thumb Most ARM + based systems require an 6:1 division; ARM11 cores use an 8:1 + division. Xilinx rule of thumb is 1/12 the clock speed. + + Note: most full speed FT2232 based JTAG adapters are limited to a + maximum of 6MHz. The ones using USB high speed chips (FT2232H) + often support faster clock rates (and adaptive clocking). + + You can still debug the 'low power' situations - you just need to + either use a fixed and very slow JTAG clock rate ... or else + manually adjust the clock speed at every step. (Adjusting is + painful and tedious, and is not always practical.) + + It is however easy to "code your way around it" - i.e.: Cheat a + little, have a special debug mode in your application that does a + "high power sleep". If you are careful - 98% of your problems can + be debugged this way. + + Note that on ARM you may need to avoid using the _wait for + interrupt_ operation in your idle loops even if you don't otherwise + change the CPU clock rate. That operation gates the CPU clock, and + thus the JTAG clock; which prevents JTAG access. One consequence + is not being able to 'halt' cores which are executing that _wait + for interrupt_ operation. + + To set the JTAG frequency use the command: + + # Example: 1.234MHz + adapter_khz 1234 + + 2. Win32 Pathnames Why don't backslashes work in Windows paths? + + OpenOCD uses Tcl and a backslash is an escape char. Use { and } + around Windows filenames. + + > echo \a + + > echo {\a} + \a + > echo "\a" + + > + + 3. Missing: cygwin1.dll OpenOCD complains about a missing cygwin1.dll. + + Make sure you have Cygwin installed, or at least a version of + OpenOCD that claims to come with all the necessary DLLs. When + using Cygwin, try launching OpenOCD from the Cygwin shell. + + 4. Breakpoint Issue I'm trying to set a breakpoint using GDB (or a + frontend like Insight or Eclipse), but OpenOCD complains that + "Info: arm7_9_common.c:213 arm7_9_add_breakpoint(): sw breakpoint + requested, but software breakpoints not enabled". + + GDB issues software breakpoints when a normal breakpoint is + requested, or to implement source-line single-stepping. On ARMv4T + systems, like ARM7TDMI, ARM720T or ARM920T, software breakpoints + consume one of the two available hardware breakpoints. + + 5. LPC2000 Flash When erasing or writing LPC2000 on-chip flash, the + operation fails at random. + + Make sure the core frequency specified in the 'flash lpc2000' line + matches the clock at the time you're programming the flash. If + you've specified the crystal's frequency, make sure the PLL is + disabled. If you've specified the full core speed (e.g. 60MHz), + make sure the PLL is enabled. + + 6. Amontec Chameleon When debugging using an Amontec Chameleon in its + JTAG Accelerator configuration, I keep getting "Error: + amt_jtagaccel.c:184 amt_wait_scan_busy(): amt_jtagaccel timed out + while waiting for end of scan, rtck was disabled". + + Make sure your PC's parallel port operates in EPP mode. You might + have to try several settings in your PC BIOS (ECP, EPP, and + different versions of those). + + 7. Data Aborts When debugging with OpenOCD and GDB (plain GDB, + Insight, or Eclipse), I get lots of "Error: arm7_9_common.c:1771 + arm7_9_read_memory(): memory read caused data abort". + + The errors are non-fatal, and are the result of GDB trying to trace + stack frames beyond the last valid frame. It might be possible to + prevent this by setting up a proper "initial" stack frame, if you + happen to know what exactly has to be done, feel free to add this + here. + + Simple: In your startup code - push 8 registers of zeros onto the + stack before calling main(). What GDB is doing is "climbing" the + run time stack by reading various values on the stack using the + standard call frame for the target. GDB keeps going - until one of + 2 things happen #1 an invalid frame is found, or #2 some huge + number of stackframes have been processed. By pushing zeros on the + stack, GDB gracefully stops. + + Debugging Interrupt Service Routines - In your ISR before you call + your C code, do the same - artifically push some zeros onto the + stack, remember to pop them off when the ISR is done. + + Also note: If you have a multi-threaded operating system, they + often do not in the intrest of saving memory waste these few bytes. + Painful... + + 8. JTAG Reset Config I get the following message in the OpenOCD + console (or log file): "Warning: arm7_9_common.c:679 + arm7_9_assert_reset(): srst resets test logic, too". + + This warning doesn't indicate any serious problem, as long as you + don't want to debug your core right out of reset. Your .cfg file + specified 'jtag_reset trst_and_srst srst_pulls_trst' to tell + OpenOCD that either your board, your debugger or your target uC + (e.g. LPC2000) can't assert the two reset signals independently. + With this setup, it's not possible to halt the core right out of + reset, everything else should work fine. + + 9. USB Power When using OpenOCD in conjunction with Amontec JTAGkey + and the Yagarto toolchain (Eclipse, arm-elf-gcc, arm-elf-gdb), the + debugging seems to be unstable. When single-stepping over large + blocks of code, GDB and OpenOCD quit with an error message. Is + there a stability issue with OpenOCD? + + No, this is not a stability issue concerning OpenOCD. Most users + have solved this issue by simply using a self-powered USB hub, + which they connect their Amontec JTAGkey to. Apparently, some + computers do not provide a USB power supply stable enough for the + Amontec JTAGkey to be operated. + + Laptops running on battery have this problem too... + + 10. USB Power When using the Amontec JTAGkey, sometimes OpenOCD + crashes with the following error messages: "Error: ft2232.c:201 + ft2232_read(): FT_Read returned: 4" and "Error: ft2232.c:365 + ft2232_send_and_recv(): couldn't read from FT2232". What does that + mean and what might be the reason for this? + + First of all, the reason might be the USB power supply. Try using + a self-powered hub instead of a direct connection to your computer. + Secondly, the error code 4 corresponds to an FT_IO_ERROR, which + means that the driver for the FTDI USB chip ran into some sort of + error - this points us to a USB problem. + + 11. GDB Disconnects When using the Amontec JTAGkey, sometimes OpenOCD + crashes with the following error message: "Error: gdb_server.c:101 + gdb_get_char(): read: 10054". What does that mean and what might + be the reason for this? + + Error code 10054 corresponds to WSAECONNRESET, which means that the + debugger (GDB) has closed the connection to OpenOCD. This might be + a GDB issue. + + 12. LPC2000 Flash In the configuration file in the section where flash + device configurations are described, there is a parameter for + specifying the clock frequency for LPC2000 internal flash devices + (e.g. 'flash bank $_FLASHNAME lpc2000 0x0 0x40000 0 0 $_TARGETNAME + lpc2000_v1 14746 calc_checksum'), which must be specified in + kilohertz. However, I do have a quartz crystal of a frequency that + contains fractions of kilohertz (e.g. 14,745,600 Hz, i.e. + 14,745.600 kHz). Is it possible to specify real numbers for the + clock frequency? + + No. The clock frequency specified here must be given as an + integral number. However, this clock frequency is used by the + In-Application-Programming (IAP) routines of the LPC2000 family + only, which seems to be very tolerant concerning the given clock + frequency, so a slight difference between the specified clock + frequency and the actual clock frequency will not cause any + trouble. + + 13. Command Order Do I have to keep a specific order for the commands + in the configuration file? + + Well, yes and no. Commands can be given in arbitrary order, yet + the devices listed for the JTAG scan chain must be given in the + right order (jtag newdevice), with the device closest to the + TDO-Pin being listed first. In general, whenever objects of the + same type exist which require an index number, then these objects + must be given in the right order (jtag newtap, targets and flash + banks - a target references a jtag newtap and a flash bank + references a target). + + You can use the "scan_chain" command to verify and display the tap + order. + + Also, some commands can't execute until after 'init' has been + processed. Such commands include 'nand probe' and everything else + that needs to write to controller registers, perhaps for setting up + DRAM and loading it with code. + + 14. JTAG TAP Order Do I have to declare the TAPS in some particular + order? + + Yes; whenever you have more than one, you must declare them in the + same order used by the hardware. + + Many newer devices have multiple JTAG TAPs. For example: ST + Microsystems STM32 chips have two TAPs, a "boundary scan TAP" and + "Cortex-M3" TAP. Example: The STM32 reference manual, Document ID: + RM0008, Section 26.5, Figure 259, page 651/681, the "TDI" pin is + connected to the boundary scan TAP, which then connects to the + Cortex-M3 TAP, which then connects to the TDO pin. + + Thus, the proper order for the STM32 chip is: (1) The Cortex-M3, + then (2) The boundary scan TAP. If your board includes an + additional JTAG chip in the scan chain (for example a Xilinx CPLD + or FPGA) you could place it before or after the STM32 chip in the + chain. For example: + + * OpenOCD_TDI(output) -> STM32 TDI Pin (BS Input) + * STM32 BS TDO (output) -> STM32 Cortex-M3 TDI (input) + * STM32 Cortex-M3 TDO (output) -> SM32 TDO Pin + * STM32 TDO Pin (output) -> Xilinx TDI Pin (input) + * Xilinx TDO Pin -> OpenOCD TDO (input) + + The "jtag device" commands would thus be in the order shown below. + Note: + + * jtag newtap Xilinx tap -irlen ... + * jtag newtap stm32 cpu -irlen ... + * jtag newtap stm32 bs -irlen ... + * # Create the debug target and say where it is + * target create stm32.cpu -chain-position stm32.cpu ... + + 15. SYSCOMP Sometimes my debugging session terminates with an error. + When I look into the log file, I can see these error messages: + Error: arm7_9_common.c:561 arm7_9_execute_sys_speed(): timeout + waiting for SYSCOMP + + TODO. + + +File: openocd.info, Node: Tcl Crash Course, Next: License, Prev: FAQ, Up: Top + +24 Tcl Crash Course +******************* + +Not everyone knows Tcl - this is not intended to be a replacement for +learning Tcl, the intent of this chapter is to give you some idea of how +the Tcl scripts work. + +This chapter is written with two audiences in mind. (1) OpenOCD users +who need to understand a bit more of how Jim-Tcl works so they can do +something useful, and (2) those that want to add a new command to +OpenOCD. + +24.1 Tcl Rule #1 +================ + +There is a famous joke, it goes like this: + 1. Rule #1: The wife is always correct + 2. Rule #2: If you think otherwise, See Rule #1 + +The Tcl equal is this: + + 1. Rule #1: Everything is a string + 2. Rule #2: If you think otherwise, See Rule #1 + +As in the famous joke, the consequences of Rule #1 are profound. Once +you understand Rule #1, you will understand Tcl. + +24.2 Tcl Rule #1b +================= + +There is a second pair of rules. + 1. Rule #1: Control flow does not exist. Only commands + For example: the classic FOR loop or IF statement is not a control + flow item, they are commands, there is no such thing as control + flow in Tcl. + 2. Rule #2: If you think otherwise, See Rule #1 + Actually what happens is this: There are commands that by + convention, act like control flow key words in other languages. + One of those commands is the word "for", another command is "if". + +24.3 Per Rule #1 - All Results are strings +========================================== + +Every Tcl command results in a string. The word "result" is used +deliberatly. No result is just an empty string. Remember: Rule #1 - +Everything is a string + +24.4 Tcl Quoting Operators +========================== + +In life of a Tcl script, there are two important periods of time, the +difference is subtle. + 1. Parse Time + 2. Evaluation Time + +The two key items here are how "quoted things" work in Tcl. Tcl has +three primary quoting constructs, the [square-brackets] the +{curly-braces} and "double-quotes" + +By now you should know $VARIABLES always start with a $DOLLAR sign. +BTW: To set a variable, you actually use the command "set", as in "set +VARNAME VALUE" much like the ancient BASIC langauge "let x = 1" +statement, but without the equal sign. + + * [square-brackets] + [square-brackets] are command substitutions. It operates much like + Unix Shell 'back-ticks'. The result of a [square-bracket] + operation is exactly 1 string. Remember Rule #1 - Everything is a + string. These two statements are roughly identical: + # bash example + X=`date` + echo "The Date is: $X" + # Tcl example + set X [date] + puts "The Date is: $X" + * "double-quoted-things" + "double-quoted-things" are just simply quoted text. $VARIABLES and + [square-brackets] are expanded in place - the result however is + exactly 1 string. Remember Rule #1 - Everything is a string + set x "Dinner" + puts "It is now \"[date]\", $x is in 1 hour" + * {Curly-Braces} + {Curly-Braces} are magic: $VARIABLES and [square-brackets] are + parsed, but are NOT expanded or executed. {Curly-Braces} are like + 'single-quote' operators in BASH shell scripts, with the added + feature: {curly-braces} can be nested, single quotes can not. + {{{this is nested 3 times}}} NOTE: [date] is a bad example; at this + writing, Jim/OpenOCD does not have a date command. + +24.5 Consequences of Rule 1/2/3/4 +================================= + +The consequences of Rule 1 are profound. + +24.5.1 Tokenisation & Execution. +-------------------------------- + +Of course, whitespace, blank lines and #comment lines are handled in the +normal way. + +As a script is parsed, each (multi) line in the script file is tokenised +and according to the quoting rules. After tokenisation, that line is +immedatly executed. + +Multi line statements end with one or more "still-open" {curly-braces} +which - eventually - closes a few lines later. + +24.5.2 Command Execution +------------------------ + +Remember earlier: There are no "control flow" statements in Tcl. +Instead there are COMMANDS that simply act like control flow operators. + +Commands are executed like this: + + 1. Parse the next line into (argc) and (argv[]). + 2. Look up (argv[0]) in a table and call its function. + 3. Repeat until End Of File. + +It sort of works like this: + for(;;){ + ReadAndParse( &argc, &argv ); + + cmdPtr = LookupCommand( argv[0] ); + + (*cmdPtr->Execute)( argc, argv ); + } + +When the command "proc" is parsed (which creates a procedure function) +it gets 3 parameters on the command line. 1 the name of the proc +(function), 2 the list of parameters, and 3 the body of the function. +Not the choice of words: LIST and BODY. The PROC command stores these +items in a table somewhere so it can be found by "LookupCommand()" + +24.5.3 The FOR command +---------------------- + +The most interesting command to look at is the FOR command. In Tcl, the +FOR command is normally implemented in C. Remember, FOR is a command +just like any other command. + +When the ascii text containing the FOR command is parsed, the parser +produces 5 parameter strings, (If in doubt: Refer to Rule #1) they are: + + 0. The ascii text 'for' + 1. The start text + 2. The test expression + 3. The next text + 4. The body text + +Sort of reminds you of "main( int argc, char **argv )" does it not? +Remember Rule #1 - Everything is a string. The key point is this: Often +many of those parameters are in {curly-braces} - thus the variables +inside are not expanded or replaced until later. + +Remember that every Tcl command looks like the classic "main( argc, argv +)" function in C. In JimTCL - they actually look like this: + + int + MyCommand( Jim_Interp *interp, + int *argc, + Jim_Obj * const *argvs ); + +Real Tcl is nearly identical. Although the newer versions have +introduced a byte-code parser and intepreter, but at the core, it still +operates in the same basic way. + +24.5.4 FOR command implementation +--------------------------------- + +To understand Tcl it is perhaps most helpful to see the FOR command. +Remember, it is a COMMAND not a control flow structure. + +In Tcl there are two underlying C helper functions. + +Remember Rule #1 - You are a string. + +The first helper parses and executes commands found in an ascii string. +Commands can be seperated by semicolons, or newlines. While parsing, +variables are expanded via the quoting rules. + +The second helper evaluates an ascii string as a numerical expression +and returns a value. + +Here is an example of how the FOR command could be implemented. The +pseudo code below does not show error handling. + void Execute_AsciiString( void *interp, const char *string ); + + int Evaluate_AsciiExpression( void *interp, const char *string ); + + int + MyForCommand( void *interp, + int argc, + char **argv ) + { + if( argc != 5 ){ + SetResult( interp, "WRONG number of parameters"); + return ERROR; + } + + // argv[0] = the ascii string just like C + + // Execute the start statement. + Execute_AsciiString( interp, argv[1] ); + + // Top of loop test + for(;;){ + i = Evaluate_AsciiExpression(interp, argv[2]); + if( i == 0 ) + break; + + // Execute the body + Execute_AsciiString( interp, argv[3] ); + + // Execute the LOOP part + Execute_AsciiString( interp, argv[4] ); + } + + // Return no error + SetResult( interp, "" ); + return SUCCESS; + } + +Every other command IF, WHILE, FORMAT, PUTS, EXPR, everything works in +the same basic way. + +24.6 OpenOCD Tcl Usage +====================== + +24.6.1 source and find commands +------------------------------- + +Where: In many configuration files +Example: source [find FILENAME] +Remember the parsing rules + 1. The 'find' command is in square brackets, and is executed with the + parameter FILENAME. It should find and return the full path to a + file with that name; it uses an internal search path. The RESULT + is a string, which is substituted into the command line in place of + the bracketed 'find' command. (Don't try to use a FILENAME which + includes the "#" character. That character begins Tcl comments.) + 2. The 'source' command is executed with the resulting filename; it + reads a file and executes as a script. + +24.6.2 format command +--------------------- + +Where: Generally occurs in numerous places. +Tcl has no command like printf(), instead it has format, which is really +more like sprintf(). Example + set x 6 + set y 7 + puts [format "The answer: %d" [expr $x * $y]] + 1. The SET command creates 2 variables, X and Y. + 2. The double [nested] EXPR command performs math + The EXPR command produces numerical result as a string. + Refer to Rule #1 + 3. The format command is executed, producing a single string + Refer to Rule #1. + 4. The PUTS command outputs the text. + +24.6.3 Body or Inlined Text +--------------------------- + +Where: Various TARGET scripts. + #1 Good + proc someproc {} { + ... multiple lines of stuff ... + } + $_TARGETNAME configure -event FOO someproc + #2 Good - no variables + $_TARGETNAME confgure -event foo "this ; that;" + #3 Good Curly Braces + $_TARGETNAME configure -event FOO { + puts "Time: [date]" + } + #4 DANGER DANGER DANGER + $_TARGETNAME configure -event foo "puts \"Time: [date]\"" + 1. The $_TARGETNAME is an OpenOCD variable convention. + $_TARGETNAME represents the last target created, the value changes + each time a new target is created. Remember the parsing rules. + When the ascii text is parsed, the $_TARGETNAME becomes a simple + string, the name of the target which happens to be a TARGET + (object) command. + 2. The 2nd parameter to the '-event' parameter is a TCBODY + There are 4 examples: + 1. The TCLBODY is a simple string that happens to be a proc name + 2. The TCLBODY is several simple commands seperated by semicolons + 3. The TCLBODY is a multi-line {curly-brace} quoted string + 4. The TCLBODY is a string with variables that get expanded. + + In the end, when the target event FOO occurs the TCLBODY is + evaluated. Method #1 and #2 are functionally identical. For + Method #3 and #4 it is more interesting. What is the TCLBODY? + + Remember the parsing rules. In case #3, {curly-braces} mean the + $VARS and [square-brackets] are expanded later, when the EVENT + occurs, and the text is evaluated. In case #4, they are replaced + before the "Target Object Command" is executed. This occurs at the + same time $_TARGETNAME is replaced. In case #4 the date will never + change. {BTW: [date] is a bad example; at this writing, + Jim/OpenOCD does not have a date command} + +24.6.4 Global Variables +----------------------- + +Where: You might discover this when writing your own procs +In simple terms: Inside a PROC, if you need to access a global variable +you must say so. See also "upvar". Example: + proc myproc { } { + set y 0 #Local variable Y + global x #Global variable X + puts [format "X=%d, Y=%d" $x $y] + } + +24.7 Other Tcl Hacks +==================== + +Dynamic variable creation + # Dynamically create a bunch of variables. + for { set x 0 } { $x < 32 } { set x [expr $x + 1]} { + # Create var name + set vn [format "BIT%d" $x] + # Make it a global + global $vn + # Set it. + set $vn [expr (1 << $x)] + } +Dynamic proc/command creation + # One "X" function - 5 uart functions. + foreach who {A B C D E} + proc [format "show_uart%c" $who] { } "show_UARTx $who" + } + + +File: openocd.info, Node: License, Next: OpenOCD Concept Index, Prev: Tcl Crash Course, Up: Top + +Appendix A The GNU Free Documentation License. +********************************************** + + Version 1.2, November 2002 + + Copyright (C) 2000,2001,2002 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. + + 0. PREAMBLE + + The purpose of this License is to make a manual, textbook, or other + functional and useful document "free" in the sense of freedom: to + assure everyone the effective freedom to copy and redistribute it, + with or without modifying it, either commercially or + noncommercially. Secondarily, this License preserves for the + author and publisher a way to get credit for their work, while not + being considered responsible for modifications made by others. + + This License is a kind of "copyleft", which means that derivative + works of the document must themselves be free in the same sense. + It complements the GNU General Public License, which is a copyleft + license designed for free software. + + We have designed this License in order to use it for manuals for + free software, because free software needs free documentation: a + free program should come with manuals providing the same freedoms + that the software does. But this License is not limited to + software manuals; it can be used for any textual work, regardless + of subject matter or whether it is published as a printed book. We + recommend this License principally for works whose purpose is + instruction or reference. + + 1. APPLICABILITY AND DEFINITIONS + + This License applies to any manual or other work, in any medium, + that contains a notice placed by the copyright holder saying it can + be distributed under the terms of this License. Such a notice + grants a world-wide, royalty-free license, unlimited in duration, + to use that work under the conditions stated herein. The + "Document", below, refers to any such manual or work. Any member + of the public is a licensee, and is addressed as "you". You accept + the license if you copy, modify or distribute the work in a way + requiring permission under copyright law. + + A "Modified Version" of the Document means any work containing the + Document or a portion of it, either copied verbatim, or with + modifications and/or translated into another language. + + A "Secondary Section" is a named appendix or a front-matter section + of the Document that deals exclusively with the relationship of the + publishers or authors of the Document to the Document's overall + subject (or to related matters) and contains nothing that could + fall directly within that overall subject. (Thus, if the Document + is in part a textbook of mathematics, a Secondary Section may not + explain any mathematics.) The relationship could be a matter of + historical connection with the subject or with related matters, or + of legal, commercial, philosophical, ethical or political position + regarding them. + + The "Invariant Sections" are certain Secondary Sections whose + titles are designated, as being those of Invariant Sections, in the + notice that says that the Document is released under this License. + If a section does not fit the above definition of Secondary then it + is not allowed to be designated as Invariant. The Document may + contain zero Invariant Sections. If the Document does not identify + any Invariant Sections then there are none. + + The "Cover Texts" are certain short passages of text that are + listed, as Front-Cover Texts or Back-Cover Texts, in the notice + that says that the Document is released under this License. A + Front-Cover Text may be at most 5 words, and a Back-Cover Text may + be at most 25 words. + + A "Transparent" copy of the Document means a machine-readable copy, + represented in a format whose specification is available to the + general public, that is suitable for revising the document + straightforwardly with generic text editors or (for images composed + of pixels) generic paint programs or (for drawings) some widely + available drawing editor, and that is suitable for input to text + formatters or for automatic translation to a variety of formats + suitable for input to text formatters. A copy made in an otherwise + Transparent file format whose markup, or absence of markup, has + been arranged to thwart or discourage subsequent modification by + readers is not Transparent. An image format is not Transparent if + used for any substantial amount of text. A copy that is not + "Transparent" is called "Opaque". + + Examples of suitable formats for Transparent copies include plain + ASCII without markup, Texinfo input format, LaTeX input format, + SGML or XML using a publicly available DTD, and standard-conforming + simple HTML, PostScript or PDF designed for human modification. + Examples of transparent image formats include PNG, XCF and JPG. + Opaque formats include proprietary formats that can be read and + edited only by proprietary word processors, SGML or XML for which + the DTD and/or processing tools are not generally available, and + the machine-generated HTML, PostScript or PDF produced by some word + processors for output purposes only. + + The "Title Page" means, for a printed book, the title page itself, + plus such following pages as are needed to hold, legibly, the + material this License requires to appear in the title page. For + works in formats which do not have any title page as such, "Title + Page" means the text near the most prominent appearance of the + work's title, preceding the beginning of the body of the text. + + A section "Entitled XYZ" means a named subunit of the Document + whose title either is precisely XYZ or contains XYZ in parentheses + following text that translates XYZ in another language. (Here XYZ + stands for a specific section name mentioned below, such as + "Acknowledgements", "Dedications", "Endorsements", or "History".) + To "Preserve the Title" of such a section when you modify the + Document means that it remains a section "Entitled XYZ" according + to this definition. + + The Document may include Warranty Disclaimers next to the notice + which states that this License applies to the Document. These + Warranty Disclaimers are considered to be included by reference in + this License, but only as regards disclaiming warranties: any other + implication that these Warranty Disclaimers may have is void and + has no effect on the meaning of this License. + + 2. VERBATIM COPYING + + You may copy and distribute the Document in any medium, either + commercially or noncommercially, provided that this License, the + copyright notices, and the license notice saying this License + applies to the Document are reproduced in all copies, and that you + add no other conditions whatsoever to those of this License. You + may not use technical measures to obstruct or control the reading + or further copying of the copies you make or distribute. However, + you may accept compensation in exchange for copies. If you + distribute a large enough number of copies you must also follow the + conditions in section 3. + + You may also lend copies, under the same conditions stated above, + and you may publicly display copies. + + 3. COPYING IN QUANTITY + + If you publish printed copies (or copies in media that commonly + have printed covers) of the Document, numbering more than 100, and + the Document's license notice requires Cover Texts, you must + enclose the copies in covers that carry, clearly and legibly, all + these Cover Texts: Front-Cover Texts on the front cover, and + Back-Cover Texts on the back cover. Both covers must also clearly + and legibly identify you as the publisher of these copies. The + front cover must present the full title with all words of the title + equally prominent and visible. You may add other material on the + covers in addition. Copying with changes limited to the covers, as + long as they preserve the title of the Document and satisfy these + conditions, can be treated as verbatim copying in other respects. + + If the required texts for either cover are too voluminous to fit + legibly, you should put the first ones listed (as many as fit + reasonably) on the actual cover, and continue the rest onto + adjacent pages. + + If you publish or distribute Opaque copies of the Document + numbering more than 100, you must either include a machine-readable + Transparent copy along with each Opaque copy, or state in or with + each Opaque copy a computer-network location from which the general + network-using public has access to download using public-standard + network protocols a complete Transparent copy of the Document, free + of added material. If you use the latter option, you must take + reasonably prudent steps, when you begin distribution of Opaque + copies in quantity, to ensure that this Transparent copy will + remain thus accessible at the stated location until at least one + year after the last time you distribute an Opaque copy (directly or + through your agents or retailers) of that edition to the public. + + It is requested, but not required, that you contact the authors of + the Document well before redistributing any large number of copies, + to give them a chance to provide you with an updated version of the + Document. + + 4. MODIFICATIONS + + You may copy and distribute a Modified Version of the Document + under the conditions of sections 2 and 3 above, provided that you + release the Modified Version under precisely this License, with the + Modified Version filling the role of the Document, thus licensing + distribution and modification of the Modified Version to whoever + possesses a copy of it. In addition, you must do these things in + the Modified Version: + + A. Use in the Title Page (and on the covers, if any) a title + distinct from that of the Document, and from those of previous + versions (which should, if there were any, be listed in the + History section of the Document). You may use the same title + as a previous version if the original publisher of that + version gives permission. + + B. List on the Title Page, as authors, one or more persons or + entities responsible for authorship of the modifications in + the Modified Version, together with at least five of the + principal authors of the Document (all of its principal + authors, if it has fewer than five), unless they release you + from this requirement. + + C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. + + D. Preserve all the copyright notices of the Document. + + E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. + + F. Include, immediately after the copyright notices, a license + notice giving the public permission to use the Modified + Version under the terms of this License, in the form shown in + the Addendum below. + + G. Preserve in that license notice the full lists of Invariant + Sections and required Cover Texts given in the Document's + license notice. + + H. Include an unaltered copy of this License. + + I. Preserve the section Entitled "History", Preserve its Title, + and add to it an item stating at least the title, year, new + authors, and publisher of the Modified Version as given on the + Title Page. If there is no section Entitled "History" in the + Document, create one stating the title, year, authors, and + publisher of the Document as given on its Title Page, then add + an item describing the Modified Version as stated in the + previous sentence. + + J. Preserve the network location, if any, given in the Document + for public access to a Transparent copy of the Document, and + likewise the network locations given in the Document for + previous versions it was based on. These may be placed in the + "History" section. You may omit a network location for a work + that was published at least four years before the Document + itself, or if the original publisher of the version it refers + to gives permission. + + K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the section + all the substance and tone of each of the contributor + acknowledgements and/or dedications given therein. + + L. Preserve all the Invariant Sections of the Document, unaltered + in their text and in their titles. Section numbers or the + equivalent are not considered part of the section titles. + + M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. + + N. Do not retitle any existing section to be Entitled + "Endorsements" or to conflict in title with any Invariant + Section. + + O. Preserve any Warranty Disclaimers. + + If the Modified Version includes new front-matter sections or + appendices that qualify as Secondary Sections and contain no + material copied from the Document, you may at your option designate + some or all of these sections as invariant. To do this, add their + titles to the list of Invariant Sections in the Modified Version's + license notice. These titles must be distinct from any other + section titles. + + You may add a section Entitled "Endorsements", provided it contains + nothing but endorsements of your Modified Version by various + parties--for example, statements of peer review or that the text + has been approved by an organization as the authoritative + definition of a standard. + + You may add a passage of up to five words as a Front-Cover Text, + and a passage of up to 25 words as a Back-Cover Text, to the end of + the list of Cover Texts in the Modified Version. Only one passage + of Front-Cover Text and one of Back-Cover Text may be added by (or + through arrangements made by) any one entity. If the Document + already includes a cover text for the same cover, previously added + by you or by arrangement made by the same entity you are acting on + behalf of, you may not add another; but you may replace the old + one, on explicit permission from the previous publisher that added + the old one. + + The author(s) and publisher(s) of the Document do not by this + License give permission to use their names for publicity for or to + assert or imply endorsement of any Modified Version. + + 5. COMBINING DOCUMENTS + + You may combine the Document with other documents released under + this License, under the terms defined in section 4 above for + modified versions, provided that you include in the combination all + of the Invariant Sections of all of the original documents, + unmodified, and list them all as Invariant Sections of your + combined work in its license notice, and that you preserve all + their Warranty Disclaimers. + + The combined work need only contain one copy of this License, and + multiple identical Invariant Sections may be replaced with a single + copy. If there are multiple Invariant Sections with the same name + but different contents, make the title of each such section unique + by adding at the end of it, in parentheses, the name of the + original author or publisher of that section if known, or else a + unique number. Make the same adjustment to the section titles in + the list of Invariant Sections in the license notice of the + combined work. + + In the combination, you must combine any sections Entitled + "History" in the various original documents, forming one section + Entitled "History"; likewise combine any sections Entitled + "Acknowledgements", and any sections Entitled "Dedications". You + must delete all sections Entitled "Endorsements." + + 6. COLLECTIONS OF DOCUMENTS + + You may make a collection consisting of the Document and other + documents released under this License, and replace the individual + copies of this License in the various documents with a single copy + that is included in the collection, provided that you follow the + rules of this License for verbatim copying of each of the documents + in all other respects. + + You may extract a single document from such a collection, and + distribute it individually under this License, provided you insert + a copy of this License into the extracted document, and follow this + License in all other respects regarding verbatim copying of that + document. + + 7. AGGREGATION WITH INDEPENDENT WORKS + + A compilation of the Document or its derivatives with other + separate and independent documents or works, in or on a volume of a + storage or distribution medium, is called an "aggregate" if the + copyright resulting from the compilation is not used to limit the + legal rights of the compilation's users beyond what the individual + works permit. When the Document is included in an aggregate, this + License does not apply to the other works in the aggregate which + are not themselves derivative works of the Document. + + If the Cover Text requirement of section 3 is applicable to these + copies of the Document, then if the Document is less than one half + of the entire aggregate, the Document's Cover Texts may be placed + on covers that bracket the Document within the aggregate, or the + electronic equivalent of covers if the Document is in electronic + form. Otherwise they must appear on printed covers that bracket + the whole aggregate. + + 8. TRANSLATION + + Translation is considered a kind of modification, so you may + distribute translations of the Document under the terms of section + 4. Replacing Invariant Sections with translations requires special + permission from their copyright holders, but you may include + translations of some or all Invariant Sections in addition to the + original versions of these Invariant Sections. You may include a + translation of this License, and all the license notices in the + Document, and any Warranty Disclaimers, provided that you also + include the original English version of this License and the + original versions of those notices and disclaimers. In case of a + disagreement between the translation and the original version of + this License or a notice or disclaimer, the original version will + prevail. + + If a section in the Document is Entitled "Acknowledgements", + "Dedications", or "History", the requirement (section 4) to + Preserve its Title (section 1) will typically require changing the + actual title. + + 9. TERMINATION + + You may not copy, modify, sublicense, or distribute the Document + except as expressly provided for under this License. Any other + attempt to copy, modify, sublicense or distribute the Document 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. + + 10. FUTURE REVISIONS OF THIS LICENSE + + The Free Software Foundation may publish new, revised versions of + the GNU Free Documentation 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. See + . + + Each version of the License is given a distinguishing version + number. If the Document specifies that a particular numbered + version of this License "or any later version" applies to it, you + have the option of following the terms and conditions either of + that specified version or of any later version that has been + published (not as a draft) by the Free Software Foundation. If the + Document does not specify a version number of this License, you may + choose any version ever published (not as a draft) by the Free + Software Foundation. + +ADDENDUM: How to use this License for your documents +==================================================== + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and license +notices just after the title page: + + Copyright (C) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with + the Front-Cover Texts being LIST, and with the Back-Cover Texts + being LIST. + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of free +software license, such as the GNU General Public License, to permit +their use in free software. + + +File: openocd.info, Node: OpenOCD Concept Index, Next: Command and Driver Index, Prev: License, Up: Top + +OpenOCD Concept Index +********************* + +[index] +* Menu: + +* about: About. (line 6) +* adaptive clocking: Debug Adapter Configuration. + (line 661) +* adaptive clocking <1>: FAQ. (line 6) +* Architecture Specific Commands: Architecture and Core Commands. + (line 6) +* ARM: Architecture and Core Commands. + (line 244) +* ARM semihosting: OpenOCD Project Setup. + (line 313) +* ARM semihosting <1>: Architecture and Core Commands. + (line 285) +* ARM11: Architecture and Core Commands. + (line 585) +* ARM7: Architecture and Core Commands. + (line 305) +* ARM720T: Architecture and Core Commands. + (line 343) +* ARM9: Architecture and Core Commands. + (line 305) +* ARM9 <1>: Architecture and Core Commands. + (line 359) +* ARM920T: Architecture and Core Commands. + (line 379) +* ARM926ej-s: Architecture and Core Commands. + (line 414) +* ARM966E: Architecture and Core Commands. + (line 428) +* ARMv4: Architecture and Core Commands. + (line 298) +* ARMv5: Architecture and Core Commands. + (line 298) +* ARMv6: Architecture and Core Commands. + (line 581) +* ARMv7: Architecture and Core Commands. + (line 618) +* at91sam3: Flash Commands. (line 290) +* at91sam4: Flash Commands. (line 345) +* autoprobe: TAP Declaration. (line 316) +* board config file: Config File Guidelines. + (line 256) +* breakpoint: General Commands. (line 309) +* CFI: Flash Commands. (line 210) +* command line options: Running. (line 6) +* commands: General Commands. (line 6) +* Common Flash Interface: Flash Commands. (line 210) +* config command: Daemon Configuration. + (line 13) +* config file, board: Config File Guidelines. + (line 256) +* config file, interface: Debug Adapter Configuration. + (line 6) +* config file, overview: OpenOCD Project Setup. + (line 138) +* config file, target: Config File Guidelines. + (line 483) +* config file, user: OpenOCD Project Setup. + (line 138) +* configuration stage: Daemon Configuration. + (line 13) +* Connecting to GDB: GDB and OpenOCD. (line 27) +* Core Specific Commands: Architecture and Core Commands. + (line 6) +* Cortex-M: Architecture and Core Commands. + (line 653) +* CPU type: CPU Configuration. (line 82) +* CPU variant: CPU Configuration. (line 82) +* DAP: Architecture and Core Commands. + (line 622) +* DCC: Architecture and Core Commands. + (line 321) +* DCC <1>: Architecture and Core Commands. + (line 703) +* Debug Access Port: Architecture and Core Commands. + (line 622) +* developers: Developers. (line 6) +* directory search: Running. (line 6) +* disassemble: Architecture and Core Commands. + (line 255) +* dongles: Debug Adapter Hardware. + (line 6) +* dotted name: TAP Declaration. (line 97) +* ETB: Architecture and Core Commands. + (line 14) +* ETM: Architecture and Core Commands. + (line 14) +* event, reset-init: Config File Guidelines. + (line 372) +* events: Reset Configuration. (line 226) +* events <1>: TAP Declaration. (line 215) +* events <2>: CPU Configuration. (line 363) +* faq: FAQ. (line 6) +* flash configuration: Flash Commands. (line 36) +* flash erasing: Flash Commands. (line 87) +* flash programming: Flash Commands. (line 87) +* flash protection: Flash Commands. (line 178) +* flash reading: Flash Commands. (line 87) +* flash writing: Flash Commands. (line 87) +* FPGA: PLD/FPGA Commands. (line 6) +* FTDI: Debug Adapter Hardware. + (line 6) +* GDB: Daemon Configuration. + (line 131) +* GDB <1>: GDB and OpenOCD. (line 6) +* GDB configuration: Daemon Configuration. + (line 131) +* GDB server: Daemon Configuration. + (line 91) +* GDB target: CPU Configuration. (line 6) +* halt: General Commands. (line 77) +* image dumping: General Commands. (line 261) +* image loading: General Commands. (line 261) +* initialization: Daemon Configuration. + (line 6) +* init_board procedure: Config File Guidelines. + (line 437) +* init_targets procedure: Config File Guidelines. + (line 706) +* interface config file: Debug Adapter Configuration. + (line 6) +* Jim-Tcl: About Jim-Tcl. (line 6) +* jrc: TAP Declaration. (line 253) +* JTAG: About. (line 15) +* JTAG <1>: Debug Adapter Configuration. + (line 580) +* JTAG autoprobe: TAP Declaration. (line 316) +* JTAG Commands: JTAG Commands. (line 6) +* JTAG Route Controller: TAP Declaration. (line 253) +* libdcc: Architecture and Core Commands. + (line 703) +* Linux-ARM DCC support: Architecture and Core Commands. + (line 703) +* logfile: Running. (line 6) +* lpcspifi: Flash Commands. (line 241) +* memory access: General Commands. (line 228) +* message level: General Commands. (line 54) +* mFlash commands: Flash Commands. (line 839) +* mFlash Configuration: Flash Commands. (line 823) +* NAND: NAND Flash Commands. (line 6) +* NAND configuration: NAND Flash Commands. (line 61) +* NAND erasing: NAND Flash Commands. (line 141) +* NAND other commands: NAND Flash Commands. (line 232) +* NAND programming: NAND Flash Commands. (line 141) +* NAND programming <1>: NAND Flash Commands. (line 154) +* NAND programming <2>: NAND Flash Commands. (line 207) +* NAND reading: NAND Flash Commands. (line 108) +* NAND verification: NAND Flash Commands. (line 207) +* NAND writing: NAND Flash Commands. (line 154) +* NXP SPI Flash Interface: Flash Commands. (line 241) +* object command: CPU Configuration. (line 257) +* PLD: PLD/FPGA Commands. (line 6) +* port: Daemon Configuration. + (line 81) +* printer port: Debug Adapter Hardware. + (line 6) +* profiling: General Commands. (line 341) +* Programming using GDB: GDB and OpenOCD. (line 126) +* reset: General Commands. (line 77) +* Reset Configuration: Reset Configuration. (line 6) +* reset-init handler: Config File Guidelines. + (line 372) +* RTCK: Debug Adapter Hardware. + (line 6) +* RTCK <1>: Debug Adapter Configuration. + (line 661) +* RTCK <2>: FAQ. (line 6) +* scan chain: TAP Declaration. (line 28) +* security: Daemon Configuration. + (line 81) +* Serial Peripheral Interface: Debug Adapter Configuration. + (line 604) +* Serial Vector Format: Boundary Scan Commands. + (line 13) +* Serial Wire Debug: Debug Adapter Configuration. + (line 589) +* server: Daemon Configuration. + (line 81) +* SMI: Flash Commands. (line 258) +* SMP: Config File Guidelines. + (line 610) +* SMP <1>: GDB and OpenOCD. (line 164) +* SPI: Debug Adapter Configuration. + (line 604) +* SPIFI: Flash Commands. (line 241) +* STMicroelectronics Serial Memory Interface: Flash Commands. (line 258) +* stmsmi: Flash Commands. (line 258) +* str9xpec: Flash Commands. (line 741) +* SVF: Boundary Scan Commands. + (line 13) +* SWD: Debug Adapter Configuration. + (line 589) +* TAP: About. (line 15) +* TAP configuration: TAP Declaration. (line 6) +* TAP declaration: TAP Declaration. (line 6) +* TAP events: TAP Declaration. (line 215) +* TAP naming convention: TAP Declaration. (line 128) +* TAP state names: JTAG Commands. (line 142) +* target config file: Config File Guidelines. + (line 483) +* target events: CPU Configuration. (line 363) +* target initialization: General Commands. (line 77) +* target type: CPU Configuration. (line 82) +* target, current: CPU Configuration. (line 18) +* target, list: CPU Configuration. (line 18) +* tcl: About Jim-Tcl. (line 6) +* Tcl: Tcl Crash Course. (line 6) +* Tcl Scripting API: Tcl Scripting API. (line 6) +* Tcl scripts: Tcl Scripting API. (line 5) +* TCP port: Daemon Configuration. + (line 81) +* TFTP: TFTP. (line 6) +* tracing: Architecture and Core Commands. + (line 14) +* tracing <1>: Architecture and Core Commands. + (line 703) +* translation: Config File Guidelines. + (line 787) +* Transport: Debug Adapter Configuration. + (line 563) +* USB Adapter: Debug Adapter Hardware. + (line 6) +* user config file: OpenOCD Project Setup. + (line 138) +* variable names: Config File Guidelines. + (line 340) +* vector_catch: OpenOCD Project Setup. + (line 212) +* vector_catch <1>: Architecture and Core Commands. + (line 364) +* vector_catch <2>: Architecture and Core Commands. + (line 554) +* vector_catch <3>: Architecture and Core Commands. + (line 607) +* vector_catch <4>: Architecture and Core Commands. + (line 672) +* vector_table: Architecture and Core Commands. + (line 569) +* watchpoint: General Commands. (line 309) +* wiggler: Debug Adapter Hardware. + (line 6) +* Xilinx Serial Vector Format: Boundary Scan Commands. + (line 25) +* XScale: Architecture and Core Commands. + (line 442) +* XSVF: Boundary Scan Commands. + (line 25) +* zy1000: Debug Adapter Hardware. + (line 6) + + +File: openocd.info, Node: Command and Driver Index, Prev: OpenOCD Concept Index, Up: Top + +Command and Driver Index +************************ + +[index] +* Menu: + +* $target_name arp_examine: CPU Configuration. (line 282) +* $target_name arp_halt: CPU Configuration. (line 283) +* $target_name arp_poll: CPU Configuration. (line 284) +* $target_name arp_reset: CPU Configuration. (line 285) +* $target_name arp_waitstate: CPU Configuration. (line 286) +* $target_name array2mem: CPU Configuration. (line 291) +* $target_name cget: CPU Configuration. (line 309) +* $target_name configure: CPU Configuration. (line 206) +* $target_name curstate: CPU Configuration. (line 332) +* $target_name eventlist: CPU Configuration. (line 337) +* $target_name invoke-event: CPU Configuration. (line 341) +* $target_name mdb: CPU Configuration. (line 348) +* $target_name mdh: CPU Configuration. (line 347) +* $target_name mdw: CPU Configuration. (line 346) +* $target_name mem2array: CPU Configuration. (line 292) +* $target_name mwb: CPU Configuration. (line 356) +* $target_name mwh: CPU Configuration. (line 355) +* $target_name mww: CPU Configuration. (line 354) +* adapter_khz: Debug Adapter Configuration. + (line 644) +* adapter_name: Debug Adapter Configuration. + (line 54) +* adapter_nsrst_assert_width: Reset Configuration. (line 121) +* adapter_nsrst_delay: Reset Configuration. (line 126) +* add_script_search_dir: General Commands. (line 71) +* aduc702x: Flash Commands. (line 280) +* amt_jtagaccel: Debug Adapter Configuration. + (line 63) +* append_file: General Commands. (line 189) +* arm core_state: Architecture and Core Commands. + (line 248) +* arm disassemble: Architecture and Core Commands. + (line 254) +* arm mcr: Architecture and Core Commands. + (line 268) +* arm mrc: Architecture and Core Commands. + (line 274) +* arm reg: Architecture and Core Commands. + (line 280) +* arm semihosting: Architecture and Core Commands. + (line 284) +* arm-jtag-ew: Debug Adapter Configuration. + (line 76) +* arm11 memwrite burst: Architecture and Core Commands. + (line 585) +* arm11 memwrite error_fatal: Architecture and Core Commands. + (line 595) +* arm11 step_irq_enable: Architecture and Core Commands. + (line 601) +* arm11 vcr: Architecture and Core Commands. + (line 606) +* arm720t cp15: Architecture and Core Commands. + (line 348) +* arm7_9 dbgrq: Architecture and Core Commands. + (line 310) +* arm7_9 dcc_downloads: Architecture and Core Commands. + (line 320) +* arm7_9 fast_memory_access: Architecture and Core Commands. + (line 331) +* arm9 vector_catch: Architecture and Core Commands. + (line 363) +* arm920t cache_info: Architecture and Core Commands. + (line 384) +* arm920t cp15: Architecture and Core Commands. + (line 389) +* arm920t cp15i: Architecture and Core Commands. + (line 395) +* arm920t read_cache: Architecture and Core Commands. + (line 405) +* arm920t read_mmu: Architecture and Core Commands. + (line 408) +* arm926ejs cache_info: Architecture and Core Commands. + (line 422) +* arm966e cp15: Architecture and Core Commands. + (line 432) +* armjtagew_info: Debug Adapter Configuration. + (line 80) +* at91rm9200: Debug Adapter Configuration. + (line 83) +* at91sam3: Flash Commands. (line 289) +* at91sam3 gpnvm: Flash Commands. (line 321) +* at91sam3 gpnvm clear: Flash Commands. (line 322) +* at91sam3 gpnvm set: Flash Commands. (line 323) +* at91sam3 gpnvm show: Flash Commands. (line 324) +* at91sam3 info: Flash Commands. (line 330) +* at91sam3 slowclk: Flash Commands. (line 340) +* at91sam4: Flash Commands. (line 344) +* at91sam7: Flash Commands. (line 349) +* at91sam7 gpnvm: Flash Commands. (line 382) +* at91sam9: NAND Flash Commands. (line 273) +* at91sam9 ale: NAND Flash Commands. (line 287) +* at91sam9 ce: NAND Flash Commands. (line 298) +* at91sam9 cle: NAND Flash Commands. (line 284) +* at91sam9 rdy_busy: NAND Flash Commands. (line 293) +* avr: Flash Commands. (line 390) +* bp: General Commands. (line 313) +* cat: General Commands. (line 194) +* cfi: Flash Commands. (line 209) +* cortex_m maskisr: Architecture and Core Commands. + (line 653) +* cortex_m reset_config: Architecture and Core Commands. + (line 687) +* cortex_m vector_catch: Architecture and Core Commands. + (line 671) +* cp: General Commands. (line 197) +* dap apcsw: Architecture and Core Commands. + (line 646) +* dap apid: Architecture and Core Commands. + (line 626) +* dap apsel: Architecture and Core Commands. + (line 630) +* dap baseaddr: Architecture and Core Commands. + (line 633) +* dap info: Architecture and Core Commands. + (line 637) +* dap memaccess: Architecture and Core Commands. + (line 641) +* davinci: NAND Flash Commands. (line 304) +* debug_level: General Commands. (line 53) +* drscan: JTAG Commands. (line 42) +* dummy: Debug Adapter Configuration. + (line 87) +* dummy <1>: Architecture and Core Commands. + (line 190) +* dump_image: General Commands. (line 261) +* echo: General Commands. (line 62) +* efm32: Flash Commands. (line 394) +* ep93xx: Debug Adapter Configuration. + (line 90) +* etb: Architecture and Core Commands. + (line 198) +* etb config: Architecture and Core Commands. + (line 201) +* etb trigger_percent: Architecture and Core Commands. + (line 204) +* etm analyze: Architecture and Core Commands. + (line 166) +* etm config: Architecture and Core Commands. + (line 63) +* etm dump: Architecture and Core Commands. + (line 170) +* etm image: Architecture and Core Commands. + (line 173) +* etm info: Architecture and Core Commands. + (line 89) +* etm load: Architecture and Core Commands. + (line 176) +* etm start: Architecture and Core Commands. + (line 179) +* etm status: Architecture and Core Commands. + (line 95) +* etm stop: Architecture and Core Commands. + (line 182) +* etm tracemode: Architecture and Core Commands. + (line 100) +* etm trigger_debug: Architecture and Core Commands. + (line 119) +* etm_dummy config: Architecture and Core Commands. + (line 195) +* exit: General Commands. (line 30) +* fast_load: General Commands. (line 265) +* fast_load_image: General Commands. (line 269) +* flash bank: Flash Commands. (line 36) +* flash banks: Flash Commands. (line 67) +* flash erase_address: Flash Commands. (line 120) +* flash erase_check: Flash Commands. (line 178) +* flash erase_sector: Flash Commands. (line 114) +* flash fillb: Flash Commands. (line 133) +* flash fillh: Flash Commands. (line 132) +* flash fillw: Flash Commands. (line 131) +* flash info: Flash Commands. (line 182) +* flash list: Flash Commands. (line 72) +* flash probe: Flash Commands. (line 77) +* flash protect: Flash Commands. (line 187) +* flash write_bank: Flash Commands. (line 143) +* flash write_image: Flash Commands. (line 148) +* flush_count: JTAG Commands. (line 70) +* fm3: Flash Commands. (line 729) +* ft2232: Debug Adapter Configuration. + (line 94) +* ft2232_channel: Debug Adapter Configuration. + (line 171) +* ft2232_device_desc: Debug Adapter Configuration. + (line 104) +* ft2232_latency: Debug Adapter Configuration. + (line 160) +* ft2232_layout: Debug Adapter Configuration. + (line 118) +* ft2232_serial: Debug Adapter Configuration. + (line 110) +* ft2232_vid_pid: Debug Adapter Configuration. + (line 154) +* ftdi: Debug Adapter Configuration. + (line 183) +* ftdi_channel: Debug Adapter Configuration. + (line 241) +* ftdi_device_desc: Debug Adapter Configuration. + (line 228) +* ftdi_layout_init: Debug Adapter Configuration. + (line 246) +* ftdi_layout_signal: Debug Adapter Configuration. + (line 256) +* ftdi_serial: Debug Adapter Configuration. + (line 233) +* ftdi_set_signal: Debug Adapter Configuration. + (line 285) +* ftdi_vid_pid: Debug Adapter Configuration. + (line 222) +* gdb_breakpoint_override: Daemon Configuration. + (line 136) +* gdb_flash_program: Daemon Configuration. + (line 143) +* gdb_memory_map: Daemon Configuration. + (line 147) +* gdb_port: Daemon Configuration. + (line 90) +* gdb_report_data_abort: Daemon Configuration. + (line 155) +* gw16012: Debug Adapter Configuration. + (line 355) +* halt: General Commands. (line 115) +* help: General Commands. (line 33) +* hla: Debug Adapter Configuration. + (line 522) +* hla_device_desc: Debug Adapter Configuration. + (line 529) +* hla_layout: Debug Adapter Configuration. + (line 535) +* hla_serial: Debug Adapter Configuration. + (line 532) +* hla_vid_pid: Debug Adapter Configuration. + (line 538) +* init: Daemon Configuration. + (line 47) +* init_reset: Reset Configuration. (line 257) +* interface: Debug Adapter Configuration. + (line 42) +* interface transports: Debug Adapter Configuration. + (line 48) +* interface_list: Debug Adapter Configuration. + (line 45) +* ip: General Commands. (line 200) +* irscan: JTAG Commands. (line 81) +* jlink: Debug Adapter Configuration. + (line 365) +* jlink caps: Debug Adapter Configuration. + (line 382) +* jlink config: Debug Adapter Configuration. + (line 390) +* jlink config ip: Debug Adapter Configuration. + (line 398) +* jlink config kickstart: Debug Adapter Configuration. + (line 392) +* jlink config mac_address: Debug Adapter Configuration. + (line 395) +* jlink config reset: Debug Adapter Configuration. + (line 405) +* jlink config save: Debug Adapter Configuration. + (line 407) +* jlink config usb_address: Debug Adapter Configuration. + (line 402) +* jlink hw_jtag: Debug Adapter Configuration. + (line 387) +* jlink info: Debug Adapter Configuration. + (line 384) +* jlink pid: Debug Adapter Configuration. + (line 410) +* jtag arp_init: Reset Configuration. (line 275) +* jtag arp_init-reset: Reset Configuration. (line 285) +* jtag cget: TAP Declaration. (line 201) +* jtag configure: TAP Declaration. (line 202) +* jtag names: TAP Declaration. (line 80) +* jtag newtap: TAP Declaration. (line 120) +* jtag tapdisable: TAP Declaration. (line 296) +* jtag tapenable: TAP Declaration. (line 301) +* jtag tapisenabled: TAP Declaration. (line 306) +* jtag_init: Daemon Configuration. + (line 65) +* jtag_ntrst_assert_width: Reset Configuration. (line 133) +* jtag_ntrst_delay: Reset Configuration. (line 138) +* jtag_rclk: Debug Adapter Configuration. + (line 660) +* jtag_reset: JTAG Commands. (line 98) +* load_image: General Commands. (line 280) +* log_output: General Commands. (line 67) +* lpc2000: Flash Commands. (line 403) +* lpc2000 part_id: Flash Commands. (line 438) +* lpc288x: Flash Commands. (line 442) +* lpc2900: Flash Commands. (line 450) +* lpc2900 password: Flash Commands. (line 506) +* lpc2900 read_custom: Flash Commands. (line 495) +* lpc2900 secure_jtag: Flash Commands. (line 541) +* lpc2900 secure_sector: Flash Commands. (line 527) +* lpc2900 signature: Flash Commands. (line 486) +* lpc2900 write_custom: Flash Commands. (line 516) +* lpc3180: NAND Flash Commands. (line 317) +* lpc3180 select: NAND Flash Commands. (line 320) +* lpcspifi: Flash Commands. (line 240) +* ls: General Commands. (line 203) +* mac: General Commands. (line 206) +* mdb: General Commands. (line 240) +* mdh: General Commands. (line 239) +* mdw: General Commands. (line 238) +* meminfo: General Commands. (line 209) +* mflash bank: Flash Commands. (line 823) +* mflash config boot: Flash Commands. (line 846) +* mflash config pll: Flash Commands. (line 839) +* mflash config storage: Flash Commands. (line 850) +* mflash dump: Flash Commands. (line 854) +* mflash probe: Flash Commands. (line 858) +* mflash write: Flash Commands. (line 861) +* mwb: General Commands. (line 251) +* mwh: General Commands. (line 250) +* mww: General Commands. (line 249) +* mx3: NAND Flash Commands. (line 330) +* mxc: NAND Flash Commands. (line 334) +* mxc biswap: NAND Flash Commands. (line 342) +* nand check_bad_blocks: NAND Flash Commands. (line 232) +* nand device: NAND Flash Commands. (line 64) +* nand dump: NAND Flash Commands. (line 107) +* nand erase: NAND Flash Commands. (line 140) +* nand info: NAND Flash Commands. (line 244) +* nand list: NAND Flash Commands. (line 87) +* nand probe: NAND Flash Commands. (line 97) +* nand raw_access: NAND Flash Commands. (line 249) +* nand verify: NAND Flash Commands. (line 206) +* nand write: NAND Flash Commands. (line 153) +* ocl: Flash Commands. (line 548) +* oocd_trace: Architecture and Core Commands. + (line 222) +* oocd_trace config: Architecture and Core Commands. + (line 231) +* oocd_trace resync: Architecture and Core Commands. + (line 235) +* oocd_trace status: Architecture and Core Commands. + (line 238) +* opendous: Debug Adapter Configuration. + (line 545) +* orion: NAND Flash Commands. (line 346) +* parport: Debug Adapter Configuration. + (line 414) +* parport_cable: Debug Adapter Configuration. + (line 420) +* parport_port: Debug Adapter Configuration. + (line 68) +* parport_port <1>: Debug Adapter Configuration. + (line 359) +* parport_port <2>: Debug Adapter Configuration. + (line 449) +* parport_toggling_time: Debug Adapter Configuration. + (line 459) +* parport_write_on_exit: Debug Adapter Configuration. + (line 493) +* pathmove: JTAG Commands. (line 115) +* peek: General Commands. (line 213) +* pic32mx: Flash Commands. (line 553) +* pic32mx pgm_word: Flash Commands. (line 561) +* pic32mx unlock: Flash Commands. (line 564) +* pld device: PLD/FPGA Commands. (line 23) +* pld devices: PLD/FPGA Commands. (line 28) +* pld load: PLD/FPGA Commands. (line 31) +* poke: General Commands. (line 216) +* poll: Daemon Configuration. + (line 195) +* power: Debug Adapter Configuration. + (line 557) +* presto: Debug Adapter Configuration. + (line 505) +* presto_serial: Debug Adapter Configuration. + (line 507) +* profile: General Commands. (line 341) +* program: Flash Commands. (line 194) +* rbp: General Commands. (line 323) +* reg: General Commands. (line 83) +* remote_bitbang: Debug Adapter Configuration. + (line 294) +* remote_bitbang_host: Debug Adapter Configuration. + (line 306) +* remote_bitbang_port: Debug Adapter Configuration. + (line 302) +* reset: General Commands. (line 154) +* reset halt: General Commands. (line 156) +* reset init: General Commands. (line 157) +* reset run: General Commands. (line 155) +* reset_config: Reset Configuration. (line 143) +* resume: General Commands. (line 145) +* rlink: Debug Adapter Configuration. + (line 510) +* rm: General Commands. (line 219) +* rtck: Debug Adapter Configuration. + (line 72) +* runtest: JTAG Commands. (line 123) +* rwp: General Commands. (line 326) +* s3c2410: NAND Flash Commands. (line 354) +* s3c2412: NAND Flash Commands. (line 355) +* s3c2440: NAND Flash Commands. (line 356) +* s3c2443: NAND Flash Commands. (line 357) +* s3c6400: NAND Flash Commands. (line 358) +* scan_chain: TAP Declaration. (line 88) +* shutdown: General Commands. (line 49) +* sleep: General Commands. (line 43) +* soft_reset_halt: General Commands. (line 172) +* stellaris: Flash Commands. (line 568) +* stellaris recover bank_id: Flash Commands. (line 577) +* step: General Commands. (line 150) +* stlink_api: Debug Adapter Configuration. + (line 541) +* stm32f1x: Flash Commands. (line 590) +* stm32f1x lock: Flash Commands. (line 611) +* stm32f1x options_read: Flash Commands. (line 619) +* stm32f1x options_write: Flash Commands. (line 624) +* stm32f1x unlock: Flash Commands. (line 615) +* stm32f2x: Flash Commands. (line 629) +* stm32f2x lock: Flash Commands. (line 644) +* stm32f2x unlock: Flash Commands. (line 648) +* stm32lx: Flash Commands. (line 652) +* stmsmi: Flash Commands. (line 257) +* str7x: Flash Commands. (line 664) +* str7x disable_jtag: Flash Commands. (line 672) +* str9x: Flash Commands. (line 676) +* str9x flash_config: Flash Commands. (line 685) +* str9xpec: Flash Commands. (line 774) +* str9xpec disable_turbo: Flash Commands. (line 782) +* str9xpec enable_turbo: Flash Commands. (line 785) +* str9xpec lock: Flash Commands. (line 789) +* str9xpec options_cmap: Flash Commands. (line 796) +* str9xpec options_lvdsel: Flash Commands. (line 799) +* str9xpec options_lvdthd: Flash Commands. (line 802) +* str9xpec options_lvdwarn: Flash Commands. (line 805) +* str9xpec options_read: Flash Commands. (line 808) +* str9xpec options_write: Flash Commands. (line 811) +* str9xpec part_id: Flash Commands. (line 793) +* str9xpec unlock: Flash Commands. (line 814) +* svf: Boundary Scan Commands. + (line 17) +* swd newdap: Debug Adapter Configuration. + (line 594) +* swd wcr trn prescale: Debug Adapter Configuration. + (line 597) +* target count: CPU Configuration. (line 37) +* target create: CPU Configuration. (line 183) +* target current: CPU Configuration. (line 50) +* target names: CPU Configuration. (line 53) +* target number: CPU Configuration. (line 59) +* target types: CPU Configuration. (line 99) +* targets: CPU Configuration. (line 68) +* target_request debugmsgs: Architecture and Core Commands. + (line 742) +* tcl_port: Daemon Configuration. + (line 114) +* telnet_port: Daemon Configuration. + (line 121) +* test_image: General Commands. (line 294) +* tms470: Flash Commands. (line 694) +* tms470 flash_keyset: Flash Commands. (line 701) +* tms470 osc_mhz: Flash Commands. (line 705) +* tms470 plldis: Flash Commands. (line 708) +* trace history: Architecture and Core Commands. + (line 752) +* trace point: Architecture and Core Commands. + (line 758) +* transport list: Debug Adapter Configuration. + (line 566) +* transport select: Debug Adapter Configuration. + (line 570) +* trunc: General Commands. (line 222) +* ulink: Debug Adapter Configuration. + (line 548) +* usbprog: Debug Adapter Configuration. + (line 513) +* usb_blaster: Debug Adapter Configuration. + (line 325) +* usb_blaster <1>: Debug Adapter Configuration. + (line 345) +* usb_blaster_device_desc: Debug Adapter Configuration. + (line 331) +* usb_blaster_vid_pid: Debug Adapter Configuration. + (line 337) +* verify_image: General Commands. (line 300) +* verify_ircapture: JTAG Commands. (line 128) +* verify_jtag: JTAG Commands. (line 134) +* version: General Commands. (line 346) +* virt2phys: General Commands. (line 349) +* virtex2: PLD/FPGA Commands. (line 42) +* virtex2 read_stat: PLD/FPGA Commands. (line 48) +* virtual: Flash Commands. (line 712) +* vsllink: Debug Adapter Configuration. + (line 516) +* wait_halt: General Commands. (line 116) +* wp: General Commands. (line 329) +* xscale analyze_trace: Architecture and Core Commands. + (line 514) +* xscale cache_clean_address: Architecture and Core Commands. + (line 517) +* xscale cache_info: Architecture and Core Commands. + (line 520) +* xscale cp15: Architecture and Core Commands. + (line 523) +* xscale dcache: Architecture and Core Commands. + (line 530) +* xscale debug_handler: Architecture and Core Commands. + (line 527) +* xscale dump_trace: Architecture and Core Commands. + (line 533) +* xscale icache: Architecture and Core Commands. + (line 536) +* xscale mmu: Architecture and Core Commands. + (line 539) +* xscale trace_buffer: Architecture and Core Commands. + (line 542) +* xscale trace_image: Architecture and Core Commands. + (line 547) +* xscale vector_catch: Architecture and Core Commands. + (line 553) +* xscale vector_table: Architecture and Core Commands. + (line 568) +* xsvf: Boundary Scan Commands. + (line 32) +* ZY1000: Debug Adapter Configuration. + (line 551) + diff --git a/debuggers/openocd/doc/openocd.texi b/debuggers/openocd/doc/openocd.texi new file mode 100644 index 00000000..bc92452d --- /dev/null +++ b/debuggers/openocd/doc/openocd.texi @@ -0,0 +1,8825 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename openocd.info +@settitle OpenOCD User's Guide +@dircategory Development +@direntry +* OpenOCD: (openocd). OpenOCD User's Guide +@end direntry +@paragraphindent 0 +@c %**end of header + +@include version.texi + +@copying + +This User's Guide documents +release @value{VERSION}, +dated @value{UPDATED}, +of the Open On-Chip Debugger (OpenOCD). + +@itemize @bullet +@item Copyright @copyright{} 2008 The OpenOCD Project +@item Copyright @copyright{} 2007-2008 Spencer Oliver @email{spen@@spen-soft.co.uk} +@item Copyright @copyright{} 2008-2010 Oyvind Harboe @email{oyvind.harboe@@zylin.com} +@item Copyright @copyright{} 2008 Duane Ellis @email{openocd@@duaneellis.com} +@item Copyright @copyright{} 2009-2010 David Brownell +@end itemize + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +Texts. A copy of the license is included in the section entitled ``GNU +Free Documentation License''. +@end quotation +@end copying + +@titlepage +@titlefont{@emph{Open On-Chip Debugger:}} +@sp 1 +@title OpenOCD User's Guide +@subtitle for release @value{VERSION} +@subtitle @value{UPDATED} + +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@summarycontents +@contents + +@ifnottex +@node Top +@top OpenOCD User's Guide + +@insertcopying +@end ifnottex + +@menu +* About:: About OpenOCD +* Developers:: OpenOCD Developer Resources +* Debug Adapter Hardware:: Debug Adapter Hardware +* About Jim-Tcl:: About Jim-Tcl +* Running:: Running OpenOCD +* OpenOCD Project Setup:: OpenOCD Project Setup +* Config File Guidelines:: Config File Guidelines +* Daemon Configuration:: Daemon Configuration +* Debug Adapter Configuration:: Debug Adapter Configuration +* Reset Configuration:: Reset Configuration +* TAP Declaration:: TAP Declaration +* CPU Configuration:: CPU Configuration +* Flash Commands:: Flash Commands +* Flash Programming:: Flash Programming +* NAND Flash Commands:: NAND Flash Commands +* PLD/FPGA Commands:: PLD/FPGA Commands +* General Commands:: General Commands +* Architecture and Core Commands:: Architecture and Core Commands +* JTAG Commands:: JTAG Commands +* Boundary Scan Commands:: Boundary Scan Commands +* TFTP:: TFTP +* GDB and OpenOCD:: Using GDB and OpenOCD +* Tcl Scripting API:: Tcl Scripting API +* FAQ:: Frequently Asked Questions +* Tcl Crash Course:: Tcl Crash Course +* License:: GNU Free Documentation License + +@comment DO NOT use the plain word ``Index'', reason: CYGWIN filename +@comment case issue with ``Index.html'' and ``index.html'' +@comment Occurs when creating ``--html --no-split'' output +@comment This fix is based on: http://sourceware.org/ml/binutils/2006-05/msg00215.html +* OpenOCD Concept Index:: Concept Index +* Command and Driver Index:: Command and Driver Index +@end menu + +@node About +@unnumbered About +@cindex about + +OpenOCD was created by Dominic Rath as part of a diploma thesis written at the +University of Applied Sciences Augsburg (@uref{http://www.fh-augsburg.de}). +Since that time, the project has grown into an active open-source project, +supported by a diverse community of software and hardware developers from +around the world. + +@section What is OpenOCD? +@cindex TAP +@cindex JTAG + +The Open On-Chip Debugger (OpenOCD) aims to provide debugging, +in-system programming and boundary-scan testing for embedded target +devices. + +It does so with the assistance of a @dfn{debug adapter}, which is +a small hardware module which helps provide the right kind of +electrical signaling to the target being debugged. These are +required since the debug host (on which OpenOCD runs) won't +usually have native support for such signaling, or the connector +needed to hook up to the target. + +Such debug adapters support one or more @dfn{transport} protocols, +each of which involves different electrical signaling (and uses +different messaging protocols on top of that signaling). There +are many types of debug adapter, and little uniformity in what +they are called. (There are also product naming differences.) + +These adapters are sometimes packaged as discrete dongles, which +may generically be called @dfn{hardware interface dongles}. +Some development boards also integrate them directly, which may +let the development board can be directly connected to the debug +host over USB (and sometimes also to power it over USB). + +For example, a @dfn{JTAG Adapter} supports JTAG +signaling, and is used to communicate +with JTAG (IEEE 1149.1) compliant TAPs on your target board. +A @dfn{TAP} is a ``Test Access Port'', a module which processes +special instructions and data. TAPs are daisy-chained within and +between chips and boards. JTAG supports debugging and boundary +scan operations. + +There are also @dfn{SWD Adapters} that support Serial Wire Debug (SWD) +signaling to communicate with some newer ARM cores, as well as debug +adapters which support both JTAG and SWD transports. SWD only supports +debugging, whereas JTAG also supports boundary scan operations. + +For some chips, there are also @dfn{Programming Adapters} supporting +special transports used only to write code to flash memory, without +support for on-chip debugging or boundary scan. +(At this writing, OpenOCD does not support such non-debug adapters.) + + +@b{Dongles:} OpenOCD currently supports many types of hardware dongles: USB +based, parallel port based, and other standalone boxes that run +OpenOCD internally. @xref{Debug Adapter Hardware}. + +@b{GDB Debug:} It allows ARM7 (ARM7TDMI and ARM720t), ARM9 (ARM920T, +ARM922T, ARM926EJ--S, ARM966E--S), XScale (PXA25x, IXP42x) and +Cortex-M3 (Stellaris LM3, ST STM32 and Energy Micro EFM32) based cores to be +debugged via the GDB protocol. + +@b{Flash Programing:} Flash writing is supported for external CFI +compatible NOR flashes (Intel and AMD/Spansion command set) and several +internal flashes (LPC1700, LPC1800, LPC2000, LPC4300, AT91SAM7, AT91SAM3U, +STR7x, STR9x, LM3, STM32x and EFM32). Preliminary support for various NAND flash +controllers (LPC3180, Orion, S3C24xx, more) controller is included. + +@section OpenOCD Web Site + +The OpenOCD web site provides the latest public news from the community: + +@uref{http://openocd.sourceforge.net/} + +@section Latest User's Guide: + +The user's guide you are now reading may not be the latest one +available. A version for more recent code may be available. +Its HTML form is published regularly at: + +@uref{http://openocd.sourceforge.net/doc/html/index.html} + +PDF form is likewise published at: + +@uref{http://openocd.sourceforge.net/doc/pdf/openocd.pdf} + +@section OpenOCD User's Forum + +There is an OpenOCD forum (phpBB) hosted by SparkFun, +which might be helpful to you. Note that if you want +anything to come to the attention of developers, you +should post it to the OpenOCD Developer Mailing List +instead of this forum. + +@uref{http://forum.sparkfun.com/viewforum.php?f=18} + +@section OpenOCD User's Mailing List + +The OpenOCD User Mailing List provides the primary means of +communication between users: + +@uref{https://lists.sourceforge.net/mailman/listinfo/openocd-user} + +@section OpenOCD IRC + +Support can also be found on irc: +@uref{irc://irc.freenode.net/openocd} + +@node Developers +@chapter OpenOCD Developer Resources +@cindex developers + +If you are interested in improving the state of OpenOCD's debugging and +testing support, new contributions will be welcome. Motivated developers +can produce new target, flash or interface drivers, improve the +documentation, as well as more conventional bug fixes and enhancements. + +The resources in this chapter are available for developers wishing to explore +or expand the OpenOCD source code. + +@section OpenOCD GIT Repository + +During the 0.3.x release cycle, OpenOCD switched from Subversion to +a GIT repository hosted at SourceForge. The repository URL is: + +@uref{git://git.code.sf.net/p/openocd/code} + +or via http + +@uref{http://git.code.sf.net/p/openocd/code} + +You may prefer to use a mirror and the HTTP protocol: + +@uref{http://repo.or.cz/r/openocd.git} + +With standard GIT tools, use @command{git clone} to initialize +a local repository, and @command{git pull} to update it. +There are also gitweb pages letting you browse the repository +with a web browser, or download arbitrary snapshots without +needing a GIT client: + +@uref{http://repo.or.cz/w/openocd.git} + +The @file{README} file contains the instructions for building the project +from the repository or a snapshot. + +Developers that want to contribute patches to the OpenOCD system are +@b{strongly} encouraged to work against mainline. +Patches created against older versions may require additional +work from their submitter in order to be updated for newer releases. + +@section Doxygen Developer Manual + +During the 0.2.x release cycle, the OpenOCD project began +providing a Doxygen reference manual. This document contains more +technical information about the software internals, development +processes, and similar documentation: + +@uref{http://openocd.sourceforge.net/doc/doxygen/html/index.html} + +This document is a work-in-progress, but contributions would be welcome +to fill in the gaps. All of the source files are provided in-tree, +listed in the Doxyfile configuration in the top of the source tree. + +@section OpenOCD Developer Mailing List + +The OpenOCD Developer Mailing List provides the primary means of +communication between developers: + +@uref{https://lists.sourceforge.net/mailman/listinfo/openocd-devel} + +Discuss and submit patches to this list. +The @file{HACKING} file contains basic information about how +to prepare patches. + +@section OpenOCD Bug Database + +During the 0.4.x release cycle the OpenOCD project team began +using Trac for its bug database: + +@uref{https://sourceforge.net/apps/trac/openocd} + + +@node Debug Adapter Hardware +@chapter Debug Adapter Hardware +@cindex dongles +@cindex FTDI +@cindex wiggler +@cindex zy1000 +@cindex printer port +@cindex USB Adapter +@cindex RTCK + +Defined: @b{dongle}: A small device that plugins into a computer and serves as +an adapter .... [snip] + +In the OpenOCD case, this generally refers to @b{a small adapter} that +attaches to your computer via USB or the Parallel Printer Port. One +exception is the Zylin ZY1000, packaged as a small box you attach via +an ethernet cable. The Zylin ZY1000 has the advantage that it does not +require any drivers to be installed on the developer PC. It also has +a built in web interface. It supports RTCK/RCLK or adaptive clocking +and has a built in relay to power cycle targets remotely. + + +@section Choosing a Dongle + +There are several things you should keep in mind when choosing a dongle. + +@enumerate +@item @b{Transport} Does it support the kind of communication that you need? +OpenOCD focusses mostly on JTAG. Your version may also support +other ways to communicate with target devices. +@item @b{Voltage} What voltage is your target - 1.8, 2.8, 3.3, or 5V? +Does your dongle support it? You might need a level converter. +@item @b{Pinout} What pinout does your target board use? +Does your dongle support it? You may be able to use jumper +wires, or an "octopus" connector, to convert pinouts. +@item @b{Connection} Does your computer have the USB, printer, or +Ethernet port needed? +@item @b{RTCK} Do you expect to use it with ARM chips and boards with +RTCK support? Also known as ``adaptive clocking'' +@end enumerate + +@section Stand alone Systems + +@b{ZY1000} See: @url{http://www.ultsol.com/index.php/component/content/article/8/33-zylin-zy1000-jtag-probe} +Technically, not a dongle, but a standalone box. The ZY1000 has the advantage that it does +not require any drivers installed on the developer PC. It also has +a built in web interface. It supports RTCK/RCLK or adaptive clocking +and has a built in relay to power cycle targets remotely. + +@section USB FT2232 Based + +There are many USB JTAG dongles on the market, many of them are based +on a chip from ``Future Technology Devices International'' (FTDI) +known as the FTDI FT2232; this is a USB full speed (12 Mbps) chip. +See: @url{http://www.ftdichip.com} for more information. +In summer 2009, USB high speed (480 Mbps) versions of these FTDI +chips are starting to become available in JTAG adapters. Around 2012 a new +variant appeared - FT232H - this is a single-channel version of FT2232H. +(Adapters using those high speed FT2232H or FT232H chips may support adaptive +clocking.) + +The FT2232 chips are flexible enough to support some other +transport options, such as SWD or the SPI variants used to +program some chips. They have two communications channels, +and one can be used for a UART adapter at the same time the +other one is used to provide a debug adapter. + +Also, some development boards integrate an FT2232 chip to serve as +a built-in low cost debug adapter and usb-to-serial solution. + +@itemize @bullet +@item @b{usbjtag} +@* Link @url{http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html} +@item @b{jtagkey} +@* See: @url{http://www.amontec.com/jtagkey.shtml} +@item @b{jtagkey2} +@* See: @url{http://www.amontec.com/jtagkey2.shtml} +@item @b{oocdlink} +@* See: @url{http://www.oocdlink.com} By Joern Kaipf +@item @b{signalyzer} +@* See: @url{http://www.signalyzer.com} +@item @b{Stellaris Eval Boards} +@* See: @url{http://www.ti.com} - The Stellaris eval boards +bundle FT2232-based JTAG and SWD support, which can be used to debug +the Stellaris chips. Using separate JTAG adapters is optional. +These boards can also be used in a "pass through" mode as JTAG adapters +to other target boards, disabling the Stellaris chip. +@item @b{TI/Luminary ICDI} +@* See: @url{http://www.ti.com} - TI/Luminary In-Circuit Debug +Interface (ICDI) Boards are included in Stellaris LM3S9B9x +Evaluation Kits. Like the non-detachable FT2232 support on the other +Stellaris eval boards, they can be used to debug other target boards. +@item @b{olimex-jtag} +@* See: @url{http://www.olimex.com} +@item @b{Flyswatter/Flyswatter2} +@* See: @url{http://www.tincantools.com} +@item @b{turtelizer2} +@* See: +@uref{http://www.ethernut.de/en/hardware/turtelizer/index.html, Turtelizer 2}, or +@url{http://www.ethernut.de} +@item @b{comstick} +@* Link: @url{http://www.hitex.com/index.php?id=383} +@item @b{stm32stick} +@* Link @url{http://www.hitex.com/stm32-stick} +@item @b{axm0432_jtag} +@* Axiom AXM-0432 Link @url{http://www.axman.com} - NOTE: This JTAG does not appear +to be available anymore as of April 2012. +@item @b{cortino} +@* Link @url{http://www.hitex.com/index.php?id=cortino} +@item @b{dlp-usb1232h} +@* Link @url{http://www.dlpdesign.com/usb/usb1232h.shtml} +@item @b{digilent-hs1} +@* Link @url{http://www.digilentinc.com/Products/Detail.cfm?Prod=JTAG-HS1} +@item @b{opendous} +@* Link @url{http://code.google.com/p/opendous/wiki/JTAG} FT2232H-based +(OpenHardware). +@item @b{JTAG-lock-pick Tiny 2} +@* Link @url{http://www.distortec.com/jtag-lock-pick-tiny-2} FT232H-based +@end itemize + +@section USB-JTAG / Altera USB-Blaster compatibles + +These devices also show up as FTDI devices, but are not +protocol-compatible with the FT2232 devices. They are, however, +protocol-compatible among themselves. USB-JTAG devices typically consist +of a FT245 followed by a CPLD that understands a particular protocol, +or emulate this protocol using some other hardware. + +They may appear under different USB VID/PID depending on the particular +product. The driver can be configured to search for any VID/PID pair +(see the section on driver commands). + +@itemize +@item @b{USB-JTAG} Kolja Waschk's USB Blaster-compatible adapter +@* Link: @url{http://ixo-jtag.sourceforge.net/} +@item @b{Altera USB-Blaster} +@* Link: @url{http://www.altera.com/literature/ug/ug_usb_blstr.pdf} +@end itemize + +@section USB JLINK based +There are several OEM versions of the Segger @b{JLINK} adapter. It is +an example of a micro controller based JTAG adapter, it uses an +AT91SAM764 internally. + +@itemize @bullet +@item @b{ATMEL SAMICE} Only works with ATMEL chips! +@* Link: @url{http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3892} +@item @b{SEGGER JLINK} +@* Link: @url{http://www.segger.com/jlink.html} +@item @b{IAR J-Link} +@* Link: @url{http://www.iar.com/en/products/hardware-debug-probes/iar-j-link/} +@end itemize + +@section USB RLINK based +Raisonance has an adapter called @b{RLink}. It exists in a stripped-down form on the STM32 Primer, +permanently attached to the JTAG lines. It also exists on the STM32 Primer2, but that is wired for +SWD and not JTAG, thus not supported. + +@itemize @bullet +@item @b{Raisonance RLink} +@* Link: @url{http://www.mcu-raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html} +@item @b{STM32 Primer} +@* Link: @url{http://www.stm32circle.com/resources/stm32primer.php} +@item @b{STM32 Primer2} +@* Link: @url{http://www.stm32circle.com/resources/stm32primer2.php} +@end itemize + +@section USB ST-LINK based +ST Micro has an adapter called @b{ST-LINK}. +They only work with ST Micro chips, notably STM32 and STM8. + +@itemize @bullet +@item @b{ST-LINK} +@* This is available standalone and as part of some kits, eg. STM32VLDISCOVERY. +@* Link: @url{http://www.st.com/internet/evalboard/product/219866.jsp} +@item @b{ST-LINK/V2} +@* This is available standalone and as part of some kits, eg. STM32F4DISCOVERY. +@* Link: @url{http://www.st.com/internet/evalboard/product/251168.jsp} +@end itemize + +For info the original ST-LINK enumerates using the mass storage usb class, however +it's implementation is completely broken. The result is this causes issues under linux. +The simplest solution is to get linux to ignore the ST-LINK using one of the following methods: +@itemize @bullet +@item modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i +@item add "options usb-storage quirks=483:3744:i" to /etc/modprobe.conf +@end itemize + +@section USB TI/Stellaris ICDI based +Texas Instruments has an adapter called @b{ICDI}. +It is not to be confused with the FTDI based adapters that were originally fitted to their +evaluation boards. This is the adapter fitted to the Stellaris LaunchPad. + +@section USB Other +@itemize @bullet +@item @b{USBprog} +@* Link: @url{http://shop.embedded-projects.net/} - which uses an Atmel MEGA32 and a UBN9604 + +@item @b{USB - Presto} +@* Link: @url{http://tools.asix.net/prg_presto.htm} + +@item @b{Versaloon-Link} +@* Link: @url{http://www.versaloon.com} + +@item @b{ARM-JTAG-EW} +@* Link: @url{http://www.olimex.com/dev/arm-jtag-ew.html} + +@item @b{Buspirate} +@* Link: @url{http://dangerousprototypes.com/bus-pirate-manual/} + +@item @b{opendous} +@* Link: @url{http://code.google.com/p/opendous-jtag/} - which uses an AT90USB162 + +@item @b{estick} +@* Link: @url{http://code.google.com/p/estick-jtag/} + +@item @b{Keil ULINK v1} +@* Link: @url{http://www.keil.com/ulink1/} +@end itemize + +@section IBM PC Parallel Printer Port Based + +The two well known ``JTAG Parallel Ports'' cables are the Xilnx DLC5 +and the Macraigor Wiggler. There are many clones and variations of +these on the market. + +Note that parallel ports are becoming much less common, so if you +have the choice you should probably avoid these adapters in favor +of USB-based ones. + +@itemize @bullet + +@item @b{Wiggler} - There are many clones of this. +@* Link: @url{http://www.macraigor.com/wiggler.htm} + +@item @b{DLC5} - From XILINX - There are many clones of this +@* Link: Search the web for: ``XILINX DLC5'' - it is no longer +produced, PDF schematics are easily found and it is easy to make. + +@item @b{Amontec - JTAG Accelerator} +@* Link: @url{http://www.amontec.com/jtag_accelerator.shtml} + +@item @b{GW16402} +@* Link: @url{http://www.gateworks.com/products/avila_accessories/gw16042.php} + +@item @b{Wiggler2} +@* Link: @url{http://www.ccac.rwth-aachen.de/~michaels/index.php/hardware/armjtag} + +@item @b{Wiggler_ntrst_inverted} +@* Yet another variation - See the source code, src/jtag/parport.c + +@item @b{old_amt_wiggler} +@* Unknown - probably not on the market today + +@item @b{arm-jtag} +@* Link: Most likely @url{http://www.olimex.com/dev/arm-jtag.html} [another wiggler clone] + +@item @b{chameleon} +@* Link: @url{http://www.amontec.com/chameleon.shtml} + +@item @b{Triton} +@* Unknown. + +@item @b{Lattice} +@* ispDownload from Lattice Semiconductor +@url{http://www.latticesemi.com/lit/docs/@/devtools/dlcable.pdf} + +@item @b{flashlink} +@* From ST Microsystems; +@* Link: @url{http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATA_BRIEF/DM00039500.pdf} + +@end itemize + +@section Other... +@itemize @bullet + +@item @b{ep93xx} +@* An EP93xx based Linux machine using the GPIO pins directly. + +@item @b{at91rm9200} +@* Like the EP93xx - but an ATMEL AT91RM9200 based solution using the GPIO pins on the chip. + +@end itemize + +@node About Jim-Tcl +@chapter About Jim-Tcl +@cindex Jim-Tcl +@cindex tcl + +OpenOCD uses a small ``Tcl Interpreter'' known as Jim-Tcl. +This programming language provides a simple and extensible +command interpreter. + +All commands presented in this Guide are extensions to Jim-Tcl. +You can use them as simple commands, without needing to learn +much of anything about Tcl. +Alternatively, can write Tcl programs with them. + +You can learn more about Jim at its website, @url{http://jim.berlios.de}. +There is an active and responsive community, get on the mailing list +if you have any questions. Jim-Tcl maintainers also lurk on the +OpenOCD mailing list. + +@itemize @bullet +@item @b{Jim vs. Tcl} +@* Jim-Tcl is a stripped down version of the well known Tcl language, +which can be found here: @url{http://www.tcl.tk}. Jim-Tcl has far +fewer features. Jim-Tcl is several dozens of .C files and .H files and +implements the basic Tcl command set. In contrast: Tcl 8.6 is a +4.2 MB .zip file containing 1540 files. + +@item @b{Missing Features} +@* Our practice has been: Add/clone the real Tcl feature if/when +needed. We welcome Jim-Tcl improvements, not bloat. Also there +are a large number of optional Jim-Tcl features that are not +enabled in OpenOCD. + +@item @b{Scripts} +@* OpenOCD configuration scripts are Jim-Tcl Scripts. OpenOCD's +command interpreter today is a mixture of (newer) +Jim-Tcl commands, and (older) the orginal command interpreter. + +@item @b{Commands} +@* At the OpenOCD telnet command line (or via the GDB monitor command) one +can type a Tcl for() loop, set variables, etc. +Some of the commands documented in this guide are implemented +as Tcl scripts, from a @file{startup.tcl} file internal to the server. + +@item @b{Historical Note} +@* Jim-Tcl was introduced to OpenOCD in spring 2008. Fall 2010, +before OpenOCD 0.5 release OpenOCD switched to using Jim Tcl +as a git submodule, which greatly simplified upgrading Jim Tcl +to benefit from new features and bugfixes in Jim Tcl. + +@item @b{Need a crash course in Tcl?} +@*@xref{Tcl Crash Course}. +@end itemize + +@node Running +@chapter Running +@cindex command line options +@cindex logfile +@cindex directory search + +Properly installing OpenOCD sets up your operating system to grant it access +to the debug adapters. On Linux, this usually involves installing a file +in @file{/etc/udev/rules.d,} so OpenOCD has permissions. MS-Windows needs +complex and confusing driver configuration for every peripheral. Such issues +are unique to each operating system, and are not detailed in this User's Guide. + +Then later you will invoke the OpenOCD server, with various options to +tell it how each debug session should work. +The @option{--help} option shows: +@verbatim +bash$ openocd --help + +--help | -h display this help +--version | -v display OpenOCD version +--file | -f use configuration file +--search | -s dir to search for config files and scripts +--debug | -d set debug level <0-3> +--log_output | -l redirect log output to file +--command | -c run +@end verbatim + +If you don't give any @option{-f} or @option{-c} options, +OpenOCD tries to read the configuration file @file{openocd.cfg}. +To specify one or more different +configuration files, use @option{-f} options. For example: + +@example +openocd -f config1.cfg -f config2.cfg -f config3.cfg +@end example + +Configuration files and scripts are searched for in +@enumerate +@item the current directory, +@item any search dir specified on the command line using the @option{-s} option, +@item any search dir specified using the @command{add_script_search_dir} command, +@item @file{$HOME/.openocd} (not on Windows), +@item the site wide script library @file{$pkgdatadir/site} and +@item the OpenOCD-supplied script library @file{$pkgdatadir/scripts}. +@end enumerate +The first found file with a matching file name will be used. + +@quotation Note +Don't try to use configuration script names or paths which +include the "#" character. That character begins Tcl comments. +@end quotation + +@section Simple setup, no customization + +In the best case, you can use two scripts from one of the script +libraries, hook up your JTAG adapter, and start the server ... and +your JTAG setup will just work "out of the box". Always try to +start by reusing those scripts, but assume you'll need more +customization even if this works. @xref{OpenOCD Project Setup}. + +If you find a script for your JTAG adapter, and for your board or +target, you may be able to hook up your JTAG adapter then start +the server like: + +@example +openocd -f interface/ADAPTER.cfg -f board/MYBOARD.cfg +@end example + +You might also need to configure which reset signals are present, +using @option{-c 'reset_config trst_and_srst'} or something similar. +If all goes well you'll see output something like + +@example +Open On-Chip Debugger 0.4.0 (2010-01-14-15:06) +For bug reports, read + http://openocd.sourceforge.net/doc/doxygen/bugs.html +Info : JTAG tap: lm3s.cpu tap/device found: 0x3ba00477 + (mfg: 0x23b, part: 0xba00, ver: 0x3) +@end example + +Seeing that "tap/device found" message, and no warnings, means +the JTAG communication is working. That's a key milestone, but +you'll probably need more project-specific setup. + +@section What OpenOCD does as it starts + +OpenOCD starts by processing the configuration commands provided +on the command line or, if there were no @option{-c command} or +@option{-f file.cfg} options given, in @file{openocd.cfg}. +@xref{configurationstage,,Configuration Stage}. +At the end of the configuration stage it verifies the JTAG scan +chain defined using those commands; your configuration should +ensure that this always succeeds. +Normally, OpenOCD then starts running as a daemon. +Alternatively, commands may be used to terminate the configuration +stage early, perform work (such as updating some flash memory), +and then shut down without acting as a daemon. + +Once OpenOCD starts running as a daemon, it waits for connections from +clients (Telnet, GDB, Other) and processes the commands issued through +those channels. + +If you are having problems, you can enable internal debug messages via +the @option{-d} option. + +Also it is possible to interleave Jim-Tcl commands w/config scripts using the +@option{-c} command line switch. + +To enable debug output (when reporting problems or working on OpenOCD +itself), use the @option{-d} command line switch. This sets the +@option{debug_level} to "3", outputting the most information, +including debug messages. The default setting is "2", outputting only +informational messages, warnings and errors. You can also change this +setting from within a telnet or gdb session using @command{debug_level} +(@pxref{debuglevel,,debug_level}). + +You can redirect all output from the daemon to a file using the +@option{-l } switch. + +Note! OpenOCD will launch the GDB & telnet server even if it can not +establish a connection with the target. In general, it is possible for +the JTAG controller to be unresponsive until the target is set up +correctly via e.g. GDB monitor commands in a GDB init script. + +@node OpenOCD Project Setup +@chapter OpenOCD Project Setup + +To use OpenOCD with your development projects, you need to do more than +just connecting the JTAG adapter hardware (dongle) to your development board +and then starting the OpenOCD server. +You also need to configure that server so that it knows +about that adapter and board, and helps your work. +You may also want to connect OpenOCD to GDB, possibly +using Eclipse or some other GUI. + +@section Hooking up the JTAG Adapter + +Today's most common case is a dongle with a JTAG cable on one side +(such as a ribbon cable with a 10-pin or 20-pin IDC connector) +and a USB cable on the other. +Instead of USB, some cables use Ethernet; +older ones may use a PC parallel port, or even a serial port. + +@enumerate +@item @emph{Start with power to your target board turned off}, +and nothing connected to your JTAG adapter. +If you're particularly paranoid, unplug power to the board. +It's important to have the ground signal properly set up, +unless you are using a JTAG adapter which provides +galvanic isolation between the target board and the +debugging host. + +@item @emph{Be sure it's the right kind of JTAG connector.} +If your dongle has a 20-pin ARM connector, you need some kind +of adapter (or octopus, see below) to hook it up to +boards using 14-pin or 10-pin connectors ... or to 20-pin +connectors which don't use ARM's pinout. + +In the same vein, make sure the voltage levels are compatible. +Not all JTAG adapters have the level shifters needed to work +with 1.2 Volt boards. + +@item @emph{Be certain the cable is properly oriented} or you might +damage your board. In most cases there are only two possible +ways to connect the cable. +Connect the JTAG cable from your adapter to the board. +Be sure it's firmly connected. + +In the best case, the connector is keyed to physically +prevent you from inserting it wrong. +This is most often done using a slot on the board's male connector +housing, which must match a key on the JTAG cable's female connector. +If there's no housing, then you must look carefully and +make sure pin 1 on the cable hooks up to pin 1 on the board. +Ribbon cables are frequently all grey except for a wire on one +edge, which is red. The red wire is pin 1. + +Sometimes dongles provide cables where one end is an ``octopus'' of +color coded single-wire connectors, instead of a connector block. +These are great when converting from one JTAG pinout to another, +but are tedious to set up. +Use these with connector pinout diagrams to help you match up the +adapter signals to the right board pins. + +@item @emph{Connect the adapter's other end} once the JTAG cable is connected. +A USB, parallel, or serial port connector will go to the host which +you are using to run OpenOCD. +For Ethernet, consult the documentation and your network administrator. + +For USB based JTAG adapters you have an easy sanity check at this point: +does the host operating system see the JTAG adapter? If that host is an +MS-Windows host, you'll need to install a driver before OpenOCD works. + +@item @emph{Connect the adapter's power supply, if needed.} +This step is primarily for non-USB adapters, +but sometimes USB adapters need extra power. + +@item @emph{Power up the target board.} +Unless you just let the magic smoke escape, +you're now ready to set up the OpenOCD server +so you can use JTAG to work with that board. + +@end enumerate + +Talk with the OpenOCD server using +telnet (@code{telnet localhost 4444} on many systems) or GDB. +@xref{GDB and OpenOCD}. + +@section Project Directory + +There are many ways you can configure OpenOCD and start it up. + +A simple way to organize them all involves keeping a +single directory for your work with a given board. +When you start OpenOCD from that directory, +it searches there first for configuration files, scripts, +files accessed through semihosting, +and for code you upload to the target board. +It is also the natural place to write files, +such as log files and data you download from the board. + +@section Configuration Basics + +There are two basic ways of configuring OpenOCD, and +a variety of ways you can mix them. +Think of the difference as just being how you start the server: + +@itemize +@item Many @option{-f file} or @option{-c command} options on the command line +@item No options, but a @dfn{user config file} +in the current directory named @file{openocd.cfg} +@end itemize + +Here is an example @file{openocd.cfg} file for a setup +using a Signalyzer FT2232-based JTAG adapter to talk to +a board with an Atmel AT91SAM7X256 microcontroller: + +@example +source [find interface/signalyzer.cfg] + +# GDB can also flash my flash! +gdb_memory_map enable +gdb_flash_program enable + +source [find target/sam7x256.cfg] +@end example + +Here is the command line equivalent of that configuration: + +@example +openocd -f interface/signalyzer.cfg \ + -c "gdb_memory_map enable" \ + -c "gdb_flash_program enable" \ + -f target/sam7x256.cfg +@end example + +You could wrap such long command lines in shell scripts, +each supporting a different development task. +One might re-flash the board with a specific firmware version. +Another might set up a particular debugging or run-time environment. + +@quotation Important +At this writing (October 2009) the command line method has +problems with how it treats variables. +For example, after @option{-c "set VAR value"}, or doing the +same in a script, the variable @var{VAR} will have no value +that can be tested in a later script. +@end quotation + +Here we will focus on the simpler solution: one user config +file, including basic configuration plus any TCL procedures +to simplify your work. + +@section User Config Files +@cindex config file, user +@cindex user config file +@cindex config file, overview + +A user configuration file ties together all the parts of a project +in one place. +One of the following will match your situation best: + +@itemize +@item Ideally almost everything comes from configuration files +provided by someone else. +For example, OpenOCD distributes a @file{scripts} directory +(probably in @file{/usr/share/openocd/scripts} on Linux). +Board and tool vendors can provide these too, as can individual +user sites; the @option{-s} command line option lets you say +where to find these files. (@xref{Running}.) +The AT91SAM7X256 example above works this way. + +Three main types of non-user configuration file each have their +own subdirectory in the @file{scripts} directory: + +@enumerate +@item @b{interface} -- one for each different debug adapter; +@item @b{board} -- one for each different board +@item @b{target} -- the chips which integrate CPUs and other JTAG TAPs +@end enumerate + +Best case: include just two files, and they handle everything else. +The first is an interface config file. +The second is board-specific, and it sets up the JTAG TAPs and +their GDB targets (by deferring to some @file{target.cfg} file), +declares all flash memory, and leaves you nothing to do except +meet your deadline: + +@example +source [find interface/olimex-jtag-tiny.cfg] +source [find board/csb337.cfg] +@end example + +Boards with a single microcontroller often won't need more +than the target config file, as in the AT91SAM7X256 example. +That's because there is no external memory (flash, DDR RAM), and +the board differences are encapsulated by application code. + +@item Maybe you don't know yet what your board looks like to JTAG. +Once you know the @file{interface.cfg} file to use, you may +need help from OpenOCD to discover what's on the board. +Once you find the JTAG TAPs, you can just search for appropriate +target and board +configuration files ... or write your own, from the bottom up. +@xref{autoprobing,,Autoprobing}. + +@item You can often reuse some standard config files but +need to write a few new ones, probably a @file{board.cfg} file. +You will be using commands described later in this User's Guide, +and working with the guidelines in the next chapter. + +For example, there may be configuration files for your JTAG adapter +and target chip, but you need a new board-specific config file +giving access to your particular flash chips. +Or you might need to write another target chip configuration file +for a new chip built around the Cortex M3 core. + +@quotation Note +When you write new configuration files, please submit +them for inclusion in the next OpenOCD release. +For example, a @file{board/newboard.cfg} file will help the +next users of that board, and a @file{target/newcpu.cfg} +will help support users of any board using that chip. +@end quotation + +@item +You may may need to write some C code. +It may be as simple as a supporting a new ft2232 or parport +based adapter; a bit more involved, like a NAND or NOR flash +controller driver; or a big piece of work like supporting +a new chip architecture. +@end itemize + +Reuse the existing config files when you can. +Look first in the @file{scripts/boards} area, then @file{scripts/targets}. +You may find a board configuration that's a good example to follow. + +When you write config files, separate the reusable parts +(things every user of that interface, chip, or board needs) +from ones specific to your environment and debugging approach. +@itemize + +@item +For example, a @code{gdb-attach} event handler that invokes +the @command{reset init} command will interfere with debugging +early boot code, which performs some of the same actions +that the @code{reset-init} event handler does. + +@item +Likewise, the @command{arm9 vector_catch} command (or +@cindex vector_catch +its siblings @command{xscale vector_catch} +and @command{cortex_m vector_catch}) can be a timesaver +during some debug sessions, but don't make everyone use that either. +Keep those kinds of debugging aids in your user config file, +along with messaging and tracing setup. +(@xref{softwaredebugmessagesandtracing,,Software Debug Messages and Tracing}.) + +@item +You might need to override some defaults. +For example, you might need to move, shrink, or back up the target's +work area if your application needs much SRAM. + +@item +TCP/IP port configuration is another example of something which +is environment-specific, and should only appear in +a user config file. @xref{tcpipports,,TCP/IP Ports}. +@end itemize + +@section Project-Specific Utilities + +A few project-specific utility +routines may well speed up your work. +Write them, and keep them in your project's user config file. + +For example, if you are making a boot loader work on a +board, it's nice to be able to debug the ``after it's +loaded to RAM'' parts separately from the finicky early +code which sets up the DDR RAM controller and clocks. +A script like this one, or a more GDB-aware sibling, +may help: + +@example +proc ramboot @{ @} @{ + # Reset, running the target's "reset-init" scripts + # to initialize clocks and the DDR RAM controller. + # Leave the CPU halted. + reset init + + # Load CONFIG_SKIP_LOWLEVEL_INIT version into DDR RAM. + load_image u-boot.bin 0x20000000 + + # Start running. + resume 0x20000000 +@} +@end example + +Then once that code is working you will need to make it +boot from NOR flash; a different utility would help. +Alternatively, some developers write to flash using GDB. +(You might use a similar script if you're working with a flash +based microcontroller application instead of a boot loader.) + +@example +proc newboot @{ @} @{ + # Reset, leaving the CPU halted. The "reset-init" event + # proc gives faster access to the CPU and to NOR flash; + # "reset halt" would be slower. + reset init + + # Write standard version of U-Boot into the first two + # sectors of NOR flash ... the standard version should + # do the same lowlevel init as "reset-init". + flash protect 0 0 1 off + flash erase_sector 0 0 1 + flash write_bank 0 u-boot.bin 0x0 + flash protect 0 0 1 on + + # Reboot from scratch using that new boot loader. + reset run +@} +@end example + +You may need more complicated utility procedures when booting +from NAND. +That often involves an extra bootloader stage, +running from on-chip SRAM to perform DDR RAM setup so it can load +the main bootloader code (which won't fit into that SRAM). + +Other helper scripts might be used to write production system images, +involving considerably more than just a three stage bootloader. + +@section Target Software Changes + +Sometimes you may want to make some small changes to the software +you're developing, to help make JTAG debugging work better. +For example, in C or assembly language code you might +use @code{#ifdef JTAG_DEBUG} (or its converse) around code +handling issues like: + +@itemize @bullet + +@item @b{Watchdog Timers}... +Watchog timers are typically used to automatically reset systems if +some application task doesn't periodically reset the timer. (The +assumption is that the system has locked up if the task can't run.) +When a JTAG debugger halts the system, that task won't be able to run +and reset the timer ... potentially causing resets in the middle of +your debug sessions. + +It's rarely a good idea to disable such watchdogs, since their usage +needs to be debugged just like all other parts of your firmware. +That might however be your only option. + +Look instead for chip-specific ways to stop the watchdog from counting +while the system is in a debug halt state. It may be simplest to set +that non-counting mode in your debugger startup scripts. You may however +need a different approach when, for example, a motor could be physically +damaged by firmware remaining inactive in a debug halt state. That might +involve a type of firmware mode where that "non-counting" mode is disabled +at the beginning then re-enabled at the end; a watchdog reset might fire +and complicate the debug session, but hardware (or people) would be +protected.@footnote{Note that many systems support a "monitor mode" debug +that is a somewhat cleaner way to address such issues. You can think of +it as only halting part of the system, maybe just one task, +instead of the whole thing. +At this writing, January 2010, OpenOCD based debugging does not support +monitor mode debug, only "halt mode" debug.} + +@item @b{ARM Semihosting}... +@cindex ARM semihosting +When linked with a special runtime library provided with many +toolchains@footnote{See chapter 8 "Semihosting" in +@uref{http://infocenter.arm.com/help/topic/com.arm.doc.dui0203i/DUI0203I_rvct_developer_guide.pdf, +ARM DUI 0203I}, the "RealView Compilation Tools Developer Guide". +The CodeSourcery EABI toolchain also includes a semihosting library.}, +your target code can use I/O facilities on the debug host. That library +provides a small set of system calls which are handled by OpenOCD. +It can let the debugger provide your system console and a file system, +helping with early debugging or providing a more capable environment +for sometimes-complex tasks like installing system firmware onto +NAND or SPI flash. + +@item @b{ARM Wait-For-Interrupt}... +Many ARM chips synchronize the JTAG clock using the core clock. +Low power states which stop that core clock thus prevent JTAG access. +Idle loops in tasking environments often enter those low power states +via the @code{WFI} instruction (or its coprocessor equivalent, before ARMv7). + +You may want to @emph{disable that instruction} in source code, +or otherwise prevent using that state, +to ensure you can get JTAG access at any time.@footnote{As a more +polite alternative, some processors have special debug-oriented +registers which can be used to change various features including +how the low power states are clocked while debugging. +The STM32 DBGMCU_CR register is an example; at the cost of extra +power consumption, JTAG can be used during low power states.} +For example, the OpenOCD @command{halt} command may not +work for an idle processor otherwise. + +@item @b{Delay after reset}... +Not all chips have good support for debugger access +right after reset; many LPC2xxx chips have issues here. +Similarly, applications that reconfigure pins used for +JTAG access as they start will also block debugger access. + +To work with boards like this, @emph{enable a short delay loop} +the first thing after reset, before "real" startup activities. +For example, one second's delay is usually more than enough +time for a JTAG debugger to attach, so that +early code execution can be debugged +or firmware can be replaced. + +@item @b{Debug Communications Channel (DCC)}... +Some processors include mechanisms to send messages over JTAG. +Many ARM cores support these, as do some cores from other vendors. +(OpenOCD may be able to use this DCC internally, speeding up some +operations like writing to memory.) + +Your application may want to deliver various debugging messages +over JTAG, by @emph{linking with a small library of code} +provided with OpenOCD and using the utilities there to send +various kinds of message. +@xref{softwaredebugmessagesandtracing,,Software Debug Messages and Tracing}. + +@end itemize + +@section Target Hardware Setup + +Chip vendors often provide software development boards which +are highly configurable, so that they can support all options +that product boards may require. @emph{Make sure that any +jumpers or switches match the system configuration you are +working with.} + +Common issues include: + +@itemize @bullet + +@item @b{JTAG setup} ... +Boards may support more than one JTAG configuration. +Examples include jumpers controlling pullups versus pulldowns +on the nTRST and/or nSRST signals, and choice of connectors +(e.g. which of two headers on the base board, +or one from a daughtercard). +For some Texas Instruments boards, you may need to jumper the +EMU0 and EMU1 signals (which OpenOCD won't currently control). + +@item @b{Boot Modes} ... +Complex chips often support multiple boot modes, controlled +by external jumpers. Make sure this is set up correctly. +For example many i.MX boards from NXP need to be jumpered +to "ATX mode" to start booting using the on-chip ROM, when +using second stage bootloader code stored in a NAND flash chip. + +Such explicit configuration is common, and not limited to +booting from NAND. You might also need to set jumpers to +start booting using code loaded from an MMC/SD card; external +SPI flash; Ethernet, UART, or USB links; NOR flash; OneNAND +flash; some external host; or various other sources. + + +@item @b{Memory Addressing} ... +Boards which support multiple boot modes may also have jumpers +to configure memory addressing. One board, for example, jumpers +external chipselect 0 (used for booting) to address either +a large SRAM (which must be pre-loaded via JTAG), NOR flash, +or NAND flash. When it's jumpered to address NAND flash, that +board must also be told to start booting from on-chip ROM. + +Your @file{board.cfg} file may also need to be told this jumper +configuration, so that it can know whether to declare NOR flash +using @command{flash bank} or instead declare NAND flash with +@command{nand device}; and likewise which probe to perform in +its @code{reset-init} handler. + +A closely related issue is bus width. Jumpers might need to +distinguish between 8 bit or 16 bit bus access for the flash +used to start booting. + +@item @b{Peripheral Access} ... +Development boards generally provide access to every peripheral +on the chip, sometimes in multiple modes (such as by providing +multiple audio codec chips). +This interacts with software +configuration of pin multiplexing, where for example a +given pin may be routed either to the MMC/SD controller +or the GPIO controller. It also often interacts with +configuration jumpers. One jumper may be used to route +signals to an MMC/SD card slot or an expansion bus (which +might in turn affect booting); others might control which +audio or video codecs are used. + +@end itemize + +Plus you should of course have @code{reset-init} event handlers +which set up the hardware to match that jumper configuration. +That includes in particular any oscillator or PLL used to clock +the CPU, and any memory controllers needed to access external +memory and peripherals. Without such handlers, you won't be +able to access those resources without working target firmware +which can do that setup ... this can be awkward when you're +trying to debug that target firmware. Even if there's a ROM +bootloader which handles a few issues, it rarely provides full +access to all board-specific capabilities. + + +@node Config File Guidelines +@chapter Config File Guidelines + +This chapter is aimed at any user who needs to write a config file, +including developers and integrators of OpenOCD and any user who +needs to get a new board working smoothly. +It provides guidelines for creating those files. + +You should find the following directories under @t{$(INSTALLDIR)/scripts}, +with files including the ones listed here. +Use them as-is where you can; or as models for new files. +@itemize @bullet +@item @file{interface} ... +These are for debug adapters. +Files that configure JTAG adapters go here. +@example +$ ls interface -R +interface/: +altera-usb-blaster.cfg hilscher_nxhx50_re.cfg openocd-usb-hs.cfg +arm-jtag-ew.cfg hitex_str9-comstick.cfg openrd.cfg +at91rm9200.cfg icebear.cfg osbdm.cfg +axm0432.cfg jlink.cfg parport.cfg +busblaster.cfg jtagkey2.cfg parport_dlc5.cfg +buspirate.cfg jtagkey2p.cfg redbee-econotag.cfg +calao-usb-a9260-c01.cfg jtagkey.cfg redbee-usb.cfg +calao-usb-a9260-c02.cfg jtagkey-tiny.cfg rlink.cfg +calao-usb-a9260.cfg jtag-lock-pick_tiny_2.cfg sheevaplug.cfg +chameleon.cfg kt-link.cfg signalyzer.cfg +cortino.cfg lisa-l.cfg signalyzer-h2.cfg +digilent-hs1.cfg luminary.cfg signalyzer-h4.cfg +dlp-usb1232h.cfg luminary-icdi.cfg signalyzer-lite.cfg +dummy.cfg luminary-lm3s811.cfg stlink-v1.cfg +estick.cfg minimodule.cfg stlink-v2.cfg +flashlink.cfg neodb.cfg stm32-stick.cfg +flossjtag.cfg ngxtech.cfg sysfsgpio-raspberrypi.cfg +flossjtag-noeeprom.cfg olimex-arm-usb-ocd.cfg ti-icdi.cfg +flyswatter2.cfg olimex-arm-usb-ocd-h.cfg turtelizer2.cfg +flyswatter.cfg olimex-arm-usb-tiny-h.cfg ulink.cfg +ftdi olimex-jtag-tiny.cfg usb-jtag.cfg +hilscher_nxhx10_etm.cfg oocdlink.cfg usbprog.cfg +hilscher_nxhx500_etm.cfg opendous.cfg vpaclink.cfg +hilscher_nxhx500_re.cfg opendous_ftdi.cfg vsllink.cfg +hilscher_nxhx50_etm.cfg openocd-usb.cfg xds100v2.cfg + +interface/ftdi: +axm0432.cfg icebear.cfg oocdlink.cfg +calao-usb-a9260-c01.cfg jtagkey2.cfg opendous_ftdi.cfg +calao-usb-a9260-c02.cfg jtagkey2p.cfg openocd-usb.cfg +cortino.cfg jtagkey.cfg openocd-usb-hs.cfg +dlp-usb1232h.cfg jtag-lock-pick_tiny_2.cfg openrd.cfg +dp_busblaster.cfg kt-link.cfg redbee-econotag.cfg +flossjtag.cfg lisa-l.cfg redbee-usb.cfg +flossjtag-noeeprom.cfg luminary.cfg sheevaplug.cfg +flyswatter2.cfg luminary-icdi.cfg signalyzer.cfg +flyswatter.cfg luminary-lm3s811.cfg signalyzer-lite.cfg +hilscher_nxhx10_etm.cfg minimodule.cfg stm32-stick.cfg +hilscher_nxhx500_etm.cfg neodb.cfg turtelizer2-revB.cfg +hilscher_nxhx500_re.cfg ngxtech.cfg turtelizer2-revC.cfg +hilscher_nxhx50_etm.cfg olimex-arm-usb-ocd.cfg vpaclink.cfg +hilscher_nxhx50_re.cfg olimex-arm-usb-ocd-h.cfg xds100v2.cfg +hitex_lpc1768stick.cfg olimex-arm-usb-tiny-h.cfg +hitex_str9-comstick.cfg olimex-jtag-tiny.cfg +$ +@end example +@item @file{board} ... +think Circuit Board, PWA, PCB, they go by many names. Board files +contain initialization items that are specific to a board. +They reuse target configuration files, since the same +microprocessor chips are used on many boards, +but support for external parts varies widely. For +example, the SDRAM initialization sequence for the board, or the type +of external flash and what address it uses. Any initialization +sequence to enable that external flash or SDRAM should be found in the +board file. Boards may also contain multiple targets: two CPUs; or +a CPU and an FPGA. +@example +$ ls board +actux3.cfg lpc1850_spifi_generic.cfg +am3517evm.cfg lpc4350_spifi_generic.cfg +arm_evaluator7t.cfg lubbock.cfg +at91cap7a-stk-sdram.cfg mcb1700.cfg +at91eb40a.cfg microchip_explorer16.cfg +at91rm9200-dk.cfg mini2440.cfg +at91rm9200-ek.cfg mini6410.cfg +at91sam9261-ek.cfg netgear-dg834v3.cfg +at91sam9263-ek.cfg olimex_LPC2378STK.cfg +at91sam9g20-ek.cfg olimex_lpc_h2148.cfg +atmel_at91sam7s-ek.cfg olimex_sam7_ex256.cfg +atmel_at91sam9260-ek.cfg olimex_sam9_l9260.cfg +atmel_at91sam9rl-ek.cfg olimex_stm32_h103.cfg +atmel_sam3n_ek.cfg olimex_stm32_h107.cfg +atmel_sam3s_ek.cfg olimex_stm32_p107.cfg +atmel_sam3u_ek.cfg omap2420_h4.cfg +atmel_sam3x_ek.cfg open-bldc.cfg +atmel_sam4s_ek.cfg openrd.cfg +balloon3-cpu.cfg osk5912.cfg +colibri.cfg phone_se_j100i.cfg +crossbow_tech_imote2.cfg phytec_lpc3250.cfg +csb337.cfg pic-p32mx.cfg +csb732.cfg propox_mmnet1001.cfg +da850evm.cfg pxa255_sst.cfg +digi_connectcore_wi-9c.cfg redbee.cfg +diolan_lpc4350-db1.cfg rsc-w910.cfg +dm355evm.cfg sheevaplug.cfg +dm365evm.cfg smdk6410.cfg +dm6446evm.cfg spear300evb.cfg +efikamx.cfg spear300evb_mod.cfg +eir.cfg spear310evb20.cfg +ek-lm3s1968.cfg spear310evb20_mod.cfg +ek-lm3s3748.cfg spear320cpu.cfg +ek-lm3s6965.cfg spear320cpu_mod.cfg +ek-lm3s811.cfg steval_pcc010.cfg +ek-lm3s811-revb.cfg stm320518_eval_stlink.cfg +ek-lm3s8962.cfg stm32100b_eval.cfg +ek-lm3s9b9x.cfg stm3210b_eval.cfg +ek-lm3s9d92.cfg stm3210c_eval.cfg +ek-lm4f120xl.cfg stm3210e_eval.cfg +ek-lm4f232.cfg stm3220g_eval.cfg +embedded-artists_lpc2478-32.cfg stm3220g_eval_stlink.cfg +ethernut3.cfg stm3241g_eval.cfg +glyn_tonga2.cfg stm3241g_eval_stlink.cfg +hammer.cfg stm32f0discovery.cfg +hilscher_nxdb500sys.cfg stm32f3discovery.cfg +hilscher_nxeb500hmi.cfg stm32f4discovery.cfg +hilscher_nxhx10.cfg stm32ldiscovery.cfg +hilscher_nxhx500.cfg stm32vldiscovery.cfg +hilscher_nxhx50.cfg str910-eval.cfg +hilscher_nxsb100.cfg telo.cfg +hitex_lpc1768stick.cfg ti_am335xevm.cfg +hitex_lpc2929.cfg ti_beagleboard.cfg +hitex_stm32-performancestick.cfg ti_beagleboard_xm.cfg +hitex_str9-comstick.cfg ti_beaglebone.cfg +iar_lpc1768.cfg ti_blaze.cfg +iar_str912_sk.cfg ti_pandaboard.cfg +icnova_imx53_sodimm.cfg ti_pandaboard_es.cfg +icnova_sam9g45_sodimm.cfg topas910.cfg +imx27ads.cfg topasa900.cfg +imx27lnst.cfg twr-k60f120m.cfg +imx28evk.cfg twr-k60n512.cfg +imx31pdk.cfg tx25_stk5.cfg +imx35pdk.cfg tx27_stk5.cfg +imx53loco.cfg unknown_at91sam9260.cfg +keil_mcb1700.cfg uptech_2410.cfg +keil_mcb2140.cfg verdex.cfg +kwikstik.cfg voipac.cfg +linksys_nslu2.cfg voltcraft_dso-3062c.cfg +lisa-l.cfg x300t.cfg +logicpd_imx27.cfg zy1000.cfg +$ +@end example +@item @file{target} ... +think chip. The ``target'' directory represents the JTAG TAPs +on a chip +which OpenOCD should control, not a board. Two common types of targets +are ARM chips and FPGA or CPLD chips. +When a chip has multiple TAPs (maybe it has both ARM and DSP cores), +the target config file defines all of them. +@example +$ ls target +aduc702x.cfg lpc1763.cfg +am335x.cfg lpc1764.cfg +amdm37x.cfg lpc1765.cfg +ar71xx.cfg lpc1766.cfg +at32ap7000.cfg lpc1767.cfg +at91r40008.cfg lpc1768.cfg +at91rm9200.cfg lpc1769.cfg +at91sam3ax_4x.cfg lpc1788.cfg +at91sam3ax_8x.cfg lpc17xx.cfg +at91sam3ax_xx.cfg lpc1850.cfg +at91sam3nXX.cfg lpc2103.cfg +at91sam3sXX.cfg lpc2124.cfg +at91sam3u1c.cfg lpc2129.cfg +at91sam3u1e.cfg lpc2148.cfg +at91sam3u2c.cfg lpc2294.cfg +at91sam3u2e.cfg lpc2378.cfg +at91sam3u4c.cfg lpc2460.cfg +at91sam3u4e.cfg lpc2478.cfg +at91sam3uxx.cfg lpc2900.cfg +at91sam3XXX.cfg lpc2xxx.cfg +at91sam4sd32x.cfg lpc3131.cfg +at91sam4sXX.cfg lpc3250.cfg +at91sam4XXX.cfg lpc4350.cfg +at91sam7se512.cfg lpc4350.cfg.orig +at91sam7sx.cfg mc13224v.cfg +at91sam7x256.cfg nuc910.cfg +at91sam7x512.cfg omap2420.cfg +at91sam9260.cfg omap3530.cfg +at91sam9260_ext_RAM_ext_flash.cfg omap4430.cfg +at91sam9261.cfg omap4460.cfg +at91sam9263.cfg omap5912.cfg +at91sam9.cfg omapl138.cfg +at91sam9g10.cfg pic32mx.cfg +at91sam9g20.cfg pxa255.cfg +at91sam9g45.cfg pxa270.cfg +at91sam9rl.cfg pxa3xx.cfg +atmega128.cfg readme.txt +avr32.cfg samsung_s3c2410.cfg +c100.cfg samsung_s3c2440.cfg +c100config.tcl samsung_s3c2450.cfg +c100helper.tcl samsung_s3c4510.cfg +c100regs.tcl samsung_s3c6410.cfg +cs351x.cfg sharp_lh79532.cfg +davinci.cfg smp8634.cfg +dragonite.cfg spear3xx.cfg +dsp56321.cfg stellaris.cfg +dsp568013.cfg stellaris_icdi.cfg +dsp568037.cfg stm32f0x_stlink.cfg +efm32_stlink.cfg stm32f1x.cfg +epc9301.cfg stm32f1x_stlink.cfg +faux.cfg stm32f2x.cfg +feroceon.cfg stm32f2x_stlink.cfg +fm3.cfg stm32f3x.cfg +hilscher_netx10.cfg stm32f3x_stlink.cfg +hilscher_netx500.cfg stm32f4x.cfg +hilscher_netx50.cfg stm32f4x_stlink.cfg +icepick.cfg stm32l.cfg +imx21.cfg stm32lx_dual_bank.cfg +imx25.cfg stm32lx_stlink.cfg +imx27.cfg stm32_stlink.cfg +imx28.cfg stm32w108_stlink.cfg +imx31.cfg stm32xl.cfg +imx35.cfg str710.cfg +imx51.cfg str730.cfg +imx53.cfg str750.cfg +imx6.cfg str912.cfg +imx.cfg swj-dp.tcl +is5114.cfg test_reset_syntax_error.cfg +ixp42x.cfg test_syntax_error.cfg +k40.cfg ti-ar7.cfg +k60.cfg ti_calypso.cfg +lpc1751.cfg ti_dm355.cfg +lpc1752.cfg ti_dm365.cfg +lpc1754.cfg ti_dm6446.cfg +lpc1756.cfg tmpa900.cfg +lpc1758.cfg tmpa910.cfg +lpc1759.cfg u8500.cfg +@end example +@item @emph{more} ... browse for other library files which may be useful. +For example, there are various generic and CPU-specific utilities. +@end itemize + +The @file{openocd.cfg} user config +file may override features in any of the above files by +setting variables before sourcing the target file, or by adding +commands specific to their situation. + +@section Interface Config Files + +The user config file +should be able to source one of these files with a command like this: + +@example +source [find interface/FOOBAR.cfg] +@end example + +A preconfigured interface file should exist for every debug adapter +in use today with OpenOCD. +That said, perhaps some of these config files +have only been used by the developer who created it. + +A separate chapter gives information about how to set these up. +@xref{Debug Adapter Configuration}. +Read the OpenOCD source code (and Developer's Guide) +if you have a new kind of hardware interface +and need to provide a driver for it. + +@section Board Config Files +@cindex config file, board +@cindex board config file + +The user config file +should be able to source one of these files with a command like this: + +@example +source [find board/FOOBAR.cfg] +@end example + +The point of a board config file is to package everything +about a given board that user config files need to know. +In summary the board files should contain (if present) + +@enumerate +@item One or more @command{source [target/...cfg]} statements +@item NOR flash configuration (@pxref{norconfiguration,,NOR Configuration}) +@item NAND flash configuration (@pxref{nandconfiguration,,NAND Configuration}) +@item Target @code{reset} handlers for SDRAM and I/O configuration +@item JTAG adapter reset configuration (@pxref{Reset Configuration}) +@item All things that are not ``inside a chip'' +@end enumerate + +Generic things inside target chips belong in target config files, +not board config files. So for example a @code{reset-init} event +handler should know board-specific oscillator and PLL parameters, +which it passes to target-specific utility code. + +The most complex task of a board config file is creating such a +@code{reset-init} event handler. +Define those handlers last, after you verify the rest of the board +configuration works. + +@subsection Communication Between Config files + +In addition to target-specific utility code, another way that +board and target config files communicate is by following a +convention on how to use certain variables. + +The full Tcl/Tk language supports ``namespaces'', but Jim-Tcl does not. +Thus the rule we follow in OpenOCD is this: Variables that begin with +a leading underscore are temporary in nature, and can be modified and +used at will within a target configuration file. + +Complex board config files can do the things like this, +for a board with three chips: + +@example +# Chip #1: PXA270 for network side, big endian +set CHIPNAME network +set ENDIAN big +source [find target/pxa270.cfg] +# on return: _TARGETNAME = network.cpu +# other commands can refer to the "network.cpu" target. +$_TARGETNAME configure .... events for this CPU.. + +# Chip #2: PXA270 for video side, little endian +set CHIPNAME video +set ENDIAN little +source [find target/pxa270.cfg] +# on return: _TARGETNAME = video.cpu +# other commands can refer to the "video.cpu" target. +$_TARGETNAME configure .... events for this CPU.. + +# Chip #3: Xilinx FPGA for glue logic +set CHIPNAME xilinx +unset ENDIAN +source [find target/spartan3.cfg] +@end example + +That example is oversimplified because it doesn't show any flash memory, +or the @code{reset-init} event handlers to initialize external DRAM +or (assuming it needs it) load a configuration into the FPGA. +Such features are usually needed for low-level work with many boards, +where ``low level'' implies that the board initialization software may +not be working. (That's a common reason to need JTAG tools. Another +is to enable working with microcontroller-based systems, which often +have no debugging support except a JTAG connector.) + +Target config files may also export utility functions to board and user +config files. Such functions should use name prefixes, to help avoid +naming collisions. + +Board files could also accept input variables from user config files. +For example, there might be a @code{J4_JUMPER} setting used to identify +what kind of flash memory a development board is using, or how to set +up other clocks and peripherals. + +@subsection Variable Naming Convention +@cindex variable names + +Most boards have only one instance of a chip. +However, it should be easy to create a board with more than +one such chip (as shown above). +Accordingly, we encourage these conventions for naming +variables associated with different @file{target.cfg} files, +to promote consistency and +so that board files can override target defaults. + +Inputs to target config files include: + +@itemize @bullet +@item @code{CHIPNAME} ... +This gives a name to the overall chip, and is used as part of +tap identifier dotted names. +While the default is normally provided by the chip manufacturer, +board files may need to distinguish between instances of a chip. +@item @code{ENDIAN} ... +By default @option{little} - although chips may hard-wire @option{big}. +Chips that can't change endianness don't need to use this variable. +@item @code{CPUTAPID} ... +When OpenOCD examines the JTAG chain, it can be told verify the +chips against the JTAG IDCODE register. +The target file will hold one or more defaults, but sometimes the +chip in a board will use a different ID (perhaps a newer revision). +@end itemize + +Outputs from target config files include: + +@itemize @bullet +@item @code{_TARGETNAME} ... +By convention, this variable is created by the target configuration +script. The board configuration file may make use of this variable to +configure things like a ``reset init'' script, or other things +specific to that board and that target. +If the chip has 2 targets, the names are @code{_TARGETNAME0}, +@code{_TARGETNAME1}, ... etc. +@end itemize + +@subsection The reset-init Event Handler +@cindex event, reset-init +@cindex reset-init handler + +Board config files run in the OpenOCD configuration stage; +they can't use TAPs or targets, since they haven't been +fully set up yet. +This means you can't write memory or access chip registers; +you can't even verify that a flash chip is present. +That's done later in event handlers, of which the target @code{reset-init} +handler is one of the most important. + +Except on microcontrollers, the basic job of @code{reset-init} event +handlers is setting up flash and DRAM, as normally handled by boot loaders. +Microcontrollers rarely use boot loaders; they run right out of their +on-chip flash and SRAM memory. But they may want to use one of these +handlers too, if just for developer convenience. + +@quotation Note +Because this is so very board-specific, and chip-specific, no examples +are included here. +Instead, look at the board config files distributed with OpenOCD. +If you have a boot loader, its source code will help; so will +configuration files for other JTAG tools +(@pxref{translatingconfigurationfiles,,Translating Configuration Files}). +@end quotation + +Some of this code could probably be shared between different boards. +For example, setting up a DRAM controller often doesn't differ by +much except the bus width (16 bits or 32?) and memory timings, so a +reusable TCL procedure loaded by the @file{target.cfg} file might take +those as parameters. +Similarly with oscillator, PLL, and clock setup; +and disabling the watchdog. +Structure the code cleanly, and provide comments to help +the next developer doing such work. +(@emph{You might be that next person} trying to reuse init code!) + +The last thing normally done in a @code{reset-init} handler is probing +whatever flash memory was configured. For most chips that needs to be +done while the associated target is halted, either because JTAG memory +access uses the CPU or to prevent conflicting CPU access. + +@subsection JTAG Clock Rate + +Before your @code{reset-init} handler has set up +the PLLs and clocking, you may need to run with +a low JTAG clock rate. +@xref{jtagspeed,,JTAG Speed}. +Then you'd increase that rate after your handler has +made it possible to use the faster JTAG clock. +When the initial low speed is board-specific, for example +because it depends on a board-specific oscillator speed, then +you should probably set it up in the board config file; +if it's target-specific, it belongs in the target config file. + +For most ARM-based processors the fastest JTAG clock@footnote{A FAQ +@uref{http://www.arm.com/support/faqdev/4170.html} gives details.} +is one sixth of the CPU clock; or one eighth for ARM11 cores. +Consult chip documentation to determine the peak JTAG clock rate, +which might be less than that. + +@quotation Warning +On most ARMs, JTAG clock detection is coupled to the core clock, so +software using a @option{wait for interrupt} operation blocks JTAG access. +Adaptive clocking provides a partial workaround, but a more complete +solution just avoids using that instruction with JTAG debuggers. +@end quotation + +If both the chip and the board support adaptive clocking, +use the @command{jtag_rclk} +command, in case your board is used with JTAG adapter which +also supports it. Otherwise use @command{adapter_khz}. +Set the slow rate at the beginning of the reset sequence, +and the faster rate as soon as the clocks are at full speed. + +@anchor{theinitboardprocedure} +@subsection The init_board procedure +@cindex init_board procedure + +The concept of @code{init_board} procedure is very similar to @code{init_targets} +(@xref{theinittargetsprocedure,,The init_targets procedure}.) - it's a replacement of ``linear'' +configuration scripts. This procedure is meant to be executed when OpenOCD enters run stage +(@xref{enteringtherunstage,,Entering the Run Stage},) after @code{init_targets}. The idea to have +spearate @code{init_targets} and @code{init_board} procedures is to allow the first one to configure +everything target specific (internal flash, internal RAM, etc.) and the second one to configure +everything board specific (reset signals, chip frequency, reset-init event handler, external memory, etc.). +Additionally ``linear'' board config file will most likely fail when target config file uses +@code{init_targets} scheme (``linear'' script is executed before @code{init} and @code{init_targets} - after), +so separating these two configuration stages is very convenient, as the easiest way to overcome this +problem is to convert board config file to use @code{init_board} procedure. Board config scripts don't +need to override @code{init_targets} defined in target config files when they only need to to add some specifics. + +Just as @code{init_targets}, the @code{init_board} procedure can be overriden by ``next level'' script (which sources +the original), allowing greater code reuse. + +@example +### board_file.cfg ### + +# source target file that does most of the config in init_targets +source [find target/target.cfg] + +proc enable_fast_clock @{@} @{ + # enables fast on-board clock source + # configures the chip to use it +@} + +# initialize only board specifics - reset, clock, adapter frequency +proc init_board @{@} @{ + reset_config trst_and_srst trst_pulls_srst + + $_TARGETNAME configure -event reset-init @{ + adapter_khz 1 + enable_fast_clock + adapter_khz 10000 + @} +@} +@end example + +@section Target Config Files +@cindex config file, target +@cindex target config file + +Board config files communicate with target config files using +naming conventions as described above, and may source one or +more target config files like this: + +@example +source [find target/FOOBAR.cfg] +@end example + +The point of a target config file is to package everything +about a given chip that board config files need to know. +In summary the target files should contain + +@enumerate +@item Set defaults +@item Add TAPs to the scan chain +@item Add CPU targets (includes GDB support) +@item CPU/Chip/CPU-Core specific features +@item On-Chip flash +@end enumerate + +As a rule of thumb, a target file sets up only one chip. +For a microcontroller, that will often include a single TAP, +which is a CPU needing a GDB target, and its on-chip flash. + +More complex chips may include multiple TAPs, and the target +config file may need to define them all before OpenOCD +can talk to the chip. +For example, some phone chips have JTAG scan chains that include +an ARM core for operating system use, a DSP, +another ARM core embedded in an image processing engine, +and other processing engines. + +@subsection Default Value Boiler Plate Code + +All target configuration files should start with code like this, +letting board config files express environment-specific +differences in how things should be set up. + +@example +# Boards may override chip names, perhaps based on role, +# but the default should match what the vendor uses +if @{ [info exists CHIPNAME] @} @{ + set _CHIPNAME $CHIPNAME +@} else @{ + set _CHIPNAME sam7x256 +@} + +# ONLY use ENDIAN with targets that can change it. +if @{ [info exists ENDIAN] @} @{ + set _ENDIAN $ENDIAN +@} else @{ + set _ENDIAN little +@} + +# TAP identifiers may change as chips mature, for example with +# new revision fields (the "3" here). Pick a good default; you +# can pass several such identifiers to the "jtag newtap" command. +if @{ [info exists CPUTAPID ] @} @{ + set _CPUTAPID $CPUTAPID +@} else @{ + set _CPUTAPID 0x3f0f0f0f +@} +@end example +@c but 0x3f0f0f0f is for an str73x part ... + +@emph{Remember:} Board config files may include multiple target +config files, or the same target file multiple times +(changing at least @code{CHIPNAME}). + +Likewise, the target configuration file should define +@code{_TARGETNAME} (or @code{_TARGETNAME0} etc) and +use it later on when defining debug targets: + +@example +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME +@end example + +@subsection Adding TAPs to the Scan Chain +After the ``defaults'' are set up, +add the TAPs on each chip to the JTAG scan chain. +@xref{TAP Declaration}, and the naming convention +for taps. + +In the simplest case the chip has only one TAP, +probably for a CPU or FPGA. +The config file for the Atmel AT91SAM7X256 +looks (in part) like this: + +@example +jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID +@end example + +A board with two such at91sam7 chips would be able +to source such a config file twice, with different +values for @code{CHIPNAME}, so +it adds a different TAP each time. + +If there are nonzero @option{-expected-id} values, +OpenOCD attempts to verify the actual tap id against those values. +It will issue error messages if there is mismatch, which +can help to pinpoint problems in OpenOCD configurations. + +@example +JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f + (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3) +ERROR: Tap: sam7x256.cpu - Expected id: 0x12345678, Got: 0x3f0f0f0f +ERROR: expected: mfg: 0x33c, part: 0x2345, ver: 0x1 +ERROR: got: mfg: 0x787, part: 0xf0f0, ver: 0x3 +@end example + +There are more complex examples too, with chips that have +multiple TAPs. Ones worth looking at include: + +@itemize +@item @file{target/omap3530.cfg} -- with disabled ARM and DSP, +plus a JRC to enable them +@item @file{target/str912.cfg} -- with flash, CPU, and boundary scan +@item @file{target/ti_dm355.cfg} -- with ETM, ARM, and JRC (this JRC +is not currently used) +@end itemize + +@subsection Add CPU targets + +After adding a TAP for a CPU, you should set it up so that +GDB and other commands can use it. +@xref{CPU Configuration}. +For the at91sam7 example above, the command can look like this; +note that @code{$_ENDIAN} is not needed, since OpenOCD defaults +to little endian, and this chip doesn't support changing that. + +@example +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME +@end example + +Work areas are small RAM areas associated with CPU targets. +They are used by OpenOCD to speed up downloads, +and to download small snippets of code to program flash chips. +If the chip includes a form of ``on-chip-ram'' - and many do - define +a work area if you can. +Again using the at91sam7 as an example, this can look like: + +@example +$_TARGETNAME configure -work-area-phys 0x00200000 \ + -work-area-size 0x4000 -work-area-backup 0 +@end example + +@anchor{definecputargetsworkinginsmp} +@subsection Define CPU targets working in SMP +@cindex SMP +After setting targets, you can define a list of targets working in SMP. + +@example +set _TARGETNAME_1 $_CHIPNAME.cpu1 +set _TARGETNAME_2 $_CHIPNAME.cpu2 +target create $_TARGETNAME_1 cortex_a -chain-position $_CHIPNAME.dap \ +-coreid 0 -dbgbase $_DAP_DBG1 +target create $_TARGETNAME_2 cortex_a -chain-position $_CHIPNAME.dap \ +-coreid 1 -dbgbase $_DAP_DBG2 +#define 2 targets working in smp. +target smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1 +@end example +In the above example on cortex_a, 2 cpus are working in SMP. +In SMP only one GDB instance is created and : +@itemize @bullet +@item a set of hardware breakpoint sets the same breakpoint on all targets in the list. +@item halt command triggers the halt of all targets in the list. +@item resume command triggers the write context and the restart of all targets in the list. +@item following a breakpoint: the target stopped by the breakpoint is displayed to the GDB session. +@item dedicated GDB serial protocol packets are implemented for switching/retrieving the target +displayed by the GDB session @pxref{usingopenocdsmpwithgdb,,Using OpenOCD SMP with GDB}. +@end itemize + +The SMP behaviour can be disabled/enabled dynamically. On cortex_a following +command have been implemented. +@itemize @bullet +@item cortex_a smp_on : enable SMP mode, behaviour is as described above. +@item cortex_a smp_off : disable SMP mode, the current target is the one +displayed in the GDB session, only this target is now controlled by GDB +session. This behaviour is useful during system boot up. +@item cortex_a smp_gdb : display/fix the core id displayed in GDB session see +following example. +@end itemize + +@example +>cortex_a smp_gdb +gdb coreid 0 -> -1 +#0 : coreid 0 is displayed to GDB , +#-> -1 : next resume triggers a real resume +> cortex_a smp_gdb 1 +gdb coreid 0 -> 1 +#0 :coreid 0 is displayed to GDB , +#->1 : next resume displays coreid 1 to GDB +> resume +> cortex_a smp_gdb +gdb coreid 1 -> 1 +#1 :coreid 1 is displayed to GDB , +#->1 : next resume displays coreid 1 to GDB +> cortex_a smp_gdb -1 +gdb coreid 1 -> -1 +#1 :coreid 1 is displayed to GDB, +#->-1 : next resume triggers a real resume +@end example + + +@subsection Chip Reset Setup + +As a rule, you should put the @command{reset_config} command +into the board file. Most things you think you know about a +chip can be tweaked by the board. + +Some chips have specific ways the TRST and SRST signals are +managed. In the unusual case that these are @emph{chip specific} +and can never be changed by board wiring, they could go here. +For example, some chips can't support JTAG debugging without +both signals. + +Provide a @code{reset-assert} event handler if you can. +Such a handler uses JTAG operations to reset the target, +letting this target config be used in systems which don't +provide the optional SRST signal, or on systems where you +don't want to reset all targets at once. +Such a handler might write to chip registers to force a reset, +use a JRC to do that (preferable -- the target may be wedged!), +or force a watchdog timer to trigger. +(For Cortex-M targets, this is not necessary. The target +driver knows how to use trigger an NVIC reset when SRST is +not available.) + +Some chips need special attention during reset handling if +they're going to be used with JTAG. +An example might be needing to send some commands right +after the target's TAP has been reset, providing a +@code{reset-deassert-post} event handler that writes a chip +register to report that JTAG debugging is being done. +Another would be reconfiguring the watchdog so that it stops +counting while the core is halted in the debugger. + +JTAG clocking constraints often change during reset, and in +some cases target config files (rather than board config files) +are the right places to handle some of those issues. +For example, immediately after reset most chips run using a +slower clock than they will use later. +That means that after reset (and potentially, as OpenOCD +first starts up) they must use a slower JTAG clock rate +than they will use later. +@xref{jtagspeed,,JTAG Speed}. + +@quotation Important +When you are debugging code that runs right after chip +reset, getting these issues right is critical. +In particular, if you see intermittent failures when +OpenOCD verifies the scan chain after reset, +look at how you are setting up JTAG clocking. +@end quotation + +@anchor{theinittargetsprocedure} +@subsection The init_targets procedure +@cindex init_targets procedure + +Target config files can either be ``linear'' (script executed line-by-line when parsed in +configuration stage, @xref{configurationstage,,Configuration Stage},) or they can contain a special +procedure called @code{init_targets}, which will be executed when entering run stage +(after parsing all config files or after @code{init} command, @xref{enteringtherunstage,,Entering the Run Stage}.) +Such procedure can be overriden by ``next level'' script (which sources the original). +This concept faciliates code reuse when basic target config files provide generic configuration +procedures and @code{init_targets} procedure, which can then be sourced and enchanced or changed in +a ``more specific'' target config file. This is not possible with ``linear'' config scripts, +because sourcing them executes every initialization commands they provide. + +@example +### generic_file.cfg ### + +proc setup_my_chip @{chip_name flash_size ram_size@} @{ + # basic initialization procedure ... +@} + +proc init_targets @{@} @{ + # initializes generic chip with 4kB of flash and 1kB of RAM + setup_my_chip MY_GENERIC_CHIP 4096 1024 +@} + +### specific_file.cfg ### + +source [find target/generic_file.cfg] + +proc init_targets @{@} @{ + # initializes specific chip with 128kB of flash and 64kB of RAM + setup_my_chip MY_CHIP_WITH_128K_FLASH_64KB_RAM 131072 65536 +@} +@end example + +The easiest way to convert ``linear'' config files to @code{init_targets} version is to +enclose every line of ``code'' (i.e. not @code{source} commands, procedures, etc.) in this procedure. + +For an example of this scheme see LPC2000 target config files. + +The @code{init_boards} procedure is a similar concept concerning board config files +(@xref{theinitboardprocedure,,The init_board procedure}.) + +@subsection ARM Core Specific Hacks + +If the chip has a DCC, enable it. If the chip is an ARM9 with some +special high speed download features - enable it. + +If present, the MMU, the MPU and the CACHE should be disabled. + +Some ARM cores are equipped with trace support, which permits +examination of the instruction and data bus activity. Trace +activity is controlled through an ``Embedded Trace Module'' (ETM) +on one of the core's scan chains. The ETM emits voluminous data +through a ``trace port''. (@xref{armhardwaretracing,,ARM Hardware Tracing}.) +If you are using an external trace port, +configure it in your board config file. +If you are using an on-chip ``Embedded Trace Buffer'' (ETB), +configure it in your target config file. + +@example +etm config $_TARGETNAME 16 normal full etb +etb config $_TARGETNAME $_CHIPNAME.etb +@end example + +@subsection Internal Flash Configuration + +This applies @b{ONLY TO MICROCONTROLLERS} that have flash built in. + +@b{Never ever} in the ``target configuration file'' define any type of +flash that is external to the chip. (For example a BOOT flash on +Chip Select 0.) Such flash information goes in a board file - not +the TARGET (chip) file. + +Examples: +@itemize @bullet +@item at91sam7x256 - has 256K flash YES enable it. +@item str912 - has flash internal YES enable it. +@item imx27 - uses boot flash on CS0 - it goes in the board file. +@item pxa270 - again - CS0 flash - it goes in the board file. +@end itemize + +@anchor{translatingconfigurationfiles} +@section Translating Configuration Files +@cindex translation +If you have a configuration file for another hardware debugger +or toolset (Abatron, BDI2000, BDI3000, CCS, +Lauterbach, Segger, Macraigor, etc.), translating +it into OpenOCD syntax is often quite straightforward. The most tricky +part of creating a configuration script is oftentimes the reset init +sequence where e.g. PLLs, DRAM and the like is set up. + +One trick that you can use when translating is to write small +Tcl procedures to translate the syntax into OpenOCD syntax. This +can avoid manual translation errors and make it easier to +convert other scripts later on. + +Example of transforming quirky arguments to a simple search and +replace job: + +@example +# Lauterbach syntax(?) +# +# Data.Set c15:0x042f %long 0x40000015 +# +# OpenOCD syntax when using procedure below. +# +# setc15 0x01 0x00050078 + +proc setc15 @{regs value@} @{ + global TARGETNAME + + echo [format "set p15 0x%04x, 0x%08x" $regs $value] + + arm mcr 15 [expr ($regs>>12)&0x7] \ + [expr ($regs>>0)&0xf] [expr ($regs>>4)&0xf] \ + [expr ($regs>>8)&0x7] $value +@} +@end example + + + +@node Daemon Configuration +@chapter Daemon Configuration +@cindex initialization +The commands here are commonly found in the openocd.cfg file and are +used to specify what TCP/IP ports are used, and how GDB should be +supported. + +@anchor{configurationstage} +@section Configuration Stage +@cindex configuration stage +@cindex config command + +When the OpenOCD server process starts up, it enters a +@emph{configuration stage} which is the only time that +certain commands, @emph{configuration commands}, may be issued. +Normally, configuration commands are only available +inside startup scripts. + +In this manual, the definition of a configuration command is +presented as a @emph{Config Command}, not as a @emph{Command} +which may be issued interactively. +The runtime @command{help} command also highlights configuration +commands, and those which may be issued at any time. + +Those configuration commands include declaration of TAPs, +flash banks, +the interface used for JTAG communication, +and other basic setup. +The server must leave the configuration stage before it +may access or activate TAPs. +After it leaves this stage, configuration commands may no +longer be issued. + +@anchor{enteringtherunstage} +@section Entering the Run Stage + +The first thing OpenOCD does after leaving the configuration +stage is to verify that it can talk to the scan chain +(list of TAPs) which has been configured. +It will warn if it doesn't find TAPs it expects to find, +or finds TAPs that aren't supposed to be there. +You should see no errors at this point. +If you see errors, resolve them by correcting the +commands you used to configure the server. +Common errors include using an initial JTAG speed that's too +fast, and not providing the right IDCODE values for the TAPs +on the scan chain. + +Once OpenOCD has entered the run stage, a number of commands +become available. +A number of these relate to the debug targets you may have declared. +For example, the @command{mww} command will not be available until +a target has been successfuly instantiated. +If you want to use those commands, you may need to force +entry to the run stage. + +@deffn {Config Command} init +This command terminates the configuration stage and +enters the run stage. This helps when you need to have +the startup scripts manage tasks such as resetting the target, +programming flash, etc. To reset the CPU upon startup, add "init" and +"reset" at the end of the config script or at the end of the OpenOCD +command line using the @option{-c} command line switch. + +If this command does not appear in any startup/configuration file +OpenOCD executes the command for you after processing all +configuration files and/or command line options. + +@b{NOTE:} This command normally occurs at or near the end of your +openocd.cfg file to force OpenOCD to ``initialize'' and make the +targets ready. For example: If your openocd.cfg file needs to +read/write memory on your target, @command{init} must occur before +the memory read/write commands. This includes @command{nand probe}. +@end deffn + +@deffn {Overridable Procedure} jtag_init +This is invoked at server startup to verify that it can talk +to the scan chain (list of TAPs) which has been configured. + +The default implementation first tries @command{jtag arp_init}, +which uses only a lightweight JTAG reset before examining the +scan chain. +If that fails, it tries again, using a harder reset +from the overridable procedure @command{init_reset}. + +Implementations must have verified the JTAG scan chain before +they return. +This is done by calling @command{jtag arp_init} +(or @command{jtag arp_init-reset}). +@end deffn + +@anchor{tcpipports} +@section TCP/IP Ports +@cindex TCP port +@cindex server +@cindex port +@cindex security +The OpenOCD server accepts remote commands in several syntaxes. +Each syntax uses a different TCP/IP port, which you may specify +only during configuration (before those ports are opened). + +For reasons including security, you may wish to prevent remote +access using one or more of these ports. +In such cases, just specify the relevant port number as zero. +If you disable all access through TCP/IP, you will need to +use the command line @option{-pipe} option. + +@deffn {Command} gdb_port [number] +@cindex GDB server +Normally gdb listens to a TCP/IP port, but GDB can also +communicate via pipes(stdin/out or named pipes). The name +"gdb_port" stuck because it covers probably more than 90% of +the normal use cases. + +No arguments reports GDB port. "pipe" means listen to stdin +output to stdout, an integer is base port number, "disable" +disables the gdb server. + +When using "pipe", also use log_output to redirect the log +output to a file so as not to flood the stdin/out pipes. + +The -p/--pipe option is deprecated and a warning is printed +as it is equivalent to passing in -c "gdb_port pipe; log_output openocd.log". + +Any other string is interpreted as named pipe to listen to. +Output pipe is the same name as input pipe, but with 'o' appended, +e.g. /var/gdb, /var/gdbo. + +The GDB port for the first target will be the base port, the +second target will listen on gdb_port + 1, and so on. +When not specified during the configuration stage, +the port @var{number} defaults to 3333. +@end deffn + +@deffn {Command} tcl_port [number] +Specify or query the port used for a simplified RPC +connection that can be used by clients to issue TCL commands and get the +output from the Tcl engine. +Intended as a machine interface. +When not specified during the configuration stage, +the port @var{number} defaults to 6666. + +@end deffn + +@deffn {Command} telnet_port [number] +Specify or query the +port on which to listen for incoming telnet connections. +This port is intended for interaction with one human through TCL commands. +When not specified during the configuration stage, +the port @var{number} defaults to 4444. +When specified as zero, this port is not activated. +@end deffn + +@anchor{gdbconfiguration} +@section GDB Configuration +@cindex GDB +@cindex GDB configuration +You can reconfigure some GDB behaviors if needed. +The ones listed here are static and global. +@xref{targetconfiguration,,Target Configuration}, about configuring individual targets. +@xref{targetevents,,Target Events}, about configuring target-specific event handling. + +@anchor{gdbbreakpointoverride} +@deffn {Command} gdb_breakpoint_override [@option{hard}|@option{soft}|@option{disable}] +Force breakpoint type for gdb @command{break} commands. +This option supports GDB GUIs which don't +distinguish hard versus soft breakpoints, if the default OpenOCD and +GDB behaviour is not sufficient. GDB normally uses hardware +breakpoints if the memory map has been set up for flash regions. +@end deffn + +@anchor{gdbflashprogram} +@deffn {Config Command} gdb_flash_program (@option{enable}|@option{disable}) +Set to @option{enable} to cause OpenOCD to program the flash memory when a +vFlash packet is received. +The default behaviour is @option{enable}. +@end deffn + +@deffn {Config Command} gdb_memory_map (@option{enable}|@option{disable}) +Set to @option{enable} to cause OpenOCD to send the memory configuration to GDB when +requested. GDB will then know when to set hardware breakpoints, and program flash +using the GDB load command. @command{gdb_flash_program enable} must also be enabled +for flash programming to work. +Default behaviour is @option{enable}. +@xref{gdbflashprogram,,gdb_flash_program}. +@end deffn + +@deffn {Config Command} gdb_report_data_abort (@option{enable}|@option{disable}) +Specifies whether data aborts cause an error to be reported +by GDB memory read packets. +The default behaviour is @option{disable}; +use @option{enable} see these errors reported. +@end deffn + +@anchor{eventpolling} +@section Event Polling + +Hardware debuggers are parts of asynchronous systems, +where significant events can happen at any time. +The OpenOCD server needs to detect some of these events, +so it can report them to through TCL command line +or to GDB. + +Examples of such events include: + +@itemize +@item One of the targets can stop running ... maybe it triggers +a code breakpoint or data watchpoint, or halts itself. +@item Messages may be sent over ``debug message'' channels ... many +targets support such messages sent over JTAG, +for receipt by the person debugging or tools. +@item Loss of power ... some adapters can detect these events. +@item Resets not issued through JTAG ... such reset sources +can include button presses or other system hardware, sometimes +including the target itself (perhaps through a watchdog). +@item Debug instrumentation sometimes supports event triggering +such as ``trace buffer full'' (so it can quickly be emptied) +or other signals (to correlate with code behavior). +@end itemize + +None of those events are signaled through standard JTAG signals. +However, most conventions for JTAG connectors include voltage +level and system reset (SRST) signal detection. +Some connectors also include instrumentation signals, which +can imply events when those signals are inputs. + +In general, OpenOCD needs to periodically check for those events, +either by looking at the status of signals on the JTAG connector +or by sending synchronous ``tell me your status'' JTAG requests +to the various active targets. +There is a command to manage and monitor that polling, +which is normally done in the background. + +@deffn Command poll [@option{on}|@option{off}] +Poll the current target for its current state. +(Also, @pxref{targetcurstate,,target curstate}.) +If that target is in debug mode, architecture +specific information about the current state is printed. +An optional parameter +allows background polling to be enabled and disabled. + +You could use this from the TCL command shell, or +from GDB using @command{monitor poll} command. +Leave background polling enabled while you're using GDB. +@example +> poll +background polling: on +target state: halted +target halted in ARM state due to debug-request, \ + current mode: Supervisor +cpsr: 0x800000d3 pc: 0x11081bfc +MMU: disabled, D-Cache: disabled, I-Cache: enabled +> +@end example +@end deffn + +@node Debug Adapter Configuration +@chapter Debug Adapter Configuration +@cindex config file, interface +@cindex interface config file + +Correctly installing OpenOCD includes making your operating system give +OpenOCD access to debug adapters. Once that has been done, Tcl commands +are used to select which one is used, and to configure how it is used. + +@quotation Note +Because OpenOCD started out with a focus purely on JTAG, you may find +places where it wrongly presumes JTAG is the only transport protocol +in use. Be aware that recent versions of OpenOCD are removing that +limitation. JTAG remains more functional than most other transports. +Other transports do not support boundary scan operations, or may be +specific to a given chip vendor. Some might be usable only for +programming flash memory, instead of also for debugging. +@end quotation + +Debug Adapters/Interfaces/Dongles are normally configured +through commands in an interface configuration +file which is sourced by your @file{openocd.cfg} file, or +through a command line @option{-f interface/....cfg} option. + +@example +source [find interface/olimex-jtag-tiny.cfg] +@end example + +These commands tell +OpenOCD what type of JTAG adapter you have, and how to talk to it. +A few cases are so simple that you only need to say what driver to use: + +@example +# jlink interface +interface jlink +@end example + +Most adapters need a bit more configuration than that. + + +@section Interface Configuration + +The interface command tells OpenOCD what type of debug adapter you are +using. Depending on the type of adapter, you may need to use one or +more additional commands to further identify or configure the adapter. + +@deffn {Config Command} {interface} name +Use the interface driver @var{name} to connect to the +target. +@end deffn + +@deffn Command {interface_list} +List the debug adapter drivers that have been built into +the running copy of OpenOCD. +@end deffn +@deffn Command {interface transports} transport_name+ +Specifies the transports supported by this debug adapter. +The adapter driver builds-in similar knowledge; use this only +when external configuration (such as jumpering) changes what +the hardware can support. +@end deffn + + + +@deffn Command {adapter_name} +Returns the name of the debug adapter driver being used. +@end deffn + +@section Interface Drivers + +Each of the interface drivers listed here must be explicitly +enabled when OpenOCD is configured, in order to be made +available at run time. + +@deffn {Interface Driver} {amt_jtagaccel} +Amontec Chameleon in its JTAG Accelerator configuration, +connected to a PC's EPP mode parallel port. +This defines some driver-specific commands: + +@deffn {Config Command} {parport_port} number +Specifies either the address of the I/O port (default: 0x378 for LPT1) or +the number of the @file{/dev/parport} device. +@end deffn + +@deffn {Config Command} rtck [@option{enable}|@option{disable}] +Displays status of RTCK option. +Optionally sets that option first. +@end deffn +@end deffn + +@deffn {Interface Driver} {arm-jtag-ew} +Olimex ARM-JTAG-EW USB adapter +This has one driver-specific command: + +@deffn Command {armjtagew_info} +Logs some status +@end deffn +@end deffn + +@deffn {Interface Driver} {at91rm9200} +Supports bitbanged JTAG from the local system, +presuming that system is an Atmel AT91rm9200 +and a specific set of GPIOs is used. +@c command: at91rm9200_device NAME +@c chooses among list of bit configs ... only one option +@end deffn + +@deffn {Interface Driver} {dummy} +A dummy software-only driver for debugging. +@end deffn + +@deffn {Interface Driver} {ep93xx} +Cirrus Logic EP93xx based single-board computer bit-banging (in development) +@end deffn + +@deffn {Interface Driver} {ft2232} +FTDI FT2232 (USB) based devices over one of the userspace libraries. + +Note that this driver has several flaws and the @command{ftdi} driver is +recommended as its replacement. + +These interfaces have several commands, used to configure the driver +before initializing the JTAG scan chain: + +@deffn {Config Command} {ft2232_device_desc} description +Provides the USB device description (the @emph{iProduct string}) +of the FTDI FT2232 device. If not +specified, the FTDI default value is used. This setting is only valid +if compiled with FTD2XX support. +@end deffn + +@deffn {Config Command} {ft2232_serial} serial-number +Specifies the @var{serial-number} of the FTDI FT2232 device to use, +in case the vendor provides unique IDs and more than one FT2232 device +is connected to the host. +If not specified, serial numbers are not considered. +(Note that USB serial numbers can be arbitrary Unicode strings, +and are not restricted to containing only decimal digits.) +@end deffn + +@deffn {Config Command} {ft2232_layout} name +Each vendor's FT2232 device can use different GPIO signals +to control output-enables, reset signals, and LEDs. +Currently valid layout @var{name} values include: +@itemize @minus +@item @b{axm0432_jtag} Axiom AXM-0432 +@item @b{comstick} Hitex STR9 comstick +@item @b{cortino} Hitex Cortino JTAG interface +@item @b{evb_lm3s811} TI/Luminary Micro EVB_LM3S811 as a JTAG interface, +either for the local Cortex-M3 (SRST only) +or in a passthrough mode (neither SRST nor TRST) +This layout can not support the SWO trace mechanism, and should be +used only for older boards (before rev C). +@item @b{luminary_icdi} This layout should be used with most TI/Luminary +eval boards, including Rev C LM3S811 eval boards and the eponymous +ICDI boards, to debug either the local Cortex-M3 or in passthrough mode +to debug some other target. It can support the SWO trace mechanism. +@item @b{flyswatter} Tin Can Tools Flyswatter +@item @b{icebear} ICEbear JTAG adapter from Section 5 +@item @b{jtagkey} Amontec JTAGkey and JTAGkey-Tiny (and compatibles) +@item @b{jtagkey2} Amontec JTAGkey2 (and compatibles) +@item @b{m5960} American Microsystems M5960 +@item @b{olimex-jtag} Olimex ARM-USB-OCD and ARM-USB-Tiny +@item @b{oocdlink} OOCDLink +@c oocdlink ~= jtagkey_prototype_v1 +@item @b{redbee-econotag} Integrated with a Redbee development board. +@item @b{redbee-usb} Integrated with a Redbee USB-stick development board. +@item @b{sheevaplug} Marvell Sheevaplug development kit +@item @b{signalyzer} Xverve Signalyzer +@item @b{stm32stick} Hitex STM32 Performance Stick +@item @b{turtelizer2} egnite Software turtelizer2 +@item @b{usbjtag} "USBJTAG-1" layout described in the OpenOCD diploma thesis +@end itemize +@end deffn + +@deffn {Config Command} {ft2232_vid_pid} [vid pid]+ +The vendor ID and product ID of the FTDI FT2232 device. If not specified, the FTDI +default values are used. +Currently, up to eight [@var{vid}, @var{pid}] pairs may be given, e.g. +@example +ft2232_vid_pid 0x0403 0xcff8 0x15ba 0x0003 +@end example +@end deffn + +@deffn {Config Command} {ft2232_latency} ms +On some systems using FT2232 based JTAG interfaces the FT_Read function call in +ft2232_read() fails to return the expected number of bytes. This can be caused by +USB communication delays and has proved hard to reproduce and debug. Setting the +FT2232 latency timer to a larger value increases delays for short USB packets but it +also reduces the risk of timeouts before receiving the expected number of bytes. +The OpenOCD default value is 2 and for some systems a value of 10 has proved useful. +@end deffn + +@deffn {Config Command} {ft2232_channel} channel +Used to select the channel of the ft2232 chip to use (between 1 and 4). +The default value is 1. +@end deffn + +For example, the interface config file for a +Turtelizer JTAG Adapter looks something like this: + +@example +interface ft2232 +ft2232_device_desc "Turtelizer JTAG/RS232 Adapter" +ft2232_layout turtelizer2 +ft2232_vid_pid 0x0403 0xbdc8 +@end example +@end deffn + +@deffn {Interface Driver} {ftdi} +This driver is for adapters using the MPSSE (Multi-Protocol Synchronous Serial +Engine) mode built into many FTDI chips, such as the FT2232, FT4232 and FT232H. +It is a complete rewrite to address a large number of problems with the ft2232 +interface driver. + +The driver is using libusb-1.0 in asynchronous mode to talk to the FTDI device, +bypassing intermediate libraries like libftdi of D2XX. Performance-wise it is +consistently faster than the ft2232 driver, sometimes several times faster. + +A major improvement of this driver is that support for new FTDI based adapters +can be added competely through configuration files, without the need to patch +and rebuild OpenOCD. + +The driver uses a signal abstraction to enable Tcl configuration files to +define outputs for one or several FTDI GPIO. These outputs can then be +controlled using the @command{ftdi_set_signal} command. Special signal names +are reserved for nTRST, nSRST and LED (for blink) so that they, if defined, +will be used for their customary purpose. + +Depending on the type of buffer attached to the FTDI GPIO, the outputs have to +be controlled differently. In order to support tristateable signals such as +nSRST, both a data GPIO and an output-enable GPIO can be specified for each +signal. The following output buffer configurations are supported: + +@itemize @minus +@item Push-pull with one FTDI output as (non-)inverted data line +@item Open drain with one FTDI output as (non-)inverted output-enable +@item Tristate with one FTDI output as (non-)inverted data line and another + FTDI output as (non-)inverted output-enable +@item Unbuffered, using the FTDI GPIO as a tristate output directly by + switching data and direction as necessary +@end itemize + +These interfaces have several commands, used to configure the driver +before initializing the JTAG scan chain: + +@deffn {Config Command} {ftdi_vid_pid} [vid pid]+ +The vendor ID and product ID of the adapter. If not specified, the FTDI +default values are used. +Currently, up to eight [@var{vid}, @var{pid}] pairs may be given, e.g. +@example +ftdi_vid_pid 0x0403 0xcff8 0x15ba 0x0003 +@end example +@end deffn + +@deffn {Config Command} {ftdi_device_desc} description +Provides the USB device description (the @emph{iProduct string}) +of the adapter. If not specified, the device description is ignored +during device selection. +@end deffn + +@deffn {Config Command} {ftdi_serial} serial-number +Specifies the @var{serial-number} of the adapter to use, +in case the vendor provides unique IDs and more than one adapter +is connected to the host. +If not specified, serial numbers are not considered. +(Note that USB serial numbers can be arbitrary Unicode strings, +and are not restricted to containing only decimal digits.) +@end deffn + +@deffn {Config Command} {ftdi_channel} channel +Selects the channel of the FTDI device to use for MPSSE operations. Most +adapters use the default, channel 0, but there are exceptions. +@end deffn + +@deffn {Config Command} {ftdi_layout_init} data direction +Specifies the initial values of the FTDI GPIO data and direction registers. +Each value is a 16-bit number corresponding to the concatenation of the high +and low FTDI GPIO registers. The values should be selected based on the +schematics of the adapter, such that all signals are set to safe levels with +minimal impact on the target system. Avoid floating inputs, conflicting outputs +and initially asserted reset signals. +@end deffn + +@deffn {Config Command} {ftdi_layout_signal} name [@option{-data}|@option{-ndata} data_mask] [@option{-oe}|@option{-noe} oe_mask] +Creates a signal with the specified @var{name}, controlled by one or more FTDI +GPIO pins via a range of possible buffer connections. The masks are FTDI GPIO +register bitmasks to tell the driver the connection and type of the output +buffer driving the respective signal. @var{data_mask} is the bitmask for the +pin(s) connected to the data input of the output buffer. @option{-ndata} is +used with inverting data inputs and @option{-data} with non-inverting inputs. +The @option{-oe} (or @option{-noe}) option tells where the output-enable (or +not-output-enable) input to the output buffer is connected. + +Both @var{data_mask} and @var{oe_mask} need not be specified. For example, a +simple open-collector transistor driver would be specified with @option{-oe} +only. In that case the signal can only be set to drive low or to Hi-Z and the +driver will complain if the signal is set to drive high. Which means that if +it's a reset signal, @command{reset_config} must be specified as +@option{srst_open_drain}, not @option{srst_push_pull}. + +A special case is provided when @option{-data} and @option{-oe} is set to the +same bitmask. Then the FTDI pin is considered being connected straight to the +target without any buffer. The FTDI pin is then switched between output and +input as necessary to provide the full set of low, high and Hi-Z +characteristics. In all other cases, the pins specified in a signal definition +are always driven by the FTDI. +@end deffn + +@deffn {Command} {ftdi_set_signal} name @option{0}|@option{1}|@option{z} +Set a previously defined signal to the specified level. +@itemize @minus +@item @option{0}, drive low +@item @option{1}, drive high +@item @option{z}, set to high-impedance +@end itemize +@end deffn + +For example adapter definitions, see the configuration files shipped in the +@file{interface/ftdi} directory. +@end deffn + +@deffn {Interface Driver} {remote_bitbang} +Drive JTAG from a remote process. This sets up a UNIX or TCP socket connection +with a remote process and sends ASCII encoded bitbang requests to that process +instead of directly driving JTAG. + +The remote_bitbang driver is useful for debugging software running on +processors which are being simulated. + +@deffn {Config Command} {remote_bitbang_port} number +Specifies the TCP port of the remote process to connect to or 0 to use UNIX +sockets instead of TCP. +@end deffn + +@deffn {Config Command} {remote_bitbang_host} hostname +Specifies the hostname of the remote process to connect to using TCP, or the +name of the UNIX socket to use if remote_bitbang_port is 0. +@end deffn + +For example, to connect remotely via TCP to the host foobar you might have +something like: + +@example +interface remote_bitbang +remote_bitbang_port 3335 +remote_bitbang_host foobar +@end example + +To connect to another process running locally via UNIX sockets with socket +named mysocket: + +@example +interface remote_bitbang +remote_bitbang_port 0 +remote_bitbang_host mysocket +@end example +@end deffn + +@deffn {Interface Driver} {usb_blaster} +USB JTAG/USB-Blaster compatibles over one of the userspace libraries +for FTDI chips. These interfaces have several commands, used to +configure the driver before initializing the JTAG scan chain: + +@deffn {Config Command} {usb_blaster_device_desc} description +Provides the USB device description (the @emph{iProduct string}) +of the FTDI FT245 device. If not +specified, the FTDI default value is used. This setting is only valid +if compiled with FTD2XX support. +@end deffn + +@deffn {Config Command} {usb_blaster_vid_pid} vid pid +The vendor ID and product ID of the FTDI FT245 device. If not specified, +default values are used. +Currently, only one @var{vid}, @var{pid} pair may be given, e.g. for +Altera USB-Blaster (default): +@example +usb_blaster_vid_pid 0x09FB 0x6001 +@end example +The following VID/PID is for Kolja Waschk's USB JTAG: +@example +usb_blaster_vid_pid 0x16C0 0x06AD +@end example +@end deffn + +@deffn {Command} {usb_blaster} (@option{pin6}|@option{pin8}) (@option{0}|@option{1}) +Sets the state of the unused GPIO pins on USB-Blasters (pins 6 and 8 on the +female JTAG header). These pins can be used as SRST and/or TRST provided the +appropriate connections are made on the target board. + +For example, to use pin 6 as SRST (as with an AVR board): +@example +$_TARGETNAME configure -event reset-assert \ + "usb_blaster pin6 1; wait 1; usb_blaster pin6 0" +@end example +@end deffn + +@end deffn + +@deffn {Interface Driver} {gw16012} +Gateworks GW16012 JTAG programmer. +This has one driver-specific command: + +@deffn {Config Command} {parport_port} [port_number] +Display either the address of the I/O port +(default: 0x378 for LPT1) or the number of the @file{/dev/parport} device. +If a parameter is provided, first switch to use that port. +This is a write-once setting. +@end deffn +@end deffn + +@deffn {Interface Driver} {jlink} +Segger J-Link family of USB adapters. It currently supports only the JTAG transport. + +@quotation Compatibility Note +Segger released many firmware versions for the many harware versions they +produced. OpenOCD was extensively tested and intended to run on all of them, +but some combinations were reported as incompatible. As a general +recommendation, it is advisable to use the latest firmware version +available for each hardware version. However the current V8 is a moving +target, and Segger firmware versions released after the OpenOCD was +released may not be compatible. In such cases it is recommended to +revert to the last known functional version. For 0.5.0, this is from +"Feb 8 2012 14:30:39", packed with 4.42c. For 0.6.0, the last known +version is from "May 3 2012 18:36:22", packed with 4.46f. +@end quotation + +@deffn {Command} {jlink caps} +Display the device firmware capabilities. +@end deffn +@deffn {Command} {jlink info} +Display various device information, like hardware version, firmware version, current bus status. +@end deffn +@deffn {Command} {jlink hw_jtag} [@option{2}|@option{3}] +Set the JTAG protocol version to be used. Without argument, show the actual JTAG protocol version. +@end deffn +@deffn {Command} {jlink config} +Display the J-Link configuration. +@end deffn +@deffn {Command} {jlink config kickstart} [val] +Set the Kickstart power on JTAG-pin 19. Without argument, show the Kickstart configuration. +@end deffn +@deffn {Command} {jlink config mac_address} [@option{ff:ff:ff:ff:ff:ff}] +Set the MAC address of the J-Link Pro. Without argument, show the MAC address. +@end deffn +@deffn {Command} {jlink config ip} [@option{A.B.C.D}(@option{/E}|@option{F.G.H.I})] +Set the IP configuration of the J-Link Pro, where A.B.C.D is the IP address, + E the bit of the subnet mask and + F.G.H.I the subnet mask. Without arguments, show the IP configuration. +@end deffn +@deffn {Command} {jlink config usb_address} [@option{0x00} to @option{0x03} or @option{0xff}] +Set the USB address; this will also change the product id. Without argument, show the USB address. +@end deffn +@deffn {Command} {jlink config reset} +Reset the current configuration. +@end deffn +@deffn {Command} {jlink config save} +Save the current configuration to the internal persistent storage. +@end deffn +@deffn {Config} {jlink pid} val +Set the USB PID of the interface. As a configuration command, it can be used only before 'init'. +@end deffn +@end deffn + +@deffn {Interface Driver} {parport} +Supports PC parallel port bit-banging cables: +Wigglers, PLD download cable, and more. +These interfaces have several commands, used to configure the driver +before initializing the JTAG scan chain: + +@deffn {Config Command} {parport_cable} name +Set the layout of the parallel port cable used to connect to the target. +This is a write-once setting. +Currently valid cable @var{name} values include: + +@itemize @minus +@item @b{altium} Altium Universal JTAG cable. +@item @b{arm-jtag} Same as original wiggler except SRST and +TRST connections reversed and TRST is also inverted. +@item @b{chameleon} The Amontec Chameleon's CPLD when operated +in configuration mode. This is only used to +program the Chameleon itself, not a connected target. +@item @b{dlc5} The Xilinx Parallel cable III. +@item @b{flashlink} The ST Parallel cable. +@item @b{lattice} Lattice ispDOWNLOAD Cable +@item @b{old_amt_wiggler} The Wiggler configuration that comes with +some versions of +Amontec's Chameleon Programmer. The new version available from +the website uses the original Wiggler layout ('@var{wiggler}') +@item @b{triton} The parallel port adapter found on the +``Karo Triton 1 Development Board''. +This is also the layout used by the HollyGates design +(see @uref{http://www.lartmaker.nl/projects/jtag/}). +@item @b{wiggler} The original Wiggler layout, also supported by +several clones, such as the Olimex ARM-JTAG +@item @b{wiggler2} Same as original wiggler except an led is fitted on D5. +@item @b{wiggler_ntrst_inverted} Same as original wiggler except TRST is inverted. +@end itemize +@end deffn + +@deffn {Config Command} {parport_port} [port_number] +Display either the address of the I/O port +(default: 0x378 for LPT1) or the number of the @file{/dev/parport} device. +If a parameter is provided, first switch to use that port. +This is a write-once setting. + +When using PPDEV to access the parallel port, use the number of the parallel port: +@option{parport_port 0} (the default). If @option{parport_port 0x378} is specified +you may encounter a problem. +@end deffn + +@deffn Command {parport_toggling_time} [nanoseconds] +Displays how many nanoseconds the hardware needs to toggle TCK; +the parport driver uses this value to obey the +@command{adapter_khz} configuration. +When the optional @var{nanoseconds} parameter is given, +that setting is changed before displaying the current value. + +The default setting should work reasonably well on commodity PC hardware. +However, you may want to calibrate for your specific hardware. +@quotation Tip +To measure the toggling time with a logic analyzer or a digital storage +oscilloscope, follow the procedure below: +@example +> parport_toggling_time 1000 +> adapter_khz 500 +@end example +This sets the maximum JTAG clock speed of the hardware, but +the actual speed probably deviates from the requested 500 kHz. +Now, measure the time between the two closest spaced TCK transitions. +You can use @command{runtest 1000} or something similar to generate a +large set of samples. +Update the setting to match your measurement: +@example +> parport_toggling_time +@end example +Now the clock speed will be a better match for @command{adapter_khz rate} +commands given in OpenOCD scripts and event handlers. + +You can do something similar with many digital multimeters, but note +that you'll probably need to run the clock continuously for several +seconds before it decides what clock rate to show. Adjust the +toggling time up or down until the measured clock rate is a good +match for the adapter_khz rate you specified; be conservative. +@end quotation +@end deffn + +@deffn {Config Command} {parport_write_on_exit} (@option{on}|@option{off}) +This will configure the parallel driver to write a known +cable-specific value to the parallel interface on exiting OpenOCD. +@end deffn + +For example, the interface configuration file for a +classic ``Wiggler'' cable on LPT2 might look something like this: + +@example +interface parport +parport_port 0x278 +parport_cable wiggler +@end example +@end deffn + +@deffn {Interface Driver} {presto} +ASIX PRESTO USB JTAG programmer. +@deffn {Config Command} {presto_serial} serial_string +Configures the USB serial number of the Presto device to use. +@end deffn +@end deffn + +@deffn {Interface Driver} {rlink} +Raisonance RLink USB adapter +@end deffn + +@deffn {Interface Driver} {usbprog} +usbprog is a freely programmable USB adapter. +@end deffn + +@deffn {Interface Driver} {vsllink} +vsllink is part of Versaloon which is a versatile USB programmer. + +@quotation Note +This defines quite a few driver-specific commands, +which are not currently documented here. +@end quotation +@end deffn + +@deffn {Interface Driver} {hla} +This is a driver that supports multiple High Level Adapters. +This type of adapter does not expose some of the lower level api's +that OpenOCD would normally use to access the target. + +Currently supported adapters include the ST STLINK and TI ICDI. + +@deffn {Config Command} {hla_device_desc} description +Currently Not Supported. +@end deffn + +@deffn {Config Command} {hla_serial} serial +Currently Not Supported. +@end deffn + +@deffn {Config Command} {hla_layout} (@option{stlink}|@option{icdi}) +Specifies the adapter layout to use. +@end deffn + +@deffn {Config Command} {hla_vid_pid} vid pid +The vendor ID and product ID of the device. +@end deffn + +@deffn {Config Command} {stlink_api} api_level +Manually sets the stlink api used, valid options are 1 or 2. (@b{STLINK Only}). +@end deffn +@end deffn + +@deffn {Interface Driver} {opendous} +opendous-jtag is a freely programmable USB adapter. +@end deffn + +@deffn {Interface Driver} {ulink} +This is the Keil ULINK v1 JTAG debugger. +@end deffn + +@deffn {Interface Driver} {ZY1000} +This is the Zylin ZY1000 JTAG debugger. +@end deffn + +@quotation Note +This defines some driver-specific commands, +which are not currently documented here. +@end quotation + +@deffn Command power [@option{on}|@option{off}] +Turn power switch to target on/off. +No arguments: print status. +@end deffn + +@section Transport Configuration +@cindex Transport +As noted earlier, depending on the version of OpenOCD you use, +and the debug adapter you are using, +several transports may be available to +communicate with debug targets (or perhaps to program flash memory). +@deffn Command {transport list} +displays the names of the transports supported by this +version of OpenOCD. +@end deffn + +@deffn Command {transport select} transport_name +Select which of the supported transports to use in this OpenOCD session. +The transport must be supported by the debug adapter hardware and by the +version of OPenOCD you are using (including the adapter's driver). +No arguments: returns name of session's selected transport. +@end deffn + +@subsection JTAG Transport +@cindex JTAG +JTAG is the original transport supported by OpenOCD, and most +of the OpenOCD commands support it. +JTAG transports expose a chain of one or more Test Access Points (TAPs), +each of which must be explicitly declared. +JTAG supports both debugging and boundary scan testing. +Flash programming support is built on top of debug support. +@subsection SWD Transport +@cindex SWD +@cindex Serial Wire Debug +SWD (Serial Wire Debug) is an ARM-specific transport which exposes one +Debug Access Point (DAP, which must be explicitly declared. +(SWD uses fewer signal wires than JTAG.) +SWD is debug-oriented, and does not support boundary scan testing. +Flash programming support is built on top of debug support. +(Some processors support both JTAG and SWD.) +@deffn Command {swd newdap} ... +Declares a single DAP which uses SWD transport. +Parameters are currently the same as "jtag newtap" but this is +expected to change. +@end deffn +@deffn Command {swd wcr trn prescale} +Updates TRN (turnaraound delay) and prescaling.fields of the +Wire Control Register (WCR). +No parameters: displays current settings. +@end deffn + +@subsection SPI Transport +@cindex SPI +@cindex Serial Peripheral Interface +The Serial Peripheral Interface (SPI) is a general purpose transport +which uses four wire signaling. Some processors use it as part of a +solution for flash programming. + +@anchor{jtagspeed} +@section JTAG Speed +JTAG clock setup is part of system setup. +It @emph{does not belong with interface setup} since any interface +only knows a few of the constraints for the JTAG clock speed. +Sometimes the JTAG speed is +changed during the target initialization process: (1) slow at +reset, (2) program the CPU clocks, (3) run fast. +Both the "slow" and "fast" clock rates are functions of the +oscillators used, the chip, the board design, and sometimes +power management software that may be active. + +The speed used during reset, and the scan chain verification which +follows reset, can be adjusted using a @code{reset-start} +target event handler. +It can then be reconfigured to a faster speed by a +@code{reset-init} target event handler after it reprograms those +CPU clocks, or manually (if something else, such as a boot loader, +sets up those clocks). +@xref{targetevents,,Target Events}. +When the initial low JTAG speed is a chip characteristic, perhaps +because of a required oscillator speed, provide such a handler +in the target config file. +When that speed is a function of a board-specific characteristic +such as which speed oscillator is used, it belongs in the board +config file instead. +In both cases it's safest to also set the initial JTAG clock rate +to that same slow speed, so that OpenOCD never starts up using a +clock speed that's faster than the scan chain can support. + +@example +jtag_rclk 3000 +$_TARGET.cpu configure -event reset-start @{ jtag_rclk 3000 @} +@end example + +If your system supports adaptive clocking (RTCK), configuring +JTAG to use that is probably the most robust approach. +However, it introduces delays to synchronize clocks; so it +may not be the fastest solution. + +@b{NOTE:} Script writers should consider using @command{jtag_rclk} +instead of @command{adapter_khz}, but only for (ARM) cores and boards +which support adaptive clocking. + +@deffn {Command} adapter_khz max_speed_kHz +A non-zero speed is in KHZ. Hence: 3000 is 3mhz. +JTAG interfaces usually support a limited number of +speeds. The speed actually used won't be faster +than the speed specified. + +Chip data sheets generally include a top JTAG clock rate. +The actual rate is often a function of a CPU core clock, +and is normally less than that peak rate. +For example, most ARM cores accept at most one sixth of the CPU clock. + +Speed 0 (khz) selects RTCK method. +@xref{faqrtck,,FAQ RTCK}. +If your system uses RTCK, you won't need to change the +JTAG clocking after setup. +Not all interfaces, boards, or targets support ``rtck''. +If the interface device can not +support it, an error is returned when you try to use RTCK. +@end deffn + +@defun jtag_rclk fallback_speed_kHz +@cindex adaptive clocking +@cindex RTCK +This Tcl proc (defined in @file{startup.tcl}) attempts to enable RTCK/RCLK. +If that fails (maybe the interface, board, or target doesn't +support it), falls back to the specified frequency. +@example +# Fall back to 3mhz if RTCK is not supported +jtag_rclk 3000 +@end example +@end defun + +@node Reset Configuration +@chapter Reset Configuration +@cindex Reset Configuration + +Every system configuration may require a different reset +configuration. This can also be quite confusing. +Resets also interact with @var{reset-init} event handlers, +which do things like setting up clocks and DRAM, and +JTAG clock rates. (@xref{jtagspeed,,JTAG Speed}.) +They can also interact with JTAG routers. +Please see the various board files for examples. + +@quotation Note +To maintainers and integrators: +Reset configuration touches several things at once. +Normally the board configuration file +should define it and assume that the JTAG adapter supports +everything that's wired up to the board's JTAG connector. + +However, the target configuration file could also make note +of something the silicon vendor has done inside the chip, +which will be true for most (or all) boards using that chip. +And when the JTAG adapter doesn't support everything, the +user configuration file will need to override parts of +the reset configuration provided by other files. +@end quotation + +@section Types of Reset + +There are many kinds of reset possible through JTAG, but +they may not all work with a given board and adapter. +That's part of why reset configuration can be error prone. + +@itemize @bullet +@item +@emph{System Reset} ... the @emph{SRST} hardware signal +resets all chips connected to the JTAG adapter, such as processors, +power management chips, and I/O controllers. Normally resets triggered +with this signal behave exactly like pressing a RESET button. +@item +@emph{JTAG TAP Reset} ... the @emph{TRST} hardware signal resets +just the TAP controllers connected to the JTAG adapter. +Such resets should not be visible to the rest of the system; resetting a +device's TAP controller just puts that controller into a known state. +@item +@emph{Emulation Reset} ... many devices can be reset through JTAG +commands. These resets are often distinguishable from system +resets, either explicitly (a "reset reason" register says so) +or implicitly (not all parts of the chip get reset). +@item +@emph{Other Resets} ... system-on-chip devices often support +several other types of reset. +You may need to arrange that a watchdog timer stops +while debugging, preventing a watchdog reset. +There may be individual module resets. +@end itemize + +In the best case, OpenOCD can hold SRST, then reset +the TAPs via TRST and send commands through JTAG to halt the +CPU at the reset vector before the 1st instruction is executed. +Then when it finally releases the SRST signal, the system is +halted under debugger control before any code has executed. +This is the behavior required to support the @command{reset halt} +and @command{reset init} commands; after @command{reset init} a +board-specific script might do things like setting up DRAM. +(@xref{resetcommand,,Reset Command}.) + +@anchor{srstandtrstissues} +@section SRST and TRST Issues + +Because SRST and TRST are hardware signals, they can have a +variety of system-specific constraints. Some of the most +common issues are: + +@itemize @bullet + +@item @emph{Signal not available} ... Some boards don't wire +SRST or TRST to the JTAG connector. Some JTAG adapters don't +support such signals even if they are wired up. +Use the @command{reset_config} @var{signals} options to say +when either of those signals is not connected. +When SRST is not available, your code might not be able to rely +on controllers having been fully reset during code startup. +Missing TRST is not a problem, since JTAG-level resets can +be triggered using with TMS signaling. + +@item @emph{Signals shorted} ... Sometimes a chip, board, or +adapter will connect SRST to TRST, instead of keeping them separate. +Use the @command{reset_config} @var{combination} options to say +when those signals aren't properly independent. + +@item @emph{Timing} ... Reset circuitry like a resistor/capacitor +delay circuit, reset supervisor, or on-chip features can extend +the effect of a JTAG adapter's reset for some time after the adapter +stops issuing the reset. For example, there may be chip or board +requirements that all reset pulses last for at least a +certain amount of time; and reset buttons commonly have +hardware debouncing. +Use the @command{adapter_nsrst_delay} and @command{jtag_ntrst_delay} +commands to say when extra delays are needed. + +@item @emph{Drive type} ... Reset lines often have a pullup +resistor, letting the JTAG interface treat them as open-drain +signals. But that's not a requirement, so the adapter may need +to use push/pull output drivers. +Also, with weak pullups it may be advisable to drive +signals to both levels (push/pull) to minimize rise times. +Use the @command{reset_config} @var{trst_type} and +@var{srst_type} parameters to say how to drive reset signals. + +@item @emph{Special initialization} ... Targets sometimes need +special JTAG initialization sequences to handle chip-specific +issues (not limited to errata). +For example, certain JTAG commands might need to be issued while +the system as a whole is in a reset state (SRST active) +but the JTAG scan chain is usable (TRST inactive). +Many systems treat combined assertion of SRST and TRST as a +trigger for a harder reset than SRST alone. +Such custom reset handling is discussed later in this chapter. +@end itemize + +There can also be other issues. +Some devices don't fully conform to the JTAG specifications. +Trivial system-specific differences are common, such as +SRST and TRST using slightly different names. +There are also vendors who distribute key JTAG documentation for +their chips only to developers who have signed a Non-Disclosure +Agreement (NDA). + +Sometimes there are chip-specific extensions like a requirement to use +the normally-optional TRST signal (precluding use of JTAG adapters which +don't pass TRST through), or needing extra steps to complete a TAP reset. + +In short, SRST and especially TRST handling may be very finicky, +needing to cope with both architecture and board specific constraints. + +@section Commands for Handling Resets + +@deffn {Command} adapter_nsrst_assert_width milliseconds +Minimum amount of time (in milliseconds) OpenOCD should wait +after asserting nSRST (active-low system reset) before +allowing it to be deasserted. +@end deffn + +@deffn {Command} adapter_nsrst_delay milliseconds +How long (in milliseconds) OpenOCD should wait after deasserting +nSRST (active-low system reset) before starting new JTAG operations. +When a board has a reset button connected to SRST line it will +probably have hardware debouncing, implying you should use this. +@end deffn + +@deffn {Command} jtag_ntrst_assert_width milliseconds +Minimum amount of time (in milliseconds) OpenOCD should wait +after asserting nTRST (active-low JTAG TAP reset) before +allowing it to be deasserted. +@end deffn + +@deffn {Command} jtag_ntrst_delay milliseconds +How long (in milliseconds) OpenOCD should wait after deasserting +nTRST (active-low JTAG TAP reset) before starting new JTAG operations. +@end deffn + +@deffn {Command} reset_config mode_flag ... +This command displays or modifies the reset configuration +of your combination of JTAG board and target in target +configuration scripts. + +Information earlier in this section describes the kind of problems +the command is intended to address (@pxref{srstandtrstissues,,SRST and TRST Issues}). +As a rule this command belongs only in board config files, +describing issues like @emph{board doesn't connect TRST}; +or in user config files, addressing limitations derived +from a particular combination of interface and board. +(An unlikely example would be using a TRST-only adapter +with a board that only wires up SRST.) + +The @var{mode_flag} options can be specified in any order, but only one +of each type -- @var{signals}, @var{combination}, @var{gates}, +@var{trst_type}, @var{srst_type} and @var{connect_type} +-- may be specified at a time. +If you don't provide a new value for a given type, its previous +value (perhaps the default) is unchanged. +For example, this means that you don't need to say anything at all about +TRST just to declare that if the JTAG adapter should want to drive SRST, +it must explicitly be driven high (@option{srst_push_pull}). + +@itemize +@item +@var{signals} can specify which of the reset signals are connected. +For example, If the JTAG interface provides SRST, but the board doesn't +connect that signal properly, then OpenOCD can't use it. +Possible values are @option{none} (the default), @option{trst_only}, +@option{srst_only} and @option{trst_and_srst}. + +@quotation Tip +If your board provides SRST and/or TRST through the JTAG connector, +you must declare that so those signals can be used. +@end quotation + +@item +The @var{combination} is an optional value specifying broken reset +signal implementations. +The default behaviour if no option given is @option{separate}, +indicating everything behaves normally. +@option{srst_pulls_trst} states that the +test logic is reset together with the reset of the system (e.g. NXP +LPC2000, "broken" board layout), @option{trst_pulls_srst} says that +the system is reset together with the test logic (only hypothetical, I +haven't seen hardware with such a bug, and can be worked around). +@option{combined} implies both @option{srst_pulls_trst} and +@option{trst_pulls_srst}. + +@item +The @var{gates} tokens control flags that describe some cases where +JTAG may be unvailable during reset. +@option{srst_gates_jtag} (default) +indicates that asserting SRST gates the +JTAG clock. This means that no communication can happen on JTAG +while SRST is asserted. +Its converse is @option{srst_nogate}, indicating that JTAG commands +can safely be issued while SRST is active. + +@item +The @var{connect_type} tokens control flags that describe some cases where +SRST is asserted while connecting to the target. @option{srst_nogate} +is required to use this option. +@option{connect_deassert_srst} (default) +indicates that SRST will not be asserted while connecting to the target. +Its converse is @option{connect_assert_srst}, indicating that SRST will +be asserted before any target connection. +Only some targets support this feature, STM32 and STR9 are examples. +This feature is useful if you are unable to connect to your target due +to incorrect options byte config or illegal program execution. +@end itemize + +The optional @var{trst_type} and @var{srst_type} parameters allow the +driver mode of each reset line to be specified. These values only affect +JTAG interfaces with support for different driver modes, like the Amontec +JTAGkey and JTAG Accelerator. Also, they are necessarily ignored if the +relevant signal (TRST or SRST) is not connected. + +@itemize +@item +Possible @var{trst_type} driver modes for the test reset signal (TRST) +are the default @option{trst_push_pull}, and @option{trst_open_drain}. +Most boards connect this signal to a pulldown, so the JTAG TAPs +never leave reset unless they are hooked up to a JTAG adapter. + +@item +Possible @var{srst_type} driver modes for the system reset signal (SRST) +are the default @option{srst_open_drain}, and @option{srst_push_pull}. +Most boards connect this signal to a pullup, and allow the +signal to be pulled low by various events including system +powerup and pressing a reset button. +@end itemize +@end deffn + +@section Custom Reset Handling +@cindex events + +OpenOCD has several ways to help support the various reset +mechanisms provided by chip and board vendors. +The commands shown in the previous section give standard parameters. +There are also @emph{event handlers} associated with TAPs or Targets. +Those handlers are Tcl procedures you can provide, which are invoked +at particular points in the reset sequence. + +@emph{When SRST is not an option} you must set +up a @code{reset-assert} event handler for your target. +For example, some JTAG adapters don't include the SRST signal; +and some boards have multiple targets, and you won't always +want to reset everything at once. + +After configuring those mechanisms, you might still +find your board doesn't start up or reset correctly. +For example, maybe it needs a slightly different sequence +of SRST and/or TRST manipulations, because of quirks that +the @command{reset_config} mechanism doesn't address; +or asserting both might trigger a stronger reset, which +needs special attention. + +Experiment with lower level operations, such as @command{jtag_reset} +and the @command{jtag arp_*} operations shown here, +to find a sequence of operations that works. +@xref{JTAG Commands}. +When you find a working sequence, it can be used to override +@command{jtag_init}, which fires during OpenOCD startup +(@pxref{configurationstage,,Configuration Stage}); +or @command{init_reset}, which fires during reset processing. + +You might also want to provide some project-specific reset +schemes. For example, on a multi-target board the standard +@command{reset} command would reset all targets, but you +may need the ability to reset only one target at time and +thus want to avoid using the board-wide SRST signal. + +@deffn {Overridable Procedure} init_reset mode +This is invoked near the beginning of the @command{reset} command, +usually to provide as much of a cold (power-up) reset as practical. +By default it is also invoked from @command{jtag_init} if +the scan chain does not respond to pure JTAG operations. +The @var{mode} parameter is the parameter given to the +low level reset command (@option{halt}, +@option{init}, or @option{run}), @option{setup}, +or potentially some other value. + +The default implementation just invokes @command{jtag arp_init-reset}. +Replacements will normally build on low level JTAG +operations such as @command{jtag_reset}. +Operations here must not address individual TAPs +(or their associated targets) +until the JTAG scan chain has first been verified to work. + +Implementations must have verified the JTAG scan chain before +they return. +This is done by calling @command{jtag arp_init} +(or @command{jtag arp_init-reset}). +@end deffn + +@deffn Command {jtag arp_init} +This validates the scan chain using just the four +standard JTAG signals (TMS, TCK, TDI, TDO). +It starts by issuing a JTAG-only reset. +Then it performs checks to verify that the scan chain configuration +matches the TAPs it can observe. +Those checks include checking IDCODE values for each active TAP, +and verifying the length of their instruction registers using +TAP @code{-ircapture} and @code{-irmask} values. +If these tests all pass, TAP @code{setup} events are +issued to all TAPs with handlers for that event. +@end deffn + +@deffn Command {jtag arp_init-reset} +This uses TRST and SRST to try resetting +everything on the JTAG scan chain +(and anything else connected to SRST). +It then invokes the logic of @command{jtag arp_init}. +@end deffn + + +@node TAP Declaration +@chapter TAP Declaration +@cindex TAP declaration +@cindex TAP configuration + +@emph{Test Access Ports} (TAPs) are the core of JTAG. +TAPs serve many roles, including: + +@itemize @bullet +@item @b{Debug Target} A CPU TAP can be used as a GDB debug target +@item @b{Flash Programing} Some chips program the flash directly via JTAG. +Others do it indirectly, making a CPU do it. +@item @b{Program Download} Using the same CPU support GDB uses, +you can initialize a DRAM controller, download code to DRAM, and then +start running that code. +@item @b{Boundary Scan} Most chips support boundary scan, which +helps test for board assembly problems like solder bridges +and missing connections +@end itemize + +OpenOCD must know about the active TAPs on your board(s). +Setting up the TAPs is the core task of your configuration files. +Once those TAPs are set up, you can pass their names to code +which sets up CPUs and exports them as GDB targets, +probes flash memory, performs low-level JTAG operations, and more. + +@section Scan Chains +@cindex scan chain + +TAPs are part of a hardware @dfn{scan chain}, +which is daisy chain of TAPs. +They also need to be added to +OpenOCD's software mirror of that hardware list, +giving each member a name and associating other data with it. +Simple scan chains, with a single TAP, are common in +systems with a single microcontroller or microprocessor. +More complex chips may have several TAPs internally. +Very complex scan chains might have a dozen or more TAPs: +several in one chip, more in the next, and connecting +to other boards with their own chips and TAPs. + +You can display the list with the @command{scan_chain} command. +(Don't confuse this with the list displayed by the @command{targets} +command, presented in the next chapter. +That only displays TAPs for CPUs which are configured as +debugging targets.) +Here's what the scan chain might look like for a chip more than one TAP: + +@verbatim + TapName Enabled IdCode Expected IrLen IrCap IrMask +-- ------------------ ------- ---------- ---------- ----- ----- ------ + 0 omap5912.dsp Y 0x03df1d81 0x03df1d81 38 0x01 0x03 + 1 omap5912.arm Y 0x0692602f 0x0692602f 4 0x01 0x0f + 2 omap5912.unknown Y 0x00000000 0x00000000 8 0x01 0x03 +@end verbatim + +OpenOCD can detect some of that information, but not all +of it. @xref{autoprobing,,Autoprobing}. +Unfortunately those TAPs can't always be autoconfigured, +because not all devices provide good support for that. +JTAG doesn't require supporting IDCODE instructions, and +chips with JTAG routers may not link TAPs into the chain +until they are told to do so. + +The configuration mechanism currently supported by OpenOCD +requires explicit configuration of all TAP devices using +@command{jtag newtap} commands, as detailed later in this chapter. +A command like this would declare one tap and name it @code{chip1.cpu}: + +@example +jtag newtap chip1 cpu -irlen 4 -expected-id 0x3ba00477 +@end example + +Each target configuration file lists the TAPs provided +by a given chip. +Board configuration files combine all the targets on a board, +and so forth. +Note that @emph{the order in which TAPs are declared is very important.} +It must match the order in the JTAG scan chain, both inside +a single chip and between them. +@xref{faqtaporder,,FAQ TAP Order}. + +For example, the ST Microsystems STR912 chip has +three separate TAPs@footnote{See the ST +document titled: @emph{STR91xFAxxx, Section 3.15 Jtag Interface, Page: +28/102, Figure 3: JTAG chaining inside the STR91xFA}. +@url{http://eu.st.com/stonline/products/literature/ds/13495.pdf}}. +To configure those taps, @file{target/str912.cfg} +includes commands something like this: + +@example +jtag newtap str912 flash ... params ... +jtag newtap str912 cpu ... params ... +jtag newtap str912 bs ... params ... +@end example + +Actual config files use a variable instead of literals like +@option{str912}, to support more than one chip of each type. +@xref{Config File Guidelines}. + +@deffn Command {jtag names} +Returns the names of all current TAPs in the scan chain. +Use @command{jtag cget} or @command{jtag tapisenabled} +to examine attributes and state of each TAP. +@example +foreach t [jtag names] @{ + puts [format "TAP: %s\n" $t] +@} +@end example +@end deffn + +@deffn Command {scan_chain} +Displays the TAPs in the scan chain configuration, +and their status. +The set of TAPs listed by this command is fixed by +exiting the OpenOCD configuration stage, +but systems with a JTAG router can +enable or disable TAPs dynamically. +@end deffn + +@c FIXME! "jtag cget" should be able to return all TAP +@c attributes, like "$target_name cget" does for targets. + +@c Probably want "jtag eventlist", and a "tap-reset" event +@c (on entry to RESET state). + +@section TAP Names +@cindex dotted name + +When TAP objects are declared with @command{jtag newtap}, +a @dfn{dotted.name} is created for the TAP, combining the +name of a module (usually a chip) and a label for the TAP. +For example: @code{xilinx.tap}, @code{str912.flash}, +@code{omap3530.jrc}, @code{dm6446.dsp}, or @code{stm32.cpu}. +Many other commands use that dotted.name to manipulate or +refer to the TAP. For example, CPU configuration uses the +name, as does declaration of NAND or NOR flash banks. + +The components of a dotted name should follow ``C'' symbol +name rules: start with an alphabetic character, then numbers +and underscores are OK; while others (including dots!) are not. + +@quotation Tip +In older code, JTAG TAPs were numbered from 0..N. +This feature is still present. +However its use is highly discouraged, and +should not be relied on; it will be removed by mid-2010. +Update all of your scripts to use TAP names rather than numbers, +by paying attention to the runtime warnings they trigger. +Using TAP numbers in target configuration scripts prevents +reusing those scripts on boards with multiple targets. +@end quotation + +@section TAP Declaration Commands + +@c shouldn't this be(come) a {Config Command}? +@deffn Command {jtag newtap} chipname tapname configparams... +Declares a new TAP with the dotted name @var{chipname}.@var{tapname}, +and configured according to the various @var{configparams}. + +The @var{chipname} is a symbolic name for the chip. +Conventionally target config files use @code{$_CHIPNAME}, +defaulting to the model name given by the chip vendor but +overridable. + +@cindex TAP naming convention +The @var{tapname} reflects the role of that TAP, +and should follow this convention: + +@itemize @bullet +@item @code{bs} -- For boundary scan if this is a seperate TAP; +@item @code{cpu} -- The main CPU of the chip, alternatively +@code{arm} and @code{dsp} on chips with both ARM and DSP CPUs, +@code{arm1} and @code{arm2} on chips two ARMs, and so forth; +@item @code{etb} -- For an embedded trace buffer (example: an ARM ETB11); +@item @code{flash} -- If the chip has a flash TAP, like the str912; +@item @code{jrc} -- For JTAG route controller (example: the ICEpick modules +on many Texas Instruments chips, like the OMAP3530 on Beagleboards); +@item @code{tap} -- Should be used only FPGA or CPLD like devices +with a single TAP; +@item @code{unknownN} -- If you have no idea what the TAP is for (N is a number); +@item @emph{when in doubt} -- Use the chip maker's name in their data sheet. +For example, the Freescale IMX31 has a SDMA (Smart DMA) with +a JTAG TAP; that TAP should be named @code{sdma}. +@end itemize + +Every TAP requires at least the following @var{configparams}: + +@itemize @bullet +@item @code{-irlen} @var{NUMBER} +@*The length in bits of the +instruction register, such as 4 or 5 bits. +@end itemize + +A TAP may also provide optional @var{configparams}: + +@itemize @bullet +@item @code{-disable} (or @code{-enable}) +@*Use the @code{-disable} parameter to flag a TAP which is not +linked in to the scan chain after a reset using either TRST +or the JTAG state machine's @sc{reset} state. +You may use @code{-enable} to highlight the default state +(the TAP is linked in). +@xref{enablinganddisablingtaps,,Enabling and Disabling TAPs}. +@item @code{-expected-id} @var{number} +@*A non-zero @var{number} represents a 32-bit IDCODE +which you expect to find when the scan chain is examined. +These codes are not required by all JTAG devices. +@emph{Repeat the option} as many times as required if more than one +ID code could appear (for example, multiple versions). +Specify @var{number} as zero to suppress warnings about IDCODE +values that were found but not included in the list. + +Provide this value if at all possible, since it lets OpenOCD +tell when the scan chain it sees isn't right. These values +are provided in vendors' chip documentation, usually a technical +reference manual. Sometimes you may need to probe the JTAG +hardware to find these values. +@xref{autoprobing,,Autoprobing}. +@item @code{-ignore-version} +@*Specify this to ignore the JTAG version field in the @code{-expected-id} +option. When vendors put out multiple versions of a chip, or use the same +JTAG-level ID for several largely-compatible chips, it may be more practical +to ignore the version field than to update config files to handle all of +the various chip IDs. The version field is defined as bit 28-31 of the IDCODE. +@item @code{-ircapture} @var{NUMBER} +@*The bit pattern loaded by the TAP into the JTAG shift register +on entry to the @sc{ircapture} state, such as 0x01. +JTAG requires the two LSBs of this value to be 01. +By default, @code{-ircapture} and @code{-irmask} are set +up to verify that two-bit value. You may provide +additional bits, if you know them, or indicate that +a TAP doesn't conform to the JTAG specification. +@item @code{-irmask} @var{NUMBER} +@*A mask used with @code{-ircapture} +to verify that instruction scans work correctly. +Such scans are not used by OpenOCD except to verify that +there seems to be no problems with JTAG scan chain operations. +@end itemize +@end deffn + +@section Other TAP commands + +@deffn Command {jtag cget} dotted.name @option{-event} name +@deffnx Command {jtag configure} dotted.name @option{-event} name string +At this writing this TAP attribute +mechanism is used only for event handling. +(It is not a direct analogue of the @code{cget}/@code{configure} +mechanism for debugger targets.) +See the next section for information about the available events. + +The @code{configure} subcommand assigns an event handler, +a TCL string which is evaluated when the event is triggered. +The @code{cget} subcommand returns that handler. +@end deffn + +@section TAP Events +@cindex events +@cindex TAP events + +OpenOCD includes two event mechanisms. +The one presented here applies to all JTAG TAPs. +The other applies to debugger targets, +which are associated with certain TAPs. + +The TAP events currently defined are: + +@itemize @bullet +@item @b{post-reset} +@* The TAP has just completed a JTAG reset. +The tap may still be in the JTAG @sc{reset} state. +Handlers for these events might perform initialization sequences +such as issuing TCK cycles, TMS sequences to ensure +exit from the ARM SWD mode, and more. + +Because the scan chain has not yet been verified, handlers for these events +@emph{should not issue commands which scan the JTAG IR or DR registers} +of any particular target. +@b{NOTE:} As this is written (September 2009), nothing prevents such access. +@item @b{setup} +@* The scan chain has been reset and verified. +This handler may enable TAPs as needed. +@item @b{tap-disable} +@* The TAP needs to be disabled. This handler should +implement @command{jtag tapdisable} +by issuing the relevant JTAG commands. +@item @b{tap-enable} +@* The TAP needs to be enabled. This handler should +implement @command{jtag tapenable} +by issuing the relevant JTAG commands. +@end itemize + +If you need some action after each JTAG reset, which isn't actually +specific to any TAP (since you can't yet trust the scan chain's +contents to be accurate), you might: + +@example +jtag configure CHIP.jrc -event post-reset @{ + echo "JTAG Reset done" + ... non-scan jtag operations to be done after reset +@} +@end example + + +@anchor{enablinganddisablingtaps} +@section Enabling and Disabling TAPs +@cindex JTAG Route Controller +@cindex jrc + +In some systems, a @dfn{JTAG Route Controller} (JRC) +is used to enable and/or disable specific JTAG TAPs. +Many ARM based chips from Texas Instruments include +an ``ICEpick'' module, which is a JRC. +Such chips include DaVinci and OMAP3 processors. + +A given TAP may not be visible until the JRC has been +told to link it into the scan chain; and if the JRC +has been told to unlink that TAP, it will no longer +be visible. +Such routers address problems that JTAG ``bypass mode'' +ignores, such as: + +@itemize +@item The scan chain can only go as fast as its slowest TAP. +@item Having many TAPs slows instruction scans, since all +TAPs receive new instructions. +@item TAPs in the scan chain must be powered up, which wastes +power and prevents debugging some power management mechanisms. +@end itemize + +The IEEE 1149.1 JTAG standard has no concept of a ``disabled'' tap, +as implied by the existence of JTAG routers. +However, the upcoming IEEE 1149.7 framework (layered on top of JTAG) +does include a kind of JTAG router functionality. + +@c (a) currently the event handlers don't seem to be able to +@c fail in a way that could lead to no-change-of-state. + +In OpenOCD, tap enabling/disabling is invoked by the Tcl commands +shown below, and is implemented using TAP event handlers. +So for example, when defining a TAP for a CPU connected to +a JTAG router, your @file{target.cfg} file +should define TAP event handlers using +code that looks something like this: + +@example +jtag configure CHIP.cpu -event tap-enable @{ + ... jtag operations using CHIP.jrc +@} +jtag configure CHIP.cpu -event tap-disable @{ + ... jtag operations using CHIP.jrc +@} +@end example + +Then you might want that CPU's TAP enabled almost all the time: + +@example +jtag configure $CHIP.jrc -event setup "jtag tapenable $CHIP.cpu" +@end example + +Note how that particular setup event handler declaration +uses quotes to evaluate @code{$CHIP} when the event is configured. +Using brackets @{ @} would cause it to be evaluated later, +at runtime, when it might have a different value. + +@deffn Command {jtag tapdisable} dotted.name +If necessary, disables the tap +by sending it a @option{tap-disable} event. +Returns the string "1" if the tap +specified by @var{dotted.name} is enabled, +and "0" if it is disabled. +@end deffn + +@deffn Command {jtag tapenable} dotted.name +If necessary, enables the tap +by sending it a @option{tap-enable} event. +Returns the string "1" if the tap +specified by @var{dotted.name} is enabled, +and "0" if it is disabled. +@end deffn + +@deffn Command {jtag tapisenabled} dotted.name +Returns the string "1" if the tap +specified by @var{dotted.name} is enabled, +and "0" if it is disabled. + +@quotation Note +Humans will find the @command{scan_chain} command more helpful +for querying the state of the JTAG taps. +@end quotation +@end deffn + +@anchor{autoprobing} +@section Autoprobing +@cindex autoprobe +@cindex JTAG autoprobe + +TAP configuration is the first thing that needs to be done +after interface and reset configuration. Sometimes it's +hard finding out what TAPs exist, or how they are identified. +Vendor documentation is not always easy to find and use. + +To help you get past such problems, OpenOCD has a limited +@emph{autoprobing} ability to look at the scan chain, doing +a @dfn{blind interrogation} and then reporting the TAPs it finds. +To use this mechanism, start the OpenOCD server with only data +that configures your JTAG interface, and arranges to come up +with a slow clock (many devices don't support fast JTAG clocks +right when they come out of reset). + +For example, your @file{openocd.cfg} file might have: + +@example +source [find interface/olimex-arm-usb-tiny-h.cfg] +reset_config trst_and_srst +jtag_rclk 8 +@end example + +When you start the server without any TAPs configured, it will +attempt to autoconfigure the TAPs. There are two parts to this: + +@enumerate +@item @emph{TAP discovery} ... +After a JTAG reset (sometimes a system reset may be needed too), +each TAP's data registers will hold the contents of either the +IDCODE or BYPASS register. +If JTAG communication is working, OpenOCD will see each TAP, +and report what @option{-expected-id} to use with it. +@item @emph{IR Length discovery} ... +Unfortunately JTAG does not provide a reliable way to find out +the value of the @option{-irlen} parameter to use with a TAP +that is discovered. +If OpenOCD can discover the length of a TAP's instruction +register, it will report it. +Otherwise you may need to consult vendor documentation, such +as chip data sheets or BSDL files. +@end enumerate + +In many cases your board will have a simple scan chain with just +a single device. Here's what OpenOCD reported with one board +that's a bit more complex: + +@example +clock speed 8 kHz +There are no enabled taps. AUTO PROBING MIGHT NOT WORK!! +AUTO auto0.tap - use "jtag newtap auto0 tap -expected-id 0x2b900f0f ..." +AUTO auto1.tap - use "jtag newtap auto1 tap -expected-id 0x07926001 ..." +AUTO auto2.tap - use "jtag newtap auto2 tap -expected-id 0x0b73b02f ..." +AUTO auto0.tap - use "... -irlen 4" +AUTO auto1.tap - use "... -irlen 4" +AUTO auto2.tap - use "... -irlen 6" +no gdb ports allocated as no target has been specified +@end example + +Given that information, you should be able to either find some existing +config files to use, or create your own. If you create your own, you +would configure from the bottom up: first a @file{target.cfg} file +with these TAPs, any targets associated with them, and any on-chip +resources; then a @file{board.cfg} with off-chip resources, clocking, +and so forth. + +@node CPU Configuration +@chapter CPU Configuration +@cindex GDB target + +This chapter discusses how to set up GDB debug targets for CPUs. +You can also access these targets without GDB +(@pxref{Architecture and Core Commands}, +and @ref{targetstatehandling,,Target State handling}) and +through various kinds of NAND and NOR flash commands. +If you have multiple CPUs you can have multiple such targets. + +We'll start by looking at how to examine the targets you have, +then look at how to add one more target and how to configure it. + +@section Target List +@cindex target, current +@cindex target, list + +All targets that have been set up are part of a list, +where each member has a name. +That name should normally be the same as the TAP name. +You can display the list with the @command{targets} +(plural!) command. +This display often has only one CPU; here's what it might +look like with more than one: +@verbatim + TargetName Type Endian TapName State +-- ------------------ ---------- ------ ------------------ ------------ + 0* at91rm9200.cpu arm920t little at91rm9200.cpu running + 1 MyTarget cortex_m little mychip.foo tap-disabled +@end verbatim + +One member of that list is the @dfn{current target}, which +is implicitly referenced by many commands. +It's the one marked with a @code{*} near the target name. +In particular, memory addresses often refer to the address +space seen by that current target. +Commands like @command{mdw} (memory display words) +and @command{flash erase_address} (erase NOR flash blocks) +are examples; and there are many more. + +Several commands let you examine the list of targets: + +@deffn Command {target count} +@emph{Note: target numbers are deprecated; don't use them. +They will be removed shortly after August 2010, including this command. +Iterate target using @command{target names}, not by counting.} + +Returns the number of targets, @math{N}. +The highest numbered target is @math{N - 1}. +@example +set c [target count] +for @{ set x 0 @} @{ $x < $c @} @{ incr x @} @{ + # Assuming you have created this function + print_target_details $x +@} +@end example +@end deffn + +@deffn Command {target current} +Returns the name of the current target. +@end deffn + +@deffn Command {target names} +Lists the names of all current targets in the list. +@example +foreach t [target names] @{ + puts [format "Target: %s\n" $t] +@} +@end example +@end deffn + +@deffn Command {target number} number +@emph{Note: target numbers are deprecated; don't use them. +They will be removed shortly after August 2010, including this command.} + +The list of targets is numbered starting at zero. +This command returns the name of the target at index @var{number}. +@example +set thename [target number $x] +puts [format "Target %d is: %s\n" $x $thename] +@end example +@end deffn + +@c yep, "target list" would have been better. +@c plus maybe "target setdefault". + +@deffn Command targets [name] +@emph{Note: the name of this command is plural. Other target +command names are singular.} + +With no parameter, this command displays a table of all known +targets in a user friendly form. + +With a parameter, this command sets the current target to +the given target with the given @var{name}; this is +only relevant on boards which have more than one target. +@end deffn + +@section Target CPU Types and Variants +@cindex target type +@cindex CPU type +@cindex CPU variant + +Each target has a @dfn{CPU type}, as shown in the output of +the @command{targets} command. You need to specify that type +when calling @command{target create}. +The CPU type indicates more than just the instruction set. +It also indicates how that instruction set is implemented, +what kind of debug support it integrates, +whether it has an MMU (and if so, what kind), +what core-specific commands may be available +(@pxref{Architecture and Core Commands}), +and more. + +For some CPU types, OpenOCD also defines @dfn{variants} which +indicate differences that affect their handling. +For example, a particular implementation bug might need to be +worked around in some chip versions. + +It's easy to see what target types are supported, +since there's a command to list them. +However, there is currently no way to list what target variants +are supported (other than by reading the OpenOCD source code). + +@anchor{targettypes} +@deffn Command {target types} +Lists all supported target types. +At this writing, the supported CPU types and variants are: + +@itemize @bullet +@item @code{arm11} -- this is a generation of ARMv6 cores +@item @code{arm720t} -- this is an ARMv4 core with an MMU +@item @code{arm7tdmi} -- this is an ARMv4 core +@item @code{arm920t} -- this is an ARMv4 core with an MMU +@item @code{arm926ejs} -- this is an ARMv5 core with an MMU +@item @code{arm966e} -- this is an ARMv5 core +@item @code{arm9tdmi} -- this is an ARMv4 core +@item @code{avr} -- implements Atmel's 8-bit AVR instruction set. +(Support for this is preliminary and incomplete.) +@item @code{cortex_a} -- this is an ARMv7 core with an MMU +@item @code{cortex_m} -- this is an ARMv7 core, supporting only the +compact Thumb2 instruction set. +@item @code{dragonite} -- resembles arm966e +@item @code{dsp563xx} -- implements Freescale's 24-bit DSP. +(Support for this is still incomplete.) +@item @code{fa526} -- resembles arm920 (w/o Thumb) +@item @code{feroceon} -- resembles arm926 +@item @code{mips_m4k} -- a MIPS core. This supports one variant: +@item @code{xscale} -- this is actually an architecture, +not a CPU type. It is based on the ARMv5 architecture. +There are several variants defined: +@itemize @minus +@item @code{ixp42x}, @code{ixp45x}, @code{ixp46x}, +@code{pxa27x} ... instruction register length is 7 bits +@item @code{pxa250}, @code{pxa255}, +@code{pxa26x} ... instruction register length is 5 bits +@item @code{pxa3xx} ... instruction register length is 11 bits +@end itemize +@end itemize +@end deffn + +To avoid being confused by the variety of ARM based cores, remember +this key point: @emph{ARM is a technology licencing company}. +(See: @url{http://www.arm.com}.) +The CPU name used by OpenOCD will reflect the CPU design that was +licenced, not a vendor brand which incorporates that design. +Name prefixes like arm7, arm9, arm11, and cortex +reflect design generations; +while names like ARMv4, ARMv5, ARMv6, and ARMv7 +reflect an architecture version implemented by a CPU design. + +@anchor{targetconfiguration} +@section Target Configuration + +Before creating a ``target'', you must have added its TAP to the scan chain. +When you've added that TAP, you will have a @code{dotted.name} +which is used to set up the CPU support. +The chip-specific configuration file will normally configure its CPU(s) +right after it adds all of the chip's TAPs to the scan chain. + +Although you can set up a target in one step, it's often clearer if you +use shorter commands and do it in two steps: create it, then configure +optional parts. +All operations on the target after it's created will use a new +command, created as part of target creation. + +The two main things to configure after target creation are +a work area, which usually has target-specific defaults even +if the board setup code overrides them later; +and event handlers (@pxref{targetevents,,Target Events}), which tend +to be much more board-specific. +The key steps you use might look something like this + +@example +target create MyTarget cortex_m -chain-position mychip.cpu +$MyTarget configure -work-area-phys 0x08000 -work-area-size 8096 +$MyTarget configure -event reset-deassert-pre @{ jtag_rclk 5 @} +$MyTarget configure -event reset-init @{ myboard_reinit @} +@end example + +You should specify a working area if you can; typically it uses some +on-chip SRAM. +Such a working area can speed up many things, including bulk +writes to target memory; +flash operations like checking to see if memory needs to be erased; +GDB memory checksumming; +and more. + +@quotation Warning +On more complex chips, the work area can become +inaccessible when application code +(such as an operating system) +enables or disables the MMU. +For example, the particular MMU context used to acess the virtual +address will probably matter ... and that context might not have +easy access to other addresses needed. +At this writing, OpenOCD doesn't have much MMU intelligence. +@end quotation + +It's often very useful to define a @code{reset-init} event handler. +For systems that are normally used with a boot loader, +common tasks include updating clocks and initializing memory +controllers. +That may be needed to let you write the boot loader into flash, +in order to ``de-brick'' your board; or to load programs into +external DDR memory without having run the boot loader. + +@deffn Command {target create} target_name type configparams... +This command creates a GDB debug target that refers to a specific JTAG tap. +It enters that target into a list, and creates a new +command (@command{@var{target_name}}) which is used for various +purposes including additional configuration. + +@itemize @bullet +@item @var{target_name} ... is the name of the debug target. +By convention this should be the same as the @emph{dotted.name} +of the TAP associated with this target, which must be specified here +using the @code{-chain-position @var{dotted.name}} configparam. + +This name is also used to create the target object command, +referred to here as @command{$target_name}, +and in other places the target needs to be identified. +@item @var{type} ... specifies the target type. @xref{targettypes,,target types}. +@item @var{configparams} ... all parameters accepted by +@command{$target_name configure} are permitted. +If the target is big-endian, set it here with @code{-endian big}. +If the variant matters, set it here with @code{-variant}. + +You @emph{must} set the @code{-chain-position @var{dotted.name}} here. +@end itemize +@end deffn + +@deffn Command {$target_name configure} configparams... +The options accepted by this command may also be +specified as parameters to @command{target create}. +Their values can later be queried one at a time by +using the @command{$target_name cget} command. + +@emph{Warning:} changing some of these after setup is dangerous. +For example, moving a target from one TAP to another; +and changing its endianness or variant. + +@itemize @bullet + +@item @code{-chain-position} @var{dotted.name} -- names the TAP +used to access this target. + +@item @code{-endian} (@option{big}|@option{little}) -- specifies +whether the CPU uses big or little endian conventions + +@item @code{-event} @var{event_name} @var{event_body} -- +@xref{targetevents,,Target Events}. +Note that this updates a list of named event handlers. +Calling this twice with two different event names assigns +two different handlers, but calling it twice with the +same event name assigns only one handler. + +@item @code{-variant} @var{name} -- specifies a variant of the target, +which OpenOCD needs to know about. + +@item @code{-work-area-backup} (@option{0}|@option{1}) -- says +whether the work area gets backed up; by default, +@emph{it is not backed up.} +When possible, use a working_area that doesn't need to be backed up, +since performing a backup slows down operations. +For example, the beginning of an SRAM block is likely to +be used by most build systems, but the end is often unused. + +@item @code{-work-area-size} @var{size} -- specify work are size, +in bytes. The same size applies regardless of whether its physical +or virtual address is being used. + +@item @code{-work-area-phys} @var{address} -- set the work area +base @var{address} to be used when no MMU is active. + +@item @code{-work-area-virt} @var{address} -- set the work area +base @var{address} to be used when an MMU is active. +@emph{Do not specify a value for this except on targets with an MMU.} +The value should normally correspond to a static mapping for the +@code{-work-area-phys} address, set up by the current operating system. + +@item @code{-rtos} @var{rtos_type} -- enable rtos support for target, +@var{rtos_type} can be one of @option{auto}|@option{eCos}|@option{ThreadX}| +@option{FreeRTOS}|@option{linux}|@option{ChibiOS}. + +@end itemize +@end deffn + +@section Other $target_name Commands +@cindex object command + +The Tcl/Tk language has the concept of object commands, +and OpenOCD adopts that same model for targets. + +A good Tk example is a on screen button. +Once a button is created a button +has a name (a path in Tk terms) and that name is useable as a first +class command. For example in Tk, one can create a button and later +configure it like this: + +@example +# Create +button .foobar -background red -command @{ foo @} +# Modify +.foobar configure -foreground blue +# Query +set x [.foobar cget -background] +# Report +puts [format "The button is %s" $x] +@end example + +In OpenOCD's terms, the ``target'' is an object just like a Tcl/Tk +button, and its object commands are invoked the same way. + +@example +str912.cpu mww 0x1234 0x42 +omap3530.cpu mww 0x5555 123 +@end example + +The commands supported by OpenOCD target objects are: + +@deffn Command {$target_name arp_examine} +@deffnx Command {$target_name arp_halt} +@deffnx Command {$target_name arp_poll} +@deffnx Command {$target_name arp_reset} +@deffnx Command {$target_name arp_waitstate} +Internal OpenOCD scripts (most notably @file{startup.tcl}) +use these to deal with specific reset cases. +They are not otherwise documented here. +@end deffn + +@deffn Command {$target_name array2mem} arrayname width address count +@deffnx Command {$target_name mem2array} arrayname width address count +These provide an efficient script-oriented interface to memory. +The @code{array2mem} primitive writes bytes, halfwords, or words; +while @code{mem2array} reads them. +In both cases, the TCL side uses an array, and +the target side uses raw memory. + +The efficiency comes from enabling the use of +bulk JTAG data transfer operations. +The script orientation comes from working with data +values that are packaged for use by TCL scripts; +@command{mdw} type primitives only print data they retrieve, +and neither store nor return those values. + +@itemize +@item @var{arrayname} ... is the name of an array variable +@item @var{width} ... is 8/16/32 - indicating the memory access size +@item @var{address} ... is the target memory address +@item @var{count} ... is the number of elements to process +@end itemize +@end deffn + +@deffn Command {$target_name cget} queryparm +Each configuration parameter accepted by +@command{$target_name configure} +can be individually queried, to return its current value. +The @var{queryparm} is a parameter name +accepted by that command, such as @code{-work-area-phys}. +There are a few special cases: + +@itemize @bullet +@item @code{-event} @var{event_name} -- returns the handler for the +event named @var{event_name}. +This is a special case because setting a handler requires +two parameters. +@item @code{-type} -- returns the target type. +This is a special case because this is set using +@command{target create} and can't be changed +using @command{$target_name configure}. +@end itemize + +For example, if you wanted to summarize information about +all the targets you might use something like this: + +@example +foreach name [target names] @{ + set y [$name cget -endian] + set z [$name cget -type] + puts [format "Chip %d is %s, Endian: %s, type: %s" \ + $x $name $y $z] +@} +@end example +@end deffn + +@anchor{targetcurstate} +@deffn Command {$target_name curstate} +Displays the current target state: +@code{debug-running}, +@code{halted}, +@code{reset}, +@code{running}, or @code{unknown}. +(Also, @pxref{eventpolling,,Event Polling}.) +@end deffn + +@deffn Command {$target_name eventlist} +Displays a table listing all event handlers +currently associated with this target. +@xref{targetevents,,Target Events}. +@end deffn + +@deffn Command {$target_name invoke-event} event_name +Invokes the handler for the event named @var{event_name}. +(This is primarily intended for use by OpenOCD framework +code, for example by the reset code in @file{startup.tcl}.) +@end deffn + +@deffn Command {$target_name mdw} addr [count] +@deffnx Command {$target_name mdh} addr [count] +@deffnx Command {$target_name mdb} addr [count] +Display contents of address @var{addr}, as +32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}), +or 8-bit bytes (@command{mdb}). +If @var{count} is specified, displays that many units. +(If you want to manipulate the data instead of displaying it, +see the @code{mem2array} primitives.) +@end deffn + +@deffn Command {$target_name mww} addr word +@deffnx Command {$target_name mwh} addr halfword +@deffnx Command {$target_name mwb} addr byte +Writes the specified @var{word} (32 bits), +@var{halfword} (16 bits), or @var{byte} (8-bit) pattern, +at the specified address @var{addr}. +@end deffn + +@anchor{targetevents} +@section Target Events +@cindex target events +@cindex events +At various times, certain things can happen, or you want them to happen. +For example: +@itemize @bullet +@item What should happen when GDB connects? Should your target reset? +@item When GDB tries to flash the target, do you need to enable the flash via a special command? +@item Is using SRST appropriate (and possible) on your system? +Or instead of that, do you need to issue JTAG commands to trigger reset? +SRST usually resets everything on the scan chain, which can be inappropriate. +@item During reset, do you need to write to certain memory locations +to set up system clocks or +to reconfigure the SDRAM? +How about configuring the watchdog timer, or other peripherals, +to stop running while you hold the core stopped for debugging? +@end itemize + +All of the above items can be addressed by target event handlers. +These are set up by @command{$target_name configure -event} or +@command{target create ... -event}. + +The programmer's model matches the @code{-command} option used in Tcl/Tk +buttons and events. The two examples below act the same, but one creates +and invokes a small procedure while the other inlines it. + +@example +proc my_attach_proc @{ @} @{ + echo "Reset..." + reset halt +@} +mychip.cpu configure -event gdb-attach my_attach_proc +mychip.cpu configure -event gdb-attach @{ + echo "Reset..." + # To make flash probe and gdb load to flash work we need a reset init. + reset init +@} +@end example + +The following target events are defined: + +@itemize @bullet +@item @b{debug-halted} +@* The target has halted for debug reasons (i.e.: breakpoint) +@item @b{debug-resumed} +@* The target has resumed (i.e.: gdb said run) +@item @b{early-halted} +@* Occurs early in the halt process +@item @b{examine-start} +@* Before target examine is called. +@item @b{examine-end} +@* After target examine is called with no errors. +@item @b{gdb-attach} +@* When GDB connects. This is before any communication with the target, so this +can be used to set up the target so it is possible to probe flash. Probing flash +is necessary during gdb connect if gdb load is to write the image to flash. Another +use of the flash memory map is for GDB to automatically hardware/software breakpoints +depending on whether the breakpoint is in RAM or read only memory. +@item @b{gdb-detach} +@* When GDB disconnects +@item @b{gdb-end} +@* When the target has halted and GDB is not doing anything (see early halt) +@item @b{gdb-flash-erase-start} +@* Before the GDB flash process tries to erase the flash +@item @b{gdb-flash-erase-end} +@* After the GDB flash process has finished erasing the flash +@item @b{gdb-flash-write-start} +@* Before GDB writes to the flash +@item @b{gdb-flash-write-end} +@* After GDB writes to the flash +@item @b{gdb-start} +@* Before the target steps, gdb is trying to start/resume the target +@item @b{halted} +@* The target has halted +@item @b{reset-assert-pre} +@* Issued as part of @command{reset} processing +after @command{reset_init} was triggered +but before either SRST alone is re-asserted on the scan chain, +or @code{reset-assert} is triggered. +@item @b{reset-assert} +@* Issued as part of @command{reset} processing +after @command{reset-assert-pre} was triggered. +When such a handler is present, cores which support this event will use +it instead of asserting SRST. +This support is essential for debugging with JTAG interfaces which +don't include an SRST line (JTAG doesn't require SRST), and for +selective reset on scan chains that have multiple targets. +@item @b{reset-assert-post} +@* Issued as part of @command{reset} processing +after @code{reset-assert} has been triggered. +or the target asserted SRST on the entire scan chain. +@item @b{reset-deassert-pre} +@* Issued as part of @command{reset} processing +after @code{reset-assert-post} has been triggered. +@item @b{reset-deassert-post} +@* Issued as part of @command{reset} processing +after @code{reset-deassert-pre} has been triggered +and (if the target is using it) after SRST has been +released on the scan chain. +@item @b{reset-end} +@* Issued as the final step in @command{reset} processing. +@ignore +@item @b{reset-halt-post} +@* Currently not used +@item @b{reset-halt-pre} +@* Currently not used +@end ignore +@item @b{reset-init} +@* Used by @b{reset init} command for board-specific initialization. +This event fires after @emph{reset-deassert-post}. + +This is where you would configure PLLs and clocking, set up DRAM so +you can download programs that don't fit in on-chip SRAM, set up pin +multiplexing, and so on. +(You may be able to switch to a fast JTAG clock rate here, after +the target clocks are fully set up.) +@item @b{reset-start} +@* Issued as part of @command{reset} processing +before @command{reset_init} is called. + +This is the most robust place to use @command{jtag_rclk} +or @command{adapter_khz} to switch to a low JTAG clock rate, +when reset disables PLLs needed to use a fast clock. +@ignore +@item @b{reset-wait-pos} +@* Currently not used +@item @b{reset-wait-pre} +@* Currently not used +@end ignore +@item @b{resume-start} +@* Before any target is resumed +@item @b{resume-end} +@* After all targets have resumed +@item @b{resumed} +@* Target has resumed +@end itemize + +@node Flash Commands +@chapter Flash Commands + +OpenOCD has different commands for NOR and NAND flash; +the ``flash'' command works with NOR flash, while +the ``nand'' command works with NAND flash. +This partially reflects different hardware technologies: +NOR flash usually supports direct CPU instruction and data bus access, +while data from a NAND flash must be copied to memory before it can be +used. (SPI flash must also be copied to memory before use.) +However, the documentation also uses ``flash'' as a generic term; +for example, ``Put flash configuration in board-specific files''. + +Flash Steps: +@enumerate +@item Configure via the command @command{flash bank} +@* Do this in a board-specific configuration file, +passing parameters as needed by the driver. +@item Operate on the flash via @command{flash subcommand} +@* Often commands to manipulate the flash are typed by a human, or run +via a script in some automated way. Common tasks include writing a +boot loader, operating system, or other data. +@item GDB Flashing +@* Flashing via GDB requires the flash be configured via ``flash +bank'', and the GDB flash features be enabled. +@xref{gdbconfiguration,,GDB Configuration}. +@end enumerate + +Many CPUs have the ablity to ``boot'' from the first flash bank. +This means that misprogramming that bank can ``brick'' a system, +so that it can't boot. +JTAG tools, like OpenOCD, are often then used to ``de-brick'' the +board by (re)installing working boot firmware. + +@anchor{norconfiguration} +@section Flash Configuration Commands +@cindex flash configuration + +@deffn {Config Command} {flash bank} name driver base size chip_width bus_width target [driver_options] +Configures a flash bank which provides persistent storage +for addresses from @math{base} to @math{base + size - 1}. +These banks will often be visible to GDB through the target's memory map. +In some cases, configuring a flash bank will activate extra commands; +see the driver-specific documentation. + +@itemize @bullet +@item @var{name} ... may be used to reference the flash bank +in other flash commands. A number is also available. +@item @var{driver} ... identifies the controller driver +associated with the flash bank being declared. +This is usually @code{cfi} for external flash, or else +the name of a microcontroller with embedded flash memory. +@xref{flashdriverlist,,Flash Driver List}. +@item @var{base} ... Base address of the flash chip. +@item @var{size} ... Size of the chip, in bytes. +For some drivers, this value is detected from the hardware. +@item @var{chip_width} ... Width of the flash chip, in bytes; +ignored for most microcontroller drivers. +@item @var{bus_width} ... Width of the data bus used to access the +chip, in bytes; ignored for most microcontroller drivers. +@item @var{target} ... Names the target used to issue +commands to the flash controller. +@comment Actually, it's currently a controller-specific parameter... +@item @var{driver_options} ... drivers may support, or require, +additional parameters. See the driver-specific documentation +for more information. +@end itemize +@quotation Note +This command is not available after OpenOCD initialization has completed. +Use it in board specific configuration files, not interactively. +@end quotation +@end deffn + +@comment the REAL name for this command is "ocd_flash_banks" +@comment less confusing would be: "flash list" (like "nand list") +@deffn Command {flash banks} +Prints a one-line summary of each device that was +declared using @command{flash bank}, numbered from zero. +Note that this is the @emph{plural} form; +the @emph{singular} form is a very different command. +@end deffn + +@deffn Command {flash list} +Retrieves a list of associative arrays for each device that was +declared using @command{flash bank}, numbered from zero. +This returned list can be manipulated easily from within scripts. +@end deffn + +@deffn Command {flash probe} num +Identify the flash, or validate the parameters of the configured flash. Operation +depends on the flash type. +The @var{num} parameter is a value shown by @command{flash banks}. +Most flash commands will implicitly @emph{autoprobe} the bank; +flash drivers can distinguish between probing and autoprobing, +but most don't bother. +@end deffn + +@section Erasing, Reading, Writing to Flash +@cindex flash erasing +@cindex flash reading +@cindex flash writing +@cindex flash programming +@anchor{flashprogrammingcommands} + +One feature distinguishing NOR flash from NAND or serial flash technologies +is that for read access, it acts exactly like any other addressible memory. +This means you can use normal memory read commands like @command{mdw} or +@command{dump_image} with it, with no special @command{flash} subcommands. +@xref{memoryaccess,,Memory access}, and @ref{imageaccess,,Image access}. + +Write access works differently. Flash memory normally needs to be erased +before it's written. Erasing a sector turns all of its bits to ones, and +writing can turn ones into zeroes. This is why there are special commands +for interactive erasing and writing, and why GDB needs to know which parts +of the address space hold NOR flash memory. + +@quotation Note +Most of these erase and write commands leverage the fact that NOR flash +chips consume target address space. They implicitly refer to the current +JTAG target, and map from an address in that target's address space +back to a flash bank. +@comment In May 2009, those mappings may fail if any bank associated +@comment with that target doesn't succesfuly autoprobe ... bug worth fixing? +A few commands use abstract addressing based on bank and sector numbers, +and don't depend on searching the current target and its address space. +Avoid confusing the two command models. +@end quotation + +Some flash chips implement software protection against accidental writes, +since such buggy writes could in some cases ``brick'' a system. +For such systems, erasing and writing may require sector protection to be +disabled first. +Examples include CFI flash such as ``Intel Advanced Bootblock flash'', +and AT91SAM7 on-chip flash. +@xref{flashprotect,,flash protect}. + +@deffn Command {flash erase_sector} num first last +Erase sectors in bank @var{num}, starting at sector @var{first} +up to and including @var{last}. +Sector numbering starts at 0. +Providing a @var{last} sector of @option{last} +specifies "to the end of the flash bank". +The @var{num} parameter is a value shown by @command{flash banks}. +@end deffn + +@deffn Command {flash erase_address} [@option{pad}] [@option{unlock}] address length +Erase sectors starting at @var{address} for @var{length} bytes. +Unless @option{pad} is specified, @math{address} must begin a +flash sector, and @math{address + length - 1} must end a sector. +Specifying @option{pad} erases extra data at the beginning and/or +end of the specified region, as needed to erase only full sectors. +The flash bank to use is inferred from the @var{address}, and +the specified length must stay within that bank. +As a special case, when @var{length} is zero and @var{address} is +the start of the bank, the whole flash is erased. +If @option{unlock} is specified, then the flash is unprotected +before erase starts. +@end deffn + +@deffn Command {flash fillw} address word length +@deffnx Command {flash fillh} address halfword length +@deffnx Command {flash fillb} address byte length +Fills flash memory with the specified @var{word} (32 bits), +@var{halfword} (16 bits), or @var{byte} (8-bit) pattern, +starting at @var{address} and continuing +for @var{length} units (word/halfword/byte). +No erasure is done before writing; when needed, that must be done +before issuing this command. +Writes are done in blocks of up to 1024 bytes, and each write is +verified by reading back the data and comparing it to what was written. +The flash bank to use is inferred from the @var{address} of +each block, and the specified length must stay within that bank. +@end deffn +@comment no current checks for errors if fill blocks touch multiple banks! + +@deffn Command {flash write_bank} num filename offset +Write the binary @file{filename} to flash bank @var{num}, +starting at @var{offset} bytes from the beginning of the bank. +The @var{num} parameter is a value shown by @command{flash banks}. +@end deffn + +@deffn Command {flash write_image} [erase] [unlock] filename [offset] [type] +Write the image @file{filename} to the current target's flash bank(s). +A relocation @var{offset} may be specified, in which case it is added +to the base address for each section in the image. +The file [@var{type}] can be specified +explicitly as @option{bin} (binary), @option{ihex} (Intel hex), +@option{elf} (ELF file), @option{s19} (Motorola s19). +@option{mem}, or @option{builder}. +The relevant flash sectors will be erased prior to programming +if the @option{erase} parameter is given. If @option{unlock} is +provided, then the flash banks are unlocked before erase and +program. The flash bank to use is inferred from the address of +each image section. + +@quotation Warning +Be careful using the @option{erase} flag when the flash is holding +data you want to preserve. +Portions of the flash outside those described in the image's +sections might be erased with no notice. +@itemize +@item +When a section of the image being written does not fill out all the +sectors it uses, the unwritten parts of those sectors are necessarily +also erased, because sectors can't be partially erased. +@item +Data stored in sector "holes" between image sections are also affected. +For example, "@command{flash write_image erase ...}" of an image with +one byte at the beginning of a flash bank and one byte at the end +erases the entire bank -- not just the two sectors being written. +@end itemize +Also, when flash protection is important, you must re-apply it after +it has been removed by the @option{unlock} flag. +@end quotation + +@end deffn + +@section Other Flash commands +@cindex flash protection + +@deffn Command {flash erase_check} num +Check erase state of sectors in flash bank @var{num}, +and display that status. +The @var{num} parameter is a value shown by @command{flash banks}. +@end deffn + +@deffn Command {flash info} num +Print info about flash bank @var{num} +The @var{num} parameter is a value shown by @command{flash banks}. +This command will first query the hardware, it does not print cached +and possibly stale information. +@end deffn + +@anchor{flashprotect} +@deffn Command {flash protect} num first last (@option{on}|@option{off}) +Enable (@option{on}) or disable (@option{off}) protection of flash sectors +in flash bank @var{num}, starting at sector @var{first} +and continuing up to and including @var{last}. +Providing a @var{last} sector of @option{last} +specifies "to the end of the flash bank". +The @var{num} parameter is a value shown by @command{flash banks}. +@end deffn + +@anchor{program} +@deffn Command {program} filename [verify] [reset] [offset] +This is a helper script that simplifies using OpenOCD as a standalone +programmer. The only required parameter is @option{filename}, the others are optional. +@xref{Flash Programming}. +@end deffn + +@anchor{flashdriverlist} +@section Flash Driver List +As noted above, the @command{flash bank} command requires a driver name, +and allows driver-specific options and behaviors. +Some drivers also activate driver-specific commands. + +@subsection External Flash + +@deffn {Flash Driver} cfi +@cindex Common Flash Interface +@cindex CFI +The ``Common Flash Interface'' (CFI) is the main standard for +external NOR flash chips, each of which connects to a +specific external chip select on the CPU. +Frequently the first such chip is used to boot the system. +Your board's @code{reset-init} handler might need to +configure additional chip selects using other commands (like: @command{mww} to +configure a bus and its timings), or +perhaps configure a GPIO pin that controls the ``write protect'' pin +on the flash chip. +The CFI driver can use a target-specific working area to significantly +speed up operation. + +The CFI driver can accept the following optional parameters, in any order: + +@itemize +@item @var{jedec_probe} ... is used to detect certain non-CFI flash ROMs, +like AM29LV010 and similar types. +@item @var{x16_as_x8} ... when a 16-bit flash is hooked up to an 8-bit bus. +@end itemize + +To configure two adjacent banks of 16 MBytes each, both sixteen bits (two bytes) +wide on a sixteen bit bus: + +@example +flash bank $_FLASHNAME cfi 0x00000000 0x01000000 2 2 $_TARGETNAME +flash bank $_FLASHNAME cfi 0x01000000 0x01000000 2 2 $_TARGETNAME +@end example + +To configure one bank of 32 MBytes +built from two sixteen bit (two byte) wide parts wired in parallel +to create a thirty-two bit (four byte) bus with doubled throughput: + +@example +flash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME +@end example + +@c "cfi part_id" disabled +@end deffn + +@deffn {Flash Driver} lpcspifi +@cindex NXP SPI Flash Interface +@cindex SPIFI +@cindex lpcspifi +NXP's LPC43xx and LPC18xx families include a proprietary SPI +Flash Interface (SPIFI) peripheral that can drive and provide +memory mapped access to external SPI flash devices. + +The lpcspifi driver initializes this interface and provides +program and erase functionality for these serial flash devices. +Use of this driver @b{requires} a working area of at least 1kB +to be configured on the target device; more than this will +significantly reduce flash programming times. + +The setup command only requires the @var{base} parameter. All +other parameters are ignored, and the flash size and layout +are configured by the driver. + +@example +flash bank $_FLASHNAME lpcspifi 0x14000000 0 0 0 $_TARGETNAME +@end example + +@end deffn + +@deffn {Flash Driver} stmsmi +@cindex STMicroelectronics Serial Memory Interface +@cindex SMI +@cindex stmsmi +Some devices form STMicroelectronics (e.g. STR75x MCU family, +SPEAr MPU family) include a proprietary +``Serial Memory Interface'' (SMI) controller able to drive external +SPI flash devices. +Depending on specific device and board configuration, up to 4 external +flash devices can be connected. + +SMI makes the flash content directly accessible in the CPU address +space; each external device is mapped in a memory bank. +CPU can directly read data, execute code and boot from SMI banks. +Normal OpenOCD commands like @command{mdw} can be used to display +the flash content. + +The setup command only requires the @var{base} parameter in order +to identify the memory bank. +All other parameters are ignored. Additional information, like +flash size, are detected automatically. + +@example +flash bank $_FLASHNAME stmsmi 0xf8000000 0 0 0 $_TARGETNAME +@end example + +@end deffn + +@subsection Internal Flash (Microcontrollers) + +@deffn {Flash Driver} aduc702x +The ADUC702x analog microcontrollers from Analog Devices +include internal flash and use ARM7TDMI cores. +The aduc702x flash driver works with models ADUC7019 through ADUC7028. +The setup command only requires the @var{target} argument +since all devices in this family have the same memory layout. + +@example +flash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME +@end example +@end deffn + +@anchor{at91sam3} +@deffn {Flash Driver} at91sam3 +@cindex at91sam3 +All members of the AT91SAM3 microcontroller family from +Atmel include internal flash and use ARM's Cortex-M3 core. The driver +currently (6/22/09) recognizes the AT91SAM3U[1/2/4][C/E] chips. Note +that the driver was orginaly developed and tested using the +AT91SAM3U4E, using a SAM3U-EK eval board. Support for other chips in +the family was cribbed from the data sheet. @emph{Note to future +readers/updaters: Please remove this worrysome comment after other +chips are confirmed.} + +The AT91SAM3U4[E/C] (256K) chips have two flash banks; most other chips +have one flash bank. In all cases the flash banks are at +the following fixed locations: + +@example +# Flash bank 0 - all chips +flash bank $_FLASHNAME at91sam3 0x00080000 0 1 1 $_TARGETNAME +# Flash bank 1 - only 256K chips +flash bank $_FLASHNAME at91sam3 0x00100000 0 1 1 $_TARGETNAME +@end example + +Internally, the AT91SAM3 flash memory is organized as follows. +Unlike the AT91SAM7 chips, these are not used as parameters +to the @command{flash bank} command: + +@itemize +@item @emph{N-Banks:} 256K chips have 2 banks, others have 1 bank. +@item @emph{Bank Size:} 128K/64K Per flash bank +@item @emph{Sectors:} 16 or 8 per bank +@item @emph{SectorSize:} 8K Per Sector +@item @emph{PageSize:} 256 bytes per page. Note that OpenOCD operates on 'sector' sizes, not page sizes. +@end itemize + +The AT91SAM3 driver adds some additional commands: + +@deffn Command {at91sam3 gpnvm} +@deffnx Command {at91sam3 gpnvm clear} number +@deffnx Command {at91sam3 gpnvm set} number +@deffnx Command {at91sam3 gpnvm show} [@option{all}|number] +With no parameters, @command{show} or @command{show all}, +shows the status of all GPNVM bits. +With @command{show} @var{number}, displays that bit. + +With @command{set} @var{number} or @command{clear} @var{number}, +modifies that GPNVM bit. +@end deffn + +@deffn Command {at91sam3 info} +This command attempts to display information about the AT91SAM3 +chip. @emph{First} it read the @code{CHIPID_CIDR} [address 0x400e0740, see +Section 28.2.1, page 505 of the AT91SAM3U 29/may/2009 datasheet, +document id: doc6430A] and decodes the values. @emph{Second} it reads the +various clock configuration registers and attempts to display how it +believes the chip is configured. By default, the SLOWCLK is assumed to +be 32768 Hz, see the command @command{at91sam3 slowclk}. +@end deffn + +@deffn Command {at91sam3 slowclk} [value] +This command shows/sets the slow clock frequency used in the +@command{at91sam3 info} command calculations above. +@end deffn +@end deffn + +@deffn {Flash Driver} at91sam4 +@cindex at91sam4 +All members of the AT91SAM4 microcontroller family from +Atmel include internal flash and use ARM's Cortex-M4 core. +This driver uses the same cmd names/syntax as @xref{at91sam3}. +@end deffn + +@deffn {Flash Driver} at91sam7 +All members of the AT91SAM7 microcontroller family from Atmel include +internal flash and use ARM7TDMI cores. The driver automatically +recognizes a number of these chips using the chip identification +register, and autoconfigures itself. + +@example +flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME +@end example + +For chips which are not recognized by the controller driver, you must +provide additional parameters in the following order: + +@itemize +@item @var{chip_model} ... label used with @command{flash info} +@item @var{banks} +@item @var{sectors_per_bank} +@item @var{pages_per_sector} +@item @var{pages_size} +@item @var{num_nvm_bits} +@item @var{freq_khz} ... required if an external clock is provided, +optional (but recommended) when the oscillator frequency is known +@end itemize + +It is recommended that you provide zeroes for all of those values +except the clock frequency, so that everything except that frequency +will be autoconfigured. +Knowing the frequency helps ensure correct timings for flash access. + +The flash controller handles erases automatically on a page (128/256 byte) +basis, so explicit erase commands are not necessary for flash programming. +However, there is an ``EraseAll`` command that can erase an entire flash +plane (of up to 256KB), and it will be used automatically when you issue +@command{flash erase_sector} or @command{flash erase_address} commands. + +@deffn Command {at91sam7 gpnvm} bitnum (@option{set}|@option{clear}) +Set or clear a ``General Purpose Non-Volatile Memory'' (GPNVM) +bit for the processor. Each processor has a number of such bits, +used for controlling features such as brownout detection (so they +are not truly general purpose). +@quotation Note +This assumes that the first flash bank (number 0) is associated with +the appropriate at91sam7 target. +@end quotation +@end deffn +@end deffn + +@deffn {Flash Driver} avr +The AVR 8-bit microcontrollers from Atmel integrate flash memory. +@emph{The current implementation is incomplete.} +@comment - defines mass_erase ... pointless given flash_erase_address +@end deffn + +@deffn {Flash Driver} efm32 +All members of the EFM32 microcontroller family from Energy Micro include +internal flash and use ARM Cortex M3 cores. The driver automatically recognizes +a number of these chips using the chip identification register, and +autoconfigures itself. +@example +flash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME +@end example +@emph{The current implementation is incomplete. Unprotecting flash pages is not +supported.} +@end deffn + +@deffn {Flash Driver} lpc2000 +Most members of the LPC1700, LPC1800, LPC2000 and LPC4300 microcontroller +families from NXP include internal flash and use Cortex-M3 (LPC1700, LPC1800), +Cortex-M4 (LPC4300) or ARM7TDMI (LPC2000) cores. + +@quotation Note +There are LPC2000 devices which are not supported by the @var{lpc2000} +driver: +The LPC2888 is supported by the @var{lpc288x} driver. +The LPC29xx family is supported by the @var{lpc2900} driver. +@end quotation + +The @var{lpc2000} driver defines two mandatory and one optional parameters, +which must appear in the following order: + +@itemize +@item @var{variant} ... required, may be +@option{lpc2000_v1} (older LPC21xx and LPC22xx) +@option{lpc2000_v2} (LPC213x, LPC214x, LPC210[123], LPC23xx and LPC24xx) +@option{lpc1700} (LPC175x and LPC176x) +or @option{lpc4300} - available also as @option{lpc1800} alias (LPC18x[2357] and +LPC43x[2357]) +@item @var{clock_kHz} ... the frequency, in kiloHertz, +at which the core is running +@item @option{calc_checksum} ... optional (but you probably want to provide this!), +telling the driver to calculate a valid checksum for the exception vector table. +@quotation Note +If you don't provide @option{calc_checksum} when you're writing the vector +table, the boot ROM will almost certainly ignore your flash image. +However, if you do provide it, +with most tool chains @command{verify_image} will fail. +@end quotation +@end itemize + +LPC flashes don't require the chip and bus width to be specified. + +@example +flash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 $_TARGETNAME \ + lpc2000_v2 14765 calc_checksum +@end example + +@deffn {Command} {lpc2000 part_id} bank +Displays the four byte part identifier associated with +the specified flash @var{bank}. +@end deffn +@end deffn + +@deffn {Flash Driver} lpc288x +The LPC2888 microcontroller from NXP needs slightly different flash +support from its lpc2000 siblings. +The @var{lpc288x} driver defines one mandatory parameter, +the programming clock rate in Hz. +LPC flashes don't require the chip and bus width to be specified. + +@example +flash bank $_FLASHNAME lpc288x 0 0 0 0 $_TARGETNAME 12000000 +@end example +@end deffn + +@deffn {Flash Driver} lpc2900 +This driver supports the LPC29xx ARM968E based microcontroller family +from NXP. + +The predefined parameters @var{base}, @var{size}, @var{chip_width} and +@var{bus_width} of the @code{flash bank} command are ignored. Flash size and +sector layout are auto-configured by the driver. +The driver has one additional mandatory parameter: The CPU clock rate +(in kHz) at the time the flash operations will take place. Most of the time this +will not be the crystal frequency, but a higher PLL frequency. The +@code{reset-init} event handler in the board script is usually the place where +you start the PLL. + +The driver rejects flashless devices (currently the LPC2930). + +The EEPROM in LPC2900 devices is not mapped directly into the address space. +It must be handled much more like NAND flash memory, and will therefore be +handled by a separate @code{lpc2900_eeprom} driver (not yet available). + +Sector protection in terms of the LPC2900 is handled transparently. Every time a +sector needs to be erased or programmed, it is automatically unprotected. +What is shown as protection status in the @code{flash info} command, is +actually the LPC2900 @emph{sector security}. This is a mechanism to prevent a +sector from ever being erased or programmed again. As this is an irreversible +mechanism, it is handled by a special command (@code{lpc2900 secure_sector}), +and not by the standard @code{flash protect} command. + +Example for a 125 MHz clock frequency: +@example +flash bank $_FLASHNAME lpc2900 0 0 0 0 $_TARGETNAME 125000 +@end example + +Some @code{lpc2900}-specific commands are defined. In the following command list, +the @var{bank} parameter is the bank number as obtained by the +@code{flash banks} command. + +@deffn Command {lpc2900 signature} bank +Calculates a 128-bit hash value, the @emph{signature}, from the whole flash +content. This is a hardware feature of the flash block, hence the calculation is +very fast. You may use this to verify the content of a programmed device against +a known signature. +Example: +@example +lpc2900 signature 0 + signature: 0x5f40cdc8:0xc64e592e:0x10490f89:0x32a0f317 +@end example +@end deffn + +@deffn Command {lpc2900 read_custom} bank filename +Reads the 912 bytes of customer information from the flash index sector, and +saves it to a file in binary format. +Example: +@example +lpc2900 read_custom 0 /path_to/customer_info.bin +@end example +@end deffn + +The index sector of the flash is a @emph{write-only} sector. It cannot be +erased! In order to guard against unintentional write access, all following +commands need to be preceeded by a successful call to the @code{password} +command: + +@deffn Command {lpc2900 password} bank password +You need to use this command right before each of the following commands: +@code{lpc2900 write_custom}, @code{lpc2900 secure_sector}, +@code{lpc2900 secure_jtag}. + +The password string is fixed to "I_know_what_I_am_doing". +Example: +@example +lpc2900 password 0 I_know_what_I_am_doing + Potentially dangerous operation allowed in next command! +@end example +@end deffn + +@deffn Command {lpc2900 write_custom} bank filename type +Writes the content of the file into the customer info space of the flash index +sector. The filetype can be specified with the @var{type} field. Possible values +for @var{type} are: @var{bin} (binary), @var{ihex} (Intel hex format), +@var{elf} (ELF binary) or @var{s19} (Motorola S-records). The file must +contain a single section, and the contained data length must be exactly +912 bytes. +@quotation Attention +This cannot be reverted! Be careful! +@end quotation +Example: +@example +lpc2900 write_custom 0 /path_to/customer_info.bin bin +@end example +@end deffn + +@deffn Command {lpc2900 secure_sector} bank first last +Secures the sector range from @var{first} to @var{last} (including) against +further program and erase operations. The sector security will be effective +after the next power cycle. +@quotation Attention +This cannot be reverted! Be careful! +@end quotation +Secured sectors appear as @emph{protected} in the @code{flash info} command. +Example: +@example +lpc2900 secure_sector 0 1 1 +flash info 0 + #0 : lpc2900 at 0x20000000, size 0x000c0000, (...) + # 0: 0x00000000 (0x2000 8kB) not protected + # 1: 0x00002000 (0x2000 8kB) protected + # 2: 0x00004000 (0x2000 8kB) not protected +@end example +@end deffn + +@deffn Command {lpc2900 secure_jtag} bank +Irreversibly disable the JTAG port. The new JTAG security setting will be +effective after the next power cycle. +@quotation Attention +This cannot be reverted! Be careful! +@end quotation +Examples: +@example +lpc2900 secure_jtag 0 +@end example +@end deffn +@end deffn + +@deffn {Flash Driver} ocl +@emph{No idea what this is, other than using some arm7/arm9 core.} + +@example +flash bank $_FLASHNAME ocl 0 0 0 0 $_TARGETNAME +@end example +@end deffn + +@deffn {Flash Driver} pic32mx +The PIC32MX microcontrollers are based on the MIPS 4K cores, +and integrate flash memory. + +@example +flash bank $_FLASHNAME pix32mx 0x1fc00000 0 0 0 $_TARGETNAME +flash bank $_FLASHNAME pix32mx 0x1d000000 0 0 0 $_TARGETNAME +@end example + +@comment numerous *disabled* commands are defined: +@comment - chip_erase ... pointless given flash_erase_address +@comment - lock, unlock ... pointless given protect on/off (yes?) +@comment - pgm_word ... shouldn't bank be deduced from address?? +Some pic32mx-specific commands are defined: +@deffn Command {pic32mx pgm_word} address value bank +Programs the specified 32-bit @var{value} at the given @var{address} +in the specified chip @var{bank}. +@end deffn +@deffn Command {pic32mx unlock} bank +Unlock and erase specified chip @var{bank}. +This will remove any Code Protection. +@end deffn +@end deffn + +@deffn {Flash Driver} stellaris +All members of the Stellaris LM3Sxxx microcontroller family from +Texas Instruments +include internal flash and use ARM Cortex M3 cores. +The driver automatically recognizes a number of these chips using +the chip identification register, and autoconfigures itself. +@footnote{Currently there is a @command{stellaris mass_erase} command. +That seems pointless since the same effect can be had using the +standard @command{flash erase_address} command.} + +@example +flash bank $_FLASHNAME stellaris 0 0 0 0 $_TARGETNAME +@end example + +@deffn Command {stellaris recover bank_id} +Performs the @emph{Recovering a "Locked" Device} procedure to +restore the flash specified by @var{bank_id} and its associated +nonvolatile registers to their factory default values (erased). +This is the only way to remove flash protection or re-enable +debugging if that capability has been disabled. + +Note that the final "power cycle the chip" step in this procedure +must be performed by hand, since OpenOCD can't do it. +@quotation Warning +if more than one Stellaris chip is connected, the procedure is +applied to all of them. +@end quotation +@end deffn +@end deffn + +@deffn {Flash Driver} stm32f1x +All members of the STM32F0, STM32F1 and STM32F3 microcontroller families +from ST Microelectronics include internal flash and use ARM Cortex-M0/M3/M4 cores. +The driver automatically recognizes a number of these chips using +the chip identification register, and autoconfigures itself. + +@example +flash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME +@end example + +Note that some devices have been found that have a flash size register that contains +an invalid value, to workaround this issue you can override the probed value used by +the flash driver. + +@example +flash bank $_FLASHNAME stm32f1x 0 0x20000 0 0 $_TARGETNAME +@end example + +If you have a target with dual flash banks then define the second bank +as per the following example. +@example +flash bank $_FLASHNAME stm32f1x 0x08080000 0 0 0 $_TARGETNAME +@end example + +Some stm32f1x-specific commands +@footnote{Currently there is a @command{stm32f1x mass_erase} command. +That seems pointless since the same effect can be had using the +standard @command{flash erase_address} command.} +are defined: + +@deffn Command {stm32f1x lock} num +Locks the entire stm32 device. +The @var{num} parameter is a value shown by @command{flash banks}. +@end deffn + +@deffn Command {stm32f1x unlock} num +Unlocks the entire stm32 device. +The @var{num} parameter is a value shown by @command{flash banks}. +@end deffn + +@deffn Command {stm32f1x options_read} num +Read and display the stm32 option bytes written by +the @command{stm32f1x options_write} command. +The @var{num} parameter is a value shown by @command{flash banks}. +@end deffn + +@deffn Command {stm32f1x options_write} num (@option{SWWDG}|@option{HWWDG}) (@option{RSTSTNDBY}|@option{NORSTSTNDBY}) (@option{RSTSTOP}|@option{NORSTSTOP}) +Writes the stm32 option byte with the specified values. +The @var{num} parameter is a value shown by @command{flash banks}. +@end deffn +@end deffn + +@deffn {Flash Driver} stm32f2x +All members of the STM32F2 and STM32F4 microcontroller families from ST Microelectronics +include internal flash and use ARM Cortex-M3/M4 cores. +The driver automatically recognizes a number of these chips using +the chip identification register, and autoconfigures itself. + +Note that some devices have been found that have a flash size register that contains +an invalid value, to workaround this issue you can override the probed value used by +the flash driver. + +@example +flash bank $_FLASHNAME stm32f2x 0 0x20000 0 0 $_TARGETNAME +@end example + +Some stm32f2x-specific commands are defined: + +@deffn Command {stm32f2x lock} num +Locks the entire stm32 device. +The @var{num} parameter is a value shown by @command{flash banks}. +@end deffn + +@deffn Command {stm32f2x unlock} num +Unlocks the entire stm32 device. +The @var{num} parameter is a value shown by @command{flash banks}. +@end deffn +@end deffn + +@deffn {Flash Driver} stm32lx +All members of the STM32L microcontroller families from ST Microelectronics +include internal flash and use ARM Cortex-M3 cores. +The driver automatically recognizes a number of these chips using +the chip identification register, and autoconfigures itself. + +Note that some devices have been found that have a flash size register that contains +an invalid value, to workaround this issue you can override the probed value used by +the flash driver. + +@example +flash bank $_FLASHNAME stm32lx 0 0x20000 0 0 $_TARGETNAME +@end example +@end deffn + +@deffn {Flash Driver} str7x +All members of the STR7 microcontroller family from ST Microelectronics +include internal flash and use ARM7TDMI cores. +The @var{str7x} driver defines one mandatory parameter, @var{variant}, +which is either @code{STR71x}, @code{STR73x} or @code{STR75x}. + +@example +flash bank $_FLASHNAME str7x 0x40000000 0x00040000 0 0 $_TARGETNAME STR71x +@end example + +@deffn Command {str7x disable_jtag} bank +Activate the Debug/Readout protection mechanism +for the specified flash bank. +@end deffn +@end deffn + +@deffn {Flash Driver} str9x +Most members of the STR9 microcontroller family from ST Microelectronics +include internal flash and use ARM966E cores. +The str9 needs the flash controller to be configured using +the @command{str9x flash_config} command prior to Flash programming. + +@example +flash bank $_FLASHNAME str9x 0x40000000 0x00040000 0 0 $_TARGETNAME +str9x flash_config 0 4 2 0 0x80000 +@end example + +@deffn Command {str9x flash_config} num bbsr nbbsr bbadr nbbadr +Configures the str9 flash controller. +The @var{num} parameter is a value shown by @command{flash banks}. + +@itemize @bullet +@item @var{bbsr} - Boot Bank Size register +@item @var{nbbsr} - Non Boot Bank Size register +@item @var{bbadr} - Boot Bank Start Address register +@item @var{nbbadr} - Boot Bank Start Address register +@end itemize +@end deffn + +@end deffn + +@deffn {Flash Driver} tms470 +Most members of the TMS470 microcontroller family from Texas Instruments +include internal flash and use ARM7TDMI cores. +This driver doesn't require the chip and bus width to be specified. + +Some tms470-specific commands are defined: + +@deffn Command {tms470 flash_keyset} key0 key1 key2 key3 +Saves programming keys in a register, to enable flash erase and write commands. +@end deffn + +@deffn Command {tms470 osc_mhz} clock_mhz +Reports the clock speed, which is used to calculate timings. +@end deffn + +@deffn Command {tms470 plldis} (0|1) +Disables (@var{1}) or enables (@var{0}) use of the PLL to speed up +the flash clock. +@end deffn +@end deffn + +@deffn {Flash Driver} virtual +This is a special driver that maps a previously defined bank to another +address. All bank settings will be copied from the master physical bank. + +The @var{virtual} driver defines one mandatory parameters, + +@itemize +@item @var{master_bank} The bank that this virtual address refers to. +@end itemize + +So in the following example addresses 0xbfc00000 and 0x9fc00000 refer to +the flash bank defined at address 0x1fc00000. Any cmds executed on +the virtual banks are actually performed on the physical banks. +@example +flash bank $_FLASHNAME pic32mx 0x1fc00000 0 0 0 $_TARGETNAME +flash bank vbank0 virtual 0xbfc00000 0 0 0 $_TARGETNAME $_FLASHNAME +flash bank vbank1 virtual 0x9fc00000 0 0 0 $_TARGETNAME $_FLASHNAME +@end example +@end deffn + +@deffn {Flash Driver} fm3 +All members of the FM3 microcontroller family from Fujitsu +include internal flash and use ARM Cortex M3 cores. +The @var{fm3} driver uses the @var{target} parameter to select the +correct bank config, it can currently be one of the following: +@code{mb9bfxx1.cpu}, @code{mb9bfxx2.cpu}, @code{mb9bfxx3.cpu}, +@code{mb9bfxx4.cpu}, @code{mb9bfxx5.cpu} or @code{mb9bfxx6.cpu}. + +@example +flash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME +@end example +@end deffn + +@subsection str9xpec driver +@cindex str9xpec + +Here is some background info to help +you better understand how this driver works. OpenOCD has two flash drivers for +the str9: +@enumerate +@item +Standard driver @option{str9x} programmed via the str9 core. Normally used for +flash programming as it is faster than the @option{str9xpec} driver. +@item +Direct programming @option{str9xpec} using the flash controller. This is an +ISC compilant (IEEE 1532) tap connected in series with the str9 core. The str9 +core does not need to be running to program using this flash driver. Typical use +for this driver is locking/unlocking the target and programming the option bytes. +@end enumerate + +Before we run any commands using the @option{str9xpec} driver we must first disable +the str9 core. This example assumes the @option{str9xpec} driver has been +configured for flash bank 0. +@example +# assert srst, we do not want core running +# while accessing str9xpec flash driver +jtag_reset 0 1 +# turn off target polling +poll off +# disable str9 core +str9xpec enable_turbo 0 +# read option bytes +str9xpec options_read 0 +# re-enable str9 core +str9xpec disable_turbo 0 +poll on +reset halt +@end example +The above example will read the str9 option bytes. +When performing a unlock remember that you will not be able to halt the str9 - it +has been locked. Halting the core is not required for the @option{str9xpec} driver +as mentioned above, just issue the commands above manually or from a telnet prompt. + +@deffn {Flash Driver} str9xpec +Only use this driver for locking/unlocking the device or configuring the option bytes. +Use the standard str9 driver for programming. +Before using the flash commands the turbo mode must be enabled using the +@command{str9xpec enable_turbo} command. + +Several str9xpec-specific commands are defined: + +@deffn Command {str9xpec disable_turbo} num +Restore the str9 into JTAG chain. +@end deffn + +@deffn Command {str9xpec enable_turbo} num +Enable turbo mode, will simply remove the str9 from the chain and talk +directly to the embedded flash controller. +@end deffn + +@deffn Command {str9xpec lock} num +Lock str9 device. The str9 will only respond to an unlock command that will +erase the device. +@end deffn + +@deffn Command {str9xpec part_id} num +Prints the part identifier for bank @var{num}. +@end deffn + +@deffn Command {str9xpec options_cmap} num (@option{bank0}|@option{bank1}) +Configure str9 boot bank. +@end deffn + +@deffn Command {str9xpec options_lvdsel} num (@option{vdd}|@option{vdd_vddq}) +Configure str9 lvd source. +@end deffn + +@deffn Command {str9xpec options_lvdthd} num (@option{2.4v}|@option{2.7v}) +Configure str9 lvd threshold. +@end deffn + +@deffn Command {str9xpec options_lvdwarn} bank (@option{vdd}|@option{vdd_vddq}) +Configure str9 lvd reset warning source. +@end deffn + +@deffn Command {str9xpec options_read} num +Read str9 option bytes. +@end deffn + +@deffn Command {str9xpec options_write} num +Write str9 option bytes. +@end deffn + +@deffn Command {str9xpec unlock} num +unlock str9 device. +@end deffn + +@end deffn + + +@section mFlash + +@subsection mFlash Configuration +@cindex mFlash Configuration + +@deffn {Config Command} {mflash bank} soc base RST_pin target +Configures a mflash for @var{soc} host bank at +address @var{base}. +The pin number format depends on the host GPIO naming convention. +Currently, the mflash driver supports s3c2440 and pxa270. + +Example for s3c2440 mflash where @var{RST pin} is GPIO B1: + +@example +mflash bank $_FLASHNAME s3c2440 0x10000000 1b 0 +@end example + +Example for pxa270 mflash where @var{RST pin} is GPIO 43: + +@example +mflash bank $_FLASHNAME pxa270 0x08000000 43 0 +@end example +@end deffn + +@subsection mFlash commands +@cindex mFlash commands + +@deffn Command {mflash config pll} frequency +Configure mflash PLL. +The @var{frequency} is the mflash input frequency, in Hz. +Issuing this command will erase mflash's whole internal nand and write new pll. +After this command, mflash needs power-on-reset for normal operation. +If pll was newly configured, storage and boot(optional) info also need to be update. +@end deffn + +@deffn Command {mflash config boot} +Configure bootable option. +If bootable option is set, mflash offer the first 8 sectors +(4kB) for boot. +@end deffn + +@deffn Command {mflash config storage} +Configure storage information. +For the normal storage operation, this information must be +written. +@end deffn + +@deffn Command {mflash dump} num filename offset size +Dump @var{size} bytes, starting at @var{offset} bytes from the +beginning of the bank @var{num}, to the file named @var{filename}. +@end deffn + +@deffn Command {mflash probe} +Probe mflash. +@end deffn + +@deffn Command {mflash write} num filename offset +Write the binary file @var{filename} to mflash bank @var{num}, starting at +@var{offset} bytes from the beginning of the bank. +@end deffn + +@node Flash Programming +@chapter Flash Programming + +OpenOCD implements numerous ways to program the target flash, whether internal or external. +Programming can be acheived by either using GDB @ref{programmingusinggdb,,Programming using GDB}, +or using the cmds given in @ref{flashprogrammingcommands,,Flash Programming Commands}. + +@*To simplify using the flash cmds directly a jimtcl script is available that handles the programming and verify stage. +OpenOCD will program/verify/reset the target and shutdown. + +The script is executed as follows and by default the following actions will be peformed. +@enumerate +@item 'init' is executed. +@item 'reset init' is called to reset and halt the target, any 'reset init' scripts are executed. +@item @code{flash write_image} is called to erase and write any flash using the filename given. +@item @code{verify_image} is called if @option{verify} parameter is given. +@item @code{reset run} is called if @option{reset} parameter is given. +@item OpenOCD is shutdown. +@end enumerate + +An example of usage is given below. @xref{program}. + +@example +# program and verify using elf/hex/s19. verify and reset +# are optional parameters +openocd -f board/stm32f3discovery.cfg \ + -c "program filename.elf verify reset" + +# binary files need the flash address passing +openocd -f board/stm32f3discovery.cfg \ + -c "program filename.bin 0x08000000" +@end example + +@node NAND Flash Commands +@chapter NAND Flash Commands +@cindex NAND + +Compared to NOR or SPI flash, NAND devices are inexpensive +and high density. Today's NAND chips, and multi-chip modules, +commonly hold multiple GigaBytes of data. + +NAND chips consist of a number of ``erase blocks'' of a given +size (such as 128 KBytes), each of which is divided into a +number of pages (of perhaps 512 or 2048 bytes each). Each +page of a NAND flash has an ``out of band'' (OOB) area to hold +Error Correcting Code (ECC) and other metadata, usually 16 bytes +of OOB for every 512 bytes of page data. + +One key characteristic of NAND flash is that its error rate +is higher than that of NOR flash. In normal operation, that +ECC is used to correct and detect errors. However, NAND +blocks can also wear out and become unusable; those blocks +are then marked "bad". NAND chips are even shipped from the +manufacturer with a few bad blocks. The highest density chips +use a technology (MLC) that wears out more quickly, so ECC +support is increasingly important as a way to detect blocks +that have begun to fail, and help to preserve data integrity +with techniques such as wear leveling. + +Software is used to manage the ECC. Some controllers don't +support ECC directly; in those cases, software ECC is used. +Other controllers speed up the ECC calculations with hardware. +Single-bit error correction hardware is routine. Controllers +geared for newer MLC chips may correct 4 or more errors for +every 512 bytes of data. + +You will need to make sure that any data you write using +OpenOCD includes the apppropriate kind of ECC. For example, +that may mean passing the @code{oob_softecc} flag when +writing NAND data, or ensuring that the correct hardware +ECC mode is used. + +The basic steps for using NAND devices include: +@enumerate +@item Declare via the command @command{nand device} +@* Do this in a board-specific configuration file, +passing parameters as needed by the controller. +@item Configure each device using @command{nand probe}. +@* Do this only after the associated target is set up, +such as in its reset-init script or in procures defined +to access that device. +@item Operate on the flash via @command{nand subcommand} +@* Often commands to manipulate the flash are typed by a human, or run +via a script in some automated way. Common task include writing a +boot loader, operating system, or other data needed to initialize or +de-brick a board. +@end enumerate + +@b{NOTE:} At the time this text was written, the largest NAND +flash fully supported by OpenOCD is 2 GiBytes (16 GiBits). +This is because the variables used to hold offsets and lengths +are only 32 bits wide. +(Larger chips may work in some cases, unless an offset or length +is larger than 0xffffffff, the largest 32-bit unsigned integer.) +Some larger devices will work, since they are actually multi-chip +modules with two smaller chips and individual chipselect lines. + +@anchor{nandconfiguration} +@section NAND Configuration Commands +@cindex NAND configuration + +NAND chips must be declared in configuration scripts, +plus some additional configuration that's done after +OpenOCD has initialized. + +@deffn {Config Command} {nand device} name driver target [configparams...] +Declares a NAND device, which can be read and written to +after it has been configured through @command{nand probe}. +In OpenOCD, devices are single chips; this is unlike some +operating systems, which may manage multiple chips as if +they were a single (larger) device. +In some cases, configuring a device will activate extra +commands; see the controller-specific documentation. + +@b{NOTE:} This command is not available after OpenOCD +initialization has completed. Use it in board specific +configuration files, not interactively. + +@itemize @bullet +@item @var{name} ... may be used to reference the NAND bank +in most other NAND commands. A number is also available. +@item @var{driver} ... identifies the NAND controller driver +associated with the NAND device being declared. +@xref{nanddriverlist,,NAND Driver List}. +@item @var{target} ... names the target used when issuing +commands to the NAND controller. +@comment Actually, it's currently a controller-specific parameter... +@item @var{configparams} ... controllers may support, or require, +additional parameters. See the controller-specific documentation +for more information. +@end itemize +@end deffn + +@deffn Command {nand list} +Prints a summary of each device declared +using @command{nand device}, numbered from zero. +Note that un-probed devices show no details. +@example +> nand list +#0: NAND 1GiB 3,3V 8-bit (Micron) pagesize: 2048, buswidth: 8, + blocksize: 131072, blocks: 8192 +#1: NAND 1GiB 3,3V 8-bit (Micron) pagesize: 2048, buswidth: 8, + blocksize: 131072, blocks: 8192 +> +@end example +@end deffn + +@deffn Command {nand probe} num +Probes the specified device to determine key characteristics +like its page and block sizes, and how many blocks it has. +The @var{num} parameter is the value shown by @command{nand list}. +You must (successfully) probe a device before you can use +it with most other NAND commands. +@end deffn + +@section Erasing, Reading, Writing to NAND Flash + +@deffn Command {nand dump} num filename offset length [oob_option] +@cindex NAND reading +Reads binary data from the NAND device and writes it to the file, +starting at the specified offset. +The @var{num} parameter is the value shown by @command{nand list}. + +Use a complete path name for @var{filename}, so you don't depend +on the directory used to start the OpenOCD server. + +The @var{offset} and @var{length} must be exact multiples of the +device's page size. They describe a data region; the OOB data +associated with each such page may also be accessed. + +@b{NOTE:} At the time this text was written, no error correction +was done on the data that's read, unless raw access was disabled +and the underlying NAND controller driver had a @code{read_page} +method which handled that error correction. + +By default, only page data is saved to the specified file. +Use an @var{oob_option} parameter to save OOB data: +@itemize @bullet +@item no oob_* parameter +@*Output file holds only page data; OOB is discarded. +@item @code{oob_raw} +@*Output file interleaves page data and OOB data; +the file will be longer than "length" by the size of the +spare areas associated with each data page. +Note that this kind of "raw" access is different from +what's implied by @command{nand raw_access}, which just +controls whether a hardware-aware access method is used. +@item @code{oob_only} +@*Output file has only raw OOB data, and will +be smaller than "length" since it will contain only the +spare areas associated with each data page. +@end itemize +@end deffn + +@deffn Command {nand erase} num [offset length] +@cindex NAND erasing +@cindex NAND programming +Erases blocks on the specified NAND device, starting at the +specified @var{offset} and continuing for @var{length} bytes. +Both of those values must be exact multiples of the device's +block size, and the region they specify must fit entirely in the chip. +If those parameters are not specified, +the whole NAND chip will be erased. +The @var{num} parameter is the value shown by @command{nand list}. + +@b{NOTE:} This command will try to erase bad blocks, when told +to do so, which will probably invalidate the manufacturer's bad +block marker. +For the remainder of the current server session, @command{nand info} +will still report that the block ``is'' bad. +@end deffn + +@deffn Command {nand write} num filename offset [option...] +@cindex NAND writing +@cindex NAND programming +Writes binary data from the file into the specified NAND device, +starting at the specified offset. Those pages should already +have been erased; you can't change zero bits to one bits. +The @var{num} parameter is the value shown by @command{nand list}. + +Use a complete path name for @var{filename}, so you don't depend +on the directory used to start the OpenOCD server. + +The @var{offset} must be an exact multiple of the device's page size. +All data in the file will be written, assuming it doesn't run +past the end of the device. +Only full pages are written, and any extra space in the last +page will be filled with 0xff bytes. (That includes OOB data, +if that's being written.) + +@b{NOTE:} At the time this text was written, bad blocks are +ignored. That is, this routine will not skip bad blocks, +but will instead try to write them. This can cause problems. + +Provide at most one @var{option} parameter. With some +NAND drivers, the meanings of these parameters may change +if @command{nand raw_access} was used to disable hardware ECC. +@itemize @bullet +@item no oob_* parameter +@*File has only page data, which is written. +If raw acccess is in use, the OOB area will not be written. +Otherwise, if the underlying NAND controller driver has +a @code{write_page} routine, that routine may write the OOB +with hardware-computed ECC data. +@item @code{oob_only} +@*File has only raw OOB data, which is written to the OOB area. +Each page's data area stays untouched. @i{This can be a dangerous +option}, since it can invalidate the ECC data. +You may need to force raw access to use this mode. +@item @code{oob_raw} +@*File interleaves data and OOB data, both of which are written +If raw access is enabled, the data is written first, then the +un-altered OOB. +Otherwise, if the underlying NAND controller driver has +a @code{write_page} routine, that routine may modify the OOB +before it's written, to include hardware-computed ECC data. +@item @code{oob_softecc} +@*File has only page data, which is written. +The OOB area is filled with 0xff, except for a standard 1-bit +software ECC code stored in conventional locations. +You might need to force raw access to use this mode, to prevent +the underlying driver from applying hardware ECC. +@item @code{oob_softecc_kw} +@*File has only page data, which is written. +The OOB area is filled with 0xff, except for a 4-bit software ECC +specific to the boot ROM in Marvell Kirkwood SoCs. +You might need to force raw access to use this mode, to prevent +the underlying driver from applying hardware ECC. +@end itemize +@end deffn + +@deffn Command {nand verify} num filename offset [option...] +@cindex NAND verification +@cindex NAND programming +Verify the binary data in the file has been programmed to the +specified NAND device, starting at the specified offset. +The @var{num} parameter is the value shown by @command{nand list}. + +Use a complete path name for @var{filename}, so you don't depend +on the directory used to start the OpenOCD server. + +The @var{offset} must be an exact multiple of the device's page size. +All data in the file will be read and compared to the contents of the +flash, assuming it doesn't run past the end of the device. +As with @command{nand write}, only full pages are verified, so any extra +space in the last page will be filled with 0xff bytes. + +The same @var{options} accepted by @command{nand write}, +and the file will be processed similarly to produce the buffers that +can be compared against the contents produced from @command{nand dump}. + +@b{NOTE:} This will not work when the underlying NAND controller +driver's @code{write_page} routine must update the OOB with a +hardward-computed ECC before the data is written. This limitation may +be removed in a future release. +@end deffn + +@section Other NAND commands +@cindex NAND other commands + +@deffn Command {nand check_bad_blocks} num [offset length] +Checks for manufacturer bad block markers on the specified NAND +device. If no parameters are provided, checks the whole +device; otherwise, starts at the specified @var{offset} and +continues for @var{length} bytes. +Both of those values must be exact multiples of the device's +block size, and the region they specify must fit entirely in the chip. +The @var{num} parameter is the value shown by @command{nand list}. + +@b{NOTE:} Before using this command you should force raw access +with @command{nand raw_access enable} to ensure that the underlying +driver will not try to apply hardware ECC. +@end deffn + +@deffn Command {nand info} num +The @var{num} parameter is the value shown by @command{nand list}. +This prints the one-line summary from "nand list", plus for +devices which have been probed this also prints any known +status for each block. +@end deffn + +@deffn Command {nand raw_access} num (@option{enable}|@option{disable}) +Sets or clears an flag affecting how page I/O is done. +The @var{num} parameter is the value shown by @command{nand list}. + +This flag is cleared (disabled) by default, but changing that +value won't affect all NAND devices. The key factor is whether +the underlying driver provides @code{read_page} or @code{write_page} +methods. If it doesn't provide those methods, the setting of +this flag is irrelevant; all access is effectively ``raw''. + +When those methods exist, they are normally used when reading +data (@command{nand dump} or reading bad block markers) or +writing it (@command{nand write}). However, enabling +raw access (setting the flag) prevents use of those methods, +bypassing hardware ECC logic. +@i{This can be a dangerous option}, since writing blocks +with the wrong ECC data can cause them to be marked as bad. +@end deffn + +@anchor{nanddriverlist} +@section NAND Driver List +As noted above, the @command{nand device} command allows +driver-specific options and behaviors. +Some controllers also activate controller-specific commands. + +@deffn {NAND Driver} at91sam9 +This driver handles the NAND controllers found on AT91SAM9 family chips from +Atmel. It takes two extra parameters: address of the NAND chip; +address of the ECC controller. +@example +nand device $NANDFLASH at91sam9 $CHIPNAME 0x40000000 0xfffffe800 +@end example +AT91SAM9 chips support single-bit ECC hardware. The @code{write_page} and +@code{read_page} methods are used to utilize the ECC hardware unless they are +disabled by using the @command{nand raw_access} command. There are four +additional commands that are needed to fully configure the AT91SAM9 NAND +controller. Two are optional; most boards use the same wiring for ALE/CLE: +@deffn Command {at91sam9 cle} num addr_line +Configure the address line used for latching commands. The @var{num} +parameter is the value shown by @command{nand list}. +@end deffn +@deffn Command {at91sam9 ale} num addr_line +Configure the address line used for latching addresses. The @var{num} +parameter is the value shown by @command{nand list}. +@end deffn + +For the next two commands, it is assumed that the pins have already been +properly configured for input or output. +@deffn Command {at91sam9 rdy_busy} num pio_base_addr pin +Configure the RDY/nBUSY input from the NAND device. The @var{num} +parameter is the value shown by @command{nand list}. @var{pio_base_addr} +is the base address of the PIO controller and @var{pin} is the pin number. +@end deffn +@deffn Command {at91sam9 ce} num pio_base_addr pin +Configure the chip enable input to the NAND device. The @var{num} +parameter is the value shown by @command{nand list}. @var{pio_base_addr} +is the base address of the PIO controller and @var{pin} is the pin number. +@end deffn +@end deffn + +@deffn {NAND Driver} davinci +This driver handles the NAND controllers found on DaVinci family +chips from Texas Instruments. +It takes three extra parameters: +address of the NAND chip; +hardware ECC mode to use (@option{hwecc1}, +@option{hwecc4}, @option{hwecc4_infix}); +address of the AEMIF controller on this processor. +@example +nand device davinci dm355.arm 0x02000000 hwecc4 0x01e10000 +@end example +All DaVinci processors support the single-bit ECC hardware, +and newer ones also support the four-bit ECC hardware. +The @code{write_page} and @code{read_page} methods are used +to implement those ECC modes, unless they are disabled using +the @command{nand raw_access} command. +@end deffn + +@deffn {NAND Driver} lpc3180 +These controllers require an extra @command{nand device} +parameter: the clock rate used by the controller. +@deffn Command {lpc3180 select} num [mlc|slc] +Configures use of the MLC or SLC controller mode. +MLC implies use of hardware ECC. +The @var{num} parameter is the value shown by @command{nand list}. +@end deffn + +At this writing, this driver includes @code{write_page} +and @code{read_page} methods. Using @command{nand raw_access} +to disable those methods will prevent use of hardware ECC +in the MLC controller mode, but won't change SLC behavior. +@end deffn +@comment current lpc3180 code won't issue 5-byte address cycles + +@deffn {NAND Driver} mx3 +This driver handles the NAND controller in i.MX31. The mxc driver +should work for this chip aswell. +@end deffn + +@deffn {NAND Driver} mxc +This driver handles the NAND controller found in Freescale i.MX +chips. It has support for v1 (i.MX27 and i.MX31) and v2 (i.MX35). +The driver takes 3 extra arguments, chip (@option{mx27}, +@option{mx31}, @option{mx35}), ecc (@option{noecc}, @option{hwecc}) +and optionally if bad block information should be swapped between +main area and spare area (@option{biswap}), defaults to off. +@example +nand device mx35.nand mxc imx35.cpu mx35 hwecc biswap +@end example +@deffn Command {mxc biswap} bank_num [enable|disable] +Turns on/off bad block information swaping from main area, +without parameter query status. +@end deffn +@end deffn + +@deffn {NAND Driver} orion +These controllers require an extra @command{nand device} +parameter: the address of the controller. +@example +nand device orion 0xd8000000 +@end example +These controllers don't define any specialized commands. +At this writing, their drivers don't include @code{write_page} +or @code{read_page} methods, so @command{nand raw_access} won't +change any behavior. +@end deffn + +@deffn {NAND Driver} s3c2410 +@deffnx {NAND Driver} s3c2412 +@deffnx {NAND Driver} s3c2440 +@deffnx {NAND Driver} s3c2443 +@deffnx {NAND Driver} s3c6400 +These S3C family controllers don't have any special +@command{nand device} options, and don't define any +specialized commands. +At this writing, their drivers don't include @code{write_page} +or @code{read_page} methods, so @command{nand raw_access} won't +change any behavior. +@end deffn + +@node PLD/FPGA Commands +@chapter PLD/FPGA Commands +@cindex PLD +@cindex FPGA + +Programmable Logic Devices (PLDs) and the more flexible +Field Programmable Gate Arrays (FPGAs) are both types of programmable hardware. +OpenOCD can support programming them. +Although PLDs are generally restrictive (cells are less functional, and +there are no special purpose cells for memory or computational tasks), +they share the same OpenOCD infrastructure. +Accordingly, both are called PLDs here. + +@section PLD/FPGA Configuration and Commands + +As it does for JTAG TAPs, debug targets, and flash chips (both NOR and NAND), +OpenOCD maintains a list of PLDs available for use in various commands. +Also, each such PLD requires a driver. + +They are referenced by the number shown by the @command{pld devices} command, +and new PLDs are defined by @command{pld device driver_name}. + +@deffn {Config Command} {pld device} driver_name tap_name [driver_options] +Defines a new PLD device, supported by driver @var{driver_name}, +using the TAP named @var{tap_name}. +The driver may make use of any @var{driver_options} to configure its +behavior. +@end deffn + +@deffn {Command} {pld devices} +Lists the PLDs and their numbers. +@end deffn + +@deffn {Command} {pld load} num filename +Loads the file @file{filename} into the PLD identified by @var{num}. +The file format must be inferred by the driver. +@end deffn + +@section PLD/FPGA Drivers, Options, and Commands + +Drivers may support PLD-specific options to the @command{pld device} +definition command, and may also define commands usable only with +that particular type of PLD. + +@deffn {FPGA Driver} virtex2 +Virtex-II is a family of FPGAs sold by Xilinx. +It supports the IEEE 1532 standard for In-System Configuration (ISC). +No driver-specific PLD definition options are used, +and one driver-specific command is defined. + +@deffn {Command} {virtex2 read_stat} num +Reads and displays the Virtex-II status register (STAT) +for FPGA @var{num}. +@end deffn +@end deffn + +@node General Commands +@chapter General Commands +@cindex commands + +The commands documented in this chapter here are common commands that +you, as a human, may want to type and see the output of. Configuration type +commands are documented elsewhere. + +Intent: +@itemize @bullet +@item @b{Source Of Commands} +@* OpenOCD commands can occur in a configuration script (discussed +elsewhere) or typed manually by a human or supplied programatically, +or via one of several TCP/IP Ports. + +@item @b{From the human} +@* A human should interact with the telnet interface (default port: 4444) +or via GDB (default port 3333). + +To issue commands from within a GDB session, use the @option{monitor} +command, e.g. use @option{monitor poll} to issue the @option{poll} +command. All output is relayed through the GDB session. + +@item @b{Machine Interface} +The Tcl interface's intent is to be a machine interface. The default Tcl +port is 5555. +@end itemize + + +@section Daemon Commands + +@deffn {Command} exit +Exits the current telnet session. +@end deffn + +@deffn {Command} help [string] +With no parameters, prints help text for all commands. +Otherwise, prints each helptext containing @var{string}. +Not every command provides helptext. + +Configuration commands, and commands valid at any time, are +explicitly noted in parenthesis. +In most cases, no such restriction is listed; this indicates commands +which are only available after the configuration stage has completed. +@end deffn + +@deffn Command sleep msec [@option{busy}] +Wait for at least @var{msec} milliseconds before resuming. +If @option{busy} is passed, busy-wait instead of sleeping. +(This option is strongly discouraged.) +Useful in connection with script files +(@command{script} command and @command{target_name} configuration). +@end deffn + +@deffn Command shutdown +Close the OpenOCD daemon, disconnecting all clients (GDB, telnet, other). +@end deffn + +@anchor{debuglevel} +@deffn Command debug_level [n] +@cindex message level +Display debug level. +If @var{n} (from 0..3) is provided, then set it to that level. +This affects the kind of messages sent to the server log. +Level 0 is error messages only; +level 1 adds warnings; +level 2 adds informational messages; +and level 3 adds debugging messages. +The default is level 2, but that can be overridden on +the command line along with the location of that log +file (which is normally the server's standard output). +@xref{Running}. +@end deffn + +@deffn Command echo [-n] message +Logs a message at "user" priority. +Output @var{message} to stdout. +Option "-n" suppresses trailing newline. +@example +echo "Downloading kernel -- please wait" +@end example +@end deffn + +@deffn Command log_output [filename] +Redirect logging to @var{filename}; +the initial log output channel is stderr. +@end deffn + +@deffn Command add_script_search_dir [directory] +Add @var{directory} to the file/script search path. +@end deffn + +@anchor{targetstatehandling} +@section Target State handling +@cindex reset +@cindex halt +@cindex target initialization + +In this section ``target'' refers to a CPU configured as +shown earlier (@pxref{CPU Configuration}). +These commands, like many, implicitly refer to +a current target which is used to perform the +various operations. The current target may be changed +by using @command{targets} command with the name of the +target which should become current. + +@deffn Command reg [(number|name) [value]] +Access a single register by @var{number} or by its @var{name}. +The target must generally be halted before access to CPU core +registers is allowed. Depending on the hardware, some other +registers may be accessible while the target is running. + +@emph{With no arguments}: +list all available registers for the current target, +showing number, name, size, value, and cache status. +For valid entries, a value is shown; valid entries +which are also dirty (and will be written back later) +are flagged as such. + +@emph{With number/name}: display that register's value. + +@emph{With both number/name and value}: set register's value. +Writes may be held in a writeback cache internal to OpenOCD, +so that setting the value marks the register as dirty instead +of immediately flushing that value. Resuming CPU execution +(including by single stepping) or otherwise activating the +relevant module will flush such values. + +Cores may have surprisingly many registers in their +Debug and trace infrastructure: + +@example +> reg +===== ARM registers +(0) r0 (/32): 0x0000D3C2 (dirty) +(1) r1 (/32): 0xFD61F31C +(2) r2 (/32) +... +(164) ETM_contextid_comparator_mask (/32) +> +@end example +@end deffn + +@deffn Command halt [ms] +@deffnx Command wait_halt [ms] +The @command{halt} command first sends a halt request to the target, +which @command{wait_halt} doesn't. +Otherwise these behave the same: wait up to @var{ms} milliseconds, +or 5 seconds if there is no parameter, for the target to halt +(and enter debug mode). +Using 0 as the @var{ms} parameter prevents OpenOCD from waiting. + +@quotation Warning +On ARM cores, software using the @emph{wait for interrupt} operation +often blocks the JTAG access needed by a @command{halt} command. +This is because that operation also puts the core into a low +power mode by gating the core clock; +but the core clock is needed to detect JTAG clock transitions. + +One partial workaround uses adaptive clocking: when the core is +interrupted the operation completes, then JTAG clocks are accepted +at least until the interrupt handler completes. +However, this workaround is often unusable since the processor, board, +and JTAG adapter must all support adaptive JTAG clocking. +Also, it can't work until an interrupt is issued. + +A more complete workaround is to not use that operation while you +work with a JTAG debugger. +Tasking environments generaly have idle loops where the body is the +@emph{wait for interrupt} operation. +(On older cores, it is a coprocessor action; +newer cores have a @option{wfi} instruction.) +Such loops can just remove that operation, at the cost of higher +power consumption (because the CPU is needlessly clocked). +@end quotation + +@end deffn + +@deffn Command resume [address] +Resume the target at its current code position, +or the optional @var{address} if it is provided. +OpenOCD will wait 5 seconds for the target to resume. +@end deffn + +@deffn Command step [address] +Single-step the target at its current code position, +or the optional @var{address} if it is provided. +@end deffn + +@anchor{resetcommand} +@deffn Command reset +@deffnx Command {reset run} +@deffnx Command {reset halt} +@deffnx Command {reset init} +Perform as hard a reset as possible, using SRST if possible. +@emph{All defined targets will be reset, and target +events will fire during the reset sequence.} + +The optional parameter specifies what should +happen after the reset. +If there is no parameter, a @command{reset run} is executed. +The other options will not work on all systems. +@xref{Reset Configuration}. + +@itemize @minus +@item @b{run} Let the target run +@item @b{halt} Immediately halt the target +@item @b{init} Immediately halt the target, and execute the reset-init script +@end itemize +@end deffn + +@deffn Command soft_reset_halt +Requesting target halt and executing a soft reset. This is often used +when a target cannot be reset and halted. The target, after reset is +released begins to execute code. OpenOCD attempts to stop the CPU and +then sets the program counter back to the reset vector. Unfortunately +the code that was executed may have left the hardware in an unknown +state. +@end deffn + +@section I/O Utilities + +These commands are available when +OpenOCD is built with @option{--enable-ioutil}. +They are mainly useful on embedded targets, +notably the ZY1000. +Hosts with operating systems have complementary tools. + +@emph{Note:} there are several more such commands. + +@deffn Command append_file filename [string]* +Appends the @var{string} parameters to +the text file @file{filename}. +Each string except the last one is followed by one space. +The last string is followed by a newline. +@end deffn + +@deffn Command cat filename +Reads and displays the text file @file{filename}. +@end deffn + +@deffn Command cp src_filename dest_filename +Copies contents from the file @file{src_filename} +into @file{dest_filename}. +@end deffn + +@deffn Command ip +@emph{No description provided.} +@end deffn + +@deffn Command ls +@emph{No description provided.} +@end deffn + +@deffn Command mac +@emph{No description provided.} +@end deffn + +@deffn Command meminfo +Display available RAM memory on OpenOCD host. +Used in OpenOCD regression testing scripts. +@end deffn + +@deffn Command peek +@emph{No description provided.} +@end deffn + +@deffn Command poke +@emph{No description provided.} +@end deffn + +@deffn Command rm filename +@c "rm" has both normal and Jim-level versions?? +Unlinks the file @file{filename}. +@end deffn + +@deffn Command trunc filename +Removes all data in the file @file{filename}. +@end deffn + +@anchor{memoryaccess} +@section Memory access commands +@cindex memory access + +These commands allow accesses of a specific size to the memory +system. Often these are used to configure the current target in some +special way. For example - one may need to write certain values to the +SDRAM controller to enable SDRAM. + +@enumerate +@item Use the @command{targets} (plural) command +to change the current target. +@item In system level scripts these commands are deprecated. +Please use their TARGET object siblings to avoid making assumptions +about what TAP is the current target, or about MMU configuration. +@end enumerate + +@deffn Command mdw [phys] addr [count] +@deffnx Command mdh [phys] addr [count] +@deffnx Command mdb [phys] addr [count] +Display contents of address @var{addr}, as +32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}), +or 8-bit bytes (@command{mdb}). +When the current target has an MMU which is present and active, +@var{addr} is interpreted as a virtual address. +Otherwise, or if the optional @var{phys} flag is specified, +@var{addr} is interpreted as a physical address. +If @var{count} is specified, displays that many units. +(If you want to manipulate the data instead of displaying it, +see the @code{mem2array} primitives.) +@end deffn + +@deffn Command mww [phys] addr word +@deffnx Command mwh [phys] addr halfword +@deffnx Command mwb [phys] addr byte +Writes the specified @var{word} (32 bits), +@var{halfword} (16 bits), or @var{byte} (8-bit) value, +at the specified address @var{addr}. +When the current target has an MMU which is present and active, +@var{addr} is interpreted as a virtual address. +Otherwise, or if the optional @var{phys} flag is specified, +@var{addr} is interpreted as a physical address. +@end deffn + +@anchor{imageaccess} +@section Image loading commands +@cindex image loading +@cindex image dumping + +@deffn Command {dump_image} filename address size +Dump @var{size} bytes of target memory starting at @var{address} to the +binary file named @var{filename}. +@end deffn + +@deffn Command {fast_load} +Loads an image stored in memory by @command{fast_load_image} to the +current target. Must be preceeded by fast_load_image. +@end deffn + +@deffn Command {fast_load_image} filename address [@option{bin}|@option{ihex}|@option{elf}|@option{s19}] +Normally you should be using @command{load_image} or GDB load. However, for +testing purposes or when I/O overhead is significant(OpenOCD running on an embedded +host), storing the image in memory and uploading the image to the target +can be a way to upload e.g. multiple debug sessions when the binary does not change. +Arguments are the same as @command{load_image}, but the image is stored in OpenOCD host +memory, i.e. does not affect target. This approach is also useful when profiling +target programming performance as I/O and target programming can easily be profiled +separately. +@end deffn + +@deffn Command {load_image} filename address [[@option{bin}|@option{ihex}|@option{elf}|@option{s19}] @option{min_addr} @option{max_length}] +Load image from file @var{filename} to target memory offset by @var{address} from its load address. +The file format may optionally be specified +(@option{bin}, @option{ihex}, @option{elf}, or @option{s19}). +In addition the following arguments may be specifed: +@var{min_addr} - ignore data below @var{min_addr} (this is w.r.t. to the target's load address + @var{address}) +@var{max_length} - maximum number of bytes to load. +@example +proc load_image_bin @{fname foffset address length @} @{ + # Load data from fname filename at foffset offset to + # target at address. Load at most length bytes. + load_image $fname [expr $address - $foffset] bin $address $length +@} +@end example +@end deffn + +@deffn Command {test_image} filename [address [@option{bin}|@option{ihex}|@option{elf}]] +Displays image section sizes and addresses +as if @var{filename} were loaded into target memory +starting at @var{address} (defaults to zero). +The file format may optionally be specified +(@option{bin}, @option{ihex}, or @option{elf}) +@end deffn + +@deffn Command {verify_image} filename address [@option{bin}|@option{ihex}|@option{elf}] +Verify @var{filename} against target memory starting at @var{address}. +The file format may optionally be specified +(@option{bin}, @option{ihex}, or @option{elf}) +This will first attempt a comparison using a CRC checksum, if this fails it will try a binary compare. +@end deffn + + +@section Breakpoint and Watchpoint commands +@cindex breakpoint +@cindex watchpoint + +CPUs often make debug modules accessible through JTAG, with +hardware support for a handful of code breakpoints and data +watchpoints. +In addition, CPUs almost always support software breakpoints. + +@deffn Command {bp} [address len [@option{hw}]] +With no parameters, lists all active breakpoints. +Else sets a breakpoint on code execution starting +at @var{address} for @var{length} bytes. +This is a software breakpoint, unless @option{hw} is specified +in which case it will be a hardware breakpoint. + +(@xref{arm9vectorcatch,,arm9 vector_catch}, or @pxref{xscalevectorcatch,,xscale vector_catch}, +for similar mechanisms that do not consume hardware breakpoints.) +@end deffn + +@deffn Command {rbp} address +Remove the breakpoint at @var{address}. +@end deffn + +@deffn Command {rwp} address +Remove data watchpoint on @var{address} +@end deffn + +@deffn Command {wp} [address len [(@option{r}|@option{w}|@option{a}) [value [mask]]]] +With no parameters, lists all active watchpoints. +Else sets a data watchpoint on data from @var{address} for @var{length} bytes. +The watch point is an "access" watchpoint unless +the @option{r} or @option{w} parameter is provided, +defining it as respectively a read or write watchpoint. +If a @var{value} is provided, that value is used when determining if +the watchpoint should trigger. The value may be first be masked +using @var{mask} to mark ``don't care'' fields. +@end deffn + +@section Misc Commands + +@cindex profiling +@deffn Command {profile} seconds filename +Profiling samples the CPU's program counter as quickly as possible, +which is useful for non-intrusive stochastic profiling. +Saves up to 10000 sampines in @file{filename} using ``gmon.out'' format. +@end deffn + +@deffn Command {version} +Displays a string identifying the version of this OpenOCD server. +@end deffn + +@deffn Command {virt2phys} virtual_address +Requests the current target to map the specified @var{virtual_address} +to its corresponding physical address, and displays the result. +@end deffn + +@node Architecture and Core Commands +@chapter Architecture and Core Commands +@cindex Architecture Specific Commands +@cindex Core Specific Commands + +Most CPUs have specialized JTAG operations to support debugging. +OpenOCD packages most such operations in its standard command framework. +Some of those operations don't fit well in that framework, so they are +exposed here as architecture or implementation (core) specific commands. + +@anchor{armhardwaretracing} +@section ARM Hardware Tracing +@cindex tracing +@cindex ETM +@cindex ETB + +CPUs based on ARM cores may include standard tracing interfaces, +based on an ``Embedded Trace Module'' (ETM) which sends voluminous +address and data bus trace records to a ``Trace Port''. + +@itemize +@item +Development-oriented boards will sometimes provide a high speed +trace connector for collecting that data, when the particular CPU +supports such an interface. +(The standard connector is a 38-pin Mictor, with both JTAG +and trace port support.) +Those trace connectors are supported by higher end JTAG adapters +and some logic analyzer modules; frequently those modules can +buffer several megabytes of trace data. +Configuring an ETM coupled to such an external trace port belongs +in the board-specific configuration file. +@item +If the CPU doesn't provide an external interface, it probably +has an ``Embedded Trace Buffer'' (ETB) on the chip, which is a +dedicated SRAM. 4KBytes is one common ETB size. +Configuring an ETM coupled only to an ETB belongs in the CPU-specific +(target) configuration file, since it works the same on all boards. +@end itemize + +ETM support in OpenOCD doesn't seem to be widely used yet. + +@quotation Issues +ETM support may be buggy, and at least some @command{etm config} +parameters should be detected by asking the ETM for them. + +ETM trigger events could also implement a kind of complex +hardware breakpoint, much more powerful than the simple +watchpoint hardware exported by EmbeddedICE modules. +@emph{Such breakpoints can be triggered even when using the +dummy trace port driver}. + +It seems like a GDB hookup should be possible, +as well as tracing only during specific states +(perhaps @emph{handling IRQ 23} or @emph{calls foo()}). + +There should be GUI tools to manipulate saved trace data and help +analyse it in conjunction with the source code. +It's unclear how much of a common interface is shared +with the current XScale trace support, or should be +shared with eventual Nexus-style trace module support. + +At this writing (November 2009) only ARM7, ARM9, and ARM11 support +for ETM modules is available. The code should be able to +work with some newer cores; but not all of them support +this original style of JTAG access. +@end quotation + +@subsection ETM Configuration +ETM setup is coupled with the trace port driver configuration. + +@deffn {Config Command} {etm config} target width mode clocking driver +Declares the ETM associated with @var{target}, and associates it +with a given trace port @var{driver}. @xref{traceportdrivers,,Trace Port Drivers}. + +Several of the parameters must reflect the trace port capabilities, +which are a function of silicon capabilties (exposed later +using @command{etm info}) and of what hardware is connected to +that port (such as an external pod, or ETB). +The @var{width} must be either 4, 8, or 16, +except with ETMv3.0 and newer modules which may also +support 1, 2, 24, 32, 48, and 64 bit widths. +(With those versions, @command{etm info} also shows whether +the selected port width and mode are supported.) + +The @var{mode} must be @option{normal}, @option{multiplexed}, +or @option{demultiplexed}. +The @var{clocking} must be @option{half} or @option{full}. + +@quotation Warning +With ETMv3.0 and newer, the bits set with the @var{mode} and +@var{clocking} parameters both control the mode. +This modified mode does not map to the values supported by +previous ETM modules, so this syntax is subject to change. +@end quotation + +@quotation Note +You can see the ETM registers using the @command{reg} command. +Not all possible registers are present in every ETM. +Most of the registers are write-only, and are used to configure +what CPU activities are traced. +@end quotation +@end deffn + +@deffn Command {etm info} +Displays information about the current target's ETM. +This includes resource counts from the @code{ETM_CONFIG} register, +as well as silicon capabilities (except on rather old modules). +from the @code{ETM_SYS_CONFIG} register. +@end deffn + +@deffn Command {etm status} +Displays status of the current target's ETM and trace port driver: +is the ETM idle, or is it collecting data? +Did trace data overflow? +Was it triggered? +@end deffn + +@deffn Command {etm tracemode} [type context_id_bits cycle_accurate branch_output] +Displays what data that ETM will collect. +If arguments are provided, first configures that data. +When the configuration changes, tracing is stopped +and any buffered trace data is invalidated. + +@itemize +@item @var{type} ... describing how data accesses are traced, +when they pass any ViewData filtering that that was set up. +The value is one of +@option{none} (save nothing), +@option{data} (save data), +@option{address} (save addresses), +@option{all} (save data and addresses) +@item @var{context_id_bits} ... 0, 8, 16, or 32 +@item @var{cycle_accurate} ... @option{enable} or @option{disable} +cycle-accurate instruction tracing. +Before ETMv3, enabling this causes much extra data to be recorded. +@item @var{branch_output} ... @option{enable} or @option{disable}. +Disable this unless you need to try reconstructing the instruction +trace stream without an image of the code. +@end itemize +@end deffn + +@deffn Command {etm trigger_debug} (@option{enable}|@option{disable}) +Displays whether ETM triggering debug entry (like a breakpoint) is +enabled or disabled, after optionally modifying that configuration. +The default behaviour is @option{disable}. +Any change takes effect after the next @command{etm start}. + +By using script commands to configure ETM registers, you can make the +processor enter debug state automatically when certain conditions, +more complex than supported by the breakpoint hardware, happen. +@end deffn + +@subsection ETM Trace Operation + +After setting up the ETM, you can use it to collect data. +That data can be exported to files for later analysis. +It can also be parsed with OpenOCD, for basic sanity checking. + +To configure what is being traced, you will need to write +various trace registers using @command{reg ETM_*} commands. +For the definitions of these registers, read ARM publication +@emph{IHI 0014, ``Embedded Trace Macrocell, Architecture Specification''}. +Be aware that most of the relevant registers are write-only, +and that ETM resources are limited. There are only a handful +of address comparators, data comparators, counters, and so on. + +Examples of scenarios you might arrange to trace include: + +@itemize +@item Code flow within a function, @emph{excluding} subroutines +it calls. Use address range comparators to enable tracing +for instruction access within that function's body. +@item Code flow within a function, @emph{including} subroutines +it calls. Use the sequencer and address comparators to activate +tracing on an ``entered function'' state, then deactivate it by +exiting that state when the function's exit code is invoked. +@item Code flow starting at the fifth invocation of a function, +combining one of the above models with a counter. +@item CPU data accesses to the registers for a particular device, +using address range comparators and the ViewData logic. +@item Such data accesses only during IRQ handling, combining the above +model with sequencer triggers which on entry and exit to the IRQ handler. +@item @emph{... more} +@end itemize + +At this writing, September 2009, there are no Tcl utility +procedures to help set up any common tracing scenarios. + +@deffn Command {etm analyze} +Reads trace data into memory, if it wasn't already present. +Decodes and prints the data that was collected. +@end deffn + +@deffn Command {etm dump} filename +Stores the captured trace data in @file{filename}. +@end deffn + +@deffn Command {etm image} filename [base_address] [type] +Opens an image file. +@end deffn + +@deffn Command {etm load} filename +Loads captured trace data from @file{filename}. +@end deffn + +@deffn Command {etm start} +Starts trace data collection. +@end deffn + +@deffn Command {etm stop} +Stops trace data collection. +@end deffn + +@anchor{traceportdrivers} +@subsection Trace Port Drivers + +To use an ETM trace port it must be associated with a driver. + +@deffn {Trace Port Driver} dummy +Use the @option{dummy} driver if you are configuring an ETM that's +not connected to anything (on-chip ETB or off-chip trace connector). +@emph{This driver lets OpenOCD talk to the ETM, but it does not expose +any trace data collection.} +@deffn {Config Command} {etm_dummy config} target +Associates the ETM for @var{target} with a dummy driver. +@end deffn +@end deffn + +@deffn {Trace Port Driver} etb +Use the @option{etb} driver if you are configuring an ETM +to use on-chip ETB memory. +@deffn {Config Command} {etb config} target etb_tap +Associates the ETM for @var{target} with the ETB at @var{etb_tap}. +You can see the ETB registers using the @command{reg} command. +@end deffn +@deffn Command {etb trigger_percent} [percent] +This displays, or optionally changes, ETB behavior after the +ETM's configured @emph{trigger} event fires. +It controls how much more trace data is saved after the (single) +trace trigger becomes active. + +@itemize +@item The default corresponds to @emph{trace around} usage, +recording 50 percent data before the event and the rest +afterwards. +@item The minimum value of @var{percent} is 2 percent, +recording almost exclusively data before the trigger. +Such extreme @emph{trace before} usage can help figure out +what caused that event to happen. +@item The maximum value of @var{percent} is 100 percent, +recording data almost exclusively after the event. +This extreme @emph{trace after} usage might help sort out +how the event caused trouble. +@end itemize +@c REVISIT allow "break" too -- enter debug mode. +@end deffn + +@end deffn + +@deffn {Trace Port Driver} oocd_trace +This driver isn't available unless OpenOCD was explicitly configured +with the @option{--enable-oocd_trace} option. You probably don't want +to configure it unless you've built the appropriate prototype hardware; +it's @emph{proof-of-concept} software. + +Use the @option{oocd_trace} driver if you are configuring an ETM that's +connected to an off-chip trace connector. + +@deffn {Config Command} {oocd_trace config} target tty +Associates the ETM for @var{target} with a trace driver which +collects data through the serial port @var{tty}. +@end deffn + +@deffn Command {oocd_trace resync} +Re-synchronizes with the capture clock. +@end deffn + +@deffn Command {oocd_trace status} +Reports whether the capture clock is locked or not. +@end deffn +@end deffn + + +@section Generic ARM +@cindex ARM + +These commands should be available on all ARM processors. +They are available in addition to other core-specific +commands that may be available. + +@deffn Command {arm core_state} [@option{arm}|@option{thumb}] +Displays the core_state, optionally changing it to process +either @option{arm} or @option{thumb} instructions. +The target may later be resumed in the currently set core_state. +(Processors may also support the Jazelle state, but +that is not currently supported in OpenOCD.) +@end deffn + +@deffn Command {arm disassemble} address [count [@option{thumb}]] +@cindex disassemble +Disassembles @var{count} instructions starting at @var{address}. +If @var{count} is not specified, a single instruction is disassembled. +If @option{thumb} is specified, or the low bit of the address is set, +Thumb2 (mixed 16/32-bit) instructions are used; +else ARM (32-bit) instructions are used. +(Processors may also support the Jazelle state, but +those instructions are not currently understood by OpenOCD.) + +Note that all Thumb instructions are Thumb2 instructions, +so older processors (without Thumb2 support) will still +see correct disassembly of Thumb code. +Also, ThumbEE opcodes are the same as Thumb2, +with a handful of exceptions. +ThumbEE disassembly currently has no explicit support. +@end deffn + +@deffn Command {arm mcr} pX op1 CRn CRm op2 value +Write @var{value} to a coprocessor @var{pX} register +passing parameters @var{CRn}, +@var{CRm}, opcodes @var{opc1} and @var{opc2}, +and using the MCR instruction. +(Parameter sequence matches the ARM instruction, but omits +an ARM register.) +@end deffn + +@deffn Command {arm mrc} pX coproc op1 CRn CRm op2 +Read a coprocessor @var{pX} register passing parameters @var{CRn}, +@var{CRm}, opcodes @var{opc1} and @var{opc2}, +and the MRC instruction. +Returns the result so it can be manipulated by Jim scripts. +(Parameter sequence matches the ARM instruction, but omits +an ARM register.) +@end deffn + +@deffn Command {arm reg} +Display a table of all banked core registers, fetching the current value from every +core mode if necessary. +@end deffn + +@deffn Command {arm semihosting} [@option{enable}|@option{disable}] +@cindex ARM semihosting +Display status of semihosting, after optionally changing that status. + +Semihosting allows for code executing on an ARM target to use the +I/O facilities on the host computer i.e. the system where OpenOCD +is running. The target application must be linked against a library +implementing the ARM semihosting convention that forwards operation +requests by using a special SVC instruction that is trapped at the +Supervisor Call vector by OpenOCD. +@end deffn + +@section ARMv4 and ARMv5 Architecture +@cindex ARMv4 +@cindex ARMv5 + +The ARMv4 and ARMv5 architectures are widely used in embedded systems, +and introduced core parts of the instruction set in use today. +That includes the Thumb instruction set, introduced in the ARMv4T +variant. + +@subsection ARM7 and ARM9 specific commands +@cindex ARM7 +@cindex ARM9 + +These commands are specific to ARM7 and ARM9 cores, like ARM7TDMI, ARM720T, +ARM9TDMI, ARM920T or ARM926EJ-S. +They are available in addition to the ARM commands, +and any other core-specific commands that may be available. + +@deffn Command {arm7_9 dbgrq} [@option{enable}|@option{disable}] +Displays the value of the flag controlling use of the +the EmbeddedIce DBGRQ signal to force entry into debug mode, +instead of breakpoints. +If a boolean parameter is provided, first assigns that flag. + +This should be +safe for all but ARM7TDMI-S cores (like NXP LPC). +This feature is enabled by default on most ARM9 cores, +including ARM9TDMI, ARM920T, and ARM926EJ-S. +@end deffn + +@deffn Command {arm7_9 dcc_downloads} [@option{enable}|@option{disable}] +@cindex DCC +Displays the value of the flag controlling use of the debug communications +channel (DCC) to write larger (>128 byte) amounts of memory. +If a boolean parameter is provided, first assigns that flag. + +DCC downloads offer a huge speed increase, but might be +unsafe, especially with targets running at very low speeds. This command was introduced +with OpenOCD rev. 60, and requires a few bytes of working area. +@end deffn + +@deffn Command {arm7_9 fast_memory_access} [@option{enable}|@option{disable}] +Displays the value of the flag controlling use of memory writes and reads +that don't check completion of the operation. +If a boolean parameter is provided, first assigns that flag. + +This provides a huge speed increase, especially with USB JTAG +cables (FT2232), but might be unsafe if used with targets running at very low +speeds, like the 32kHz startup clock of an AT91RM9200. +@end deffn + +@subsection ARM720T specific commands +@cindex ARM720T + +These commands are available to ARM720T based CPUs, +which are implementations of the ARMv4T architecture +based on the ARM7TDMI-S integer core. +They are available in addition to the ARM and ARM7/ARM9 commands. + +@deffn Command {arm720t cp15} opcode [value] +@emph{DEPRECATED -- avoid using this. +Use the @command{arm mrc} or @command{arm mcr} commands instead.} + +Display cp15 register returned by the ARM instruction @var{opcode}; +else if a @var{value} is provided, that value is written to that register. +The @var{opcode} should be the value of either an MRC or MCR instruction. +@end deffn + +@subsection ARM9 specific commands +@cindex ARM9 + +ARM9-family cores are built around ARM9TDMI or ARM9E (including ARM9EJS) +integer processors. +Such cores include the ARM920T, ARM926EJ-S, and ARM966. + +@c 9-june-2009: tried this on arm920t, it didn't work. +@c no-params always lists nothing caught, and that's how it acts. +@c 23-oct-2009: doesn't work _consistently_ ... as if the ICE +@c versions have different rules about when they commit writes. + +@anchor{arm9vectorcatch} +@deffn Command {arm9 vector_catch} [@option{all}|@option{none}|list] +@cindex vector_catch +Vector Catch hardware provides a sort of dedicated breakpoint +for hardware events such as reset, interrupt, and abort. +You can use this to conserve normal breakpoint resources, +so long as you're not concerned with code that branches directly +to those hardware vectors. + +This always finishes by listing the current configuration. +If parameters are provided, it first reconfigures the +vector catch hardware to intercept +@option{all} of the hardware vectors, +@option{none} of them, +or a list with one or more of the following: +@option{reset} @option{undef} @option{swi} @option{pabt} @option{dabt} +@option{irq} @option{fiq}. +@end deffn + +@subsection ARM920T specific commands +@cindex ARM920T + +These commands are available to ARM920T based CPUs, +which are implementations of the ARMv4T architecture +built using the ARM9TDMI integer core. +They are available in addition to the ARM, ARM7/ARM9, +and ARM9 commands. + +@deffn Command {arm920t cache_info} +Print information about the caches found. This allows to see whether your target +is an ARM920T (2x16kByte cache) or ARM922T (2x8kByte cache). +@end deffn + +@deffn Command {arm920t cp15} regnum [value] +Display cp15 register @var{regnum}; +else if a @var{value} is provided, that value is written to that register. +This uses "physical access" and the register number is as +shown in bits 38..33 of table 9-9 in the ARM920T TRM. +(Not all registers can be written.) +@end deffn + +@deffn Command {arm920t cp15i} opcode [value [address]] +@emph{DEPRECATED -- avoid using this. +Use the @command{arm mrc} or @command{arm mcr} commands instead.} + +Interpreted access using ARM instruction @var{opcode}, which should +be the value of either an MRC or MCR instruction +(as shown tables 9-11, 9-12, and 9-13 in the ARM920T TRM). +If no @var{value} is provided, the result is displayed. +Else if that value is written using the specified @var{address}, +or using zero if no other address is provided. +@end deffn + +@deffn Command {arm920t read_cache} filename +Dump the content of ICache and DCache to a file named @file{filename}. +@end deffn + +@deffn Command {arm920t read_mmu} filename +Dump the content of the ITLB and DTLB to a file named @file{filename}. +@end deffn + +@subsection ARM926ej-s specific commands +@cindex ARM926ej-s + +These commands are available to ARM926ej-s based CPUs, +which are implementations of the ARMv5TEJ architecture +based on the ARM9EJ-S integer core. +They are available in addition to the ARM, ARM7/ARM9, +and ARM9 commands. + +The Feroceon cores also support these commands, although +they are not built from ARM926ej-s designs. + +@deffn Command {arm926ejs cache_info} +Print information about the caches found. +@end deffn + +@subsection ARM966E specific commands +@cindex ARM966E + +These commands are available to ARM966 based CPUs, +which are implementations of the ARMv5TE architecture. +They are available in addition to the ARM, ARM7/ARM9, +and ARM9 commands. + +@deffn Command {arm966e cp15} regnum [value] +Display cp15 register @var{regnum}; +else if a @var{value} is provided, that value is written to that register. +The six bit @var{regnum} values are bits 37..32 from table 7-2 of the +ARM966E-S TRM. +There is no current control over bits 31..30 from that table, +as required for BIST support. +@end deffn + +@subsection XScale specific commands +@cindex XScale + +Some notes about the debug implementation on the XScale CPUs: + +The XScale CPU provides a special debug-only mini-instruction cache +(mini-IC) in which exception vectors and target-resident debug handler +code are placed by OpenOCD. In order to get access to the CPU, OpenOCD +must point vector 0 (the reset vector) to the entry of the debug +handler. However, this means that the complete first cacheline in the +mini-IC is marked valid, which makes the CPU fetch all exception +handlers from the mini-IC, ignoring the code in RAM. + +To address this situation, OpenOCD provides the @code{xscale +vector_table} command, which allows the user to explicity write +individual entries to either the high or low vector table stored in +the mini-IC. + +It is recommended to place a pc-relative indirect branch in the vector +table, and put the branch destination somewhere in memory. Doing so +makes sure the code in the vector table stays constant regardless of +code layout in memory: +@example +_vectors: + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + ldr pc,[pc,#0x100-8] + .org 0x100 + .long real_reset_vector + .long real_ui_handler + .long real_swi_handler + .long real_pf_abort + .long real_data_abort + .long 0 /* unused */ + .long real_irq_handler + .long real_fiq_handler +@end example + +Alternatively, you may choose to keep some or all of the mini-IC +vector table entries synced with those written to memory by your +system software. The mini-IC can not be modified while the processor +is executing, but for each vector table entry not previously defined +using the @code{xscale vector_table} command, OpenOCD will copy the +value from memory to the mini-IC every time execution resumes from a +halt. This is done for both high and low vector tables (although the +table not in use may not be mapped to valid memory, and in this case +that copy operation will silently fail). This means that you will +need to briefly halt execution at some strategic point during system +start-up; e.g., after the software has initialized the vector table, +but before exceptions are enabled. A breakpoint can be used to +accomplish this once the appropriate location in the start-up code has +been identified. A watchpoint over the vector table region is helpful +in finding the location if you're not sure. Note that the same +situation exists any time the vector table is modified by the system +software. + +The debug handler must be placed somewhere in the address space using +the @code{xscale debug_handler} command. The allowed locations for the +debug handler are either (0x800 - 0x1fef800) or (0xfe000800 - +0xfffff800). The default value is 0xfe000800. + +XScale has resources to support two hardware breakpoints and two +watchpoints. However, the following restrictions on watchpoint +functionality apply: (1) the value and mask arguments to the @code{wp} +command are not supported, (2) the watchpoint length must be a +power of two and not less than four, and can not be greater than the +watchpoint address, and (3) a watchpoint with a length greater than +four consumes all the watchpoint hardware resources. This means that +at any one time, you can have enabled either two watchpoints with a +length of four, or one watchpoint with a length greater than four. + +These commands are available to XScale based CPUs, +which are implementations of the ARMv5TE architecture. + +@deffn Command {xscale analyze_trace} +Displays the contents of the trace buffer. +@end deffn + +@deffn Command {xscale cache_clean_address} address +Changes the address used when cleaning the data cache. +@end deffn + +@deffn Command {xscale cache_info} +Displays information about the CPU caches. +@end deffn + +@deffn Command {xscale cp15} regnum [value] +Display cp15 register @var{regnum}; +else if a @var{value} is provided, that value is written to that register. +@end deffn + +@deffn Command {xscale debug_handler} target address +Changes the address used for the specified target's debug handler. +@end deffn + +@deffn Command {xscale dcache} [@option{enable}|@option{disable}] +Enables or disable the CPU's data cache. +@end deffn + +@deffn Command {xscale dump_trace} filename +Dumps the raw contents of the trace buffer to @file{filename}. +@end deffn + +@deffn Command {xscale icache} [@option{enable}|@option{disable}] +Enables or disable the CPU's instruction cache. +@end deffn + +@deffn Command {xscale mmu} [@option{enable}|@option{disable}] +Enables or disable the CPU's memory management unit. +@end deffn + +@deffn Command {xscale trace_buffer} [@option{enable}|@option{disable} [@option{fill} [n] | @option{wrap}]] +Displays the trace buffer status, after optionally +enabling or disabling the trace buffer +and modifying how it is emptied. +@end deffn + +@deffn Command {xscale trace_image} filename [offset [type]] +Opens a trace image from @file{filename}, optionally rebasing +its segment addresses by @var{offset}. +The image @var{type} may be one of +@option{bin} (binary), @option{ihex} (Intel hex), +@option{elf} (ELF file), @option{s19} (Motorola s19), +@option{mem}, or @option{builder}. +@end deffn + +@anchor{xscalevectorcatch} +@deffn Command {xscale vector_catch} [mask] +@cindex vector_catch +Display a bitmask showing the hardware vectors to catch. +If the optional parameter is provided, first set the bitmask to that value. + +The mask bits correspond with bit 16..23 in the DCSR: +@example +0x01 Trap Reset +0x02 Trap Undefined Instructions +0x04 Trap Software Interrupt +0x08 Trap Prefetch Abort +0x10 Trap Data Abort +0x20 reserved +0x40 Trap IRQ +0x80 Trap FIQ +@end example +@end deffn + +@deffn Command {xscale vector_table} [(@option{low}|@option{high}) index value] +@cindex vector_table + +Set an entry in the mini-IC vector table. There are two tables: one for +low vectors (at 0x00000000), and one for high vectors (0xFFFF0000), each +holding the 8 exception vectors. @var{index} can be 1-7, because vector 0 +points to the debug handler entry and can not be overwritten. +@var{value} holds the 32-bit opcode that is placed in the mini-IC. + +Without arguments, the current settings are displayed. + +@end deffn + +@section ARMv6 Architecture +@cindex ARMv6 + +@subsection ARM11 specific commands +@cindex ARM11 + +@deffn Command {arm11 memwrite burst} [@option{enable}|@option{disable}] +Displays the value of the memwrite burst-enable flag, +which is enabled by default. +If a boolean parameter is provided, first assigns that flag. +Burst writes are only used for memory writes larger than 1 word. +They improve performance by assuming that the CPU has read each data +word over JTAG and completed its write before the next word arrives, +instead of polling for a status flag to verify that completion. +This is usually safe, because JTAG runs much slower than the CPU. +@end deffn + +@deffn Command {arm11 memwrite error_fatal} [@option{enable}|@option{disable}] +Displays the value of the memwrite error_fatal flag, +which is enabled by default. +If a boolean parameter is provided, first assigns that flag. +When set, certain memory write errors cause earlier transfer termination. +@end deffn + +@deffn Command {arm11 step_irq_enable} [@option{enable}|@option{disable}] +Displays the value of the flag controlling whether +IRQs are enabled during single stepping; +they are disabled by default. +If a boolean parameter is provided, first assigns that. +@end deffn + +@deffn Command {arm11 vcr} [value] +@cindex vector_catch +Displays the value of the @emph{Vector Catch Register (VCR)}, +coprocessor 14 register 7. +If @var{value} is defined, first assigns that. + +Vector Catch hardware provides dedicated breakpoints +for certain hardware events. +The specific bit values are core-specific (as in fact is using +coprocessor 14 register 7 itself) but all current ARM11 +cores @emph{except the ARM1176} use the same six bits. +@end deffn + +@section ARMv7 Architecture +@cindex ARMv7 + +@subsection ARMv7 Debug Access Port (DAP) specific commands +@cindex Debug Access Port +@cindex DAP +These commands are specific to ARM architecture v7 Debug Access Port (DAP), +included on Cortex-M and Cortex-A systems. +They are available in addition to other core-specific commands that may be available. + +@deffn Command {dap apid} [num] +Displays ID register from AP @var{num}, +defaulting to the currently selected AP. +@end deffn + +@deffn Command {dap apsel} [num] +Select AP @var{num}, defaulting to 0. +@end deffn + +@deffn Command {dap baseaddr} [num] +Displays debug base address from MEM-AP @var{num}, +defaulting to the currently selected AP. +@end deffn + +@deffn Command {dap info} [num] +Displays the ROM table for MEM-AP @var{num}, +defaulting to the currently selected AP. +@end deffn + +@deffn Command {dap memaccess} [value] +Displays the number of extra tck cycles in the JTAG idle to use for MEM-AP +memory bus access [0-255], giving additional time to respond to reads. +If @var{value} is defined, first assigns that. +@end deffn + +@deffn Command {dap apcsw} [0 / 1] +fix CSW_SPROT from register AP_REG_CSW on selected dap. +Defaulting to 0. +@end deffn + +@subsection Cortex-M specific commands +@cindex Cortex-M + +@deffn Command {cortex_m maskisr} (@option{auto}|@option{on}|@option{off}) +Control masking (disabling) interrupts during target step/resume. + +The @option{auto} option handles interrupts during stepping a way they get +served but don't disturb the program flow. The step command first allows +pending interrupt handlers to execute, then disables interrupts and steps over +the next instruction where the core was halted. After the step interrupts +are enabled again. If the interrupt handlers don't complete within 500ms, +the step command leaves with the core running. + +Note that a free breakpoint is required for the @option{auto} option. If no +breakpoint is available at the time of the step, then the step is taken +with interrupts enabled, i.e. the same way the @option{off} option does. + +Default is @option{auto}. +@end deffn + +@deffn Command {cortex_m vector_catch} [@option{all}|@option{none}|list] +@cindex vector_catch +Vector Catch hardware provides dedicated breakpoints +for certain hardware events. + +Parameters request interception of +@option{all} of these hardware event vectors, +@option{none} of them, +or one or more of the following: +@option{hard_err} for a HardFault exception; +@option{mm_err} for a MemManage exception; +@option{bus_err} for a BusFault exception; +@option{irq_err}, +@option{state_err}, +@option{chk_err}, or +@option{nocp_err} for various UsageFault exceptions; or +@option{reset}. +If NVIC setup code does not enable them, +MemManage, BusFault, and UsageFault exceptions +are mapped to HardFault. +UsageFault checks for +divide-by-zero and unaligned access +must also be explicitly enabled. + +This finishes by listing the current vector catch configuration. +@end deffn + +@deffn Command {cortex_m reset_config} (@option{srst}|@option{sysresetreq}|@option{vectreset}) +Control reset handling. The default @option{srst} is to use srst if fitted, +otherwise fallback to @option{vectreset}. +@itemize @minus +@item @option{srst} use hardware srst if fitted otherwise fallback to @option{vectreset}. +@item @option{sysresetreq} use NVIC SYSRESETREQ to reset system. +@item @option{vectreset} use NVIC VECTRESET to reset system. +@end itemize +Using @option{vectreset} is a safe option for all current Cortex-M cores. +This however has the disadvantage of only resetting the core, all peripherals +are uneffected. A solution would be to use a @code{reset-init} event handler to manually reset +the peripherals. +@xref{targetevents,,Target Events}. +@end deffn + +@anchor{softwaredebugmessagesandtracing} +@section Software Debug Messages and Tracing +@cindex Linux-ARM DCC support +@cindex tracing +@cindex libdcc +@cindex DCC +OpenOCD can process certain requests from target software, when +the target uses appropriate libraries. +The most powerful mechanism is semihosting, but there is also +a lighter weight mechanism using only the DCC channel. + +Currently @command{target_request debugmsgs} +is supported only for @option{arm7_9} and @option{cortex_m} cores. +These messages are received as part of target polling, so +you need to have @command{poll on} active to receive them. +They are intrusive in that they will affect program execution +times. If that is a problem, @pxref{armhardwaretracing,,ARM Hardware Tracing}. + +See @file{libdcc} in the contrib dir for more details. +In addition to sending strings, characters, and +arrays of various size integers from the target, +@file{libdcc} also exports a software trace point mechanism. +The target being debugged may +issue trace messages which include a 24-bit @dfn{trace point} number. +Trace point support includes two distinct mechanisms, +each supported by a command: + +@itemize +@item @emph{History} ... A circular buffer of trace points +can be set up, and then displayed at any time. +This tracks where code has been, which can be invaluable in +finding out how some fault was triggered. + +The buffer may overflow, since it collects records continuously. +It may be useful to use some of the 24 bits to represent a +particular event, and other bits to hold data. + +@item @emph{Counting} ... An array of counters can be set up, +and then displayed at any time. +This can help establish code coverage and identify hot spots. + +The array of counters is directly indexed by the trace point +number, so trace points with higher numbers are not counted. +@end itemize + +Linux-ARM kernels have a ``Kernel low-level debugging +via EmbeddedICE DCC channel'' option (CONFIG_DEBUG_ICEDCC, +depends on CONFIG_DEBUG_LL) which uses this mechanism to +deliver messages before a serial console can be activated. +This is not the same format used by @file{libdcc}. +Other software, such as the U-Boot boot loader, sometimes +does the same thing. + +@deffn Command {target_request debugmsgs} [@option{enable}|@option{disable}|@option{charmsg}] +Displays current handling of target DCC message requests. +These messages may be sent to the debugger while the target is running. +The optional @option{enable} and @option{charmsg} parameters +both enable the messages, while @option{disable} disables them. + +With @option{charmsg} the DCC words each contain one character, +as used by Linux with CONFIG_DEBUG_ICEDCC; +otherwise the libdcc format is used. +@end deffn + +@deffn Command {trace history} [@option{clear}|count] +With no parameter, displays all the trace points that have triggered +in the order they triggered. +With the parameter @option{clear}, erases all current trace history records. +With a @var{count} parameter, allocates space for that many +history records. +@end deffn + +@deffn Command {trace point} [@option{clear}|identifier] +With no parameter, displays all trace point identifiers and how many times +they have been triggered. +With the parameter @option{clear}, erases all current trace point counters. +With a numeric @var{identifier} parameter, creates a new a trace point counter +and associates it with that identifier. + +@emph{Important:} The identifier and the trace point number +are not related except by this command. +These trace point numbers always start at zero (from server startup, +or after @command{trace point clear}) and count up from there. +@end deffn + + +@node JTAG Commands +@chapter JTAG Commands +@cindex JTAG Commands +Most general purpose JTAG commands have been presented earlier. +(@xref{jtagspeed,,JTAG Speed}, @ref{Reset Configuration}, and @ref{TAP Declaration}.) +Lower level JTAG commands, as presented here, +may be needed to work with targets which require special +attention during operations such as reset or initialization. + +To use these commands you will need to understand some +of the basics of JTAG, including: + +@itemize @bullet +@item A JTAG scan chain consists of a sequence of individual TAP +devices such as a CPUs. +@item Control operations involve moving each TAP through the same +standard state machine (in parallel) +using their shared TMS and clock signals. +@item Data transfer involves shifting data through the chain of +instruction or data registers of each TAP, writing new register values +while the reading previous ones. +@item Data register sizes are a function of the instruction active in +a given TAP, while instruction register sizes are fixed for each TAP. +All TAPs support a BYPASS instruction with a single bit data register. +@item The way OpenOCD differentiates between TAP devices is by +shifting different instructions into (and out of) their instruction +registers. +@end itemize + +@section Low Level JTAG Commands + +These commands are used by developers who need to access +JTAG instruction or data registers, possibly controlling +the order of TAP state transitions. +If you're not debugging OpenOCD internals, or bringing up a +new JTAG adapter or a new type of TAP device (like a CPU or +JTAG router), you probably won't need to use these commands. +In a debug session that doesn't use JTAG for its transport protocol, +these commands are not available. + +@deffn Command {drscan} tap [numbits value]+ [@option{-endstate} tap_state] +Loads the data register of @var{tap} with a series of bit fields +that specify the entire register. +Each field is @var{numbits} bits long with +a numeric @var{value} (hexadecimal encouraged). +The return value holds the original value of each +of those fields. + +For example, a 38 bit number might be specified as one +field of 32 bits then one of 6 bits. +@emph{For portability, never pass fields which are more +than 32 bits long. Many OpenOCD implementations do not +support 64-bit (or larger) integer values.} + +All TAPs other than @var{tap} must be in BYPASS mode. +The single bit in their data registers does not matter. + +When @var{tap_state} is specified, the JTAG state machine is left +in that state. +For example @sc{drpause} might be specified, so that more +instructions can be issued before re-entering the @sc{run/idle} state. +If the end state is not specified, the @sc{run/idle} state is entered. + +@quotation Warning +OpenOCD does not record information about data register lengths, +so @emph{it is important that you get the bit field lengths right}. +Remember that different JTAG instructions refer to different +data registers, which may have different lengths. +Moreover, those lengths may not be fixed; +the SCAN_N instruction can change the length of +the register accessed by the INTEST instruction +(by connecting a different scan chain). +@end quotation +@end deffn + +@deffn Command {flush_count} +Returns the number of times the JTAG queue has been flushed. +This may be used for performance tuning. + +For example, flushing a queue over USB involves a +minimum latency, often several milliseconds, which does +not change with the amount of data which is written. +You may be able to identify performance problems by finding +tasks which waste bandwidth by flushing small transfers too often, +instead of batching them into larger operations. +@end deffn + +@deffn Command {irscan} [tap instruction]+ [@option{-endstate} tap_state] +For each @var{tap} listed, loads the instruction register +with its associated numeric @var{instruction}. +(The number of bits in that instruction may be displayed +using the @command{scan_chain} command.) +For other TAPs, a BYPASS instruction is loaded. + +When @var{tap_state} is specified, the JTAG state machine is left +in that state. +For example @sc{irpause} might be specified, so the data register +can be loaded before re-entering the @sc{run/idle} state. +If the end state is not specified, the @sc{run/idle} state is entered. + +@quotation Note +OpenOCD currently supports only a single field for instruction +register values, unlike data register values. +For TAPs where the instruction register length is more than 32 bits, +portable scripts currently must issue only BYPASS instructions. +@end quotation +@end deffn + +@deffn Command {jtag_reset} trst srst +Set values of reset signals. +The @var{trst} and @var{srst} parameter values may be +@option{0}, indicating that reset is inactive (pulled or driven high), +or @option{1}, indicating it is active (pulled or driven low). +The @command{reset_config} command should already have been used +to configure how the board and JTAG adapter treat these two +signals, and to say if either signal is even present. +@xref{Reset Configuration}. + +Note that TRST is specially handled. +It actually signifies JTAG's @sc{reset} state. +So if the board doesn't support the optional TRST signal, +or it doesn't support it along with the specified SRST value, +JTAG reset is triggered with TMS and TCK signals +instead of the TRST signal. +And no matter how that JTAG reset is triggered, once +the scan chain enters @sc{reset} with TRST inactive, +TAP @code{post-reset} events are delivered to all TAPs +with handlers for that event. +@end deffn + +@deffn Command {pathmove} start_state [next_state ...] +Start by moving to @var{start_state}, which +must be one of the @emph{stable} states. +Unless it is the only state given, this will often be the +current state, so that no TCK transitions are needed. +Then, in a series of single state transitions +(conforming to the JTAG state machine) shift to +each @var{next_state} in sequence, one per TCK cycle. +The final state must also be stable. +@end deffn + +@deffn Command {runtest} @var{num_cycles} +Move to the @sc{run/idle} state, and execute at least +@var{num_cycles} of the JTAG clock (TCK). +Instructions often need some time +to execute before they take effect. +@end deffn + +@c tms_sequence (short|long) +@c ... temporary, debug-only, other than USBprog bug workaround... + +@deffn Command {verify_ircapture} (@option{enable}|@option{disable}) +Verify values captured during @sc{ircapture} and returned +during IR scans. Default is enabled, but this can be +overridden by @command{verify_jtag}. +This flag is ignored when validating JTAG chain configuration. +@end deffn + +@deffn Command {verify_jtag} (@option{enable}|@option{disable}) +Enables verification of DR and IR scans, to help detect +programming errors. For IR scans, @command{verify_ircapture} +must also be enabled. +Default is enabled. +@end deffn + +@section TAP state names +@cindex TAP state names + +The @var{tap_state} names used by OpenOCD in the @command{drscan}, +@command{irscan}, and @command{pathmove} commands are the same +as those used in SVF boundary scan documents, except that +SVF uses @sc{idle} instead of @sc{run/idle}. + +@itemize @bullet +@item @b{RESET} ... @emph{stable} (with TMS high); +acts as if TRST were pulsed +@item @b{RUN/IDLE} ... @emph{stable}; don't assume this always means IDLE +@item @b{DRSELECT} +@item @b{DRCAPTURE} +@item @b{DRSHIFT} ... @emph{stable}; TDI/TDO shifting +through the data register +@item @b{DREXIT1} +@item @b{DRPAUSE} ... @emph{stable}; data register ready +for update or more shifting +@item @b{DREXIT2} +@item @b{DRUPDATE} +@item @b{IRSELECT} +@item @b{IRCAPTURE} +@item @b{IRSHIFT} ... @emph{stable}; TDI/TDO shifting +through the instruction register +@item @b{IREXIT1} +@item @b{IRPAUSE} ... @emph{stable}; instruction register ready +for update or more shifting +@item @b{IREXIT2} +@item @b{IRUPDATE} +@end itemize + +Note that only six of those states are fully ``stable'' in the +face of TMS fixed (low except for @sc{reset}) +and a free-running JTAG clock. For all the +others, the next TCK transition changes to a new state. + +@itemize @bullet +@item From @sc{drshift} and @sc{irshift}, clock transitions will +produce side effects by changing register contents. The values +to be latched in upcoming @sc{drupdate} or @sc{irupdate} states +may not be as expected. +@item @sc{run/idle}, @sc{drpause}, and @sc{irpause} are reasonable +choices after @command{drscan} or @command{irscan} commands, +since they are free of JTAG side effects. +@item @sc{run/idle} may have side effects that appear at non-JTAG +levels, such as advancing the ARM9E-S instruction pipeline. +Consult the documentation for the TAP(s) you are working with. +@end itemize + +@node Boundary Scan Commands +@chapter Boundary Scan Commands + +One of the original purposes of JTAG was to support +boundary scan based hardware testing. +Although its primary focus is to support On-Chip Debugging, +OpenOCD also includes some boundary scan commands. + +@section SVF: Serial Vector Format +@cindex Serial Vector Format +@cindex SVF + +The Serial Vector Format, better known as @dfn{SVF}, is a +way to represent JTAG test patterns in text files. +In a debug session using JTAG for its transport protocol, +OpenOCD supports running such test files. + +@deffn Command {svf} filename [@option{quiet}] +This issues a JTAG reset (Test-Logic-Reset) and then +runs the SVF script from @file{filename}. +Unless the @option{quiet} option is specified, +each command is logged before it is executed. +@end deffn + +@section XSVF: Xilinx Serial Vector Format +@cindex Xilinx Serial Vector Format +@cindex XSVF + +The Xilinx Serial Vector Format, better known as @dfn{XSVF}, is a +binary representation of SVF which is optimized for use with +Xilinx devices. +In a debug session using JTAG for its transport protocol, +OpenOCD supports running such test files. + +@quotation Important +Not all XSVF commands are supported. +@end quotation + +@deffn Command {xsvf} (tapname|@option{plain}) filename [@option{virt2}] [@option{quiet}] +This issues a JTAG reset (Test-Logic-Reset) and then +runs the XSVF script from @file{filename}. +When a @var{tapname} is specified, the commands are directed at +that TAP. +When @option{virt2} is specified, the @sc{xruntest} command counts +are interpreted as TCK cycles instead of microseconds. +Unless the @option{quiet} option is specified, +messages are logged for comments and some retries. +@end deffn + +The OpenOCD sources also include two utility scripts +for working with XSVF; they are not currently installed +after building the software. +You may find them useful: + +@itemize +@item @emph{svf2xsvf} ... converts SVF files into the extended XSVF +syntax understood by the @command{xsvf} command; see notes below. +@item @emph{xsvfdump} ... converts XSVF files into a text output format; +understands the OpenOCD extensions. +@end itemize + +The input format accepts a handful of non-standard extensions. +These include three opcodes corresponding to SVF extensions +from Lattice Semiconductor (LCOUNT, LDELAY, LDSR), and +two opcodes supporting a more accurate translation of SVF +(XTRST, XWAITSTATE). +If @emph{xsvfdump} shows a file is using those opcodes, it +probably will not be usable with other XSVF tools. + + +@node TFTP +@chapter TFTP +@cindex TFTP +If OpenOCD runs on an embedded host(as ZY1000 does), then TFTP can +be used to access files on PCs (either the developer's PC or some other PC). + +The way this works on the ZY1000 is to prefix a filename by +"/tftp/ip/" and append the TFTP path on the TFTP +server (tftpd). For example, + +@example +load_image /tftp/10.0.0.96/c:\temp\abc.elf +@end example + +will load c:\temp\abc.elf from the developer pc (10.0.0.96) into memory as +if the file was hosted on the embedded host. + +In order to achieve decent performance, you must choose a TFTP server +that supports a packet size bigger than the default packet size (512 bytes). There +are numerous TFTP servers out there (free and commercial) and you will have to do +a bit of googling to find something that fits your requirements. + +@node GDB and OpenOCD +@chapter GDB and OpenOCD +@cindex GDB +OpenOCD complies with the remote gdbserver protocol, and as such can be used +to debug remote targets. +Setting up GDB to work with OpenOCD can involve several components: + +@itemize +@item The OpenOCD server support for GDB may need to be configured. +@xref{gdbconfiguration,,GDB Configuration}. +@item GDB's support for OpenOCD may need configuration, +as shown in this chapter. +@item If you have a GUI environment like Eclipse, +that also will probably need to be configured. +@end itemize + +Of course, the version of GDB you use will need to be one which has +been built to know about the target CPU you're using. It's probably +part of the tool chain you're using. For example, if you are doing +cross-development for ARM on an x86 PC, instead of using the native +x86 @command{gdb} command you might use @command{arm-none-eabi-gdb} +if that's the tool chain used to compile your code. + +@section Connecting to GDB +@cindex Connecting to GDB +Use GDB 6.7 or newer with OpenOCD if you run into trouble. For +instance GDB 6.3 has a known bug that produces bogus memory access +errors, which has since been fixed; see +@url{http://osdir.com/ml/gdb.bugs.discuss/2004-12/msg00018.html} + +OpenOCD can communicate with GDB in two ways: + +@enumerate +@item +A socket (TCP/IP) connection is typically started as follows: +@example +target remote localhost:3333 +@end example +This would cause GDB to connect to the gdbserver on the local pc using port 3333. + +It is also possible to use the GDB extended remote protocol as follows: +@example +target extended-remote localhost:3333 +@end example +@item +A pipe connection is typically started as follows: +@example +target remote | openocd -c "gdb_port pipe; log_output openocd.log" +@end example +This would cause GDB to run OpenOCD and communicate using pipes (stdin/stdout). +Using this method has the advantage of GDB starting/stopping OpenOCD for the debug +session. log_output sends the log output to a file to ensure that the pipe is +not saturated when using higher debug level outputs. +@end enumerate + +To list the available OpenOCD commands type @command{monitor help} on the +GDB command line. + +@section Sample GDB session startup + +With the remote protocol, GDB sessions start a little differently +than they do when you're debugging locally. +Here's an examples showing how to start a debug session with a +small ARM program. +In this case the program was linked to be loaded into SRAM on a Cortex-M3. +Most programs would be written into flash (address 0) and run from there. + +@example +$ arm-none-eabi-gdb example.elf +(gdb) target remote localhost:3333 +Remote debugging using localhost:3333 +... +(gdb) monitor reset halt +... +(gdb) load +Loading section .vectors, size 0x100 lma 0x20000000 +Loading section .text, size 0x5a0 lma 0x20000100 +Loading section .data, size 0x18 lma 0x200006a0 +Start address 0x2000061c, load size 1720 +Transfer rate: 22 KB/sec, 573 bytes/write. +(gdb) continue +Continuing. +... +@end example + +You could then interrupt the GDB session to make the program break, +type @command{where} to show the stack, @command{list} to show the +code around the program counter, @command{step} through code, +set breakpoints or watchpoints, and so on. + +@section Configuring GDB for OpenOCD + +OpenOCD supports the gdb @option{qSupported} packet, this enables information +to be sent by the GDB remote server (i.e. OpenOCD) to GDB. Typical information includes +packet size and the device's memory map. +You do not need to configure the packet size by hand, +and the relevant parts of the memory map should be automatically +set up when you declare (NOR) flash banks. + +However, there are other things which GDB can't currently query. +You may need to set those up by hand. +As OpenOCD starts up, you will often see a line reporting +something like: + +@example +Info : lm3s.cpu: hardware has 6 breakpoints, 4 watchpoints +@end example + +You can pass that information to GDB with these commands: + +@example +set remote hardware-breakpoint-limit 6 +set remote hardware-watchpoint-limit 4 +@end example + +With that particular hardware (Cortex-M3) the hardware breakpoints +only work for code running from flash memory. Most other ARM systems +do not have such restrictions. + +Another example of useful GDB configuration came from a user who +found that single stepping his Cortex-M3 didn't work well with IRQs +and an RTOS until he told GDB to disable the IRQs while stepping: + +@example +define hook-step +mon cortex_m maskisr on +end +define hookpost-step +mon cortex_m maskisr off +end +@end example + +Rather than typing such commands interactively, you may prefer to +save them in a file and have GDB execute them as it starts, perhaps +using a @file{.gdbinit} in your project directory or starting GDB +using @command{gdb -x filename}. + +@section Programming using GDB +@cindex Programming using GDB +@anchor{programmingusinggdb} + +By default the target memory map is sent to GDB. This can be disabled by +the following OpenOCD configuration option: +@example +gdb_memory_map disable +@end example +For this to function correctly a valid flash configuration must also be set +in OpenOCD. For faster performance you should also configure a valid +working area. + +Informing GDB of the memory map of the target will enable GDB to protect any +flash areas of the target and use hardware breakpoints by default. This means +that the OpenOCD option @command{gdb_breakpoint_override} is not required when +using a memory map. @xref{gdbbreakpointoverride,,gdb_breakpoint_override}. + +To view the configured memory map in GDB, use the GDB command @option{info mem} +All other unassigned addresses within GDB are treated as RAM. + +GDB 6.8 and higher set any memory area not in the memory map as inaccessible. +This can be changed to the old behaviour by using the following GDB command +@example +set mem inaccessible-by-default off +@end example + +If @command{gdb_flash_program enable} is also used, GDB will be able to +program any flash memory using the vFlash interface. + +GDB will look at the target memory map when a load command is given, if any +areas to be programmed lie within the target flash area the vFlash packets +will be used. + +If the target needs configuring before GDB programming, an event +script can be executed: +@example +$_TARGETNAME configure -event EVENTNAME BODY +@end example + +To verify any flash programming the GDB command @option{compare-sections} +can be used. +@anchor{usingopenocdsmpwithgdb} +@section Using OpenOCD SMP with GDB +@cindex SMP +For SMP support following GDB serial protocol packet have been defined : +@itemize @bullet +@item j - smp status request +@item J - smp set request +@end itemize + +OpenOCD implements : +@itemize @bullet +@item @option{jc} packet for reading core id displayed by +GDB connection. Reply is @option{XXXXXXXX} (8 hex digits giving core id) or + @option{E01} for target not smp. +@item @option{JcXXXXXXXX} (8 hex digits) packet for setting core id displayed at next GDB continue +(core id -1 is reserved for returning to normal resume mode). Reply @option{E01} +for target not smp or @option{OK} on success. +@end itemize + +Handling of this packet within GDB can be done : +@itemize @bullet +@item by the creation of an internal variable (i.e @option{_core}) by mean +of function allocate_computed_value allowing following GDB command. +@example +set $_core 1 +#Jc01 packet is sent +print $_core +#jc packet is sent and result is affected in $ +@end example + +@item by the usage of GDB maintenance command as described in following example (2 cpus in SMP with +core id 0 and 1 @pxref{definecputargetsworkinginsmp,,Define CPU targets working in SMP}). + +@example +# toggle0 : force display of coreid 0 +define toggle0 +maint packet Jc0 +continue +main packet Jc-1 +end +# toggle1 : force display of coreid 1 +define toggle1 +maint packet Jc1 +continue +main packet Jc-1 +end +@end example +@end itemize + + +@node Tcl Scripting API +@chapter Tcl Scripting API +@cindex Tcl Scripting API +@cindex Tcl scripts +@section API rules + +The commands are stateless. E.g. the telnet command line has a concept +of currently active target, the Tcl API proc's take this sort of state +information as an argument to each proc. + +There are three main types of return values: single value, name value +pair list and lists. + +Name value pair. The proc 'foo' below returns a name/value pair +list. + +@verbatim + + > set foo(me) Duane + > set foo(you) Oyvind + > set foo(mouse) Micky + > set foo(duck) Donald + +If one does this: + + > set foo + +The result is: + + me Duane you Oyvind mouse Micky duck Donald + +Thus, to get the names of the associative array is easy: + + foreach { name value } [set foo] { + puts "Name: $name, Value: $value" + } +@end verbatim + +Lists returned must be relatively small. Otherwise a range +should be passed in to the proc in question. + +@section Internal low-level Commands + +By low-level, the intent is a human would not directly use these commands. + +Low-level commands are (should be) prefixed with "ocd_", e.g. +@command{ocd_flash_banks} +is the low level API upon which @command{flash banks} is implemented. + +@itemize @bullet +@item @b{mem2array} <@var{varname}> <@var{width}> <@var{addr}> <@var{nelems}> + +Read memory and return as a Tcl array for script processing +@item @b{array2mem} <@var{varname}> <@var{width}> <@var{addr}> <@var{nelems}> + +Convert a Tcl array to memory locations and write the values +@item @b{ocd_flash_banks} <@var{driver}> <@var{base}> <@var{size}> <@var{chip_width}> <@var{bus_width}> <@var{target}> [@option{driver options} ...] + +Return information about the flash banks +@end itemize + +OpenOCD commands can consist of two words, e.g. "flash banks". The +@file{startup.tcl} "unknown" proc will translate this into a Tcl proc +called "flash_banks". + +@section OpenOCD specific Global Variables + +Real Tcl has ::tcl_platform(), and platform::identify, and many other +variables. JimTCL, as implemented in OpenOCD creates $ocd_HOSTOS which +holds one of the following values: + +@itemize @bullet +@item @b{cygwin} Running under Cygwin +@item @b{darwin} Darwin (Mac-OS) is the underlying operating sytem. +@item @b{freebsd} Running under FreeBSD +@item @b{linux} Linux is the underlying operating sytem +@item @b{mingw32} Running under MingW32 +@item @b{winxx} Built using Microsoft Visual Studio +@item @b{other} Unknown, none of the above. +@end itemize + +Note: 'winxx' was choosen because today (March-2009) no distinction is made between Win32 and Win64. + +@quotation Note +We should add support for a variable like Tcl variable +@code{tcl_platform(platform)}, it should be called +@code{jim_platform} (because it +is jim, not real tcl). +@end quotation + +@node FAQ +@chapter FAQ +@cindex faq +@enumerate +@anchor{faqrtck} +@item @b{RTCK, also known as: Adaptive Clocking - What is it?} +@cindex RTCK +@cindex adaptive clocking +@* + +In digital circuit design it is often refered to as ``clock +synchronisation'' the JTAG interface uses one clock (TCK or TCLK) +operating at some speed, your CPU target is operating at another. +The two clocks are not synchronised, they are ``asynchronous'' + +In order for the two to work together they must be synchronised +well enough to work; JTAG can't go ten times faster than the CPU, +for example. There are 2 basic options: +@enumerate +@item +Use a special "adaptive clocking" circuit to change the JTAG +clock rate to match what the CPU currently supports. +@item +The JTAG clock must be fixed at some speed that's enough slower than +the CPU clock that all TMS and TDI transitions can be detected. +@end enumerate + +@b{Does this really matter?} For some chips and some situations, this +is a non-issue, like a 500MHz ARM926 with a 5 MHz JTAG link; +the CPU has no difficulty keeping up with JTAG. +Startup sequences are often problematic though, as are other +situations where the CPU clock rate changes (perhaps to save +power). + +For example, Atmel AT91SAM chips start operation from reset with +a 32kHz system clock. Boot firmware may activate the main oscillator +and PLL before switching to a faster clock (perhaps that 500 MHz +ARM926 scenario). +If you're using JTAG to debug that startup sequence, you must slow +the JTAG clock to sometimes 1 to 4kHz. After startup completes, +JTAG can use a faster clock. + +Consider also debugging a 500MHz ARM926 hand held battery powered +device that enters a low power ``deep sleep'' mode, at 32kHz CPU +clock, between keystrokes unless it has work to do. When would +that 5 MHz JTAG clock be usable? + +@b{Solution #1 - A special circuit} + +In order to make use of this, +your CPU, board, and JTAG adapter must all support the RTCK +feature. Not all of them support this; keep reading! + +The RTCK ("Return TCK") signal in some ARM chips is used to help with +this problem. ARM has a good description of the problem described at +this link: @url{http://www.arm.com/support/faqdev/4170.html} [checked +28/nov/2008]. Link title: ``How does the JTAG synchronisation logic +work? / how does adaptive clocking work?''. + +The nice thing about adaptive clocking is that ``battery powered hand +held device example'' - the adaptiveness works perfectly all the +time. One can set a break point or halt the system in the deep power +down code, slow step out until the system speeds up. + +Note that adaptive clocking may also need to work at the board level, +when a board-level scan chain has multiple chips. +Parallel clock voting schemes are good way to implement this, +both within and between chips, and can easily be implemented +with a CPLD. +It's not difficult to have logic fan a module's input TCK signal out +to each TAP in the scan chain, and then wait until each TAP's RTCK comes +back with the right polarity before changing the output RTCK signal. +Texas Instruments makes some clock voting logic available +for free (with no support) in VHDL form; see +@url{http://tiexpressdsp.com/index.php/Adaptive_Clocking} + +@b{Solution #2 - Always works - but may be slower} + +Often this is a perfectly acceptable solution. + +In most simple terms: Often the JTAG clock must be 1/10 to 1/12 of +the target clock speed. But what that ``magic division'' is varies +depending on the chips on your board. +@b{ARM rule of thumb} Most ARM based systems require an 6:1 division; +ARM11 cores use an 8:1 division. +@b{Xilinx rule of thumb} is 1/12 the clock speed. + +Note: most full speed FT2232 based JTAG adapters are limited to a +maximum of 6MHz. The ones using USB high speed chips (FT2232H) +often support faster clock rates (and adaptive clocking). + +You can still debug the 'low power' situations - you just need to +either use a fixed and very slow JTAG clock rate ... or else +manually adjust the clock speed at every step. (Adjusting is painful +and tedious, and is not always practical.) + +It is however easy to ``code your way around it'' - i.e.: Cheat a little, +have a special debug mode in your application that does a ``high power +sleep''. If you are careful - 98% of your problems can be debugged +this way. + +Note that on ARM you may need to avoid using the @emph{wait for interrupt} +operation in your idle loops even if you don't otherwise change the CPU +clock rate. +That operation gates the CPU clock, and thus the JTAG clock; which +prevents JTAG access. One consequence is not being able to @command{halt} +cores which are executing that @emph{wait for interrupt} operation. + +To set the JTAG frequency use the command: + +@example +# Example: 1.234MHz +adapter_khz 1234 +@end example + + +@item @b{Win32 Pathnames} Why don't backslashes work in Windows paths? + +OpenOCD uses Tcl and a backslash is an escape char. Use @{ and @} +around Windows filenames. + +@example +> echo \a + +> echo @{\a@} +\a +> echo "\a" + +> +@end example + + +@item @b{Missing: cygwin1.dll} OpenOCD complains about a missing cygwin1.dll. + +Make sure you have Cygwin installed, or at least a version of OpenOCD that +claims to come with all the necessary DLLs. When using Cygwin, try launching +OpenOCD from the Cygwin shell. + +@item @b{Breakpoint Issue} I'm trying to set a breakpoint using GDB (or a frontend like Insight or +Eclipse), but OpenOCD complains that "Info: arm7_9_common.c:213 +arm7_9_add_breakpoint(): sw breakpoint requested, but software breakpoints not enabled". + +GDB issues software breakpoints when a normal breakpoint is requested, or to implement +source-line single-stepping. On ARMv4T systems, like ARM7TDMI, ARM720T or ARM920T, +software breakpoints consume one of the two available hardware breakpoints. + +@item @b{LPC2000 Flash} When erasing or writing LPC2000 on-chip flash, the operation fails at random. + +Make sure the core frequency specified in the @option{flash lpc2000} line matches the +clock at the time you're programming the flash. If you've specified the crystal's +frequency, make sure the PLL is disabled. If you've specified the full core speed +(e.g. 60MHz), make sure the PLL is enabled. + +@item @b{Amontec Chameleon} When debugging using an Amontec Chameleon in its JTAG Accelerator configuration, +I keep getting "Error: amt_jtagaccel.c:184 amt_wait_scan_busy(): amt_jtagaccel timed +out while waiting for end of scan, rtck was disabled". + +Make sure your PC's parallel port operates in EPP mode. You might have to try several +settings in your PC BIOS (ECP, EPP, and different versions of those). + +@item @b{Data Aborts} When debugging with OpenOCD and GDB (plain GDB, Insight, or Eclipse), +I get lots of "Error: arm7_9_common.c:1771 arm7_9_read_memory(): +memory read caused data abort". + +The errors are non-fatal, and are the result of GDB trying to trace stack frames +beyond the last valid frame. It might be possible to prevent this by setting up +a proper "initial" stack frame, if you happen to know what exactly has to +be done, feel free to add this here. + +@b{Simple:} In your startup code - push 8 registers of zeros onto the +stack before calling main(). What GDB is doing is ``climbing'' the run +time stack by reading various values on the stack using the standard +call frame for the target. GDB keeps going - until one of 2 things +happen @b{#1} an invalid frame is found, or @b{#2} some huge number of +stackframes have been processed. By pushing zeros on the stack, GDB +gracefully stops. + +@b{Debugging Interrupt Service Routines} - In your ISR before you call +your C code, do the same - artifically push some zeros onto the stack, +remember to pop them off when the ISR is done. + +@b{Also note:} If you have a multi-threaded operating system, they +often do not @b{in the intrest of saving memory} waste these few +bytes. Painful... + + +@item @b{JTAG Reset Config} I get the following message in the OpenOCD console (or log file): +"Warning: arm7_9_common.c:679 arm7_9_assert_reset(): srst resets test logic, too". + +This warning doesn't indicate any serious problem, as long as you don't want to +debug your core right out of reset. Your .cfg file specified @option{jtag_reset +trst_and_srst srst_pulls_trst} to tell OpenOCD that either your board, +your debugger or your target uC (e.g. LPC2000) can't assert the two reset signals +independently. With this setup, it's not possible to halt the core right out of +reset, everything else should work fine. + +@item @b{USB Power} When using OpenOCD in conjunction with Amontec JTAGkey and the Yagarto +toolchain (Eclipse, arm-elf-gcc, arm-elf-gdb), the debugging seems to be +unstable. When single-stepping over large blocks of code, GDB and OpenOCD +quit with an error message. Is there a stability issue with OpenOCD? + +No, this is not a stability issue concerning OpenOCD. Most users have solved +this issue by simply using a self-powered USB hub, which they connect their +Amontec JTAGkey to. Apparently, some computers do not provide a USB power +supply stable enough for the Amontec JTAGkey to be operated. + +@b{Laptops running on battery have this problem too...} + +@item @b{USB Power} When using the Amontec JTAGkey, sometimes OpenOCD crashes with the +following error messages: "Error: ft2232.c:201 ft2232_read(): FT_Read returned: +4" and "Error: ft2232.c:365 ft2232_send_and_recv(): couldn't read from FT2232". +What does that mean and what might be the reason for this? + +First of all, the reason might be the USB power supply. Try using a self-powered +hub instead of a direct connection to your computer. Secondly, the error code 4 +corresponds to an FT_IO_ERROR, which means that the driver for the FTDI USB +chip ran into some sort of error - this points us to a USB problem. + +@item @b{GDB Disconnects} When using the Amontec JTAGkey, sometimes OpenOCD crashes with the following +error message: "Error: gdb_server.c:101 gdb_get_char(): read: 10054". +What does that mean and what might be the reason for this? + +Error code 10054 corresponds to WSAECONNRESET, which means that the debugger (GDB) +has closed the connection to OpenOCD. This might be a GDB issue. + +@item @b{LPC2000 Flash} In the configuration file in the section where flash device configurations +are described, there is a parameter for specifying the clock frequency +for LPC2000 internal flash devices (e.g. @option{flash bank $_FLASHNAME lpc2000 +0x0 0x40000 0 0 $_TARGETNAME lpc2000_v1 14746 calc_checksum}), which must be +specified in kilohertz. However, I do have a quartz crystal of a +frequency that contains fractions of kilohertz (e.g. 14,745,600 Hz, +i.e. 14,745.600 kHz). Is it possible to specify real numbers for the +clock frequency? + +No. The clock frequency specified here must be given as an integral number. +However, this clock frequency is used by the In-Application-Programming (IAP) +routines of the LPC2000 family only, which seems to be very tolerant concerning +the given clock frequency, so a slight difference between the specified clock +frequency and the actual clock frequency will not cause any trouble. + +@item @b{Command Order} Do I have to keep a specific order for the commands in the configuration file? + +Well, yes and no. Commands can be given in arbitrary order, yet the +devices listed for the JTAG scan chain must be given in the right +order (jtag newdevice), with the device closest to the TDO-Pin being +listed first. In general, whenever objects of the same type exist +which require an index number, then these objects must be given in the +right order (jtag newtap, targets and flash banks - a target +references a jtag newtap and a flash bank references a target). + +You can use the ``scan_chain'' command to verify and display the tap order. + +Also, some commands can't execute until after @command{init} has been +processed. Such commands include @command{nand probe} and everything +else that needs to write to controller registers, perhaps for setting +up DRAM and loading it with code. + +@anchor{faqtaporder} +@item @b{JTAG TAP Order} Do I have to declare the TAPS in some +particular order? + +Yes; whenever you have more than one, you must declare them in +the same order used by the hardware. + +Many newer devices have multiple JTAG TAPs. For example: ST +Microsystems STM32 chips have two TAPs, a ``boundary scan TAP'' and +``Cortex-M3'' TAP. Example: The STM32 reference manual, Document ID: +RM0008, Section 26.5, Figure 259, page 651/681, the ``TDI'' pin is +connected to the boundary scan TAP, which then connects to the +Cortex-M3 TAP, which then connects to the TDO pin. + +Thus, the proper order for the STM32 chip is: (1) The Cortex-M3, then +(2) The boundary scan TAP. If your board includes an additional JTAG +chip in the scan chain (for example a Xilinx CPLD or FPGA) you could +place it before or after the STM32 chip in the chain. For example: + +@itemize @bullet +@item OpenOCD_TDI(output) -> STM32 TDI Pin (BS Input) +@item STM32 BS TDO (output) -> STM32 Cortex-M3 TDI (input) +@item STM32 Cortex-M3 TDO (output) -> SM32 TDO Pin +@item STM32 TDO Pin (output) -> Xilinx TDI Pin (input) +@item Xilinx TDO Pin -> OpenOCD TDO (input) +@end itemize + +The ``jtag device'' commands would thus be in the order shown below. Note: + +@itemize @bullet +@item jtag newtap Xilinx tap -irlen ... +@item jtag newtap stm32 cpu -irlen ... +@item jtag newtap stm32 bs -irlen ... +@item # Create the debug target and say where it is +@item target create stm32.cpu -chain-position stm32.cpu ... +@end itemize + + +@item @b{SYSCOMP} Sometimes my debugging session terminates with an error. When I look into the +log file, I can see these error messages: Error: arm7_9_common.c:561 +arm7_9_execute_sys_speed(): timeout waiting for SYSCOMP + +TODO. + +@end enumerate + +@node Tcl Crash Course +@chapter Tcl Crash Course +@cindex Tcl + +Not everyone knows Tcl - this is not intended to be a replacement for +learning Tcl, the intent of this chapter is to give you some idea of +how the Tcl scripts work. + +This chapter is written with two audiences in mind. (1) OpenOCD users +who need to understand a bit more of how Jim-Tcl works so they can do +something useful, and (2) those that want to add a new command to +OpenOCD. + +@section Tcl Rule #1 +There is a famous joke, it goes like this: +@enumerate +@item Rule #1: The wife is always correct +@item Rule #2: If you think otherwise, See Rule #1 +@end enumerate + +The Tcl equal is this: + +@enumerate +@item Rule #1: Everything is a string +@item Rule #2: If you think otherwise, See Rule #1 +@end enumerate + +As in the famous joke, the consequences of Rule #1 are profound. Once +you understand Rule #1, you will understand Tcl. + +@section Tcl Rule #1b +There is a second pair of rules. +@enumerate +@item Rule #1: Control flow does not exist. Only commands +@* For example: the classic FOR loop or IF statement is not a control +flow item, they are commands, there is no such thing as control flow +in Tcl. +@item Rule #2: If you think otherwise, See Rule #1 +@* Actually what happens is this: There are commands that by +convention, act like control flow key words in other languages. One of +those commands is the word ``for'', another command is ``if''. +@end enumerate + +@section Per Rule #1 - All Results are strings +Every Tcl command results in a string. The word ``result'' is used +deliberatly. No result is just an empty string. Remember: @i{Rule #1 - +Everything is a string} + +@section Tcl Quoting Operators +In life of a Tcl script, there are two important periods of time, the +difference is subtle. +@enumerate +@item Parse Time +@item Evaluation Time +@end enumerate + +The two key items here are how ``quoted things'' work in Tcl. Tcl has +three primary quoting constructs, the [square-brackets] the +@{curly-braces@} and ``double-quotes'' + +By now you should know $VARIABLES always start with a $DOLLAR +sign. BTW: To set a variable, you actually use the command ``set'', as +in ``set VARNAME VALUE'' much like the ancient BASIC langauge ``let x += 1'' statement, but without the equal sign. + +@itemize @bullet +@item @b{[square-brackets]} +@* @b{[square-brackets]} are command substitutions. It operates much +like Unix Shell `back-ticks`. The result of a [square-bracket] +operation is exactly 1 string. @i{Remember Rule #1 - Everything is a +string}. These two statements are roughly identical: +@example + # bash example + X=`date` + echo "The Date is: $X" + # Tcl example + set X [date] + puts "The Date is: $X" +@end example +@item @b{``double-quoted-things''} +@* @b{``double-quoted-things''} are just simply quoted +text. $VARIABLES and [square-brackets] are expanded in place - the +result however is exactly 1 string. @i{Remember Rule #1 - Everything +is a string} +@example + set x "Dinner" + puts "It is now \"[date]\", $x is in 1 hour" +@end example +@item @b{@{Curly-Braces@}} +@*@b{@{Curly-Braces@}} are magic: $VARIABLES and [square-brackets] are +parsed, but are NOT expanded or executed. @{Curly-Braces@} are like +'single-quote' operators in BASH shell scripts, with the added +feature: @{curly-braces@} can be nested, single quotes can not. @{@{@{this is +nested 3 times@}@}@} NOTE: [date] is a bad example; +at this writing, Jim/OpenOCD does not have a date command. +@end itemize + +@section Consequences of Rule 1/2/3/4 + +The consequences of Rule 1 are profound. + +@subsection Tokenisation & Execution. + +Of course, whitespace, blank lines and #comment lines are handled in +the normal way. + +As a script is parsed, each (multi) line in the script file is +tokenised and according to the quoting rules. After tokenisation, that +line is immedatly executed. + +Multi line statements end with one or more ``still-open'' +@{curly-braces@} which - eventually - closes a few lines later. + +@subsection Command Execution + +Remember earlier: There are no ``control flow'' +statements in Tcl. Instead there are COMMANDS that simply act like +control flow operators. + +Commands are executed like this: + +@enumerate +@item Parse the next line into (argc) and (argv[]). +@item Look up (argv[0]) in a table and call its function. +@item Repeat until End Of File. +@end enumerate + +It sort of works like this: +@example + for(;;)@{ + ReadAndParse( &argc, &argv ); + + cmdPtr = LookupCommand( argv[0] ); + + (*cmdPtr->Execute)( argc, argv ); + @} +@end example + +When the command ``proc'' is parsed (which creates a procedure +function) it gets 3 parameters on the command line. @b{1} the name of +the proc (function), @b{2} the list of parameters, and @b{3} the body +of the function. Not the choice of words: LIST and BODY. The PROC +command stores these items in a table somewhere so it can be found by +``LookupCommand()'' + +@subsection The FOR command + +The most interesting command to look at is the FOR command. In Tcl, +the FOR command is normally implemented in C. Remember, FOR is a +command just like any other command. + +When the ascii text containing the FOR command is parsed, the parser +produces 5 parameter strings, @i{(If in doubt: Refer to Rule #1)} they +are: + +@enumerate 0 +@item The ascii text 'for' +@item The start text +@item The test expression +@item The next text +@item The body text +@end enumerate + +Sort of reminds you of ``main( int argc, char **argv )'' does it not? +Remember @i{Rule #1 - Everything is a string.} The key point is this: +Often many of those parameters are in @{curly-braces@} - thus the +variables inside are not expanded or replaced until later. + +Remember that every Tcl command looks like the classic ``main( argc, +argv )'' function in C. In JimTCL - they actually look like this: + +@example +int +MyCommand( Jim_Interp *interp, + int *argc, + Jim_Obj * const *argvs ); +@end example + +Real Tcl is nearly identical. Although the newer versions have +introduced a byte-code parser and intepreter, but at the core, it +still operates in the same basic way. + +@subsection FOR command implementation + +To understand Tcl it is perhaps most helpful to see the FOR +command. Remember, it is a COMMAND not a control flow structure. + +In Tcl there are two underlying C helper functions. + +Remember Rule #1 - You are a string. + +The @b{first} helper parses and executes commands found in an ascii +string. Commands can be seperated by semicolons, or newlines. While +parsing, variables are expanded via the quoting rules. + +The @b{second} helper evaluates an ascii string as a numerical +expression and returns a value. + +Here is an example of how the @b{FOR} command could be +implemented. The pseudo code below does not show error handling. +@example +void Execute_AsciiString( void *interp, const char *string ); + +int Evaluate_AsciiExpression( void *interp, const char *string ); + +int +MyForCommand( void *interp, + int argc, + char **argv ) +@{ + if( argc != 5 )@{ + SetResult( interp, "WRONG number of parameters"); + return ERROR; + @} + + // argv[0] = the ascii string just like C + + // Execute the start statement. + Execute_AsciiString( interp, argv[1] ); + + // Top of loop test + for(;;)@{ + i = Evaluate_AsciiExpression(interp, argv[2]); + if( i == 0 ) + break; + + // Execute the body + Execute_AsciiString( interp, argv[3] ); + + // Execute the LOOP part + Execute_AsciiString( interp, argv[4] ); + @} + + // Return no error + SetResult( interp, "" ); + return SUCCESS; +@} +@end example + +Every other command IF, WHILE, FORMAT, PUTS, EXPR, everything works +in the same basic way. + +@section OpenOCD Tcl Usage + +@subsection source and find commands +@b{Where:} In many configuration files +@* Example: @b{ source [find FILENAME] } +@*Remember the parsing rules +@enumerate +@item The @command{find} command is in square brackets, +and is executed with the parameter FILENAME. It should find and return +the full path to a file with that name; it uses an internal search path. +The RESULT is a string, which is substituted into the command line in +place of the bracketed @command{find} command. +(Don't try to use a FILENAME which includes the "#" character. +That character begins Tcl comments.) +@item The @command{source} command is executed with the resulting filename; +it reads a file and executes as a script. +@end enumerate +@subsection format command +@b{Where:} Generally occurs in numerous places. +@* Tcl has no command like @b{printf()}, instead it has @b{format}, which is really more like +@b{sprintf()}. +@b{Example} +@example + set x 6 + set y 7 + puts [format "The answer: %d" [expr $x * $y]] +@end example +@enumerate +@item The SET command creates 2 variables, X and Y. +@item The double [nested] EXPR command performs math +@* The EXPR command produces numerical result as a string. +@* Refer to Rule #1 +@item The format command is executed, producing a single string +@* Refer to Rule #1. +@item The PUTS command outputs the text. +@end enumerate +@subsection Body or Inlined Text +@b{Where:} Various TARGET scripts. +@example +#1 Good + proc someproc @{@} @{ + ... multiple lines of stuff ... + @} + $_TARGETNAME configure -event FOO someproc +#2 Good - no variables + $_TARGETNAME confgure -event foo "this ; that;" +#3 Good Curly Braces + $_TARGETNAME configure -event FOO @{ + puts "Time: [date]" + @} +#4 DANGER DANGER DANGER + $_TARGETNAME configure -event foo "puts \"Time: [date]\"" +@end example +@enumerate +@item The $_TARGETNAME is an OpenOCD variable convention. +@*@b{$_TARGETNAME} represents the last target created, the value changes +each time a new target is created. Remember the parsing rules. When +the ascii text is parsed, the @b{$_TARGETNAME} becomes a simple string, +the name of the target which happens to be a TARGET (object) +command. +@item The 2nd parameter to the @option{-event} parameter is a TCBODY +@*There are 4 examples: +@enumerate +@item The TCLBODY is a simple string that happens to be a proc name +@item The TCLBODY is several simple commands seperated by semicolons +@item The TCLBODY is a multi-line @{curly-brace@} quoted string +@item The TCLBODY is a string with variables that get expanded. +@end enumerate + +In the end, when the target event FOO occurs the TCLBODY is +evaluated. Method @b{#1} and @b{#2} are functionally identical. For +Method @b{#3} and @b{#4} it is more interesting. What is the TCLBODY? + +Remember the parsing rules. In case #3, @{curly-braces@} mean the +$VARS and [square-brackets] are expanded later, when the EVENT occurs, +and the text is evaluated. In case #4, they are replaced before the +``Target Object Command'' is executed. This occurs at the same time +$_TARGETNAME is replaced. In case #4 the date will never +change. @{BTW: [date] is a bad example; at this writing, +Jim/OpenOCD does not have a date command@} +@end enumerate +@subsection Global Variables +@b{Where:} You might discover this when writing your own procs @* In +simple terms: Inside a PROC, if you need to access a global variable +you must say so. See also ``upvar''. Example: +@example +proc myproc @{ @} @{ + set y 0 #Local variable Y + global x #Global variable X + puts [format "X=%d, Y=%d" $x $y] +@} +@end example +@section Other Tcl Hacks +@b{Dynamic variable creation} +@example +# Dynamically create a bunch of variables. +for @{ set x 0 @} @{ $x < 32 @} @{ set x [expr $x + 1]@} @{ + # Create var name + set vn [format "BIT%d" $x] + # Make it a global + global $vn + # Set it. + set $vn [expr (1 << $x)] +@} +@end example +@b{Dynamic proc/command creation} +@example +# One "X" function - 5 uart functions. +foreach who @{A B C D E@} + proc [format "show_uart%c" $who] @{ @} "show_UARTx $who" +@} +@end example + +@include fdl.texi + +@node OpenOCD Concept Index +@comment DO NOT use the plain word ``Index'', reason: CYGWIN filename +@comment case issue with ``Index.html'' and ``index.html'' +@comment Occurs when creating ``--html --no-split'' output +@comment This fix is based on: http://sourceware.org/ml/binutils/2006-05/msg00215.html +@unnumbered OpenOCD Concept Index + +@printindex cp + +@node Command and Driver Index +@unnumbered Command and Driver Index +@printindex fn + +@bye diff --git a/debuggers/openocd/doc/stamp-vti b/debuggers/openocd/doc/stamp-vti new file mode 100644 index 00000000..47f311b3 --- /dev/null +++ b/debuggers/openocd/doc/stamp-vti @@ -0,0 +1,4 @@ +@set UPDATED 4 May 2013 +@set UPDATED-MONTH May 2013 +@set EDITION 0.7.0 +@set VERSION 0.7.0 diff --git a/debuggers/openocd/doc/texinfo.tex b/debuggers/openocd/doc/texinfo.tex new file mode 100644 index 00000000..b5f31415 --- /dev/null +++ b/debuggers/openocd/doc/texinfo.tex @@ -0,0 +1,10074 @@ +% texinfo.tex -- TeX macros to handle Texinfo files. +% +% Load plain if necessary, i.e., if running under initex. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi +% +\def\texinfoversion{2012-11-08.11} +% +% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, +% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +% 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +% +% This texinfo.tex file 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 3 of the +% License, or (at your option) any later version. +% +% This texinfo.tex file 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, see . +% +% As a special exception, when this file is read by TeX when processing +% a Texinfo source document, you may use the result without +% restriction. (This has been our intent since Texinfo was invented.) +% +% Please try the latest version of texinfo.tex before submitting bug +% reports; you can get the latest version from: +% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or +% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or +% http://www.gnu.org/software/texinfo/ (the Texinfo home page) +% The texinfo.tex in any given distribution could well be out +% of date, so if that's what you're using, please check. +% +% Send bug reports to bug-texinfo@gnu.org. Please include including a +% complete document in each bug report with which we can reproduce the +% problem. Patches are, of course, greatly appreciated. +% +% To process a Texinfo manual with TeX, it's most reliable to use the +% texi2dvi shell script that comes with the distribution. For a simple +% manual foo.texi, however, you can get away with this: +% tex foo.texi +% texindex foo.?? +% tex foo.texi +% tex foo.texi +% dvips foo.dvi -o # or whatever; this makes foo.ps. +% The extra TeX runs get the cross-reference information correct. +% Sometimes one run after texindex suffices, and sometimes you need more +% than two; texi2dvi does it as many times as necessary. +% +% It is possible to adapt texinfo.tex for other languages, to some +% extent. You can get the existing language-specific files from the +% full Texinfo distribution. +% +% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. + + +\message{Loading texinfo [version \texinfoversion]:} + +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}% + \catcode`+=\active \catcode`\_=\active} + +\chardef\other=12 + +% We never want plain's \outer definition of \+ in Texinfo. +% For @tex, we can use \tabalign. +\let\+ = \relax + +% Save some plain tex macros whose names we will redefine. +\let\ptexb=\b +\let\ptexbullet=\bullet +\let\ptexc=\c +\let\ptexcomma=\, +\let\ptexdot=\. +\let\ptexdots=\dots +\let\ptexend=\end +\let\ptexequiv=\equiv +\let\ptexexclam=\! +\let\ptexfootnote=\footnote +\let\ptexgtr=> +\let\ptexhat=^ +\let\ptexi=\i +\let\ptexindent=\indent +\let\ptexinsert=\insert +\let\ptexlbrace=\{ +\let\ptexless=< +\let\ptexnewwrite\newwrite +\let\ptexnoindent=\noindent +\let\ptexplus=+ +\let\ptexraggedright=\raggedright +\let\ptexrbrace=\} +\let\ptexslash=\/ +\let\ptexstar=\* +\let\ptext=\t +\let\ptextop=\top +{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode + +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% Use TeX 3.0's \inputlineno to get the line number, for better error +% messages, but if we're using an old version of TeX, don't do anything. +% +\ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Pre-3.0. +\else + \def\linenumber{l.\the\inputlineno:\space} +\fi + +% Set up fixed words for English if not already set. +\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi +\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +\ifx\putworderror\undefined \gdef\putworderror{error}\fi +\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi +\ifx\putwordin\undefined \gdef\putwordin{in}\fi +\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi +\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi +\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi +\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi +\ifx\putwordof\undefined \gdef\putwordof{of}\fi +\ifx\putwordon\undefined \gdef\putwordon{on}\fi +\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi +\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi +\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi +\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi +\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi +\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi +\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi +% +\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi +\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi +\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi +\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi +\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi +\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi +\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi +\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi +\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi +\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi +\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi +\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi +% +\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi +\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi +\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi +\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi +\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi + +% Since the category of space is not known, we have to be careful. +\chardef\spacecat = 10 +\def\spaceisspace{\catcode`\ =\spacecat} + +% sometimes characters are active, so we need control sequences. +\chardef\ampChar = `\& +\chardef\colonChar = `\: +\chardef\commaChar = `\, +\chardef\dashChar = `\- +\chardef\dotChar = `\. +\chardef\exclamChar= `\! +\chardef\hashChar = `\# +\chardef\lquoteChar= `\` +\chardef\questChar = `\? +\chardef\rquoteChar= `\' +\chardef\semiChar = `\; +\chardef\slashChar = `\/ +\chardef\underChar = `\_ + +% Ignore a token. +% +\def\gobble#1{} + +% The following is used inside several \edef's. +\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname} + +% Hyphenation fixes. +\hyphenation{ + Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script + ap-pen-dix bit-map bit-maps + data-base data-bases eshell fall-ing half-way long-est man-u-script + man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm + par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces + spell-ing spell-ings + stand-alone strong-est time-stamp time-stamps which-ever white-space + wide-spread wrap-around +} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen\bindingoffset +\newdimen\normaloffset +\newdimen\pagewidth \newdimen\pageheight + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt } + +% Sometimes it is convenient to have everything in the transcript file +% and nothing on the terminal. We don't just call \tracingall here, +% since that produces some useless output on the terminal. We also make +% some effort to order the tracing commands to reduce output in the log +% file; cf. trace.sty in LaTeX. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\def\loggingall{% + \tracingstats2 + \tracingpages1 + \tracinglostchars2 % 2 gives us more in etex + \tracingparagraphs1 + \tracingoutput1 + \tracingmacros2 + \tracingrestores1 + \showboxbreadth\maxdimen \showboxdepth\maxdimen + \ifx\eTeXversion\thisisundefined\else % etex gives us more logging + \tracingscantokens1 + \tracingifs1 + \tracinggroups1 + \tracingnesting2 + \tracingassigns1 + \fi + \tracingcommands3 % 3 gives us more in etex + \errorcontextlines16 +}% + +% @errormsg{MSG}. Do the index-like expansions on MSG, but if things +% aren't perfect, it's not the end of the world, being an error message, +% after all. +% +\def\errormsg{\begingroup \indexnofonts \doerrormsg} +\def\doerrormsg#1{\errmessage{#1}} + +% add check for \lastpenalty to plain's definitions. If the last thing +% we did was a \nobreak, we don't want to insert more space. +% +\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount + \removelastskip\penalty-50\smallskip\fi\fi} +\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount + \removelastskip\penalty-100\medskip\fi\fi} +\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount + \removelastskip\penalty-200\bigskip\fi\fi} + +% Do @cropmarks to get crop marks. +% +\newif\ifcropmarks +\let\cropmarks = \cropmarkstrue +% +% Dimensions to add cropmarks at corners. +% Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines +\newdimen\cornerlong \cornerlong=1pc +\newdimen\cornerthick \cornerthick=.3pt +\newdimen\topandbottommargin \topandbottommargin=.75in + +% Output a mark which sets \thischapter, \thissection and \thiscolor. +% We dump everything together because we only have one kind of mark. +% This works because we only use \botmark / \topmark, not \firstmark. +% +% A mark contains a subexpression of the \ifcase ... \fi construct. +% \get*marks macros below extract the needed part using \ifcase. +% +% Another complication is to let the user choose whether \thischapter +% (\thissection) refers to the chapter (section) in effect at the top +% of a page, or that at the bottom of a page. The solution is +% described on page 260 of The TeXbook. It involves outputting two +% marks for the sectioning macros, one before the section break, and +% one after. I won't pretend I can describe this better than DEK... +\def\domark{% + \toks0=\expandafter{\lastchapterdefs}% + \toks2=\expandafter{\lastsectiondefs}% + \toks4=\expandafter{\prevchapterdefs}% + \toks6=\expandafter{\prevsectiondefs}% + \toks8=\expandafter{\lastcolordefs}% + \mark{% + \the\toks0 \the\toks2 + \noexpand\or \the\toks4 \the\toks6 + \noexpand\else \the\toks8 + }% +} +% \topmark doesn't work for the very first chapter (after the title +% page or the contents), so we use \firstmark there -- this gets us +% the mark with the chapter defs, unless the user sneaks in, e.g., +% @setcolor (or @url, or @link, etc.) between @contents and the very +% first @chapter. +\def\gettopheadingmarks{% + \ifcase0\topmark\fi + \ifx\thischapter\empty \ifcase0\firstmark\fi \fi +} +\def\getbottomheadingmarks{\ifcase1\botmark\fi} +\def\getcolormarks{\ifcase2\topmark\fi} + +% Avoid "undefined control sequence" errors. +\def\lastchapterdefs{} +\def\lastsectiondefs{} +\def\prevchapterdefs{} +\def\prevsectiondefs{} +\def\lastcolordefs{} + +% Main output routine. +\chardef\PAGE = 255 +\output = {\onepageout{\pagecontents\PAGE}} + +\newbox\headlinebox +\newbox\footlinebox + +% \onepageout takes a vbox as an argument. Note that \pagecontents +% does insertions, but you have to call it yourself. +\def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi + \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% + \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi + \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% + % + {% + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + % We don't want .vr (or whatever) entries like this: + % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}} + % "\acronym" won't work when it's read back in; + % it needs to be + % {\code {{\tt \backslashcurfont }acronym} + \shipout\vbox{% + % Do this early so pdf references go to the beginning of the page. + \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi + % + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \vskip-\topandbottommargin + \vtop to0pt{% + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vss}% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingyyy.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 24pt + \unvbox\footlinebox + \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \vbox to0pt{\vss + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + }% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \indexdummies + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi +} + +\newinsert\margin \dimen\margin=\maxdimen + +\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +\dimen@=\dp#1\relax \unvbox#1\relax +\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +} + +% Here are the rules for the cropmarks. Note that they are +% offset so that the space between them is truly \outerhsize or \outervsize +% (P. A. MacKay, 12 November, 1986) +% +\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +\def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +\def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + +% Parse an argument, then pass it to #1. The argument is the rest of +% the input line (except we remove a trailing comment). #1 should be a +% macro which expects an ordinary undelimited TeX argument. +% +\def\parsearg{\parseargusing{}} +\def\parseargusing#1#2{% + \def\argtorun{#2}% + \begingroup + \obeylines + \spaceisspace + #1% + \parseargline\empty% Insert the \empty token, see \finishparsearg below. +} + +{\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + \argremovecomment #1\comment\ArgTerm% + }% +} + +% First remove any @comment, then any @c comment. +\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} +\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} + +% Each occurrence of `\^^M' or `\^^M' is replaced by a single space. +% +% \argremovec might leave us with trailing space, e.g., +% @end itemize @c foo +% This space token undergoes the same procedure and is eventually removed +% by \finishparsearg. +% +\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M} +\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M} +\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{% + \def\temp{#3}% + \ifx\temp\empty + % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp: + \let\temp\finishparsearg + \else + \let\temp\argcheckspaces + \fi + % Put the space token in: + \temp#1 #3\ArgTerm +} + +% If a _delimited_ argument is enclosed in braces, they get stripped; so +% to get _exactly_ the rest of the line, we had to prevent such situation. +% We prepended an \empty token at the very beginning and we expand it now, +% just before passing the control to \argtorun. +% (Similarly, we have to think about #3 of \argcheckspacesY above: it is +% either the null string, or it ends with \^^M---thus there is no danger +% that a pair of braces would be stripped. +% +% But first, we have to remove the trailing space token. +% +\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} + +% \parseargdef\foo{...} +% is roughly equivalent to +% \def\foo{\parsearg\Xfoo} +% \def\Xfoo#1{...} +% +% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my +% favourite TeX trick. --kasal, 16nov03 + +\def\parseargdef#1{% + \expandafter \doparseargdef \csname\string#1\endcsname #1% +} +\def\doparseargdef#1#2{% + \def#2{\parsearg#1}% + \def#1##1% +} + +% Several utility definitions with active space: +{ + \obeyspaces + \gdef\obeyedspace{ } + + % Make each space character in the input produce a normal interword + % space in the output. Don't allow a line break at this space, as this + % is used only in environments like @example, where each line of input + % should produce a line of output anyway. + % + \gdef\sepspaces{\obeyspaces\let =\tie} + + % If an index command is used in an @example environment, any spaces + % therein should become regular spaces in the raw index file, not the + % expansion of \tie (\leavevmode \penalty \@M \ ). + \gdef\unsepspaces{\let =\space} +} + + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +% Define the framework for environments in texinfo.tex. It's used like this: +% +% \envdef\foo{...} +% \def\Efoo{...} +% +% It's the responsibility of \envdef to insert \begingroup before the +% actual body; @end closes the group after calling \Efoo. \envdef also +% defines \thisenv, so the current environment is known; @end checks +% whether the environment name matches. The \checkenv macro can also be +% used to check whether the current environment is the one expected. +% +% Non-false conditionals (@iftex, @ifset) don't fit into this, so they +% are not treated as environments; they don't open a group. (The +% implementation of @end takes care not to call \endgroup in this +% special case.) + + +% At run-time, environments start with this: +\def\startenvironment#1{\begingroup\def\thisenv{#1}} +% initialize +\let\thisenv\empty + +% ... but they get defined via ``\envdef\foo{...}'': +\long\def\envdef#1#2{\def#1{\startenvironment#1#2}} +\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}} + +% Check whether we're in the right environment: +\def\checkenv#1{% + \def\temp{#1}% + \ifx\thisenv\temp + \else + \badenverr + \fi +} + +% Environment mismatch, #1 expected: +\def\badenverr{% + \errhelp = \EMsimple + \errmessage{This command can appear only \inenvironment\temp, + not \inenvironment\thisenv}% +} +\def\inenvironment#1{% + \ifx#1\empty + outside of any environment% + \else + in environment \expandafter\string#1% + \fi +} + +% @end foo executes the definition of \Efoo. +% But first, it executes a specialized version of \checkenv +% +\parseargdef\end{% + \if 1\csname iscond.#1\endcsname + \else + % The general wording of \badenverr may not be ideal. + \expandafter\checkenv\csname#1\endcsname + \csname E#1\endcsname + \endgroup + \fi +} + +\newhelp\EMsimple{Press RETURN to continue.} + + +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\unskip\hfil\break\hbox{}\ignorespaces} + +% @/ allows a line break. +\let\/=\allowbreak + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=\endofsentencespacefactor\space} + +% @! is an end-of-sentence bang. +\def\!{!\spacefactor=\endofsentencespacefactor\space} + +% @? is an end-of-sentence query. +\def\?{?\spacefactor=\endofsentencespacefactor\space} + +% @frenchspacing on|off says whether to put extra space after punctuation. +% +\def\onword{on} +\def\offword{off} +% +\parseargdef\frenchspacing{% + \def\temp{#1}% + \ifx\temp\onword \plainfrenchspacing + \else\ifx\temp\offword \plainnonfrenchspacing + \else + \errhelp = \EMsimple + \errmessage{Unknown @frenchspacing option `\temp', must be on|off}% + \fi\fi +} + +% @w prevents a word break. Without the \leavevmode, @w at the +% beginning of a paragraph, when TeX is still in vertical mode, would +% produce a whole line of output instead of starting the paragraph. +\def\w#1{\leavevmode\hbox{#1}} + +% @group ... @end group forces ... to be all on one page, by enclosing +% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +% to keep its height that of a normal line. According to the rules for +% \topskip (p.114 of the TeXbook), the glue inserted is +% max (\topskip - \ht (first item), 0). If that height is large, +% therefore, no glue is inserted, and the space between the headline and +% the text is small, which looks bad. +% +% Another complication is that the group might be very large. This can +% cause the glue on the previous page to be unduly stretched, because it +% does not have much material. In this case, it's better to add an +% explicit \vfill so that the extra space is at the bottom. The +% threshold for doing this is if the group is more than \vfilllimit +% percent of a page (\vfilllimit can be changed inside of @tex). +% +\newbox\groupbox +\def\vfilllimit{0.7} +% +\envdef\group{% + \ifnum\catcode`\^^M=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + \startsavinginserts + % + \setbox\groupbox = \vtop\bgroup + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment +} +% +% The \vtop produces a box with normal height and large depth; thus, TeX puts +% \baselineskip glue before it, and (when the next line of text is done) +% \lineskip glue after it. Thus, space below is not quite equal to space +% above. But it's pretty close. +\def\Egroup{% + % To get correct interline space between the last line of the group + % and the first line afterwards, we have to propagate \prevdepth. + \endgraf % Not \par, as it may have been set to \lisppar. + \global\dimen1 = \prevdepth + \egroup % End the \vtop. + % \dimen0 is the vertical size of the group's box. + \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox + % \dimen2 is how much space is left on the page (more or less). + \dimen2 = \pageheight \advance\dimen2 by -\pagetotal + % if the group doesn't fit on the current page, and it's a big big + % group, force a page break. + \ifdim \dimen0 > \dimen2 + \ifdim \pagetotal < \vfilllimit\pageheight + \page + \fi + \fi + \box\groupbox + \prevdepth = \dimen1 + \checkinserts +} +% +% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +% message, so this ends up printing `@group can only ...'. +% +\newhelp\groupinvalidhelp{% +group can only be used in environments such as @example,^^J% +where each line of input produces a line of output.} + +% @need space-in-mils +% forces a page break if there is not space-in-mils remaining. + +\newdimen\mil \mil=0.001in + +\parseargdef\need{% + % Ensure vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % If the @need value is less than one line space, it's useless. + \dimen0 = #1\mil + \dimen2 = \ht\strutbox + \advance\dimen2 by \dp\strutbox + \ifdim\dimen0 > \dimen2 + % + % Do a \strut just to make the height of this box be normal, so the + % normal leading is inserted relative to the preceding line. + % And a page break here is fine. + \vtop to #1\mil{\strut\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak + \fi +} + +% @br forces paragraph break (and is undocumented). + +\let\br = \par + +% @page forces the start of a new page. +% +\def\page{\par\vfill\supereject} + +% @exdent text.... +% outputs text on separate line in roman font, starting at standard page margin + +% This records the amount of indent in the innermost environment. +% That's how much \exdent should take out. +\newskip\exdentamount + +% This defn is used inside fill environments such as @defun. +\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break} + +% This defn is used inside nofill environments such as @example. +\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount + \leftline{\hskip\leftskip{\rm#1}}}} + +% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current +% paragraph. For more general purposes, use the \margin insertion +% class. WHICH is `l' or `r'. Not documented, written for gawk manual. +% +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} +% +\def\doinmargin#1#2{\strut\vadjust{% + \nobreak + \kern-\strutdepth + \vtop to \strutdepth{% + \baselineskip=\strutdepth + \vss + % if you have multiple lines of stuff to put here, you'll need to + % make the vbox yourself of the appropriate size. + \ifx#1l% + \llap{\ignorespaces #2\hskip\inmarginspacing}% + \else + \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% + \fi + \null + }% +}} +\def\inleftmargin{\doinmargin l} +\def\inrightmargin{\doinmargin r} +% +% @inmargin{TEXT [, RIGHT-TEXT]} +% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; +% else use TEXT for both). +% +\def\inmargin#1{\parseinmargin #1,,\finish} +\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \def\lefttext{#1}% have both texts + \def\righttext{#2}% + \else + \def\lefttext{#1}% have only one text + \def\righttext{#1}% + \fi + % + \ifodd\pageno + \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin + \else + \def\temp{\inleftmargin\lefttext}% + \fi + \temp +} + +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). This command +% is not documented, not supported, and doesn't work. +% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% +} + +% @include FILE -- \input text of FILE. +% +\def\include{\parseargusing\filenamecatcodes\includezzz} +\def\includezzz#1{% + \pushthisfilestack + \def\thisfile{#1}% + {% + \makevalueexpandable % we want to expand any @value in FILE. + \turnoffactive % and allow special characters in the expansion + \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @include of #1^^J}% + \edef\temp{\noexpand\input #1 }% + % + % This trickery is to read FILE outside of a group, in case it makes + % definitions, etc. + \expandafter + }\temp + \popthisfilestack +} +\def\filenamecatcodes{% + \catcode`\\=\other + \catcode`~=\other + \catcode`^=\other + \catcode`_=\other + \catcode`|=\other + \catcode`<=\other + \catcode`>=\other + \catcode`+=\other + \catcode`-=\other + \catcode`\`=\other + \catcode`\'=\other +} + +\def\pushthisfilestack{% + \expandafter\pushthisfilestackX\popthisfilestack\StackTerm +} +\def\pushthisfilestackX{% + \expandafter\pushthisfilestackY\thisfile\StackTerm +} +\def\pushthisfilestackY #1\StackTerm #2\StackTerm {% + \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}% +} + +\def\popthisfilestack{\errthisfilestackempty} +\def\errthisfilestackempty{\errmessage{Internal error: + the stack of filenames is empty.}} +% +\def\thisfile{} + +% @center line +% outputs that line, centered. +% +\parseargdef\center{% + \ifhmode + \let\centersub\centerH + \else + \let\centersub\centerV + \fi + \centersub{\hfil \ignorespaces#1\unskip \hfil}% + \let\centersub\relax % don't let the definition persist, just in case +} +\def\centerH#1{{% + \hfil\break + \advance\hsize by -\leftskip + \advance\hsize by -\rightskip + \line{#1}% + \break +}} +% +\newcount\centerpenalty +\def\centerV#1{% + % The idea here is the same as in \startdefun, \cartouche, etc.: if + % @center is the first thing after a section heading, we need to wipe + % out the negative parskip inserted by \sectionheading, but still + % prevent a page break here. + \centerpenalty = \lastpenalty + \ifnum\centerpenalty>10000 \vskip\parskip \fi + \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi + \line{\kern\leftskip #1\kern\rightskip}% +} + +% @sp n outputs n lines of vertical space +% +\parseargdef\sp{\vskip #1\baselineskip} + +% @comment ...line which is ignored... +% @c is the same as @comment +% @ignore ... @end ignore is another way to write a comment +% +\def\comment{\begingroup \catcode`\^^M=\other% +\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% +\commentxxx} +{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} +% +\let\c=\comment + +% @paragraphindent NCHARS +% We'll use ems for NCHARS, close enough. +% NCHARS can also be the word `asis' or `none'. +% We cannot feasibly implement @paragraphindent asis, though. +% +\def\asisword{asis} % no translation, these are keywords +\def\noneword{none} +% +\parseargdef\paragraphindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \defaultparindent = 0pt + \else + \defaultparindent = #1em + \fi + \fi + \parindent = \defaultparindent +} + +% @exampleindent NCHARS +% We'll use ems for NCHARS like @paragraphindent. +% It seems @exampleindent asis isn't necessary, but +% I preserve it to make it similar to @paragraphindent. +\parseargdef\exampleindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \lispnarrowing = 0pt + \else + \lispnarrowing = #1em + \fi + \fi +} + +% @firstparagraphindent WORD +% If WORD is `none', then suppress indentation of the first paragraph +% after a section heading. If WORD is `insert', then do indent at such +% paragraphs. +% +% The paragraph indentation is suppressed or not by calling +% \suppressfirstparagraphindent, which the sectioning commands do. +% We switch the definition of this back and forth according to WORD. +% By default, we suppress indentation. +% +\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} +\def\insertword{insert} +% +\parseargdef\firstparagraphindent{% + \def\temp{#1}% + \ifx\temp\noneword + \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent + \else\ifx\temp\insertword + \let\suppressfirstparagraphindent = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @firstparagraphindent option `\temp'}% + \fi\fi +} + +% Here is how we actually suppress indentation. Redefine \everypar to +% \kern backwards by \parindent, and then reset itself to empty. +% +% We also make \indent itself not actually do anything until the next +% paragraph. +% +\gdef\dosuppressfirstparagraphindent{% + \gdef\indent{% + \restorefirstparagraphindent + \indent + }% + \gdef\noindent{% + \restorefirstparagraphindent + \noindent + }% + \global\everypar = {% + \kern -\parindent + \restorefirstparagraphindent + }% +} + +\gdef\restorefirstparagraphindent{% + \global \let \indent = \ptexindent + \global \let \noindent = \ptexnoindent + \global \everypar = {}% +} + + +% @refill is a no-op. +\let\refill=\relax + +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate (before @setfilename). +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% @setfilename is done at the beginning of every texinfo file. +% So open here the files we need to have open while reading the input. +% This makes it possible to make a .fmt file for texinfo. +\def\setfilename{% + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \iflinks + \tryauxfile + % Open the new aux file. TeX will close it automatically at exit. + \immediate\openout\auxfile=\jobname.aux + \fi % \openindices needs to do some work in any case. + \openindices + \let\setfilename=\comment % Ignore extra @setfilename cmds. + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. + \openin 1 texinfo.cnf + \ifeof 1 \else \input texinfo.cnf \fi + \closein 1 + % + \comment % Ignore the actual filename. +} + +% Called from \setfilename. +% +\def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% +} + +% @bye. +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + +\message{pdf,} +% adobe `portable' document format +\newcount\tempnum +\newcount\lnkcount +\newtoks\filename +\newcount\filenamelength +\newcount\pgn +\newtoks\toksA +\newtoks\toksB +\newtoks\toksC +\newtoks\toksD +\newbox\boxA +\newcount\countA +\newif\ifpdf +\newif\ifpdfmakepagedest + +% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 +% can be set). So we test for \relax and 0 as well as being undefined. +\ifx\pdfoutput\thisisundefined +\else + \ifx\pdfoutput\relax + \else + \ifcase\pdfoutput + \else + \pdftrue + \fi + \fi +\fi + +% PDF uses PostScript string constants for the names of xref targets, +% for display in the outlines, and in other places. Thus, we have to +% double any backslashes. Otherwise, a name like "\node" will be +% interpreted as a newline (\n), followed by o, d, e. Not good. +% +% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and +% related messages. The final outcome is that it is up to the TeX user +% to double the backslashes and otherwise make the string valid, so +% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to +% do this reliably, so we use it. + +% #1 is a control sequence in which to do the replacements, +% which we \xdef. +\def\txiescapepdf#1{% + \ifx\pdfescapestring\thisisundefined + % No primitive available; should we give a warning or log? + % Many times it won't matter. + \else + % The expandable \pdfescapestring primitive escapes parentheses, + % backslashes, and other special chars. + \xdef#1{\pdfescapestring{#1}}% + \fi +} + +\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images +with PDF output, and none of those formats could be found. (.eps cannot +be supported due to the design of the PDF format; use regular TeX (DVI +output) for that.)} + +\ifpdf + % + % Color manipulation macros based on pdfcolor.tex, + % except using rgb instead of cmyk; the latter is said to render as a + % very dark gray on-screen and a very dark halftone in print, instead + % of actual black. + \def\rgbDarkRed{0.50 0.09 0.12} + \def\rgbBlack{0 0 0} + % + % k sets the color for filling (usual text, etc.); + % K sets the color for stroking (thin rules, e.g., normal _'s). + \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}} + % + % Set color, and create a mark which defines \thiscolor accordingly, + % so that \makeheadline knows which color to restore. + \def\setcolor#1{% + \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% + \domark + \pdfsetcolor{#1}% + } + % + \def\maincolor{\rgbBlack} + \pdfsetcolor{\maincolor} + \edef\thiscolor{\maincolor} + \def\lastcolordefs{} + % + \def\makefootline{% + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}% + } + % + \def\makeheadline{% + \vbox to 0pt{% + \vskip-22.5pt + \line{% + \vbox to8.5pt{}% + % Extract \thiscolor definition from the marks. + \getcolormarks + % Typeset the headline with \maincolor, then restore the color. + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% + }% + \vss + }% + \nointerlineskip + } + % + % + \pdfcatalog{/PageMode /UseOutlines} + % + % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). + \def\dopdfimage#1#2#3{% + \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + % + % pdftex (and the PDF format) support .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if + % someone has a scalable image, presumably better to use that than a + % bitmap. + \let\pdfimgext=\empty + \begingroup + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \errhelp = \nopdfimagehelp + \errmessage{Could not find image file #1 for pdf}% + \else \gdef\pdfimgext{JPG}% + \fi + \else \gdef\pdfimgext{jpeg}% + \fi + \else \gdef\pdfimgext{jpg}% + \fi + \else \gdef\pdfimgext{png}% + \fi + \else \gdef\pdfimgext{PDF}% + \fi + \else \gdef\pdfimgext{pdf}% + \fi + \closein 1 + \endgroup + % + % without \immediate, ancient pdftex seg faults when the same image is + % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) + \ifnum\pdftexversion < 14 + \immediate\pdfimage + \else + \immediate\pdfximage + \fi + \ifdim \wd0 >0pt width \pdfimagewidth \fi + \ifdim \wd2 >0pt height \pdfimageheight \fi + \ifnum\pdftexversion<13 + #1.\pdfimgext + \else + {#1.\pdfimgext}% + \fi + \ifnum\pdftexversion < 14 \else + \pdfrefximage \pdflastximage + \fi} + % + \def\pdfmkdest#1{{% + % We have to set dummies so commands such as @code, and characters + % such as \, aren't expanded when present in a section title. + \indexnofonts + \turnoffactive + \makevalueexpandable + \def\pdfdestname{#1}% + \txiescapepdf\pdfdestname + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + }} + % + % used to mark target names; must be expandable. + \def\pdfmkpgn#1{#1} + % + % by default, use a color that is dark enough to print on paper as + % nearly black, but still distinguishable for online viewing. + \def\urlcolor{\rgbDarkRed} + \def\linkcolor{\rgbDarkRed} + \def\endlink{\setcolor{\maincolor}\pdfendlink} + % + % Adding outlines to PDF; macros for calculating structure of outlines + % come from Petr Olsak + \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% + \else \csname#1\endcsname \fi} + \def\advancenumber#1{\tempnum=\expnumber{#1}\relax + \advance\tempnum by 1 + \expandafter\xdef\csname#1\endcsname{\the\tempnum}} + % + % #1 is the section text, which is what will be displayed in the + % outline by the pdf viewer. #2 is the pdf expression for the number + % of subentries (or empty, for subsubsections). #3 is the node text, + % which might be empty if this toc entry had no corresponding node. + % #4 is the page number + % + \def\dopdfoutline#1#2#3#4{% + % Generate a link to the node text if that exists; else, use the + % page number. We could generate a destination for the section + % text in the case where a section has no node, but it doesn't + % seem worth the trouble, since most documents are normally structured. + \edef\pdfoutlinedest{#3}% + \ifx\pdfoutlinedest\empty + \def\pdfoutlinedest{#4}% + \else + \txiescapepdf\pdfoutlinedest + \fi + % + % Also escape PDF chars in the display string. + \edef\pdfoutlinetext{#1}% + \txiescapepdf\pdfoutlinetext + % + \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}% + } + % + \def\pdfmakeoutlines{% + \begingroup + % Read toc silently, to get counts of subentries for \pdfoutline. + \def\partentry##1##2##3##4{}% ignore parts in the outlines + \def\numchapentry##1##2##3##4{% + \def\thischapnum{##2}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + }% + \def\numsecentry##1##2##3##4{% + \advancenumber{chap\thischapnum}% + \def\thissecnum{##2}% + \def\thissubsecnum{0}% + }% + \def\numsubsecentry##1##2##3##4{% + \advancenumber{sec\thissecnum}% + \def\thissubsecnum{##2}% + }% + \def\numsubsubsecentry##1##2##3##4{% + \advancenumber{subsec\thissubsecnum}% + }% + \def\thischapnum{0}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + % + % use \def rather than \let here because we redefine \chapentry et + % al. a second time, below. + \def\appentry{\numchapentry}% + \def\appsecentry{\numsecentry}% + \def\appsubsecentry{\numsubsecentry}% + \def\appsubsubsecentry{\numsubsubsecentry}% + \def\unnchapentry{\numchapentry}% + \def\unnsecentry{\numsecentry}% + \def\unnsubsecentry{\numsubsecentry}% + \def\unnsubsubsecentry{\numsubsubsecentry}% + \readdatafile{toc}% + % + % Read toc second time, this time actually producing the outlines. + % The `-' means take the \expnumber as the absolute number of + % subentries, which we calculated on our first read of the .toc above. + % + % We use the node names as the destinations. + \def\numchapentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% + \def\numsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% + \def\numsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% + \def\numsubsubsecentry##1##2##3##4{% count is always zero + \dopdfoutline{##1}{}{##3}{##4}}% + % + % PDF outlines are displayed using system fonts, instead of + % document fonts. Therefore we cannot use special characters, + % since the encoding is unknown. For example, the eogonek from + % Latin 2 (0xea) gets translated to a | character. Info from + % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. + % + % TODO this right, we have to translate 8-bit characters to + % their "best" equivalent, based on the @documentencoding. Too + % much work for too little return. Just use the ASCII equivalents + % we use for the index sort strings. + % + \indexnofonts + \setupdatafile + % We can have normal brace characters in the PDF outlines, unlike + % Texinfo index files. So set that up. + \def\{{\lbracecharliteral}% + \def\}{\rbracecharliteral}% + \catcode`\\=\active \otherbackslash + \input \tocreadfilename + \endgroup + } + {\catcode`[=1 \catcode`]=2 + \catcode`{=\other \catcode`}=\other + \gdef\lbracecharliteral[{]% + \gdef\rbracecharliteral[}]% + ] + % + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \nextsp} + \def\getfilename#1{% + \filenamelength=0 + % If we don't expand the argument now, \skipspaces will get + % snagged on things like "@value{foo}". + \edef\temp{#1}% + \expandafter\skipspaces\temp|\relax + } + \ifnum\pdftexversion < 14 + \let \startlink \pdfannotlink + \else + \let \startlink \pdfstartlink + \fi + % make a live url in pdf output. + \def\pdfurl#1{% + \begingroup + % it seems we really need yet another set of dummies; have not + % tried to figure out what each command should do in the context + % of @url. for now, just make @/ a no-op, that's the only one + % people have actually reported a problem with. + % + \normalturnoffactive + \def\@{@}% + \let\/=\empty + \makevalueexpandable + % do we want to go so far as to use \indexnofonts instead of just + % special-casing \var here? + \def\var##1{##1}% + % + \leavevmode\setcolor{\urlcolor}% + \startlink attr{/Border [0 0 0]}% + user{/Subtype /Link /A << /S /URI /URI (#1) >>}% + \endgroup} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS|\relax + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} + \setcolor{\linkcolor}#1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +\else + % non-pdf mode + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\setcolor = \gobble + \let\pdfsetcolor = \gobble + \let\pdfmakeoutlines = \relax +\fi % \ifx\pdfoutput + + +\message{fonts,} + +% Change the current font style to #1, remembering it in \curfontstyle. +% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in +% italics, not bold italics. +% +\def\setfontstyle#1{% + \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. + \csname ten#1\endcsname % change the current font +} + +% Select #1 fonts with the current style. +% +\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname} + +\def\rm{\fam=0 \setfontstyle{rm}} +\def\it{\fam=\itfam \setfontstyle{it}} +\def\sl{\fam=\slfam \setfontstyle{sl}} +\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} +\def\tt{\fam=\ttfam \setfontstyle{tt}} + +% Unfortunately, we have to override this for titles and the like, since +% in those cases "rm" is bold. Sigh. +\def\rmisbold{\rm\def\curfontstyle{bf}} + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf. +\newfam\sffam +\def\sf{\fam=\sffam \setfontstyle{sf}} +\let\li = \sf % Sometimes we call it \li, not \sf. + +% We don't need math for this font style. +\def\ttsl{\setfontstyle{ttsl}} + + +% Set the baselineskip to #1, and the lineskip and strut size +% correspondingly. There is no deep meaning behind these magic numbers +% used as factors; they just match (closely enough) what Knuth defined. +% +\def\lineskipfactor{.08333} +\def\strutheightpercent{.70833} +\def\strutdepthpercent {.29167} +% +% can get a sort of poor man's double spacing by redefining this. +\def\baselinefactor{1} +% +\newdimen\textleading +\def\setleading#1{% + \dimen0 = #1\relax + \normalbaselineskip = \baselinefactor\dimen0 + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% PDF CMaps. See also LaTeX's t1.cmap. +% +% do nothing with this by default. +\expandafter\let\csname cmapOT1\endcsname\gobble +\expandafter\let\csname cmapOT1IT\endcsname\gobble +\expandafter\let\csname cmapOT1TT\endcsname\gobble + +% if we are producing pdf, and we have \pdffontattr, then define cmaps. +% (\pdffontattr was introduced many years ago, but people still run +% older pdftex's; it's easy to conditionalize, so we do.) +\ifpdf \ifx\pdffontattr\thisisundefined \else + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1-0) +%%Title: (TeX-OT1-0 TeX OT1 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1) +/Supplement 0 +>> def +/CMapName /TeX-OT1-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<23> <26> <0023> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +40 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1IT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1IT-0) +%%Title: (TeX-OT1IT-0 TeX OT1IT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1IT) +/Supplement 0 +>> def +/CMapName /TeX-OT1IT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<25> <26> <0025> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +42 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<23> <0023> +<24> <00A3> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1IT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1TT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1TT-0) +%%Title: (TeX-OT1TT-0 TeX OT1TT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1TT) +/Supplement 0 +>> def +/CMapName /TeX-OT1TT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +5 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<21> <26> <0021> +<28> <5F> <0028> +<61> <7E> <0061> +endbfrange +32 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <2191> +<0C> <2193> +<0D> <0027> +<0E> <00A1> +<0F> <00BF> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<20> <2423> +<27> <2019> +<60> <2018> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1TT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +\fi\fi + + +% Set the font macro #1 to the font named \fontprefix#2. +% #3 is the font's design size, #4 is a scale factor, #5 is the CMap +% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit). +% Example: +% #1 = \textrm +% #2 = \rmshape +% #3 = 10 +% #4 = \mainmagstep +% #5 = OT1 +% +\def\setfont#1#2#3#4#5{% + \font#1=\fontprefix#2#3 scaled #4 + \csname cmap#5\endcsname#1% +} +% This is what gets called when #5 of \setfont is empty. +\let\cmap\gobble +% +% (end of cmaps) + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\thisisundefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} % where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{bxti} +\def\slshape{sl} +\def\slbshape{bxsl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + +% Definitions for a main text size of 11pt. (The default in Texinfo.) +% +\def\definetextfontsizexi{% +% Text fonts (11.2pt, magstep1). +\def\textnominalsize{11pt} +\edef\mainmagstep{\magstephalf} +\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1095} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstep1}{OT1} +\setfont\deftt\ttshape{10}{\magstep1}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\def\smallnominalsize{9pt} +\setfont\smallrm\rmshape{9}{1000}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\titleecsize{2074} + +% Chapter (and unnumbered) fonts (17.28pt). +\def\chapnominalsize{17pt} +\setfont\chaprm\rmbshape{12}{\magstep2}{OT1} +\setfont\chapit\itbshape{10}{\magstep3}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep3}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT} +\setfont\chapsf\sfbshape{17}{1000}{OT1} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3}{OT1} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 +\def\chapecsize{1728} + +% Section fonts (14.4pt). +\def\secnominalsize{14pt} +\setfont\secrm\rmbshape{12}{\magstep1}{OT1} +\setfont\secit\itbshape{10}{\magstep2}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep2}{OT1} +\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\secsf\sfbshape{12}{\magstep1}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2}{OT1} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 +\def\sececsize{1440} + +% Subsection fonts (13.15pt). +\def\ssecnominalsize{13pt} +\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1} +\setfont\ssecit\itbshape{10}{1315}{OT1IT} +\setfont\ssecsl\slbshape{10}{1315}{OT1} +\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT} +\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1315}{OT1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +\def\ssececsize{1200} + +% Reduced fonts for @acro in text (10pt). +\def\reducednominalsize{10pt} +\setfont\reducedrm\rmshape{10}{1000}{OT1} +\setfont\reducedtt\ttshape{10}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{1000}{OT1} +\setfont\reducedit\itshape{10}{1000}{OT1IT} +\setfont\reducedsl\slshape{10}{1000}{OT1} +\setfont\reducedsf\sfshape{10}{1000}{OT1} +\setfont\reducedsc\scshape{10}{1000}{OT1} +\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT} +\font\reducedi=cmmi10 +\font\reducedsy=cmsy10 +\def\reducedecsize{1000} + +\textleading = 13.2pt % line spacing for 11pt CM +\textfonts % reset the current fonts +\rm +} % end of 11pt text font size definitions, \definetextfontsizexi + + +% Definitions to make the main text be 10pt Computer Modern, with +% section, chapter, etc., sizes following suit. This is for the GNU +% Press printing of the Emacs 22 manual. Maybe other manuals in the +% future. Used with @smallbook, which sets the leading to 12pt. +% +\def\definetextfontsizex{% +% Text fonts (10pt). +\def\textnominalsize{10pt} +\edef\mainmagstep{1000} +\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1000} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstephalf}{OT1} +\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\def\smallnominalsize{9pt} +\setfont\smallrm\rmshape{9}{1000}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\titleecsize{2074} + +% Chapter fonts (14.4pt). +\def\chapnominalsize{14pt} +\setfont\chaprm\rmbshape{12}{\magstep1}{OT1} +\setfont\chapit\itbshape{10}{\magstep2}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep2}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\chapsf\sfbshape{12}{\magstep1}{OT1} +\let\chapbf\chaprm +\setfont\chapsc\scbshape{10}{\magstep2}{OT1} +\font\chapi=cmmi12 scaled \magstep1 +\font\chapsy=cmsy10 scaled \magstep2 +\def\chapecsize{1440} + +% Section fonts (12pt). +\def\secnominalsize{12pt} +\setfont\secrm\rmbshape{12}{1000}{OT1} +\setfont\secit\itbshape{10}{\magstep1}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep1}{OT1} +\setfont\sectt\ttbshape{12}{1000}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT} +\setfont\secsf\sfbshape{12}{1000}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep1}{OT1} +\font\seci=cmmi12 +\font\secsy=cmsy10 scaled \magstep1 +\def\sececsize{1200} + +% Subsection fonts (10pt). +\def\ssecnominalsize{10pt} +\setfont\ssecrm\rmbshape{10}{1000}{OT1} +\setfont\ssecit\itbshape{10}{1000}{OT1IT} +\setfont\ssecsl\slbshape{10}{1000}{OT1} +\setfont\ssectt\ttbshape{10}{1000}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT} +\setfont\ssecsf\sfbshape{10}{1000}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1000}{OT1} +\font\sseci=cmmi10 +\font\ssecsy=cmsy10 +\def\ssececsize{1000} + +% Reduced fonts for @acro in text (9pt). +\def\reducednominalsize{9pt} +\setfont\reducedrm\rmshape{9}{1000}{OT1} +\setfont\reducedtt\ttshape{9}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{900}{OT1} +\setfont\reducedit\itshape{9}{1000}{OT1IT} +\setfont\reducedsl\slshape{9}{1000}{OT1} +\setfont\reducedsf\sfshape{9}{1000}{OT1} +\setfont\reducedsc\scshape{10}{900}{OT1} +\setfont\reducedttsl\ttslshape{10}{900}{OT1TT} +\font\reducedi=cmmi9 +\font\reducedsy=cmsy9 +\def\reducedecsize{0900} + +\divide\parskip by 2 % reduce space between paragraphs +\textleading = 12pt % line spacing for 10pt CM +\textfonts % reset the current fonts +\rm +} % end of 10pt text font size definitions, \definetextfontsizex + + +% We provide the user-level command +% @fonttextsize 10 +% (or 11) to redefine the text font size. pt is assumed. +% +\def\xiword{11} +\def\xword{10} +\def\xwordpt{10pt} +% +\parseargdef\fonttextsize{% + \def\textsizearg{#1}% + %\wlog{doing @fonttextsize \textsizearg}% + % + % Set \globaldefs so that documents can use this inside @tex, since + % makeinfo 4.8 does not support it, but we need it nonetheless. + % + \begingroup \globaldefs=1 + \ifx\textsizearg\xword \definetextfontsizex + \else \ifx\textsizearg\xiword \definetextfontsizexi + \else + \errhelp=\EMsimple + \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'} + \fi\fi + \endgroup +} + + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. Since +% texinfo doesn't allow for producing subscripts and superscripts except +% in the main text, we don't bother to reset \scriptfont and +% \scriptscriptfont (which would also require loading a lot more fonts). +% +\def\resetmathfonts{% + \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy + \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf + \textfont\ttfam=\tentt \textfont\sffam=\tensf +} + +% The font-changing commands redefine the meanings of \tenSTYLE, instead +% of just \STYLE. We do this because \STYLE needs to also set the +% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire +% \tenSTYLE to set the current font. +% +% Each font-changing command also sets the names \lsize (one size lower) +% and \lllsize (three sizes lower). These relative commands are used in +% the LaTeX logo and acronyms. +% +% This all needs generalizing, badly. +% +\def\textfonts{% + \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl + \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy + \let\tenttsl=\textttsl + \def\curfontsize{text}% + \def\lsize{reduced}\def\lllsize{smaller}% + \resetmathfonts \setleading{\textleading}} +\def\titlefonts{% + \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl + \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc + \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy + \let\tenttsl=\titlettsl + \def\curfontsize{title}% + \def\lsize{chap}\def\lllsize{subsec}% + \resetmathfonts \setleading{27pt}} +\def\titlefont#1{{\titlefonts\rmisbold #1}} +\def\chapfonts{% + \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl + \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc + \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy + \let\tenttsl=\chapttsl + \def\curfontsize{chap}% + \def\lsize{sec}\def\lllsize{text}% + \resetmathfonts \setleading{19pt}} +\def\secfonts{% + \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl + \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy + \let\tenttsl=\secttsl + \def\curfontsize{sec}% + \def\lsize{subsec}\def\lllsize{reduced}% + \resetmathfonts \setleading{16pt}} +\def\subsecfonts{% + \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl + \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy + \let\tenttsl=\ssecttsl + \def\curfontsize{ssec}% + \def\lsize{text}\def\lllsize{small}% + \resetmathfonts \setleading{15pt}} +\let\subsubsecfonts = \subsecfonts +\def\reducedfonts{% + \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl + \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc + \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy + \let\tenttsl=\reducedttsl + \def\curfontsize{reduced}% + \def\lsize{small}\def\lllsize{smaller}% + \resetmathfonts \setleading{10.5pt}} +\def\smallfonts{% + \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl + \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc + \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy + \let\tenttsl=\smallttsl + \def\curfontsize{small}% + \def\lsize{smaller}\def\lllsize{smaller}% + \resetmathfonts \setleading{10.5pt}} +\def\smallerfonts{% + \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl + \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc + \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy + \let\tenttsl=\smallerttsl + \def\curfontsize{smaller}% + \def\lsize{smaller}\def\lllsize{smaller}% + \resetmathfonts \setleading{9.5pt}} + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000}{OT1} +\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 +\setfont\shortcontsl\slshape{12}{1000}{OT1} +\setfont\shortconttt\ttshape{12}{1000}{OT1TT} + +% Define these just so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + +% Set the fonts to use with the @small... environments. +\let\smallexamplefonts = \smallfonts + +% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample +% can fit this many characters: +% 8.5x11=86 smallbook=72 a4=90 a5=69 +% If we use \scriptfonts (8pt), then we can fit this many characters: +% 8.5x11=90+ smallbook=80 a4=90+ a5=77 +% For me, subjectively, the few extra characters that fit aren't worth +% the additional smallness of 8pt. So I'm making the default 9pt. +% +% By the way, for comparison, here's what fits with @example (10pt): +% 8.5x11=71 smallbook=60 a4=75 a5=58 +% --karl, 24jan03. + +% Set up the default fonts, so we can use them for creating boxes. +% +\definetextfontsizexi + + +\message{markup,} + +% Check if we are currently using a typewriter font. Since all the +% Computer Modern typewriter fonts have zero interword stretch (and +% shrink), and it is reasonable to expect all typewriter fonts to have +% this property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } + +% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will +% define and register \INITMACRO to be called on markup style changes. +% \INITMACRO can check \currentmarkupstyle for the innermost +% style and the set of \ifmarkupSTYLE switches for all styles +% currently in effect. +\newif\ifmarkupvar +\newif\ifmarkupsamp +\newif\ifmarkupkey +%\newif\ifmarkupfile % @file == @samp. +%\newif\ifmarkupoption % @option == @samp. +\newif\ifmarkupcode +\newif\ifmarkupkbd +%\newif\ifmarkupenv % @env == @code. +%\newif\ifmarkupcommand % @command == @code. +\newif\ifmarkuptex % @tex (and part of @math, for now). +\newif\ifmarkupexample +\newif\ifmarkupverb +\newif\ifmarkupverbatim + +\let\currentmarkupstyle\empty + +\def\setupmarkupstyle#1{% + \csname markup#1true\endcsname + \def\currentmarkupstyle{#1}% + \markupstylesetup +} + +\let\markupstylesetup\empty + +\def\defmarkupstylesetup#1{% + \expandafter\def\expandafter\markupstylesetup + \expandafter{\markupstylesetup #1}% + \def#1% +} + +% Markup style setup for left and right quotes. +\defmarkupstylesetup\markupsetuplq{% + \expandafter\let\expandafter \temp + \csname markupsetuplq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuplqdefault \else \temp \fi +} + +\defmarkupstylesetup\markupsetuprq{% + \expandafter\let\expandafter \temp + \csname markupsetuprq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuprqdefault \else \temp \fi +} + +{ +\catcode`\'=\active +\catcode`\`=\active + +\gdef\markupsetuplqdefault{\let`\lq} +\gdef\markupsetuprqdefault{\let'\rq} + +\gdef\markupsetcodequoteleft{\let`\codequoteleft} +\gdef\markupsetcodequoteright{\let'\codequoteright} +} + +\let\markupsetuplqcode \markupsetcodequoteleft +\let\markupsetuprqcode \markupsetcodequoteright +% +\let\markupsetuplqexample \markupsetcodequoteleft +\let\markupsetuprqexample \markupsetcodequoteright +% +\let\markupsetuplqkbd \markupsetcodequoteleft +\let\markupsetuprqkbd \markupsetcodequoteright +% +\let\markupsetuplqsamp \markupsetcodequoteleft +\let\markupsetuprqsamp \markupsetcodequoteright +% +\let\markupsetuplqverb \markupsetcodequoteleft +\let\markupsetuprqverb \markupsetcodequoteright +% +\let\markupsetuplqverbatim \markupsetcodequoteleft +\let\markupsetuprqverbatim \markupsetcodequoteright + +% Allow an option to not use regular directed right quote/apostrophe +% (char 0x27), but instead the undirected quote from cmtt (char 0x0d). +% The undirected quote is ugly, so don't make it the default, but it +% works for pasting with more pdf viewers (at least evince), the +% lilypond developers report. xpdf does work with the regular 0x27. +% +\def\codequoteright{% + \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax + \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax + '% + \else \char'15 \fi + \else \char'15 \fi +} +% +% and a similar option for the left quote char vs. a grave accent. +% Modern fonts display ASCII 0x60 as a grave accent, so some people like +% the code environments to do likewise. +% +\def\codequoteleft{% + \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax + \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax + % [Knuth] pp. 380,381,391 + % \relax disables Spanish ligatures ?` and !` of \tt font. + \relax`% + \else \char'22 \fi + \else \char'22 \fi +} + +% Commands to set the quote options. +% +\parseargdef\codequoteundirected{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}% + \fi\fi +} +% +\parseargdef\codequotebacktick{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}% + \fi\fi +} + +% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. +\def\noligaturesquoteleft{\relax\lq} + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Font commands. + +% #1 is the font command (\sl or \it), #2 is the text to slant. +% If we are in a monospaced environment, however, 1) always use \ttsl, +% and 2) do not add an italic correction. +\def\dosmartslant#1#2{% + \ifusingtt + {{\ttsl #2}\let\next=\relax}% + {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}% + \next +} +\def\smartslanted{\dosmartslant\sl} +\def\smartitalic{\dosmartslant\it} + +% Output an italic correction unless \next (presumed to be the following +% character) is such as not to need one. +\def\smartitaliccorrection{% + \ifx\next,% + \else\ifx\next-% + \else\ifx\next.% + \else\ptexslash + \fi\fi\fi + \aftersmartic +} + +% Unconditional use \ttsl, and no ic. @var is set to this for defuns. +\def\ttslanted#1{{\ttsl #1}} + +% @cite is like \smartslanted except unconditionally use \sl. We never want +% ttsl for book titles, do we? +\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection} + +\def\aftersmartic{} +\def\var#1{% + \let\saveaftersmartic = \aftersmartic + \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}% + \smartslanted{#1}% +} + +\let\i=\smartitalic +\let\slanted=\smartslanted +\let\dfn=\smartslanted +\let\emph=\smartitalic + +% Explicit font changes: @r, @sc, undocumented @ii. +\def\r#1{{\rm #1}} % roman font +\def\sc#1{{\smallcaps#1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +% @b, explicit bold. Also @strong. +\def\b#1{{\bf #1}} +\let\strong=\b + +% @sansserif, explicit sans. +\def\sansserif#1{{\sf #1}} + +% We can't just use \exhyphenpenalty, because that only has effect at +% the end of a paragraph. Restore normal hyphenation at the end of the +% group within which \nohyphenation is presumably called. +% +\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +\def\restorehyphenation{\hyphenchar\font = `- } + +% Set sfcode to normal for the chars that usually have another value. +% Can't use plain's \frenchspacing because it uses the `\x notation, and +% sometimes \x has an active definition that messes things up. +% +\catcode`@=11 + \def\plainfrenchspacing{% + \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m + \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m + \def\endofsentencespacefactor{1000}% for @. and friends + } + \def\plainnonfrenchspacing{% + \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000 + \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 + \def\endofsentencespacefactor{3000}% for @. and friends + } +\catcode`@=\other +\def\endofsentencespacefactor{3000}% default + +% @t, explicit typewriter. +\def\t#1{% + {\tt \rawbackslash \plainfrenchspacing #1}% + \null +} + +% @samp. +\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} + +% @indicateurl is \samp, that is, with quotes. +\let\indicateurl=\samp + +% @code (and similar) prints in typewriter, but with spaces the same +% size as normal in the surrounding text, without hyphenation, etc. +% This is a subroutine for that. +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \plainfrenchspacing + #1% + }% + \null % reset spacefactor to 1000 +} + +% We *must* turn on hyphenation at `-' and `_' in @code. +% Otherwise, it is too hard to avoid overfull hboxes +% in the Emacs manual, the Library manual, etc. +% +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate at a dash. +% -- rms. +{ + \catcode`\-=\active \catcode`\_=\active + \catcode`\'=\active \catcode`\`=\active + \global\let'=\rq \global\let`=\lq % default definitions + % + \global\def\code{\begingroup + \setupmarkupstyle{code}% + % The following should really be moved into \setupmarkupstyle handlers. + \catcode\dashChar=\active \catcode\underChar=\active + \ifallowcodebreaks + \let-\codedash + \let_\codeunder + \else + \let-\realdash + \let_\realunder + \fi + \codex + } +} + +\def\codex #1{\tclose{#1}\endgroup} + +\def\realdash{-} +\def\codedash{-\discretionary{}{}{}} +\def\codeunder{% + % this is all so @math{@code{var_name}+1} can work. In math mode, _ + % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) + % will therefore expand the active definition of _, which is us + % (inside @code that is), therefore an endless loop. + \ifusingtt{\ifmmode + \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. + \else\normalunderscore \fi + \discretionary{}{}{}}% + {\_}% +} + +% An additional complication: the above will allow breaks after, e.g., +% each of the four underscores in __typeof__. This is undesirable in +% some manuals, especially if they don't have long identifiers in +% general. @allowcodebreaks provides a way to control this. +% +\newif\ifallowcodebreaks \allowcodebreakstrue + +\def\keywordtrue{true} +\def\keywordfalse{false} + +\parseargdef\allowcodebreaks{% + \def\txiarg{#1}% + \ifx\txiarg\keywordtrue + \allowcodebreakstrue + \else\ifx\txiarg\keywordfalse + \allowcodebreaksfalse + \else + \errhelp = \EMsimple + \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}% + \fi\fi +} + +% For @command, @env, @file, @option quotes seem unnecessary, +% so use \code rather than \samp. +\let\command=\code +\let\env=\code +\let\file=\code +\let\option=\code + +% @uref (abbreviation for `urlref') takes an optional (comma-separated) +% second argument specifying the text to display and an optional third +% arg as text to display instead of (rather than in addition to) the url +% itself. First (mandatory) arg is the url. +% (This \urefnobreak definition isn't used now, leaving it for a while +% for comparison.) +\def\urefnobreak#1{\dourefnobreak #1,,,\finish} +\def\dourefnobreak#1,#2,#3,#4\finish{\begingroup + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \code{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% This \urefbreak definition is the active one. +\def\urefbreak{\begingroup \urefcatcodes \dourefbreak} +\let\uref=\urefbreak +\def\dourefbreak#1{\urefbreakfinish #1,,,\finish} +\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \urefcode{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% Allow line breaks around only a few characters (only). +\def\urefcatcodes{% + \catcode\ampChar=\active \catcode\dotChar=\active + \catcode\hashChar=\active \catcode\questChar=\active + \catcode\slashChar=\active +} +{ + \urefcatcodes + % + \global\def\urefcode{\begingroup + \setupmarkupstyle{code}% + \urefcatcodes + \let&\urefcodeamp + \let.\urefcodedot + \let#\urefcodehash + \let?\urefcodequest + \let/\urefcodeslash + \codex + } + % + % By default, they are just regular characters. + \global\def&{\normalamp} + \global\def.{\normaldot} + \global\def#{\normalhash} + \global\def?{\normalquest} + \global\def/{\normalslash} +} + +% we put a little stretch before and after the breakable chars, to help +% line breaking of long url's. The unequal skips make look better in +% cmtt at least, especially for dots. +\def\urefprestretch{\urefprebreak \hskip0pt plus.13em } +\def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em } +% +\def\urefcodeamp{\urefprestretch \&\urefpoststretch} +\def\urefcodedot{\urefprestretch .\urefpoststretch} +\def\urefcodehash{\urefprestretch \#\urefpoststretch} +\def\urefcodequest{\urefprestretch ?\urefpoststretch} +\def\urefcodeslash{\futurelet\next\urefcodeslashfinish} +{ + \catcode`\/=\active + \global\def\urefcodeslashfinish{% + \urefprestretch \slashChar + % Allow line break only after the final / in a sequence of + % slashes, to avoid line break between the slashes in http://. + \ifx\next/\else \urefpoststretch \fi + } +} + +% One more complication: by default we'll break after the special +% characters, but some people like to break before the special chars, so +% allow that. Also allow no breaking at all, for manual control. +% +\parseargdef\urefbreakstyle{% + \def\txiarg{#1}% + \ifx\txiarg\wordnone + \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordbefore + \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordafter + \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak} + \else + \errhelp = \EMsimple + \errmessage{Unknown @urefbreakstyle setting `\txiarg'}% + \fi\fi\fi +} +\def\wordafter{after} +\def\wordbefore{before} +\def\wordnone{none} + +\urefbreakstyle after + +% @url synonym for @uref, since that's how everyone uses it. +% +\let\url=\uref + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \let\email=\uref +\fi + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\parseargdef\kbdinputstyle{% + \def\txiarg{#1}% + \ifx\txiarg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\txiarg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\txiarg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \else + \errhelp = \EMsimple + \errmessage{Unknown @kbdinputstyle setting `\txiarg'}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is `distinct'. +\kbdinputstyle distinct + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. +\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} + +\def\xkey{\key} +\def\kbdsub#1#2#3\par{% + \def\one{#1}\def\three{#3}\def\threex{??}% + \ifx\one\xkey\ifx\threex\three \key{#2}% + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi +} + +% definition of @key that produces a lozenge. Doesn't adjust to text size. +%\setfont\keyrm\rmshape{8}{1000}{OT1} +%\font\keysy=cmsy9 +%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% +% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% +% \vbox{\hrule\kern-0.4pt +% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% +% \kern-0.4pt\hrule}% +% \kern-.06em\raise0.4pt\hbox{\angleright}}}} + +% definition of @key with no lozenge. If the current font is already +% monospace, don't change it; that way, we respect @kbdinputstyle. But +% if it isn't monospace, then use \tt. +% +\def\key#1{{\setupmarkupstyle{key}% + \nohyphenation + \ifmonospace\else\tt\fi + #1}\null} + +% @clicksequence{File @click{} Open ...} +\def\clicksequence#1{\begingroup #1\endgroup} + +% @clickstyle @arrow (by default) +\parseargdef\clickstyle{\def\click{#1}} +\def\click{\arrow} + +% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. +% +\def\dmn#1{\thinspace #1} + +% @l was never documented to mean ``switch to the Lisp font'', +% and it is not used as such in any manual I can find. We need it for +% Polish suppressed-l. --karl, 22sep96. +%\def\l#1{{\li #1}\null} + +% @acronym for "FBI", "NATO", and the like. +% We print this one point size smaller, since it's intended for +% all-uppercase. +% +\def\acronym#1{\doacronym #1,,\finish} +\def\doacronym#1,#2,#3\finish{% + {\selectfonts\lsize #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 +} + +% @abbr for "Comput. J." and the like. +% No font change, but don't do end-of-sentence spacing. +% +\def\abbr#1{\doabbr #1,,\finish} +\def\doabbr#1,#2,#3\finish{% + {\plainfrenchspacing #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 +} + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math outputs its argument in math mode. +% +% One complication: _ usually means subscripts, but it could also mean +% an actual _ character, as in @math{@var{some_variable} + 1}. So make +% _ active, and distinguish by seeing if the current family is \slfam, +% which is what @var uses. +{ + \catcode`\_ = \active + \gdef\mathunderscore{% + \catcode`\_=\active + \def_{\ifnum\fam=\slfam \_\else\sb\fi}% + } +} +% Another complication: we want \\ (and @\) to output a math (or tt) \. +% FYI, plain.tex uses \\ as a temporary control sequence (for no +% particular reason), but this is not advertised and we don't care. +% +% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. +\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} +% +\def\math{% + \tex + \mathunderscore + \let\\ = \mathbackslash + \mathactive + % make the texinfo accent commands work in math mode + \let\"=\ddot + \let\'=\acute + \let\==\bar + \let\^=\hat + \let\`=\grave + \let\u=\breve + \let\v=\check + \let\~=\tilde + \let\dotaccent=\dot + $\finishmath +} +\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. + +% Some active characters (such as <) are spaced differently in math. +% We have to reset their definitions in case the @math was an argument +% to a command which sets the catcodes (such as @item or @section). +% +{ + \catcode`^ = \active + \catcode`< = \active + \catcode`> = \active + \catcode`+ = \active + \catcode`' = \active + \gdef\mathactive{% + \let^ = \ptexhat + \let< = \ptexless + \let> = \ptexgtr + \let+ = \ptexplus + \let' = \ptexquoteright + } +} + +% ctrl is no longer a Texinfo command, but leave this definition for fun. +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + +% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. +% Ignore unless FMTNAME == tex; then it is like @iftex and @tex, +% except specified as a normal braced arg, so no newlines to worry about. +% +\def\outfmtnametex{tex} +% +\long\def\inlinefmt#1{\doinlinefmt #1,\finish} +\long\def\doinlinefmt#1,#2,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi +} +% For raw, must switch into @tex before parsing the argument, to avoid +% setting catcodes prematurely. Doing it this way means that, for +% example, @inlineraw{html, foo{bar} gets a parse error instead of being +% ignored. But this isn't important because if people want a literal +% *right* brace they would have to use a command anyway, so they may as +% well use a command to get a left brace too. We could re-use the +% delimiter character idea from \verb, but it seems like overkill. +% +\long\def\inlineraw{\tex \doinlineraw} +\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish} +\def\doinlinerawtwo#1,#2,\finish{% + \def\inlinerawname{#1}% + \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi + \endgroup % close group opened by \tex. +} + + +\message{glyphs,} +% and logos. + +% @@ prints an @, as does @atchar{}. +\def\@{\char64 } +\let\atchar=\@ + +% @{ @} @lbracechar{} @rbracechar{} all generate brace characters. +% Unless we're in typewriter, use \ecfont because the CM text fonts do +% not have braces, and we don't want to switch into math. +\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}} +\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}} +\let\{=\mylbrace \let\lbracechar=\{ +\let\}=\myrbrace \let\rbracechar=\} +\begingroup + % Definitions to produce \{ and \} commands for indices, + % and @{ and @} for the aux/toc files. + \catcode`\{ = \other \catcode`\} = \other + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\! = 0 \catcode`\\ = \other + !gdef!lbracecmd[\{]% + !gdef!rbracecmd[\}]% + !gdef!lbraceatcmd[@{]% + !gdef!rbraceatcmd[@}]% +!endgroup + +% @comma{} to avoid , parsing problems. +\let\comma = , + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. +\let\, = \ptexc +\let\dotaccent = \ptexdot +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \ptext +\let\ubaraccent = \ptexb +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown @ordf @ordm +% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} +\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} +\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi + \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% The \TeX{} logo, as in plain, but resetting the spacing so that a +% period following counts as ending a sentence. (Idea found in latex.) +% +\edef\TeX{\TeX \spacefactor=1000 } + +% @LaTeX{} logo. Not quite the same results as the definition in +% latex.ltx, since we use a different font for the raised A; it's most +% convenient for us to use an explicitly smaller font, rather than using +% the \scriptstyle font (since we don't reset \scriptstyle and +% \scriptscriptstyle). +% +\def\LaTeX{% + L\kern-.36em + {\setbox0=\hbox{T}% + \vbox to \ht0{\hbox{% + \ifx\textnominalsize\xwordpt + % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX. + % Revert to plain's \scriptsize, which is 7pt. + \count255=\the\fam $\fam\count255 \scriptstyle A$% + \else + % For 11pt, we can use our lllsize. + \selectfonts\lllsize A% + \fi + }% + \vss + }}% + \kern-.15em + \TeX +} + +% Some math mode symbols. +\def\bullet{$\ptexbullet$} +\def\geq{\ifmmode \ge\else $\ge$\fi} +\def\leq{\ifmmode \le\else $\le$\fi} +\def\minus{\ifmmode -\else $-$\fi} + +% @dots{} outputs an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in the cm +% typewriter fonts as three actual period characters; on the other hand, +% in other typewriter fonts three periods are wider than 1.5em. So do +% whichever is larger. +% +\def\dots{% + \leavevmode + \setbox0=\hbox{...}% get width of three periods + \ifdim\wd0 > 1.5em + \dimen0 = \wd0 + \else + \dimen0 = 1.5em + \fi + \hbox to \dimen0{% + \hskip 0pt plus.25fil + .\hskip 0pt plus1fil + .\hskip 0pt plus1fil + .\hskip 0pt plus.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \dots + \spacefactor=\endofsentencespacefactor +} + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +% +% Since these characters are used in examples, they should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% +\def\point{$\star$} +\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}} +\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}} + +% The @error{} command. +% Adapted from the TeXbook's \boxit. +% +\newbox\errorbox +% +{\tentt \global\dimen0 = 3em}% Width of the box. +\dimen2 = .55pt % Thickness of rules +% The text. (`r' is open on the right, `e' somewhat less so on the left.) +\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt} +% +\setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{% + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} +% +\def\error{\leavevmode\lower.7ex\copy\errorbox} + +% @pounds{} is a sterling sign, which Knuth put in the CM italic font. +% +\def\pounds{{\it\$}} + +% @euro{} comes from a separate font, depending on the current style. +% We use the free feym* fonts from the eurosym package by Henrik +% Theiling, which support regular, slanted, bold and bold slanted (and +% "outlined" (blackboard board, sort of) versions, which we don't need). +% It is available from http://www.ctan.org/tex-archive/fonts/eurosym. +% +% Although only regular is the truly official Euro symbol, we ignore +% that. The Euro is designed to be slightly taller than the regular +% font height. +% +% feymr - regular +% feymo - slanted +% feybr - bold +% feybo - bold slanted +% +% There is no good (free) typewriter version, to my knowledge. +% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide. +% Hmm. +% +% Also doesn't work in math. Do we need to do math with euro symbols? +% Hope not. +% +% +\def\euro{{\eurofont e}} +\def\eurofont{% + % We set the font at each command, rather than predefining it in + % \textfonts and the other font-switching commands, so that + % installations which never need the symbol don't have to have the + % font installed. + % + % There is only one designed size (nominal 10pt), so we always scale + % that to the current nominal size. + % + % By the way, simply using "at 1em" works for cmr10 and the like, but + % does not work for cmbx10 and other extended/shrunken fonts. + % + \def\eurosize{\csname\curfontsize nominalsize\endcsname}% + % + \ifx\curfontstyle\bfstylename + % bold: + \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize + \else + % regular: + \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize + \fi + \thiseurofont +} + +% Glyphs from the EC fonts. We don't use \let for the aliases, because +% sometimes we redefine the original macro, and the alias should reflect +% the redefinition. +% +% Use LaTeX names for the Icelandic letters. +\def\DH{{\ecfont \char"D0}} % Eth +\def\dh{{\ecfont \char"F0}} % eth +\def\TH{{\ecfont \char"DE}} % Thorn +\def\th{{\ecfont \char"FE}} % thorn +% +\def\guillemetleft{{\ecfont \char"13}} +\def\guillemotleft{\guillemetleft} +\def\guillemetright{{\ecfont \char"14}} +\def\guillemotright{\guillemetright} +\def\guilsinglleft{{\ecfont \char"0E}} +\def\guilsinglright{{\ecfont \char"0F}} +\def\quotedblbase{{\ecfont \char"12}} +\def\quotesinglbase{{\ecfont \char"0D}} +% +% This positioning is not perfect (see the ogonek LaTeX package), but +% we have the precomposed glyphs for the most common cases. We put the +% tests to use those glyphs in the single \ogonek macro so we have fewer +% dummy definitions to worry about for index entries, etc. +% +% ogonek is also used with other letters in Lithuanian (IOU), but using +% the precomposed glyphs for those is not so easy since they aren't in +% the same EC font. +\def\ogonek#1{{% + \def\temp{#1}% + \ifx\temp\macrocharA\Aogonek + \else\ifx\temp\macrochara\aogonek + \else\ifx\temp\macrocharE\Eogonek + \else\ifx\temp\macrochare\eogonek + \else + \ecfont \setbox0=\hbox{#1}% + \ifdim\ht0=1ex\accent"0C #1% + \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}% + \fi + \fi\fi\fi\fi + }% +} +\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A} +\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a} +\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E} +\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e} +% +% Use the ec* fonts (cm-super in outline format) for non-CM glyphs. +\def\ecfont{% + % We can't distinguish serif/sans and italic/slanted, but this + % is used for crude hacks anyway (like adding French and German + % quotes to documents typeset with CM, where we lose kerning), so + % hopefully nobody will notice/care. + \edef\ecsize{\csname\curfontsize ecsize\endcsname}% + \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% + \ifmonospace + % typewriter: + \font\thisecfont = ectt\ecsize \space at \nominalsize + \else + \ifx\curfontstyle\bfstylename + % bold: + \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize + \else + % regular: + \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \fi + \fi + \thisecfont +} + +% @registeredsymbol - R in a circle. The font for the R should really +% be smaller yet, but lllsize is the best we can do for now. +% Adapted from the plain.tex definition of \copyright. +% +\def\registeredsymbol{% + $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}% + \hfil\crcr\Orb}}% + }$% +} + +% @textdegree - the normal degrees sign. +% +\def\textdegree{$^\circ$} + +% Laurent Siebenmann reports \Orb undefined with: +% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 +% so we'll define it if necessary. +% +\ifx\Orb\thisisundefined +\def\Orb{\mathhexbox20D} +\fi + +% Quotes. +\chardef\quotedblleft="5C +\chardef\quotedblright=`\" +\chardef\quoteleft=`\` +\chardef\quoteright=`\' + + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\newif\ifseenauthor +\newif\iffinishedtitlepage + +% Do an implicit @contents or @shortcontents after @end titlepage if the +% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. +% +\newif\ifsetcontentsaftertitlepage + \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue +\newif\ifsetshortcontentsaftertitlepage + \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue + +\parseargdef\shorttitlepage{% + \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + +\envdef\titlepage{% + % Open one extra group, as we want to close it in the middle of \Etitlepage. + \begingroup + \parindent=0pt \textfonts + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \let\page = \oldpage + \page + \null + }% +} + +\def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + % + % Need this before the \...aftertitlepage checks so that if they are + % in effect the toc pages will come out with page numbers. + \HEADINGSon + % + % If they want short, they certainly want long too. + \ifsetshortcontentsaftertitlepage + \shortcontents + \contents + \global\let\shortcontents = \relax + \global\let\contents = \relax + \fi + % + \ifsetcontentsaftertitlepage + \contents + \global\let\contents = \relax + \global\let\shortcontents = \relax + \fi +} + +\def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue +} + +% Settings used for typesetting titles: no hyphenation, no indentation, +% don't worry much about spacing, ragged right. This should be used +% inside a \vbox, and fonts need to be set appropriately first. Because +% it is always used for titles, nothing else, we call \rmisbold. \par +% should be specified before the end of the \vbox, since a vbox is a group. +% +\def\raggedtitlesettings{% + \rmisbold + \hyphenpenalty=10000 + \parindent=0pt + \tolerance=5000 + \ptexraggedright +} + +% Macros to be used within @titlepage: + +\let\subtitlerm=\tenrm +\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} + +\parseargdef\title{% + \checkenv\titlepage + \vbox{\titlefonts \raggedtitlesettings #1\par}% + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt +} + +\parseargdef\subtitle{% + \checkenv\titlepage + {\subtitlefont \rightline{#1}}% +} + +% @author should come last, but may come many times. +% It can also be used inside @quotation. +% +\parseargdef\author{% + \def\temp{\quotation}% + \ifx\thisenv\temp + \def\quotationauthor{#1}% printed in \Equotation. + \else + \checkenv\titlepage + \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi + {\secfonts\rmisbold \leftline{#1}}% + \fi +} + + +% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks\evenheadline % headline on even pages +\newtoks\oddheadline % headline on odd pages +\newtoks\evenfootline % footline on even pages +\newtoks\oddfootline % footline on odd pages + +% Now make TeX use those variables +\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} +\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} +\let\HEADINGShook=\relax + +% Commands to set those variables. +% For example, this is what @headings on does +% @evenheading @thistitle|@thispage|@thischapter +% @oddheading @thischapter|@thispage|@thistitle +% @evenfooting @thisfile|| +% @oddfooting ||@thisfile + + +\def\evenheading{\parsearg\evenheadingxxx} +\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish} +\def\evenheadingyyy #1\|#2\|#3\|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\def\oddheading{\parsearg\oddheadingxxx} +\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish} +\def\oddheadingyyy #1\|#2\|#3\|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish} +\def\evenfootingyyy #1\|#2\|#3\|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\def\oddfooting{\parsearg\oddfootingxxx} +\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish} +\def\oddfootingyyy #1\|#2\|#3\|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\pageheight by -12pt + \global\advance\vsize by -12pt +} + +\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}} + +% @evenheadingmarks top \thischapter <- chapter at the top of a page +% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page +% +% The same set of arguments for: +% +% @oddheadingmarks +% @evenfootingmarks +% @oddfootingmarks +% @everyheadingmarks +% @everyfootingmarks + +\def\evenheadingmarks{\headingmarks{even}{heading}} +\def\oddheadingmarks{\headingmarks{odd}{heading}} +\def\evenfootingmarks{\headingmarks{even}{footing}} +\def\oddfootingmarks{\headingmarks{odd}{footing}} +\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1} + \headingmarks{odd}{heading}{#1} } +\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1} + \headingmarks{odd}{footing}{#1} } +% #1 = even/odd, #2 = heading/footing, #3 = top/bottom. +\def\headingmarks#1#2#3 {% + \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname + \global\expandafter\let\csname get#1#2marks\endcsname \temp +} + +\everyheadingmarks bottom +\everyfootingmarks bottom + +% @headings double turns headings on for double-sided printing. +% @headings single turns headings on for single-sided printing. +% @headings off turns them off. +% @headings on same as @headings double, retained for compatibility. +% @headings after turns on double-sided headings after this page. +% @headings doubleafter turns on double-sided headings after this page. +% @headings singleafter turns on single-sided headings after this page. +% By default, they are off at the start of a document, +% and turned `on' after @end titlepage. + +\def\headings #1 {\csname HEADINGS#1\endcsname} + +\def\headingsoff{% non-global headings elimination + \evenheadline={\hfil}\evenfootline={\hfil}% + \oddheadline={\hfil}\oddfootline={\hfil}% +} + +\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting +\HEADINGSoff % it's the default + +% When we turn headings on, set the page number to 1. +% For double-sided printing, put current file name in lower left corner, +% chapter name on inside top of right hand pages, document +% title on inside top of left hand pages, and page numbers on outside top +% edge of all pages. +\def\HEADINGSdouble{% +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} +\let\contentsalignmacro = \chappager + +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{% +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} +\def\HEADINGSon{\HEADINGSdouble} + +\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} +\let\HEADINGSdoubleafter=\HEADINGSafter +\def\HEADINGSdoublex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} + +\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +\def\HEADINGSsinglex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% Subroutines used in generating headings +% This produces Day Month Year style of output. +% Only define if not already defined, in case a txi-??.tex file has set +% up a different format (e.g., txi-cs.tex does this). +\ifx\today\thisisundefined +\def\today{% + \number\day\space + \ifcase\month + \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr + \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug + \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec + \fi + \space\number\year} +\fi + +% @settitle line... specifies the title of the document, for headings. +% It generates no output of its own. +\def\thistitle{\putwordNoTitle} +\def\settitle{\parsearg{\gdef\thistitle}} + + +\message{tables,} +% Tables -- @table, @ftable, @vtable, @item(x). + +% default indentation of table text +\newdimen\tableindent \tableindent=.8in +% default indentation of @itemize and @enumerate text +\newdimen\itemindent \itemindent=.3in +% margin between end of table item and start of table text. +\newdimen\itemmargin \itemmargin=.1in + +% used internally for \itemindent minus \itemmargin +\newdimen\itemmax + +% Note @table, @ftable, and @vtable define @item, @itemx, etc., with +% these defs. +% They also define \itemindex +% to index the item name in whatever manner is desired (perhaps none). + +\newif\ifitemxneedsnegativevskip + +\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} + +\def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemindicate{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil\relax + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. However, if + % what follows is an environment such as @example, there will be no + % \parskip glue; then the negative vskip we just inserted would + % cause the example and the item to crash together. So we use this + % bizarre value of 10001 as a signal to \aboveenvbreak to insert + % \parskip glue after all. Section titles are handled this way also. + % + \penalty 10001 + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. + \noindent + % Do this with kerns and \unhbox so that if there is a footnote in + % the item text, it can migrate to the main vertical list and + % eventually be printed. + \nobreak\kern-\tableindent + \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 + \unhbox0 + \nobreak\kern\dimen0 + \endgroup + \itemxneedsnegativevskiptrue + \fi +} + +\def\item{\errmessage{@item while not in a list environment}} +\def\itemx{\errmessage{@itemx while not in a list environment}} + +% @table, @ftable, @vtable. +\envdef\table{% + \let\itemindex\gobble + \tablecheck{table}% +} +\envdef\ftable{% + \def\itemindex ##1{\doind {fn}{\code{##1}}}% + \tablecheck{ftable}% +} +\envdef\vtable{% + \def\itemindex ##1{\doind {vr}{\code{##1}}}% + \tablecheck{vtable}% +} +\def\tablecheck#1{% + \ifnum \the\catcode`\^^M=\active + \endgroup + \errmessage{This command won't work in this context; perhaps the problem is + that we are \inenvironment\thisenv}% + \def\next{\doignore{#1}}% + \else + \let\next\tablex + \fi + \next +} +\def\tablex#1{% + \def\itemindicate{#1}% + \parsearg\tabley +} +\def\tabley#1{% + {% + \makevalueexpandable + \edef\temp{\noexpand\tablez #1\space\space\space}% + \expandafter + }\temp \endtablez +} +\def\tablez #1 #2 #3 #4\endtablez{% + \aboveenvbreak + \ifnum 0#1>0 \advance \leftskip by #1\mil \fi + \ifnum 0#2>0 \tableindent=#2\mil \fi + \ifnum 0#3>0 \advance \rightskip by #3\mil \fi + \itemmax=\tableindent + \advance \itemmax by -\itemmargin + \advance \leftskip by \tableindent + \exdentamount=\tableindent + \parindent = 0pt + \parskip = \smallskipamount + \ifdim \parskip=0pt \parskip=2pt \fi + \let\item = \internalBitem + \let\itemx = \internalBitemx +} +\def\Etable{\endgraf\afterenvbreak} +\let\Eftable\Etable +\let\Evtable\Etable +\let\Eitemize\Etable +\let\Eenumerate\Etable + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\envdef\itemize{\parsearg\doitemize} + +\def\doitemize#1{% + \aboveenvbreak + \itemmax=\itemindent + \advance\itemmax by -\itemmargin + \advance\leftskip by \itemindent + \exdentamount=\itemindent + \parindent=0pt + \parskip=\smallskipamount + \ifdim\parskip=0pt \parskip=2pt \fi + % + % Try typesetting the item mark that if the document erroneously says + % something like @itemize @samp (intending @table), there's an error + % right away at the @itemize. It's not the best error message in the + % world, but it's better than leaving it to the @item. This means if + % the user wants an empty mark, they have to say @w{} not just @w. + \def\itemcontents{#1}% + \setbox0 = \hbox{\itemcontents}% + % + % @itemize with no arg is equivalent to @itemize @bullet. + \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi + % + \let\item=\itemizeitem +} + +% Definition of @item while inside @itemize and @enumerate. +% +\def\itemizeitem{% + \advance\itemno by 1 % for enumerations + {\let\par=\endgraf \smallbreak}% reasonable place to break + {% + % If the document has an @itemize directly after a section title, a + % \nobreak will be last on the list, and \sectionheading will have + % done a \vskip-\parskip. In that case, we don't want to zero + % parskip, or the item text will crash with the heading. On the + % other hand, when there is normal text preceding the item (as there + % usually is), we do want to zero parskip, or there would be too much + % space. In that case, we won't have a \nobreak before. At least + % that's the theory. + \ifnum\lastpenalty<10000 \parskip=0in \fi + \noindent + \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% + % + \vadjust{\penalty 1200}}% not good to break after first line of item. + \flushcr +} + +% \splitoff TOKENS\endmark defines \first to be the first token in +% TOKENS, and \rest to be the remainder. +% +\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + +% Allow an optional argument of an uppercase letter, lowercase letter, +% or number, to specify the first label in the enumerated list. No +% argument is the same as `1'. +% +\envparseargdef\enumerate{\enumeratey #1 \endenumeratey} +\def\enumeratey #1 #2\endenumeratey{% + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a . + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi +} + +% An @enumerate whose labels are integers. The starting integer is +% given in \thearg. +% +\def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% +} + +% The starting (lowercase) letter is in \thearg. +\def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% +} + +% The starting (uppercase) letter is in \thearg. +\def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% +} + +% Call \doitemize, adding a period to the first argument and supplying the +% common last two arguments. Also subtract one from the initial value in +% \itemno, since @item increments \itemno. +% +\def\startenumeration#1{% + \advance\itemno by -1 + \doitemize{#1.}\flushcr +} + +% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +% to @enumerate. +% +\def\alphaenumerate{\enumerate{a}} +\def\capsenumerate{\enumerate{A}} +\def\Ealphaenumerate{\Eenumerate} +\def\Ecapsenumerate{\Eenumerate} + + +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab do not need to be on their own lines, but it will not hurt +% if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. +% +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +% Macros used to set up halign preamble: +% +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +% #1 is the @columnfraction, usually a decimal number like .5, but might +% be just 1. We just use it, whatever it is. +% +\def\pickupwholefraction#1 {% + \global\advance\colcount by 1 + \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}% + \setuptable +} + +\newcount\colcount +\def\setuptable#1{% + \def\firstarg{#1}% + \ifx\firstarg\xendsetuptable + \let\go = \relax + \else + \ifx\firstarg\xcolumnfractions + \global\setpercenttrue + \else + \ifsetpercent + \let\go\pickupwholefraction + \else + \global\advance\colcount by 1 + \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a + % separator; typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi + \fi + \ifx\go\pickupwholefraction + % Put the argument back for the \pickupwholefraction call, so + % we'll always have a period there to be parsed. + \def\go{\pickupwholefraction#1}% + \else + \let\go = \setuptable + \fi% + \fi + \go +} + +% multitable-only commands. +% +% @headitem starts a heading row, which we typeset in bold. +% Assignments have to be global since we are inside the implicit group +% of an alignment entry. \everycr resets \everytab so we don't have to +% undo it ourselves. +\def\headitemfont{\b}% for people to use in the template row; not changeable +\def\headitem{% + \checkenv\multitable + \crcr + \global\everytab={\bf}% can't use \headitemfont since the parsing differs + \the\everytab % for the first item +}% +% +% A \tab used to include \hskip1sp. But then the space in a template +% line is not enough. That is bad. So let's go back to just `&' until +% we again encounter the problem the 1sp was intended to solve. +% --karl, nathan@acm.org, 20apr99. +\def\tab{\checkenv\multitable &\the\everytab}% + +% @multitable ... @end multitable definitions: +% +\newtoks\everytab % insert after every tab. +% +\envdef\multitable{% + \vskip\parskip + \startsavinginserts + % + % @item within a multitable starts a normal row. + % We use \def instead of \let so that if one of the multitable entries + % contains an @itemize, we don't choke on the \item (seen as \crcr aka + % \endtemplate) expanding \doitemize. + \def\item{\crcr}% + % + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + % + \everycr = {% + \noalign{% + \global\everytab={}% + \global\colcount=0 % Reset the column counter. + % Check for saved footnotes, etc. + \checkinserts + % Keeps underfull box messages off when table breaks over pages. + %\filbreak + % Maybe so, but it also creates really weird page breaks when the + % table breaks over pages. Wouldn't \vfil be better? Wait until the + % problem manifests itself, so it can be fixed for real --karl. + }% + }% + % + \parsearg\domultitable +} +\def\domultitable#1{% + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. + \halign\bgroup &% + \global\advance\colcount by 1 + \multistrut + \vtop{% + % Use the current \colcount to find the correct column width: + \hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively + % marking characters. + \noindent\ignorespaces##\unskip\multistrut + }\cr +} +\def\Emultitable{% + \crcr + \egroup % end the \halign + \global\setpercentfalse +} + +\def\setmultitablespacing{% + \def\multistrut{\strut}% just use the standard line spacing + % + % Compute \multitablelinespace (if not defined by user) for use in + % \multitableparskip calculation. We used define \multistrut based on + % this, but (ironically) that caused the spacing to be off. + % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100. +\ifdim\multitablelinespace=0pt +\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip +\global\advance\multitablelinespace by-\ht0 +\fi +% Test to see if parskip is larger than space between lines of +% table. If not, do nothing. +% If so, set to same dimension as multitablelinespace. +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. +\fi} + + +\message{conditionals,} + +% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext, +% @ifnotxml always succeed. They currently do nothing; we don't +% attempt to check whether the conditionals are properly nested. But we +% have to remember that they are conditionals, so that @end doesn't +% attempt to close an environment group. +% +\def\makecond#1{% + \expandafter\let\csname #1\endcsname = \relax + \expandafter\let\csname iscond.#1\endcsname = 1 +} +\makecond{iftex} +\makecond{ifnotdocbook} +\makecond{ifnothtml} +\makecond{ifnotinfo} +\makecond{ifnotplaintext} +\makecond{ifnotxml} + +% Ignore @ignore, @ifhtml, @ifinfo, and the like. +% +\def\direntry{\doignore{direntry}} +\def\documentdescription{\doignore{documentdescription}} +\def\docbook{\doignore{docbook}} +\def\html{\doignore{html}} +\def\ifdocbook{\doignore{ifdocbook}} +\def\ifhtml{\doignore{ifhtml}} +\def\ifinfo{\doignore{ifinfo}} +\def\ifnottex{\doignore{ifnottex}} +\def\ifplaintext{\doignore{ifplaintext}} +\def\ifxml{\doignore{ifxml}} +\def\ignore{\doignore{ignore}} +\def\menu{\doignore{menu}} +\def\xml{\doignore{xml}} + +% Ignore text until a line `@end #1', keeping track of nested conditionals. +% +% A count to remember the depth of nesting. +\newcount\doignorecount + +\def\doignore#1{\begingroup + % Scan in ``verbatim'' mode: + \obeylines + \catcode`\@ = \other + \catcode`\{ = \other + \catcode`\} = \other + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \spaceisspace + % + % Count number of #1's that we've seen. + \doignorecount = 0 + % + % Swallow text until we reach the matching `@end #1'. + \dodoignore{#1}% +} + +{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source. + \obeylines % + % + \gdef\dodoignore#1{% + % #1 contains the command name as a string, e.g., `ifinfo'. + % + % Define a command to find the next `@end #1'. + \long\def\doignoretext##1^^M@end #1{% + \doignoretextyyy##1^^M@#1\_STOP_}% + % + % And this command to find another #1 command, at the beginning of a + % line. (Otherwise, we would consider a line `@c @ifset', for + % example, to count as an @ifset for nesting.) + \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}% + % + % And now expand that command. + \doignoretext ^^M% + }% +} + +\def\doignoreyyy#1{% + \def\temp{#1}% + \ifx\temp\empty % Nothing found. + \let\next\doignoretextzzz + \else % Found a nested condition, ... + \advance\doignorecount by 1 + \let\next\doignoretextyyy % ..., look for another. + % If we're here, #1 ends with ^^M\ifinfo (for example). + \fi + \next #1% the token \_STOP_ is present just after this macro. +} + +% We have to swallow the remaining "\_STOP_". +% +\def\doignoretextzzz#1{% + \ifnum\doignorecount = 0 % We have just found the outermost @end. + \let\next\enddoignore + \else % Still inside a nested condition. + \advance\doignorecount by -1 + \let\next\doignoretext % Look for the next @end. + \fi + \next +} + +% Finish off ignored text. +{ \obeylines% + % Ignore anything after the last `@end #1'; this matters in verbatim + % environments, where otherwise the newline after an ignored conditional + % would result in a blank line in the output. + \gdef\enddoignore#1^^M{\endgroup\ignorespaces}% +} + + +% @set VAR sets the variable VAR to an empty value. +% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +% +% Since we want to separate VAR from REST-OF-LINE (which might be +% empty), we can't just use \parsearg; we have to insert a space of our +% own to delimit the rest of the line, and then take it out again if we +% didn't need it. +% We rely on the fact that \parsearg sets \catcode`\ =10. +% +\parseargdef\set{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + {% + \makevalueexpandable + \def\temp{#2}% + \edef\next{\gdef\makecsname{SET#1}}% + \ifx\temp\empty + \next{}% + \else + \setzzz#2\endsetzzz + \fi + }% +} +% Remove the trailing space \setxxx inserted. +\def\setzzz#1 \endsetzzz{\next{#1}} + +% @clear VAR clears (i.e., unsets) the variable VAR. +% +\parseargdef\clear{% + {% + \makevalueexpandable + \global\expandafter\let\csname SET#1\endcsname=\relax + }% +} + +% @value{foo} gets the text saved in variable foo. +\def\value{\begingroup\makevalueexpandable\valuexxx} +\def\valuexxx#1{\expandablevalue{#1}\endgroup} +{ + \catcode`\- = \active \catcode`\_ = \active + % + \gdef\makevalueexpandable{% + \let\value = \expandablevalue + % We don't want these characters active, ... + \catcode`\-=\other \catcode`\_=\other + % ..., but we might end up with active ones in the argument if + % we're called from @code, as @code{@value{foo-bar_}}, though. + % So \let them to their normal equivalents. + \let-\realdash \let_\normalunderscore + } +} + +% We have this subroutine so that we can handle at least some @value's +% properly in indexes (we call \makevalueexpandable in \indexdummies). +% The command has to be fully expandable (if the variable is set), since +% the result winds up in the index file. This means that if the +% variable's value contains other Texinfo commands, it's almost certain +% it will fail (although perhaps we could fix that with sufficient work +% to do a one-level expansion on the result, instead of complete). +% +\def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% + \message{Variable `#1', used in @value, is not set.}% + \else + \csname SET#1\endcsname + \fi +} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +% To get special treatment of `@end ifset,' call \makeond and the redefine. +% +\makecond{ifset} +\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} +\def\doifset#1#2{% + {% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname SET#2\endcsname\relax + #1% If not set, redefine \next. + \fi + \expandafter + }\next +} +\def\ifsetfail{\doignore{ifset}} + +% @ifclear VAR ... @end executes the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +% The `\else' inside the `\doifset' parameter is a trick to reuse the +% above code: if the variable is not set, do nothing, if it is set, +% then redefine \next to \ifclearfail. +% +\makecond{ifclear} +\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} +\def\ifclearfail{\doignore{ifclear}} + +% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written +% without the @) is in fact defined. We can only feasibly check at the +% TeX level, so something like `mathcode' is going to considered +% defined even though it is not a Texinfo command. +% +\makecond{ifcommanddefined} +\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} +% +\def\doifcmddefined#1#2{{% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname #2\endcsname\relax + #1% If not defined, \let\next as above. + \fi + \expandafter + }\next +} +\def\ifcmddefinedfail{\doignore{ifcommanddefined}} + +% @ifcommandnotdefined CMD ... handled similar to @ifclear above. +\makecond{ifcommandnotdefined} +\def\ifcommandnotdefined{% + \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} +\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} + +% Set the `txicommandconditionals' variable, so documents have a way to +% test if the @ifcommand...defined conditionals are available. +\set txicommandconditionals + +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory=\comment + +% @defininfoenclose. +\let\definfoenclose=\comment + + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within macros and \if's. +\edef\newwrite{\makecsname{ptexnewwrite}} + +% \newindex {foo} defines an index named foo. +% It automatically defines \fooindex such that +% \fooindex ...rest of line... puts an entry in the index foo. +% It also defines \fooindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is foo. +% The name of an index should be no more than 2 characters long +% for the sake of vms. +% +\def\newindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 % Open the file + \fi + \expandafter\xdef\csname#1index\endcsname{% % Define @#1index + \noexpand\doindex{#1}} +} + +% @defindex foo == \newindex{foo} +% +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. +% +\def\defcodeindex{\parsearg\newcodeindex} +% +\def\newcodeindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 + \fi + \expandafter\xdef\csname#1index\endcsname{% + \noexpand\docodeindex{#1}}% +} + + +% @synindex foo bar makes index foo feed into index bar. +% Do this instead of @defindex foo if you don't want it as a separate index. +% +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +% +\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} +\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} + +% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), +% #3 the target index (bar). +\def\dosynindex#1#2#3{% + % Only do \closeout if we haven't already done it, else we'll end up + % closing the target index. + \expandafter \ifx\csname donesynindex#2\endcsname \relax + % The \closeout helps reduce unnecessary open files; the limit on the + % Acorn RISC OS is a mere 16 files. + \expandafter\closeout\csname#2indfile\endcsname + \expandafter\let\csname donesynindex#2\endcsname = 1 + \fi + % redefine \fooindfile: + \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname + \expandafter\let\csname#2indfile\endcsname=\temp + % redefine \fooindex: + \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% +} + +% Define \doindex, the driver for all \fooindex macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is "foo", the name of the index. + +% \doindex just uses \parsearg; it calls \doind for the actual work. +% This is because \doind is more useful to call from other macros. + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} +\def\singleindexer #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} +\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} + +% Take care of Texinfo commands that can appear in an index entry. +% Since there are some commands we want to expand, and others we don't, +% we have to laboriously prevent expansion for those that we don't. +% +\def\indexdummies{% + \escapechar = `\\ % use backslash in output files. + \def\@{@}% change to @@ when we switch to @ as escape char in index files. + \def\ {\realbackslash\space }% + % + % Need these unexpandable (because we define \tt as a dummy) + % definitions when @{ or @} appear in index entry text. Also, more + % complicated, when \tex is in effect and \{ is a \delimiter again. + % We can't use \lbracecmd and \rbracecmd because texindex assumes + % braces and backslashes are used only as delimiters. Perhaps we + % should define @lbrace and @rbrace commands a la @comma. + \def\{{{\tt\char123}}% + \def\}{{\tt\char125}}% + % + % I don't entirely understand this, but when an index entry is + % generated from a macro call, the \endinput which \scanmacro inserts + % causes processing to be prematurely terminated. This is, + % apparently, because \indexsorttmp is fully expanded, and \endinput + % is an expandable command. The redefinition below makes \endinput + % disappear altogether for that purpose -- although logging shows that + % processing continues to some further point. On the other hand, it + % seems \endinput does not hurt in the printed index arg, since that + % is still getting written without apparent harm. + % + % Sample source (mac-idx3.tex, reported by Graham Percival to + % help-texinfo, 22may06): + % @macro funindex {WORD} + % @findex xyz + % @end macro + % ... + % @funindex commtest + % + % The above is not enough to reproduce the bug, but it gives the flavor. + % + % Sample whatsit resulting: + % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}} + % + % So: + \let\endinput = \empty + % + % Do the redefinitions. + \commondummies +} + +% For the aux and toc files, @ is the escape character. So we want to +% redefine everything using @ as the escape character (instead of +% \realbackslash, still used for index files). When everything uses @, +% this will be simpler. +% +\def\atdummies{% + \def\@{@@}% + \def\ {@ }% + \let\{ = \lbraceatcmd + \let\} = \rbraceatcmd + % + % Do the redefinitions. + \commondummies + \otherbackslash +} + +% Called from \indexdummies and \atdummies. +% +\def\commondummies{% + % + % \definedummyword defines \#1 as \string\#1\space, thus effectively + % preventing its expansion. This is used only for control words, + % not control letters, because the \space would be incorrect for + % control characters, but is needed to separate the control word + % from whatever follows. + % + % For control letters, we have \definedummyletter, which omits the + % space. + % + % These can be used both for control words that take an argument and + % those that do not. If it is followed by {arg} in the input, then + % that will dutifully get written to the index (or wherever). + % + \def\definedummyword ##1{\def##1{\string##1\space}}% + \def\definedummyletter##1{\def##1{\string##1}}% + \let\definedummyaccent\definedummyletter + % + \commondummiesnofonts + % + \definedummyletter\_% + \definedummyletter\-% + % + % Non-English letters. + \definedummyword\AA + \definedummyword\AE + \definedummyword\DH + \definedummyword\L + \definedummyword\O + \definedummyword\OE + \definedummyword\TH + \definedummyword\aa + \definedummyword\ae + \definedummyword\dh + \definedummyword\exclamdown + \definedummyword\l + \definedummyword\o + \definedummyword\oe + \definedummyword\ordf + \definedummyword\ordm + \definedummyword\questiondown + \definedummyword\ss + \definedummyword\th + % + % Although these internal commands shouldn't show up, sometimes they do. + \definedummyword\bf + \definedummyword\gtr + \definedummyword\hat + \definedummyword\less + \definedummyword\sf + \definedummyword\sl + \definedummyword\tclose + \definedummyword\tt + % + \definedummyword\LaTeX + \definedummyword\TeX + % + % Assorted special characters. + \definedummyword\arrow + \definedummyword\bullet + \definedummyword\comma + \definedummyword\copyright + \definedummyword\registeredsymbol + \definedummyword\dots + \definedummyword\enddots + \definedummyword\entrybreak + \definedummyword\equiv + \definedummyword\error + \definedummyword\euro + \definedummyword\expansion + \definedummyword\geq + \definedummyword\guillemetleft + \definedummyword\guillemetright + \definedummyword\guilsinglleft + \definedummyword\guilsinglright + \definedummyword\lbracechar + \definedummyword\leq + \definedummyword\minus + \definedummyword\ogonek + \definedummyword\pounds + \definedummyword\point + \definedummyword\print + \definedummyword\quotedblbase + \definedummyword\quotedblleft + \definedummyword\quotedblright + \definedummyword\quoteleft + \definedummyword\quoteright + \definedummyword\quotesinglbase + \definedummyword\rbracechar + \definedummyword\result + \definedummyword\textdegree + % + % We want to disable all macros so that they are not expanded by \write. + \macrolist + % + \normalturnoffactive + % + % Handle some cases of @value -- where it does not contain any + % (non-fully-expandable) commands. + \makevalueexpandable +} + +% \commondummiesnofonts: common to \commondummies and \indexnofonts. +% +\def\commondummiesnofonts{% + % Control letters and accents. + \definedummyletter\!% + \definedummyaccent\"% + \definedummyaccent\'% + \definedummyletter\*% + \definedummyaccent\,% + \definedummyletter\.% + \definedummyletter\/% + \definedummyletter\:% + \definedummyaccent\=% + \definedummyletter\?% + \definedummyaccent\^% + \definedummyaccent\`% + \definedummyaccent\~% + \definedummyword\u + \definedummyword\v + \definedummyword\H + \definedummyword\dotaccent + \definedummyword\ogonek + \definedummyword\ringaccent + \definedummyword\tieaccent + \definedummyword\ubaraccent + \definedummyword\udotaccent + \definedummyword\dotless + % + % Texinfo font commands. + \definedummyword\b + \definedummyword\i + \definedummyword\r + \definedummyword\sansserif + \definedummyword\sc + \definedummyword\slanted + \definedummyword\t + % + % Commands that take arguments. + \definedummyword\abbr + \definedummyword\acronym + \definedummyword\anchor + \definedummyword\cite + \definedummyword\code + \definedummyword\command + \definedummyword\dfn + \definedummyword\dmn + \definedummyword\email + \definedummyword\emph + \definedummyword\env + \definedummyword\file + \definedummyword\image + \definedummyword\indicateurl + \definedummyword\inforef + \definedummyword\kbd + \definedummyword\key + \definedummyword\math + \definedummyword\option + \definedummyword\pxref + \definedummyword\ref + \definedummyword\samp + \definedummyword\strong + \definedummyword\tie + \definedummyword\uref + \definedummyword\url + \definedummyword\var + \definedummyword\verb + \definedummyword\w + \definedummyword\xref +} + +% \indexnofonts is used when outputting the strings to sort the index +% by, and when constructing control sequence names. It eliminates all +% control sequences and just writes whatever the best ASCII sort string +% would be for a given command (usually its argument). +% +\def\indexnofonts{% + % Accent commands should become @asis. + \def\definedummyaccent##1{\let##1\asis}% + % We can just ignore other control letters. + \def\definedummyletter##1{\let##1\empty}% + % All control words become @asis by default; overrides below. + \let\definedummyword\definedummyaccent + % + \commondummiesnofonts + % + % Don't no-op \tt, since it isn't a user-level command + % and is used in the definitions of the active chars like <, >, |, etc. + % Likewise with the other plain tex font commands. + %\let\tt=\asis + % + \def\ { }% + \def\@{@}% + \def\_{\normalunderscore}% + \def\-{}% @- shouldn't affect sorting + % + % Unfortunately, texindex is not prepared to handle braces in the + % content at all. So for index sorting, we map @{ and @} to strings + % starting with |, since that ASCII character is between ASCII { and }. + \def\{{|a}% + \def\lbracechar{|a}% + % + \def\}{|b}% + \def\rbracechar{|b}% + % + % Non-English letters. + \def\AA{AA}% + \def\AE{AE}% + \def\DH{DZZ}% + \def\L{L}% + \def\OE{OE}% + \def\O{O}% + \def\TH{ZZZ}% + \def\aa{aa}% + \def\ae{ae}% + \def\dh{dzz}% + \def\exclamdown{!}% + \def\l{l}% + \def\oe{oe}% + \def\ordf{a}% + \def\ordm{o}% + \def\o{o}% + \def\questiondown{?}% + \def\ss{ss}% + \def\th{zzz}% + % + \def\LaTeX{LaTeX}% + \def\TeX{TeX}% + % + % Assorted special characters. + % (The following {} will end up in the sort string, but that's ok.) + \def\arrow{->}% + \def\bullet{bullet}% + \def\comma{,}% + \def\copyright{copyright}% + \def\dots{...}% + \def\enddots{...}% + \def\equiv{==}% + \def\error{error}% + \def\euro{euro}% + \def\expansion{==>}% + \def\geq{>=}% + \def\guillemetleft{<<}% + \def\guillemetright{>>}% + \def\guilsinglleft{<}% + \def\guilsinglright{>}% + \def\leq{<=}% + \def\minus{-}% + \def\point{.}% + \def\pounds{pounds}% + \def\print{-|}% + \def\quotedblbase{"}% + \def\quotedblleft{"}% + \def\quotedblright{"}% + \def\quoteleft{`}% + \def\quoteright{'}% + \def\quotesinglbase{,}% + \def\registeredsymbol{R}% + \def\result{=>}% + \def\textdegree{o}% + % + \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax + \else \indexlquoteignore \fi + % + % We need to get rid of all macros, leaving only the arguments (if present). + % Of course this is not nearly correct, but it is the best we can do for now. + % makeinfo does not expand macros in the argument to @deffn, which ends up + % writing an index entry, and texindex isn't prepared for an index sort entry + % that starts with \. + % + % Since macro invocations are followed by braces, we can just redefine them + % to take a single TeX argument. The case of a macro invocation that + % goes to end-of-line is not handled. + % + \macrolist +} + +% Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us +% ignore left quotes in the sort term. +{\catcode`\`=\active + \gdef\indexlquoteignore{\let`=\empty}} + +\let\indexbackslash=0 %overridden during \printindex. +\let\SETmarginindex=\relax % put index entries in margin (undocumented)? + +% Most index entries go through here, but \dosubind is the general case. +% #1 is the index name, #2 is the entry text. +\def\doind#1#2{\dosubind{#1}{#2}{}} + +% Workhorse for all \fooindexes. +% #1 is name of index, #2 is stuff to put there, #3 is subentry -- +% empty if called from \doind, as we usually are (the main exception +% is with most defuns, which call us directly). +% +\def\dosubind#1#2#3{% + \iflinks + {% + % Store the main index entry text (including the third arg). + \toks0 = {#2}% + % If third arg is present, precede it with a space. + \def\thirdarg{#3}% + \ifx\thirdarg\empty \else + \toks0 = \expandafter{\the\toks0 \space #3}% + \fi + % + \edef\writeto{\csname#1indfile\endcsname}% + % + \safewhatsit\dosubindwrite + }% + \fi +} + +% Write the entry in \toks0 to the index file: +% +\def\dosubindwrite{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% + \fi + % + % Remember, we are within a group. + \indexdummies % Must do this here, since \bf, etc expand at this stage + \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now + % so it will be output as is; and it will print as backslash. + % + % Process the index entry with all font commands turned off, to + % get the string to sort by. + {\indexnofonts + \edef\temp{\the\toks0}% need full expansion + \xdef\indexsorttmp{\temp}% + }% + % + % Set up the complete index entry, with both the sort key and + % the original text, including any font commands. We write + % three arguments to \entry to the .?? file (four in the + % subentry case), texindex reduces to two when writing the .??s + % sorted result. + \edef\temp{% + \write\writeto{% + \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}% + }% + \temp +} + +% Take care of unwanted page breaks/skips around a whatsit: +% +% If a skip is the last thing on the list now, preserve it +% by backing up by \lastskip, doing the \write, then inserting +% the skip again. Otherwise, the whatsit generated by the +% \write or \pdfdest will make \lastskip zero. The result is that +% sequences like this: +% @end defun +% @tindex whatever +% @defun ... +% will have extra space inserted, because the \medbreak in the +% start of the @defun won't see the skip inserted by the @end of +% the previous defun. +% +% But don't do any of this if we're not in vertical mode. We +% don't want to do a \vskip and prematurely end a paragraph. +% +% Avoid page breaks due to these extra skips, too. +% +% But wait, there is a catch there: +% We'll have to check whether \lastskip is zero skip. \ifdim is not +% sufficient for this purpose, as it ignores stretch and shrink parts +% of the skip. The only way seems to be to check the textual +% representation of the skip. +% +% The following is almost like \def\zeroskipmacro{0.0pt} except that +% the ``p'' and ``t'' characters have catcode \other, not 11 (letter). +% +\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname} +% +\newskip\whatsitskip +\newcount\whatsitpenalty +% +% ..., ready, GO: +% +\def\safewhatsit#1{\ifhmode + #1% + \else + % \lastskip and \lastpenalty cannot both be nonzero simultaneously. + \whatsitskip = \lastskip + \edef\lastskipmacro{\the\lastskip}% + \whatsitpenalty = \lastpenalty + % + % If \lastskip is nonzero, that means the last item was a + % skip. And since a skip is discardable, that means this + % -\whatsitskip glue we're inserting is preceded by a + % non-discardable item, therefore it is not a potential + % breakpoint, therefore no \nobreak needed. + \ifx\lastskipmacro\zeroskipmacro + \else + \vskip-\whatsitskip + \fi + % + #1% + % + \ifx\lastskipmacro\zeroskipmacro + % If \lastskip was zero, perhaps the last item was a penalty, and + % perhaps it was >=10000, e.g., a \nobreak. In that case, we want + % to re-insert the same penalty (values >10000 are used for various + % signals); since we just inserted a non-discardable item, any + % following glue (such as a \parskip) would be a breakpoint. For example: + % @deffn deffn-whatever + % @vindex index-whatever + % Description. + % would allow a break between the index-whatever whatsit + % and the "Description." paragraph. + \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi + \else + % On the other hand, if we had a nonzero \lastskip, + % this make-up glue would be preceded by a non-discardable item + % (the whatsit from the \write), so we must insert a \nobreak. + \nobreak\vskip\whatsitskip + \fi +\fi} + +% The index entry written in the file actually looks like +% \entry {sortstring}{page}{topic} +% or +% \entry {sortstring}{page}{topic}{subtopic} +% The texindex program reads in these files and writes files +% containing these kinds of lines: +% \initial {c} +% before the first topic whose initial is c +% \entry {topic}{pagelist} +% for a topic that is used without subtopics +% \primary {topic} +% for the beginning of a topic that is used with subtopics +% \secondary {subtopic}{pagelist} +% for each subtopic. + +% Define the user-accessible indexing commands +% @findex, @vindex, @kindex, @cindex. + +\def\findex {\fnindex} +\def\kindex {\kyindex} +\def\cindex {\cpindex} +\def\vindex {\vrindex} +\def\tindex {\tpindex} +\def\pindex {\pgindex} + +\def\cindexsub {\begingroup\obeylines\cindexsub} +{\obeylines % +\gdef\cindexsub "#1" #2^^M{\endgroup % +\dosubind{cp}{#2}{#1}}} + +% Define the macros used in formatting output of the sorted index material. + +% @printindex causes a particular index (the ??s file) to get printed. +% It does not print any chapter heading (usually an @unnumbered). +% +\parseargdef\printindex{\begingroup + \dobreak \chapheadingskip{10000}% + % + \smallfonts \rm + \tolerance = 9500 + \plainfrenchspacing + \everypar = {}% don't want the \kern\-parindent from indentation suppression. + % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 11 + \openin 1 \jobname.#1s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + \putwordIndexNonexistent + \else + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \temp + \ifeof 1 + \putwordIndexIsEmpty + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\backslashcurfont}% + \catcode`\\ = 0 + \escapechar = `\\ + \begindoublecolumns + \input \jobname.#1s + \enddoublecolumns + \fi + \fi + \closein 1 +\endgroup} + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +\def\initial#1{{% + % Some minor font changes for the special characters. + \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt + % + % Remove any glue we may have, we'll be inserting our own. + \removelastskip + % + % We like breaks before the index initials, so insert a bonus. + \nobreak + \vskip 0pt plus 3\baselineskip + \penalty 0 + \vskip 0pt plus -3\baselineskip + % + % Typeset the initial. Making this add up to a whole number of + % baselineskips increases the chance of the dots lining up from column + % to column. It still won't often be perfect, because of the stretch + % we need before each entry, but it's better. + % + % No shrink because it confuses \balancecolumns. + \vskip 1.67\baselineskip plus .5\baselineskip + \leftline{\secbf #1}% + % Do our best not to break after the initial. + \nobreak + \vskip .33\baselineskip plus .1\baselineskip +}} + +% \entry typesets a paragraph consisting of the text (#1), dot leaders, and +% then page number (#2) flushed to the right margin. It is used for index +% and table of contents entries. The paragraph is indented by \leftskip. +% +% A straightforward implementation would start like this: +% \def\entry#1#2{... +% But this freezes the catcodes in the argument, and can cause problems to +% @code, which sets - active. This problem was fixed by a kludge--- +% ``-'' was active throughout whole index, but this isn't really right. +% The right solution is to prevent \entry from swallowing the whole text. +% --kasal, 21nov03 +\def\entry{% + \begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent = 2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % A bit of stretch before each entry for the benefit of balancing + % columns. + \vskip 0pt plus1pt + % + % When reading the text of entry, convert explicit line breaks + % from @* into spaces. The user might give these in long section + % titles, for instance. + \def\*{\unskip\space\ignorespaces}% + \def\entrybreak{\hfil\break}% + % + % Swallow the left brace of the text (first parameter): + \afterassignment\doentry + \let\temp = +} +\def\entrybreak{\unskip\space\ignorespaces}% +\def\doentry{% + \bgroup % Instead of the swallowed brace. + \noindent + \aftergroup\finishentry + % And now comes the text of the entry. +} +\def\finishentry#1{% + % #1 is the page number. + % + % The following is kludged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \setbox\boxA = \hbox{#1}% + \ifdim\wd\boxA = 0pt + \ % + \else + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ifpdf + \pdfgettoks#1.% + \ \the\toksA + \else + \ #1% + \fi + \fi + \par + \endgroup +} + +% Like plain.tex's \dotfill, except uses up at least 1 em. +\def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill} + +\def\primary #1{\line{#1\hfil}} + +\newskip\secondaryindent \secondaryindent=0.5cm +\def\secondary#1#2{{% + \parfillskip=0in + \parskip=0in + \hangindent=1in + \hangafter=1 + \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + #2 + \fi + \par +}} + +% Define two-column mode, which we use to typeset indexes. +% Adapted from the TeXbook, page 416, which is to say, +% the manmac.tex format used to print the TeXbook itself. +\catcode`\@=11 + +\newbox\partialpage +\newdimen\doublecolumnhsize + +\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % Grab any single-column material above us. + \output = {% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case we just ship out what is in \partialpage with the normal + % output routine. Generally, \partialpage will be empty when this + % runs and this will be a no-op. See the indexspread.tex test case. + \ifvoid\partialpage \else + \onepageout{\pagecontents\partialpage}% + \fi + % + \global\setbox\partialpage = \vbox{% + % Unvbox the main output page. + \unvbox\PAGE + \kern-\topskip \kern\baselineskip + }% + }% + \eject % run that output routine to set \partialpage + % + % Use the double-column output routine for subsequent pages. + \output = {\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it in one place. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +-<1pt) + % as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. (We don't need a separate register here, + % since nobody clobbers \vsize.) + \vsize = 2\vsize +} + +% The double-column output routine for all double-column pages except +% the last. +% +\def\doublecolumnout{% + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@ = \vsize + \divide\dimen@ by 2 + \advance\dimen@ by -\ht\partialpage + % + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \onepageout\pagesofar + \unvbox255 + \penalty\outputpenalty +} +% +% Re-output the contents of the output page -- any previous material, +% followed by the two boxes we just split, in box0 and box2. +\def\pagesofar{% + \unvbox\partialpage + % + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize + \hbox to\pagewidth{\box0\hfil\box2}% +} +% +% All done with double columns. +\def\enddoublecolumns{% + % The following penalty ensures that the page builder is exercised + % _before_ we change the output routine. This is necessary in the + % following situation: + % + % The last section of the index consists only of a single entry. + % Before this section, \pagetotal is less than \pagegoal, so no + % break occurs before the last section starts. However, the last + % section, consisting of \initial and the single \entry, does not + % fit on the page and has to be broken off. Without the following + % penalty the page builder will not be exercised until \eject + % below, and by that time we'll already have changed the output + % routine to the \balancecolumns version, so the next-to-last + % double-column page will be processed with \balancecolumns, which + % is wrong: The two columns will go to the main vertical list, with + % the broken-off section in the recent contributions. As soon as + % the output routine finishes, TeX starts reconsidering the page + % break. The two columns and the broken-off section both fit on the + % page, because the two columns now take up only half of the page + % goal. When TeX sees \eject from below which follows the final + % section, it invokes the new output routine that we've set after + % \balancecolumns below; \onepageout will try to fit the two columns + % and the final section into the vbox of \pageheight (see + % \pagebody), causing an overfull box. + % + % Note that glue won't work here, because glue does not exercise the + % page builder, unlike penalties (see The TeXbook, pp. 280-281). + \penalty0 + % + \output = {% + % Split the last of the double-column material. Leave it on the + % current page, no automatic page break. + \balancecolumns + % + % If we end up splitting too much material for the current page, + % though, there will be another page break right after this \output + % invocation ends. Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. (We hope \balancecolumns will never be + % called on to balance too much material, but if it is, this makes + % the output somewhat more palatable.) + \global\output = {\onepageout{\pagecontents\PAGE}}% + }% + \eject + \endgroup % started in \begindoublecolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize (after the + % \endgroup where \vsize got restored). + \pagegoal = \vsize +} +% +% Called at the end of the double column material. +\def\balancecolumns{% + \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \divide\dimen@ by 2 % target to split to + %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% + \splittopskip = \topskip + % Loop until we get a decent breakpoint. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht3>\dimen@ + \global\advance\dimen@ by 1pt + \repeat + }% + %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% + \setbox0=\vbox to\dimen@{\unvbox1}% + \setbox2=\vbox to\dimen@{\unvbox3}% + % + \pagesofar +} +\catcode`\@ = \other + + +\message{sectioning,} +% Chapters, sections, etc. + +% Let's start with @part. +\outer\parseargdef\part{\partzzz{#1}} +\def\partzzz#1{% + \chapoddpage + \null + \vskip.3\vsize % move it down on the page a bit + \begingroup + \noindent \titlefonts\rmisbold #1\par % the text + \let\lastnode=\empty % no node to associate with + \writetocentry{part}{#1}{}% but put it in the toc + \headingsoff % no headline or footline on the part page + \chapoddpage + \endgroup +} + +% \unnumberedno is an oxymoron. But we count the unnumbered +% sections so that we can refer to them unambiguously in the pdf +% outlines by their "section number". We avoid collisions with chapter +% numbers by starting them at 10000. (If a document ever has 10000 +% chapters, we're in trouble anyway, I'm sure.) +\newcount\unnumberedno \unnumberedno = 10000 +\newcount\chapno +\newcount\secno \secno=0 +\newcount\subsecno \subsecno=0 +\newcount\subsubsecno \subsubsecno=0 + +% This counter is funny since it counts through charcodes of letters A, B, ... +\newcount\appendixno \appendixno = `\@ +% +% \def\appendixletter{\char\the\appendixno} +% We do the following ugly conditional instead of the above simple +% construct for the sake of pdftex, which needs the actual +% letter in the expansion, not just typeset. +% +\def\appendixletter{% + \ifnum\appendixno=`A A% + \else\ifnum\appendixno=`B B% + \else\ifnum\appendixno=`C C% + \else\ifnum\appendixno=`D D% + \else\ifnum\appendixno=`E E% + \else\ifnum\appendixno=`F F% + \else\ifnum\appendixno=`G G% + \else\ifnum\appendixno=`H H% + \else\ifnum\appendixno=`I I% + \else\ifnum\appendixno=`J J% + \else\ifnum\appendixno=`K K% + \else\ifnum\appendixno=`L L% + \else\ifnum\appendixno=`M M% + \else\ifnum\appendixno=`N N% + \else\ifnum\appendixno=`O O% + \else\ifnum\appendixno=`P P% + \else\ifnum\appendixno=`Q Q% + \else\ifnum\appendixno=`R R% + \else\ifnum\appendixno=`S S% + \else\ifnum\appendixno=`T T% + \else\ifnum\appendixno=`U U% + \else\ifnum\appendixno=`V V% + \else\ifnum\appendixno=`W W% + \else\ifnum\appendixno=`X X% + \else\ifnum\appendixno=`Y Y% + \else\ifnum\appendixno=`Z Z% + % The \the is necessary, despite appearances, because \appendixletter is + % expanded while writing the .toc file. \char\appendixno is not + % expandable, thus it is written literally, thus all appendixes come out + % with the same letter (or @) in the toc without it. + \else\char\the\appendixno + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +% Each @chapter defines these (using marks) as the number+name, number +% and name of the chapter. Page headings and footings can use +% these. @section does likewise. +\def\thischapter{} +\def\thischapternum{} +\def\thischaptername{} +\def\thissection{} +\def\thissectionnum{} +\def\thissectionname{} + +\newcount\absseclevel % used to calculate proper heading level +\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count + +% @raisesections: treat @section as chapter, @subsection as section, etc. +\def\raisesections{\global\advance\secbase by -1} +\let\up=\raisesections % original BFox name + +% @lowersections: treat @chapter as section, @section as subsection, etc. +\def\lowersections{\global\advance\secbase by 1} +\let\down=\lowersections % original BFox name + +% we only have subsub. +\chardef\maxseclevel = 3 +% +% A numbered section within an unnumbered changes to unnumbered too. +% To achieve this, remember the "biggest" unnum. sec. we are currently in: +\chardef\unnlevel = \maxseclevel +% +% Trace whether the current chapter is an appendix or not: +% \chapheadtype is "N" or "A", unnumbered chapters are ignored. +\def\chapheadtype{N} + +% Choose a heading macro +% #1 is heading type +% #2 is heading level +% #3 is text for heading +\def\genhead#1#2#3{% + % Compute the abs. sec. level: + \absseclevel=#2 + \advance\absseclevel by \secbase + % Make sure \absseclevel doesn't fall outside the range: + \ifnum \absseclevel < 0 + \absseclevel = 0 + \else + \ifnum \absseclevel > 3 + \absseclevel = 3 + \fi + \fi + % The heading type: + \def\headtype{#1}% + \if \headtype U% + \ifnum \absseclevel < \unnlevel + \chardef\unnlevel = \absseclevel + \fi + \else + % Check for appendix sections: + \ifnum \absseclevel = 0 + \edef\chapheadtype{\headtype}% + \else + \if \headtype A\if \chapheadtype N% + \errmessage{@appendix... within a non-appendix chapter}% + \fi\fi + \fi + % Check for numbered within unnumbered: + \ifnum \absseclevel > \unnlevel + \def\headtype{U}% + \else + \chardef\unnlevel = 3 + \fi + \fi + % Now print the heading: + \if \headtype U% + \ifcase\absseclevel + \unnumberedzzz{#3}% + \or \unnumberedseczzz{#3}% + \or \unnumberedsubseczzz{#3}% + \or \unnumberedsubsubseczzz{#3}% + \fi + \else + \if \headtype A% + \ifcase\absseclevel + \appendixzzz{#3}% + \or \appendixsectionzzz{#3}% + \or \appendixsubseczzz{#3}% + \or \appendixsubsubseczzz{#3}% + \fi + \else + \ifcase\absseclevel + \chapterzzz{#3}% + \or \seczzz{#3}% + \or \numberedsubseczzz{#3}% + \or \numberedsubsubseczzz{#3}% + \fi + \fi + \fi + \suppressfirstparagraphindent +} + +% an interface: +\def\numhead{\genhead N} +\def\apphead{\genhead A} +\def\unnmhead{\genhead U} + +% @chapter, @appendix, @unnumbered. Increment top-level counter, reset +% all lower-level sectioning counters to zero. +% +% Also set \chaplevelprefix, which we prepend to @float sequence numbers +% (e.g., figures), q.v. By default (before any chapter), that is empty. +\let\chaplevelprefix = \empty +% +\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz#1{% + % section resetting is \global in case the chapter is in a group, such + % as an @include file. + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\chapno by 1 + % + % Used for \float. + \gdef\chaplevelprefix{\the\chapno.}% + \resetallfloatnos + % + % \putwordChapter can contain complex things in translations. + \toks0=\expandafter{\putwordChapter}% + \message{\the\toks0 \space \the\chapno}% + % + % Write the actual heading. + \chapmacro{#1}{Ynumbered}{\the\chapno}% + % + % So @section and the like are numbered underneath this chapter. + \global\let\section = \numberedsec + \global\let\subsection = \numberedsubsec + \global\let\subsubsection = \numberedsubsubsec +} + +\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz +% +\def\appendixzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\appendixno by 1 + \gdef\chaplevelprefix{\appendixletter.}% + \resetallfloatnos + % + % \putwordAppendix can contain complex things in translations. + \toks0=\expandafter{\putwordAppendix}% + \message{\the\toks0 \space \appendixletter}% + % + \chapmacro{#1}{Yappendix}{\appendixletter}% + % + \global\let\section = \appendixsec + \global\let\subsection = \appendixsubsec + \global\let\subsubsection = \appendixsubsubsec +} + +% normally unnmhead0 calls unnumberedzzz: +\outer\parseargdef\unnumbered{\unnmhead0{#1}} +\def\unnumberedzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\unnumberedno by 1 + % + % Since an unnumbered has no number, no prefix for figures. + \global\let\chaplevelprefix = \empty + \resetallfloatnos + % + % This used to be simply \message{#1}, but TeX fully expands the + % argument to \message. Therefore, if #1 contained @-commands, TeX + % expanded them. For example, in `@unnumbered The @cite{Book}', TeX + % expanded @cite (which turns out to cause errors because \cite is meant + % to be executed, not expanded). + % + % Anyway, we don't want the fully-expanded definition of @cite to appear + % as a result of the \message, we just want `@cite' itself. We use + % \the to achieve this: TeX expands \the only once, + % simply yielding the contents of . (We also do this for + % the toc entries.) + \toks0 = {#1}% + \message{(\the\toks0)}% + % + \chapmacro{#1}{Ynothing}{\the\unnumberedno}% + % + \global\let\section = \unnumberedsec + \global\let\subsection = \unnumberedsubsec + \global\let\subsubsection = \unnumberedsubsubsec +} + +% @centerchap is like @unnumbered, but the heading is centered. +\outer\parseargdef\centerchap{% + % Well, we could do the following in a group, but that would break + % an assumption that \chapmacro is called at the outermost level. + % Thus we are safer this way: --kasal, 24feb04 + \let\centerparametersmaybe = \centerparameters + \unnmhead0{#1}% + \let\centerparametersmaybe = \relax +} + +% @top is like @unnumbered. +\let\top\unnumbered + +% Sections. +% +\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz +\def\seczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% +} + +% normally calls appendixsectionzzz: +\outer\parseargdef\appendixsection{\apphead1{#1}} +\def\appendixsectionzzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% +} +\let\appendixsec\appendixsection + +% normally calls unnumberedseczzz: +\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} +\def\unnumberedseczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% +} + +% Subsections. +% +% normally calls numberedsubseczzz: +\outer\parseargdef\numberedsubsec{\numhead2{#1}} +\def\numberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% +} + +% normally calls appendixsubseczzz: +\outer\parseargdef\appendixsubsec{\apphead2{#1}} +\def\appendixsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno}% +} + +% normally calls unnumberedsubseczzz: +\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} +\def\unnumberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno}% +} + +% Subsubsections. +% +% normally numberedsubsubseczzz: +\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} +\def\numberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynumbered}% + {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% normally appendixsubsubseczzz: +\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} +\def\appendixsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% normally unnumberedsubsubseczzz: +\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} +\def\unnumberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% These macros control what the section commands do, according +% to what kind of chapter we are in (ordinary, appendix, or unnumbered). +% Define them by default for a numbered chapter. +\let\section = \numberedsec +\let\subsection = \numberedsubsec +\let\subsubsection = \numberedsubsubsec + +% Define @majorheading, @heading and @subheading + +\def\majorheading{% + {\advance\chapheadingskip by 10pt \chapbreak }% + \parsearg\chapheadingzzz +} + +\def\chapheading{\chapbreak \parsearg\chapheadingzzz} +\def\chapheadingzzz#1{% + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip \nobreak + \suppressfirstparagraphindent +} + +% @heading, @subheading, @subsubheading. +\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} + +% These macros generate a chapter, section, etc. heading only +% (including whitespace, linebreaking, etc. around it), +% given all the information in convenient, parsed form. + +% Args are the skip and penalty (usually negative) +\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + +% Parameter controlling skip before chapter headings (if needed) +\newskip\chapheadingskip + +% Define plain chapter starts, and page on/off switching for it. +\def\chapbreak{\dobreak \chapheadingskip {-4000}} +\def\chappager{\par\vfill\supereject} +% Because \domark is called before \chapoddpage, the filler page will +% get the headings for the next chapter, which is wrong. But we don't +% care -- we just disable all headings on the filler page. +\def\chapoddpage{% + \chappager + \ifodd\pageno \else + \begingroup + \headingsoff + \null + \chappager + \endgroup + \fi +} + +\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{% +\global\let\contentsalignmacro = \chapoddpage +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +% Chapter opening. +% +% #1 is the text, #2 is the section type (Ynumbered, Ynothing, +% Yappendix, Yomitfromtoc), #3 the chapter number. +% +% To test against our argument. +\def\Ynothingkeyword{Ynothing} +\def\Yomitfromtockeyword{Yomitfromtoc} +\def\Yappendixkeyword{Yappendix} +% +\def\chapmacro#1#2#3{% + % Insert the first mark before the heading break (see notes for \domark). + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}% + \gdef\thissection{}}% + % + \def\temptype{#2}% + \ifx\temptype\Ynothingkeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{\thischaptername}}% + \else\ifx\temptype\Yomitfromtockeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{}}% + \else\ifx\temptype\Yappendixkeyword + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\appendixletter}% + % \noexpand\putwordAppendix avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordAppendix{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \else + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\the\chapno}% + % \noexpand\putwordChapter avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordChapter{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \fi\fi\fi + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert the chapter heading break. + \pchapsepmacro + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \domark + % + {% + \chapfonts \rmisbold + % + % Have to define \lastsection before calling \donoderef, because the + % xref code eventually uses it. On the other hand, it has to be called + % after \pchapsepmacro, or the headline will change too soon. + \gdef\lastsection{#1}% + % + % Only insert the separating space if we have a chapter/appendix + % number, and don't print the unnumbered ``number''. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unnchap}% + \else\ifx\temptype\Yomitfromtockeyword + \setbox0 = \hbox{}% contents like unnumbered, but no toc entry + \def\toctype{omit}% + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% + \def\toctype{app}% + \else + \setbox0 = \hbox{#3\enspace}% + \def\toctype{numchap}% + \fi\fi\fi + % + % Write the toc entry for this chapter. Must come before the + % \donoderef, because we include the current node name in the toc + % entry, and \donoderef resets it to empty. + \writetocentry{\toctype}{#1}{#3}% + % + % For pdftex, we have to write out the node definition (aka, make + % the pdfdest) after any page break, but before the actual text has + % been typeset. If the destination for the pdf outline is after the + % text, then jumping from the outline may wind up with the text not + % being visible, for instance under high magnification. + \donoderef{#2}% + % + % Typeset the actual heading. + \nobreak % Avoid page breaks at the interline glue. + \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak +} + +% @centerchap -- centered and unnumbered. +\let\centerparametersmaybe = \relax +\def\centerparameters{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt +} + + +% I don't think this chapter style is supported any more, so I'm not +% updating it with the new noderef stuff. We'll see. --karl, 11aug03. +% +\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} +% +\def\unnchfopen #1{% + \chapoddpage + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip\nobreak +} +\def\chfopen #1#2{\chapoddpage {\chapfonts +\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% +\par\penalty 5000 % +} +\def\centerchfopen #1{% + \chapoddpage + \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}% + \nobreak\bigskip \nobreak +} +\def\CHAPFopen{% + \global\let\chapmacro=\chfopen + \global\let\centerchapmacro=\centerchfopen} + + +% Section titles. These macros combine the section number parts and +% call the generic \sectionheading to do the printing. +% +\newskip\secheadingskip +\def\secheadingbreak{\dobreak \secheadingskip{-1000}} + +% Subsection titles. +\newskip\subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} + +% Subsubsection titles. +\def\subsubsecheadingskip{\subsecheadingskip} +\def\subsubsecheadingbreak{\subsecheadingbreak} + + +% Print any size, any type, section title. +% +% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is +% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the +% section number. +% +\def\seckeyword{sec} +% +\def\sectionheading#1#2#3#4{% + {% + \checkenv{}% should not be in an environment. + % + % Switch to the right set of fonts. + \csname #2fonts\endcsname \rmisbold + % + \def\sectionlevel{#2}% + \def\temptype{#3}% + % + % Insert first mark before the heading break (see notes for \domark). + \let\prevsectiondefs=\lastsectiondefs + \ifx\temptype\Ynothingkeyword + \ifx\sectionlevel\seckeyword + \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}% + \gdef\thissection{\thissectionname}}% + \fi + \else\ifx\temptype\Yomitfromtockeyword + % Don't redefine \thissection. + \else\ifx\temptype\Yappendixkeyword + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \else + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \fi\fi\fi + % + % Go into vertical mode. Usually we'll already be there, but we + % don't want the following whatsit to end up in a preceding paragraph + % if the document didn't happen to have a blank line. + \par + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert space above the heading. + \csname #2headingbreak\endcsname + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \let\prevsectiondefs=\lastsectiondefs + \domark + % + % Only insert the space after the number if we have a section number. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unn}% + \gdef\lastsection{#1}% + \else\ifx\temptype\Yomitfromtockeyword + % for @headings -- no section number, don't include in toc, + % and don't redefine \lastsection. + \setbox0 = \hbox{}% + \def\toctype{omit}% + \let\sectionlevel=\empty + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{#4\enspace}% + \def\toctype{app}% + \gdef\lastsection{#1}% + \else + \setbox0 = \hbox{#4\enspace}% + \def\toctype{num}% + \gdef\lastsection{#1}% + \fi\fi\fi + % + % Write the toc entry (before \donoderef). See comments in \chapmacro. + \writetocentry{\toctype\sectionlevel}{#1}{#4}% + % + % Write the node reference (= pdf destination for pdftex). + % Again, see comments in \chapmacro. + \donoderef{#3}% + % + % Interline glue will be inserted when the vbox is completed. + % That glue will be a valid breakpoint for the page, since it'll be + % preceded by a whatsit (usually from the \donoderef, or from the + % \writetocentry if there was no node). We don't want to allow that + % break, since then the whatsits could end up on page n while the + % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000. + \nobreak + % + % Output the actual section heading. + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright + \hangindent=\wd0 % zero if no section number + \unhbox0 #1}% + }% + % Add extra space after the heading -- half of whatever came above it. + % Don't allow stretch, though. + \kern .5 \csname #2headingskip\endcsname + % + % Do not let the kern be a potential breakpoint, as it would be if it + % was followed by glue. + \nobreak + % + % We'll almost certainly start a paragraph next, so don't let that + % glue accumulate. (Not a breakpoint because it's preceded by a + % discardable item.) However, when a paragraph is not started next + % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out + % or the negative glue will cause weirdly wrong output, typically + % obscuring the section heading with something else. + \vskip-\parskip + % + % This is so the last item on the main vertical list is a known + % \penalty > 10000, so \startdefun, etc., can recognize the situation + % and do the needful. + \penalty 10001 +} + + +\message{toc,} +% Table of contents. +\newwrite\tocfile + +% Write an entry to the toc file, opening it if necessary. +% Called from @chapter, etc. +% +% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} +% We append the current node name (if any) and page number as additional +% arguments for the \{chap,sec,...}entry macros which will eventually +% read this. The node name is used in the pdf outlines as the +% destination to jump to. +% +% We open the .toc file for writing here instead of at @setfilename (or +% any other fixed time) so that @contents can be anywhere in the document. +% But if #1 is `omit', then we don't do anything. This is used for the +% table of contents chapter openings themselves. +% +\newif\iftocfileopened +\def\omitkeyword{omit}% +% +\def\writetocentry#1#2#3{% + \edef\writetoctype{#1}% + \ifx\writetoctype\omitkeyword \else + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + % + \iflinks + {\atdummies + \edef\temp{% + \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}% + \temp + }% + \fi + \fi + % + % Tell \shipout to create a pdf destination on each page, if we're + % writing pdf. These are used in the table of contents. We can't + % just write one on every page because the title pages are numbered + % 1 and 2 (the page numbers aren't printed), and so are the first + % two pages of the document. Thus, we'd have two destinations named + % `1', and two named `2'. + \ifpdf \global\pdfmakepagedesttrue \fi +} + + +% These characters do not print properly in the Computer Modern roman +% fonts, so we must take special care. This is more or less redundant +% with the Texinfo input format setup at the end of this file. +% +\def\activecatcodes{% + \catcode`\"=\active + \catcode`\$=\active + \catcode`\<=\active + \catcode`\>=\active + \catcode`\\=\active + \catcode`\^=\active + \catcode`\_=\active + \catcode`\|=\active + \catcode`\~=\active +} + + +% Read the toc file, which is essentially Texinfo input. +\def\readtocfile{% + \setupdatafile + \activecatcodes + \input \tocreadfilename +} + +\newskip\contentsrightmargin \contentsrightmargin=1in +\newcount\savepageno +\newcount\lastnegativepageno \lastnegativepageno = -1 + +% Prepare to read what we've written to \tocfile. +% +\def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \chapmacro{#1}{Yomitfromtoc}{}% + % + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi +} + +% redefined for the two-volume lispref. We always output on +% \jobname.toc even if this is redefined. +% +\def\tocreadfilename{\jobname.toc} + +% Normal (long) toc. +% +\def\contents{% + \startcontents{\putwordTOC}% + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \ifeof 1 \else + \pdfmakeoutlines + \fi + \closein 1 + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} + +% And just the chapters. +\def\summarycontents{% + \startcontents{\putwordShortTOC}% + % + \let\partentry = \shortpartentry + \let\numchapentry = \shortchapentry + \let\appentry = \shortchapentry + \let\unnchapentry = \shortunnchapentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf + \let\sl=\shortcontsl \let\tt=\shortconttt + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\numsecentry##1##2##3##4{} + \let\appsecentry = \numsecentry + \let\unnsecentry = \numsecentry + \let\numsubsecentry = \numsecentry + \let\appsubsecentry = \numsecentry + \let\unnsubsecentry = \numsecentry + \let\numsubsubsecentry = \numsecentry + \let\appsubsubsecentry = \numsecentry + \let\unnsubsubsecentry = \numsecentry + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \closein 1 + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} +\let\shortcontents = \summarycontents + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g., `A' for an appendix, or `3' for a chapter. +% +\def\shortchaplabel#1{% + % This space should be enough, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % But use \hss just in case. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + % + % We'd like to right-justify chapter numbers, but that looks strange + % with appendix letters. And right-justifying numbers and + % left-justifying letters looks strange when there is less than 10 + % chapters. Have to read the whole toc once to know how many chapters + % there are before deciding ... + \hbox to 1em{#1\hss}% +} + +% These macros generate individual entries in the table of contents. +% The first argument is the chapter or section name. +% The last argument is the page number. +% The arguments in between are the chapter number, section number, ... + +% Parts, in the main contents. Replace the part number, which doesn't +% exist, with an empty box. Let's hope all the numbers have the same width. +% Also ignore the page number, which is conventionally not printed. +\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}} +\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}} +% +% Parts, in the short toc. +\def\shortpartentry#1#2#3#4{% + \penalty-300 + \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip + \shortchapentry{{\bf #1}}{\numeralbox}{}{}% +} + +% Chapters, in the main contents. +\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} +% +% Chapters, in the short toc. +% See comments in \dochapentry re vbox and related settings. +\def\shortchapentry#1#2#3#4{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% +} + +% Appendices, in the main contents. +% Need the word Appendix, and a fixed-size box. +% +\def\appendixbox#1{% + % We use M since it's probably the widest letter. + \setbox0 = \hbox{\putwordAppendix{} M}% + \hbox to \wd0{\putwordAppendix{} #1\hss}} +% +\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}} + +% Unnumbered chapters. +\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} +\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} + +% Sections. +\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} +\let\appsecentry=\numsecentry +\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} + +% Subsections. +\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} +\let\appsubsecentry=\numsubsecentry +\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} + +% And subsubsections. +\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} +\let\appsubsubsecentry=\numsubsubsecentry +\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} + +% This parameter controls the indentation of the various levels. +% Same as \defaultparindent. +\newdimen\tocindent \tocindent = 15pt + +% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% page number. +% +% If the toc has to be broken over pages, we want it to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + \chapentryfonts + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip +} + +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +% We use the same \entry macro as for the index entries. +\let\tocentry = \entry + +% Space between chapter (or whatever) number and the title. +\def\labelspace{\hskip1em \relax} + +\def\dopageno#1{{\rm #1}} +\def\doshortpageno#1{{\rm #1}} + +\def\chapentryfonts{\secfonts \rm} +\def\secentryfonts{\textfonts} +\def\subsecentryfonts{\textfonts} +\def\subsubsecentryfonts{\textfonts} + + +\message{environments,} +% @foo ... @end foo. + +% @tex ... @end tex escapes into raw TeX temporarily. +% One exception: @ is still an escape character, so that @end tex works. +% But \@ or @@ will get a plain @ character. + +\envdef\tex{% + \setupmarkupstyle{tex}% + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie + \catcode `\%=14 + \catcode `\+=\other + \catcode `\"=\other + \catcode `\|=\other + \catcode `\<=\other + \catcode `\>=\other + \catcode`\`=\other + \catcode`\'=\other + \escapechar=`\\ + % + % ' is active in math mode (mathcode"8000). So reset it, and all our + % other math active characters (just in case), to plain's definitions. + \mathactive + % + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \let\{=\ptexlbrace + \let\+=\tabalign + \let\}=\ptexrbrace + \let\/=\ptexslash + \let\*=\ptexstar + \let\t=\ptext + \expandafter \let\csname top\endcsname=\ptextop % outer + \let\frenchspacing=\plainfrenchspacing + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% +} +% There is no need to define \Etex. + +% Define @lisp ... @end lisp. +% @lisp environment forms a group so it can rebind things, +% including the definition of @end lisp (which normally is erroneous). + +% Amount to narrow the margins by for @lisp. +\newskip\lispnarrowing \lispnarrowing=0.4in + +% This is the definition that ^^M gets inside @lisp, @example, and other +% such environments. \null is better than a space, since it doesn't +% have any width. +\def\lisppar{\null\endgraf} + +% This space is always present above and below environments. +\newskip\envskipamount \envskipamount = 0pt + +% Make spacing and below environment symmetrical. We use \parskip here +% to help in doing that, since in @example-like environments \parskip +% is reset to zero; thus the \afterenvbreak inserts no space -- but the +% start of the next paragraph will insert \parskip. +% +\def\aboveenvbreak{{% + % =10000 instead of <10000 because of a special case in \itemzzz and + % \sectionheading, q.v. + \ifnum \lastpenalty=10000 \else + \advance\envskipamount by \parskip + \endgraf + \ifdim\lastskip<\envskipamount + \removelastskip + % it's not a good place to break if the last penalty was \nobreak + % or better ... + \ifnum\lastpenalty<10000 \penalty-50 \fi + \vskip\envskipamount + \fi + \fi +}} + +\let\afterenvbreak = \aboveenvbreak + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will +% also clear it, so that its embedded environments do the narrowing again. +\let\nonarrowing=\relax + +% @cartouche ... @end cartouche: draw rectangle w/rounded corners around +% environment contents. +\font\circle=lcircle10 +\newdimen\circthick +\newdimen\cartouter\newdimen\cartinner +\newskip\normbskip\newskip\normpskip\newskip\normlskip +\circthick=\fontdimen8\circle +% +\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth +\def\ctr{{\hskip 6pt\circle\char'010}} +\def\cbl{{\circle\char'012\hskip -6pt}} +\def\cbr{{\hskip 6pt\circle\char'011}} +\def\carttop{\hbox to \cartouter{\hskip\lskip + \ctl\leaders\hrule height\circthick\hfil\ctr + \hskip\rskip}} +\def\cartbot{\hbox to \cartouter{\hskip\lskip + \cbl\leaders\hrule height\circthick\hfil\cbr + \hskip\rskip}} +% +\newskip\lskip\newskip\rskip + +\envdef\cartouche{% + \ifhmode\par\fi % can't be in the midst of a paragraph. + \startsavinginserts + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt % we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18.4pt % allow for 3pt kerns on either + % side, and for 6pt waste from + % each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing = t% + % + % If this cartouche directly follows a sectioning command, we need the + % \parskip glue (backspaced over by default) or the cartouche can + % collide with the section heading. + \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi + % + \vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \kern3pt + \hsize=\cartinner + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip + \comment % For explanation, see the end of def\group. +} +\def\Ecartouche{% + \ifhmode\par\fi + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup + \checkinserts +} + + +% This macro is called at the beginning of all the @example variants, +% inside a group. +\newdimen\nonfillparindent +\def\nonfillstart{% + \aboveenvbreak + \hfuzz = 12pt % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + % Turn off paragraph indentation but redefine \indent to emulate + % the normal \indent. + \nonfillparindent=\parindent + \parindent = 0pt + \let\indent\nonfillindent + % + \emergencystretch = 0pt % don't try to avoid overfull boxes + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \else + \let\nonarrowing = \relax + \fi + \let\exdent=\nofillexdent +} + +\begingroup +\obeyspaces +% We want to swallow spaces (but not other tokens) after the fake +% @indent in our nonfill-environments, where spaces are normally +% active and set to @tie, resulting in them not being ignored after +% @indent. +\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}% +\gdef\nonfillindentcheck{% +\ifx\temp % +\expandafter\nonfillindentgobble% +\else% +\leavevmode\nonfillindentbox% +\fi% +}% +\endgroup +\def\nonfillindentgobble#1{\nonfillindent} +\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}} + +% If you want all examples etc. small: @set dispenvsize small. +% If you want even small examples the full size: @set dispenvsize nosmall. +% This affects the following displayed environments: +% @example, @display, @format, @lisp +% +\def\smallword{small} +\def\nosmallword{nosmall} +\let\SETdispenvsize\relax +\def\setnormaldispenv{% + \ifx\SETdispenvsize\smallword + % end paragraph for sake of leading, in case document has no blank + % line. This is redundant with what happens in \aboveenvbreak, but + % we need to do it before changing the fonts, and it's inconvenient + % to change the fonts afterward. + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} +\def\setsmalldispenv{% + \ifx\SETdispenvsize\nosmallword + \else + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} + +% We often define two environments, @foo and @smallfoo. +% Let's do it in one command. #1 is the env name, #2 the definition. +\def\makedispenvdef#1#2{% + \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}% + \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}% + \expandafter\let\csname E#1\endcsname \afterenvbreak + \expandafter\let\csname Esmall#1\endcsname \afterenvbreak +} + +% Define two environment synonyms (#1 and #2) for an environment. +\def\maketwodispenvdef#1#2#3{% + \makedispenvdef{#1}{#3}% + \makedispenvdef{#2}{#3}% +} +% +% @lisp: indented, narrowed, typewriter font; +% @example: same as @lisp. +% +% @smallexample and @smalllisp: use smaller fonts. +% Originally contributed by Pavel@xerox. +% +\maketwodispenvdef{lisp}{example}{% + \nonfillstart + \tt\setupmarkupstyle{example}% + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return +} +% @display/@smalldisplay: same as @lisp except keep current font. +% +\makedispenvdef{display}{% + \nonfillstart + \gobble +} + +% @format/@smallformat: same as @display except don't narrow margins. +% +\makedispenvdef{format}{% + \let\nonarrowing = t% + \nonfillstart + \gobble +} + +% @flushleft: same as @format, but doesn't obey \SETdispenvsize. +\envdef\flushleft{% + \let\nonarrowing = t% + \nonfillstart + \gobble +} +\let\Eflushleft = \afterenvbreak + +% @flushright. +% +\envdef\flushright{% + \let\nonarrowing = t% + \nonfillstart + \advance\leftskip by 0pt plus 1fill\relax + \gobble +} +\let\Eflushright = \afterenvbreak + + +% @raggedright does more-or-less normal line breaking but no right +% justification. From plain.tex. +\envdef\raggedright{% + \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax +} +\let\Eraggedright\par + +\envdef\raggedleft{% + \parindent=0pt \leftskip0pt plus2em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. +} +\let\Eraggedleft\par + +\envdef\raggedcenter{% + \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. +} +\let\Eraggedcenter\par + + +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. We keep \parskip nonzero in general, since +% we're doing normal filling. So, when using \aboveenvbreak and +% \afterenvbreak, temporarily make \parskip 0. +% +\makedispenvdef{quotation}{\quotationstart} +% +\def\quotationstart{% + \indentedblockstart % same as \indentedblock, but increase right margin too. + \ifx\nonarrowing\relax + \advance\rightskip by \lispnarrowing + \fi + \parsearg\quotationlabel +} + +% We have retained a nonzero parskip for the environment, since we're +% doing normal filling. +% +\def\Equotation{% + \par + \ifx\quotationauthor\thisisundefined\else + % indent a bit. + \leftline{\kern 2\leftskip \sl ---\quotationauthor}% + \fi + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallquotation{\Equotation} + +% If we're given an argument, typeset it in bold with a colon after. +\def\quotationlabel#1{% + \def\temp{#1}% + \ifx\temp\empty \else + {\bf #1: }% + \fi +} + +% @indentedblock is like @quotation, but indents only on the left and +% has no optional argument. +% +\makedispenvdef{indentedblock}{\indentedblockstart} +% +\def\indentedblockstart{% + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \parindent=0pt + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \exdentamount = \lispnarrowing + \else + \let\nonarrowing = \relax + \fi +} + +% Keep a nonzero parskip for the environment, since we're doing normal filling. +% +\def\Eindentedblock{% + \par + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallindentedblock{\Eindentedblock} + + +% LaTeX-like @verbatim...@end verbatim and @verb{...} +% If we want to allow any as delimiter, +% we need the curly braces so that makeinfo sees the @verb command, eg: +% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org +% +% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. +% +% [Knuth] p.344; only we need to do the other characters Texinfo sets +% active too. Otherwise, they get lost as the first character on a +% verbatim line. +\def\dospecials{% + \do\ \do\\\do\{\do\}\do\$\do\&% + \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% + \do\<\do\>\do\|\do\@\do+\do\"% + % Don't do the quotes -- if we do, @set txicodequoteundirected and + % @set txicodequotebacktick will not have effect on @verb and + % @verbatim, and ?` and !` ligatures won't get disabled. + %\do\`\do\'% +} +% +% [Knuth] p. 380 +\def\uncatcodespecials{% + \def\do##1{\catcode`##1=\other}\dospecials} +% +% Setup for the @verb command. +% +% Eight spaces for a tab +\begingroup + \catcode`\^^I=\active + \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} +\endgroup +% +\def\setupverb{% + \tt % easiest (and conventionally used) font for verbatim + \def\par{\leavevmode\endgraf}% + \setupmarkupstyle{verb}% + \tabeightspaces + % Respect line breaks, + % print special symbols as themselves, and + % make each space count + % must do in this order: + \obeylines \uncatcodespecials \sepspaces +} + +% Setup for the @verbatim environment +% +% Real tab expansion. +\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount +% +% We typeset each line of the verbatim in an \hbox, so we can handle +% tabs. The \global is in case the verbatim line starts with an accent, +% or some other command that starts with a begin-group. Otherwise, the +% entire \verbbox would disappear at the corresponding end-group, before +% it is typeset. Meanwhile, we can't have nested verbatim commands +% (can we?), so the \global won't be overwriting itself. +\newbox\verbbox +\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup} +% +\begingroup + \catcode`\^^I=\active + \gdef\tabexpand{% + \catcode`\^^I=\active + \def^^I{\leavevmode\egroup + \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab + \divide\dimen\verbbox by\tabw + \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw + \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw + \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox + }% + } +\endgroup + +% start the verbatim environment. +\def\setupverbatim{% + \let\nonarrowing = t% + \nonfillstart + \tt % easiest (and conventionally used) font for verbatim + % The \leavevmode here is for blank lines. Otherwise, we would + % never \starttabox and the \egroup would end verbatim mode. + \def\par{\leavevmode\egroup\box\verbbox\endgraf}% + \tabexpand + \setupmarkupstyle{verbatim}% + % Respect line breaks, + % print special symbols as themselves, and + % make each space count. + % Must do in this order: + \obeylines \uncatcodespecials \sepspaces + \everypar{\starttabbox}% +} + +% Do the @verb magic: verbatim text is quoted by unique +% delimiter characters. Before first delimiter expect a +% right brace, after last delimiter expect closing brace: +% +% \def\doverb'{'#1'}'{#1} +% +% [Knuth] p. 382; only eat outer {} +\begingroup + \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other + \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] +\endgroup +% +\def\verb{\begingroup\setupverb\doverb} +% +% +% Do the @verbatim magic: define the macro \doverbatim so that +% the (first) argument ends when '@end verbatim' is reached, ie: +% +% \def\doverbatim#1@end verbatim{#1} +% +% For Texinfo it's a lot easier than for LaTeX, +% because texinfo's \verbatim doesn't stop at '\end{verbatim}': +% we need not redefine '\', '{' and '}'. +% +% Inspired by LaTeX's verbatim command set [latex.ltx] +% +\begingroup + \catcode`\ =\active + \obeylines % + % ignore everything up to the first ^^M, that's the newline at the end + % of the @verbatim input line itself. Otherwise we get an extra blank + % line in the output. + \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}% + % We really want {...\end verbatim} in the body of the macro, but + % without the active space; thus we have to use \xdef and \gobble. +\endgroup +% +\envdef\verbatim{% + \setupverbatim\doverbatim +} +\let\Everbatim = \afterenvbreak + + +% @verbatiminclude FILE - insert text of file in verbatim environment. +% +\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude} +% +\def\doverbatiminclude#1{% + {% + \makevalueexpandable + \setupverbatim + \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}% + \input #1 + \afterenvbreak + }% +} + +% @copying ... @end copying. +% Save the text away for @insertcopying later. +% +% We save the uninterpreted tokens, rather than creating a box. +% Saving the text in a box would be much easier, but then all the +% typesetting commands (@smallbook, font changes, etc.) have to be done +% beforehand -- and a) we want @copying to be done first in the source +% file; b) letting users define the frontmatter in as flexible order as +% possible is very desirable. +% +\def\copying{\checkenv{}\begingroup\scanargctxt\docopying} +\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}} +% +\def\insertcopying{% + \begingroup + \parindent = 0pt % paragraph indentation looks wrong on title page + \scanexp\copyingtext + \endgroup +} + + +\message{defuns,} +% @defun etc. + +\newskip\defbodyindent \defbodyindent=.4in +\newskip\defargsindent \defargsindent=50pt +\newskip\deflastargmargin \deflastargmargin=18pt +\newcount\defunpenalty + +% Start the processing of @deffn: +\def\startdefun{% + \ifnum\lastpenalty<10000 + \medbreak + \defunpenalty=10003 % Will keep this @deffn together with the + % following @def command, see below. + \else + % If there are two @def commands in a row, we'll have a \nobreak, + % which is there to keep the function description together with its + % header. But if there's nothing but headers, we need to allow a + % break somewhere. Check specifically for penalty 10002, inserted + % by \printdefunline, instead of 10000, since the sectioning + % commands also insert a nobreak penalty, and we don't want to allow + % a break between a section heading and a defun. + % + % As a further refinement, we avoid "club" headers by signalling + % with penalty of 10003 after the very first @deffn in the + % sequence (see above), and penalty of 10002 after any following + % @def command. + \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi + % + % Similarly, after a section heading, do not allow a break. + % But do insert the glue. + \medskip % preceded by discardable penalty, so not a breakpoint + \fi + % + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent +} + +\def\dodefunx#1{% + % First, check whether we are in the right environment: + \checkenv#1% + % + % As above, allow line break if we have multiple x headers in a row. + % It's not a great place, though. + \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi + % + % And now, it's time to reuse the body of the original defun: + \expandafter\gobbledefun#1% +} +\def\gobbledefun#1\startdefun{} + +% \printdefunline \deffnheader{text} +% +\def\printdefunline#1#2{% + \begingroup + % call \deffnheader: + #1#2 \endheader + % common ending: + \interlinepenalty = 10000 + \advance\rightskip by 0pt plus 1fil\relax + \endgraf + \nobreak\vskip -\parskip + \penalty\defunpenalty % signal to \startdefun and \dodefunx + % Some of the @defun-type tags do not enable magic parentheses, + % rendering the following check redundant. But we don't optimize. + \checkparencounts + \endgroup +} + +\def\Edefun{\endgraf\medbreak} + +% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn; +% the only thing remaining is to define \deffnheader. +% +\def\makedefun#1{% + \expandafter\let\csname E#1\endcsname = \Edefun + \edef\temp{\noexpand\domakedefun + \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}% + \temp +} + +% \domakedefun \deffn \deffnx \deffnheader +% +% Define \deffn and \deffnx, without parameters. +% \deffnheader has to be defined explicitly. +% +\def\domakedefun#1#2#3{% + \envdef#1{% + \startdefun + \doingtypefnfalse % distinguish typed functions from all else + \parseargusing\activeparens{\printdefunline#3}% + }% + \def#2{\dodefunx#1}% + \def#3% +} + +\newif\ifdoingtypefn % doing typed function? +\newif\ifrettypeownline % typeset return type on its own line? + +% @deftypefnnewline on|off says whether the return type of typed functions +% are printed on their own line. This affects @deftypefn, @deftypefun, +% @deftypeop, and @deftypemethod. +% +\parseargdef\deftypefnnewline{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @txideftypefnnl value `\temp', + must be on|off}% + \fi\fi +} + +% Untyped functions: + +% @deffn category name args +\makedefun{deffn}{\deffngeneral{}} + +% @deffn category class name args +\makedefun{defop}#1 {\defopon{#1\ \putwordon}} + +% \defopon {category on}class name args +\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + +% \deffngeneral {subind}category name args +% +\def\deffngeneral#1#2 #3 #4\endheader{% + % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}. + \dosubind{fn}{\code{#3}}{#1}% + \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% +} + +% Typed functions: + +% @deftypefn category type name args +\makedefun{deftypefn}{\deftypefngeneral{}} + +% @deftypeop category class type name args +\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}} + +% \deftypeopon {category on}class type name args +\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + +% \deftypefngeneral {subind}category type name args +% +\def\deftypefngeneral#1#2 #3 #4 #5\endheader{% + \dosubind{fn}{\code{#4}}{#1}% + \doingtypefntrue + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +} + +% Typed variables: + +% @deftypevr category type var args +\makedefun{deftypevr}{\deftypecvgeneral{}} + +% @deftypecv category class type var args +\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}} + +% \deftypecvof {category of}class type var args +\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} } + +% \deftypecvgeneral {subind}category type var args +% +\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{% + \dosubind{vr}{\code{#4}}{#1}% + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +} + +% Untyped variables: + +% @defvr category var args +\makedefun{defvr}#1 {\deftypevrheader{#1} {} } + +% @defcv category class var args +\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}} + +% \defcvof {category of}class var args +\def\defcvof#1#2 {\deftypecvof{#1}#2 {} } + +% Types: + +% @deftp category name args +\makedefun{deftp}#1 #2 #3\endheader{% + \doind{tp}{\code{#2}}% + \defname{#1}{}{#2}\defunargs{#3\unskip}% +} + +% Remaining @defun-like shortcuts: +\makedefun{defun}{\deffnheader{\putwordDeffunc} } +\makedefun{defmac}{\deffnheader{\putwordDefmac} } +\makedefun{defspec}{\deffnheader{\putwordDefspec} } +\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} } +\makedefun{defvar}{\defvrheader{\putwordDefvar} } +\makedefun{defopt}{\defvrheader{\putwordDefopt} } +\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} } +\makedefun{defmethod}{\defopon\putwordMethodon} +\makedefun{deftypemethod}{\deftypeopon\putwordMethodon} +\makedefun{defivar}{\defcvof\putwordInstanceVariableof} +\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof} + +% \defname, which formats the name of the @def (not the args). +% #1 is the category, such as "Function". +% #2 is the return type, if any. +% #3 is the function name. +% +% We are followed by (but not passed) the arguments, if any. +% +\def\defname#1#2#3{% + \par + % Get the values of \leftskip and \rightskip as they were outside the @def... + \advance\leftskip by -\defbodyindent + % + % Determine if we are typesetting the return type of a typed function + % on a line by itself. + \rettypeownlinefalse + \ifdoingtypefn % doing a typed function specifically? + % then check user option for putting return type on its own line: + \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else + \rettypeownlinetrue + \fi + \fi + % + % How we'll format the category name. Putting it in brackets helps + % distinguish it from the body text that may end up on the next line + % just below it. + \def\temp{#1}% + \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} + % + % Figure out line sizes for the paragraph shape. We'll always have at + % least two. + \tempnum = 2 + % + % The first line needs space for \box0; but if \rightskip is nonzero, + % we need only space for the part of \box0 which exceeds it: + \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip + % + % If doing a return type on its own line, we'll have another line. + \ifrettypeownline + \advance\tempnum by 1 + \def\maybeshapeline{0in \hsize}% + \else + \def\maybeshapeline{}% + \fi + % + % The continuations: + \dimen2=\hsize \advance\dimen2 by -\defargsindent + % + % The final paragraph shape: + \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2 + % + % Put the category name at the right margin. + \noindent + \hbox to 0pt{% + \hfil\box0 \kern-\hsize + % \hsize has to be shortened this way: + \kern\leftskip + % Intentionally do not respect \rightskip, since we need the space. + }% + % + % Allow all lines to be underfull without complaint: + \tolerance=10000 \hbadness=10000 + \exdentamount=\defbodyindent + {% + % defun fonts. We use typewriter by default (used to be bold) because: + % . we're printing identifiers, they should be in tt in principle. + % . in languages with many accents, such as Czech or French, it's + % common to leave accents off identifiers. The result looks ok in + % tt, but exceedingly strange in rm. + % . we don't want -- and --- to be treated as ligatures. + % . this still does not fix the ?` and !` ligatures, but so far no + % one has made identifiers using them :). + \df \tt + \def\temp{#2}% text of the return type + \ifx\temp\empty\else + \tclose{\temp}% typeset the return type + \ifrettypeownline + % put return type on its own line; prohibit line break following: + \hfil\vadjust{\nobreak}\break + \else + \space % type on same line, so just followed by a space + \fi + \fi % no return type + #3% output function name + }% + {\rm\enskip}% hskip 0.5 em of \tenrm + % + \boldbrax + % arguments will be output next, if any. +} + +% Print arguments in slanted roman (not ttsl), inconsistently with using +% tt for the name. This is because literal text is sometimes needed in +% the argument list (groff manual), and ttsl and tt are not very +% distinguishable. Prevent hyphenation at `-' chars. +% +\def\defunargs#1{% + % use sl by default (not ttsl), + % tt for the names. + \df \sl \hyphenchar\font=0 + % + % On the other hand, if an argument has two dashes (for instance), we + % want a way to get ttsl. We used to recommend @var for that, so + % leave the code in, but it's strange for @var to lead to typewriter. + % Nowadays we recommend @code, since the difference between a ttsl hyphen + % and a tt hyphen is pretty tiny. @code also disables ?` !`. + \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% + #1% + \sl\hyphenchar\font=45 +} + +% We want ()&[] to print specially on the defun line. +% +\def\activeparens{% + \catcode`\(=\active \catcode`\)=\active + \catcode`\[=\active \catcode`\]=\active + \catcode`\&=\active +} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +{ + \activeparens + \global\let(=\lparen \global\let)=\rparen + \global\let[=\lbrack \global\let]=\rbrack + \global\let& = \& + + \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} + \gdef\magicamp{\let&=\amprm} +} + +\newcount\parencount + +% If we encounter &foo, then turn on ()-hacking afterwards +\newif\ifampseen +\def\amprm#1 {\ampseentrue{\bf\ }} + +\def\parenfont{% + \ifampseen + % At the first level, print parens in roman, + % otherwise use the default font. + \ifnum \parencount=1 \rm \fi + \else + % The \sf parens (in \boldbrax) actually are a little bolder than + % the contained text. This is especially needed for [ and ] . + \sf + \fi +} +\def\infirstlevel#1{% + \ifampseen + \ifnum\parencount=1 + #1% + \fi + \fi +} +\def\bfafterword#1 {#1 \bf} + +\def\opnr{% + \global\advance\parencount by 1 + {\parenfont(}% + \infirstlevel \bfafterword +} +\def\clnr{% + {\parenfont)}% + \infirstlevel \sl + \global\advance\parencount by -1 +} + +\newcount\brackcount +\def\lbrb{% + \global\advance\brackcount by 1 + {\bf[}% +} +\def\rbrb{% + {\bf]}% + \global\advance\brackcount by -1 +} + +\def\checkparencounts{% + \ifnum\parencount=0 \else \badparencount \fi + \ifnum\brackcount=0 \else \badbrackcount \fi +} +% these should not use \errmessage; the glibc manual, at least, actually +% has such constructs (when documenting function pointers). +\def\badparencount{% + \message{Warning: unbalanced parentheses in @def...}% + \global\parencount=0 +} +\def\badbrackcount{% + \message{Warning: unbalanced square brackets in @def...}% + \global\brackcount=0 +} + + +\message{macros,} +% @macro. + +% To do this right we need a feature of e-TeX, \scantokens, +% which we arrange to emulate with a temporary file in ordinary TeX. +\ifx\eTeXversion\thisisundefined + \newwrite\macscribble + \def\scantokens#1{% + \toks0={#1}% + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{\the\toks0}% + \immediate\closeout\macscribble + \input \jobname.tmp + } +\fi + +\def\scanmacro#1{\begingroup + \newlinechar`\^^M + \let\xeatspaces\eatspaces + % + % Undo catcode changes of \startcontents and \doprintindex + % When called from @insertcopying or (short)caption, we need active + % backslash to get it printed correctly. Previously, we had + % \catcode`\\=\other instead. We'll see whether a problem appears + % with macro expansion. --kasal, 19aug04 + \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ + % + % ... and for \example: + \spaceisspace + % + % The \empty here causes a following catcode 5 newline to be eaten as + % part of reading whitespace after a control sequence. It does not + % eat a catcode 13 newline. There's no good way to handle the two + % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX + % would then have different behavior). See the Macro Details node in + % the manual for the workaround we recommend for macros and + % line-oriented commands. + % + \scantokens{#1\empty}% +\endgroup} + +\def\scanexp#1{% + \edef\temp{\noexpand\scanmacro{#1}}% + \temp +} + +\newcount\paramno % Count of parameters +\newtoks\macname % Macro name +\newif\ifrecursive % Is it recursive? + +% List of all defined macros in the form +% \definedummyword\macro1\definedummyword\macro2... +% Currently is also contains all @aliases; the list can be split +% if there is a need. +\def\macrolist{} + +% Add the macro to \macrolist +\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname} +\def\addtomacrolistxxx#1{% + \toks0 = \expandafter{\macrolist\definedummyword#1}% + \xdef\macrolist{\the\toks0}% +} + +% Utility routines. +% This does \let #1 = #2, with \csnames; that is, +% \let \csname#1\endcsname = \csname#2\endcsname +% (except of course we have to play expansion games). +% +\def\cslet#1#2{% + \expandafter\let + \csname#1\expandafter\endcsname + \csname#2\endcsname +} + +% Trim leading and trailing spaces off a string. +% Concepts from aro-bend problem 15 (see CTAN). +{\catcode`\@=11 +\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} +\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} +\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} +\def\unbrace#1{#1} +\unbrace{\gdef\trim@@@ #1 } #2@{#1} +} + +% Trim a single trailing ^^M off a string. +{\catcode`\^^M=\other \catcode`\Q=3% +\gdef\eatcr #1{\eatcra #1Q^^MQ}% +\gdef\eatcra#1^^MQ{\eatcrb#1Q}% +\gdef\eatcrb#1Q#2Q{#1}% +} + +% Macro bodies are absorbed as an argument in a context where +% all characters are catcode 10, 11 or 12, except \ which is active +% (as in normal texinfo). It is necessary to change the definition of \ +% to recognize macro arguments; this is the job of \mbodybackslash. +% +% Non-ASCII encodings make 8-bit characters active, so un-activate +% them to avoid their expansion. Must do this non-globally, to +% confine the change to the current group. +% +% It's necessary to have hard CRs when the macro is executed. This is +% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% body, and then making it the \newlinechar in \scanmacro. +% +\def\scanctxt{% used as subroutine + \catcode`\"=\other + \catcode`\+=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\@=\other + \catcode`\^=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\~=\other + \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi +} + +\def\scanargctxt{% used for copying and captions, not macros. + \scanctxt + \catcode`\\=\other + \catcode`\^^M=\other +} + +\def\macrobodyctxt{% used for @macro definitions + \scanctxt + \catcode`\{=\other + \catcode`\}=\other + \catcode`\^^M=\other + \usembodybackslash +} + +\def\macroargctxt{% used when scanning invocations + \scanctxt + \catcode`\\=0 +} +% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes" +% for the single characters \ { }. Thus, we end up with the "commands" +% that would be written @\ @{ @} in a Texinfo document. +% +% We already have @{ and @}. For @\, we define it here, and only for +% this purpose, to produce a typewriter backslash (so, the @\ that we +% define for @math can't be used with @macro calls): +% +\def\\{\normalbackslash}% +% +% We would like to do this for \, too, since that is what makeinfo does. +% But it is not possible, because Texinfo already has a command @, for a +% cedilla accent. Documents must use @comma{} instead. +% +% \anythingelse will almost certainly be an error of some kind. + + +% \mbodybackslash is the definition of \ in @macro bodies. +% It maps \foo\ => \csname macarg.foo\endcsname => #N +% where N is the macro parameter number. +% We define \csname macarg.\endcsname to be \realbackslash, so +% \\ in macro replacement text gets you a backslash. +% +{\catcode`@=0 @catcode`@\=@active + @gdef@usembodybackslash{@let\=@mbodybackslash} + @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} +} +\expandafter\def\csname macarg.\endcsname{\realbackslash} + +\def\margbackslash#1{\char`\#1 } + +\def\macro{\recursivefalse\parsearg\macroxxx} +\def\rmacro{\recursivetrue\parsearg\macroxxx} + +\def\macroxxx#1{% + \getargs{#1}% now \macname is the macname and \argl the arglist + \ifx\argl\empty % no arguments + \paramno=0\relax + \else + \expandafter\parsemargdef \argl;% + \if\paramno>256\relax + \ifx\eTeXversion\thisisundefined + \errhelp = \EMsimple + \errmessage{You need eTeX to compile a file with macros with more than 256 arguments} + \fi + \fi + \fi + \if1\csname ismacro.\the\macname\endcsname + \message{Warning: redefining \the\macname}% + \else + \expandafter\ifx\csname \the\macname\endcsname \relax + \else \errmessage{Macro name \the\macname\space already defined}\fi + \global\cslet{macsave.\the\macname}{\the\macname}% + \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% + \addtomacrolist{\the\macname}% + \fi + \begingroup \macrobodyctxt + \ifrecursive \expandafter\parsermacbody + \else \expandafter\parsemacbody + \fi} + +\parseargdef\unmacro{% + \if1\csname ismacro.#1\endcsname + \global\cslet{#1}{macsave.#1}% + \global\expandafter\let \csname ismacro.#1\endcsname=0% + % Remove the macro name from \macrolist: + \begingroup + \expandafter\let\csname#1\endcsname \relax + \let\definedummyword\unmacrodo + \xdef\macrolist{\macrolist}% + \endgroup + \else + \errmessage{Macro #1 not defined}% + \fi +} + +% Called by \do from \dounmacro on each macro. The idea is to omit any +% macro definitions that have been changed to \relax. +% +\def\unmacrodo#1{% + \ifx #1\relax + % remove this + \else + \noexpand\definedummyword \noexpand#1% + \fi +} + +% This makes use of the obscure feature that if the last token of a +% is #, then the preceding argument is delimited by +% an opening brace, and that opening brace is not consumed. +\def\getargs#1{\getargsxxx#1{}} +\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +\def\getmacname#1 #2\relax{\macname={#1}} +\def\getmacargs#1{\def\argl{#1}} + +% For macro processing make @ a letter so that we can make Texinfo private macro names. +\edef\texiatcatcode{\the\catcode`\@} +\catcode `@=11\relax + +% Parse the optional {params} list. Set up \paramno and \paramlist +% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH +% in the params list to some hook where the argument si to be expanded. If +% there are less than 10 arguments that hook is to be replaced by ##N where N +% is the position in that list, that is to say the macro arguments are to be +% defined `a la TeX in the macro body. +% +% That gets used by \mbodybackslash (above). +% +% We need to get `macro parameter char #' into several definitions. +% The technique used is stolen from LaTeX: let \hash be something +% unexpandable, insert that wherever you need a #, and then redefine +% it to # just before using the token list produced. +% +% The same technique is used to protect \eatspaces till just before +% the macro is used. +% +% If there are 10 or more arguments, a different technique is used, where the +% hook remains in the body, and when macro is to be expanded the body is +% processed again to replace the arguments. +% +% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the +% argument N value and then \edef the body (nothing else will expand because of +% the catcode regime underwhich the body was input). +% +% If you compile with TeX (not eTeX), and you have macros with 10 or more +% arguments, you need that no macro has more than 256 arguments, otherwise an +% error is produced. +\def\parsemargdef#1;{% + \paramno=0\def\paramlist{}% + \let\hash\relax + \let\xeatspaces\relax + \parsemargdefxxx#1,;,% + % In case that there are 10 or more arguments we parse again the arguments + % list to set new definitions for the \macarg.BLAH macros corresponding to + % each BLAH argument. It was anyhow needed to parse already once this list + % in order to count the arguments, and as macros with at most 9 arguments + % are by far more frequent than macro with 10 or more arguments, defining + % twice the \macarg.BLAH macros does not cost too much processing power. + \ifnum\paramno<10\relax\else + \paramno0\relax + \parsemmanyargdef@@#1,;,% 10 or more arguments + \fi +} +\def\parsemargdefxxx#1,{% + \if#1;\let\next=\relax + \else \let\next=\parsemargdefxxx + \advance\paramno by 1 + \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname + {\xeatspaces{\hash\the\paramno}}% + \edef\paramlist{\paramlist\hash\the\paramno,}% + \fi\next} + +\def\parsemmanyargdef@@#1,{% + \if#1;\let\next=\relax + \else + \let\next=\parsemmanyargdef@@ + \edef\tempb{\eatspaces{#1}}% + \expandafter\def\expandafter\tempa + \expandafter{\csname macarg.\tempb\endcsname}% + % Note that we need some extra \noexpand\noexpand, this is because we + % don't want \the to be expanded in the \parsermacbody as it uses an + % \xdef . + \expandafter\edef\tempa + {\noexpand\noexpand\noexpand\the\toks\the\paramno}% + \advance\paramno by 1\relax + \fi\next} + +% These two commands read recursive and nonrecursive macro bodies. +% (They're different since rec and nonrec macros end differently.) +% + +\catcode `\@\texiatcatcode +\long\def\parsemacbody#1@end macro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\long\def\parsermacbody#1@end rmacro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\catcode `\@=11\relax + +\let\endargs@\relax +\let\nil@\relax +\def\nilm@{\nil@}% +\long\def\nillm@{\nil@}% + +% This macro is expanded during the Texinfo macro expansion, not during its +% definition. It gets all the arguments values and assigns them to macros +% macarg.ARGNAME +% +% #1 is the macro name +% #2 is the list of argument names +% #3 is the list of argument values +\def\getargvals@#1#2#3{% + \def\macargdeflist@{}% + \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion. + \def\paramlist{#2,\nil@}% + \def\macroname{#1}% + \begingroup + \macroargctxt + \def\argvaluelist{#3,\nil@}% + \def\@tempa{#3}% + \ifx\@tempa\empty + \setemptyargvalues@ + \else + \getargvals@@ + \fi +} + +% +\def\getargvals@@{% + \ifx\paramlist\nilm@ + % Some sanity check needed here that \argvaluelist is also empty. + \ifx\argvaluelist\nillm@ + \else + \errhelp = \EMsimple + \errmessage{Too many arguments in macro `\macroname'!}% + \fi + \let\next\macargexpandinbody@ + \else + \ifx\argvaluelist\nillm@ + % No more arguments values passed to macro. Set remaining named-arg + % macros to empty. + \let\next\setemptyargvalues@ + \else + % pop current arg name into \@tempb + \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}% + \expandafter\@tempa\expandafter{\paramlist}% + % pop current argument value into \@tempc + \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}% + \expandafter\@tempa\expandafter{\argvaluelist}% + % Here \@tempb is the current arg name and \@tempc is the current arg value. + % First place the new argument macro definition into \@tempd + \expandafter\macname\expandafter{\@tempc}% + \expandafter\let\csname macarg.\@tempb\endcsname\relax + \expandafter\def\expandafter\@tempe\expandafter{% + \csname macarg.\@tempb\endcsname}% + \edef\@tempd{\long\def\@tempe{\the\macname}}% + \push@\@tempd\macargdeflist@ + \let\next\getargvals@@ + \fi + \fi + \next +} + +\def\push@#1#2{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#2% + \expandafter\expandafter\expandafter{% + \expandafter#1#2}% +} + +% Replace arguments by their values in the macro body, and place the result +% in macro \@tempa +\def\macvalstoargs@{% + % To do this we use the property that token registers that are \the'ed + % within an \edef expand only once. So we are going to place all argument + % values into respective token registers. + % + % First we save the token context, and initialize argument numbering. + \begingroup + \paramno0\relax + % Then, for each argument number #N, we place the corresponding argument + % value into a new token list register \toks#N + \expandafter\putargsintokens@\saveparamlist@,;,% + % Then, we expand the body so that argument are replaced by their + % values. The trick for values not to be expanded themselves is that they + % are within tokens and that tokens expand only once in an \edef . + \edef\@tempc{\csname mac.\macroname .body\endcsname}% + % Now we restore the token stack pointer to free the token list registers + % which we have used, but we make sure that expanded body is saved after + % group. + \expandafter + \endgroup + \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% + } + +\def\macargexpandinbody@{% + %% Define the named-macro outside of this group and then close this group. + \expandafter + \endgroup + \macargdeflist@ + % First the replace in body the macro arguments by their values, the result + % is in \@tempa . + \macvalstoargs@ + % Then we point at the \norecurse or \gobble (for recursive) macro value + % with \@tempb . + \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname + % Depending on whether it is recursive or not, we need some tailing + % \egroup . + \ifx\@tempb\gobble + \let\@tempc\relax + \else + \let\@tempc\egroup + \fi + % And now we do the real job: + \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}% + \@tempd +} + +\def\putargsintokens@#1,{% + \if#1;\let\next\relax + \else + \let\next\putargsintokens@ + % First we allocate the new token list register, and give it a temporary + % alias \@tempb . + \toksdef\@tempb\the\paramno + % Then we place the argument value into that token list register. + \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname + \expandafter\@tempb\expandafter{\@tempa}% + \advance\paramno by 1\relax + \fi + \next +} + +% Save the token stack pointer into macro #1 +\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}} +% Restore the token stack pointer from number in macro #1 +\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax} +% newtoks that can be used non \outer . +\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi} + +% Tailing missing arguments are set to empty +\def\setemptyargvalues@{% + \ifx\paramlist\nilm@ + \let\next\macargexpandinbody@ + \else + \expandafter\setemptyargvaluesparser@\paramlist\endargs@ + \let\next\setemptyargvalues@ + \fi + \next +} + +\def\setemptyargvaluesparser@#1,#2\endargs@{% + \expandafter\def\expandafter\@tempa\expandafter{% + \expandafter\def\csname macarg.#1\endcsname{}}% + \push@\@tempa\macargdeflist@ + \def\paramlist{#2}% +} + +% #1 is the element target macro +% #2 is the list macro +% #3,#4\endargs@ is the list value +\def\pop@#1#2#3,#4\endargs@{% + \def#1{#3}% + \def#2{#4}% +} +\long\def\longpop@#1#2#3,#4\endargs@{% + \long\def#1{#3}% + \long\def#2{#4}% +} + +% This defines a Texinfo @macro. There are eight cases: recursive and +% nonrecursive macros of zero, one, up to nine, and many arguments. +% Much magic with \expandafter here. +% \xdef is used so that macro definitions will survive the file +% they're defined in; @include reads the file inside a group. +% +\def\defmacro{% + \let\hash=##% convert placeholders to macro parameter chars + \ifrecursive + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\scanmacro{\temp}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup\noexpand\scanmacro{\temp}}% + \else + \ifnum\paramno<10\relax % at most 9 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \else % 10 or more + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble + \fi + \fi + \else + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % at most 9 + \ifnum\paramno<10\relax + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \expandafter\noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % 10 or more: + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse + \fi + \fi + \fi} + +\catcode `\@\texiatcatcode\relax + +\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} + +% \braceorline decides whether the next nonwhitespace character is a +% {. If so it reads up to the closing }, if not, it reads the whole +% line. Whatever was read is then fed to the next control sequence +% as an argument (by \parsebrace or \parsearg). +% +\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} +\def\braceorlinexxx{% + \ifx\nchar\bgroup\else + \expandafter\parsearg + \fi \macnamexxx} + + +% @alias. +% We need some trickery to remove the optional spaces around the equal +% sign. Make them active and then expand them all to nothing. +% +\def\alias{\parseargusing\obeyspaces\aliasxxx} +\def\aliasxxx #1{\aliasyyy#1\relax} +\def\aliasyyy #1=#2\relax{% + {% + \expandafter\let\obeyedspace=\empty + \addtomacrolist{#1}% + \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}% + }% + \next +} + + +\message{cross references,} + +\newwrite\auxfile +\newif\ifhavexrefs % True if xref values are known. +\newif\ifwarnedxrefs % True if we warned once that they aren't known. + +% @inforef is relatively simple. +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{% + \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + +% @node's only job in TeX is to define \lastnode, which is used in +% cross-references. The @node line might or might not have commas, and +% might or might not have spaces before the first comma, like: +% @node foo , bar , ... +% We don't want such trailing spaces in the node name. +% +\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse} +% +% also remove a trailing comma, in case of something like this: +% @node Help-Cross, , , Cross-refs +\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse} +\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}} + +\let\nwnode=\node +\let\lastnode=\empty + +% Write a cross-reference definition for the current node. #1 is the +% type (Ynumbered, Yappendix, Ynothing). +% +\def\donoderef#1{% + \ifx\lastnode\empty\else + \setref{\lastnode}{#1}% + \global\let\lastnode=\empty + \fi +} + +% @anchor{NAME} -- define xref target at arbitrary point. +% +\newcount\savesfregister +% +\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} +\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} +\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} + +% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an +% anchor), which consists of three parts: +% 1) NAME-title - the current sectioning name taken from \lastsection, +% or the anchor name. +% 2) NAME-snt - section number and type, passed as the SNT arg, or +% empty for anchors. +% 3) NAME-pg - the page number. +% +% This is called from \donoderef, \anchor, and \dofloat. In the case of +% floats, there is an additional part, which is not written here: +% 4) NAME-lof - the text as it should appear in a @listoffloats. +% +\def\setref#1#2{% + \pdfmkdest{#1}% + \iflinks + {% + \atdummies % preserve commands, but don't expand them + \edef\writexrdef##1##2{% + \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef + ##1}{##2}}% these are parameters of \writexrdef + }% + \toks0 = \expandafter{\lastsection}% + \immediate \writexrdef{title}{\the\toks0 }% + \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. + \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout + }% + \fi +} + +% @xrefautosectiontitle on|off says whether @section(ing) names are used +% automatically in xrefs, if the third arg is not explicitly specified. +% This was provided as a "secret" @set xref-automatic-section-title +% variable, now it's official. +% +\parseargdef\xrefautomaticsectiontitle{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @xrefautomaticsectiontitle value `\temp', + must be on|off}% + \fi\fi +} + +% +% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is +% the node name, #2 the name of the Info cross-reference, #3 the printed +% node name, #4 the name of the Info file, #5 the name of the printed +% manual. All but the node name can be omitted. +% +\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} +\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} +\def\ref#1{\xrefX[#1,,,,,,,]} +% +\newbox\toprefbox +\newbox\printedrefnamebox +\newbox\infofilenamebox +\newbox\printedmanualbox +% +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \unsepspaces + % + % Get args without leading/trailing spaces. + \def\printedrefname{\ignorespaces #3}% + \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% + % + \def\infofilename{\ignorespaces #4}% + \setbox\infofilenamebox = \hbox{\infofilename\unskip}% + % + \def\printedmanual{\ignorespaces #5}% + \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% + % + % If the printed reference name (arg #3) was not explicitly given in + % the @xref, figure out what we want to use. + \ifdim \wd\printedrefnamebox = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax + % Not auto section-title: use node name inside the square brackets. + \def\printedrefname{\ignorespaces #1}% + \else + % Auto section-title: use chapter/section title inside + % the square brackets if we have it. + \ifdim \wd\printedmanualbox > 0pt + % It is in another manual, so we don't have it; use node name. + \def\printedrefname{\ignorespaces #1}% + \else + \ifhavexrefs + % We (should) know the real title if we have the xref values. + \def\printedrefname{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printedrefname{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % Make link in pdf output. + \ifpdf + {\indexnofonts + \turnoffactive + \makevalueexpandable + % This expands tokens, so do it after making catcode changes, so _ + % etc. don't get their TeX definitions. This ignores all spaces in + % #4, including (wrongly) those in the middle of the filename. + \getfilename{#4}% + % + % This (wrongly) does not take account of leading or trailing + % spaces in #1, which should be ignored. + \edef\pdfxrefdest{#1}% + \ifx\pdfxrefdest\empty + \def\pdfxrefdest{Top}% no empty targets + \else + \txiescapepdf\pdfxrefdest % escape PDF special chars + \fi + % + \leavevmode + \startlink attr{/Border [0 0 0]}% + \ifnum\filenamelength>0 + goto file{\the\filename.pdf} name{\pdfxrefdest}% + \else + goto name{\pdfmkpgn{\pdfxrefdest}}% + \fi + }% + \setcolor{\linkcolor}% + \fi + % + % Float references are printed completely differently: "Figure 1.2" + % instead of "[somenode], p.3". We distinguish them by the + % LABEL-title being set to a magic string. + {% + % Have to otherify everything special to allow the \csname to + % include an _ in the xref name, etc. + \indexnofonts + \turnoffactive + \expandafter\global\expandafter\let\expandafter\Xthisreftitle + \csname XR#1-title\endcsname + }% + \iffloat\Xthisreftitle + % If the user specified the print name (third arg) to the ref, + % print it instead of our usual "Figure 1.2". + \ifdim\wd\printedrefnamebox = 0pt + \refx{#1-snt}{}% + \else + \printedrefname + \fi + % + % If the user also gave the printed manual name (fifth arg), append + % "in MANUALNAME". + \ifdim \wd\printedmanualbox > 0pt + \space \putwordin{} \cite{\printedmanual}% + \fi + \else + % node/anchor (non-float) references. + % + % If we use \unhbox to print the node names, TeX does not insert + % empty discretionaries after hyphens, which means that it will not + % find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, + % this is a loss. Therefore, we give the text of the node name + % again, so it is as if TeX is seeing it for the first time. + % + \ifdim \wd\printedmanualbox > 0pt + % Cross-manual reference with a printed manual name. + % + \crossmanualxref{\cite{\printedmanual\unskip}}% + % + \else\ifdim \wd\infofilenamebox > 0pt + % Cross-manual reference with only an info filename (arg 4), no + % printed manual name (arg 5). This is essentially the same as + % the case above; we output the filename, since we have nothing else. + % + \crossmanualxref{\code{\infofilename\unskip}}% + % + \else + % Reference within this manual. + % + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\turnoffactive + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % output the `[mynode]' via the macro below so it can be overridden. + \xrefprintnodename\printedrefname + % + % But we always want a comma and a space: + ,\space + % + % output the `page 3'. + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + \fi\fi + \fi + \endlink +\endgroup} + +% Output a cross-manual xref to #1. Used just above (twice). +% +% Only include the text "Section ``foo'' in" if the foo is neither +% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply +% "see The Foo Manual", the idea being to refer to the whole manual. +% +% But, this being TeX, we can't easily compare our node name against the +% string "Top" while ignoring the possible spaces before and after in +% the input. By adding the arbitrary 7sp below, we make it much less +% likely that a real node name would have the same width as "Top" (e.g., +% in a monospaced font). Hopefully it will never happen in practice. +% +% For the same basic reason, we retypeset the "Top" at every +% reference, since the current font is indeterminate. +% +\def\crossmanualxref#1{% + \setbox\toprefbox = \hbox{Top\kern7sp}% + \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% + \ifdim \wd2 > 7sp % nonempty? + \ifdim \wd2 = \wd\toprefbox \else % same as Top? + \putwordSection{} ``\printedrefname'' \putwordin{}\space + \fi + \fi + #1% +} + +% This macro is called from \xrefX for the `[nodename]' part of xref +% output. It's a separate macro only so it can be changed more easily, +% since square brackets don't work well in some documents. Particularly +% one that Bob is working on :). +% +\def\xrefprintnodename#1{[#1]} + +% Things referred to by \setref. +% +\def\Ynothing{} +\def\Yomitfromtoc{} +\def\Ynumbered{% + \ifnum\secno=0 + \putwordChapter@tie \the\chapno + \else \ifnum\subsecno=0 + \putwordSection@tie \the\chapno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno + \else + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} +\def\Yappendix{% + \ifnum\secno=0 + \putwordAppendix@tie @char\the\appendixno{}% + \else \ifnum\subsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno + \else + \putwordSection@tie + @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} + +% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. +% If its value is nonempty, SUFFIX is output afterward. +% +\def\refx#1#2{% + {% + \indexnofonts + \otherbackslash + \expandafter\global\expandafter\let\expandafter\thisrefX + \csname XR#1\endcsname + }% + \ifx\thisrefX\relax + % If not defined, say something at least. + \angleleft un\-de\-fined\angleright + \iflinks + \ifhavexrefs + {\toks0 = {#1}% avoid expansion of possibly-complex value + \message{\linenumber Undefined cross reference `\the\toks0'.}}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \fi + \else + % It's defined, so just use it. + \thisrefX + \fi + #2% Output the suffix in any case. +} + +% This is the macro invoked by entries in the aux file. Usually it's +% just a \def (we prepend XR to the control sequence name to avoid +% collisions). But if this is a float type, we have more work to do. +% +\def\xrdef#1#2{% + {% The node name might contain 8-bit characters, which in our current + % implementation are changed to commands like @'e. Don't let these + % mess up the control sequence name. + \indexnofonts + \turnoffactive + \xdef\safexrefname{#1}% + }% + % + \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref + % + % Was that xref control sequence that we just defined for a float? + \expandafter\iffloat\csname XR\safexrefname\endcsname + % it was a float, and we have the (safe) float type in \iffloattype. + \expandafter\let\expandafter\floatlist + \csname floatlist\iffloattype\endcsname + % + % Is this the first time we've seen this float type? + \expandafter\ifx\floatlist\relax + \toks0 = {\do}% yes, so just \do + \else + % had it before, so preserve previous elements in list. + \toks0 = \expandafter{\floatlist\do}% + \fi + % + % Remember this xref in the control sequence \floatlistFLOATTYPE, + % for later use in \listoffloats. + \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0 + {\safexrefname}}% + \fi +} + +% Read the last existing aux file, if any. No error if none exists. +% +\def\tryauxfile{% + \openin 1 \jobname.aux + \ifeof 1 \else + \readdatafile{aux}% + \global\havexrefstrue + \fi + \closein 1 +} + +\def\setupdatafile{% + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\^=\other + % + % Special characters. Should be turned off anyway, but... + \catcode`\~=\other + \catcode`\[=\other + \catcode`\]=\other + \catcode`\"=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\$=\other + \catcode`\#=\other + \catcode`\&=\other + \catcode`\%=\other + \catcode`+=\other % avoid \+ for paranoia even though we've turned it off + % + % This is to support \ in node names and titles, since the \ + % characters end up in a \csname. It's easier than + % leaving it active and making its active definition an actual \ + % character. What I don't understand is why it works in the *value* + % of the xrdef. Seems like it should be a catcode12 \, and that + % should not typeset properly. But it works, so I'm moving on for + % now. --karl, 15jan04. + \catcode`\\=\other + % + % Make the characters 128-255 be printing characters. + {% + \count1=128 + \def\loop{% + \catcode\count1=\other + \advance\count1 by 1 + \ifnum \count1<256 \loop \fi + }% + }% + % + % @ is our escape character in .aux files, and we need braces. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\@=0 +} + +\def\readdatafile#1{% +\begingroup + \setupdatafile + \input\jobname.#1 +\endgroup} + + +\message{insertions,} +% including footnotes. + +\newcount \footnoteno + +% The trailing space in the following definition for supereject is +% vital for proper filling; pages come out unaligned when you do a +% pagealignmacro call if that space before the closing brace is +% removed. (Generally, numeric constants should always be followed by a +% space to prevent strange expansion errors.) +\def\supereject{\par\penalty -20000\footnoteno =0 } + +% @footnotestyle is meaningful for Info output only. +\let\footnotestyle=\comment + +{\catcode `\@=11 +% +% Auto-number footnotes. Otherwise like plain. +\gdef\footnote{% + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \dofootnote +}% + +% Don't bother with the trickery in plain.tex to not require the +% footnote text as a parameter. Our footnotes don't need to be so general. +% +% Oh yes, they do; otherwise, @ifset (and anything else that uses +% \parseargline) fails inside footnotes because the tokens are fixed when +% the footnote is read. --karl, 16nov96. +% +\gdef\dofootnote{% + \insert\footins\bgroup + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. + \hsize=\pagewidth + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + \smallfonts \rm + % + % Because we use hanging indentation in footnotes, a @noindent appears + % to exdent this text, so make it be a no-op. makeinfo does not use + % hanging indentation so @noindent can still be needed within footnote + % text after an @example or the like (not that this is good style). + \let\noindent = \relax + % + % Hang the footnote text off the number. Use \everypar in case the + % footnote extends for more than one paragraph. + \everypar = {\hang}% + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + % + % Invoke rest of plain TeX footnote routine. + \futurelet\next\fo@t +} +}%end \catcode `\@=11 + +% In case a @footnote appears in a vbox, save the footnote text and create +% the real \insert just after the vbox finished. Otherwise, the insertion +% would be lost. +% Similarly, if a @footnote appears inside an alignment, save the footnote +% text to a box and make the \insert when a row of the table is finished. +% And the same can be done for other insert classes. --kasal, 16nov03. + +% Replace the \insert primitive by a cheating macro. +% Deeper inside, just make sure that the saved insertions are not spilled +% out prematurely. +% +\def\startsavinginserts{% + \ifx \insert\ptexinsert + \let\insert\saveinsert + \else + \let\checkinserts\relax + \fi +} + +% This \insert replacement works for both \insert\footins{foo} and +% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}. +% +\def\saveinsert#1{% + \edef\next{\noexpand\savetobox \makeSAVEname#1}% + \afterassignment\next + % swallow the left brace + \let\temp = +} +\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}} +\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1} + +\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi} + +\def\placesaveins#1{% + \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname + {\box#1}% +} + +% eat @SAVE -- beware, all of them have catcode \other: +{ + \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-) + \gdef\gobblesave @SAVE{} +} + +% initialization: +\def\newsaveins #1{% + \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}% + \next +} +\def\newsaveinsX #1{% + \csname newbox\endcsname #1% + \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts + \checksaveins #1}% +} + +% initialize: +\let\checkinserts\empty +\newsaveins\footins +\newsaveins\margin + + +% @image. We use the macros from epsf.tex to support this. +% If epsf.tex is not installed and @image is used, we complain. +% +% Check for and read epsf.tex up front. If we read it only at @image +% time, we might be inside a group, and then its definitions would get +% undone and the next image would fail. +\openin 1 = epsf.tex +\ifeof 1 \else + % Do not bother showing banner with epsf.tex v2.7k (available in + % doc/epsf.tex and on ctan). + \def\epsfannounce{\toks0 = }% + \input epsf.tex +\fi +\closein 1 +% +% We will only complain once about lack of epsf.tex. +\newif\ifwarnednoepsf +\newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from ftp://tug.org/tex/epsf.tex.} +% +\def\image#1{% + \ifx\epsfbox\thisisundefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,,,\finish + \fi +} +% +% Arguments to @image: +% #1 is (mandatory) image filename; we tack on .eps extension. +% #2 is (optional) width, #3 is (optional) height. +% #4 is (ignored optional) html alt text. +% #5 is (ignored optional) extension. +% #6 is just the usual extra ignored arg for parsing stuff. +\newif\ifimagevmode +\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup + \catcode`\^^M = 5 % in case we're inside an example + \normalturnoffactive % allow _ et al. in names + % If the image is by itself, center it. + \ifvmode + \imagevmodetrue + \else \ifx\centersub\centerV + % for @center @image, we need a vbox so we can have our vertical space + \imagevmodetrue + \vbox\bgroup % vbox has better behavior than vtop herev + \fi\fi + % + \ifimagevmode + \nobreak\medskip + % Usually we'll have text after the image which will insert + % \parskip glue, so insert it here too to equalize the space + % above and below. + \nobreak\vskip\parskip + \nobreak + \fi + % + % Leave vertical mode so that indentation from an enclosing + % environment such as @quotation is respected. + % However, if we're at the top level, we don't want the + % normal paragraph indentation. + % On the other hand, if we are in the case of @center @image, we don't + % want to start a paragraph, which will create a hsize-width box and + % eradicate the centering. + \ifx\centersub\centerV\else \noindent \fi + % + % Output the image. + \ifpdf + \dopdfimage{#1}{#2}{#3}% + \else + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \epsfbox{#1.eps}% + \fi + % + \ifimagevmode + \medskip % space after a standalone image + \fi + \ifx\centersub\centerV \egroup \fi +\endgroup} + + +% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables, +% etc. We don't actually implement floating yet, we always include the +% float "here". But it seemed the best name for the future. +% +\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish} + +% There may be a space before second and/or third parameter; delete it. +\def\eatcommaspace#1, {#1,} + +% #1 is the optional FLOATTYPE, the text label for this float, typically +% "Figure", "Table", "Example", etc. Can't contain commas. If omitted, +% this float will not be numbered and cannot be referred to. +% +% #2 is the optional xref label. Also must be present for the float to +% be referable. +% +% #3 is the optional positioning argument; for now, it is ignored. It +% will somehow specify the positions allowed to float to (here, top, bottom). +% +% We keep a separate counter for each FLOATTYPE, which we reset at each +% chapter-level command. +\let\resetallfloatnos=\empty +% +\def\dofloat#1,#2,#3,#4\finish{% + \let\thiscaption=\empty + \let\thisshortcaption=\empty + % + % don't lose footnotes inside @float. + % + % BEWARE: when the floats start float, we have to issue warning whenever an + % insert appears inside a float which could possibly float. --kasal, 26may04 + % + \startsavinginserts + % + % We can't be used inside a paragraph. + \par + % + \vtop\bgroup + \def\floattype{#1}% + \def\floatlabel{#2}% + \def\floatloc{#3}% we do nothing with this yet. + % + \ifx\floattype\empty + \let\safefloattype=\empty + \else + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + \fi + % + % If label is given but no type, we handle that as the empty type. + \ifx\floatlabel\empty \else + % We want each FLOATTYPE to be numbered separately (Figure 1, + % Table 1, Figure 2, ...). (And if no label, no number.) + % + \expandafter\getfloatno\csname\safefloattype floatno\endcsname + \global\advance\floatno by 1 + % + {% + % This magic value for \lastsection is output by \setref as the + % XREFLABEL-title value. \xrefX uses it to distinguish float + % labels (which have a completely different output format) from + % node and anchor labels. And \xrdef uses it to construct the + % lists of floats. + % + \edef\lastsection{\floatmagic=\safefloattype}% + \setref{\floatlabel}{Yfloat}% + }% + \fi + % + % start with \parskip glue, I guess. + \vskip\parskip + % + % Don't suppress indentation if a float happens to start a section. + \restorefirstparagraphindent +} + +% we have these possibilities: +% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap +% @float Foo,lbl & no caption: Foo 1.1 +% @float Foo & @caption{Cap}: Foo: Cap +% @float Foo & no caption: Foo +% @float ,lbl & Caption{Cap}: 1.1: Cap +% @float ,lbl & no caption: 1.1 +% @float & @caption{Cap}: Cap +% @float & no caption: +% +\def\Efloat{% + \let\floatident = \empty + % + % In all cases, if we have a float type, it comes first. + \ifx\floattype\empty \else \def\floatident{\floattype}\fi + % + % If we have an xref label, the number comes next. + \ifx\floatlabel\empty \else + \ifx\floattype\empty \else % if also had float type, need tie first. + \appendtomacro\floatident{\tie}% + \fi + % the number. + \appendtomacro\floatident{\chaplevelprefix\the\floatno}% + \fi + % + % Start the printed caption with what we've constructed in + % \floatident, but keep it separate; we need \floatident again. + \let\captionline = \floatident + % + \ifx\thiscaption\empty \else + \ifx\floatident\empty \else + \appendtomacro\captionline{: }% had ident, so need a colon between + \fi + % + % caption text. + \appendtomacro\captionline{\scanexp\thiscaption}% + \fi + % + % If we have anything to print, print it, with space before. + % Eventually this needs to become an \insert. + \ifx\captionline\empty \else + \vskip.5\parskip + \captionline + % + % Space below caption. + \vskip\parskip + \fi + % + % If have an xref label, write the list of floats info. Do this + % after the caption, to avoid chance of it being a breakpoint. + \ifx\floatlabel\empty \else + % Write the text that goes in the lof to the aux file as + % \floatlabel-lof. Besides \floatident, we include the short + % caption if specified, else the full caption if specified, else nothing. + {% + \atdummies + % + % since we read the caption text in the macro world, where ^^M + % is turned into a normal character, we have to scan it back, so + % we don't write the literal three characters "^^M" into the aux file. + \scanexp{% + \xdef\noexpand\gtemp{% + \ifx\thisshortcaption\empty + \thiscaption + \else + \thisshortcaption + \fi + }% + }% + \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident + \ifx\gtemp\empty \else : \gtemp \fi}}% + }% + \fi + \egroup % end of \vtop + % + % place the captured inserts + % + % BEWARE: when the floats start floating, we have to issue warning + % whenever an insert appears inside a float which could possibly + % float. --kasal, 26may04 + % + \checkinserts +} + +% Append the tokens #2 to the definition of macro #1, not expanding either. +% +\def\appendtomacro#1#2{% + \expandafter\def\expandafter#1\expandafter{#1#2}% +} + +% @caption, @shortcaption +% +\def\caption{\docaption\thiscaption} +\def\shortcaption{\docaption\thisshortcaption} +\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption} +\def\defcaption#1#2{\egroup \def#1{#2}} + +% The parameter is the control sequence identifying the counter we are +% going to use. Create it if it doesn't exist and assign it to \floatno. +\def\getfloatno#1{% + \ifx#1\relax + % Haven't seen this figure type before. + \csname newcount\endcsname #1% + % + % Remember to reset this floatno at the next chap. + \expandafter\gdef\expandafter\resetallfloatnos + \expandafter{\resetallfloatnos #1=0 }% + \fi + \let\floatno#1% +} + +% \setref calls this to get the XREFLABEL-snt value. We want an @xref +% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we +% first read the @float command. +% +\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}% + +% Magic string used for the XREFLABEL-title value, so \xrefX can +% distinguish floats from other xref types. +\def\floatmagic{!!float!!} + +% #1 is the control sequence we are passed; we expand into a conditional +% which is true if #1 represents a float ref. That is, the magic +% \lastsection value which we \setref above. +% +\def\iffloat#1{\expandafter\doiffloat#1==\finish} +% +% #1 is (maybe) the \floatmagic string. If so, #2 will be the +% (safe) float type for this float. We set \iffloattype to #2. +% +\def\doiffloat#1=#2=#3\finish{% + \def\temp{#1}% + \def\iffloattype{#2}% + \ifx\temp\floatmagic +} + +% @listoffloats FLOATTYPE - print a list of floats like a table of contents. +% +\parseargdef\listoffloats{% + \def\floattype{#1}% floattype + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + % + % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE. + \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax + \ifhavexrefs + % if the user said @listoffloats foo but never @float foo. + \message{\linenumber No `\safefloattype' floats to list.}% + \fi + \else + \begingroup + \leftskip=\tocindent % indent these entries like a toc + \let\do=\listoffloatsdo + \csname floatlist\safefloattype\endcsname + \endgroup + \fi +} + +% This is called on each entry in a list of floats. We're passed the +% xref label, in the form LABEL-title, which is how we save it in the +% aux file. We strip off the -title and look up \XRLABEL-lof, which +% has the text we're supposed to typeset here. +% +% Figures without xref labels will not be included in the list (since +% they won't appear in the aux file). +% +\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish} +\def\listoffloatsdoentry#1-title\finish{{% + % Can't fully expand XR#1-lof because it can contain anything. Just + % pass the control sequence. On the other hand, XR#1-pg is just the + % page number, and we want to fully expand that so we can get a link + % in pdf output. + \toksA = \expandafter{\csname XR#1-lof\endcsname}% + % + % use the same \entry macro we use to generate the TOC and index. + \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% + \writeentry +}} + + +\message{localization,} + +% For single-language documents, @documentlanguage is usually given very +% early, just after @documentencoding. Single argument is the language +% (de) or locale (de_DE) abbreviation. +% +{ + \catcode`\_ = \active + \globaldefs=1 +\parseargdef\documentlanguage{\begingroup + \let_=\normalunderscore % normal _ character for filenames + \tex % read txi-??.tex file in plain TeX. + % Read the file by the name they passed if it exists. + \openin 1 txi-#1.tex + \ifeof 1 + \documentlanguagetrywithoutunderscore{#1_\finish}% + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 + \endgroup % end raw TeX +\endgroup} +% +% If they passed de_DE, and txi-de_DE.tex doesn't exist, +% try txi-de.tex. +% +\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{% + \openin 1 txi-#1.tex + \ifeof 1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 +} +}% end of special _ catcode +% +\newhelp\nolanghelp{The given language definition file cannot be found or +is empty. Maybe you need to install it? Putting it in the current +directory should work if nowhere else does.} + +% This macro is called from txi-??.tex files; the first argument is the +% \language name to set (without the "\lang@" prefix), the second and +% third args are \{left,right}hyphenmin. +% +% The language names to pass are determined when the format is built. +% See the etex.log file created at that time, e.g., +% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log. +% +% With TeX Live 2008, etex now includes hyphenation patterns for all +% available languages. This means we can support hyphenation in +% Texinfo, at least to some extent. (This still doesn't solve the +% accented characters problem.) +% +\catcode`@=11 +\def\txisetlanguage#1#2#3{% + % do not set the language if the name is undefined in the current TeX. + \expandafter\ifx\csname lang@#1\endcsname \relax + \message{no patterns for #1}% + \else + \global\language = \csname lang@#1\endcsname + \fi + % but there is no harm in adjusting the hyphenmin values regardless. + \global\lefthyphenmin = #2\relax + \global\righthyphenmin = #3\relax +} + +% Helpers for encodings. +% Set the catcode of characters 128 through 255 to the specified number. +% +\def\setnonasciicharscatcode#1{% + \count255=128 + \loop\ifnum\count255<256 + \global\catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +\def\setnonasciicharscatcodenonglobal#1{% + \count255=128 + \loop\ifnum\count255<256 + \catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +% @documentencoding sets the definition of non-ASCII characters +% according to the specified encoding. +% +\parseargdef\documentencoding{% + % Encoding being declared for the document. + \def\declaredencoding{\csname #1.enc\endcsname}% + % + % Supported encodings: names converted to tokens in order to be able + % to compare them with \ifx. + \def\ascii{\csname US-ASCII.enc\endcsname}% + \def\latnine{\csname ISO-8859-15.enc\endcsname}% + \def\latone{\csname ISO-8859-1.enc\endcsname}% + \def\lattwo{\csname ISO-8859-2.enc\endcsname}% + \def\utfeight{\csname UTF-8.enc\endcsname}% + % + \ifx \declaredencoding \ascii + \asciichardefs + % + \else \ifx \declaredencoding \lattwo + \setnonasciicharscatcode\active + \lattwochardefs + % + \else \ifx \declaredencoding \latone + \setnonasciicharscatcode\active + \latonechardefs + % + \else \ifx \declaredencoding \latnine + \setnonasciicharscatcode\active + \latninechardefs + % + \else \ifx \declaredencoding \utfeight + \setnonasciicharscatcode\active + \utfeightchardefs + % + \else + \message{Unknown document encoding #1, ignoring.}% + % + \fi % utfeight + \fi % latnine + \fi % latone + \fi % lattwo + \fi % ascii +} + +% A message to be logged when using a character that isn't available +% the default font encoding (OT1). +% +\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}} + +% Take account of \c (plain) vs. \, (Texinfo) difference. +\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi} + +% First, make active non-ASCII characters in order for them to be +% correctly categorized when TeX reads the replacement text of +% macros containing the character definitions. +\setnonasciicharscatcode\active +% +% Latin1 (ISO-8859-1) character definitions. +\def\latonechardefs{% + \gdef^^a0{\tie} + \gdef^^a1{\exclamdown} + \gdef^^a2{\missingcharmsg{CENT SIGN}} + \gdef^^a3{{\pounds}} + \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdef^^a5{\missingcharmsg{YEN SIGN}} + \gdef^^a6{\missingcharmsg{BROKEN BAR}} + \gdef^^a7{\S} + \gdef^^a8{\"{}} + \gdef^^a9{\copyright} + \gdef^^aa{\ordf} + \gdef^^ab{\guillemetleft} + \gdef^^ac{$\lnot$} + \gdef^^ad{\-} + \gdef^^ae{\registeredsymbol} + \gdef^^af{\={}} + % + \gdef^^b0{\textdegree} + \gdef^^b1{$\pm$} + \gdef^^b2{$^2$} + \gdef^^b3{$^3$} + \gdef^^b4{\'{}} + \gdef^^b5{$\mu$} + \gdef^^b6{\P} + % + \gdef^^b7{$^.$} + \gdef^^b8{\cedilla\ } + \gdef^^b9{$^1$} + \gdef^^ba{\ordm} + % + \gdef^^bb{\guillemetright} + \gdef^^bc{$1\over4$} + \gdef^^bd{$1\over2$} + \gdef^^be{$3\over4$} + \gdef^^bf{\questiondown} + % + \gdef^^c0{\`A} + \gdef^^c1{\'A} + \gdef^^c2{\^A} + \gdef^^c3{\~A} + \gdef^^c4{\"A} + \gdef^^c5{\ringaccent A} + \gdef^^c6{\AE} + \gdef^^c7{\cedilla C} + \gdef^^c8{\`E} + \gdef^^c9{\'E} + \gdef^^ca{\^E} + \gdef^^cb{\"E} + \gdef^^cc{\`I} + \gdef^^cd{\'I} + \gdef^^ce{\^I} + \gdef^^cf{\"I} + % + \gdef^^d0{\DH} + \gdef^^d1{\~N} + \gdef^^d2{\`O} + \gdef^^d3{\'O} + \gdef^^d4{\^O} + \gdef^^d5{\~O} + \gdef^^d6{\"O} + \gdef^^d7{$\times$} + \gdef^^d8{\O} + \gdef^^d9{\`U} + \gdef^^da{\'U} + \gdef^^db{\^U} + \gdef^^dc{\"U} + \gdef^^dd{\'Y} + \gdef^^de{\TH} + \gdef^^df{\ss} + % + \gdef^^e0{\`a} + \gdef^^e1{\'a} + \gdef^^e2{\^a} + \gdef^^e3{\~a} + \gdef^^e4{\"a} + \gdef^^e5{\ringaccent a} + \gdef^^e6{\ae} + \gdef^^e7{\cedilla c} + \gdef^^e8{\`e} + \gdef^^e9{\'e} + \gdef^^ea{\^e} + \gdef^^eb{\"e} + \gdef^^ec{\`{\dotless i}} + \gdef^^ed{\'{\dotless i}} + \gdef^^ee{\^{\dotless i}} + \gdef^^ef{\"{\dotless i}} + % + \gdef^^f0{\dh} + \gdef^^f1{\~n} + \gdef^^f2{\`o} + \gdef^^f3{\'o} + \gdef^^f4{\^o} + \gdef^^f5{\~o} + \gdef^^f6{\"o} + \gdef^^f7{$\div$} + \gdef^^f8{\o} + \gdef^^f9{\`u} + \gdef^^fa{\'u} + \gdef^^fb{\^u} + \gdef^^fc{\"u} + \gdef^^fd{\'y} + \gdef^^fe{\th} + \gdef^^ff{\"y} +} + +% Latin9 (ISO-8859-15) encoding character definitions. +\def\latninechardefs{% + % Encoding is almost identical to Latin1. + \latonechardefs + % + \gdef^^a4{\euro} + \gdef^^a6{\v S} + \gdef^^a8{\v s} + \gdef^^b4{\v Z} + \gdef^^b8{\v z} + \gdef^^bc{\OE} + \gdef^^bd{\oe} + \gdef^^be{\"Y} +} + +% Latin2 (ISO-8859-2) character definitions. +\def\lattwochardefs{% + \gdef^^a0{\tie} + \gdef^^a1{\ogonek{A}} + \gdef^^a2{\u{}} + \gdef^^a3{\L} + \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdef^^a5{\v L} + \gdef^^a6{\'S} + \gdef^^a7{\S} + \gdef^^a8{\"{}} + \gdef^^a9{\v S} + \gdef^^aa{\cedilla S} + \gdef^^ab{\v T} + \gdef^^ac{\'Z} + \gdef^^ad{\-} + \gdef^^ae{\v Z} + \gdef^^af{\dotaccent Z} + % + \gdef^^b0{\textdegree} + \gdef^^b1{\ogonek{a}} + \gdef^^b2{\ogonek{ }} + \gdef^^b3{\l} + \gdef^^b4{\'{}} + \gdef^^b5{\v l} + \gdef^^b6{\'s} + \gdef^^b7{\v{}} + \gdef^^b8{\cedilla\ } + \gdef^^b9{\v s} + \gdef^^ba{\cedilla s} + \gdef^^bb{\v t} + \gdef^^bc{\'z} + \gdef^^bd{\H{}} + \gdef^^be{\v z} + \gdef^^bf{\dotaccent z} + % + \gdef^^c0{\'R} + \gdef^^c1{\'A} + \gdef^^c2{\^A} + \gdef^^c3{\u A} + \gdef^^c4{\"A} + \gdef^^c5{\'L} + \gdef^^c6{\'C} + \gdef^^c7{\cedilla C} + \gdef^^c8{\v C} + \gdef^^c9{\'E} + \gdef^^ca{\ogonek{E}} + \gdef^^cb{\"E} + \gdef^^cc{\v E} + \gdef^^cd{\'I} + \gdef^^ce{\^I} + \gdef^^cf{\v D} + % + \gdef^^d0{\DH} + \gdef^^d1{\'N} + \gdef^^d2{\v N} + \gdef^^d3{\'O} + \gdef^^d4{\^O} + \gdef^^d5{\H O} + \gdef^^d6{\"O} + \gdef^^d7{$\times$} + \gdef^^d8{\v R} + \gdef^^d9{\ringaccent U} + \gdef^^da{\'U} + \gdef^^db{\H U} + \gdef^^dc{\"U} + \gdef^^dd{\'Y} + \gdef^^de{\cedilla T} + \gdef^^df{\ss} + % + \gdef^^e0{\'r} + \gdef^^e1{\'a} + \gdef^^e2{\^a} + \gdef^^e3{\u a} + \gdef^^e4{\"a} + \gdef^^e5{\'l} + \gdef^^e6{\'c} + \gdef^^e7{\cedilla c} + \gdef^^e8{\v c} + \gdef^^e9{\'e} + \gdef^^ea{\ogonek{e}} + \gdef^^eb{\"e} + \gdef^^ec{\v e} + \gdef^^ed{\'{\dotless{i}}} + \gdef^^ee{\^{\dotless{i}}} + \gdef^^ef{\v d} + % + \gdef^^f0{\dh} + \gdef^^f1{\'n} + \gdef^^f2{\v n} + \gdef^^f3{\'o} + \gdef^^f4{\^o} + \gdef^^f5{\H o} + \gdef^^f6{\"o} + \gdef^^f7{$\div$} + \gdef^^f8{\v r} + \gdef^^f9{\ringaccent u} + \gdef^^fa{\'u} + \gdef^^fb{\H u} + \gdef^^fc{\"u} + \gdef^^fd{\'y} + \gdef^^fe{\cedilla t} + \gdef^^ff{\dotaccent{}} +} + +% UTF-8 character definitions. +% +% This code to support UTF-8 is based on LaTeX's utf8.def, with some +% changes for Texinfo conventions. It is included here under the GPL by +% permission from Frank Mittelbach and the LaTeX team. +% +\newcount\countUTFx +\newcount\countUTFy +\newcount\countUTFz + +\gdef\UTFviiiTwoOctets#1#2{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\endcsname} +% +\gdef\UTFviiiThreeOctets#1#2#3{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname} +% +\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname} + +\gdef\UTFviiiDefined#1{% + \ifx #1\relax + \message{\linenumber Unicode char \string #1 not defined for Texinfo}% + \else + \expandafter #1% + \fi +} + +\begingroup + \catcode`\~13 + \catcode`\"12 + + \def\UTFviiiLoop{% + \global\catcode\countUTFx\active + \uccode`\~\countUTFx + \uppercase\expandafter{\UTFviiiTmp}% + \advance\countUTFx by 1 + \ifnum\countUTFx < \countUTFy + \expandafter\UTFviiiLoop + \fi} + + \countUTFx = "C2 + \countUTFy = "E0 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiTwoOctets\string~}} + \UTFviiiLoop + + \countUTFx = "E0 + \countUTFy = "F0 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiThreeOctets\string~}} + \UTFviiiLoop + + \countUTFx = "F0 + \countUTFy = "F4 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiFourOctets\string~}} + \UTFviiiLoop +\endgroup + +\begingroup + \catcode`\"=12 + \catcode`\<=12 + \catcode`\.=12 + \catcode`\,=12 + \catcode`\;=12 + \catcode`\!=12 + \catcode`\~=13 + + \gdef\DeclareUnicodeCharacter#1#2{% + \countUTFz = "#1\relax + %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% + \begingroup + \parseXMLCharref + \def\UTFviiiTwoOctets##1##2{% + \csname u8:##1\string ##2\endcsname}% + \def\UTFviiiThreeOctets##1##2##3{% + \csname u8:##1\string ##2\string ##3\endcsname}% + \def\UTFviiiFourOctets##1##2##3##4{% + \csname u8:##1\string ##2\string ##3\string ##4\endcsname}% + \expandafter\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter + \gdef\UTFviiiTmp{#2}% + \endgroup} + + \gdef\parseXMLCharref{% + \ifnum\countUTFz < "A0\relax + \errhelp = \EMsimple + \errmessage{Cannot define Unicode char value < 00A0}% + \else\ifnum\countUTFz < "800\relax + \parseUTFviiiA,% + \parseUTFviiiB C\UTFviiiTwoOctets.,% + \else\ifnum\countUTFz < "10000\relax + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiB E\UTFviiiThreeOctets.{,;}% + \else + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiA!% + \parseUTFviiiB F\UTFviiiFourOctets.{!,;}% + \fi\fi\fi + } + + \gdef\parseUTFviiiA#1{% + \countUTFx = \countUTFz + \divide\countUTFz by 64 + \countUTFy = \countUTFz + \multiply\countUTFz by 64 + \advance\countUTFx by -\countUTFz + \advance\countUTFx by 128 + \uccode `#1\countUTFx + \countUTFz = \countUTFy} + + \gdef\parseUTFviiiB#1#2#3#4{% + \advance\countUTFz by "#10\relax + \uccode `#3\countUTFz + \uppercase{\gdef\UTFviiiTmp{#2#3#4}}} +\endgroup + +\def\utfeightchardefs{% + \DeclareUnicodeCharacter{00A0}{\tie} + \DeclareUnicodeCharacter{00A1}{\exclamdown} + \DeclareUnicodeCharacter{00A3}{\pounds} + \DeclareUnicodeCharacter{00A8}{\"{ }} + \DeclareUnicodeCharacter{00A9}{\copyright} + \DeclareUnicodeCharacter{00AA}{\ordf} + \DeclareUnicodeCharacter{00AB}{\guillemetleft} + \DeclareUnicodeCharacter{00AD}{\-} + \DeclareUnicodeCharacter{00AE}{\registeredsymbol} + \DeclareUnicodeCharacter{00AF}{\={ }} + + \DeclareUnicodeCharacter{00B0}{\ringaccent{ }} + \DeclareUnicodeCharacter{00B4}{\'{ }} + \DeclareUnicodeCharacter{00B8}{\cedilla{ }} + \DeclareUnicodeCharacter{00BA}{\ordm} + \DeclareUnicodeCharacter{00BB}{\guillemetright} + \DeclareUnicodeCharacter{00BF}{\questiondown} + + \DeclareUnicodeCharacter{00C0}{\`A} + \DeclareUnicodeCharacter{00C1}{\'A} + \DeclareUnicodeCharacter{00C2}{\^A} + \DeclareUnicodeCharacter{00C3}{\~A} + \DeclareUnicodeCharacter{00C4}{\"A} + \DeclareUnicodeCharacter{00C5}{\AA} + \DeclareUnicodeCharacter{00C6}{\AE} + \DeclareUnicodeCharacter{00C7}{\cedilla{C}} + \DeclareUnicodeCharacter{00C8}{\`E} + \DeclareUnicodeCharacter{00C9}{\'E} + \DeclareUnicodeCharacter{00CA}{\^E} + \DeclareUnicodeCharacter{00CB}{\"E} + \DeclareUnicodeCharacter{00CC}{\`I} + \DeclareUnicodeCharacter{00CD}{\'I} + \DeclareUnicodeCharacter{00CE}{\^I} + \DeclareUnicodeCharacter{00CF}{\"I} + + \DeclareUnicodeCharacter{00D0}{\DH} + \DeclareUnicodeCharacter{00D1}{\~N} + \DeclareUnicodeCharacter{00D2}{\`O} + \DeclareUnicodeCharacter{00D3}{\'O} + \DeclareUnicodeCharacter{00D4}{\^O} + \DeclareUnicodeCharacter{00D5}{\~O} + \DeclareUnicodeCharacter{00D6}{\"O} + \DeclareUnicodeCharacter{00D8}{\O} + \DeclareUnicodeCharacter{00D9}{\`U} + \DeclareUnicodeCharacter{00DA}{\'U} + \DeclareUnicodeCharacter{00DB}{\^U} + \DeclareUnicodeCharacter{00DC}{\"U} + \DeclareUnicodeCharacter{00DD}{\'Y} + \DeclareUnicodeCharacter{00DE}{\TH} + \DeclareUnicodeCharacter{00DF}{\ss} + + \DeclareUnicodeCharacter{00E0}{\`a} + \DeclareUnicodeCharacter{00E1}{\'a} + \DeclareUnicodeCharacter{00E2}{\^a} + \DeclareUnicodeCharacter{00E3}{\~a} + \DeclareUnicodeCharacter{00E4}{\"a} + \DeclareUnicodeCharacter{00E5}{\aa} + \DeclareUnicodeCharacter{00E6}{\ae} + \DeclareUnicodeCharacter{00E7}{\cedilla{c}} + \DeclareUnicodeCharacter{00E8}{\`e} + \DeclareUnicodeCharacter{00E9}{\'e} + \DeclareUnicodeCharacter{00EA}{\^e} + \DeclareUnicodeCharacter{00EB}{\"e} + \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}} + \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}} + \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}} + \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}} + + \DeclareUnicodeCharacter{00F0}{\dh} + \DeclareUnicodeCharacter{00F1}{\~n} + \DeclareUnicodeCharacter{00F2}{\`o} + \DeclareUnicodeCharacter{00F3}{\'o} + \DeclareUnicodeCharacter{00F4}{\^o} + \DeclareUnicodeCharacter{00F5}{\~o} + \DeclareUnicodeCharacter{00F6}{\"o} + \DeclareUnicodeCharacter{00F8}{\o} + \DeclareUnicodeCharacter{00F9}{\`u} + \DeclareUnicodeCharacter{00FA}{\'u} + \DeclareUnicodeCharacter{00FB}{\^u} + \DeclareUnicodeCharacter{00FC}{\"u} + \DeclareUnicodeCharacter{00FD}{\'y} + \DeclareUnicodeCharacter{00FE}{\th} + \DeclareUnicodeCharacter{00FF}{\"y} + + \DeclareUnicodeCharacter{0100}{\=A} + \DeclareUnicodeCharacter{0101}{\=a} + \DeclareUnicodeCharacter{0102}{\u{A}} + \DeclareUnicodeCharacter{0103}{\u{a}} + \DeclareUnicodeCharacter{0104}{\ogonek{A}} + \DeclareUnicodeCharacter{0105}{\ogonek{a}} + \DeclareUnicodeCharacter{0106}{\'C} + \DeclareUnicodeCharacter{0107}{\'c} + \DeclareUnicodeCharacter{0108}{\^C} + \DeclareUnicodeCharacter{0109}{\^c} + \DeclareUnicodeCharacter{0118}{\ogonek{E}} + \DeclareUnicodeCharacter{0119}{\ogonek{e}} + \DeclareUnicodeCharacter{010A}{\dotaccent{C}} + \DeclareUnicodeCharacter{010B}{\dotaccent{c}} + \DeclareUnicodeCharacter{010C}{\v{C}} + \DeclareUnicodeCharacter{010D}{\v{c}} + \DeclareUnicodeCharacter{010E}{\v{D}} + + \DeclareUnicodeCharacter{0112}{\=E} + \DeclareUnicodeCharacter{0113}{\=e} + \DeclareUnicodeCharacter{0114}{\u{E}} + \DeclareUnicodeCharacter{0115}{\u{e}} + \DeclareUnicodeCharacter{0116}{\dotaccent{E}} + \DeclareUnicodeCharacter{0117}{\dotaccent{e}} + \DeclareUnicodeCharacter{011A}{\v{E}} + \DeclareUnicodeCharacter{011B}{\v{e}} + \DeclareUnicodeCharacter{011C}{\^G} + \DeclareUnicodeCharacter{011D}{\^g} + \DeclareUnicodeCharacter{011E}{\u{G}} + \DeclareUnicodeCharacter{011F}{\u{g}} + + \DeclareUnicodeCharacter{0120}{\dotaccent{G}} + \DeclareUnicodeCharacter{0121}{\dotaccent{g}} + \DeclareUnicodeCharacter{0124}{\^H} + \DeclareUnicodeCharacter{0125}{\^h} + \DeclareUnicodeCharacter{0128}{\~I} + \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}} + \DeclareUnicodeCharacter{012A}{\=I} + \DeclareUnicodeCharacter{012B}{\={\dotless{i}}} + \DeclareUnicodeCharacter{012C}{\u{I}} + \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}} + + \DeclareUnicodeCharacter{0130}{\dotaccent{I}} + \DeclareUnicodeCharacter{0131}{\dotless{i}} + \DeclareUnicodeCharacter{0132}{IJ} + \DeclareUnicodeCharacter{0133}{ij} + \DeclareUnicodeCharacter{0134}{\^J} + \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}} + \DeclareUnicodeCharacter{0139}{\'L} + \DeclareUnicodeCharacter{013A}{\'l} + + \DeclareUnicodeCharacter{0141}{\L} + \DeclareUnicodeCharacter{0142}{\l} + \DeclareUnicodeCharacter{0143}{\'N} + \DeclareUnicodeCharacter{0144}{\'n} + \DeclareUnicodeCharacter{0147}{\v{N}} + \DeclareUnicodeCharacter{0148}{\v{n}} + \DeclareUnicodeCharacter{014C}{\=O} + \DeclareUnicodeCharacter{014D}{\=o} + \DeclareUnicodeCharacter{014E}{\u{O}} + \DeclareUnicodeCharacter{014F}{\u{o}} + + \DeclareUnicodeCharacter{0150}{\H{O}} + \DeclareUnicodeCharacter{0151}{\H{o}} + \DeclareUnicodeCharacter{0152}{\OE} + \DeclareUnicodeCharacter{0153}{\oe} + \DeclareUnicodeCharacter{0154}{\'R} + \DeclareUnicodeCharacter{0155}{\'r} + \DeclareUnicodeCharacter{0158}{\v{R}} + \DeclareUnicodeCharacter{0159}{\v{r}} + \DeclareUnicodeCharacter{015A}{\'S} + \DeclareUnicodeCharacter{015B}{\'s} + \DeclareUnicodeCharacter{015C}{\^S} + \DeclareUnicodeCharacter{015D}{\^s} + \DeclareUnicodeCharacter{015E}{\cedilla{S}} + \DeclareUnicodeCharacter{015F}{\cedilla{s}} + + \DeclareUnicodeCharacter{0160}{\v{S}} + \DeclareUnicodeCharacter{0161}{\v{s}} + \DeclareUnicodeCharacter{0162}{\cedilla{t}} + \DeclareUnicodeCharacter{0163}{\cedilla{T}} + \DeclareUnicodeCharacter{0164}{\v{T}} + + \DeclareUnicodeCharacter{0168}{\~U} + \DeclareUnicodeCharacter{0169}{\~u} + \DeclareUnicodeCharacter{016A}{\=U} + \DeclareUnicodeCharacter{016B}{\=u} + \DeclareUnicodeCharacter{016C}{\u{U}} + \DeclareUnicodeCharacter{016D}{\u{u}} + \DeclareUnicodeCharacter{016E}{\ringaccent{U}} + \DeclareUnicodeCharacter{016F}{\ringaccent{u}} + + \DeclareUnicodeCharacter{0170}{\H{U}} + \DeclareUnicodeCharacter{0171}{\H{u}} + \DeclareUnicodeCharacter{0174}{\^W} + \DeclareUnicodeCharacter{0175}{\^w} + \DeclareUnicodeCharacter{0176}{\^Y} + \DeclareUnicodeCharacter{0177}{\^y} + \DeclareUnicodeCharacter{0178}{\"Y} + \DeclareUnicodeCharacter{0179}{\'Z} + \DeclareUnicodeCharacter{017A}{\'z} + \DeclareUnicodeCharacter{017B}{\dotaccent{Z}} + \DeclareUnicodeCharacter{017C}{\dotaccent{z}} + \DeclareUnicodeCharacter{017D}{\v{Z}} + \DeclareUnicodeCharacter{017E}{\v{z}} + + \DeclareUnicodeCharacter{01C4}{D\v{Z}} + \DeclareUnicodeCharacter{01C5}{D\v{z}} + \DeclareUnicodeCharacter{01C6}{d\v{z}} + \DeclareUnicodeCharacter{01C7}{LJ} + \DeclareUnicodeCharacter{01C8}{Lj} + \DeclareUnicodeCharacter{01C9}{lj} + \DeclareUnicodeCharacter{01CA}{NJ} + \DeclareUnicodeCharacter{01CB}{Nj} + \DeclareUnicodeCharacter{01CC}{nj} + \DeclareUnicodeCharacter{01CD}{\v{A}} + \DeclareUnicodeCharacter{01CE}{\v{a}} + \DeclareUnicodeCharacter{01CF}{\v{I}} + + \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}} + \DeclareUnicodeCharacter{01D1}{\v{O}} + \DeclareUnicodeCharacter{01D2}{\v{o}} + \DeclareUnicodeCharacter{01D3}{\v{U}} + \DeclareUnicodeCharacter{01D4}{\v{u}} + + \DeclareUnicodeCharacter{01E2}{\={\AE}} + \DeclareUnicodeCharacter{01E3}{\={\ae}} + \DeclareUnicodeCharacter{01E6}{\v{G}} + \DeclareUnicodeCharacter{01E7}{\v{g}} + \DeclareUnicodeCharacter{01E8}{\v{K}} + \DeclareUnicodeCharacter{01E9}{\v{k}} + + \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}} + \DeclareUnicodeCharacter{01F1}{DZ} + \DeclareUnicodeCharacter{01F2}{Dz} + \DeclareUnicodeCharacter{01F3}{dz} + \DeclareUnicodeCharacter{01F4}{\'G} + \DeclareUnicodeCharacter{01F5}{\'g} + \DeclareUnicodeCharacter{01F8}{\`N} + \DeclareUnicodeCharacter{01F9}{\`n} + \DeclareUnicodeCharacter{01FC}{\'{\AE}} + \DeclareUnicodeCharacter{01FD}{\'{\ae}} + \DeclareUnicodeCharacter{01FE}{\'{\O}} + \DeclareUnicodeCharacter{01FF}{\'{\o}} + + \DeclareUnicodeCharacter{021E}{\v{H}} + \DeclareUnicodeCharacter{021F}{\v{h}} + + \DeclareUnicodeCharacter{0226}{\dotaccent{A}} + \DeclareUnicodeCharacter{0227}{\dotaccent{a}} + \DeclareUnicodeCharacter{0228}{\cedilla{E}} + \DeclareUnicodeCharacter{0229}{\cedilla{e}} + \DeclareUnicodeCharacter{022E}{\dotaccent{O}} + \DeclareUnicodeCharacter{022F}{\dotaccent{o}} + + \DeclareUnicodeCharacter{0232}{\=Y} + \DeclareUnicodeCharacter{0233}{\=y} + \DeclareUnicodeCharacter{0237}{\dotless{j}} + + \DeclareUnicodeCharacter{02DB}{\ogonek{ }} + + \DeclareUnicodeCharacter{1E02}{\dotaccent{B}} + \DeclareUnicodeCharacter{1E03}{\dotaccent{b}} + \DeclareUnicodeCharacter{1E04}{\udotaccent{B}} + \DeclareUnicodeCharacter{1E05}{\udotaccent{b}} + \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}} + \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}} + \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}} + \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}} + \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}} + \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}} + \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}} + \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}} + + \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}} + \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}} + + \DeclareUnicodeCharacter{1E20}{\=G} + \DeclareUnicodeCharacter{1E21}{\=g} + \DeclareUnicodeCharacter{1E22}{\dotaccent{H}} + \DeclareUnicodeCharacter{1E23}{\dotaccent{h}} + \DeclareUnicodeCharacter{1E24}{\udotaccent{H}} + \DeclareUnicodeCharacter{1E25}{\udotaccent{h}} + \DeclareUnicodeCharacter{1E26}{\"H} + \DeclareUnicodeCharacter{1E27}{\"h} + + \DeclareUnicodeCharacter{1E30}{\'K} + \DeclareUnicodeCharacter{1E31}{\'k} + \DeclareUnicodeCharacter{1E32}{\udotaccent{K}} + \DeclareUnicodeCharacter{1E33}{\udotaccent{k}} + \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}} + \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}} + \DeclareUnicodeCharacter{1E36}{\udotaccent{L}} + \DeclareUnicodeCharacter{1E37}{\udotaccent{l}} + \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}} + \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}} + \DeclareUnicodeCharacter{1E3E}{\'M} + \DeclareUnicodeCharacter{1E3F}{\'m} + + \DeclareUnicodeCharacter{1E40}{\dotaccent{M}} + \DeclareUnicodeCharacter{1E41}{\dotaccent{m}} + \DeclareUnicodeCharacter{1E42}{\udotaccent{M}} + \DeclareUnicodeCharacter{1E43}{\udotaccent{m}} + \DeclareUnicodeCharacter{1E44}{\dotaccent{N}} + \DeclareUnicodeCharacter{1E45}{\dotaccent{n}} + \DeclareUnicodeCharacter{1E46}{\udotaccent{N}} + \DeclareUnicodeCharacter{1E47}{\udotaccent{n}} + \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}} + \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}} + + \DeclareUnicodeCharacter{1E54}{\'P} + \DeclareUnicodeCharacter{1E55}{\'p} + \DeclareUnicodeCharacter{1E56}{\dotaccent{P}} + \DeclareUnicodeCharacter{1E57}{\dotaccent{p}} + \DeclareUnicodeCharacter{1E58}{\dotaccent{R}} + \DeclareUnicodeCharacter{1E59}{\dotaccent{r}} + \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}} + \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}} + \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}} + \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}} + + \DeclareUnicodeCharacter{1E60}{\dotaccent{S}} + \DeclareUnicodeCharacter{1E61}{\dotaccent{s}} + \DeclareUnicodeCharacter{1E62}{\udotaccent{S}} + \DeclareUnicodeCharacter{1E63}{\udotaccent{s}} + \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}} + \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}} + \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}} + \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}} + \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}} + \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}} + + \DeclareUnicodeCharacter{1E7C}{\~V} + \DeclareUnicodeCharacter{1E7D}{\~v} + \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}} + \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}} + + \DeclareUnicodeCharacter{1E80}{\`W} + \DeclareUnicodeCharacter{1E81}{\`w} + \DeclareUnicodeCharacter{1E82}{\'W} + \DeclareUnicodeCharacter{1E83}{\'w} + \DeclareUnicodeCharacter{1E84}{\"W} + \DeclareUnicodeCharacter{1E85}{\"w} + \DeclareUnicodeCharacter{1E86}{\dotaccent{W}} + \DeclareUnicodeCharacter{1E87}{\dotaccent{w}} + \DeclareUnicodeCharacter{1E88}{\udotaccent{W}} + \DeclareUnicodeCharacter{1E89}{\udotaccent{w}} + \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}} + \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}} + \DeclareUnicodeCharacter{1E8C}{\"X} + \DeclareUnicodeCharacter{1E8D}{\"x} + \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}} + \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}} + + \DeclareUnicodeCharacter{1E90}{\^Z} + \DeclareUnicodeCharacter{1E91}{\^z} + \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}} + \DeclareUnicodeCharacter{1E93}{\udotaccent{z}} + \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}} + \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}} + \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}} + \DeclareUnicodeCharacter{1E97}{\"t} + \DeclareUnicodeCharacter{1E98}{\ringaccent{w}} + \DeclareUnicodeCharacter{1E99}{\ringaccent{y}} + + \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}} + \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}} + + \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}} + \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}} + \DeclareUnicodeCharacter{1EBC}{\~E} + \DeclareUnicodeCharacter{1EBD}{\~e} + + \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}} + \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}} + \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}} + \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}} + + \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}} + \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}} + + \DeclareUnicodeCharacter{1EF2}{\`Y} + \DeclareUnicodeCharacter{1EF3}{\`y} + \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}} + + \DeclareUnicodeCharacter{1EF8}{\~Y} + \DeclareUnicodeCharacter{1EF9}{\~y} + + \DeclareUnicodeCharacter{2013}{--} + \DeclareUnicodeCharacter{2014}{---} + \DeclareUnicodeCharacter{2018}{\quoteleft} + \DeclareUnicodeCharacter{2019}{\quoteright} + \DeclareUnicodeCharacter{201A}{\quotesinglbase} + \DeclareUnicodeCharacter{201C}{\quotedblleft} + \DeclareUnicodeCharacter{201D}{\quotedblright} + \DeclareUnicodeCharacter{201E}{\quotedblbase} + \DeclareUnicodeCharacter{2022}{\bullet} + \DeclareUnicodeCharacter{2026}{\dots} + \DeclareUnicodeCharacter{2039}{\guilsinglleft} + \DeclareUnicodeCharacter{203A}{\guilsinglright} + \DeclareUnicodeCharacter{20AC}{\euro} + + \DeclareUnicodeCharacter{2192}{\expansion} + \DeclareUnicodeCharacter{21D2}{\result} + + \DeclareUnicodeCharacter{2212}{\minus} + \DeclareUnicodeCharacter{2217}{\point} + \DeclareUnicodeCharacter{2261}{\equiv} +}% end of \utfeightchardefs + + +% US-ASCII character definitions. +\def\asciichardefs{% nothing need be done + \relax +} + +% Make non-ASCII characters printable again for compatibility with +% existing Texinfo documents that may use them, even without declaring a +% document encoding. +% +\setnonasciicharscatcode \other + + +\message{formatting,} + +\newdimen\defaultparindent \defaultparindent = 15pt + +\chapheadingskip = 15pt plus 4pt minus 2pt +\secheadingskip = 12pt plus 3pt minus 2pt +\subsecheadingskip = 9pt plus 2pt minus 2pt + +% Prevent underfull vbox error messages. +\vbadness = 10000 + +% Don't be very finicky about underfull hboxes, either. +\hbadness = 6666 + +% Following George Bush, get rid of widows and orphans. +\widowpenalty=10000 +\clubpenalty=10000 + +% Use TeX 3.0's \emergencystretch to help line breaking, but if we're +% using an old version of TeX, don't do anything. We want the amount of +% stretch added to depend on the line length, hence the dependence on +% \hsize. We call this whenever the paper size is set. +% +\def\setemergencystretch{% + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = .15\hsize + \fi +} + +% Parameters in order: 1) textheight; 2) textwidth; +% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip; +% 7) physical page height; 8) physical page width. +% +% We also call \setleading{\textleading}, so the caller should define +% \textleading. The caller should also set \parskip. +% +\def\internalpagesizes#1#2#3#4#5#6#7#8{% + \voffset = #3\relax + \topskip = #6\relax + \splittopskip = \topskip + % + \vsize = #1\relax + \advance\vsize by \topskip + \outervsize = \vsize + \advance\outervsize by 2\topandbottommargin + \pageheight = \vsize + % + \hsize = #2\relax + \outerhsize = \hsize + \advance\outerhsize by 0.5in + \pagewidth = \hsize + % + \normaloffset = #4\relax + \bindingoffset = #5\relax + % + \ifpdf + \pdfpageheight #7\relax + \pdfpagewidth #8\relax + % if we don't reset these, they will remain at "1 true in" of + % whatever layout pdftex was dumped with. + \pdfhorigin = 1 true in + \pdfvorigin = 1 true in + \fi + % + \setleading{\textleading} + % + \parindent = \defaultparindent + \setemergencystretch +} + +% @letterpaper (the default). +\def\letterpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % If page is nothing but text, make it come out even. + \internalpagesizes{607.2pt}{6in}% that's 46 lines + {\voffset}{.25in}% + {\bindingoffset}{36pt}% + {11in}{8.5in}% +}} + +% Use @smallbook to reset parameters for 7x9.25 trim size. +\def\smallbook{{\globaldefs = 1 + \parskip = 2pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.5in}{5in}% + {-.2in}{0in}% + {\bindingoffset}{16pt}% + {9.25in}{7in}% + % + \lispnarrowing = 0.3in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = .5cm +}} + +% Use @smallerbook to reset parameters for 6x9 trim size. +% (Just testing, parameters still in flux.) +\def\smallerbook{{\globaldefs = 1 + \parskip = 1.5pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.4in}{4.8in}% + {-.2in}{-.4in}% + {0pt}{14pt}% + {9in}{6in}% + % + \lispnarrowing = 0.25in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = .4cm +}} + +% Use @afourpaper to print on European A4 paper. +\def\afourpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % Double-side printing via postscript on Laserjet 4050 + % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. + % To change the settings for a different printer or situation, adjust + % \normaloffset until the front-side and back-side texts align. Then + % do the same for \bindingoffset. You can set these for testing in + % your texinfo source file like this: + % @tex + % \global\normaloffset = -6mm + % \global\bindingoffset = 10mm + % @end tex + \internalpagesizes{673.2pt}{160mm}% that's 51 lines + {\voffset}{\hoffset}% + {\bindingoffset}{44pt}% + {297mm}{210mm}% + % + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = 5mm +}} + +% Use @afivepaper to print on European A5 paper. +% From romildo@urano.iceb.ufop.br, 2 July 2000. +% He also recommends making @example and @lisp be small. +\def\afivepaper{{\globaldefs = 1 + \parskip = 2pt plus 1pt minus 0.1pt + \textleading = 12.5pt + % + \internalpagesizes{160mm}{120mm}% + {\voffset}{\hoffset}% + {\bindingoffset}{8pt}% + {210mm}{148mm}% + % + \lispnarrowing = 0.2in + \tolerance = 800 + \hfuzz = 1.2pt + \contentsrightmargin = 0pt + \defbodyindent = 2mm + \tableindent = 12mm +}} + +% A specific text layout, 24x15cm overall, intended for A4 paper. +\def\afourlatex{{\globaldefs = 1 + \afourpaper + \internalpagesizes{237mm}{150mm}% + {\voffset}{4.6mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + % + % Must explicitly reset to 0 because we call \afourpaper. + \globaldefs = 0 +}} + +% Use @afourwide to print on A4 paper in landscape format. +\def\afourwide{{\globaldefs = 1 + \afourpaper + \internalpagesizes{241mm}{165mm}% + {\voffset}{-2.95mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + \globaldefs = 0 +}} + +% @pagesizes TEXTHEIGHT[,TEXTWIDTH] +% Perhaps we should allow setting the margins, \topskip, \parskip, +% and/or leading, also. Or perhaps we should compute them somehow. +% +\parseargdef\pagesizes{\pagesizesyyy #1,,\finish} +\def\pagesizesyyy#1,#2,#3\finish{{% + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi + \globaldefs = 1 + % + \parskip = 3pt plus 2pt minus 1pt + \setleading{\textleading}% + % + \dimen0 = #1\relax + \advance\dimen0 by \voffset + % + \dimen2 = \hsize + \advance\dimen2 by \normaloffset + % + \internalpagesizes{#1}{\hsize}% + {\voffset}{\normaloffset}% + {\bindingoffset}{44pt}% + {\dimen0}{\dimen2}% +}} + +% Set default to letter. +% +\letterpaper + + +\message{and turning on texinfo input format.} + +\def^^L{\par} % remove \outer, so ^L can appear in an @comment + +% DEL is a comment character, in case @c does not suffice. +\catcode`\^^? = 14 + +% Define macros to output various characters with catcode for normal text. +\catcode`\"=\other \def\normaldoublequote{"} +\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix +\catcode`\+=\other \def\normalplus{+} +\catcode`\<=\other \def\normalless{<} +\catcode`\>=\other \def\normalgreater{>} +\catcode`\^=\other \def\normalcaret{^} +\catcode`\_=\other \def\normalunderscore{_} +\catcode`\|=\other \def\normalverticalbar{|} +\catcode`\~=\other \def\normaltilde{~} + +% This macro is used to make a character print one way in \tt +% (where it can probably be output as-is), and another way in other fonts, +% where something hairier probably needs to be done. +% +% #1 is what to print if we are indeed using \tt; #2 is what to print +% otherwise. Since all the Computer Modern typewriter fonts have zero +% interword stretch (and shrink), and it is reasonable to expect all +% typewriter fonts to have this, we can check that font parameter. +% +\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} + +% Same as above, but check for italic font. Actually this also catches +% non-italic slanted fonts since it is impossible to distinguish them from +% italic fonts. But since this is only used by $ and it uses \sl anyway +% this is not a problem. +\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} + +% Turn off all special characters except @ +% (and those which the user can use as if they were ordinary). +% Most of these we simply print from the \tt font, but for some, we can +% use math or other variants that look better in normal text. + +\catcode`\"=\active +\def\activedoublequote{{\tt\char34}} +\let"=\activedoublequote +\catcode`\~=\active +\def~{{\tt\char126}} +\chardef\hat=`\^ +\catcode`\^=\active +\def^{{\tt \hat}} + +\catcode`\_=\active +\def_{\ifusingtt\normalunderscore\_} +\let\realunder=_ +% Subroutine for the previous macro. +\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } + +\catcode`\|=\active +\def|{{\tt\char124}} +\chardef \less=`\< +\catcode`\<=\active +\def<{{\tt \less}} +\chardef \gtr=`\> +\catcode`\>=\active +\def>{{\tt \gtr}} +\catcode`\+=\active +\def+{{\tt \char 43}} +\catcode`\$=\active +\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have \everyjob (or @setfilename) turn them on. +% \otherifyactive is called near the end of this file. +\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + +% Used sometimes to turn off (effectively) the active characters even after +% parsing them. +\def\turnoffactive{% + \normalturnoffactive + \otherbackslash +} + +\catcode`\@=0 + +% \backslashcurfont outputs one backslash character in current font, +% as in \char`\\. +\global\chardef\backslashcurfont=`\\ +\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work + +% \realbackslash is an actual character `\' with catcode other, and +% \doublebackslash is two of them (for the pdf outlines). +{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}} + +% In texinfo, backslash is an active character; it prints the backslash +% in fixed width font. +\catcode`\\=\active % @ for escape char from now on. + +% The story here is that in math mode, the \char of \backslashcurfont +% ends up printing the roman \ from the math symbol font (because \char +% in math mode uses the \mathcode, and plain.tex sets +% \mathcode`\\="026E). It seems better for @backslashchar{} to always +% print a typewriter backslash, hence we use an explicit \mathchar, +% which is the decimal equivalent of "715c (class 7, e.g., use \fam; +% ignored family value; char position "5C). We can't use " for the +% usual hex value because it has already been made active. +@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} +@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents. + +% On startup, @fixbackslash assigns: +% @let \ = @normalbackslash +% \rawbackslash defines an active \ to do \backslashcurfont. +% \otherbackslash defines an active \ to be a literal `\' character with +% catcode other. We switch back and forth between these. +@gdef@rawbackslash{@let\=@backslashcurfont} +@gdef@otherbackslash{@let\=@realbackslash} + +% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of +% the literal character `\'. +% +@def@normalturnoffactive{% + @let"=@normaldoublequote + @let$=@normaldollar %$ font-lock fix + @let+=@normalplus + @let<=@normalless + @let>=@normalgreater + @let\=@normalbackslash + @let^=@normalcaret + @let_=@normalunderscore + @let|=@normalverticalbar + @let~=@normaltilde + @markupsetuplqdefault + @markupsetuprqdefault + @unsepspaces +} + +% Make _ and + \other characters, temporarily. +% This is canceled by @fixbackslash. +@otherifyactive + +% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +% That is what \eatinput is for; after that, the `\' should revert to printing +% a backslash. +% +@gdef@eatinput input texinfo{@fixbackslash} +@global@let\ = @eatinput + +% On the other hand, perhaps the file did not have a `\input texinfo'. Then +% the first `\' in the file would cause an error. This macro tries to fix +% that, assuming it is called before the first `\' could plausibly occur. +% Also turn back on active characters that might appear in the input +% file name, in case not using a pre-dumped format. +% +@gdef@fixbackslash{% + @ifx\@eatinput @let\ = @normalbackslash @fi + @catcode`+=@active + @catcode`@_=@active +} + +% Say @foo, not \foo, in error messages. +@escapechar = `@@ + +% These (along with & and #) are made active for url-breaking, so need +% active definitions as the normal characters. +@def@normaldot{.} +@def@normalquest{?} +@def@normalslash{/} + +% These look ok in all fonts, so just make them not special. +% @hashchar{} gets its own user-level command, because of #line. +@catcode`@& = @other @def@normalamp{&} +@catcode`@# = @other @def@normalhash{#} +@catcode`@% = @other @def@normalpercent{%} + +@let @hashchar = @normalhash + +@c Finally, make ` and ' active, so that txicodequoteundirected and +@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we +@c don't make ` and ' active, @code will not get them as active chars. +@c Do this last of all since we use ` in the previous @catcode assignments. +@catcode`@'=@active +@catcode`@`=@active +@markupsetuplqdefault +@markupsetuprqdefault + +@c Local variables: +@c eval: (add-hook 'write-file-hooks 'time-stamp) +@c page-delimiter: "^\\\\message" +@c time-stamp-start: "def\\\\texinfoversion{" +@c time-stamp-format: "%:y-%02m-%02d.%02H" +@c time-stamp-end: "}" +@c End: + +@c vim:sw=2: + +@ignore + arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115 +@end ignore diff --git a/debuggers/openocd/doc/version.texi b/debuggers/openocd/doc/version.texi new file mode 100644 index 00000000..47f311b3 --- /dev/null +++ b/debuggers/openocd/doc/version.texi @@ -0,0 +1,4 @@ +@set UPDATED 4 May 2013 +@set UPDATED-MONTH May 2013 +@set EDITION 0.7.0 +@set VERSION 0.7.0 diff --git a/debuggers/openocd/install-sh b/debuggers/openocd/install-sh new file mode 100755 index 00000000..377bb868 --- /dev/null +++ b/debuggers/openocd/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-11-20.07; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/debuggers/openocd/jimtcl/.gitignore b/debuggers/openocd/jimtcl/.gitignore new file mode 100644 index 00000000..87705d57 --- /dev/null +++ b/debuggers/openocd/jimtcl/.gitignore @@ -0,0 +1,21 @@ +config.log +tags +/Makefile +Tcl.html +jimautoconf.h +jimautoconfext.h +jim-config.h +_*.c +jim-stdlib.c +jim-tclcompat.c +jim-tree.c +jim-oo.c +jimsh +*.exe +libjim.a +*.so +*.dll +*.o +configure.gnu +jimsh0 +build-jim-ext diff --git a/debuggers/openocd/jimtcl/.indent.pro b/debuggers/openocd/jimtcl/.indent.pro new file mode 100644 index 00000000..128d5636 --- /dev/null +++ b/debuggers/openocd/jimtcl/.indent.pro @@ -0,0 +1,34 @@ +-ncs +-npcs +-nut +-bad +-bap +-bbb +-nbc +-nlp +-ci4 +-br +-ncdb +-nce +-cli4 +-d0 +-di1 +-nfc1 +-i4 +-l100 +-npsl +-TJim_Stack +-TJim_HashEntry +-TJim_HashTableType +-TJim_HashTable +-TJim_HashTableIterator +-TJim_Obj +-TJim_ObjType +-TJim_CallFrame +-TJim_Var +-TJim_Cmd +-TJim_PrngState +-TJim_Interp +-TJim_Reference +-TParseToken +-TParseTokenList diff --git a/debuggers/openocd/jimtcl/.project b/debuggers/openocd/jimtcl/.project new file mode 100644 index 00000000..c23ac286 --- /dev/null +++ b/debuggers/openocd/jimtcl/.project @@ -0,0 +1,11 @@ + + + jim + + + + + + + + diff --git a/debuggers/openocd/jimtcl/AUTHORS b/debuggers/openocd/jimtcl/AUTHORS new file mode 100644 index 00000000..2ea710e3 --- /dev/null +++ b/debuggers/openocd/jimtcl/AUTHORS @@ -0,0 +1,41 @@ +Salvatore Sanfilippo + +with the help (patches, bug reports, ideas, extensions) of: + +Pat Thoyts +Clemens Hintze + +See also the ChangeLog and README files for other credits. + +DESIGN CREDITS: + +some of the idea inside Jim are the fruit of long discussions +inside the Tclers chat room. The feedback of the Tcl +comunity in general, and of the members of the Tcl Core Team, was +very important to avoid mistakes: I used the great experience of +this people as a test for some of the ideas I put into Jim. +Bad ideas tend to be demolished in no time by good engineers. + +Also the following ideas are due to the following authors: + +- Jim locals were originally proposed by Miguel Sofer, I (SS) added + the feature that make they similar to lexical scoped closures + using capturing of the local variables value if no explicit + intialization is provided. + +- The [lmap] command is my (SS) design, but I incorporated inside the + command an interesting idea of Donal K. Fellows that proposed that + the [continue] command may be used to skip the accumulation of the + current-iteartion result, providing in one command the power of + [map] and [filter] together. + + +ChangeLog committers to be identified. Tentative list: + +antirez - Salvatore Sanfilippo +patthoyts - Pat Thoyts +oharboe - yvind Harboe - soyvind.harboe@zylin.com +Andrew Lunn +Duane Ellis +Uwe Klein +Clemens Hintze ml-jim@qiao.in-berlin.de aka chi diff --git a/debuggers/openocd/jimtcl/BUGS b/debuggers/openocd/jimtcl/BUGS new file mode 100644 index 00000000..b0843187 --- /dev/null +++ b/debuggers/openocd/jimtcl/BUGS @@ -0,0 +1,4 @@ +Known bugs +========== + +None! diff --git a/debuggers/openocd/jimtcl/DEVELOPING b/debuggers/openocd/jimtcl/DEVELOPING new file mode 100644 index 00000000..42fb0544 --- /dev/null +++ b/debuggers/openocd/jimtcl/DEVELOPING @@ -0,0 +1,93 @@ +Working on Jim +============== + +Jim's sources are kept in Git Version Control System. Global repository of +Jim project is placed on this Web site: + + http://repo.or.cz/w/jimtcl.git + +There are two ways of contributing to Jim project. First is suited for +one-time fixes and small corrections. The second is more appropriate +for long-term contributors interested in Jim internals. + +Small changes +============= + +For small modifications, procedure of preparing a traditional 'patch' +is enough. In order to prepare a patch, you first have to obtain the +most recent copy of Jim Tcl. This can be done with following command: + + git clone http://repo.or.cz/r/jimtcl.git + +After entering newly created directory you can easily correct/fix/modify +files. Once finished, patch can be easily generated: + + git diff > my_patch_fixing_x_y.patch + +If working without Git system, you'll have to backup files first, modify +the original files and obtain a patch manually: + + cp jim.c jim.c.ORIGINAL + + [...] <- modifications go here + + diff -u jim.c.ORIGINAL jim.c > my_patch_fixing_z.patch + +Bigger changes +============== + +In order to help extending and correcting Jim in a long term basis, one +needs to create separate fork of Jim project and maintain his changes in a +separate copy of a repository. + +By visiting this site, you'll have a chance to fork a project. This can +be easily done with "fork" link. Form that will show up next refers to +the project that is about to be started. The only thing that has to be +taken care of is the project mode -- it should be "push mode". + +Once the project is created one must add a user that will actually +start commiting new files to the repo. It can also be done through the +WWW interface, so nothing more is necessary. + +Once finished with setting up a project on the WWW panel, one can +start playing with actual import of the files. In order to obtain copy +of Jim sources, we have to clone the repository: + + git clone http://repo.or.cz/r/jimtcl.git + +Now, we must push fresh copy of Jim to your project URL: + + git push master + +So for example for me it was: + + git push ssh://repo.or.cz/srv/git/jimtcl/wkoszek.git master + +In order to add file we type "git add ". For remove, we do "git rm +". To remove all local changes that aren't in a repository you do "git +reset --hard HEAD". Once inserted, files have to be commited with "git commit +-a". Once done with commits for today, "git push" can be used to propagate +changes from your local disk to the remote repository. + +Right now you can verify whether this works by trying to clone your +project's repository somewhere else, this time using anonymount HTTP +access: + + git clone http://repo.or.cz/r/jimtcl/wkoszek.git + +Review, testing and publishing +============================== + +Notification of work that can be considered finished is more than welcome on +Jim-devel mailing list: + + https://lists.berlios.de/mailman/listinfo/jim-devel + +Patches prepared with the procedures presented abore are welcome. Before +submitting patches, you can verify that your changes didn't bring any +regressions to the Jim. In order to do so, sample regression tests have +been implemented. You can execute them by typing: + + make test + +All tests should succeed. diff --git a/debuggers/openocd/jimtcl/LICENSE b/debuggers/openocd/jimtcl/LICENSE new file mode 100644 index 00000000..48f2cc85 --- /dev/null +++ b/debuggers/openocd/jimtcl/LICENSE @@ -0,0 +1,45 @@ +Unless explicitly stated, all files within Jim repository are released +under following license: + +/* Jim - A small embeddable Tcl interpreter + * + * Copyright 2005 Salvatore Sanfilippo + * Copyright 2005 Clemens Hintze + * Copyright 2005 patthoyts - Pat Thoyts + * Copyright 2008 oharboe - yvind Harboe - oyvind.harboe@zylin.com + * Copyright 2008 Andrew Lunn + * Copyright 2008 Duane Ellis + * Copyright 2008 Uwe Klein + * Copyright 2008 Steve Bennett + * Copyright 2009 Nico Coesel + * Copyright 2009 Zachary T Welch zw@superlucidity.net + * Copyright 2009 David Brownell + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + */ diff --git a/debuggers/openocd/jimtcl/Makefile.in b/debuggers/openocd/jimtcl/Makefile.in new file mode 100644 index 00000000..da4c85fa --- /dev/null +++ b/debuggers/openocd/jimtcl/Makefile.in @@ -0,0 +1,204 @@ +# Tools +CC = @CCACHE@ @CC@ +CXX = @CCACHE@ @CXX@ +RANLIB = @RANLIB@ +AR = @AR@ +STRIP = @STRIP@ + +# Configuration + +SH_CFLAGS ?= @SH_CFLAGS@ +SH_LDFLAGS ?= @SH_LDFLAGS@ +SHOBJ_CFLAGS ?= @SHOBJ_CFLAGS@ +@if JIM_STATICLIB +SHOBJ_LDFLAGS ?= @SHOBJ_LDFLAGS@ +@else +SHOBJ_LDFLAGS ?= @SHOBJ_LDFLAGS_R@ +@endif +CFLAGS = @CFLAGS@ +CXXFLAGS = @CXXFLAGS@ +LDFLAGS = @LDFLAGS@ +LDLIBS += @LDLIBS@ +exec_prefix ?= @exec_prefix@ +prefix ?= @prefix@ + +CC += -D_GNU_SOURCE -Wall $(OPTIM) -I. +CXX += -D_GNU_SOURCE -Wall $(OPTIM) -I. +@if srcdir != . +CFLAGS += -I@srcdir@ +CXXFLAGS += -I@srcdir@ +VPATH := @srcdir@ +@endif + +@if JIM_STATICLIB +LIBJIM := libjim.a +@else +LIBJIM := libjim.@LIBSOEXT@ +SH_LIBJIM := $(LIBJIM) +CC += $(SH_CFLAGS) +CXX += $(SH_CFLAGS) +DEF_LD_PATH := @LD_LIBRARY_PATH@=@builddir@ +@endif + +@if HAVE_CXX_EXTENSIONS +JIMSH_CC := $(CXX) $(CXXFLAGS) +@else +JIMSH_CC := $(CC) $(CFLAGS) +@endif + +OBJS := _load-static-exts.o jim-subcmd.o jim-interactive.o jim-format.o jim.o utf8.o jimregexp.o \ + @EXTRA_OBJS@ @C_EXT_OBJS@ @TCL_EXT_OBJS@ + +JIMSH := jimsh@EXEEXT@ + +all: $(JIMSH) @C_EXT_SHOBJS@ + +# Create C extensions from pure Tcl extensions +.SUFFIXES: .tcl +.tcl.o: + @tclsh@ @srcdir@/make-c-ext.tcl $< >_$*.c || ( rm _$*.c; exit 1) + $(CC) $(CFLAGS) -c -o $@ _$*.c || ( rm _$*.c; exit 1) + @rm -f _$*.c + +docs: Tcl.html + +$(JIMSH): $(LIBJIM) jimsh.o initjimsh.o + $(JIMSH_CC) @SH_LINKFLAGS@ $(LDFLAGS) -o $@ jimsh.o initjimsh.o $(LIBJIM) $(LDLIBS) + +@if JIM_INSTALL +install: all docs @TCL_EXTS@ install-exec + mkdir -p $(DESTDIR)$(prefix)/lib/jim + cp $(LIBJIM) $(DESTDIR)$(prefix)/lib + cp @srcdir@/README.extensions @C_EXT_SHOBJS@ @TCL_EXTS@ $(DESTDIR)$(prefix)/lib/jim + mkdir -p $(DESTDIR)$(prefix)/include + cp @srcdir@/jim.h @srcdir@/jim-eventloop.h @srcdir@/jim-signal.h \ + @srcdir@/jim-subcmd.h @srcdir@/jim-win32compat.h $(DESTDIR)$(prefix)/include + cp jim-config.h $(DESTDIR)$(prefix)/include + mkdir -p $(DESTDIR)$(prefix)/doc/jim + cp Tcl.html $(DESTDIR)$(prefix)/doc/jim + mkdir -p $(DESTDIR)$(prefix)/bin + cp build-jim-ext $(DESTDIR)$(prefix)/bin + +install-exec: all + mkdir -p $(DESTDIR)$(prefix)/bin + cp $(JIMSH) $(DESTDIR)$(prefix)/bin + +uninstall: + rm -f $(DESTDIR)$(prefix)/bin/$(JIMSH) + rm -f $(DESTDIR)$(prefix)/bin/build-jim-ext + rm -f $(DESTDIR)$(prefix)/lib/$(LIBJIM) + for i in README.extensions @C_EXT_SHOBJS@ @TCL_EXTS@; do rm -f $(DESTDIR)$(prefix)/lib/jim/$$i; done + rm -f $(DESTDIR)$(prefix)/include/jim*.h + rm -f $(DESTDIR)$(prefix)/doc/jim/Tcl.html +@else +install install-exec: all +uninstall: +@endif + +test: $(JIMSH) + cd @srcdir@/tests; $(DEF_LD_PATH) $(MAKE) jimsh=@builddir@/jimsh + +$(OBJS): Makefile + +@if JIM_UTF8 +# Generate the unicode case mapping +utf8.o: _unicode_mapping.c + +_unicode_mapping.c: @srcdir@/UnicodeData.txt @srcdir@/parse-unidata.tcl + @tclsh@ @srcdir@/parse-unidata.tcl @srcdir@/UnicodeData.txt >$@ || ( rm $@; exit 1) +@endif + +_load-static-exts.c: @srcdir@/make-load-static-exts.tcl Makefile + @tclsh@ @srcdir@/make-load-static-exts.tcl @STATIC_EXTS@ >$@ || ( rm $@; exit 1) + +@if JIM_STATICLIB +$(LIBJIM): $(OBJS) + $(AR) cr $@ $(OBJS) + $(RANLIB) $@ +@else +$(LIBJIM): $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(SH_LDFLAGS) -o $@ $(OBJS) $(LDLIBS) +@endif + +# Note that $> $^ is for compatibility with both GNU make and BSD make +readdir.so: jim-readdir.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-readdir.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-readdir.o $(SH_LIBJIM) + +array.so: jim-array.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-array.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-array.o $(SH_LIBJIM) + +clock.so: jim-clock.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-clock.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-clock.o $(SH_LIBJIM) + +file.so: jim-file.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-file.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-file.o $(SH_LIBJIM) + +posix.so: jim-posix.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-posix.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-posix.o $(SH_LIBJIM) + +regexp.so: jim-regexp.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-regexp.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-regexp.o $(SH_LIBJIM) + +syslog.so: jim-syslog.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-syslog.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-syslog.o $(SH_LIBJIM) + +readline.so: jim-readline.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-readline.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-readline.o $(SH_LIBJIM) @LDLIBS_readline@ + +pack.so: jim-pack.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-pack.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-pack.o $(SH_LIBJIM) @LDLIBS_pack@ + +tclprefix.so: jim-tclprefix.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-tclprefix.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-tclprefix.o $(SH_LIBJIM) @LDLIBS_tclprefix@ + +sqlite3.so: jim-sqlite3.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-sqlite3.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-sqlite3.o $(SH_LIBJIM) @LDLIBS_sqlite3@ + +win32.so: jim-win32.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-win32.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-win32.o $(SH_LIBJIM) @LDLIBS_win32@ + +mk.so: jim-mk.cpp + $(CXX) $(CXXFLAGS) $(SHOBJ_CFLAGS) -c -o jim-mk.o $> $^ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-mk.o $(SH_LIBJIM) @LDLIBS_mk@ + +sdl.so: jim-sdl.c + $(CC) $(CFLAGS) $(SHOBJ_CFLAGS) -c -o jim-sdl.o $> $^ + $(CC) $(CFLAGS) $(LDFLAGS) $(SHOBJ_LDFLAGS) -o $@ jim-sdl.o $(SH_LIBJIM) @LDLIBS_sdl@ + +Tcl.html: jim_tcl.txt + @tclsh@ @srcdir@/make-index $> $^ | asciidoc -o $@ -d manpage - || cp @srcdir@/Tcl_shipped.html Tcl.html + +clean: + rm -f *.o *.so *.dll *.exe lib*.a $(JIMSH) Tcl.html _*.c + +distclean: clean + rm -f jimautoconf.h jim-config.h Makefile config.log autosetup/jimsh0@EXEEXT@ build-jim-ext + +ship: Tcl.html + cp $< Tcl_shipped.html + +# automake compatibility. do nothing for all these targets +EMPTY_AUTOMAKE_TARGETS := dvi pdf ps info html tags ctags mostlyclean maintainer-clean check installcheck installdirs \ + install-pdf install-ps install-info install-html -install-dvi uninstall install-data +.PHONY: $(EMPTY_AUTOMAKE_TARGETS) +$(EMPTY_AUTOMAKE_TARGETS): + +# automake compatibility - install sources from the current dir to $(distdir) +distdir_full := $(shell cd $(distdir); pwd) +distdir: + cd "@srcdir@"; git ls-files | cpio -pdmu $(distdir_full) + +reconfig: + CC='@CC@' @AUTOREMAKE@ diff --git a/debuggers/openocd/jimtcl/README b/debuggers/openocd/jimtcl/README new file mode 100644 index 00000000..8ce80869 --- /dev/null +++ b/debuggers/openocd/jimtcl/README @@ -0,0 +1,235 @@ +The Jim Interpreter + +A small-footprint implementation of the Tcl programming language. + +-------------------------------------------------------------------------------- +WHAT IS JIM? +-------------------------------------------------------------------------------- + +Jim is a small footprint implementation of the Tcl programming language +written from scratch. Currently Jim Tcl is very feature complete with +an extensive test suite (see the tests directory). +There are some Tcl commands and features which are not implemented +(and likely never will be), including namespaces, traces and Tk. However +Jim Tcl offers a number of both Tcl8.5 and Tcl8.6 features ({*}, dict, lassign, +tailcall and optional UTF-8 support) and some unique features. +These unique features include [lambda] with garbage collection, a general GC/references +system, arrays as syntax sugar for [dict]tionaries, object-based I/O and more. + +Other common features of the Tcl programming language are present, like +the "everything is a string" behaviour, implemented internally as +dual ported objects to ensure that the execution time does not reflect +the semantic of the language :) + +-------------------------------------------------------------------------------- +WHEN JIM CAN BE USEFUL? +-------------------------------------------------------------------------------- + +1) If you are writing an application, and want to make it scriptable, with +Jim you have a way to do it that does not require to link your application +with a big system. You can include the Jim source directly in your project +and use the Jim API to write the glue code that makes your application +scriptable in Jim, with the following advantages: + +- Jim is not the next "little language", but it's a Tcl implementation. + You can reuse your knowledge if you already Tcl skills, or enjoy + the availability of documentation, books, web resources, ... + (for example check my online Tcl book at http://www.invece.org/tclwise) + +- Jim is simple, 14k lines of core code. If you want to adapt it you can hack + the source code to meet the needs of your application. It makes you + able to have scripting for default, and avoid external dependences. + + Having scripting support *inside*, and in a way that a given version + of your program always gets shipped a given version of Jim, you can + write part of your application in Jim itself. Like it happens for + Emacs/Elisp, or Gimp/Scheme, both this applications have the interpreter + inside. + +- Jim is Tcl, and Tcl looks like a configuration file if you want. So + if you use Jim you have also a flexible syntax for your config file. + This is a valid Tcl script: + + set MyFeature on + ifssl { + set SslPort 45000 + use compression + } + + It looks like a configuration file, but if you implement the [ifssl] + and [use] commands, it's a valid Tcl script. + +- Tcl scales with the user. Not all know it, but Tcl is so powerful that + you can reprogram the language in itself. Jim support this features + of the Tcl programming language. You can write new control structures, + use the flexible data types it offers (Lists are a central data structure, + with Dictionaries that are also lists). Still Tcl is simpler for the + casual programmer, especially if compared to other languages offering + small footprint implementations (like Scheme and FORTH). + +- Because of the Tcl semantic (pass by value, everything is a command + since there are no reserved words), there is a nice API to glue + your application with Jim. See under the Jim Tcl manual for more detail. + +- Jim is supported. If you need commercial software, contact the original author + at 'antirez@gmail.com' or the current maintainer at 'steveb@workware.net.au'. + +2) The other "field" where Jim can be useful is obviously embedded systems. + +3) We are working to make Jim as feature-complete as possible, thanks to + dynamically loaded extensions it may stay as little as it is today + but able to do interesting things for you. So it's not excluded that + in the future Jim will be an option as general purpose language. + But don't mind, for this there is already the mainstream Tcl + implementation ;). + +-------------------------------------------------------------------------------- +HOW BIG IS IT? +-------------------------------------------------------------------------------- + +Jim with the default extensions configured and compiled with -Os is about 130k. +Without any extensions, it is about 85k. + +-------------------------------------------------------------------------------- +HOW FAST IS IT? +-------------------------------------------------------------------------------- + +Jim is in most code faster than Tcl7.6p2 (latest 7.x version), +and slower than Tcl 8.4.x. You can expect pretty decent performance +for such a little interpreter. + +If you want a more precise measure, there is 'bench.tcl' inside this +distribution that will run both under Jim and Tcl, so just execute +it with both the interpreters and see what you get :) + +-------------------------------------------------------------------------------- +HOW TO COMPILE +-------------------------------------------------------------------------------- + +Jim was tested under Linux, FreeBSD, MacosX, eCos, QNX, Windows XP (mingw, MVC). + +To compile jim itself try: + + ./configure + make + +-------------------------------------------------------------------------------- +EXTENSIONS +-------------------------------------------------------------------------------- + +Many optional extensions are included. Some are C extensions and others are pure Tcl. +Form more information, try: + + ./configure --help + +-------------------------------------------------------------------------------- +HOW TO EMBED JIM INTO APPLICATIONS +-------------------------------------------------------------------------------- + +See the "examples.api" directory + +-------------------------------------------------------------------------------- +HOW TO WRITE EXTENSIONS FOR JIM +-------------------------------------------------------------------------------- + +See the extensions shipped with Jim, jim-readline.c, jim-clock.c, glob.tcl and oo.tcl + +-------------------------------------------------------------------------------- +COPYRIGHT and LICENSE +-------------------------------------------------------------------------------- + +Unless explicitly stated, all files within Jim repository are released +under following license: + +/* Jim - A small embeddable Tcl interpreter + * + * Copyright 2005 Salvatore Sanfilippo + * Copyright 2005 Clemens Hintze + * Copyright 2005 patthoyts - Pat Thoyts + * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com + * Copyright 2008 Andrew Lunn + * Copyright 2008 Duane Ellis + * Copyright 2008 Uwe Klein + * Copyright 2008 Steve Bennett + * Copyright 2009 Nico Coesel + * Copyright 2009 Zachary T Welch zw@superlucidity.net + * Copyright 2009 David Brownell + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + */ +-------------------------------------------------------------------------------- +HISTORY +-------------------------------------------------------------------------------- + +"first Jim goal: to vent my need to hack on Tcl." + +And actually this is exactly why I started Jim, in the first days +of Jenuary 2005. After a month of hacking Jim was able to run +simple scripts, now, after two months it started to be clear to +me that it was not just the next toy to throw away but something +that may evolve into a real interpreter. In the same time +Pat Thoyts and Clemens Hintze started to contribute code, so that +the development of new core commands was faster, and also more +people hacking on the same code had as result fixes in the API, +C macros, and so on. + +Currently we are at the point that the core interpreter is almost finished +and it is entering the Beta stage. There is to add some other core command, +to do a code review to ensure quality of all the parts and to write +documentation. + +We already started to work on extensions like OOP, event loop, +I/O, networking, regexp. Some extensions are already ready for +prime time, like the Sqlite extension and the ANSI I/O. + +------------------------------------------------------------------------------ +Thanks to... +------------------------------------------------------------------------------ + +- First of all, thanks to every guy that are listed in the AUTHORS file, + that directly helped with code and ideas. Also check the ChangeLog + file for additional credits about patches or bug reports. +- Elisa Manara that helped me to select this ill conceived name for + an interpreter. +- Many people on the Tclers Chat that helped me to explore issues + about the use and the implementation of the Tcl programming language. +- David Welton for the tech info sharing and our chats about + programming languages design and the ability of software to "scale down". +- Martin S. Weber for the great help with Solaris issues, debugging of + problems with [load] on this arch, 64bit tests. +- The authors of "valgrind", for this wonderful tool, that helped me a + lot to fix bugs in minutes instead of hours. + + +---- +Enjoy! +Salvatore Sanfilippo +10 Mar 2005 + + diff --git a/debuggers/openocd/jimtcl/README.extensions b/debuggers/openocd/jimtcl/README.extensions new file mode 100644 index 00000000..0eaca1c8 --- /dev/null +++ b/debuggers/openocd/jimtcl/README.extensions @@ -0,0 +1,15 @@ +The /lib/jim directory contains both dynamically loadable extensions +and pure-Tcl extensions. + +Dynamically loadable extensions must have a .so file extension +Tcl extensions must have a .tcl file extension + +As long as /lib/jim is in $::auto_path (it is by default), extension +abc can be loaded with: + + package require abc + +First abc.so will be tried, and then abc.tcl + +Note that this directory may be something like /lib/jim, /usr/lib/jim or +/usr/local/lib/jim, depending upon where jim was installed. diff --git a/debuggers/openocd/jimtcl/README.metakit b/debuggers/openocd/jimtcl/README.metakit new file mode 100644 index 00000000..ce9830b5 --- /dev/null +++ b/debuggers/openocd/jimtcl/README.metakit @@ -0,0 +1,316 @@ +--- +title: Metakit +--- + +Metakit Extension for Jim Tcl +============================= + +OVERVIEW +-------- +The mk extension provides an interface to the Metakit small-footprint +embeddable database library (). The underlying +library is efficient at manipulating not-so-large amounts of data and takes a +different approach to composing database operations than common SQL-based +relational databases. + +Both the Metakit core library and the mk package can be linked either +statically or dynamically and loaded using + + package require mk + +CREATING A DATABASE +------------------- +A database (called a "storage" in Metakit terms) may either reside totally in +memory or be backed by a file. To open or create a database, call the +`storage` command with an optional filename parameter: + + set db [storage test.mk] + +The returned handle can be used as a command name to access the database. When +you are done, execute the `close` method, that is, run + + $db close + +A lost handle won't be found by GC but will be closed when the interpreter +exits. Note that by default Metakit will only record changes to the database +when you close the handle. Use the `commit` method to record the current +state of the database to disk. + +CREATING VIEWS +-------------- +*Views* in Metakit are what is called "tables" in conventional databases. A view +may several typed *properties*, or columns, and contains homogenous *rows*, or +records. New properties may be added to a view as needed; however, new properties +are not stored in the database file by default. The structure method specifies +the stored properties of a view, creating a new view or restructuring an old one +as needed: + + $db structure viewName description + +The view description must be a list of form `{propName type propName type ...}`. +The supported property types include: + +`string` +: A NULL-terminated string, stored as an array of bytes (without any encoding + assumptions). + +`binary` +: **Not yet supported by the `mk` extension.** + Blob of binary data that may contain embedded NULLs (zero bytes). Stored + as-is. This is more efficient than `string` when storing large blocks of + data (e.g. images) and will adjust the storage strategy as needed. + +`integer` +: An signed integer value occupying a maximum of 32 bits. If all values + stored in a column can fit in a smaller range (16, 8, or even 4 or 2 bits), + they are packed automatically. + +`long` +: Like `integer`, but is required to fit into 64 bits. + +`float` and `double` +: 32-bit and 64-bit IEEE floating-point values respectively. + +`subview` +: This type is not usually specified directly; instead, a structure + description of a nested view is given. `subview` properties store complete + views as their value, creating hierarchical data structures. When retreived + from a view, a value of a subview property is a normal view handle. + +Without a `description` parameter, the `structure` method returns the current +structure of the named view; without any parameters, it returns a dictionary +containing structure descriptions of all views stored in the database. + +After specifying the properties you expect to see in the view, call + + [$db view $viewName] as viewHandle + +to obtain a view handle. These handles are also commands, but are +garbage-collected and also destroy themselves after a single method call; the +`as viewHandle` call assigns the view handle to the specified variable and also +tells the view not to destroy itself until all the references to it are gone. + +View handles may also be made permanent by giving them a global command name, +e.g. + + rename [$db view data] .db.data + +However, such view handles are not managed automatically at all and must be +destroyed using the `destroy` method, or by renaming them to `""`. + +MANIPULATING DATA +----------------- +The value of a particular property is obtained using + + cursor get $cur propName + +where `$cur` is a string of form `viewHandle!index`. Row indices are zero-based +and may also be specified relative to the last row of the view using the +`end[+-]integer` notation. + +A dictionary containing all property name and value pairs can be retreived by +omitting the `propName` argument: + + cursor get $cur + +Setting property values is also performed either individually, using + + cursor set $cur propName value ?propName value ...? + +or via a dictionary with + + cursor set $cur dictValue + +In the first form of the command, property names may also be preceded by a +-_typeName_ option. In this case, a new property of the specified type will be +created if it doesn't already exist; note that this will cause *all* the rows +in the view to have the property (but see **A NOTE ON NULL** below). + +If the row index points after the end of the view, an appropriate number of +fresh rows will be inserted first. So, for example, you can use `end+1` +to append a new row. (Note that you then have to set it all at once, though.) + +The total number of rows can be obtained using + + $viewHandle size + +and set manually with + + $viewHandle resize newSize + +For example, you can use `$viewHandle resize 0` to clear a view. + +INSERT AND REMOVE +----------------- +New rows may also be inserted at an arbitrary position in a view with + + cursor insert $cur ?count? + +This will insert _count_ fresh rows into the view so that _$cur_ points to +the first one. The inverse of this operation is + + cursor remove $cur ?count? + +COMPOSING VIEWS +--------------- +The real power of Metakit lies in the way existing views are combined to create +new ones to obtain a particular perspective on the stored data. A single +operation takes one or more views and possibly additional options and produces a +new view, usually tracking notifications to the underlying views and sometimes +even supporting modification. + +Binary operations are left-biased when there are conflicting property values; +that is, they always prefer the values from the left view. + +### Unary operations ### + +*view* `unique` +: Derived view with duplicate rows removed. + +*view* `sort` *crit ?crit ...?* +: Derived view sorted on the specified criteria, in order. A single _crit_ + is either a property name or a property name preceded by a dash; the latter + specifies that the sorting is to be performed in reverse order. + +### Binary operations ### + +The operations taking _set_ arguments require that the given views have no +duplicate rows. The `unique` method can be used to ensure this. + +*view1* `concat` *view2* +: Vertical concatenation; that is, all the rows of _view1_ and then all rows + of _view2_. + +*view1* `pair` *view2* +: Pairing, or horizontal concatenation: every row in _view1_ is matched with + a row with the same index in _view2_; the result has all the properties of + _view1_ and all the properties of _view2_. + +*view1* `product` *view2* +: Cartesian product: each row in _view1_ horizontally concatenated with every + row in _view2_. + +*set1* `union` *set2* +: Set union. Unlike `concat`, this operation removes duplicates from the + result. A row is in the result if it is in _set1_ **or** in _set2_. + +*set1* `intersect` *set2* +: Set intersection. A row is in the result if it is in _set1_ **and** in + _set2_. + +*set1* `different` *set2* +: Symmetric difference. A row is in the result if it is in _set1_ **xor** in + _set2_, that is, in _set1_ or in _set2_, but not in both. + +*set1* `minus` *set2* +: Set minus. A row is in the result if it is in _set1_ **and not** in _set2_. + +### Relational operations ### + +*view1* `join` *view2* ?`-outer`? *prop ?prop ...?* +: Relational join on the specified properties: the rows from _view1_ and + _view2_ with all the specified properties equal are concatenated to form a + new row. If the `-outer` option is specified, the rows from _view1_ that do + not have a corresponding one in _view2_ are also left in the view, with the + properties existing only in _view2_ filled with default values. + +*view* `group` *subviewName prop ?prop ...?* +: Groups the rows with all the specified properties equal; moves all the + remaining properties into a newly created subview property called + _subviewName_. + +*view* `flatten` *subviewProp* +: The inverse of `group`. + +### Projections and selections ### + +*view* `project` *prop ?prop ...?* +: Projection: a derived view with only the specified properties left. + +*view* `without` *prop ?prop ...?* +: The opposite of `project`: a derived view with the specified properties + removed. + +*view* `range` *start end ?step?* + A slice or a segment of _view_: rows at _start_, _start+step_, and so on, + until the row number becomes larger than _end_. The usual `end[+-]integer` + notation is supported, but the indices don't change if the underlying view + is resized. + +**(!) select etc. should go here** + +### Search and storage optimization ### + +*view* `blocked` +: Invokes an optimization designed for storing large amounts of data. _view_ + must have a single subview property called `_B` with the desired structure + inside. This additional level of indirection is used by `blocked` to create + a view that looks like a usual one, but can store much more data + efficiently. As a result, indexing into the view becomes a bit slower. Once + this method is invoked, all access to _view_ must go through the returned + view. + +*view* `ordered` *prop ?prop ...?* +: Does not transform the structure of the view in any way, but signals that + the view should be considered ordered on a unique key consisting of the + specified properties, enabling some optimizations. Note that duplicate keys + are not allowed in an ordered view. + +**(!) TODO: hash, indexed(?) -- these make no sense until searches are implemented** + +### Pipelines ### + +Because constructs like `[[view op1 ...] op2 ...] op3 ...` tend to be common in +programs using Metakit, a shorthand syntax is introduced: such expressions may +also be written as `view op1 ... | op2 ... | op3 ...`. + +Note though that this syntax is not in any way magically wired into the +interpreter: it is understood only by the view handles and the two commands that +can possibly return a view: `$db view` and `cursor get`. If you want to support +this syntax in Tcl procedures, you'll need to do this yourself, or you may want +to create a custom view method and have the view handle work out the syntax for +you (see **USER-DEFINED METHODS** below). + +OTHER VIEW METHODS +------------------ + +*view* `copy` +: Creates a copy of view with the same data. + +*view* `clone` +: Creates a view with the same structure, but no data. + +*view* `pin` +: Specifies that the view should not be destroyed after a single method call. + Returns _view_. + +*view* `as` *varName* +: In addition to the actions performed by `pin`, assigns the view handle to + the variable named varName in the caller's scope. + +*view* `properties` +: Returns the names of all properties in the view. + +*view* `type` *prop* +: Returns the type of the specified property. + +A NOTE ON NULL +-------------- +Note that Metakit does not have a special `NULL` value like conventional +relational databases do. Instead, it defines _default_ property values: `""` for +`string` and `binary` types, `0` for all numeric types and a view with no rows +for subviews. These defaults are used when a fresh row is inserted and when +a new property is added to the view to fill in the missing values. + +USER-DEFINED METHODS +-------------------- +The storage and view handles support custom methods defined in Tcl: to define +_methodName_ on every storage or view handle, create a procedure called +{`mk.storage` *methodName*} or {`mk.view` *methodName*} respectively. These +procedures will receive the handle as the first argument and all the remaining +arguments. Remember to `pin` the view handle in view methods if you call more +than one method of it! + +Custom `cursor` subcommands may also be defined by creating a procedure called +{`cursor` *methodName*}. These receive all the arguments without any +modifications. diff --git a/debuggers/openocd/jimtcl/README.namespaces b/debuggers/openocd/jimtcl/README.namespaces new file mode 100644 index 00000000..e08d68e4 --- /dev/null +++ b/debuggers/openocd/jimtcl/README.namespaces @@ -0,0 +1,191 @@ +Lightweight Namespaces for Jim Tcl +================================== + +There are two broad requirements for namespace support in Jim Tcl. + +1. To allow code from multiple sources while reducing the chance of name clashes +2. To simplify porting existing Tcl code which uses namespaces + +This proposal addresses both of these requirements, with the following +additional requirements imposed by Jim Tcl. + +3. Support for namespaces should be optional, with the space and time overhead + when namespaces are disabled as close to zero as possible. +4. The implementation should be small and reasonably efficient. + +To further expand on requirement (2), the goal is not to be able to run +any Tcl scripts using namespaces with no changes. Rather, scripts +which use namespaces in a straightforward manner, should be easily +ported with changes which are compatible with Tcl. + +Implicit namespaces +------------------- +Rather than supporting explicit namespaces as Tcl does, Jim Tcl +supports implicit namespaces. Any procedure or variable which +is defined with a name containing ::, is implicitly scoped within +a namespace. + +For example, the following procedure and variable are created +in the namespace 'test' + +proc ::test::myproc {} { + puts "I am in namespace [namespace current]" +} +set ::test::myvar 3 + +This approach allows much of the existing variable and command +resolution machinery to be used with little change. It also means +that it is possible to simply define a namespace-scoped variable +or procedure without first creating the namespace, and similarly, +namespaces "disappear" when all variables and procedures defined +with the namespace scope are deleted. + +Namespaces, procedures and call frames +-------------------------------------- +When namespace support is enabled (at build time), each procedure has an associated +namespace (based on the procedure name). When the procedure is evaluated, +the namespace for the created call frame is set to the namespace associated +with the procedure. + +Command resolution is based on the namespace of the current call frame. +An unscoped command name will first be looked up in the current namespace, +and then in the global namespace. + +This also means that commands which do not create a call frame (such as commands +implemented in C) do not have an associated namespace. + +Similarly to Tcl, namespace eval introduces a temporary, anonymous +call frame with the associated namespace. For example, the following +will return "::test,1". + +namespace eval test { + puts [namespace current],[info level] +} + +Variable resolution +------------------- +The variable command in Jim Tcl has the same syntax as Tcl, but is closer in behaviour to the global command. +The variable command creates a link from a local variable to a namespace variable, possibly initialising it. + +For example, the following procedure uses 'variable' to initialse and access myvar. + +proc ::test::myproc {} { + variable myvar 4 + incr myvar +} + +Note that there is no automatic resolution of namespace variables. +For example, the following will *not* work. + +namespace eval ::test { + variable myvar 4 +} +namespace eval ::test { + # This will increment a local variable, not ::test::myvar + incr myvar +} + +And similarly, the following will only access local variables + +set x 3 +namespace eval ::test { + # This will incremement a local variable, not ::x + incr x + # This will also increment a local variable + incr abc::def +} + +In the same way that variable resolution does not "fall back" to +global variables, it also does not "fall back" to namespace variables. + +This approach allows name resolution to be simpler and more efficient +since it uses the same variable linking mechanism as upvar/global +and it allows namespaces to be implicit. It also solves the "creative +writing" problem where a variable may be created in an unintentional +scope. + +The namespace command +--------------------- +Currently, the following namespace commands are supported. + +* current - returns the current, fully-qualified namespace +* eval - evaluates a script in a namespace (introduces a call frame) +* qualifiers, tail, parent - note that these do not check for existence +* code, inscope - implemented +* delete - deletes all variables and commands with the namespace prefix +* which - implemented +* upvar - implemented + +namespace children, exists, path +-------------------------------- +With implicit namespaces, the namespace exists and namespace children commands +are expensive to implement and are of limited use. Checking the existence +of a namespace can be better done by checking for the existence of a known procedure +or variable in the namespace. + +Command resolution is always done by first looking in the namespace and then +at the global scope, so namespace path is not required. + +namespace ensemble +------------------ +The namespace ensemble command is not currently supported. A future version +of Jim Tcl will have a general-purpose ensemble creation and manipulation +mechanism and namespace ensemble will be implemented in terms of that mechanism. + +namespace import, export, forget, origin +---------------------------------------- +Since Jim Tcl namespaces are implicit, there is no location to store export patterns. +Therefore the namespace export command is a dummy command which does nothing. +All procedures in a namespace are considered to be exported. + +The namespace import command works by creating aliases to the target namespace +procedures. + +namespace forget is not implemented. + +namespace origin understands aliases created by namespace import +and can return the original command. + +namespace unknown +----------------- +If an undefined command is invoked, the "unknown" command is invoked. +The same namespace resolution rules apply for the unknown command. +This means that in the following example, test::unknown will be invoked +for the missing command rather than the global ::unknown. + +proc unknown {args} { + puts "global unknown" +} + +proc test::unknown {args} { + puts "test unknown" +} + +namespace eval test { + bogus +} + +This approach requires no special support and provides enough flexibility that +the namespace unknown command is not implemented. + +Porting namespace code from Tcl to Jim Tcl +------------------------------------------ +For most code, the following changes will be sufficient to port code. + +1. Canonicalise namespace names. For example, ::ns:: should be written + as ::ns or ns as appropriate, and excess colons should be removed. + For example ::ns:::blah should be written as ::ns::blah + (Note that the only "excess colon" case supported is ::::abc + in order to support [namespace current]::abc in the global namespace) + +2. The variable command should be used within namespace eval to link + to namespace variables, and access to variables in other namespaces + should be fully qualified + +Changes in the core Jim Tcl +--------------------------- +Previously Jim Tcl performed no scoping of command names. i.e. The +::format command was considered different from the format command. + +Even if namespace support is disabled, the command resolution will +recognised global scoping of commands and treat these as identical. diff --git a/debuggers/openocd/jimtcl/README.oo b/debuggers/openocd/jimtcl/README.oo new file mode 100644 index 00000000..fc59fafd --- /dev/null +++ b/debuggers/openocd/jimtcl/README.oo @@ -0,0 +1,253 @@ +OO Package for Jim Tcl +====================== + +Author: Steve Bennett +Date: 1 Nov 2010 09:18:40 + +OVERVIEW +-------- +The pure-Tcl oo package leverages Jim's unique strengths +to provide support for Object Oriented programming. + +The oo package can be statically linked with Jim or installed +as a separate Tcl package and loaded with: + + package require oo + +DECLARING CLASSES +----------------- +A class is declared with the 'class' proc as follows. + + class myclass ?baseclasses? classvars + +This declares a class named 'myclass' with the given dictionary, +'classvars', providing the initial state of all new objects. +It is important to list all class variables in 'classvars', even +if initialised only to the empty string, since the class makes +these variables available in methods and via [myclass vars]. + +A list of zero or more base classes may also be specified from +which methods and class variables are imported. See INHERITANCE +below for more details. + +Declaring a class creates a procedure with the class name along +with some related procedures. For example: + + . class Account {balance 0} + Account + . info procs Account* + {Account get} {Account methods} {Account eval} Account {Account new} {Account destroy} + {Account vars} {Account classname} {Account classvars} {Account method} + +Notice that apart from the main 'Account' procedure, all the remaining procedures (methods) +are prefixed with 'Account' and a space. + +PREDEFINED CLASS METHODS +------------------------ +Decaring a class pre-defines a number of "class" methods. i.e. those which don't +require an object and simply return or manipulate properties of the class. These are: + + new ?instancevars?:: + Creates and returns new object, optionally overriding the default class variable values. + Note that the class name is an alias for 'classname new {}' and can be used as a shorthand + for creating new objects with default values. + + method name arglist body:: + Creates or redefines a method for the class with the given name, argument list and body. + + methods:: + Returns a list of the methods supported by this class, including both class methods + and instance methods. Also includes base class methods. + + vars:: + Returns a list of the class variables for this class (names + only). Also includes base class variables. + + classvars:: + Returns a dictionary the class variables, including initial values, for this class. + Also includes base class variables. + + classname:: + Returns the classname. This can be useful as [$self classname]. + +Class methods may be invoked either via the class name or via an object of the class. +For example: + + . class Account {balance 0} + Account + . Account methods + classname classvars destroy eval get method methods new vars + . set a [Account] + .00000000000000000001> + . $a methods + classname classvars destroy eval get method methods new vars + +PREDEFINED OBJECT METHODS +------------------------- +Decaring a class pre-defines a number of "object" methods. i.e. those which operate +on a specific object. + + destroy:: + Destroys the object. This method may be overridden, but note that it should + delete the object with {rename $self ""}. This method will also be called + if the object is reaped during garbage collection. + + get varname:: + Returns the value of the given instance variable. + + eval ?locals? body:: + Makes any given local variables available to the body, along with + the instance variables, and evaluate the body in that context. + This can be used for one-off evaluation to avoid declaring a method. + +CREATING OBJECTS +---------------- +An object is created with the 'new' method, or simply by using the classname shortcut. +If the 'new' method is used, the variables for the newly created object (instance variables) +may be initialised. Otherwise they are set to the default values specified when the +class was declared. + +For example: + + . class Account {balance 0} + Account + . set a [Account] + .00000000000000000001> + . set b [Account new {balance 1000}] + .00000000000000000002> + . $a get balance + 0 + . $b get balance + 1000 + +DECLARING METHODS +----------------- +In addition to the predefined methods, new methods may be decared, or existing +methods redefined with the class method, method. + +Declaring a method is very similar to defining a proc, and the arglist +has identical syntax. For example: + + . Account method show {{channel stdout}} { $channel puts "Balance of account is $balance" } + . $b show + Balance of account is 1000 + +All instance variables are available within the method and any +changes to these variables are maintained by the object. + +In addition, the $self variables is defined and refers to the current object. +This may be used to invoke further methods on the object. For example: + + . Account method show {} { puts "Balance of account is [$self get balance]" } + . $b show + Balance of account is 1000 + +Notes: +* It is a bad idea to unset an instance variable. +* In general, you should avoid redefining any of the pre-defined methods, except for 'destroy'. +* When accessing the caller's scope with upvar or uplevel, note that there + are two frame levels between the caller and the method. Thus it is necessary + to use 'upvar 2' or 'uplevel 2' + +INHERITANCE +----------- +For each base class given in a new class declaration, the methods +and variables of those classes are imported into the new class being +defined. Base classes are imported in left to right order, so that if a +method is defined in more than one base class, the later definition +is selected. This applies similarly to class variables. + +Within a method, 'super' may be used to explicitly invoke a +base class method on the object. This applies only to the *last* +base class given. For example: + + # Assumes the existence of classes Account and Client + . Account method debit {amount} { incr balance -$amount } + . class CreditAccount {Client Account} {type visa} + CreditAccount + . CreditAccount method debit {amount} { + puts "Debit $type card" + super debit $amount + } + . set a [CreditAccount] + .00000000000000000001> + . $a debit 20 + Debit visa card + . $a balance + -20 + +In the CreditAccount debit method, the call to 'super debit' invokes +the method 'Account debit' since Account is the last base class listed. + +OBJECT LIFETIME/GARBAGE COLLECTION +---------------------------------- +Objects are implemented as lambdas. That is, they are procedures with state +and are named as references. This means that when an object is no longer +reachable by any name and garbage collection runs, the object will be +discarded and the destructor will be invoked. Note that the garbage collector +can be invoked manually with 'collect' if required. + + . class Account {} + Account + . Account method destroy {} { puts dying...; rename $self "" } + Account destroy + . proc a {} { set b [Account]; return "" } + a + . a + . collect + dying... + 1 + +CLASS METHODS/CLASS STATIC VARIABLES +------------------------------------ +All methods defined with 'method' operate on objects (instances). +If a class method is required, it is possible to simply declare one with 'proc'. +The method dispatcher will automatically be able to dispatch to this method. +Using this approach, it is also possible to add class static variables by +defining static variables to the proc. Although strictly these variables +are accessible only to that proc, not the class as a whole. + +For example: + + . class Account {} + Account + . proc {Account nextid} {} {{id 0}} { incr id } + Account nextid + . Account nextid + 1 + . Account nextid + 2 + . set a [Account] + .00000000000000000001> + . $a nextid + 3 + . $a eval { $self nextid } + 4 + +HOW METHOD DISPATCH WORKS +------------------------- +All class and object methods are name "classname methodname". + +The class method dispatcher is named "classname". When invoked with a methodname, +it simply invokes the method "classname methodname". + +The method dispatch is via a two step process. Firstly the object procedure is invoked +with the method name. This procedure then invokes "classname method" which sets up +the appropriate access to the object variables, and then invokes the method body. + +EXAMPLES +-------- +tree.tcl +~~~~~~~~ +The 'tree' package is implemented using the 'oo' package. +See the source code in tree.tcl and a usage example in tests/tree.test + +Of particular note is how callbacks and recursive invocation is used in the 'walk' method. + +examples/ootest.tcl +~~~~~~~~~~~~~~~~~~~ +A comprehensive OO example is provided in examples/ootest.tcl. + +It can be run simply as: + + ./jimsh examples/ootest.tcl diff --git a/debuggers/openocd/jimtcl/README.sqlite b/debuggers/openocd/jimtcl/README.sqlite new file mode 100644 index 00000000..dde7de5c --- /dev/null +++ b/debuggers/openocd/jimtcl/README.sqlite @@ -0,0 +1,177 @@ +Jim Sqlite extension documentation. +Copyright 2005 Salvatore Sanfilippo + + +Overview +~~~~~~~~ + +The Sqlite extension makes possible to work with sqlite (http://www.sqlite.org) +databases from Jim. SQLite is a small C library that implements a +self-contained, embeddable, zero-configuration SQL database engine. This +means it is perfect for embedded systems, and for stand-alone applications +that need the power of SQL without to use an external server like Mysql. + +Basic usage +~~~~~~~~~~~ + +The Sqlite extension exports an Object Based interface for databases. In order +to open a database use: + + set f [sqlite3.open dbname] + +The [sqlite3.open] command returns a db handle, that is a command name that +can be used to perform operations on the database. A real example: + + . set db [sqlite3.open test.db] + sqlite.handle0 + . $db query "SELECT * from tbl1" + {one hello! two 10} {one goodbye two 20} + +In the second line the handle is used as a command name, followed +by the 'method' or 'subcommand' ("query" in the example), and the arguments. + +The query method +~~~~~~~~~~~~~~~~ + +The query method has the following signature: + + $db query SqlQuery ?args? + +The sql query may contain occurrences of "%s" that are substituted +in the actual query with the following arguments, quoted in order +to make sure that the query is correct even if this arguments contain +"'" characters. So for example it is possible to write: + + . $db query "SELECT * from tbl1 WHERE one='%s'" hello! + {one hello! two 10} + +Instead of hello! it is possible to use a string with embedded "'": + + . $db query "SELECT * from tbl1 WHERE one='%s'" a'b + (no matches - the empty list is returned) + +This does not work instead using the Tcl variable expansion in the string: + + . $db query "SELECT * from tbl1 WHERE one='$foo'" + Runtime error, file "?", line 1: + near "b": syntax error + +In order to obtain an actual '%' character in the query, there is just +to use two, like in "foo %% bar". This is the same as the [format] argument. + +Specification of query results +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In one of the above examples, the following query was used: + + . $db query "SELECT * from tbl1" + {one hello! two 10} {one goodbye two 20} + +As you can see the result of a query is a list of lists. Every +element of the list represents a row, as a list of key/value pairs, +so actually every row is a Jim dictionary. + +The following example and generated output show how to take advantage +of this representation: + + . set res [$db query "SELECT * from tbl1"] + {one hello! two 10} {one goodbye two 20} + . foreach row $res {puts "One: $row(one), Two: $row(two)"} + One: hello!, Two: 10 + One: goodbye, Two: 20 + +To access every row sequentially is very simple, and field of a row +can be accessed using the $row(field) syntax. + +The close method +~~~~~~~~~~~~~~~~ + +In order to close the db, use the 'close' method that will have as side effect +to close the db and to remove the command associated with the db. +Just use: + + $db close + +Handling NULL values +~~~~~~~~~~~~~~~~~~~~ + +In the SQL language there is a special value NULL that is not the empty +string, so how to represent it in a typeless language like Tcl? +For default this extension will use the empty string, but it is possible +to specify a different string for the NULL value. + +In the above example there were two rows in the 'tbl1' table. Now +we can add using the "sqlite" command line client another one with +a NULL value: + + sqlite> INSERT INTO tbl1 VALUES(NULL,30); + sqlite> .exit + +That's what the sqlite extension will return for default: + + . $db query "SELECT * from tbl1" + {one hello! two 10} {one goodbye two 20} {one {} two 30} + +As you can see in the last row, the NULL is represented as {}, that's +the empty string. Using the -null option of the 'query' command we +can change this default, and tell the sqlite extension to represent +the NULL value as a different string: + + . $db query -null <> "SELECT * from tbl1" + {one hello! two 10} {one goodbye two 20} {one <> two 30} + +This way if the emtpy string has some semantical value for your +dataset you can change it. + +Finding the ID of the last inserted row +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is as simple as: + + . $db lastid + 10 + +Number of rows changed by the most recent query +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is also very simple, there is just to use the 'changes' method +without arugments. + + . $db changes + 5 + +Note that if you drop an entire table the number of changes will +be reported as zero, because of details of the sqlite implementation. + +That's all, +Enjoy! +Salvatore Sanfilippo + +p.s. this extension is just the work of some hour thanks to the cool +clean C API that sqlite exports. Thanks to the author of sqlite for this +great work. + +In memory databases +~~~~~~~~~~~~~~~~~~~ + +SQLite is able to create in-memory databases instead to use files. +This is of course faster and does not need the ability to write +to the filesystem. Of course this databases are only useful for +temp data. + +In-memory DBs are used just like regular databases, just the name used to +open the database is :memory:. That's an example that does not use the +filesystem at all to create and work with the db. + + package require sqlite3 + set db [sqlite3.open :memory:] + $db query {CREATE TABLE plays (id, author, title)} + $db query {INSERT INTO plays (id, author, title) VALUES (1, 'Goethe', 'Faust');} + $db query {INSERT INTO plays (id, author, title) VALUES (2, 'Shakespeare', 'Hamlet');} + $db query {INSERT INTO plays (id, author, title) VALUES (3, 'Sophocles', 'Oedipus Rex');} + set res [$db query "SELECT * FROM plays"] + $db close + foreach r $res {puts $r(author)} + +Of course once the Jim process is destroyed the database will no longer +exists. diff --git a/debuggers/openocd/jimtcl/README.utf-8 b/debuggers/openocd/jimtcl/README.utf-8 new file mode 100644 index 00000000..7128d76f --- /dev/null +++ b/debuggers/openocd/jimtcl/README.utf-8 @@ -0,0 +1,123 @@ +UTF-8 Support for Jim Tcl +========================= + +Author: Steve Bennett +Date: 2 Nov 2010 10:55:52 EST + +OVERVIEW +-------- +Traditionally Jim Tcl has support strings, including binary strings containing +nulls, however it has had no support for multi-byte character encodings. + +In some fields, such as when dealing with the web, or other user-generated content, +support for multi-byte character encodings is necessary. +In these cases it would be very useful for Jim Tcl to be able to process strings +as multi-byte character strings rather than simply binary bytes. + +Supporting multiple character encodings and translation between those encodings +is beyond the scope of Jim Tcl. Therefore, Jim has been enhanced to add support +for UTF-8, as probably the most popular general purpose multi-byte encoding. + +UTF-8 support is optional. It can be enabled at compile time with: + + ./configure --enable-utf8 + +The Jim Tcl documentation fully documents the UTF-8 support. This README includes +additional background information. + +Unicode vs UTF-8 +---------------- +It is important to understand that Unicode is an abstract representation +of the concept of a "character", while UTF-8 is an encoding of +Unicode into bytes. Thus the Unicode codepoint U+00B5 is encoded +in UTF-8 with the byte sequence: 0xc2, 0xb5. This is different from +ASCII which the same name is used interchangeably between a character +set and an encoding. + +Unicode Escapes +--------------- +Even without UTF-8 enabled, it is useful to be able to encode UTF-8 characters +in strings. This can be done with the \uNNNN Unicode escape. This syntax +is compatible with Tcl and is enabled even if UTF-8 is disabled. + +Like Tcl, currently only 16-bit Unicode characters can be encoded. + +UTF-8 Properties +---------------- +Due to the design of the UTF-8 encoding, many (most) commands continue +to work with UTF-8 strings. This is due to the following properties of UTF-8: + +* ASCII characters in strings have the same representation in UTF-8 +* An ASCII string will never match the middle of a multi-byte UTF-8 sequence +* UTF-8 strings can be sorted as bytes and produce the same result as sorting + by characters +* UTF-8 strings in Jim continue to be null terminated + +Commands Supporting UTF-8 +------------------------- +The following commands have been enhanced to support UTF-8 strings. + +* array {get,names,unset} +* case +* glob +* lsearch -glob, -regexp +* switch -glob, -regexp +* regexp, regsub +* format +* scan +* split +* string index, range, length, compare, equal, first, last, map, match, reverse, tolower, toupper +* string bytelength (new) +* info procs, commands, vars, globals, locals + +Character Classes +----------------- +Jim Tcl has no support for UTF-8 character classes. Thus [:alpha:] +will match [a-zA-Z], but not non-ASCII alphabetic characters. The +same is true for 'string is'. + +Regular Expressions +------------------- +Normally, Jim Tcl uses the system-supplied POSIX-compatible regex +implementation. + +Typically systems do not provide a UTF-8 capable regex implementation, +therefore when UTF-8 support is enabled, the built-in regex +implementation is used which includes UTF-8 support. + +Case Insensitivity +------------------ +Case folding is much more complex under Unicode than under ASCII. +For example it is possible for a character to change the number of +bytes required for representation when converting from one case to +another. Jim Tcl supports only "simple" case folding, where case +is folded only where the number of bytes does not change. + +Case folding tables are automatically generated from the official +unicode data table at http://unicode.org/Public/UNIDATA/UnicodeData.txt + +Working with Binary Data and non-UTF-8 encodings +------------------------------------------------ +Almost all Jim commands will work identically with binary data and +UTF-8 encoded data, including read, gets, puts and 'string eq'. It +is only certain string manipulation commands which will operated +differently. For example, 'string index' will return UTF-8 characters, +not bytes. + +If it is necessary to manipulate strings containing binary, non-ASCII +data (bytes >= 0x80), there are two options. + +1. Build Jim without UTF-8 support +2. Arrange to encode and decode binary data or data in other encodings + to UTF-8 before manipulation. + +Internal Details +---------------- +Jim_Utf8Length() will calculate the character length of the string and cache +it for later access. It uses utf8_strlen() which relies on the string to be null +terminated (which it always will be). + +It is possible to tell if a string is ascii-only because length == bytelength + +It is possible to provide optimised versions of various routines for +the ascii-only case. Currently this is done only for 'string index' and 'string range'. diff --git a/debuggers/openocd/jimtcl/STYLE b/debuggers/openocd/jimtcl/STYLE new file mode 100644 index 00000000..7a9b56cd --- /dev/null +++ b/debuggers/openocd/jimtcl/STYLE @@ -0,0 +1,64 @@ +This file summarizes the C style used for Jim. +Copyright (C) 2005 Salvatore Sanfilippo. + +----------- +INDENTATION +----------- + +Indentation is 4 spaces, no smart-tabs are used (i.e. +two indentation steps of 4 spaces will not be converted +into a real tab, but 8 spaces). + +--------------- +FUNCTIONS NAMES +--------------- + +Functions names of exported functions are in the form: + +Jim_ExportedFunctionName() + +The prefix is "Jim_", every word composing the function name +is capitalized. + +Not exported functions that are of general interest for the Jim +core, like JimFreeInterp() are capitalized the same way, but the +prefix used for this functions is "Jim" instead of "Jim_". +Another example is: + +JimNotExportedFunction() + +Not exported functions that are not general, like functions +implementing hashtables or Jim objects methods can be named +in any prefix as long as capitalization rules are followed, +like in: + +ListSetIndex() + +--------------- +VARIABLES NAMES +--------------- + +Global variables follow the same names convention of functions. + +Local variables have usually short names. A counter is just 'i', or 'j', +or something like this. When a longer name is required, composed of +more words, capitalization is used, but the first word starts in +lowcase: + +thisIsALogVarName + +---- +GOTO +---- + +Goto is allowed every time it makes the code cleaner, like in complex +functions that need to handle exceptions, there is often an "err" label +at the end of the function where allocated resources are freed before to exit +with an error. Goto is also used in order to escape multiple nested loops. + +---------- +C FEATURES +---------- + +Only C89 ANSI C is allowed. C99 features can't be used currently. +GCC extensions are not allowed. diff --git a/debuggers/openocd/jimtcl/TODO b/debuggers/openocd/jimtcl/TODO new file mode 100644 index 00000000..fc62aef8 --- /dev/null +++ b/debuggers/openocd/jimtcl/TODO @@ -0,0 +1,26 @@ +CORE LANGUAGE FEATURES + +CORE COMMANDS + +- [onleave] command, executing something as soon as the current procedure + returns. With no arguments it returns the script set, with one appends + the onleave script. There should be a way to reset. + + Currently we have [local] which can be used to delete procs on proc exit. + Also try/on/finally. Is [onleave] really needed? + +OTHER COMMANDS NOT IN TCL BUT THAT SHOULD BE IN JIM + +- Set commands: [lunion], [lintersect], and [ldifference] + +EXTENSIONS + +- Cryptography: hash functions, block ciphers, strim ciphers, PRNGs. +- Tuplespace extension (http://wiki.tcl.tk/3947) (using sqlite as backend) +- Zlib +- Gdlib +- CGI (interface compatible with ncgi, but possibly written in C for speed) + +REFERENCES SYSTEM + +- Unify ref/getref/setref/collect/finalize under an unique [ref] command. diff --git a/debuggers/openocd/jimtcl/Tcl_shipped.html b/debuggers/openocd/jimtcl/Tcl_shipped.html new file mode 100644 index 00000000..a687f097 --- /dev/null +++ b/debuggers/openocd/jimtcl/Tcl_shipped.html @@ -0,0 +1,8078 @@ + + + + + +Jim Tcl(n) + + + + + +
+
+

SYNOPSIS

+
+
+
+
cc <source> -ljim
+
+

or

+
+
+
jimsh [<scriptfile>]
+jimsh -e '<immediate-script>'
+jimsh --version
+
+
Quick Index
+
+
+
+

INTRODUCTION

+
+

Jim Tcl is a small footprint reimplementation of the Tcl scripting language. +The core language engine is compatible with Tcl 8.5+, while implementing +a significant subset of the Tcl 8.6 command set, plus additional features +available only in Jim Tcl.

+

Some notable differences with Tcl 8.5/8.6 are:

+
    +
  1. +

    +Object-based I/O (aio), but with a Tcl-compatibility layer +

    +
  2. +
  3. +

    +I/O: Support for sockets and pipes including udp, unix domain sockets and IPv6 +

    +
  4. +
  5. +

    +Integers are 64bit +

    +
  6. +
  7. +

    +Support for references (ref/getref/setref) and garbage collection +

    +
  8. +
  9. +

    +Builtin dictionary type (dict) with some limitations compared to Tcl 8.6 +

    +
  10. +
  11. +

    +env command to access environment variables +

    +
  12. +
  13. +

    +Operating system features: os.fork, os.wait, os.uptime, signal, alarm, sleep +

    +
  14. +
  15. +

    +Much better error reporting. info stacktrace as a replacement for $errorInfo, $errorCode +

    +
  16. +
  17. +

    +Support for "static" variables in procedures +

    +
  18. +
  19. +

    +Threads and coroutines are not supported +

    +
  20. +
  21. +

    +Command and variable traces are not supported +

    +
  22. +
  23. +

    +Built-in command line editing +

    +
  24. +
  25. +

    +Expression shorthand syntax: $(…) +

    +
  26. +
  27. +

    +Modular build allows many features to be omitted or built as dynamic, loadable modules +

    +
  28. +
  29. +

    +Highly suitable for use in an embedded environment +

    +
  30. +
  31. +

    +Support for UDP, IPv6, Unix-Domain sockets in addition to TCP sockets +

    +
  32. +
+
+
+
+

RECENT CHANGES

+
+
+

Changes between 0.73 and 0.74

+
    +
  1. +

    +Numbers with leading zeros are treated as decimal, not octal +

    +
  2. +
+
+
+

Changes between 0.72 and 0.73

+
    +
  1. +

    +Built-in regexp now support non-capturing parentheses: (?:…) +

    +
  2. +
  3. +

    +Add string replace +

    +
  4. +
  5. +

    +Add string totitle +

    +
  6. +
  7. +

    +Add info statics +

    +
  8. +
  9. +

    +Add build-jim-ext for easy separate building of loadable modules (extensions) +

    +
  10. +
  11. +

    +local now works with any command, not just procs +

    +
  12. +
  13. +

    +Add info alias to access the target of an alias +

    +
  14. +
  15. +

    +UTF-8 encoding past the basic multilingual plane (BMP) is supported +

    +
  16. +
  17. +

    +Add tcl::prefix +

    +
  18. +
  19. +

    +Add history +

    +
  20. +
  21. +

    +Most extensions are now enabled by default +

    +
  22. +
  23. +

    +Add support for namespaces and the namespace command +

    +
  24. +
  25. +

    +Add apply +

    +
  26. +
+
+
+

Changes between 0.71 and 0.72

+
    +
  1. +

    +procs now allow args and optional parameters in any position +

    +
  2. +
  3. +

    +Add Tcl-compatible expr functions, rand(), srand() and pow() +

    +
  4. +
  5. +

    +Add support for the -force option to file delete +

    +
  6. +
  7. +

    +Better diagnostics when source fails to load a script with a missing quote or bracket +

    +
  8. +
  9. +

    +New tcl_platform(pathSeparator) +

    +
  10. +
  11. +

    +Add support settings the modification time with file mtime +

    +
  12. +
  13. +

    +exec is now fully supported on win32 (mingw32) +

    +
  14. +
  15. +

    +file join, pwd, glob etc. now work for mingw32 +

    +
  16. +
  17. +

    +Line editing is now supported for the win32 console (mingw32) +

    +
  18. +
  19. +

    +Add aio listen command +

    +
  20. +
+
+
+

Changes between 0.70 and 0.71

+
    +
  1. +

    +Allow args to be renamed in procs +

    +
  2. +
  3. +

    +Add $(…) shorthand syntax for expressions +

    +
  4. +
  5. +

    +Add automatic reference variables in procs with &var syntax +

    +
  6. +
  7. +

    +Support jimsh --version +

    +
  8. +
  9. +

    +Additional variables in tcl_platform() +

    +
  10. +
  11. +

    +local procs now push existing commands and upcall can call them +

    +
  12. +
  13. +

    +Add loop command (TclX compatible) +

    +
  14. +
  15. +

    +Add aio buffering command +

    +
  16. +
  17. +

    +info complete can now return the missing character +

    +
  18. +
  19. +

    +binary format and binary scan are now (optionally) supported +

    +
  20. +
  21. +

    +Add string byterange +

    +
  22. +
  23. +

    +Built-in regexp now support non-greedy repetition (*?, +?, ??) +

    +
  24. +
+
+
+
+
+

TCL INTRODUCTION

+
+

Tcl stands for tool command language and is pronounced tickle. +It is actually two things: a language and a library.

+

First, Tcl is a simple textual language, intended primarily for +issuing commands to interactive programs such as text editors, +debuggers, illustrators, and shells. It has a simple syntax and is also +programmable, so Tcl users can write command procedures to provide more +powerful commands than those in the built-in set.

+

Second, Tcl is a library package that can be embedded in application +programs. The Tcl library consists of a parser for the Tcl language, +routines to implement the Tcl built-in commands, and procedures that +allow each application to extend Tcl with additional commands specific +to that application. The application program generates Tcl commands and +passes them to the Tcl parser for execution. Commands may be generated +by reading characters from an input source, or by associating command +strings with elements of the application’s user interface, such as menu +entries, buttons, or keystrokes.

+

When the Tcl library receives commands it parses them into component +fields and executes built-in commands directly. For commands implemented +by the application, Tcl calls back to the application to execute the +commands. In many cases commands will invoke recursive invocations of the +Tcl interpreter by passing in additional strings to execute (procedures, +looping commands, and conditional commands all work in this way).

+

An application program gains three advantages by using Tcl for its command +language. First, Tcl provides a standard syntax: once users know Tcl, +they will be able to issue commands easily to any Tcl-based application. +Second, Tcl provides programmability. All a Tcl application needs +to do is to implement a few application-specific low-level commands. +Tcl provides many utility commands plus a general programming interface +for building up complex command procedures. By using Tcl, applications +need not re-implement these features.

+

Third, Tcl can be used as a common language for communicating between +applications. Inter-application communication is not built into the +Tcl core described here, but various add-on libraries, such as the Tk +toolkit, allow applications to issue commands to each other. This makes +it possible for applications to work together in much more powerful ways +than was previously possible.

+

Fourth, Jim Tcl includes a command processor, jimsh, which can be +used to run standalone Tcl scripts, or to run Tcl commands interactively.

+

This manual page focuses primarily on the Tcl language. It describes +the language syntax and the built-in commands that will be available +in any application based on Tcl. The individual library procedures are +described in more detail in separate manual pages, one per procedure.

+
+
+
+

JIMSH COMMAND INTERPRETER

+
+

A simple, but powerful command processor, jimsh, is part of Jim Tcl. +It may be invoked in interactive mode as:

+
+
+
jimsh
+
+

or to process the Tcl script in a file with:

+
+
+
jimsh filename
+
+

It may also be invoked to execute an immediate script with:

+
+
+
jimsh -e "script"
+
+
+

Interactive Mode

+

Interactive mode reads Tcl commands from standard input, evaluates +those commands and prints the results.

+
+
+
$ jimsh
+Welcome to Jim version 0.73, Copyright (c) 2005-8 Salvatore Sanfilippo
+. info version
+0.73
+. lsort [info commands p*]
+package parray pid popen proc puts pwd
+. foreach i {a b c} {
+{> puts $i
+{> }
+a
+b
+c
+. bad
+invalid command name "bad"
+[error] . exit
+$
+
+

If jimsh is configured with line editing (it is by default) and a VT-100-compatible +terminal is detected, Emacs-style line editing commands are available, including: +arrow keys, ^W to erase a word, ^U to erase the line, ^R for reverse incremental search +in history. Additionally, the h command may be used to display the command history.

+

Command line history is automatically saved and loaded from ~/.jim_history

+

In interactive mode, jimsh automatically runs the script ~/.jimrc at startup +if it exists.

+
+
+
+
+

INTERPRETERS

+
+

The central data structure in Tcl is an interpreter (C type Jim_Interp). +An interpreter consists of a set of command bindings, a set of variable +values, and a few other miscellaneous pieces of state. Each Tcl command +is interpreted in the context of a particular interpreter.

+

Some Tcl-based applications will maintain multiple interpreters +simultaneously, each associated with a different widget or portion of +the application. Interpreters are relatively lightweight structures. +They can be created and deleted quickly, so application programmers should +feel free to use multiple interpreters if that simplifies the application.

+
+
+
+

DATA TYPES

+
+

Tcl supports only one type of data: strings. All commands, all arguments +to commands, all command results, and all variable values are strings.

+

Where commands require numeric arguments or return numeric results, +the arguments and results are passed as strings. Many commands expect +their string arguments to have certain formats, but this interpretation +is up to the individual commands. For example, arguments often contain +Tcl command strings, which may get executed as part of the commands. +The easiest way to understand the Tcl interpreter is to remember that +everything is just an operation on a string. In many cases Tcl constructs +will look similar to more structured constructs from other languages. +However, the Tcl constructs are not structured at all; they are just +strings of characters, and this gives them a different behaviour than +the structures they may look like.

+

Although the exact interpretation of a Tcl string depends on who is doing +the interpretation, there are three common forms that strings take: +commands, expressions, and lists. The major sections below discuss +these three forms in more detail.

+
+
+
+

BASIC COMMAND SYNTAX

+
+

The Tcl language has syntactic similarities to both the Unix shells +and Lisp. However, the interpretation of commands is different +in Tcl than in either of those other two systems. +A Tcl command string consists of one or more commands separated +by newline characters or semi-colons. +Each command consists of a collection of fields separated by +white space (spaces or tabs). +The first field must be the name of a command, and the +additional fields, if any, are arguments that will be passed to +that command. For example, the command:

+
+
+
set a 22
+
+

has three fields: the first, set, is the name of a Tcl command, and +the last two, a and 22, will be passed as arguments to +the set command. The command name may refer either to a built-in +Tcl command, an application-specific command bound in with the library +procedure Jim_CreateCommand, or a command procedure defined with the +proc built-in command.

+

Arguments are passed literally as text strings. Individual commands may +interpret those strings in any fashion they wish. The set command, +for example, will treat its first argument as the name of a variable +and its second argument as a string value to assign to that variable. +For other commands arguments may be interpreted as integers, lists, +file names, or Tcl commands.

+

Command names should normally be typed completely (e.g. no abbreviations). +However, if the Tcl interpreter cannot locate a command it invokes a +special command named unknown which attempts to find or create the +command.

+

For example, at many sites unknown will search through library +directories for the desired command and create it as a Tcl procedure if +it is found. The unknown command often provides automatic completion +of abbreviated commands, but usually only for commands that were typed +interactively.

+

It’s probably a bad idea to use abbreviations in command scripts and +other forms that will be re-used over time: changes to the command set +may cause abbreviations to become ambiguous, resulting in scripts that +no longer work.

+
+
+
+

COMMENTS

+
+

If the first non-blank character in a command is #, then everything +from the # up through the next newline character is treated as +a comment and ignored. When comments are embedded inside nested +commands (e.g. fields enclosed in braces) they must have properly-matched +braces (this is necessary because when Tcl parses the top-level command +it doesn’t yet know that the nested field will be used as a command so +it cannot process the nested comment character as a comment).

+
+
+
+

GROUPING ARGUMENTS WITH DOUBLE-QUOTES

+
+

Normally each argument field ends at the next white space, but +double-quotes may be used to create arguments with embedded space.

+

If an argument field begins with a double-quote, then the argument isn’t +terminated by white space (including newlines) or a semi-colon (see below +for information on semi-colons); instead it ends at the next double-quote +character. The double-quotes are not included in the resulting argument. +For example, the command

+
+
+
set a "This is a single argument"
+
+

will pass two arguments to set: a and This is a single argument.

+

Within double-quotes, command substitutions, variable substitutions, +and backslash substitutions still occur, as described below. If the +first character of a command field is not a quote, then quotes receive +no special interpretation in the parsing of that field.

+
+
+
+

GROUPING ARGUMENTS WITH BRACES

+
+

Curly braces may also be used for grouping arguments. They are similar +to quotes except for two differences. First, they nest; this makes them +easier to use for complicated arguments like nested Tcl command strings. +Second, the substitutions described below for commands, variables, and +backslashes do not occur in arguments enclosed in braces, so braces +can be used to prevent substitutions where they are undesirable.

+

If an argument field begins with a left brace, then the argument ends +at the matching right brace. Tcl will strip off the outermost layer +of braces and pass the information between the braces to the command +without any further modification. For example, in the command

+
+
+
set a {xyz a {b c d}}
+
+

the set command will receive two arguments: a +and xyz a {b c d}.

+

When braces or quotes are in effect, the matching brace or quote need +not be on the same line as the starting quote or brace; in this case +the newline will be included in the argument field along with any other +characters up to the matching brace or quote. For example, the eval +command takes one argument, which is a command string; eval invokes +the Tcl interpreter to execute the command string. The command

+
+
+
eval {
+  set a 22
+  set b 33
+}
+
+

will assign the value 22 to a and 33 to b.

+

If the first character of a command field is not a left +brace, then neither left nor right +braces in the field will be treated specially (except as part of +variable substitution; see below).

+
+
+
+

COMMAND SUBSTITUTION WITH BRACKETS

+
+

If an open bracket occurs in a field of a command, then command +substitution occurs (except for fields enclosed in braces). All of the +text up to the matching close bracket is treated as a Tcl command and +executed immediately. Then the result of that command is substituted +for the bracketed text. For example, consider the command

+
+
+
set a [set b]
+
+

When the set command has only a single argument, it is the name of a +variable and set returns the contents of that variable. In this case, +if variable b has the value foo, then the command above is equivalent +to the command

+
+
+
set a foo
+
+

Brackets can be used in more complex ways. For example, if the variable +b has the value foo and the variable c has the value gorp, +then the command

+
+
+
set a xyz[set b].[set c]
+
+

is equivalent to the command

+
+
+
set a xyzfoo.gorp
+
+

A bracketed command may contain multiple commands separated by newlines +or semi-colons in the usual fashion. In this case the value of the last +command is used for substitution. For example, the command

+
+
+
set a x[set b 22
+expr $b+2]x
+
+

is equivalent to the command

+
+
+
set a x24x
+
+

If a field is enclosed in braces then the brackets and the characters +between them are not interpreted specially; they are passed through to +the argument verbatim.

+
+
+
+

VARIABLE SUBSTITUTION WITH $

+
+

The dollar sign ($) may be used as a special shorthand form for +substituting variable values. If $ appears in an argument that isn’t +enclosed in braces then variable substitution will occur. The characters +after the $, up to the first character that isn’t a number, letter, +or underscore, are taken as a variable name and the string value of that +variable is substituted for the name.

+

For example, if variable foo has the value test, then the command

+
+
+
set a $foo.c
+
+

is equivalent to the command

+
+
+
set a test.c
+
+

There are two special forms for variable substitution. If the next +character after the name of the variable is an open parenthesis, then +the variable is assumed to be an array name, and all of the characters +between the open parenthesis and the next close parenthesis are taken as +an index into the array. Command substitutions and variable substitutions +are performed on the information between the parentheses before it is +used as an index.

+

For example, if the variable x is an array with one element named +first and value 87 and another element named 14 and value more, +then the command

+
+
+
set a xyz$x(first)zyx
+
+

is equivalent to the command

+
+
+
set a xyz87zyx
+
+

If the variable index has the value 14, then the command

+
+
+
set a xyz$x($index)zyx
+
+

is equivalent to the command

+
+
+
set a xyzmorezyx
+
+

For more information on arrays, see VARIABLES AND ARRAYS below.

+

The second special form for variables occurs when the dollar sign is +followed by an open curly brace. In this case the variable name consists +of all the characters up to the next curly brace.

+

Array references are not possible in this form: the name between braces +is assumed to refer to a scalar variable. For example, if variable +foo has the value test, then the command

+
+
+
set a abc${foo}bar
+
+

is equivalent to the command

+
+
+
set a abctestbar
+
+

Variable substitution does not occur in arguments that are enclosed in +braces: the dollar sign and variable name are passed through to the +argument verbatim.

+

The dollar sign abbreviation is simply a shorthand form. $a is +completely equivalent to [set a]; it is provided as a convenience +to reduce typing.

+
+
+
+

SEPARATING COMMANDS WITH SEMI-COLONS

+
+

Normally, each command occupies one line (the command is terminated by a +newline character). However, semi-colon (;) is treated as a command +separator character; multiple commands may be placed on one line by +separating them with a semi-colon. Semi-colons are not treated as +command separators if they appear within curly braces or double-quotes.

+
+
+
+

BACKSLASH SUBSTITUTION

+
+

Backslashes may be used to insert non-printing characters into command +fields and also to insert special characters like braces and brackets +into fields without them being interpreted specially as described above.

+

The backslash sequences understood by the Tcl interpreter are +listed below. In each case, the backslash +sequence is replaced by the given character:

+
+
+\b +
+
+

+ Backspace (0x8) +

+
+
+\f +
+
+

+ Form feed (0xc) +

+
+
+\n +
+
+

+ Newline (0xa) +

+
+
+\r +
+
+

+ Carriage-return (0xd). +

+
+
+\t +
+
+

+ Tab (0x9). +

+
+
+\v +
+
+

+ Vertical tab (0xb). +

+
+
+\{ +
+
+

+ Left brace ({). +

+
+
+\} +
+
+

+ Right brace (}). +

+
+
+\[ +
+
+

+ Open bracket ([). +

+
+
+\] +
+
+

+ Close bracket (]). +

+
+
+\$ +
+
+

+ Dollar sign ($). +

+
+
+\<space> +
+
+

+ Space ( ): doesn’t terminate argument. +

+
+
+\; +
+
+

+ Semi-colon: doesn’t terminate command. +

+
+
+\" +
+
+

+ Double-quote. +

+
+
+\<newline> +
+
+

+ Nothing: this joins two lines together + into a single line. This backslash feature is unique in that + it will be applied even when the sequence occurs within braces. +

+
+
+\\ +
+
+

+ Backslash (\). +

+
+
+\ddd +
+
+

+ The digits ddd (one, two, or three of them) give the octal value of + the character. Note that Jim supports null characters in strings. +

+
+
+\unnnn +
+
+\u{nnn} +
+
+\Unnnnnnnn +
+
+

+ The UTF-8 encoding of the unicode codepoint represented by the hex digits, nnnn, is inserted. + The u form allows for one to four hex digits. + The U form allows for one to eight hex digits. + The u{nnn} form allows for one to eight hex digits, but makes it easier to insert + characters UTF-8 characters which are followed by a hex digit. +

+
+
+

For example, in the command

+
+
+
set a \{x\[\ yz\141
+
+

the second argument to set will be {x[ yza.

+

If a backslash is followed by something other than one of the options +described above, then the backslash is transmitted to the argument +field without any special processing, and the Tcl scanner continues +normal processing with the next character. For example, in the +command

+
+
+
set \*a \\\{foo
+
+

The first argument to set will be \*a and the second +argument will be \{foo.

+

If an argument is enclosed in braces, then backslash sequences inside +the argument are parsed but no substitution occurs (except for +backslash-newline): the backslash +sequence is passed through to the argument as is, without making +any special interpretation of the characters in the backslash sequence. +In particular, backslashed braces are not counted in locating the +matching right brace that terminates the argument. +For example, in the +command

+
+
+
set a {\{abc}
+
+

the second argument to set will be \{abc.

+

This backslash mechanism is not sufficient to generate absolutely +any argument structure; it only covers the +most common cases. To produce particularly complicated arguments +it is probably easiest to use the format command along with +command substitution.

+
+
+
+

STRING AND LIST INDEX SPECIFICATIONS

+
+

Many string and list commands take one or more index parameters which +specify a position in the string relative to the start or end of the string/list.

+

The index may be one of the following forms:

+
+
+integer +
+
+

+ A simple integer, where 0 refers to the first element of the string + or list. +

+
+
+integer+integer or +
+
+integer-integer +
+
+

+ The sum or difference of the two integers. e.g. 2+3 refers to the 5th element. + This is useful when used with (e.g.) $i+1 rather than the more verbose + [expr {$i+1}] +

+
+
+end +
+
+

+ The last element of the string or list. +

+
+
+end-integer +
+
+

+ The nth-from-last element of the string or list. +

+
+
+
+
+
+

COMMAND SUMMARY

+
+
    +
  1. +

    +A command is just a string. +

    +
  2. +
  3. +

    +Within a string commands are separated by newlines or semi-colons + (unless the newline or semi-colon is within braces or brackets + or is backslashed). +

    +
  4. +
  5. +

    +A command consists of fields. The first field is the name of the command. + The other fields are strings that are passed to that command as arguments. +

    +
  6. +
  7. +

    +Fields are normally separated by white space. +

    +
  8. +
  9. +

    +Double-quotes allow white space and semi-colons to appear within + a single argument. + Command substitution, variable substitution, and backslash substitution + still occur inside quotes. +

    +
  10. +
  11. +

    +Braces defer interpretation of special characters. + If a field begins with a left brace, then it consists of everything + between the left brace and the matching right brace. The + braces themselves are not included in the argument. + No further processing is done on the information between the braces + except that backslash-newline sequences are eliminated. +

    +
  12. +
  13. +

    +If a field doesn’t begin with a brace then backslash, + variable, and command substitution are done on the field. Only a + single level of processing is done: the results of one substitution + are not scanned again for further substitutions or any other + special treatment. Substitution can + occur on any field of a command, including the command name + as well as the arguments. +

    +
  14. +
  15. +

    +If the first non-blank character of a command is a #, everything + from the # up through the next newline is treated as a comment + and ignored. +

    +
  16. +
+
+
+
+

EXPRESSIONS

+
+

The second major interpretation applied to strings in Tcl is +as expressions. Several commands, such as expr, for, +and if, treat one or more of their arguments as expressions +and call the Tcl expression processors (Jim_ExprLong, +Jim_ExprBoolean, etc.) to evaluate them.

+

The operators permitted in Tcl expressions are a subset of +the operators permitted in C expressions, and they have the +same meaning and precedence as the corresponding C operators. +Expressions almost always yield numeric results +(integer or floating-point values). +For example, the expression

+
+
+
8.2 + 6
+
+

evaluates to 14.2.

+

Tcl expressions differ from C expressions in the way that +operands are specified, and in that Tcl expressions support +non-numeric operands and string comparisons.

+

A Tcl expression consists of a combination of operands, operators, +and parentheses.

+

White space may be used between the operands and operators and +parentheses; it is ignored by the expression processor. +Where possible, operands are interpreted as integer values.

+

Integer values may be specified in decimal (the normal case) or in +hexadecimal (if the first two characters of the operand are 0x). +Note that Jim Tcl does not treat numbers with leading zeros as octal.

+

If an operand does not have one of the integer formats given +above, then it is treated as a floating-point number if that is +possible. Floating-point numbers may be specified in any of the +ways accepted by an ANSI-compliant C compiler (except that the +f, F, l, and L suffixes will not be permitted in +most installations). For example, all of the +following are valid floating-point numbers: 2.1, 3., 6e4, 7.91e+16.

+

If no numeric interpretation is possible, then an operand is left +as a string (and only a limited set of operators may be applied to +it).

+
    +
  1. +

    +Operands may be specified in any of the following ways: +

    +
  2. +
  3. +

    +As a numeric value, either integer or floating-point. +

    +
  4. +
  5. +

    +As a Tcl variable, using standard $ notation. +The variable’s value will be used as the operand. +

    +
  6. +
  7. +

    +As a string enclosed in double-quotes. +The expression parser will perform backslash, variable, and +command substitutions on the information between the quotes, +and use the resulting value as the operand +

    +
  8. +
  9. +

    +As a string enclosed in braces. +The characters between the open brace and matching close brace +will be used as the operand without any substitutions. +

    +
  10. +
  11. +

    +As a Tcl command enclosed in brackets. +The command will be executed and its result will be used as +the operand. +

    +
  12. +
+

Where substitutions occur above (e.g. inside quoted strings), they +are performed by the expression processor. +However, an additional layer of substitution may already have +been performed by the command parser before the expression +processor was called.

+

As discussed below, it is usually best to enclose expressions +in braces to prevent the command parser from performing substitutions +on the contents.

+

For some examples of simple expressions, suppose the variable a has +the value 3 and the variable b has the value 6. Then the expression +on the left side of each of the lines below will evaluate to the value +on the right side of the line:

+
+
+
$a + 3.1                6.1
+2 + "$a.$b"             5.6
+4*[llength "6 2"]       8
+{word one} < "word $a"  0
+
+

The valid operators are listed below, grouped in decreasing order +of precedence:

+
+
+int() double() round() abs(), rand(), srand() +
+
+

+ Unary functions (except rand() which takes no arguments) +

+
    +
  • +

    +int() converts the numeric argument to an integer by truncating down. +

    +
  • +
  • +

    +double() converts the numeric argument to floating point. +

    +
  • +
  • +

    +round() converts the numeric argument to the closest integer value. +

    +
  • +
  • +

    +abs() takes the absolute value of the numeric argument. +

    +
  • +
  • +

    +rand() takes the absolute value of the numeric argument. +

    +
  • +
  • +

    +rand() returns a pseudo-random floating-point value in the range (0,1). +

    +
  • +
  • +

    +srand() takes an integer argument to (re)seed the random number generator. Returns the first random number from that seed. +

    +
  • +
+
+
+sin() cos() tan() asin() acos() atan() sinh() cosh() tanh() ceil() floor() exp() log() log10() sqrt() +
+
+

+ Unary math functions. + If Jim is compiled with math support, these functions are available. +

+
+
+- + ~ ! +
+
+

+ Unary minus, unary plus, bit-wise NOT, logical NOT. None of these operands + may be applied to string operands, and bit-wise NOT may be + applied only to integers. +

+
+
+** pow(x,y) +
+
+

+ Power. e.g. xy. If Jim is compiled with math support, supports doubles and + integers. Otherwise supports integers only. (Note that the math-function form + has the same highest precedence) +

+
+
+* / % +
+
+

+ Multiply, divide, remainder. None of these operands may be + applied to string operands, and remainder may be applied only + to integers. +

+
+
++ - +
+
+

+ Add and subtract. Valid for any numeric operands. +

+
+
+<< >> <<< >>> +
+
+

+ Left and right shift, left and right rotate. Valid for integer operands only. +

+
+
+< > <= >= +
+
+

+ Boolean less, greater, less than or equal, and greater than or equal. + Each operator produces 1 if the condition is true, 0 otherwise. + These operators may be applied to strings as well as numeric operands, + in which case string comparison is used. +

+
+
+== != +
+
+

+ Boolean equal and not equal. Each operator produces a zero/one result. + Valid for all operand types. Note that values will be converted to integers + if possible, then floating point types, and finally strings will be compared. + It is recommended that eq and ne should be used for string comparison. +

+
+
+eq ne +
+
+

+ String equal and not equal. Uses the string value directly without + attempting to convert to a number first. +

+
+
+in ni +
+
+

+ String in list and not in list. For in, result is 1 if the left operand (as a string) + is contained in the right operand (as a list), or 0 otherwise. The result for + {$a ni $list} is equivalent to {!($a in $list)}. +

+
+
+& +
+
+

+ Bit-wise AND. Valid for integer operands only. +

+
+
+| +
+
+

+ Bit-wise OR. Valid for integer operands only. +

+
+
+^ +
+
+

+ Bit-wise exclusive OR. Valid for integer operands only. +

+
+
+&& +
+
+

+ Logical AND. Produces a 1 result if both operands are non-zero, 0 otherwise. + Valid for numeric operands only (integers or floating-point). +

+
+
+|| +
+
+

+ Logical OR. Produces a 0 result if both operands are zero, 1 otherwise. + Valid for numeric operands only (integers or floating-point). +

+
+
+x ? y : z +
+
+

+ If-then-else, as in C. If x + evaluates to non-zero, then the result is the value of y. + Otherwise the result is the value of z. + The x operand must have a numeric value, while y and z can + be of any type. +

+
+
+

See the C manual for more details on the results +produced by each operator. +All of the binary operators group left-to-right within the same +precedence level. For example, the expression

+
+
+
4*2 < 7
+
+

evaluates to 0.

+

The &&, ||, and ?: operators have lazy evaluation, just as +in C, which means that operands are not evaluated if they are not +needed to determine the outcome. For example, in

+
+
+
$v ? [a] : [b]
+
+

only one of [a] or [b] will actually be evaluated, +depending on the value of $v.

+

All internal computations involving integers are done with the C +type long long if available, or long otherwise, and all internal +computations involving floating-point are done with the C type +double.

+

When converting a string to floating-point, exponent overflow is +detected and results in a Tcl error. +For conversion to integer from string, detection of overflow depends +on the behaviour of some routines in the local C library, so it should +be regarded as unreliable. +In any case, overflow and underflow are generally not detected +reliably for intermediate results.

+

Conversion among internal representations for integer, floating-point, +and string operands is done automatically as needed. +For arithmetic computations, integers are used until some +floating-point number is introduced, after which floating-point is used. +For example,

+
+
+
5 / 4
+
+

yields the result 1, while

+
+
+
5 / 4.0
+5 / ( [string length "abcd"] + 0.0 )
+
+

both yield the result 1.25.

+

String values may be used as operands of the comparison operators, +although the expression evaluator tries to do comparisons as integer +or floating-point when it can. +If one of the operands of a comparison is a string and the other +has a numeric value, the numeric operand is converted back to +a string using the C sprintf format specifier +%d for integers and %g for floating-point values. +For example, the expressions

+
+
+
"0x03" > "2"
+"0y" < "0x12"
+
+

both evaluate to 1. The first comparison is done using integer +comparison, and the second is done using string comparison after +the second operand is converted to the string 18.

+

In general it is safest to enclose an expression in braces when +entering it in a command: otherwise, if the expression contains +any white space then the Tcl interpreter will split it +among several arguments. For example, the command

+
+
+
expr $a + $b
+
+

results in three arguments being passed to expr: $a, ++, and $b. In addition, if the expression isn’t in braces +then the Tcl interpreter will perform variable and command substitution +immediately (it will happen in the command parser rather than in +the expression parser). In many cases the expression is being +passed to a command that will evaluate the expression later (or +even many times if, for example, the expression is to be used to +decide when to exit a loop). Usually the desired goal is to re-do +the variable or command substitutions each time the expression is +evaluated, rather than once and for all at the beginning. For example, +the command

+
+
+
for {set i 1} $i<=10 {incr i} {...}        ** WRONG **
+
+

is probably intended to iterate over all values of i from 1 to 10. +After each iteration of the body of the loop, for will pass +its second argument to the expression evaluator to see whether or not +to continue processing. Unfortunately, in this case the value of i +in the second argument will be substituted once and for all when the +for command is parsed. If i was 0 before the for +command was invoked then the second argument of for will be 0<=10 +which will always evaluate to 1, even though i eventually +becomes greater than 10. In the above case the loop will never +terminate. Instead, the expression should be placed in braces:

+
+
+
for {set i 1} {$i<=10} {incr i} {...}      ** RIGHT **
+
+

This causes the substitution of i +to be delayed; it will be re-done each time the expression is +evaluated, which is the desired result.

+
+
+
+

LISTS

+
+

The third major way that strings are interpreted in Tcl is as lists. +A list is just a string with a list-like structure +consisting of fields separated by white space. For example, the +string

+
+
+
Al Sue Anne John
+
+

is a list with four elements or fields. +Lists have the same basic structure as command strings, except +that a newline character in a list is treated as a field separator +just like space or tab. Conventions for braces and quotes +and backslashes are the same for lists as for commands. For example, +the string

+
+
+
a b\ c {d e {f g h}}
+
+

is a list with three elements: a, b c, and d e {f g h}.

+

Whenever an element is extracted from a list, the same rules about +braces and quotes and backslashes are applied as for commands. Thus in +the example above when the third element is extracted from the list, +the result is

+
+
+
d e {f g h}
+
+

(when the field was extracted, all that happened was to strip off +the outermost layer of braces). Command substitution and +variable substitution are never +made on a list (at least, not by the list-processing commands; the +list can always be passed to the Tcl interpreter for evaluation).

+

The Tcl commands concat, foreach, lappend, lindex, linsert, +list, llength, lrange, lreplace, lsearch, and lsort allow +you to build lists, extract elements from them, search them, and perform +other list-related functions.

+

Advanced list commands include lrepeat, lreverse, lmap, lassign, lset.

+
+
+
+

LIST EXPANSION

+
+

A new addition to Tcl 8.5 is the ability to expand a list into separate +arguments. Support for this feature is also available in Jim.

+

Consider the following attempt to exec a list:

+
+
+
set cmd {ls -l}
+exec $cmd
+
+

This will attempt to exec the a command named "ls -l", which will clearly not +work. Typically eval and concat are required to solve this problem, however +it can be solved much more easily with {*}.

+
+
+
exec {*}$cmd
+
+

This will expand the following argument into individual elements and then evaluate +the resulting command.

+

Note that the official Tcl syntax is {*}, however {expand} is retained +for backward compatibility with experimental versions of this feature.

+
+
+
+

REGULAR EXPRESSIONS

+
+

Tcl provides two commands that support string matching using regular +expressions, regexp and regsub, as well as switch -regexp and +lsearch -regexp.

+

Regular expressions may be implemented one of two ways. Either using the system’s C library +POSIX regular expression support, or using the built-in regular expression engine. +The differences between these are described below.

+

NOTE Tcl 7.x and 8.x use perl-style Advanced Regular Expressions (ARE).

+
+

POSIX Regular Expressions

+

If the system supports POSIX regular expressions, and UTF-8 support is not enabled, +this support will be used by default. The type of regular expressions supported are +Extended Regular Expressions (ERE) rather than Basic Regular Expressions (BRE). +See REG_EXTENDED in the documentation.

+

Using the system-supported POSIX regular expressions will typically +make for the smallest code size, but some features such as UTF-8 +and \w, \d, \s are not supported.

+

See regex(3) and regex(7) for full details.

+
+
+

Jim built-in Regular Expressions

+

The Jim built-in regulare expression engine may be selected with ./configure --with-jim-regexp +or it will be selected automatically if UTF-8 support is enabled.

+

This engine supports UTF-8 as well as some ARE features. The differences with both Tcl 7.x/8.x +and POSIX are highlighted below.

+
    +
  1. +

    +UTF-8 strings and patterns are both supported +

    +
  2. +
  3. +

    +Supported character classes: [:alnum:], [:digit:] and [:space:] +

    +
  4. +
  5. +

    +Supported shorthand character classes: \w = [:alnum:], \d = [:digit:], \s = [:space:] +

    +
  6. +
  7. +

    +Character classes apply to ASCII characters only +

    +
  8. +
  9. +

    +Supported constraint escapes: \m = \< = start of word, \M = \> = end of word +

    +
  10. +
  11. +

    +Backslash escapes may be used within regular expressions, such as \n = newline, \uNNNN = unicode +

    +
  12. +
  13. +

    +Support for the ? non-greedy quantifier. e.g. *? +

    +
  14. +
  15. +

    +Support for non-capuring parentheses (?:…) +

    +
  16. +
+
+
+
+
+

COMMAND RESULTS

+
+

Each command produces two results: a code and a string. The +code indicates whether the command completed successfully or not, +and the string gives additional information. The valid codes are +defined in jim.h, and are:

+
+
+JIM_OK(0) +
+
+

+ This is the normal return code, and indicates that the command completed + successfully. The string gives the command’s return value. +

+
+
+JIM_ERR(1) +
+
+

+ Indicates that an error occurred; the string gives a message describing + the error. +

+
+
+JIM_RETURN(2) +
+
+

+ Indicates that the return command has been invoked, and that the + current procedure (or top-level command or source command) + should return immediately. The + string gives the return value for the procedure or command. +

+
+
+JIM_BREAK(3) +
+
+

+ Indicates that the break command has been invoked, so the + innermost loop should abort immediately. The string should always + be empty. +

+
+
+JIM_CONTINUE(4) +
+
+

+ Indicates that the continue command has been invoked, so the + innermost loop should go on to the next iteration. The string + should always be empty. +

+
+
+JIM_SIGNAL(5) +
+
+

+ Indicates that a signal was caught while executing a commands. + The string contains the name of the signal caught. + See the signal and catch commands. +

+
+
+JIM_EXIT(6) +
+
+

+ Indicates that the command called the exit command. + The string contains the exit code. +

+
+
+

Tcl programmers do not normally need to think about return codes, +since JIM_OK is almost always returned. If anything else is returned +by a command, then the Tcl interpreter immediately stops processing +commands and returns to its caller. If there are several nested +invocations of the Tcl interpreter in progress, then each nested +command will usually return the error to its caller, until eventually +the error is reported to the top-level application code. The +application will then display the error message for the user.

+

In a few cases, some commands will handle certain error conditions +themselves and not return them upwards. For example, the for +command checks for the JIM_BREAK code; if it occurs, then for +stops executing the body of the loop and returns JIM_OK to its +caller. The for command also handles JIM_CONTINUE codes and the +procedure interpreter handles JIM_RETURN codes. The catch +command allows Tcl programs to catch errors and handle them without +aborting command interpretation any further.

+

The info returncodes command may be used to programmatically map between +return codes and names.

+
+
+
+

PROCEDURES

+
+

Tcl allows you to extend the command interface by defining +procedures. A Tcl procedure can be invoked just like any other Tcl +command (it has a name and it receives one or more arguments). +The only difference is that its body isn’t a piece of C code linked +into the program; it is a string containing one or more other +Tcl commands.

+

The proc command is used to create a new Tcl command procedure:

+

proc name arglist ?statics? body

+

The new command is named name, and it replaces any existing command +there may have been by that name. Whenever the new command is +invoked, the contents of body will be executed by the Tcl +interpreter.

+

arglist specifies the formal arguments to the procedure. +It consists of a list, possibly empty, of the following +argument specifiers:

+
+
+name +
+
+

+ Required Argument - A simple argument name. +

+
+
+name default +
+
+

+ Optional Argument - A two-element list consisting of the + argument name, followed by the default value, which will + be used if the corresponding argument is not supplied. +

+
+
+&name +
+
+

+ Reference Argument - The caller is expected to pass the name of + an existing variable. An implicit upvar 1 'origname' 'name' is done + to make the variable available in the proc scope. +

+
+
+args +
+
+

+ Variable Argument - The special name args, which is + assigned all remaining arguments (including none) as a list. The + variable argument may only be specified once. Note that + the syntax args newname may be used to retain the special + behaviour of args with a different local name. In this case, + the variable is named newname rather than args. +

+
+
+

When the command is invoked, a local variable will be created for each of +the formal arguments to the procedure; its value will be the value +of corresponding argument in the invoking command or the argument’s +default value.

+

Arguments with default values need not be specified in a procedure +invocation. However, there must be enough actual arguments for all +required arguments, and there must not be any extra actual arguments +(unless the Variable Argument is specified).

+

Actual arguments are assigned to formal arguments as in left-to-right +order with the following precedence.

+
    +
  1. +

    +Required Arguments (including Reference Arguments) +

    +
  2. +
  3. +

    +Optional Arguments +

    +
  4. +
  5. +

    +Variable Argument +

    +
  6. +
+

The following example illustrates precedence. Assume a procedure declaration:

+
+
+
proc p {{a A} args b {c C} d} {...}
+
+

This procedure requires at least two arguments, but can accept an unlimited number. +The following table shows how various numbers of arguments are assigned. +Values marked as - are assigned the default value.

+
+ +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Number of argumentsaargsbcd

2

-

-

1

-

2

3

1

-

2

-

3

4

1

-

2

3

4

5

1

2

3

4

5

6

1

2,3

4

5

6

+
+

When body is being executed, variable names normally refer to local +variables, which are created automatically when referenced and deleted +when the procedure returns. One local variable is automatically created +for each of the procedure’s arguments. Global variables can be +accessed by invoking the global command or via the :: prefix.

+
+

New in Jim

+

In addition to procedure arguments, Jim procedures may declare static variables. +These variables scoped to the procedure and initialised at procedure definition. +Either from the static variable definition, or from the enclosing scope.

+

Consider the following example:

+
+
+
jim> set a 1
+jim> proc a {} {a {b 2}} {
+    set c 1
+    puts "$a $b $c"
+    incr a
+    incr b
+    incr c
+}
+jim> a
+1 2 1
+jim> a
+2 3 1
+
+

The static variable a has no initialiser, so it is initialised from +the enclosing scope with the value 1. (Note that it is an error if there +is no variable with the same name in the enclosing scope). However b +has an initialiser, so it is initialised to 2.

+

Unlike a local variable, the value of a static variable is retained across +invocations of the procedure.

+

See the proc command for information on how to define procedures +and what happens when they are invoked. See also NAMESPACES.

+
+
+
+
+

VARIABLES - SCALARS AND ARRAYS

+
+

Tcl allows the definition of variables and the use of their values +either through $-style variable substitution, the set +command, or a few other mechanisms.

+

Variables need not be declared: a new variable will automatically +be created each time a new variable name is used.

+

Tcl supports two types of variables: scalars and arrays. +A scalar variable has a single value, whereas an array variable +can have any number of elements, each with a name (called +its index) and a value.

+

Array indexes may be arbitrary strings; they need not be numeric. +Parentheses are used refer to array elements in Tcl commands. +For example, the command

+
+
+
set x(first) 44
+
+

will modify the element of x whose index is first +so that its new value is 44.

+

Two-dimensional arrays can be simulated in Tcl by using indexes +that contain multiple concatenated values. +For example, the commands

+
+
+
set a(2,3) 1
+set a(3,6) 2
+
+

set the elements of a whose indexes are 2,3 and 3,6.

+

In general, array elements may be used anywhere in Tcl that scalar +variables may be used.

+

If an array is defined with a particular name, then there may +not be a scalar variable with the same name.

+

Similarly, if there is a scalar variable with a particular +name then it is not possible to make array references to the +variable.

+

To convert a scalar variable to an array or vice versa, remove +the existing variable with the unset command.

+

The array command provides several features for dealing +with arrays, such as querying the names of all the elements of +the array and converting between an array and a list.

+

Variables may be either global or local. If a variable +name is used when a procedure isn’t being executed, then it +automatically refers to a global variable. Variable names used +within a procedure normally refer to local variables associated with that +invocation of the procedure. Local variables are deleted whenever +a procedure exits. Either global command may be used to request +that a name refer to a global variable for the duration of the current +procedure (this is somewhat analogous to extern in C), or the variable +may be explicitly scoped with the :: prefix. For example

+
+
+
set a 1
+set b 2
+proc p {} {
+    set c 3
+    global a
+
+
+
+
    puts "$a $::b $c"
+}
+p
+
+

will output:

+
+
+
1 2 3
+
+
+
+
+

ARRAYS AS LISTS IN JIM

+
+

Unlike Tcl, Jim can automatically convert between a list (with an even +number of elements) and an array value. This is similar to the way Tcl +can convert between a string and a list.

+

For example:

+
+
+
set a {1 one 2 two}
+puts $a(2)
+
+

will output:

+
+
+
two
+
+

Thus array set is equivalent to set when the variable does not +exist or is empty.

+

The reverse is also true where an array will be converted into +a list.

+
+
+
set a(1) one; set a(2) two
+puts $a
+
+

will output:

+
+
+
1 one 2 two
+
+
+
+
+

DICTIONARY VALUES

+
+

Tcl 8.5 introduced the dict command, and Jim Tcl has added a version +of this command. Dictionaries provide efficient access to key-value +pairs, just like arrays, but dictionaries are pure values. This +means that you can pass them to a procedure just as a list or a +string. Tcl dictionaries are therefore much more like Tcl lists, +except that they represent a mapping from keys to values, rather +than an ordered sequence.

+

You can nest dictionaries, so that the value for a particular key +consists of another dictionary. That way you can elegantly build +complicated data structures, such as hierarchical databases. You +can also combine dictionaries with other Tcl data structures. For +instance, you can build a list of dictionaries that themselves +contain lists.

+

Dictionaries are values that contain an efficient, order-preserving +mapping from arbitrary keys to arbitrary values. Each key in the +dictionary maps to a single value. They have a textual format that +is exactly that of any list with an even number of elements, with +each mapping in the dictionary being represented as two items in +the list. When a command takes a dictionary and produces a new +dictionary based on it (either returning it or writing it back into +the variable that the starting dictionary was read from) the new +dictionary will have the same order of keys, modulo any deleted +keys and with new keys added on to the end. When a string is +interpreted as a dictionary and it would otherwise have duplicate +keys, only the last value for a particular key is used; the others +are ignored, meaning that, "apple banana" and "apple carrot apple +banana" are equivalent dictionaries (with different string +representations).

+

Note that in Jim, arrays are implemented as dictionaries. +Thus automatic conversion between lists and dictionaries applies +as it does for arrays.

+
+
+
jim> dict set a 1 one
+1 one
+jim> dict set a 2 two
+1 one 2 two
+jim> puts $a
+1 one 2 two
+jim> puts $a(2)
+two
+jim> dict set a 3 T three
+1 one 2 two 3 {T three}
+
+

See the dict command for more details.

+
+
+
+

NAMESPACES

+
+

Tcl added namespaces as a mechanism avoiding name clashes, especially in applications +including a number of 3rd party components. While there is less need for namespaces +in Jim Tcl (which does not strive to support large applications), it is convenient to +provide a subset of the support for namespaces to easy porting code from Tcl.

+

Jim Tcl currently supports "light-weight" namespaces which should be adequate for most +purposes. This feature is currently experimental. See README.namespaces for more information +and the documentation of the namespace command.

+
+
+
+

GARBAGE COLLECTION, REFERENCES, LAMBDA

+
+

Unlike Tcl, Jim has some sophisticated support for functional programming. +These are described briefly below.

+

More information may be found at http://wiki.tcl.tk/13847

+
+

References

+

A reference can be thought of as holding a value with one level of indirection, +where the value may be garbage collected when unreferenced. +Consider the following example:

+
+
+
jim> set r [ref "One String" test]
+<reference.<test___>.00000000000000000000>
+jim> getref $r
+One String
+
+

The operation ref creates a references to the value specified by the +first argument. (The second argument is a "type" used for documentation purposes).

+

The operation getref is the dereferencing operation which retrieves the value +stored in the reference.

+
+
+
jim> setref $r "New String"
+New String
+jim> getref $r
+New String
+
+

The operation setref replaces the value stored by the reference. If the old value +is no longer accessible by any reference, it will eventually be automatically be garbage +collected.

+
+
+

Garbage Collection

+

Normally, all values in Tcl are passed by value. As such values are copied and released +automatically as necessary.

+

With the introduction of references, it is possible to create values whose lifetime +transcend their scope. To support this, case, the Jim system will periodically identify +and discard objects which are no longer accessible by any reference.

+

The collect command may be used to force garbage collection. Consider a reference created +with a finalizer:

+
+
+
jim> proc f {ref value} { puts "Finaliser called for $ref,$value" }
+jim> set r [ref "One String" test f]
+<reference.<test___>.00000000000
+jim> collect
+0
+jim> set r ""
+jim> collect
+Finaliser called for <reference.<test___>.00000000000,One String
+1
+
+

Note that once the reference, r, was modified so that it no longer +contained a reference to the value, the garbage collector discarded +the value (after calling the finalizer).

+

The finalizer for a reference may be examined or changed with the finalize command

+
+
+
jim> finalize $r
+f
+jim> finalize $r newf
+newf
+
+
+
+

Lambda

+

Jim provides a garbage collected lambda function. This is a procedure +which is able to create an anonymous procedure. Consider:

+
+
+
jim> set f [lambda {a} {{x 0}} { incr x $a }]
+jim> $f 1
+1
+jim> $f 2
+3
+jim> set f ""
+
+

This create an anonymous procedure (with the name stored in f), with a static variable +which is incremented by the supplied value and the result returned.

+

Once the procedure name is no longer accessible, it will automatically be deleted +when the garbage collector runs.

+

The procedure may also be delete immediately by renaming it "". e.g.

+
+
+
jim> rename $f ""
+
+
+
+
+
+

UTF-8 AND UNICODE

+
+

If Jim is built with UTF-8 support enabled (configure --enable-utf), +then most string-related commands become UTF-8 aware. These include, +but are not limited to, string match, split, glob, scan and +format.

+

UTF-8 encoding has many advantages, but one of the complications is that +characters can take a variable number of bytes. Thus the addition of +string bytelength which returns the number of bytes in a string, +while string length returns the number of characters.

+

If UTF-8 support is not enabled, all commands treat bytes as characters +and string bytelength returns the same value as string length.

+

Note that even if UTF-8 support is not enabled, the \uNNNN and related syntax +is still available to embed UTF-8 sequences.

+

Jim Tcl supports all currently defined unicode codepoints. That is 21 bits, up to +U+1FFFFF.

+
+

String Matching

+

Commands such as string match, lsearch -glob, array names and others use string +pattern matching rules. These commands support UTF-8. For example:

+
+
+
string match a\[\ua0-\ubf\]b "a\u00a3b"
+
+
+
+

format and scan

+

format %c allows a unicode codepoint to be be encoded. For example, the following will return +a string with two bytes and one character. The same as \ub5

+
+
+
format %c 0xb5
+
+

format respects widths as character widths, not byte widths. For example, the following will +return a string with three characters, not three bytes.

+
+
+
format %.3s \ub5\ub6\ub7\ub8
+
+

Similarly, scan … %c allows a UTF-8 to be decoded to a unicode codepoint. The following will set +a to 181 (0xb5) and b to 65 (0x41).

+
+
+
scan \u00b5A %c%c a b
+
+

scan %s will also accept a character class, including unicode ranges.

+
+
+

String Classes

+

string is has not been extended to classify UTF-8 characters. Therefore, the following +will return 0, even though the string may be considered to be alphabetic.

+
+
+
string is alpha \ub5Test
+
+

This does not affect the string classes ascii, control, digit, double, integer or xdigit.

+
+
+

Case Mapping and Conversion

+

Jim provides a simplified unicode case mapping. This means that case conversion +and comparison will not increase or decrease the number of characters in a string. +(Although it may change the number of bytes).

+

string toupper will convert any lowercase letters to their uppercase equivalent. +Any character which is not a letter or has no uppercase equivalent is left unchanged. +Similarly for string tolower and string totitle.

+

Commands which perform case insensitive matches, such as string compare -nocase +and lsearch -nocase fold both strings to uppercase before comparison.

+
+
+

Invalid UTF-8 Sequences

+

Some UTF-8 character sequences are invalid, such as those beginning with 0xff, +those which represent character sequences longer than 3 bytes (greater than U+FFFF), +and those which end prematurely, such as a lone 0xc2.

+

In these situations, the offending bytes are treated as single characters. For example, +the following returns 2.

+
+
+
string bytelength \xff\xff
+
+
+
+

Regular Expressions

+

If UTF-8 support is enabled, the built-in regular expression engine will be +selected which supports UTF-8 strings and patterns.

+

See REGULAR EXPRESSIONS

+
+
+
+
+

BUILT-IN COMMANDS

+
+

The Tcl library provides the following built-in commands, which will +be available in any application using Tcl. In addition to these +built-in commands, there may be additional commands defined by each +application, plus commands defined as Tcl procedures.

+

In the command syntax descriptions below, words in boldface are +literals that you type verbatim to Tcl.

+

Words in italics are meta-symbols; they serve as names for any of +a range of values that you can type.

+

Optional arguments or groups of arguments are indicated by enclosing them +in ?question-marks?.

+

Ellipses (...) indicate that any number of additional +arguments or groups of arguments may appear, in the same format +as the preceding argument(s).

+ +
+

alarm

+

alarm seconds

+

Delivers the SIGALRM signal to the process after the given +number of seconds. If the platform supports ualarm(3) then +the argument may be a floating point value. Otherwise it must +be an integer.

+

Note that unless a signal handler for SIGALRM has been installed +(see signal), the process will exit on this signal.

+
+
+

alias

+

alias name args...

+

Creates a single word alias (command) for one or more words. For example, +the following creates an alias for the command info exists.

+
+
+
alias e info exists
+if {[e var]} {
+  ...
+}
+
+

alias returns name, allowing it to be used with local.

+

See also proc, curry, lambda, local, info alias, exists -alias

+
+
+

append

+

append varName value ?value value …?

+

Append all of the value arguments to the current value +of variable varName. If varName doesn’t exist, +it is given a value equal to the concatenation of all the +value arguments.

+

This command provides an efficient way to build up long +variables incrementally. +For example, "append a $b" is much more efficient than +"set a $a$b" if $a is long.

+
+
+

apply

+

apply lambdaExpr ?arg1 arg2 ...?

+

The command apply provides for anonymous procedure calls, +similar to lambda, but without command name being created, even temporarily.

+

The function lambdaExpr is a two element list {args body} +or a three element list {args body namespace}. The first element +args specifies the formal arguments, in the same form as the proc and lambda commands.

+
+
+

array

+

array option arrayName ?arg...?

+

This command performs one of several operations on the +variable given by arrayName.

+

Note that in general, if the named array does not exist, the array command behaves +as though the array exists but is empty.

+

The option argument determines what action is carried out by the +command. The legal options (which may be abbreviated) are:

+
+
+array exists arrayName +
+
+

+ Returns 1 if arrayName is an array variable, 0 if there is + no variable by that name. This command is essentially + identical to info exists +

+
+
+array get arrayName ?pattern? +
+
+

+ Returns a list containing pairs of elements. The first + element in each pair is the name of an element in arrayName + and the second element of each pair is the value of the + array element. The order of the pairs is undefined. If + pattern is not specified, then all of the elements of the + array are included in the result. If pattern is specified, + then only those elements whose names match pattern (using + the matching rules of string match) are included. If arrayName + isn’t the name of an array variable, or if the array contains + no elements, then an empty list is returned. +

+
+
+array names arrayName ?pattern? +
+
+

+ Returns a list containing the names of all of the elements + in the array that match pattern. If pattern is omitted then + the command returns all of the element names in the array. + If pattern is specified, then only those elements whose + names match pattern (using the matching rules of string + match) are included. If there are no (matching) elements + in the array, or if arrayName isn’t the name of an array + variable, then an empty string is returned. +

+
+
+array set arrayName list +
+
+

+ Sets the values of one or more elements in arrayName. list + must have a form like that returned by array get, consisting + of an even number of elements. Each odd-numbered element + in list is treated as an element name within arrayName, and + the following element in list is used as a new value for + that array element. If the variable arrayName does not + already exist and list is empty, arrayName is created with + an empty array value. +

+
+
+array size arrayName +
+
+

+ Returns the number of elements in the array. If arrayName + isn’t the name of an array then 0 is returned. +

+
+
+array unset arrayName ?pattern? +
+
+

+ Unsets all of the elements in the array that match pattern + (using the matching rules of string match). If arrayName + isn’t the name of an array variable or there are no matching + elements in the array, no error will be raised. If pattern + is omitted and arrayName is an array variable, then the + command unsets the entire array. The command always returns + an empty string. +

+
+
+
+
+

break

+

break

+

This command may be invoked only inside the body of a loop command +such as for or foreach or while. It returns a JIM_BREAK code +to signal the innermost containing loop command to return immediately.

+
+
+

case

+

case string ?in? patList body ?patList body …?

+

case string ?in? {patList body ?patList body …?}

+

Note that the switch command should generally be preferred unless compatibility +with Tcl 6.x is desired.

+

Match string against each of the patList arguments +in order. If one matches, then evaluate the following body argument +by passing it recursively to the Tcl interpreter, and return the result +of that evaluation. Each patList argument consists of a single +pattern or list of patterns. Each pattern may contain any of the wild-cards +described under string match.

+

If a patList argument is default, the corresponding body will be +evaluated if no patList matches string. If no patList argument +matches string and no default is given, then the case command returns +an empty string.

+

Two syntaxes are provided.

+

The first uses a separate argument for each of the patterns and commands; +this form is convenient if substitutions are desired on some of the +patterns or commands.

+

The second form places all of the patterns and commands together into +a single argument; the argument must have proper list structure, with +the elements of the list being the patterns and commands.

+

The second form makes it easy to construct multi-line case commands, +since the braces around the whole list make it unnecessary to include a +backslash at the end of each line.

+

Since the patList arguments are in braces in the second form, +no command or variable substitutions are performed on them; this makes +the behaviour of the second form different than the first form in some +cases.

+

Below are some examples of case commands:

+
+
+
case abc in {a b} {format 1} default {format 2} a* {format 3}
+
+

will return 3,

+
+
+
case a in {
+    {a b} {format 1}
+    default {format 2}
+    a* {format 3}
+}
+
+

will return 1, and

+
+
+
case xyz {
+    {a b}
+        {format 1}
+    default
+        {format 2}
+    a*
+        {format 3}
+}
+
+

will return 2.

+
+
+

catch

+

catch ?-?no?code ...? ?--? command ?resultVarName? ?optionsVarName?

+

The catch command may be used to prevent errors from aborting +command interpretation. catch evaluates command, and returns a +JIM_OK code, regardless of any errors that might occur while +executing command (with the possible exception of JIM_SIGNAL - +see below).

+

The return value from catch is a decimal string giving the code +returned by the Tcl interpreter after executing command. This +will be 0 (JIM_OK) if there were no errors in command; otherwise +it will have a non-zero value corresponding to one of the exceptional +return codes (see jim.h for the definitions of code values, or the +info returncodes command).

+

If the resultVarName argument is given, then it gives the name +of a variable; catch will set the value of the variable to the +string returned from command (either a result or an error message).

+

If the optionsVarName argument is given, then it gives the name +of a variable; catch will set the value of the variable to a +dictionary. For any return code other than JIM_RETURN, the value +for the key -code will be set to the return code. For JIM_RETURN +it will be set to the code given in return -code. Additionally, +for the return code JIM_ERR, the value of the key -errorinfo +will contain the current stack trace (the same result as info stacktrace), +the value of the key -errorcode will contain the +same value as the global variable $::errorCode, and the value of +the key -level will be the current return level (see return -level). +This can be useful to rethrow an error:

+
+
+
if {[catch {...} msg opts]} {
+    ...maybe do something with the error...
+    incr opts(-level)
+    return {*}$opts $msg
+}
+
+

Normally catch will not catch any of the codes JIM_EXIT, JIM_EVAL or JIM_SIGNAL. +The set of codes which will be caught may be modified by specifying the one more codes before +command.

+

e.g. To catch JIM_EXIT but not JIM_BREAK or JIM_CONTINUE

+
+
+
catch -exit -nobreak -nocontinue -- { ... }
+
+

The use of -- is optional. It signifies that no more return code options follow.

+

Note that if a signal marked as signal handle is caught with catch -signal, the return value +(stored in resultVarName) is name of the signal caught.

+
+
+

cd

+

cd dirName

+

Change the current working directory to dirName.

+

Returns an empty string.

+

This command can potentially be disruptive to an application, so it may +be removed in some applications.

+
+
+

clock

+
+
+clock seconds +
+
+

+ Returns the current time as seconds since the epoch. +

+
+
+clock format seconds ?-format format? +
+
+

+ Format the given time (seconds since the epoch) according to the given + format. See strftime(3) for supported formats. + If no format is supplied, "%c" is used. +

+
+
+clock scan str -format format +
+
+

+ Scan the given time string using the given format string. + See strptime(3) for supported formats. +

+
+
+
+
+

close

+

close fileId

+

fileId close

+

Closes the file given by fileId. +fileId must be the return value from a previous invocation +of the open command; after this command, it should not be +used anymore.

+
+
+

collect

+

collect

+

Normally reference garbage collection is automatically performed periodically. +However it may be run immediately with the collect command.

+

See GARBAGE COLLECTION, REFERENCES, LAMBDA for more detail.

+
+
+

concat

+

concat arg ?arg ...?

+

This command treats each argument as a list and concatenates them +into a single list. It permits any number of arguments. For example, +the command

+
+
+
concat a b {c d e} {f {g h}}
+
+

will return

+
+
+
a b c d e f {g h}
+
+

as its result.

+
+
+

continue

+

continue

+

This command may be invoked only inside the body of a loop command such +as for or foreach or while. It returns a JIM_CONTINUE code to +signal the innermost containing loop command to skip the remainder of +the loop’s body but continue with the next iteration of the loop.

+
+
+

curry

+

alias args...

+

Similar to alias except it creates an anonymous procedure (lambda) instead of +a named procedure.

+

the following creates a local, unnamed alias for the command info exists.

+
+
+
set e [local curry info exists]
+if {[$e var]} {
+  ...
+}
+
+

curry returns the name of the procedure.

+

See also proc, alias, lambda, local.

+
+
+

dict

+

dict option ?arg...?

+

Performs one of several operations on dictionary values.

+

The option argument determines what action is carried out by the +command. The legal options are:

+
+
+dict create ?key value ...? +
+
+

+ Create and return a new dictionary value that contains each of + the key/value mappings listed as arguments (keys and values + alternating, with each key being followed by its associated + value.) +

+
+
+dict exists dictionary key ?key ...? +
+
+

+ Returns a boolean value indicating whether the given key (or path + of keys through a set of nested dictionaries) exists in the given + dictionary value. This returns a true value exactly when dict get + on that path will succeed. +

+
+
+dict get dictionary ?key ...? +
+
+

+ Given a dictionary value (first argument) and a key (second argument), + this will retrieve the value for that key. Where several keys are + supplied, the behaviour of the command shall be as if the result + of "dict get $dictVal $key" was passed as the first argument to + dict get with the remaining arguments as second (and possibly + subsequent) arguments. This facilitates lookups in nested dictionaries. + If no keys are provided, dict would return a list containing pairs + of elements in a man- ner similar to array get. That is, the first + element of each pair would be the key and the second element would + be the value for that key. It is an error to attempt to retrieve + a value for a key that is not present in the dictionary. +

+
+
+dict keys dictionary ?pattern? +
+
+

+ Returns a list of the keys in the dictionary. + If pattern is specified, then only those keys whose + names match pattern (using the matching rules of string + match) are included. +

+
+
+dict merge ?dictionary ...? +
+
+

+ Return a dictionary that contains the contents of each of the + dictionary arguments. Where two (or more) dictionaries + contain a mapping for the same key, the resulting dictionary + maps that key to the value according to the last dictionary on + the command line containing a mapping for that key. +

+
+
+dict set dictionaryName key ?key ...? value +
+
+

+ This operation takes the name of a variable containing a dictionary + value and places an updated dictionary value in that variable + containing a mapping from the given key to the given value. When + multiple keys are present, this operation creates or updates a chain + of nested dictionaries. +

+
+
+dict size dictionary +
+
+

+ Return the number of key/value mappings in the given dictionary value. +

+
+
+dict unset dictionaryName key ?key ...? value +
+
+

+ This operation (the companion to dict set) takes the name of a + variable containing a dictionary value and places an updated + dictionary value in that variable that does not contain a mapping + for the given key. Where multiple keys are present, this describes + a path through nested dictionaries to the mapping to remove. At + least one key must be specified, but the last key on the key-path + need not exist. All other components on the path must exist. +

+
+
+dict with dictionaryName key ?key ...? script +
+
+

+ Execute the Tcl script in script with the value for each + key in dictionaryName mapped to a variable with the same + name. Where one or more keys are given, these indicate a chain + of nested dictionaries, with the innermost dictionary being the + one opened out for the execution of body. Making dictionaryName + unreadable will make the updates to the dictionary be discarded, + and this also happens if the contents of dictionaryName are + adjusted so that the chain of dictionaries no longer exists. + The result of dict with is (unless some kind of error occurs) + the result of the evaluation of body. +

+
+
+ +
+
+

+ The variables are mapped in the scope enclosing the dict with; + it is recommended that this command only be used in a local + scope (procedure). Because of this, the variables set by + dict with will continue to exist after the command finishes (unless + explicitly unset). Note that changes to the contents of dictionaryName + only happen when script terminates. +

+
+
+
+
+

env

+

env ?name? ?default?

+

If name is supplied, returns the value of name from the initial +environment (see getenv(3)). An error is returned if name does not +exist in the environment, unless default is supplied - in which case +that value is returned instead.

+

If no arguments are supplied, returns a list of all environment variables +and their values as {name value ...}

+

See also the global variable ::env

+
+
+

eof

+

eof fileId

+

fileId eof

+

Returns 1 if an end-of-file condition has occurred on fileId, +0 otherwise.

+

fileId must have been the return value from a previous call to open, +or it may be stdin, stdout, or stderr to refer to one of the +standard I/O channels.

+
+
+

error

+

error message ?stacktrace?

+

Returns a JIM_ERR code, which causes command interpretation to be +unwound. message is a string that is returned to the application +to indicate what went wrong.

+

If the stacktrace argument is provided and is non-empty, +it is used to initialize the stacktrace.

+

This feature is most useful in conjunction with the catch command: +if a caught error cannot be handled successfully, stacktrace can be used +to return a stack trace reflecting the original point of occurrence +of the error:

+
+
+
catch {...} errMsg
+...
+error $errMsg [info stacktrace]
+
+

See also errorInfo, info stacktrace, catch and return

+
+
+

errorInfo

+

errorInfo error ?stacktrace?

+

Returns a human-readable representation of the given error message and stack trace. +Typical usage is:

+
+
+
if {[catch {...} error]} {
+    puts stderr [errorInfo $error [info stacktrace]]
+    exit 1
+}
+
+

See also error.

+
+
+

eval

+

eval arg ?arg...?

+

eval takes one or more arguments, which together comprise a Tcl +command (or collection of Tcl commands separated by newlines in the +usual way). eval concatenates all its arguments in the same +fashion as the concat command, passes the concatenated string to the +Tcl interpreter recursively, and returns the result of that +evaluation (or any error generated by it).

+
+
+

exec

+

exec arg ?arg...?

+

This command treats its arguments as the specification +of one or more UNIX commands to execute as subprocesses. +The commands take the form of a standard shell pipeline; +| arguments separate commands in the +pipeline and cause standard output of the preceding command +to be piped into standard input of the next command (or |& for +both standard output and standard error).

+

Under normal conditions the result of the exec command +consists of the standard output produced by the last command +in the pipeline.

+

If any of the commands in the pipeline exit abnormally or +are killed or suspended, then exec will return an error +and the error message will include the pipeline’s output followed by +error messages describing the abnormal terminations.

+

If any of the commands writes to its standard error file, +then exec will return an error, and the error message +will include the pipeline’s output, followed by messages +about abnormal terminations (if any), followed by the standard error +output.

+

If the last character of the result or error message +is a newline then that character is deleted from the result +or error message for consistency with normal +Tcl return values.

+

An arg may have one of the following special forms:

+
+
+>filename +
+
+

+ The standard output of the last command in the pipeline + is redirected to the file. In this situation exec + will normally return an empty string. +

+
+
+>>filename +
+
+

+ As above, but append to the file. +

+
+
+>@fileId +
+
+

+ The standard output of the last command in the pipeline is + redirected to the given (writable) file descriptor (e.g. stdout, + stderr, or the result of open). In this situation exec + will normally return an empty string. +

+
+
+2>filename +
+
+

+ The standard error of the last command in the pipeline + is redirected to the file. +

+
+
+2>>filename +
+
+

+ As above, but append to the file. +

+
+
+2>@fileId +
+
+

+ The standard error of the last command in the pipeline is + redirected to the given (writable) file descriptor. +

+
+
+2>@1 +
+
+

+ The standard error of the last command in the pipeline is + redirected to the same file descriptor as the standard output. +

+
+
+>&filename +
+
+

+ Both the standard output and standard error of the last command + in the pipeline is redirected to the file. +

+
+
+>>&filename +
+
+

+ As above, but append to the file. +

+
+
+<filename +
+
+

+ The standard input of the first command in the pipeline + is taken from the file. +

+
+
+<<string +
+
+

+ The standard input of the first command is taken as the + given immediate value. +

+
+
+<@fileId +
+
+

+ The standard input of the first command in the pipeline + is taken from the given (readable) file descriptor. +

+
+
+

If there is no redirection of standard input, standard error +or standard output, these are connected to the corresponding +input or output of the application.

+

If the last arg is & then the command will be +executed in background. +In this case the standard output from the last command +in the pipeline will +go to the application’s standard output unless +redirected in the command, and error output from all +the commands in the pipeline will go to the application’s +standard error file. The return value of exec in this case +is a list of process ids (pids) in the pipeline.

+

Each arg becomes one word for a command, except for +|, <, <<, >, and & arguments, and the +arguments that follow <, <<, and >.

+

The first word in each command is taken as the command name; +the directories in the PATH environment variable are searched for +an executable by the given name.

+

No glob expansion or other shell-like substitutions +are performed on the arguments to commands.

+

If the command fails, the global $::errorCode (and the -errorcode +option in catch) will be set to a list, as follows:

+
+
+CHILDKILLED pid sigName msg +
+
+

+ This format is used when a child process has been killed + because of a signal. The pid element will be the process’s + identifier (in decimal). The sigName element will be the + symbolic name of the signal that caused the process to + terminate; it will be one of the names from the include + file signal.h, such as SIGPIPE. The msg element will be a + short human-readable message describing the signal, such + as "write on pipe with no readers" for SIGPIPE. +

+
+
+CHILDSUSP pid sigName msg +
+
+

+ This format is used when a child process has been suspended + because of a signal. The pid element will be the process’s + identifier, in decimal. The sigName element will be the + symbolic name of the signal that caused the process to + suspend; this will be one of the names from the include + file signal.h, such as SIGTTIN. The msg element will be a + short human-readable message describing the signal, such + as "background tty read" for SIGTTIN. +

+
+
+CHILDSTATUS pid code +
+
+

+ This format is used when a child process has exited with a + non-zero exit status. The pid element will be the process’s + identifier (in decimal) and the code element will be the + exit code returned by the process (also in decimal). +

+
+
+

The environment for the executed command is set from $::env (unless +this variable is unset, in which case the original environment is used).

+
+
+

exists

+

exists ?-var|-proc|-command|-alias? name

+

Checks the existence of the given variable, procedure, command +or alias respectively and returns 1 if it exists or 0 if not. This command +provides a more simplified/convenient version of info exists, +info procs and info commands.

+

If the type is omitted, a type of -var is used. The type may be abbreviated.

+
+
+

exit

+

exit ?returnCode?

+

Terminate the process, returning returnCode to the +parent as the exit status.

+

If returnCode isn’t specified then it defaults +to 0.

+

Note that exit can be caught with catch.

+
+
+

expr

+

expr arg

+

Calls the expression processor to evaluate arg, and returns +the result as a string. See the section EXPRESSIONS above.

+

Note that Jim supports a shorthand syntax for expr as $(...) +The following two are identical.

+
+
+
set x [expr {3 * 2 + 1}]
+set x $(3 * 2 + 1)
+
+
+
+

file

+

file option name ?arg...?

+

Operate on a file or a file name. name is the name of a file.

+

option indicates what to do with the file name. Any unique +abbreviation for option is acceptable. The valid options are:

+
+
+file atime name +
+
+

+ Return a decimal string giving the time at which file name + was last accessed. The time is measured in the standard UNIX + fashion as seconds from a fixed starting time (often January 1, 1970). + If the file doesn’t exist or its access time cannot be queried then an + error is generated. +

+
+
+file copy ?-force? source target +
+
+

+ Copies file source to file target. The source file must exist. + The target file must not exist, unless -force is specified. +

+
+
+file delete ?-force? name... +
+
+

+ Deletes file or directory name. If the file or directory doesn’t exist, nothing happens. + If it can’t be deleted, an error is generated. Non-empty directories will not be deleted + unless the -force options is given. In this case no errors will be generated, even + if the file/directory can’t be deleted. +

+
+
+file dirname name +
+
+

+ Return all of the characters in name up to but not including + the last slash character. If there are no slashes in name + then return . (a single dot). If the last slash in name is its first + character, then return /. +

+
+
+file executable name +
+
+

+ Return 1 if file name is executable by + the current user, 0 otherwise. +

+
+
+file exists name +
+
+

+ Return 1 if file name exists and the current user has + search privileges for the directories leading to it, 0 otherwise. +

+
+
+file extension name +
+
+

+ Return all of the characters in name after and including the + last dot in name. If there is no dot in name then return + the empty string. +

+
+
+file isdirectory name +
+
+

+ Return 1 if file name is a directory, + 0 otherwise. +

+
+
+file isfile name +
+
+

+ Return 1 if file name is a regular file, + 0 otherwise. +

+
+
+file join arg... +
+
+

+ Joins multiple path components. Note that if any components is + an absolute path, the preceding components are ignored. + Thus "file join /tmp /root" returns "/root". +

+
+
+file lstat name varName +
+
+

+ Same as stat option (see below) except uses the lstat + kernel call instead of stat. This means that if name + refers to a symbolic link the information returned in varName + is for the link rather than the file it refers to. On systems that + don’t support symbolic links this option behaves exactly the same + as the stat option. +

+
+
+file mkdir dir1 ?dir2...? +
+
+

+ Creates each directory specified. For each pathname dir specified, + this command will create all non-existing parent directories + as well as dir itself. If an existing directory is specified, + then no action is taken and no error is returned. Trying to + overwrite an existing file with a directory will result in an + error. Arguments are processed in the order specified, halting + at the first error, if any. +

+
+
+file mtime name ?time? +
+
+

+ Return a decimal string giving the time at which file name + was last modified. The time is measured in the standard UNIX + fashion as seconds from a fixed starting time (often January 1, 1970). + If the file doesn’t exist or its modified time cannot be queried then an + error is generated. If time is given, sets the modification time + of the file to the given value. +

+
+
+file normalize name +
+
+

+ Return the normalized path of name. See realpath(3). +

+
+
+file owned name +
+
+

+ Return 1 if file name is owned by the current user, + 0 otherwise. +

+
+
+file readable name +
+
+

+ Return 1 if file name is readable by + the current user, 0 otherwise. +

+
+
+file readlink name +
+
+

+ Returns the value of the symbolic link given by name (i.e. the + name of the file it points to). If + name isn’t a symbolic link or its value cannot be read, then + an error is returned. On systems that don’t support symbolic links + this option is undefined. +

+
+
+file rename oldname newname +
+
+

+ Renames the file from the old name to the new name. +

+
+
+file rootname name +
+
+

+ Return all of the characters in name up to but not including + the last . character in the name. If name doesn’t contain + a dot, then return name. +

+
+
+file size name +
+
+

+ Return a decimal string giving the size of file name in bytes. + If the file doesn’t exist or its size cannot be queried then an + error is generated. +

+
+
+file stat name varName +
+
+

+ Invoke the stat kernel call on name, and use the + variable given by varName to hold information returned from + the kernel call. + varName is treated as an array variable, + and the following elements of that variable are set: atime, + ctime, dev, gid, ino, mode, mtime, + nlink, size, type, uid. + Each element except type is a decimal string with the value of + the corresponding field from the stat return structure; see the + manual entry for stat for details on the meanings of the values. + The type element gives the type of the file in the same form + returned by the command file type. + This command returns an empty string. +

+
+
+file tail name +
+
+

+ Return all of the characters in name after the last slash. + If name contains no slashes then return name. +

+
+
+file tempfile ?template? +
+
+

+ Creates and returns the name of a unique temporary file. If template is omitted, a + default template will be used to place the file in /tmp. See mkstemp(3) for + the format of the template and security concerns. +

+
+
+file type name +
+
+

+ Returns a string giving the type of file name, which will be + one of file, directory, characterSpecial, + blockSpecial, fifo, link, or socket. +

+
+
+file writable name +
+
+

+ Return 1 if file name is writable by + the current user, 0 otherwise. +

+
+
+

The file commands that return 0/1 results are often used in +conditional or looping commands, for example:

+
+
+
if {![file exists foo]} {
+    error {bad file name}
+} else {
+    ...
+}
+
+
+
+

finalize

+

finalize reference ?command?

+

If command is omitted, returns the finalizer command for the given reference.

+

Otherwise, sets a new finalizer command for the given reference. command may be +the empty string to remove the current finalizer.

+

The reference must be a valid reference create with the ref +command.

+

See GARBAGE COLLECTION, REFERENCES, LAMBDA for more detail.

+
+
+

flush

+

flush fileId

+

fileId flush

+

Flushes any output that has been buffered for fileId. fileId must +have been the return value from a previous call to open, or it may be +stdout or stderr to access one of the standard I/O streams; it must +refer to a file that was opened for writing. This command returns an +empty string.

+
+
+

for

+

for start test next body

+

for is a looping command, similar in structure to the C for statement. +The start, next, and body arguments must be Tcl command strings, +and test is an expression string.

+

The for command first invokes the Tcl interpreter to execute start. +Then it repeatedly evaluates test as an expression; if the result is +non-zero it invokes the Tcl interpreter on body, then invokes the Tcl +interpreter on next, then repeats the loop. The command terminates +when test evaluates to 0.

+

If a continue command is invoked within body then any remaining +commands in the current execution of body are skipped; processing +continues by invoking the Tcl interpreter on next, then evaluating +test, and so on.

+

If a break command is invoked within body or next, then the for +command will return immediately.

+

The operation of break and continue are similar to the corresponding +statements in C.

+

for returns an empty string.

+
+
+

foreach

+

foreach varName list body

+

foreach varList list ?varList2 list2 ...? body

+

In this command, varName is the name of a variable, list +is a list of values to assign to varName, and body is a +collection of Tcl commands.

+

For each field in list (in order from left to right), foreach assigns +the contents of the field to varName (as if the lindex command +had been used to extract the field), then calls the Tcl interpreter to +execute body.

+

If instead of being a simple name, varList is used, multiple assignments +are made each time through the loop, one for each element of varList.

+

For example, if there are two elements in varList and six elements in +the list, the loop will be executed three times.

+

If the length of the list doesn’t evenly divide by the number of elements +in varList, the value of the remaining variables in the last iteration +of the loop are undefined.

+

The break and continue statements may be invoked inside body, +with the same effect as in the for command.

+

foreach returns an empty string.

+
+
+

format

+

format formatString ?arg ...?

+

This command generates a formatted string in the same way as the +C sprintf procedure (it uses sprintf in its +implementation). formatString indicates how to format +the result, using % fields as in sprintf, and the additional +arguments, if any, provide values to be substituted into the result.

+

All of the sprintf options are valid; see the sprintf +man page for details. Each arg must match the expected type +from the % field in formatString; the format command +converts each argument to the correct type (floating, integer, etc.) +before passing it to sprintf for formatting.

+

The only unusual conversion is for %c; in this case the argument +must be a decimal string, which will then be converted to the corresponding +ASCII character value.

+

format does backslash substitution on its formatString +argument, so backslash sequences in formatString will be handled +correctly even if the argument is in braces.

+

The return value from format is the formatted string.

+
+
+

getref

+

getref reference

+

Returns the string associated with reference. The reference must +be a valid reference create with the ref command.

+

See GARBAGE COLLECTION, REFERENCES, LAMBDA for more detail.

+
+
+

gets

+

gets fileId ?varName?

+

fileId gets ?varName?

+

Reads the next line from the file given by fileId and discards +the terminating newline character.

+

If varName is specified, then the line is placed in the variable +by that name and the return value is a count of the number of characters +read (not including the newline).

+

If the end of the file is reached before reading +any characters then -1 is returned and varName is set to an +empty string.

+

If varName is not specified then the return value will be +the line (minus the newline character) or an empty string if +the end of the file is reached before reading any characters.

+

An empty string will also be returned if a line contains no characters +except the newline, so eof may have to be used to determine +what really happened.

+

If the last character in the file is not a newline character, then +gets behaves as if there were an additional newline character +at the end of the file.

+

fileId must be stdin or the return value from a previous +call to open; it must refer to a file that was opened +for reading.

+
+
+

glob

+

glob ?-nocomplain? pattern ?pattern ...?

+

This command performs filename globbing, using csh rules. The returned +value from glob is the list of expanded filenames.

+

If -nocomplain is specified as the first argument then an empty +list may be returned; otherwise an error is returned if the expanded +list is empty. The -nocomplain argument must be provided +exactly: an abbreviation will not be accepted.

+
+
+

global

+

global varName ?varName ...?

+

This command is ignored unless a Tcl procedure is being interpreted. +If so, then it declares each given varName to be a global variable +rather than a local one. For the duration of the current procedure +(and only while executing in the current procedure), any reference to +varName will be bound to a global variable instead +of a local one.

+

An alternative to using global is to use the :: prefix +to explicitly name a variable in the global scope.

+
+
+

if

+

if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?

+

The if command evaluates expr1 as an expression (in the same way +that expr evaluates its argument). The value of the expression must +be numeric; if it is non-zero then body1 is executed by passing it to +the Tcl interpreter.

+

Otherwise expr2 is evaluated as an expression and if it is non-zero +then body2 is executed, and so on.

+

If none of the expressions evaluates to non-zero then bodyN is executed.

+

The then and else arguments are optional "noise words" to make the +command easier to read.

+

There may be any number of elseif clauses, including zero. bodyN +may also be omitted as long as else is omitted too.

+

The return value from the command is the result of the body script that +was executed, or an empty string if none of the expressions was non-zero +and there was no bodyN.

+
+
+

incr

+

incr varName ?increment?

+

Increment the value stored in the variable whose name is varName. +The value of the variable must be integral.

+

If increment is supplied then its value (which must be an +integer) is added to the value of variable varName; otherwise +1 is added to varName.

+

The new value is stored as a decimal string in variable varName +and also returned as result.

+

If the variable does not exist, the variable is implicitly created +and set to 0 first.

+
+
+

info

+
+
+info option ?arg...? +
+
+

+Provide information about various internals to the Tcl interpreter. +The legal option's (which may be abbreviated) are: +

+
+
+info args procname +
+
+

+ Returns a list containing the names of the arguments to procedure + procname, in order. procname must be the name of a + Tcl command procedure. +

+
+
+info alias command +
+
+

+ command must be an alias created with alias. In which case the target + command and arguments, as passed to alias are returned. See exists -alias +

+
+
+info body procname +
+
+

+ Returns the body of procedure procname. procname must be + the name of a Tcl command procedure. +

+
+
+info channels +
+
+

+ Returns a list of all open file handles from open or socket +

+
+
+info commands ?pattern? +
+
+

+ If pattern isn’t specified, returns a list of names of all the + Tcl commands, including both the built-in commands written in C and + the command procedures defined using the proc command. + If pattern is specified, only those names matching pattern + are returned. Matching is determined using the same rules as for + string match. +

+
+
+info complete command ?missing? +
+
+

+ Returns 1 if command is a complete Tcl command in the sense of + having no unclosed quotes, braces, brackets or array element names, + If the command doesn’t appear to be complete then 0 is returned. + This command is typically used in line-oriented input environments + to allow users to type in commands that span multiple lines; if the + command isn’t complete, the script can delay evaluating it until additional + lines have been typed to complete the command. If varName is specified, the + missing character is stored in the variable with that name. +

+
+
+info exists varName +
+
+

+ Returns 1 if the variable named varName exists in the + current context (either as a global or local variable), returns 0 + otherwise. +

+
+
+info frame ?number? +
+
+

+ If number is not specified, this command returns a number + which is the same result as info level - the current stack frame level. + If number is specified, then the result is a list consisting of the procedure, + filename and line number for the procedure call at level number on the stack. + If number is positive then it selects a particular stack level (1 refers + to the top-most active procedure, 2 to the procedure it called, and + so on); otherwise it gives a level relative to the current level + (0 refers to the current procedure, -1 to its caller, and so on). + The level has an identical meaning to info level. +

+
+
+info globals ?pattern? +
+
+

+ If pattern isn’t specified, returns a list of all the names + of currently-defined global variables. + If pattern is specified, only those names matching pattern + are returned. Matching is determined using the same rules as for + string match. +

+
+
+info hostname +
+
+

+ An alias for os.gethostname for compatibility with Tcl 6.x +

+
+
+info level ?number? +
+
+

+ If number is not specified, this command returns a number + giving the stack level of the invoking procedure, or 0 if the + command is invoked at top-level. If number is specified, + then the result is a list consisting of the name and arguments for the + procedure call at level number on the stack. If number + is positive then it selects a particular stack level (1 refers + to the top-most active procedure, 2 to the procedure it called, and + so on); otherwise it gives a level relative to the current level + (0 refers to the current procedure, -1 to its caller, and so on). + See the uplevel command for more information on what stack + levels mean. +

+
+
+info locals ?pattern? +
+
+

+ If pattern isn’t specified, returns a list of all the names + of currently-defined local variables, including arguments to the + current procedure, if any. Variables defined with the global + and upvar commands will not be returned. If pattern is + specified, only those names matching pattern are returned. + Matching is determined using the same rules as for string match. +

+
+
+info nameofexecutable +
+
+

+ Returns the name of the binary file from which the application + was invoked. A full path will be returned, unless the path + can’t be determined, in which case the empty string will be returned. +

+
+
+info procs ?pattern? +
+
+

+ If pattern isn’t specified, returns a list of all the + names of Tcl command procedures. + If pattern is specified, only those names matching pattern + are returned. Matching is determined using the same rules as for + string match. +

+
+
+info references +
+
+

+ Returns a list of all references which have not yet been garbage + collected. +

+
+
+info returncodes ?code? +
+
+

+ Returns a list representing the mapping of standard return codes + to names. e.g. {0 ok 1 error 2 return ...}. If a code is given, + instead returns the name for the given code. +

+
+
+info script +
+
+

+ If a Tcl script file is currently being evaluated (i.e. there is a + call to Jim_EvalFile active or there is an active invocation + of the source command), then this command returns the name + of the innermost file being processed. Otherwise the command returns an + empty string. +

+
+
+info source script +
+
+

+ Returns the original source location of the given script as a list of + {filename linenumber}. If the source location can’t be determined, the + list {{} 0} is returned. +

+
+
+info stacktrace +
+
+

+ After an error is caught with catch, returns the stack trace as a list + of {procedure filename line ...}. +

+
+
+info statics procname +
+
+

+ Returns a dictionary of the static variables of procedure + procname. procname must be the name of a Tcl command + procedure. An empty dictionary is returned if the procedure has + no static variables. +

+
+
+info version +
+
+

+ Returns the version number for this version of Jim in the form x.yy. +

+
+
+info vars ?pattern? +
+
+

+ If pattern isn’t specified, + returns a list of all the names of currently-visible variables, including + both locals and currently-visible globals. + If pattern is specified, only those names matching pattern + are returned. Matching is determined using the same rules as for + string match. +

+
+
+
+
+

join

+

join list ?joinString?

+

The list argument must be a valid Tcl list. This command returns the +string formed by joining all of the elements of list together with +joinString separating each adjacent pair of elements.

+

The joinString argument defaults to a space character.

+
+
+

kill

+

kill ?SIG|-0? pid

+

Sends the given signal to the process identified by pid.

+

The signal may be specified by name or number in one of the following forms:

+
    +
  • +

    +TERM +

    +
  • +
  • +

    +SIGTERM +

    +
  • +
  • +

    +-TERM +

    +
  • +
  • +

    +15 +

    +
  • +
  • +

    +-15 +

    +
  • +
+

The signal name may be in either upper or lower case.

+

The special signal name -0 simply checks that a signal could be sent.

+

If no signal is specified, SIGTERM is used.

+

An error is raised if the signal could not be delivered.

+
+
+

lambda

+

lambda args ?statics? body

+

The lambda command is identical to proc, except rather than +creating a named procedure, it creates an anonymous procedure and returns +the name of the procedure.

+

See proc and GARBAGE COLLECTION, REFERENCES, LAMBDA for more detail.

+
+
+

lappend

+

lappend varName value ?value value ...?

+

Treat the variable given by varName as a list and append each of +the value arguments to that list as a separate element, with spaces +between elements.

+

If varName doesn’t exist, it is created as a list with elements given +by the value arguments. lappend is similar to append except that +each value is appended as a list element rather than raw text.

+

This command provides a relatively efficient way to build up large lists. +For example,

+
+
+
lappend a $b
+
+

is much more efficient than

+
+
+
set a [concat $a [list $b]]
+
+

when $a is long.

+
+
+

lassign

+

lassign list varName ?varName ...?

+

This command treats the value list as a list and assigns successive elements from that list to +the variables given by the varName arguments in order. If there are more variable names than +list elements, the remaining variables are set to the empty string. If there are more list ele- +ments than variables, a list of unassigned elements is returned.

+
+
+
jim> lassign {1 2 3} a b; puts a=$a,b=$b
+3
+a=1,b=2
+
+
+
+

local

+

local cmd ?arg...?

+

First, local evaluates cmd with the given arguments. The return value must +be the name of an existing command, which is marked as having local scope. +This means that when the current procedure exits, the specified +command is deleted. This can be useful with lambda, local procedures or +to automatically close a filehandle.

+

In addition, if a command already exists with the same name, +the existing command will be kept rather than deleted, and may be called +via upcall. The previous command will be restored when the current +procedure exits. See upcall for more details.

+

In this example, a local procedure is created. Note that the procedure +continues to have global scope while it is active.

+
+
+
proc outer {} {
+  # proc ... returns "inner" which is marked local
+  local proc inner {} {
+    # will be deleted when 'outer' exits
+  }
+
+
+
+
  inner
+  ...
+}
+
+

In this example, the lambda is deleted at the end of the procedure rather +than waiting until garbage collection.

+
+
+
proc outer {} {
+  set x [lambda inner {args} {
+    # will be deleted when 'outer' exits
+  }]
+  # Use 'function' here which simply returns $x
+  local function $x
+
+
+
+
  $x ...
+  ...
+}
+
+
+
+

loop

+

loop var first limit ?incr? body

+

Similar to for except simpler and possibly more efficient. +With a positive increment, equivalent to:

+
+
+
for {set var $first} {$var < $limit} {incr var $incr} $body
+
+

If incr is not specified, 1 is used. +Note that setting the loop variable inside the loop does not +affect the loop count.

+
+
+

lindex

+

lindex list index

+

Treats list as a Tcl list and returns element index from it +(0 refers to the first element of the list). +See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for index.

+

In extracting the element, lindex observes the same rules concerning +braces and quotes and backslashes as the Tcl command interpreter; however, +variable substitution and command substitution do not occur.

+

If index is negative or greater than or equal to the number of elements +in value, then an empty string is returned.

+
+
+

linsert

+

linsert list index element ?element element ...?

+

This command produces a new list from list by inserting all +of the element arguments just before the element index +of list. Each element argument will become +a separate element of the new list. If index is less than +or equal to zero, then the new elements are inserted at the +beginning of the list. If index is greater than or equal +to the number of elements in the list, then the new elements are +appended to the list.

+

See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for index.

+
+
+

list

+

list arg ?arg ...?

+

This command returns a list comprised of all the arguments, arg. Braces +and backslashes get added as necessary, so that the lindex command +may be used on the result to re-extract the original arguments, and also +so that eval may be used to execute the resulting list, with +arg1 comprising the command’s name and the other args comprising +its arguments. list produces slightly different results than +concat: concat removes one level of grouping before forming +the list, while list works directly from the original arguments. +For example, the command

+
+
+
list a b {c d e} {f {g h}}
+
+

will return

+
+
+
a b {c d e} {f {g h}}
+
+

while concat with the same arguments will return

+
+
+
a b c d e f {g h}
+
+
+
+

llength

+

llength list

+

Treats list as a list and returns a decimal string giving +the number of elements in it.

+
+
+

lset

+

lset varName ?index ..? newValue

+

Sets an element in a list.

+

The lset command accepts a parameter, varName, which it interprets +as the name of a variable containing a Tcl list. It also accepts +zero or more indices into the list. Finally, it accepts a new value +for an element of varName. If no indices are presented, the command +takes the form:

+
+
+
lset varName newValue
+
+

In this case, newValue replaces the old value of the variable +varName.

+

When presented with a single index, the lset command +treats the content of the varName variable as a Tcl list. It addresses +the index’th element in it (0 refers to the first element of the +list). When interpreting the list, lset observes the same rules +concerning braces and quotes and backslashes as the Tcl command +interpreter; however, variable substitution and command substitution +do not occur. The command constructs a new list in which the +designated element is replaced with newValue. This new list is +stored in the variable varName, and is also the return value from +the lset command.

+

If index is negative or greater than or equal to the number of +elements in $varName, then an error occurs.

+

See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for index.

+

If additional index arguments are supplied, then each argument is +used in turn to address an element within a sublist designated by +the previous indexing operation, allowing the script to alter +elements in sublists. The command,

+
+
+
lset a 1 2 newValue
+
+

replaces element 2 of sublist 1 with newValue.

+

The integer appearing in each index argument must be greater than +or equal to zero. The integer appearing in each index argument must +be strictly less than the length of the corresponding list. In other +words, the lset command cannot change the size of a list. If an +index is outside the permitted range, an error is reported.

+
+
+

lmap

+

lmap varName list body

+

lmap varList list ?varList2 list2 ...? body

+

lmap is a "collecting" foreach which returns a list of its results.

+

For example:

+
+
+
jim> lmap i {1 2 3 4 5} {expr $i*$i}
+1 4 9 16 25
+jim> lmap a {1 2 3} b {A B C} {list $a $b}
+{1 A} {2 B} {3 C}
+
+

If the body invokes continue, no value is added for this iteration. +If the body invokes break, the loop ends and no more values are added.

+
+
+

load

+

load filename

+

Loads the dynamic extension, filename. Generally the filename should have +the extension .so. The initialisation function for the module must be based +on the name of the file. For example loading hwaccess.so will invoke +the initialisation function, Jim_hwaccessInit. Normally the load command +should not be used directly. Instead it is invoked automatically by package require.

+
+
+

lrange

+

lrange list first last

+

list must be a valid Tcl list. This command will return a new +list consisting of elements first through last, inclusive.

+

See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for first and last.

+

If last is greater than or equal to the number of elements +in the list, then it is treated as if it were end.

+

If first is greater than last then an empty string +is returned.

+

Note: "lrange list first first" does not always produce the +same result as "lindex list first" (although it often does +for simple fields that aren’t enclosed in braces); it does, however, +produce exactly the same results as "list [lindex list first]"

+
+
+

lreplace

+

lreplace list first last ?element element ...?

+

Returns a new list formed by replacing one or more elements of +list with the element arguments.

+

first gives the index in list of the first element +to be replaced.

+

If first is less than zero then it refers to the first +element of list; the element indicated by first +must exist in the list.

+

last gives the index in list of the last element +to be replaced; it must be greater than or equal to first.

+

See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for first and last.

+

The element arguments specify zero or more new arguments to +be added to the list in place of those that were deleted.

+

Each element argument will become a separate element of +the list.

+

If no element arguments are specified, then the elements +between first and last are simply deleted.

+
+
+

lrepeat

+

lrepeat number element1 ?element2 ...?

+

Build a list by repeating elements number times (which must be +a positive integer).

+
+
+
jim> lrepeat 3 a b
+a b a b a b
+
+
+
+

lreverse

+

lreverse list

+

Returns the list in reverse order.

+
+
+
jim> lreverse {1 2 3}
+3 2 1
+
+
+
+

lsearch

+

lsearch ?options? list pattern

+

This command searches the elements list to see if one of them matches pattern. If so, the +command returns the index of the first matching element (unless the options -all, -inline or -bool are +specified.) If not, the command returns -1. The option arguments indicates how the elements of +the list are to be matched against pattern and must have one of the values below:

+

Note that this command is different from Tcl in that default match type is -exact rather than -glob.

+
+
+-exact +
+
+

+ pattern is a literal string that is compared for exact equality against each list element. + This is the default. +

+
+
+-glob +
+
+

+ pattern is a glob-style pattern which is matched against each list element using the same + rules as the string match command. +

+
+
+-regexp +
+
+

+ pattern is treated as a regular expression and matched against each list element using + the rules described by regexp. +

+
+
+-command cmdname +
+
+

+ cmdname is a command which is used to match the pattern against each element of the + list. It is invoked as cmdname ?-nocase? pattern listvalue and should return 1 + for a match, or 0 for no match. +

+
+
+-all +
+
+

+ Changes the result to be the list of all matching indices (or all matching values if + -inline is specified as well). If indices are returned, the indices will be in numeric + order. If values are returned, the order of the values will be the order of those values + within the input list. +

+
+
+-inline +
+
+

+ The matching value is returned instead of its index (or an empty string if no value + matches). If -all is also specified, then the result of the command is the list of all + values that matched. The -inline and -bool options are mutually exclusive. +

+
+
+-bool +
+
+

+ Changes the result to 1 if a match was found, or 0 otherwise. If -all is also specified, + the result will be a list of 0 and 1 for each element of the list depending upon whether + the corresponding element matches. The -inline and -bool options are mutually exclusive. +

+
+
+-not +
+
+

+ This negates the sense of the match, returning the index (or value + if -inline is specified) of the first non-matching value in the + list. If -bool is also specified, the 0 will be returned if a + match is found, or 1 otherwise. If -all is also specified, + non-matches will be returned rather than matches. +

+
+
+-nocase +
+
+

+ Causes comparisons to be handled in a case-insensitive manner. +

+
+
+
+
+

lsort

+

lsort ?-index listindex? ?-integer|-command cmdname? ?-decreasing|-increasing? list

+

Sort the elements of list, returning a new list in sorted order. +By default, ASCII sorting is used, with the result in increasing order.

+

If -integer is specified, numeric sorting is used.

+

If -command cmdname is specified, cmdname is treated as a command +name. For each comparison, cmdname $value1 $value2 is called which +should compare the values and return an integer less than, equal +to, or greater than zero if the $value1 is to be considered less +than, equal to, or greater than $value2, respectively.

+

If -decreasing is specified, the resulting list is in the opposite +order to what it would be otherwise. -increasing is the default.

+

If -index listindex is specified, each element of the list is treated as a list and +the given index is extracted from the list for comparison. The list index may +be any valid list index, such as 1, end or end-2.

+

If -index listindex is specified, each element of the list is treated as a list and +the given index is extracted from the list for comparison. The list index may +be any valid list index, such as 1, end or end-2.

+
+
+

open

+

open fileName ?access?

+

open |command-pipeline ?access?

+

Opens a file and returns an identifier +that may be used in future invocations +of commands like read, puts, and close. +fileName gives the name of the file to open.

+

The access argument indicates the way in which the file is to be accessed. +It may have any of the following values:

+
+
+r +
+
+

+ Open the file for reading only; the file must already exist. +

+
+
+r+ +
+
+

+ Open the file for both reading and writing; the file must + already exist. +

+
+
+w +
+
+

+ Open the file for writing only. Truncate it if it exists. If it doesn’t + exist, create a new file. +

+
+
+w+ +
+
+

+ Open the file for reading and writing. Truncate it if it exists. + If it doesn’t exist, create a new file. +

+
+
+a +
+
+

+ Open the file for writing only. The file must already exist, and the file + is positioned so that new data is appended to the file. +

+
+
+a+ +
+
+

+ Open the file for reading and writing. If the file doesn’t + exist, create a new empty file. Set the initial access position + to the end of the file. +

+
+
+

access defaults to r.

+

If a file is opened for both reading and writing, then seek +must be invoked between a read and a write, or vice versa.

+

If the first character of fileName is "|" then the remaining +characters of fileName are treated as a list of arguments that +describe a command pipeline to invoke, in the same style as the +arguments for exec. In this case, the channel identifier returned +by open may be used to write to the command’s input pipe or read +from its output pipe, depending on the value of access. If write-only +access is used (e.g. access is w), then standard output for the +pipeline is directed to the current standard output unless overridden +by the command. If read-only access is used (e.g. access is r), +standard input for the pipeline is taken from the current standard +input unless overridden by the command.

+

The pid command may be used to return the process ids of the commands +forming the command pipeline.

+

See also socket, pid, exec

+
+
+

package

+

package provide name ?version?

+

Indicates that the current script provides the package named name. +If no version is specified, 1.0 is used.

+

Any script which provides a package may include this statement +as the first statement, although it is not required.

+

package require name ?version?*

+

Searches for the package with the given name by examining each path +in $::auto_path and trying to load $path/$name.so as a dynamic extension, +or $path/$name.tcl as a script package.

+

The first such file which is found is considered to provide the the package. +(The version number is ignored).

+

If $name.so exists, it is loaded with the load command, +otherwise if $name.tcl exists it is loaded with the source command.

+

If load or source fails, package require will fail immediately. +No further attempt will be made to locate the file.

+
+
+

pid

+

pid

+

pid fileId

+

The first form returns the process identifier of the current process.

+

The second form accepts a handle returned by open and returns a list +of the process ids forming the pipeline in the same form as exec ... &. +If fileId represents a regular file handle rather than a command pipeline, +the empty string is returned instead.

+

See also open, exec

+
+
+

proc

+

proc name args ?statics? body

+

The proc command creates a new Tcl command procedure, name. +When the new command is invoked, the contents of body will be executed. +Tcl interpreter. args specifies the formal arguments to the procedure. +If specified, static, declares static variables which are bound to the +procedure.

+

See PROCEDURES for detailed information about Tcl procedures.

+

The proc command returns name (which is useful with local).

+

When a procedure is invoked, the procedure’s return value is the +value specified in a return command. If the procedure doesn’t +execute an explicit return, then its return value is the value +of the last command executed in the procedure’s body.

+

If an error occurs while executing the procedure body, then the +procedure-as-a-whole will return that same error.

+
+
+

puts

+

puts ?-nonewline? ?fileId? string

+

fileId puts ?-nonewline? string

+

Writes the characters given by string to the file given +by fileId. fileId must have been the return +value from a previous call to open, or it may be +stdout or stderr to refer to one of the standard I/O +channels; it must refer to a file that was opened for +writing.

+

In the first form, if no fileId is specified then it defaults to stdout. +puts normally outputs a newline character after string, +but this feature may be suppressed by specifying the -nonewline +switch.

+

Output to files is buffered internally by Tcl; the flush +command may be used to force buffered characters to be output.

+
+
+

pwd

+

pwd

+

Returns the path name of the current working directory.

+
+
+

rand

+

rand ?min? ?max?

+

Returns a random integer between min (defaults to 0) and max +(defaults to the maximum integer).

+

If only one argument is given, it is interpreted as max.

+
+
+

range

+

range ?start? end ?step?

+

Returns a list of integers starting at start (defaults to 0) +and ranging up to but not including end in steps of step defaults to 1).

+
+
+
jim> range 5
+0 1 2 3 4
+jim> range 2 5
+2 3 4
+jim> range 2 10 4
+2 6
+jim> range 7 4 -2
+7 5
+
+
+
+

read

+

read ?-nonewline? fileId

+

fileId read ?-nonewline?

+

read fileId numBytes

+

fileId read numBytes

+

In the first form, all of the remaining bytes are read from the file +given by fileId; they are returned as the result of the command. +If the -nonewline switch is specified then the last +character of the file is discarded if it is a newline.

+

In the second form, the extra argument specifies how many bytes to read; +exactly this many bytes will be read and returned, unless there are fewer than +numBytes bytes left in the file; in this case, all the remaining +bytes are returned.

+

fileId must be stdin or the return value from a previous call +to open; it must refer to a file that was opened for reading.

+
+
+

regexp

+

regexp ?-nocase? ?-line? ?-indices? ?-start offset? ?-all? ?-inline? ?--? exp string ?matchVar? ?subMatchVar subMatchVar ...?

+

Determines whether the regular expression exp matches part or +all of string and returns 1 if it does, 0 if it doesn’t.

+

See REGULAR EXPRESSIONS above for complete information on the +syntax of exp and how it is matched against string.

+

If additional arguments are specified after string then they +are treated as the names of variables to use to return +information about which part(s) of string matched exp. +matchVar will be set to the range of string that +matched all of exp. The first subMatchVar will contain +the characters in string that matched the leftmost parenthesized +subexpression within exp, the next subMatchVar will +contain the characters that matched the next parenthesized +subexpression to the right in exp, and so on.

+

Normally, matchVar and the each subMatchVar are set to hold the +matching characters from string, however see -indices and +-inline below.

+

If there are more values for subMatchVar than parenthesized subexpressions +within exp, or if a particular subexpression in exp doesn’t +match the string (e.g. because it was in a portion of the expression +that wasn’t matched), then the corresponding subMatchVar will be +set to "-1 -1" if -indices has been specified or to an empty +string otherwise.

+

The following switches modify the behaviour of regexp

+
+
+-nocase +
+
+

+ Causes upper-case and lower-case characters to be treated as + identical during the matching process. +

+
+
+-line +
+
+

+ Use newline-sensitive matching. By default, newline + is a completely ordinary character with no special meaning in + either REs or strings. With this flag, [ bracket expressions + and . never match newline, a anchor matches the null + string after any newline in the string in addition to its normal + function, and the $ anchor matches the null string before any + newline in the string in addition to its normal function. +

+
+
+-indices +
+
+

+ Changes what is stored in the subMatchVars. Instead of + storing the matching characters from string, each variable + will contain a list of two decimal strings giving the indices + in string of the first and last characters in the matching + range of characters. +

+
+
+-start offset +
+
+

+ Specifies a character index offset into the string at which to start + matching the regular expression. If -indices is + specified, the indices will be indexed starting from the + absolute beginning of the input string. offset will be + constrained to the bounds of the input string. +

+
+
+-all +
+
+

+ Causes the regular expression to be matched as many times as possible + in the string, returning the total number of matches found. If this + is specified with match variables, they will contain information + for the last match only. +

+
+
+-inline +
+
+

+ Causes the command to return, as a list, the data that would otherwise + be placed in match variables. When using -inline, match variables + may not be specified. If used with -all, the list will be concatenated + at each iteration, such that a flat list is always returned. For + each match iteration, the command will append the overall match + data, plus one element for each subexpression in the regular + expression. +

+
+
+-- +
+
+

+ Marks the end of switches. The argument following this one will be + treated as exp even if it starts with a -. +

+
+
+
+
+

regsub

+

regsub ?-nocase? ?-all? ?-line? ?-start offset? ?--? exp string subSpec ?varName?

+

This command matches the regular expression exp against +string using the rules described in REGULAR EXPRESSIONS +above.

+

If varName is specified, the commands stores string to varName +with the substitutions detailed below, and returns the number of +substitutions made (normally 1 unless -all is specified). +This is 0 if there were no matches.

+

If varName is not specified, the substituted string will be returned +instead.

+

When copying string, the portion of string that +matched exp is replaced with subSpec. +If subSpec contains a & or \0, then it is replaced +in the substitution with the portion of string that +matched exp.

+

If subSpec contains a \n, where n is a digit +between 1 and 9, then it is replaced in the substitution with +the portion of string that matched the n'-th +parenthesized subexpression of exp. +Additional backslashes may be used in subSpec to prevent special +interpretation of & or \0 or \n or +backslash.

+

The use of backslashes in subSpec tends to interact badly +with the Tcl parser’s use of backslashes, so it’s generally +safest to enclose subSpec in braces if it includes +backslashes.

+

The following switches modify the behaviour of regsub

+
+
+-nocase +
+
+

+ Upper-case characters in string are converted to lower-case + before matching against exp; however, substitutions + specified by subSpec use the original unconverted form + of string. +

+
+
+-all +
+
+

+ All ranges in string that match exp are found and substitution + is performed for each of these ranges, rather than only the + first. The & and \n sequences are handled for + each substitution using the information from the corresponding + match. +

+
+
+-line +
+
+

+ Use newline-sensitive matching. By default, newline + is a completely ordinary character with no special meaning in + either REs or strings. With this flag, [ bracket expressions + and . never match newline, a anchor matches the null + string after any newline in the string in addition to its normal + function, and the $ anchor matches the null string before any + newline in the string in addition to its normal function. +

+
+
+-start offset +
+
+

+ Specifies a character index offset into the string at which to + start matching the regular expression. offset will be + constrained to the bounds of the input string. +

+
+
+-- +
+
+

+ Marks the end of switches. The argument following this one will be + treated as exp even if it starts with a -. +

+
+
+
+
+

ref

+

ref string tag ?finalizer?

+

Create a new reference containing string of type tag. +If finalizer is specified, it is a command which will be invoked +when the a garbage collection cycle runs and this reference is +no longer accessible.

+

The finalizer is invoked as:

+
+
+
finalizer reference string
+
+

See GARBAGE COLLECTION, REFERENCES, LAMBDA for more detail.

+
+
+

rename

+

rename oldName newName

+

Rename the command that used to be called oldName so that it +is now called newName. If newName is an empty string +(e.g. {}) then oldName is deleted. The rename command +returns an empty string as result.

+
+
+

return

+

return ?-code code? ?-errorinfo stacktrace? ?-errorcode errorcode? ?-level n? ?value?

+

Return immediately from the current procedure (or top-level command +or source command), with value as the return value. If value +is not specified, an empty string will be returned as result.

+

If -code is specified (as either a number or ok, error, break, +continue, signal, return or exit), this code will be used instead +of JIM_OK. This is generally useful when implementing flow of control +commands.

+

If -level is specified and greater than 1, it has the effect of delaying +the new return code from -code. This is useful when rethrowing an error +from catch. See the implementation of try/catch in tclcompat.tcl for +an example of how this is done.

+

Note: The following options are only used when -code is JIM_ERR.

+

If -errorinfo is specified (as returned from info stacktrace) +it is used to initialize the stacktrace.

+

If -errorcode is specified, it is used to set the global variable $::errorCode.

+
+
+

scan

+

scan string format varName1 ?varName2 ...?

+

This command parses fields from an input string in the same fashion +as the C sscanf procedure. string gives the input to be parsed +and format indicates how to parse it, using % fields as in +sscanf. All of the sscanf options are valid; see the sscanf +man page for details. Each varName gives the name of a variable; +when a field is scanned from string, the result is converted back +into a string and assigned to the corresponding varName. The +only unusual conversion is for %c. For %c conversions a single +character value is converted to a decimal string, which is then +assigned to the corresponding varName; no field width may be +specified for this conversion.

+
+
+

seek

+

seek fileId offset ?origin?

+

fileId seek offset ?origin?

+

Change the current access position for fileId. +The offset and origin arguments specify the position at +which the next read or write will occur for fileId. +offset must be a number (which may be negative) and origin +must be one of the following:

+
+
+start +
+
+

+ The new access position will be offset bytes from the start + of the file. +

+
+
+current +
+
+

+ The new access position will be offset bytes from the current + access position; a negative offset moves the access position + backwards in the file. +

+
+
+end +
+
+

+ The new access position will be offset bytes from the end of + the file. A negative offset places the access position before + the end-of-file, and a positive offset places the access position + after the end-of-file. +

+
+
+

The origin argument defaults to start.

+

fileId must have been the return value from a previous call to +open, or it may be stdin, stdout, or stderr to refer to one +of the standard I/O channels.

+

This command returns an empty string.

+
+
+

set

+

set varName ?value?

+

Returns the value of variable varName.

+

If value is specified, then set the value of varName to value, +creating a new variable if one doesn’t already exist, and return +its value.

+

If varName contains an open parenthesis and ends with a +close parenthesis, then it refers to an array element: the characters +before the open parenthesis are the name of the array, and the characters +between the parentheses are the index within the array. +Otherwise varName refers to a scalar variable.

+

If no procedure is active, then varName refers to a global +variable.

+

If a procedure is active, then varName refers to a parameter +or local variable of the procedure, unless the global command +has been invoked to declare varName to be global.

+

The :: prefix may also be used to explicitly reference a variable +in the global scope.

+
+
+

setref

+

setref reference string

+

Store a new string in reference, replacing the existing string. +The reference must be a valid reference create with the ref +command.

+

See GARBAGE COLLECTION, REFERENCES, LAMBDA for more detail.

+
+
+

signal

+

Command for signal handling.

+

See kill for the different forms which may be used to specify signals.

+

Commands which return a list of signal names do so using the canonical form: +"SIGINT SIGTERM".

+
+
+signal handle ?signals ...? +
+
+

+ If no signals are given, returns a list of all signals which are currently + being handled. + If signals are specified, these are added to the list of signals currently + being handled. +

+
+
+signal ignore ?signals ...? +
+
+

+ If no signals are given, returns a lists all signals which are currently + being ignored. + If signals are specified, these are added to the list of signals + currently being ignored. These signals are still delivered, but + are not considered by catch -signal or try -signal. Use + signal check to determine which signals have occurred but + been ignored. +

+
+
+signal default ?signals ...? +
+
+

+ If no signals are given, returns a lists all signals which are currently have + the default behaviour. + If signals are specified, these are added to the list of signals which have + the default behaviour. +

+
+
+signal check ?-clear? ?signals ...? +
+
+

+ Returns a list of signals which have been delivered to the process + but are ignored. If signals are specified, only that set of signals will + be checked, otherwise all signals will be checked. + If -clear is specified, any signals returned are removed and will not be + returned by subsequent calls to signal check unless delivered again. +

+
+
+signal throw ?signal? +
+
+

+ Raises the given signal, which defaults to SIGINT if not specified. + The behaviour is identical to: +

+
+
+
kill signal [pid]
+
+
+
+

Note that signal handle and signal ignore represent two forms of signal +handling. signal handle is used in conjunction with catch -signal or try -signal +to immediately abort execution when the signal is delivered. Alternatively, signal ignore +is used in conjunction with signal check to handle signal synchronously. Consider the +two examples below.

+

Prevent a processing from taking too long

+
+
+
signal handle SIGALRM
+alarm 20
+try -signal {
+    .. possibly long running process ..
+    alarm 0
+} on signal {sig} {
+    puts stderr "Process took too long"
+}
+
+

Handle SIGHUP to reconfigure:

+
+
+
signal ignore SIGHUP
+while {1} {
+    ... handle configuration/reconfiguration ...
+    while {[signal check -clear SIGHUP] eq ""} {
+        ... do processing ..
+    }
+    # Received SIGHUP, so reconfigure
+}
+
+
+
+

sleep

+

sleep seconds

+

Pauses for the given number of seconds, which may be a floating +point value less than one to sleep for less than a second, or an +integer to sleep for one or more seconds.

+
+
+

source

+

source fileName

+

Read file fileName and pass the contents to the Tcl interpreter +as a sequence of commands to execute in the normal fashion. The return +value of source is the return value of the last command executed +from the file. If an error occurs in executing the contents of the +file, then the source command will return that error.

+

If a return command is invoked from within the file, the remainder of +the file will be skipped and the source command will return +normally with the result from the return command.

+
+
+

split

+

split string ?splitChars?

+

Returns a list created by splitting string at each character +that is in the splitChars argument.

+

Each element of the result list will consist of the +characters from string between instances of the +characters in splitChars.

+

Empty list elements will be generated if string contains +adjacent characters in splitChars, or if the first or last +character of string is in splitChars.

+

If splitChars is an empty string then each character of +string becomes a separate element of the result list.

+

splitChars defaults to the standard white-space characters. +For example,

+
+
+
split "comp.unix.misc" .
+
+

returns "comp unix misc" and

+
+
+
split "Hello world" {}
+
+

returns "H e l l o { } w o r l d".

+
+
+

stackdump

+

stackdump stacktrace

+

Creates a human readable representation of a stack trace.

+
+
+

stacktrace

+

stacktrace

+

Returns a live stack trace as a list of proc file line proc file line .... +Iteratively uses info frame to create the stack trace. This stack trace is in the +same form as produced by catch and info stacktrace

+

See also stackdump.

+
+
+

string

+

string option arg ?arg ...?

+

Perform one of several string operations, depending on option. +The legal options (which may be abbreviated) are:

+
+
+string bytelength string +
+
+

+ Returns the length of the string in bytes. This will return + the same value as string length if UTF-8 support is not enabled, + or if the string is composed entirely of ASCII characters. + See UTF-8 AND UNICODE. +

+
+
+string byterange string first last +
+
+

+ Like string range except works on bytes rather than characters. + These commands are identical if UTF-8 support is not enabled. +

+
+
+string compare ?-nocase? ?-length len? string1 string2 +
+
+

+ Perform a character-by-character comparison of strings string1 and + string2 in the same way as the C strcmp procedure. Return + -1, 0, or 1, depending on whether string1 is lexicographically + less than, equal to, or greater than string2. If -length + is specified, then only the first len characters are used + in the comparison. If len is negative, it is ignored. + Performs a case-insensitive comparison if -nocase is specified. +

+
+
+string equal ?-nocase? ?-length len? string1 string2 +
+
+

+ Returns 1 if the strings are equal, or 0 otherwise. If -length + is specified, then only the first len characters are used + in the comparison. If len is negative, it is ignored. + Performs a case-insensitive comparison if -nocase is specified. +

+
+
+string first string1 string2 ?firstIndex? +
+
+

+ Search string2 for a sequence of characters that exactly match + the characters in string1. If found, return the index of the + first character in the first such match within string2. If not + found, return -1. If firstIndex is specified, matching will start + from firstIndex of string1. +

+
+
+ +
+
+

+ See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for firstIndex. +

+
+
+string index string charIndex +
+
+

+ Returns the charIndexth character of the 'string + argument. A charIndex of 0 corresponds to the first + character of the string. + If charIndex is less than 0 or greater than + or equal to the length of the string then an empty string is + returned. +

+
+
+ +
+
+

+ See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for charIndex. +

+
+
+string is class ?-strict? string +
+
+

+ Returns 1 if string is a valid member of the specified character + class, otherwise returns 0. If -strict is specified, then an + empty string returns 0, otherwise an empty string will return 1 + on any class. The following character classes are recognized + (the class name can be abbreviated): +

+
+
+ +
+
+
+
+alnum +
+
+

+Any alphabet or digit character. +

+
+
+alpha +
+
+

+Any alphabet character. +

+
+
+ascii +
+
+

+Any character with a value less than 128 (those that are in the 7-bit ascii range). +

+
+
+control +
+
+

+Any control character. +

+
+
+digit +
+
+

+Any digit character. +

+
+
+double +
+
+

+Any of the valid forms for a double in Tcl, with optional surrounding whitespace. + In case of under/overflow in the value, 0 is returned. +

+
+
+graph +
+
+

+Any printing character, except space. +

+
+
+integer +
+
+

+Any of the valid string formats for an integer value in Tcl, with optional surrounding whitespace. +

+
+
+lower +
+
+

+Any lower case alphabet character. +

+
+
+print +
+
+

+Any printing character, including space. +

+
+
+punct +
+
+

+Any punctuation character. +

+
+
+space +
+
+

+Any space character. +

+
+
+upper +
+
+

+Any upper case alphabet character. +

+
+
+xdigit +
+
+

+Any hexadecimal digit character ([0-9A-Fa-f]). +

+
+
+
+
+ +
+
+

+ Note that string classification does not respect UTF-8. See UTF-8 AND UNICODE +

+
+
+string last string1 string2 ?lastIndex? +
+
+

+ Search string2 for a sequence of characters that exactly match + the characters in string1. If found, return the index of the + first character in the last such match within string2. If there + is no match, then return -1. If lastIndex is specified, only characters + up to lastIndex of string2 will be considered in the match. +

+
+
+ +
+
+

+ See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for lastIndex. +

+
+
+string length string +
+
+

+ Returns a decimal string giving the number of characters in string. + If UTF-8 support is enabled, this may be different than the number of bytes. + See UTF-8 AND UNICODE +

+
+
+string map ?-nocase? mapping string +
+
+

+ Replaces substrings in string based on the key-value pairs in + mapping, which is a list of key value key value ... as in the form + returned by array get. Each instance of a key in the string will be + replaced with its corresponding value. If -nocase is specified, then + matching is done without regard to case differences. Both key and value may + be multiple characters. Replacement is done in an ordered manner, so the + key appearing first in the list will be checked first, and so on. string is + only iterated over once, so earlier key replacements will have no affect for + later key matches. For example, +

+
+
+
string map {abc 1 ab 2 a 3 1 0} 1abcaababcabababc
+
+
+
+ +
+
+

+ will return the string 01321221. +

+
+
+ +
+
+

+ Note that if an earlier key is a prefix of a later one, it will completely mask the later + one. So if the previous example is reordered like this, +

+
+
+
string map {1 0 ab 2 a 3 abc 1} 1abcaababcabababc
+
+
+
+ +
+
+

+ it will return the string 02c322c222c. +

+
+
+string match ?-nocase? pattern string +
+
+

+ See if pattern matches string; return 1 if it does, 0 + if it doesn’t. Matching is done in a fashion similar to that + used by the C-shell. For the two strings to match, their contents + must be identical except that the following special sequences + may appear in pattern: +

+
+
+* +
+
+

+ Matches any sequence of characters in string, + including a null string. +

+
+
+? +
+
+

+ Matches any single character in string. +

+
+
+[chars] +
+
+

+ Matches any character in the set given by chars. + If a sequence of the form x-y appears in chars, + then any character between x and y, inclusive, + will match. +

+
+
+\x +
+
+

+ Matches the single character x. This provides a way of + avoiding the special interpretation of the characters \*?[] + in pattern. +

+
+
+
+
+ +
+
+

+ Performs a case-insensitive comparison if -nocase is specified. +

+
+
+string range string first last +
+
+

+ Returns a range of consecutive characters from string, starting + with the character whose index is first and ending with the + character whose index is last. An index of 0 refers to the + first character of the string. +

+
+
+ +
+
+

+ See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for first and last. +

+
+
+ +
+
+

+ If first is less than zero then it is treated as if it were zero, and + if last is greater than or equal to the length of the string then + it is treated as if it were end. If first is greater than + last then an empty string is returned. +

+
+
+string repeat string count +
+
+

+ Returns a new string consisting of string repeated count times. +

+
+
+string replace string first last ?newstring? +
+
+

+ Removes a range of consecutive characters from string, starting + with the character whose index is first and ending with the + character whose index is last. If newstring is specified, + then it is placed in the removed character range. If first is + less than zero then it is treated as if it were zero, and if last + is greater than or equal to the length of the string then it is + treated as if it were end. If first is greater than last + or the length of the initial string, or last is less than 0, + then the initial string is returned untouched. +

+
+
+string reverse string +
+
+

+ Returns a string that is the same length as string but + with its characters in the reverse order. +

+
+
+string tolower string +
+
+

+ Returns a value equal to string except that all upper case + letters have been converted to lower case. +

+
+
+string totitle string +
+
+

+ Returns a value equal to string except that the first character + is converted to title case (or upper case if there is no UTF-8 titlecase variant) + and all remaining characters have been converted to lower case. +

+
+
+string toupper string +
+
+

+ Returns a value equal to string except that all lower case + letters have been converted to upper case. +

+
+
+string trim string ?chars? +
+
+

+ Returns a value equal to string except that any leading + or trailing characters from the set given by chars are + removed. + If chars is not specified then white space is removed + (spaces, tabs, newlines, and carriage returns). +

+
+
+string trimleft string ?chars? +
+
+

+ Returns a value equal to string except that any + leading characters from the set given by chars are + removed. + If chars is not specified then white space is removed + (spaces, tabs, newlines, and carriage returns). +

+
+
+string trimright string ?chars? +
+
+

+ Returns a value equal to string except that any + trailing characters from the set given by chars are + removed. + If chars is not specified then white space is removed + (spaces, tabs, newlines, and carriage returns). + Null characters are always removed. +

+
+
+
+
+

subst

+

subst ?-nobackslashes? ?-nocommands? ?-novariables? string

+

This command performs variable substitutions, command substitutions, +and backslash substitutions on its string argument and returns the +fully-substituted result. The substitutions are performed in exactly +the same way as for Tcl commands. As a result, the string argument +is actually substituted twice, once by the Tcl parser in the usual +fashion for Tcl commands, and again by the subst command.

+

If any of the -nobackslashes, -nocommands, or -novariables are +specified, then the corresponding substitutions are not performed. +For example, if -nocommands is specified, no command substitution +is performed: open and close brackets are treated as ordinary +characters with no special interpretation.

+

Note: when it performs its substitutions, subst does not give any +special treatment to double quotes or curly braces. For example, +the following script returns xyz {44}, not xyz {$a}.

+
+
+
set a 44
+subst {xyz {$a}}
+
+
+
+

switch

+

switch ?options? string pattern body ?pattern body ...?

+

switch ?options? string {pattern body ?pattern body ...?}

+

The switch command matches its string argument against each of +the pattern arguments in order. As soon as it finds a pattern that +matches string it evaluates the following body and returns the +result of that evaluation. If the last pattern argument is default +then it matches anything. If no pattern argument matches string and +no default is given, then the switch command returns an empty string. +If the initial arguments to switch start with - then they are treated +as options. The following options are currently supported:

+
+
+-exact +
+
+

+ Use exact matching when comparing string to a + pattern. This is the default. +

+
+
+-glob +
+
+

+ When matching string to the patterns, use glob-style + matching (i.e. the same as implemented by the string + match command). +

+
+
+-regexp +
+
+

+ When matching string to the patterns, use regular + expression matching (i.e. the same as implemented + by the regexp command). +

+
+
+-command commandname +
+
+

+ When matching string to the patterns, use the given command, which + must be a single word. The command is invoked as + commandname pattern string, or commandname -nocase pattern string + and must return 1 if matched, or 0 if not. +

+
+
+-- +
+
+

+ Marks the end of options. The argument following + this one will be treated as string even if it starts + with a -. +

+
+
+

Two syntaxes are provided for the pattern and body arguments. The +first uses a separate argument for each of the patterns and commands; +this form is convenient if substitutions are desired on some of the +patterns or commands. The second form places all of the patterns +and commands together into a single argument; the argument must +have proper list structure, with the elements of the list being the +patterns and commands. The second form makes it easy to construct +multi-line switch commands, since the braces around the whole list +make it unnecessary to include a backslash at the end of each line. +Since the pattern arguments are in braces in the second form, no +command or variable substitutions are performed on them; this makes +the behaviour of the second form different than the first form in +some cases.

+

If a body is specified as - it means that the body for the next +pattern should also be used as the body for this pattern (if the +next pattern also has a body of - then the body after that is +used, and so on). This feature makes it possible to share a single +body among several patterns.

+

Below are some examples of switch commands:

+
+
+
switch abc a - b {format 1} abc {format 2} default {format 3}
+
+

will return 2,

+
+
+
switch -regexp aaab {
+       ^a.*b$ -
+       b {format 1}
+       a* {format 2}
+       default {format 3}
+}
+
+

will return 1, and

+
+
+
switch xyz {
+       a -
+       b {format 1}
+       a* {format 2}
+       default {format 3}
+}
+
+

will return 3.

+
+
+

tailcall

+

tailcall cmd ?arg...?

+

The tailcall command provides an optimised way of invoking a command whilst replacing +the current call frame. This is similar to exec in Bourne Shell.

+

The following are identical except the first immediately replaces the current call frame.

+
+
+
tailcall a b c
+
+
+
+
return [uplevel 1 [list a b c]]
+
+

tailcall is useful as a dispatch mechanism:

+
+
+
proc a {cmd args} {
+  tailcall sub_$cmd {*}$args
+}
+proc sub_cmd1 ...
+proc sub_cmd2 ...
+
+
+
+

tell

+

tell fileId

+

fileId tell

+

Returns a decimal string giving the current access position in +fileId.

+

fileId must have been the return value from a previous call to +open, or it may be stdin, stdout, or stderr to refer to one +of the standard I/O channels.

+
+
+

throw

+

throw code ?msg?

+

This command throws an exception (return) code along with an optional message. +This command is mostly for convenient usage with try.

+

The command throw break is equivalent to break. +The command throw 20 message can be caught with an on 20 ... clause to try.

+
+
+

time

+

time command ?count?

+

This command will call the Tcl interpreter count +times to execute command (or once if count isn’t +specified). It will then return a string of the form

+
+
+
503 microseconds per iteration
+
+

which indicates the average amount of time required per iteration, +in microseconds.

+

Time is measured in elapsed time, not CPU time.

+
+
+

try

+

try ?catchopts? tryscript ?on returncodes {?resultvar? ?optsvar?} handlerscript ...? ?finally finalscript?

+

The try command is provided as a convenience for exception handling.

+

This interpeter first evaluates tryscript under the effect of the catch +options catchopts (e.g. -signal -noexit --, see catch).

+

It then evaluates the script for the first matching on handler +(there many be zero or more) based on the return code from the try +section. For example a normal JIM_ERR error will be matched by +an on error handler.

+

Finally, any finalscript is evaluated.

+

The result of this command is the result of tryscript, except in the +case where an exception occurs in a matching on handler script or the finally script, +in which case the result is this new exception.

+

The specified returncodes is a list of return codes either as names (ok, error, break, etc.) +or as integers.

+

If resultvar and optsvar are specified, they are set as for catch before evaluating +the matching handler.

+

For example:

+
+
+
set f [open input]
+try -signal {
+    process $f
+} on {continue break} {} {
+    error "Unexpected break/continue"
+} on error {msg opts} {
+    puts "Dealing with error"
+    return {*}$opts $msg
+} on signal sig {
+    puts "Got signal: $sig"
+} finally {
+    $f close
+}
+
+

If break, continue or error are raised, they are dealt with by the matching +handler.

+

In any case, the file will be closed via the finally clause.

+

See also throw, catch, return, error.

+
+
+

unknown

+

unknown cmdName ?arg arg …?

+

This command doesn’t actually exist as part of Tcl, but Tcl will +invoke it if it does exist.

+

If the Tcl interpreter encounters a command name for which there +is not a defined command, then Tcl checks for the existence of +a command named unknown.

+

If there is no such command, then the interpreter returns an +error.

+

If the unknown command exists, then it is invoked with +arguments consisting of the fully-substituted name and arguments +for the original non-existent command.

+

The unknown command typically does things like searching +through library directories for a command procedure with the name +cmdName, or expanding abbreviated command names to full-length, +or automatically executing unknown commands as UNIX sub-processes.

+

In some cases (such as expanding abbreviations) unknown will +change the original command slightly and then (re-)execute it. +The result of the unknown command is used as the result for +the original non-existent command.

+
+
+

unset

+

unset ?-nocomplain? ?--? ?name name …?

+

Remove variables. +Each name is a variable name, specified in any of the +ways acceptable to the set command.

+

If a name refers to an element of an array, then that +element is removed without affecting the rest of the array.

+

If a name consists of an array name with no parenthesized +index, then the entire array is deleted.

+

The unset command returns an empty string as result.

+

An error occurs if any of the variables doesn’t exist, unless -nocomplain +is specified. The -- argument may be specified to stop option processing +in case the variable name may be -nocomplain.

+
+
+

upcall

+

upcall command ?args …?

+

May be used from within a proc defined as local proc in order to call +the previous, hidden version of the same command.

+

If there is no previous definition of the command, an error is returned.

+
+
+

uplevel

+

uplevel ?level? command ?command …?

+

All of the command arguments are concatenated as if they had +been passed to concat; the result is then evaluated in the +variable context indicated by level. uplevel returns +the result of that evaluation. If level is an integer, then +it gives a distance (up the procedure calling stack) to move before +executing the command. If level consists of # followed by +a number then the number gives an absolute level number. If level +is omitted then it defaults to 1. level cannot be +defaulted if the first command argument starts with a digit or #.

+

For example, suppose that procedure a was invoked +from top-level, and that it called b, and that b called c. +Suppose that c invokes the uplevel command. If level +is 1 or #2 or omitted, then the command will be executed +in the variable context of b. If level is 2 or #1 +then the command will be executed in the variable context of a.

+

If level is 3 or #0 then the command will be executed +at top-level (only global variables will be visible). +The uplevel command causes the invoking procedure to disappear +from the procedure calling stack while the command is being executed. +In the above example, suppose c invokes the command

+
+
+
uplevel 1 {set x 43; d}
+
+

where d is another Tcl procedure. The set command will +modify the variable x in b’s context, and 'd will execute +at level 3, as if called from b. If it in turn executes +the command

+
+
+
uplevel {set x 42}
+
+

then the set command will modify the same variable x in b’s +context: the procedure 'c does not appear to be on the call stack +when d is executing. The command info level may +be used to obtain the level of the current procedure.

+

uplevel makes it possible to implement new control +constructs as Tcl procedures (for example, uplevel could +be used to implement the while construct as a Tcl procedure).

+
+
+

upvar

+

upvar ?level? otherVar myVar ?otherVar myVar …?

+

This command arranges for one or more local variables in the current +procedure to refer to variables in an enclosing procedure call or +to global variables.

+

level may have any of the forms permitted for the uplevel +command, and may be omitted if the first letter of the first otherVar +isn’t # or a digit (it defaults to 1).

+

For each otherVar argument, upvar makes the variable +by that name in the procedure frame given by level (or at +global level, if level is #0) accessible +in the current procedure by the name given in the corresponding +myVar argument.

+

The variable named by otherVar need not exist at the time of the +call; it will be created the first time myVar is referenced, just like +an ordinary variable.

+

upvar may only be invoked from within procedures.

+

upvar returns an empty string.

+

The upvar command simplifies the implementation of call-by-name +procedure calling and also makes it easier to build new control constructs +as Tcl procedures. +For example, consider the following procedure:

+
+
+
proc add2 name {
+    upvar $name x
+    set x [expr $x+2]
+}
+
+

add2 is invoked with an argument giving the name of a variable, +and it adds two to the value of that variable. +Although add2 could have been implemented using uplevel +instead of upvar, upvar makes it simpler for add2 +to access the variable in the caller’s procedure frame.

+
+
+

while

+

while test body

+

The while command evaluates test as an expression +(in the same way that expr evaluates its argument). +The value of the expression must be numeric; if it is non-zero +then body is executed by passing it to the Tcl interpreter.

+

Once body has been executed then test is evaluated +again, and the process repeats until eventually test +evaluates to a zero numeric value. continue +commands may be executed inside body to terminate the current +iteration of the loop, and break +commands may be executed inside body to cause immediate +termination of the while command.

+

The while command always returns an empty string.

+
+
+
+
+

OPTIONAL-EXTENSIONS

+
+

The following extensions may or may not be available depending upon +what options were selected when Jim Tcl was built.

+
+

posix: os.fork, os.wait, os.gethostname, os.getids, os.uptime

+
+
+os.fork +
+
+

+ Invokes fork(2) and returns the result. +

+
+
+os.wait -nohang pid +
+
+

+ Invokes waitpid(2), with WNOHANG if -nohang is specified. + Returns a list of 3 elements. +

+
+
+
{0 none 0} if -nohang is specified, and the process is still alive.
+
+
+
+
{-1 error <error-description>} if the process does not exist or has already been waited for.
+
+
+
+
{<pid> exit <exit-status>} if the process exited normally.
+
+
+
+
{<pid> signal <signal-number>} if the process terminated on a signal.
+
+
+
+
{<pid> other 0} otherwise (core dump, stopped, continued, etc.)
+
+
+
+os.gethostname +
+
+

+ Invokes gethostname(3) and returns the result. +

+
+
+os.getids +
+
+

+ Returns the various user/group ids for the current process. +

+
+
+
jim> os.getids
+uid 1000 euid 1000 gid 100 egid 100
+
+
+
+os.uptime +
+
+

+ Returns the number of seconds since system boot. See description of uptime in sysinfo(2). +

+
+
+
+
+
+
+

ANSI I/O (aio) and EVENTLOOP API

+
+

Jim provides an alternative object-based API for I/O.

+

See open and socket for commands which return an I/O handle.

+
+

aio

+
+
+$handle read ?-nonewline? ?len? +
+
+

+ Read and return bytes from the stream. To eof if no len. +

+
+
+$handle gets ?var? +
+
+

+ Read one line and return it or store it in the var +

+
+
+$handle puts ?-nonewline? str +
+
+

+ Write the string, with newline unless -nonewline +

+
+
+$handle copyto tofd ?size? +
+
+

+ Copy bytes to the file descriptor tofd. If size is specified, at most + that many bytes will be copied. Otherwise copying continues until the end + of the input file. Returns the number of bytes actually copied. +

+
+
+$handle flush +
+
+

+ Flush the stream +

+
+
+$handle filename +
+
+

+ Returns the original filename associated with the handle. + Handles returned by socket give the socket type instead of a filename. +

+
+
+$handle eof +
+
+

+ Returns 1 if stream is at eof +

+
+
+$handle close +
+
+

+ Closes the stream +

+
+
+$handle seek offset ?start|current|end? +
+
+

+ Seeks in the stream (default current) +

+
+
+$handle tell +
+
+

+ Returns the current seek position +

+
+
+$handle filename +
+
+

+ Returns the original filename used when opening the file. + If the handle was returned from socket, the type of the + handle is returned instead. +

+
+
+$handle ndelay ?0|1? +
+
+

+ Set O_NDELAY (if arg). Returns current/new setting. + Note that in general ANSI I/O interacts badly with non-blocking I/O. + Use with care. +

+
+
+$handle buffering none|line|full +
+
+

+ Sets the buffering mode of the stream. +

+
+
+$handle accept +
+
+

+ Server socket only: Accept a connection and return stream +

+
+
+$handle sendto str ?hostname:?port +
+
+

+ Sends the string, str, to the given address via the socket using sendto(2). + This is intended for udp sockets and may give an error or behave in unintended + ways for other handle types. + Returns the number of bytes written. +

+
+
+$handle recvfrom maxlen ?addrvar? +
+
+

+ Receives a message from the handle via recvfrom(2) and returns it. + At most maxlen bytes are read. + If addrvar is specified, the sending address of the message is stored in + the named variable in the form addr:port. See socket for details. +

+
+
+
+
+

fconfigure

+
+
+fconfigure handle ?-blocking 0|1? ?-buffering noneline|full? ?-translation mode? +
+
+

+ For compatibility with Tcl, a limited form of the fconfigure + command is supported. +

+
+
+
+
+
+

eventloop: after, vwait, update

+

The following commands allow a script to be invoked when the given condition occurs. +If no script is given, returns the current script. If the given script is the empty, the +handler is removed.

+
+
+$handle readable ?readable-script? +
+
+

+ Sets or returns the script for when the socket is readable. +

+
+
+$handle writable ?writable-script? +
+
+

+ Sets or returns the script for when the socket is writable. +

+
+
+$handle onexception ?exception-script? +
+
+

+ Sets or returns the script for when when oob data received. +

+
+
+

For compatibility with Tcl, these may be prefixed with fileevent. e.g.

+
+
+ +
+
+

+ fileevent $handle readable ... +

+
+
+

Time-based execution is also available via the eventloop API.

+
+
+after ms +
+
+

+ Sleeps for the given number of milliseconds. No events are + processed during this time. +

+
+
+after ms|idle script ?script ...?' +
+
+

+ The scripts are concatenated and executed after the given + number of milliseconds have elapsed. If idle is specified, + the script will run the next time the event loop is processed + with vwait or update. The script is only run once and + then removed. Returns an event id. +

+
+
+after cancel id|command +
+
+

+ Cancels an after event with the given event id or matching + command (script). Returns the number of milliseconds + remaining until the event would have fired. Returns the + empty string if no matching event is found. +

+
+
+after info ?id? +
+
+

+ If id is not given, returns a list of current after + events. If id is given, returns a list containing the + associated script and either timer or idle to indicated + the type of the event. An error occurs if id does not + match an event. +

+
+
+vwait variable +
+
+

+ A call to vwait is enters the eventloop. vwait processes + events until the named (global) variable changes or all + event handlers are removed. The variable need not exist + beforehand. If there are no event handlers defined, vwait + returns immediately. +

+
+
+update ?idletasks? +
+
+

+ A call to update enters the eventloop to process expired events, but + no new events. If idletasks is specified, only expired time events are handled, + not file events. + Returns once handlers have been run for all expired events. +

+
+
+

Scripts are executed at the global scope. If an error occurs during a handler script, +an attempt is made to call (the user-defined command) bgerror with the details of the error. +If the bgerror commands does not exist, it is printed to stderr instead.

+

If a file event handler script generates an error, the handler is automatically removed +to prevent infinite errors. (A time event handler is always removed after execution).

+
+
+bgerror error +
+
+

+ Called when an event handler script generates an error. +

+
+
+
+
+

socket

+

Various socket types may be created.

+
+
+socket unix path +
+
+

+ A unix domain socket client. +

+
+
+socket unix.server path +
+
+

+ A unix domain socket server. +

+
+
+socket ?-ipv6? stream addr:port +
+
+

+ A TCP socket client. +

+
+
+socket ?-ipv6? stream.server ?addr:?port +
+
+

+ A TCP socket server (addr defaults to 0.0.0.0 for IPv4 or [::] for IPv6). +

+
+
+socket ?-ipv6? dgram ?addr:port? +
+
+

+ A UDP socket client. If the address is not specified, + the client socket will be unbound and sendto must be used + to indicated the destination. +

+
+
+socket ?-ipv6? dgram.server addr:port +
+
+

+ A UDP socket server. +

+
+
+socket pipe +
+
+

+ A pipe. Note that unlike all other socket types, this command returns + a list of two channels: {read write} +

+
+
+

This command creates a socket connected (client) or bound (server) to the given +address.

+

The returned value is channel and may generally be used with the various file I/O +commands (gets, puts, read, etc.), either as object-based syntax or Tcl-compatible syntax.

+
+
+
set f [socket stream www.google.com:80]
+aio.sockstream1
+$f puts -nonewline "GET / HTTP/1.0\r\n\r\n"
+$f gets
+HTTP/1.0 302 Found
+$f close
+
+

Server sockets, however support only accept, which is most useful in conjunction with +the EVENTLOOP API.

+
+
+
set f [socket stream.server 80]
+$f readable {
+    set client [$f accept]
+    $client gets $buf
+    ...
+    $client puts -nonewline "HTTP/1.1 404 Not found\r\n"
+    $client close
+}
+vwait done
+
+

The address, addr, can be given in one of the following forms:

+
    +
  1. +

    +For IPv4 socket types, an IPv4 address such as 192.168.1.1 +

    +
  2. +
  3. +

    +For IPv6 socket types, an IPv6 address such as [fe80::1234] or [::] +

    +
  4. +
  5. +

    +A hostname +

    +
  6. +
+

Note that on many systems, listening on an IPv6 address such as [::] will +also accept requests via IPv4.

+

Where a hostname is specified, the first returned address is used +which matches the socket type is used.

+

The special type pipe isn’t really a socket.

+
+
+
lassign [socket pipe] r w
+
+
+
+
# Must close $w after exec
+exec ps >@$w &
+$w close
+
+
+
+
$r readable ...
+
+
+
+

syslog

+

syslog ?options? ?priority? message

+

This command sends message to system syslog facility with given +priority. Valid priorities are:

+
+
+
emerg, alert, crit, err, error, warning, notice, info, debug
+
+

If a message is specified, but no priority is specified, then a +priority of info is used.

+

By default, facility user is used and the value of global tcl variable +argv0 is used as ident string. However, any of the following options +may be specified before priority to control these parameters:

+
+
+-facility value +
+
+

+ Use specified facility instead of user. The following + values for facility are recognized: +

+
+
+
authpriv, cron, daemon, kernel, lpr, mail, news, syslog, user,
+uucp, local0-local7
+
+
+
+-ident string +
+
+

+ Use given string instead of argv0 variable for ident string. +

+
+
+-options integer +
+
+

+ Set syslog options such as LOG_CONS, LOG_NDELAY. You should + use numeric values of those from your system syslog.h file, + because I haven’t got time to implement yet another hash + table. +

+
+
+
+
+

pack: pack, unpack

+

The optional pack extension provides commands to encode and decode binary strings.

+
+
+pack varName value -intle|-intbe|-str bitwidth ?bitoffset? +
+
+

+ Packs the binary representation of value into the variable + varName. The value is packed according to the given type + (integer/string, big-endian/little-endian), width and bit offset. + The variable is created if necessary (like append). + Ihe variable is expanded if necessary. +

+
+
+unpack binvalue -intbe|-intle|-uintbe|-uintle|-str bitpos bitwidth +
+
+

+ Unpacks bits from binvalue at bit position bitpos and with bitwidth. + Interprets the value according to the type (integer/string, big-endian/little-endian + and signed/unsigned) and returns it. For integer types, bitwidth + may be up to the size of a Jim Tcl integer (typically 64 bits). For the string type, + both the width and the offset must be on a byte boundary (multiple of 8). Attempting to + access outside the length of the value will return 0 for integer types or the empty string + for the string type. +

+
+
+
+
+

binary

+

The optional, pure-Tcl binary extension provides the Tcl-compatible binary scan and binary format +commands based on the low-level pack and unpack commands.

+ +

Note that packing and unpacking of floating point values is not supported.

+
+
+

oo: class, super

+

The optional, pure-Tcl oo extension provides object-oriented (OO) support for Jim Tcl.

+

See the online documentation (http://jim.berlios.de/documentation/oo/) for more details.

+
+
+class classname ?baseclasses? classvars +
+
+

+ Create a new class, classname, with the given dictionary + (classvars) as class variables. These are the initial variables + which all newly created objects of this class are initialised with. + If a list of baseclasses is given, methods and instance variables + are inherited. +

+
+
+super method ?args ...? +
+
+

+ From within a method, invokes the given method on the base class. + Note that this will only call the last baseclass given. +

+
+
+
+
+

tree

+

The optional, pure-Tcl tree extension implements an OO, general purpose tree structure +similar to that provided by tcllib ::struct::tree (http://tcllib.sourceforge.net/doc/struct_tree.html)

+

A tree is a collection of nodes, where each node (except the root node) has a single parent +and zero or more child nodes (ordered), as well as zero or more attribute/value pairs.

+
+
+tree +
+
+

+ Creates and returns a new tree object with a single node named "root". + All operations on the tree are invoked through this object. +

+
+
+$tree destroy +
+
+

+ Destroy the tree and all it’s nodes. (Note that the the tree will also + be automatically garbage collected once it goes out of scope). +

+
+
+$tree set nodename key value +
+
+

+ Set the value for the given attribute key. +

+
+
+$tree lappend nodename key value ... +
+
+

+ Append to the (list) value(s) for the given attribute key, or set if not yet set. +

+
+
+$tree keyexists nodename key +
+
+

+ Returns 1 if the given attribute key exists. +

+
+
+$tree get nodename key +
+
+

+ Returns the value associated with the given attribute key. +

+
+
+$tree getall nodename +
+
+

+ Returns the entire attribute dictionary associated with the given key. +

+
+
+$tree depth nodename +
+
+

+ Returns the depth of the given node. The depth of "root" is 0. +

+
+
+$tree parent nodename +
+
+

+ Returns the node name of the parent node, or "" for the root node. +

+
+
+$tree numchildren nodename +
+
+

+ Returns the number of child nodes. +

+
+
+$tree children nodename +
+
+

+ Returns a list of the child nodes. +

+
+
+$tree next nodename +
+
+

+ Returns the next sibling node, or "" if none. +

+
+
+$tree insert nodename ?index? +
+
+

+ Add a new child node to the given node. The index is a list index + such as 3 or end-2. The default index is end. + Returns the name of the newly added node. +

+
+
+$tree walk nodename dfs|bfs {actionvar nodevar} script +
+
+

+ Walks the tree starting from the given node, either breadth first (bfs) + depth first (dfs). + The value "enter" or "exit" is stored in variable actionvar. + The name of each node is stored in nodevar. + The script is evaluated twice for each node, on entry and exit. +

+
+
+$tree dump +
+
+

+ Dumps the tree contents to stdout +

+
+
+
+
+

tcl::prefix

+

The optional tclprefix extension provides the Tcl8.6-compatible tcl::prefix command +(http://www.tcl.tk/man/tcl8.6/TclCmd/prefix.htm) for matching strings against a table +of possible values (typically commands or options).

+
+
+tcl::prefix all table string +
+
+

+ Returns a list of all elements in table that begin with the prefix string. +

+
+
+tcl::prefix longest table string +
+
+

+ Returns the longest common prefix of all elements in table that begin with the prefix string. +

+
+
+tcl::prefix match ?options? table string +
+
+

+ If string equals one element in table or is a prefix to + exactly one element, the matched element is returned. If not, the + result depends on the -error option. +

+
    +
  • +

    +-exact Accept only exact matches. +

    +
  • +
  • +

    +-message string Use string in the error message at a mismatch. Default is "option". +

    +
  • +
  • +

    +-error options The options are used when no match is found. If options is + empty, no error is generated and an empty string is returned. + Otherwise the options are used as return options when + generating the error message. The default corresponds to + setting -level 0. +

    +
  • +
+
+
+
+
+

history

+

The optional history extension provides script access to the command line editing +and history support available in jimsh. See examples/jtclsh.tcl for an example. +Note: if line editing support is not available, history getline acts like gets and +the remaining subcommands do nothing.

+
+
+history load filename +
+
+

+ Load history from a (text) file. If the file does not exist or is not readable, + it is ignored. +

+
+
+history getline prompt ?varname? +
+
+

+ Displays the given prompt and allows a line to be entered. Similarly to gets, + if varname is given, it receives the line and the length of the line is returned, + or -1 on EOF. If varname is not given, the line is returned directly. +

+
+
+history add line +
+
+

+ Adds the given line to the history buffer. +

+
+
+history save filename +
+
+

+ Saves the current history buffer to the given file. +

+
+
+history show +
+
+

+ Displays the current history buffer to standard output. +

+
+
+
+
+

namespace

+

Provides namespace-related functions. See also: http://www.tcl.tk/man/tcl8.6/TclCmd/namespace.htm

+
+
+namespace code script +
+
+

+ Captures the current namespace context for later execution of + the script script. It returns a new script in which script has + been wrapped in a namespace inscope command. +

+
+
+namespace current +
+
+

+ Returns the fully-qualified name for the current namespace. +

+
+
+namespace delete ?namespace …? +
+
+

+ Deletes all commands and variables with the given namespace prefixes. +

+
+
+namespace eval namespace arg ?arg…? +
+
+

+ Activates a namespace called namespace and evaluates some code in that context. +

+
+
+namespace origin command +
+
+

+ Returns the fully-qualified name of the original command to which the imported command command refers. +

+
+
+namespace parent ?namespace? +
+
+

+ Returns the fully-qualified name of the parent namespace for namespace namespace, if given, otherwise + for the current namespace. +

+
+
+namespace qualifiers string +
+
+

+ Returns any leading namespace qualifiers for string +

+
+
+namespace tail string +
+
+

+ Returns the simple name at the end of a qualified string. +

+
+
+namespace upvar namespace ?arg…? +
+
+

+ This command arranges for zero or more local variables in the current procedure to refer to variables in namespace +

+
+
+namespace which ?-command|-variable? name +
+
+

+ Looks up name as either a command (the default) or variable and returns its fully-qualified name. +

+
+
+
+
+
+
+

BUILT-IN VARIABLES

+
+

The following global variables are created automatically +by the Tcl library.

+
+
+env +
+
+

+ This variable is set by Jim as an array + whose elements are the environment variables for the process. + Reading an element will return the value of the corresponding + environment variable. + This array is initialised at startup from the env command. + It may be modified and will affect the environment passed to + commands invoked with exec. +

+
+
+platform_tcl +
+
+

+ This variable is set by Jim as an array containing information + about the platform on which Jim was built. Currently this includes + os and platform. +

+
+
+auto_path +
+
+

+ This variable contains a list of paths to search for packages. + It defaults to a location based on where jim is installed + (e.g. /usr/local/lib/jim), but may be changed by jimsh + or the embedding application. Note that jimsh will consider + the environment variable $JIMLIB to be a list of colon-separated + list of paths to add to auto_path. +

+
+
+errorCode +
+
+

+ This variable holds the value of the -errorcode return + option set by the most recent error that occurred in this + interpreter. This list value represents additional information + about the error in a form that is easy to process with + programs. The first element of the list identifies a general + class of errors, and determines the format of the rest of + the list. The following formats for -errorcode return options + are used by the Tcl core; individual applications may define + additional formats. Currently only exec sets this variable. + Otherwise it will be NONE. +

+
+
+

The following global variables are set by jimsh.

+
+
+tcl_interactive +
+
+

+ This variable is set to 1 if jimsh is started in interactive mode + or 0 otherwise. +

+
+
+tcl_platform +
+
+

+ This variable is set by Jim as an array containing information + about the platform upon which Jim was built. The following is an + example of the contents of this array. +

+
+
+
tcl_platform(byteOrder)     = littleEndian
+tcl_platform(os)            = Darwin
+tcl_platform(platform)      = unix
+tcl_platform(pointerSize)   = 8
+tcl_platform(threaded)      = 0
+tcl_platform(wordSize)      = 8
+tcl_platform(pathSeparator) = :
+
+
+
+argv0 +
+
+

+ If jimsh is invoked to run a script, this variable contains the name + of the script. +

+
+
+argv +
+
+

+ If jimsh is invoked to run a script, this variable contains a list + of any arguments supplied to the script. +

+
+
+argc +
+
+

+ If jimsh is invoked to run a script, this variable contains the number + of arguments supplied to the script. +

+
+
+jim_argv0 +
+
+

+ The value of argv[0] when jimsh was invoked. +

+
+
+
+
+
+

CHANGES IN PREVIOUS RELEASES

+
+
+

In v0.70

+
    +
  1. +

    +platform_tcl() settings are now automatically determined +

    +
  2. +
  3. +

    +Add aio $handle filename +

    +
  4. +
  5. +

    +Add info channels +

    +
  6. +
  7. +

    +The bio extension is gone. Now aio supports copyto. +

    +
  8. +
  9. +

    +Add exists command +

    +
  10. +
  11. +

    +Add the pure-Tcl oo extension +

    +
  12. +
  13. +

    +The exec command now only uses vfork(), not fork() +

    +
  14. +
  15. +

    +Unit test framework is less verbose and more Tcl-compatible +

    +
  16. +
  17. +

    +Optional UTF-8 support +

    +
  18. +
  19. +

    +Optional built-in regexp engine for better Tcl compatibility and UTF-8 support +

    +
  20. +
  21. +

    +Command line editing in interactive mode, e.g. jimsh +

    +
  22. +
+
+
+

In v0.63

+
    +
  1. +

    +source now checks that a script is complete (.i.e. not missing a brace) +

    +
  2. +
  3. +

    +info complete now uses the real parser and so is 100% accurate +

    +
  4. +
  5. +

    +Better access to live stack frames with info frame, stacktrace and stackdump +

    +
  6. +
  7. +

    +tailcall no longer loses stack trace information +

    +
  8. +
  9. +

    +Add alias and curry +

    +
  10. +
  11. +

    +lambda, alias and curry are implemented via tailcall for efficiency +

    +
  12. +
  13. +

    +local allows procedures to be deleted automatically at the end of the current procedure +

    +
  14. +
  15. +

    +udp sockets are now supported for both clients and servers. +

    +
  16. +
  17. +

    +vfork-based exec is now working correctly +

    +
  18. +
  19. +

    +Add file tempfile +

    +
  20. +
  21. +

    +Add socket pipe +

    +
  22. +
  23. +

    +Enhance try … on … finally to be more Tcl 8.6 compatible +

    +
  24. +
  25. +

    +It is now possible to return from within try +

    +
  26. +
  27. +

    +IPv6 support is now included +

    +
  28. +
  29. +

    +Add string is +

    +
  30. +
  31. +

    +Event handlers works better if an error occurs. eof handler has been removed. +

    +
  32. +
  33. +

    +exec now sets $::errorCode, and catch sets opts(-errorcode) for exit status +

    +
  34. +
  35. +

    +Command pipelines via open "|…" are now supported +

    +
  36. +
  37. +

    +pid can now return pids of a command pipeline +

    +
  38. +
  39. +

    +Add info references +

    +
  40. +
  41. +

    +Add support for after 'ms, 'after idle, after info, update +

    +
  42. +
  43. +

    +exec now sets environment based on $::env +

    +
  44. +
  45. +

    +Add dict keys +

    +
  46. +
  47. +

    +Add support for lsort -index +

    +
  48. +
+
+
+

In v0.62

+
    +
  1. +

    +Add support to exec for >&, >>&, |&, 2>@1 +

    +
  2. +
  3. +

    +Fix exec error messages when special token (e.g. >) is the last token +

    +
  4. +
  5. +

    +Fix subst handling of backslash escapes. +

    +
  6. +
  7. +

    +Allow abbreviated options for subst +

    +
  8. +
  9. +

    +Add support for return, break, continue in subst +

    +
  10. +
  11. +

    +Many expr bug fixes +

    +
  12. +
  13. +

    +Add support for functions in expr (e.g. int(), abs()), and also in, ni list operations +

    +
  14. +
  15. +

    +The variable name argument to regsub is now optional +

    +
  16. +
  17. +

    +Add support for unset -nocomplain +

    +
  18. +
  19. +

    +Add support for list commands: lassign, lrepeat +

    +
  20. +
  21. +

    +Fully-functional lsearch is now implemented +

    +
  22. +
  23. +

    +Add info nameofexecutable and info returncodes +

    +
  24. +
  25. +

    +Allow catch to determine what return codes are caught +

    +
  26. +
  27. +

    +Allow incr to increment an unset variable by first setting to 0 +

    +
  28. +
  29. +

    +Allow args and optional arguments to the left or required arguments in proc +

    +
  30. +
  31. +

    +Add file copy +

    +
  32. +
  33. +

    +Add try … finally command +

    +
  34. +
+
+
+
+
+

LICENCE

+
+
+
+
Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
+Copyright 2005 Clemens Hintze <c.hintze@gmx.net>
+Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>
+Copyright 2008 oharboe - Oyvind Harboe - oyvind.harboe@zylin.com
+Copyright 2008 Andrew Lunn <andrew@lunn.ch>
+Copyright 2008 Duane Ellis <openocd@duaneellis.com>
+Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>
+Copyright 2009 Steve Bennett <steveb@workware.net.au>
+
+
+
+
Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above
+   copyright notice, this list of conditions and the following
+   disclaimer in the documentation and/or other materials
+   provided with the distribution.
+
+
+
+
THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
The views and conclusions contained in the software and documentation
+are those of the authors and should not be interpreted as representing
+official policies, either expressed or implied, of the Jim Tcl Project.
+
+
+
+
+

+ + + diff --git a/debuggers/openocd/jimtcl/UnicodeData.txt b/debuggers/openocd/jimtcl/UnicodeData.txt new file mode 100644 index 00000000..6b01d90a --- /dev/null +++ b/debuggers/openocd/jimtcl/UnicodeData.txt @@ -0,0 +1,21829 @@ +0000;;Cc;0;BN;;;;;N;NULL;;;; +0001;;Cc;0;BN;;;;;N;START OF HEADING;;;; +0002;;Cc;0;BN;;;;;N;START OF TEXT;;;; +0003;;Cc;0;BN;;;;;N;END OF TEXT;;;; +0004;;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;; +0005;;Cc;0;BN;;;;;N;ENQUIRY;;;; +0006;;Cc;0;BN;;;;;N;ACKNOWLEDGE;;;; +0007;;Cc;0;BN;;;;;N;BELL;;;; +0008;;Cc;0;BN;;;;;N;BACKSPACE;;;; +0009;;Cc;0;S;;;;;N;CHARACTER TABULATION;;;; +000A;;Cc;0;B;;;;;N;LINE FEED (LF);;;; +000B;;Cc;0;S;;;;;N;LINE TABULATION;;;; +000C;;Cc;0;WS;;;;;N;FORM FEED (FF);;;; +000D;;Cc;0;B;;;;;N;CARRIAGE RETURN (CR);;;; +000E;;Cc;0;BN;;;;;N;SHIFT OUT;;;; +000F;;Cc;0;BN;;;;;N;SHIFT IN;;;; +0010;;Cc;0;BN;;;;;N;DATA LINK ESCAPE;;;; +0011;;Cc;0;BN;;;;;N;DEVICE CONTROL ONE;;;; +0012;;Cc;0;BN;;;;;N;DEVICE CONTROL TWO;;;; +0013;;Cc;0;BN;;;;;N;DEVICE CONTROL THREE;;;; +0014;;Cc;0;BN;;;;;N;DEVICE CONTROL FOUR;;;; +0015;;Cc;0;BN;;;;;N;NEGATIVE ACKNOWLEDGE;;;; +0016;;Cc;0;BN;;;;;N;SYNCHRONOUS IDLE;;;; +0017;;Cc;0;BN;;;;;N;END OF TRANSMISSION BLOCK;;;; +0018;;Cc;0;BN;;;;;N;CANCEL;;;; +0019;;Cc;0;BN;;;;;N;END OF MEDIUM;;;; +001A;;Cc;0;BN;;;;;N;SUBSTITUTE;;;; +001B;;Cc;0;BN;;;;;N;ESCAPE;;;; +001C;;Cc;0;B;;;;;N;INFORMATION SEPARATOR FOUR;;;; +001D;;Cc;0;B;;;;;N;INFORMATION SEPARATOR THREE;;;; +001E;;Cc;0;B;;;;;N;INFORMATION SEPARATOR TWO;;;; +001F;;Cc;0;S;;;;;N;INFORMATION SEPARATOR ONE;;;; +0020;SPACE;Zs;0;WS;;;;;N;;;;; +0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;; +0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;; +0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;; +0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;; +0026;AMPERSAND;Po;0;ON;;;;;N;;;;; +0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;; +0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;; +0029;RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;CLOSING PARENTHESIS;;;; +002A;ASTERISK;Po;0;ON;;;;;N;;;;; +002B;PLUS SIGN;Sm;0;ES;;;;;N;;;;; +002C;COMMA;Po;0;CS;;;;;N;;;;; +002D;HYPHEN-MINUS;Pd;0;ES;;;;;N;;;;; +002E;FULL STOP;Po;0;CS;;;;;N;PERIOD;;;; +002F;SOLIDUS;Po;0;CS;;;;;N;SLASH;;;; +0030;DIGIT ZERO;Nd;0;EN;;0;0;0;N;;;;; +0031;DIGIT ONE;Nd;0;EN;;1;1;1;N;;;;; +0032;DIGIT TWO;Nd;0;EN;;2;2;2;N;;;;; +0033;DIGIT THREE;Nd;0;EN;;3;3;3;N;;;;; +0034;DIGIT FOUR;Nd;0;EN;;4;4;4;N;;;;; +0035;DIGIT FIVE;Nd;0;EN;;5;5;5;N;;;;; +0036;DIGIT SIX;Nd;0;EN;;6;6;6;N;;;;; +0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;; +0038;DIGIT EIGHT;Nd;0;EN;;8;8;8;N;;;;; +0039;DIGIT NINE;Nd;0;EN;;9;9;9;N;;;;; +003A;COLON;Po;0;CS;;;;;N;;;;; +003B;SEMICOLON;Po;0;ON;;;;;N;;;;; +003C;LESS-THAN SIGN;Sm;0;ON;;;;;Y;;;;; +003D;EQUALS SIGN;Sm;0;ON;;;;;N;;;;; +003E;GREATER-THAN SIGN;Sm;0;ON;;;;;Y;;;;; +003F;QUESTION MARK;Po;0;ON;;;;;N;;;;; +0040;COMMERCIAL AT;Po;0;ON;;;;;N;;;;; +0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061; +0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062; +0043;LATIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;0063; +0044;LATIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;0064; +0045;LATIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;0065; +0046;LATIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;0066; +0047;LATIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;0067; +0048;LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;;0068; +0049;LATIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;0069; +004A;LATIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;006A; +004B;LATIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;006B; +004C;LATIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;006C; +004D;LATIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;006D; +004E;LATIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;006E; +004F;LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F; +0050;LATIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;0070; +0051;LATIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;0071; +0052;LATIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;0072; +0053;LATIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;0073; +0054;LATIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;0074; +0055;LATIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0075; +0056;LATIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;0076; +0057;LATIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;0077; +0058;LATIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;0078; +0059;LATIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;0079; +005A;LATIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;007A; +005B;LEFT SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING SQUARE BRACKET;;;; +005C;REVERSE SOLIDUS;Po;0;ON;;;;;N;BACKSLASH;;;; +005D;RIGHT SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING SQUARE BRACKET;;;; +005E;CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;SPACING CIRCUMFLEX;;;; +005F;LOW LINE;Pc;0;ON;;;;;N;SPACING UNDERSCORE;;;; +0060;GRAVE ACCENT;Sk;0;ON;;;;;N;SPACING GRAVE;;;; +0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041 +0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042 +0063;LATIN SMALL LETTER C;Ll;0;L;;;;;N;;;0043;;0043 +0064;LATIN SMALL LETTER D;Ll;0;L;;;;;N;;;0044;;0044 +0065;LATIN SMALL LETTER E;Ll;0;L;;;;;N;;;0045;;0045 +0066;LATIN SMALL LETTER F;Ll;0;L;;;;;N;;;0046;;0046 +0067;LATIN SMALL LETTER G;Ll;0;L;;;;;N;;;0047;;0047 +0068;LATIN SMALL LETTER H;Ll;0;L;;;;;N;;;0048;;0048 +0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049 +006A;LATIN SMALL LETTER J;Ll;0;L;;;;;N;;;004A;;004A +006B;LATIN SMALL LETTER K;Ll;0;L;;;;;N;;;004B;;004B +006C;LATIN SMALL LETTER L;Ll;0;L;;;;;N;;;004C;;004C +006D;LATIN SMALL LETTER M;Ll;0;L;;;;;N;;;004D;;004D +006E;LATIN SMALL LETTER N;Ll;0;L;;;;;N;;;004E;;004E +006F;LATIN SMALL LETTER O;Ll;0;L;;;;;N;;;004F;;004F +0070;LATIN SMALL LETTER P;Ll;0;L;;;;;N;;;0050;;0050 +0071;LATIN SMALL LETTER Q;Ll;0;L;;;;;N;;;0051;;0051 +0072;LATIN SMALL LETTER R;Ll;0;L;;;;;N;;;0052;;0052 +0073;LATIN SMALL LETTER S;Ll;0;L;;;;;N;;;0053;;0053 +0074;LATIN SMALL LETTER T;Ll;0;L;;;;;N;;;0054;;0054 +0075;LATIN SMALL LETTER U;Ll;0;L;;;;;N;;;0055;;0055 +0076;LATIN SMALL LETTER V;Ll;0;L;;;;;N;;;0056;;0056 +0077;LATIN SMALL LETTER W;Ll;0;L;;;;;N;;;0057;;0057 +0078;LATIN SMALL LETTER X;Ll;0;L;;;;;N;;;0058;;0058 +0079;LATIN SMALL LETTER Y;Ll;0;L;;;;;N;;;0059;;0059 +007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A +007B;LEFT CURLY BRACKET;Ps;0;ON;;;;;Y;OPENING CURLY BRACKET;;;; +007C;VERTICAL LINE;Sm;0;ON;;;;;N;VERTICAL BAR;;;; +007D;RIGHT CURLY BRACKET;Pe;0;ON;;;;;Y;CLOSING CURLY BRACKET;;;; +007E;TILDE;Sm;0;ON;;;;;N;;;;; +007F;;Cc;0;BN;;;;;N;DELETE;;;; +0080;;Cc;0;BN;;;;;N;;;;; +0081;;Cc;0;BN;;;;;N;;;;; +0082;;Cc;0;BN;;;;;N;BREAK PERMITTED HERE;;;; +0083;;Cc;0;BN;;;;;N;NO BREAK HERE;;;; +0084;;Cc;0;BN;;;;;N;;;;; +0085;;Cc;0;B;;;;;N;NEXT LINE (NEL);;;; +0086;;Cc;0;BN;;;;;N;START OF SELECTED AREA;;;; +0087;;Cc;0;BN;;;;;N;END OF SELECTED AREA;;;; +0088;;Cc;0;BN;;;;;N;CHARACTER TABULATION SET;;;; +0089;;Cc;0;BN;;;;;N;CHARACTER TABULATION WITH JUSTIFICATION;;;; +008A;;Cc;0;BN;;;;;N;LINE TABULATION SET;;;; +008B;;Cc;0;BN;;;;;N;PARTIAL LINE FORWARD;;;; +008C;;Cc;0;BN;;;;;N;PARTIAL LINE BACKWARD;;;; +008D;;Cc;0;BN;;;;;N;REVERSE LINE FEED;;;; +008E;;Cc;0;BN;;;;;N;SINGLE SHIFT TWO;;;; +008F;;Cc;0;BN;;;;;N;SINGLE SHIFT THREE;;;; +0090;;Cc;0;BN;;;;;N;DEVICE CONTROL STRING;;;; +0091;;Cc;0;BN;;;;;N;PRIVATE USE ONE;;;; +0092;;Cc;0;BN;;;;;N;PRIVATE USE TWO;;;; +0093;;Cc;0;BN;;;;;N;SET TRANSMIT STATE;;;; +0094;;Cc;0;BN;;;;;N;CANCEL CHARACTER;;;; +0095;;Cc;0;BN;;;;;N;MESSAGE WAITING;;;; +0096;;Cc;0;BN;;;;;N;START OF GUARDED AREA;;;; +0097;;Cc;0;BN;;;;;N;END OF GUARDED AREA;;;; +0098;;Cc;0;BN;;;;;N;START OF STRING;;;; +0099;;Cc;0;BN;;;;;N;;;;; +009A;;Cc;0;BN;;;;;N;SINGLE CHARACTER INTRODUCER;;;; +009B;;Cc;0;BN;;;;;N;CONTROL SEQUENCE INTRODUCER;;;; +009C;;Cc;0;BN;;;;;N;STRING TERMINATOR;;;; +009D;;Cc;0;BN;;;;;N;OPERATING SYSTEM COMMAND;;;; +009E;;Cc;0;BN;;;;;N;PRIVACY MESSAGE;;;; +009F;;Cc;0;BN;;;;;N;APPLICATION PROGRAM COMMAND;;;; +00A0;NO-BREAK SPACE;Zs;0;CS; 0020;;;;N;NON-BREAKING SPACE;;;; +00A1;INVERTED EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +00A2;CENT SIGN;Sc;0;ET;;;;;N;;;;; +00A3;POUND SIGN;Sc;0;ET;;;;;N;;;;; +00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;; +00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;; +00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;; +00A7;SECTION SIGN;So;0;ON;;;;;N;;;;; +00A8;DIAERESIS;Sk;0;ON; 0020 0308;;;;N;SPACING DIAERESIS;;;; +00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;; +00AA;FEMININE ORDINAL INDICATOR;Ll;0;L; 0061;;;;N;;;;; +00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;;;; +00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;; +00AD;SOFT HYPHEN;Cf;0;BN;;;;;N;;;;; +00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;; +00AF;MACRON;Sk;0;ON; 0020 0304;;;;N;SPACING MACRON;;;; +00B0;DEGREE SIGN;So;0;ET;;;;;N;;;;; +00B1;PLUS-MINUS SIGN;Sm;0;ET;;;;;N;PLUS-OR-MINUS SIGN;;;; +00B2;SUPERSCRIPT TWO;No;0;EN; 0032;;2;2;N;SUPERSCRIPT DIGIT TWO;;;; +00B3;SUPERSCRIPT THREE;No;0;EN; 0033;;3;3;N;SUPERSCRIPT DIGIT THREE;;;; +00B4;ACUTE ACCENT;Sk;0;ON; 0020 0301;;;;N;SPACING ACUTE;;;; +00B5;MICRO SIGN;Ll;0;L; 03BC;;;;N;;;039C;;039C +00B6;PILCROW SIGN;So;0;ON;;;;;N;PARAGRAPH SIGN;;;; +00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;; +00B8;CEDILLA;Sk;0;ON; 0020 0327;;;;N;SPACING CEDILLA;;;; +00B9;SUPERSCRIPT ONE;No;0;EN; 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;; +00BA;MASCULINE ORDINAL INDICATOR;Ll;0;L; 006F;;;;N;;;;; +00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;;;; +00BC;VULGAR FRACTION ONE QUARTER;No;0;ON; 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;; +00BD;VULGAR FRACTION ONE HALF;No;0;ON; 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;; +00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON; 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;; +00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;; +00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0; +00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1; +00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2; +00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3; +00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4; +00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5; +00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;;;00E6; +00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7; +00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8; +00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9; +00CA;LATIN CAPITAL LETTER E WITH CIRCUMFLEX;Lu;0;L;0045 0302;;;;N;LATIN CAPITAL LETTER E CIRCUMFLEX;;;00EA; +00CB;LATIN CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;0045 0308;;;;N;LATIN CAPITAL LETTER E DIAERESIS;;;00EB; +00CC;LATIN CAPITAL LETTER I WITH GRAVE;Lu;0;L;0049 0300;;;;N;LATIN CAPITAL LETTER I GRAVE;;;00EC; +00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED; +00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE; +00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF; +00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;00F0; +00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1; +00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2; +00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3; +00D4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX;Lu;0;L;004F 0302;;;;N;LATIN CAPITAL LETTER O CIRCUMFLEX;;;00F4; +00D5;LATIN CAPITAL LETTER O WITH TILDE;Lu;0;L;004F 0303;;;;N;LATIN CAPITAL LETTER O TILDE;;;00F5; +00D6;LATIN CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;004F 0308;;;;N;LATIN CAPITAL LETTER O DIAERESIS;;;00F6; +00D7;MULTIPLICATION SIGN;Sm;0;ON;;;;;N;;;;; +00D8;LATIN CAPITAL LETTER O WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O SLASH;;;00F8; +00D9;LATIN CAPITAL LETTER U WITH GRAVE;Lu;0;L;0055 0300;;;;N;LATIN CAPITAL LETTER U GRAVE;;;00F9; +00DA;LATIN CAPITAL LETTER U WITH ACUTE;Lu;0;L;0055 0301;;;;N;LATIN CAPITAL LETTER U ACUTE;;;00FA; +00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB; +00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC; +00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD; +00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;;;00FE; +00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;;;; +00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0 +00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1 +00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2 +00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3 +00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4 +00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5 +00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;;00C6;;00C6 +00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7 +00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8 +00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9 +00EA;LATIN SMALL LETTER E WITH CIRCUMFLEX;Ll;0;L;0065 0302;;;;N;LATIN SMALL LETTER E CIRCUMFLEX;;00CA;;00CA +00EB;LATIN SMALL LETTER E WITH DIAERESIS;Ll;0;L;0065 0308;;;;N;LATIN SMALL LETTER E DIAERESIS;;00CB;;00CB +00EC;LATIN SMALL LETTER I WITH GRAVE;Ll;0;L;0069 0300;;;;N;LATIN SMALL LETTER I GRAVE;;00CC;;00CC +00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD +00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE +00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF +00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;;00D0;;00D0 +00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1 +00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2 +00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3 +00F4;LATIN SMALL LETTER O WITH CIRCUMFLEX;Ll;0;L;006F 0302;;;;N;LATIN SMALL LETTER O CIRCUMFLEX;;00D4;;00D4 +00F5;LATIN SMALL LETTER O WITH TILDE;Ll;0;L;006F 0303;;;;N;LATIN SMALL LETTER O TILDE;;00D5;;00D5 +00F6;LATIN SMALL LETTER O WITH DIAERESIS;Ll;0;L;006F 0308;;;;N;LATIN SMALL LETTER O DIAERESIS;;00D6;;00D6 +00F7;DIVISION SIGN;Sm;0;ON;;;;;N;;;;; +00F8;LATIN SMALL LETTER O WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER O SLASH;;00D8;;00D8 +00F9;LATIN SMALL LETTER U WITH GRAVE;Ll;0;L;0075 0300;;;;N;LATIN SMALL LETTER U GRAVE;;00D9;;00D9 +00FA;LATIN SMALL LETTER U WITH ACUTE;Ll;0;L;0075 0301;;;;N;LATIN SMALL LETTER U ACUTE;;00DA;;00DA +00FB;LATIN SMALL LETTER U WITH CIRCUMFLEX;Ll;0;L;0075 0302;;;;N;LATIN SMALL LETTER U CIRCUMFLEX;;00DB;;00DB +00FC;LATIN SMALL LETTER U WITH DIAERESIS;Ll;0;L;0075 0308;;;;N;LATIN SMALL LETTER U DIAERESIS;;00DC;;00DC +00FD;LATIN SMALL LETTER Y WITH ACUTE;Ll;0;L;0079 0301;;;;N;LATIN SMALL LETTER Y ACUTE;;00DD;;00DD +00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;;00DE;;00DE +00FF;LATIN SMALL LETTER Y WITH DIAERESIS;Ll;0;L;0079 0308;;;;N;LATIN SMALL LETTER Y DIAERESIS;;0178;;0178 +0100;LATIN CAPITAL LETTER A WITH MACRON;Lu;0;L;0041 0304;;;;N;LATIN CAPITAL LETTER A MACRON;;;0101; +0101;LATIN SMALL LETTER A WITH MACRON;Ll;0;L;0061 0304;;;;N;LATIN SMALL LETTER A MACRON;;0100;;0100 +0102;LATIN CAPITAL LETTER A WITH BREVE;Lu;0;L;0041 0306;;;;N;LATIN CAPITAL LETTER A BREVE;;;0103; +0103;LATIN SMALL LETTER A WITH BREVE;Ll;0;L;0061 0306;;;;N;LATIN SMALL LETTER A BREVE;;0102;;0102 +0104;LATIN CAPITAL LETTER A WITH OGONEK;Lu;0;L;0041 0328;;;;N;LATIN CAPITAL LETTER A OGONEK;;;0105; +0105;LATIN SMALL LETTER A WITH OGONEK;Ll;0;L;0061 0328;;;;N;LATIN SMALL LETTER A OGONEK;;0104;;0104 +0106;LATIN CAPITAL LETTER C WITH ACUTE;Lu;0;L;0043 0301;;;;N;LATIN CAPITAL LETTER C ACUTE;;;0107; +0107;LATIN SMALL LETTER C WITH ACUTE;Ll;0;L;0063 0301;;;;N;LATIN SMALL LETTER C ACUTE;;0106;;0106 +0108;LATIN CAPITAL LETTER C WITH CIRCUMFLEX;Lu;0;L;0043 0302;;;;N;LATIN CAPITAL LETTER C CIRCUMFLEX;;;0109; +0109;LATIN SMALL LETTER C WITH CIRCUMFLEX;Ll;0;L;0063 0302;;;;N;LATIN SMALL LETTER C CIRCUMFLEX;;0108;;0108 +010A;LATIN CAPITAL LETTER C WITH DOT ABOVE;Lu;0;L;0043 0307;;;;N;LATIN CAPITAL LETTER C DOT;;;010B; +010B;LATIN SMALL LETTER C WITH DOT ABOVE;Ll;0;L;0063 0307;;;;N;LATIN SMALL LETTER C DOT;;010A;;010A +010C;LATIN CAPITAL LETTER C WITH CARON;Lu;0;L;0043 030C;;;;N;LATIN CAPITAL LETTER C HACEK;;;010D; +010D;LATIN SMALL LETTER C WITH CARON;Ll;0;L;0063 030C;;;;N;LATIN SMALL LETTER C HACEK;;010C;;010C +010E;LATIN CAPITAL LETTER D WITH CARON;Lu;0;L;0044 030C;;;;N;LATIN CAPITAL LETTER D HACEK;;;010F; +010F;LATIN SMALL LETTER D WITH CARON;Ll;0;L;0064 030C;;;;N;LATIN SMALL LETTER D HACEK;;010E;;010E +0110;LATIN CAPITAL LETTER D WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D BAR;;;0111; +0111;LATIN SMALL LETTER D WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER D BAR;;0110;;0110 +0112;LATIN CAPITAL LETTER E WITH MACRON;Lu;0;L;0045 0304;;;;N;LATIN CAPITAL LETTER E MACRON;;;0113; +0113;LATIN SMALL LETTER E WITH MACRON;Ll;0;L;0065 0304;;;;N;LATIN SMALL LETTER E MACRON;;0112;;0112 +0114;LATIN CAPITAL LETTER E WITH BREVE;Lu;0;L;0045 0306;;;;N;LATIN CAPITAL LETTER E BREVE;;;0115; +0115;LATIN SMALL LETTER E WITH BREVE;Ll;0;L;0065 0306;;;;N;LATIN SMALL LETTER E BREVE;;0114;;0114 +0116;LATIN CAPITAL LETTER E WITH DOT ABOVE;Lu;0;L;0045 0307;;;;N;LATIN CAPITAL LETTER E DOT;;;0117; +0117;LATIN SMALL LETTER E WITH DOT ABOVE;Ll;0;L;0065 0307;;;;N;LATIN SMALL LETTER E DOT;;0116;;0116 +0118;LATIN CAPITAL LETTER E WITH OGONEK;Lu;0;L;0045 0328;;;;N;LATIN CAPITAL LETTER E OGONEK;;;0119; +0119;LATIN SMALL LETTER E WITH OGONEK;Ll;0;L;0065 0328;;;;N;LATIN SMALL LETTER E OGONEK;;0118;;0118 +011A;LATIN CAPITAL LETTER E WITH CARON;Lu;0;L;0045 030C;;;;N;LATIN CAPITAL LETTER E HACEK;;;011B; +011B;LATIN SMALL LETTER E WITH CARON;Ll;0;L;0065 030C;;;;N;LATIN SMALL LETTER E HACEK;;011A;;011A +011C;LATIN CAPITAL LETTER G WITH CIRCUMFLEX;Lu;0;L;0047 0302;;;;N;LATIN CAPITAL LETTER G CIRCUMFLEX;;;011D; +011D;LATIN SMALL LETTER G WITH CIRCUMFLEX;Ll;0;L;0067 0302;;;;N;LATIN SMALL LETTER G CIRCUMFLEX;;011C;;011C +011E;LATIN CAPITAL LETTER G WITH BREVE;Lu;0;L;0047 0306;;;;N;LATIN CAPITAL LETTER G BREVE;;;011F; +011F;LATIN SMALL LETTER G WITH BREVE;Ll;0;L;0067 0306;;;;N;LATIN SMALL LETTER G BREVE;;011E;;011E +0120;LATIN CAPITAL LETTER G WITH DOT ABOVE;Lu;0;L;0047 0307;;;;N;LATIN CAPITAL LETTER G DOT;;;0121; +0121;LATIN SMALL LETTER G WITH DOT ABOVE;Ll;0;L;0067 0307;;;;N;LATIN SMALL LETTER G DOT;;0120;;0120 +0122;LATIN CAPITAL LETTER G WITH CEDILLA;Lu;0;L;0047 0327;;;;N;LATIN CAPITAL LETTER G CEDILLA;;;0123; +0123;LATIN SMALL LETTER G WITH CEDILLA;Ll;0;L;0067 0327;;;;N;LATIN SMALL LETTER G CEDILLA;;0122;;0122 +0124;LATIN CAPITAL LETTER H WITH CIRCUMFLEX;Lu;0;L;0048 0302;;;;N;LATIN CAPITAL LETTER H CIRCUMFLEX;;;0125; +0125;LATIN SMALL LETTER H WITH CIRCUMFLEX;Ll;0;L;0068 0302;;;;N;LATIN SMALL LETTER H CIRCUMFLEX;;0124;;0124 +0126;LATIN CAPITAL LETTER H WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER H BAR;;;0127; +0127;LATIN SMALL LETTER H WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER H BAR;;0126;;0126 +0128;LATIN CAPITAL LETTER I WITH TILDE;Lu;0;L;0049 0303;;;;N;LATIN CAPITAL LETTER I TILDE;;;0129; +0129;LATIN SMALL LETTER I WITH TILDE;Ll;0;L;0069 0303;;;;N;LATIN SMALL LETTER I TILDE;;0128;;0128 +012A;LATIN CAPITAL LETTER I WITH MACRON;Lu;0;L;0049 0304;;;;N;LATIN CAPITAL LETTER I MACRON;;;012B; +012B;LATIN SMALL LETTER I WITH MACRON;Ll;0;L;0069 0304;;;;N;LATIN SMALL LETTER I MACRON;;012A;;012A +012C;LATIN CAPITAL LETTER I WITH BREVE;Lu;0;L;0049 0306;;;;N;LATIN CAPITAL LETTER I BREVE;;;012D; +012D;LATIN SMALL LETTER I WITH BREVE;Ll;0;L;0069 0306;;;;N;LATIN SMALL LETTER I BREVE;;012C;;012C +012E;LATIN CAPITAL LETTER I WITH OGONEK;Lu;0;L;0049 0328;;;;N;LATIN CAPITAL LETTER I OGONEK;;;012F; +012F;LATIN SMALL LETTER I WITH OGONEK;Ll;0;L;0069 0328;;;;N;LATIN SMALL LETTER I OGONEK;;012E;;012E +0130;LATIN CAPITAL LETTER I WITH DOT ABOVE;Lu;0;L;0049 0307;;;;N;LATIN CAPITAL LETTER I DOT;;;0069; +0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049 +0132;LATIN CAPITAL LIGATURE IJ;Lu;0;L; 0049 004A;;;;N;LATIN CAPITAL LETTER I J;;;0133; +0133;LATIN SMALL LIGATURE IJ;Ll;0;L; 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132 +0134;LATIN CAPITAL LETTER J WITH CIRCUMFLEX;Lu;0;L;004A 0302;;;;N;LATIN CAPITAL LETTER J CIRCUMFLEX;;;0135; +0135;LATIN SMALL LETTER J WITH CIRCUMFLEX;Ll;0;L;006A 0302;;;;N;LATIN SMALL LETTER J CIRCUMFLEX;;0134;;0134 +0136;LATIN CAPITAL LETTER K WITH CEDILLA;Lu;0;L;004B 0327;;;;N;LATIN CAPITAL LETTER K CEDILLA;;;0137; +0137;LATIN SMALL LETTER K WITH CEDILLA;Ll;0;L;006B 0327;;;;N;LATIN SMALL LETTER K CEDILLA;;0136;;0136 +0138;LATIN SMALL LETTER KRA;Ll;0;L;;;;;N;;;;; +0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A; +013A;LATIN SMALL LETTER L WITH ACUTE;Ll;0;L;006C 0301;;;;N;LATIN SMALL LETTER L ACUTE;;0139;;0139 +013B;LATIN CAPITAL LETTER L WITH CEDILLA;Lu;0;L;004C 0327;;;;N;LATIN CAPITAL LETTER L CEDILLA;;;013C; +013C;LATIN SMALL LETTER L WITH CEDILLA;Ll;0;L;006C 0327;;;;N;LATIN SMALL LETTER L CEDILLA;;013B;;013B +013D;LATIN CAPITAL LETTER L WITH CARON;Lu;0;L;004C 030C;;;;N;LATIN CAPITAL LETTER L HACEK;;;013E; +013E;LATIN SMALL LETTER L WITH CARON;Ll;0;L;006C 030C;;;;N;LATIN SMALL LETTER L HACEK;;013D;;013D +013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L; 004C 00B7;;;;N;;;;0140; +0140;LATIN SMALL LETTER L WITH MIDDLE DOT;Ll;0;L; 006C 00B7;;;;N;;;013F;;013F +0141;LATIN CAPITAL LETTER L WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER L SLASH;;;0142; +0142;LATIN SMALL LETTER L WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER L SLASH;;0141;;0141 +0143;LATIN CAPITAL LETTER N WITH ACUTE;Lu;0;L;004E 0301;;;;N;LATIN CAPITAL LETTER N ACUTE;;;0144; +0144;LATIN SMALL LETTER N WITH ACUTE;Ll;0;L;006E 0301;;;;N;LATIN SMALL LETTER N ACUTE;;0143;;0143 +0145;LATIN CAPITAL LETTER N WITH CEDILLA;Lu;0;L;004E 0327;;;;N;LATIN CAPITAL LETTER N CEDILLA;;;0146; +0146;LATIN SMALL LETTER N WITH CEDILLA;Ll;0;L;006E 0327;;;;N;LATIN SMALL LETTER N CEDILLA;;0145;;0145 +0147;LATIN CAPITAL LETTER N WITH CARON;Lu;0;L;004E 030C;;;;N;LATIN CAPITAL LETTER N HACEK;;;0148; +0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147 +0149;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE;Ll;0;L; 02BC 006E;;;;N;LATIN SMALL LETTER APOSTROPHE N;;;; +014A;LATIN CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;014B; +014B;LATIN SMALL LETTER ENG;Ll;0;L;;;;;N;;;014A;;014A +014C;LATIN CAPITAL LETTER O WITH MACRON;Lu;0;L;004F 0304;;;;N;LATIN CAPITAL LETTER O MACRON;;;014D; +014D;LATIN SMALL LETTER O WITH MACRON;Ll;0;L;006F 0304;;;;N;LATIN SMALL LETTER O MACRON;;014C;;014C +014E;LATIN CAPITAL LETTER O WITH BREVE;Lu;0;L;004F 0306;;;;N;LATIN CAPITAL LETTER O BREVE;;;014F; +014F;LATIN SMALL LETTER O WITH BREVE;Ll;0;L;006F 0306;;;;N;LATIN SMALL LETTER O BREVE;;014E;;014E +0150;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE;Lu;0;L;004F 030B;;;;N;LATIN CAPITAL LETTER O DOUBLE ACUTE;;;0151; +0151;LATIN SMALL LETTER O WITH DOUBLE ACUTE;Ll;0;L;006F 030B;;;;N;LATIN SMALL LETTER O DOUBLE ACUTE;;0150;;0150 +0152;LATIN CAPITAL LIGATURE OE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O E;;;0153; +0153;LATIN SMALL LIGATURE OE;Ll;0;L;;;;;N;LATIN SMALL LETTER O E;;0152;;0152 +0154;LATIN CAPITAL LETTER R WITH ACUTE;Lu;0;L;0052 0301;;;;N;LATIN CAPITAL LETTER R ACUTE;;;0155; +0155;LATIN SMALL LETTER R WITH ACUTE;Ll;0;L;0072 0301;;;;N;LATIN SMALL LETTER R ACUTE;;0154;;0154 +0156;LATIN CAPITAL LETTER R WITH CEDILLA;Lu;0;L;0052 0327;;;;N;LATIN CAPITAL LETTER R CEDILLA;;;0157; +0157;LATIN SMALL LETTER R WITH CEDILLA;Ll;0;L;0072 0327;;;;N;LATIN SMALL LETTER R CEDILLA;;0156;;0156 +0158;LATIN CAPITAL LETTER R WITH CARON;Lu;0;L;0052 030C;;;;N;LATIN CAPITAL LETTER R HACEK;;;0159; +0159;LATIN SMALL LETTER R WITH CARON;Ll;0;L;0072 030C;;;;N;LATIN SMALL LETTER R HACEK;;0158;;0158 +015A;LATIN CAPITAL LETTER S WITH ACUTE;Lu;0;L;0053 0301;;;;N;LATIN CAPITAL LETTER S ACUTE;;;015B; +015B;LATIN SMALL LETTER S WITH ACUTE;Ll;0;L;0073 0301;;;;N;LATIN SMALL LETTER S ACUTE;;015A;;015A +015C;LATIN CAPITAL LETTER S WITH CIRCUMFLEX;Lu;0;L;0053 0302;;;;N;LATIN CAPITAL LETTER S CIRCUMFLEX;;;015D; +015D;LATIN SMALL LETTER S WITH CIRCUMFLEX;Ll;0;L;0073 0302;;;;N;LATIN SMALL LETTER S CIRCUMFLEX;;015C;;015C +015E;LATIN CAPITAL LETTER S WITH CEDILLA;Lu;0;L;0053 0327;;;;N;LATIN CAPITAL LETTER S CEDILLA;;;015F; +015F;LATIN SMALL LETTER S WITH CEDILLA;Ll;0;L;0073 0327;;;;N;LATIN SMALL LETTER S CEDILLA;;015E;;015E +0160;LATIN CAPITAL LETTER S WITH CARON;Lu;0;L;0053 030C;;;;N;LATIN CAPITAL LETTER S HACEK;;;0161; +0161;LATIN SMALL LETTER S WITH CARON;Ll;0;L;0073 030C;;;;N;LATIN SMALL LETTER S HACEK;;0160;;0160 +0162;LATIN CAPITAL LETTER T WITH CEDILLA;Lu;0;L;0054 0327;;;;N;LATIN CAPITAL LETTER T CEDILLA;;;0163; +0163;LATIN SMALL LETTER T WITH CEDILLA;Ll;0;L;0074 0327;;;;N;LATIN SMALL LETTER T CEDILLA;;0162;;0162 +0164;LATIN CAPITAL LETTER T WITH CARON;Lu;0;L;0054 030C;;;;N;LATIN CAPITAL LETTER T HACEK;;;0165; +0165;LATIN SMALL LETTER T WITH CARON;Ll;0;L;0074 030C;;;;N;LATIN SMALL LETTER T HACEK;;0164;;0164 +0166;LATIN CAPITAL LETTER T WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T BAR;;;0167; +0167;LATIN SMALL LETTER T WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER T BAR;;0166;;0166 +0168;LATIN CAPITAL LETTER U WITH TILDE;Lu;0;L;0055 0303;;;;N;LATIN CAPITAL LETTER U TILDE;;;0169; +0169;LATIN SMALL LETTER U WITH TILDE;Ll;0;L;0075 0303;;;;N;LATIN SMALL LETTER U TILDE;;0168;;0168 +016A;LATIN CAPITAL LETTER U WITH MACRON;Lu;0;L;0055 0304;;;;N;LATIN CAPITAL LETTER U MACRON;;;016B; +016B;LATIN SMALL LETTER U WITH MACRON;Ll;0;L;0075 0304;;;;N;LATIN SMALL LETTER U MACRON;;016A;;016A +016C;LATIN CAPITAL LETTER U WITH BREVE;Lu;0;L;0055 0306;;;;N;LATIN CAPITAL LETTER U BREVE;;;016D; +016D;LATIN SMALL LETTER U WITH BREVE;Ll;0;L;0075 0306;;;;N;LATIN SMALL LETTER U BREVE;;016C;;016C +016E;LATIN CAPITAL LETTER U WITH RING ABOVE;Lu;0;L;0055 030A;;;;N;LATIN CAPITAL LETTER U RING;;;016F; +016F;LATIN SMALL LETTER U WITH RING ABOVE;Ll;0;L;0075 030A;;;;N;LATIN SMALL LETTER U RING;;016E;;016E +0170;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0055 030B;;;;N;LATIN CAPITAL LETTER U DOUBLE ACUTE;;;0171; +0171;LATIN SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0075 030B;;;;N;LATIN SMALL LETTER U DOUBLE ACUTE;;0170;;0170 +0172;LATIN CAPITAL LETTER U WITH OGONEK;Lu;0;L;0055 0328;;;;N;LATIN CAPITAL LETTER U OGONEK;;;0173; +0173;LATIN SMALL LETTER U WITH OGONEK;Ll;0;L;0075 0328;;;;N;LATIN SMALL LETTER U OGONEK;;0172;;0172 +0174;LATIN CAPITAL LETTER W WITH CIRCUMFLEX;Lu;0;L;0057 0302;;;;N;LATIN CAPITAL LETTER W CIRCUMFLEX;;;0175; +0175;LATIN SMALL LETTER W WITH CIRCUMFLEX;Ll;0;L;0077 0302;;;;N;LATIN SMALL LETTER W CIRCUMFLEX;;0174;;0174 +0176;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX;Lu;0;L;0059 0302;;;;N;LATIN CAPITAL LETTER Y CIRCUMFLEX;;;0177; +0177;LATIN SMALL LETTER Y WITH CIRCUMFLEX;Ll;0;L;0079 0302;;;;N;LATIN SMALL LETTER Y CIRCUMFLEX;;0176;;0176 +0178;LATIN CAPITAL LETTER Y WITH DIAERESIS;Lu;0;L;0059 0308;;;;N;LATIN CAPITAL LETTER Y DIAERESIS;;;00FF; +0179;LATIN CAPITAL LETTER Z WITH ACUTE;Lu;0;L;005A 0301;;;;N;LATIN CAPITAL LETTER Z ACUTE;;;017A; +017A;LATIN SMALL LETTER Z WITH ACUTE;Ll;0;L;007A 0301;;;;N;LATIN SMALL LETTER Z ACUTE;;0179;;0179 +017B;LATIN CAPITAL LETTER Z WITH DOT ABOVE;Lu;0;L;005A 0307;;;;N;LATIN CAPITAL LETTER Z DOT;;;017C; +017C;LATIN SMALL LETTER Z WITH DOT ABOVE;Ll;0;L;007A 0307;;;;N;LATIN SMALL LETTER Z DOT;;017B;;017B +017D;LATIN CAPITAL LETTER Z WITH CARON;Lu;0;L;005A 030C;;;;N;LATIN CAPITAL LETTER Z HACEK;;;017E; +017E;LATIN SMALL LETTER Z WITH CARON;Ll;0;L;007A 030C;;;;N;LATIN SMALL LETTER Z HACEK;;017D;;017D +017F;LATIN SMALL LETTER LONG S;Ll;0;L; 0073;;;;N;;;0053;;0053 +0180;LATIN SMALL LETTER B WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER B BAR;;0243;;0243 +0181;LATIN CAPITAL LETTER B WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B HOOK;;;0253; +0182;LATIN CAPITAL LETTER B WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B TOPBAR;;;0183; +0183;LATIN SMALL LETTER B WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER B TOPBAR;;0182;;0182 +0184;LATIN CAPITAL LETTER TONE SIX;Lu;0;L;;;;;N;;;;0185; +0185;LATIN SMALL LETTER TONE SIX;Ll;0;L;;;;;N;;;0184;;0184 +0186;LATIN CAPITAL LETTER OPEN O;Lu;0;L;;;;;N;;;;0254; +0187;LATIN CAPITAL LETTER C WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER C HOOK;;;0188; +0188;LATIN SMALL LETTER C WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER C HOOK;;0187;;0187 +0189;LATIN CAPITAL LETTER AFRICAN D;Lu;0;L;;;;;N;;;;0256; +018A;LATIN CAPITAL LETTER D WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D HOOK;;;0257; +018B;LATIN CAPITAL LETTER D WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D TOPBAR;;;018C; +018C;LATIN SMALL LETTER D WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER D TOPBAR;;018B;;018B +018D;LATIN SMALL LETTER TURNED DELTA;Ll;0;L;;;;;N;;;;; +018E;LATIN CAPITAL LETTER REVERSED E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER TURNED E;;;01DD; +018F;LATIN CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;0259; +0190;LATIN CAPITAL LETTER OPEN E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER EPSILON;;;025B; +0191;LATIN CAPITAL LETTER F WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER F HOOK;;;0192; +0192;LATIN SMALL LETTER F WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT F;;0191;;0191 +0193;LATIN CAPITAL LETTER G WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G HOOK;;;0260; +0194;LATIN CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;0263; +0195;LATIN SMALL LETTER HV;Ll;0;L;;;;;N;LATIN SMALL LETTER H V;;01F6;;01F6 +0196;LATIN CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;0269; +0197;LATIN CAPITAL LETTER I WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED I;;;0268; +0198;LATIN CAPITAL LETTER K WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER K HOOK;;;0199; +0199;LATIN SMALL LETTER K WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER K HOOK;;0198;;0198 +019A;LATIN SMALL LETTER L WITH BAR;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED L;;023D;;023D +019B;LATIN SMALL LETTER LAMBDA WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED LAMBDA;;;; +019C;LATIN CAPITAL LETTER TURNED M;Lu;0;L;;;;;N;;;;026F; +019D;LATIN CAPITAL LETTER N WITH LEFT HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER N HOOK;;;0272; +019E;LATIN SMALL LETTER N WITH LONG RIGHT LEG;Ll;0;L;;;;;N;;;0220;;0220 +019F;LATIN CAPITAL LETTER O WITH MIDDLE TILDE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED O;;;0275; +01A0;LATIN CAPITAL LETTER O WITH HORN;Lu;0;L;004F 031B;;;;N;LATIN CAPITAL LETTER O HORN;;;01A1; +01A1;LATIN SMALL LETTER O WITH HORN;Ll;0;L;006F 031B;;;;N;LATIN SMALL LETTER O HORN;;01A0;;01A0 +01A2;LATIN CAPITAL LETTER OI;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O I;;;01A3; +01A3;LATIN SMALL LETTER OI;Ll;0;L;;;;;N;LATIN SMALL LETTER O I;;01A2;;01A2 +01A4;LATIN CAPITAL LETTER P WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER P HOOK;;;01A5; +01A5;LATIN SMALL LETTER P WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER P HOOK;;01A4;;01A4 +01A6;LATIN LETTER YR;Lu;0;L;;;;;N;LATIN LETTER Y R;;;0280; +01A7;LATIN CAPITAL LETTER TONE TWO;Lu;0;L;;;;;N;;;;01A8; +01A8;LATIN SMALL LETTER TONE TWO;Ll;0;L;;;;;N;;;01A7;;01A7 +01A9;LATIN CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;0283; +01AA;LATIN LETTER REVERSED ESH LOOP;Ll;0;L;;;;;N;;;;; +01AB;LATIN SMALL LETTER T WITH PALATAL HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T PALATAL HOOK;;;; +01AC;LATIN CAPITAL LETTER T WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T HOOK;;;01AD; +01AD;LATIN SMALL LETTER T WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T HOOK;;01AC;;01AC +01AE;LATIN CAPITAL LETTER T WITH RETROFLEX HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T RETROFLEX HOOK;;;0288; +01AF;LATIN CAPITAL LETTER U WITH HORN;Lu;0;L;0055 031B;;;;N;LATIN CAPITAL LETTER U HORN;;;01B0; +01B0;LATIN SMALL LETTER U WITH HORN;Ll;0;L;0075 031B;;;;N;LATIN SMALL LETTER U HORN;;01AF;;01AF +01B1;LATIN CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;028A; +01B2;LATIN CAPITAL LETTER V WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER SCRIPT V;;;028B; +01B3;LATIN CAPITAL LETTER Y WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Y HOOK;;;01B4; +01B4;LATIN SMALL LETTER Y WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Y HOOK;;01B3;;01B3 +01B5;LATIN CAPITAL LETTER Z WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Z BAR;;;01B6; +01B6;LATIN SMALL LETTER Z WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER Z BAR;;01B5;;01B5 +01B7;LATIN CAPITAL LETTER EZH;Lu;0;L;;;;;N;LATIN CAPITAL LETTER YOGH;;;0292; +01B8;LATIN CAPITAL LETTER EZH REVERSED;Lu;0;L;;;;;N;LATIN CAPITAL LETTER REVERSED YOGH;;;01B9; +01B9;LATIN SMALL LETTER EZH REVERSED;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED YOGH;;01B8;;01B8 +01BA;LATIN SMALL LETTER EZH WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH WITH TAIL;;;; +01BB;LATIN LETTER TWO WITH STROKE;Lo;0;L;;;;;N;LATIN LETTER TWO BAR;;;; +01BC;LATIN CAPITAL LETTER TONE FIVE;Lu;0;L;;;;;N;;;;01BD; +01BD;LATIN SMALL LETTER TONE FIVE;Ll;0;L;;;;;N;;;01BC;;01BC +01BE;LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER INVERTED GLOTTAL STOP BAR;;;; +01BF;LATIN LETTER WYNN;Ll;0;L;;;;;N;;;01F7;;01F7 +01C0;LATIN LETTER DENTAL CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE;;;; +01C1;LATIN LETTER LATERAL CLICK;Lo;0;L;;;;;N;LATIN LETTER DOUBLE PIPE;;;; +01C2;LATIN LETTER ALVEOLAR CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE DOUBLE BAR;;;; +01C3;LATIN LETTER RETROFLEX CLICK;Lo;0;L;;;;;N;LATIN LETTER EXCLAMATION MARK;;;; +01C4;LATIN CAPITAL LETTER DZ WITH CARON;Lu;0;L; 0044 017D;;;;N;LATIN CAPITAL LETTER D Z HACEK;;;01C6;01C5 +01C5;LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON;Lt;0;L; 0044 017E;;;;N;LATIN LETTER CAPITAL D SMALL Z HACEK;;01C4;01C6;01C5 +01C6;LATIN SMALL LETTER DZ WITH CARON;Ll;0;L; 0064 017E;;;;N;LATIN SMALL LETTER D Z HACEK;;01C4;;01C5 +01C7;LATIN CAPITAL LETTER LJ;Lu;0;L; 004C 004A;;;;N;LATIN CAPITAL LETTER L J;;;01C9;01C8 +01C8;LATIN CAPITAL LETTER L WITH SMALL LETTER J;Lt;0;L; 004C 006A;;;;N;LATIN LETTER CAPITAL L SMALL J;;01C7;01C9;01C8 +01C9;LATIN SMALL LETTER LJ;Ll;0;L; 006C 006A;;;;N;LATIN SMALL LETTER L J;;01C7;;01C8 +01CA;LATIN CAPITAL LETTER NJ;Lu;0;L; 004E 004A;;;;N;LATIN CAPITAL LETTER N J;;;01CC;01CB +01CB;LATIN CAPITAL LETTER N WITH SMALL LETTER J;Lt;0;L; 004E 006A;;;;N;LATIN LETTER CAPITAL N SMALL J;;01CA;01CC;01CB +01CC;LATIN SMALL LETTER NJ;Ll;0;L; 006E 006A;;;;N;LATIN SMALL LETTER N J;;01CA;;01CB +01CD;LATIN CAPITAL LETTER A WITH CARON;Lu;0;L;0041 030C;;;;N;LATIN CAPITAL LETTER A HACEK;;;01CE; +01CE;LATIN SMALL LETTER A WITH CARON;Ll;0;L;0061 030C;;;;N;LATIN SMALL LETTER A HACEK;;01CD;;01CD +01CF;LATIN CAPITAL LETTER I WITH CARON;Lu;0;L;0049 030C;;;;N;LATIN CAPITAL LETTER I HACEK;;;01D0; +01D0;LATIN SMALL LETTER I WITH CARON;Ll;0;L;0069 030C;;;;N;LATIN SMALL LETTER I HACEK;;01CF;;01CF +01D1;LATIN CAPITAL LETTER O WITH CARON;Lu;0;L;004F 030C;;;;N;LATIN CAPITAL LETTER O HACEK;;;01D2; +01D2;LATIN SMALL LETTER O WITH CARON;Ll;0;L;006F 030C;;;;N;LATIN SMALL LETTER O HACEK;;01D1;;01D1 +01D3;LATIN CAPITAL LETTER U WITH CARON;Lu;0;L;0055 030C;;;;N;LATIN CAPITAL LETTER U HACEK;;;01D4; +01D4;LATIN SMALL LETTER U WITH CARON;Ll;0;L;0075 030C;;;;N;LATIN SMALL LETTER U HACEK;;01D3;;01D3 +01D5;LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON;Lu;0;L;00DC 0304;;;;N;LATIN CAPITAL LETTER U DIAERESIS MACRON;;;01D6; +01D6;LATIN SMALL LETTER U WITH DIAERESIS AND MACRON;Ll;0;L;00FC 0304;;;;N;LATIN SMALL LETTER U DIAERESIS MACRON;;01D5;;01D5 +01D7;LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE;Lu;0;L;00DC 0301;;;;N;LATIN CAPITAL LETTER U DIAERESIS ACUTE;;;01D8; +01D8;LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE;Ll;0;L;00FC 0301;;;;N;LATIN SMALL LETTER U DIAERESIS ACUTE;;01D7;;01D7 +01D9;LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON;Lu;0;L;00DC 030C;;;;N;LATIN CAPITAL LETTER U DIAERESIS HACEK;;;01DA; +01DA;LATIN SMALL LETTER U WITH DIAERESIS AND CARON;Ll;0;L;00FC 030C;;;;N;LATIN SMALL LETTER U DIAERESIS HACEK;;01D9;;01D9 +01DB;LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE;Lu;0;L;00DC 0300;;;;N;LATIN CAPITAL LETTER U DIAERESIS GRAVE;;;01DC; +01DC;LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE;Ll;0;L;00FC 0300;;;;N;LATIN SMALL LETTER U DIAERESIS GRAVE;;01DB;;01DB +01DD;LATIN SMALL LETTER TURNED E;Ll;0;L;;;;;N;;;018E;;018E +01DE;LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON;Lu;0;L;00C4 0304;;;;N;LATIN CAPITAL LETTER A DIAERESIS MACRON;;;01DF; +01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE +01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1; +01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0 +01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;;;01E3; +01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;;01E2;;01E2 +01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5; +01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4 +01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7; +01E7;LATIN SMALL LETTER G WITH CARON;Ll;0;L;0067 030C;;;;N;LATIN SMALL LETTER G HACEK;;01E6;;01E6 +01E8;LATIN CAPITAL LETTER K WITH CARON;Lu;0;L;004B 030C;;;;N;LATIN CAPITAL LETTER K HACEK;;;01E9; +01E9;LATIN SMALL LETTER K WITH CARON;Ll;0;L;006B 030C;;;;N;LATIN SMALL LETTER K HACEK;;01E8;;01E8 +01EA;LATIN CAPITAL LETTER O WITH OGONEK;Lu;0;L;004F 0328;;;;N;LATIN CAPITAL LETTER O OGONEK;;;01EB; +01EB;LATIN SMALL LETTER O WITH OGONEK;Ll;0;L;006F 0328;;;;N;LATIN SMALL LETTER O OGONEK;;01EA;;01EA +01EC;LATIN CAPITAL LETTER O WITH OGONEK AND MACRON;Lu;0;L;01EA 0304;;;;N;LATIN CAPITAL LETTER O OGONEK MACRON;;;01ED; +01ED;LATIN SMALL LETTER O WITH OGONEK AND MACRON;Ll;0;L;01EB 0304;;;;N;LATIN SMALL LETTER O OGONEK MACRON;;01EC;;01EC +01EE;LATIN CAPITAL LETTER EZH WITH CARON;Lu;0;L;01B7 030C;;;;N;LATIN CAPITAL LETTER YOGH HACEK;;;01EF; +01EF;LATIN SMALL LETTER EZH WITH CARON;Ll;0;L;0292 030C;;;;N;LATIN SMALL LETTER YOGH HACEK;;01EE;;01EE +01F0;LATIN SMALL LETTER J WITH CARON;Ll;0;L;006A 030C;;;;N;LATIN SMALL LETTER J HACEK;;;; +01F1;LATIN CAPITAL LETTER DZ;Lu;0;L; 0044 005A;;;;N;;;;01F3;01F2 +01F2;LATIN CAPITAL LETTER D WITH SMALL LETTER Z;Lt;0;L; 0044 007A;;;;N;;;01F1;01F3;01F2 +01F3;LATIN SMALL LETTER DZ;Ll;0;L; 0064 007A;;;;N;;;01F1;;01F2 +01F4;LATIN CAPITAL LETTER G WITH ACUTE;Lu;0;L;0047 0301;;;;N;;;;01F5; +01F5;LATIN SMALL LETTER G WITH ACUTE;Ll;0;L;0067 0301;;;;N;;;01F4;;01F4 +01F6;LATIN CAPITAL LETTER HWAIR;Lu;0;L;;;;;N;;;;0195; +01F7;LATIN CAPITAL LETTER WYNN;Lu;0;L;;;;;N;;;;01BF; +01F8;LATIN CAPITAL LETTER N WITH GRAVE;Lu;0;L;004E 0300;;;;N;;;;01F9; +01F9;LATIN SMALL LETTER N WITH GRAVE;Ll;0;L;006E 0300;;;;N;;;01F8;;01F8 +01FA;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE;Lu;0;L;00C5 0301;;;;N;;;;01FB; +01FB;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE;Ll;0;L;00E5 0301;;;;N;;;01FA;;01FA +01FC;LATIN CAPITAL LETTER AE WITH ACUTE;Lu;0;L;00C6 0301;;;;N;;;;01FD; +01FD;LATIN SMALL LETTER AE WITH ACUTE;Ll;0;L;00E6 0301;;;;N;;;01FC;;01FC +01FE;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE;Lu;0;L;00D8 0301;;;;N;;;;01FF; +01FF;LATIN SMALL LETTER O WITH STROKE AND ACUTE;Ll;0;L;00F8 0301;;;;N;;;01FE;;01FE +0200;LATIN CAPITAL LETTER A WITH DOUBLE GRAVE;Lu;0;L;0041 030F;;;;N;;;;0201; +0201;LATIN SMALL LETTER A WITH DOUBLE GRAVE;Ll;0;L;0061 030F;;;;N;;;0200;;0200 +0202;LATIN CAPITAL LETTER A WITH INVERTED BREVE;Lu;0;L;0041 0311;;;;N;;;;0203; +0203;LATIN SMALL LETTER A WITH INVERTED BREVE;Ll;0;L;0061 0311;;;;N;;;0202;;0202 +0204;LATIN CAPITAL LETTER E WITH DOUBLE GRAVE;Lu;0;L;0045 030F;;;;N;;;;0205; +0205;LATIN SMALL LETTER E WITH DOUBLE GRAVE;Ll;0;L;0065 030F;;;;N;;;0204;;0204 +0206;LATIN CAPITAL LETTER E WITH INVERTED BREVE;Lu;0;L;0045 0311;;;;N;;;;0207; +0207;LATIN SMALL LETTER E WITH INVERTED BREVE;Ll;0;L;0065 0311;;;;N;;;0206;;0206 +0208;LATIN CAPITAL LETTER I WITH DOUBLE GRAVE;Lu;0;L;0049 030F;;;;N;;;;0209; +0209;LATIN SMALL LETTER I WITH DOUBLE GRAVE;Ll;0;L;0069 030F;;;;N;;;0208;;0208 +020A;LATIN CAPITAL LETTER I WITH INVERTED BREVE;Lu;0;L;0049 0311;;;;N;;;;020B; +020B;LATIN SMALL LETTER I WITH INVERTED BREVE;Ll;0;L;0069 0311;;;;N;;;020A;;020A +020C;LATIN CAPITAL LETTER O WITH DOUBLE GRAVE;Lu;0;L;004F 030F;;;;N;;;;020D; +020D;LATIN SMALL LETTER O WITH DOUBLE GRAVE;Ll;0;L;006F 030F;;;;N;;;020C;;020C +020E;LATIN CAPITAL LETTER O WITH INVERTED BREVE;Lu;0;L;004F 0311;;;;N;;;;020F; +020F;LATIN SMALL LETTER O WITH INVERTED BREVE;Ll;0;L;006F 0311;;;;N;;;020E;;020E +0210;LATIN CAPITAL LETTER R WITH DOUBLE GRAVE;Lu;0;L;0052 030F;;;;N;;;;0211; +0211;LATIN SMALL LETTER R WITH DOUBLE GRAVE;Ll;0;L;0072 030F;;;;N;;;0210;;0210 +0212;LATIN CAPITAL LETTER R WITH INVERTED BREVE;Lu;0;L;0052 0311;;;;N;;;;0213; +0213;LATIN SMALL LETTER R WITH INVERTED BREVE;Ll;0;L;0072 0311;;;;N;;;0212;;0212 +0214;LATIN CAPITAL LETTER U WITH DOUBLE GRAVE;Lu;0;L;0055 030F;;;;N;;;;0215; +0215;LATIN SMALL LETTER U WITH DOUBLE GRAVE;Ll;0;L;0075 030F;;;;N;;;0214;;0214 +0216;LATIN CAPITAL LETTER U WITH INVERTED BREVE;Lu;0;L;0055 0311;;;;N;;;;0217; +0217;LATIN SMALL LETTER U WITH INVERTED BREVE;Ll;0;L;0075 0311;;;;N;;;0216;;0216 +0218;LATIN CAPITAL LETTER S WITH COMMA BELOW;Lu;0;L;0053 0326;;;;N;;;;0219; +0219;LATIN SMALL LETTER S WITH COMMA BELOW;Ll;0;L;0073 0326;;;;N;;;0218;;0218 +021A;LATIN CAPITAL LETTER T WITH COMMA BELOW;Lu;0;L;0054 0326;;;;N;;;;021B; +021B;LATIN SMALL LETTER T WITH COMMA BELOW;Ll;0;L;0074 0326;;;;N;;;021A;;021A +021C;LATIN CAPITAL LETTER YOGH;Lu;0;L;;;;;N;;;;021D; +021D;LATIN SMALL LETTER YOGH;Ll;0;L;;;;;N;;;021C;;021C +021E;LATIN CAPITAL LETTER H WITH CARON;Lu;0;L;0048 030C;;;;N;;;;021F; +021F;LATIN SMALL LETTER H WITH CARON;Ll;0;L;0068 030C;;;;N;;;021E;;021E +0220;LATIN CAPITAL LETTER N WITH LONG RIGHT LEG;Lu;0;L;;;;;N;;;;019E; +0221;LATIN SMALL LETTER D WITH CURL;Ll;0;L;;;;;N;;;;; +0222;LATIN CAPITAL LETTER OU;Lu;0;L;;;;;N;;;;0223; +0223;LATIN SMALL LETTER OU;Ll;0;L;;;;;N;;;0222;;0222 +0224;LATIN CAPITAL LETTER Z WITH HOOK;Lu;0;L;;;;;N;;;;0225; +0225;LATIN SMALL LETTER Z WITH HOOK;Ll;0;L;;;;;N;;;0224;;0224 +0226;LATIN CAPITAL LETTER A WITH DOT ABOVE;Lu;0;L;0041 0307;;;;N;;;;0227; +0227;LATIN SMALL LETTER A WITH DOT ABOVE;Ll;0;L;0061 0307;;;;N;;;0226;;0226 +0228;LATIN CAPITAL LETTER E WITH CEDILLA;Lu;0;L;0045 0327;;;;N;;;;0229; +0229;LATIN SMALL LETTER E WITH CEDILLA;Ll;0;L;0065 0327;;;;N;;;0228;;0228 +022A;LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON;Lu;0;L;00D6 0304;;;;N;;;;022B; +022B;LATIN SMALL LETTER O WITH DIAERESIS AND MACRON;Ll;0;L;00F6 0304;;;;N;;;022A;;022A +022C;LATIN CAPITAL LETTER O WITH TILDE AND MACRON;Lu;0;L;00D5 0304;;;;N;;;;022D; +022D;LATIN SMALL LETTER O WITH TILDE AND MACRON;Ll;0;L;00F5 0304;;;;N;;;022C;;022C +022E;LATIN CAPITAL LETTER O WITH DOT ABOVE;Lu;0;L;004F 0307;;;;N;;;;022F; +022F;LATIN SMALL LETTER O WITH DOT ABOVE;Ll;0;L;006F 0307;;;;N;;;022E;;022E +0230;LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON;Lu;0;L;022E 0304;;;;N;;;;0231; +0231;LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON;Ll;0;L;022F 0304;;;;N;;;0230;;0230 +0232;LATIN CAPITAL LETTER Y WITH MACRON;Lu;0;L;0059 0304;;;;N;;;;0233; +0233;LATIN SMALL LETTER Y WITH MACRON;Ll;0;L;0079 0304;;;;N;;;0232;;0232 +0234;LATIN SMALL LETTER L WITH CURL;Ll;0;L;;;;;N;;;;; +0235;LATIN SMALL LETTER N WITH CURL;Ll;0;L;;;;;N;;;;; +0236;LATIN SMALL LETTER T WITH CURL;Ll;0;L;;;;;N;;;;; +0237;LATIN SMALL LETTER DOTLESS J;Ll;0;L;;;;;N;;;;; +0238;LATIN SMALL LETTER DB DIGRAPH;Ll;0;L;;;;;N;;;;; +0239;LATIN SMALL LETTER QP DIGRAPH;Ll;0;L;;;;;N;;;;; +023A;LATIN CAPITAL LETTER A WITH STROKE;Lu;0;L;;;;;N;;;;2C65; +023B;LATIN CAPITAL LETTER C WITH STROKE;Lu;0;L;;;;;N;;;;023C; +023C;LATIN SMALL LETTER C WITH STROKE;Ll;0;L;;;;;N;;;023B;;023B +023D;LATIN CAPITAL LETTER L WITH BAR;Lu;0;L;;;;;N;;;;019A; +023E;LATIN CAPITAL LETTER T WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;2C66; +023F;LATIN SMALL LETTER S WITH SWASH TAIL;Ll;0;L;;;;;N;;;2C7E;;2C7E +0240;LATIN SMALL LETTER Z WITH SWASH TAIL;Ll;0;L;;;;;N;;;2C7F;;2C7F +0241;LATIN CAPITAL LETTER GLOTTAL STOP;Lu;0;L;;;;;N;;;;0242; +0242;LATIN SMALL LETTER GLOTTAL STOP;Ll;0;L;;;;;N;;;0241;;0241 +0243;LATIN CAPITAL LETTER B WITH STROKE;Lu;0;L;;;;;N;;;;0180; +0244;LATIN CAPITAL LETTER U BAR;Lu;0;L;;;;;N;;;;0289; +0245;LATIN CAPITAL LETTER TURNED V;Lu;0;L;;;;;N;;;;028C; +0246;LATIN CAPITAL LETTER E WITH STROKE;Lu;0;L;;;;;N;;;;0247; +0247;LATIN SMALL LETTER E WITH STROKE;Ll;0;L;;;;;N;;;0246;;0246 +0248;LATIN CAPITAL LETTER J WITH STROKE;Lu;0;L;;;;;N;;;;0249; +0249;LATIN SMALL LETTER J WITH STROKE;Ll;0;L;;;;;N;;;0248;;0248 +024A;LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL;Lu;0;L;;;;;N;;;;024B; +024B;LATIN SMALL LETTER Q WITH HOOK TAIL;Ll;0;L;;;;;N;;;024A;;024A +024C;LATIN CAPITAL LETTER R WITH STROKE;Lu;0;L;;;;;N;;;;024D; +024D;LATIN SMALL LETTER R WITH STROKE;Ll;0;L;;;;;N;;;024C;;024C +024E;LATIN CAPITAL LETTER Y WITH STROKE;Lu;0;L;;;;;N;;;;024F; +024F;LATIN SMALL LETTER Y WITH STROKE;Ll;0;L;;;;;N;;;024E;;024E +0250;LATIN SMALL LETTER TURNED A;Ll;0;L;;;;;N;;;2C6F;;2C6F +0251;LATIN SMALL LETTER ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT A;;2C6D;;2C6D +0252;LATIN SMALL LETTER TURNED ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED SCRIPT A;;2C70;;2C70 +0253;LATIN SMALL LETTER B WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER B HOOK;;0181;;0181 +0254;LATIN SMALL LETTER OPEN O;Ll;0;L;;;;;N;;;0186;;0186 +0255;LATIN SMALL LETTER C WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER C CURL;;;; +0256;LATIN SMALL LETTER D WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER D RETROFLEX HOOK;;0189;;0189 +0257;LATIN SMALL LETTER D WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER D HOOK;;018A;;018A +0258;LATIN SMALL LETTER REVERSED E;Ll;0;L;;;;;N;;;;; +0259;LATIN SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;018F;;018F +025A;LATIN SMALL LETTER SCHWA WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCHWA HOOK;;;; +025B;LATIN SMALL LETTER OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER EPSILON;;0190;;0190 +025C;LATIN SMALL LETTER REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON;;;; +025D;LATIN SMALL LETTER REVERSED OPEN E WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON HOOK;;;; +025E;LATIN SMALL LETTER CLOSED REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED REVERSED EPSILON;;;; +025F;LATIN SMALL LETTER DOTLESS J WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR;;;; +0260;LATIN SMALL LETTER G WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER G HOOK;;0193;;0193 +0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;;; +0262;LATIN LETTER SMALL CAPITAL G;Ll;0;L;;;;;N;;;;; +0263;LATIN SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0194;;0194 +0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;;; +0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;;; +0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;;; +0267;LATIN SMALL LETTER HENG WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER HENG HOOK;;;; +0268;LATIN SMALL LETTER I WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED I;;0197;;0197 +0269;LATIN SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0196;;0196 +026A;LATIN LETTER SMALL CAPITAL I;Ll;0;L;;;;;N;;;;; +026B;LATIN SMALL LETTER L WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;2C62;;2C62 +026C;LATIN SMALL LETTER L WITH BELT;Ll;0;L;;;;;N;LATIN SMALL LETTER L BELT;;;; +026D;LATIN SMALL LETTER L WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER L RETROFLEX HOOK;;;; +026E;LATIN SMALL LETTER LEZH;Ll;0;L;;;;;N;LATIN SMALL LETTER L YOGH;;;; +026F;LATIN SMALL LETTER TURNED M;Ll;0;L;;;;;N;;;019C;;019C +0270;LATIN SMALL LETTER TURNED M WITH LONG LEG;Ll;0;L;;;;;N;;;;; +0271;LATIN SMALL LETTER M WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER M HOOK;;2C6E;;2C6E +0272;LATIN SMALL LETTER N WITH LEFT HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N HOOK;;019D;;019D +0273;LATIN SMALL LETTER N WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N RETROFLEX HOOK;;;; +0274;LATIN LETTER SMALL CAPITAL N;Ll;0;L;;;;;N;;;;; +0275;LATIN SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;019F;;019F +0276;LATIN LETTER SMALL CAPITAL OE;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL O E;;;; +0277;LATIN SMALL LETTER CLOSED OMEGA;Ll;0;L;;;;;N;;;;; +0278;LATIN SMALL LETTER PHI;Ll;0;L;;;;;N;;;;; +0279;LATIN SMALL LETTER TURNED R;Ll;0;L;;;;;N;;;;; +027A;LATIN SMALL LETTER TURNED R WITH LONG LEG;Ll;0;L;;;;;N;;;;; +027B;LATIN SMALL LETTER TURNED R WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED R HOOK;;;; +027C;LATIN SMALL LETTER R WITH LONG LEG;Ll;0;L;;;;;N;;;;; +027D;LATIN SMALL LETTER R WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER R HOOK;;2C64;;2C64 +027E;LATIN SMALL LETTER R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER FISHHOOK R;;;; +027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;; +0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;;01A6;;01A6 +0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;; +0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;;; +0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9 +0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;; +0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;; +0286;LATIN SMALL LETTER ESH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER ESH CURL;;;; +0287;LATIN SMALL LETTER TURNED T;Ll;0;L;;;;;N;;;;; +0288;LATIN SMALL LETTER T WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T RETROFLEX HOOK;;01AE;;01AE +0289;LATIN SMALL LETTER U BAR;Ll;0;L;;;;;N;;;0244;;0244 +028A;LATIN SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;01B1;;01B1 +028B;LATIN SMALL LETTER V WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT V;;01B2;;01B2 +028C;LATIN SMALL LETTER TURNED V;Ll;0;L;;;;;N;;;0245;;0245 +028D;LATIN SMALL LETTER TURNED W;Ll;0;L;;;;;N;;;;; +028E;LATIN SMALL LETTER TURNED Y;Ll;0;L;;;;;N;;;;; +028F;LATIN LETTER SMALL CAPITAL Y;Ll;0;L;;;;;N;;;;; +0290;LATIN SMALL LETTER Z WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Z RETROFLEX HOOK;;;; +0291;LATIN SMALL LETTER Z WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER Z CURL;;;; +0292;LATIN SMALL LETTER EZH;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH;;01B7;;01B7 +0293;LATIN SMALL LETTER EZH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH CURL;;;; +0294;LATIN LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;; +0295;LATIN LETTER PHARYNGEAL VOICED FRICATIVE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP;;;; +0296;LATIN LETTER INVERTED GLOTTAL STOP;Ll;0;L;;;;;N;;;;; +0297;LATIN LETTER STRETCHED C;Ll;0;L;;;;;N;;;;; +0298;LATIN LETTER BILABIAL CLICK;Ll;0;L;;;;;N;LATIN LETTER BULLSEYE;;;; +0299;LATIN LETTER SMALL CAPITAL B;Ll;0;L;;;;;N;;;;; +029A;LATIN SMALL LETTER CLOSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED EPSILON;;;; +029B;LATIN LETTER SMALL CAPITAL G WITH HOOK;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL G HOOK;;;; +029C;LATIN LETTER SMALL CAPITAL H;Ll;0;L;;;;;N;;;;; +029D;LATIN SMALL LETTER J WITH CROSSED-TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER CROSSED-TAIL J;;;; +029E;LATIN SMALL LETTER TURNED K;Ll;0;L;;;;;N;;;;; +029F;LATIN LETTER SMALL CAPITAL L;Ll;0;L;;;;;N;;;;; +02A0;LATIN SMALL LETTER Q WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Q HOOK;;;; +02A1;LATIN LETTER GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER GLOTTAL STOP BAR;;;; +02A2;LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP BAR;;;; +02A3;LATIN SMALL LETTER DZ DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z;;;; +02A4;LATIN SMALL LETTER DEZH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D YOGH;;;; +02A5;LATIN SMALL LETTER DZ DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z CURL;;;; +02A6;LATIN SMALL LETTER TS DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T S;;;; +02A7;LATIN SMALL LETTER TESH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T ESH;;;; +02A8;LATIN SMALL LETTER TC DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER T C CURL;;;; +02A9;LATIN SMALL LETTER FENG DIGRAPH;Ll;0;L;;;;;N;;;;; +02AA;LATIN SMALL LETTER LS DIGRAPH;Ll;0;L;;;;;N;;;;; +02AB;LATIN SMALL LETTER LZ DIGRAPH;Ll;0;L;;;;;N;;;;; +02AC;LATIN LETTER BILABIAL PERCUSSIVE;Ll;0;L;;;;;N;;;;; +02AD;LATIN LETTER BIDENTAL PERCUSSIVE;Ll;0;L;;;;;N;;;;; +02AE;LATIN SMALL LETTER TURNED H WITH FISHHOOK;Ll;0;L;;;;;N;;;;; +02AF;LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL;Ll;0;L;;;;;N;;;;; +02B0;MODIFIER LETTER SMALL H;Lm;0;L; 0068;;;;N;;;;; +02B1;MODIFIER LETTER SMALL H WITH HOOK;Lm;0;L; 0266;;;;N;MODIFIER LETTER SMALL H HOOK;;;; +02B2;MODIFIER LETTER SMALL J;Lm;0;L; 006A;;;;N;;;;; +02B3;MODIFIER LETTER SMALL R;Lm;0;L; 0072;;;;N;;;;; +02B4;MODIFIER LETTER SMALL TURNED R;Lm;0;L; 0279;;;;N;;;;; +02B5;MODIFIER LETTER SMALL TURNED R WITH HOOK;Lm;0;L; 027B;;;;N;MODIFIER LETTER SMALL TURNED R HOOK;;;; +02B6;MODIFIER LETTER SMALL CAPITAL INVERTED R;Lm;0;L; 0281;;;;N;;;;; +02B7;MODIFIER LETTER SMALL W;Lm;0;L; 0077;;;;N;;;;; +02B8;MODIFIER LETTER SMALL Y;Lm;0;L; 0079;;;;N;;;;; +02B9;MODIFIER LETTER PRIME;Lm;0;ON;;;;;N;;;;; +02BA;MODIFIER LETTER DOUBLE PRIME;Lm;0;ON;;;;;N;;;;; +02BB;MODIFIER LETTER TURNED COMMA;Lm;0;L;;;;;N;;;;; +02BC;MODIFIER LETTER APOSTROPHE;Lm;0;L;;;;;N;;;;; +02BD;MODIFIER LETTER REVERSED COMMA;Lm;0;L;;;;;N;;;;; +02BE;MODIFIER LETTER RIGHT HALF RING;Lm;0;L;;;;;N;;;;; +02BF;MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;; +02C0;MODIFIER LETTER GLOTTAL STOP;Lm;0;L;;;;;N;;;;; +02C1;MODIFIER LETTER REVERSED GLOTTAL STOP;Lm;0;L;;;;;N;;;;; +02C2;MODIFIER LETTER LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C3;MODIFIER LETTER RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C4;MODIFIER LETTER UP ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C5;MODIFIER LETTER DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C6;MODIFIER LETTER CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER CIRCUMFLEX;;;; +02C7;CARON;Lm;0;ON;;;;;N;MODIFIER LETTER HACEK;;;; +02C8;MODIFIER LETTER VERTICAL LINE;Lm;0;ON;;;;;N;;;;; +02C9;MODIFIER LETTER MACRON;Lm;0;ON;;;;;N;;;;; +02CA;MODIFIER LETTER ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER ACUTE;;;; +02CB;MODIFIER LETTER GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER GRAVE;;;; +02CC;MODIFIER LETTER LOW VERTICAL LINE;Lm;0;ON;;;;;N;;;;; +02CD;MODIFIER LETTER LOW MACRON;Lm;0;ON;;;;;N;;;;; +02CE;MODIFIER LETTER LOW GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW GRAVE;;;; +02CF;MODIFIER LETTER LOW ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW ACUTE;;;; +02D0;MODIFIER LETTER TRIANGULAR COLON;Lm;0;L;;;;;N;;;;; +02D1;MODIFIER LETTER HALF TRIANGULAR COLON;Lm;0;L;;;;;N;;;;; +02D2;MODIFIER LETTER CENTRED RIGHT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED RIGHT HALF RING;;;; +02D3;MODIFIER LETTER CENTRED LEFT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED LEFT HALF RING;;;; +02D4;MODIFIER LETTER UP TACK;Sk;0;ON;;;;;N;;;;; +02D5;MODIFIER LETTER DOWN TACK;Sk;0;ON;;;;;N;;;;; +02D6;MODIFIER LETTER PLUS SIGN;Sk;0;ON;;;;;N;;;;; +02D7;MODIFIER LETTER MINUS SIGN;Sk;0;ON;;;;;N;;;;; +02D8;BREVE;Sk;0;ON; 0020 0306;;;;N;SPACING BREVE;;;; +02D9;DOT ABOVE;Sk;0;ON; 0020 0307;;;;N;SPACING DOT ABOVE;;;; +02DA;RING ABOVE;Sk;0;ON; 0020 030A;;;;N;SPACING RING ABOVE;;;; +02DB;OGONEK;Sk;0;ON; 0020 0328;;;;N;SPACING OGONEK;;;; +02DC;SMALL TILDE;Sk;0;ON; 0020 0303;;;;N;SPACING TILDE;;;; +02DD;DOUBLE ACUTE ACCENT;Sk;0;ON; 0020 030B;;;;N;SPACING DOUBLE ACUTE;;;; +02DE;MODIFIER LETTER RHOTIC HOOK;Sk;0;ON;;;;;N;;;;; +02DF;MODIFIER LETTER CROSS ACCENT;Sk;0;ON;;;;;N;;;;; +02E0;MODIFIER LETTER SMALL GAMMA;Lm;0;L; 0263;;;;N;;;;; +02E1;MODIFIER LETTER SMALL L;Lm;0;L; 006C;;;;N;;;;; +02E2;MODIFIER LETTER SMALL S;Lm;0;L; 0073;;;;N;;;;; +02E3;MODIFIER LETTER SMALL X;Lm;0;L; 0078;;;;N;;;;; +02E4;MODIFIER LETTER SMALL REVERSED GLOTTAL STOP;Lm;0;L; 0295;;;;N;;;;; +02E5;MODIFIER LETTER EXTRA-HIGH TONE BAR;Sk;0;ON;;;;;N;;;;; +02E6;MODIFIER LETTER HIGH TONE BAR;Sk;0;ON;;;;;N;;;;; +02E7;MODIFIER LETTER MID TONE BAR;Sk;0;ON;;;;;N;;;;; +02E8;MODIFIER LETTER LOW TONE BAR;Sk;0;ON;;;;;N;;;;; +02E9;MODIFIER LETTER EXTRA-LOW TONE BAR;Sk;0;ON;;;;;N;;;;; +02EA;MODIFIER LETTER YIN DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;; +02EB;MODIFIER LETTER YANG DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;; +02EC;MODIFIER LETTER VOICING;Lm;0;ON;;;;;N;;;;; +02ED;MODIFIER LETTER UNASPIRATED;Sk;0;ON;;;;;N;;;;; +02EE;MODIFIER LETTER DOUBLE APOSTROPHE;Lm;0;L;;;;;N;;;;; +02EF;MODIFIER LETTER LOW DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02F0;MODIFIER LETTER LOW UP ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02F1;MODIFIER LETTER LOW LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02F2;MODIFIER LETTER LOW RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02F3;MODIFIER LETTER LOW RING;Sk;0;ON;;;;;N;;;;; +02F4;MODIFIER LETTER MIDDLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;; +02F5;MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;; +02F6;MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT;Sk;0;ON;;;;;N;;;;; +02F7;MODIFIER LETTER LOW TILDE;Sk;0;ON;;;;;N;;;;; +02F8;MODIFIER LETTER RAISED COLON;Sk;0;ON;;;;;N;;;;; +02F9;MODIFIER LETTER BEGIN HIGH TONE;Sk;0;ON;;;;;N;;;;; +02FA;MODIFIER LETTER END HIGH TONE;Sk;0;ON;;;;;N;;;;; +02FB;MODIFIER LETTER BEGIN LOW TONE;Sk;0;ON;;;;;N;;;;; +02FC;MODIFIER LETTER END LOW TONE;Sk;0;ON;;;;;N;;;;; +02FD;MODIFIER LETTER SHELF;Sk;0;ON;;;;;N;;;;; +02FE;MODIFIER LETTER OPEN SHELF;Sk;0;ON;;;;;N;;;;; +02FF;MODIFIER LETTER LOW LEFT ARROW;Sk;0;ON;;;;;N;;;;; +0300;COMBINING GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING GRAVE;;;; +0301;COMBINING ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING ACUTE;;;; +0302;COMBINING CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;NON-SPACING CIRCUMFLEX;;;; +0303;COMBINING TILDE;Mn;230;NSM;;;;;N;NON-SPACING TILDE;;;; +0304;COMBINING MACRON;Mn;230;NSM;;;;;N;NON-SPACING MACRON;;;; +0305;COMBINING OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING OVERSCORE;;;; +0306;COMBINING BREVE;Mn;230;NSM;;;;;N;NON-SPACING BREVE;;;; +0307;COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOT ABOVE;;;; +0308;COMBINING DIAERESIS;Mn;230;NSM;;;;;N;NON-SPACING DIAERESIS;;;; +0309;COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;NON-SPACING HOOK ABOVE;;;; +030A;COMBINING RING ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RING ABOVE;;;; +030B;COMBINING DOUBLE ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE ACUTE;;;; +030C;COMBINING CARON;Mn;230;NSM;;;;;N;NON-SPACING HACEK;;;; +030D;COMBINING VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL LINE ABOVE;;;; +030E;COMBINING DOUBLE VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE VERTICAL LINE ABOVE;;;; +030F;COMBINING DOUBLE GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE GRAVE;;;; +0310;COMBINING CANDRABINDU;Mn;230;NSM;;;;;N;NON-SPACING CANDRABINDU;;;; +0311;COMBINING INVERTED BREVE;Mn;230;NSM;;;;;N;NON-SPACING INVERTED BREVE;;;; +0312;COMBINING TURNED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING TURNED COMMA ABOVE;;;; +0313;COMBINING COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING COMMA ABOVE;;;; +0314;COMBINING REVERSED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING REVERSED COMMA ABOVE;;;; +0315;COMBINING COMMA ABOVE RIGHT;Mn;232;NSM;;;;;N;NON-SPACING COMMA ABOVE RIGHT;;;; +0316;COMBINING GRAVE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING GRAVE BELOW;;;; +0317;COMBINING ACUTE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING ACUTE BELOW;;;; +0318;COMBINING LEFT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT TACK BELOW;;;; +0319;COMBINING RIGHT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT TACK BELOW;;;; +031A;COMBINING LEFT ANGLE ABOVE;Mn;232;NSM;;;;;N;NON-SPACING LEFT ANGLE ABOVE;;;; +031B;COMBINING HORN;Mn;216;NSM;;;;;N;NON-SPACING HORN;;;; +031C;COMBINING LEFT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT HALF RING BELOW;;;; +031D;COMBINING UP TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING UP TACK BELOW;;;; +031E;COMBINING DOWN TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOWN TACK BELOW;;;; +031F;COMBINING PLUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING PLUS SIGN BELOW;;;; +0320;COMBINING MINUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING MINUS SIGN BELOW;;;; +0321;COMBINING PALATALIZED HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING PALATALIZED HOOK BELOW;;;; +0322;COMBINING RETROFLEX HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING RETROFLEX HOOK BELOW;;;; +0323;COMBINING DOT BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOT BELOW;;;; +0324;COMBINING DIAERESIS BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE DOT BELOW;;;; +0325;COMBINING RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RING BELOW;;;; +0326;COMBINING COMMA BELOW;Mn;220;NSM;;;;;N;NON-SPACING COMMA BELOW;;;; +0327;COMBINING CEDILLA;Mn;202;NSM;;;;;N;NON-SPACING CEDILLA;;;; +0328;COMBINING OGONEK;Mn;202;NSM;;;;;N;NON-SPACING OGONEK;;;; +0329;COMBINING VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;NON-SPACING VERTICAL LINE BELOW;;;; +032A;COMBINING BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BRIDGE BELOW;;;; +032B;COMBINING INVERTED DOUBLE ARCH BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED DOUBLE ARCH BELOW;;;; +032C;COMBINING CARON BELOW;Mn;220;NSM;;;;;N;NON-SPACING HACEK BELOW;;;; +032D;COMBINING CIRCUMFLEX ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING CIRCUMFLEX BELOW;;;; +032E;COMBINING BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BREVE BELOW;;;; +032F;COMBINING INVERTED BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BREVE BELOW;;;; +0330;COMBINING TILDE BELOW;Mn;220;NSM;;;;;N;NON-SPACING TILDE BELOW;;;; +0331;COMBINING MACRON BELOW;Mn;220;NSM;;;;;N;NON-SPACING MACRON BELOW;;;; +0332;COMBINING LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING UNDERSCORE;;;; +0333;COMBINING DOUBLE LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE UNDERSCORE;;;; +0334;COMBINING TILDE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING TILDE OVERLAY;;;; +0335;COMBINING SHORT STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT BAR OVERLAY;;;; +0336;COMBINING LONG STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG BAR OVERLAY;;;; +0337;COMBINING SHORT SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT SLASH OVERLAY;;;; +0338;COMBINING LONG SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG SLASH OVERLAY;;;; +0339;COMBINING RIGHT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT HALF RING BELOW;;;; +033A;COMBINING INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BRIDGE BELOW;;;; +033B;COMBINING SQUARE BELOW;Mn;220;NSM;;;;;N;NON-SPACING SQUARE BELOW;;;; +033C;COMBINING SEAGULL BELOW;Mn;220;NSM;;;;;N;NON-SPACING SEAGULL BELOW;;;; +033D;COMBINING X ABOVE;Mn;230;NSM;;;;;N;NON-SPACING X ABOVE;;;; +033E;COMBINING VERTICAL TILDE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL TILDE;;;; +033F;COMBINING DOUBLE OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE OVERSCORE;;;; +0340;COMBINING GRAVE TONE MARK;Mn;230;NSM;0300;;;;N;NON-SPACING GRAVE TONE MARK;;;; +0341;COMBINING ACUTE TONE MARK;Mn;230;NSM;0301;;;;N;NON-SPACING ACUTE TONE MARK;;;; +0342;COMBINING GREEK PERISPOMENI;Mn;230;NSM;;;;;N;;;;; +0343;COMBINING GREEK KORONIS;Mn;230;NSM;0313;;;;N;;;;; +0344;COMBINING GREEK DIALYTIKA TONOS;Mn;230;NSM;0308 0301;;;;N;GREEK NON-SPACING DIAERESIS TONOS;;;; +0345;COMBINING GREEK YPOGEGRAMMENI;Mn;240;NSM;;;;;N;GREEK NON-SPACING IOTA BELOW;;0399;;0399 +0346;COMBINING BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;; +0347;COMBINING EQUALS SIGN BELOW;Mn;220;NSM;;;;;N;;;;; +0348;COMBINING DOUBLE VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;;;;; +0349;COMBINING LEFT ANGLE BELOW;Mn;220;NSM;;;;;N;;;;; +034A;COMBINING NOT TILDE ABOVE;Mn;230;NSM;;;;;N;;;;; +034B;COMBINING HOMOTHETIC ABOVE;Mn;230;NSM;;;;;N;;;;; +034C;COMBINING ALMOST EQUAL TO ABOVE;Mn;230;NSM;;;;;N;;;;; +034D;COMBINING LEFT RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +034E;COMBINING UPWARDS ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +034F;COMBINING GRAPHEME JOINER;Mn;0;NSM;;;;;N;;;;; +0350;COMBINING RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;; +0351;COMBINING LEFT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;; +0352;COMBINING FERMATA;Mn;230;NSM;;;;;N;;;;; +0353;COMBINING X BELOW;Mn;220;NSM;;;;;N;;;;; +0354;COMBINING LEFT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +0355;COMBINING RIGHT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +0356;COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +0357;COMBINING RIGHT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;; +0358;COMBINING DOT ABOVE RIGHT;Mn;232;NSM;;;;;N;;;;; +0359;COMBINING ASTERISK BELOW;Mn;220;NSM;;;;;N;;;;; +035A;COMBINING DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;; +035B;COMBINING ZIGZAG ABOVE;Mn;230;NSM;;;;;N;;;;; +035C;COMBINING DOUBLE BREVE BELOW;Mn;233;NSM;;;;;N;;;;; +035D;COMBINING DOUBLE BREVE;Mn;234;NSM;;;;;N;;;;; +035E;COMBINING DOUBLE MACRON;Mn;234;NSM;;;;;N;;;;; +035F;COMBINING DOUBLE MACRON BELOW;Mn;233;NSM;;;;;N;;;;; +0360;COMBINING DOUBLE TILDE;Mn;234;NSM;;;;;N;;;;; +0361;COMBINING DOUBLE INVERTED BREVE;Mn;234;NSM;;;;;N;;;;; +0362;COMBINING DOUBLE RIGHTWARDS ARROW BELOW;Mn;233;NSM;;;;;N;;;;; +0363;COMBINING LATIN SMALL LETTER A;Mn;230;NSM;;;;;N;;;;; +0364;COMBINING LATIN SMALL LETTER E;Mn;230;NSM;;;;;N;;;;; +0365;COMBINING LATIN SMALL LETTER I;Mn;230;NSM;;;;;N;;;;; +0366;COMBINING LATIN SMALL LETTER O;Mn;230;NSM;;;;;N;;;;; +0367;COMBINING LATIN SMALL LETTER U;Mn;230;NSM;;;;;N;;;;; +0368;COMBINING LATIN SMALL LETTER C;Mn;230;NSM;;;;;N;;;;; +0369;COMBINING LATIN SMALL LETTER D;Mn;230;NSM;;;;;N;;;;; +036A;COMBINING LATIN SMALL LETTER H;Mn;230;NSM;;;;;N;;;;; +036B;COMBINING LATIN SMALL LETTER M;Mn;230;NSM;;;;;N;;;;; +036C;COMBINING LATIN SMALL LETTER R;Mn;230;NSM;;;;;N;;;;; +036D;COMBINING LATIN SMALL LETTER T;Mn;230;NSM;;;;;N;;;;; +036E;COMBINING LATIN SMALL LETTER V;Mn;230;NSM;;;;;N;;;;; +036F;COMBINING LATIN SMALL LETTER X;Mn;230;NSM;;;;;N;;;;; +0370;GREEK CAPITAL LETTER HETA;Lu;0;L;;;;;N;;;;0371; +0371;GREEK SMALL LETTER HETA;Ll;0;L;;;;;N;;;0370;;0370 +0372;GREEK CAPITAL LETTER ARCHAIC SAMPI;Lu;0;L;;;;;N;;;;0373; +0373;GREEK SMALL LETTER ARCHAIC SAMPI;Ll;0;L;;;;;N;;;0372;;0372 +0374;GREEK NUMERAL SIGN;Lm;0;ON;02B9;;;;N;GREEK UPPER NUMERAL SIGN;;;; +0375;GREEK LOWER NUMERAL SIGN;Sk;0;ON;;;;;N;;;;; +0376;GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA;Lu;0;L;;;;;N;;;;0377; +0377;GREEK SMALL LETTER PAMPHYLIAN DIGAMMA;Ll;0;L;;;;;N;;;0376;;0376 +037A;GREEK YPOGEGRAMMENI;Lm;0;L; 0020 0345;;;;N;GREEK SPACING IOTA BELOW;;;; +037B;GREEK SMALL REVERSED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FD;;03FD +037C;GREEK SMALL DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FE;;03FE +037D;GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FF;;03FF +037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;;;; +0384;GREEK TONOS;Sk;0;ON; 0020 0301;;;;N;GREEK SPACING TONOS;;;; +0385;GREEK DIALYTIKA TONOS;Sk;0;ON;00A8 0301;;;;N;GREEK SPACING DIAERESIS TONOS;;;; +0386;GREEK CAPITAL LETTER ALPHA WITH TONOS;Lu;0;L;0391 0301;;;;N;GREEK CAPITAL LETTER ALPHA TONOS;;;03AC; +0387;GREEK ANO TELEIA;Po;0;ON;00B7;;;;N;;;;; +0388;GREEK CAPITAL LETTER EPSILON WITH TONOS;Lu;0;L;0395 0301;;;;N;GREEK CAPITAL LETTER EPSILON TONOS;;;03AD; +0389;GREEK CAPITAL LETTER ETA WITH TONOS;Lu;0;L;0397 0301;;;;N;GREEK CAPITAL LETTER ETA TONOS;;;03AE; +038A;GREEK CAPITAL LETTER IOTA WITH TONOS;Lu;0;L;0399 0301;;;;N;GREEK CAPITAL LETTER IOTA TONOS;;;03AF; +038C;GREEK CAPITAL LETTER OMICRON WITH TONOS;Lu;0;L;039F 0301;;;;N;GREEK CAPITAL LETTER OMICRON TONOS;;;03CC; +038E;GREEK CAPITAL LETTER UPSILON WITH TONOS;Lu;0;L;03A5 0301;;;;N;GREEK CAPITAL LETTER UPSILON TONOS;;;03CD; +038F;GREEK CAPITAL LETTER OMEGA WITH TONOS;Lu;0;L;03A9 0301;;;;N;GREEK CAPITAL LETTER OMEGA TONOS;;;03CE; +0390;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS;Ll;0;L;03CA 0301;;;;N;GREEK SMALL LETTER IOTA DIAERESIS TONOS;;;; +0391;GREEK CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;03B1; +0392;GREEK CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;03B2; +0393;GREEK CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;03B3; +0394;GREEK CAPITAL LETTER DELTA;Lu;0;L;;;;;N;;;;03B4; +0395;GREEK CAPITAL LETTER EPSILON;Lu;0;L;;;;;N;;;;03B5; +0396;GREEK CAPITAL LETTER ZETA;Lu;0;L;;;;;N;;;;03B6; +0397;GREEK CAPITAL LETTER ETA;Lu;0;L;;;;;N;;;;03B7; +0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8; +0399;GREEK CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;03B9; +039A;GREEK CAPITAL LETTER KAPPA;Lu;0;L;;;;;N;;;;03BA; +039B;GREEK CAPITAL LETTER LAMDA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER LAMBDA;;;03BB; +039C;GREEK CAPITAL LETTER MU;Lu;0;L;;;;;N;;;;03BC; +039D;GREEK CAPITAL LETTER NU;Lu;0;L;;;;;N;;;;03BD; +039E;GREEK CAPITAL LETTER XI;Lu;0;L;;;;;N;;;;03BE; +039F;GREEK CAPITAL LETTER OMICRON;Lu;0;L;;;;;N;;;;03BF; +03A0;GREEK CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;03C0; +03A1;GREEK CAPITAL LETTER RHO;Lu;0;L;;;;;N;;;;03C1; +03A3;GREEK CAPITAL LETTER SIGMA;Lu;0;L;;;;;N;;;;03C3; +03A4;GREEK CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;03C4; +03A5;GREEK CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;03C5; +03A6;GREEK CAPITAL LETTER PHI;Lu;0;L;;;;;N;;;;03C6; +03A7;GREEK CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;03C7; +03A8;GREEK CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;03C8; +03A9;GREEK CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;03C9; +03AA;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA;Lu;0;L;0399 0308;;;;N;GREEK CAPITAL LETTER IOTA DIAERESIS;;;03CA; +03AB;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA;Lu;0;L;03A5 0308;;;;N;GREEK CAPITAL LETTER UPSILON DIAERESIS;;;03CB; +03AC;GREEK SMALL LETTER ALPHA WITH TONOS;Ll;0;L;03B1 0301;;;;N;GREEK SMALL LETTER ALPHA TONOS;;0386;;0386 +03AD;GREEK SMALL LETTER EPSILON WITH TONOS;Ll;0;L;03B5 0301;;;;N;GREEK SMALL LETTER EPSILON TONOS;;0388;;0388 +03AE;GREEK SMALL LETTER ETA WITH TONOS;Ll;0;L;03B7 0301;;;;N;GREEK SMALL LETTER ETA TONOS;;0389;;0389 +03AF;GREEK SMALL LETTER IOTA WITH TONOS;Ll;0;L;03B9 0301;;;;N;GREEK SMALL LETTER IOTA TONOS;;038A;;038A +03B0;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS;Ll;0;L;03CB 0301;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS TONOS;;;; +03B1;GREEK SMALL LETTER ALPHA;Ll;0;L;;;;;N;;;0391;;0391 +03B2;GREEK SMALL LETTER BETA;Ll;0;L;;;;;N;;;0392;;0392 +03B3;GREEK SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0393;;0393 +03B4;GREEK SMALL LETTER DELTA;Ll;0;L;;;;;N;;;0394;;0394 +03B5;GREEK SMALL LETTER EPSILON;Ll;0;L;;;;;N;;;0395;;0395 +03B6;GREEK SMALL LETTER ZETA;Ll;0;L;;;;;N;;;0396;;0396 +03B7;GREEK SMALL LETTER ETA;Ll;0;L;;;;;N;;;0397;;0397 +03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398 +03B9;GREEK SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0399;;0399 +03BA;GREEK SMALL LETTER KAPPA;Ll;0;L;;;;;N;;;039A;;039A +03BB;GREEK SMALL LETTER LAMDA;Ll;0;L;;;;;N;GREEK SMALL LETTER LAMBDA;;039B;;039B +03BC;GREEK SMALL LETTER MU;Ll;0;L;;;;;N;;;039C;;039C +03BD;GREEK SMALL LETTER NU;Ll;0;L;;;;;N;;;039D;;039D +03BE;GREEK SMALL LETTER XI;Ll;0;L;;;;;N;;;039E;;039E +03BF;GREEK SMALL LETTER OMICRON;Ll;0;L;;;;;N;;;039F;;039F +03C0;GREEK SMALL LETTER PI;Ll;0;L;;;;;N;;;03A0;;03A0 +03C1;GREEK SMALL LETTER RHO;Ll;0;L;;;;;N;;;03A1;;03A1 +03C2;GREEK SMALL LETTER FINAL SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3 +03C3;GREEK SMALL LETTER SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3 +03C4;GREEK SMALL LETTER TAU;Ll;0;L;;;;;N;;;03A4;;03A4 +03C5;GREEK SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;03A5;;03A5 +03C6;GREEK SMALL LETTER PHI;Ll;0;L;;;;;N;;;03A6;;03A6 +03C7;GREEK SMALL LETTER CHI;Ll;0;L;;;;;N;;;03A7;;03A7 +03C8;GREEK SMALL LETTER PSI;Ll;0;L;;;;;N;;;03A8;;03A8 +03C9;GREEK SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;03A9;;03A9 +03CA;GREEK SMALL LETTER IOTA WITH DIALYTIKA;Ll;0;L;03B9 0308;;;;N;GREEK SMALL LETTER IOTA DIAERESIS;;03AA;;03AA +03CB;GREEK SMALL LETTER UPSILON WITH DIALYTIKA;Ll;0;L;03C5 0308;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS;;03AB;;03AB +03CC;GREEK SMALL LETTER OMICRON WITH TONOS;Ll;0;L;03BF 0301;;;;N;GREEK SMALL LETTER OMICRON TONOS;;038C;;038C +03CD;GREEK SMALL LETTER UPSILON WITH TONOS;Ll;0;L;03C5 0301;;;;N;GREEK SMALL LETTER UPSILON TONOS;;038E;;038E +03CE;GREEK SMALL LETTER OMEGA WITH TONOS;Ll;0;L;03C9 0301;;;;N;GREEK SMALL LETTER OMEGA TONOS;;038F;;038F +03CF;GREEK CAPITAL KAI SYMBOL;Lu;0;L;;;;;N;;;;03D7; +03D0;GREEK BETA SYMBOL;Ll;0;L; 03B2;;;;N;GREEK SMALL LETTER CURLED BETA;;0392;;0392 +03D1;GREEK THETA SYMBOL;Ll;0;L; 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398 +03D2;GREEK UPSILON WITH HOOK SYMBOL;Lu;0;L; 03A5;;;;N;GREEK CAPITAL LETTER UPSILON HOOK;;;; +03D3;GREEK UPSILON WITH ACUTE AND HOOK SYMBOL;Lu;0;L;03D2 0301;;;;N;GREEK CAPITAL LETTER UPSILON HOOK TONOS;;;; +03D4;GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL;Lu;0;L;03D2 0308;;;;N;GREEK CAPITAL LETTER UPSILON HOOK DIAERESIS;;;; +03D5;GREEK PHI SYMBOL;Ll;0;L; 03C6;;;;N;GREEK SMALL LETTER SCRIPT PHI;;03A6;;03A6 +03D6;GREEK PI SYMBOL;Ll;0;L; 03C0;;;;N;GREEK SMALL LETTER OMEGA PI;;03A0;;03A0 +03D7;GREEK KAI SYMBOL;Ll;0;L;;;;;N;;;03CF;;03CF +03D8;GREEK LETTER ARCHAIC KOPPA;Lu;0;L;;;;;N;;;;03D9; +03D9;GREEK SMALL LETTER ARCHAIC KOPPA;Ll;0;L;;;;;N;;;03D8;;03D8 +03DA;GREEK LETTER STIGMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER STIGMA;;;03DB; +03DB;GREEK SMALL LETTER STIGMA;Ll;0;L;;;;;N;;;03DA;;03DA +03DC;GREEK LETTER DIGAMMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DIGAMMA;;;03DD; +03DD;GREEK SMALL LETTER DIGAMMA;Ll;0;L;;;;;N;;;03DC;;03DC +03DE;GREEK LETTER KOPPA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KOPPA;;;03DF; +03DF;GREEK SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;03DE;;03DE +03E0;GREEK LETTER SAMPI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SAMPI;;;03E1; +03E1;GREEK SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;03E0;;03E0 +03E2;COPTIC CAPITAL LETTER SHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHEI;;;03E3; +03E3;COPTIC SMALL LETTER SHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER SHEI;;03E2;;03E2 +03E4;COPTIC CAPITAL LETTER FEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER FEI;;;03E5; +03E5;COPTIC SMALL LETTER FEI;Ll;0;L;;;;;N;GREEK SMALL LETTER FEI;;03E4;;03E4 +03E6;COPTIC CAPITAL LETTER KHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KHEI;;;03E7; +03E7;COPTIC SMALL LETTER KHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER KHEI;;03E6;;03E6 +03E8;COPTIC CAPITAL LETTER HORI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER HORI;;;03E9; +03E9;COPTIC SMALL LETTER HORI;Ll;0;L;;;;;N;GREEK SMALL LETTER HORI;;03E8;;03E8 +03EA;COPTIC CAPITAL LETTER GANGIA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER GANGIA;;;03EB; +03EB;COPTIC SMALL LETTER GANGIA;Ll;0;L;;;;;N;GREEK SMALL LETTER GANGIA;;03EA;;03EA +03EC;COPTIC CAPITAL LETTER SHIMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHIMA;;;03ED; +03ED;COPTIC SMALL LETTER SHIMA;Ll;0;L;;;;;N;GREEK SMALL LETTER SHIMA;;03EC;;03EC +03EE;COPTIC CAPITAL LETTER DEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DEI;;;03EF; +03EF;COPTIC SMALL LETTER DEI;Ll;0;L;;;;;N;GREEK SMALL LETTER DEI;;03EE;;03EE +03F0;GREEK KAPPA SYMBOL;Ll;0;L; 03BA;;;;N;GREEK SMALL LETTER SCRIPT KAPPA;;039A;;039A +03F1;GREEK RHO SYMBOL;Ll;0;L; 03C1;;;;N;GREEK SMALL LETTER TAILED RHO;;03A1;;03A1 +03F2;GREEK LUNATE SIGMA SYMBOL;Ll;0;L; 03C2;;;;N;GREEK SMALL LETTER LUNATE SIGMA;;03F9;;03F9 +03F3;GREEK LETTER YOT;Ll;0;L;;;;;N;;;;; +03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L; 0398;;;;N;;;;03B8; +03F5;GREEK LUNATE EPSILON SYMBOL;Ll;0;L; 03B5;;;;N;;;0395;;0395 +03F6;GREEK REVERSED LUNATE EPSILON SYMBOL;Sm;0;ON;;;;;N;;;;; +03F7;GREEK CAPITAL LETTER SHO;Lu;0;L;;;;;N;;;;03F8; +03F8;GREEK SMALL LETTER SHO;Ll;0;L;;;;;N;;;03F7;;03F7 +03F9;GREEK CAPITAL LUNATE SIGMA SYMBOL;Lu;0;L; 03A3;;;;N;;;;03F2; +03FA;GREEK CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;03FB; +03FB;GREEK SMALL LETTER SAN;Ll;0;L;;;;;N;;;03FA;;03FA +03FC;GREEK RHO WITH STROKE SYMBOL;Ll;0;L;;;;;N;;;;; +03FD;GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037B; +03FE;GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037C; +03FF;GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037D; +0400;CYRILLIC CAPITAL LETTER IE WITH GRAVE;Lu;0;L;0415 0300;;;;N;;;;0450; +0401;CYRILLIC CAPITAL LETTER IO;Lu;0;L;0415 0308;;;;N;;;;0451; +0402;CYRILLIC CAPITAL LETTER DJE;Lu;0;L;;;;;N;;;;0452; +0403;CYRILLIC CAPITAL LETTER GJE;Lu;0;L;0413 0301;;;;N;;;;0453; +0404;CYRILLIC CAPITAL LETTER UKRAINIAN IE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER E;;;0454; +0405;CYRILLIC CAPITAL LETTER DZE;Lu;0;L;;;;;N;;;;0455; +0406;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER I;;;0456; +0407;CYRILLIC CAPITAL LETTER YI;Lu;0;L;0406 0308;;;;N;;;;0457; +0408;CYRILLIC CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;0458; +0409;CYRILLIC CAPITAL LETTER LJE;Lu;0;L;;;;;N;;;;0459; +040A;CYRILLIC CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;045A; +040B;CYRILLIC CAPITAL LETTER TSHE;Lu;0;L;;;;;N;;;;045B; +040C;CYRILLIC CAPITAL LETTER KJE;Lu;0;L;041A 0301;;;;N;;;;045C; +040D;CYRILLIC CAPITAL LETTER I WITH GRAVE;Lu;0;L;0418 0300;;;;N;;;;045D; +040E;CYRILLIC CAPITAL LETTER SHORT U;Lu;0;L;0423 0306;;;;N;;;;045E; +040F;CYRILLIC CAPITAL LETTER DZHE;Lu;0;L;;;;;N;;;;045F; +0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430; +0411;CYRILLIC CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;0431; +0412;CYRILLIC CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;0432; +0413;CYRILLIC CAPITAL LETTER GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE;;;0433; +0414;CYRILLIC CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;0434; +0415;CYRILLIC CAPITAL LETTER IE;Lu;0;L;;;;;N;;;;0435; +0416;CYRILLIC CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;0436; +0417;CYRILLIC CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;0437; +0418;CYRILLIC CAPITAL LETTER I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER II;;;0438; +0419;CYRILLIC CAPITAL LETTER SHORT I;Lu;0;L;0418 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT II;;;0439; +041A;CYRILLIC CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;043A; +041B;CYRILLIC CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;043B; +041C;CYRILLIC CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;043C; +041D;CYRILLIC CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;043D; +041E;CYRILLIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;043E; +041F;CYRILLIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;043F; +0420;CYRILLIC CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;0440; +0421;CYRILLIC CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;0441; +0422;CYRILLIC CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;0442; +0423;CYRILLIC CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0443; +0424;CYRILLIC CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;0444; +0425;CYRILLIC CAPITAL LETTER HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA;;;0445; +0426;CYRILLIC CAPITAL LETTER TSE;Lu;0;L;;;;;N;;;;0446; +0427;CYRILLIC CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;0447; +0428;CYRILLIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0448; +0429;CYRILLIC CAPITAL LETTER SHCHA;Lu;0;L;;;;;N;;;;0449; +042A;CYRILLIC CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;044A; +042B;CYRILLIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER YERI;;;044B; +042C;CYRILLIC CAPITAL LETTER SOFT SIGN;Lu;0;L;;;;;N;;;;044C; +042D;CYRILLIC CAPITAL LETTER E;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED E;;;044D; +042E;CYRILLIC CAPITAL LETTER YU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IU;;;044E; +042F;CYRILLIC CAPITAL LETTER YA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IA;;;044F; +0430;CYRILLIC SMALL LETTER A;Ll;0;L;;;;;N;;;0410;;0410 +0431;CYRILLIC SMALL LETTER BE;Ll;0;L;;;;;N;;;0411;;0411 +0432;CYRILLIC SMALL LETTER VE;Ll;0;L;;;;;N;;;0412;;0412 +0433;CYRILLIC SMALL LETTER GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE;;0413;;0413 +0434;CYRILLIC SMALL LETTER DE;Ll;0;L;;;;;N;;;0414;;0414 +0435;CYRILLIC SMALL LETTER IE;Ll;0;L;;;;;N;;;0415;;0415 +0436;CYRILLIC SMALL LETTER ZHE;Ll;0;L;;;;;N;;;0416;;0416 +0437;CYRILLIC SMALL LETTER ZE;Ll;0;L;;;;;N;;;0417;;0417 +0438;CYRILLIC SMALL LETTER I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER II;;0418;;0418 +0439;CYRILLIC SMALL LETTER SHORT I;Ll;0;L;0438 0306;;;;N;CYRILLIC SMALL LETTER SHORT II;;0419;;0419 +043A;CYRILLIC SMALL LETTER KA;Ll;0;L;;;;;N;;;041A;;041A +043B;CYRILLIC SMALL LETTER EL;Ll;0;L;;;;;N;;;041B;;041B +043C;CYRILLIC SMALL LETTER EM;Ll;0;L;;;;;N;;;041C;;041C +043D;CYRILLIC SMALL LETTER EN;Ll;0;L;;;;;N;;;041D;;041D +043E;CYRILLIC SMALL LETTER O;Ll;0;L;;;;;N;;;041E;;041E +043F;CYRILLIC SMALL LETTER PE;Ll;0;L;;;;;N;;;041F;;041F +0440;CYRILLIC SMALL LETTER ER;Ll;0;L;;;;;N;;;0420;;0420 +0441;CYRILLIC SMALL LETTER ES;Ll;0;L;;;;;N;;;0421;;0421 +0442;CYRILLIC SMALL LETTER TE;Ll;0;L;;;;;N;;;0422;;0422 +0443;CYRILLIC SMALL LETTER U;Ll;0;L;;;;;N;;;0423;;0423 +0444;CYRILLIC SMALL LETTER EF;Ll;0;L;;;;;N;;;0424;;0424 +0445;CYRILLIC SMALL LETTER HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA;;0425;;0425 +0446;CYRILLIC SMALL LETTER TSE;Ll;0;L;;;;;N;;;0426;;0426 +0447;CYRILLIC SMALL LETTER CHE;Ll;0;L;;;;;N;;;0427;;0427 +0448;CYRILLIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;0428;;0428 +0449;CYRILLIC SMALL LETTER SHCHA;Ll;0;L;;;;;N;;;0429;;0429 +044A;CYRILLIC SMALL LETTER HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A +044B;CYRILLIC SMALL LETTER YERU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER YERI;;042B;;042B +044C;CYRILLIC SMALL LETTER SOFT SIGN;Ll;0;L;;;;;N;;;042C;;042C +044D;CYRILLIC SMALL LETTER E;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED E;;042D;;042D +044E;CYRILLIC SMALL LETTER YU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IU;;042E;;042E +044F;CYRILLIC SMALL LETTER YA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IA;;042F;;042F +0450;CYRILLIC SMALL LETTER IE WITH GRAVE;Ll;0;L;0435 0300;;;;N;;;0400;;0400 +0451;CYRILLIC SMALL LETTER IO;Ll;0;L;0435 0308;;;;N;;;0401;;0401 +0452;CYRILLIC SMALL LETTER DJE;Ll;0;L;;;;;N;;;0402;;0402 +0453;CYRILLIC SMALL LETTER GJE;Ll;0;L;0433 0301;;;;N;;;0403;;0403 +0454;CYRILLIC SMALL LETTER UKRAINIAN IE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER E;;0404;;0404 +0455;CYRILLIC SMALL LETTER DZE;Ll;0;L;;;;;N;;;0405;;0405 +0456;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER I;;0406;;0406 +0457;CYRILLIC SMALL LETTER YI;Ll;0;L;0456 0308;;;;N;;;0407;;0407 +0458;CYRILLIC SMALL LETTER JE;Ll;0;L;;;;;N;;;0408;;0408 +0459;CYRILLIC SMALL LETTER LJE;Ll;0;L;;;;;N;;;0409;;0409 +045A;CYRILLIC SMALL LETTER NJE;Ll;0;L;;;;;N;;;040A;;040A +045B;CYRILLIC SMALL LETTER TSHE;Ll;0;L;;;;;N;;;040B;;040B +045C;CYRILLIC SMALL LETTER KJE;Ll;0;L;043A 0301;;;;N;;;040C;;040C +045D;CYRILLIC SMALL LETTER I WITH GRAVE;Ll;0;L;0438 0300;;;;N;;;040D;;040D +045E;CYRILLIC SMALL LETTER SHORT U;Ll;0;L;0443 0306;;;;N;;;040E;;040E +045F;CYRILLIC SMALL LETTER DZHE;Ll;0;L;;;;;N;;;040F;;040F +0460;CYRILLIC CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;0461; +0461;CYRILLIC SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;0460;;0460 +0462;CYRILLIC CAPITAL LETTER YAT;Lu;0;L;;;;;N;;;;0463; +0463;CYRILLIC SMALL LETTER YAT;Ll;0;L;;;;;N;;;0462;;0462 +0464;CYRILLIC CAPITAL LETTER IOTIFIED E;Lu;0;L;;;;;N;;;;0465; +0465;CYRILLIC SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;0464;;0464 +0466;CYRILLIC CAPITAL LETTER LITTLE YUS;Lu;0;L;;;;;N;;;;0467; +0467;CYRILLIC SMALL LETTER LITTLE YUS;Ll;0;L;;;;;N;;;0466;;0466 +0468;CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS;Lu;0;L;;;;;N;;;;0469; +0469;CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS;Ll;0;L;;;;;N;;;0468;;0468 +046A;CYRILLIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;046B; +046B;CYRILLIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;046A;;046A +046C;CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS;Lu;0;L;;;;;N;;;;046D; +046D;CYRILLIC SMALL LETTER IOTIFIED BIG YUS;Ll;0;L;;;;;N;;;046C;;046C +046E;CYRILLIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;046F; +046F;CYRILLIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;046E;;046E +0470;CYRILLIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;0471; +0471;CYRILLIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;0470;;0470 +0472;CYRILLIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;0473; +0473;CYRILLIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;0472;;0472 +0474;CYRILLIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;0475; +0475;CYRILLIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;0474;;0474 +0476;CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Lu;0;L;0474 030F;;;;N;CYRILLIC CAPITAL LETTER IZHITSA DOUBLE GRAVE;;;0477; +0477;CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Ll;0;L;0475 030F;;;;N;CYRILLIC SMALL LETTER IZHITSA DOUBLE GRAVE;;0476;;0476 +0478;CYRILLIC CAPITAL LETTER UK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER UK DIGRAPH;;;0479; +0479;CYRILLIC SMALL LETTER UK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER UK DIGRAPH;;0478;;0478 +047A;CYRILLIC CAPITAL LETTER ROUND OMEGA;Lu;0;L;;;;;N;;;;047B; +047B;CYRILLIC SMALL LETTER ROUND OMEGA;Ll;0;L;;;;;N;;;047A;;047A +047C;CYRILLIC CAPITAL LETTER OMEGA WITH TITLO;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER OMEGA TITLO;;;047D; +047D;CYRILLIC SMALL LETTER OMEGA WITH TITLO;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER OMEGA TITLO;;047C;;047C +047E;CYRILLIC CAPITAL LETTER OT;Lu;0;L;;;;;N;;;;047F; +047F;CYRILLIC SMALL LETTER OT;Ll;0;L;;;;;N;;;047E;;047E +0480;CYRILLIC CAPITAL LETTER KOPPA;Lu;0;L;;;;;N;;;;0481; +0481;CYRILLIC SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;0480;;0480 +0482;CYRILLIC THOUSANDS SIGN;So;0;L;;;;;N;;;;; +0483;COMBINING CYRILLIC TITLO;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING TITLO;;;; +0484;COMBINING CYRILLIC PALATALIZATION;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PALATALIZATION;;;; +0485;COMBINING CYRILLIC DASIA PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING DASIA PNEUMATA;;;; +0486;COMBINING CYRILLIC PSILI PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PSILI PNEUMATA;;;; +0487;COMBINING CYRILLIC POKRYTIE;Mn;230;NSM;;;;;N;;;;; +0488;COMBINING CYRILLIC HUNDRED THOUSANDS SIGN;Me;0;NSM;;;;;N;;;;; +0489;COMBINING CYRILLIC MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +048A;CYRILLIC CAPITAL LETTER SHORT I WITH TAIL;Lu;0;L;;;;;N;;;;048B; +048B;CYRILLIC SMALL LETTER SHORT I WITH TAIL;Ll;0;L;;;;;N;;;048A;;048A +048C;CYRILLIC CAPITAL LETTER SEMISOFT SIGN;Lu;0;L;;;;;N;;;;048D; +048D;CYRILLIC SMALL LETTER SEMISOFT SIGN;Ll;0;L;;;;;N;;;048C;;048C +048E;CYRILLIC CAPITAL LETTER ER WITH TICK;Lu;0;L;;;;;N;;;;048F; +048F;CYRILLIC SMALL LETTER ER WITH TICK;Ll;0;L;;;;;N;;;048E;;048E +0490;CYRILLIC CAPITAL LETTER GHE WITH UPTURN;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE WITH UPTURN;;;0491; +0491;CYRILLIC SMALL LETTER GHE WITH UPTURN;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE WITH UPTURN;;0490;;0490 +0492;CYRILLIC CAPITAL LETTER GHE WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE BAR;;;0493; +0493;CYRILLIC SMALL LETTER GHE WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE BAR;;0492;;0492 +0494;CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE HOOK;;;0495; +0495;CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE HOOK;;0494;;0494 +0496;CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZHE WITH RIGHT DESCENDER;;;0497; +0497;CYRILLIC SMALL LETTER ZHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZHE WITH RIGHT DESCENDER;;0496;;0496 +0498;CYRILLIC CAPITAL LETTER ZE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZE CEDILLA;;;0499; +0499;CYRILLIC SMALL LETTER ZE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZE CEDILLA;;0498;;0498 +049A;CYRILLIC CAPITAL LETTER KA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA WITH RIGHT DESCENDER;;;049B; +049B;CYRILLIC SMALL LETTER KA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA WITH RIGHT DESCENDER;;049A;;049A +049C;CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA VERTICAL BAR;;;049D; +049D;CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA VERTICAL BAR;;049C;;049C +049E;CYRILLIC CAPITAL LETTER KA WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA BAR;;;049F; +049F;CYRILLIC SMALL LETTER KA WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA BAR;;049E;;049E +04A0;CYRILLIC CAPITAL LETTER BASHKIR KA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED GE KA;;;04A1; +04A1;CYRILLIC SMALL LETTER BASHKIR KA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED GE KA;;04A0;;04A0 +04A2;CYRILLIC CAPITAL LETTER EN WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN WITH RIGHT DESCENDER;;;04A3; +04A3;CYRILLIC SMALL LETTER EN WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER;;04A2;;04A2 +04A4;CYRILLIC CAPITAL LIGATURE EN GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN GE;;;04A5; +04A5;CYRILLIC SMALL LIGATURE EN GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN GE;;04A4;;04A4 +04A6;CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER PE HOOK;;;04A7; +04A7;CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER PE HOOK;;04A6;;04A6 +04A8;CYRILLIC CAPITAL LETTER ABKHASIAN HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER O HOOK;;;04A9; +04A9;CYRILLIC SMALL LETTER ABKHASIAN HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER O HOOK;;04A8;;04A8 +04AA;CYRILLIC CAPITAL LETTER ES WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ES CEDILLA;;;04AB; +04AB;CYRILLIC SMALL LETTER ES WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ES CEDILLA;;04AA;;04AA +04AC;CYRILLIC CAPITAL LETTER TE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE WITH RIGHT DESCENDER;;;04AD; +04AD;CYRILLIC SMALL LETTER TE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE WITH RIGHT DESCENDER;;04AC;;04AC +04AE;CYRILLIC CAPITAL LETTER STRAIGHT U;Lu;0;L;;;;;N;;;;04AF; +04AF;CYRILLIC SMALL LETTER STRAIGHT U;Ll;0;L;;;;;N;;;04AE;;04AE +04B0;CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER STRAIGHT U BAR;;;04B1; +04B1;CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER STRAIGHT U BAR;;04B0;;04B0 +04B2;CYRILLIC CAPITAL LETTER HA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER;;;04B3; +04B3;CYRILLIC SMALL LETTER HA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER;;04B2;;04B2 +04B4;CYRILLIC CAPITAL LIGATURE TE TSE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE TSE;;;04B5; +04B5;CYRILLIC SMALL LIGATURE TE TSE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE TSE;;04B4;;04B4 +04B6;CYRILLIC CAPITAL LETTER CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER;;;04B7; +04B7;CYRILLIC SMALL LETTER CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER;;04B6;;04B6 +04B8;CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE VERTICAL BAR;;;04B9; +04B9;CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE VERTICAL BAR;;04B8;;04B8 +04BA;CYRILLIC CAPITAL LETTER SHHA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER H;;;04BB; +04BB;CYRILLIC SMALL LETTER SHHA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER H;;04BA;;04BA +04BC;CYRILLIC CAPITAL LETTER ABKHASIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK;;;04BD; +04BD;CYRILLIC SMALL LETTER ABKHASIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK;;04BC;;04BC +04BE;CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK OGONEK;;;04BF; +04BF;CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK OGONEK;;04BE;;04BE +04C0;CYRILLIC LETTER PALOCHKA;Lu;0;L;;;;;N;CYRILLIC LETTER I;;;04CF; +04C1;CYRILLIC CAPITAL LETTER ZHE WITH BREVE;Lu;0;L;0416 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT ZHE;;;04C2; +04C2;CYRILLIC SMALL LETTER ZHE WITH BREVE;Ll;0;L;0436 0306;;;;N;CYRILLIC SMALL LETTER SHORT ZHE;;04C1;;04C1 +04C3;CYRILLIC CAPITAL LETTER KA WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA HOOK;;;04C4; +04C4;CYRILLIC SMALL LETTER KA WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA HOOK;;04C3;;04C3 +04C5;CYRILLIC CAPITAL LETTER EL WITH TAIL;Lu;0;L;;;;;N;;;;04C6; +04C6;CYRILLIC SMALL LETTER EL WITH TAIL;Ll;0;L;;;;;N;;;04C5;;04C5 +04C7;CYRILLIC CAPITAL LETTER EN WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN HOOK;;;04C8; +04C8;CYRILLIC SMALL LETTER EN WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN HOOK;;04C7;;04C7 +04C9;CYRILLIC CAPITAL LETTER EN WITH TAIL;Lu;0;L;;;;;N;;;;04CA; +04CA;CYRILLIC SMALL LETTER EN WITH TAIL;Ll;0;L;;;;;N;;;04C9;;04C9 +04CB;CYRILLIC CAPITAL LETTER KHAKASSIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH LEFT DESCENDER;;;04CC; +04CC;CYRILLIC SMALL LETTER KHAKASSIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH LEFT DESCENDER;;04CB;;04CB +04CD;CYRILLIC CAPITAL LETTER EM WITH TAIL;Lu;0;L;;;;;N;;;;04CE; +04CE;CYRILLIC SMALL LETTER EM WITH TAIL;Ll;0;L;;;;;N;;;04CD;;04CD +04CF;CYRILLIC SMALL LETTER PALOCHKA;Ll;0;L;;;;;N;;;04C0;;04C0 +04D0;CYRILLIC CAPITAL LETTER A WITH BREVE;Lu;0;L;0410 0306;;;;N;;;;04D1; +04D1;CYRILLIC SMALL LETTER A WITH BREVE;Ll;0;L;0430 0306;;;;N;;;04D0;;04D0 +04D2;CYRILLIC CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0410 0308;;;;N;;;;04D3; +04D3;CYRILLIC SMALL LETTER A WITH DIAERESIS;Ll;0;L;0430 0308;;;;N;;;04D2;;04D2 +04D4;CYRILLIC CAPITAL LIGATURE A IE;Lu;0;L;;;;;N;;;;04D5; +04D5;CYRILLIC SMALL LIGATURE A IE;Ll;0;L;;;;;N;;;04D4;;04D4 +04D6;CYRILLIC CAPITAL LETTER IE WITH BREVE;Lu;0;L;0415 0306;;;;N;;;;04D7; +04D7;CYRILLIC SMALL LETTER IE WITH BREVE;Ll;0;L;0435 0306;;;;N;;;04D6;;04D6 +04D8;CYRILLIC CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;04D9; +04D9;CYRILLIC SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;04D8;;04D8 +04DA;CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS;Lu;0;L;04D8 0308;;;;N;;;;04DB; +04DB;CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS;Ll;0;L;04D9 0308;;;;N;;;04DA;;04DA +04DC;CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS;Lu;0;L;0416 0308;;;;N;;;;04DD; +04DD;CYRILLIC SMALL LETTER ZHE WITH DIAERESIS;Ll;0;L;0436 0308;;;;N;;;04DC;;04DC +04DE;CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS;Lu;0;L;0417 0308;;;;N;;;;04DF; +04DF;CYRILLIC SMALL LETTER ZE WITH DIAERESIS;Ll;0;L;0437 0308;;;;N;;;04DE;;04DE +04E0;CYRILLIC CAPITAL LETTER ABKHASIAN DZE;Lu;0;L;;;;;N;;;;04E1; +04E1;CYRILLIC SMALL LETTER ABKHASIAN DZE;Ll;0;L;;;;;N;;;04E0;;04E0 +04E2;CYRILLIC CAPITAL LETTER I WITH MACRON;Lu;0;L;0418 0304;;;;N;;;;04E3; +04E3;CYRILLIC SMALL LETTER I WITH MACRON;Ll;0;L;0438 0304;;;;N;;;04E2;;04E2 +04E4;CYRILLIC CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0418 0308;;;;N;;;;04E5; +04E5;CYRILLIC SMALL LETTER I WITH DIAERESIS;Ll;0;L;0438 0308;;;;N;;;04E4;;04E4 +04E6;CYRILLIC CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;041E 0308;;;;N;;;;04E7; +04E7;CYRILLIC SMALL LETTER O WITH DIAERESIS;Ll;0;L;043E 0308;;;;N;;;04E6;;04E6 +04E8;CYRILLIC CAPITAL LETTER BARRED O;Lu;0;L;;;;;N;;;;04E9; +04E9;CYRILLIC SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;04E8;;04E8 +04EA;CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS;Lu;0;L;04E8 0308;;;;N;;;;04EB; +04EB;CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS;Ll;0;L;04E9 0308;;;;N;;;04EA;;04EA +04EC;CYRILLIC CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;042D 0308;;;;N;;;;04ED; +04ED;CYRILLIC SMALL LETTER E WITH DIAERESIS;Ll;0;L;044D 0308;;;;N;;;04EC;;04EC +04EE;CYRILLIC CAPITAL LETTER U WITH MACRON;Lu;0;L;0423 0304;;;;N;;;;04EF; +04EF;CYRILLIC SMALL LETTER U WITH MACRON;Ll;0;L;0443 0304;;;;N;;;04EE;;04EE +04F0;CYRILLIC CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0423 0308;;;;N;;;;04F1; +04F1;CYRILLIC SMALL LETTER U WITH DIAERESIS;Ll;0;L;0443 0308;;;;N;;;04F0;;04F0 +04F2;CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0423 030B;;;;N;;;;04F3; +04F3;CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0443 030B;;;;N;;;04F2;;04F2 +04F4;CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS;Lu;0;L;0427 0308;;;;N;;;;04F5; +04F5;CYRILLIC SMALL LETTER CHE WITH DIAERESIS;Ll;0;L;0447 0308;;;;N;;;04F4;;04F4 +04F6;CYRILLIC CAPITAL LETTER GHE WITH DESCENDER;Lu;0;L;;;;;N;;;;04F7; +04F7;CYRILLIC SMALL LETTER GHE WITH DESCENDER;Ll;0;L;;;;;N;;;04F6;;04F6 +04F8;CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS;Lu;0;L;042B 0308;;;;N;;;;04F9; +04F9;CYRILLIC SMALL LETTER YERU WITH DIAERESIS;Ll;0;L;044B 0308;;;;N;;;04F8;;04F8 +04FA;CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK;Lu;0;L;;;;;N;;;;04FB; +04FB;CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK;Ll;0;L;;;;;N;;;04FA;;04FA +04FC;CYRILLIC CAPITAL LETTER HA WITH HOOK;Lu;0;L;;;;;N;;;;04FD; +04FD;CYRILLIC SMALL LETTER HA WITH HOOK;Ll;0;L;;;;;N;;;04FC;;04FC +04FE;CYRILLIC CAPITAL LETTER HA WITH STROKE;Lu;0;L;;;;;N;;;;04FF; +04FF;CYRILLIC SMALL LETTER HA WITH STROKE;Ll;0;L;;;;;N;;;04FE;;04FE +0500;CYRILLIC CAPITAL LETTER KOMI DE;Lu;0;L;;;;;N;;;;0501; +0501;CYRILLIC SMALL LETTER KOMI DE;Ll;0;L;;;;;N;;;0500;;0500 +0502;CYRILLIC CAPITAL LETTER KOMI DJE;Lu;0;L;;;;;N;;;;0503; +0503;CYRILLIC SMALL LETTER KOMI DJE;Ll;0;L;;;;;N;;;0502;;0502 +0504;CYRILLIC CAPITAL LETTER KOMI ZJE;Lu;0;L;;;;;N;;;;0505; +0505;CYRILLIC SMALL LETTER KOMI ZJE;Ll;0;L;;;;;N;;;0504;;0504 +0506;CYRILLIC CAPITAL LETTER KOMI DZJE;Lu;0;L;;;;;N;;;;0507; +0507;CYRILLIC SMALL LETTER KOMI DZJE;Ll;0;L;;;;;N;;;0506;;0506 +0508;CYRILLIC CAPITAL LETTER KOMI LJE;Lu;0;L;;;;;N;;;;0509; +0509;CYRILLIC SMALL LETTER KOMI LJE;Ll;0;L;;;;;N;;;0508;;0508 +050A;CYRILLIC CAPITAL LETTER KOMI NJE;Lu;0;L;;;;;N;;;;050B; +050B;CYRILLIC SMALL LETTER KOMI NJE;Ll;0;L;;;;;N;;;050A;;050A +050C;CYRILLIC CAPITAL LETTER KOMI SJE;Lu;0;L;;;;;N;;;;050D; +050D;CYRILLIC SMALL LETTER KOMI SJE;Ll;0;L;;;;;N;;;050C;;050C +050E;CYRILLIC CAPITAL LETTER KOMI TJE;Lu;0;L;;;;;N;;;;050F; +050F;CYRILLIC SMALL LETTER KOMI TJE;Ll;0;L;;;;;N;;;050E;;050E +0510;CYRILLIC CAPITAL LETTER REVERSED ZE;Lu;0;L;;;;;N;;;;0511; +0511;CYRILLIC SMALL LETTER REVERSED ZE;Ll;0;L;;;;;N;;;0510;;0510 +0512;CYRILLIC CAPITAL LETTER EL WITH HOOK;Lu;0;L;;;;;N;;;;0513; +0513;CYRILLIC SMALL LETTER EL WITH HOOK;Ll;0;L;;;;;N;;;0512;;0512 +0514;CYRILLIC CAPITAL LETTER LHA;Lu;0;L;;;;;N;;;;0515; +0515;CYRILLIC SMALL LETTER LHA;Ll;0;L;;;;;N;;;0514;;0514 +0516;CYRILLIC CAPITAL LETTER RHA;Lu;0;L;;;;;N;;;;0517; +0517;CYRILLIC SMALL LETTER RHA;Ll;0;L;;;;;N;;;0516;;0516 +0518;CYRILLIC CAPITAL LETTER YAE;Lu;0;L;;;;;N;;;;0519; +0519;CYRILLIC SMALL LETTER YAE;Ll;0;L;;;;;N;;;0518;;0518 +051A;CYRILLIC CAPITAL LETTER QA;Lu;0;L;;;;;N;;;;051B; +051B;CYRILLIC SMALL LETTER QA;Ll;0;L;;;;;N;;;051A;;051A +051C;CYRILLIC CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;051D; +051D;CYRILLIC SMALL LETTER WE;Ll;0;L;;;;;N;;;051C;;051C +051E;CYRILLIC CAPITAL LETTER ALEUT KA;Lu;0;L;;;;;N;;;;051F; +051F;CYRILLIC SMALL LETTER ALEUT KA;Ll;0;L;;;;;N;;;051E;;051E +0520;CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0521; +0521;CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0520;;0520 +0522;CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0523; +0523;CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0522;;0522 +0524;CYRILLIC CAPITAL LETTER PE WITH DESCENDER;Lu;0;L;;;;;N;;;;0525; +0525;CYRILLIC SMALL LETTER PE WITH DESCENDER;Ll;0;L;;;;;N;;;0524;;0524 +0531;ARMENIAN CAPITAL LETTER AYB;Lu;0;L;;;;;N;;;;0561; +0532;ARMENIAN CAPITAL LETTER BEN;Lu;0;L;;;;;N;;;;0562; +0533;ARMENIAN CAPITAL LETTER GIM;Lu;0;L;;;;;N;;;;0563; +0534;ARMENIAN CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;0564; +0535;ARMENIAN CAPITAL LETTER ECH;Lu;0;L;;;;;N;;;;0565; +0536;ARMENIAN CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;0566; +0537;ARMENIAN CAPITAL LETTER EH;Lu;0;L;;;;;N;;;;0567; +0538;ARMENIAN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;0568; +0539;ARMENIAN CAPITAL LETTER TO;Lu;0;L;;;;;N;;;;0569; +053A;ARMENIAN CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;056A; +053B;ARMENIAN CAPITAL LETTER INI;Lu;0;L;;;;;N;;;;056B; +053C;ARMENIAN CAPITAL LETTER LIWN;Lu;0;L;;;;;N;;;;056C; +053D;ARMENIAN CAPITAL LETTER XEH;Lu;0;L;;;;;N;;;;056D; +053E;ARMENIAN CAPITAL LETTER CA;Lu;0;L;;;;;N;;;;056E; +053F;ARMENIAN CAPITAL LETTER KEN;Lu;0;L;;;;;N;;;;056F; +0540;ARMENIAN CAPITAL LETTER HO;Lu;0;L;;;;;N;;;;0570; +0541;ARMENIAN CAPITAL LETTER JA;Lu;0;L;;;;;N;;;;0571; +0542;ARMENIAN CAPITAL LETTER GHAD;Lu;0;L;;;;;N;ARMENIAN CAPITAL LETTER LAD;;;0572; +0543;ARMENIAN CAPITAL LETTER CHEH;Lu;0;L;;;;;N;;;;0573; +0544;ARMENIAN CAPITAL LETTER MEN;Lu;0;L;;;;;N;;;;0574; +0545;ARMENIAN CAPITAL LETTER YI;Lu;0;L;;;;;N;;;;0575; +0546;ARMENIAN CAPITAL LETTER NOW;Lu;0;L;;;;;N;;;;0576; +0547;ARMENIAN CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0577; +0548;ARMENIAN CAPITAL LETTER VO;Lu;0;L;;;;;N;;;;0578; +0549;ARMENIAN CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;0579; +054A;ARMENIAN CAPITAL LETTER PEH;Lu;0;L;;;;;N;;;;057A; +054B;ARMENIAN CAPITAL LETTER JHEH;Lu;0;L;;;;;N;;;;057B; +054C;ARMENIAN CAPITAL LETTER RA;Lu;0;L;;;;;N;;;;057C; +054D;ARMENIAN CAPITAL LETTER SEH;Lu;0;L;;;;;N;;;;057D; +054E;ARMENIAN CAPITAL LETTER VEW;Lu;0;L;;;;;N;;;;057E; +054F;ARMENIAN CAPITAL LETTER TIWN;Lu;0;L;;;;;N;;;;057F; +0550;ARMENIAN CAPITAL LETTER REH;Lu;0;L;;;;;N;;;;0580; +0551;ARMENIAN CAPITAL LETTER CO;Lu;0;L;;;;;N;;;;0581; +0552;ARMENIAN CAPITAL LETTER YIWN;Lu;0;L;;;;;N;;;;0582; +0553;ARMENIAN CAPITAL LETTER PIWR;Lu;0;L;;;;;N;;;;0583; +0554;ARMENIAN CAPITAL LETTER KEH;Lu;0;L;;;;;N;;;;0584; +0555;ARMENIAN CAPITAL LETTER OH;Lu;0;L;;;;;N;;;;0585; +0556;ARMENIAN CAPITAL LETTER FEH;Lu;0;L;;;;;N;;;;0586; +0559;ARMENIAN MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;; +055A;ARMENIAN APOSTROPHE;Po;0;L;;;;;N;ARMENIAN MODIFIER LETTER RIGHT HALF RING;;;; +055B;ARMENIAN EMPHASIS MARK;Po;0;L;;;;;N;;;;; +055C;ARMENIAN EXCLAMATION MARK;Po;0;L;;;;;N;;;;; +055D;ARMENIAN COMMA;Po;0;L;;;;;N;;;;; +055E;ARMENIAN QUESTION MARK;Po;0;L;;;;;N;;;;; +055F;ARMENIAN ABBREVIATION MARK;Po;0;L;;;;;N;;;;; +0561;ARMENIAN SMALL LETTER AYB;Ll;0;L;;;;;N;;;0531;;0531 +0562;ARMENIAN SMALL LETTER BEN;Ll;0;L;;;;;N;;;0532;;0532 +0563;ARMENIAN SMALL LETTER GIM;Ll;0;L;;;;;N;;;0533;;0533 +0564;ARMENIAN SMALL LETTER DA;Ll;0;L;;;;;N;;;0534;;0534 +0565;ARMENIAN SMALL LETTER ECH;Ll;0;L;;;;;N;;;0535;;0535 +0566;ARMENIAN SMALL LETTER ZA;Ll;0;L;;;;;N;;;0536;;0536 +0567;ARMENIAN SMALL LETTER EH;Ll;0;L;;;;;N;;;0537;;0537 +0568;ARMENIAN SMALL LETTER ET;Ll;0;L;;;;;N;;;0538;;0538 +0569;ARMENIAN SMALL LETTER TO;Ll;0;L;;;;;N;;;0539;;0539 +056A;ARMENIAN SMALL LETTER ZHE;Ll;0;L;;;;;N;;;053A;;053A +056B;ARMENIAN SMALL LETTER INI;Ll;0;L;;;;;N;;;053B;;053B +056C;ARMENIAN SMALL LETTER LIWN;Ll;0;L;;;;;N;;;053C;;053C +056D;ARMENIAN SMALL LETTER XEH;Ll;0;L;;;;;N;;;053D;;053D +056E;ARMENIAN SMALL LETTER CA;Ll;0;L;;;;;N;;;053E;;053E +056F;ARMENIAN SMALL LETTER KEN;Ll;0;L;;;;;N;;;053F;;053F +0570;ARMENIAN SMALL LETTER HO;Ll;0;L;;;;;N;;;0540;;0540 +0571;ARMENIAN SMALL LETTER JA;Ll;0;L;;;;;N;;;0541;;0541 +0572;ARMENIAN SMALL LETTER GHAD;Ll;0;L;;;;;N;ARMENIAN SMALL LETTER LAD;;0542;;0542 +0573;ARMENIAN SMALL LETTER CHEH;Ll;0;L;;;;;N;;;0543;;0543 +0574;ARMENIAN SMALL LETTER MEN;Ll;0;L;;;;;N;;;0544;;0544 +0575;ARMENIAN SMALL LETTER YI;Ll;0;L;;;;;N;;;0545;;0545 +0576;ARMENIAN SMALL LETTER NOW;Ll;0;L;;;;;N;;;0546;;0546 +0577;ARMENIAN SMALL LETTER SHA;Ll;0;L;;;;;N;;;0547;;0547 +0578;ARMENIAN SMALL LETTER VO;Ll;0;L;;;;;N;;;0548;;0548 +0579;ARMENIAN SMALL LETTER CHA;Ll;0;L;;;;;N;;;0549;;0549 +057A;ARMENIAN SMALL LETTER PEH;Ll;0;L;;;;;N;;;054A;;054A +057B;ARMENIAN SMALL LETTER JHEH;Ll;0;L;;;;;N;;;054B;;054B +057C;ARMENIAN SMALL LETTER RA;Ll;0;L;;;;;N;;;054C;;054C +057D;ARMENIAN SMALL LETTER SEH;Ll;0;L;;;;;N;;;054D;;054D +057E;ARMENIAN SMALL LETTER VEW;Ll;0;L;;;;;N;;;054E;;054E +057F;ARMENIAN SMALL LETTER TIWN;Ll;0;L;;;;;N;;;054F;;054F +0580;ARMENIAN SMALL LETTER REH;Ll;0;L;;;;;N;;;0550;;0550 +0581;ARMENIAN SMALL LETTER CO;Ll;0;L;;;;;N;;;0551;;0551 +0582;ARMENIAN SMALL LETTER YIWN;Ll;0;L;;;;;N;;;0552;;0552 +0583;ARMENIAN SMALL LETTER PIWR;Ll;0;L;;;;;N;;;0553;;0553 +0584;ARMENIAN SMALL LETTER KEH;Ll;0;L;;;;;N;;;0554;;0554 +0585;ARMENIAN SMALL LETTER OH;Ll;0;L;;;;;N;;;0555;;0555 +0586;ARMENIAN SMALL LETTER FEH;Ll;0;L;;;;;N;;;0556;;0556 +0587;ARMENIAN SMALL LIGATURE ECH YIWN;Ll;0;L; 0565 0582;;;;N;;;;; +0589;ARMENIAN FULL STOP;Po;0;L;;;;;N;ARMENIAN PERIOD;;;; +058A;ARMENIAN HYPHEN;Pd;0;ON;;;;;N;;;;; +0591;HEBREW ACCENT ETNAHTA;Mn;220;NSM;;;;;N;;;;; +0592;HEBREW ACCENT SEGOL;Mn;230;NSM;;;;;N;;;;; +0593;HEBREW ACCENT SHALSHELET;Mn;230;NSM;;;;;N;;;;; +0594;HEBREW ACCENT ZAQEF QATAN;Mn;230;NSM;;;;;N;;;;; +0595;HEBREW ACCENT ZAQEF GADOL;Mn;230;NSM;;;;;N;;;;; +0596;HEBREW ACCENT TIPEHA;Mn;220;NSM;;;;;N;;;;; +0597;HEBREW ACCENT REVIA;Mn;230;NSM;;;;;N;;;;; +0598;HEBREW ACCENT ZARQA;Mn;230;NSM;;;;;N;;;;; +0599;HEBREW ACCENT PASHTA;Mn;230;NSM;;;;;N;;;;; +059A;HEBREW ACCENT YETIV;Mn;222;NSM;;;;;N;;;;; +059B;HEBREW ACCENT TEVIR;Mn;220;NSM;;;;;N;;;;; +059C;HEBREW ACCENT GERESH;Mn;230;NSM;;;;;N;;;;; +059D;HEBREW ACCENT GERESH MUQDAM;Mn;230;NSM;;;;;N;;;;; +059E;HEBREW ACCENT GERSHAYIM;Mn;230;NSM;;;;;N;;;;; +059F;HEBREW ACCENT QARNEY PARA;Mn;230;NSM;;;;;N;;;;; +05A0;HEBREW ACCENT TELISHA GEDOLA;Mn;230;NSM;;;;;N;;;;; +05A1;HEBREW ACCENT PAZER;Mn;230;NSM;;;;;N;;;;; +05A2;HEBREW ACCENT ATNAH HAFUKH;Mn;220;NSM;;;;;N;;;;; +05A3;HEBREW ACCENT MUNAH;Mn;220;NSM;;;;;N;;;;; +05A4;HEBREW ACCENT MAHAPAKH;Mn;220;NSM;;;;;N;;;;; +05A5;HEBREW ACCENT MERKHA;Mn;220;NSM;;;;;N;;;;; +05A6;HEBREW ACCENT MERKHA KEFULA;Mn;220;NSM;;;;;N;;;;; +05A7;HEBREW ACCENT DARGA;Mn;220;NSM;;;;;N;;;;; +05A8;HEBREW ACCENT QADMA;Mn;230;NSM;;;;;N;;;;; +05A9;HEBREW ACCENT TELISHA QETANA;Mn;230;NSM;;;;;N;;;;; +05AA;HEBREW ACCENT YERAH BEN YOMO;Mn;220;NSM;;;;;N;;;;; +05AB;HEBREW ACCENT OLE;Mn;230;NSM;;;;;N;;;;; +05AC;HEBREW ACCENT ILUY;Mn;230;NSM;;;;;N;;;;; +05AD;HEBREW ACCENT DEHI;Mn;222;NSM;;;;;N;;;;; +05AE;HEBREW ACCENT ZINOR;Mn;228;NSM;;;;;N;;;;; +05AF;HEBREW MARK MASORA CIRCLE;Mn;230;NSM;;;;;N;;;;; +05B0;HEBREW POINT SHEVA;Mn;10;NSM;;;;;N;;;;; +05B1;HEBREW POINT HATAF SEGOL;Mn;11;NSM;;;;;N;;;;; +05B2;HEBREW POINT HATAF PATAH;Mn;12;NSM;;;;;N;;;;; +05B3;HEBREW POINT HATAF QAMATS;Mn;13;NSM;;;;;N;;;;; +05B4;HEBREW POINT HIRIQ;Mn;14;NSM;;;;;N;;;;; +05B5;HEBREW POINT TSERE;Mn;15;NSM;;;;;N;;;;; +05B6;HEBREW POINT SEGOL;Mn;16;NSM;;;;;N;;;;; +05B7;HEBREW POINT PATAH;Mn;17;NSM;;;;;N;;;;; +05B8;HEBREW POINT QAMATS;Mn;18;NSM;;;;;N;;;;; +05B9;HEBREW POINT HOLAM;Mn;19;NSM;;;;;N;;;;; +05BA;HEBREW POINT HOLAM HASER FOR VAV;Mn;19;NSM;;;;;N;;;;; +05BB;HEBREW POINT QUBUTS;Mn;20;NSM;;;;;N;;;;; +05BC;HEBREW POINT DAGESH OR MAPIQ;Mn;21;NSM;;;;;N;HEBREW POINT DAGESH;;;; +05BD;HEBREW POINT METEG;Mn;22;NSM;;;;;N;;;;; +05BE;HEBREW PUNCTUATION MAQAF;Pd;0;R;;;;;N;;;;; +05BF;HEBREW POINT RAFE;Mn;23;NSM;;;;;N;;;;; +05C0;HEBREW PUNCTUATION PASEQ;Po;0;R;;;;;N;HEBREW POINT PASEQ;;;; +05C1;HEBREW POINT SHIN DOT;Mn;24;NSM;;;;;N;;;;; +05C2;HEBREW POINT SIN DOT;Mn;25;NSM;;;;;N;;;;; +05C3;HEBREW PUNCTUATION SOF PASUQ;Po;0;R;;;;;N;;;;; +05C4;HEBREW MARK UPPER DOT;Mn;230;NSM;;;;;N;;;;; +05C5;HEBREW MARK LOWER DOT;Mn;220;NSM;;;;;N;;;;; +05C6;HEBREW PUNCTUATION NUN HAFUKHA;Po;0;R;;;;;N;;;;; +05C7;HEBREW POINT QAMATS QATAN;Mn;18;NSM;;;;;N;;;;; +05D0;HEBREW LETTER ALEF;Lo;0;R;;;;;N;;;;; +05D1;HEBREW LETTER BET;Lo;0;R;;;;;N;;;;; +05D2;HEBREW LETTER GIMEL;Lo;0;R;;;;;N;;;;; +05D3;HEBREW LETTER DALET;Lo;0;R;;;;;N;;;;; +05D4;HEBREW LETTER HE;Lo;0;R;;;;;N;;;;; +05D5;HEBREW LETTER VAV;Lo;0;R;;;;;N;;;;; +05D6;HEBREW LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +05D7;HEBREW LETTER HET;Lo;0;R;;;;;N;;;;; +05D8;HEBREW LETTER TET;Lo;0;R;;;;;N;;;;; +05D9;HEBREW LETTER YOD;Lo;0;R;;;;;N;;;;; +05DA;HEBREW LETTER FINAL KAF;Lo;0;R;;;;;N;;;;; +05DB;HEBREW LETTER KAF;Lo;0;R;;;;;N;;;;; +05DC;HEBREW LETTER LAMED;Lo;0;R;;;;;N;;;;; +05DD;HEBREW LETTER FINAL MEM;Lo;0;R;;;;;N;;;;; +05DE;HEBREW LETTER MEM;Lo;0;R;;;;;N;;;;; +05DF;HEBREW LETTER FINAL NUN;Lo;0;R;;;;;N;;;;; +05E0;HEBREW LETTER NUN;Lo;0;R;;;;;N;;;;; +05E1;HEBREW LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +05E2;HEBREW LETTER AYIN;Lo;0;R;;;;;N;;;;; +05E3;HEBREW LETTER FINAL PE;Lo;0;R;;;;;N;;;;; +05E4;HEBREW LETTER PE;Lo;0;R;;;;;N;;;;; +05E5;HEBREW LETTER FINAL TSADI;Lo;0;R;;;;;N;;;;; +05E6;HEBREW LETTER TSADI;Lo;0;R;;;;;N;;;;; +05E7;HEBREW LETTER QOF;Lo;0;R;;;;;N;;;;; +05E8;HEBREW LETTER RESH;Lo;0;R;;;;;N;;;;; +05E9;HEBREW LETTER SHIN;Lo;0;R;;;;;N;;;;; +05EA;HEBREW LETTER TAV;Lo;0;R;;;;;N;;;;; +05F0;HEBREW LIGATURE YIDDISH DOUBLE VAV;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE VAV;;;; +05F1;HEBREW LIGATURE YIDDISH VAV YOD;Lo;0;R;;;;;N;HEBREW LETTER VAV YOD;;;; +05F2;HEBREW LIGATURE YIDDISH DOUBLE YOD;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE YOD;;;; +05F3;HEBREW PUNCTUATION GERESH;Po;0;R;;;;;N;;;;; +05F4;HEBREW PUNCTUATION GERSHAYIM;Po;0;R;;;;;N;;;;; +0600;ARABIC NUMBER SIGN;Cf;0;AN;;;;;N;;;;; +0601;ARABIC SIGN SANAH;Cf;0;AN;;;;;N;;;;; +0602;ARABIC FOOTNOTE MARKER;Cf;0;AN;;;;;N;;;;; +0603;ARABIC SIGN SAFHA;Cf;0;AN;;;;;N;;;;; +0606;ARABIC-INDIC CUBE ROOT;Sm;0;ON;;;;;N;;;;; +0607;ARABIC-INDIC FOURTH ROOT;Sm;0;ON;;;;;N;;;;; +0608;ARABIC RAY;Sm;0;AL;;;;;N;;;;; +0609;ARABIC-INDIC PER MILLE SIGN;Po;0;ET;;;;;N;;;;; +060A;ARABIC-INDIC PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;; +060B;AFGHANI SIGN;Sc;0;AL;;;;;N;;;;; +060C;ARABIC COMMA;Po;0;CS;;;;;N;;;;; +060D;ARABIC DATE SEPARATOR;Po;0;AL;;;;;N;;;;; +060E;ARABIC POETIC VERSE SIGN;So;0;ON;;;;;N;;;;; +060F;ARABIC SIGN MISRA;So;0;ON;;;;;N;;;;; +0610;ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM;Mn;230;NSM;;;;;N;;;;; +0611;ARABIC SIGN ALAYHE ASSALLAM;Mn;230;NSM;;;;;N;;;;; +0612;ARABIC SIGN RAHMATULLAH ALAYHE;Mn;230;NSM;;;;;N;;;;; +0613;ARABIC SIGN RADI ALLAHOU ANHU;Mn;230;NSM;;;;;N;;;;; +0614;ARABIC SIGN TAKHALLUS;Mn;230;NSM;;;;;N;;;;; +0615;ARABIC SMALL HIGH TAH;Mn;230;NSM;;;;;N;;;;; +0616;ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH;Mn;230;NSM;;;;;N;;;;; +0617;ARABIC SMALL HIGH ZAIN;Mn;230;NSM;;;;;N;;;;; +0618;ARABIC SMALL FATHA;Mn;30;NSM;;;;;N;;;;; +0619;ARABIC SMALL DAMMA;Mn;31;NSM;;;;;N;;;;; +061A;ARABIC SMALL KASRA;Mn;32;NSM;;;;;N;;;;; +061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;; +061E;ARABIC TRIPLE DOT PUNCTUATION MARK;Po;0;AL;;;;;N;;;;; +061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;; +0621;ARABIC LETTER HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH;;;; +0622;ARABIC LETTER ALEF WITH MADDA ABOVE;Lo;0;AL;0627 0653;;;;N;ARABIC LETTER MADDAH ON ALEF;;;; +0623;ARABIC LETTER ALEF WITH HAMZA ABOVE;Lo;0;AL;0627 0654;;;;N;ARABIC LETTER HAMZAH ON ALEF;;;; +0624;ARABIC LETTER WAW WITH HAMZA ABOVE;Lo;0;AL;0648 0654;;;;N;ARABIC LETTER HAMZAH ON WAW;;;; +0625;ARABIC LETTER ALEF WITH HAMZA BELOW;Lo;0;AL;0627 0655;;;;N;ARABIC LETTER HAMZAH UNDER ALEF;;;; +0626;ARABIC LETTER YEH WITH HAMZA ABOVE;Lo;0;AL;064A 0654;;;;N;ARABIC LETTER HAMZAH ON YA;;;; +0627;ARABIC LETTER ALEF;Lo;0;AL;;;;;N;;;;; +0628;ARABIC LETTER BEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA;;;; +0629;ARABIC LETTER TEH MARBUTA;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH;;;; +062A;ARABIC LETTER TEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA;;;; +062B;ARABIC LETTER THEH;Lo;0;AL;;;;;N;ARABIC LETTER THAA;;;; +062C;ARABIC LETTER JEEM;Lo;0;AL;;;;;N;;;;; +062D;ARABIC LETTER HAH;Lo;0;AL;;;;;N;ARABIC LETTER HAA;;;; +062E;ARABIC LETTER KHAH;Lo;0;AL;;;;;N;ARABIC LETTER KHAA;;;; +062F;ARABIC LETTER DAL;Lo;0;AL;;;;;N;;;;; +0630;ARABIC LETTER THAL;Lo;0;AL;;;;;N;;;;; +0631;ARABIC LETTER REH;Lo;0;AL;;;;;N;ARABIC LETTER RA;;;; +0632;ARABIC LETTER ZAIN;Lo;0;AL;;;;;N;;;;; +0633;ARABIC LETTER SEEN;Lo;0;AL;;;;;N;;;;; +0634;ARABIC LETTER SHEEN;Lo;0;AL;;;;;N;;;;; +0635;ARABIC LETTER SAD;Lo;0;AL;;;;;N;;;;; +0636;ARABIC LETTER DAD;Lo;0;AL;;;;;N;;;;; +0637;ARABIC LETTER TAH;Lo;0;AL;;;;;N;;;;; +0638;ARABIC LETTER ZAH;Lo;0;AL;;;;;N;ARABIC LETTER DHAH;;;; +0639;ARABIC LETTER AIN;Lo;0;AL;;;;;N;;;;; +063A;ARABIC LETTER GHAIN;Lo;0;AL;;;;;N;;;;; +063B;ARABIC LETTER KEHEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +063C;ARABIC LETTER KEHEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +063D;ARABIC LETTER FARSI YEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +063E;ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +063F;ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0640;ARABIC TATWEEL;Lm;0;AL;;;;;N;;;;; +0641;ARABIC LETTER FEH;Lo;0;AL;;;;;N;ARABIC LETTER FA;;;; +0642;ARABIC LETTER QAF;Lo;0;AL;;;;;N;;;;; +0643;ARABIC LETTER KAF;Lo;0;AL;;;;;N;ARABIC LETTER CAF;;;; +0644;ARABIC LETTER LAM;Lo;0;AL;;;;;N;;;;; +0645;ARABIC LETTER MEEM;Lo;0;AL;;;;;N;;;;; +0646;ARABIC LETTER NOON;Lo;0;AL;;;;;N;;;;; +0647;ARABIC LETTER HEH;Lo;0;AL;;;;;N;ARABIC LETTER HA;;;; +0648;ARABIC LETTER WAW;Lo;0;AL;;;;;N;;;;; +0649;ARABIC LETTER ALEF MAKSURA;Lo;0;AL;;;;;N;ARABIC LETTER ALEF MAQSURAH;;;; +064A;ARABIC LETTER YEH;Lo;0;AL;;;;;N;ARABIC LETTER YA;;;; +064B;ARABIC FATHATAN;Mn;27;NSM;;;;;N;;;;; +064C;ARABIC DAMMATAN;Mn;28;NSM;;;;;N;;;;; +064D;ARABIC KASRATAN;Mn;29;NSM;;;;;N;;;;; +064E;ARABIC FATHA;Mn;30;NSM;;;;;N;ARABIC FATHAH;;;; +064F;ARABIC DAMMA;Mn;31;NSM;;;;;N;ARABIC DAMMAH;;;; +0650;ARABIC KASRA;Mn;32;NSM;;;;;N;ARABIC KASRAH;;;; +0651;ARABIC SHADDA;Mn;33;NSM;;;;;N;ARABIC SHADDAH;;;; +0652;ARABIC SUKUN;Mn;34;NSM;;;;;N;;;;; +0653;ARABIC MADDAH ABOVE;Mn;230;NSM;;;;;N;;;;; +0654;ARABIC HAMZA ABOVE;Mn;230;NSM;;;;;N;;;;; +0655;ARABIC HAMZA BELOW;Mn;220;NSM;;;;;N;;;;; +0656;ARABIC SUBSCRIPT ALEF;Mn;220;NSM;;;;;N;;;;; +0657;ARABIC INVERTED DAMMA;Mn;230;NSM;;;;;N;;;;; +0658;ARABIC MARK NOON GHUNNA;Mn;230;NSM;;;;;N;;;;; +0659;ARABIC ZWARAKAY;Mn;230;NSM;;;;;N;;;;; +065A;ARABIC VOWEL SIGN SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;; +065B;ARABIC VOWEL SIGN INVERTED SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;; +065C;ARABIC VOWEL SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;; +065D;ARABIC REVERSED DAMMA;Mn;230;NSM;;;;;N;;;;; +065E;ARABIC FATHA WITH TWO DOTS;Mn;230;NSM;;;;;N;;;;; +0660;ARABIC-INDIC DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;; +0661;ARABIC-INDIC DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;; +0662;ARABIC-INDIC DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;; +0663;ARABIC-INDIC DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;; +0664;ARABIC-INDIC DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;; +0665;ARABIC-INDIC DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;; +0666;ARABIC-INDIC DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;; +0667;ARABIC-INDIC DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;; +0668;ARABIC-INDIC DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;; +0669;ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;; +066A;ARABIC PERCENT SIGN;Po;0;ET;;;;;N;;;;; +066B;ARABIC DECIMAL SEPARATOR;Po;0;AN;;;;;N;;;;; +066C;ARABIC THOUSANDS SEPARATOR;Po;0;AN;;;;;N;;;;; +066D;ARABIC FIVE POINTED STAR;Po;0;AL;;;;;N;;;;; +066E;ARABIC LETTER DOTLESS BEH;Lo;0;AL;;;;;N;;;;; +066F;ARABIC LETTER DOTLESS QAF;Lo;0;AL;;;;;N;;;;; +0670;ARABIC LETTER SUPERSCRIPT ALEF;Mn;35;NSM;;;;;N;ARABIC ALEF ABOVE;;;; +0671;ARABIC LETTER ALEF WASLA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAT WASL ON ALEF;;;; +0672;ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH ON ALEF;;;; +0673;ARABIC LETTER ALEF WITH WAVY HAMZA BELOW;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH UNDER ALEF;;;; +0674;ARABIC LETTER HIGH HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HIGH HAMZAH;;;; +0675;ARABIC LETTER HIGH HAMZA ALEF;Lo;0;AL; 0627 0674;;;;N;ARABIC LETTER HIGH HAMZAH ALEF;;;; +0676;ARABIC LETTER HIGH HAMZA WAW;Lo;0;AL; 0648 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW;;;; +0677;ARABIC LETTER U WITH HAMZA ABOVE;Lo;0;AL; 06C7 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW WITH DAMMAH;;;; +0678;ARABIC LETTER HIGH HAMZA YEH;Lo;0;AL; 064A 0674;;;;N;ARABIC LETTER HIGH HAMZAH YA;;;; +0679;ARABIC LETTER TTEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH SMALL TAH;;;; +067A;ARABIC LETTER TTEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH TWO DOTS VERTICAL ABOVE;;;; +067B;ARABIC LETTER BEEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH TWO DOTS VERTICAL BELOW;;;; +067C;ARABIC LETTER TEH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH RING;;;; +067D;ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS ABOVE DOWNWARD;;;; +067E;ARABIC LETTER PEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS BELOW;;;; +067F;ARABIC LETTER TEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH FOUR DOTS ABOVE;;;; +0680;ARABIC LETTER BEHEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH FOUR DOTS BELOW;;;; +0681;ARABIC LETTER HAH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH ON HAA;;;; +0682;ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH TWO DOTS VERTICAL ABOVE;;;; +0683;ARABIC LETTER NYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS;;;; +0684;ARABIC LETTER DYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS VERTICAL;;;; +0685;ARABIC LETTER HAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH THREE DOTS ABOVE;;;; +0686;ARABIC LETTER TCHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE THREE DOTS DOWNWARD;;;; +0687;ARABIC LETTER TCHEHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE FOUR DOTS;;;; +0688;ARABIC LETTER DDAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH SMALL TAH;;;; +0689;ARABIC LETTER DAL WITH RING;Lo;0;AL;;;;;N;;;;; +068A;ARABIC LETTER DAL WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +068B;ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;; +068C;ARABIC LETTER DAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS ABOVE;;;; +068D;ARABIC LETTER DDAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS BELOW;;;; +068E;ARABIC LETTER DUL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE;;;; +068F;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARD;;;; +0690;ARABIC LETTER DAL WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0691;ARABIC LETTER RREH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL TAH;;;; +0692;ARABIC LETTER REH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V;;;; +0693;ARABIC LETTER REH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH RING;;;; +0694;ARABIC LETTER REH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW;;;; +0695;ARABIC LETTER REH WITH SMALL V BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V BELOW;;;; +0696;ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW AND DOT ABOVE;;;; +0697;ARABIC LETTER REH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH TWO DOTS ABOVE;;;; +0698;ARABIC LETTER JEH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH THREE DOTS ABOVE;;;; +0699;ARABIC LETTER REH WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH FOUR DOTS ABOVE;;;; +069A;ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;; +069B;ARABIC LETTER SEEN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +069C;ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +069D;ARABIC LETTER SAD WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +069E;ARABIC LETTER SAD WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +069F;ARABIC LETTER TAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06A0;ARABIC LETTER AIN WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06A1;ARABIC LETTER DOTLESS FEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS FA;;;; +06A2;ARABIC LETTER FEH WITH DOT MOVED BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT MOVED BELOW;;;; +06A3;ARABIC LETTER FEH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT BELOW;;;; +06A4;ARABIC LETTER VEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS ABOVE;;;; +06A5;ARABIC LETTER FEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS BELOW;;;; +06A6;ARABIC LETTER PEHEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH FOUR DOTS ABOVE;;;; +06A7;ARABIC LETTER QAF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06A8;ARABIC LETTER QAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06A9;ARABIC LETTER KEHEH;Lo;0;AL;;;;;N;ARABIC LETTER OPEN CAF;;;; +06AA;ARABIC LETTER SWASH KAF;Lo;0;AL;;;;;N;ARABIC LETTER SWASH CAF;;;; +06AB;ARABIC LETTER KAF WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH RING;;;; +06AC;ARABIC LETTER KAF WITH DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH DOT ABOVE;;;; +06AD;ARABIC LETTER NG;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS ABOVE;;;; +06AE;ARABIC LETTER KAF WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS BELOW;;;; +06AF;ARABIC LETTER GAF;Lo;0;AL;;;;;N;;;;; +06B0;ARABIC LETTER GAF WITH RING;Lo;0;AL;;;;;N;;;;; +06B1;ARABIC LETTER NGOEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS ABOVE;;;; +06B2;ARABIC LETTER GAF WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +06B3;ARABIC LETTER GUEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS VERTICAL BELOW;;;; +06B4;ARABIC LETTER GAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06B5;ARABIC LETTER LAM WITH SMALL V;Lo;0;AL;;;;;N;;;;; +06B6;ARABIC LETTER LAM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06B7;ARABIC LETTER LAM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06B8;ARABIC LETTER LAM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +06B9;ARABIC LETTER NOON WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06BA;ARABIC LETTER NOON GHUNNA;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON;;;; +06BB;ARABIC LETTER RNOON;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON WITH SMALL TAH;;;; +06BC;ARABIC LETTER NOON WITH RING;Lo;0;AL;;;;;N;;;;; +06BD;ARABIC LETTER NOON WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06BE;ARABIC LETTER HEH DOACHASHMEE;Lo;0;AL;;;;;N;ARABIC LETTER KNOTTED HA;;;; +06BF;ARABIC LETTER TCHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06C0;ARABIC LETTER HEH WITH YEH ABOVE;Lo;0;AL;06D5 0654;;;;N;ARABIC LETTER HAMZAH ON HA;;;; +06C1;ARABIC LETTER HEH GOAL;Lo;0;AL;;;;;N;ARABIC LETTER HA GOAL;;;; +06C2;ARABIC LETTER HEH GOAL WITH HAMZA ABOVE;Lo;0;AL;06C1 0654;;;;N;ARABIC LETTER HAMZAH ON HA GOAL;;;; +06C3;ARABIC LETTER TEH MARBUTA GOAL;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH GOAL;;;; +06C4;ARABIC LETTER WAW WITH RING;Lo;0;AL;;;;;N;;;;; +06C5;ARABIC LETTER KIRGHIZ OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH BAR;;;; +06C6;ARABIC LETTER OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH SMALL V;;;; +06C7;ARABIC LETTER U;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH DAMMAH;;;; +06C8;ARABIC LETTER YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH ALEF ABOVE;;;; +06C9;ARABIC LETTER KIRGHIZ YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH INVERTED SMALL V;;;; +06CA;ARABIC LETTER WAW WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06CB;ARABIC LETTER VE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH THREE DOTS ABOVE;;;; +06CC;ARABIC LETTER FARSI YEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS YA;;;; +06CD;ARABIC LETTER YEH WITH TAIL;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TAIL;;;; +06CE;ARABIC LETTER YEH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH SMALL V;;;; +06CF;ARABIC LETTER WAW WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06D0;ARABIC LETTER E;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TWO DOTS VERTICAL BELOW;;;; +06D1;ARABIC LETTER YEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH THREE DOTS BELOW;;;; +06D2;ARABIC LETTER YEH BARREE;Lo;0;AL;;;;;N;ARABIC LETTER YA BARREE;;;; +06D3;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE;Lo;0;AL;06D2 0654;;;;N;ARABIC LETTER HAMZAH ON YA BARREE;;;; +06D4;ARABIC FULL STOP;Po;0;AL;;;;;N;ARABIC PERIOD;;;; +06D5;ARABIC LETTER AE;Lo;0;AL;;;;;N;;;;; +06D6;ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;; +06D7;ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;; +06D8;ARABIC SMALL HIGH MEEM INITIAL FORM;Mn;230;NSM;;;;;N;;;;; +06D9;ARABIC SMALL HIGH LAM ALEF;Mn;230;NSM;;;;;N;;;;; +06DA;ARABIC SMALL HIGH JEEM;Mn;230;NSM;;;;;N;;;;; +06DB;ARABIC SMALL HIGH THREE DOTS;Mn;230;NSM;;;;;N;;;;; +06DC;ARABIC SMALL HIGH SEEN;Mn;230;NSM;;;;;N;;;;; +06DD;ARABIC END OF AYAH;Cf;0;AN;;;;;N;;;;; +06DE;ARABIC START OF RUB EL HIZB;Me;0;NSM;;;;;N;;;;; +06DF;ARABIC SMALL HIGH ROUNDED ZERO;Mn;230;NSM;;;;;N;;;;; +06E0;ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO;Mn;230;NSM;;;;;N;;;;; +06E1;ARABIC SMALL HIGH DOTLESS HEAD OF KHAH;Mn;230;NSM;;;;;N;;;;; +06E2;ARABIC SMALL HIGH MEEM ISOLATED FORM;Mn;230;NSM;;;;;N;;;;; +06E3;ARABIC SMALL LOW SEEN;Mn;220;NSM;;;;;N;;;;; +06E4;ARABIC SMALL HIGH MADDA;Mn;230;NSM;;;;;N;;;;; +06E5;ARABIC SMALL WAW;Lm;0;AL;;;;;N;;;;; +06E6;ARABIC SMALL YEH;Lm;0;AL;;;;;N;;;;; +06E7;ARABIC SMALL HIGH YEH;Mn;230;NSM;;;;;N;;;;; +06E8;ARABIC SMALL HIGH NOON;Mn;230;NSM;;;;;N;;;;; +06E9;ARABIC PLACE OF SAJDAH;So;0;ON;;;;;N;;;;; +06EA;ARABIC EMPTY CENTRE LOW STOP;Mn;220;NSM;;;;;N;;;;; +06EB;ARABIC EMPTY CENTRE HIGH STOP;Mn;230;NSM;;;;;N;;;;; +06EC;ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE;Mn;230;NSM;;;;;N;;;;; +06ED;ARABIC SMALL LOW MEEM;Mn;220;NSM;;;;;N;;;;; +06EE;ARABIC LETTER DAL WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +06EF;ARABIC LETTER REH WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +06F0;EXTENDED ARABIC-INDIC DIGIT ZERO;Nd;0;EN;;0;0;0;N;EASTERN ARABIC-INDIC DIGIT ZERO;;;; +06F1;EXTENDED ARABIC-INDIC DIGIT ONE;Nd;0;EN;;1;1;1;N;EASTERN ARABIC-INDIC DIGIT ONE;;;; +06F2;EXTENDED ARABIC-INDIC DIGIT TWO;Nd;0;EN;;2;2;2;N;EASTERN ARABIC-INDIC DIGIT TWO;;;; +06F3;EXTENDED ARABIC-INDIC DIGIT THREE;Nd;0;EN;;3;3;3;N;EASTERN ARABIC-INDIC DIGIT THREE;;;; +06F4;EXTENDED ARABIC-INDIC DIGIT FOUR;Nd;0;EN;;4;4;4;N;EASTERN ARABIC-INDIC DIGIT FOUR;;;; +06F5;EXTENDED ARABIC-INDIC DIGIT FIVE;Nd;0;EN;;5;5;5;N;EASTERN ARABIC-INDIC DIGIT FIVE;;;; +06F6;EXTENDED ARABIC-INDIC DIGIT SIX;Nd;0;EN;;6;6;6;N;EASTERN ARABIC-INDIC DIGIT SIX;;;; +06F7;EXTENDED ARABIC-INDIC DIGIT SEVEN;Nd;0;EN;;7;7;7;N;EASTERN ARABIC-INDIC DIGIT SEVEN;;;; +06F8;EXTENDED ARABIC-INDIC DIGIT EIGHT;Nd;0;EN;;8;8;8;N;EASTERN ARABIC-INDIC DIGIT EIGHT;;;; +06F9;EXTENDED ARABIC-INDIC DIGIT NINE;Nd;0;EN;;9;9;9;N;EASTERN ARABIC-INDIC DIGIT NINE;;;; +06FA;ARABIC LETTER SHEEN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06FB;ARABIC LETTER DAD WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06FC;ARABIC LETTER GHAIN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06FD;ARABIC SIGN SINDHI AMPERSAND;So;0;AL;;;;;N;;;;; +06FE;ARABIC SIGN SINDHI POSTPOSITION MEN;So;0;AL;;;;;N;;;;; +06FF;ARABIC LETTER HEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +0700;SYRIAC END OF PARAGRAPH;Po;0;AL;;;;;N;;;;; +0701;SYRIAC SUPRALINEAR FULL STOP;Po;0;AL;;;;;N;;;;; +0702;SYRIAC SUBLINEAR FULL STOP;Po;0;AL;;;;;N;;;;; +0703;SYRIAC SUPRALINEAR COLON;Po;0;AL;;;;;N;;;;; +0704;SYRIAC SUBLINEAR COLON;Po;0;AL;;;;;N;;;;; +0705;SYRIAC HORIZONTAL COLON;Po;0;AL;;;;;N;;;;; +0706;SYRIAC COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;; +0707;SYRIAC COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;; +0708;SYRIAC SUPRALINEAR COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;; +0709;SYRIAC SUBLINEAR COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;; +070A;SYRIAC CONTRACTION;Po;0;AL;;;;;N;;;;; +070B;SYRIAC HARKLEAN OBELUS;Po;0;AL;;;;;N;;;;; +070C;SYRIAC HARKLEAN METOBELUS;Po;0;AL;;;;;N;;;;; +070D;SYRIAC HARKLEAN ASTERISCUS;Po;0;AL;;;;;N;;;;; +070F;SYRIAC ABBREVIATION MARK;Cf;0;BN;;;;;N;;;;; +0710;SYRIAC LETTER ALAPH;Lo;0;AL;;;;;N;;;;; +0711;SYRIAC LETTER SUPERSCRIPT ALAPH;Mn;36;NSM;;;;;N;;;;; +0712;SYRIAC LETTER BETH;Lo;0;AL;;;;;N;;;;; +0713;SYRIAC LETTER GAMAL;Lo;0;AL;;;;;N;;;;; +0714;SYRIAC LETTER GAMAL GARSHUNI;Lo;0;AL;;;;;N;;;;; +0715;SYRIAC LETTER DALATH;Lo;0;AL;;;;;N;;;;; +0716;SYRIAC LETTER DOTLESS DALATH RISH;Lo;0;AL;;;;;N;;;;; +0717;SYRIAC LETTER HE;Lo;0;AL;;;;;N;;;;; +0718;SYRIAC LETTER WAW;Lo;0;AL;;;;;N;;;;; +0719;SYRIAC LETTER ZAIN;Lo;0;AL;;;;;N;;;;; +071A;SYRIAC LETTER HETH;Lo;0;AL;;;;;N;;;;; +071B;SYRIAC LETTER TETH;Lo;0;AL;;;;;N;;;;; +071C;SYRIAC LETTER TETH GARSHUNI;Lo;0;AL;;;;;N;;;;; +071D;SYRIAC LETTER YUDH;Lo;0;AL;;;;;N;;;;; +071E;SYRIAC LETTER YUDH HE;Lo;0;AL;;;;;N;;;;; +071F;SYRIAC LETTER KAPH;Lo;0;AL;;;;;N;;;;; +0720;SYRIAC LETTER LAMADH;Lo;0;AL;;;;;N;;;;; +0721;SYRIAC LETTER MIM;Lo;0;AL;;;;;N;;;;; +0722;SYRIAC LETTER NUN;Lo;0;AL;;;;;N;;;;; +0723;SYRIAC LETTER SEMKATH;Lo;0;AL;;;;;N;;;;; +0724;SYRIAC LETTER FINAL SEMKATH;Lo;0;AL;;;;;N;;;;; +0725;SYRIAC LETTER E;Lo;0;AL;;;;;N;;;;; +0726;SYRIAC LETTER PE;Lo;0;AL;;;;;N;;;;; +0727;SYRIAC LETTER REVERSED PE;Lo;0;AL;;;;;N;;;;; +0728;SYRIAC LETTER SADHE;Lo;0;AL;;;;;N;;;;; +0729;SYRIAC LETTER QAPH;Lo;0;AL;;;;;N;;;;; +072A;SYRIAC LETTER RISH;Lo;0;AL;;;;;N;;;;; +072B;SYRIAC LETTER SHIN;Lo;0;AL;;;;;N;;;;; +072C;SYRIAC LETTER TAW;Lo;0;AL;;;;;N;;;;; +072D;SYRIAC LETTER PERSIAN BHETH;Lo;0;AL;;;;;N;;;;; +072E;SYRIAC LETTER PERSIAN GHAMAL;Lo;0;AL;;;;;N;;;;; +072F;SYRIAC LETTER PERSIAN DHALATH;Lo;0;AL;;;;;N;;;;; +0730;SYRIAC PTHAHA ABOVE;Mn;230;NSM;;;;;N;;;;; +0731;SYRIAC PTHAHA BELOW;Mn;220;NSM;;;;;N;;;;; +0732;SYRIAC PTHAHA DOTTED;Mn;230;NSM;;;;;N;;;;; +0733;SYRIAC ZQAPHA ABOVE;Mn;230;NSM;;;;;N;;;;; +0734;SYRIAC ZQAPHA BELOW;Mn;220;NSM;;;;;N;;;;; +0735;SYRIAC ZQAPHA DOTTED;Mn;230;NSM;;;;;N;;;;; +0736;SYRIAC RBASA ABOVE;Mn;230;NSM;;;;;N;;;;; +0737;SYRIAC RBASA BELOW;Mn;220;NSM;;;;;N;;;;; +0738;SYRIAC DOTTED ZLAMA HORIZONTAL;Mn;220;NSM;;;;;N;;;;; +0739;SYRIAC DOTTED ZLAMA ANGULAR;Mn;220;NSM;;;;;N;;;;; +073A;SYRIAC HBASA ABOVE;Mn;230;NSM;;;;;N;;;;; +073B;SYRIAC HBASA BELOW;Mn;220;NSM;;;;;N;;;;; +073C;SYRIAC HBASA-ESASA DOTTED;Mn;220;NSM;;;;;N;;;;; +073D;SYRIAC ESASA ABOVE;Mn;230;NSM;;;;;N;;;;; +073E;SYRIAC ESASA BELOW;Mn;220;NSM;;;;;N;;;;; +073F;SYRIAC RWAHA;Mn;230;NSM;;;;;N;;;;; +0740;SYRIAC FEMININE DOT;Mn;230;NSM;;;;;N;;;;; +0741;SYRIAC QUSHSHAYA;Mn;230;NSM;;;;;N;;;;; +0742;SYRIAC RUKKAKHA;Mn;220;NSM;;;;;N;;;;; +0743;SYRIAC TWO VERTICAL DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; +0744;SYRIAC TWO VERTICAL DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +0745;SYRIAC THREE DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; +0746;SYRIAC THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +0747;SYRIAC OBLIQUE LINE ABOVE;Mn;230;NSM;;;;;N;;;;; +0748;SYRIAC OBLIQUE LINE BELOW;Mn;220;NSM;;;;;N;;;;; +0749;SYRIAC MUSIC;Mn;230;NSM;;;;;N;;;;; +074A;SYRIAC BARREKH;Mn;230;NSM;;;;;N;;;;; +074D;SYRIAC LETTER SOGDIAN ZHAIN;Lo;0;AL;;;;;N;;;;; +074E;SYRIAC LETTER SOGDIAN KHAPH;Lo;0;AL;;;;;N;;;;; +074F;SYRIAC LETTER SOGDIAN FE;Lo;0;AL;;;;;N;;;;; +0750;ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW;Lo;0;AL;;;;;N;;;;; +0751;ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0752;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;; +0753;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0754;ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;; +0755;ARABIC LETTER BEH WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;; +0756;ARABIC LETTER BEH WITH SMALL V;Lo;0;AL;;;;;N;;;;; +0757;ARABIC LETTER HAH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0758;ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;; +0759;ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;; +075A;ARABIC LETTER DAL WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;; +075B;ARABIC LETTER REH WITH STROKE;Lo;0;AL;;;;;N;;;;; +075C;ARABIC LETTER SEEN WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +075D;ARABIC LETTER AIN WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +075E;ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE;Lo;0;AL;;;;;N;;;;; +075F;ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;; +0760;ARABIC LETTER FEH WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +0761;ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;; +0762;ARABIC LETTER KEHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +0763;ARABIC LETTER KEHEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0764;ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;; +0765;ARABIC LETTER MEEM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +0766;ARABIC LETTER MEEM WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +0767;ARABIC LETTER NOON WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +0768;ARABIC LETTER NOON WITH SMALL TAH;Lo;0;AL;;;;;N;;;;; +0769;ARABIC LETTER NOON WITH SMALL V;Lo;0;AL;;;;;N;;;;; +076A;ARABIC LETTER LAM WITH BAR;Lo;0;AL;;;;;N;;;;; +076B;ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;; +076C;ARABIC LETTER REH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;; +076D;ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;; +076E;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH BELOW;Lo;0;AL;;;;;N;;;;; +076F;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;; +0770;ARABIC LETTER SEEN WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;; +0771;ARABIC LETTER REH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;; +0772;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH ABOVE;Lo;0;AL;;;;;N;;;;; +0773;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;; +0774;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;; +0775;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;; +0776;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;; +0777;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;; +0778;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;; +0779;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;; +077A;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;; +077B;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;; +077C;ARABIC LETTER HAH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;; +077D;ARABIC LETTER SEEN WITH EXTENDED ARABIC-INDIC DIGIT FOUR ABOVE;Lo;0;AL;;;;;N;;;;; +077E;ARABIC LETTER SEEN WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +077F;ARABIC LETTER KAF WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0780;THAANA LETTER HAA;Lo;0;AL;;;;;N;;;;; +0781;THAANA LETTER SHAVIYANI;Lo;0;AL;;;;;N;;;;; +0782;THAANA LETTER NOONU;Lo;0;AL;;;;;N;;;;; +0783;THAANA LETTER RAA;Lo;0;AL;;;;;N;;;;; +0784;THAANA LETTER BAA;Lo;0;AL;;;;;N;;;;; +0785;THAANA LETTER LHAVIYANI;Lo;0;AL;;;;;N;;;;; +0786;THAANA LETTER KAAFU;Lo;0;AL;;;;;N;;;;; +0787;THAANA LETTER ALIFU;Lo;0;AL;;;;;N;;;;; +0788;THAANA LETTER VAAVU;Lo;0;AL;;;;;N;;;;; +0789;THAANA LETTER MEEMU;Lo;0;AL;;;;;N;;;;; +078A;THAANA LETTER FAAFU;Lo;0;AL;;;;;N;;;;; +078B;THAANA LETTER DHAALU;Lo;0;AL;;;;;N;;;;; +078C;THAANA LETTER THAA;Lo;0;AL;;;;;N;;;;; +078D;THAANA LETTER LAAMU;Lo;0;AL;;;;;N;;;;; +078E;THAANA LETTER GAAFU;Lo;0;AL;;;;;N;;;;; +078F;THAANA LETTER GNAVIYANI;Lo;0;AL;;;;;N;;;;; +0790;THAANA LETTER SEENU;Lo;0;AL;;;;;N;;;;; +0791;THAANA LETTER DAVIYANI;Lo;0;AL;;;;;N;;;;; +0792;THAANA LETTER ZAVIYANI;Lo;0;AL;;;;;N;;;;; +0793;THAANA LETTER TAVIYANI;Lo;0;AL;;;;;N;;;;; +0794;THAANA LETTER YAA;Lo;0;AL;;;;;N;;;;; +0795;THAANA LETTER PAVIYANI;Lo;0;AL;;;;;N;;;;; +0796;THAANA LETTER JAVIYANI;Lo;0;AL;;;;;N;;;;; +0797;THAANA LETTER CHAVIYANI;Lo;0;AL;;;;;N;;;;; +0798;THAANA LETTER TTAA;Lo;0;AL;;;;;N;;;;; +0799;THAANA LETTER HHAA;Lo;0;AL;;;;;N;;;;; +079A;THAANA LETTER KHAA;Lo;0;AL;;;;;N;;;;; +079B;THAANA LETTER THAALU;Lo;0;AL;;;;;N;;;;; +079C;THAANA LETTER ZAA;Lo;0;AL;;;;;N;;;;; +079D;THAANA LETTER SHEENU;Lo;0;AL;;;;;N;;;;; +079E;THAANA LETTER SAADHU;Lo;0;AL;;;;;N;;;;; +079F;THAANA LETTER DAADHU;Lo;0;AL;;;;;N;;;;; +07A0;THAANA LETTER TO;Lo;0;AL;;;;;N;;;;; +07A1;THAANA LETTER ZO;Lo;0;AL;;;;;N;;;;; +07A2;THAANA LETTER AINU;Lo;0;AL;;;;;N;;;;; +07A3;THAANA LETTER GHAINU;Lo;0;AL;;;;;N;;;;; +07A4;THAANA LETTER QAAFU;Lo;0;AL;;;;;N;;;;; +07A5;THAANA LETTER WAAVU;Lo;0;AL;;;;;N;;;;; +07A6;THAANA ABAFILI;Mn;0;NSM;;;;;N;;;;; +07A7;THAANA AABAAFILI;Mn;0;NSM;;;;;N;;;;; +07A8;THAANA IBIFILI;Mn;0;NSM;;;;;N;;;;; +07A9;THAANA EEBEEFILI;Mn;0;NSM;;;;;N;;;;; +07AA;THAANA UBUFILI;Mn;0;NSM;;;;;N;;;;; +07AB;THAANA OOBOOFILI;Mn;0;NSM;;;;;N;;;;; +07AC;THAANA EBEFILI;Mn;0;NSM;;;;;N;;;;; +07AD;THAANA EYBEYFILI;Mn;0;NSM;;;;;N;;;;; +07AE;THAANA OBOFILI;Mn;0;NSM;;;;;N;;;;; +07AF;THAANA OABOAFILI;Mn;0;NSM;;;;;N;;;;; +07B0;THAANA SUKUN;Mn;0;NSM;;;;;N;;;;; +07B1;THAANA LETTER NAA;Lo;0;AL;;;;;N;;;;; +07C0;NKO DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;; +07C1;NKO DIGIT ONE;Nd;0;R;;1;1;1;N;;;;; +07C2;NKO DIGIT TWO;Nd;0;R;;2;2;2;N;;;;; +07C3;NKO DIGIT THREE;Nd;0;R;;3;3;3;N;;;;; +07C4;NKO DIGIT FOUR;Nd;0;R;;4;4;4;N;;;;; +07C5;NKO DIGIT FIVE;Nd;0;R;;5;5;5;N;;;;; +07C6;NKO DIGIT SIX;Nd;0;R;;6;6;6;N;;;;; +07C7;NKO DIGIT SEVEN;Nd;0;R;;7;7;7;N;;;;; +07C8;NKO DIGIT EIGHT;Nd;0;R;;8;8;8;N;;;;; +07C9;NKO DIGIT NINE;Nd;0;R;;9;9;9;N;;;;; +07CA;NKO LETTER A;Lo;0;R;;;;;N;;;;; +07CB;NKO LETTER EE;Lo;0;R;;;;;N;;;;; +07CC;NKO LETTER I;Lo;0;R;;;;;N;;;;; +07CD;NKO LETTER E;Lo;0;R;;;;;N;;;;; +07CE;NKO LETTER U;Lo;0;R;;;;;N;;;;; +07CF;NKO LETTER OO;Lo;0;R;;;;;N;;;;; +07D0;NKO LETTER O;Lo;0;R;;;;;N;;;;; +07D1;NKO LETTER DAGBASINNA;Lo;0;R;;;;;N;;;;; +07D2;NKO LETTER N;Lo;0;R;;;;;N;;;;; +07D3;NKO LETTER BA;Lo;0;R;;;;;N;;;;; +07D4;NKO LETTER PA;Lo;0;R;;;;;N;;;;; +07D5;NKO LETTER TA;Lo;0;R;;;;;N;;;;; +07D6;NKO LETTER JA;Lo;0;R;;;;;N;;;;; +07D7;NKO LETTER CHA;Lo;0;R;;;;;N;;;;; +07D8;NKO LETTER DA;Lo;0;R;;;;;N;;;;; +07D9;NKO LETTER RA;Lo;0;R;;;;;N;;;;; +07DA;NKO LETTER RRA;Lo;0;R;;;;;N;;;;; +07DB;NKO LETTER SA;Lo;0;R;;;;;N;;;;; +07DC;NKO LETTER GBA;Lo;0;R;;;;;N;;;;; +07DD;NKO LETTER FA;Lo;0;R;;;;;N;;;;; +07DE;NKO LETTER KA;Lo;0;R;;;;;N;;;;; +07DF;NKO LETTER LA;Lo;0;R;;;;;N;;;;; +07E0;NKO LETTER NA WOLOSO;Lo;0;R;;;;;N;;;;; +07E1;NKO LETTER MA;Lo;0;R;;;;;N;;;;; +07E2;NKO LETTER NYA;Lo;0;R;;;;;N;;;;; +07E3;NKO LETTER NA;Lo;0;R;;;;;N;;;;; +07E4;NKO LETTER HA;Lo;0;R;;;;;N;;;;; +07E5;NKO LETTER WA;Lo;0;R;;;;;N;;;;; +07E6;NKO LETTER YA;Lo;0;R;;;;;N;;;;; +07E7;NKO LETTER NYA WOLOSO;Lo;0;R;;;;;N;;;;; +07E8;NKO LETTER JONA JA;Lo;0;R;;;;;N;;;;; +07E9;NKO LETTER JONA CHA;Lo;0;R;;;;;N;;;;; +07EA;NKO LETTER JONA RA;Lo;0;R;;;;;N;;;;; +07EB;NKO COMBINING SHORT HIGH TONE;Mn;230;NSM;;;;;N;;;;; +07EC;NKO COMBINING SHORT LOW TONE;Mn;230;NSM;;;;;N;;;;; +07ED;NKO COMBINING SHORT RISING TONE;Mn;230;NSM;;;;;N;;;;; +07EE;NKO COMBINING LONG DESCENDING TONE;Mn;230;NSM;;;;;N;;;;; +07EF;NKO COMBINING LONG HIGH TONE;Mn;230;NSM;;;;;N;;;;; +07F0;NKO COMBINING LONG LOW TONE;Mn;230;NSM;;;;;N;;;;; +07F1;NKO COMBINING LONG RISING TONE;Mn;230;NSM;;;;;N;;;;; +07F2;NKO COMBINING NASALIZATION MARK;Mn;220;NSM;;;;;N;;;;; +07F3;NKO COMBINING DOUBLE DOT ABOVE;Mn;230;NSM;;;;;N;;;;; +07F4;NKO HIGH TONE APOSTROPHE;Lm;0;R;;;;;N;;;;; +07F5;NKO LOW TONE APOSTROPHE;Lm;0;R;;;;;N;;;;; +07F6;NKO SYMBOL OO DENNEN;So;0;ON;;;;;N;;;;; +07F7;NKO SYMBOL GBAKURUNEN;Po;0;ON;;;;;N;;;;; +07F8;NKO COMMA;Po;0;ON;;;;;N;;;;; +07F9;NKO EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +07FA;NKO LAJANYALAN;Lm;0;R;;;;;N;;;;; +0800;SAMARITAN LETTER ALAF;Lo;0;R;;;;;N;;;;; +0801;SAMARITAN LETTER BIT;Lo;0;R;;;;;N;;;;; +0802;SAMARITAN LETTER GAMAN;Lo;0;R;;;;;N;;;;; +0803;SAMARITAN LETTER DALAT;Lo;0;R;;;;;N;;;;; +0804;SAMARITAN LETTER IY;Lo;0;R;;;;;N;;;;; +0805;SAMARITAN LETTER BAA;Lo;0;R;;;;;N;;;;; +0806;SAMARITAN LETTER ZEN;Lo;0;R;;;;;N;;;;; +0807;SAMARITAN LETTER IT;Lo;0;R;;;;;N;;;;; +0808;SAMARITAN LETTER TIT;Lo;0;R;;;;;N;;;;; +0809;SAMARITAN LETTER YUT;Lo;0;R;;;;;N;;;;; +080A;SAMARITAN LETTER KAAF;Lo;0;R;;;;;N;;;;; +080B;SAMARITAN LETTER LABAT;Lo;0;R;;;;;N;;;;; +080C;SAMARITAN LETTER MIM;Lo;0;R;;;;;N;;;;; +080D;SAMARITAN LETTER NUN;Lo;0;R;;;;;N;;;;; +080E;SAMARITAN LETTER SINGAAT;Lo;0;R;;;;;N;;;;; +080F;SAMARITAN LETTER IN;Lo;0;R;;;;;N;;;;; +0810;SAMARITAN LETTER FI;Lo;0;R;;;;;N;;;;; +0811;SAMARITAN LETTER TSAADIY;Lo;0;R;;;;;N;;;;; +0812;SAMARITAN LETTER QUF;Lo;0;R;;;;;N;;;;; +0813;SAMARITAN LETTER RISH;Lo;0;R;;;;;N;;;;; +0814;SAMARITAN LETTER SHAN;Lo;0;R;;;;;N;;;;; +0815;SAMARITAN LETTER TAAF;Lo;0;R;;;;;N;;;;; +0816;SAMARITAN MARK IN;Mn;230;NSM;;;;;N;;;;; +0817;SAMARITAN MARK IN-ALAF;Mn;230;NSM;;;;;N;;;;; +0818;SAMARITAN MARK OCCLUSION;Mn;230;NSM;;;;;N;;;;; +0819;SAMARITAN MARK DAGESH;Mn;230;NSM;;;;;N;;;;; +081A;SAMARITAN MODIFIER LETTER EPENTHETIC YUT;Lm;0;R;;;;;N;;;;; +081B;SAMARITAN MARK EPENTHETIC YUT;Mn;230;NSM;;;;;N;;;;; +081C;SAMARITAN VOWEL SIGN LONG E;Mn;230;NSM;;;;;N;;;;; +081D;SAMARITAN VOWEL SIGN E;Mn;230;NSM;;;;;N;;;;; +081E;SAMARITAN VOWEL SIGN OVERLONG AA;Mn;230;NSM;;;;;N;;;;; +081F;SAMARITAN VOWEL SIGN LONG AA;Mn;230;NSM;;;;;N;;;;; +0820;SAMARITAN VOWEL SIGN AA;Mn;230;NSM;;;;;N;;;;; +0821;SAMARITAN VOWEL SIGN OVERLONG A;Mn;230;NSM;;;;;N;;;;; +0822;SAMARITAN VOWEL SIGN LONG A;Mn;230;NSM;;;;;N;;;;; +0823;SAMARITAN VOWEL SIGN A;Mn;230;NSM;;;;;N;;;;; +0824;SAMARITAN MODIFIER LETTER SHORT A;Lm;0;R;;;;;N;;;;; +0825;SAMARITAN VOWEL SIGN SHORT A;Mn;230;NSM;;;;;N;;;;; +0826;SAMARITAN VOWEL SIGN LONG U;Mn;230;NSM;;;;;N;;;;; +0827;SAMARITAN VOWEL SIGN U;Mn;230;NSM;;;;;N;;;;; +0828;SAMARITAN MODIFIER LETTER I;Lm;0;R;;;;;N;;;;; +0829;SAMARITAN VOWEL SIGN LONG I;Mn;230;NSM;;;;;N;;;;; +082A;SAMARITAN VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;; +082B;SAMARITAN VOWEL SIGN O;Mn;230;NSM;;;;;N;;;;; +082C;SAMARITAN VOWEL SIGN SUKUN;Mn;230;NSM;;;;;N;;;;; +082D;SAMARITAN MARK NEQUDAA;Mn;230;NSM;;;;;N;;;;; +0830;SAMARITAN PUNCTUATION NEQUDAA;Po;0;R;;;;;N;;;;; +0831;SAMARITAN PUNCTUATION AFSAAQ;Po;0;R;;;;;N;;;;; +0832;SAMARITAN PUNCTUATION ANGED;Po;0;R;;;;;N;;;;; +0833;SAMARITAN PUNCTUATION BAU;Po;0;R;;;;;N;;;;; +0834;SAMARITAN PUNCTUATION ATMAAU;Po;0;R;;;;;N;;;;; +0835;SAMARITAN PUNCTUATION SHIYYAALAA;Po;0;R;;;;;N;;;;; +0836;SAMARITAN ABBREVIATION MARK;Po;0;R;;;;;N;;;;; +0837;SAMARITAN PUNCTUATION MELODIC QITSA;Po;0;R;;;;;N;;;;; +0838;SAMARITAN PUNCTUATION ZIQAA;Po;0;R;;;;;N;;;;; +0839;SAMARITAN PUNCTUATION QITSA;Po;0;R;;;;;N;;;;; +083A;SAMARITAN PUNCTUATION ZAEF;Po;0;R;;;;;N;;;;; +083B;SAMARITAN PUNCTUATION TURU;Po;0;R;;;;;N;;;;; +083C;SAMARITAN PUNCTUATION ARKAANU;Po;0;R;;;;;N;;;;; +083D;SAMARITAN PUNCTUATION SOF MASHFAAT;Po;0;R;;;;;N;;;;; +083E;SAMARITAN PUNCTUATION ANNAAU;Po;0;R;;;;;N;;;;; +0900;DEVANAGARI SIGN INVERTED CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0901;DEVANAGARI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0902;DEVANAGARI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +0903;DEVANAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0904;DEVANAGARI LETTER SHORT A;Lo;0;L;;;;;N;;;;; +0905;DEVANAGARI LETTER A;Lo;0;L;;;;;N;;;;; +0906;DEVANAGARI LETTER AA;Lo;0;L;;;;;N;;;;; +0907;DEVANAGARI LETTER I;Lo;0;L;;;;;N;;;;; +0908;DEVANAGARI LETTER II;Lo;0;L;;;;;N;;;;; +0909;DEVANAGARI LETTER U;Lo;0;L;;;;;N;;;;; +090A;DEVANAGARI LETTER UU;Lo;0;L;;;;;N;;;;; +090B;DEVANAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +090C;DEVANAGARI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +090D;DEVANAGARI LETTER CANDRA E;Lo;0;L;;;;;N;;;;; +090E;DEVANAGARI LETTER SHORT E;Lo;0;L;;;;;N;;;;; +090F;DEVANAGARI LETTER E;Lo;0;L;;;;;N;;;;; +0910;DEVANAGARI LETTER AI;Lo;0;L;;;;;N;;;;; +0911;DEVANAGARI LETTER CANDRA O;Lo;0;L;;;;;N;;;;; +0912;DEVANAGARI LETTER SHORT O;Lo;0;L;;;;;N;;;;; +0913;DEVANAGARI LETTER O;Lo;0;L;;;;;N;;;;; +0914;DEVANAGARI LETTER AU;Lo;0;L;;;;;N;;;;; +0915;DEVANAGARI LETTER KA;Lo;0;L;;;;;N;;;;; +0916;DEVANAGARI LETTER KHA;Lo;0;L;;;;;N;;;;; +0917;DEVANAGARI LETTER GA;Lo;0;L;;;;;N;;;;; +0918;DEVANAGARI LETTER GHA;Lo;0;L;;;;;N;;;;; +0919;DEVANAGARI LETTER NGA;Lo;0;L;;;;;N;;;;; +091A;DEVANAGARI LETTER CA;Lo;0;L;;;;;N;;;;; +091B;DEVANAGARI LETTER CHA;Lo;0;L;;;;;N;;;;; +091C;DEVANAGARI LETTER JA;Lo;0;L;;;;;N;;;;; +091D;DEVANAGARI LETTER JHA;Lo;0;L;;;;;N;;;;; +091E;DEVANAGARI LETTER NYA;Lo;0;L;;;;;N;;;;; +091F;DEVANAGARI LETTER TTA;Lo;0;L;;;;;N;;;;; +0920;DEVANAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;; +0921;DEVANAGARI LETTER DDA;Lo;0;L;;;;;N;;;;; +0922;DEVANAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;; +0923;DEVANAGARI LETTER NNA;Lo;0;L;;;;;N;;;;; +0924;DEVANAGARI LETTER TA;Lo;0;L;;;;;N;;;;; +0925;DEVANAGARI LETTER THA;Lo;0;L;;;;;N;;;;; +0926;DEVANAGARI LETTER DA;Lo;0;L;;;;;N;;;;; +0927;DEVANAGARI LETTER DHA;Lo;0;L;;;;;N;;;;; +0928;DEVANAGARI LETTER NA;Lo;0;L;;;;;N;;;;; +0929;DEVANAGARI LETTER NNNA;Lo;0;L;0928 093C;;;;N;;;;; +092A;DEVANAGARI LETTER PA;Lo;0;L;;;;;N;;;;; +092B;DEVANAGARI LETTER PHA;Lo;0;L;;;;;N;;;;; +092C;DEVANAGARI LETTER BA;Lo;0;L;;;;;N;;;;; +092D;DEVANAGARI LETTER BHA;Lo;0;L;;;;;N;;;;; +092E;DEVANAGARI LETTER MA;Lo;0;L;;;;;N;;;;; +092F;DEVANAGARI LETTER YA;Lo;0;L;;;;;N;;;;; +0930;DEVANAGARI LETTER RA;Lo;0;L;;;;;N;;;;; +0931;DEVANAGARI LETTER RRA;Lo;0;L;0930 093C;;;;N;;;;; +0932;DEVANAGARI LETTER LA;Lo;0;L;;;;;N;;;;; +0933;DEVANAGARI LETTER LLA;Lo;0;L;;;;;N;;;;; +0934;DEVANAGARI LETTER LLLA;Lo;0;L;0933 093C;;;;N;;;;; +0935;DEVANAGARI LETTER VA;Lo;0;L;;;;;N;;;;; +0936;DEVANAGARI LETTER SHA;Lo;0;L;;;;;N;;;;; +0937;DEVANAGARI LETTER SSA;Lo;0;L;;;;;N;;;;; +0938;DEVANAGARI LETTER SA;Lo;0;L;;;;;N;;;;; +0939;DEVANAGARI LETTER HA;Lo;0;L;;;;;N;;;;; +093C;DEVANAGARI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +093D;DEVANAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +093E;DEVANAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +093F;DEVANAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0940;DEVANAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0941;DEVANAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0942;DEVANAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0943;DEVANAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0944;DEVANAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0945;DEVANAGARI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;; +0946;DEVANAGARI VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;; +0947;DEVANAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0948;DEVANAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +0949;DEVANAGARI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;; +094A;DEVANAGARI VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;; +094B;DEVANAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +094C;DEVANAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +094D;DEVANAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +094E;DEVANAGARI VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;; +0950;DEVANAGARI OM;Lo;0;L;;;;;N;;;;; +0951;DEVANAGARI STRESS SIGN UDATTA;Mn;230;NSM;;;;;N;;;;; +0952;DEVANAGARI STRESS SIGN ANUDATTA;Mn;220;NSM;;;;;N;;;;; +0953;DEVANAGARI GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;; +0954;DEVANAGARI ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;; +0955;DEVANAGARI VOWEL SIGN CANDRA LONG E;Mn;0;NSM;;;;;N;;;;; +0958;DEVANAGARI LETTER QA;Lo;0;L;0915 093C;;;;N;;;;; +0959;DEVANAGARI LETTER KHHA;Lo;0;L;0916 093C;;;;N;;;;; +095A;DEVANAGARI LETTER GHHA;Lo;0;L;0917 093C;;;;N;;;;; +095B;DEVANAGARI LETTER ZA;Lo;0;L;091C 093C;;;;N;;;;; +095C;DEVANAGARI LETTER DDDHA;Lo;0;L;0921 093C;;;;N;;;;; +095D;DEVANAGARI LETTER RHA;Lo;0;L;0922 093C;;;;N;;;;; +095E;DEVANAGARI LETTER FA;Lo;0;L;092B 093C;;;;N;;;;; +095F;DEVANAGARI LETTER YYA;Lo;0;L;092F 093C;;;;N;;;;; +0960;DEVANAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0961;DEVANAGARI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0962;DEVANAGARI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0963;DEVANAGARI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0964;DEVANAGARI DANDA;Po;0;L;;;;;N;;;;; +0965;DEVANAGARI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +0966;DEVANAGARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0967;DEVANAGARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0968;DEVANAGARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0969;DEVANAGARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +096A;DEVANAGARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +096B;DEVANAGARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +096C;DEVANAGARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +096D;DEVANAGARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +096E;DEVANAGARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +096F;DEVANAGARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0970;DEVANAGARI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +0971;DEVANAGARI SIGN HIGH SPACING DOT;Lm;0;L;;;;;N;;;;; +0972;DEVANAGARI LETTER CANDRA A;Lo;0;L;;;;;N;;;;; +0979;DEVANAGARI LETTER ZHA;Lo;0;L;;;;;N;;;;; +097A;DEVANAGARI LETTER HEAVY YA;Lo;0;L;;;;;N;;;;; +097B;DEVANAGARI LETTER GGA;Lo;0;L;;;;;N;;;;; +097C;DEVANAGARI LETTER JJA;Lo;0;L;;;;;N;;;;; +097D;DEVANAGARI LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;; +097E;DEVANAGARI LETTER DDDA;Lo;0;L;;;;;N;;;;; +097F;DEVANAGARI LETTER BBA;Lo;0;L;;;;;N;;;;; +0981;BENGALI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0982;BENGALI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0983;BENGALI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0985;BENGALI LETTER A;Lo;0;L;;;;;N;;;;; +0986;BENGALI LETTER AA;Lo;0;L;;;;;N;;;;; +0987;BENGALI LETTER I;Lo;0;L;;;;;N;;;;; +0988;BENGALI LETTER II;Lo;0;L;;;;;N;;;;; +0989;BENGALI LETTER U;Lo;0;L;;;;;N;;;;; +098A;BENGALI LETTER UU;Lo;0;L;;;;;N;;;;; +098B;BENGALI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +098C;BENGALI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +098F;BENGALI LETTER E;Lo;0;L;;;;;N;;;;; +0990;BENGALI LETTER AI;Lo;0;L;;;;;N;;;;; +0993;BENGALI LETTER O;Lo;0;L;;;;;N;;;;; +0994;BENGALI LETTER AU;Lo;0;L;;;;;N;;;;; +0995;BENGALI LETTER KA;Lo;0;L;;;;;N;;;;; +0996;BENGALI LETTER KHA;Lo;0;L;;;;;N;;;;; +0997;BENGALI LETTER GA;Lo;0;L;;;;;N;;;;; +0998;BENGALI LETTER GHA;Lo;0;L;;;;;N;;;;; +0999;BENGALI LETTER NGA;Lo;0;L;;;;;N;;;;; +099A;BENGALI LETTER CA;Lo;0;L;;;;;N;;;;; +099B;BENGALI LETTER CHA;Lo;0;L;;;;;N;;;;; +099C;BENGALI LETTER JA;Lo;0;L;;;;;N;;;;; +099D;BENGALI LETTER JHA;Lo;0;L;;;;;N;;;;; +099E;BENGALI LETTER NYA;Lo;0;L;;;;;N;;;;; +099F;BENGALI LETTER TTA;Lo;0;L;;;;;N;;;;; +09A0;BENGALI LETTER TTHA;Lo;0;L;;;;;N;;;;; +09A1;BENGALI LETTER DDA;Lo;0;L;;;;;N;;;;; +09A2;BENGALI LETTER DDHA;Lo;0;L;;;;;N;;;;; +09A3;BENGALI LETTER NNA;Lo;0;L;;;;;N;;;;; +09A4;BENGALI LETTER TA;Lo;0;L;;;;;N;;;;; +09A5;BENGALI LETTER THA;Lo;0;L;;;;;N;;;;; +09A6;BENGALI LETTER DA;Lo;0;L;;;;;N;;;;; +09A7;BENGALI LETTER DHA;Lo;0;L;;;;;N;;;;; +09A8;BENGALI LETTER NA;Lo;0;L;;;;;N;;;;; +09AA;BENGALI LETTER PA;Lo;0;L;;;;;N;;;;; +09AB;BENGALI LETTER PHA;Lo;0;L;;;;;N;;;;; +09AC;BENGALI LETTER BA;Lo;0;L;;;;;N;;;;; +09AD;BENGALI LETTER BHA;Lo;0;L;;;;;N;;;;; +09AE;BENGALI LETTER MA;Lo;0;L;;;;;N;;;;; +09AF;BENGALI LETTER YA;Lo;0;L;;;;;N;;;;; +09B0;BENGALI LETTER RA;Lo;0;L;;;;;N;;;;; +09B2;BENGALI LETTER LA;Lo;0;L;;;;;N;;;;; +09B6;BENGALI LETTER SHA;Lo;0;L;;;;;N;;;;; +09B7;BENGALI LETTER SSA;Lo;0;L;;;;;N;;;;; +09B8;BENGALI LETTER SA;Lo;0;L;;;;;N;;;;; +09B9;BENGALI LETTER HA;Lo;0;L;;;;;N;;;;; +09BC;BENGALI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +09BD;BENGALI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +09BE;BENGALI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +09BF;BENGALI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +09C0;BENGALI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +09C1;BENGALI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +09C2;BENGALI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +09C3;BENGALI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +09C4;BENGALI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +09C7;BENGALI VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +09C8;BENGALI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +09CB;BENGALI VOWEL SIGN O;Mc;0;L;09C7 09BE;;;;N;;;;; +09CC;BENGALI VOWEL SIGN AU;Mc;0;L;09C7 09D7;;;;N;;;;; +09CD;BENGALI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +09CE;BENGALI LETTER KHANDA TA;Lo;0;L;;;;;N;;;;; +09D7;BENGALI AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +09DC;BENGALI LETTER RRA;Lo;0;L;09A1 09BC;;;;N;;;;; +09DD;BENGALI LETTER RHA;Lo;0;L;09A2 09BC;;;;N;;;;; +09DF;BENGALI LETTER YYA;Lo;0;L;09AF 09BC;;;;N;;;;; +09E0;BENGALI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +09E1;BENGALI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +09E2;BENGALI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +09E3;BENGALI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +09E6;BENGALI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +09E7;BENGALI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +09E8;BENGALI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +09E9;BENGALI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +09EA;BENGALI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +09EB;BENGALI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +09EC;BENGALI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +09ED;BENGALI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +09EE;BENGALI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +09EF;BENGALI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +09F0;BENGALI LETTER RA WITH MIDDLE DIAGONAL;Lo;0;L;;;;;N;;;;; +09F1;BENGALI LETTER RA WITH LOWER DIAGONAL;Lo;0;L;;;;;N;BENGALI LETTER VA WITH LOWER DIAGONAL;;;; +09F2;BENGALI RUPEE MARK;Sc;0;ET;;;;;N;;;;; +09F3;BENGALI RUPEE SIGN;Sc;0;ET;;;;;N;;;;; +09F4;BENGALI CURRENCY NUMERATOR ONE;No;0;L;;;;1/16;N;;;;; +09F5;BENGALI CURRENCY NUMERATOR TWO;No;0;L;;;;1/8;N;;;;; +09F6;BENGALI CURRENCY NUMERATOR THREE;No;0;L;;;;3/16;N;;;;; +09F7;BENGALI CURRENCY NUMERATOR FOUR;No;0;L;;;;1/4;N;;;;; +09F8;BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR;No;0;L;;;;3/4;N;;;;; +09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;; +09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;; +09FB;BENGALI GANDA MARK;Sc;0;ET;;;;;N;;;;; +0A01;GURMUKHI SIGN ADAK BINDI;Mn;0;NSM;;;;;N;;;;; +0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;; +0A03;GURMUKHI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0A05;GURMUKHI LETTER A;Lo;0;L;;;;;N;;;;; +0A06;GURMUKHI LETTER AA;Lo;0;L;;;;;N;;;;; +0A07;GURMUKHI LETTER I;Lo;0;L;;;;;N;;;;; +0A08;GURMUKHI LETTER II;Lo;0;L;;;;;N;;;;; +0A09;GURMUKHI LETTER U;Lo;0;L;;;;;N;;;;; +0A0A;GURMUKHI LETTER UU;Lo;0;L;;;;;N;;;;; +0A0F;GURMUKHI LETTER EE;Lo;0;L;;;;;N;;;;; +0A10;GURMUKHI LETTER AI;Lo;0;L;;;;;N;;;;; +0A13;GURMUKHI LETTER OO;Lo;0;L;;;;;N;;;;; +0A14;GURMUKHI LETTER AU;Lo;0;L;;;;;N;;;;; +0A15;GURMUKHI LETTER KA;Lo;0;L;;;;;N;;;;; +0A16;GURMUKHI LETTER KHA;Lo;0;L;;;;;N;;;;; +0A17;GURMUKHI LETTER GA;Lo;0;L;;;;;N;;;;; +0A18;GURMUKHI LETTER GHA;Lo;0;L;;;;;N;;;;; +0A19;GURMUKHI LETTER NGA;Lo;0;L;;;;;N;;;;; +0A1A;GURMUKHI LETTER CA;Lo;0;L;;;;;N;;;;; +0A1B;GURMUKHI LETTER CHA;Lo;0;L;;;;;N;;;;; +0A1C;GURMUKHI LETTER JA;Lo;0;L;;;;;N;;;;; +0A1D;GURMUKHI LETTER JHA;Lo;0;L;;;;;N;;;;; +0A1E;GURMUKHI LETTER NYA;Lo;0;L;;;;;N;;;;; +0A1F;GURMUKHI LETTER TTA;Lo;0;L;;;;;N;;;;; +0A20;GURMUKHI LETTER TTHA;Lo;0;L;;;;;N;;;;; +0A21;GURMUKHI LETTER DDA;Lo;0;L;;;;;N;;;;; +0A22;GURMUKHI LETTER DDHA;Lo;0;L;;;;;N;;;;; +0A23;GURMUKHI LETTER NNA;Lo;0;L;;;;;N;;;;; +0A24;GURMUKHI LETTER TA;Lo;0;L;;;;;N;;;;; +0A25;GURMUKHI LETTER THA;Lo;0;L;;;;;N;;;;; +0A26;GURMUKHI LETTER DA;Lo;0;L;;;;;N;;;;; +0A27;GURMUKHI LETTER DHA;Lo;0;L;;;;;N;;;;; +0A28;GURMUKHI LETTER NA;Lo;0;L;;;;;N;;;;; +0A2A;GURMUKHI LETTER PA;Lo;0;L;;;;;N;;;;; +0A2B;GURMUKHI LETTER PHA;Lo;0;L;;;;;N;;;;; +0A2C;GURMUKHI LETTER BA;Lo;0;L;;;;;N;;;;; +0A2D;GURMUKHI LETTER BHA;Lo;0;L;;;;;N;;;;; +0A2E;GURMUKHI LETTER MA;Lo;0;L;;;;;N;;;;; +0A2F;GURMUKHI LETTER YA;Lo;0;L;;;;;N;;;;; +0A30;GURMUKHI LETTER RA;Lo;0;L;;;;;N;;;;; +0A32;GURMUKHI LETTER LA;Lo;0;L;;;;;N;;;;; +0A33;GURMUKHI LETTER LLA;Lo;0;L;0A32 0A3C;;;;N;;;;; +0A35;GURMUKHI LETTER VA;Lo;0;L;;;;;N;;;;; +0A36;GURMUKHI LETTER SHA;Lo;0;L;0A38 0A3C;;;;N;;;;; +0A38;GURMUKHI LETTER SA;Lo;0;L;;;;;N;;;;; +0A39;GURMUKHI LETTER HA;Lo;0;L;;;;;N;;;;; +0A3C;GURMUKHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0A3E;GURMUKHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0A3F;GURMUKHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0A40;GURMUKHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0A41;GURMUKHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0A42;GURMUKHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0A47;GURMUKHI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; +0A48;GURMUKHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +0A4B;GURMUKHI VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;; +0A4C;GURMUKHI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +0A4D;GURMUKHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0A51;GURMUKHI SIGN UDAAT;Mn;0;NSM;;;;;N;;;;; +0A59;GURMUKHI LETTER KHHA;Lo;0;L;0A16 0A3C;;;;N;;;;; +0A5A;GURMUKHI LETTER GHHA;Lo;0;L;0A17 0A3C;;;;N;;;;; +0A5B;GURMUKHI LETTER ZA;Lo;0;L;0A1C 0A3C;;;;N;;;;; +0A5C;GURMUKHI LETTER RRA;Lo;0;L;;;;;N;;;;; +0A5E;GURMUKHI LETTER FA;Lo;0;L;0A2B 0A3C;;;;N;;;;; +0A66;GURMUKHI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0A67;GURMUKHI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0A68;GURMUKHI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0A69;GURMUKHI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0A6A;GURMUKHI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0A6B;GURMUKHI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0A6C;GURMUKHI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0A6D;GURMUKHI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0A6E;GURMUKHI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0A6F;GURMUKHI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0A70;GURMUKHI TIPPI;Mn;0;NSM;;;;;N;;;;; +0A71;GURMUKHI ADDAK;Mn;0;NSM;;;;;N;;;;; +0A72;GURMUKHI IRI;Lo;0;L;;;;;N;;;;; +0A73;GURMUKHI URA;Lo;0;L;;;;;N;;;;; +0A74;GURMUKHI EK ONKAR;Lo;0;L;;;;;N;;;;; +0A75;GURMUKHI SIGN YAKASH;Mn;0;NSM;;;;;N;;;;; +0A81;GUJARATI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0A82;GUJARATI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +0A83;GUJARATI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0A85;GUJARATI LETTER A;Lo;0;L;;;;;N;;;;; +0A86;GUJARATI LETTER AA;Lo;0;L;;;;;N;;;;; +0A87;GUJARATI LETTER I;Lo;0;L;;;;;N;;;;; +0A88;GUJARATI LETTER II;Lo;0;L;;;;;N;;;;; +0A89;GUJARATI LETTER U;Lo;0;L;;;;;N;;;;; +0A8A;GUJARATI LETTER UU;Lo;0;L;;;;;N;;;;; +0A8B;GUJARATI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0A8C;GUJARATI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0A8D;GUJARATI VOWEL CANDRA E;Lo;0;L;;;;;N;;;;; +0A8F;GUJARATI LETTER E;Lo;0;L;;;;;N;;;;; +0A90;GUJARATI LETTER AI;Lo;0;L;;;;;N;;;;; +0A91;GUJARATI VOWEL CANDRA O;Lo;0;L;;;;;N;;;;; +0A93;GUJARATI LETTER O;Lo;0;L;;;;;N;;;;; +0A94;GUJARATI LETTER AU;Lo;0;L;;;;;N;;;;; +0A95;GUJARATI LETTER KA;Lo;0;L;;;;;N;;;;; +0A96;GUJARATI LETTER KHA;Lo;0;L;;;;;N;;;;; +0A97;GUJARATI LETTER GA;Lo;0;L;;;;;N;;;;; +0A98;GUJARATI LETTER GHA;Lo;0;L;;;;;N;;;;; +0A99;GUJARATI LETTER NGA;Lo;0;L;;;;;N;;;;; +0A9A;GUJARATI LETTER CA;Lo;0;L;;;;;N;;;;; +0A9B;GUJARATI LETTER CHA;Lo;0;L;;;;;N;;;;; +0A9C;GUJARATI LETTER JA;Lo;0;L;;;;;N;;;;; +0A9D;GUJARATI LETTER JHA;Lo;0;L;;;;;N;;;;; +0A9E;GUJARATI LETTER NYA;Lo;0;L;;;;;N;;;;; +0A9F;GUJARATI LETTER TTA;Lo;0;L;;;;;N;;;;; +0AA0;GUJARATI LETTER TTHA;Lo;0;L;;;;;N;;;;; +0AA1;GUJARATI LETTER DDA;Lo;0;L;;;;;N;;;;; +0AA2;GUJARATI LETTER DDHA;Lo;0;L;;;;;N;;;;; +0AA3;GUJARATI LETTER NNA;Lo;0;L;;;;;N;;;;; +0AA4;GUJARATI LETTER TA;Lo;0;L;;;;;N;;;;; +0AA5;GUJARATI LETTER THA;Lo;0;L;;;;;N;;;;; +0AA6;GUJARATI LETTER DA;Lo;0;L;;;;;N;;;;; +0AA7;GUJARATI LETTER DHA;Lo;0;L;;;;;N;;;;; +0AA8;GUJARATI LETTER NA;Lo;0;L;;;;;N;;;;; +0AAA;GUJARATI LETTER PA;Lo;0;L;;;;;N;;;;; +0AAB;GUJARATI LETTER PHA;Lo;0;L;;;;;N;;;;; +0AAC;GUJARATI LETTER BA;Lo;0;L;;;;;N;;;;; +0AAD;GUJARATI LETTER BHA;Lo;0;L;;;;;N;;;;; +0AAE;GUJARATI LETTER MA;Lo;0;L;;;;;N;;;;; +0AAF;GUJARATI LETTER YA;Lo;0;L;;;;;N;;;;; +0AB0;GUJARATI LETTER RA;Lo;0;L;;;;;N;;;;; +0AB2;GUJARATI LETTER LA;Lo;0;L;;;;;N;;;;; +0AB3;GUJARATI LETTER LLA;Lo;0;L;;;;;N;;;;; +0AB5;GUJARATI LETTER VA;Lo;0;L;;;;;N;;;;; +0AB6;GUJARATI LETTER SHA;Lo;0;L;;;;;N;;;;; +0AB7;GUJARATI LETTER SSA;Lo;0;L;;;;;N;;;;; +0AB8;GUJARATI LETTER SA;Lo;0;L;;;;;N;;;;; +0AB9;GUJARATI LETTER HA;Lo;0;L;;;;;N;;;;; +0ABC;GUJARATI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0ABD;GUJARATI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0ABE;GUJARATI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0ABF;GUJARATI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0AC0;GUJARATI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0AC1;GUJARATI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0AC2;GUJARATI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0AC3;GUJARATI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0AC4;GUJARATI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0AC5;GUJARATI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;; +0AC7;GUJARATI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0AC8;GUJARATI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +0AC9;GUJARATI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;; +0ACB;GUJARATI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +0ACC;GUJARATI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +0ACD;GUJARATI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0AD0;GUJARATI OM;Lo;0;L;;;;;N;;;;; +0AE0;GUJARATI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0AE1;GUJARATI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0AE2;GUJARATI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0AE3;GUJARATI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0AE6;GUJARATI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0AE7;GUJARATI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0AE8;GUJARATI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0AE9;GUJARATI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0AEA;GUJARATI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0AEB;GUJARATI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0AEC;GUJARATI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0AED;GUJARATI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0AEE;GUJARATI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0AEF;GUJARATI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0AF1;GUJARATI RUPEE SIGN;Sc;0;ET;;;;;N;;;;; +0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0B05;ORIYA LETTER A;Lo;0;L;;;;;N;;;;; +0B06;ORIYA LETTER AA;Lo;0;L;;;;;N;;;;; +0B07;ORIYA LETTER I;Lo;0;L;;;;;N;;;;; +0B08;ORIYA LETTER II;Lo;0;L;;;;;N;;;;; +0B09;ORIYA LETTER U;Lo;0;L;;;;;N;;;;; +0B0A;ORIYA LETTER UU;Lo;0;L;;;;;N;;;;; +0B0B;ORIYA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0B0C;ORIYA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0B0F;ORIYA LETTER E;Lo;0;L;;;;;N;;;;; +0B10;ORIYA LETTER AI;Lo;0;L;;;;;N;;;;; +0B13;ORIYA LETTER O;Lo;0;L;;;;;N;;;;; +0B14;ORIYA LETTER AU;Lo;0;L;;;;;N;;;;; +0B15;ORIYA LETTER KA;Lo;0;L;;;;;N;;;;; +0B16;ORIYA LETTER KHA;Lo;0;L;;;;;N;;;;; +0B17;ORIYA LETTER GA;Lo;0;L;;;;;N;;;;; +0B18;ORIYA LETTER GHA;Lo;0;L;;;;;N;;;;; +0B19;ORIYA LETTER NGA;Lo;0;L;;;;;N;;;;; +0B1A;ORIYA LETTER CA;Lo;0;L;;;;;N;;;;; +0B1B;ORIYA LETTER CHA;Lo;0;L;;;;;N;;;;; +0B1C;ORIYA LETTER JA;Lo;0;L;;;;;N;;;;; +0B1D;ORIYA LETTER JHA;Lo;0;L;;;;;N;;;;; +0B1E;ORIYA LETTER NYA;Lo;0;L;;;;;N;;;;; +0B1F;ORIYA LETTER TTA;Lo;0;L;;;;;N;;;;; +0B20;ORIYA LETTER TTHA;Lo;0;L;;;;;N;;;;; +0B21;ORIYA LETTER DDA;Lo;0;L;;;;;N;;;;; +0B22;ORIYA LETTER DDHA;Lo;0;L;;;;;N;;;;; +0B23;ORIYA LETTER NNA;Lo;0;L;;;;;N;;;;; +0B24;ORIYA LETTER TA;Lo;0;L;;;;;N;;;;; +0B25;ORIYA LETTER THA;Lo;0;L;;;;;N;;;;; +0B26;ORIYA LETTER DA;Lo;0;L;;;;;N;;;;; +0B27;ORIYA LETTER DHA;Lo;0;L;;;;;N;;;;; +0B28;ORIYA LETTER NA;Lo;0;L;;;;;N;;;;; +0B2A;ORIYA LETTER PA;Lo;0;L;;;;;N;;;;; +0B2B;ORIYA LETTER PHA;Lo;0;L;;;;;N;;;;; +0B2C;ORIYA LETTER BA;Lo;0;L;;;;;N;;;;; +0B2D;ORIYA LETTER BHA;Lo;0;L;;;;;N;;;;; +0B2E;ORIYA LETTER MA;Lo;0;L;;;;;N;;;;; +0B2F;ORIYA LETTER YA;Lo;0;L;;;;;N;;;;; +0B30;ORIYA LETTER RA;Lo;0;L;;;;;N;;;;; +0B32;ORIYA LETTER LA;Lo;0;L;;;;;N;;;;; +0B33;ORIYA LETTER LLA;Lo;0;L;;;;;N;;;;; +0B35;ORIYA LETTER VA;Lo;0;L;;;;;N;;;;; +0B36;ORIYA LETTER SHA;Lo;0;L;;;;;N;;;;; +0B37;ORIYA LETTER SSA;Lo;0;L;;;;;N;;;;; +0B38;ORIYA LETTER SA;Lo;0;L;;;;;N;;;;; +0B39;ORIYA LETTER HA;Lo;0;L;;;;;N;;;;; +0B3C;ORIYA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0B3D;ORIYA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0B3E;ORIYA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0B3F;ORIYA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0B40;ORIYA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0B41;ORIYA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0B42;ORIYA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0B43;ORIYA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0B44;ORIYA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0B47;ORIYA VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +0B48;ORIYA VOWEL SIGN AI;Mc;0;L;0B47 0B56;;;;N;;;;; +0B4B;ORIYA VOWEL SIGN O;Mc;0;L;0B47 0B3E;;;;N;;;;; +0B4C;ORIYA VOWEL SIGN AU;Mc;0;L;0B47 0B57;;;;N;;;;; +0B4D;ORIYA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0B56;ORIYA AI LENGTH MARK;Mn;0;NSM;;;;;N;;;;; +0B57;ORIYA AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +0B5C;ORIYA LETTER RRA;Lo;0;L;0B21 0B3C;;;;N;;;;; +0B5D;ORIYA LETTER RHA;Lo;0;L;0B22 0B3C;;;;N;;;;; +0B5F;ORIYA LETTER YYA;Lo;0;L;;;;;N;;;;; +0B60;ORIYA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0B61;ORIYA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0B62;ORIYA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0B63;ORIYA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0B66;ORIYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0B67;ORIYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0B68;ORIYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0B69;ORIYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0B6A;ORIYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0B6B;ORIYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0B6C;ORIYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0B6D;ORIYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0B6E;ORIYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0B6F;ORIYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0B70;ORIYA ISSHAR;So;0;L;;;;;N;;;;; +0B71;ORIYA LETTER WA;Lo;0;L;;;;;N;;;;; +0B82;TAMIL SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +0B83;TAMIL SIGN VISARGA;Lo;0;L;;;;;N;;;;; +0B85;TAMIL LETTER A;Lo;0;L;;;;;N;;;;; +0B86;TAMIL LETTER AA;Lo;0;L;;;;;N;;;;; +0B87;TAMIL LETTER I;Lo;0;L;;;;;N;;;;; +0B88;TAMIL LETTER II;Lo;0;L;;;;;N;;;;; +0B89;TAMIL LETTER U;Lo;0;L;;;;;N;;;;; +0B8A;TAMIL LETTER UU;Lo;0;L;;;;;N;;;;; +0B8E;TAMIL LETTER E;Lo;0;L;;;;;N;;;;; +0B8F;TAMIL LETTER EE;Lo;0;L;;;;;N;;;;; +0B90;TAMIL LETTER AI;Lo;0;L;;;;;N;;;;; +0B92;TAMIL LETTER O;Lo;0;L;;;;;N;;;;; +0B93;TAMIL LETTER OO;Lo;0;L;;;;;N;;;;; +0B94;TAMIL LETTER AU;Lo;0;L;0B92 0BD7;;;;N;;;;; +0B95;TAMIL LETTER KA;Lo;0;L;;;;;N;;;;; +0B99;TAMIL LETTER NGA;Lo;0;L;;;;;N;;;;; +0B9A;TAMIL LETTER CA;Lo;0;L;;;;;N;;;;; +0B9C;TAMIL LETTER JA;Lo;0;L;;;;;N;;;;; +0B9E;TAMIL LETTER NYA;Lo;0;L;;;;;N;;;;; +0B9F;TAMIL LETTER TTA;Lo;0;L;;;;;N;;;;; +0BA3;TAMIL LETTER NNA;Lo;0;L;;;;;N;;;;; +0BA4;TAMIL LETTER TA;Lo;0;L;;;;;N;;;;; +0BA8;TAMIL LETTER NA;Lo;0;L;;;;;N;;;;; +0BA9;TAMIL LETTER NNNA;Lo;0;L;;;;;N;;;;; +0BAA;TAMIL LETTER PA;Lo;0;L;;;;;N;;;;; +0BAE;TAMIL LETTER MA;Lo;0;L;;;;;N;;;;; +0BAF;TAMIL LETTER YA;Lo;0;L;;;;;N;;;;; +0BB0;TAMIL LETTER RA;Lo;0;L;;;;;N;;;;; +0BB1;TAMIL LETTER RRA;Lo;0;L;;;;;N;;;;; +0BB2;TAMIL LETTER LA;Lo;0;L;;;;;N;;;;; +0BB3;TAMIL LETTER LLA;Lo;0;L;;;;;N;;;;; +0BB4;TAMIL LETTER LLLA;Lo;0;L;;;;;N;;;;; +0BB5;TAMIL LETTER VA;Lo;0;L;;;;;N;;;;; +0BB6;TAMIL LETTER SHA;Lo;0;L;;;;;N;;;;; +0BB7;TAMIL LETTER SSA;Lo;0;L;;;;;N;;;;; +0BB8;TAMIL LETTER SA;Lo;0;L;;;;;N;;;;; +0BB9;TAMIL LETTER HA;Lo;0;L;;;;;N;;;;; +0BBE;TAMIL VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0BBF;TAMIL VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0BC0;TAMIL VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +0BC1;TAMIL VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +0BC2;TAMIL VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +0BC6;TAMIL VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +0BC7;TAMIL VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +0BC8;TAMIL VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +0BCA;TAMIL VOWEL SIGN O;Mc;0;L;0BC6 0BBE;;;;N;;;;; +0BCB;TAMIL VOWEL SIGN OO;Mc;0;L;0BC7 0BBE;;;;N;;;;; +0BCC;TAMIL VOWEL SIGN AU;Mc;0;L;0BC6 0BD7;;;;N;;;;; +0BCD;TAMIL SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0BD0;TAMIL OM;Lo;0;L;;;;;N;;;;; +0BD7;TAMIL AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +0BE6;TAMIL DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0BE7;TAMIL DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0BE8;TAMIL DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0BE9;TAMIL DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0BEA;TAMIL DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0BEB;TAMIL DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0BEC;TAMIL DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0BED;TAMIL DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0BEE;TAMIL DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0BEF;TAMIL DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0BF0;TAMIL NUMBER TEN;No;0;L;;;;10;N;;;;; +0BF1;TAMIL NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; +0BF2;TAMIL NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; +0BF3;TAMIL DAY SIGN;So;0;ON;;;;;N;;;;; +0BF4;TAMIL MONTH SIGN;So;0;ON;;;;;N;;;;; +0BF5;TAMIL YEAR SIGN;So;0;ON;;;;;N;;;;; +0BF6;TAMIL DEBIT SIGN;So;0;ON;;;;;N;;;;; +0BF7;TAMIL CREDIT SIGN;So;0;ON;;;;;N;;;;; +0BF8;TAMIL AS ABOVE SIGN;So;0;ON;;;;;N;;;;; +0BF9;TAMIL RUPEE SIGN;Sc;0;ET;;;;;N;;;;; +0BFA;TAMIL NUMBER SIGN;So;0;ON;;;;;N;;;;; +0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;; +0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0C05;TELUGU LETTER A;Lo;0;L;;;;;N;;;;; +0C06;TELUGU LETTER AA;Lo;0;L;;;;;N;;;;; +0C07;TELUGU LETTER I;Lo;0;L;;;;;N;;;;; +0C08;TELUGU LETTER II;Lo;0;L;;;;;N;;;;; +0C09;TELUGU LETTER U;Lo;0;L;;;;;N;;;;; +0C0A;TELUGU LETTER UU;Lo;0;L;;;;;N;;;;; +0C0B;TELUGU LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0C0C;TELUGU LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0C0E;TELUGU LETTER E;Lo;0;L;;;;;N;;;;; +0C0F;TELUGU LETTER EE;Lo;0;L;;;;;N;;;;; +0C10;TELUGU LETTER AI;Lo;0;L;;;;;N;;;;; +0C12;TELUGU LETTER O;Lo;0;L;;;;;N;;;;; +0C13;TELUGU LETTER OO;Lo;0;L;;;;;N;;;;; +0C14;TELUGU LETTER AU;Lo;0;L;;;;;N;;;;; +0C15;TELUGU LETTER KA;Lo;0;L;;;;;N;;;;; +0C16;TELUGU LETTER KHA;Lo;0;L;;;;;N;;;;; +0C17;TELUGU LETTER GA;Lo;0;L;;;;;N;;;;; +0C18;TELUGU LETTER GHA;Lo;0;L;;;;;N;;;;; +0C19;TELUGU LETTER NGA;Lo;0;L;;;;;N;;;;; +0C1A;TELUGU LETTER CA;Lo;0;L;;;;;N;;;;; +0C1B;TELUGU LETTER CHA;Lo;0;L;;;;;N;;;;; +0C1C;TELUGU LETTER JA;Lo;0;L;;;;;N;;;;; +0C1D;TELUGU LETTER JHA;Lo;0;L;;;;;N;;;;; +0C1E;TELUGU LETTER NYA;Lo;0;L;;;;;N;;;;; +0C1F;TELUGU LETTER TTA;Lo;0;L;;;;;N;;;;; +0C20;TELUGU LETTER TTHA;Lo;0;L;;;;;N;;;;; +0C21;TELUGU LETTER DDA;Lo;0;L;;;;;N;;;;; +0C22;TELUGU LETTER DDHA;Lo;0;L;;;;;N;;;;; +0C23;TELUGU LETTER NNA;Lo;0;L;;;;;N;;;;; +0C24;TELUGU LETTER TA;Lo;0;L;;;;;N;;;;; +0C25;TELUGU LETTER THA;Lo;0;L;;;;;N;;;;; +0C26;TELUGU LETTER DA;Lo;0;L;;;;;N;;;;; +0C27;TELUGU LETTER DHA;Lo;0;L;;;;;N;;;;; +0C28;TELUGU LETTER NA;Lo;0;L;;;;;N;;;;; +0C2A;TELUGU LETTER PA;Lo;0;L;;;;;N;;;;; +0C2B;TELUGU LETTER PHA;Lo;0;L;;;;;N;;;;; +0C2C;TELUGU LETTER BA;Lo;0;L;;;;;N;;;;; +0C2D;TELUGU LETTER BHA;Lo;0;L;;;;;N;;;;; +0C2E;TELUGU LETTER MA;Lo;0;L;;;;;N;;;;; +0C2F;TELUGU LETTER YA;Lo;0;L;;;;;N;;;;; +0C30;TELUGU LETTER RA;Lo;0;L;;;;;N;;;;; +0C31;TELUGU LETTER RRA;Lo;0;L;;;;;N;;;;; +0C32;TELUGU LETTER LA;Lo;0;L;;;;;N;;;;; +0C33;TELUGU LETTER LLA;Lo;0;L;;;;;N;;;;; +0C35;TELUGU LETTER VA;Lo;0;L;;;;;N;;;;; +0C36;TELUGU LETTER SHA;Lo;0;L;;;;;N;;;;; +0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;; +0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;; +0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;; +0C3D;TELUGU SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0C40;TELUGU VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +0C41;TELUGU VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +0C42;TELUGU VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +0C43;TELUGU VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +0C44;TELUGU VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +0C46;TELUGU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0C47;TELUGU VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; +0C48;TELUGU VOWEL SIGN AI;Mn;0;NSM;0C46 0C56;;;;N;;;;; +0C4A;TELUGU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +0C4B;TELUGU VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;; +0C4C;TELUGU VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +0C4D;TELUGU SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0C55;TELUGU LENGTH MARK;Mn;84;NSM;;;;;N;;;;; +0C56;TELUGU AI LENGTH MARK;Mn;91;NSM;;;;;N;;;;; +0C58;TELUGU LETTER TSA;Lo;0;L;;;;;N;;;;; +0C59;TELUGU LETTER DZA;Lo;0;L;;;;;N;;;;; +0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0C62;TELUGU VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0C63;TELUGU VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0C66;TELUGU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0C67;TELUGU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0C68;TELUGU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0C69;TELUGU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0C6A;TELUGU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0C6B;TELUGU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0C6C;TELUGU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0C78;TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR;No;0;ON;;;;0;N;;;;; +0C79;TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR;No;0;ON;;;;1;N;;;;; +0C7A;TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR;No;0;ON;;;;2;N;;;;; +0C7B;TELUGU FRACTION DIGIT THREE FOR ODD POWERS OF FOUR;No;0;ON;;;;3;N;;;;; +0C7C;TELUGU FRACTION DIGIT ONE FOR EVEN POWERS OF FOUR;No;0;ON;;;;1;N;;;;; +0C7D;TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR;No;0;ON;;;;2;N;;;;; +0C7E;TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR;No;0;ON;;;;3;N;;;;; +0C7F;TELUGU SIGN TUUMU;So;0;L;;;;;N;;;;; +0C82;KANNADA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0C83;KANNADA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0C85;KANNADA LETTER A;Lo;0;L;;;;;N;;;;; +0C86;KANNADA LETTER AA;Lo;0;L;;;;;N;;;;; +0C87;KANNADA LETTER I;Lo;0;L;;;;;N;;;;; +0C88;KANNADA LETTER II;Lo;0;L;;;;;N;;;;; +0C89;KANNADA LETTER U;Lo;0;L;;;;;N;;;;; +0C8A;KANNADA LETTER UU;Lo;0;L;;;;;N;;;;; +0C8B;KANNADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0C8C;KANNADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0C8E;KANNADA LETTER E;Lo;0;L;;;;;N;;;;; +0C8F;KANNADA LETTER EE;Lo;0;L;;;;;N;;;;; +0C90;KANNADA LETTER AI;Lo;0;L;;;;;N;;;;; +0C92;KANNADA LETTER O;Lo;0;L;;;;;N;;;;; +0C93;KANNADA LETTER OO;Lo;0;L;;;;;N;;;;; +0C94;KANNADA LETTER AU;Lo;0;L;;;;;N;;;;; +0C95;KANNADA LETTER KA;Lo;0;L;;;;;N;;;;; +0C96;KANNADA LETTER KHA;Lo;0;L;;;;;N;;;;; +0C97;KANNADA LETTER GA;Lo;0;L;;;;;N;;;;; +0C98;KANNADA LETTER GHA;Lo;0;L;;;;;N;;;;; +0C99;KANNADA LETTER NGA;Lo;0;L;;;;;N;;;;; +0C9A;KANNADA LETTER CA;Lo;0;L;;;;;N;;;;; +0C9B;KANNADA LETTER CHA;Lo;0;L;;;;;N;;;;; +0C9C;KANNADA LETTER JA;Lo;0;L;;;;;N;;;;; +0C9D;KANNADA LETTER JHA;Lo;0;L;;;;;N;;;;; +0C9E;KANNADA LETTER NYA;Lo;0;L;;;;;N;;;;; +0C9F;KANNADA LETTER TTA;Lo;0;L;;;;;N;;;;; +0CA0;KANNADA LETTER TTHA;Lo;0;L;;;;;N;;;;; +0CA1;KANNADA LETTER DDA;Lo;0;L;;;;;N;;;;; +0CA2;KANNADA LETTER DDHA;Lo;0;L;;;;;N;;;;; +0CA3;KANNADA LETTER NNA;Lo;0;L;;;;;N;;;;; +0CA4;KANNADA LETTER TA;Lo;0;L;;;;;N;;;;; +0CA5;KANNADA LETTER THA;Lo;0;L;;;;;N;;;;; +0CA6;KANNADA LETTER DA;Lo;0;L;;;;;N;;;;; +0CA7;KANNADA LETTER DHA;Lo;0;L;;;;;N;;;;; +0CA8;KANNADA LETTER NA;Lo;0;L;;;;;N;;;;; +0CAA;KANNADA LETTER PA;Lo;0;L;;;;;N;;;;; +0CAB;KANNADA LETTER PHA;Lo;0;L;;;;;N;;;;; +0CAC;KANNADA LETTER BA;Lo;0;L;;;;;N;;;;; +0CAD;KANNADA LETTER BHA;Lo;0;L;;;;;N;;;;; +0CAE;KANNADA LETTER MA;Lo;0;L;;;;;N;;;;; +0CAF;KANNADA LETTER YA;Lo;0;L;;;;;N;;;;; +0CB0;KANNADA LETTER RA;Lo;0;L;;;;;N;;;;; +0CB1;KANNADA LETTER RRA;Lo;0;L;;;;;N;;;;; +0CB2;KANNADA LETTER LA;Lo;0;L;;;;;N;;;;; +0CB3;KANNADA LETTER LLA;Lo;0;L;;;;;N;;;;; +0CB5;KANNADA LETTER VA;Lo;0;L;;;;;N;;;;; +0CB6;KANNADA LETTER SHA;Lo;0;L;;;;;N;;;;; +0CB7;KANNADA LETTER SSA;Lo;0;L;;;;;N;;;;; +0CB8;KANNADA LETTER SA;Lo;0;L;;;;;N;;;;; +0CB9;KANNADA LETTER HA;Lo;0;L;;;;;N;;;;; +0CBC;KANNADA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0CBD;KANNADA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0CBE;KANNADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0CBF;KANNADA VOWEL SIGN I;Mn;0;L;;;;;N;;;;; +0CC0;KANNADA VOWEL SIGN II;Mc;0;L;0CBF 0CD5;;;;N;;;;; +0CC1;KANNADA VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +0CC2;KANNADA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +0CC3;KANNADA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +0CC4;KANNADA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +0CC6;KANNADA VOWEL SIGN E;Mn;0;L;;;;;N;;;;; +0CC7;KANNADA VOWEL SIGN EE;Mc;0;L;0CC6 0CD5;;;;N;;;;; +0CC8;KANNADA VOWEL SIGN AI;Mc;0;L;0CC6 0CD6;;;;N;;;;; +0CCA;KANNADA VOWEL SIGN O;Mc;0;L;0CC6 0CC2;;;;N;;;;; +0CCB;KANNADA VOWEL SIGN OO;Mc;0;L;0CCA 0CD5;;;;N;;;;; +0CCC;KANNADA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;; +0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;; +0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;; +0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0CE2;KANNADA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0CE3;KANNADA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0CE6;KANNADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0CE7;KANNADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0CE8;KANNADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0CE9;KANNADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0CEA;KANNADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0CEB;KANNADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0CEC;KANNADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0CED;KANNADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0CEE;KANNADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0CF1;KANNADA SIGN JIHVAMULIYA;So;0;ON;;;;;N;;;;; +0CF2;KANNADA SIGN UPADHMANIYA;So;0;ON;;;;;N;;;;; +0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;; +0D06;MALAYALAM LETTER AA;Lo;0;L;;;;;N;;;;; +0D07;MALAYALAM LETTER I;Lo;0;L;;;;;N;;;;; +0D08;MALAYALAM LETTER II;Lo;0;L;;;;;N;;;;; +0D09;MALAYALAM LETTER U;Lo;0;L;;;;;N;;;;; +0D0A;MALAYALAM LETTER UU;Lo;0;L;;;;;N;;;;; +0D0B;MALAYALAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0D0C;MALAYALAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0D0E;MALAYALAM LETTER E;Lo;0;L;;;;;N;;;;; +0D0F;MALAYALAM LETTER EE;Lo;0;L;;;;;N;;;;; +0D10;MALAYALAM LETTER AI;Lo;0;L;;;;;N;;;;; +0D12;MALAYALAM LETTER O;Lo;0;L;;;;;N;;;;; +0D13;MALAYALAM LETTER OO;Lo;0;L;;;;;N;;;;; +0D14;MALAYALAM LETTER AU;Lo;0;L;;;;;N;;;;; +0D15;MALAYALAM LETTER KA;Lo;0;L;;;;;N;;;;; +0D16;MALAYALAM LETTER KHA;Lo;0;L;;;;;N;;;;; +0D17;MALAYALAM LETTER GA;Lo;0;L;;;;;N;;;;; +0D18;MALAYALAM LETTER GHA;Lo;0;L;;;;;N;;;;; +0D19;MALAYALAM LETTER NGA;Lo;0;L;;;;;N;;;;; +0D1A;MALAYALAM LETTER CA;Lo;0;L;;;;;N;;;;; +0D1B;MALAYALAM LETTER CHA;Lo;0;L;;;;;N;;;;; +0D1C;MALAYALAM LETTER JA;Lo;0;L;;;;;N;;;;; +0D1D;MALAYALAM LETTER JHA;Lo;0;L;;;;;N;;;;; +0D1E;MALAYALAM LETTER NYA;Lo;0;L;;;;;N;;;;; +0D1F;MALAYALAM LETTER TTA;Lo;0;L;;;;;N;;;;; +0D20;MALAYALAM LETTER TTHA;Lo;0;L;;;;;N;;;;; +0D21;MALAYALAM LETTER DDA;Lo;0;L;;;;;N;;;;; +0D22;MALAYALAM LETTER DDHA;Lo;0;L;;;;;N;;;;; +0D23;MALAYALAM LETTER NNA;Lo;0;L;;;;;N;;;;; +0D24;MALAYALAM LETTER TA;Lo;0;L;;;;;N;;;;; +0D25;MALAYALAM LETTER THA;Lo;0;L;;;;;N;;;;; +0D26;MALAYALAM LETTER DA;Lo;0;L;;;;;N;;;;; +0D27;MALAYALAM LETTER DHA;Lo;0;L;;;;;N;;;;; +0D28;MALAYALAM LETTER NA;Lo;0;L;;;;;N;;;;; +0D2A;MALAYALAM LETTER PA;Lo;0;L;;;;;N;;;;; +0D2B;MALAYALAM LETTER PHA;Lo;0;L;;;;;N;;;;; +0D2C;MALAYALAM LETTER BA;Lo;0;L;;;;;N;;;;; +0D2D;MALAYALAM LETTER BHA;Lo;0;L;;;;;N;;;;; +0D2E;MALAYALAM LETTER MA;Lo;0;L;;;;;N;;;;; +0D2F;MALAYALAM LETTER YA;Lo;0;L;;;;;N;;;;; +0D30;MALAYALAM LETTER RA;Lo;0;L;;;;;N;;;;; +0D31;MALAYALAM LETTER RRA;Lo;0;L;;;;;N;;;;; +0D32;MALAYALAM LETTER LA;Lo;0;L;;;;;N;;;;; +0D33;MALAYALAM LETTER LLA;Lo;0;L;;;;;N;;;;; +0D34;MALAYALAM LETTER LLLA;Lo;0;L;;;;;N;;;;; +0D35;MALAYALAM LETTER VA;Lo;0;L;;;;;N;;;;; +0D36;MALAYALAM LETTER SHA;Lo;0;L;;;;;N;;;;; +0D37;MALAYALAM LETTER SSA;Lo;0;L;;;;;N;;;;; +0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;; +0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;; +0D3D;MALAYALAM SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0D40;MALAYALAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0D41;MALAYALAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0D42;MALAYALAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0D43;MALAYALAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0D44;MALAYALAM VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0D46;MALAYALAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +0D47;MALAYALAM VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +0D48;MALAYALAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +0D4A;MALAYALAM VOWEL SIGN O;Mc;0;L;0D46 0D3E;;;;N;;;;; +0D4B;MALAYALAM VOWEL SIGN OO;Mc;0;L;0D47 0D3E;;;;N;;;;; +0D4C;MALAYALAM VOWEL SIGN AU;Mc;0;L;0D46 0D57;;;;N;;;;; +0D4D;MALAYALAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0D57;MALAYALAM AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +0D60;MALAYALAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0D61;MALAYALAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0D62;MALAYALAM VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0D63;MALAYALAM VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0D66;MALAYALAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0D67;MALAYALAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0D68;MALAYALAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0D69;MALAYALAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0D6A;MALAYALAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0D6B;MALAYALAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0D6C;MALAYALAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0D6D;MALAYALAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0D6E;MALAYALAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0D6F;MALAYALAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0D70;MALAYALAM NUMBER TEN;No;0;L;;;;10;N;;;;; +0D71;MALAYALAM NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; +0D72;MALAYALAM NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; +0D73;MALAYALAM FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;; +0D74;MALAYALAM FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;; +0D75;MALAYALAM FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;; +0D79;MALAYALAM DATE MARK;So;0;L;;;;;N;;;;; +0D7A;MALAYALAM LETTER CHILLU NN;Lo;0;L;;;;;N;;;;; +0D7B;MALAYALAM LETTER CHILLU N;Lo;0;L;;;;;N;;;;; +0D7C;MALAYALAM LETTER CHILLU RR;Lo;0;L;;;;;N;;;;; +0D7D;MALAYALAM LETTER CHILLU L;Lo;0;L;;;;;N;;;;; +0D7E;MALAYALAM LETTER CHILLU LL;Lo;0;L;;;;;N;;;;; +0D7F;MALAYALAM LETTER CHILLU K;Lo;0;L;;;;;N;;;;; +0D82;SINHALA SIGN ANUSVARAYA;Mc;0;L;;;;;N;;;;; +0D83;SINHALA SIGN VISARGAYA;Mc;0;L;;;;;N;;;;; +0D85;SINHALA LETTER AYANNA;Lo;0;L;;;;;N;;;;; +0D86;SINHALA LETTER AAYANNA;Lo;0;L;;;;;N;;;;; +0D87;SINHALA LETTER AEYANNA;Lo;0;L;;;;;N;;;;; +0D88;SINHALA LETTER AEEYANNA;Lo;0;L;;;;;N;;;;; +0D89;SINHALA LETTER IYANNA;Lo;0;L;;;;;N;;;;; +0D8A;SINHALA LETTER IIYANNA;Lo;0;L;;;;;N;;;;; +0D8B;SINHALA LETTER UYANNA;Lo;0;L;;;;;N;;;;; +0D8C;SINHALA LETTER UUYANNA;Lo;0;L;;;;;N;;;;; +0D8D;SINHALA LETTER IRUYANNA;Lo;0;L;;;;;N;;;;; +0D8E;SINHALA LETTER IRUUYANNA;Lo;0;L;;;;;N;;;;; +0D8F;SINHALA LETTER ILUYANNA;Lo;0;L;;;;;N;;;;; +0D90;SINHALA LETTER ILUUYANNA;Lo;0;L;;;;;N;;;;; +0D91;SINHALA LETTER EYANNA;Lo;0;L;;;;;N;;;;; +0D92;SINHALA LETTER EEYANNA;Lo;0;L;;;;;N;;;;; +0D93;SINHALA LETTER AIYANNA;Lo;0;L;;;;;N;;;;; +0D94;SINHALA LETTER OYANNA;Lo;0;L;;;;;N;;;;; +0D95;SINHALA LETTER OOYANNA;Lo;0;L;;;;;N;;;;; +0D96;SINHALA LETTER AUYANNA;Lo;0;L;;;;;N;;;;; +0D9A;SINHALA LETTER ALPAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;; +0D9B;SINHALA LETTER MAHAAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;; +0D9C;SINHALA LETTER ALPAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;; +0D9D;SINHALA LETTER MAHAAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;; +0D9E;SINHALA LETTER KANTAJA NAASIKYAYA;Lo;0;L;;;;;N;;;;; +0D9F;SINHALA LETTER SANYAKA GAYANNA;Lo;0;L;;;;;N;;;;; +0DA0;SINHALA LETTER ALPAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;; +0DA1;SINHALA LETTER MAHAAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;; +0DA2;SINHALA LETTER ALPAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;; +0DA3;SINHALA LETTER MAHAAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;; +0DA4;SINHALA LETTER TAALUJA NAASIKYAYA;Lo;0;L;;;;;N;;;;; +0DA5;SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA;Lo;0;L;;;;;N;;;;; +0DA6;SINHALA LETTER SANYAKA JAYANNA;Lo;0;L;;;;;N;;;;; +0DA7;SINHALA LETTER ALPAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;; +0DA8;SINHALA LETTER MAHAAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;; +0DA9;SINHALA LETTER ALPAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;; +0DAA;SINHALA LETTER MAHAAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;; +0DAB;SINHALA LETTER MUURDHAJA NAYANNA;Lo;0;L;;;;;N;;;;; +0DAC;SINHALA LETTER SANYAKA DDAYANNA;Lo;0;L;;;;;N;;;;; +0DAD;SINHALA LETTER ALPAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;; +0DAE;SINHALA LETTER MAHAAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;; +0DAF;SINHALA LETTER ALPAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;; +0DB0;SINHALA LETTER MAHAAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;; +0DB1;SINHALA LETTER DANTAJA NAYANNA;Lo;0;L;;;;;N;;;;; +0DB3;SINHALA LETTER SANYAKA DAYANNA;Lo;0;L;;;;;N;;;;; +0DB4;SINHALA LETTER ALPAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;; +0DB5;SINHALA LETTER MAHAAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;; +0DB6;SINHALA LETTER ALPAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;; +0DB7;SINHALA LETTER MAHAAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;; +0DB8;SINHALA LETTER MAYANNA;Lo;0;L;;;;;N;;;;; +0DB9;SINHALA LETTER AMBA BAYANNA;Lo;0;L;;;;;N;;;;; +0DBA;SINHALA LETTER YAYANNA;Lo;0;L;;;;;N;;;;; +0DBB;SINHALA LETTER RAYANNA;Lo;0;L;;;;;N;;;;; +0DBD;SINHALA LETTER DANTAJA LAYANNA;Lo;0;L;;;;;N;;;;; +0DC0;SINHALA LETTER VAYANNA;Lo;0;L;;;;;N;;;;; +0DC1;SINHALA LETTER TAALUJA SAYANNA;Lo;0;L;;;;;N;;;;; +0DC2;SINHALA LETTER MUURDHAJA SAYANNA;Lo;0;L;;;;;N;;;;; +0DC3;SINHALA LETTER DANTAJA SAYANNA;Lo;0;L;;;;;N;;;;; +0DC4;SINHALA LETTER HAYANNA;Lo;0;L;;;;;N;;;;; +0DC5;SINHALA LETTER MUURDHAJA LAYANNA;Lo;0;L;;;;;N;;;;; +0DC6;SINHALA LETTER FAYANNA;Lo;0;L;;;;;N;;;;; +0DCA;SINHALA SIGN AL-LAKUNA;Mn;9;NSM;;;;;N;;;;; +0DCF;SINHALA VOWEL SIGN AELA-PILLA;Mc;0;L;;;;;N;;;;; +0DD0;SINHALA VOWEL SIGN KETTI AEDA-PILLA;Mc;0;L;;;;;N;;;;; +0DD1;SINHALA VOWEL SIGN DIGA AEDA-PILLA;Mc;0;L;;;;;N;;;;; +0DD2;SINHALA VOWEL SIGN KETTI IS-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD3;SINHALA VOWEL SIGN DIGA IS-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD4;SINHALA VOWEL SIGN KETTI PAA-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD6;SINHALA VOWEL SIGN DIGA PAA-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD8;SINHALA VOWEL SIGN GAETTA-PILLA;Mc;0;L;;;;;N;;;;; +0DD9;SINHALA VOWEL SIGN KOMBUVA;Mc;0;L;;;;;N;;;;; +0DDA;SINHALA VOWEL SIGN DIGA KOMBUVA;Mc;0;L;0DD9 0DCA;;;;N;;;;; +0DDB;SINHALA VOWEL SIGN KOMBU DEKA;Mc;0;L;;;;;N;;;;; +0DDC;SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA;Mc;0;L;0DD9 0DCF;;;;N;;;;; +0DDD;SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA;Mc;0;L;0DDC 0DCA;;;;N;;;;; +0DDE;SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA;Mc;0;L;0DD9 0DDF;;;;N;;;;; +0DDF;SINHALA VOWEL SIGN GAYANUKITTA;Mc;0;L;;;;;N;;;;; +0DF2;SINHALA VOWEL SIGN DIGA GAETTA-PILLA;Mc;0;L;;;;;N;;;;; +0DF3;SINHALA VOWEL SIGN DIGA GAYANUKITTA;Mc;0;L;;;;;N;;;;; +0DF4;SINHALA PUNCTUATION KUNDDALIYA;Po;0;L;;;;;N;;;;; +0E01;THAI CHARACTER KO KAI;Lo;0;L;;;;;N;THAI LETTER KO KAI;;;; +0E02;THAI CHARACTER KHO KHAI;Lo;0;L;;;;;N;THAI LETTER KHO KHAI;;;; +0E03;THAI CHARACTER KHO KHUAT;Lo;0;L;;;;;N;THAI LETTER KHO KHUAT;;;; +0E04;THAI CHARACTER KHO KHWAI;Lo;0;L;;;;;N;THAI LETTER KHO KHWAI;;;; +0E05;THAI CHARACTER KHO KHON;Lo;0;L;;;;;N;THAI LETTER KHO KHON;;;; +0E06;THAI CHARACTER KHO RAKHANG;Lo;0;L;;;;;N;THAI LETTER KHO RAKHANG;;;; +0E07;THAI CHARACTER NGO NGU;Lo;0;L;;;;;N;THAI LETTER NGO NGU;;;; +0E08;THAI CHARACTER CHO CHAN;Lo;0;L;;;;;N;THAI LETTER CHO CHAN;;;; +0E09;THAI CHARACTER CHO CHING;Lo;0;L;;;;;N;THAI LETTER CHO CHING;;;; +0E0A;THAI CHARACTER CHO CHANG;Lo;0;L;;;;;N;THAI LETTER CHO CHANG;;;; +0E0B;THAI CHARACTER SO SO;Lo;0;L;;;;;N;THAI LETTER SO SO;;;; +0E0C;THAI CHARACTER CHO CHOE;Lo;0;L;;;;;N;THAI LETTER CHO CHOE;;;; +0E0D;THAI CHARACTER YO YING;Lo;0;L;;;;;N;THAI LETTER YO YING;;;; +0E0E;THAI CHARACTER DO CHADA;Lo;0;L;;;;;N;THAI LETTER DO CHADA;;;; +0E0F;THAI CHARACTER TO PATAK;Lo;0;L;;;;;N;THAI LETTER TO PATAK;;;; +0E10;THAI CHARACTER THO THAN;Lo;0;L;;;;;N;THAI LETTER THO THAN;;;; +0E11;THAI CHARACTER THO NANGMONTHO;Lo;0;L;;;;;N;THAI LETTER THO NANGMONTHO;;;; +0E12;THAI CHARACTER THO PHUTHAO;Lo;0;L;;;;;N;THAI LETTER THO PHUTHAO;;;; +0E13;THAI CHARACTER NO NEN;Lo;0;L;;;;;N;THAI LETTER NO NEN;;;; +0E14;THAI CHARACTER DO DEK;Lo;0;L;;;;;N;THAI LETTER DO DEK;;;; +0E15;THAI CHARACTER TO TAO;Lo;0;L;;;;;N;THAI LETTER TO TAO;;;; +0E16;THAI CHARACTER THO THUNG;Lo;0;L;;;;;N;THAI LETTER THO THUNG;;;; +0E17;THAI CHARACTER THO THAHAN;Lo;0;L;;;;;N;THAI LETTER THO THAHAN;;;; +0E18;THAI CHARACTER THO THONG;Lo;0;L;;;;;N;THAI LETTER THO THONG;;;; +0E19;THAI CHARACTER NO NU;Lo;0;L;;;;;N;THAI LETTER NO NU;;;; +0E1A;THAI CHARACTER BO BAIMAI;Lo;0;L;;;;;N;THAI LETTER BO BAIMAI;;;; +0E1B;THAI CHARACTER PO PLA;Lo;0;L;;;;;N;THAI LETTER PO PLA;;;; +0E1C;THAI CHARACTER PHO PHUNG;Lo;0;L;;;;;N;THAI LETTER PHO PHUNG;;;; +0E1D;THAI CHARACTER FO FA;Lo;0;L;;;;;N;THAI LETTER FO FA;;;; +0E1E;THAI CHARACTER PHO PHAN;Lo;0;L;;;;;N;THAI LETTER PHO PHAN;;;; +0E1F;THAI CHARACTER FO FAN;Lo;0;L;;;;;N;THAI LETTER FO FAN;;;; +0E20;THAI CHARACTER PHO SAMPHAO;Lo;0;L;;;;;N;THAI LETTER PHO SAMPHAO;;;; +0E21;THAI CHARACTER MO MA;Lo;0;L;;;;;N;THAI LETTER MO MA;;;; +0E22;THAI CHARACTER YO YAK;Lo;0;L;;;;;N;THAI LETTER YO YAK;;;; +0E23;THAI CHARACTER RO RUA;Lo;0;L;;;;;N;THAI LETTER RO RUA;;;; +0E24;THAI CHARACTER RU;Lo;0;L;;;;;N;THAI LETTER RU;;;; +0E25;THAI CHARACTER LO LING;Lo;0;L;;;;;N;THAI LETTER LO LING;;;; +0E26;THAI CHARACTER LU;Lo;0;L;;;;;N;THAI LETTER LU;;;; +0E27;THAI CHARACTER WO WAEN;Lo;0;L;;;;;N;THAI LETTER WO WAEN;;;; +0E28;THAI CHARACTER SO SALA;Lo;0;L;;;;;N;THAI LETTER SO SALA;;;; +0E29;THAI CHARACTER SO RUSI;Lo;0;L;;;;;N;THAI LETTER SO RUSI;;;; +0E2A;THAI CHARACTER SO SUA;Lo;0;L;;;;;N;THAI LETTER SO SUA;;;; +0E2B;THAI CHARACTER HO HIP;Lo;0;L;;;;;N;THAI LETTER HO HIP;;;; +0E2C;THAI CHARACTER LO CHULA;Lo;0;L;;;;;N;THAI LETTER LO CHULA;;;; +0E2D;THAI CHARACTER O ANG;Lo;0;L;;;;;N;THAI LETTER O ANG;;;; +0E2E;THAI CHARACTER HO NOKHUK;Lo;0;L;;;;;N;THAI LETTER HO NOK HUK;;;; +0E2F;THAI CHARACTER PAIYANNOI;Lo;0;L;;;;;N;THAI PAI YAN NOI;;;; +0E30;THAI CHARACTER SARA A;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA A;;;; +0E31;THAI CHARACTER MAI HAN-AKAT;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI HAN-AKAT;;;; +0E32;THAI CHARACTER SARA AA;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AA;;;; +0E33;THAI CHARACTER SARA AM;Lo;0;L; 0E4D 0E32;;;;N;THAI VOWEL SIGN SARA AM;;;; +0E34;THAI CHARACTER SARA I;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA I;;;; +0E35;THAI CHARACTER SARA II;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA II;;;; +0E36;THAI CHARACTER SARA UE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UE;;;; +0E37;THAI CHARACTER SARA UEE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UEE;;;; +0E38;THAI CHARACTER SARA U;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA U;;;; +0E39;THAI CHARACTER SARA UU;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA UU;;;; +0E3A;THAI CHARACTER PHINTHU;Mn;9;NSM;;;;;N;THAI VOWEL SIGN PHINTHU;;;; +0E3F;THAI CURRENCY SYMBOL BAHT;Sc;0;ET;;;;;N;THAI BAHT SIGN;;;; +0E40;THAI CHARACTER SARA E;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA E;;;; +0E41;THAI CHARACTER SARA AE;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AE;;;; +0E42;THAI CHARACTER SARA O;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA O;;;; +0E43;THAI CHARACTER SARA AI MAIMUAN;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MUAN;;;; +0E44;THAI CHARACTER SARA AI MAIMALAI;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MALAI;;;; +0E45;THAI CHARACTER LAKKHANGYAO;Lo;0;L;;;;;N;THAI LAK KHANG YAO;;;; +0E46;THAI CHARACTER MAIYAMOK;Lm;0;L;;;;;N;THAI MAI YAMOK;;;; +0E47;THAI CHARACTER MAITAIKHU;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI TAI KHU;;;; +0E48;THAI CHARACTER MAI EK;Mn;107;NSM;;;;;N;THAI TONE MAI EK;;;; +0E49;THAI CHARACTER MAI THO;Mn;107;NSM;;;;;N;THAI TONE MAI THO;;;; +0E4A;THAI CHARACTER MAI TRI;Mn;107;NSM;;;;;N;THAI TONE MAI TRI;;;; +0E4B;THAI CHARACTER MAI CHATTAWA;Mn;107;NSM;;;;;N;THAI TONE MAI CHATTAWA;;;; +0E4C;THAI CHARACTER THANTHAKHAT;Mn;0;NSM;;;;;N;THAI THANTHAKHAT;;;; +0E4D;THAI CHARACTER NIKHAHIT;Mn;0;NSM;;;;;N;THAI NIKKHAHIT;;;; +0E4E;THAI CHARACTER YAMAKKAN;Mn;0;NSM;;;;;N;THAI YAMAKKAN;;;; +0E4F;THAI CHARACTER FONGMAN;Po;0;L;;;;;N;THAI FONGMAN;;;; +0E50;THAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0E51;THAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0E52;THAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0E53;THAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0E54;THAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0E55;THAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0E56;THAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0E57;THAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0E58;THAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0E59;THAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0E5A;THAI CHARACTER ANGKHANKHU;Po;0;L;;;;;N;THAI ANGKHANKHU;;;; +0E5B;THAI CHARACTER KHOMUT;Po;0;L;;;;;N;THAI KHOMUT;;;; +0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;; +0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;; +0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;; +0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;; +0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;; +0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;; +0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;; +0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;; +0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;; +0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;; +0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;; +0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;; +0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;; +0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;; +0E9C;LAO LETTER PHO SUNG;Lo;0;L;;;;;N;;;;; +0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;; +0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;; +0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;; +0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;; +0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;; +0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;; +0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;; +0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;; +0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;; +0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;; +0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;; +0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;; +0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;; +0EB0;LAO VOWEL SIGN A;Lo;0;L;;;;;N;;;;; +0EB1;LAO VOWEL SIGN MAI KAN;Mn;0;NSM;;;;;N;;;;; +0EB2;LAO VOWEL SIGN AA;Lo;0;L;;;;;N;;;;; +0EB3;LAO VOWEL SIGN AM;Lo;0;L; 0ECD 0EB2;;;;N;;;;; +0EB4;LAO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0EB5;LAO VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +0EB6;LAO VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;; +0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;; +0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;; +0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;; +0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;; +0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;; +0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;; +0EC0;LAO VOWEL SIGN E;Lo;0;L;;;;;N;;;;; +0EC1;LAO VOWEL SIGN EI;Lo;0;L;;;;;N;;;;; +0EC2;LAO VOWEL SIGN O;Lo;0;L;;;;;N;;;;; +0EC3;LAO VOWEL SIGN AY;Lo;0;L;;;;;N;;;;; +0EC4;LAO VOWEL SIGN AI;Lo;0;L;;;;;N;;;;; +0EC6;LAO KO LA;Lm;0;L;;;;;N;;;;; +0EC8;LAO TONE MAI EK;Mn;122;NSM;;;;;N;;;;; +0EC9;LAO TONE MAI THO;Mn;122;NSM;;;;;N;;;;; +0ECA;LAO TONE MAI TI;Mn;122;NSM;;;;;N;;;;; +0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;; +0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;; +0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;; +0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0ED3;LAO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0ED4;LAO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0ED5;LAO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0ED6;LAO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0ED7;LAO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0ED8;LAO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0ED9;LAO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0EDC;LAO HO NO;Lo;0;L; 0EAB 0E99;;;;N;;;;; +0EDD;LAO HO MO;Lo;0;L; 0EAB 0EA1;;;;N;;;;; +0F00;TIBETAN SYLLABLE OM;Lo;0;L;;;;;N;;;;; +0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;;;; +0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;;;; +0F03;TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA;So;0;L;;;;;N;;;;; +0F04;TIBETAN MARK INITIAL YIG MGO MDUN MA;Po;0;L;;;;;N;TIBETAN SINGLE ORNAMENT;;;; +0F05;TIBETAN MARK CLOSING YIG MGO SGAB MA;Po;0;L;;;;;N;;;;; +0F06;TIBETAN MARK CARET YIG MGO PHUR SHAD MA;Po;0;L;;;;;N;;;;; +0F07;TIBETAN MARK YIG MGO TSHEG SHAD MA;Po;0;L;;;;;N;;;;; +0F08;TIBETAN MARK SBRUL SHAD;Po;0;L;;;;;N;TIBETAN RGYANSHAD;;;; +0F09;TIBETAN MARK BSKUR YIG MGO;Po;0;L;;;;;N;;;;; +0F0A;TIBETAN MARK BKA- SHOG YIG MGO;Po;0;L;;;;;N;;;;; +0F0B;TIBETAN MARK INTERSYLLABIC TSHEG;Po;0;L;;;;;N;TIBETAN TSEG;;;; +0F0C;TIBETAN MARK DELIMITER TSHEG BSTAR;Po;0;L; 0F0B;;;;N;;;;; +0F0D;TIBETAN MARK SHAD;Po;0;L;;;;;N;TIBETAN SHAD;;;; +0F0E;TIBETAN MARK NYIS SHAD;Po;0;L;;;;;N;TIBETAN DOUBLE SHAD;;;; +0F0F;TIBETAN MARK TSHEG SHAD;Po;0;L;;;;;N;;;;; +0F10;TIBETAN MARK NYIS TSHEG SHAD;Po;0;L;;;;;N;;;;; +0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;;;; +0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;;;; +0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;;;; +0F14;TIBETAN MARK GTER TSHEG;So;0;L;;;;;N;TIBETAN COMMA;;;; +0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;;;; +0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;;;; +0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;;;; +0F18;TIBETAN ASTROLOGICAL SIGN -KHYUD PA;Mn;220;NSM;;;;;N;;;;; +0F19;TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS;Mn;220;NSM;;;;;N;;;;; +0F1A;TIBETAN SIGN RDEL DKAR GCIG;So;0;L;;;;;N;;;;; +0F1B;TIBETAN SIGN RDEL DKAR GNYIS;So;0;L;;;;;N;;;;; +0F1C;TIBETAN SIGN RDEL DKAR GSUM;So;0;L;;;;;N;;;;; +0F1D;TIBETAN SIGN RDEL NAG GCIG;So;0;L;;;;;N;;;;; +0F1E;TIBETAN SIGN RDEL NAG GNYIS;So;0;L;;;;;N;;;;; +0F1F;TIBETAN SIGN RDEL DKAR RDEL NAG;So;0;L;;;;;N;;;;; +0F20;TIBETAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0F21;TIBETAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0F22;TIBETAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0F23;TIBETAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0F24;TIBETAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0F25;TIBETAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0F26;TIBETAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0F27;TIBETAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0F28;TIBETAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0F29;TIBETAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0F2A;TIBETAN DIGIT HALF ONE;No;0;L;;;;1/2;N;;;;; +0F2B;TIBETAN DIGIT HALF TWO;No;0;L;;;;3/2;N;;;;; +0F2C;TIBETAN DIGIT HALF THREE;No;0;L;;;;5/2;N;;;;; +0F2D;TIBETAN DIGIT HALF FOUR;No;0;L;;;;7/2;N;;;;; +0F2E;TIBETAN DIGIT HALF FIVE;No;0;L;;;;9/2;N;;;;; +0F2F;TIBETAN DIGIT HALF SIX;No;0;L;;;;11/2;N;;;;; +0F30;TIBETAN DIGIT HALF SEVEN;No;0;L;;;;13/2;N;;;;; +0F31;TIBETAN DIGIT HALF EIGHT;No;0;L;;;;15/2;N;;;;; +0F32;TIBETAN DIGIT HALF NINE;No;0;L;;;;17/2;N;;;;; +0F33;TIBETAN DIGIT HALF ZERO;No;0;L;;;;-1/2;N;;;;; +0F34;TIBETAN MARK BSDUS RTAGS;So;0;L;;;;;N;;;;; +0F35;TIBETAN MARK NGAS BZUNG NYI ZLA;Mn;220;NSM;;;;;N;TIBETAN HONORIFIC UNDER RING;;;; +0F36;TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN;So;0;L;;;;;N;;;;; +0F37;TIBETAN MARK NGAS BZUNG SGOR RTAGS;Mn;220;NSM;;;;;N;TIBETAN UNDER RING;;;; +0F38;TIBETAN MARK CHE MGO;So;0;L;;;;;N;;;;; +0F39;TIBETAN MARK TSA -PHRU;Mn;216;NSM;;;;;N;TIBETAN LENITION MARK;;;; +0F3A;TIBETAN MARK GUG RTAGS GYON;Ps;0;ON;;;;;Y;;;;; +0F3B;TIBETAN MARK GUG RTAGS GYAS;Pe;0;ON;;;;;Y;;;;; +0F3C;TIBETAN MARK ANG KHANG GYON;Ps;0;ON;;;;;Y;TIBETAN LEFT BRACE;;;; +0F3D;TIBETAN MARK ANG KHANG GYAS;Pe;0;ON;;;;;Y;TIBETAN RIGHT BRACE;;;; +0F3E;TIBETAN SIGN YAR TSHES;Mc;0;L;;;;;N;;;;; +0F3F;TIBETAN SIGN MAR TSHES;Mc;0;L;;;;;N;;;;; +0F40;TIBETAN LETTER KA;Lo;0;L;;;;;N;;;;; +0F41;TIBETAN LETTER KHA;Lo;0;L;;;;;N;;;;; +0F42;TIBETAN LETTER GA;Lo;0;L;;;;;N;;;;; +0F43;TIBETAN LETTER GHA;Lo;0;L;0F42 0FB7;;;;N;;;;; +0F44;TIBETAN LETTER NGA;Lo;0;L;;;;;N;;;;; +0F45;TIBETAN LETTER CA;Lo;0;L;;;;;N;;;;; +0F46;TIBETAN LETTER CHA;Lo;0;L;;;;;N;;;;; +0F47;TIBETAN LETTER JA;Lo;0;L;;;;;N;;;;; +0F49;TIBETAN LETTER NYA;Lo;0;L;;;;;N;;;;; +0F4A;TIBETAN LETTER TTA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED TA;;;; +0F4B;TIBETAN LETTER TTHA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED THA;;;; +0F4C;TIBETAN LETTER DDA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED DA;;;; +0F4D;TIBETAN LETTER DDHA;Lo;0;L;0F4C 0FB7;;;;N;;;;; +0F4E;TIBETAN LETTER NNA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED NA;;;; +0F4F;TIBETAN LETTER TA;Lo;0;L;;;;;N;;;;; +0F50;TIBETAN LETTER THA;Lo;0;L;;;;;N;;;;; +0F51;TIBETAN LETTER DA;Lo;0;L;;;;;N;;;;; +0F52;TIBETAN LETTER DHA;Lo;0;L;0F51 0FB7;;;;N;;;;; +0F53;TIBETAN LETTER NA;Lo;0;L;;;;;N;;;;; +0F54;TIBETAN LETTER PA;Lo;0;L;;;;;N;;;;; +0F55;TIBETAN LETTER PHA;Lo;0;L;;;;;N;;;;; +0F56;TIBETAN LETTER BA;Lo;0;L;;;;;N;;;;; +0F57;TIBETAN LETTER BHA;Lo;0;L;0F56 0FB7;;;;N;;;;; +0F58;TIBETAN LETTER MA;Lo;0;L;;;;;N;;;;; +0F59;TIBETAN LETTER TSA;Lo;0;L;;;;;N;;;;; +0F5A;TIBETAN LETTER TSHA;Lo;0;L;;;;;N;;;;; +0F5B;TIBETAN LETTER DZA;Lo;0;L;;;;;N;;;;; +0F5C;TIBETAN LETTER DZHA;Lo;0;L;0F5B 0FB7;;;;N;;;;; +0F5D;TIBETAN LETTER WA;Lo;0;L;;;;;N;;;;; +0F5E;TIBETAN LETTER ZHA;Lo;0;L;;;;;N;;;;; +0F5F;TIBETAN LETTER ZA;Lo;0;L;;;;;N;;;;; +0F60;TIBETAN LETTER -A;Lo;0;L;;;;;N;TIBETAN LETTER AA;;;; +0F61;TIBETAN LETTER YA;Lo;0;L;;;;;N;;;;; +0F62;TIBETAN LETTER RA;Lo;0;L;;;;;N;;;;; +0F63;TIBETAN LETTER LA;Lo;0;L;;;;;N;;;;; +0F64;TIBETAN LETTER SHA;Lo;0;L;;;;;N;;;;; +0F65;TIBETAN LETTER SSA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED SHA;;;; +0F66;TIBETAN LETTER SA;Lo;0;L;;;;;N;;;;; +0F67;TIBETAN LETTER HA;Lo;0;L;;;;;N;;;;; +0F68;TIBETAN LETTER A;Lo;0;L;;;;;N;;;;; +0F69;TIBETAN LETTER KSSA;Lo;0;L;0F40 0FB5;;;;N;;;;; +0F6A;TIBETAN LETTER FIXED-FORM RA;Lo;0;L;;;;;N;;;;; +0F6B;TIBETAN LETTER KKA;Lo;0;L;;;;;N;;;;; +0F6C;TIBETAN LETTER RRA;Lo;0;L;;;;;N;;;;; +0F71;TIBETAN VOWEL SIGN AA;Mn;129;NSM;;;;;N;;;;; +0F72;TIBETAN VOWEL SIGN I;Mn;130;NSM;;;;;N;;;;; +0F73;TIBETAN VOWEL SIGN II;Mn;0;NSM;0F71 0F72;;;;N;;;;; +0F74;TIBETAN VOWEL SIGN U;Mn;132;NSM;;;;;N;;;;; +0F75;TIBETAN VOWEL SIGN UU;Mn;0;NSM;0F71 0F74;;;;N;;;;; +0F76;TIBETAN VOWEL SIGN VOCALIC R;Mn;0;NSM;0FB2 0F80;;;;N;;;;; +0F77;TIBETAN VOWEL SIGN VOCALIC RR;Mn;0;NSM; 0FB2 0F81;;;;N;;;;; +0F78;TIBETAN VOWEL SIGN VOCALIC L;Mn;0;NSM;0FB3 0F80;;;;N;;;;; +0F79;TIBETAN VOWEL SIGN VOCALIC LL;Mn;0;NSM; 0FB3 0F81;;;;N;;;;; +0F7A;TIBETAN VOWEL SIGN E;Mn;130;NSM;;;;;N;;;;; +0F7B;TIBETAN VOWEL SIGN EE;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AI;;;; +0F7C;TIBETAN VOWEL SIGN O;Mn;130;NSM;;;;;N;;;;; +0F7D;TIBETAN VOWEL SIGN OO;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AU;;;; +0F7E;TIBETAN SIGN RJES SU NGA RO;Mn;0;NSM;;;;;N;TIBETAN ANUSVARA;;;; +0F7F;TIBETAN SIGN RNAM BCAD;Mc;0;L;;;;;N;TIBETAN VISARGA;;;; +0F80;TIBETAN VOWEL SIGN REVERSED I;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN SHORT I;;;; +0F81;TIBETAN VOWEL SIGN REVERSED II;Mn;0;NSM;0F71 0F80;;;;N;;;;; +0F82;TIBETAN SIGN NYI ZLA NAA DA;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU WITH ORNAMENT;;;; +0F83;TIBETAN SIGN SNA LDAN;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU;;;; +0F84;TIBETAN MARK HALANTA;Mn;9;NSM;;;;;N;TIBETAN VIRAMA;;;; +0F85;TIBETAN MARK PALUTA;Po;0;L;;;;;N;TIBETAN CHUCHENYIGE;;;; +0F86;TIBETAN SIGN LCI RTAGS;Mn;230;NSM;;;;;N;;;;; +0F87;TIBETAN SIGN YANG RTAGS;Mn;230;NSM;;;;;N;;;;; +0F88;TIBETAN SIGN LCE TSA CAN;Lo;0;L;;;;;N;;;;; +0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;;;; +0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;;;; +0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;;;; +0F90;TIBETAN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;; +0F91;TIBETAN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;; +0F92;TIBETAN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;; +0F93;TIBETAN SUBJOINED LETTER GHA;Mn;0;NSM;0F92 0FB7;;;;N;;;;; +0F94;TIBETAN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;; +0F95;TIBETAN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;; +0F96;TIBETAN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;; +0F97;TIBETAN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;; +0F99;TIBETAN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;; +0F9A;TIBETAN SUBJOINED LETTER TTA;Mn;0;NSM;;;;;N;;;;; +0F9B;TIBETAN SUBJOINED LETTER TTHA;Mn;0;NSM;;;;;N;;;;; +0F9C;TIBETAN SUBJOINED LETTER DDA;Mn;0;NSM;;;;;N;;;;; +0F9D;TIBETAN SUBJOINED LETTER DDHA;Mn;0;NSM;0F9C 0FB7;;;;N;;;;; +0F9E;TIBETAN SUBJOINED LETTER NNA;Mn;0;NSM;;;;;N;;;;; +0F9F;TIBETAN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;; +0FA0;TIBETAN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;; +0FA1;TIBETAN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;; +0FA2;TIBETAN SUBJOINED LETTER DHA;Mn;0;NSM;0FA1 0FB7;;;;N;;;;; +0FA3;TIBETAN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;; +0FA4;TIBETAN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;; +0FA5;TIBETAN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;; +0FA6;TIBETAN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;; +0FA7;TIBETAN SUBJOINED LETTER BHA;Mn;0;NSM;0FA6 0FB7;;;;N;;;;; +0FA8;TIBETAN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;; +0FA9;TIBETAN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;; +0FAA;TIBETAN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;; +0FAB;TIBETAN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;; +0FAC;TIBETAN SUBJOINED LETTER DZHA;Mn;0;NSM;0FAB 0FB7;;;;N;;;;; +0FAD;TIBETAN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;;;; +0FAE;TIBETAN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;; +0FAF;TIBETAN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;; +0FB0;TIBETAN SUBJOINED LETTER -A;Mn;0;NSM;;;;;N;;;;; +0FB1;TIBETAN SUBJOINED LETTER YA;Mn;0;NSM;;;;;N;;;;; +0FB2;TIBETAN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;;;; +0FB3;TIBETAN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;; +0FB4;TIBETAN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;; +0FB5;TIBETAN SUBJOINED LETTER SSA;Mn;0;NSM;;;;;N;;;;; +0FB6;TIBETAN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;; +0FB7;TIBETAN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;; +0FB8;TIBETAN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;; +0FB9;TIBETAN SUBJOINED LETTER KSSA;Mn;0;NSM;0F90 0FB5;;;;N;;;;; +0FBA;TIBETAN SUBJOINED LETTER FIXED-FORM WA;Mn;0;NSM;;;;;N;;;;; +0FBB;TIBETAN SUBJOINED LETTER FIXED-FORM YA;Mn;0;NSM;;;;;N;;;;; +0FBC;TIBETAN SUBJOINED LETTER FIXED-FORM RA;Mn;0;NSM;;;;;N;;;;; +0FBE;TIBETAN KU RU KHA;So;0;L;;;;;N;;;;; +0FBF;TIBETAN KU RU KHA BZHI MIG CAN;So;0;L;;;;;N;;;;; +0FC0;TIBETAN CANTILLATION SIGN HEAVY BEAT;So;0;L;;;;;N;;;;; +0FC1;TIBETAN CANTILLATION SIGN LIGHT BEAT;So;0;L;;;;;N;;;;; +0FC2;TIBETAN CANTILLATION SIGN CANG TE-U;So;0;L;;;;;N;;;;; +0FC3;TIBETAN CANTILLATION SIGN SBUB -CHAL;So;0;L;;;;;N;;;;; +0FC4;TIBETAN SYMBOL DRIL BU;So;0;L;;;;;N;;;;; +0FC5;TIBETAN SYMBOL RDO RJE;So;0;L;;;;;N;;;;; +0FC6;TIBETAN SYMBOL PADMA GDAN;Mn;220;NSM;;;;;N;;;;; +0FC7;TIBETAN SYMBOL RDO RJE RGYA GRAM;So;0;L;;;;;N;;;;; +0FC8;TIBETAN SYMBOL PHUR PA;So;0;L;;;;;N;;;;; +0FC9;TIBETAN SYMBOL NOR BU;So;0;L;;;;;N;;;;; +0FCA;TIBETAN SYMBOL NOR BU NYIS -KHYIL;So;0;L;;;;;N;;;;; +0FCB;TIBETAN SYMBOL NOR BU GSUM -KHYIL;So;0;L;;;;;N;;;;; +0FCC;TIBETAN SYMBOL NOR BU BZHI -KHYIL;So;0;L;;;;;N;;;;; +0FCE;TIBETAN SIGN RDEL NAG RDEL DKAR;So;0;L;;;;;N;;;;; +0FCF;TIBETAN SIGN RDEL NAG GSUM;So;0;L;;;;;N;;;;; +0FD0;TIBETAN MARK BSKA- SHOG GI MGO RGYAN;Po;0;L;;;;;N;;;;; +0FD1;TIBETAN MARK MNYAM YIG GI MGO RGYAN;Po;0;L;;;;;N;;;;; +0FD2;TIBETAN MARK NYIS TSHEG;Po;0;L;;;;;N;;;;; +0FD3;TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA;Po;0;L;;;;;N;;;;; +0FD4;TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA;Po;0;L;;;;;N;;;;; +0FD5;RIGHT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;; +0FD6;LEFT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;; +0FD7;RIGHT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;; +0FD8;LEFT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;; +1000;MYANMAR LETTER KA;Lo;0;L;;;;;N;;;;; +1001;MYANMAR LETTER KHA;Lo;0;L;;;;;N;;;;; +1002;MYANMAR LETTER GA;Lo;0;L;;;;;N;;;;; +1003;MYANMAR LETTER GHA;Lo;0;L;;;;;N;;;;; +1004;MYANMAR LETTER NGA;Lo;0;L;;;;;N;;;;; +1005;MYANMAR LETTER CA;Lo;0;L;;;;;N;;;;; +1006;MYANMAR LETTER CHA;Lo;0;L;;;;;N;;;;; +1007;MYANMAR LETTER JA;Lo;0;L;;;;;N;;;;; +1008;MYANMAR LETTER JHA;Lo;0;L;;;;;N;;;;; +1009;MYANMAR LETTER NYA;Lo;0;L;;;;;N;;;;; +100A;MYANMAR LETTER NNYA;Lo;0;L;;;;;N;;;;; +100B;MYANMAR LETTER TTA;Lo;0;L;;;;;N;;;;; +100C;MYANMAR LETTER TTHA;Lo;0;L;;;;;N;;;;; +100D;MYANMAR LETTER DDA;Lo;0;L;;;;;N;;;;; +100E;MYANMAR LETTER DDHA;Lo;0;L;;;;;N;;;;; +100F;MYANMAR LETTER NNA;Lo;0;L;;;;;N;;;;; +1010;MYANMAR LETTER TA;Lo;0;L;;;;;N;;;;; +1011;MYANMAR LETTER THA;Lo;0;L;;;;;N;;;;; +1012;MYANMAR LETTER DA;Lo;0;L;;;;;N;;;;; +1013;MYANMAR LETTER DHA;Lo;0;L;;;;;N;;;;; +1014;MYANMAR LETTER NA;Lo;0;L;;;;;N;;;;; +1015;MYANMAR LETTER PA;Lo;0;L;;;;;N;;;;; +1016;MYANMAR LETTER PHA;Lo;0;L;;;;;N;;;;; +1017;MYANMAR LETTER BA;Lo;0;L;;;;;N;;;;; +1018;MYANMAR LETTER BHA;Lo;0;L;;;;;N;;;;; +1019;MYANMAR LETTER MA;Lo;0;L;;;;;N;;;;; +101A;MYANMAR LETTER YA;Lo;0;L;;;;;N;;;;; +101B;MYANMAR LETTER RA;Lo;0;L;;;;;N;;;;; +101C;MYANMAR LETTER LA;Lo;0;L;;;;;N;;;;; +101D;MYANMAR LETTER WA;Lo;0;L;;;;;N;;;;; +101E;MYANMAR LETTER SA;Lo;0;L;;;;;N;;;;; +101F;MYANMAR LETTER HA;Lo;0;L;;;;;N;;;;; +1020;MYANMAR LETTER LLA;Lo;0;L;;;;;N;;;;; +1021;MYANMAR LETTER A;Lo;0;L;;;;;N;;;;; +1022;MYANMAR LETTER SHAN A;Lo;0;L;;;;;N;;;;; +1023;MYANMAR LETTER I;Lo;0;L;;;;;N;;;;; +1024;MYANMAR LETTER II;Lo;0;L;;;;;N;;;;; +1025;MYANMAR LETTER U;Lo;0;L;;;;;N;;;;; +1026;MYANMAR LETTER UU;Lo;0;L;1025 102E;;;;N;;;;; +1027;MYANMAR LETTER E;Lo;0;L;;;;;N;;;;; +1028;MYANMAR LETTER MON E;Lo;0;L;;;;;N;;;;; +1029;MYANMAR LETTER O;Lo;0;L;;;;;N;;;;; +102A;MYANMAR LETTER AU;Lo;0;L;;;;;N;;;;; +102B;MYANMAR VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;; +102C;MYANMAR VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +102D;MYANMAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +102E;MYANMAR VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +102F;MYANMAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1030;MYANMAR VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +1031;MYANMAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +1032;MYANMAR VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +1033;MYANMAR VOWEL SIGN MON II;Mn;0;NSM;;;;;N;;;;; +1034;MYANMAR VOWEL SIGN MON O;Mn;0;NSM;;;;;N;;;;; +1035;MYANMAR VOWEL SIGN E ABOVE;Mn;0;NSM;;;;;N;;;;; +1036;MYANMAR SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +1037;MYANMAR SIGN DOT BELOW;Mn;7;NSM;;;;;N;;;;; +1038;MYANMAR SIGN VISARGA;Mc;0;L;;;;;N;;;;; +1039;MYANMAR SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +103A;MYANMAR SIGN ASAT;Mn;9;NSM;;;;;N;;;;; +103B;MYANMAR CONSONANT SIGN MEDIAL YA;Mc;0;L;;;;;N;;;;; +103C;MYANMAR CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;; +103D;MYANMAR CONSONANT SIGN MEDIAL WA;Mn;0;NSM;;;;;N;;;;; +103E;MYANMAR CONSONANT SIGN MEDIAL HA;Mn;0;NSM;;;;;N;;;;; +103F;MYANMAR LETTER GREAT SA;Lo;0;L;;;;;N;;;;; +1040;MYANMAR DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1041;MYANMAR DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1042;MYANMAR DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1043;MYANMAR DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1044;MYANMAR DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1045;MYANMAR DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1046;MYANMAR DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1047;MYANMAR DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1048;MYANMAR DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1049;MYANMAR DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +104A;MYANMAR SIGN LITTLE SECTION;Po;0;L;;;;;N;;;;; +104B;MYANMAR SIGN SECTION;Po;0;L;;;;;N;;;;; +104C;MYANMAR SYMBOL LOCATIVE;Po;0;L;;;;;N;;;;; +104D;MYANMAR SYMBOL COMPLETED;Po;0;L;;;;;N;;;;; +104E;MYANMAR SYMBOL AFOREMENTIONED;Po;0;L;;;;;N;;;;; +104F;MYANMAR SYMBOL GENITIVE;Po;0;L;;;;;N;;;;; +1050;MYANMAR LETTER SHA;Lo;0;L;;;;;N;;;;; +1051;MYANMAR LETTER SSA;Lo;0;L;;;;;N;;;;; +1052;MYANMAR LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +1053;MYANMAR LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +1054;MYANMAR LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +1055;MYANMAR LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +1056;MYANMAR VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +1057;MYANMAR VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +1058;MYANMAR VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +1059;MYANMAR VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +105A;MYANMAR LETTER MON NGA;Lo;0;L;;;;;N;;;;; +105B;MYANMAR LETTER MON JHA;Lo;0;L;;;;;N;;;;; +105C;MYANMAR LETTER MON BBA;Lo;0;L;;;;;N;;;;; +105D;MYANMAR LETTER MON BBE;Lo;0;L;;;;;N;;;;; +105E;MYANMAR CONSONANT SIGN MON MEDIAL NA;Mn;0;NSM;;;;;N;;;;; +105F;MYANMAR CONSONANT SIGN MON MEDIAL MA;Mn;0;NSM;;;;;N;;;;; +1060;MYANMAR CONSONANT SIGN MON MEDIAL LA;Mn;0;NSM;;;;;N;;;;; +1061;MYANMAR LETTER SGAW KAREN SHA;Lo;0;L;;;;;N;;;;; +1062;MYANMAR VOWEL SIGN SGAW KAREN EU;Mc;0;L;;;;;N;;;;; +1063;MYANMAR TONE MARK SGAW KAREN HATHI;Mc;0;L;;;;;N;;;;; +1064;MYANMAR TONE MARK SGAW KAREN KE PHO;Mc;0;L;;;;;N;;;;; +1065;MYANMAR LETTER WESTERN PWO KAREN THA;Lo;0;L;;;;;N;;;;; +1066;MYANMAR LETTER WESTERN PWO KAREN PWA;Lo;0;L;;;;;N;;;;; +1067;MYANMAR VOWEL SIGN WESTERN PWO KAREN EU;Mc;0;L;;;;;N;;;;; +1068;MYANMAR VOWEL SIGN WESTERN PWO KAREN UE;Mc;0;L;;;;;N;;;;; +1069;MYANMAR SIGN WESTERN PWO KAREN TONE-1;Mc;0;L;;;;;N;;;;; +106A;MYANMAR SIGN WESTERN PWO KAREN TONE-2;Mc;0;L;;;;;N;;;;; +106B;MYANMAR SIGN WESTERN PWO KAREN TONE-3;Mc;0;L;;;;;N;;;;; +106C;MYANMAR SIGN WESTERN PWO KAREN TONE-4;Mc;0;L;;;;;N;;;;; +106D;MYANMAR SIGN WESTERN PWO KAREN TONE-5;Mc;0;L;;;;;N;;;;; +106E;MYANMAR LETTER EASTERN PWO KAREN NNA;Lo;0;L;;;;;N;;;;; +106F;MYANMAR LETTER EASTERN PWO KAREN YWA;Lo;0;L;;;;;N;;;;; +1070;MYANMAR LETTER EASTERN PWO KAREN GHWA;Lo;0;L;;;;;N;;;;; +1071;MYANMAR VOWEL SIGN GEBA KAREN I;Mn;0;NSM;;;;;N;;;;; +1072;MYANMAR VOWEL SIGN KAYAH OE;Mn;0;NSM;;;;;N;;;;; +1073;MYANMAR VOWEL SIGN KAYAH U;Mn;0;NSM;;;;;N;;;;; +1074;MYANMAR VOWEL SIGN KAYAH EE;Mn;0;NSM;;;;;N;;;;; +1075;MYANMAR LETTER SHAN KA;Lo;0;L;;;;;N;;;;; +1076;MYANMAR LETTER SHAN KHA;Lo;0;L;;;;;N;;;;; +1077;MYANMAR LETTER SHAN GA;Lo;0;L;;;;;N;;;;; +1078;MYANMAR LETTER SHAN CA;Lo;0;L;;;;;N;;;;; +1079;MYANMAR LETTER SHAN ZA;Lo;0;L;;;;;N;;;;; +107A;MYANMAR LETTER SHAN NYA;Lo;0;L;;;;;N;;;;; +107B;MYANMAR LETTER SHAN DA;Lo;0;L;;;;;N;;;;; +107C;MYANMAR LETTER SHAN NA;Lo;0;L;;;;;N;;;;; +107D;MYANMAR LETTER SHAN PHA;Lo;0;L;;;;;N;;;;; +107E;MYANMAR LETTER SHAN FA;Lo;0;L;;;;;N;;;;; +107F;MYANMAR LETTER SHAN BA;Lo;0;L;;;;;N;;;;; +1080;MYANMAR LETTER SHAN THA;Lo;0;L;;;;;N;;;;; +1081;MYANMAR LETTER SHAN HA;Lo;0;L;;;;;N;;;;; +1082;MYANMAR CONSONANT SIGN SHAN MEDIAL WA;Mn;0;NSM;;;;;N;;;;; +1083;MYANMAR VOWEL SIGN SHAN AA;Mc;0;L;;;;;N;;;;; +1084;MYANMAR VOWEL SIGN SHAN E;Mc;0;L;;;;;N;;;;; +1085;MYANMAR VOWEL SIGN SHAN E ABOVE;Mn;0;NSM;;;;;N;;;;; +1086;MYANMAR VOWEL SIGN SHAN FINAL Y;Mn;0;NSM;;;;;N;;;;; +1087;MYANMAR SIGN SHAN TONE-2;Mc;0;L;;;;;N;;;;; +1088;MYANMAR SIGN SHAN TONE-3;Mc;0;L;;;;;N;;;;; +1089;MYANMAR SIGN SHAN TONE-5;Mc;0;L;;;;;N;;;;; +108A;MYANMAR SIGN SHAN TONE-6;Mc;0;L;;;;;N;;;;; +108B;MYANMAR SIGN SHAN COUNCIL TONE-2;Mc;0;L;;;;;N;;;;; +108C;MYANMAR SIGN SHAN COUNCIL TONE-3;Mc;0;L;;;;;N;;;;; +108D;MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE;Mn;220;NSM;;;;;N;;;;; +108E;MYANMAR LETTER RUMAI PALAUNG FA;Lo;0;L;;;;;N;;;;; +108F;MYANMAR SIGN RUMAI PALAUNG TONE-5;Mc;0;L;;;;;N;;;;; +1090;MYANMAR SHAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1091;MYANMAR SHAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1092;MYANMAR SHAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1093;MYANMAR SHAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1094;MYANMAR SHAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1095;MYANMAR SHAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1096;MYANMAR SHAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1097;MYANMAR SHAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1098;MYANMAR SHAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1099;MYANMAR SHAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +109A;MYANMAR SIGN KHAMTI TONE-1;Mc;0;L;;;;;N;;;;; +109B;MYANMAR SIGN KHAMTI TONE-3;Mc;0;L;;;;;N;;;;; +109C;MYANMAR VOWEL SIGN AITON A;Mc;0;L;;;;;N;;;;; +109D;MYANMAR VOWEL SIGN AITON AI;Mn;0;NSM;;;;;N;;;;; +109E;MYANMAR SYMBOL SHAN ONE;So;0;L;;;;;N;;;;; +109F;MYANMAR SYMBOL SHAN EXCLAMATION;So;0;L;;;;;N;;;;; +10A0;GEORGIAN CAPITAL LETTER AN;Lu;0;L;;;;;N;;;;2D00; +10A1;GEORGIAN CAPITAL LETTER BAN;Lu;0;L;;;;;N;;;;2D01; +10A2;GEORGIAN CAPITAL LETTER GAN;Lu;0;L;;;;;N;;;;2D02; +10A3;GEORGIAN CAPITAL LETTER DON;Lu;0;L;;;;;N;;;;2D03; +10A4;GEORGIAN CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;2D04; +10A5;GEORGIAN CAPITAL LETTER VIN;Lu;0;L;;;;;N;;;;2D05; +10A6;GEORGIAN CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;;;2D06; +10A7;GEORGIAN CAPITAL LETTER TAN;Lu;0;L;;;;;N;;;;2D07; +10A8;GEORGIAN CAPITAL LETTER IN;Lu;0;L;;;;;N;;;;2D08; +10A9;GEORGIAN CAPITAL LETTER KAN;Lu;0;L;;;;;N;;;;2D09; +10AA;GEORGIAN CAPITAL LETTER LAS;Lu;0;L;;;;;N;;;;2D0A; +10AB;GEORGIAN CAPITAL LETTER MAN;Lu;0;L;;;;;N;;;;2D0B; +10AC;GEORGIAN CAPITAL LETTER NAR;Lu;0;L;;;;;N;;;;2D0C; +10AD;GEORGIAN CAPITAL LETTER ON;Lu;0;L;;;;;N;;;;2D0D; +10AE;GEORGIAN CAPITAL LETTER PAR;Lu;0;L;;;;;N;;;;2D0E; +10AF;GEORGIAN CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;;;2D0F; +10B0;GEORGIAN CAPITAL LETTER RAE;Lu;0;L;;;;;N;;;;2D10; +10B1;GEORGIAN CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;2D11; +10B2;GEORGIAN CAPITAL LETTER TAR;Lu;0;L;;;;;N;;;;2D12; +10B3;GEORGIAN CAPITAL LETTER UN;Lu;0;L;;;;;N;;;;2D13; +10B4;GEORGIAN CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;;;2D14; +10B5;GEORGIAN CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;;;2D15; +10B6;GEORGIAN CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;;;2D16; +10B7;GEORGIAN CAPITAL LETTER QAR;Lu;0;L;;;;;N;;;;2D17; +10B8;GEORGIAN CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;;;2D18; +10B9;GEORGIAN CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;;;2D19; +10BA;GEORGIAN CAPITAL LETTER CAN;Lu;0;L;;;;;N;;;;2D1A; +10BB;GEORGIAN CAPITAL LETTER JIL;Lu;0;L;;;;;N;;;;2D1B; +10BC;GEORGIAN CAPITAL LETTER CIL;Lu;0;L;;;;;N;;;;2D1C; +10BD;GEORGIAN CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;;;2D1D; +10BE;GEORGIAN CAPITAL LETTER XAN;Lu;0;L;;;;;N;;;;2D1E; +10BF;GEORGIAN CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;;;2D1F; +10C0;GEORGIAN CAPITAL LETTER HAE;Lu;0;L;;;;;N;;;;2D20; +10C1;GEORGIAN CAPITAL LETTER HE;Lu;0;L;;;;;N;;;;2D21; +10C2;GEORGIAN CAPITAL LETTER HIE;Lu;0;L;;;;;N;;;;2D22; +10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;2D23; +10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;2D24; +10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;;;2D25; +10D0;GEORGIAN LETTER AN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;;; +10D1;GEORGIAN LETTER BAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;;; +10D2;GEORGIAN LETTER GAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;;; +10D3;GEORGIAN LETTER DON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER DON;;;; +10D4;GEORGIAN LETTER EN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER EN;;;; +10D5;GEORGIAN LETTER VIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER VIN;;;; +10D6;GEORGIAN LETTER ZEN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZEN;;;; +10D7;GEORGIAN LETTER TAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAN;;;; +10D8;GEORGIAN LETTER IN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER IN;;;; +10D9;GEORGIAN LETTER KAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KAN;;;; +10DA;GEORGIAN LETTER LAS;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER LAS;;;; +10DB;GEORGIAN LETTER MAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER MAN;;;; +10DC;GEORGIAN LETTER NAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER NAR;;;; +10DD;GEORGIAN LETTER ON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ON;;;; +10DE;GEORGIAN LETTER PAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PAR;;;; +10DF;GEORGIAN LETTER ZHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZHAR;;;; +10E0;GEORGIAN LETTER RAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER RAE;;;; +10E1;GEORGIAN LETTER SAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SAN;;;; +10E2;GEORGIAN LETTER TAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAR;;;; +10E3;GEORGIAN LETTER UN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER UN;;;; +10E4;GEORGIAN LETTER PHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PHAR;;;; +10E5;GEORGIAN LETTER KHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KHAR;;;; +10E6;GEORGIAN LETTER GHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GHAN;;;; +10E7;GEORGIAN LETTER QAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER QAR;;;; +10E8;GEORGIAN LETTER SHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SHIN;;;; +10E9;GEORGIAN LETTER CHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHIN;;;; +10EA;GEORGIAN LETTER CAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CAN;;;; +10EB;GEORGIAN LETTER JIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JIL;;;; +10EC;GEORGIAN LETTER CIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CIL;;;; +10ED;GEORGIAN LETTER CHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHAR;;;; +10EE;GEORGIAN LETTER XAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER XAN;;;; +10EF;GEORGIAN LETTER JHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JHAN;;;; +10F0;GEORGIAN LETTER HAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAE;;;; +10F1;GEORGIAN LETTER HE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HE;;;; +10F2;GEORGIAN LETTER HIE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HIE;;;; +10F3;GEORGIAN LETTER WE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER WE;;;; +10F4;GEORGIAN LETTER HAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAR;;;; +10F5;GEORGIAN LETTER HOE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HOE;;;; +10F6;GEORGIAN LETTER FI;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER FI;;;; +10F7;GEORGIAN LETTER YN;Lo;0;L;;;;;N;;;;; +10F8;GEORGIAN LETTER ELIFI;Lo;0;L;;;;;N;;;;; +10F9;GEORGIAN LETTER TURNED GAN;Lo;0;L;;;;;N;;;;; +10FA;GEORGIAN LETTER AIN;Lo;0;L;;;;;N;;;;; +10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;; +10FC;MODIFIER LETTER GEORGIAN NAR;Lm;0;L; 10DC;;;;N;;;;; +1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;;;; +1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;;;; +1103;HANGUL CHOSEONG TIKEUT;Lo;0;L;;;;;N;;;;; +1104;HANGUL CHOSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;;;; +1105;HANGUL CHOSEONG RIEUL;Lo;0;L;;;;;N;;;;; +1106;HANGUL CHOSEONG MIEUM;Lo;0;L;;;;;N;;;;; +1107;HANGUL CHOSEONG PIEUP;Lo;0;L;;;;;N;;;;; +1108;HANGUL CHOSEONG SSANGPIEUP;Lo;0;L;;;;;N;;;;; +1109;HANGUL CHOSEONG SIOS;Lo;0;L;;;;;N;;;;; +110A;HANGUL CHOSEONG SSANGSIOS;Lo;0;L;;;;;N;;;;; +110B;HANGUL CHOSEONG IEUNG;Lo;0;L;;;;;N;;;;; +110C;HANGUL CHOSEONG CIEUC;Lo;0;L;;;;;N;;;;; +110D;HANGUL CHOSEONG SSANGCIEUC;Lo;0;L;;;;;N;;;;; +110E;HANGUL CHOSEONG CHIEUCH;Lo;0;L;;;;;N;;;;; +110F;HANGUL CHOSEONG KHIEUKH;Lo;0;L;;;;;N;;;;; +1110;HANGUL CHOSEONG THIEUTH;Lo;0;L;;;;;N;;;;; +1111;HANGUL CHOSEONG PHIEUPH;Lo;0;L;;;;;N;;;;; +1112;HANGUL CHOSEONG HIEUH;Lo;0;L;;;;;N;;;;; +1113;HANGUL CHOSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;; +1114;HANGUL CHOSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;; +1115;HANGUL CHOSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;; +1116;HANGUL CHOSEONG NIEUN-PIEUP;Lo;0;L;;;;;N;;;;; +1117;HANGUL CHOSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;; +1118;HANGUL CHOSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;; +1119;HANGUL CHOSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;; +111A;HANGUL CHOSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;; +111B;HANGUL CHOSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;; +111C;HANGUL CHOSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;; +111D;HANGUL CHOSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;; +111E;HANGUL CHOSEONG PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;; +111F;HANGUL CHOSEONG PIEUP-NIEUN;Lo;0;L;;;;;N;;;;; +1120;HANGUL CHOSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;; +1121;HANGUL CHOSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +1122;HANGUL CHOSEONG PIEUP-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +1123;HANGUL CHOSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +1124;HANGUL CHOSEONG PIEUP-SIOS-PIEUP;Lo;0;L;;;;;N;;;;; +1125;HANGUL CHOSEONG PIEUP-SSANGSIOS;Lo;0;L;;;;;N;;;;; +1126;HANGUL CHOSEONG PIEUP-SIOS-CIEUC;Lo;0;L;;;;;N;;;;; +1127;HANGUL CHOSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;; +1128;HANGUL CHOSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;; +1129;HANGUL CHOSEONG PIEUP-THIEUTH;Lo;0;L;;;;;N;;;;; +112A;HANGUL CHOSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; +112B;HANGUL CHOSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +112C;HANGUL CHOSEONG KAPYEOUNSSANGPIEUP;Lo;0;L;;;;;N;;;;; +112D;HANGUL CHOSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +112E;HANGUL CHOSEONG SIOS-NIEUN;Lo;0;L;;;;;N;;;;; +112F;HANGUL CHOSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +1130;HANGUL CHOSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;; +1131;HANGUL CHOSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;; +1132;HANGUL CHOSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;; +1133;HANGUL CHOSEONG SIOS-PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;; +1134;HANGUL CHOSEONG SIOS-SSANGSIOS;Lo;0;L;;;;;N;;;;; +1135;HANGUL CHOSEONG SIOS-IEUNG;Lo;0;L;;;;;N;;;;; +1136;HANGUL CHOSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;; +1137;HANGUL CHOSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;; +1138;HANGUL CHOSEONG SIOS-KHIEUKH;Lo;0;L;;;;;N;;;;; +1139;HANGUL CHOSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;; +113A;HANGUL CHOSEONG SIOS-PHIEUPH;Lo;0;L;;;;;N;;;;; +113B;HANGUL CHOSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;; +113C;HANGUL CHOSEONG CHITUEUMSIOS;Lo;0;L;;;;;N;;;;; +113D;HANGUL CHOSEONG CHITUEUMSSANGSIOS;Lo;0;L;;;;;N;;;;; +113E;HANGUL CHOSEONG CEONGCHIEUMSIOS;Lo;0;L;;;;;N;;;;; +113F;HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS;Lo;0;L;;;;;N;;;;; +1140;HANGUL CHOSEONG PANSIOS;Lo;0;L;;;;;N;;;;; +1141;HANGUL CHOSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;; +1142;HANGUL CHOSEONG IEUNG-TIKEUT;Lo;0;L;;;;;N;;;;; +1143;HANGUL CHOSEONG IEUNG-MIEUM;Lo;0;L;;;;;N;;;;; +1144;HANGUL CHOSEONG IEUNG-PIEUP;Lo;0;L;;;;;N;;;;; +1145;HANGUL CHOSEONG IEUNG-SIOS;Lo;0;L;;;;;N;;;;; +1146;HANGUL CHOSEONG IEUNG-PANSIOS;Lo;0;L;;;;;N;;;;; +1147;HANGUL CHOSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;; +1148;HANGUL CHOSEONG IEUNG-CIEUC;Lo;0;L;;;;;N;;;;; +1149;HANGUL CHOSEONG IEUNG-CHIEUCH;Lo;0;L;;;;;N;;;;; +114A;HANGUL CHOSEONG IEUNG-THIEUTH;Lo;0;L;;;;;N;;;;; +114B;HANGUL CHOSEONG IEUNG-PHIEUPH;Lo;0;L;;;;;N;;;;; +114C;HANGUL CHOSEONG YESIEUNG;Lo;0;L;;;;;N;;;;; +114D;HANGUL CHOSEONG CIEUC-IEUNG;Lo;0;L;;;;;N;;;;; +114E;HANGUL CHOSEONG CHITUEUMCIEUC;Lo;0;L;;;;;N;;;;; +114F;HANGUL CHOSEONG CHITUEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;; +1150;HANGUL CHOSEONG CEONGCHIEUMCIEUC;Lo;0;L;;;;;N;;;;; +1151;HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;; +1152;HANGUL CHOSEONG CHIEUCH-KHIEUKH;Lo;0;L;;;;;N;;;;; +1153;HANGUL CHOSEONG CHIEUCH-HIEUH;Lo;0;L;;;;;N;;;;; +1154;HANGUL CHOSEONG CHITUEUMCHIEUCH;Lo;0;L;;;;;N;;;;; +1155;HANGUL CHOSEONG CEONGCHIEUMCHIEUCH;Lo;0;L;;;;;N;;;;; +1156;HANGUL CHOSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;; +1157;HANGUL CHOSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;; +1158;HANGUL CHOSEONG SSANGHIEUH;Lo;0;L;;;;;N;;;;; +1159;HANGUL CHOSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;; +115A;HANGUL CHOSEONG KIYEOK-TIKEUT;Lo;0;L;;;;;N;;;;; +115B;HANGUL CHOSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;; +115C;HANGUL CHOSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;;;; +115D;HANGUL CHOSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;;;; +115E;HANGUL CHOSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;; +115F;HANGUL CHOSEONG FILLER;Lo;0;L;;;;;N;;;;; +1160;HANGUL JUNGSEONG FILLER;Lo;0;L;;;;;N;;;;; +1161;HANGUL JUNGSEONG A;Lo;0;L;;;;;N;;;;; +1162;HANGUL JUNGSEONG AE;Lo;0;L;;;;;N;;;;; +1163;HANGUL JUNGSEONG YA;Lo;0;L;;;;;N;;;;; +1164;HANGUL JUNGSEONG YAE;Lo;0;L;;;;;N;;;;; +1165;HANGUL JUNGSEONG EO;Lo;0;L;;;;;N;;;;; +1166;HANGUL JUNGSEONG E;Lo;0;L;;;;;N;;;;; +1167;HANGUL JUNGSEONG YEO;Lo;0;L;;;;;N;;;;; +1168;HANGUL JUNGSEONG YE;Lo;0;L;;;;;N;;;;; +1169;HANGUL JUNGSEONG O;Lo;0;L;;;;;N;;;;; +116A;HANGUL JUNGSEONG WA;Lo;0;L;;;;;N;;;;; +116B;HANGUL JUNGSEONG WAE;Lo;0;L;;;;;N;;;;; +116C;HANGUL JUNGSEONG OE;Lo;0;L;;;;;N;;;;; +116D;HANGUL JUNGSEONG YO;Lo;0;L;;;;;N;;;;; +116E;HANGUL JUNGSEONG U;Lo;0;L;;;;;N;;;;; +116F;HANGUL JUNGSEONG WEO;Lo;0;L;;;;;N;;;;; +1170;HANGUL JUNGSEONG WE;Lo;0;L;;;;;N;;;;; +1171;HANGUL JUNGSEONG WI;Lo;0;L;;;;;N;;;;; +1172;HANGUL JUNGSEONG YU;Lo;0;L;;;;;N;;;;; +1173;HANGUL JUNGSEONG EU;Lo;0;L;;;;;N;;;;; +1174;HANGUL JUNGSEONG YI;Lo;0;L;;;;;N;;;;; +1175;HANGUL JUNGSEONG I;Lo;0;L;;;;;N;;;;; +1176;HANGUL JUNGSEONG A-O;Lo;0;L;;;;;N;;;;; +1177;HANGUL JUNGSEONG A-U;Lo;0;L;;;;;N;;;;; +1178;HANGUL JUNGSEONG YA-O;Lo;0;L;;;;;N;;;;; +1179;HANGUL JUNGSEONG YA-YO;Lo;0;L;;;;;N;;;;; +117A;HANGUL JUNGSEONG EO-O;Lo;0;L;;;;;N;;;;; +117B;HANGUL JUNGSEONG EO-U;Lo;0;L;;;;;N;;;;; +117C;HANGUL JUNGSEONG EO-EU;Lo;0;L;;;;;N;;;;; +117D;HANGUL JUNGSEONG YEO-O;Lo;0;L;;;;;N;;;;; +117E;HANGUL JUNGSEONG YEO-U;Lo;0;L;;;;;N;;;;; +117F;HANGUL JUNGSEONG O-EO;Lo;0;L;;;;;N;;;;; +1180;HANGUL JUNGSEONG O-E;Lo;0;L;;;;;N;;;;; +1181;HANGUL JUNGSEONG O-YE;Lo;0;L;;;;;N;;;;; +1182;HANGUL JUNGSEONG O-O;Lo;0;L;;;;;N;;;;; +1183;HANGUL JUNGSEONG O-U;Lo;0;L;;;;;N;;;;; +1184;HANGUL JUNGSEONG YO-YA;Lo;0;L;;;;;N;;;;; +1185;HANGUL JUNGSEONG YO-YAE;Lo;0;L;;;;;N;;;;; +1186;HANGUL JUNGSEONG YO-YEO;Lo;0;L;;;;;N;;;;; +1187;HANGUL JUNGSEONG YO-O;Lo;0;L;;;;;N;;;;; +1188;HANGUL JUNGSEONG YO-I;Lo;0;L;;;;;N;;;;; +1189;HANGUL JUNGSEONG U-A;Lo;0;L;;;;;N;;;;; +118A;HANGUL JUNGSEONG U-AE;Lo;0;L;;;;;N;;;;; +118B;HANGUL JUNGSEONG U-EO-EU;Lo;0;L;;;;;N;;;;; +118C;HANGUL JUNGSEONG U-YE;Lo;0;L;;;;;N;;;;; +118D;HANGUL JUNGSEONG U-U;Lo;0;L;;;;;N;;;;; +118E;HANGUL JUNGSEONG YU-A;Lo;0;L;;;;;N;;;;; +118F;HANGUL JUNGSEONG YU-EO;Lo;0;L;;;;;N;;;;; +1190;HANGUL JUNGSEONG YU-E;Lo;0;L;;;;;N;;;;; +1191;HANGUL JUNGSEONG YU-YEO;Lo;0;L;;;;;N;;;;; +1192;HANGUL JUNGSEONG YU-YE;Lo;0;L;;;;;N;;;;; +1193;HANGUL JUNGSEONG YU-U;Lo;0;L;;;;;N;;;;; +1194;HANGUL JUNGSEONG YU-I;Lo;0;L;;;;;N;;;;; +1195;HANGUL JUNGSEONG EU-U;Lo;0;L;;;;;N;;;;; +1196;HANGUL JUNGSEONG EU-EU;Lo;0;L;;;;;N;;;;; +1197;HANGUL JUNGSEONG YI-U;Lo;0;L;;;;;N;;;;; +1198;HANGUL JUNGSEONG I-A;Lo;0;L;;;;;N;;;;; +1199;HANGUL JUNGSEONG I-YA;Lo;0;L;;;;;N;;;;; +119A;HANGUL JUNGSEONG I-O;Lo;0;L;;;;;N;;;;; +119B;HANGUL JUNGSEONG I-U;Lo;0;L;;;;;N;;;;; +119C;HANGUL JUNGSEONG I-EU;Lo;0;L;;;;;N;;;;; +119D;HANGUL JUNGSEONG I-ARAEA;Lo;0;L;;;;;N;;;;; +119E;HANGUL JUNGSEONG ARAEA;Lo;0;L;;;;;N;;;;; +119F;HANGUL JUNGSEONG ARAEA-EO;Lo;0;L;;;;;N;;;;; +11A0;HANGUL JUNGSEONG ARAEA-U;Lo;0;L;;;;;N;;;;; +11A1;HANGUL JUNGSEONG ARAEA-I;Lo;0;L;;;;;N;;;;; +11A2;HANGUL JUNGSEONG SSANGARAEA;Lo;0;L;;;;;N;;;;; +11A3;HANGUL JUNGSEONG A-EU;Lo;0;L;;;;;N;;;;; +11A4;HANGUL JUNGSEONG YA-U;Lo;0;L;;;;;N;;;;; +11A5;HANGUL JUNGSEONG YEO-YA;Lo;0;L;;;;;N;;;;; +11A6;HANGUL JUNGSEONG O-YA;Lo;0;L;;;;;N;;;;; +11A7;HANGUL JUNGSEONG O-YAE;Lo;0;L;;;;;N;;;;; +11A8;HANGUL JONGSEONG KIYEOK;Lo;0;L;;;;;N;;;;; +11A9;HANGUL JONGSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +11AA;HANGUL JONGSEONG KIYEOK-SIOS;Lo;0;L;;;;;N;;;;; +11AB;HANGUL JONGSEONG NIEUN;Lo;0;L;;;;;N;;;;; +11AC;HANGUL JONGSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;;;; +11AD;HANGUL JONGSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;;;; +11AE;HANGUL JONGSEONG TIKEUT;Lo;0;L;;;;;N;;;;; +11AF;HANGUL JONGSEONG RIEUL;Lo;0;L;;;;;N;;;;; +11B0;HANGUL JONGSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;;;; +11B1;HANGUL JONGSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;;;; +11B2;HANGUL JONGSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;;;; +11B3;HANGUL JONGSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;;;; +11B4;HANGUL JONGSEONG RIEUL-THIEUTH;Lo;0;L;;;;;N;;;;; +11B5;HANGUL JONGSEONG RIEUL-PHIEUPH;Lo;0;L;;;;;N;;;;; +11B6;HANGUL JONGSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;; +11B7;HANGUL JONGSEONG MIEUM;Lo;0;L;;;;;N;;;;; +11B8;HANGUL JONGSEONG PIEUP;Lo;0;L;;;;;N;;;;; +11B9;HANGUL JONGSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +11BA;HANGUL JONGSEONG SIOS;Lo;0;L;;;;;N;;;;; +11BB;HANGUL JONGSEONG SSANGSIOS;Lo;0;L;;;;;N;;;;; +11BC;HANGUL JONGSEONG IEUNG;Lo;0;L;;;;;N;;;;; +11BD;HANGUL JONGSEONG CIEUC;Lo;0;L;;;;;N;;;;; +11BE;HANGUL JONGSEONG CHIEUCH;Lo;0;L;;;;;N;;;;; +11BF;HANGUL JONGSEONG KHIEUKH;Lo;0;L;;;;;N;;;;; +11C0;HANGUL JONGSEONG THIEUTH;Lo;0;L;;;;;N;;;;; +11C1;HANGUL JONGSEONG PHIEUPH;Lo;0;L;;;;;N;;;;; +11C2;HANGUL JONGSEONG HIEUH;Lo;0;L;;;;;N;;;;; +11C3;HANGUL JONGSEONG KIYEOK-RIEUL;Lo;0;L;;;;;N;;;;; +11C4;HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +11C5;HANGUL JONGSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;; +11C6;HANGUL JONGSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;; +11C7;HANGUL JONGSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;; +11C8;HANGUL JONGSEONG NIEUN-PANSIOS;Lo;0;L;;;;;N;;;;; +11C9;HANGUL JONGSEONG NIEUN-THIEUTH;Lo;0;L;;;;;N;;;;; +11CA;HANGUL JONGSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;; +11CB;HANGUL JONGSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;; +11CC;HANGUL JONGSEONG RIEUL-KIYEOK-SIOS;Lo;0;L;;;;;N;;;;; +11CD;HANGUL JONGSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;; +11CE;HANGUL JONGSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;; +11CF;HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH;Lo;0;L;;;;;N;;;;; +11D0;HANGUL JONGSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;; +11D1;HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; +11D2;HANGUL JONGSEONG RIEUL-MIEUM-SIOS;Lo;0;L;;;;;N;;;;; +11D3;HANGUL JONGSEONG RIEUL-PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +11D4;HANGUL JONGSEONG RIEUL-PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; +11D5;HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +11D6;HANGUL JONGSEONG RIEUL-SSANGSIOS;Lo;0;L;;;;;N;;;;; +11D7;HANGUL JONGSEONG RIEUL-PANSIOS;Lo;0;L;;;;;N;;;;; +11D8;HANGUL JONGSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;; +11D9;HANGUL JONGSEONG RIEUL-YEORINHIEUH;Lo;0;L;;;;;N;;;;; +11DA;HANGUL JONGSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; +11DB;HANGUL JONGSEONG MIEUM-RIEUL;Lo;0;L;;;;;N;;;;; +11DC;HANGUL JONGSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;; +11DD;HANGUL JONGSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;; +11DE;HANGUL JONGSEONG MIEUM-SSANGSIOS;Lo;0;L;;;;;N;;;;; +11DF;HANGUL JONGSEONG MIEUM-PANSIOS;Lo;0;L;;;;;N;;;;; +11E0;HANGUL JONGSEONG MIEUM-CHIEUCH;Lo;0;L;;;;;N;;;;; +11E1;HANGUL JONGSEONG MIEUM-HIEUH;Lo;0;L;;;;;N;;;;; +11E2;HANGUL JONGSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;; +11E3;HANGUL JONGSEONG PIEUP-RIEUL;Lo;0;L;;;;;N;;;;; +11E4;HANGUL JONGSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; +11E5;HANGUL JONGSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; +11E6;HANGUL JONGSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +11E7;HANGUL JONGSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +11E8;HANGUL JONGSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +11E9;HANGUL JONGSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;; +11EA;HANGUL JONGSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;; +11EB;HANGUL JONGSEONG PANSIOS;Lo;0;L;;;;;N;;;;; +11EC;HANGUL JONGSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;; +11ED;HANGUL JONGSEONG IEUNG-SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +11EE;HANGUL JONGSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;; +11EF;HANGUL JONGSEONG IEUNG-KHIEUKH;Lo;0;L;;;;;N;;;;; +11F0;HANGUL JONGSEONG YESIEUNG;Lo;0;L;;;;;N;;;;; +11F1;HANGUL JONGSEONG YESIEUNG-SIOS;Lo;0;L;;;;;N;;;;; +11F2;HANGUL JONGSEONG YESIEUNG-PANSIOS;Lo;0;L;;;;;N;;;;; +11F3;HANGUL JONGSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;; +11F4;HANGUL JONGSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;; +11F5;HANGUL JONGSEONG HIEUH-NIEUN;Lo;0;L;;;;;N;;;;; +11F6;HANGUL JONGSEONG HIEUH-RIEUL;Lo;0;L;;;;;N;;;;; +11F7;HANGUL JONGSEONG HIEUH-MIEUM;Lo;0;L;;;;;N;;;;; +11F8;HANGUL JONGSEONG HIEUH-PIEUP;Lo;0;L;;;;;N;;;;; +11F9;HANGUL JONGSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;; +11FA;HANGUL JONGSEONG KIYEOK-NIEUN;Lo;0;L;;;;;N;;;;; +11FB;HANGUL JONGSEONG KIYEOK-PIEUP;Lo;0;L;;;;;N;;;;; +11FC;HANGUL JONGSEONG KIYEOK-CHIEUCH;Lo;0;L;;;;;N;;;;; +11FD;HANGUL JONGSEONG KIYEOK-KHIEUKH;Lo;0;L;;;;;N;;;;; +11FE;HANGUL JONGSEONG KIYEOK-HIEUH;Lo;0;L;;;;;N;;;;; +11FF;HANGUL JONGSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;; +1200;ETHIOPIC SYLLABLE HA;Lo;0;L;;;;;N;;;;; +1201;ETHIOPIC SYLLABLE HU;Lo;0;L;;;;;N;;;;; +1202;ETHIOPIC SYLLABLE HI;Lo;0;L;;;;;N;;;;; +1203;ETHIOPIC SYLLABLE HAA;Lo;0;L;;;;;N;;;;; +1204;ETHIOPIC SYLLABLE HEE;Lo;0;L;;;;;N;;;;; +1205;ETHIOPIC SYLLABLE HE;Lo;0;L;;;;;N;;;;; +1206;ETHIOPIC SYLLABLE HO;Lo;0;L;;;;;N;;;;; +1207;ETHIOPIC SYLLABLE HOA;Lo;0;L;;;;;N;;;;; +1208;ETHIOPIC SYLLABLE LA;Lo;0;L;;;;;N;;;;; +1209;ETHIOPIC SYLLABLE LU;Lo;0;L;;;;;N;;;;; +120A;ETHIOPIC SYLLABLE LI;Lo;0;L;;;;;N;;;;; +120B;ETHIOPIC SYLLABLE LAA;Lo;0;L;;;;;N;;;;; +120C;ETHIOPIC SYLLABLE LEE;Lo;0;L;;;;;N;;;;; +120D;ETHIOPIC SYLLABLE LE;Lo;0;L;;;;;N;;;;; +120E;ETHIOPIC SYLLABLE LO;Lo;0;L;;;;;N;;;;; +120F;ETHIOPIC SYLLABLE LWA;Lo;0;L;;;;;N;;;;; +1210;ETHIOPIC SYLLABLE HHA;Lo;0;L;;;;;N;;;;; +1211;ETHIOPIC SYLLABLE HHU;Lo;0;L;;;;;N;;;;; +1212;ETHIOPIC SYLLABLE HHI;Lo;0;L;;;;;N;;;;; +1213;ETHIOPIC SYLLABLE HHAA;Lo;0;L;;;;;N;;;;; +1214;ETHIOPIC SYLLABLE HHEE;Lo;0;L;;;;;N;;;;; +1215;ETHIOPIC SYLLABLE HHE;Lo;0;L;;;;;N;;;;; +1216;ETHIOPIC SYLLABLE HHO;Lo;0;L;;;;;N;;;;; +1217;ETHIOPIC SYLLABLE HHWA;Lo;0;L;;;;;N;;;;; +1218;ETHIOPIC SYLLABLE MA;Lo;0;L;;;;;N;;;;; +1219;ETHIOPIC SYLLABLE MU;Lo;0;L;;;;;N;;;;; +121A;ETHIOPIC SYLLABLE MI;Lo;0;L;;;;;N;;;;; +121B;ETHIOPIC SYLLABLE MAA;Lo;0;L;;;;;N;;;;; +121C;ETHIOPIC SYLLABLE MEE;Lo;0;L;;;;;N;;;;; +121D;ETHIOPIC SYLLABLE ME;Lo;0;L;;;;;N;;;;; +121E;ETHIOPIC SYLLABLE MO;Lo;0;L;;;;;N;;;;; +121F;ETHIOPIC SYLLABLE MWA;Lo;0;L;;;;;N;;;;; +1220;ETHIOPIC SYLLABLE SZA;Lo;0;L;;;;;N;;;;; +1221;ETHIOPIC SYLLABLE SZU;Lo;0;L;;;;;N;;;;; +1222;ETHIOPIC SYLLABLE SZI;Lo;0;L;;;;;N;;;;; +1223;ETHIOPIC SYLLABLE SZAA;Lo;0;L;;;;;N;;;;; +1224;ETHIOPIC SYLLABLE SZEE;Lo;0;L;;;;;N;;;;; +1225;ETHIOPIC SYLLABLE SZE;Lo;0;L;;;;;N;;;;; +1226;ETHIOPIC SYLLABLE SZO;Lo;0;L;;;;;N;;;;; +1227;ETHIOPIC SYLLABLE SZWA;Lo;0;L;;;;;N;;;;; +1228;ETHIOPIC SYLLABLE RA;Lo;0;L;;;;;N;;;;; +1229;ETHIOPIC SYLLABLE RU;Lo;0;L;;;;;N;;;;; +122A;ETHIOPIC SYLLABLE RI;Lo;0;L;;;;;N;;;;; +122B;ETHIOPIC SYLLABLE RAA;Lo;0;L;;;;;N;;;;; +122C;ETHIOPIC SYLLABLE REE;Lo;0;L;;;;;N;;;;; +122D;ETHIOPIC SYLLABLE RE;Lo;0;L;;;;;N;;;;; +122E;ETHIOPIC SYLLABLE RO;Lo;0;L;;;;;N;;;;; +122F;ETHIOPIC SYLLABLE RWA;Lo;0;L;;;;;N;;;;; +1230;ETHIOPIC SYLLABLE SA;Lo;0;L;;;;;N;;;;; +1231;ETHIOPIC SYLLABLE SU;Lo;0;L;;;;;N;;;;; +1232;ETHIOPIC SYLLABLE SI;Lo;0;L;;;;;N;;;;; +1233;ETHIOPIC SYLLABLE SAA;Lo;0;L;;;;;N;;;;; +1234;ETHIOPIC SYLLABLE SEE;Lo;0;L;;;;;N;;;;; +1235;ETHIOPIC SYLLABLE SE;Lo;0;L;;;;;N;;;;; +1236;ETHIOPIC SYLLABLE SO;Lo;0;L;;;;;N;;;;; +1237;ETHIOPIC SYLLABLE SWA;Lo;0;L;;;;;N;;;;; +1238;ETHIOPIC SYLLABLE SHA;Lo;0;L;;;;;N;;;;; +1239;ETHIOPIC SYLLABLE SHU;Lo;0;L;;;;;N;;;;; +123A;ETHIOPIC SYLLABLE SHI;Lo;0;L;;;;;N;;;;; +123B;ETHIOPIC SYLLABLE SHAA;Lo;0;L;;;;;N;;;;; +123C;ETHIOPIC SYLLABLE SHEE;Lo;0;L;;;;;N;;;;; +123D;ETHIOPIC SYLLABLE SHE;Lo;0;L;;;;;N;;;;; +123E;ETHIOPIC SYLLABLE SHO;Lo;0;L;;;;;N;;;;; +123F;ETHIOPIC SYLLABLE SHWA;Lo;0;L;;;;;N;;;;; +1240;ETHIOPIC SYLLABLE QA;Lo;0;L;;;;;N;;;;; +1241;ETHIOPIC SYLLABLE QU;Lo;0;L;;;;;N;;;;; +1242;ETHIOPIC SYLLABLE QI;Lo;0;L;;;;;N;;;;; +1243;ETHIOPIC SYLLABLE QAA;Lo;0;L;;;;;N;;;;; +1244;ETHIOPIC SYLLABLE QEE;Lo;0;L;;;;;N;;;;; +1245;ETHIOPIC SYLLABLE QE;Lo;0;L;;;;;N;;;;; +1246;ETHIOPIC SYLLABLE QO;Lo;0;L;;;;;N;;;;; +1247;ETHIOPIC SYLLABLE QOA;Lo;0;L;;;;;N;;;;; +1248;ETHIOPIC SYLLABLE QWA;Lo;0;L;;;;;N;;;;; +124A;ETHIOPIC SYLLABLE QWI;Lo;0;L;;;;;N;;;;; +124B;ETHIOPIC SYLLABLE QWAA;Lo;0;L;;;;;N;;;;; +124C;ETHIOPIC SYLLABLE QWEE;Lo;0;L;;;;;N;;;;; +124D;ETHIOPIC SYLLABLE QWE;Lo;0;L;;;;;N;;;;; +1250;ETHIOPIC SYLLABLE QHA;Lo;0;L;;;;;N;;;;; +1251;ETHIOPIC SYLLABLE QHU;Lo;0;L;;;;;N;;;;; +1252;ETHIOPIC SYLLABLE QHI;Lo;0;L;;;;;N;;;;; +1253;ETHIOPIC SYLLABLE QHAA;Lo;0;L;;;;;N;;;;; +1254;ETHIOPIC SYLLABLE QHEE;Lo;0;L;;;;;N;;;;; +1255;ETHIOPIC SYLLABLE QHE;Lo;0;L;;;;;N;;;;; +1256;ETHIOPIC SYLLABLE QHO;Lo;0;L;;;;;N;;;;; +1258;ETHIOPIC SYLLABLE QHWA;Lo;0;L;;;;;N;;;;; +125A;ETHIOPIC SYLLABLE QHWI;Lo;0;L;;;;;N;;;;; +125B;ETHIOPIC SYLLABLE QHWAA;Lo;0;L;;;;;N;;;;; +125C;ETHIOPIC SYLLABLE QHWEE;Lo;0;L;;;;;N;;;;; +125D;ETHIOPIC SYLLABLE QHWE;Lo;0;L;;;;;N;;;;; +1260;ETHIOPIC SYLLABLE BA;Lo;0;L;;;;;N;;;;; +1261;ETHIOPIC SYLLABLE BU;Lo;0;L;;;;;N;;;;; +1262;ETHIOPIC SYLLABLE BI;Lo;0;L;;;;;N;;;;; +1263;ETHIOPIC SYLLABLE BAA;Lo;0;L;;;;;N;;;;; +1264;ETHIOPIC SYLLABLE BEE;Lo;0;L;;;;;N;;;;; +1265;ETHIOPIC SYLLABLE BE;Lo;0;L;;;;;N;;;;; +1266;ETHIOPIC SYLLABLE BO;Lo;0;L;;;;;N;;;;; +1267;ETHIOPIC SYLLABLE BWA;Lo;0;L;;;;;N;;;;; +1268;ETHIOPIC SYLLABLE VA;Lo;0;L;;;;;N;;;;; +1269;ETHIOPIC SYLLABLE VU;Lo;0;L;;;;;N;;;;; +126A;ETHIOPIC SYLLABLE VI;Lo;0;L;;;;;N;;;;; +126B;ETHIOPIC SYLLABLE VAA;Lo;0;L;;;;;N;;;;; +126C;ETHIOPIC SYLLABLE VEE;Lo;0;L;;;;;N;;;;; +126D;ETHIOPIC SYLLABLE VE;Lo;0;L;;;;;N;;;;; +126E;ETHIOPIC SYLLABLE VO;Lo;0;L;;;;;N;;;;; +126F;ETHIOPIC SYLLABLE VWA;Lo;0;L;;;;;N;;;;; +1270;ETHIOPIC SYLLABLE TA;Lo;0;L;;;;;N;;;;; +1271;ETHIOPIC SYLLABLE TU;Lo;0;L;;;;;N;;;;; +1272;ETHIOPIC SYLLABLE TI;Lo;0;L;;;;;N;;;;; +1273;ETHIOPIC SYLLABLE TAA;Lo;0;L;;;;;N;;;;; +1274;ETHIOPIC SYLLABLE TEE;Lo;0;L;;;;;N;;;;; +1275;ETHIOPIC SYLLABLE TE;Lo;0;L;;;;;N;;;;; +1276;ETHIOPIC SYLLABLE TO;Lo;0;L;;;;;N;;;;; +1277;ETHIOPIC SYLLABLE TWA;Lo;0;L;;;;;N;;;;; +1278;ETHIOPIC SYLLABLE CA;Lo;0;L;;;;;N;;;;; +1279;ETHIOPIC SYLLABLE CU;Lo;0;L;;;;;N;;;;; +127A;ETHIOPIC SYLLABLE CI;Lo;0;L;;;;;N;;;;; +127B;ETHIOPIC SYLLABLE CAA;Lo;0;L;;;;;N;;;;; +127C;ETHIOPIC SYLLABLE CEE;Lo;0;L;;;;;N;;;;; +127D;ETHIOPIC SYLLABLE CE;Lo;0;L;;;;;N;;;;; +127E;ETHIOPIC SYLLABLE CO;Lo;0;L;;;;;N;;;;; +127F;ETHIOPIC SYLLABLE CWA;Lo;0;L;;;;;N;;;;; +1280;ETHIOPIC SYLLABLE XA;Lo;0;L;;;;;N;;;;; +1281;ETHIOPIC SYLLABLE XU;Lo;0;L;;;;;N;;;;; +1282;ETHIOPIC SYLLABLE XI;Lo;0;L;;;;;N;;;;; +1283;ETHIOPIC SYLLABLE XAA;Lo;0;L;;;;;N;;;;; +1284;ETHIOPIC SYLLABLE XEE;Lo;0;L;;;;;N;;;;; +1285;ETHIOPIC SYLLABLE XE;Lo;0;L;;;;;N;;;;; +1286;ETHIOPIC SYLLABLE XO;Lo;0;L;;;;;N;;;;; +1287;ETHIOPIC SYLLABLE XOA;Lo;0;L;;;;;N;;;;; +1288;ETHIOPIC SYLLABLE XWA;Lo;0;L;;;;;N;;;;; +128A;ETHIOPIC SYLLABLE XWI;Lo;0;L;;;;;N;;;;; +128B;ETHIOPIC SYLLABLE XWAA;Lo;0;L;;;;;N;;;;; +128C;ETHIOPIC SYLLABLE XWEE;Lo;0;L;;;;;N;;;;; +128D;ETHIOPIC SYLLABLE XWE;Lo;0;L;;;;;N;;;;; +1290;ETHIOPIC SYLLABLE NA;Lo;0;L;;;;;N;;;;; +1291;ETHIOPIC SYLLABLE NU;Lo;0;L;;;;;N;;;;; +1292;ETHIOPIC SYLLABLE NI;Lo;0;L;;;;;N;;;;; +1293;ETHIOPIC SYLLABLE NAA;Lo;0;L;;;;;N;;;;; +1294;ETHIOPIC SYLLABLE NEE;Lo;0;L;;;;;N;;;;; +1295;ETHIOPIC SYLLABLE NE;Lo;0;L;;;;;N;;;;; +1296;ETHIOPIC SYLLABLE NO;Lo;0;L;;;;;N;;;;; +1297;ETHIOPIC SYLLABLE NWA;Lo;0;L;;;;;N;;;;; +1298;ETHIOPIC SYLLABLE NYA;Lo;0;L;;;;;N;;;;; +1299;ETHIOPIC SYLLABLE NYU;Lo;0;L;;;;;N;;;;; +129A;ETHIOPIC SYLLABLE NYI;Lo;0;L;;;;;N;;;;; +129B;ETHIOPIC SYLLABLE NYAA;Lo;0;L;;;;;N;;;;; +129C;ETHIOPIC SYLLABLE NYEE;Lo;0;L;;;;;N;;;;; +129D;ETHIOPIC SYLLABLE NYE;Lo;0;L;;;;;N;;;;; +129E;ETHIOPIC SYLLABLE NYO;Lo;0;L;;;;;N;;;;; +129F;ETHIOPIC SYLLABLE NYWA;Lo;0;L;;;;;N;;;;; +12A0;ETHIOPIC SYLLABLE GLOTTAL A;Lo;0;L;;;;;N;;;;; +12A1;ETHIOPIC SYLLABLE GLOTTAL U;Lo;0;L;;;;;N;;;;; +12A2;ETHIOPIC SYLLABLE GLOTTAL I;Lo;0;L;;;;;N;;;;; +12A3;ETHIOPIC SYLLABLE GLOTTAL AA;Lo;0;L;;;;;N;;;;; +12A4;ETHIOPIC SYLLABLE GLOTTAL EE;Lo;0;L;;;;;N;;;;; +12A5;ETHIOPIC SYLLABLE GLOTTAL E;Lo;0;L;;;;;N;;;;; +12A6;ETHIOPIC SYLLABLE GLOTTAL O;Lo;0;L;;;;;N;;;;; +12A7;ETHIOPIC SYLLABLE GLOTTAL WA;Lo;0;L;;;;;N;;;;; +12A8;ETHIOPIC SYLLABLE KA;Lo;0;L;;;;;N;;;;; +12A9;ETHIOPIC SYLLABLE KU;Lo;0;L;;;;;N;;;;; +12AA;ETHIOPIC SYLLABLE KI;Lo;0;L;;;;;N;;;;; +12AB;ETHIOPIC SYLLABLE KAA;Lo;0;L;;;;;N;;;;; +12AC;ETHIOPIC SYLLABLE KEE;Lo;0;L;;;;;N;;;;; +12AD;ETHIOPIC SYLLABLE KE;Lo;0;L;;;;;N;;;;; +12AE;ETHIOPIC SYLLABLE KO;Lo;0;L;;;;;N;;;;; +12AF;ETHIOPIC SYLLABLE KOA;Lo;0;L;;;;;N;;;;; +12B0;ETHIOPIC SYLLABLE KWA;Lo;0;L;;;;;N;;;;; +12B2;ETHIOPIC SYLLABLE KWI;Lo;0;L;;;;;N;;;;; +12B3;ETHIOPIC SYLLABLE KWAA;Lo;0;L;;;;;N;;;;; +12B4;ETHIOPIC SYLLABLE KWEE;Lo;0;L;;;;;N;;;;; +12B5;ETHIOPIC SYLLABLE KWE;Lo;0;L;;;;;N;;;;; +12B8;ETHIOPIC SYLLABLE KXA;Lo;0;L;;;;;N;;;;; +12B9;ETHIOPIC SYLLABLE KXU;Lo;0;L;;;;;N;;;;; +12BA;ETHIOPIC SYLLABLE KXI;Lo;0;L;;;;;N;;;;; +12BB;ETHIOPIC SYLLABLE KXAA;Lo;0;L;;;;;N;;;;; +12BC;ETHIOPIC SYLLABLE KXEE;Lo;0;L;;;;;N;;;;; +12BD;ETHIOPIC SYLLABLE KXE;Lo;0;L;;;;;N;;;;; +12BE;ETHIOPIC SYLLABLE KXO;Lo;0;L;;;;;N;;;;; +12C0;ETHIOPIC SYLLABLE KXWA;Lo;0;L;;;;;N;;;;; +12C2;ETHIOPIC SYLLABLE KXWI;Lo;0;L;;;;;N;;;;; +12C3;ETHIOPIC SYLLABLE KXWAA;Lo;0;L;;;;;N;;;;; +12C4;ETHIOPIC SYLLABLE KXWEE;Lo;0;L;;;;;N;;;;; +12C5;ETHIOPIC SYLLABLE KXWE;Lo;0;L;;;;;N;;;;; +12C8;ETHIOPIC SYLLABLE WA;Lo;0;L;;;;;N;;;;; +12C9;ETHIOPIC SYLLABLE WU;Lo;0;L;;;;;N;;;;; +12CA;ETHIOPIC SYLLABLE WI;Lo;0;L;;;;;N;;;;; +12CB;ETHIOPIC SYLLABLE WAA;Lo;0;L;;;;;N;;;;; +12CC;ETHIOPIC SYLLABLE WEE;Lo;0;L;;;;;N;;;;; +12CD;ETHIOPIC SYLLABLE WE;Lo;0;L;;;;;N;;;;; +12CE;ETHIOPIC SYLLABLE WO;Lo;0;L;;;;;N;;;;; +12CF;ETHIOPIC SYLLABLE WOA;Lo;0;L;;;;;N;;;;; +12D0;ETHIOPIC SYLLABLE PHARYNGEAL A;Lo;0;L;;;;;N;;;;; +12D1;ETHIOPIC SYLLABLE PHARYNGEAL U;Lo;0;L;;;;;N;;;;; +12D2;ETHIOPIC SYLLABLE PHARYNGEAL I;Lo;0;L;;;;;N;;;;; +12D3;ETHIOPIC SYLLABLE PHARYNGEAL AA;Lo;0;L;;;;;N;;;;; +12D4;ETHIOPIC SYLLABLE PHARYNGEAL EE;Lo;0;L;;;;;N;;;;; +12D5;ETHIOPIC SYLLABLE PHARYNGEAL E;Lo;0;L;;;;;N;;;;; +12D6;ETHIOPIC SYLLABLE PHARYNGEAL O;Lo;0;L;;;;;N;;;;; +12D8;ETHIOPIC SYLLABLE ZA;Lo;0;L;;;;;N;;;;; +12D9;ETHIOPIC SYLLABLE ZU;Lo;0;L;;;;;N;;;;; +12DA;ETHIOPIC SYLLABLE ZI;Lo;0;L;;;;;N;;;;; +12DB;ETHIOPIC SYLLABLE ZAA;Lo;0;L;;;;;N;;;;; +12DC;ETHIOPIC SYLLABLE ZEE;Lo;0;L;;;;;N;;;;; +12DD;ETHIOPIC SYLLABLE ZE;Lo;0;L;;;;;N;;;;; +12DE;ETHIOPIC SYLLABLE ZO;Lo;0;L;;;;;N;;;;; +12DF;ETHIOPIC SYLLABLE ZWA;Lo;0;L;;;;;N;;;;; +12E0;ETHIOPIC SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; +12E1;ETHIOPIC SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; +12E2;ETHIOPIC SYLLABLE ZHI;Lo;0;L;;;;;N;;;;; +12E3;ETHIOPIC SYLLABLE ZHAA;Lo;0;L;;;;;N;;;;; +12E4;ETHIOPIC SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;; +12E5;ETHIOPIC SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; +12E6;ETHIOPIC SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; +12E7;ETHIOPIC SYLLABLE ZHWA;Lo;0;L;;;;;N;;;;; +12E8;ETHIOPIC SYLLABLE YA;Lo;0;L;;;;;N;;;;; +12E9;ETHIOPIC SYLLABLE YU;Lo;0;L;;;;;N;;;;; +12EA;ETHIOPIC SYLLABLE YI;Lo;0;L;;;;;N;;;;; +12EB;ETHIOPIC SYLLABLE YAA;Lo;0;L;;;;;N;;;;; +12EC;ETHIOPIC SYLLABLE YEE;Lo;0;L;;;;;N;;;;; +12ED;ETHIOPIC SYLLABLE YE;Lo;0;L;;;;;N;;;;; +12EE;ETHIOPIC SYLLABLE YO;Lo;0;L;;;;;N;;;;; +12EF;ETHIOPIC SYLLABLE YOA;Lo;0;L;;;;;N;;;;; +12F0;ETHIOPIC SYLLABLE DA;Lo;0;L;;;;;N;;;;; +12F1;ETHIOPIC SYLLABLE DU;Lo;0;L;;;;;N;;;;; +12F2;ETHIOPIC SYLLABLE DI;Lo;0;L;;;;;N;;;;; +12F3;ETHIOPIC SYLLABLE DAA;Lo;0;L;;;;;N;;;;; +12F4;ETHIOPIC SYLLABLE DEE;Lo;0;L;;;;;N;;;;; +12F5;ETHIOPIC SYLLABLE DE;Lo;0;L;;;;;N;;;;; +12F6;ETHIOPIC SYLLABLE DO;Lo;0;L;;;;;N;;;;; +12F7;ETHIOPIC SYLLABLE DWA;Lo;0;L;;;;;N;;;;; +12F8;ETHIOPIC SYLLABLE DDA;Lo;0;L;;;;;N;;;;; +12F9;ETHIOPIC SYLLABLE DDU;Lo;0;L;;;;;N;;;;; +12FA;ETHIOPIC SYLLABLE DDI;Lo;0;L;;;;;N;;;;; +12FB;ETHIOPIC SYLLABLE DDAA;Lo;0;L;;;;;N;;;;; +12FC;ETHIOPIC SYLLABLE DDEE;Lo;0;L;;;;;N;;;;; +12FD;ETHIOPIC SYLLABLE DDE;Lo;0;L;;;;;N;;;;; +12FE;ETHIOPIC SYLLABLE DDO;Lo;0;L;;;;;N;;;;; +12FF;ETHIOPIC SYLLABLE DDWA;Lo;0;L;;;;;N;;;;; +1300;ETHIOPIC SYLLABLE JA;Lo;0;L;;;;;N;;;;; +1301;ETHIOPIC SYLLABLE JU;Lo;0;L;;;;;N;;;;; +1302;ETHIOPIC SYLLABLE JI;Lo;0;L;;;;;N;;;;; +1303;ETHIOPIC SYLLABLE JAA;Lo;0;L;;;;;N;;;;; +1304;ETHIOPIC SYLLABLE JEE;Lo;0;L;;;;;N;;;;; +1305;ETHIOPIC SYLLABLE JE;Lo;0;L;;;;;N;;;;; +1306;ETHIOPIC SYLLABLE JO;Lo;0;L;;;;;N;;;;; +1307;ETHIOPIC SYLLABLE JWA;Lo;0;L;;;;;N;;;;; +1308;ETHIOPIC SYLLABLE GA;Lo;0;L;;;;;N;;;;; +1309;ETHIOPIC SYLLABLE GU;Lo;0;L;;;;;N;;;;; +130A;ETHIOPIC SYLLABLE GI;Lo;0;L;;;;;N;;;;; +130B;ETHIOPIC SYLLABLE GAA;Lo;0;L;;;;;N;;;;; +130C;ETHIOPIC SYLLABLE GEE;Lo;0;L;;;;;N;;;;; +130D;ETHIOPIC SYLLABLE GE;Lo;0;L;;;;;N;;;;; +130E;ETHIOPIC SYLLABLE GO;Lo;0;L;;;;;N;;;;; +130F;ETHIOPIC SYLLABLE GOA;Lo;0;L;;;;;N;;;;; +1310;ETHIOPIC SYLLABLE GWA;Lo;0;L;;;;;N;;;;; +1312;ETHIOPIC SYLLABLE GWI;Lo;0;L;;;;;N;;;;; +1313;ETHIOPIC SYLLABLE GWAA;Lo;0;L;;;;;N;;;;; +1314;ETHIOPIC SYLLABLE GWEE;Lo;0;L;;;;;N;;;;; +1315;ETHIOPIC SYLLABLE GWE;Lo;0;L;;;;;N;;;;; +1318;ETHIOPIC SYLLABLE GGA;Lo;0;L;;;;;N;;;;; +1319;ETHIOPIC SYLLABLE GGU;Lo;0;L;;;;;N;;;;; +131A;ETHIOPIC SYLLABLE GGI;Lo;0;L;;;;;N;;;;; +131B;ETHIOPIC SYLLABLE GGAA;Lo;0;L;;;;;N;;;;; +131C;ETHIOPIC SYLLABLE GGEE;Lo;0;L;;;;;N;;;;; +131D;ETHIOPIC SYLLABLE GGE;Lo;0;L;;;;;N;;;;; +131E;ETHIOPIC SYLLABLE GGO;Lo;0;L;;;;;N;;;;; +131F;ETHIOPIC SYLLABLE GGWAA;Lo;0;L;;;;;N;;;;; +1320;ETHIOPIC SYLLABLE THA;Lo;0;L;;;;;N;;;;; +1321;ETHIOPIC SYLLABLE THU;Lo;0;L;;;;;N;;;;; +1322;ETHIOPIC SYLLABLE THI;Lo;0;L;;;;;N;;;;; +1323;ETHIOPIC SYLLABLE THAA;Lo;0;L;;;;;N;;;;; +1324;ETHIOPIC SYLLABLE THEE;Lo;0;L;;;;;N;;;;; +1325;ETHIOPIC SYLLABLE THE;Lo;0;L;;;;;N;;;;; +1326;ETHIOPIC SYLLABLE THO;Lo;0;L;;;;;N;;;;; +1327;ETHIOPIC SYLLABLE THWA;Lo;0;L;;;;;N;;;;; +1328;ETHIOPIC SYLLABLE CHA;Lo;0;L;;;;;N;;;;; +1329;ETHIOPIC SYLLABLE CHU;Lo;0;L;;;;;N;;;;; +132A;ETHIOPIC SYLLABLE CHI;Lo;0;L;;;;;N;;;;; +132B;ETHIOPIC SYLLABLE CHAA;Lo;0;L;;;;;N;;;;; +132C;ETHIOPIC SYLLABLE CHEE;Lo;0;L;;;;;N;;;;; +132D;ETHIOPIC SYLLABLE CHE;Lo;0;L;;;;;N;;;;; +132E;ETHIOPIC SYLLABLE CHO;Lo;0;L;;;;;N;;;;; +132F;ETHIOPIC SYLLABLE CHWA;Lo;0;L;;;;;N;;;;; +1330;ETHIOPIC SYLLABLE PHA;Lo;0;L;;;;;N;;;;; +1331;ETHIOPIC SYLLABLE PHU;Lo;0;L;;;;;N;;;;; +1332;ETHIOPIC SYLLABLE PHI;Lo;0;L;;;;;N;;;;; +1333;ETHIOPIC SYLLABLE PHAA;Lo;0;L;;;;;N;;;;; +1334;ETHIOPIC SYLLABLE PHEE;Lo;0;L;;;;;N;;;;; +1335;ETHIOPIC SYLLABLE PHE;Lo;0;L;;;;;N;;;;; +1336;ETHIOPIC SYLLABLE PHO;Lo;0;L;;;;;N;;;;; +1337;ETHIOPIC SYLLABLE PHWA;Lo;0;L;;;;;N;;;;; +1338;ETHIOPIC SYLLABLE TSA;Lo;0;L;;;;;N;;;;; +1339;ETHIOPIC SYLLABLE TSU;Lo;0;L;;;;;N;;;;; +133A;ETHIOPIC SYLLABLE TSI;Lo;0;L;;;;;N;;;;; +133B;ETHIOPIC SYLLABLE TSAA;Lo;0;L;;;;;N;;;;; +133C;ETHIOPIC SYLLABLE TSEE;Lo;0;L;;;;;N;;;;; +133D;ETHIOPIC SYLLABLE TSE;Lo;0;L;;;;;N;;;;; +133E;ETHIOPIC SYLLABLE TSO;Lo;0;L;;;;;N;;;;; +133F;ETHIOPIC SYLLABLE TSWA;Lo;0;L;;;;;N;;;;; +1340;ETHIOPIC SYLLABLE TZA;Lo;0;L;;;;;N;;;;; +1341;ETHIOPIC SYLLABLE TZU;Lo;0;L;;;;;N;;;;; +1342;ETHIOPIC SYLLABLE TZI;Lo;0;L;;;;;N;;;;; +1343;ETHIOPIC SYLLABLE TZAA;Lo;0;L;;;;;N;;;;; +1344;ETHIOPIC SYLLABLE TZEE;Lo;0;L;;;;;N;;;;; +1345;ETHIOPIC SYLLABLE TZE;Lo;0;L;;;;;N;;;;; +1346;ETHIOPIC SYLLABLE TZO;Lo;0;L;;;;;N;;;;; +1347;ETHIOPIC SYLLABLE TZOA;Lo;0;L;;;;;N;;;;; +1348;ETHIOPIC SYLLABLE FA;Lo;0;L;;;;;N;;;;; +1349;ETHIOPIC SYLLABLE FU;Lo;0;L;;;;;N;;;;; +134A;ETHIOPIC SYLLABLE FI;Lo;0;L;;;;;N;;;;; +134B;ETHIOPIC SYLLABLE FAA;Lo;0;L;;;;;N;;;;; +134C;ETHIOPIC SYLLABLE FEE;Lo;0;L;;;;;N;;;;; +134D;ETHIOPIC SYLLABLE FE;Lo;0;L;;;;;N;;;;; +134E;ETHIOPIC SYLLABLE FO;Lo;0;L;;;;;N;;;;; +134F;ETHIOPIC SYLLABLE FWA;Lo;0;L;;;;;N;;;;; +1350;ETHIOPIC SYLLABLE PA;Lo;0;L;;;;;N;;;;; +1351;ETHIOPIC SYLLABLE PU;Lo;0;L;;;;;N;;;;; +1352;ETHIOPIC SYLLABLE PI;Lo;0;L;;;;;N;;;;; +1353;ETHIOPIC SYLLABLE PAA;Lo;0;L;;;;;N;;;;; +1354;ETHIOPIC SYLLABLE PEE;Lo;0;L;;;;;N;;;;; +1355;ETHIOPIC SYLLABLE PE;Lo;0;L;;;;;N;;;;; +1356;ETHIOPIC SYLLABLE PO;Lo;0;L;;;;;N;;;;; +1357;ETHIOPIC SYLLABLE PWA;Lo;0;L;;;;;N;;;;; +1358;ETHIOPIC SYLLABLE RYA;Lo;0;L;;;;;N;;;;; +1359;ETHIOPIC SYLLABLE MYA;Lo;0;L;;;;;N;;;;; +135A;ETHIOPIC SYLLABLE FYA;Lo;0;L;;;;;N;;;;; +135F;ETHIOPIC COMBINING GEMINATION MARK;Mn;230;NSM;;;;;N;;;;; +1360;ETHIOPIC SECTION MARK;So;0;L;;;;;N;;;;; +1361;ETHIOPIC WORDSPACE;Po;0;L;;;;;N;;;;; +1362;ETHIOPIC FULL STOP;Po;0;L;;;;;N;;;;; +1363;ETHIOPIC COMMA;Po;0;L;;;;;N;;;;; +1364;ETHIOPIC SEMICOLON;Po;0;L;;;;;N;;;;; +1365;ETHIOPIC COLON;Po;0;L;;;;;N;;;;; +1366;ETHIOPIC PREFACE COLON;Po;0;L;;;;;N;;;;; +1367;ETHIOPIC QUESTION MARK;Po;0;L;;;;;N;;;;; +1368;ETHIOPIC PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;; +1369;ETHIOPIC DIGIT ONE;No;0;L;;;1;1;N;;;;; +136A;ETHIOPIC DIGIT TWO;No;0;L;;;2;2;N;;;;; +136B;ETHIOPIC DIGIT THREE;No;0;L;;;3;3;N;;;;; +136C;ETHIOPIC DIGIT FOUR;No;0;L;;;4;4;N;;;;; +136D;ETHIOPIC DIGIT FIVE;No;0;L;;;5;5;N;;;;; +136E;ETHIOPIC DIGIT SIX;No;0;L;;;6;6;N;;;;; +136F;ETHIOPIC DIGIT SEVEN;No;0;L;;;7;7;N;;;;; +1370;ETHIOPIC DIGIT EIGHT;No;0;L;;;8;8;N;;;;; +1371;ETHIOPIC DIGIT NINE;No;0;L;;;9;9;N;;;;; +1372;ETHIOPIC NUMBER TEN;No;0;L;;;;10;N;;;;; +1373;ETHIOPIC NUMBER TWENTY;No;0;L;;;;20;N;;;;; +1374;ETHIOPIC NUMBER THIRTY;No;0;L;;;;30;N;;;;; +1375;ETHIOPIC NUMBER FORTY;No;0;L;;;;40;N;;;;; +1376;ETHIOPIC NUMBER FIFTY;No;0;L;;;;50;N;;;;; +1377;ETHIOPIC NUMBER SIXTY;No;0;L;;;;60;N;;;;; +1378;ETHIOPIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;; +1379;ETHIOPIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;; +137A;ETHIOPIC NUMBER NINETY;No;0;L;;;;90;N;;;;; +137B;ETHIOPIC NUMBER HUNDRED;No;0;L;;;;100;N;;;;; +137C;ETHIOPIC NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;; +1380;ETHIOPIC SYLLABLE SEBATBEIT MWA;Lo;0;L;;;;;N;;;;; +1381;ETHIOPIC SYLLABLE MWI;Lo;0;L;;;;;N;;;;; +1382;ETHIOPIC SYLLABLE MWEE;Lo;0;L;;;;;N;;;;; +1383;ETHIOPIC SYLLABLE MWE;Lo;0;L;;;;;N;;;;; +1384;ETHIOPIC SYLLABLE SEBATBEIT BWA;Lo;0;L;;;;;N;;;;; +1385;ETHIOPIC SYLLABLE BWI;Lo;0;L;;;;;N;;;;; +1386;ETHIOPIC SYLLABLE BWEE;Lo;0;L;;;;;N;;;;; +1387;ETHIOPIC SYLLABLE BWE;Lo;0;L;;;;;N;;;;; +1388;ETHIOPIC SYLLABLE SEBATBEIT FWA;Lo;0;L;;;;;N;;;;; +1389;ETHIOPIC SYLLABLE FWI;Lo;0;L;;;;;N;;;;; +138A;ETHIOPIC SYLLABLE FWEE;Lo;0;L;;;;;N;;;;; +138B;ETHIOPIC SYLLABLE FWE;Lo;0;L;;;;;N;;;;; +138C;ETHIOPIC SYLLABLE SEBATBEIT PWA;Lo;0;L;;;;;N;;;;; +138D;ETHIOPIC SYLLABLE PWI;Lo;0;L;;;;;N;;;;; +138E;ETHIOPIC SYLLABLE PWEE;Lo;0;L;;;;;N;;;;; +138F;ETHIOPIC SYLLABLE PWE;Lo;0;L;;;;;N;;;;; +1390;ETHIOPIC TONAL MARK YIZET;So;0;ON;;;;;N;;;;; +1391;ETHIOPIC TONAL MARK DERET;So;0;ON;;;;;N;;;;; +1392;ETHIOPIC TONAL MARK RIKRIK;So;0;ON;;;;;N;;;;; +1393;ETHIOPIC TONAL MARK SHORT RIKRIK;So;0;ON;;;;;N;;;;; +1394;ETHIOPIC TONAL MARK DIFAT;So;0;ON;;;;;N;;;;; +1395;ETHIOPIC TONAL MARK KENAT;So;0;ON;;;;;N;;;;; +1396;ETHIOPIC TONAL MARK CHIRET;So;0;ON;;;;;N;;;;; +1397;ETHIOPIC TONAL MARK HIDET;So;0;ON;;;;;N;;;;; +1398;ETHIOPIC TONAL MARK DERET-HIDET;So;0;ON;;;;;N;;;;; +1399;ETHIOPIC TONAL MARK KURT;So;0;ON;;;;;N;;;;; +13A0;CHEROKEE LETTER A;Lo;0;L;;;;;N;;;;; +13A1;CHEROKEE LETTER E;Lo;0;L;;;;;N;;;;; +13A2;CHEROKEE LETTER I;Lo;0;L;;;;;N;;;;; +13A3;CHEROKEE LETTER O;Lo;0;L;;;;;N;;;;; +13A4;CHEROKEE LETTER U;Lo;0;L;;;;;N;;;;; +13A5;CHEROKEE LETTER V;Lo;0;L;;;;;N;;;;; +13A6;CHEROKEE LETTER GA;Lo;0;L;;;;;N;;;;; +13A7;CHEROKEE LETTER KA;Lo;0;L;;;;;N;;;;; +13A8;CHEROKEE LETTER GE;Lo;0;L;;;;;N;;;;; +13A9;CHEROKEE LETTER GI;Lo;0;L;;;;;N;;;;; +13AA;CHEROKEE LETTER GO;Lo;0;L;;;;;N;;;;; +13AB;CHEROKEE LETTER GU;Lo;0;L;;;;;N;;;;; +13AC;CHEROKEE LETTER GV;Lo;0;L;;;;;N;;;;; +13AD;CHEROKEE LETTER HA;Lo;0;L;;;;;N;;;;; +13AE;CHEROKEE LETTER HE;Lo;0;L;;;;;N;;;;; +13AF;CHEROKEE LETTER HI;Lo;0;L;;;;;N;;;;; +13B0;CHEROKEE LETTER HO;Lo;0;L;;;;;N;;;;; +13B1;CHEROKEE LETTER HU;Lo;0;L;;;;;N;;;;; +13B2;CHEROKEE LETTER HV;Lo;0;L;;;;;N;;;;; +13B3;CHEROKEE LETTER LA;Lo;0;L;;;;;N;;;;; +13B4;CHEROKEE LETTER LE;Lo;0;L;;;;;N;;;;; +13B5;CHEROKEE LETTER LI;Lo;0;L;;;;;N;;;;; +13B6;CHEROKEE LETTER LO;Lo;0;L;;;;;N;;;;; +13B7;CHEROKEE LETTER LU;Lo;0;L;;;;;N;;;;; +13B8;CHEROKEE LETTER LV;Lo;0;L;;;;;N;;;;; +13B9;CHEROKEE LETTER MA;Lo;0;L;;;;;N;;;;; +13BA;CHEROKEE LETTER ME;Lo;0;L;;;;;N;;;;; +13BB;CHEROKEE LETTER MI;Lo;0;L;;;;;N;;;;; +13BC;CHEROKEE LETTER MO;Lo;0;L;;;;;N;;;;; +13BD;CHEROKEE LETTER MU;Lo;0;L;;;;;N;;;;; +13BE;CHEROKEE LETTER NA;Lo;0;L;;;;;N;;;;; +13BF;CHEROKEE LETTER HNA;Lo;0;L;;;;;N;;;;; +13C0;CHEROKEE LETTER NAH;Lo;0;L;;;;;N;;;;; +13C1;CHEROKEE LETTER NE;Lo;0;L;;;;;N;;;;; +13C2;CHEROKEE LETTER NI;Lo;0;L;;;;;N;;;;; +13C3;CHEROKEE LETTER NO;Lo;0;L;;;;;N;;;;; +13C4;CHEROKEE LETTER NU;Lo;0;L;;;;;N;;;;; +13C5;CHEROKEE LETTER NV;Lo;0;L;;;;;N;;;;; +13C6;CHEROKEE LETTER QUA;Lo;0;L;;;;;N;;;;; +13C7;CHEROKEE LETTER QUE;Lo;0;L;;;;;N;;;;; +13C8;CHEROKEE LETTER QUI;Lo;0;L;;;;;N;;;;; +13C9;CHEROKEE LETTER QUO;Lo;0;L;;;;;N;;;;; +13CA;CHEROKEE LETTER QUU;Lo;0;L;;;;;N;;;;; +13CB;CHEROKEE LETTER QUV;Lo;0;L;;;;;N;;;;; +13CC;CHEROKEE LETTER SA;Lo;0;L;;;;;N;;;;; +13CD;CHEROKEE LETTER S;Lo;0;L;;;;;N;;;;; +13CE;CHEROKEE LETTER SE;Lo;0;L;;;;;N;;;;; +13CF;CHEROKEE LETTER SI;Lo;0;L;;;;;N;;;;; +13D0;CHEROKEE LETTER SO;Lo;0;L;;;;;N;;;;; +13D1;CHEROKEE LETTER SU;Lo;0;L;;;;;N;;;;; +13D2;CHEROKEE LETTER SV;Lo;0;L;;;;;N;;;;; +13D3;CHEROKEE LETTER DA;Lo;0;L;;;;;N;;;;; +13D4;CHEROKEE LETTER TA;Lo;0;L;;;;;N;;;;; +13D5;CHEROKEE LETTER DE;Lo;0;L;;;;;N;;;;; +13D6;CHEROKEE LETTER TE;Lo;0;L;;;;;N;;;;; +13D7;CHEROKEE LETTER DI;Lo;0;L;;;;;N;;;;; +13D8;CHEROKEE LETTER TI;Lo;0;L;;;;;N;;;;; +13D9;CHEROKEE LETTER DO;Lo;0;L;;;;;N;;;;; +13DA;CHEROKEE LETTER DU;Lo;0;L;;;;;N;;;;; +13DB;CHEROKEE LETTER DV;Lo;0;L;;;;;N;;;;; +13DC;CHEROKEE LETTER DLA;Lo;0;L;;;;;N;;;;; +13DD;CHEROKEE LETTER TLA;Lo;0;L;;;;;N;;;;; +13DE;CHEROKEE LETTER TLE;Lo;0;L;;;;;N;;;;; +13DF;CHEROKEE LETTER TLI;Lo;0;L;;;;;N;;;;; +13E0;CHEROKEE LETTER TLO;Lo;0;L;;;;;N;;;;; +13E1;CHEROKEE LETTER TLU;Lo;0;L;;;;;N;;;;; +13E2;CHEROKEE LETTER TLV;Lo;0;L;;;;;N;;;;; +13E3;CHEROKEE LETTER TSA;Lo;0;L;;;;;N;;;;; +13E4;CHEROKEE LETTER TSE;Lo;0;L;;;;;N;;;;; +13E5;CHEROKEE LETTER TSI;Lo;0;L;;;;;N;;;;; +13E6;CHEROKEE LETTER TSO;Lo;0;L;;;;;N;;;;; +13E7;CHEROKEE LETTER TSU;Lo;0;L;;;;;N;;;;; +13E8;CHEROKEE LETTER TSV;Lo;0;L;;;;;N;;;;; +13E9;CHEROKEE LETTER WA;Lo;0;L;;;;;N;;;;; +13EA;CHEROKEE LETTER WE;Lo;0;L;;;;;N;;;;; +13EB;CHEROKEE LETTER WI;Lo;0;L;;;;;N;;;;; +13EC;CHEROKEE LETTER WO;Lo;0;L;;;;;N;;;;; +13ED;CHEROKEE LETTER WU;Lo;0;L;;;;;N;;;;; +13EE;CHEROKEE LETTER WV;Lo;0;L;;;;;N;;;;; +13EF;CHEROKEE LETTER YA;Lo;0;L;;;;;N;;;;; +13F0;CHEROKEE LETTER YE;Lo;0;L;;;;;N;;;;; +13F1;CHEROKEE LETTER YI;Lo;0;L;;;;;N;;;;; +13F2;CHEROKEE LETTER YO;Lo;0;L;;;;;N;;;;; +13F3;CHEROKEE LETTER YU;Lo;0;L;;;;;N;;;;; +13F4;CHEROKEE LETTER YV;Lo;0;L;;;;;N;;;;; +1400;CANADIAN SYLLABICS HYPHEN;Pd;0;ON;;;;;N;;;;; +1401;CANADIAN SYLLABICS E;Lo;0;L;;;;;N;;;;; +1402;CANADIAN SYLLABICS AAI;Lo;0;L;;;;;N;;;;; +1403;CANADIAN SYLLABICS I;Lo;0;L;;;;;N;;;;; +1404;CANADIAN SYLLABICS II;Lo;0;L;;;;;N;;;;; +1405;CANADIAN SYLLABICS O;Lo;0;L;;;;;N;;;;; +1406;CANADIAN SYLLABICS OO;Lo;0;L;;;;;N;;;;; +1407;CANADIAN SYLLABICS Y-CREE OO;Lo;0;L;;;;;N;;;;; +1408;CANADIAN SYLLABICS CARRIER EE;Lo;0;L;;;;;N;;;;; +1409;CANADIAN SYLLABICS CARRIER I;Lo;0;L;;;;;N;;;;; +140A;CANADIAN SYLLABICS A;Lo;0;L;;;;;N;;;;; +140B;CANADIAN SYLLABICS AA;Lo;0;L;;;;;N;;;;; +140C;CANADIAN SYLLABICS WE;Lo;0;L;;;;;N;;;;; +140D;CANADIAN SYLLABICS WEST-CREE WE;Lo;0;L;;;;;N;;;;; +140E;CANADIAN SYLLABICS WI;Lo;0;L;;;;;N;;;;; +140F;CANADIAN SYLLABICS WEST-CREE WI;Lo;0;L;;;;;N;;;;; +1410;CANADIAN SYLLABICS WII;Lo;0;L;;;;;N;;;;; +1411;CANADIAN SYLLABICS WEST-CREE WII;Lo;0;L;;;;;N;;;;; +1412;CANADIAN SYLLABICS WO;Lo;0;L;;;;;N;;;;; +1413;CANADIAN SYLLABICS WEST-CREE WO;Lo;0;L;;;;;N;;;;; +1414;CANADIAN SYLLABICS WOO;Lo;0;L;;;;;N;;;;; +1415;CANADIAN SYLLABICS WEST-CREE WOO;Lo;0;L;;;;;N;;;;; +1416;CANADIAN SYLLABICS NASKAPI WOO;Lo;0;L;;;;;N;;;;; +1417;CANADIAN SYLLABICS WA;Lo;0;L;;;;;N;;;;; +1418;CANADIAN SYLLABICS WEST-CREE WA;Lo;0;L;;;;;N;;;;; +1419;CANADIAN SYLLABICS WAA;Lo;0;L;;;;;N;;;;; +141A;CANADIAN SYLLABICS WEST-CREE WAA;Lo;0;L;;;;;N;;;;; +141B;CANADIAN SYLLABICS NASKAPI WAA;Lo;0;L;;;;;N;;;;; +141C;CANADIAN SYLLABICS AI;Lo;0;L;;;;;N;;;;; +141D;CANADIAN SYLLABICS Y-CREE W;Lo;0;L;;;;;N;;;;; +141E;CANADIAN SYLLABICS GLOTTAL STOP;Lo;0;L;;;;;N;;;;; +141F;CANADIAN SYLLABICS FINAL ACUTE;Lo;0;L;;;;;N;;;;; +1420;CANADIAN SYLLABICS FINAL GRAVE;Lo;0;L;;;;;N;;;;; +1421;CANADIAN SYLLABICS FINAL BOTTOM HALF RING;Lo;0;L;;;;;N;;;;; +1422;CANADIAN SYLLABICS FINAL TOP HALF RING;Lo;0;L;;;;;N;;;;; +1423;CANADIAN SYLLABICS FINAL RIGHT HALF RING;Lo;0;L;;;;;N;;;;; +1424;CANADIAN SYLLABICS FINAL RING;Lo;0;L;;;;;N;;;;; +1425;CANADIAN SYLLABICS FINAL DOUBLE ACUTE;Lo;0;L;;;;;N;;;;; +1426;CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES;Lo;0;L;;;;;N;;;;; +1427;CANADIAN SYLLABICS FINAL MIDDLE DOT;Lo;0;L;;;;;N;;;;; +1428;CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE;Lo;0;L;;;;;N;;;;; +1429;CANADIAN SYLLABICS FINAL PLUS;Lo;0;L;;;;;N;;;;; +142A;CANADIAN SYLLABICS FINAL DOWN TACK;Lo;0;L;;;;;N;;;;; +142B;CANADIAN SYLLABICS EN;Lo;0;L;;;;;N;;;;; +142C;CANADIAN SYLLABICS IN;Lo;0;L;;;;;N;;;;; +142D;CANADIAN SYLLABICS ON;Lo;0;L;;;;;N;;;;; +142E;CANADIAN SYLLABICS AN;Lo;0;L;;;;;N;;;;; +142F;CANADIAN SYLLABICS PE;Lo;0;L;;;;;N;;;;; +1430;CANADIAN SYLLABICS PAAI;Lo;0;L;;;;;N;;;;; +1431;CANADIAN SYLLABICS PI;Lo;0;L;;;;;N;;;;; +1432;CANADIAN SYLLABICS PII;Lo;0;L;;;;;N;;;;; +1433;CANADIAN SYLLABICS PO;Lo;0;L;;;;;N;;;;; +1434;CANADIAN SYLLABICS POO;Lo;0;L;;;;;N;;;;; +1435;CANADIAN SYLLABICS Y-CREE POO;Lo;0;L;;;;;N;;;;; +1436;CANADIAN SYLLABICS CARRIER HEE;Lo;0;L;;;;;N;;;;; +1437;CANADIAN SYLLABICS CARRIER HI;Lo;0;L;;;;;N;;;;; +1438;CANADIAN SYLLABICS PA;Lo;0;L;;;;;N;;;;; +1439;CANADIAN SYLLABICS PAA;Lo;0;L;;;;;N;;;;; +143A;CANADIAN SYLLABICS PWE;Lo;0;L;;;;;N;;;;; +143B;CANADIAN SYLLABICS WEST-CREE PWE;Lo;0;L;;;;;N;;;;; +143C;CANADIAN SYLLABICS PWI;Lo;0;L;;;;;N;;;;; +143D;CANADIAN SYLLABICS WEST-CREE PWI;Lo;0;L;;;;;N;;;;; +143E;CANADIAN SYLLABICS PWII;Lo;0;L;;;;;N;;;;; +143F;CANADIAN SYLLABICS WEST-CREE PWII;Lo;0;L;;;;;N;;;;; +1440;CANADIAN SYLLABICS PWO;Lo;0;L;;;;;N;;;;; +1441;CANADIAN SYLLABICS WEST-CREE PWO;Lo;0;L;;;;;N;;;;; +1442;CANADIAN SYLLABICS PWOO;Lo;0;L;;;;;N;;;;; +1443;CANADIAN SYLLABICS WEST-CREE PWOO;Lo;0;L;;;;;N;;;;; +1444;CANADIAN SYLLABICS PWA;Lo;0;L;;;;;N;;;;; +1445;CANADIAN SYLLABICS WEST-CREE PWA;Lo;0;L;;;;;N;;;;; +1446;CANADIAN SYLLABICS PWAA;Lo;0;L;;;;;N;;;;; +1447;CANADIAN SYLLABICS WEST-CREE PWAA;Lo;0;L;;;;;N;;;;; +1448;CANADIAN SYLLABICS Y-CREE PWAA;Lo;0;L;;;;;N;;;;; +1449;CANADIAN SYLLABICS P;Lo;0;L;;;;;N;;;;; +144A;CANADIAN SYLLABICS WEST-CREE P;Lo;0;L;;;;;N;;;;; +144B;CANADIAN SYLLABICS CARRIER H;Lo;0;L;;;;;N;;;;; +144C;CANADIAN SYLLABICS TE;Lo;0;L;;;;;N;;;;; +144D;CANADIAN SYLLABICS TAAI;Lo;0;L;;;;;N;;;;; +144E;CANADIAN SYLLABICS TI;Lo;0;L;;;;;N;;;;; +144F;CANADIAN SYLLABICS TII;Lo;0;L;;;;;N;;;;; +1450;CANADIAN SYLLABICS TO;Lo;0;L;;;;;N;;;;; +1451;CANADIAN SYLLABICS TOO;Lo;0;L;;;;;N;;;;; +1452;CANADIAN SYLLABICS Y-CREE TOO;Lo;0;L;;;;;N;;;;; +1453;CANADIAN SYLLABICS CARRIER DEE;Lo;0;L;;;;;N;;;;; +1454;CANADIAN SYLLABICS CARRIER DI;Lo;0;L;;;;;N;;;;; +1455;CANADIAN SYLLABICS TA;Lo;0;L;;;;;N;;;;; +1456;CANADIAN SYLLABICS TAA;Lo;0;L;;;;;N;;;;; +1457;CANADIAN SYLLABICS TWE;Lo;0;L;;;;;N;;;;; +1458;CANADIAN SYLLABICS WEST-CREE TWE;Lo;0;L;;;;;N;;;;; +1459;CANADIAN SYLLABICS TWI;Lo;0;L;;;;;N;;;;; +145A;CANADIAN SYLLABICS WEST-CREE TWI;Lo;0;L;;;;;N;;;;; +145B;CANADIAN SYLLABICS TWII;Lo;0;L;;;;;N;;;;; +145C;CANADIAN SYLLABICS WEST-CREE TWII;Lo;0;L;;;;;N;;;;; +145D;CANADIAN SYLLABICS TWO;Lo;0;L;;;;;N;;;;; +145E;CANADIAN SYLLABICS WEST-CREE TWO;Lo;0;L;;;;;N;;;;; +145F;CANADIAN SYLLABICS TWOO;Lo;0;L;;;;;N;;;;; +1460;CANADIAN SYLLABICS WEST-CREE TWOO;Lo;0;L;;;;;N;;;;; +1461;CANADIAN SYLLABICS TWA;Lo;0;L;;;;;N;;;;; +1462;CANADIAN SYLLABICS WEST-CREE TWA;Lo;0;L;;;;;N;;;;; +1463;CANADIAN SYLLABICS TWAA;Lo;0;L;;;;;N;;;;; +1464;CANADIAN SYLLABICS WEST-CREE TWAA;Lo;0;L;;;;;N;;;;; +1465;CANADIAN SYLLABICS NASKAPI TWAA;Lo;0;L;;;;;N;;;;; +1466;CANADIAN SYLLABICS T;Lo;0;L;;;;;N;;;;; +1467;CANADIAN SYLLABICS TTE;Lo;0;L;;;;;N;;;;; +1468;CANADIAN SYLLABICS TTI;Lo;0;L;;;;;N;;;;; +1469;CANADIAN SYLLABICS TTO;Lo;0;L;;;;;N;;;;; +146A;CANADIAN SYLLABICS TTA;Lo;0;L;;;;;N;;;;; +146B;CANADIAN SYLLABICS KE;Lo;0;L;;;;;N;;;;; +146C;CANADIAN SYLLABICS KAAI;Lo;0;L;;;;;N;;;;; +146D;CANADIAN SYLLABICS KI;Lo;0;L;;;;;N;;;;; +146E;CANADIAN SYLLABICS KII;Lo;0;L;;;;;N;;;;; +146F;CANADIAN SYLLABICS KO;Lo;0;L;;;;;N;;;;; +1470;CANADIAN SYLLABICS KOO;Lo;0;L;;;;;N;;;;; +1471;CANADIAN SYLLABICS Y-CREE KOO;Lo;0;L;;;;;N;;;;; +1472;CANADIAN SYLLABICS KA;Lo;0;L;;;;;N;;;;; +1473;CANADIAN SYLLABICS KAA;Lo;0;L;;;;;N;;;;; +1474;CANADIAN SYLLABICS KWE;Lo;0;L;;;;;N;;;;; +1475;CANADIAN SYLLABICS WEST-CREE KWE;Lo;0;L;;;;;N;;;;; +1476;CANADIAN SYLLABICS KWI;Lo;0;L;;;;;N;;;;; +1477;CANADIAN SYLLABICS WEST-CREE KWI;Lo;0;L;;;;;N;;;;; +1478;CANADIAN SYLLABICS KWII;Lo;0;L;;;;;N;;;;; +1479;CANADIAN SYLLABICS WEST-CREE KWII;Lo;0;L;;;;;N;;;;; +147A;CANADIAN SYLLABICS KWO;Lo;0;L;;;;;N;;;;; +147B;CANADIAN SYLLABICS WEST-CREE KWO;Lo;0;L;;;;;N;;;;; +147C;CANADIAN SYLLABICS KWOO;Lo;0;L;;;;;N;;;;; +147D;CANADIAN SYLLABICS WEST-CREE KWOO;Lo;0;L;;;;;N;;;;; +147E;CANADIAN SYLLABICS KWA;Lo;0;L;;;;;N;;;;; +147F;CANADIAN SYLLABICS WEST-CREE KWA;Lo;0;L;;;;;N;;;;; +1480;CANADIAN SYLLABICS KWAA;Lo;0;L;;;;;N;;;;; +1481;CANADIAN SYLLABICS WEST-CREE KWAA;Lo;0;L;;;;;N;;;;; +1482;CANADIAN SYLLABICS NASKAPI KWAA;Lo;0;L;;;;;N;;;;; +1483;CANADIAN SYLLABICS K;Lo;0;L;;;;;N;;;;; +1484;CANADIAN SYLLABICS KW;Lo;0;L;;;;;N;;;;; +1485;CANADIAN SYLLABICS SOUTH-SLAVEY KEH;Lo;0;L;;;;;N;;;;; +1486;CANADIAN SYLLABICS SOUTH-SLAVEY KIH;Lo;0;L;;;;;N;;;;; +1487;CANADIAN SYLLABICS SOUTH-SLAVEY KOH;Lo;0;L;;;;;N;;;;; +1488;CANADIAN SYLLABICS SOUTH-SLAVEY KAH;Lo;0;L;;;;;N;;;;; +1489;CANADIAN SYLLABICS CE;Lo;0;L;;;;;N;;;;; +148A;CANADIAN SYLLABICS CAAI;Lo;0;L;;;;;N;;;;; +148B;CANADIAN SYLLABICS CI;Lo;0;L;;;;;N;;;;; +148C;CANADIAN SYLLABICS CII;Lo;0;L;;;;;N;;;;; +148D;CANADIAN SYLLABICS CO;Lo;0;L;;;;;N;;;;; +148E;CANADIAN SYLLABICS COO;Lo;0;L;;;;;N;;;;; +148F;CANADIAN SYLLABICS Y-CREE COO;Lo;0;L;;;;;N;;;;; +1490;CANADIAN SYLLABICS CA;Lo;0;L;;;;;N;;;;; +1491;CANADIAN SYLLABICS CAA;Lo;0;L;;;;;N;;;;; +1492;CANADIAN SYLLABICS CWE;Lo;0;L;;;;;N;;;;; +1493;CANADIAN SYLLABICS WEST-CREE CWE;Lo;0;L;;;;;N;;;;; +1494;CANADIAN SYLLABICS CWI;Lo;0;L;;;;;N;;;;; +1495;CANADIAN SYLLABICS WEST-CREE CWI;Lo;0;L;;;;;N;;;;; +1496;CANADIAN SYLLABICS CWII;Lo;0;L;;;;;N;;;;; +1497;CANADIAN SYLLABICS WEST-CREE CWII;Lo;0;L;;;;;N;;;;; +1498;CANADIAN SYLLABICS CWO;Lo;0;L;;;;;N;;;;; +1499;CANADIAN SYLLABICS WEST-CREE CWO;Lo;0;L;;;;;N;;;;; +149A;CANADIAN SYLLABICS CWOO;Lo;0;L;;;;;N;;;;; +149B;CANADIAN SYLLABICS WEST-CREE CWOO;Lo;0;L;;;;;N;;;;; +149C;CANADIAN SYLLABICS CWA;Lo;0;L;;;;;N;;;;; +149D;CANADIAN SYLLABICS WEST-CREE CWA;Lo;0;L;;;;;N;;;;; +149E;CANADIAN SYLLABICS CWAA;Lo;0;L;;;;;N;;;;; +149F;CANADIAN SYLLABICS WEST-CREE CWAA;Lo;0;L;;;;;N;;;;; +14A0;CANADIAN SYLLABICS NASKAPI CWAA;Lo;0;L;;;;;N;;;;; +14A1;CANADIAN SYLLABICS C;Lo;0;L;;;;;N;;;;; +14A2;CANADIAN SYLLABICS SAYISI TH;Lo;0;L;;;;;N;;;;; +14A3;CANADIAN SYLLABICS ME;Lo;0;L;;;;;N;;;;; +14A4;CANADIAN SYLLABICS MAAI;Lo;0;L;;;;;N;;;;; +14A5;CANADIAN SYLLABICS MI;Lo;0;L;;;;;N;;;;; +14A6;CANADIAN SYLLABICS MII;Lo;0;L;;;;;N;;;;; +14A7;CANADIAN SYLLABICS MO;Lo;0;L;;;;;N;;;;; +14A8;CANADIAN SYLLABICS MOO;Lo;0;L;;;;;N;;;;; +14A9;CANADIAN SYLLABICS Y-CREE MOO;Lo;0;L;;;;;N;;;;; +14AA;CANADIAN SYLLABICS MA;Lo;0;L;;;;;N;;;;; +14AB;CANADIAN SYLLABICS MAA;Lo;0;L;;;;;N;;;;; +14AC;CANADIAN SYLLABICS MWE;Lo;0;L;;;;;N;;;;; +14AD;CANADIAN SYLLABICS WEST-CREE MWE;Lo;0;L;;;;;N;;;;; +14AE;CANADIAN SYLLABICS MWI;Lo;0;L;;;;;N;;;;; +14AF;CANADIAN SYLLABICS WEST-CREE MWI;Lo;0;L;;;;;N;;;;; +14B0;CANADIAN SYLLABICS MWII;Lo;0;L;;;;;N;;;;; +14B1;CANADIAN SYLLABICS WEST-CREE MWII;Lo;0;L;;;;;N;;;;; +14B2;CANADIAN SYLLABICS MWO;Lo;0;L;;;;;N;;;;; +14B3;CANADIAN SYLLABICS WEST-CREE MWO;Lo;0;L;;;;;N;;;;; +14B4;CANADIAN SYLLABICS MWOO;Lo;0;L;;;;;N;;;;; +14B5;CANADIAN SYLLABICS WEST-CREE MWOO;Lo;0;L;;;;;N;;;;; +14B6;CANADIAN SYLLABICS MWA;Lo;0;L;;;;;N;;;;; +14B7;CANADIAN SYLLABICS WEST-CREE MWA;Lo;0;L;;;;;N;;;;; +14B8;CANADIAN SYLLABICS MWAA;Lo;0;L;;;;;N;;;;; +14B9;CANADIAN SYLLABICS WEST-CREE MWAA;Lo;0;L;;;;;N;;;;; +14BA;CANADIAN SYLLABICS NASKAPI MWAA;Lo;0;L;;;;;N;;;;; +14BB;CANADIAN SYLLABICS M;Lo;0;L;;;;;N;;;;; +14BC;CANADIAN SYLLABICS WEST-CREE M;Lo;0;L;;;;;N;;;;; +14BD;CANADIAN SYLLABICS MH;Lo;0;L;;;;;N;;;;; +14BE;CANADIAN SYLLABICS ATHAPASCAN M;Lo;0;L;;;;;N;;;;; +14BF;CANADIAN SYLLABICS SAYISI M;Lo;0;L;;;;;N;;;;; +14C0;CANADIAN SYLLABICS NE;Lo;0;L;;;;;N;;;;; +14C1;CANADIAN SYLLABICS NAAI;Lo;0;L;;;;;N;;;;; +14C2;CANADIAN SYLLABICS NI;Lo;0;L;;;;;N;;;;; +14C3;CANADIAN SYLLABICS NII;Lo;0;L;;;;;N;;;;; +14C4;CANADIAN SYLLABICS NO;Lo;0;L;;;;;N;;;;; +14C5;CANADIAN SYLLABICS NOO;Lo;0;L;;;;;N;;;;; +14C6;CANADIAN SYLLABICS Y-CREE NOO;Lo;0;L;;;;;N;;;;; +14C7;CANADIAN SYLLABICS NA;Lo;0;L;;;;;N;;;;; +14C8;CANADIAN SYLLABICS NAA;Lo;0;L;;;;;N;;;;; +14C9;CANADIAN SYLLABICS NWE;Lo;0;L;;;;;N;;;;; +14CA;CANADIAN SYLLABICS WEST-CREE NWE;Lo;0;L;;;;;N;;;;; +14CB;CANADIAN SYLLABICS NWA;Lo;0;L;;;;;N;;;;; +14CC;CANADIAN SYLLABICS WEST-CREE NWA;Lo;0;L;;;;;N;;;;; +14CD;CANADIAN SYLLABICS NWAA;Lo;0;L;;;;;N;;;;; +14CE;CANADIAN SYLLABICS WEST-CREE NWAA;Lo;0;L;;;;;N;;;;; +14CF;CANADIAN SYLLABICS NASKAPI NWAA;Lo;0;L;;;;;N;;;;; +14D0;CANADIAN SYLLABICS N;Lo;0;L;;;;;N;;;;; +14D1;CANADIAN SYLLABICS CARRIER NG;Lo;0;L;;;;;N;;;;; +14D2;CANADIAN SYLLABICS NH;Lo;0;L;;;;;N;;;;; +14D3;CANADIAN SYLLABICS LE;Lo;0;L;;;;;N;;;;; +14D4;CANADIAN SYLLABICS LAAI;Lo;0;L;;;;;N;;;;; +14D5;CANADIAN SYLLABICS LI;Lo;0;L;;;;;N;;;;; +14D6;CANADIAN SYLLABICS LII;Lo;0;L;;;;;N;;;;; +14D7;CANADIAN SYLLABICS LO;Lo;0;L;;;;;N;;;;; +14D8;CANADIAN SYLLABICS LOO;Lo;0;L;;;;;N;;;;; +14D9;CANADIAN SYLLABICS Y-CREE LOO;Lo;0;L;;;;;N;;;;; +14DA;CANADIAN SYLLABICS LA;Lo;0;L;;;;;N;;;;; +14DB;CANADIAN SYLLABICS LAA;Lo;0;L;;;;;N;;;;; +14DC;CANADIAN SYLLABICS LWE;Lo;0;L;;;;;N;;;;; +14DD;CANADIAN SYLLABICS WEST-CREE LWE;Lo;0;L;;;;;N;;;;; +14DE;CANADIAN SYLLABICS LWI;Lo;0;L;;;;;N;;;;; +14DF;CANADIAN SYLLABICS WEST-CREE LWI;Lo;0;L;;;;;N;;;;; +14E0;CANADIAN SYLLABICS LWII;Lo;0;L;;;;;N;;;;; +14E1;CANADIAN SYLLABICS WEST-CREE LWII;Lo;0;L;;;;;N;;;;; +14E2;CANADIAN SYLLABICS LWO;Lo;0;L;;;;;N;;;;; +14E3;CANADIAN SYLLABICS WEST-CREE LWO;Lo;0;L;;;;;N;;;;; +14E4;CANADIAN SYLLABICS LWOO;Lo;0;L;;;;;N;;;;; +14E5;CANADIAN SYLLABICS WEST-CREE LWOO;Lo;0;L;;;;;N;;;;; +14E6;CANADIAN SYLLABICS LWA;Lo;0;L;;;;;N;;;;; +14E7;CANADIAN SYLLABICS WEST-CREE LWA;Lo;0;L;;;;;N;;;;; +14E8;CANADIAN SYLLABICS LWAA;Lo;0;L;;;;;N;;;;; +14E9;CANADIAN SYLLABICS WEST-CREE LWAA;Lo;0;L;;;;;N;;;;; +14EA;CANADIAN SYLLABICS L;Lo;0;L;;;;;N;;;;; +14EB;CANADIAN SYLLABICS WEST-CREE L;Lo;0;L;;;;;N;;;;; +14EC;CANADIAN SYLLABICS MEDIAL L;Lo;0;L;;;;;N;;;;; +14ED;CANADIAN SYLLABICS SE;Lo;0;L;;;;;N;;;;; +14EE;CANADIAN SYLLABICS SAAI;Lo;0;L;;;;;N;;;;; +14EF;CANADIAN SYLLABICS SI;Lo;0;L;;;;;N;;;;; +14F0;CANADIAN SYLLABICS SII;Lo;0;L;;;;;N;;;;; +14F1;CANADIAN SYLLABICS SO;Lo;0;L;;;;;N;;;;; +14F2;CANADIAN SYLLABICS SOO;Lo;0;L;;;;;N;;;;; +14F3;CANADIAN SYLLABICS Y-CREE SOO;Lo;0;L;;;;;N;;;;; +14F4;CANADIAN SYLLABICS SA;Lo;0;L;;;;;N;;;;; +14F5;CANADIAN SYLLABICS SAA;Lo;0;L;;;;;N;;;;; +14F6;CANADIAN SYLLABICS SWE;Lo;0;L;;;;;N;;;;; +14F7;CANADIAN SYLLABICS WEST-CREE SWE;Lo;0;L;;;;;N;;;;; +14F8;CANADIAN SYLLABICS SWI;Lo;0;L;;;;;N;;;;; +14F9;CANADIAN SYLLABICS WEST-CREE SWI;Lo;0;L;;;;;N;;;;; +14FA;CANADIAN SYLLABICS SWII;Lo;0;L;;;;;N;;;;; +14FB;CANADIAN SYLLABICS WEST-CREE SWII;Lo;0;L;;;;;N;;;;; +14FC;CANADIAN SYLLABICS SWO;Lo;0;L;;;;;N;;;;; +14FD;CANADIAN SYLLABICS WEST-CREE SWO;Lo;0;L;;;;;N;;;;; +14FE;CANADIAN SYLLABICS SWOO;Lo;0;L;;;;;N;;;;; +14FF;CANADIAN SYLLABICS WEST-CREE SWOO;Lo;0;L;;;;;N;;;;; +1500;CANADIAN SYLLABICS SWA;Lo;0;L;;;;;N;;;;; +1501;CANADIAN SYLLABICS WEST-CREE SWA;Lo;0;L;;;;;N;;;;; +1502;CANADIAN SYLLABICS SWAA;Lo;0;L;;;;;N;;;;; +1503;CANADIAN SYLLABICS WEST-CREE SWAA;Lo;0;L;;;;;N;;;;; +1504;CANADIAN SYLLABICS NASKAPI SWAA;Lo;0;L;;;;;N;;;;; +1505;CANADIAN SYLLABICS S;Lo;0;L;;;;;N;;;;; +1506;CANADIAN SYLLABICS ATHAPASCAN S;Lo;0;L;;;;;N;;;;; +1507;CANADIAN SYLLABICS SW;Lo;0;L;;;;;N;;;;; +1508;CANADIAN SYLLABICS BLACKFOOT S;Lo;0;L;;;;;N;;;;; +1509;CANADIAN SYLLABICS MOOSE-CREE SK;Lo;0;L;;;;;N;;;;; +150A;CANADIAN SYLLABICS NASKAPI SKW;Lo;0;L;;;;;N;;;;; +150B;CANADIAN SYLLABICS NASKAPI S-W;Lo;0;L;;;;;N;;;;; +150C;CANADIAN SYLLABICS NASKAPI SPWA;Lo;0;L;;;;;N;;;;; +150D;CANADIAN SYLLABICS NASKAPI STWA;Lo;0;L;;;;;N;;;;; +150E;CANADIAN SYLLABICS NASKAPI SKWA;Lo;0;L;;;;;N;;;;; +150F;CANADIAN SYLLABICS NASKAPI SCWA;Lo;0;L;;;;;N;;;;; +1510;CANADIAN SYLLABICS SHE;Lo;0;L;;;;;N;;;;; +1511;CANADIAN SYLLABICS SHI;Lo;0;L;;;;;N;;;;; +1512;CANADIAN SYLLABICS SHII;Lo;0;L;;;;;N;;;;; +1513;CANADIAN SYLLABICS SHO;Lo;0;L;;;;;N;;;;; +1514;CANADIAN SYLLABICS SHOO;Lo;0;L;;;;;N;;;;; +1515;CANADIAN SYLLABICS SHA;Lo;0;L;;;;;N;;;;; +1516;CANADIAN SYLLABICS SHAA;Lo;0;L;;;;;N;;;;; +1517;CANADIAN SYLLABICS SHWE;Lo;0;L;;;;;N;;;;; +1518;CANADIAN SYLLABICS WEST-CREE SHWE;Lo;0;L;;;;;N;;;;; +1519;CANADIAN SYLLABICS SHWI;Lo;0;L;;;;;N;;;;; +151A;CANADIAN SYLLABICS WEST-CREE SHWI;Lo;0;L;;;;;N;;;;; +151B;CANADIAN SYLLABICS SHWII;Lo;0;L;;;;;N;;;;; +151C;CANADIAN SYLLABICS WEST-CREE SHWII;Lo;0;L;;;;;N;;;;; +151D;CANADIAN SYLLABICS SHWO;Lo;0;L;;;;;N;;;;; +151E;CANADIAN SYLLABICS WEST-CREE SHWO;Lo;0;L;;;;;N;;;;; +151F;CANADIAN SYLLABICS SHWOO;Lo;0;L;;;;;N;;;;; +1520;CANADIAN SYLLABICS WEST-CREE SHWOO;Lo;0;L;;;;;N;;;;; +1521;CANADIAN SYLLABICS SHWA;Lo;0;L;;;;;N;;;;; +1522;CANADIAN SYLLABICS WEST-CREE SHWA;Lo;0;L;;;;;N;;;;; +1523;CANADIAN SYLLABICS SHWAA;Lo;0;L;;;;;N;;;;; +1524;CANADIAN SYLLABICS WEST-CREE SHWAA;Lo;0;L;;;;;N;;;;; +1525;CANADIAN SYLLABICS SH;Lo;0;L;;;;;N;;;;; +1526;CANADIAN SYLLABICS YE;Lo;0;L;;;;;N;;;;; +1527;CANADIAN SYLLABICS YAAI;Lo;0;L;;;;;N;;;;; +1528;CANADIAN SYLLABICS YI;Lo;0;L;;;;;N;;;;; +1529;CANADIAN SYLLABICS YII;Lo;0;L;;;;;N;;;;; +152A;CANADIAN SYLLABICS YO;Lo;0;L;;;;;N;;;;; +152B;CANADIAN SYLLABICS YOO;Lo;0;L;;;;;N;;;;; +152C;CANADIAN SYLLABICS Y-CREE YOO;Lo;0;L;;;;;N;;;;; +152D;CANADIAN SYLLABICS YA;Lo;0;L;;;;;N;;;;; +152E;CANADIAN SYLLABICS YAA;Lo;0;L;;;;;N;;;;; +152F;CANADIAN SYLLABICS YWE;Lo;0;L;;;;;N;;;;; +1530;CANADIAN SYLLABICS WEST-CREE YWE;Lo;0;L;;;;;N;;;;; +1531;CANADIAN SYLLABICS YWI;Lo;0;L;;;;;N;;;;; +1532;CANADIAN SYLLABICS WEST-CREE YWI;Lo;0;L;;;;;N;;;;; +1533;CANADIAN SYLLABICS YWII;Lo;0;L;;;;;N;;;;; +1534;CANADIAN SYLLABICS WEST-CREE YWII;Lo;0;L;;;;;N;;;;; +1535;CANADIAN SYLLABICS YWO;Lo;0;L;;;;;N;;;;; +1536;CANADIAN SYLLABICS WEST-CREE YWO;Lo;0;L;;;;;N;;;;; +1537;CANADIAN SYLLABICS YWOO;Lo;0;L;;;;;N;;;;; +1538;CANADIAN SYLLABICS WEST-CREE YWOO;Lo;0;L;;;;;N;;;;; +1539;CANADIAN SYLLABICS YWA;Lo;0;L;;;;;N;;;;; +153A;CANADIAN SYLLABICS WEST-CREE YWA;Lo;0;L;;;;;N;;;;; +153B;CANADIAN SYLLABICS YWAA;Lo;0;L;;;;;N;;;;; +153C;CANADIAN SYLLABICS WEST-CREE YWAA;Lo;0;L;;;;;N;;;;; +153D;CANADIAN SYLLABICS NASKAPI YWAA;Lo;0;L;;;;;N;;;;; +153E;CANADIAN SYLLABICS Y;Lo;0;L;;;;;N;;;;; +153F;CANADIAN SYLLABICS BIBLE-CREE Y;Lo;0;L;;;;;N;;;;; +1540;CANADIAN SYLLABICS WEST-CREE Y;Lo;0;L;;;;;N;;;;; +1541;CANADIAN SYLLABICS SAYISI YI;Lo;0;L;;;;;N;;;;; +1542;CANADIAN SYLLABICS RE;Lo;0;L;;;;;N;;;;; +1543;CANADIAN SYLLABICS R-CREE RE;Lo;0;L;;;;;N;;;;; +1544;CANADIAN SYLLABICS WEST-CREE LE;Lo;0;L;;;;;N;;;;; +1545;CANADIAN SYLLABICS RAAI;Lo;0;L;;;;;N;;;;; +1546;CANADIAN SYLLABICS RI;Lo;0;L;;;;;N;;;;; +1547;CANADIAN SYLLABICS RII;Lo;0;L;;;;;N;;;;; +1548;CANADIAN SYLLABICS RO;Lo;0;L;;;;;N;;;;; +1549;CANADIAN SYLLABICS ROO;Lo;0;L;;;;;N;;;;; +154A;CANADIAN SYLLABICS WEST-CREE LO;Lo;0;L;;;;;N;;;;; +154B;CANADIAN SYLLABICS RA;Lo;0;L;;;;;N;;;;; +154C;CANADIAN SYLLABICS RAA;Lo;0;L;;;;;N;;;;; +154D;CANADIAN SYLLABICS WEST-CREE LA;Lo;0;L;;;;;N;;;;; +154E;CANADIAN SYLLABICS RWAA;Lo;0;L;;;;;N;;;;; +154F;CANADIAN SYLLABICS WEST-CREE RWAA;Lo;0;L;;;;;N;;;;; +1550;CANADIAN SYLLABICS R;Lo;0;L;;;;;N;;;;; +1551;CANADIAN SYLLABICS WEST-CREE R;Lo;0;L;;;;;N;;;;; +1552;CANADIAN SYLLABICS MEDIAL R;Lo;0;L;;;;;N;;;;; +1553;CANADIAN SYLLABICS FE;Lo;0;L;;;;;N;;;;; +1554;CANADIAN SYLLABICS FAAI;Lo;0;L;;;;;N;;;;; +1555;CANADIAN SYLLABICS FI;Lo;0;L;;;;;N;;;;; +1556;CANADIAN SYLLABICS FII;Lo;0;L;;;;;N;;;;; +1557;CANADIAN SYLLABICS FO;Lo;0;L;;;;;N;;;;; +1558;CANADIAN SYLLABICS FOO;Lo;0;L;;;;;N;;;;; +1559;CANADIAN SYLLABICS FA;Lo;0;L;;;;;N;;;;; +155A;CANADIAN SYLLABICS FAA;Lo;0;L;;;;;N;;;;; +155B;CANADIAN SYLLABICS FWAA;Lo;0;L;;;;;N;;;;; +155C;CANADIAN SYLLABICS WEST-CREE FWAA;Lo;0;L;;;;;N;;;;; +155D;CANADIAN SYLLABICS F;Lo;0;L;;;;;N;;;;; +155E;CANADIAN SYLLABICS THE;Lo;0;L;;;;;N;;;;; +155F;CANADIAN SYLLABICS N-CREE THE;Lo;0;L;;;;;N;;;;; +1560;CANADIAN SYLLABICS THI;Lo;0;L;;;;;N;;;;; +1561;CANADIAN SYLLABICS N-CREE THI;Lo;0;L;;;;;N;;;;; +1562;CANADIAN SYLLABICS THII;Lo;0;L;;;;;N;;;;; +1563;CANADIAN SYLLABICS N-CREE THII;Lo;0;L;;;;;N;;;;; +1564;CANADIAN SYLLABICS THO;Lo;0;L;;;;;N;;;;; +1565;CANADIAN SYLLABICS THOO;Lo;0;L;;;;;N;;;;; +1566;CANADIAN SYLLABICS THA;Lo;0;L;;;;;N;;;;; +1567;CANADIAN SYLLABICS THAA;Lo;0;L;;;;;N;;;;; +1568;CANADIAN SYLLABICS THWAA;Lo;0;L;;;;;N;;;;; +1569;CANADIAN SYLLABICS WEST-CREE THWAA;Lo;0;L;;;;;N;;;;; +156A;CANADIAN SYLLABICS TH;Lo;0;L;;;;;N;;;;; +156B;CANADIAN SYLLABICS TTHE;Lo;0;L;;;;;N;;;;; +156C;CANADIAN SYLLABICS TTHI;Lo;0;L;;;;;N;;;;; +156D;CANADIAN SYLLABICS TTHO;Lo;0;L;;;;;N;;;;; +156E;CANADIAN SYLLABICS TTHA;Lo;0;L;;;;;N;;;;; +156F;CANADIAN SYLLABICS TTH;Lo;0;L;;;;;N;;;;; +1570;CANADIAN SYLLABICS TYE;Lo;0;L;;;;;N;;;;; +1571;CANADIAN SYLLABICS TYI;Lo;0;L;;;;;N;;;;; +1572;CANADIAN SYLLABICS TYO;Lo;0;L;;;;;N;;;;; +1573;CANADIAN SYLLABICS TYA;Lo;0;L;;;;;N;;;;; +1574;CANADIAN SYLLABICS NUNAVIK HE;Lo;0;L;;;;;N;;;;; +1575;CANADIAN SYLLABICS NUNAVIK HI;Lo;0;L;;;;;N;;;;; +1576;CANADIAN SYLLABICS NUNAVIK HII;Lo;0;L;;;;;N;;;;; +1577;CANADIAN SYLLABICS NUNAVIK HO;Lo;0;L;;;;;N;;;;; +1578;CANADIAN SYLLABICS NUNAVIK HOO;Lo;0;L;;;;;N;;;;; +1579;CANADIAN SYLLABICS NUNAVIK HA;Lo;0;L;;;;;N;;;;; +157A;CANADIAN SYLLABICS NUNAVIK HAA;Lo;0;L;;;;;N;;;;; +157B;CANADIAN SYLLABICS NUNAVIK H;Lo;0;L;;;;;N;;;;; +157C;CANADIAN SYLLABICS NUNAVUT H;Lo;0;L;;;;;N;;;;; +157D;CANADIAN SYLLABICS HK;Lo;0;L;;;;;N;;;;; +157E;CANADIAN SYLLABICS QAAI;Lo;0;L;;;;;N;;;;; +157F;CANADIAN SYLLABICS QI;Lo;0;L;;;;;N;;;;; +1580;CANADIAN SYLLABICS QII;Lo;0;L;;;;;N;;;;; +1581;CANADIAN SYLLABICS QO;Lo;0;L;;;;;N;;;;; +1582;CANADIAN SYLLABICS QOO;Lo;0;L;;;;;N;;;;; +1583;CANADIAN SYLLABICS QA;Lo;0;L;;;;;N;;;;; +1584;CANADIAN SYLLABICS QAA;Lo;0;L;;;;;N;;;;; +1585;CANADIAN SYLLABICS Q;Lo;0;L;;;;;N;;;;; +1586;CANADIAN SYLLABICS TLHE;Lo;0;L;;;;;N;;;;; +1587;CANADIAN SYLLABICS TLHI;Lo;0;L;;;;;N;;;;; +1588;CANADIAN SYLLABICS TLHO;Lo;0;L;;;;;N;;;;; +1589;CANADIAN SYLLABICS TLHA;Lo;0;L;;;;;N;;;;; +158A;CANADIAN SYLLABICS WEST-CREE RE;Lo;0;L;;;;;N;;;;; +158B;CANADIAN SYLLABICS WEST-CREE RI;Lo;0;L;;;;;N;;;;; +158C;CANADIAN SYLLABICS WEST-CREE RO;Lo;0;L;;;;;N;;;;; +158D;CANADIAN SYLLABICS WEST-CREE RA;Lo;0;L;;;;;N;;;;; +158E;CANADIAN SYLLABICS NGAAI;Lo;0;L;;;;;N;;;;; +158F;CANADIAN SYLLABICS NGI;Lo;0;L;;;;;N;;;;; +1590;CANADIAN SYLLABICS NGII;Lo;0;L;;;;;N;;;;; +1591;CANADIAN SYLLABICS NGO;Lo;0;L;;;;;N;;;;; +1592;CANADIAN SYLLABICS NGOO;Lo;0;L;;;;;N;;;;; +1593;CANADIAN SYLLABICS NGA;Lo;0;L;;;;;N;;;;; +1594;CANADIAN SYLLABICS NGAA;Lo;0;L;;;;;N;;;;; +1595;CANADIAN SYLLABICS NG;Lo;0;L;;;;;N;;;;; +1596;CANADIAN SYLLABICS NNG;Lo;0;L;;;;;N;;;;; +1597;CANADIAN SYLLABICS SAYISI SHE;Lo;0;L;;;;;N;;;;; +1598;CANADIAN SYLLABICS SAYISI SHI;Lo;0;L;;;;;N;;;;; +1599;CANADIAN SYLLABICS SAYISI SHO;Lo;0;L;;;;;N;;;;; +159A;CANADIAN SYLLABICS SAYISI SHA;Lo;0;L;;;;;N;;;;; +159B;CANADIAN SYLLABICS WOODS-CREE THE;Lo;0;L;;;;;N;;;;; +159C;CANADIAN SYLLABICS WOODS-CREE THI;Lo;0;L;;;;;N;;;;; +159D;CANADIAN SYLLABICS WOODS-CREE THO;Lo;0;L;;;;;N;;;;; +159E;CANADIAN SYLLABICS WOODS-CREE THA;Lo;0;L;;;;;N;;;;; +159F;CANADIAN SYLLABICS WOODS-CREE TH;Lo;0;L;;;;;N;;;;; +15A0;CANADIAN SYLLABICS LHI;Lo;0;L;;;;;N;;;;; +15A1;CANADIAN SYLLABICS LHII;Lo;0;L;;;;;N;;;;; +15A2;CANADIAN SYLLABICS LHO;Lo;0;L;;;;;N;;;;; +15A3;CANADIAN SYLLABICS LHOO;Lo;0;L;;;;;N;;;;; +15A4;CANADIAN SYLLABICS LHA;Lo;0;L;;;;;N;;;;; +15A5;CANADIAN SYLLABICS LHAA;Lo;0;L;;;;;N;;;;; +15A6;CANADIAN SYLLABICS LH;Lo;0;L;;;;;N;;;;; +15A7;CANADIAN SYLLABICS TH-CREE THE;Lo;0;L;;;;;N;;;;; +15A8;CANADIAN SYLLABICS TH-CREE THI;Lo;0;L;;;;;N;;;;; +15A9;CANADIAN SYLLABICS TH-CREE THII;Lo;0;L;;;;;N;;;;; +15AA;CANADIAN SYLLABICS TH-CREE THO;Lo;0;L;;;;;N;;;;; +15AB;CANADIAN SYLLABICS TH-CREE THOO;Lo;0;L;;;;;N;;;;; +15AC;CANADIAN SYLLABICS TH-CREE THA;Lo;0;L;;;;;N;;;;; +15AD;CANADIAN SYLLABICS TH-CREE THAA;Lo;0;L;;;;;N;;;;; +15AE;CANADIAN SYLLABICS TH-CREE TH;Lo;0;L;;;;;N;;;;; +15AF;CANADIAN SYLLABICS AIVILIK B;Lo;0;L;;;;;N;;;;; +15B0;CANADIAN SYLLABICS BLACKFOOT E;Lo;0;L;;;;;N;;;;; +15B1;CANADIAN SYLLABICS BLACKFOOT I;Lo;0;L;;;;;N;;;;; +15B2;CANADIAN SYLLABICS BLACKFOOT O;Lo;0;L;;;;;N;;;;; +15B3;CANADIAN SYLLABICS BLACKFOOT A;Lo;0;L;;;;;N;;;;; +15B4;CANADIAN SYLLABICS BLACKFOOT WE;Lo;0;L;;;;;N;;;;; +15B5;CANADIAN SYLLABICS BLACKFOOT WI;Lo;0;L;;;;;N;;;;; +15B6;CANADIAN SYLLABICS BLACKFOOT WO;Lo;0;L;;;;;N;;;;; +15B7;CANADIAN SYLLABICS BLACKFOOT WA;Lo;0;L;;;;;N;;;;; +15B8;CANADIAN SYLLABICS BLACKFOOT NE;Lo;0;L;;;;;N;;;;; +15B9;CANADIAN SYLLABICS BLACKFOOT NI;Lo;0;L;;;;;N;;;;; +15BA;CANADIAN SYLLABICS BLACKFOOT NO;Lo;0;L;;;;;N;;;;; +15BB;CANADIAN SYLLABICS BLACKFOOT NA;Lo;0;L;;;;;N;;;;; +15BC;CANADIAN SYLLABICS BLACKFOOT KE;Lo;0;L;;;;;N;;;;; +15BD;CANADIAN SYLLABICS BLACKFOOT KI;Lo;0;L;;;;;N;;;;; +15BE;CANADIAN SYLLABICS BLACKFOOT KO;Lo;0;L;;;;;N;;;;; +15BF;CANADIAN SYLLABICS BLACKFOOT KA;Lo;0;L;;;;;N;;;;; +15C0;CANADIAN SYLLABICS SAYISI HE;Lo;0;L;;;;;N;;;;; +15C1;CANADIAN SYLLABICS SAYISI HI;Lo;0;L;;;;;N;;;;; +15C2;CANADIAN SYLLABICS SAYISI HO;Lo;0;L;;;;;N;;;;; +15C3;CANADIAN SYLLABICS SAYISI HA;Lo;0;L;;;;;N;;;;; +15C4;CANADIAN SYLLABICS CARRIER GHU;Lo;0;L;;;;;N;;;;; +15C5;CANADIAN SYLLABICS CARRIER GHO;Lo;0;L;;;;;N;;;;; +15C6;CANADIAN SYLLABICS CARRIER GHE;Lo;0;L;;;;;N;;;;; +15C7;CANADIAN SYLLABICS CARRIER GHEE;Lo;0;L;;;;;N;;;;; +15C8;CANADIAN SYLLABICS CARRIER GHI;Lo;0;L;;;;;N;;;;; +15C9;CANADIAN SYLLABICS CARRIER GHA;Lo;0;L;;;;;N;;;;; +15CA;CANADIAN SYLLABICS CARRIER RU;Lo;0;L;;;;;N;;;;; +15CB;CANADIAN SYLLABICS CARRIER RO;Lo;0;L;;;;;N;;;;; +15CC;CANADIAN SYLLABICS CARRIER RE;Lo;0;L;;;;;N;;;;; +15CD;CANADIAN SYLLABICS CARRIER REE;Lo;0;L;;;;;N;;;;; +15CE;CANADIAN SYLLABICS CARRIER RI;Lo;0;L;;;;;N;;;;; +15CF;CANADIAN SYLLABICS CARRIER RA;Lo;0;L;;;;;N;;;;; +15D0;CANADIAN SYLLABICS CARRIER WU;Lo;0;L;;;;;N;;;;; +15D1;CANADIAN SYLLABICS CARRIER WO;Lo;0;L;;;;;N;;;;; +15D2;CANADIAN SYLLABICS CARRIER WE;Lo;0;L;;;;;N;;;;; +15D3;CANADIAN SYLLABICS CARRIER WEE;Lo;0;L;;;;;N;;;;; +15D4;CANADIAN SYLLABICS CARRIER WI;Lo;0;L;;;;;N;;;;; +15D5;CANADIAN SYLLABICS CARRIER WA;Lo;0;L;;;;;N;;;;; +15D6;CANADIAN SYLLABICS CARRIER HWU;Lo;0;L;;;;;N;;;;; +15D7;CANADIAN SYLLABICS CARRIER HWO;Lo;0;L;;;;;N;;;;; +15D8;CANADIAN SYLLABICS CARRIER HWE;Lo;0;L;;;;;N;;;;; +15D9;CANADIAN SYLLABICS CARRIER HWEE;Lo;0;L;;;;;N;;;;; +15DA;CANADIAN SYLLABICS CARRIER HWI;Lo;0;L;;;;;N;;;;; +15DB;CANADIAN SYLLABICS CARRIER HWA;Lo;0;L;;;;;N;;;;; +15DC;CANADIAN SYLLABICS CARRIER THU;Lo;0;L;;;;;N;;;;; +15DD;CANADIAN SYLLABICS CARRIER THO;Lo;0;L;;;;;N;;;;; +15DE;CANADIAN SYLLABICS CARRIER THE;Lo;0;L;;;;;N;;;;; +15DF;CANADIAN SYLLABICS CARRIER THEE;Lo;0;L;;;;;N;;;;; +15E0;CANADIAN SYLLABICS CARRIER THI;Lo;0;L;;;;;N;;;;; +15E1;CANADIAN SYLLABICS CARRIER THA;Lo;0;L;;;;;N;;;;; +15E2;CANADIAN SYLLABICS CARRIER TTU;Lo;0;L;;;;;N;;;;; +15E3;CANADIAN SYLLABICS CARRIER TTO;Lo;0;L;;;;;N;;;;; +15E4;CANADIAN SYLLABICS CARRIER TTE;Lo;0;L;;;;;N;;;;; +15E5;CANADIAN SYLLABICS CARRIER TTEE;Lo;0;L;;;;;N;;;;; +15E6;CANADIAN SYLLABICS CARRIER TTI;Lo;0;L;;;;;N;;;;; +15E7;CANADIAN SYLLABICS CARRIER TTA;Lo;0;L;;;;;N;;;;; +15E8;CANADIAN SYLLABICS CARRIER PU;Lo;0;L;;;;;N;;;;; +15E9;CANADIAN SYLLABICS CARRIER PO;Lo;0;L;;;;;N;;;;; +15EA;CANADIAN SYLLABICS CARRIER PE;Lo;0;L;;;;;N;;;;; +15EB;CANADIAN SYLLABICS CARRIER PEE;Lo;0;L;;;;;N;;;;; +15EC;CANADIAN SYLLABICS CARRIER PI;Lo;0;L;;;;;N;;;;; +15ED;CANADIAN SYLLABICS CARRIER PA;Lo;0;L;;;;;N;;;;; +15EE;CANADIAN SYLLABICS CARRIER P;Lo;0;L;;;;;N;;;;; +15EF;CANADIAN SYLLABICS CARRIER GU;Lo;0;L;;;;;N;;;;; +15F0;CANADIAN SYLLABICS CARRIER GO;Lo;0;L;;;;;N;;;;; +15F1;CANADIAN SYLLABICS CARRIER GE;Lo;0;L;;;;;N;;;;; +15F2;CANADIAN SYLLABICS CARRIER GEE;Lo;0;L;;;;;N;;;;; +15F3;CANADIAN SYLLABICS CARRIER GI;Lo;0;L;;;;;N;;;;; +15F4;CANADIAN SYLLABICS CARRIER GA;Lo;0;L;;;;;N;;;;; +15F5;CANADIAN SYLLABICS CARRIER KHU;Lo;0;L;;;;;N;;;;; +15F6;CANADIAN SYLLABICS CARRIER KHO;Lo;0;L;;;;;N;;;;; +15F7;CANADIAN SYLLABICS CARRIER KHE;Lo;0;L;;;;;N;;;;; +15F8;CANADIAN SYLLABICS CARRIER KHEE;Lo;0;L;;;;;N;;;;; +15F9;CANADIAN SYLLABICS CARRIER KHI;Lo;0;L;;;;;N;;;;; +15FA;CANADIAN SYLLABICS CARRIER KHA;Lo;0;L;;;;;N;;;;; +15FB;CANADIAN SYLLABICS CARRIER KKU;Lo;0;L;;;;;N;;;;; +15FC;CANADIAN SYLLABICS CARRIER KKO;Lo;0;L;;;;;N;;;;; +15FD;CANADIAN SYLLABICS CARRIER KKE;Lo;0;L;;;;;N;;;;; +15FE;CANADIAN SYLLABICS CARRIER KKEE;Lo;0;L;;;;;N;;;;; +15FF;CANADIAN SYLLABICS CARRIER KKI;Lo;0;L;;;;;N;;;;; +1600;CANADIAN SYLLABICS CARRIER KKA;Lo;0;L;;;;;N;;;;; +1601;CANADIAN SYLLABICS CARRIER KK;Lo;0;L;;;;;N;;;;; +1602;CANADIAN SYLLABICS CARRIER NU;Lo;0;L;;;;;N;;;;; +1603;CANADIAN SYLLABICS CARRIER NO;Lo;0;L;;;;;N;;;;; +1604;CANADIAN SYLLABICS CARRIER NE;Lo;0;L;;;;;N;;;;; +1605;CANADIAN SYLLABICS CARRIER NEE;Lo;0;L;;;;;N;;;;; +1606;CANADIAN SYLLABICS CARRIER NI;Lo;0;L;;;;;N;;;;; +1607;CANADIAN SYLLABICS CARRIER NA;Lo;0;L;;;;;N;;;;; +1608;CANADIAN SYLLABICS CARRIER MU;Lo;0;L;;;;;N;;;;; +1609;CANADIAN SYLLABICS CARRIER MO;Lo;0;L;;;;;N;;;;; +160A;CANADIAN SYLLABICS CARRIER ME;Lo;0;L;;;;;N;;;;; +160B;CANADIAN SYLLABICS CARRIER MEE;Lo;0;L;;;;;N;;;;; +160C;CANADIAN SYLLABICS CARRIER MI;Lo;0;L;;;;;N;;;;; +160D;CANADIAN SYLLABICS CARRIER MA;Lo;0;L;;;;;N;;;;; +160E;CANADIAN SYLLABICS CARRIER YU;Lo;0;L;;;;;N;;;;; +160F;CANADIAN SYLLABICS CARRIER YO;Lo;0;L;;;;;N;;;;; +1610;CANADIAN SYLLABICS CARRIER YE;Lo;0;L;;;;;N;;;;; +1611;CANADIAN SYLLABICS CARRIER YEE;Lo;0;L;;;;;N;;;;; +1612;CANADIAN SYLLABICS CARRIER YI;Lo;0;L;;;;;N;;;;; +1613;CANADIAN SYLLABICS CARRIER YA;Lo;0;L;;;;;N;;;;; +1614;CANADIAN SYLLABICS CARRIER JU;Lo;0;L;;;;;N;;;;; +1615;CANADIAN SYLLABICS SAYISI JU;Lo;0;L;;;;;N;;;;; +1616;CANADIAN SYLLABICS CARRIER JO;Lo;0;L;;;;;N;;;;; +1617;CANADIAN SYLLABICS CARRIER JE;Lo;0;L;;;;;N;;;;; +1618;CANADIAN SYLLABICS CARRIER JEE;Lo;0;L;;;;;N;;;;; +1619;CANADIAN SYLLABICS CARRIER JI;Lo;0;L;;;;;N;;;;; +161A;CANADIAN SYLLABICS SAYISI JI;Lo;0;L;;;;;N;;;;; +161B;CANADIAN SYLLABICS CARRIER JA;Lo;0;L;;;;;N;;;;; +161C;CANADIAN SYLLABICS CARRIER JJU;Lo;0;L;;;;;N;;;;; +161D;CANADIAN SYLLABICS CARRIER JJO;Lo;0;L;;;;;N;;;;; +161E;CANADIAN SYLLABICS CARRIER JJE;Lo;0;L;;;;;N;;;;; +161F;CANADIAN SYLLABICS CARRIER JJEE;Lo;0;L;;;;;N;;;;; +1620;CANADIAN SYLLABICS CARRIER JJI;Lo;0;L;;;;;N;;;;; +1621;CANADIAN SYLLABICS CARRIER JJA;Lo;0;L;;;;;N;;;;; +1622;CANADIAN SYLLABICS CARRIER LU;Lo;0;L;;;;;N;;;;; +1623;CANADIAN SYLLABICS CARRIER LO;Lo;0;L;;;;;N;;;;; +1624;CANADIAN SYLLABICS CARRIER LE;Lo;0;L;;;;;N;;;;; +1625;CANADIAN SYLLABICS CARRIER LEE;Lo;0;L;;;;;N;;;;; +1626;CANADIAN SYLLABICS CARRIER LI;Lo;0;L;;;;;N;;;;; +1627;CANADIAN SYLLABICS CARRIER LA;Lo;0;L;;;;;N;;;;; +1628;CANADIAN SYLLABICS CARRIER DLU;Lo;0;L;;;;;N;;;;; +1629;CANADIAN SYLLABICS CARRIER DLO;Lo;0;L;;;;;N;;;;; +162A;CANADIAN SYLLABICS CARRIER DLE;Lo;0;L;;;;;N;;;;; +162B;CANADIAN SYLLABICS CARRIER DLEE;Lo;0;L;;;;;N;;;;; +162C;CANADIAN SYLLABICS CARRIER DLI;Lo;0;L;;;;;N;;;;; +162D;CANADIAN SYLLABICS CARRIER DLA;Lo;0;L;;;;;N;;;;; +162E;CANADIAN SYLLABICS CARRIER LHU;Lo;0;L;;;;;N;;;;; +162F;CANADIAN SYLLABICS CARRIER LHO;Lo;0;L;;;;;N;;;;; +1630;CANADIAN SYLLABICS CARRIER LHE;Lo;0;L;;;;;N;;;;; +1631;CANADIAN SYLLABICS CARRIER LHEE;Lo;0;L;;;;;N;;;;; +1632;CANADIAN SYLLABICS CARRIER LHI;Lo;0;L;;;;;N;;;;; +1633;CANADIAN SYLLABICS CARRIER LHA;Lo;0;L;;;;;N;;;;; +1634;CANADIAN SYLLABICS CARRIER TLHU;Lo;0;L;;;;;N;;;;; +1635;CANADIAN SYLLABICS CARRIER TLHO;Lo;0;L;;;;;N;;;;; +1636;CANADIAN SYLLABICS CARRIER TLHE;Lo;0;L;;;;;N;;;;; +1637;CANADIAN SYLLABICS CARRIER TLHEE;Lo;0;L;;;;;N;;;;; +1638;CANADIAN SYLLABICS CARRIER TLHI;Lo;0;L;;;;;N;;;;; +1639;CANADIAN SYLLABICS CARRIER TLHA;Lo;0;L;;;;;N;;;;; +163A;CANADIAN SYLLABICS CARRIER TLU;Lo;0;L;;;;;N;;;;; +163B;CANADIAN SYLLABICS CARRIER TLO;Lo;0;L;;;;;N;;;;; +163C;CANADIAN SYLLABICS CARRIER TLE;Lo;0;L;;;;;N;;;;; +163D;CANADIAN SYLLABICS CARRIER TLEE;Lo;0;L;;;;;N;;;;; +163E;CANADIAN SYLLABICS CARRIER TLI;Lo;0;L;;;;;N;;;;; +163F;CANADIAN SYLLABICS CARRIER TLA;Lo;0;L;;;;;N;;;;; +1640;CANADIAN SYLLABICS CARRIER ZU;Lo;0;L;;;;;N;;;;; +1641;CANADIAN SYLLABICS CARRIER ZO;Lo;0;L;;;;;N;;;;; +1642;CANADIAN SYLLABICS CARRIER ZE;Lo;0;L;;;;;N;;;;; +1643;CANADIAN SYLLABICS CARRIER ZEE;Lo;0;L;;;;;N;;;;; +1644;CANADIAN SYLLABICS CARRIER ZI;Lo;0;L;;;;;N;;;;; +1645;CANADIAN SYLLABICS CARRIER ZA;Lo;0;L;;;;;N;;;;; +1646;CANADIAN SYLLABICS CARRIER Z;Lo;0;L;;;;;N;;;;; +1647;CANADIAN SYLLABICS CARRIER INITIAL Z;Lo;0;L;;;;;N;;;;; +1648;CANADIAN SYLLABICS CARRIER DZU;Lo;0;L;;;;;N;;;;; +1649;CANADIAN SYLLABICS CARRIER DZO;Lo;0;L;;;;;N;;;;; +164A;CANADIAN SYLLABICS CARRIER DZE;Lo;0;L;;;;;N;;;;; +164B;CANADIAN SYLLABICS CARRIER DZEE;Lo;0;L;;;;;N;;;;; +164C;CANADIAN SYLLABICS CARRIER DZI;Lo;0;L;;;;;N;;;;; +164D;CANADIAN SYLLABICS CARRIER DZA;Lo;0;L;;;;;N;;;;; +164E;CANADIAN SYLLABICS CARRIER SU;Lo;0;L;;;;;N;;;;; +164F;CANADIAN SYLLABICS CARRIER SO;Lo;0;L;;;;;N;;;;; +1650;CANADIAN SYLLABICS CARRIER SE;Lo;0;L;;;;;N;;;;; +1651;CANADIAN SYLLABICS CARRIER SEE;Lo;0;L;;;;;N;;;;; +1652;CANADIAN SYLLABICS CARRIER SI;Lo;0;L;;;;;N;;;;; +1653;CANADIAN SYLLABICS CARRIER SA;Lo;0;L;;;;;N;;;;; +1654;CANADIAN SYLLABICS CARRIER SHU;Lo;0;L;;;;;N;;;;; +1655;CANADIAN SYLLABICS CARRIER SHO;Lo;0;L;;;;;N;;;;; +1656;CANADIAN SYLLABICS CARRIER SHE;Lo;0;L;;;;;N;;;;; +1657;CANADIAN SYLLABICS CARRIER SHEE;Lo;0;L;;;;;N;;;;; +1658;CANADIAN SYLLABICS CARRIER SHI;Lo;0;L;;;;;N;;;;; +1659;CANADIAN SYLLABICS CARRIER SHA;Lo;0;L;;;;;N;;;;; +165A;CANADIAN SYLLABICS CARRIER SH;Lo;0;L;;;;;N;;;;; +165B;CANADIAN SYLLABICS CARRIER TSU;Lo;0;L;;;;;N;;;;; +165C;CANADIAN SYLLABICS CARRIER TSO;Lo;0;L;;;;;N;;;;; +165D;CANADIAN SYLLABICS CARRIER TSE;Lo;0;L;;;;;N;;;;; +165E;CANADIAN SYLLABICS CARRIER TSEE;Lo;0;L;;;;;N;;;;; +165F;CANADIAN SYLLABICS CARRIER TSI;Lo;0;L;;;;;N;;;;; +1660;CANADIAN SYLLABICS CARRIER TSA;Lo;0;L;;;;;N;;;;; +1661;CANADIAN SYLLABICS CARRIER CHU;Lo;0;L;;;;;N;;;;; +1662;CANADIAN SYLLABICS CARRIER CHO;Lo;0;L;;;;;N;;;;; +1663;CANADIAN SYLLABICS CARRIER CHE;Lo;0;L;;;;;N;;;;; +1664;CANADIAN SYLLABICS CARRIER CHEE;Lo;0;L;;;;;N;;;;; +1665;CANADIAN SYLLABICS CARRIER CHI;Lo;0;L;;;;;N;;;;; +1666;CANADIAN SYLLABICS CARRIER CHA;Lo;0;L;;;;;N;;;;; +1667;CANADIAN SYLLABICS CARRIER TTSU;Lo;0;L;;;;;N;;;;; +1668;CANADIAN SYLLABICS CARRIER TTSO;Lo;0;L;;;;;N;;;;; +1669;CANADIAN SYLLABICS CARRIER TTSE;Lo;0;L;;;;;N;;;;; +166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;; +166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;; +166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;; +166D;CANADIAN SYLLABICS CHI SIGN;Po;0;L;;;;;N;;;;; +166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;; +166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;; +1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;; +1671;CANADIAN SYLLABICS NNGI;Lo;0;L;;;;;N;;;;; +1672;CANADIAN SYLLABICS NNGII;Lo;0;L;;;;;N;;;;; +1673;CANADIAN SYLLABICS NNGO;Lo;0;L;;;;;N;;;;; +1674;CANADIAN SYLLABICS NNGOO;Lo;0;L;;;;;N;;;;; +1675;CANADIAN SYLLABICS NNGA;Lo;0;L;;;;;N;;;;; +1676;CANADIAN SYLLABICS NNGAA;Lo;0;L;;;;;N;;;;; +1677;CANADIAN SYLLABICS WOODS-CREE THWEE;Lo;0;L;;;;;N;;;;; +1678;CANADIAN SYLLABICS WOODS-CREE THWI;Lo;0;L;;;;;N;;;;; +1679;CANADIAN SYLLABICS WOODS-CREE THWII;Lo;0;L;;;;;N;;;;; +167A;CANADIAN SYLLABICS WOODS-CREE THWO;Lo;0;L;;;;;N;;;;; +167B;CANADIAN SYLLABICS WOODS-CREE THWOO;Lo;0;L;;;;;N;;;;; +167C;CANADIAN SYLLABICS WOODS-CREE THWA;Lo;0;L;;;;;N;;;;; +167D;CANADIAN SYLLABICS WOODS-CREE THWAA;Lo;0;L;;;;;N;;;;; +167E;CANADIAN SYLLABICS WOODS-CREE FINAL TH;Lo;0;L;;;;;N;;;;; +167F;CANADIAN SYLLABICS BLACKFOOT W;Lo;0;L;;;;;N;;;;; +1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;; +1681;OGHAM LETTER BEITH;Lo;0;L;;;;;N;;;;; +1682;OGHAM LETTER LUIS;Lo;0;L;;;;;N;;;;; +1683;OGHAM LETTER FEARN;Lo;0;L;;;;;N;;;;; +1684;OGHAM LETTER SAIL;Lo;0;L;;;;;N;;;;; +1685;OGHAM LETTER NION;Lo;0;L;;;;;N;;;;; +1686;OGHAM LETTER UATH;Lo;0;L;;;;;N;;;;; +1687;OGHAM LETTER DAIR;Lo;0;L;;;;;N;;;;; +1688;OGHAM LETTER TINNE;Lo;0;L;;;;;N;;;;; +1689;OGHAM LETTER COLL;Lo;0;L;;;;;N;;;;; +168A;OGHAM LETTER CEIRT;Lo;0;L;;;;;N;;;;; +168B;OGHAM LETTER MUIN;Lo;0;L;;;;;N;;;;; +168C;OGHAM LETTER GORT;Lo;0;L;;;;;N;;;;; +168D;OGHAM LETTER NGEADAL;Lo;0;L;;;;;N;;;;; +168E;OGHAM LETTER STRAIF;Lo;0;L;;;;;N;;;;; +168F;OGHAM LETTER RUIS;Lo;0;L;;;;;N;;;;; +1690;OGHAM LETTER AILM;Lo;0;L;;;;;N;;;;; +1691;OGHAM LETTER ONN;Lo;0;L;;;;;N;;;;; +1692;OGHAM LETTER UR;Lo;0;L;;;;;N;;;;; +1693;OGHAM LETTER EADHADH;Lo;0;L;;;;;N;;;;; +1694;OGHAM LETTER IODHADH;Lo;0;L;;;;;N;;;;; +1695;OGHAM LETTER EABHADH;Lo;0;L;;;;;N;;;;; +1696;OGHAM LETTER OR;Lo;0;L;;;;;N;;;;; +1697;OGHAM LETTER UILLEANN;Lo;0;L;;;;;N;;;;; +1698;OGHAM LETTER IFIN;Lo;0;L;;;;;N;;;;; +1699;OGHAM LETTER EAMHANCHOLL;Lo;0;L;;;;;N;;;;; +169A;OGHAM LETTER PEITH;Lo;0;L;;;;;N;;;;; +169B;OGHAM FEATHER MARK;Ps;0;ON;;;;;Y;;;;; +169C;OGHAM REVERSED FEATHER MARK;Pe;0;ON;;;;;Y;;;;; +16A0;RUNIC LETTER FEHU FEOH FE F;Lo;0;L;;;;;N;;;;; +16A1;RUNIC LETTER V;Lo;0;L;;;;;N;;;;; +16A2;RUNIC LETTER URUZ UR U;Lo;0;L;;;;;N;;;;; +16A3;RUNIC LETTER YR;Lo;0;L;;;;;N;;;;; +16A4;RUNIC LETTER Y;Lo;0;L;;;;;N;;;;; +16A5;RUNIC LETTER W;Lo;0;L;;;;;N;;;;; +16A6;RUNIC LETTER THURISAZ THURS THORN;Lo;0;L;;;;;N;;;;; +16A7;RUNIC LETTER ETH;Lo;0;L;;;;;N;;;;; +16A8;RUNIC LETTER ANSUZ A;Lo;0;L;;;;;N;;;;; +16A9;RUNIC LETTER OS O;Lo;0;L;;;;;N;;;;; +16AA;RUNIC LETTER AC A;Lo;0;L;;;;;N;;;;; +16AB;RUNIC LETTER AESC;Lo;0;L;;;;;N;;;;; +16AC;RUNIC LETTER LONG-BRANCH-OSS O;Lo;0;L;;;;;N;;;;; +16AD;RUNIC LETTER SHORT-TWIG-OSS O;Lo;0;L;;;;;N;;;;; +16AE;RUNIC LETTER O;Lo;0;L;;;;;N;;;;; +16AF;RUNIC LETTER OE;Lo;0;L;;;;;N;;;;; +16B0;RUNIC LETTER ON;Lo;0;L;;;;;N;;;;; +16B1;RUNIC LETTER RAIDO RAD REID R;Lo;0;L;;;;;N;;;;; +16B2;RUNIC LETTER KAUNA;Lo;0;L;;;;;N;;;;; +16B3;RUNIC LETTER CEN;Lo;0;L;;;;;N;;;;; +16B4;RUNIC LETTER KAUN K;Lo;0;L;;;;;N;;;;; +16B5;RUNIC LETTER G;Lo;0;L;;;;;N;;;;; +16B6;RUNIC LETTER ENG;Lo;0;L;;;;;N;;;;; +16B7;RUNIC LETTER GEBO GYFU G;Lo;0;L;;;;;N;;;;; +16B8;RUNIC LETTER GAR;Lo;0;L;;;;;N;;;;; +16B9;RUNIC LETTER WUNJO WYNN W;Lo;0;L;;;;;N;;;;; +16BA;RUNIC LETTER HAGLAZ H;Lo;0;L;;;;;N;;;;; +16BB;RUNIC LETTER HAEGL H;Lo;0;L;;;;;N;;;;; +16BC;RUNIC LETTER LONG-BRANCH-HAGALL H;Lo;0;L;;;;;N;;;;; +16BD;RUNIC LETTER SHORT-TWIG-HAGALL H;Lo;0;L;;;;;N;;;;; +16BE;RUNIC LETTER NAUDIZ NYD NAUD N;Lo;0;L;;;;;N;;;;; +16BF;RUNIC LETTER SHORT-TWIG-NAUD N;Lo;0;L;;;;;N;;;;; +16C0;RUNIC LETTER DOTTED-N;Lo;0;L;;;;;N;;;;; +16C1;RUNIC LETTER ISAZ IS ISS I;Lo;0;L;;;;;N;;;;; +16C2;RUNIC LETTER E;Lo;0;L;;;;;N;;;;; +16C3;RUNIC LETTER JERAN J;Lo;0;L;;;;;N;;;;; +16C4;RUNIC LETTER GER;Lo;0;L;;;;;N;;;;; +16C5;RUNIC LETTER LONG-BRANCH-AR AE;Lo;0;L;;;;;N;;;;; +16C6;RUNIC LETTER SHORT-TWIG-AR A;Lo;0;L;;;;;N;;;;; +16C7;RUNIC LETTER IWAZ EOH;Lo;0;L;;;;;N;;;;; +16C8;RUNIC LETTER PERTHO PEORTH P;Lo;0;L;;;;;N;;;;; +16C9;RUNIC LETTER ALGIZ EOLHX;Lo;0;L;;;;;N;;;;; +16CA;RUNIC LETTER SOWILO S;Lo;0;L;;;;;N;;;;; +16CB;RUNIC LETTER SIGEL LONG-BRANCH-SOL S;Lo;0;L;;;;;N;;;;; +16CC;RUNIC LETTER SHORT-TWIG-SOL S;Lo;0;L;;;;;N;;;;; +16CD;RUNIC LETTER C;Lo;0;L;;;;;N;;;;; +16CE;RUNIC LETTER Z;Lo;0;L;;;;;N;;;;; +16CF;RUNIC LETTER TIWAZ TIR TYR T;Lo;0;L;;;;;N;;;;; +16D0;RUNIC LETTER SHORT-TWIG-TYR T;Lo;0;L;;;;;N;;;;; +16D1;RUNIC LETTER D;Lo;0;L;;;;;N;;;;; +16D2;RUNIC LETTER BERKANAN BEORC BJARKAN B;Lo;0;L;;;;;N;;;;; +16D3;RUNIC LETTER SHORT-TWIG-BJARKAN B;Lo;0;L;;;;;N;;;;; +16D4;RUNIC LETTER DOTTED-P;Lo;0;L;;;;;N;;;;; +16D5;RUNIC LETTER OPEN-P;Lo;0;L;;;;;N;;;;; +16D6;RUNIC LETTER EHWAZ EH E;Lo;0;L;;;;;N;;;;; +16D7;RUNIC LETTER MANNAZ MAN M;Lo;0;L;;;;;N;;;;; +16D8;RUNIC LETTER LONG-BRANCH-MADR M;Lo;0;L;;;;;N;;;;; +16D9;RUNIC LETTER SHORT-TWIG-MADR M;Lo;0;L;;;;;N;;;;; +16DA;RUNIC LETTER LAUKAZ LAGU LOGR L;Lo;0;L;;;;;N;;;;; +16DB;RUNIC LETTER DOTTED-L;Lo;0;L;;;;;N;;;;; +16DC;RUNIC LETTER INGWAZ;Lo;0;L;;;;;N;;;;; +16DD;RUNIC LETTER ING;Lo;0;L;;;;;N;;;;; +16DE;RUNIC LETTER DAGAZ DAEG D;Lo;0;L;;;;;N;;;;; +16DF;RUNIC LETTER OTHALAN ETHEL O;Lo;0;L;;;;;N;;;;; +16E0;RUNIC LETTER EAR;Lo;0;L;;;;;N;;;;; +16E1;RUNIC LETTER IOR;Lo;0;L;;;;;N;;;;; +16E2;RUNIC LETTER CWEORTH;Lo;0;L;;;;;N;;;;; +16E3;RUNIC LETTER CALC;Lo;0;L;;;;;N;;;;; +16E4;RUNIC LETTER CEALC;Lo;0;L;;;;;N;;;;; +16E5;RUNIC LETTER STAN;Lo;0;L;;;;;N;;;;; +16E6;RUNIC LETTER LONG-BRANCH-YR;Lo;0;L;;;;;N;;;;; +16E7;RUNIC LETTER SHORT-TWIG-YR;Lo;0;L;;;;;N;;;;; +16E8;RUNIC LETTER ICELANDIC-YR;Lo;0;L;;;;;N;;;;; +16E9;RUNIC LETTER Q;Lo;0;L;;;;;N;;;;; +16EA;RUNIC LETTER X;Lo;0;L;;;;;N;;;;; +16EB;RUNIC SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;; +16EC;RUNIC MULTIPLE PUNCTUATION;Po;0;L;;;;;N;;;;; +16ED;RUNIC CROSS PUNCTUATION;Po;0;L;;;;;N;;;;; +16EE;RUNIC ARLAUG SYMBOL;Nl;0;L;;;;17;N;;;;; +16EF;RUNIC TVIMADUR SYMBOL;Nl;0;L;;;;18;N;;;;; +16F0;RUNIC BELGTHOR SYMBOL;Nl;0;L;;;;19;N;;;;; +1700;TAGALOG LETTER A;Lo;0;L;;;;;N;;;;; +1701;TAGALOG LETTER I;Lo;0;L;;;;;N;;;;; +1702;TAGALOG LETTER U;Lo;0;L;;;;;N;;;;; +1703;TAGALOG LETTER KA;Lo;0;L;;;;;N;;;;; +1704;TAGALOG LETTER GA;Lo;0;L;;;;;N;;;;; +1705;TAGALOG LETTER NGA;Lo;0;L;;;;;N;;;;; +1706;TAGALOG LETTER TA;Lo;0;L;;;;;N;;;;; +1707;TAGALOG LETTER DA;Lo;0;L;;;;;N;;;;; +1708;TAGALOG LETTER NA;Lo;0;L;;;;;N;;;;; +1709;TAGALOG LETTER PA;Lo;0;L;;;;;N;;;;; +170A;TAGALOG LETTER BA;Lo;0;L;;;;;N;;;;; +170B;TAGALOG LETTER MA;Lo;0;L;;;;;N;;;;; +170C;TAGALOG LETTER YA;Lo;0;L;;;;;N;;;;; +170E;TAGALOG LETTER LA;Lo;0;L;;;;;N;;;;; +170F;TAGALOG LETTER WA;Lo;0;L;;;;;N;;;;; +1710;TAGALOG LETTER SA;Lo;0;L;;;;;N;;;;; +1711;TAGALOG LETTER HA;Lo;0;L;;;;;N;;;;; +1712;TAGALOG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1713;TAGALOG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1714;TAGALOG SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +1720;HANUNOO LETTER A;Lo;0;L;;;;;N;;;;; +1721;HANUNOO LETTER I;Lo;0;L;;;;;N;;;;; +1722;HANUNOO LETTER U;Lo;0;L;;;;;N;;;;; +1723;HANUNOO LETTER KA;Lo;0;L;;;;;N;;;;; +1724;HANUNOO LETTER GA;Lo;0;L;;;;;N;;;;; +1725;HANUNOO LETTER NGA;Lo;0;L;;;;;N;;;;; +1726;HANUNOO LETTER TA;Lo;0;L;;;;;N;;;;; +1727;HANUNOO LETTER DA;Lo;0;L;;;;;N;;;;; +1728;HANUNOO LETTER NA;Lo;0;L;;;;;N;;;;; +1729;HANUNOO LETTER PA;Lo;0;L;;;;;N;;;;; +172A;HANUNOO LETTER BA;Lo;0;L;;;;;N;;;;; +172B;HANUNOO LETTER MA;Lo;0;L;;;;;N;;;;; +172C;HANUNOO LETTER YA;Lo;0;L;;;;;N;;;;; +172D;HANUNOO LETTER RA;Lo;0;L;;;;;N;;;;; +172E;HANUNOO LETTER LA;Lo;0;L;;;;;N;;;;; +172F;HANUNOO LETTER WA;Lo;0;L;;;;;N;;;;; +1730;HANUNOO LETTER SA;Lo;0;L;;;;;N;;;;; +1731;HANUNOO LETTER HA;Lo;0;L;;;;;N;;;;; +1732;HANUNOO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1733;HANUNOO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1734;HANUNOO SIGN PAMUDPOD;Mn;9;NSM;;;;;N;;;;; +1735;PHILIPPINE SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;; +1736;PHILIPPINE DOUBLE PUNCTUATION;Po;0;L;;;;;N;;;;; +1740;BUHID LETTER A;Lo;0;L;;;;;N;;;;; +1741;BUHID LETTER I;Lo;0;L;;;;;N;;;;; +1742;BUHID LETTER U;Lo;0;L;;;;;N;;;;; +1743;BUHID LETTER KA;Lo;0;L;;;;;N;;;;; +1744;BUHID LETTER GA;Lo;0;L;;;;;N;;;;; +1745;BUHID LETTER NGA;Lo;0;L;;;;;N;;;;; +1746;BUHID LETTER TA;Lo;0;L;;;;;N;;;;; +1747;BUHID LETTER DA;Lo;0;L;;;;;N;;;;; +1748;BUHID LETTER NA;Lo;0;L;;;;;N;;;;; +1749;BUHID LETTER PA;Lo;0;L;;;;;N;;;;; +174A;BUHID LETTER BA;Lo;0;L;;;;;N;;;;; +174B;BUHID LETTER MA;Lo;0;L;;;;;N;;;;; +174C;BUHID LETTER YA;Lo;0;L;;;;;N;;;;; +174D;BUHID LETTER RA;Lo;0;L;;;;;N;;;;; +174E;BUHID LETTER LA;Lo;0;L;;;;;N;;;;; +174F;BUHID LETTER WA;Lo;0;L;;;;;N;;;;; +1750;BUHID LETTER SA;Lo;0;L;;;;;N;;;;; +1751;BUHID LETTER HA;Lo;0;L;;;;;N;;;;; +1752;BUHID VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1753;BUHID VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1760;TAGBANWA LETTER A;Lo;0;L;;;;;N;;;;; +1761;TAGBANWA LETTER I;Lo;0;L;;;;;N;;;;; +1762;TAGBANWA LETTER U;Lo;0;L;;;;;N;;;;; +1763;TAGBANWA LETTER KA;Lo;0;L;;;;;N;;;;; +1764;TAGBANWA LETTER GA;Lo;0;L;;;;;N;;;;; +1765;TAGBANWA LETTER NGA;Lo;0;L;;;;;N;;;;; +1766;TAGBANWA LETTER TA;Lo;0;L;;;;;N;;;;; +1767;TAGBANWA LETTER DA;Lo;0;L;;;;;N;;;;; +1768;TAGBANWA LETTER NA;Lo;0;L;;;;;N;;;;; +1769;TAGBANWA LETTER PA;Lo;0;L;;;;;N;;;;; +176A;TAGBANWA LETTER BA;Lo;0;L;;;;;N;;;;; +176B;TAGBANWA LETTER MA;Lo;0;L;;;;;N;;;;; +176C;TAGBANWA LETTER YA;Lo;0;L;;;;;N;;;;; +176E;TAGBANWA LETTER LA;Lo;0;L;;;;;N;;;;; +176F;TAGBANWA LETTER WA;Lo;0;L;;;;;N;;;;; +1770;TAGBANWA LETTER SA;Lo;0;L;;;;;N;;;;; +1772;TAGBANWA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1773;TAGBANWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1780;KHMER LETTER KA;Lo;0;L;;;;;N;;;;; +1781;KHMER LETTER KHA;Lo;0;L;;;;;N;;;;; +1782;KHMER LETTER KO;Lo;0;L;;;;;N;;;;; +1783;KHMER LETTER KHO;Lo;0;L;;;;;N;;;;; +1784;KHMER LETTER NGO;Lo;0;L;;;;;N;;;;; +1785;KHMER LETTER CA;Lo;0;L;;;;;N;;;;; +1786;KHMER LETTER CHA;Lo;0;L;;;;;N;;;;; +1787;KHMER LETTER CO;Lo;0;L;;;;;N;;;;; +1788;KHMER LETTER CHO;Lo;0;L;;;;;N;;;;; +1789;KHMER LETTER NYO;Lo;0;L;;;;;N;;;;; +178A;KHMER LETTER DA;Lo;0;L;;;;;N;;;;; +178B;KHMER LETTER TTHA;Lo;0;L;;;;;N;;;;; +178C;KHMER LETTER DO;Lo;0;L;;;;;N;;;;; +178D;KHMER LETTER TTHO;Lo;0;L;;;;;N;;;;; +178E;KHMER LETTER NNO;Lo;0;L;;;;;N;;;;; +178F;KHMER LETTER TA;Lo;0;L;;;;;N;;;;; +1790;KHMER LETTER THA;Lo;0;L;;;;;N;;;;; +1791;KHMER LETTER TO;Lo;0;L;;;;;N;;;;; +1792;KHMER LETTER THO;Lo;0;L;;;;;N;;;;; +1793;KHMER LETTER NO;Lo;0;L;;;;;N;;;;; +1794;KHMER LETTER BA;Lo;0;L;;;;;N;;;;; +1795;KHMER LETTER PHA;Lo;0;L;;;;;N;;;;; +1796;KHMER LETTER PO;Lo;0;L;;;;;N;;;;; +1797;KHMER LETTER PHO;Lo;0;L;;;;;N;;;;; +1798;KHMER LETTER MO;Lo;0;L;;;;;N;;;;; +1799;KHMER LETTER YO;Lo;0;L;;;;;N;;;;; +179A;KHMER LETTER RO;Lo;0;L;;;;;N;;;;; +179B;KHMER LETTER LO;Lo;0;L;;;;;N;;;;; +179C;KHMER LETTER VO;Lo;0;L;;;;;N;;;;; +179D;KHMER LETTER SHA;Lo;0;L;;;;;N;;;;; +179E;KHMER LETTER SSO;Lo;0;L;;;;;N;;;;; +179F;KHMER LETTER SA;Lo;0;L;;;;;N;;;;; +17A0;KHMER LETTER HA;Lo;0;L;;;;;N;;;;; +17A1;KHMER LETTER LA;Lo;0;L;;;;;N;;;;; +17A2;KHMER LETTER QA;Lo;0;L;;;;;N;;;;; +17A3;KHMER INDEPENDENT VOWEL QAQ;Lo;0;L;;;;;N;;;;; +17A4;KHMER INDEPENDENT VOWEL QAA;Lo;0;L;;;;;N;;;;; +17A5;KHMER INDEPENDENT VOWEL QI;Lo;0;L;;;;;N;;;;; +17A6;KHMER INDEPENDENT VOWEL QII;Lo;0;L;;;;;N;;;;; +17A7;KHMER INDEPENDENT VOWEL QU;Lo;0;L;;;;;N;;;;; +17A8;KHMER INDEPENDENT VOWEL QUK;Lo;0;L;;;;;N;;;;; +17A9;KHMER INDEPENDENT VOWEL QUU;Lo;0;L;;;;;N;;;;; +17AA;KHMER INDEPENDENT VOWEL QUUV;Lo;0;L;;;;;N;;;;; +17AB;KHMER INDEPENDENT VOWEL RY;Lo;0;L;;;;;N;;;;; +17AC;KHMER INDEPENDENT VOWEL RYY;Lo;0;L;;;;;N;;;;; +17AD;KHMER INDEPENDENT VOWEL LY;Lo;0;L;;;;;N;;;;; +17AE;KHMER INDEPENDENT VOWEL LYY;Lo;0;L;;;;;N;;;;; +17AF;KHMER INDEPENDENT VOWEL QE;Lo;0;L;;;;;N;;;;; +17B0;KHMER INDEPENDENT VOWEL QAI;Lo;0;L;;;;;N;;;;; +17B1;KHMER INDEPENDENT VOWEL QOO TYPE ONE;Lo;0;L;;;;;N;;;;; +17B2;KHMER INDEPENDENT VOWEL QOO TYPE TWO;Lo;0;L;;;;;N;;;;; +17B3;KHMER INDEPENDENT VOWEL QAU;Lo;0;L;;;;;N;;;;; +17B4;KHMER VOWEL INHERENT AQ;Cf;0;L;;;;;N;;;;; +17B5;KHMER VOWEL INHERENT AA;Cf;0;L;;;;;N;;;;; +17B6;KHMER VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +17B7;KHMER VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +17B8;KHMER VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +17B9;KHMER VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;; +17BA;KHMER VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;; +17BB;KHMER VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +17BC;KHMER VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +17BD;KHMER VOWEL SIGN UA;Mn;0;NSM;;;;;N;;;;; +17BE;KHMER VOWEL SIGN OE;Mc;0;L;;;;;N;;;;; +17BF;KHMER VOWEL SIGN YA;Mc;0;L;;;;;N;;;;; +17C0;KHMER VOWEL SIGN IE;Mc;0;L;;;;;N;;;;; +17C1;KHMER VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +17C2;KHMER VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; +17C3;KHMER VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +17C4;KHMER VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +17C5;KHMER VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +17C6;KHMER SIGN NIKAHIT;Mn;0;NSM;;;;;N;;;;; +17C7;KHMER SIGN REAHMUK;Mc;0;L;;;;;N;;;;; +17C8;KHMER SIGN YUUKALEAPINTU;Mc;0;L;;;;;N;;;;; +17C9;KHMER SIGN MUUSIKATOAN;Mn;0;NSM;;;;;N;;;;; +17CA;KHMER SIGN TRIISAP;Mn;0;NSM;;;;;N;;;;; +17CB;KHMER SIGN BANTOC;Mn;0;NSM;;;;;N;;;;; +17CC;KHMER SIGN ROBAT;Mn;0;NSM;;;;;N;;;;; +17CD;KHMER SIGN TOANDAKHIAT;Mn;0;NSM;;;;;N;;;;; +17CE;KHMER SIGN KAKABAT;Mn;0;NSM;;;;;N;;;;; +17CF;KHMER SIGN AHSDA;Mn;0;NSM;;;;;N;;;;; +17D0;KHMER SIGN SAMYOK SANNYA;Mn;0;NSM;;;;;N;;;;; +17D1;KHMER SIGN VIRIAM;Mn;0;NSM;;;;;N;;;;; +17D2;KHMER SIGN COENG;Mn;9;NSM;;;;;N;;;;; +17D3;KHMER SIGN BATHAMASAT;Mn;0;NSM;;;;;N;;;;; +17D4;KHMER SIGN KHAN;Po;0;L;;;;;N;;;;; +17D5;KHMER SIGN BARIYOOSAN;Po;0;L;;;;;N;;;;; +17D6;KHMER SIGN CAMNUC PII KUUH;Po;0;L;;;;;N;;;;; +17D7;KHMER SIGN LEK TOO;Lm;0;L;;;;;N;;;;; +17D8;KHMER SIGN BEYYAL;Po;0;L;;;;;N;;;;; +17D9;KHMER SIGN PHNAEK MUAN;Po;0;L;;;;;N;;;;; +17DA;KHMER SIGN KOOMUUT;Po;0;L;;;;;N;;;;; +17DB;KHMER CURRENCY SYMBOL RIEL;Sc;0;ET;;;;;N;;;;; +17DC;KHMER SIGN AVAKRAHASANYA;Lo;0;L;;;;;N;;;;; +17DD;KHMER SIGN ATTHACAN;Mn;230;NSM;;;;;N;;;;; +17E0;KHMER DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +17E1;KHMER DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +17E2;KHMER DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +17E3;KHMER DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +17E4;KHMER DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +17E5;KHMER DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +17E6;KHMER DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +17E7;KHMER DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +17E8;KHMER DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +17E9;KHMER DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +17F0;KHMER SYMBOL LEK ATTAK SON;No;0;ON;;;;0;N;;;;; +17F1;KHMER SYMBOL LEK ATTAK MUOY;No;0;ON;;;;1;N;;;;; +17F2;KHMER SYMBOL LEK ATTAK PII;No;0;ON;;;;2;N;;;;; +17F3;KHMER SYMBOL LEK ATTAK BEI;No;0;ON;;;;3;N;;;;; +17F4;KHMER SYMBOL LEK ATTAK BUON;No;0;ON;;;;4;N;;;;; +17F5;KHMER SYMBOL LEK ATTAK PRAM;No;0;ON;;;;5;N;;;;; +17F6;KHMER SYMBOL LEK ATTAK PRAM-MUOY;No;0;ON;;;;6;N;;;;; +17F7;KHMER SYMBOL LEK ATTAK PRAM-PII;No;0;ON;;;;7;N;;;;; +17F8;KHMER SYMBOL LEK ATTAK PRAM-BEI;No;0;ON;;;;8;N;;;;; +17F9;KHMER SYMBOL LEK ATTAK PRAM-BUON;No;0;ON;;;;9;N;;;;; +1800;MONGOLIAN BIRGA;Po;0;ON;;;;;N;;;;; +1801;MONGOLIAN ELLIPSIS;Po;0;ON;;;;;N;;;;; +1802;MONGOLIAN COMMA;Po;0;ON;;;;;N;;;;; +1803;MONGOLIAN FULL STOP;Po;0;ON;;;;;N;;;;; +1804;MONGOLIAN COLON;Po;0;ON;;;;;N;;;;; +1805;MONGOLIAN FOUR DOTS;Po;0;ON;;;;;N;;;;; +1806;MONGOLIAN TODO SOFT HYPHEN;Pd;0;ON;;;;;N;;;;; +1807;MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER;Po;0;ON;;;;;N;;;;; +1808;MONGOLIAN MANCHU COMMA;Po;0;ON;;;;;N;;;;; +1809;MONGOLIAN MANCHU FULL STOP;Po;0;ON;;;;;N;;;;; +180A;MONGOLIAN NIRUGU;Po;0;ON;;;;;N;;;;; +180B;MONGOLIAN FREE VARIATION SELECTOR ONE;Mn;0;NSM;;;;;N;;;;; +180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;; +180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;; +180E;MONGOLIAN VOWEL SEPARATOR;Zs;0;WS;;;;;N;;;;; +1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1813;MONGOLIAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1814;MONGOLIAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1815;MONGOLIAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1816;MONGOLIAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1817;MONGOLIAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1818;MONGOLIAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1819;MONGOLIAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1820;MONGOLIAN LETTER A;Lo;0;L;;;;;N;;;;; +1821;MONGOLIAN LETTER E;Lo;0;L;;;;;N;;;;; +1822;MONGOLIAN LETTER I;Lo;0;L;;;;;N;;;;; +1823;MONGOLIAN LETTER O;Lo;0;L;;;;;N;;;;; +1824;MONGOLIAN LETTER U;Lo;0;L;;;;;N;;;;; +1825;MONGOLIAN LETTER OE;Lo;0;L;;;;;N;;;;; +1826;MONGOLIAN LETTER UE;Lo;0;L;;;;;N;;;;; +1827;MONGOLIAN LETTER EE;Lo;0;L;;;;;N;;;;; +1828;MONGOLIAN LETTER NA;Lo;0;L;;;;;N;;;;; +1829;MONGOLIAN LETTER ANG;Lo;0;L;;;;;N;;;;; +182A;MONGOLIAN LETTER BA;Lo;0;L;;;;;N;;;;; +182B;MONGOLIAN LETTER PA;Lo;0;L;;;;;N;;;;; +182C;MONGOLIAN LETTER QA;Lo;0;L;;;;;N;;;;; +182D;MONGOLIAN LETTER GA;Lo;0;L;;;;;N;;;;; +182E;MONGOLIAN LETTER MA;Lo;0;L;;;;;N;;;;; +182F;MONGOLIAN LETTER LA;Lo;0;L;;;;;N;;;;; +1830;MONGOLIAN LETTER SA;Lo;0;L;;;;;N;;;;; +1831;MONGOLIAN LETTER SHA;Lo;0;L;;;;;N;;;;; +1832;MONGOLIAN LETTER TA;Lo;0;L;;;;;N;;;;; +1833;MONGOLIAN LETTER DA;Lo;0;L;;;;;N;;;;; +1834;MONGOLIAN LETTER CHA;Lo;0;L;;;;;N;;;;; +1835;MONGOLIAN LETTER JA;Lo;0;L;;;;;N;;;;; +1836;MONGOLIAN LETTER YA;Lo;0;L;;;;;N;;;;; +1837;MONGOLIAN LETTER RA;Lo;0;L;;;;;N;;;;; +1838;MONGOLIAN LETTER WA;Lo;0;L;;;;;N;;;;; +1839;MONGOLIAN LETTER FA;Lo;0;L;;;;;N;;;;; +183A;MONGOLIAN LETTER KA;Lo;0;L;;;;;N;;;;; +183B;MONGOLIAN LETTER KHA;Lo;0;L;;;;;N;;;;; +183C;MONGOLIAN LETTER TSA;Lo;0;L;;;;;N;;;;; +183D;MONGOLIAN LETTER ZA;Lo;0;L;;;;;N;;;;; +183E;MONGOLIAN LETTER HAA;Lo;0;L;;;;;N;;;;; +183F;MONGOLIAN LETTER ZRA;Lo;0;L;;;;;N;;;;; +1840;MONGOLIAN LETTER LHA;Lo;0;L;;;;;N;;;;; +1841;MONGOLIAN LETTER ZHI;Lo;0;L;;;;;N;;;;; +1842;MONGOLIAN LETTER CHI;Lo;0;L;;;;;N;;;;; +1843;MONGOLIAN LETTER TODO LONG VOWEL SIGN;Lm;0;L;;;;;N;;;;; +1844;MONGOLIAN LETTER TODO E;Lo;0;L;;;;;N;;;;; +1845;MONGOLIAN LETTER TODO I;Lo;0;L;;;;;N;;;;; +1846;MONGOLIAN LETTER TODO O;Lo;0;L;;;;;N;;;;; +1847;MONGOLIAN LETTER TODO U;Lo;0;L;;;;;N;;;;; +1848;MONGOLIAN LETTER TODO OE;Lo;0;L;;;;;N;;;;; +1849;MONGOLIAN LETTER TODO UE;Lo;0;L;;;;;N;;;;; +184A;MONGOLIAN LETTER TODO ANG;Lo;0;L;;;;;N;;;;; +184B;MONGOLIAN LETTER TODO BA;Lo;0;L;;;;;N;;;;; +184C;MONGOLIAN LETTER TODO PA;Lo;0;L;;;;;N;;;;; +184D;MONGOLIAN LETTER TODO QA;Lo;0;L;;;;;N;;;;; +184E;MONGOLIAN LETTER TODO GA;Lo;0;L;;;;;N;;;;; +184F;MONGOLIAN LETTER TODO MA;Lo;0;L;;;;;N;;;;; +1850;MONGOLIAN LETTER TODO TA;Lo;0;L;;;;;N;;;;; +1851;MONGOLIAN LETTER TODO DA;Lo;0;L;;;;;N;;;;; +1852;MONGOLIAN LETTER TODO CHA;Lo;0;L;;;;;N;;;;; +1853;MONGOLIAN LETTER TODO JA;Lo;0;L;;;;;N;;;;; +1854;MONGOLIAN LETTER TODO TSA;Lo;0;L;;;;;N;;;;; +1855;MONGOLIAN LETTER TODO YA;Lo;0;L;;;;;N;;;;; +1856;MONGOLIAN LETTER TODO WA;Lo;0;L;;;;;N;;;;; +1857;MONGOLIAN LETTER TODO KA;Lo;0;L;;;;;N;;;;; +1858;MONGOLIAN LETTER TODO GAA;Lo;0;L;;;;;N;;;;; +1859;MONGOLIAN LETTER TODO HAA;Lo;0;L;;;;;N;;;;; +185A;MONGOLIAN LETTER TODO JIA;Lo;0;L;;;;;N;;;;; +185B;MONGOLIAN LETTER TODO NIA;Lo;0;L;;;;;N;;;;; +185C;MONGOLIAN LETTER TODO DZA;Lo;0;L;;;;;N;;;;; +185D;MONGOLIAN LETTER SIBE E;Lo;0;L;;;;;N;;;;; +185E;MONGOLIAN LETTER SIBE I;Lo;0;L;;;;;N;;;;; +185F;MONGOLIAN LETTER SIBE IY;Lo;0;L;;;;;N;;;;; +1860;MONGOLIAN LETTER SIBE UE;Lo;0;L;;;;;N;;;;; +1861;MONGOLIAN LETTER SIBE U;Lo;0;L;;;;;N;;;;; +1862;MONGOLIAN LETTER SIBE ANG;Lo;0;L;;;;;N;;;;; +1863;MONGOLIAN LETTER SIBE KA;Lo;0;L;;;;;N;;;;; +1864;MONGOLIAN LETTER SIBE GA;Lo;0;L;;;;;N;;;;; +1865;MONGOLIAN LETTER SIBE HA;Lo;0;L;;;;;N;;;;; +1866;MONGOLIAN LETTER SIBE PA;Lo;0;L;;;;;N;;;;; +1867;MONGOLIAN LETTER SIBE SHA;Lo;0;L;;;;;N;;;;; +1868;MONGOLIAN LETTER SIBE TA;Lo;0;L;;;;;N;;;;; +1869;MONGOLIAN LETTER SIBE DA;Lo;0;L;;;;;N;;;;; +186A;MONGOLIAN LETTER SIBE JA;Lo;0;L;;;;;N;;;;; +186B;MONGOLIAN LETTER SIBE FA;Lo;0;L;;;;;N;;;;; +186C;MONGOLIAN LETTER SIBE GAA;Lo;0;L;;;;;N;;;;; +186D;MONGOLIAN LETTER SIBE HAA;Lo;0;L;;;;;N;;;;; +186E;MONGOLIAN LETTER SIBE TSA;Lo;0;L;;;;;N;;;;; +186F;MONGOLIAN LETTER SIBE ZA;Lo;0;L;;;;;N;;;;; +1870;MONGOLIAN LETTER SIBE RAA;Lo;0;L;;;;;N;;;;; +1871;MONGOLIAN LETTER SIBE CHA;Lo;0;L;;;;;N;;;;; +1872;MONGOLIAN LETTER SIBE ZHA;Lo;0;L;;;;;N;;;;; +1873;MONGOLIAN LETTER MANCHU I;Lo;0;L;;;;;N;;;;; +1874;MONGOLIAN LETTER MANCHU KA;Lo;0;L;;;;;N;;;;; +1875;MONGOLIAN LETTER MANCHU RA;Lo;0;L;;;;;N;;;;; +1876;MONGOLIAN LETTER MANCHU FA;Lo;0;L;;;;;N;;;;; +1877;MONGOLIAN LETTER MANCHU ZHA;Lo;0;L;;;;;N;;;;; +1880;MONGOLIAN LETTER ALI GALI ANUSVARA ONE;Lo;0;L;;;;;N;;;;; +1881;MONGOLIAN LETTER ALI GALI VISARGA ONE;Lo;0;L;;;;;N;;;;; +1882;MONGOLIAN LETTER ALI GALI DAMARU;Lo;0;L;;;;;N;;;;; +1883;MONGOLIAN LETTER ALI GALI UBADAMA;Lo;0;L;;;;;N;;;;; +1884;MONGOLIAN LETTER ALI GALI INVERTED UBADAMA;Lo;0;L;;;;;N;;;;; +1885;MONGOLIAN LETTER ALI GALI BALUDA;Lo;0;L;;;;;N;;;;; +1886;MONGOLIAN LETTER ALI GALI THREE BALUDA;Lo;0;L;;;;;N;;;;; +1887;MONGOLIAN LETTER ALI GALI A;Lo;0;L;;;;;N;;;;; +1888;MONGOLIAN LETTER ALI GALI I;Lo;0;L;;;;;N;;;;; +1889;MONGOLIAN LETTER ALI GALI KA;Lo;0;L;;;;;N;;;;; +188A;MONGOLIAN LETTER ALI GALI NGA;Lo;0;L;;;;;N;;;;; +188B;MONGOLIAN LETTER ALI GALI CA;Lo;0;L;;;;;N;;;;; +188C;MONGOLIAN LETTER ALI GALI TTA;Lo;0;L;;;;;N;;;;; +188D;MONGOLIAN LETTER ALI GALI TTHA;Lo;0;L;;;;;N;;;;; +188E;MONGOLIAN LETTER ALI GALI DDA;Lo;0;L;;;;;N;;;;; +188F;MONGOLIAN LETTER ALI GALI NNA;Lo;0;L;;;;;N;;;;; +1890;MONGOLIAN LETTER ALI GALI TA;Lo;0;L;;;;;N;;;;; +1891;MONGOLIAN LETTER ALI GALI DA;Lo;0;L;;;;;N;;;;; +1892;MONGOLIAN LETTER ALI GALI PA;Lo;0;L;;;;;N;;;;; +1893;MONGOLIAN LETTER ALI GALI PHA;Lo;0;L;;;;;N;;;;; +1894;MONGOLIAN LETTER ALI GALI SSA;Lo;0;L;;;;;N;;;;; +1895;MONGOLIAN LETTER ALI GALI ZHA;Lo;0;L;;;;;N;;;;; +1896;MONGOLIAN LETTER ALI GALI ZA;Lo;0;L;;;;;N;;;;; +1897;MONGOLIAN LETTER ALI GALI AH;Lo;0;L;;;;;N;;;;; +1898;MONGOLIAN LETTER TODO ALI GALI TA;Lo;0;L;;;;;N;;;;; +1899;MONGOLIAN LETTER TODO ALI GALI ZHA;Lo;0;L;;;;;N;;;;; +189A;MONGOLIAN LETTER MANCHU ALI GALI GHA;Lo;0;L;;;;;N;;;;; +189B;MONGOLIAN LETTER MANCHU ALI GALI NGA;Lo;0;L;;;;;N;;;;; +189C;MONGOLIAN LETTER MANCHU ALI GALI CA;Lo;0;L;;;;;N;;;;; +189D;MONGOLIAN LETTER MANCHU ALI GALI JHA;Lo;0;L;;;;;N;;;;; +189E;MONGOLIAN LETTER MANCHU ALI GALI TTA;Lo;0;L;;;;;N;;;;; +189F;MONGOLIAN LETTER MANCHU ALI GALI DDHA;Lo;0;L;;;;;N;;;;; +18A0;MONGOLIAN LETTER MANCHU ALI GALI TA;Lo;0;L;;;;;N;;;;; +18A1;MONGOLIAN LETTER MANCHU ALI GALI DHA;Lo;0;L;;;;;N;;;;; +18A2;MONGOLIAN LETTER MANCHU ALI GALI SSA;Lo;0;L;;;;;N;;;;; +18A3;MONGOLIAN LETTER MANCHU ALI GALI CYA;Lo;0;L;;;;;N;;;;; +18A4;MONGOLIAN LETTER MANCHU ALI GALI ZHA;Lo;0;L;;;;;N;;;;; +18A5;MONGOLIAN LETTER MANCHU ALI GALI ZA;Lo;0;L;;;;;N;;;;; +18A6;MONGOLIAN LETTER ALI GALI HALF U;Lo;0;L;;;;;N;;;;; +18A7;MONGOLIAN LETTER ALI GALI HALF YA;Lo;0;L;;;;;N;;;;; +18A8;MONGOLIAN LETTER MANCHU ALI GALI BHA;Lo;0;L;;;;;N;;;;; +18A9;MONGOLIAN LETTER ALI GALI DAGALGA;Mn;228;NSM;;;;;N;;;;; +18AA;MONGOLIAN LETTER MANCHU ALI GALI LHA;Lo;0;L;;;;;N;;;;; +18B0;CANADIAN SYLLABICS OY;Lo;0;L;;;;;N;;;;; +18B1;CANADIAN SYLLABICS AY;Lo;0;L;;;;;N;;;;; +18B2;CANADIAN SYLLABICS AAY;Lo;0;L;;;;;N;;;;; +18B3;CANADIAN SYLLABICS WAY;Lo;0;L;;;;;N;;;;; +18B4;CANADIAN SYLLABICS POY;Lo;0;L;;;;;N;;;;; +18B5;CANADIAN SYLLABICS PAY;Lo;0;L;;;;;N;;;;; +18B6;CANADIAN SYLLABICS PWOY;Lo;0;L;;;;;N;;;;; +18B7;CANADIAN SYLLABICS TAY;Lo;0;L;;;;;N;;;;; +18B8;CANADIAN SYLLABICS KAY;Lo;0;L;;;;;N;;;;; +18B9;CANADIAN SYLLABICS KWAY;Lo;0;L;;;;;N;;;;; +18BA;CANADIAN SYLLABICS MAY;Lo;0;L;;;;;N;;;;; +18BB;CANADIAN SYLLABICS NOY;Lo;0;L;;;;;N;;;;; +18BC;CANADIAN SYLLABICS NAY;Lo;0;L;;;;;N;;;;; +18BD;CANADIAN SYLLABICS LAY;Lo;0;L;;;;;N;;;;; +18BE;CANADIAN SYLLABICS SOY;Lo;0;L;;;;;N;;;;; +18BF;CANADIAN SYLLABICS SAY;Lo;0;L;;;;;N;;;;; +18C0;CANADIAN SYLLABICS SHOY;Lo;0;L;;;;;N;;;;; +18C1;CANADIAN SYLLABICS SHAY;Lo;0;L;;;;;N;;;;; +18C2;CANADIAN SYLLABICS SHWOY;Lo;0;L;;;;;N;;;;; +18C3;CANADIAN SYLLABICS YOY;Lo;0;L;;;;;N;;;;; +18C4;CANADIAN SYLLABICS YAY;Lo;0;L;;;;;N;;;;; +18C5;CANADIAN SYLLABICS RAY;Lo;0;L;;;;;N;;;;; +18C6;CANADIAN SYLLABICS NWI;Lo;0;L;;;;;N;;;;; +18C7;CANADIAN SYLLABICS OJIBWAY NWI;Lo;0;L;;;;;N;;;;; +18C8;CANADIAN SYLLABICS NWII;Lo;0;L;;;;;N;;;;; +18C9;CANADIAN SYLLABICS OJIBWAY NWII;Lo;0;L;;;;;N;;;;; +18CA;CANADIAN SYLLABICS NWO;Lo;0;L;;;;;N;;;;; +18CB;CANADIAN SYLLABICS OJIBWAY NWO;Lo;0;L;;;;;N;;;;; +18CC;CANADIAN SYLLABICS NWOO;Lo;0;L;;;;;N;;;;; +18CD;CANADIAN SYLLABICS OJIBWAY NWOO;Lo;0;L;;;;;N;;;;; +18CE;CANADIAN SYLLABICS RWEE;Lo;0;L;;;;;N;;;;; +18CF;CANADIAN SYLLABICS RWI;Lo;0;L;;;;;N;;;;; +18D0;CANADIAN SYLLABICS RWII;Lo;0;L;;;;;N;;;;; +18D1;CANADIAN SYLLABICS RWO;Lo;0;L;;;;;N;;;;; +18D2;CANADIAN SYLLABICS RWOO;Lo;0;L;;;;;N;;;;; +18D3;CANADIAN SYLLABICS RWA;Lo;0;L;;;;;N;;;;; +18D4;CANADIAN SYLLABICS OJIBWAY P;Lo;0;L;;;;;N;;;;; +18D5;CANADIAN SYLLABICS OJIBWAY T;Lo;0;L;;;;;N;;;;; +18D6;CANADIAN SYLLABICS OJIBWAY K;Lo;0;L;;;;;N;;;;; +18D7;CANADIAN SYLLABICS OJIBWAY C;Lo;0;L;;;;;N;;;;; +18D8;CANADIAN SYLLABICS OJIBWAY M;Lo;0;L;;;;;N;;;;; +18D9;CANADIAN SYLLABICS OJIBWAY N;Lo;0;L;;;;;N;;;;; +18DA;CANADIAN SYLLABICS OJIBWAY S;Lo;0;L;;;;;N;;;;; +18DB;CANADIAN SYLLABICS OJIBWAY SH;Lo;0;L;;;;;N;;;;; +18DC;CANADIAN SYLLABICS EASTERN W;Lo;0;L;;;;;N;;;;; +18DD;CANADIAN SYLLABICS WESTERN W;Lo;0;L;;;;;N;;;;; +18DE;CANADIAN SYLLABICS FINAL SMALL RING;Lo;0;L;;;;;N;;;;; +18DF;CANADIAN SYLLABICS FINAL RAISED DOT;Lo;0;L;;;;;N;;;;; +18E0;CANADIAN SYLLABICS R-CREE RWE;Lo;0;L;;;;;N;;;;; +18E1;CANADIAN SYLLABICS WEST-CREE LOO;Lo;0;L;;;;;N;;;;; +18E2;CANADIAN SYLLABICS WEST-CREE LAA;Lo;0;L;;;;;N;;;;; +18E3;CANADIAN SYLLABICS THWE;Lo;0;L;;;;;N;;;;; +18E4;CANADIAN SYLLABICS THWA;Lo;0;L;;;;;N;;;;; +18E5;CANADIAN SYLLABICS TTHWE;Lo;0;L;;;;;N;;;;; +18E6;CANADIAN SYLLABICS TTHOO;Lo;0;L;;;;;N;;;;; +18E7;CANADIAN SYLLABICS TTHAA;Lo;0;L;;;;;N;;;;; +18E8;CANADIAN SYLLABICS TLHWE;Lo;0;L;;;;;N;;;;; +18E9;CANADIAN SYLLABICS TLHOO;Lo;0;L;;;;;N;;;;; +18EA;CANADIAN SYLLABICS SAYISI SHWE;Lo;0;L;;;;;N;;;;; +18EB;CANADIAN SYLLABICS SAYISI SHOO;Lo;0;L;;;;;N;;;;; +18EC;CANADIAN SYLLABICS SAYISI HOO;Lo;0;L;;;;;N;;;;; +18ED;CANADIAN SYLLABICS CARRIER GWU;Lo;0;L;;;;;N;;;;; +18EE;CANADIAN SYLLABICS CARRIER DENE GEE;Lo;0;L;;;;;N;;;;; +18EF;CANADIAN SYLLABICS CARRIER GAA;Lo;0;L;;;;;N;;;;; +18F0;CANADIAN SYLLABICS CARRIER GWA;Lo;0;L;;;;;N;;;;; +18F1;CANADIAN SYLLABICS SAYISI JUU;Lo;0;L;;;;;N;;;;; +18F2;CANADIAN SYLLABICS CARRIER JWA;Lo;0;L;;;;;N;;;;; +18F3;CANADIAN SYLLABICS BEAVER DENE L;Lo;0;L;;;;;N;;;;; +18F4;CANADIAN SYLLABICS BEAVER DENE R;Lo;0;L;;;;;N;;;;; +18F5;CANADIAN SYLLABICS CARRIER DENTAL S;Lo;0;L;;;;;N;;;;; +1900;LIMBU VOWEL-CARRIER LETTER;Lo;0;L;;;;;N;;;;; +1901;LIMBU LETTER KA;Lo;0;L;;;;;N;;;;; +1902;LIMBU LETTER KHA;Lo;0;L;;;;;N;;;;; +1903;LIMBU LETTER GA;Lo;0;L;;;;;N;;;;; +1904;LIMBU LETTER GHA;Lo;0;L;;;;;N;;;;; +1905;LIMBU LETTER NGA;Lo;0;L;;;;;N;;;;; +1906;LIMBU LETTER CA;Lo;0;L;;;;;N;;;;; +1907;LIMBU LETTER CHA;Lo;0;L;;;;;N;;;;; +1908;LIMBU LETTER JA;Lo;0;L;;;;;N;;;;; +1909;LIMBU LETTER JHA;Lo;0;L;;;;;N;;;;; +190A;LIMBU LETTER YAN;Lo;0;L;;;;;N;;;;; +190B;LIMBU LETTER TA;Lo;0;L;;;;;N;;;;; +190C;LIMBU LETTER THA;Lo;0;L;;;;;N;;;;; +190D;LIMBU LETTER DA;Lo;0;L;;;;;N;;;;; +190E;LIMBU LETTER DHA;Lo;0;L;;;;;N;;;;; +190F;LIMBU LETTER NA;Lo;0;L;;;;;N;;;;; +1910;LIMBU LETTER PA;Lo;0;L;;;;;N;;;;; +1911;LIMBU LETTER PHA;Lo;0;L;;;;;N;;;;; +1912;LIMBU LETTER BA;Lo;0;L;;;;;N;;;;; +1913;LIMBU LETTER BHA;Lo;0;L;;;;;N;;;;; +1914;LIMBU LETTER MA;Lo;0;L;;;;;N;;;;; +1915;LIMBU LETTER YA;Lo;0;L;;;;;N;;;;; +1916;LIMBU LETTER RA;Lo;0;L;;;;;N;;;;; +1917;LIMBU LETTER LA;Lo;0;L;;;;;N;;;;; +1918;LIMBU LETTER WA;Lo;0;L;;;;;N;;;;; +1919;LIMBU LETTER SHA;Lo;0;L;;;;;N;;;;; +191A;LIMBU LETTER SSA;Lo;0;L;;;;;N;;;;; +191B;LIMBU LETTER SA;Lo;0;L;;;;;N;;;;; +191C;LIMBU LETTER HA;Lo;0;L;;;;;N;;;;; +1920;LIMBU VOWEL SIGN A;Mn;0;NSM;;;;;N;;;;; +1921;LIMBU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1922;LIMBU VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1923;LIMBU VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +1924;LIMBU VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +1925;LIMBU VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +1926;LIMBU VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +1927;LIMBU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +1928;LIMBU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +1929;LIMBU SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;; +192A;LIMBU SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;; +192B;LIMBU SUBJOINED LETTER WA;Mc;0;L;;;;;N;;;;; +1930;LIMBU SMALL LETTER KA;Mc;0;L;;;;;N;;;;; +1931;LIMBU SMALL LETTER NGA;Mc;0;L;;;;;N;;;;; +1932;LIMBU SMALL LETTER ANUSVARA;Mn;0;NSM;;;;;N;;;;; +1933;LIMBU SMALL LETTER TA;Mc;0;L;;;;;N;;;;; +1934;LIMBU SMALL LETTER NA;Mc;0;L;;;;;N;;;;; +1935;LIMBU SMALL LETTER PA;Mc;0;L;;;;;N;;;;; +1936;LIMBU SMALL LETTER MA;Mc;0;L;;;;;N;;;;; +1937;LIMBU SMALL LETTER RA;Mc;0;L;;;;;N;;;;; +1938;LIMBU SMALL LETTER LA;Mc;0;L;;;;;N;;;;; +1939;LIMBU SIGN MUKPHRENG;Mn;222;NSM;;;;;N;;;;; +193A;LIMBU SIGN KEMPHRENG;Mn;230;NSM;;;;;N;;;;; +193B;LIMBU SIGN SA-I;Mn;220;NSM;;;;;N;;;;; +1940;LIMBU SIGN LOO;So;0;ON;;;;;N;;;;; +1944;LIMBU EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +1945;LIMBU QUESTION MARK;Po;0;ON;;;;;N;;;;; +1946;LIMBU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1947;LIMBU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1948;LIMBU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1949;LIMBU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +194A;LIMBU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +194B;LIMBU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +194C;LIMBU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +194D;LIMBU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +194E;LIMBU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +194F;LIMBU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1950;TAI LE LETTER KA;Lo;0;L;;;;;N;;;;; +1951;TAI LE LETTER XA;Lo;0;L;;;;;N;;;;; +1952;TAI LE LETTER NGA;Lo;0;L;;;;;N;;;;; +1953;TAI LE LETTER TSA;Lo;0;L;;;;;N;;;;; +1954;TAI LE LETTER SA;Lo;0;L;;;;;N;;;;; +1955;TAI LE LETTER YA;Lo;0;L;;;;;N;;;;; +1956;TAI LE LETTER TA;Lo;0;L;;;;;N;;;;; +1957;TAI LE LETTER THA;Lo;0;L;;;;;N;;;;; +1958;TAI LE LETTER LA;Lo;0;L;;;;;N;;;;; +1959;TAI LE LETTER PA;Lo;0;L;;;;;N;;;;; +195A;TAI LE LETTER PHA;Lo;0;L;;;;;N;;;;; +195B;TAI LE LETTER MA;Lo;0;L;;;;;N;;;;; +195C;TAI LE LETTER FA;Lo;0;L;;;;;N;;;;; +195D;TAI LE LETTER VA;Lo;0;L;;;;;N;;;;; +195E;TAI LE LETTER HA;Lo;0;L;;;;;N;;;;; +195F;TAI LE LETTER QA;Lo;0;L;;;;;N;;;;; +1960;TAI LE LETTER KHA;Lo;0;L;;;;;N;;;;; +1961;TAI LE LETTER TSHA;Lo;0;L;;;;;N;;;;; +1962;TAI LE LETTER NA;Lo;0;L;;;;;N;;;;; +1963;TAI LE LETTER A;Lo;0;L;;;;;N;;;;; +1964;TAI LE LETTER I;Lo;0;L;;;;;N;;;;; +1965;TAI LE LETTER EE;Lo;0;L;;;;;N;;;;; +1966;TAI LE LETTER EH;Lo;0;L;;;;;N;;;;; +1967;TAI LE LETTER U;Lo;0;L;;;;;N;;;;; +1968;TAI LE LETTER OO;Lo;0;L;;;;;N;;;;; +1969;TAI LE LETTER O;Lo;0;L;;;;;N;;;;; +196A;TAI LE LETTER UE;Lo;0;L;;;;;N;;;;; +196B;TAI LE LETTER E;Lo;0;L;;;;;N;;;;; +196C;TAI LE LETTER AUE;Lo;0;L;;;;;N;;;;; +196D;TAI LE LETTER AI;Lo;0;L;;;;;N;;;;; +1970;TAI LE LETTER TONE-2;Lo;0;L;;;;;N;;;;; +1971;TAI LE LETTER TONE-3;Lo;0;L;;;;;N;;;;; +1972;TAI LE LETTER TONE-4;Lo;0;L;;;;;N;;;;; +1973;TAI LE LETTER TONE-5;Lo;0;L;;;;;N;;;;; +1974;TAI LE LETTER TONE-6;Lo;0;L;;;;;N;;;;; +1980;NEW TAI LUE LETTER HIGH QA;Lo;0;L;;;;;N;;;;; +1981;NEW TAI LUE LETTER LOW QA;Lo;0;L;;;;;N;;;;; +1982;NEW TAI LUE LETTER HIGH KA;Lo;0;L;;;;;N;;;;; +1983;NEW TAI LUE LETTER HIGH XA;Lo;0;L;;;;;N;;;;; +1984;NEW TAI LUE LETTER HIGH NGA;Lo;0;L;;;;;N;;;;; +1985;NEW TAI LUE LETTER LOW KA;Lo;0;L;;;;;N;;;;; +1986;NEW TAI LUE LETTER LOW XA;Lo;0;L;;;;;N;;;;; +1987;NEW TAI LUE LETTER LOW NGA;Lo;0;L;;;;;N;;;;; +1988;NEW TAI LUE LETTER HIGH TSA;Lo;0;L;;;;;N;;;;; +1989;NEW TAI LUE LETTER HIGH SA;Lo;0;L;;;;;N;;;;; +198A;NEW TAI LUE LETTER HIGH YA;Lo;0;L;;;;;N;;;;; +198B;NEW TAI LUE LETTER LOW TSA;Lo;0;L;;;;;N;;;;; +198C;NEW TAI LUE LETTER LOW SA;Lo;0;L;;;;;N;;;;; +198D;NEW TAI LUE LETTER LOW YA;Lo;0;L;;;;;N;;;;; +198E;NEW TAI LUE LETTER HIGH TA;Lo;0;L;;;;;N;;;;; +198F;NEW TAI LUE LETTER HIGH THA;Lo;0;L;;;;;N;;;;; +1990;NEW TAI LUE LETTER HIGH NA;Lo;0;L;;;;;N;;;;; +1991;NEW TAI LUE LETTER LOW TA;Lo;0;L;;;;;N;;;;; +1992;NEW TAI LUE LETTER LOW THA;Lo;0;L;;;;;N;;;;; +1993;NEW TAI LUE LETTER LOW NA;Lo;0;L;;;;;N;;;;; +1994;NEW TAI LUE LETTER HIGH PA;Lo;0;L;;;;;N;;;;; +1995;NEW TAI LUE LETTER HIGH PHA;Lo;0;L;;;;;N;;;;; +1996;NEW TAI LUE LETTER HIGH MA;Lo;0;L;;;;;N;;;;; +1997;NEW TAI LUE LETTER LOW PA;Lo;0;L;;;;;N;;;;; +1998;NEW TAI LUE LETTER LOW PHA;Lo;0;L;;;;;N;;;;; +1999;NEW TAI LUE LETTER LOW MA;Lo;0;L;;;;;N;;;;; +199A;NEW TAI LUE LETTER HIGH FA;Lo;0;L;;;;;N;;;;; +199B;NEW TAI LUE LETTER HIGH VA;Lo;0;L;;;;;N;;;;; +199C;NEW TAI LUE LETTER HIGH LA;Lo;0;L;;;;;N;;;;; +199D;NEW TAI LUE LETTER LOW FA;Lo;0;L;;;;;N;;;;; +199E;NEW TAI LUE LETTER LOW VA;Lo;0;L;;;;;N;;;;; +199F;NEW TAI LUE LETTER LOW LA;Lo;0;L;;;;;N;;;;; +19A0;NEW TAI LUE LETTER HIGH HA;Lo;0;L;;;;;N;;;;; +19A1;NEW TAI LUE LETTER HIGH DA;Lo;0;L;;;;;N;;;;; +19A2;NEW TAI LUE LETTER HIGH BA;Lo;0;L;;;;;N;;;;; +19A3;NEW TAI LUE LETTER LOW HA;Lo;0;L;;;;;N;;;;; +19A4;NEW TAI LUE LETTER LOW DA;Lo;0;L;;;;;N;;;;; +19A5;NEW TAI LUE LETTER LOW BA;Lo;0;L;;;;;N;;;;; +19A6;NEW TAI LUE LETTER HIGH KVA;Lo;0;L;;;;;N;;;;; +19A7;NEW TAI LUE LETTER HIGH XVA;Lo;0;L;;;;;N;;;;; +19A8;NEW TAI LUE LETTER LOW KVA;Lo;0;L;;;;;N;;;;; +19A9;NEW TAI LUE LETTER LOW XVA;Lo;0;L;;;;;N;;;;; +19AA;NEW TAI LUE LETTER HIGH SUA;Lo;0;L;;;;;N;;;;; +19AB;NEW TAI LUE LETTER LOW SUA;Lo;0;L;;;;;N;;;;; +19B0;NEW TAI LUE VOWEL SIGN VOWEL SHORTENER;Mc;0;L;;;;;N;;;;; +19B1;NEW TAI LUE VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +19B2;NEW TAI LUE VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +19B3;NEW TAI LUE VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +19B4;NEW TAI LUE VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +19B5;NEW TAI LUE VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +19B6;NEW TAI LUE VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; +19B7;NEW TAI LUE VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +19B8;NEW TAI LUE VOWEL SIGN OA;Mc;0;L;;;;;N;;;;; +19B9;NEW TAI LUE VOWEL SIGN UE;Mc;0;L;;;;;N;;;;; +19BA;NEW TAI LUE VOWEL SIGN AY;Mc;0;L;;;;;N;;;;; +19BB;NEW TAI LUE VOWEL SIGN AAY;Mc;0;L;;;;;N;;;;; +19BC;NEW TAI LUE VOWEL SIGN UY;Mc;0;L;;;;;N;;;;; +19BD;NEW TAI LUE VOWEL SIGN OY;Mc;0;L;;;;;N;;;;; +19BE;NEW TAI LUE VOWEL SIGN OAY;Mc;0;L;;;;;N;;;;; +19BF;NEW TAI LUE VOWEL SIGN UEY;Mc;0;L;;;;;N;;;;; +19C0;NEW TAI LUE VOWEL SIGN IY;Mc;0;L;;;;;N;;;;; +19C1;NEW TAI LUE LETTER FINAL V;Lo;0;L;;;;;N;;;;; +19C2;NEW TAI LUE LETTER FINAL NG;Lo;0;L;;;;;N;;;;; +19C3;NEW TAI LUE LETTER FINAL N;Lo;0;L;;;;;N;;;;; +19C4;NEW TAI LUE LETTER FINAL M;Lo;0;L;;;;;N;;;;; +19C5;NEW TAI LUE LETTER FINAL K;Lo;0;L;;;;;N;;;;; +19C6;NEW TAI LUE LETTER FINAL D;Lo;0;L;;;;;N;;;;; +19C7;NEW TAI LUE LETTER FINAL B;Lo;0;L;;;;;N;;;;; +19C8;NEW TAI LUE TONE MARK-1;Mc;0;L;;;;;N;;;;; +19C9;NEW TAI LUE TONE MARK-2;Mc;0;L;;;;;N;;;;; +19D0;NEW TAI LUE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +19D1;NEW TAI LUE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +19D2;NEW TAI LUE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +19D3;NEW TAI LUE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +19D4;NEW TAI LUE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +19D5;NEW TAI LUE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +19D6;NEW TAI LUE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +19D7;NEW TAI LUE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +19D8;NEW TAI LUE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +19D9;NEW TAI LUE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +19DA;NEW TAI LUE THAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +19DE;NEW TAI LUE SIGN LAE;Po;0;ON;;;;;N;;;;; +19DF;NEW TAI LUE SIGN LAEV;Po;0;ON;;;;;N;;;;; +19E0;KHMER SYMBOL PATHAMASAT;So;0;ON;;;;;N;;;;; +19E1;KHMER SYMBOL MUOY KOET;So;0;ON;;;;;N;;;;; +19E2;KHMER SYMBOL PII KOET;So;0;ON;;;;;N;;;;; +19E3;KHMER SYMBOL BEI KOET;So;0;ON;;;;;N;;;;; +19E4;KHMER SYMBOL BUON KOET;So;0;ON;;;;;N;;;;; +19E5;KHMER SYMBOL PRAM KOET;So;0;ON;;;;;N;;;;; +19E6;KHMER SYMBOL PRAM-MUOY KOET;So;0;ON;;;;;N;;;;; +19E7;KHMER SYMBOL PRAM-PII KOET;So;0;ON;;;;;N;;;;; +19E8;KHMER SYMBOL PRAM-BEI KOET;So;0;ON;;;;;N;;;;; +19E9;KHMER SYMBOL PRAM-BUON KOET;So;0;ON;;;;;N;;;;; +19EA;KHMER SYMBOL DAP KOET;So;0;ON;;;;;N;;;;; +19EB;KHMER SYMBOL DAP-MUOY KOET;So;0;ON;;;;;N;;;;; +19EC;KHMER SYMBOL DAP-PII KOET;So;0;ON;;;;;N;;;;; +19ED;KHMER SYMBOL DAP-BEI KOET;So;0;ON;;;;;N;;;;; +19EE;KHMER SYMBOL DAP-BUON KOET;So;0;ON;;;;;N;;;;; +19EF;KHMER SYMBOL DAP-PRAM KOET;So;0;ON;;;;;N;;;;; +19F0;KHMER SYMBOL TUTEYASAT;So;0;ON;;;;;N;;;;; +19F1;KHMER SYMBOL MUOY ROC;So;0;ON;;;;;N;;;;; +19F2;KHMER SYMBOL PII ROC;So;0;ON;;;;;N;;;;; +19F3;KHMER SYMBOL BEI ROC;So;0;ON;;;;;N;;;;; +19F4;KHMER SYMBOL BUON ROC;So;0;ON;;;;;N;;;;; +19F5;KHMER SYMBOL PRAM ROC;So;0;ON;;;;;N;;;;; +19F6;KHMER SYMBOL PRAM-MUOY ROC;So;0;ON;;;;;N;;;;; +19F7;KHMER SYMBOL PRAM-PII ROC;So;0;ON;;;;;N;;;;; +19F8;KHMER SYMBOL PRAM-BEI ROC;So;0;ON;;;;;N;;;;; +19F9;KHMER SYMBOL PRAM-BUON ROC;So;0;ON;;;;;N;;;;; +19FA;KHMER SYMBOL DAP ROC;So;0;ON;;;;;N;;;;; +19FB;KHMER SYMBOL DAP-MUOY ROC;So;0;ON;;;;;N;;;;; +19FC;KHMER SYMBOL DAP-PII ROC;So;0;ON;;;;;N;;;;; +19FD;KHMER SYMBOL DAP-BEI ROC;So;0;ON;;;;;N;;;;; +19FE;KHMER SYMBOL DAP-BUON ROC;So;0;ON;;;;;N;;;;; +19FF;KHMER SYMBOL DAP-PRAM ROC;So;0;ON;;;;;N;;;;; +1A00;BUGINESE LETTER KA;Lo;0;L;;;;;N;;;;; +1A01;BUGINESE LETTER GA;Lo;0;L;;;;;N;;;;; +1A02;BUGINESE LETTER NGA;Lo;0;L;;;;;N;;;;; +1A03;BUGINESE LETTER NGKA;Lo;0;L;;;;;N;;;;; +1A04;BUGINESE LETTER PA;Lo;0;L;;;;;N;;;;; +1A05;BUGINESE LETTER BA;Lo;0;L;;;;;N;;;;; +1A06;BUGINESE LETTER MA;Lo;0;L;;;;;N;;;;; +1A07;BUGINESE LETTER MPA;Lo;0;L;;;;;N;;;;; +1A08;BUGINESE LETTER TA;Lo;0;L;;;;;N;;;;; +1A09;BUGINESE LETTER DA;Lo;0;L;;;;;N;;;;; +1A0A;BUGINESE LETTER NA;Lo;0;L;;;;;N;;;;; +1A0B;BUGINESE LETTER NRA;Lo;0;L;;;;;N;;;;; +1A0C;BUGINESE LETTER CA;Lo;0;L;;;;;N;;;;; +1A0D;BUGINESE LETTER JA;Lo;0;L;;;;;N;;;;; +1A0E;BUGINESE LETTER NYA;Lo;0;L;;;;;N;;;;; +1A0F;BUGINESE LETTER NYCA;Lo;0;L;;;;;N;;;;; +1A10;BUGINESE LETTER YA;Lo;0;L;;;;;N;;;;; +1A11;BUGINESE LETTER RA;Lo;0;L;;;;;N;;;;; +1A12;BUGINESE LETTER LA;Lo;0;L;;;;;N;;;;; +1A13;BUGINESE LETTER VA;Lo;0;L;;;;;N;;;;; +1A14;BUGINESE LETTER SA;Lo;0;L;;;;;N;;;;; +1A15;BUGINESE LETTER A;Lo;0;L;;;;;N;;;;; +1A16;BUGINESE LETTER HA;Lo;0;L;;;;;N;;;;; +1A17;BUGINESE VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;; +1A18;BUGINESE VOWEL SIGN U;Mn;220;NSM;;;;;N;;;;; +1A19;BUGINESE VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +1A1A;BUGINESE VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +1A1B;BUGINESE VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; +1A1E;BUGINESE PALLAWA;Po;0;L;;;;;N;;;;; +1A1F;BUGINESE END OF SECTION;Po;0;L;;;;;N;;;;; +1A20;TAI THAM LETTER HIGH KA;Lo;0;L;;;;;N;;;;; +1A21;TAI THAM LETTER HIGH KHA;Lo;0;L;;;;;N;;;;; +1A22;TAI THAM LETTER HIGH KXA;Lo;0;L;;;;;N;;;;; +1A23;TAI THAM LETTER LOW KA;Lo;0;L;;;;;N;;;;; +1A24;TAI THAM LETTER LOW KXA;Lo;0;L;;;;;N;;;;; +1A25;TAI THAM LETTER LOW KHA;Lo;0;L;;;;;N;;;;; +1A26;TAI THAM LETTER NGA;Lo;0;L;;;;;N;;;;; +1A27;TAI THAM LETTER HIGH CA;Lo;0;L;;;;;N;;;;; +1A28;TAI THAM LETTER HIGH CHA;Lo;0;L;;;;;N;;;;; +1A29;TAI THAM LETTER LOW CA;Lo;0;L;;;;;N;;;;; +1A2A;TAI THAM LETTER LOW SA;Lo;0;L;;;;;N;;;;; +1A2B;TAI THAM LETTER LOW CHA;Lo;0;L;;;;;N;;;;; +1A2C;TAI THAM LETTER NYA;Lo;0;L;;;;;N;;;;; +1A2D;TAI THAM LETTER RATA;Lo;0;L;;;;;N;;;;; +1A2E;TAI THAM LETTER HIGH RATHA;Lo;0;L;;;;;N;;;;; +1A2F;TAI THAM LETTER DA;Lo;0;L;;;;;N;;;;; +1A30;TAI THAM LETTER LOW RATHA;Lo;0;L;;;;;N;;;;; +1A31;TAI THAM LETTER RANA;Lo;0;L;;;;;N;;;;; +1A32;TAI THAM LETTER HIGH TA;Lo;0;L;;;;;N;;;;; +1A33;TAI THAM LETTER HIGH THA;Lo;0;L;;;;;N;;;;; +1A34;TAI THAM LETTER LOW TA;Lo;0;L;;;;;N;;;;; +1A35;TAI THAM LETTER LOW THA;Lo;0;L;;;;;N;;;;; +1A36;TAI THAM LETTER NA;Lo;0;L;;;;;N;;;;; +1A37;TAI THAM LETTER BA;Lo;0;L;;;;;N;;;;; +1A38;TAI THAM LETTER HIGH PA;Lo;0;L;;;;;N;;;;; +1A39;TAI THAM LETTER HIGH PHA;Lo;0;L;;;;;N;;;;; +1A3A;TAI THAM LETTER HIGH FA;Lo;0;L;;;;;N;;;;; +1A3B;TAI THAM LETTER LOW PA;Lo;0;L;;;;;N;;;;; +1A3C;TAI THAM LETTER LOW FA;Lo;0;L;;;;;N;;;;; +1A3D;TAI THAM LETTER LOW PHA;Lo;0;L;;;;;N;;;;; +1A3E;TAI THAM LETTER MA;Lo;0;L;;;;;N;;;;; +1A3F;TAI THAM LETTER LOW YA;Lo;0;L;;;;;N;;;;; +1A40;TAI THAM LETTER HIGH YA;Lo;0;L;;;;;N;;;;; +1A41;TAI THAM LETTER RA;Lo;0;L;;;;;N;;;;; +1A42;TAI THAM LETTER RUE;Lo;0;L;;;;;N;;;;; +1A43;TAI THAM LETTER LA;Lo;0;L;;;;;N;;;;; +1A44;TAI THAM LETTER LUE;Lo;0;L;;;;;N;;;;; +1A45;TAI THAM LETTER WA;Lo;0;L;;;;;N;;;;; +1A46;TAI THAM LETTER HIGH SHA;Lo;0;L;;;;;N;;;;; +1A47;TAI THAM LETTER HIGH SSA;Lo;0;L;;;;;N;;;;; +1A48;TAI THAM LETTER HIGH SA;Lo;0;L;;;;;N;;;;; +1A49;TAI THAM LETTER HIGH HA;Lo;0;L;;;;;N;;;;; +1A4A;TAI THAM LETTER LLA;Lo;0;L;;;;;N;;;;; +1A4B;TAI THAM LETTER A;Lo;0;L;;;;;N;;;;; +1A4C;TAI THAM LETTER LOW HA;Lo;0;L;;;;;N;;;;; +1A4D;TAI THAM LETTER I;Lo;0;L;;;;;N;;;;; +1A4E;TAI THAM LETTER II;Lo;0;L;;;;;N;;;;; +1A4F;TAI THAM LETTER U;Lo;0;L;;;;;N;;;;; +1A50;TAI THAM LETTER UU;Lo;0;L;;;;;N;;;;; +1A51;TAI THAM LETTER EE;Lo;0;L;;;;;N;;;;; +1A52;TAI THAM LETTER OO;Lo;0;L;;;;;N;;;;; +1A53;TAI THAM LETTER LAE;Lo;0;L;;;;;N;;;;; +1A54;TAI THAM LETTER GREAT SA;Lo;0;L;;;;;N;;;;; +1A55;TAI THAM CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;; +1A56;TAI THAM CONSONANT SIGN MEDIAL LA;Mn;0;NSM;;;;;N;;;;; +1A57;TAI THAM CONSONANT SIGN LA TANG LAI;Mc;0;L;;;;;N;;;;; +1A58;TAI THAM SIGN MAI KANG LAI;Mn;0;NSM;;;;;N;;;;; +1A59;TAI THAM CONSONANT SIGN FINAL NGA;Mn;0;NSM;;;;;N;;;;; +1A5A;TAI THAM CONSONANT SIGN LOW PA;Mn;0;NSM;;;;;N;;;;; +1A5B;TAI THAM CONSONANT SIGN HIGH RATHA OR LOW PA;Mn;0;NSM;;;;;N;;;;; +1A5C;TAI THAM CONSONANT SIGN MA;Mn;0;NSM;;;;;N;;;;; +1A5D;TAI THAM CONSONANT SIGN BA;Mn;0;NSM;;;;;N;;;;; +1A5E;TAI THAM CONSONANT SIGN SA;Mn;0;NSM;;;;;N;;;;; +1A60;TAI THAM SIGN SAKOT;Mn;9;NSM;;;;;N;;;;; +1A61;TAI THAM VOWEL SIGN A;Mc;0;L;;;;;N;;;;; +1A62;TAI THAM VOWEL SIGN MAI SAT;Mn;0;NSM;;;;;N;;;;; +1A63;TAI THAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +1A64;TAI THAM VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;; +1A65;TAI THAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1A66;TAI THAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +1A67;TAI THAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;; +1A68;TAI THAM VOWEL SIGN UUE;Mn;0;NSM;;;;;N;;;;; +1A69;TAI THAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1A6A;TAI THAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +1A6B;TAI THAM VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +1A6C;TAI THAM VOWEL SIGN OA BELOW;Mn;0;NSM;;;;;N;;;;; +1A6D;TAI THAM VOWEL SIGN OY;Mc;0;L;;;;;N;;;;; +1A6E;TAI THAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +1A6F;TAI THAM VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; +1A70;TAI THAM VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +1A71;TAI THAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +1A72;TAI THAM VOWEL SIGN THAM AI;Mc;0;L;;;;;N;;;;; +1A73;TAI THAM VOWEL SIGN OA ABOVE;Mn;0;NSM;;;;;N;;;;; +1A74;TAI THAM SIGN MAI KANG;Mn;0;NSM;;;;;N;;;;; +1A75;TAI THAM SIGN TONE-1;Mn;230;NSM;;;;;N;;;;; +1A76;TAI THAM SIGN TONE-2;Mn;230;NSM;;;;;N;;;;; +1A77;TAI THAM SIGN KHUEN TONE-3;Mn;230;NSM;;;;;N;;;;; +1A78;TAI THAM SIGN KHUEN TONE-4;Mn;230;NSM;;;;;N;;;;; +1A79;TAI THAM SIGN KHUEN TONE-5;Mn;230;NSM;;;;;N;;;;; +1A7A;TAI THAM SIGN RA HAAM;Mn;230;NSM;;;;;N;;;;; +1A7B;TAI THAM SIGN MAI SAM;Mn;230;NSM;;;;;N;;;;; +1A7C;TAI THAM SIGN KHUEN-LUE KARAN;Mn;230;NSM;;;;;N;;;;; +1A7F;TAI THAM COMBINING CRYPTOGRAMMIC DOT;Mn;220;NSM;;;;;N;;;;; +1A80;TAI THAM HORA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1A81;TAI THAM HORA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1A82;TAI THAM HORA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1A83;TAI THAM HORA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1A84;TAI THAM HORA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1A85;TAI THAM HORA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1A86;TAI THAM HORA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1A87;TAI THAM HORA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1A88;TAI THAM HORA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1A89;TAI THAM HORA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1A90;TAI THAM THAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1A91;TAI THAM THAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1A92;TAI THAM THAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1A93;TAI THAM THAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1A94;TAI THAM THAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1A95;TAI THAM THAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1A96;TAI THAM THAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1A97;TAI THAM THAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1A98;TAI THAM THAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1A99;TAI THAM THAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1AA0;TAI THAM SIGN WIANG;Po;0;L;;;;;N;;;;; +1AA1;TAI THAM SIGN WIANGWAAK;Po;0;L;;;;;N;;;;; +1AA2;TAI THAM SIGN SAWAN;Po;0;L;;;;;N;;;;; +1AA3;TAI THAM SIGN KEOW;Po;0;L;;;;;N;;;;; +1AA4;TAI THAM SIGN HOY;Po;0;L;;;;;N;;;;; +1AA5;TAI THAM SIGN DOKMAI;Po;0;L;;;;;N;;;;; +1AA6;TAI THAM SIGN REVERSED ROTATED RANA;Po;0;L;;;;;N;;;;; +1AA7;TAI THAM SIGN MAI YAMOK;Lm;0;L;;;;;N;;;;; +1AA8;TAI THAM SIGN KAAN;Po;0;L;;;;;N;;;;; +1AA9;TAI THAM SIGN KAANKUU;Po;0;L;;;;;N;;;;; +1AAA;TAI THAM SIGN SATKAAN;Po;0;L;;;;;N;;;;; +1AAB;TAI THAM SIGN SATKAANKUU;Po;0;L;;;;;N;;;;; +1AAC;TAI THAM SIGN HANG;Po;0;L;;;;;N;;;;; +1AAD;TAI THAM SIGN CAANG;Po;0;L;;;;;N;;;;; +1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;;;; +1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;;;; +1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;;;; +1B03;BALINESE SIGN SURANG;Mn;0;NSM;;;;;N;;;;; +1B04;BALINESE SIGN BISAH;Mc;0;L;;;;;N;;;;; +1B05;BALINESE LETTER AKARA;Lo;0;L;;;;;N;;;;; +1B06;BALINESE LETTER AKARA TEDUNG;Lo;0;L;1B05 1B35;;;;N;;;;; +1B07;BALINESE LETTER IKARA;Lo;0;L;;;;;N;;;;; +1B08;BALINESE LETTER IKARA TEDUNG;Lo;0;L;1B07 1B35;;;;N;;;;; +1B09;BALINESE LETTER UKARA;Lo;0;L;;;;;N;;;;; +1B0A;BALINESE LETTER UKARA TEDUNG;Lo;0;L;1B09 1B35;;;;N;;;;; +1B0B;BALINESE LETTER RA REPA;Lo;0;L;;;;;N;;;;; +1B0C;BALINESE LETTER RA REPA TEDUNG;Lo;0;L;1B0B 1B35;;;;N;;;;; +1B0D;BALINESE LETTER LA LENGA;Lo;0;L;;;;;N;;;;; +1B0E;BALINESE LETTER LA LENGA TEDUNG;Lo;0;L;1B0D 1B35;;;;N;;;;; +1B0F;BALINESE LETTER EKARA;Lo;0;L;;;;;N;;;;; +1B10;BALINESE LETTER AIKARA;Lo;0;L;;;;;N;;;;; +1B11;BALINESE LETTER OKARA;Lo;0;L;;;;;N;;;;; +1B12;BALINESE LETTER OKARA TEDUNG;Lo;0;L;1B11 1B35;;;;N;;;;; +1B13;BALINESE LETTER KA;Lo;0;L;;;;;N;;;;; +1B14;BALINESE LETTER KA MAHAPRANA;Lo;0;L;;;;;N;;;;; +1B15;BALINESE LETTER GA;Lo;0;L;;;;;N;;;;; +1B16;BALINESE LETTER GA GORA;Lo;0;L;;;;;N;;;;; +1B17;BALINESE LETTER NGA;Lo;0;L;;;;;N;;;;; +1B18;BALINESE LETTER CA;Lo;0;L;;;;;N;;;;; +1B19;BALINESE LETTER CA LACA;Lo;0;L;;;;;N;;;;; +1B1A;BALINESE LETTER JA;Lo;0;L;;;;;N;;;;; +1B1B;BALINESE LETTER JA JERA;Lo;0;L;;;;;N;;;;; +1B1C;BALINESE LETTER NYA;Lo;0;L;;;;;N;;;;; +1B1D;BALINESE LETTER TA LATIK;Lo;0;L;;;;;N;;;;; +1B1E;BALINESE LETTER TA MURDA MAHAPRANA;Lo;0;L;;;;;N;;;;; +1B1F;BALINESE LETTER DA MURDA ALPAPRANA;Lo;0;L;;;;;N;;;;; +1B20;BALINESE LETTER DA MURDA MAHAPRANA;Lo;0;L;;;;;N;;;;; +1B21;BALINESE LETTER NA RAMBAT;Lo;0;L;;;;;N;;;;; +1B22;BALINESE LETTER TA;Lo;0;L;;;;;N;;;;; +1B23;BALINESE LETTER TA TAWA;Lo;0;L;;;;;N;;;;; +1B24;BALINESE LETTER DA;Lo;0;L;;;;;N;;;;; +1B25;BALINESE LETTER DA MADU;Lo;0;L;;;;;N;;;;; +1B26;BALINESE LETTER NA;Lo;0;L;;;;;N;;;;; +1B27;BALINESE LETTER PA;Lo;0;L;;;;;N;;;;; +1B28;BALINESE LETTER PA KAPAL;Lo;0;L;;;;;N;;;;; +1B29;BALINESE LETTER BA;Lo;0;L;;;;;N;;;;; +1B2A;BALINESE LETTER BA KEMBANG;Lo;0;L;;;;;N;;;;; +1B2B;BALINESE LETTER MA;Lo;0;L;;;;;N;;;;; +1B2C;BALINESE LETTER YA;Lo;0;L;;;;;N;;;;; +1B2D;BALINESE LETTER RA;Lo;0;L;;;;;N;;;;; +1B2E;BALINESE LETTER LA;Lo;0;L;;;;;N;;;;; +1B2F;BALINESE LETTER WA;Lo;0;L;;;;;N;;;;; +1B30;BALINESE LETTER SA SAGA;Lo;0;L;;;;;N;;;;; +1B31;BALINESE LETTER SA SAPA;Lo;0;L;;;;;N;;;;; +1B32;BALINESE LETTER SA;Lo;0;L;;;;;N;;;;; +1B33;BALINESE LETTER HA;Lo;0;L;;;;;N;;;;; +1B34;BALINESE SIGN REREKAN;Mn;7;NSM;;;;;N;;;;; +1B35;BALINESE VOWEL SIGN TEDUNG;Mc;0;L;;;;;N;;;;; +1B36;BALINESE VOWEL SIGN ULU;Mn;0;NSM;;;;;N;;;;; +1B37;BALINESE VOWEL SIGN ULU SARI;Mn;0;NSM;;;;;N;;;;; +1B38;BALINESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;;;; +1B39;BALINESE VOWEL SIGN SUKU ILUT;Mn;0;NSM;;;;;N;;;;; +1B3A;BALINESE VOWEL SIGN RA REPA;Mn;0;NSM;;;;;N;;;;; +1B3B;BALINESE VOWEL SIGN RA REPA TEDUNG;Mc;0;L;1B3A 1B35;;;;N;;;;; +1B3C;BALINESE VOWEL SIGN LA LENGA;Mn;0;NSM;;;;;N;;;;; +1B3D;BALINESE VOWEL SIGN LA LENGA TEDUNG;Mc;0;L;1B3C 1B35;;;;N;;;;; +1B3E;BALINESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;; +1B3F;BALINESE VOWEL SIGN TALING REPA;Mc;0;L;;;;;N;;;;; +1B40;BALINESE VOWEL SIGN TALING TEDUNG;Mc;0;L;1B3E 1B35;;;;N;;;;; +1B41;BALINESE VOWEL SIGN TALING REPA TEDUNG;Mc;0;L;1B3F 1B35;;;;N;;;;; +1B42;BALINESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;; +1B43;BALINESE VOWEL SIGN PEPET TEDUNG;Mc;0;L;1B42 1B35;;;;N;;;;; +1B44;BALINESE ADEG ADEG;Mc;9;L;;;;;N;;;;; +1B45;BALINESE LETTER KAF SASAK;Lo;0;L;;;;;N;;;;; +1B46;BALINESE LETTER KHOT SASAK;Lo;0;L;;;;;N;;;;; +1B47;BALINESE LETTER TZIR SASAK;Lo;0;L;;;;;N;;;;; +1B48;BALINESE LETTER EF SASAK;Lo;0;L;;;;;N;;;;; +1B49;BALINESE LETTER VE SASAK;Lo;0;L;;;;;N;;;;; +1B4A;BALINESE LETTER ZAL SASAK;Lo;0;L;;;;;N;;;;; +1B4B;BALINESE LETTER ASYURA SASAK;Lo;0;L;;;;;N;;;;; +1B50;BALINESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1B51;BALINESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1B52;BALINESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1B53;BALINESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1B54;BALINESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1B55;BALINESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1B56;BALINESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1B57;BALINESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1B58;BALINESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1B59;BALINESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1B5A;BALINESE PANTI;Po;0;L;;;;;N;;;;; +1B5B;BALINESE PAMADA;Po;0;L;;;;;N;;;;; +1B5C;BALINESE WINDU;Po;0;L;;;;;N;;;;; +1B5D;BALINESE CARIK PAMUNGKAH;Po;0;L;;;;;N;;;;; +1B5E;BALINESE CARIK SIKI;Po;0;L;;;;;N;;;;; +1B5F;BALINESE CARIK PAREREN;Po;0;L;;;;;N;;;;; +1B60;BALINESE PAMENENG;Po;0;L;;;;;N;;;;; +1B61;BALINESE MUSICAL SYMBOL DONG;So;0;L;;;;;N;;;;; +1B62;BALINESE MUSICAL SYMBOL DENG;So;0;L;;;;;N;;;;; +1B63;BALINESE MUSICAL SYMBOL DUNG;So;0;L;;;;;N;;;;; +1B64;BALINESE MUSICAL SYMBOL DANG;So;0;L;;;;;N;;;;; +1B65;BALINESE MUSICAL SYMBOL DANG SURANG;So;0;L;;;;;N;;;;; +1B66;BALINESE MUSICAL SYMBOL DING;So;0;L;;;;;N;;;;; +1B67;BALINESE MUSICAL SYMBOL DAENG;So;0;L;;;;;N;;;;; +1B68;BALINESE MUSICAL SYMBOL DEUNG;So;0;L;;;;;N;;;;; +1B69;BALINESE MUSICAL SYMBOL DAING;So;0;L;;;;;N;;;;; +1B6A;BALINESE MUSICAL SYMBOL DANG GEDE;So;0;L;;;;;N;;;;; +1B6B;BALINESE MUSICAL SYMBOL COMBINING TEGEH;Mn;230;NSM;;;;;N;;;;; +1B6C;BALINESE MUSICAL SYMBOL COMBINING ENDEP;Mn;220;NSM;;;;;N;;;;; +1B6D;BALINESE MUSICAL SYMBOL COMBINING KEMPUL;Mn;230;NSM;;;;;N;;;;; +1B6E;BALINESE MUSICAL SYMBOL COMBINING KEMPLI;Mn;230;NSM;;;;;N;;;;; +1B6F;BALINESE MUSICAL SYMBOL COMBINING JEGOGAN;Mn;230;NSM;;;;;N;;;;; +1B70;BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;; +1B71;BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;; +1B72;BALINESE MUSICAL SYMBOL COMBINING BENDE;Mn;230;NSM;;;;;N;;;;; +1B73;BALINESE MUSICAL SYMBOL COMBINING GONG;Mn;230;NSM;;;;;N;;;;; +1B74;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG;So;0;L;;;;;N;;;;; +1B75;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DAG;So;0;L;;;;;N;;;;; +1B76;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TUK;So;0;L;;;;;N;;;;; +1B77;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TAK;So;0;L;;;;;N;;;;; +1B78;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PANG;So;0;L;;;;;N;;;;; +1B79;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PUNG;So;0;L;;;;;N;;;;; +1B7A;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK;So;0;L;;;;;N;;;;; +1B7B;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK;So;0;L;;;;;N;;;;; +1B7C;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING;So;0;L;;;;;N;;;;; +1B80;SUNDANESE SIGN PANYECEK;Mn;0;NSM;;;;;N;;;;; +1B81;SUNDANESE SIGN PANGLAYAR;Mn;0;NSM;;;;;N;;;;; +1B82;SUNDANESE SIGN PANGWISAD;Mc;0;L;;;;;N;;;;; +1B83;SUNDANESE LETTER A;Lo;0;L;;;;;N;;;;; +1B84;SUNDANESE LETTER I;Lo;0;L;;;;;N;;;;; +1B85;SUNDANESE LETTER U;Lo;0;L;;;;;N;;;;; +1B86;SUNDANESE LETTER AE;Lo;0;L;;;;;N;;;;; +1B87;SUNDANESE LETTER O;Lo;0;L;;;;;N;;;;; +1B88;SUNDANESE LETTER E;Lo;0;L;;;;;N;;;;; +1B89;SUNDANESE LETTER EU;Lo;0;L;;;;;N;;;;; +1B8A;SUNDANESE LETTER KA;Lo;0;L;;;;;N;;;;; +1B8B;SUNDANESE LETTER QA;Lo;0;L;;;;;N;;;;; +1B8C;SUNDANESE LETTER GA;Lo;0;L;;;;;N;;;;; +1B8D;SUNDANESE LETTER NGA;Lo;0;L;;;;;N;;;;; +1B8E;SUNDANESE LETTER CA;Lo;0;L;;;;;N;;;;; +1B8F;SUNDANESE LETTER JA;Lo;0;L;;;;;N;;;;; +1B90;SUNDANESE LETTER ZA;Lo;0;L;;;;;N;;;;; +1B91;SUNDANESE LETTER NYA;Lo;0;L;;;;;N;;;;; +1B92;SUNDANESE LETTER TA;Lo;0;L;;;;;N;;;;; +1B93;SUNDANESE LETTER DA;Lo;0;L;;;;;N;;;;; +1B94;SUNDANESE LETTER NA;Lo;0;L;;;;;N;;;;; +1B95;SUNDANESE LETTER PA;Lo;0;L;;;;;N;;;;; +1B96;SUNDANESE LETTER FA;Lo;0;L;;;;;N;;;;; +1B97;SUNDANESE LETTER VA;Lo;0;L;;;;;N;;;;; +1B98;SUNDANESE LETTER BA;Lo;0;L;;;;;N;;;;; +1B99;SUNDANESE LETTER MA;Lo;0;L;;;;;N;;;;; +1B9A;SUNDANESE LETTER YA;Lo;0;L;;;;;N;;;;; +1B9B;SUNDANESE LETTER RA;Lo;0;L;;;;;N;;;;; +1B9C;SUNDANESE LETTER LA;Lo;0;L;;;;;N;;;;; +1B9D;SUNDANESE LETTER WA;Lo;0;L;;;;;N;;;;; +1B9E;SUNDANESE LETTER SA;Lo;0;L;;;;;N;;;;; +1B9F;SUNDANESE LETTER XA;Lo;0;L;;;;;N;;;;; +1BA0;SUNDANESE LETTER HA;Lo;0;L;;;;;N;;;;; +1BA1;SUNDANESE CONSONANT SIGN PAMINGKAL;Mc;0;L;;;;;N;;;;; +1BA2;SUNDANESE CONSONANT SIGN PANYAKRA;Mn;0;NSM;;;;;N;;;;; +1BA3;SUNDANESE CONSONANT SIGN PANYIKU;Mn;0;NSM;;;;;N;;;;; +1BA4;SUNDANESE VOWEL SIGN PANGHULU;Mn;0;NSM;;;;;N;;;;; +1BA5;SUNDANESE VOWEL SIGN PANYUKU;Mn;0;NSM;;;;;N;;;;; +1BA6;SUNDANESE VOWEL SIGN PANAELAENG;Mc;0;L;;;;;N;;;;; +1BA7;SUNDANESE VOWEL SIGN PANOLONG;Mc;0;L;;;;;N;;;;; +1BA8;SUNDANESE VOWEL SIGN PAMEPET;Mn;0;NSM;;;;;N;;;;; +1BA9;SUNDANESE VOWEL SIGN PANEULEUNG;Mn;0;NSM;;;;;N;;;;; +1BAA;SUNDANESE SIGN PAMAAEH;Mc;9;L;;;;;N;;;;; +1BAE;SUNDANESE LETTER KHA;Lo;0;L;;;;;N;;;;; +1BAF;SUNDANESE LETTER SYA;Lo;0;L;;;;;N;;;;; +1BB0;SUNDANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1BB1;SUNDANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1BB2;SUNDANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1BB3;SUNDANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1BB4;SUNDANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1BB5;SUNDANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1BB6;SUNDANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1BB7;SUNDANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1BB8;SUNDANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1BB9;SUNDANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1C00;LEPCHA LETTER KA;Lo;0;L;;;;;N;;;;; +1C01;LEPCHA LETTER KLA;Lo;0;L;;;;;N;;;;; +1C02;LEPCHA LETTER KHA;Lo;0;L;;;;;N;;;;; +1C03;LEPCHA LETTER GA;Lo;0;L;;;;;N;;;;; +1C04;LEPCHA LETTER GLA;Lo;0;L;;;;;N;;;;; +1C05;LEPCHA LETTER NGA;Lo;0;L;;;;;N;;;;; +1C06;LEPCHA LETTER CA;Lo;0;L;;;;;N;;;;; +1C07;LEPCHA LETTER CHA;Lo;0;L;;;;;N;;;;; +1C08;LEPCHA LETTER JA;Lo;0;L;;;;;N;;;;; +1C09;LEPCHA LETTER NYA;Lo;0;L;;;;;N;;;;; +1C0A;LEPCHA LETTER TA;Lo;0;L;;;;;N;;;;; +1C0B;LEPCHA LETTER THA;Lo;0;L;;;;;N;;;;; +1C0C;LEPCHA LETTER DA;Lo;0;L;;;;;N;;;;; +1C0D;LEPCHA LETTER NA;Lo;0;L;;;;;N;;;;; +1C0E;LEPCHA LETTER PA;Lo;0;L;;;;;N;;;;; +1C0F;LEPCHA LETTER PLA;Lo;0;L;;;;;N;;;;; +1C10;LEPCHA LETTER PHA;Lo;0;L;;;;;N;;;;; +1C11;LEPCHA LETTER FA;Lo;0;L;;;;;N;;;;; +1C12;LEPCHA LETTER FLA;Lo;0;L;;;;;N;;;;; +1C13;LEPCHA LETTER BA;Lo;0;L;;;;;N;;;;; +1C14;LEPCHA LETTER BLA;Lo;0;L;;;;;N;;;;; +1C15;LEPCHA LETTER MA;Lo;0;L;;;;;N;;;;; +1C16;LEPCHA LETTER MLA;Lo;0;L;;;;;N;;;;; +1C17;LEPCHA LETTER TSA;Lo;0;L;;;;;N;;;;; +1C18;LEPCHA LETTER TSHA;Lo;0;L;;;;;N;;;;; +1C19;LEPCHA LETTER DZA;Lo;0;L;;;;;N;;;;; +1C1A;LEPCHA LETTER YA;Lo;0;L;;;;;N;;;;; +1C1B;LEPCHA LETTER RA;Lo;0;L;;;;;N;;;;; +1C1C;LEPCHA LETTER LA;Lo;0;L;;;;;N;;;;; +1C1D;LEPCHA LETTER HA;Lo;0;L;;;;;N;;;;; +1C1E;LEPCHA LETTER HLA;Lo;0;L;;;;;N;;;;; +1C1F;LEPCHA LETTER VA;Lo;0;L;;;;;N;;;;; +1C20;LEPCHA LETTER SA;Lo;0;L;;;;;N;;;;; +1C21;LEPCHA LETTER SHA;Lo;0;L;;;;;N;;;;; +1C22;LEPCHA LETTER WA;Lo;0;L;;;;;N;;;;; +1C23;LEPCHA LETTER A;Lo;0;L;;;;;N;;;;; +1C24;LEPCHA SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;; +1C25;LEPCHA SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;; +1C26;LEPCHA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +1C27;LEPCHA VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +1C28;LEPCHA VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +1C29;LEPCHA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +1C2A;LEPCHA VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +1C2B;LEPCHA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +1C2C;LEPCHA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +1C2D;LEPCHA CONSONANT SIGN K;Mn;0;NSM;;;;;N;;;;; +1C2E;LEPCHA CONSONANT SIGN M;Mn;0;NSM;;;;;N;;;;; +1C2F;LEPCHA CONSONANT SIGN L;Mn;0;NSM;;;;;N;;;;; +1C30;LEPCHA CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;; +1C31;LEPCHA CONSONANT SIGN P;Mn;0;NSM;;;;;N;;;;; +1C32;LEPCHA CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;; +1C33;LEPCHA CONSONANT SIGN T;Mn;0;NSM;;;;;N;;;;; +1C34;LEPCHA CONSONANT SIGN NYIN-DO;Mc;0;L;;;;;N;;;;; +1C35;LEPCHA CONSONANT SIGN KANG;Mc;0;L;;;;;N;;;;; +1C36;LEPCHA SIGN RAN;Mn;0;NSM;;;;;N;;;;; +1C37;LEPCHA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +1C3B;LEPCHA PUNCTUATION TA-ROL;Po;0;L;;;;;N;;;;; +1C3C;LEPCHA PUNCTUATION NYET THYOOM TA-ROL;Po;0;L;;;;;N;;;;; +1C3D;LEPCHA PUNCTUATION CER-WA;Po;0;L;;;;;N;;;;; +1C3E;LEPCHA PUNCTUATION TSHOOK CER-WA;Po;0;L;;;;;N;;;;; +1C3F;LEPCHA PUNCTUATION TSHOOK;Po;0;L;;;;;N;;;;; +1C40;LEPCHA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1C41;LEPCHA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1C42;LEPCHA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1C43;LEPCHA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1C44;LEPCHA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1C45;LEPCHA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1C46;LEPCHA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1C47;LEPCHA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1C48;LEPCHA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1C49;LEPCHA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1C4D;LEPCHA LETTER TTA;Lo;0;L;;;;;N;;;;; +1C4E;LEPCHA LETTER TTHA;Lo;0;L;;;;;N;;;;; +1C4F;LEPCHA LETTER DDA;Lo;0;L;;;;;N;;;;; +1C50;OL CHIKI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1C51;OL CHIKI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1C52;OL CHIKI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1C53;OL CHIKI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1C54;OL CHIKI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1C55;OL CHIKI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1C56;OL CHIKI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1C57;OL CHIKI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1C58;OL CHIKI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1C59;OL CHIKI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1C5A;OL CHIKI LETTER LA;Lo;0;L;;;;;N;;;;; +1C5B;OL CHIKI LETTER AT;Lo;0;L;;;;;N;;;;; +1C5C;OL CHIKI LETTER AG;Lo;0;L;;;;;N;;;;; +1C5D;OL CHIKI LETTER ANG;Lo;0;L;;;;;N;;;;; +1C5E;OL CHIKI LETTER AL;Lo;0;L;;;;;N;;;;; +1C5F;OL CHIKI LETTER LAA;Lo;0;L;;;;;N;;;;; +1C60;OL CHIKI LETTER AAK;Lo;0;L;;;;;N;;;;; +1C61;OL CHIKI LETTER AAJ;Lo;0;L;;;;;N;;;;; +1C62;OL CHIKI LETTER AAM;Lo;0;L;;;;;N;;;;; +1C63;OL CHIKI LETTER AAW;Lo;0;L;;;;;N;;;;; +1C64;OL CHIKI LETTER LI;Lo;0;L;;;;;N;;;;; +1C65;OL CHIKI LETTER IS;Lo;0;L;;;;;N;;;;; +1C66;OL CHIKI LETTER IH;Lo;0;L;;;;;N;;;;; +1C67;OL CHIKI LETTER INY;Lo;0;L;;;;;N;;;;; +1C68;OL CHIKI LETTER IR;Lo;0;L;;;;;N;;;;; +1C69;OL CHIKI LETTER LU;Lo;0;L;;;;;N;;;;; +1C6A;OL CHIKI LETTER UC;Lo;0;L;;;;;N;;;;; +1C6B;OL CHIKI LETTER UD;Lo;0;L;;;;;N;;;;; +1C6C;OL CHIKI LETTER UNN;Lo;0;L;;;;;N;;;;; +1C6D;OL CHIKI LETTER UY;Lo;0;L;;;;;N;;;;; +1C6E;OL CHIKI LETTER LE;Lo;0;L;;;;;N;;;;; +1C6F;OL CHIKI LETTER EP;Lo;0;L;;;;;N;;;;; +1C70;OL CHIKI LETTER EDD;Lo;0;L;;;;;N;;;;; +1C71;OL CHIKI LETTER EN;Lo;0;L;;;;;N;;;;; +1C72;OL CHIKI LETTER ERR;Lo;0;L;;;;;N;;;;; +1C73;OL CHIKI LETTER LO;Lo;0;L;;;;;N;;;;; +1C74;OL CHIKI LETTER OTT;Lo;0;L;;;;;N;;;;; +1C75;OL CHIKI LETTER OB;Lo;0;L;;;;;N;;;;; +1C76;OL CHIKI LETTER OV;Lo;0;L;;;;;N;;;;; +1C77;OL CHIKI LETTER OH;Lo;0;L;;;;;N;;;;; +1C78;OL CHIKI MU TTUDDAG;Lm;0;L;;;;;N;;;;; +1C79;OL CHIKI GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;; +1C7A;OL CHIKI MU-GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;; +1C7B;OL CHIKI RELAA;Lm;0;L;;;;;N;;;;; +1C7C;OL CHIKI PHAARKAA;Lm;0;L;;;;;N;;;;; +1C7D;OL CHIKI AHAD;Lm;0;L;;;;;N;;;;; +1C7E;OL CHIKI PUNCTUATION MUCAAD;Po;0;L;;;;;N;;;;; +1C7F;OL CHIKI PUNCTUATION DOUBLE MUCAAD;Po;0;L;;;;;N;;;;; +1CD0;VEDIC TONE KARSHANA;Mn;230;NSM;;;;;N;;;;; +1CD1;VEDIC TONE SHARA;Mn;230;NSM;;;;;N;;;;; +1CD2;VEDIC TONE PRENKHA;Mn;230;NSM;;;;;N;;;;; +1CD3;VEDIC SIGN NIHSHVASA;Po;0;L;;;;;N;;;;; +1CD4;VEDIC SIGN YAJURVEDIC MIDLINE SVARITA;Mn;1;NSM;;;;;N;;;;; +1CD5;VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;; +1CD6;VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;; +1CD7;VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;; +1CD8;VEDIC TONE CANDRA BELOW;Mn;220;NSM;;;;;N;;;;; +1CD9;VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER;Mn;220;NSM;;;;;N;;;;; +1CDA;VEDIC TONE DOUBLE SVARITA;Mn;230;NSM;;;;;N;;;;; +1CDB;VEDIC TONE TRIPLE SVARITA;Mn;230;NSM;;;;;N;;;;; +1CDC;VEDIC TONE KATHAKA ANUDATTA;Mn;220;NSM;;;;;N;;;;; +1CDD;VEDIC TONE DOT BELOW;Mn;220;NSM;;;;;N;;;;; +1CDE;VEDIC TONE TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +1CDF;VEDIC TONE THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +1CE0;VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA;Mn;230;NSM;;;;;N;;;;; +1CE1;VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA;Mc;0;L;;;;;N;;;;; +1CE2;VEDIC SIGN VISARGA SVARITA;Mn;1;NSM;;;;;N;;;;; +1CE3;VEDIC SIGN VISARGA UDATTA;Mn;1;NSM;;;;;N;;;;; +1CE4;VEDIC SIGN REVERSED VISARGA UDATTA;Mn;1;NSM;;;;;N;;;;; +1CE5;VEDIC SIGN VISARGA ANUDATTA;Mn;1;NSM;;;;;N;;;;; +1CE6;VEDIC SIGN REVERSED VISARGA ANUDATTA;Mn;1;NSM;;;;;N;;;;; +1CE7;VEDIC SIGN VISARGA UDATTA WITH TAIL;Mn;1;NSM;;;;;N;;;;; +1CE8;VEDIC SIGN VISARGA ANUDATTA WITH TAIL;Mn;1;NSM;;;;;N;;;;; +1CE9;VEDIC SIGN ANUSVARA ANTARGOMUKHA;Lo;0;L;;;;;N;;;;; +1CEA;VEDIC SIGN ANUSVARA BAHIRGOMUKHA;Lo;0;L;;;;;N;;;;; +1CEB;VEDIC SIGN ANUSVARA VAMAGOMUKHA;Lo;0;L;;;;;N;;;;; +1CEC;VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL;Lo;0;L;;;;;N;;;;; +1CED;VEDIC SIGN TIRYAK;Mn;220;NSM;;;;;N;;;;; +1CEE;VEDIC SIGN HEXIFORM LONG ANUSVARA;Lo;0;L;;;;;N;;;;; +1CEF;VEDIC SIGN LONG ANUSVARA;Lo;0;L;;;;;N;;;;; +1CF0;VEDIC SIGN RTHANG LONG ANUSVARA;Lo;0;L;;;;;N;;;;; +1CF1;VEDIC SIGN ANUSVARA UBHAYATO MUKHA;Lo;0;L;;;;;N;;;;; +1CF2;VEDIC SIGN ARDHAVISARGA;Mc;0;L;;;;;N;;;;; +1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;; +1D01;LATIN LETTER SMALL CAPITAL AE;Ll;0;L;;;;;N;;;;; +1D02;LATIN SMALL LETTER TURNED AE;Ll;0;L;;;;;N;;;;; +1D03;LATIN LETTER SMALL CAPITAL BARRED B;Ll;0;L;;;;;N;;;;; +1D04;LATIN LETTER SMALL CAPITAL C;Ll;0;L;;;;;N;;;;; +1D05;LATIN LETTER SMALL CAPITAL D;Ll;0;L;;;;;N;;;;; +1D06;LATIN LETTER SMALL CAPITAL ETH;Ll;0;L;;;;;N;;;;; +1D07;LATIN LETTER SMALL CAPITAL E;Ll;0;L;;;;;N;;;;; +1D08;LATIN SMALL LETTER TURNED OPEN E;Ll;0;L;;;;;N;;;;; +1D09;LATIN SMALL LETTER TURNED I;Ll;0;L;;;;;N;;;;; +1D0A;LATIN LETTER SMALL CAPITAL J;Ll;0;L;;;;;N;;;;; +1D0B;LATIN LETTER SMALL CAPITAL K;Ll;0;L;;;;;N;;;;; +1D0C;LATIN LETTER SMALL CAPITAL L WITH STROKE;Ll;0;L;;;;;N;;;;; +1D0D;LATIN LETTER SMALL CAPITAL M;Ll;0;L;;;;;N;;;;; +1D0E;LATIN LETTER SMALL CAPITAL REVERSED N;Ll;0;L;;;;;N;;;;; +1D0F;LATIN LETTER SMALL CAPITAL O;Ll;0;L;;;;;N;;;;; +1D10;LATIN LETTER SMALL CAPITAL OPEN O;Ll;0;L;;;;;N;;;;; +1D11;LATIN SMALL LETTER SIDEWAYS O;Ll;0;L;;;;;N;;;;; +1D12;LATIN SMALL LETTER SIDEWAYS OPEN O;Ll;0;L;;;;;N;;;;; +1D13;LATIN SMALL LETTER SIDEWAYS O WITH STROKE;Ll;0;L;;;;;N;;;;; +1D14;LATIN SMALL LETTER TURNED OE;Ll;0;L;;;;;N;;;;; +1D15;LATIN LETTER SMALL CAPITAL OU;Ll;0;L;;;;;N;;;;; +1D16;LATIN SMALL LETTER TOP HALF O;Ll;0;L;;;;;N;;;;; +1D17;LATIN SMALL LETTER BOTTOM HALF O;Ll;0;L;;;;;N;;;;; +1D18;LATIN LETTER SMALL CAPITAL P;Ll;0;L;;;;;N;;;;; +1D19;LATIN LETTER SMALL CAPITAL REVERSED R;Ll;0;L;;;;;N;;;;; +1D1A;LATIN LETTER SMALL CAPITAL TURNED R;Ll;0;L;;;;;N;;;;; +1D1B;LATIN LETTER SMALL CAPITAL T;Ll;0;L;;;;;N;;;;; +1D1C;LATIN LETTER SMALL CAPITAL U;Ll;0;L;;;;;N;;;;; +1D1D;LATIN SMALL LETTER SIDEWAYS U;Ll;0;L;;;;;N;;;;; +1D1E;LATIN SMALL LETTER SIDEWAYS DIAERESIZED U;Ll;0;L;;;;;N;;;;; +1D1F;LATIN SMALL LETTER SIDEWAYS TURNED M;Ll;0;L;;;;;N;;;;; +1D20;LATIN LETTER SMALL CAPITAL V;Ll;0;L;;;;;N;;;;; +1D21;LATIN LETTER SMALL CAPITAL W;Ll;0;L;;;;;N;;;;; +1D22;LATIN LETTER SMALL CAPITAL Z;Ll;0;L;;;;;N;;;;; +1D23;LATIN LETTER SMALL CAPITAL EZH;Ll;0;L;;;;;N;;;;; +1D24;LATIN LETTER VOICED LARYNGEAL SPIRANT;Ll;0;L;;;;;N;;;;; +1D25;LATIN LETTER AIN;Ll;0;L;;;;;N;;;;; +1D26;GREEK LETTER SMALL CAPITAL GAMMA;Ll;0;L;;;;;N;;;;; +1D27;GREEK LETTER SMALL CAPITAL LAMDA;Ll;0;L;;;;;N;;;;; +1D28;GREEK LETTER SMALL CAPITAL PI;Ll;0;L;;;;;N;;;;; +1D29;GREEK LETTER SMALL CAPITAL RHO;Ll;0;L;;;;;N;;;;; +1D2A;GREEK LETTER SMALL CAPITAL PSI;Ll;0;L;;;;;N;;;;; +1D2B;CYRILLIC LETTER SMALL CAPITAL EL;Ll;0;L;;;;;N;;;;; +1D2C;MODIFIER LETTER CAPITAL A;Lm;0;L; 0041;;;;N;;;;; +1D2D;MODIFIER LETTER CAPITAL AE;Lm;0;L; 00C6;;;;N;;;;; +1D2E;MODIFIER LETTER CAPITAL B;Lm;0;L; 0042;;;;N;;;;; +1D2F;MODIFIER LETTER CAPITAL BARRED B;Lm;0;L;;;;;N;;;;; +1D30;MODIFIER LETTER CAPITAL D;Lm;0;L; 0044;;;;N;;;;; +1D31;MODIFIER LETTER CAPITAL E;Lm;0;L; 0045;;;;N;;;;; +1D32;MODIFIER LETTER CAPITAL REVERSED E;Lm;0;L; 018E;;;;N;;;;; +1D33;MODIFIER LETTER CAPITAL G;Lm;0;L; 0047;;;;N;;;;; +1D34;MODIFIER LETTER CAPITAL H;Lm;0;L; 0048;;;;N;;;;; +1D35;MODIFIER LETTER CAPITAL I;Lm;0;L; 0049;;;;N;;;;; +1D36;MODIFIER LETTER CAPITAL J;Lm;0;L; 004A;;;;N;;;;; +1D37;MODIFIER LETTER CAPITAL K;Lm;0;L; 004B;;;;N;;;;; +1D38;MODIFIER LETTER CAPITAL L;Lm;0;L; 004C;;;;N;;;;; +1D39;MODIFIER LETTER CAPITAL M;Lm;0;L; 004D;;;;N;;;;; +1D3A;MODIFIER LETTER CAPITAL N;Lm;0;L; 004E;;;;N;;;;; +1D3B;MODIFIER LETTER CAPITAL REVERSED N;Lm;0;L;;;;;N;;;;; +1D3C;MODIFIER LETTER CAPITAL O;Lm;0;L; 004F;;;;N;;;;; +1D3D;MODIFIER LETTER CAPITAL OU;Lm;0;L; 0222;;;;N;;;;; +1D3E;MODIFIER LETTER CAPITAL P;Lm;0;L; 0050;;;;N;;;;; +1D3F;MODIFIER LETTER CAPITAL R;Lm;0;L; 0052;;;;N;;;;; +1D40;MODIFIER LETTER CAPITAL T;Lm;0;L; 0054;;;;N;;;;; +1D41;MODIFIER LETTER CAPITAL U;Lm;0;L; 0055;;;;N;;;;; +1D42;MODIFIER LETTER CAPITAL W;Lm;0;L; 0057;;;;N;;;;; +1D43;MODIFIER LETTER SMALL A;Lm;0;L; 0061;;;;N;;;;; +1D44;MODIFIER LETTER SMALL TURNED A;Lm;0;L; 0250;;;;N;;;;; +1D45;MODIFIER LETTER SMALL ALPHA;Lm;0;L; 0251;;;;N;;;;; +1D46;MODIFIER LETTER SMALL TURNED AE;Lm;0;L; 1D02;;;;N;;;;; +1D47;MODIFIER LETTER SMALL B;Lm;0;L; 0062;;;;N;;;;; +1D48;MODIFIER LETTER SMALL D;Lm;0;L; 0064;;;;N;;;;; +1D49;MODIFIER LETTER SMALL E;Lm;0;L; 0065;;;;N;;;;; +1D4A;MODIFIER LETTER SMALL SCHWA;Lm;0;L; 0259;;;;N;;;;; +1D4B;MODIFIER LETTER SMALL OPEN E;Lm;0;L; 025B;;;;N;;;;; +1D4C;MODIFIER LETTER SMALL TURNED OPEN E;Lm;0;L; 025C;;;;N;;;;; +1D4D;MODIFIER LETTER SMALL G;Lm;0;L; 0067;;;;N;;;;; +1D4E;MODIFIER LETTER SMALL TURNED I;Lm;0;L;;;;;N;;;;; +1D4F;MODIFIER LETTER SMALL K;Lm;0;L; 006B;;;;N;;;;; +1D50;MODIFIER LETTER SMALL M;Lm;0;L; 006D;;;;N;;;;; +1D51;MODIFIER LETTER SMALL ENG;Lm;0;L; 014B;;;;N;;;;; +1D52;MODIFIER LETTER SMALL O;Lm;0;L; 006F;;;;N;;;;; +1D53;MODIFIER LETTER SMALL OPEN O;Lm;0;L; 0254;;;;N;;;;; +1D54;MODIFIER LETTER SMALL TOP HALF O;Lm;0;L; 1D16;;;;N;;;;; +1D55;MODIFIER LETTER SMALL BOTTOM HALF O;Lm;0;L; 1D17;;;;N;;;;; +1D56;MODIFIER LETTER SMALL P;Lm;0;L; 0070;;;;N;;;;; +1D57;MODIFIER LETTER SMALL T;Lm;0;L; 0074;;;;N;;;;; +1D58;MODIFIER LETTER SMALL U;Lm;0;L; 0075;;;;N;;;;; +1D59;MODIFIER LETTER SMALL SIDEWAYS U;Lm;0;L; 1D1D;;;;N;;;;; +1D5A;MODIFIER LETTER SMALL TURNED M;Lm;0;L; 026F;;;;N;;;;; +1D5B;MODIFIER LETTER SMALL V;Lm;0;L; 0076;;;;N;;;;; +1D5C;MODIFIER LETTER SMALL AIN;Lm;0;L; 1D25;;;;N;;;;; +1D5D;MODIFIER LETTER SMALL BETA;Lm;0;L; 03B2;;;;N;;;;; +1D5E;MODIFIER LETTER SMALL GREEK GAMMA;Lm;0;L; 03B3;;;;N;;;;; +1D5F;MODIFIER LETTER SMALL DELTA;Lm;0;L; 03B4;;;;N;;;;; +1D60;MODIFIER LETTER SMALL GREEK PHI;Lm;0;L; 03C6;;;;N;;;;; +1D61;MODIFIER LETTER SMALL CHI;Lm;0;L; 03C7;;;;N;;;;; +1D62;LATIN SUBSCRIPT SMALL LETTER I;Ll;0;L; 0069;;;;N;;;;; +1D63;LATIN SUBSCRIPT SMALL LETTER R;Ll;0;L; 0072;;;;N;;;;; +1D64;LATIN SUBSCRIPT SMALL LETTER U;Ll;0;L; 0075;;;;N;;;;; +1D65;LATIN SUBSCRIPT SMALL LETTER V;Ll;0;L; 0076;;;;N;;;;; +1D66;GREEK SUBSCRIPT SMALL LETTER BETA;Ll;0;L; 03B2;;;;N;;;;; +1D67;GREEK SUBSCRIPT SMALL LETTER GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D68;GREEK SUBSCRIPT SMALL LETTER RHO;Ll;0;L; 03C1;;;;N;;;;; +1D69;GREEK SUBSCRIPT SMALL LETTER PHI;Ll;0;L; 03C6;;;;N;;;;; +1D6A;GREEK SUBSCRIPT SMALL LETTER CHI;Ll;0;L; 03C7;;;;N;;;;; +1D6B;LATIN SMALL LETTER UE;Ll;0;L;;;;;N;;;;; +1D6C;LATIN SMALL LETTER B WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D6D;LATIN SMALL LETTER D WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D6E;LATIN SMALL LETTER F WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D6F;LATIN SMALL LETTER M WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D70;LATIN SMALL LETTER N WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D71;LATIN SMALL LETTER P WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D72;LATIN SMALL LETTER R WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D73;LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D74;LATIN SMALL LETTER S WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D75;LATIN SMALL LETTER T WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D76;LATIN SMALL LETTER Z WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D77;LATIN SMALL LETTER TURNED G;Ll;0;L;;;;;N;;;;; +1D78;MODIFIER LETTER CYRILLIC EN;Lm;0;L; 043D;;;;N;;;;; +1D79;LATIN SMALL LETTER INSULAR G;Ll;0;L;;;;;N;;;A77D;;A77D +1D7A;LATIN SMALL LETTER TH WITH STRIKETHROUGH;Ll;0;L;;;;;N;;;;; +1D7B;LATIN SMALL CAPITAL LETTER I WITH STROKE;Ll;0;L;;;;;N;;;;; +1D7C;LATIN SMALL LETTER IOTA WITH STROKE;Ll;0;L;;;;;N;;;;; +1D7D;LATIN SMALL LETTER P WITH STROKE;Ll;0;L;;;;;N;;;2C63;;2C63 +1D7E;LATIN SMALL CAPITAL LETTER U WITH STROKE;Ll;0;L;;;;;N;;;;; +1D7F;LATIN SMALL LETTER UPSILON WITH STROKE;Ll;0;L;;;;;N;;;;; +1D80;LATIN SMALL LETTER B WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D81;LATIN SMALL LETTER D WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D82;LATIN SMALL LETTER F WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D83;LATIN SMALL LETTER G WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D84;LATIN SMALL LETTER K WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D85;LATIN SMALL LETTER L WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D86;LATIN SMALL LETTER M WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D87;LATIN SMALL LETTER N WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D88;LATIN SMALL LETTER P WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D89;LATIN SMALL LETTER R WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8A;LATIN SMALL LETTER S WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8B;LATIN SMALL LETTER ESH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8C;LATIN SMALL LETTER V WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8D;LATIN SMALL LETTER X WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8F;LATIN SMALL LETTER A WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D90;LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D91;LATIN SMALL LETTER D WITH HOOK AND TAIL;Ll;0;L;;;;;N;;;;; +1D92;LATIN SMALL LETTER E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D93;LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D94;LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D95;LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D96;LATIN SMALL LETTER I WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D97;LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D98;LATIN SMALL LETTER ESH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D99;LATIN SMALL LETTER U WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D9A;LATIN SMALL LETTER EZH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D9B;MODIFIER LETTER SMALL TURNED ALPHA;Lm;0;L; 0252;;;;N;;;;; +1D9C;MODIFIER LETTER SMALL C;Lm;0;L; 0063;;;;N;;;;; +1D9D;MODIFIER LETTER SMALL C WITH CURL;Lm;0;L; 0255;;;;N;;;;; +1D9E;MODIFIER LETTER SMALL ETH;Lm;0;L; 00F0;;;;N;;;;; +1D9F;MODIFIER LETTER SMALL REVERSED OPEN E;Lm;0;L; 025C;;;;N;;;;; +1DA0;MODIFIER LETTER SMALL F;Lm;0;L; 0066;;;;N;;;;; +1DA1;MODIFIER LETTER SMALL DOTLESS J WITH STROKE;Lm;0;L; 025F;;;;N;;;;; +1DA2;MODIFIER LETTER SMALL SCRIPT G;Lm;0;L; 0261;;;;N;;;;; +1DA3;MODIFIER LETTER SMALL TURNED H;Lm;0;L; 0265;;;;N;;;;; +1DA4;MODIFIER LETTER SMALL I WITH STROKE;Lm;0;L; 0268;;;;N;;;;; +1DA5;MODIFIER LETTER SMALL IOTA;Lm;0;L; 0269;;;;N;;;;; +1DA6;MODIFIER LETTER SMALL CAPITAL I;Lm;0;L; 026A;;;;N;;;;; +1DA7;MODIFIER LETTER SMALL CAPITAL I WITH STROKE;Lm;0;L; 1D7B;;;;N;;;;; +1DA8;MODIFIER LETTER SMALL J WITH CROSSED-TAIL;Lm;0;L; 029D;;;;N;;;;; +1DA9;MODIFIER LETTER SMALL L WITH RETROFLEX HOOK;Lm;0;L; 026D;;;;N;;;;; +1DAA;MODIFIER LETTER SMALL L WITH PALATAL HOOK;Lm;0;L; 1D85;;;;N;;;;; +1DAB;MODIFIER LETTER SMALL CAPITAL L;Lm;0;L; 029F;;;;N;;;;; +1DAC;MODIFIER LETTER SMALL M WITH HOOK;Lm;0;L; 0271;;;;N;;;;; +1DAD;MODIFIER LETTER SMALL TURNED M WITH LONG LEG;Lm;0;L; 0270;;;;N;;;;; +1DAE;MODIFIER LETTER SMALL N WITH LEFT HOOK;Lm;0;L; 0272;;;;N;;;;; +1DAF;MODIFIER LETTER SMALL N WITH RETROFLEX HOOK;Lm;0;L; 0273;;;;N;;;;; +1DB0;MODIFIER LETTER SMALL CAPITAL N;Lm;0;L; 0274;;;;N;;;;; +1DB1;MODIFIER LETTER SMALL BARRED O;Lm;0;L; 0275;;;;N;;;;; +1DB2;MODIFIER LETTER SMALL PHI;Lm;0;L; 0278;;;;N;;;;; +1DB3;MODIFIER LETTER SMALL S WITH HOOK;Lm;0;L; 0282;;;;N;;;;; +1DB4;MODIFIER LETTER SMALL ESH;Lm;0;L; 0283;;;;N;;;;; +1DB5;MODIFIER LETTER SMALL T WITH PALATAL HOOK;Lm;0;L; 01AB;;;;N;;;;; +1DB6;MODIFIER LETTER SMALL U BAR;Lm;0;L; 0289;;;;N;;;;; +1DB7;MODIFIER LETTER SMALL UPSILON;Lm;0;L; 028A;;;;N;;;;; +1DB8;MODIFIER LETTER SMALL CAPITAL U;Lm;0;L; 1D1C;;;;N;;;;; +1DB9;MODIFIER LETTER SMALL V WITH HOOK;Lm;0;L; 028B;;;;N;;;;; +1DBA;MODIFIER LETTER SMALL TURNED V;Lm;0;L; 028C;;;;N;;;;; +1DBB;MODIFIER LETTER SMALL Z;Lm;0;L; 007A;;;;N;;;;; +1DBC;MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK;Lm;0;L; 0290;;;;N;;;;; +1DBD;MODIFIER LETTER SMALL Z WITH CURL;Lm;0;L; 0291;;;;N;;;;; +1DBE;MODIFIER LETTER SMALL EZH;Lm;0;L; 0292;;;;N;;;;; +1DBF;MODIFIER LETTER SMALL THETA;Lm;0;L; 03B8;;;;N;;;;; +1DC0;COMBINING DOTTED GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;; +1DC1;COMBINING DOTTED ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;; +1DC2;COMBINING SNAKE BELOW;Mn;220;NSM;;;;;N;;;;; +1DC3;COMBINING SUSPENSION MARK;Mn;230;NSM;;;;;N;;;;; +1DC4;COMBINING MACRON-ACUTE;Mn;230;NSM;;;;;N;;;;; +1DC5;COMBINING GRAVE-MACRON;Mn;230;NSM;;;;;N;;;;; +1DC6;COMBINING MACRON-GRAVE;Mn;230;NSM;;;;;N;;;;; +1DC7;COMBINING ACUTE-MACRON;Mn;230;NSM;;;;;N;;;;; +1DC8;COMBINING GRAVE-ACUTE-GRAVE;Mn;230;NSM;;;;;N;;;;; +1DC9;COMBINING ACUTE-GRAVE-ACUTE;Mn;230;NSM;;;;;N;;;;; +1DCA;COMBINING LATIN SMALL LETTER R BELOW;Mn;220;NSM;;;;;N;;;;; +1DCB;COMBINING BREVE-MACRON;Mn;230;NSM;;;;;N;;;;; +1DCC;COMBINING MACRON-BREVE;Mn;230;NSM;;;;;N;;;;; +1DCD;COMBINING DOUBLE CIRCUMFLEX ABOVE;Mn;234;NSM;;;;;N;;;;; +1DCE;COMBINING OGONEK ABOVE;Mn;214;NSM;;;;;N;;;;; +1DCF;COMBINING ZIGZAG BELOW;Mn;220;NSM;;;;;N;;;;; +1DD0;COMBINING IS BELOW;Mn;202;NSM;;;;;N;;;;; +1DD1;COMBINING UR ABOVE;Mn;230;NSM;;;;;N;;;;; +1DD2;COMBINING US ABOVE;Mn;230;NSM;;;;;N;;;;; +1DD3;COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE;Mn;230;NSM;;;;;N;;;;; +1DD4;COMBINING LATIN SMALL LETTER AE;Mn;230;NSM;;;;;N;;;;; +1DD5;COMBINING LATIN SMALL LETTER AO;Mn;230;NSM;;;;;N;;;;; +1DD6;COMBINING LATIN SMALL LETTER AV;Mn;230;NSM;;;;;N;;;;; +1DD7;COMBINING LATIN SMALL LETTER C CEDILLA;Mn;230;NSM;;;;;N;;;;; +1DD8;COMBINING LATIN SMALL LETTER INSULAR D;Mn;230;NSM;;;;;N;;;;; +1DD9;COMBINING LATIN SMALL LETTER ETH;Mn;230;NSM;;;;;N;;;;; +1DDA;COMBINING LATIN SMALL LETTER G;Mn;230;NSM;;;;;N;;;;; +1DDB;COMBINING LATIN LETTER SMALL CAPITAL G;Mn;230;NSM;;;;;N;;;;; +1DDC;COMBINING LATIN SMALL LETTER K;Mn;230;NSM;;;;;N;;;;; +1DDD;COMBINING LATIN SMALL LETTER L;Mn;230;NSM;;;;;N;;;;; +1DDE;COMBINING LATIN LETTER SMALL CAPITAL L;Mn;230;NSM;;;;;N;;;;; +1DDF;COMBINING LATIN LETTER SMALL CAPITAL M;Mn;230;NSM;;;;;N;;;;; +1DE0;COMBINING LATIN SMALL LETTER N;Mn;230;NSM;;;;;N;;;;; +1DE1;COMBINING LATIN LETTER SMALL CAPITAL N;Mn;230;NSM;;;;;N;;;;; +1DE2;COMBINING LATIN LETTER SMALL CAPITAL R;Mn;230;NSM;;;;;N;;;;; +1DE3;COMBINING LATIN SMALL LETTER R ROTUNDA;Mn;230;NSM;;;;;N;;;;; +1DE4;COMBINING LATIN SMALL LETTER S;Mn;230;NSM;;;;;N;;;;; +1DE5;COMBINING LATIN SMALL LETTER LONG S;Mn;230;NSM;;;;;N;;;;; +1DE6;COMBINING LATIN SMALL LETTER Z;Mn;230;NSM;;;;;N;;;;; +1DFD;COMBINING ALMOST EQUAL TO BELOW;Mn;220;NSM;;;;;N;;;;; +1DFE;COMBINING LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;; +1DFF;COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +1E00;LATIN CAPITAL LETTER A WITH RING BELOW;Lu;0;L;0041 0325;;;;N;;;;1E01; +1E01;LATIN SMALL LETTER A WITH RING BELOW;Ll;0;L;0061 0325;;;;N;;;1E00;;1E00 +1E02;LATIN CAPITAL LETTER B WITH DOT ABOVE;Lu;0;L;0042 0307;;;;N;;;;1E03; +1E03;LATIN SMALL LETTER B WITH DOT ABOVE;Ll;0;L;0062 0307;;;;N;;;1E02;;1E02 +1E04;LATIN CAPITAL LETTER B WITH DOT BELOW;Lu;0;L;0042 0323;;;;N;;;;1E05; +1E05;LATIN SMALL LETTER B WITH DOT BELOW;Ll;0;L;0062 0323;;;;N;;;1E04;;1E04 +1E06;LATIN CAPITAL LETTER B WITH LINE BELOW;Lu;0;L;0042 0331;;;;N;;;;1E07; +1E07;LATIN SMALL LETTER B WITH LINE BELOW;Ll;0;L;0062 0331;;;;N;;;1E06;;1E06 +1E08;LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE;Lu;0;L;00C7 0301;;;;N;;;;1E09; +1E09;LATIN SMALL LETTER C WITH CEDILLA AND ACUTE;Ll;0;L;00E7 0301;;;;N;;;1E08;;1E08 +1E0A;LATIN CAPITAL LETTER D WITH DOT ABOVE;Lu;0;L;0044 0307;;;;N;;;;1E0B; +1E0B;LATIN SMALL LETTER D WITH DOT ABOVE;Ll;0;L;0064 0307;;;;N;;;1E0A;;1E0A +1E0C;LATIN CAPITAL LETTER D WITH DOT BELOW;Lu;0;L;0044 0323;;;;N;;;;1E0D; +1E0D;LATIN SMALL LETTER D WITH DOT BELOW;Ll;0;L;0064 0323;;;;N;;;1E0C;;1E0C +1E0E;LATIN CAPITAL LETTER D WITH LINE BELOW;Lu;0;L;0044 0331;;;;N;;;;1E0F; +1E0F;LATIN SMALL LETTER D WITH LINE BELOW;Ll;0;L;0064 0331;;;;N;;;1E0E;;1E0E +1E10;LATIN CAPITAL LETTER D WITH CEDILLA;Lu;0;L;0044 0327;;;;N;;;;1E11; +1E11;LATIN SMALL LETTER D WITH CEDILLA;Ll;0;L;0064 0327;;;;N;;;1E10;;1E10 +1E12;LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW;Lu;0;L;0044 032D;;;;N;;;;1E13; +1E13;LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW;Ll;0;L;0064 032D;;;;N;;;1E12;;1E12 +1E14;LATIN CAPITAL LETTER E WITH MACRON AND GRAVE;Lu;0;L;0112 0300;;;;N;;;;1E15; +1E15;LATIN SMALL LETTER E WITH MACRON AND GRAVE;Ll;0;L;0113 0300;;;;N;;;1E14;;1E14 +1E16;LATIN CAPITAL LETTER E WITH MACRON AND ACUTE;Lu;0;L;0112 0301;;;;N;;;;1E17; +1E17;LATIN SMALL LETTER E WITH MACRON AND ACUTE;Ll;0;L;0113 0301;;;;N;;;1E16;;1E16 +1E18;LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW;Lu;0;L;0045 032D;;;;N;;;;1E19; +1E19;LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW;Ll;0;L;0065 032D;;;;N;;;1E18;;1E18 +1E1A;LATIN CAPITAL LETTER E WITH TILDE BELOW;Lu;0;L;0045 0330;;;;N;;;;1E1B; +1E1B;LATIN SMALL LETTER E WITH TILDE BELOW;Ll;0;L;0065 0330;;;;N;;;1E1A;;1E1A +1E1C;LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE;Lu;0;L;0228 0306;;;;N;;;;1E1D; +1E1D;LATIN SMALL LETTER E WITH CEDILLA AND BREVE;Ll;0;L;0229 0306;;;;N;;;1E1C;;1E1C +1E1E;LATIN CAPITAL LETTER F WITH DOT ABOVE;Lu;0;L;0046 0307;;;;N;;;;1E1F; +1E1F;LATIN SMALL LETTER F WITH DOT ABOVE;Ll;0;L;0066 0307;;;;N;;;1E1E;;1E1E +1E20;LATIN CAPITAL LETTER G WITH MACRON;Lu;0;L;0047 0304;;;;N;;;;1E21; +1E21;LATIN SMALL LETTER G WITH MACRON;Ll;0;L;0067 0304;;;;N;;;1E20;;1E20 +1E22;LATIN CAPITAL LETTER H WITH DOT ABOVE;Lu;0;L;0048 0307;;;;N;;;;1E23; +1E23;LATIN SMALL LETTER H WITH DOT ABOVE;Ll;0;L;0068 0307;;;;N;;;1E22;;1E22 +1E24;LATIN CAPITAL LETTER H WITH DOT BELOW;Lu;0;L;0048 0323;;;;N;;;;1E25; +1E25;LATIN SMALL LETTER H WITH DOT BELOW;Ll;0;L;0068 0323;;;;N;;;1E24;;1E24 +1E26;LATIN CAPITAL LETTER H WITH DIAERESIS;Lu;0;L;0048 0308;;;;N;;;;1E27; +1E27;LATIN SMALL LETTER H WITH DIAERESIS;Ll;0;L;0068 0308;;;;N;;;1E26;;1E26 +1E28;LATIN CAPITAL LETTER H WITH CEDILLA;Lu;0;L;0048 0327;;;;N;;;;1E29; +1E29;LATIN SMALL LETTER H WITH CEDILLA;Ll;0;L;0068 0327;;;;N;;;1E28;;1E28 +1E2A;LATIN CAPITAL LETTER H WITH BREVE BELOW;Lu;0;L;0048 032E;;;;N;;;;1E2B; +1E2B;LATIN SMALL LETTER H WITH BREVE BELOW;Ll;0;L;0068 032E;;;;N;;;1E2A;;1E2A +1E2C;LATIN CAPITAL LETTER I WITH TILDE BELOW;Lu;0;L;0049 0330;;;;N;;;;1E2D; +1E2D;LATIN SMALL LETTER I WITH TILDE BELOW;Ll;0;L;0069 0330;;;;N;;;1E2C;;1E2C +1E2E;LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE;Lu;0;L;00CF 0301;;;;N;;;;1E2F; +1E2F;LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE;Ll;0;L;00EF 0301;;;;N;;;1E2E;;1E2E +1E30;LATIN CAPITAL LETTER K WITH ACUTE;Lu;0;L;004B 0301;;;;N;;;;1E31; +1E31;LATIN SMALL LETTER K WITH ACUTE;Ll;0;L;006B 0301;;;;N;;;1E30;;1E30 +1E32;LATIN CAPITAL LETTER K WITH DOT BELOW;Lu;0;L;004B 0323;;;;N;;;;1E33; +1E33;LATIN SMALL LETTER K WITH DOT BELOW;Ll;0;L;006B 0323;;;;N;;;1E32;;1E32 +1E34;LATIN CAPITAL LETTER K WITH LINE BELOW;Lu;0;L;004B 0331;;;;N;;;;1E35; +1E35;LATIN SMALL LETTER K WITH LINE BELOW;Ll;0;L;006B 0331;;;;N;;;1E34;;1E34 +1E36;LATIN CAPITAL LETTER L WITH DOT BELOW;Lu;0;L;004C 0323;;;;N;;;;1E37; +1E37;LATIN SMALL LETTER L WITH DOT BELOW;Ll;0;L;006C 0323;;;;N;;;1E36;;1E36 +1E38;LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON;Lu;0;L;1E36 0304;;;;N;;;;1E39; +1E39;LATIN SMALL LETTER L WITH DOT BELOW AND MACRON;Ll;0;L;1E37 0304;;;;N;;;1E38;;1E38 +1E3A;LATIN CAPITAL LETTER L WITH LINE BELOW;Lu;0;L;004C 0331;;;;N;;;;1E3B; +1E3B;LATIN SMALL LETTER L WITH LINE BELOW;Ll;0;L;006C 0331;;;;N;;;1E3A;;1E3A +1E3C;LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW;Lu;0;L;004C 032D;;;;N;;;;1E3D; +1E3D;LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW;Ll;0;L;006C 032D;;;;N;;;1E3C;;1E3C +1E3E;LATIN CAPITAL LETTER M WITH ACUTE;Lu;0;L;004D 0301;;;;N;;;;1E3F; +1E3F;LATIN SMALL LETTER M WITH ACUTE;Ll;0;L;006D 0301;;;;N;;;1E3E;;1E3E +1E40;LATIN CAPITAL LETTER M WITH DOT ABOVE;Lu;0;L;004D 0307;;;;N;;;;1E41; +1E41;LATIN SMALL LETTER M WITH DOT ABOVE;Ll;0;L;006D 0307;;;;N;;;1E40;;1E40 +1E42;LATIN CAPITAL LETTER M WITH DOT BELOW;Lu;0;L;004D 0323;;;;N;;;;1E43; +1E43;LATIN SMALL LETTER M WITH DOT BELOW;Ll;0;L;006D 0323;;;;N;;;1E42;;1E42 +1E44;LATIN CAPITAL LETTER N WITH DOT ABOVE;Lu;0;L;004E 0307;;;;N;;;;1E45; +1E45;LATIN SMALL LETTER N WITH DOT ABOVE;Ll;0;L;006E 0307;;;;N;;;1E44;;1E44 +1E46;LATIN CAPITAL LETTER N WITH DOT BELOW;Lu;0;L;004E 0323;;;;N;;;;1E47; +1E47;LATIN SMALL LETTER N WITH DOT BELOW;Ll;0;L;006E 0323;;;;N;;;1E46;;1E46 +1E48;LATIN CAPITAL LETTER N WITH LINE BELOW;Lu;0;L;004E 0331;;;;N;;;;1E49; +1E49;LATIN SMALL LETTER N WITH LINE BELOW;Ll;0;L;006E 0331;;;;N;;;1E48;;1E48 +1E4A;LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW;Lu;0;L;004E 032D;;;;N;;;;1E4B; +1E4B;LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW;Ll;0;L;006E 032D;;;;N;;;1E4A;;1E4A +1E4C;LATIN CAPITAL LETTER O WITH TILDE AND ACUTE;Lu;0;L;00D5 0301;;;;N;;;;1E4D; +1E4D;LATIN SMALL LETTER O WITH TILDE AND ACUTE;Ll;0;L;00F5 0301;;;;N;;;1E4C;;1E4C +1E4E;LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS;Lu;0;L;00D5 0308;;;;N;;;;1E4F; +1E4F;LATIN SMALL LETTER O WITH TILDE AND DIAERESIS;Ll;0;L;00F5 0308;;;;N;;;1E4E;;1E4E +1E50;LATIN CAPITAL LETTER O WITH MACRON AND GRAVE;Lu;0;L;014C 0300;;;;N;;;;1E51; +1E51;LATIN SMALL LETTER O WITH MACRON AND GRAVE;Ll;0;L;014D 0300;;;;N;;;1E50;;1E50 +1E52;LATIN CAPITAL LETTER O WITH MACRON AND ACUTE;Lu;0;L;014C 0301;;;;N;;;;1E53; +1E53;LATIN SMALL LETTER O WITH MACRON AND ACUTE;Ll;0;L;014D 0301;;;;N;;;1E52;;1E52 +1E54;LATIN CAPITAL LETTER P WITH ACUTE;Lu;0;L;0050 0301;;;;N;;;;1E55; +1E55;LATIN SMALL LETTER P WITH ACUTE;Ll;0;L;0070 0301;;;;N;;;1E54;;1E54 +1E56;LATIN CAPITAL LETTER P WITH DOT ABOVE;Lu;0;L;0050 0307;;;;N;;;;1E57; +1E57;LATIN SMALL LETTER P WITH DOT ABOVE;Ll;0;L;0070 0307;;;;N;;;1E56;;1E56 +1E58;LATIN CAPITAL LETTER R WITH DOT ABOVE;Lu;0;L;0052 0307;;;;N;;;;1E59; +1E59;LATIN SMALL LETTER R WITH DOT ABOVE;Ll;0;L;0072 0307;;;;N;;;1E58;;1E58 +1E5A;LATIN CAPITAL LETTER R WITH DOT BELOW;Lu;0;L;0052 0323;;;;N;;;;1E5B; +1E5B;LATIN SMALL LETTER R WITH DOT BELOW;Ll;0;L;0072 0323;;;;N;;;1E5A;;1E5A +1E5C;LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON;Lu;0;L;1E5A 0304;;;;N;;;;1E5D; +1E5D;LATIN SMALL LETTER R WITH DOT BELOW AND MACRON;Ll;0;L;1E5B 0304;;;;N;;;1E5C;;1E5C +1E5E;LATIN CAPITAL LETTER R WITH LINE BELOW;Lu;0;L;0052 0331;;;;N;;;;1E5F; +1E5F;LATIN SMALL LETTER R WITH LINE BELOW;Ll;0;L;0072 0331;;;;N;;;1E5E;;1E5E +1E60;LATIN CAPITAL LETTER S WITH DOT ABOVE;Lu;0;L;0053 0307;;;;N;;;;1E61; +1E61;LATIN SMALL LETTER S WITH DOT ABOVE;Ll;0;L;0073 0307;;;;N;;;1E60;;1E60 +1E62;LATIN CAPITAL LETTER S WITH DOT BELOW;Lu;0;L;0053 0323;;;;N;;;;1E63; +1E63;LATIN SMALL LETTER S WITH DOT BELOW;Ll;0;L;0073 0323;;;;N;;;1E62;;1E62 +1E64;LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE;Lu;0;L;015A 0307;;;;N;;;;1E65; +1E65;LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE;Ll;0;L;015B 0307;;;;N;;;1E64;;1E64 +1E66;LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE;Lu;0;L;0160 0307;;;;N;;;;1E67; +1E67;LATIN SMALL LETTER S WITH CARON AND DOT ABOVE;Ll;0;L;0161 0307;;;;N;;;1E66;;1E66 +1E68;LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE;Lu;0;L;1E62 0307;;;;N;;;;1E69; +1E69;LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE;Ll;0;L;1E63 0307;;;;N;;;1E68;;1E68 +1E6A;LATIN CAPITAL LETTER T WITH DOT ABOVE;Lu;0;L;0054 0307;;;;N;;;;1E6B; +1E6B;LATIN SMALL LETTER T WITH DOT ABOVE;Ll;0;L;0074 0307;;;;N;;;1E6A;;1E6A +1E6C;LATIN CAPITAL LETTER T WITH DOT BELOW;Lu;0;L;0054 0323;;;;N;;;;1E6D; +1E6D;LATIN SMALL LETTER T WITH DOT BELOW;Ll;0;L;0074 0323;;;;N;;;1E6C;;1E6C +1E6E;LATIN CAPITAL LETTER T WITH LINE BELOW;Lu;0;L;0054 0331;;;;N;;;;1E6F; +1E6F;LATIN SMALL LETTER T WITH LINE BELOW;Ll;0;L;0074 0331;;;;N;;;1E6E;;1E6E +1E70;LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW;Lu;0;L;0054 032D;;;;N;;;;1E71; +1E71;LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW;Ll;0;L;0074 032D;;;;N;;;1E70;;1E70 +1E72;LATIN CAPITAL LETTER U WITH DIAERESIS BELOW;Lu;0;L;0055 0324;;;;N;;;;1E73; +1E73;LATIN SMALL LETTER U WITH DIAERESIS BELOW;Ll;0;L;0075 0324;;;;N;;;1E72;;1E72 +1E74;LATIN CAPITAL LETTER U WITH TILDE BELOW;Lu;0;L;0055 0330;;;;N;;;;1E75; +1E75;LATIN SMALL LETTER U WITH TILDE BELOW;Ll;0;L;0075 0330;;;;N;;;1E74;;1E74 +1E76;LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW;Lu;0;L;0055 032D;;;;N;;;;1E77; +1E77;LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW;Ll;0;L;0075 032D;;;;N;;;1E76;;1E76 +1E78;LATIN CAPITAL LETTER U WITH TILDE AND ACUTE;Lu;0;L;0168 0301;;;;N;;;;1E79; +1E79;LATIN SMALL LETTER U WITH TILDE AND ACUTE;Ll;0;L;0169 0301;;;;N;;;1E78;;1E78 +1E7A;LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS;Lu;0;L;016A 0308;;;;N;;;;1E7B; +1E7B;LATIN SMALL LETTER U WITH MACRON AND DIAERESIS;Ll;0;L;016B 0308;;;;N;;;1E7A;;1E7A +1E7C;LATIN CAPITAL LETTER V WITH TILDE;Lu;0;L;0056 0303;;;;N;;;;1E7D; +1E7D;LATIN SMALL LETTER V WITH TILDE;Ll;0;L;0076 0303;;;;N;;;1E7C;;1E7C +1E7E;LATIN CAPITAL LETTER V WITH DOT BELOW;Lu;0;L;0056 0323;;;;N;;;;1E7F; +1E7F;LATIN SMALL LETTER V WITH DOT BELOW;Ll;0;L;0076 0323;;;;N;;;1E7E;;1E7E +1E80;LATIN CAPITAL LETTER W WITH GRAVE;Lu;0;L;0057 0300;;;;N;;;;1E81; +1E81;LATIN SMALL LETTER W WITH GRAVE;Ll;0;L;0077 0300;;;;N;;;1E80;;1E80 +1E82;LATIN CAPITAL LETTER W WITH ACUTE;Lu;0;L;0057 0301;;;;N;;;;1E83; +1E83;LATIN SMALL LETTER W WITH ACUTE;Ll;0;L;0077 0301;;;;N;;;1E82;;1E82 +1E84;LATIN CAPITAL LETTER W WITH DIAERESIS;Lu;0;L;0057 0308;;;;N;;;;1E85; +1E85;LATIN SMALL LETTER W WITH DIAERESIS;Ll;0;L;0077 0308;;;;N;;;1E84;;1E84 +1E86;LATIN CAPITAL LETTER W WITH DOT ABOVE;Lu;0;L;0057 0307;;;;N;;;;1E87; +1E87;LATIN SMALL LETTER W WITH DOT ABOVE;Ll;0;L;0077 0307;;;;N;;;1E86;;1E86 +1E88;LATIN CAPITAL LETTER W WITH DOT BELOW;Lu;0;L;0057 0323;;;;N;;;;1E89; +1E89;LATIN SMALL LETTER W WITH DOT BELOW;Ll;0;L;0077 0323;;;;N;;;1E88;;1E88 +1E8A;LATIN CAPITAL LETTER X WITH DOT ABOVE;Lu;0;L;0058 0307;;;;N;;;;1E8B; +1E8B;LATIN SMALL LETTER X WITH DOT ABOVE;Ll;0;L;0078 0307;;;;N;;;1E8A;;1E8A +1E8C;LATIN CAPITAL LETTER X WITH DIAERESIS;Lu;0;L;0058 0308;;;;N;;;;1E8D; +1E8D;LATIN SMALL LETTER X WITH DIAERESIS;Ll;0;L;0078 0308;;;;N;;;1E8C;;1E8C +1E8E;LATIN CAPITAL LETTER Y WITH DOT ABOVE;Lu;0;L;0059 0307;;;;N;;;;1E8F; +1E8F;LATIN SMALL LETTER Y WITH DOT ABOVE;Ll;0;L;0079 0307;;;;N;;;1E8E;;1E8E +1E90;LATIN CAPITAL LETTER Z WITH CIRCUMFLEX;Lu;0;L;005A 0302;;;;N;;;;1E91; +1E91;LATIN SMALL LETTER Z WITH CIRCUMFLEX;Ll;0;L;007A 0302;;;;N;;;1E90;;1E90 +1E92;LATIN CAPITAL LETTER Z WITH DOT BELOW;Lu;0;L;005A 0323;;;;N;;;;1E93; +1E93;LATIN SMALL LETTER Z WITH DOT BELOW;Ll;0;L;007A 0323;;;;N;;;1E92;;1E92 +1E94;LATIN CAPITAL LETTER Z WITH LINE BELOW;Lu;0;L;005A 0331;;;;N;;;;1E95; +1E95;LATIN SMALL LETTER Z WITH LINE BELOW;Ll;0;L;007A 0331;;;;N;;;1E94;;1E94 +1E96;LATIN SMALL LETTER H WITH LINE BELOW;Ll;0;L;0068 0331;;;;N;;;;; +1E97;LATIN SMALL LETTER T WITH DIAERESIS;Ll;0;L;0074 0308;;;;N;;;;; +1E98;LATIN SMALL LETTER W WITH RING ABOVE;Ll;0;L;0077 030A;;;;N;;;;; +1E99;LATIN SMALL LETTER Y WITH RING ABOVE;Ll;0;L;0079 030A;;;;N;;;;; +1E9A;LATIN SMALL LETTER A WITH RIGHT HALF RING;Ll;0;L; 0061 02BE;;;;N;;;;; +1E9B;LATIN SMALL LETTER LONG S WITH DOT ABOVE;Ll;0;L;017F 0307;;;;N;;;1E60;;1E60 +1E9C;LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;;; +1E9D;LATIN SMALL LETTER LONG S WITH HIGH STROKE;Ll;0;L;;;;;N;;;;; +1E9E;LATIN CAPITAL LETTER SHARP S;Lu;0;L;;;;;N;;;;00DF; +1E9F;LATIN SMALL LETTER DELTA;Ll;0;L;;;;;N;;;;; +1EA0;LATIN CAPITAL LETTER A WITH DOT BELOW;Lu;0;L;0041 0323;;;;N;;;;1EA1; +1EA1;LATIN SMALL LETTER A WITH DOT BELOW;Ll;0;L;0061 0323;;;;N;;;1EA0;;1EA0 +1EA2;LATIN CAPITAL LETTER A WITH HOOK ABOVE;Lu;0;L;0041 0309;;;;N;;;;1EA3; +1EA3;LATIN SMALL LETTER A WITH HOOK ABOVE;Ll;0;L;0061 0309;;;;N;;;1EA2;;1EA2 +1EA4;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00C2 0301;;;;N;;;;1EA5; +1EA5;LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00E2 0301;;;;N;;;1EA4;;1EA4 +1EA6;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00C2 0300;;;;N;;;;1EA7; +1EA7;LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00E2 0300;;;;N;;;1EA6;;1EA6 +1EA8;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00C2 0309;;;;N;;;;1EA9; +1EA9;LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00E2 0309;;;;N;;;1EA8;;1EA8 +1EAA;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE;Lu;0;L;00C2 0303;;;;N;;;;1EAB; +1EAB;LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE;Ll;0;L;00E2 0303;;;;N;;;1EAA;;1EAA +1EAC;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EA0 0302;;;;N;;;;1EAD; +1EAD;LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EA1 0302;;;;N;;;1EAC;;1EAC +1EAE;LATIN CAPITAL LETTER A WITH BREVE AND ACUTE;Lu;0;L;0102 0301;;;;N;;;;1EAF; +1EAF;LATIN SMALL LETTER A WITH BREVE AND ACUTE;Ll;0;L;0103 0301;;;;N;;;1EAE;;1EAE +1EB0;LATIN CAPITAL LETTER A WITH BREVE AND GRAVE;Lu;0;L;0102 0300;;;;N;;;;1EB1; +1EB1;LATIN SMALL LETTER A WITH BREVE AND GRAVE;Ll;0;L;0103 0300;;;;N;;;1EB0;;1EB0 +1EB2;LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE;Lu;0;L;0102 0309;;;;N;;;;1EB3; +1EB3;LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE;Ll;0;L;0103 0309;;;;N;;;1EB2;;1EB2 +1EB4;LATIN CAPITAL LETTER A WITH BREVE AND TILDE;Lu;0;L;0102 0303;;;;N;;;;1EB5; +1EB5;LATIN SMALL LETTER A WITH BREVE AND TILDE;Ll;0;L;0103 0303;;;;N;;;1EB4;;1EB4 +1EB6;LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW;Lu;0;L;1EA0 0306;;;;N;;;;1EB7; +1EB7;LATIN SMALL LETTER A WITH BREVE AND DOT BELOW;Ll;0;L;1EA1 0306;;;;N;;;1EB6;;1EB6 +1EB8;LATIN CAPITAL LETTER E WITH DOT BELOW;Lu;0;L;0045 0323;;;;N;;;;1EB9; +1EB9;LATIN SMALL LETTER E WITH DOT BELOW;Ll;0;L;0065 0323;;;;N;;;1EB8;;1EB8 +1EBA;LATIN CAPITAL LETTER E WITH HOOK ABOVE;Lu;0;L;0045 0309;;;;N;;;;1EBB; +1EBB;LATIN SMALL LETTER E WITH HOOK ABOVE;Ll;0;L;0065 0309;;;;N;;;1EBA;;1EBA +1EBC;LATIN CAPITAL LETTER E WITH TILDE;Lu;0;L;0045 0303;;;;N;;;;1EBD; +1EBD;LATIN SMALL LETTER E WITH TILDE;Ll;0;L;0065 0303;;;;N;;;1EBC;;1EBC +1EBE;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00CA 0301;;;;N;;;;1EBF; +1EBF;LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00EA 0301;;;;N;;;1EBE;;1EBE +1EC0;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00CA 0300;;;;N;;;;1EC1; +1EC1;LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00EA 0300;;;;N;;;1EC0;;1EC0 +1EC2;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00CA 0309;;;;N;;;;1EC3; +1EC3;LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00EA 0309;;;;N;;;1EC2;;1EC2 +1EC4;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE;Lu;0;L;00CA 0303;;;;N;;;;1EC5; +1EC5;LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE;Ll;0;L;00EA 0303;;;;N;;;1EC4;;1EC4 +1EC6;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EB8 0302;;;;N;;;;1EC7; +1EC7;LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EB9 0302;;;;N;;;1EC6;;1EC6 +1EC8;LATIN CAPITAL LETTER I WITH HOOK ABOVE;Lu;0;L;0049 0309;;;;N;;;;1EC9; +1EC9;LATIN SMALL LETTER I WITH HOOK ABOVE;Ll;0;L;0069 0309;;;;N;;;1EC8;;1EC8 +1ECA;LATIN CAPITAL LETTER I WITH DOT BELOW;Lu;0;L;0049 0323;;;;N;;;;1ECB; +1ECB;LATIN SMALL LETTER I WITH DOT BELOW;Ll;0;L;0069 0323;;;;N;;;1ECA;;1ECA +1ECC;LATIN CAPITAL LETTER O WITH DOT BELOW;Lu;0;L;004F 0323;;;;N;;;;1ECD; +1ECD;LATIN SMALL LETTER O WITH DOT BELOW;Ll;0;L;006F 0323;;;;N;;;1ECC;;1ECC +1ECE;LATIN CAPITAL LETTER O WITH HOOK ABOVE;Lu;0;L;004F 0309;;;;N;;;;1ECF; +1ECF;LATIN SMALL LETTER O WITH HOOK ABOVE;Ll;0;L;006F 0309;;;;N;;;1ECE;;1ECE +1ED0;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00D4 0301;;;;N;;;;1ED1; +1ED1;LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00F4 0301;;;;N;;;1ED0;;1ED0 +1ED2;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00D4 0300;;;;N;;;;1ED3; +1ED3;LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00F4 0300;;;;N;;;1ED2;;1ED2 +1ED4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00D4 0309;;;;N;;;;1ED5; +1ED5;LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00F4 0309;;;;N;;;1ED4;;1ED4 +1ED6;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE;Lu;0;L;00D4 0303;;;;N;;;;1ED7; +1ED7;LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE;Ll;0;L;00F4 0303;;;;N;;;1ED6;;1ED6 +1ED8;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1ECC 0302;;;;N;;;;1ED9; +1ED9;LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1ECD 0302;;;;N;;;1ED8;;1ED8 +1EDA;LATIN CAPITAL LETTER O WITH HORN AND ACUTE;Lu;0;L;01A0 0301;;;;N;;;;1EDB; +1EDB;LATIN SMALL LETTER O WITH HORN AND ACUTE;Ll;0;L;01A1 0301;;;;N;;;1EDA;;1EDA +1EDC;LATIN CAPITAL LETTER O WITH HORN AND GRAVE;Lu;0;L;01A0 0300;;;;N;;;;1EDD; +1EDD;LATIN SMALL LETTER O WITH HORN AND GRAVE;Ll;0;L;01A1 0300;;;;N;;;1EDC;;1EDC +1EDE;LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE;Lu;0;L;01A0 0309;;;;N;;;;1EDF; +1EDF;LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE;Ll;0;L;01A1 0309;;;;N;;;1EDE;;1EDE +1EE0;LATIN CAPITAL LETTER O WITH HORN AND TILDE;Lu;0;L;01A0 0303;;;;N;;;;1EE1; +1EE1;LATIN SMALL LETTER O WITH HORN AND TILDE;Ll;0;L;01A1 0303;;;;N;;;1EE0;;1EE0 +1EE2;LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW;Lu;0;L;01A0 0323;;;;N;;;;1EE3; +1EE3;LATIN SMALL LETTER O WITH HORN AND DOT BELOW;Ll;0;L;01A1 0323;;;;N;;;1EE2;;1EE2 +1EE4;LATIN CAPITAL LETTER U WITH DOT BELOW;Lu;0;L;0055 0323;;;;N;;;;1EE5; +1EE5;LATIN SMALL LETTER U WITH DOT BELOW;Ll;0;L;0075 0323;;;;N;;;1EE4;;1EE4 +1EE6;LATIN CAPITAL LETTER U WITH HOOK ABOVE;Lu;0;L;0055 0309;;;;N;;;;1EE7; +1EE7;LATIN SMALL LETTER U WITH HOOK ABOVE;Ll;0;L;0075 0309;;;;N;;;1EE6;;1EE6 +1EE8;LATIN CAPITAL LETTER U WITH HORN AND ACUTE;Lu;0;L;01AF 0301;;;;N;;;;1EE9; +1EE9;LATIN SMALL LETTER U WITH HORN AND ACUTE;Ll;0;L;01B0 0301;;;;N;;;1EE8;;1EE8 +1EEA;LATIN CAPITAL LETTER U WITH HORN AND GRAVE;Lu;0;L;01AF 0300;;;;N;;;;1EEB; +1EEB;LATIN SMALL LETTER U WITH HORN AND GRAVE;Ll;0;L;01B0 0300;;;;N;;;1EEA;;1EEA +1EEC;LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE;Lu;0;L;01AF 0309;;;;N;;;;1EED; +1EED;LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE;Ll;0;L;01B0 0309;;;;N;;;1EEC;;1EEC +1EEE;LATIN CAPITAL LETTER U WITH HORN AND TILDE;Lu;0;L;01AF 0303;;;;N;;;;1EEF; +1EEF;LATIN SMALL LETTER U WITH HORN AND TILDE;Ll;0;L;01B0 0303;;;;N;;;1EEE;;1EEE +1EF0;LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW;Lu;0;L;01AF 0323;;;;N;;;;1EF1; +1EF1;LATIN SMALL LETTER U WITH HORN AND DOT BELOW;Ll;0;L;01B0 0323;;;;N;;;1EF0;;1EF0 +1EF2;LATIN CAPITAL LETTER Y WITH GRAVE;Lu;0;L;0059 0300;;;;N;;;;1EF3; +1EF3;LATIN SMALL LETTER Y WITH GRAVE;Ll;0;L;0079 0300;;;;N;;;1EF2;;1EF2 +1EF4;LATIN CAPITAL LETTER Y WITH DOT BELOW;Lu;0;L;0059 0323;;;;N;;;;1EF5; +1EF5;LATIN SMALL LETTER Y WITH DOT BELOW;Ll;0;L;0079 0323;;;;N;;;1EF4;;1EF4 +1EF6;LATIN CAPITAL LETTER Y WITH HOOK ABOVE;Lu;0;L;0059 0309;;;;N;;;;1EF7; +1EF7;LATIN SMALL LETTER Y WITH HOOK ABOVE;Ll;0;L;0079 0309;;;;N;;;1EF6;;1EF6 +1EF8;LATIN CAPITAL LETTER Y WITH TILDE;Lu;0;L;0059 0303;;;;N;;;;1EF9; +1EF9;LATIN SMALL LETTER Y WITH TILDE;Ll;0;L;0079 0303;;;;N;;;1EF8;;1EF8 +1EFA;LATIN CAPITAL LETTER MIDDLE-WELSH LL;Lu;0;L;;;;;N;;;;1EFB; +1EFB;LATIN SMALL LETTER MIDDLE-WELSH LL;Ll;0;L;;;;;N;;;1EFA;;1EFA +1EFC;LATIN CAPITAL LETTER MIDDLE-WELSH V;Lu;0;L;;;;;N;;;;1EFD; +1EFD;LATIN SMALL LETTER MIDDLE-WELSH V;Ll;0;L;;;;;N;;;1EFC;;1EFC +1EFE;LATIN CAPITAL LETTER Y WITH LOOP;Lu;0;L;;;;;N;;;;1EFF; +1EFF;LATIN SMALL LETTER Y WITH LOOP;Ll;0;L;;;;;N;;;1EFE;;1EFE +1F00;GREEK SMALL LETTER ALPHA WITH PSILI;Ll;0;L;03B1 0313;;;;N;;;1F08;;1F08 +1F01;GREEK SMALL LETTER ALPHA WITH DASIA;Ll;0;L;03B1 0314;;;;N;;;1F09;;1F09 +1F02;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA;Ll;0;L;1F00 0300;;;;N;;;1F0A;;1F0A +1F03;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA;Ll;0;L;1F01 0300;;;;N;;;1F0B;;1F0B +1F04;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA;Ll;0;L;1F00 0301;;;;N;;;1F0C;;1F0C +1F05;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA;Ll;0;L;1F01 0301;;;;N;;;1F0D;;1F0D +1F06;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI;Ll;0;L;1F00 0342;;;;N;;;1F0E;;1F0E +1F07;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI;Ll;0;L;1F01 0342;;;;N;;;1F0F;;1F0F +1F08;GREEK CAPITAL LETTER ALPHA WITH PSILI;Lu;0;L;0391 0313;;;;N;;;;1F00; +1F09;GREEK CAPITAL LETTER ALPHA WITH DASIA;Lu;0;L;0391 0314;;;;N;;;;1F01; +1F0A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA;Lu;0;L;1F08 0300;;;;N;;;;1F02; +1F0B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA;Lu;0;L;1F09 0300;;;;N;;;;1F03; +1F0C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA;Lu;0;L;1F08 0301;;;;N;;;;1F04; +1F0D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA;Lu;0;L;1F09 0301;;;;N;;;;1F05; +1F0E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI;Lu;0;L;1F08 0342;;;;N;;;;1F06; +1F0F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI;Lu;0;L;1F09 0342;;;;N;;;;1F07; +1F10;GREEK SMALL LETTER EPSILON WITH PSILI;Ll;0;L;03B5 0313;;;;N;;;1F18;;1F18 +1F11;GREEK SMALL LETTER EPSILON WITH DASIA;Ll;0;L;03B5 0314;;;;N;;;1F19;;1F19 +1F12;GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA;Ll;0;L;1F10 0300;;;;N;;;1F1A;;1F1A +1F13;GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA;Ll;0;L;1F11 0300;;;;N;;;1F1B;;1F1B +1F14;GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA;Ll;0;L;1F10 0301;;;;N;;;1F1C;;1F1C +1F15;GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA;Ll;0;L;1F11 0301;;;;N;;;1F1D;;1F1D +1F18;GREEK CAPITAL LETTER EPSILON WITH PSILI;Lu;0;L;0395 0313;;;;N;;;;1F10; +1F19;GREEK CAPITAL LETTER EPSILON WITH DASIA;Lu;0;L;0395 0314;;;;N;;;;1F11; +1F1A;GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA;Lu;0;L;1F18 0300;;;;N;;;;1F12; +1F1B;GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA;Lu;0;L;1F19 0300;;;;N;;;;1F13; +1F1C;GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA;Lu;0;L;1F18 0301;;;;N;;;;1F14; +1F1D;GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA;Lu;0;L;1F19 0301;;;;N;;;;1F15; +1F20;GREEK SMALL LETTER ETA WITH PSILI;Ll;0;L;03B7 0313;;;;N;;;1F28;;1F28 +1F21;GREEK SMALL LETTER ETA WITH DASIA;Ll;0;L;03B7 0314;;;;N;;;1F29;;1F29 +1F22;GREEK SMALL LETTER ETA WITH PSILI AND VARIA;Ll;0;L;1F20 0300;;;;N;;;1F2A;;1F2A +1F23;GREEK SMALL LETTER ETA WITH DASIA AND VARIA;Ll;0;L;1F21 0300;;;;N;;;1F2B;;1F2B +1F24;GREEK SMALL LETTER ETA WITH PSILI AND OXIA;Ll;0;L;1F20 0301;;;;N;;;1F2C;;1F2C +1F25;GREEK SMALL LETTER ETA WITH DASIA AND OXIA;Ll;0;L;1F21 0301;;;;N;;;1F2D;;1F2D +1F26;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI;Ll;0;L;1F20 0342;;;;N;;;1F2E;;1F2E +1F27;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI;Ll;0;L;1F21 0342;;;;N;;;1F2F;;1F2F +1F28;GREEK CAPITAL LETTER ETA WITH PSILI;Lu;0;L;0397 0313;;;;N;;;;1F20; +1F29;GREEK CAPITAL LETTER ETA WITH DASIA;Lu;0;L;0397 0314;;;;N;;;;1F21; +1F2A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA;Lu;0;L;1F28 0300;;;;N;;;;1F22; +1F2B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA;Lu;0;L;1F29 0300;;;;N;;;;1F23; +1F2C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA;Lu;0;L;1F28 0301;;;;N;;;;1F24; +1F2D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA;Lu;0;L;1F29 0301;;;;N;;;;1F25; +1F2E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI;Lu;0;L;1F28 0342;;;;N;;;;1F26; +1F2F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI;Lu;0;L;1F29 0342;;;;N;;;;1F27; +1F30;GREEK SMALL LETTER IOTA WITH PSILI;Ll;0;L;03B9 0313;;;;N;;;1F38;;1F38 +1F31;GREEK SMALL LETTER IOTA WITH DASIA;Ll;0;L;03B9 0314;;;;N;;;1F39;;1F39 +1F32;GREEK SMALL LETTER IOTA WITH PSILI AND VARIA;Ll;0;L;1F30 0300;;;;N;;;1F3A;;1F3A +1F33;GREEK SMALL LETTER IOTA WITH DASIA AND VARIA;Ll;0;L;1F31 0300;;;;N;;;1F3B;;1F3B +1F34;GREEK SMALL LETTER IOTA WITH PSILI AND OXIA;Ll;0;L;1F30 0301;;;;N;;;1F3C;;1F3C +1F35;GREEK SMALL LETTER IOTA WITH DASIA AND OXIA;Ll;0;L;1F31 0301;;;;N;;;1F3D;;1F3D +1F36;GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI;Ll;0;L;1F30 0342;;;;N;;;1F3E;;1F3E +1F37;GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI;Ll;0;L;1F31 0342;;;;N;;;1F3F;;1F3F +1F38;GREEK CAPITAL LETTER IOTA WITH PSILI;Lu;0;L;0399 0313;;;;N;;;;1F30; +1F39;GREEK CAPITAL LETTER IOTA WITH DASIA;Lu;0;L;0399 0314;;;;N;;;;1F31; +1F3A;GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA;Lu;0;L;1F38 0300;;;;N;;;;1F32; +1F3B;GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA;Lu;0;L;1F39 0300;;;;N;;;;1F33; +1F3C;GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA;Lu;0;L;1F38 0301;;;;N;;;;1F34; +1F3D;GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA;Lu;0;L;1F39 0301;;;;N;;;;1F35; +1F3E;GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI;Lu;0;L;1F38 0342;;;;N;;;;1F36; +1F3F;GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI;Lu;0;L;1F39 0342;;;;N;;;;1F37; +1F40;GREEK SMALL LETTER OMICRON WITH PSILI;Ll;0;L;03BF 0313;;;;N;;;1F48;;1F48 +1F41;GREEK SMALL LETTER OMICRON WITH DASIA;Ll;0;L;03BF 0314;;;;N;;;1F49;;1F49 +1F42;GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA;Ll;0;L;1F40 0300;;;;N;;;1F4A;;1F4A +1F43;GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA;Ll;0;L;1F41 0300;;;;N;;;1F4B;;1F4B +1F44;GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA;Ll;0;L;1F40 0301;;;;N;;;1F4C;;1F4C +1F45;GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA;Ll;0;L;1F41 0301;;;;N;;;1F4D;;1F4D +1F48;GREEK CAPITAL LETTER OMICRON WITH PSILI;Lu;0;L;039F 0313;;;;N;;;;1F40; +1F49;GREEK CAPITAL LETTER OMICRON WITH DASIA;Lu;0;L;039F 0314;;;;N;;;;1F41; +1F4A;GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA;Lu;0;L;1F48 0300;;;;N;;;;1F42; +1F4B;GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA;Lu;0;L;1F49 0300;;;;N;;;;1F43; +1F4C;GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA;Lu;0;L;1F48 0301;;;;N;;;;1F44; +1F4D;GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA;Lu;0;L;1F49 0301;;;;N;;;;1F45; +1F50;GREEK SMALL LETTER UPSILON WITH PSILI;Ll;0;L;03C5 0313;;;;N;;;;; +1F51;GREEK SMALL LETTER UPSILON WITH DASIA;Ll;0;L;03C5 0314;;;;N;;;1F59;;1F59 +1F52;GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA;Ll;0;L;1F50 0300;;;;N;;;;; +1F53;GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA;Ll;0;L;1F51 0300;;;;N;;;1F5B;;1F5B +1F54;GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA;Ll;0;L;1F50 0301;;;;N;;;;; +1F55;GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA;Ll;0;L;1F51 0301;;;;N;;;1F5D;;1F5D +1F56;GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI;Ll;0;L;1F50 0342;;;;N;;;;; +1F57;GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI;Ll;0;L;1F51 0342;;;;N;;;1F5F;;1F5F +1F59;GREEK CAPITAL LETTER UPSILON WITH DASIA;Lu;0;L;03A5 0314;;;;N;;;;1F51; +1F5B;GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA;Lu;0;L;1F59 0300;;;;N;;;;1F53; +1F5D;GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA;Lu;0;L;1F59 0301;;;;N;;;;1F55; +1F5F;GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI;Lu;0;L;1F59 0342;;;;N;;;;1F57; +1F60;GREEK SMALL LETTER OMEGA WITH PSILI;Ll;0;L;03C9 0313;;;;N;;;1F68;;1F68 +1F61;GREEK SMALL LETTER OMEGA WITH DASIA;Ll;0;L;03C9 0314;;;;N;;;1F69;;1F69 +1F62;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA;Ll;0;L;1F60 0300;;;;N;;;1F6A;;1F6A +1F63;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA;Ll;0;L;1F61 0300;;;;N;;;1F6B;;1F6B +1F64;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA;Ll;0;L;1F60 0301;;;;N;;;1F6C;;1F6C +1F65;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA;Ll;0;L;1F61 0301;;;;N;;;1F6D;;1F6D +1F66;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI;Ll;0;L;1F60 0342;;;;N;;;1F6E;;1F6E +1F67;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI;Ll;0;L;1F61 0342;;;;N;;;1F6F;;1F6F +1F68;GREEK CAPITAL LETTER OMEGA WITH PSILI;Lu;0;L;03A9 0313;;;;N;;;;1F60; +1F69;GREEK CAPITAL LETTER OMEGA WITH DASIA;Lu;0;L;03A9 0314;;;;N;;;;1F61; +1F6A;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA;Lu;0;L;1F68 0300;;;;N;;;;1F62; +1F6B;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA;Lu;0;L;1F69 0300;;;;N;;;;1F63; +1F6C;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA;Lu;0;L;1F68 0301;;;;N;;;;1F64; +1F6D;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA;Lu;0;L;1F69 0301;;;;N;;;;1F65; +1F6E;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI;Lu;0;L;1F68 0342;;;;N;;;;1F66; +1F6F;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI;Lu;0;L;1F69 0342;;;;N;;;;1F67; +1F70;GREEK SMALL LETTER ALPHA WITH VARIA;Ll;0;L;03B1 0300;;;;N;;;1FBA;;1FBA +1F71;GREEK SMALL LETTER ALPHA WITH OXIA;Ll;0;L;03AC;;;;N;;;1FBB;;1FBB +1F72;GREEK SMALL LETTER EPSILON WITH VARIA;Ll;0;L;03B5 0300;;;;N;;;1FC8;;1FC8 +1F73;GREEK SMALL LETTER EPSILON WITH OXIA;Ll;0;L;03AD;;;;N;;;1FC9;;1FC9 +1F74;GREEK SMALL LETTER ETA WITH VARIA;Ll;0;L;03B7 0300;;;;N;;;1FCA;;1FCA +1F75;GREEK SMALL LETTER ETA WITH OXIA;Ll;0;L;03AE;;;;N;;;1FCB;;1FCB +1F76;GREEK SMALL LETTER IOTA WITH VARIA;Ll;0;L;03B9 0300;;;;N;;;1FDA;;1FDA +1F77;GREEK SMALL LETTER IOTA WITH OXIA;Ll;0;L;03AF;;;;N;;;1FDB;;1FDB +1F78;GREEK SMALL LETTER OMICRON WITH VARIA;Ll;0;L;03BF 0300;;;;N;;;1FF8;;1FF8 +1F79;GREEK SMALL LETTER OMICRON WITH OXIA;Ll;0;L;03CC;;;;N;;;1FF9;;1FF9 +1F7A;GREEK SMALL LETTER UPSILON WITH VARIA;Ll;0;L;03C5 0300;;;;N;;;1FEA;;1FEA +1F7B;GREEK SMALL LETTER UPSILON WITH OXIA;Ll;0;L;03CD;;;;N;;;1FEB;;1FEB +1F7C;GREEK SMALL LETTER OMEGA WITH VARIA;Ll;0;L;03C9 0300;;;;N;;;1FFA;;1FFA +1F7D;GREEK SMALL LETTER OMEGA WITH OXIA;Ll;0;L;03CE;;;;N;;;1FFB;;1FFB +1F80;GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F00 0345;;;;N;;;1F88;;1F88 +1F81;GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F01 0345;;;;N;;;1F89;;1F89 +1F82;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F02 0345;;;;N;;;1F8A;;1F8A +1F83;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F03 0345;;;;N;;;1F8B;;1F8B +1F84;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F04 0345;;;;N;;;1F8C;;1F8C +1F85;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F05 0345;;;;N;;;1F8D;;1F8D +1F86;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F06 0345;;;;N;;;1F8E;;1F8E +1F87;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F07 0345;;;;N;;;1F8F;;1F8F +1F88;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F08 0345;;;;N;;;;1F80; +1F89;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F09 0345;;;;N;;;;1F81; +1F8A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0A 0345;;;;N;;;;1F82; +1F8B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0B 0345;;;;N;;;;1F83; +1F8C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0C 0345;;;;N;;;;1F84; +1F8D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0D 0345;;;;N;;;;1F85; +1F8E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0E 0345;;;;N;;;;1F86; +1F8F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0F 0345;;;;N;;;;1F87; +1F90;GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F20 0345;;;;N;;;1F98;;1F98 +1F91;GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F21 0345;;;;N;;;1F99;;1F99 +1F92;GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F22 0345;;;;N;;;1F9A;;1F9A +1F93;GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F23 0345;;;;N;;;1F9B;;1F9B +1F94;GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F24 0345;;;;N;;;1F9C;;1F9C +1F95;GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F25 0345;;;;N;;;1F9D;;1F9D +1F96;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F26 0345;;;;N;;;1F9E;;1F9E +1F97;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F27 0345;;;;N;;;1F9F;;1F9F +1F98;GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F28 0345;;;;N;;;;1F90; +1F99;GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F29 0345;;;;N;;;;1F91; +1F9A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2A 0345;;;;N;;;;1F92; +1F9B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2B 0345;;;;N;;;;1F93; +1F9C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2C 0345;;;;N;;;;1F94; +1F9D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2D 0345;;;;N;;;;1F95; +1F9E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2E 0345;;;;N;;;;1F96; +1F9F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2F 0345;;;;N;;;;1F97; +1FA0;GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F60 0345;;;;N;;;1FA8;;1FA8 +1FA1;GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F61 0345;;;;N;;;1FA9;;1FA9 +1FA2;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F62 0345;;;;N;;;1FAA;;1FAA +1FA3;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F63 0345;;;;N;;;1FAB;;1FAB +1FA4;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F64 0345;;;;N;;;1FAC;;1FAC +1FA5;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F65 0345;;;;N;;;1FAD;;1FAD +1FA6;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F66 0345;;;;N;;;1FAE;;1FAE +1FA7;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F67 0345;;;;N;;;1FAF;;1FAF +1FA8;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F68 0345;;;;N;;;;1FA0; +1FA9;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F69 0345;;;;N;;;;1FA1; +1FAA;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6A 0345;;;;N;;;;1FA2; +1FAB;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6B 0345;;;;N;;;;1FA3; +1FAC;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6C 0345;;;;N;;;;1FA4; +1FAD;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6D 0345;;;;N;;;;1FA5; +1FAE;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6E 0345;;;;N;;;;1FA6; +1FAF;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6F 0345;;;;N;;;;1FA7; +1FB0;GREEK SMALL LETTER ALPHA WITH VRACHY;Ll;0;L;03B1 0306;;;;N;;;1FB8;;1FB8 +1FB1;GREEK SMALL LETTER ALPHA WITH MACRON;Ll;0;L;03B1 0304;;;;N;;;1FB9;;1FB9 +1FB2;GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F70 0345;;;;N;;;;; +1FB3;GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI;Ll;0;L;03B1 0345;;;;N;;;1FBC;;1FBC +1FB4;GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AC 0345;;;;N;;;;; +1FB6;GREEK SMALL LETTER ALPHA WITH PERISPOMENI;Ll;0;L;03B1 0342;;;;N;;;;; +1FB7;GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FB6 0345;;;;N;;;;; +1FB8;GREEK CAPITAL LETTER ALPHA WITH VRACHY;Lu;0;L;0391 0306;;;;N;;;;1FB0; +1FB9;GREEK CAPITAL LETTER ALPHA WITH MACRON;Lu;0;L;0391 0304;;;;N;;;;1FB1; +1FBA;GREEK CAPITAL LETTER ALPHA WITH VARIA;Lu;0;L;0391 0300;;;;N;;;;1F70; +1FBB;GREEK CAPITAL LETTER ALPHA WITH OXIA;Lu;0;L;0386;;;;N;;;;1F71; +1FBC;GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI;Lt;0;L;0391 0345;;;;N;;;;1FB3; +1FBD;GREEK KORONIS;Sk;0;ON; 0020 0313;;;;N;;;;; +1FBE;GREEK PROSGEGRAMMENI;Ll;0;L;03B9;;;;N;;;0399;;0399 +1FBF;GREEK PSILI;Sk;0;ON; 0020 0313;;;;N;;;;; +1FC0;GREEK PERISPOMENI;Sk;0;ON; 0020 0342;;;;N;;;;; +1FC1;GREEK DIALYTIKA AND PERISPOMENI;Sk;0;ON;00A8 0342;;;;N;;;;; +1FC2;GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F74 0345;;;;N;;;;; +1FC3;GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI;Ll;0;L;03B7 0345;;;;N;;;1FCC;;1FCC +1FC4;GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AE 0345;;;;N;;;;; +1FC6;GREEK SMALL LETTER ETA WITH PERISPOMENI;Ll;0;L;03B7 0342;;;;N;;;;; +1FC7;GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FC6 0345;;;;N;;;;; +1FC8;GREEK CAPITAL LETTER EPSILON WITH VARIA;Lu;0;L;0395 0300;;;;N;;;;1F72; +1FC9;GREEK CAPITAL LETTER EPSILON WITH OXIA;Lu;0;L;0388;;;;N;;;;1F73; +1FCA;GREEK CAPITAL LETTER ETA WITH VARIA;Lu;0;L;0397 0300;;;;N;;;;1F74; +1FCB;GREEK CAPITAL LETTER ETA WITH OXIA;Lu;0;L;0389;;;;N;;;;1F75; +1FCC;GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI;Lt;0;L;0397 0345;;;;N;;;;1FC3; +1FCD;GREEK PSILI AND VARIA;Sk;0;ON;1FBF 0300;;;;N;;;;; +1FCE;GREEK PSILI AND OXIA;Sk;0;ON;1FBF 0301;;;;N;;;;; +1FCF;GREEK PSILI AND PERISPOMENI;Sk;0;ON;1FBF 0342;;;;N;;;;; +1FD0;GREEK SMALL LETTER IOTA WITH VRACHY;Ll;0;L;03B9 0306;;;;N;;;1FD8;;1FD8 +1FD1;GREEK SMALL LETTER IOTA WITH MACRON;Ll;0;L;03B9 0304;;;;N;;;1FD9;;1FD9 +1FD2;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA;Ll;0;L;03CA 0300;;;;N;;;;; +1FD3;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA;Ll;0;L;0390;;;;N;;;;; +1FD6;GREEK SMALL LETTER IOTA WITH PERISPOMENI;Ll;0;L;03B9 0342;;;;N;;;;; +1FD7;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CA 0342;;;;N;;;;; +1FD8;GREEK CAPITAL LETTER IOTA WITH VRACHY;Lu;0;L;0399 0306;;;;N;;;;1FD0; +1FD9;GREEK CAPITAL LETTER IOTA WITH MACRON;Lu;0;L;0399 0304;;;;N;;;;1FD1; +1FDA;GREEK CAPITAL LETTER IOTA WITH VARIA;Lu;0;L;0399 0300;;;;N;;;;1F76; +1FDB;GREEK CAPITAL LETTER IOTA WITH OXIA;Lu;0;L;038A;;;;N;;;;1F77; +1FDD;GREEK DASIA AND VARIA;Sk;0;ON;1FFE 0300;;;;N;;;;; +1FDE;GREEK DASIA AND OXIA;Sk;0;ON;1FFE 0301;;;;N;;;;; +1FDF;GREEK DASIA AND PERISPOMENI;Sk;0;ON;1FFE 0342;;;;N;;;;; +1FE0;GREEK SMALL LETTER UPSILON WITH VRACHY;Ll;0;L;03C5 0306;;;;N;;;1FE8;;1FE8 +1FE1;GREEK SMALL LETTER UPSILON WITH MACRON;Ll;0;L;03C5 0304;;;;N;;;1FE9;;1FE9 +1FE2;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA;Ll;0;L;03CB 0300;;;;N;;;;; +1FE3;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA;Ll;0;L;03B0;;;;N;;;;; +1FE4;GREEK SMALL LETTER RHO WITH PSILI;Ll;0;L;03C1 0313;;;;N;;;;; +1FE5;GREEK SMALL LETTER RHO WITH DASIA;Ll;0;L;03C1 0314;;;;N;;;1FEC;;1FEC +1FE6;GREEK SMALL LETTER UPSILON WITH PERISPOMENI;Ll;0;L;03C5 0342;;;;N;;;;; +1FE7;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CB 0342;;;;N;;;;; +1FE8;GREEK CAPITAL LETTER UPSILON WITH VRACHY;Lu;0;L;03A5 0306;;;;N;;;;1FE0; +1FE9;GREEK CAPITAL LETTER UPSILON WITH MACRON;Lu;0;L;03A5 0304;;;;N;;;;1FE1; +1FEA;GREEK CAPITAL LETTER UPSILON WITH VARIA;Lu;0;L;03A5 0300;;;;N;;;;1F7A; +1FEB;GREEK CAPITAL LETTER UPSILON WITH OXIA;Lu;0;L;038E;;;;N;;;;1F7B; +1FEC;GREEK CAPITAL LETTER RHO WITH DASIA;Lu;0;L;03A1 0314;;;;N;;;;1FE5; +1FED;GREEK DIALYTIKA AND VARIA;Sk;0;ON;00A8 0300;;;;N;;;;; +1FEE;GREEK DIALYTIKA AND OXIA;Sk;0;ON;0385;;;;N;;;;; +1FEF;GREEK VARIA;Sk;0;ON;0060;;;;N;;;;; +1FF2;GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F7C 0345;;;;N;;;;; +1FF3;GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI;Ll;0;L;03C9 0345;;;;N;;;1FFC;;1FFC +1FF4;GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03CE 0345;;;;N;;;;; +1FF6;GREEK SMALL LETTER OMEGA WITH PERISPOMENI;Ll;0;L;03C9 0342;;;;N;;;;; +1FF7;GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FF6 0345;;;;N;;;;; +1FF8;GREEK CAPITAL LETTER OMICRON WITH VARIA;Lu;0;L;039F 0300;;;;N;;;;1F78; +1FF9;GREEK CAPITAL LETTER OMICRON WITH OXIA;Lu;0;L;038C;;;;N;;;;1F79; +1FFA;GREEK CAPITAL LETTER OMEGA WITH VARIA;Lu;0;L;03A9 0300;;;;N;;;;1F7C; +1FFB;GREEK CAPITAL LETTER OMEGA WITH OXIA;Lu;0;L;038F;;;;N;;;;1F7D; +1FFC;GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI;Lt;0;L;03A9 0345;;;;N;;;;1FF3; +1FFD;GREEK OXIA;Sk;0;ON;00B4;;;;N;;;;; +1FFE;GREEK DASIA;Sk;0;ON; 0020 0314;;;;N;;;;; +2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;; +2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;; +2002;EN SPACE;Zs;0;WS; 0020;;;;N;;;;; +2003;EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2004;THREE-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2005;FOUR-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2006;SIX-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2007;FIGURE SPACE;Zs;0;WS; 0020;;;;N;;;;; +2008;PUNCTUATION SPACE;Zs;0;WS; 0020;;;;N;;;;; +2009;THIN SPACE;Zs;0;WS; 0020;;;;N;;;;; +200A;HAIR SPACE;Zs;0;WS; 0020;;;;N;;;;; +200B;ZERO WIDTH SPACE;Cf;0;BN;;;;;N;;;;; +200C;ZERO WIDTH NON-JOINER;Cf;0;BN;;;;;N;;;;; +200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;; +200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;; +200F;RIGHT-TO-LEFT MARK;Cf;0;R;;;;;N;;;;; +2010;HYPHEN;Pd;0;ON;;;;;N;;;;; +2011;NON-BREAKING HYPHEN;Pd;0;ON; 2010;;;;N;;;;; +2012;FIGURE DASH;Pd;0;ON;;;;;N;;;;; +2013;EN DASH;Pd;0;ON;;;;;N;;;;; +2014;EM DASH;Pd;0;ON;;;;;N;;;;; +2015;HORIZONTAL BAR;Pd;0;ON;;;;;N;QUOTATION DASH;;;; +2016;DOUBLE VERTICAL LINE;Po;0;ON;;;;;N;DOUBLE VERTICAL BAR;;;; +2017;DOUBLE LOW LINE;Po;0;ON; 0020 0333;;;;N;SPACING DOUBLE UNDERSCORE;;;; +2018;LEFT SINGLE QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE TURNED COMMA QUOTATION MARK;;;; +2019;RIGHT SINGLE QUOTATION MARK;Pf;0;ON;;;;;N;SINGLE COMMA QUOTATION MARK;;;; +201A;SINGLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW SINGLE COMMA QUOTATION MARK;;;; +201B;SINGLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE REVERSED COMMA QUOTATION MARK;;;; +201C;LEFT DOUBLE QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE TURNED COMMA QUOTATION MARK;;;; +201D;RIGHT DOUBLE QUOTATION MARK;Pf;0;ON;;;;;N;DOUBLE COMMA QUOTATION MARK;;;; +201E;DOUBLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW DOUBLE COMMA QUOTATION MARK;;;; +201F;DOUBLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE REVERSED COMMA QUOTATION MARK;;;; +2020;DAGGER;Po;0;ON;;;;;N;;;;; +2021;DOUBLE DAGGER;Po;0;ON;;;;;N;;;;; +2022;BULLET;Po;0;ON;;;;;N;;;;; +2023;TRIANGULAR BULLET;Po;0;ON;;;;;N;;;;; +2024;ONE DOT LEADER;Po;0;ON; 002E;;;;N;;;;; +2025;TWO DOT LEADER;Po;0;ON; 002E 002E;;;;N;;;;; +2026;HORIZONTAL ELLIPSIS;Po;0;ON; 002E 002E 002E;;;;N;;;;; +2027;HYPHENATION POINT;Po;0;ON;;;;;N;;;;; +2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; +2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; +202A;LEFT-TO-RIGHT EMBEDDING;Cf;0;LRE;;;;;N;;;;; +202B;RIGHT-TO-LEFT EMBEDDING;Cf;0;RLE;;;;;N;;;;; +202C;POP DIRECTIONAL FORMATTING;Cf;0;PDF;;;;;N;;;;; +202D;LEFT-TO-RIGHT OVERRIDE;Cf;0;LRO;;;;;N;;;;; +202E;RIGHT-TO-LEFT OVERRIDE;Cf;0;RLO;;;;;N;;;;; +202F;NARROW NO-BREAK SPACE;Zs;0;CS; 0020;;;;N;;;;; +2030;PER MILLE SIGN;Po;0;ET;;;;;N;;;;; +2031;PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;; +2032;PRIME;Po;0;ET;;;;;N;;;;; +2033;DOUBLE PRIME;Po;0;ET; 2032 2032;;;;N;;;;; +2034;TRIPLE PRIME;Po;0;ET; 2032 2032 2032;;;;N;;;;; +2035;REVERSED PRIME;Po;0;ON;;;;;N;;;;; +2036;REVERSED DOUBLE PRIME;Po;0;ON; 2035 2035;;;;N;;;;; +2037;REVERSED TRIPLE PRIME;Po;0;ON; 2035 2035 2035;;;;N;;;;; +2038;CARET;Po;0;ON;;;;;N;;;;; +2039;SINGLE LEFT-POINTING ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING SINGLE GUILLEMET;;;; +203A;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING SINGLE GUILLEMET;;;; +203B;REFERENCE MARK;Po;0;ON;;;;;N;;;;; +203C;DOUBLE EXCLAMATION MARK;Po;0;ON; 0021 0021;;;;N;;;;; +203D;INTERROBANG;Po;0;ON;;;;;N;;;;; +203E;OVERLINE;Po;0;ON; 0020 0305;;;;N;SPACING OVERSCORE;;;; +203F;UNDERTIE;Pc;0;ON;;;;;N;;;;; +2040;CHARACTER TIE;Pc;0;ON;;;;;N;;;;; +2041;CARET INSERTION POINT;Po;0;ON;;;;;N;;;;; +2042;ASTERISM;Po;0;ON;;;;;N;;;;; +2043;HYPHEN BULLET;Po;0;ON;;;;;N;;;;; +2044;FRACTION SLASH;Sm;0;CS;;;;;N;;;;; +2045;LEFT SQUARE BRACKET WITH QUILL;Ps;0;ON;;;;;Y;;;;; +2046;RIGHT SQUARE BRACKET WITH QUILL;Pe;0;ON;;;;;Y;;;;; +2047;DOUBLE QUESTION MARK;Po;0;ON; 003F 003F;;;;N;;;;; +2048;QUESTION EXCLAMATION MARK;Po;0;ON; 003F 0021;;;;N;;;;; +2049;EXCLAMATION QUESTION MARK;Po;0;ON; 0021 003F;;;;N;;;;; +204A;TIRONIAN SIGN ET;Po;0;ON;;;;;N;;;;; +204B;REVERSED PILCROW SIGN;Po;0;ON;;;;;N;;;;; +204C;BLACK LEFTWARDS BULLET;Po;0;ON;;;;;N;;;;; +204D;BLACK RIGHTWARDS BULLET;Po;0;ON;;;;;N;;;;; +204E;LOW ASTERISK;Po;0;ON;;;;;N;;;;; +204F;REVERSED SEMICOLON;Po;0;ON;;;;;N;;;;; +2050;CLOSE UP;Po;0;ON;;;;;N;;;;; +2051;TWO ASTERISKS ALIGNED VERTICALLY;Po;0;ON;;;;;N;;;;; +2052;COMMERCIAL MINUS SIGN;Sm;0;ON;;;;;N;;;;; +2053;SWUNG DASH;Po;0;ON;;;;;N;;;;; +2054;INVERTED UNDERTIE;Pc;0;ON;;;;;N;;;;; +2055;FLOWER PUNCTUATION MARK;Po;0;ON;;;;;N;;;;; +2056;THREE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +2057;QUADRUPLE PRIME;Po;0;ON; 2032 2032 2032 2032;;;;N;;;;; +2058;FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +2059;FIVE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +205A;TWO DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +205B;FOUR DOT MARK;Po;0;ON;;;;;N;;;;; +205C;DOTTED CROSS;Po;0;ON;;;;;N;;;;; +205D;TRICOLON;Po;0;ON;;;;;N;;;;; +205E;VERTICAL FOUR DOTS;Po;0;ON;;;;;N;;;;; +205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS; 0020;;;;N;;;;; +2060;WORD JOINER;Cf;0;BN;;;;;N;;;;; +2061;FUNCTION APPLICATION;Cf;0;BN;;;;;N;;;;; +2062;INVISIBLE TIMES;Cf;0;BN;;;;;N;;;;; +2063;INVISIBLE SEPARATOR;Cf;0;BN;;;;;N;;;;; +2064;INVISIBLE PLUS;Cf;0;BN;;;;;N;;;;; +206A;INHIBIT SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;; +206B;ACTIVATE SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;; +206C;INHIBIT ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;; +206D;ACTIVATE ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;; +206E;NATIONAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;; +206F;NOMINAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;; +2070;SUPERSCRIPT ZERO;No;0;EN; 0030;;0;0;N;SUPERSCRIPT DIGIT ZERO;;;; +2071;SUPERSCRIPT LATIN SMALL LETTER I;Lm;0;L; 0069;;;;N;;;;; +2074;SUPERSCRIPT FOUR;No;0;EN; 0034;;4;4;N;SUPERSCRIPT DIGIT FOUR;;;; +2075;SUPERSCRIPT FIVE;No;0;EN; 0035;;5;5;N;SUPERSCRIPT DIGIT FIVE;;;; +2076;SUPERSCRIPT SIX;No;0;EN; 0036;;6;6;N;SUPERSCRIPT DIGIT SIX;;;; +2077;SUPERSCRIPT SEVEN;No;0;EN; 0037;;7;7;N;SUPERSCRIPT DIGIT SEVEN;;;; +2078;SUPERSCRIPT EIGHT;No;0;EN; 0038;;8;8;N;SUPERSCRIPT DIGIT EIGHT;;;; +2079;SUPERSCRIPT NINE;No;0;EN; 0039;;9;9;N;SUPERSCRIPT DIGIT NINE;;;; +207A;SUPERSCRIPT PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +207B;SUPERSCRIPT MINUS;Sm;0;ES; 2212;;;;N;SUPERSCRIPT HYPHEN-MINUS;;;; +207C;SUPERSCRIPT EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +207D;SUPERSCRIPT LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SUPERSCRIPT OPENING PARENTHESIS;;;; +207E;SUPERSCRIPT RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SUPERSCRIPT CLOSING PARENTHESIS;;;; +207F;SUPERSCRIPT LATIN SMALL LETTER N;Lm;0;L; 006E;;;;N;;;;; +2080;SUBSCRIPT ZERO;No;0;EN; 0030;;0;0;N;SUBSCRIPT DIGIT ZERO;;;; +2081;SUBSCRIPT ONE;No;0;EN; 0031;;1;1;N;SUBSCRIPT DIGIT ONE;;;; +2082;SUBSCRIPT TWO;No;0;EN; 0032;;2;2;N;SUBSCRIPT DIGIT TWO;;;; +2083;SUBSCRIPT THREE;No;0;EN; 0033;;3;3;N;SUBSCRIPT DIGIT THREE;;;; +2084;SUBSCRIPT FOUR;No;0;EN; 0034;;4;4;N;SUBSCRIPT DIGIT FOUR;;;; +2085;SUBSCRIPT FIVE;No;0;EN; 0035;;5;5;N;SUBSCRIPT DIGIT FIVE;;;; +2086;SUBSCRIPT SIX;No;0;EN; 0036;;6;6;N;SUBSCRIPT DIGIT SIX;;;; +2087;SUBSCRIPT SEVEN;No;0;EN; 0037;;7;7;N;SUBSCRIPT DIGIT SEVEN;;;; +2088;SUBSCRIPT EIGHT;No;0;EN; 0038;;8;8;N;SUBSCRIPT DIGIT EIGHT;;;; +2089;SUBSCRIPT NINE;No;0;EN; 0039;;9;9;N;SUBSCRIPT DIGIT NINE;;;; +208A;SUBSCRIPT PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +208B;SUBSCRIPT MINUS;Sm;0;ES; 2212;;;;N;SUBSCRIPT HYPHEN-MINUS;;;; +208C;SUBSCRIPT EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +208D;SUBSCRIPT LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SUBSCRIPT OPENING PARENTHESIS;;;; +208E;SUBSCRIPT RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SUBSCRIPT CLOSING PARENTHESIS;;;; +2090;LATIN SUBSCRIPT SMALL LETTER A;Lm;0;L; 0061;;;;N;;;;; +2091;LATIN SUBSCRIPT SMALL LETTER E;Lm;0;L; 0065;;;;N;;;;; +2092;LATIN SUBSCRIPT SMALL LETTER O;Lm;0;L; 006F;;;;N;;;;; +2093;LATIN SUBSCRIPT SMALL LETTER X;Lm;0;L; 0078;;;;N;;;;; +2094;LATIN SUBSCRIPT SMALL LETTER SCHWA;Lm;0;L; 0259;;;;N;;;;; +20A0;EURO-CURRENCY SIGN;Sc;0;ET;;;;;N;;;;; +20A1;COLON SIGN;Sc;0;ET;;;;;N;;;;; +20A2;CRUZEIRO SIGN;Sc;0;ET;;;;;N;;;;; +20A3;FRENCH FRANC SIGN;Sc;0;ET;;;;;N;;;;; +20A4;LIRA SIGN;Sc;0;ET;;;;;N;;;;; +20A5;MILL SIGN;Sc;0;ET;;;;;N;;;;; +20A6;NAIRA SIGN;Sc;0;ET;;;;;N;;;;; +20A7;PESETA SIGN;Sc;0;ET;;;;;N;;;;; +20A8;RUPEE SIGN;Sc;0;ET; 0052 0073;;;;N;;;;; +20A9;WON SIGN;Sc;0;ET;;;;;N;;;;; +20AA;NEW SHEQEL SIGN;Sc;0;ET;;;;;N;;;;; +20AB;DONG SIGN;Sc;0;ET;;;;;N;;;;; +20AC;EURO SIGN;Sc;0;ET;;;;;N;;;;; +20AD;KIP SIGN;Sc;0;ET;;;;;N;;;;; +20AE;TUGRIK SIGN;Sc;0;ET;;;;;N;;;;; +20AF;DRACHMA SIGN;Sc;0;ET;;;;;N;;;;; +20B0;GERMAN PENNY SIGN;Sc;0;ET;;;;;N;;;;; +20B1;PESO SIGN;Sc;0;ET;;;;;N;;;;; +20B2;GUARANI SIGN;Sc;0;ET;;;;;N;;;;; +20B3;AUSTRAL SIGN;Sc;0;ET;;;;;N;;;;; +20B4;HRYVNIA SIGN;Sc;0;ET;;;;;N;;;;; +20B5;CEDI SIGN;Sc;0;ET;;;;;N;;;;; +20B6;LIVRE TOURNOIS SIGN;Sc;0;ET;;;;;N;;;;; +20B7;SPESMILO SIGN;Sc;0;ET;;;;;N;;;;; +20B8;TENGE SIGN;Sc;0;ET;;;;;N;;;;; +20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;; +20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;; +20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;; +20D3;COMBINING SHORT VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT VERTICAL BAR OVERLAY;;;; +20D4;COMBINING ANTICLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING ANTICLOCKWISE ARROW ABOVE;;;; +20D5;COMBINING CLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING CLOCKWISE ARROW ABOVE;;;; +20D6;COMBINING LEFT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT ARROW ABOVE;;;; +20D7;COMBINING RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT ARROW ABOVE;;;; +20D8;COMBINING RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING RING OVERLAY;;;; +20D9;COMBINING CLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING CLOCKWISE RING OVERLAY;;;; +20DA;COMBINING ANTICLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING ANTICLOCKWISE RING OVERLAY;;;; +20DB;COMBINING THREE DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING THREE DOTS ABOVE;;;; +20DC;COMBINING FOUR DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING FOUR DOTS ABOVE;;;; +20DD;COMBINING ENCLOSING CIRCLE;Me;0;NSM;;;;;N;ENCLOSING CIRCLE;;;; +20DE;COMBINING ENCLOSING SQUARE;Me;0;NSM;;;;;N;ENCLOSING SQUARE;;;; +20DF;COMBINING ENCLOSING DIAMOND;Me;0;NSM;;;;;N;ENCLOSING DIAMOND;;;; +20E0;COMBINING ENCLOSING CIRCLE BACKSLASH;Me;0;NSM;;;;;N;ENCLOSING CIRCLE SLASH;;;; +20E1;COMBINING LEFT RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT RIGHT ARROW ABOVE;;;; +20E2;COMBINING ENCLOSING SCREEN;Me;0;NSM;;;;;N;;;;; +20E3;COMBINING ENCLOSING KEYCAP;Me;0;NSM;;;;;N;;;;; +20E4;COMBINING ENCLOSING UPWARD POINTING TRIANGLE;Me;0;NSM;;;;;N;;;;; +20E5;COMBINING REVERSE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;; +20E6;COMBINING DOUBLE VERTICAL STROKE OVERLAY;Mn;1;NSM;;;;;N;;;;; +20E7;COMBINING ANNUITY SYMBOL;Mn;230;NSM;;;;;N;;;;; +20E8;COMBINING TRIPLE UNDERDOT;Mn;220;NSM;;;;;N;;;;; +20E9;COMBINING WIDE BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;; +20EA;COMBINING LEFTWARDS ARROW OVERLAY;Mn;1;NSM;;;;;N;;;;; +20EB;COMBINING LONG DOUBLE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;; +20EC;COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;; +20ED;COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;; +20EE;COMBINING LEFT ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +20EF;COMBINING RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +20F0;COMBINING ASTERISK ABOVE;Mn;230;NSM;;;;;N;;;;; +2100;ACCOUNT OF;So;0;ON; 0061 002F 0063;;;;N;;;;; +2101;ADDRESSED TO THE SUBJECT;So;0;ON; 0061 002F 0073;;;;N;;;;; +2102;DOUBLE-STRUCK CAPITAL C;Lu;0;L; 0043;;;;N;DOUBLE-STRUCK C;;;; +2103;DEGREE CELSIUS;So;0;ON; 00B0 0043;;;;N;DEGREES CENTIGRADE;;;; +2104;CENTRE LINE SYMBOL;So;0;ON;;;;;N;C L SYMBOL;;;; +2105;CARE OF;So;0;ON; 0063 002F 006F;;;;N;;;;; +2106;CADA UNA;So;0;ON; 0063 002F 0075;;;;N;;;;; +2107;EULER CONSTANT;Lu;0;L; 0190;;;;N;EULERS;;;; +2108;SCRUPLE;So;0;ON;;;;;N;;;;; +2109;DEGREE FAHRENHEIT;So;0;ON; 00B0 0046;;;;N;DEGREES FAHRENHEIT;;;; +210A;SCRIPT SMALL G;Ll;0;L; 0067;;;;N;;;;; +210B;SCRIPT CAPITAL H;Lu;0;L; 0048;;;;N;SCRIPT H;;;; +210C;BLACK-LETTER CAPITAL H;Lu;0;L; 0048;;;;N;BLACK-LETTER H;;;; +210D;DOUBLE-STRUCK CAPITAL H;Lu;0;L; 0048;;;;N;DOUBLE-STRUCK H;;;; +210E;PLANCK CONSTANT;Ll;0;L; 0068;;;;N;;;;; +210F;PLANCK CONSTANT OVER TWO PI;Ll;0;L; 0127;;;;N;PLANCK CONSTANT OVER 2 PI;;;; +2110;SCRIPT CAPITAL I;Lu;0;L; 0049;;;;N;SCRIPT I;;;; +2111;BLACK-LETTER CAPITAL I;Lu;0;L; 0049;;;;N;BLACK-LETTER I;;;; +2112;SCRIPT CAPITAL L;Lu;0;L; 004C;;;;N;SCRIPT L;;;; +2113;SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; +2114;L B BAR SYMBOL;So;0;ON;;;;;N;;;;; +2115;DOUBLE-STRUCK CAPITAL N;Lu;0;L; 004E;;;;N;DOUBLE-STRUCK N;;;; +2116;NUMERO SIGN;So;0;ON; 004E 006F;;;;N;NUMERO;;;; +2117;SOUND RECORDING COPYRIGHT;So;0;ON;;;;;N;;;;; +2118;SCRIPT CAPITAL P;So;0;ON;;;;;N;SCRIPT P;;;; +2119;DOUBLE-STRUCK CAPITAL P;Lu;0;L; 0050;;;;N;DOUBLE-STRUCK P;;;; +211A;DOUBLE-STRUCK CAPITAL Q;Lu;0;L; 0051;;;;N;DOUBLE-STRUCK Q;;;; +211B;SCRIPT CAPITAL R;Lu;0;L; 0052;;;;N;SCRIPT R;;;; +211C;BLACK-LETTER CAPITAL R;Lu;0;L; 0052;;;;N;BLACK-LETTER R;;;; +211D;DOUBLE-STRUCK CAPITAL R;Lu;0;L; 0052;;;;N;DOUBLE-STRUCK R;;;; +211E;PRESCRIPTION TAKE;So;0;ON;;;;;N;;;;; +211F;RESPONSE;So;0;ON;;;;;N;;;;; +2120;SERVICE MARK;So;0;ON; 0053 004D;;;;N;;;;; +2121;TELEPHONE SIGN;So;0;ON; 0054 0045 004C;;;;N;T E L SYMBOL;;;; +2122;TRADE MARK SIGN;So;0;ON; 0054 004D;;;;N;TRADEMARK;;;; +2123;VERSICLE;So;0;ON;;;;;N;;;;; +2124;DOUBLE-STRUCK CAPITAL Z;Lu;0;L; 005A;;;;N;DOUBLE-STRUCK Z;;;; +2125;OUNCE SIGN;So;0;ON;;;;;N;OUNCE;;;; +2126;OHM SIGN;Lu;0;L;03A9;;;;N;OHM;;;03C9; +2127;INVERTED OHM SIGN;So;0;ON;;;;;N;MHO;;;; +2128;BLACK-LETTER CAPITAL Z;Lu;0;L; 005A;;;;N;BLACK-LETTER Z;;;; +2129;TURNED GREEK SMALL LETTER IOTA;So;0;ON;;;;;N;;;;; +212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B; +212B;ANGSTROM SIGN;Lu;0;L;00C5;;;;N;ANGSTROM UNIT;;;00E5; +212C;SCRIPT CAPITAL B;Lu;0;L; 0042;;;;N;SCRIPT B;;;; +212D;BLACK-LETTER CAPITAL C;Lu;0;L; 0043;;;;N;BLACK-LETTER C;;;; +212E;ESTIMATED SYMBOL;So;0;ET;;;;;N;;;;; +212F;SCRIPT SMALL E;Ll;0;L; 0065;;;;N;;;;; +2130;SCRIPT CAPITAL E;Lu;0;L; 0045;;;;N;SCRIPT E;;;; +2131;SCRIPT CAPITAL F;Lu;0;L; 0046;;;;N;SCRIPT F;;;; +2132;TURNED CAPITAL F;Lu;0;L;;;;;N;TURNED F;;;214E; +2133;SCRIPT CAPITAL M;Lu;0;L; 004D;;;;N;SCRIPT M;;;; +2134;SCRIPT SMALL O;Ll;0;L; 006F;;;;N;;;;; +2135;ALEF SYMBOL;Lo;0;L; 05D0;;;;N;FIRST TRANSFINITE CARDINAL;;;; +2136;BET SYMBOL;Lo;0;L; 05D1;;;;N;SECOND TRANSFINITE CARDINAL;;;; +2137;GIMEL SYMBOL;Lo;0;L; 05D2;;;;N;THIRD TRANSFINITE CARDINAL;;;; +2138;DALET SYMBOL;Lo;0;L; 05D3;;;;N;FOURTH TRANSFINITE CARDINAL;;;; +2139;INFORMATION SOURCE;Ll;0;L; 0069;;;;N;;;;; +213A;ROTATED CAPITAL Q;So;0;ON;;;;;N;;;;; +213B;FACSIMILE SIGN;So;0;ON; 0046 0041 0058;;;;N;;;;; +213C;DOUBLE-STRUCK SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +213D;DOUBLE-STRUCK SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +213E;DOUBLE-STRUCK CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +213F;DOUBLE-STRUCK CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +2140;DOUBLE-STRUCK N-ARY SUMMATION;Sm;0;ON; 2211;;;;Y;;;;; +2141;TURNED SANS-SERIF CAPITAL G;Sm;0;ON;;;;;N;;;;; +2142;TURNED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;; +2143;REVERSED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;; +2144;TURNED SANS-SERIF CAPITAL Y;Sm;0;ON;;;;;N;;;;; +2145;DOUBLE-STRUCK ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +2146;DOUBLE-STRUCK ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +2147;DOUBLE-STRUCK ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +2148;DOUBLE-STRUCK ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +2149;DOUBLE-STRUCK ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +214A;PROPERTY LINE;So;0;ON;;;;;N;;;;; +214B;TURNED AMPERSAND;Sm;0;ON;;;;;N;;;;; +214C;PER SIGN;So;0;ON;;;;;N;;;;; +214D;AKTIESELSKAB;So;0;ON;;;;;N;;;;; +214E;TURNED SMALL F;Ll;0;L;;;;;N;;;2132;;2132 +214F;SYMBOL FOR SAMARITAN SOURCE;So;0;L;;;;;N;;;;; +2150;VULGAR FRACTION ONE SEVENTH;No;0;ON; 0031 2044 0037;;;1/7;N;;;;; +2151;VULGAR FRACTION ONE NINTH;No;0;ON; 0031 2044 0039;;;1/9;N;;;;; +2152;VULGAR FRACTION ONE TENTH;No;0;ON; 0031 2044 0031 0030;;;1/10;N;;;;; +2153;VULGAR FRACTION ONE THIRD;No;0;ON; 0031 2044 0033;;;1/3;N;FRACTION ONE THIRD;;;; +2154;VULGAR FRACTION TWO THIRDS;No;0;ON; 0032 2044 0033;;;2/3;N;FRACTION TWO THIRDS;;;; +2155;VULGAR FRACTION ONE FIFTH;No;0;ON; 0031 2044 0035;;;1/5;N;FRACTION ONE FIFTH;;;; +2156;VULGAR FRACTION TWO FIFTHS;No;0;ON; 0032 2044 0035;;;2/5;N;FRACTION TWO FIFTHS;;;; +2157;VULGAR FRACTION THREE FIFTHS;No;0;ON; 0033 2044 0035;;;3/5;N;FRACTION THREE FIFTHS;;;; +2158;VULGAR FRACTION FOUR FIFTHS;No;0;ON; 0034 2044 0035;;;4/5;N;FRACTION FOUR FIFTHS;;;; +2159;VULGAR FRACTION ONE SIXTH;No;0;ON; 0031 2044 0036;;;1/6;N;FRACTION ONE SIXTH;;;; +215A;VULGAR FRACTION FIVE SIXTHS;No;0;ON; 0035 2044 0036;;;5/6;N;FRACTION FIVE SIXTHS;;;; +215B;VULGAR FRACTION ONE EIGHTH;No;0;ON; 0031 2044 0038;;;1/8;N;FRACTION ONE EIGHTH;;;; +215C;VULGAR FRACTION THREE EIGHTHS;No;0;ON; 0033 2044 0038;;;3/8;N;FRACTION THREE EIGHTHS;;;; +215D;VULGAR FRACTION FIVE EIGHTHS;No;0;ON; 0035 2044 0038;;;5/8;N;FRACTION FIVE EIGHTHS;;;; +215E;VULGAR FRACTION SEVEN EIGHTHS;No;0;ON; 0037 2044 0038;;;7/8;N;FRACTION SEVEN EIGHTHS;;;; +215F;FRACTION NUMERATOR ONE;No;0;ON; 0031 2044;;;1;N;;;;; +2160;ROMAN NUMERAL ONE;Nl;0;L; 0049;;;1;N;;;;2170; +2161;ROMAN NUMERAL TWO;Nl;0;L; 0049 0049;;;2;N;;;;2171; +2162;ROMAN NUMERAL THREE;Nl;0;L; 0049 0049 0049;;;3;N;;;;2172; +2163;ROMAN NUMERAL FOUR;Nl;0;L; 0049 0056;;;4;N;;;;2173; +2164;ROMAN NUMERAL FIVE;Nl;0;L; 0056;;;5;N;;;;2174; +2165;ROMAN NUMERAL SIX;Nl;0;L; 0056 0049;;;6;N;;;;2175; +2166;ROMAN NUMERAL SEVEN;Nl;0;L; 0056 0049 0049;;;7;N;;;;2176; +2167;ROMAN NUMERAL EIGHT;Nl;0;L; 0056 0049 0049 0049;;;8;N;;;;2177; +2168;ROMAN NUMERAL NINE;Nl;0;L; 0049 0058;;;9;N;;;;2178; +2169;ROMAN NUMERAL TEN;Nl;0;L; 0058;;;10;N;;;;2179; +216A;ROMAN NUMERAL ELEVEN;Nl;0;L; 0058 0049;;;11;N;;;;217A; +216B;ROMAN NUMERAL TWELVE;Nl;0;L; 0058 0049 0049;;;12;N;;;;217B; +216C;ROMAN NUMERAL FIFTY;Nl;0;L; 004C;;;50;N;;;;217C; +216D;ROMAN NUMERAL ONE HUNDRED;Nl;0;L; 0043;;;100;N;;;;217D; +216E;ROMAN NUMERAL FIVE HUNDRED;Nl;0;L; 0044;;;500;N;;;;217E; +216F;ROMAN NUMERAL ONE THOUSAND;Nl;0;L; 004D;;;1000;N;;;;217F; +2170;SMALL ROMAN NUMERAL ONE;Nl;0;L; 0069;;;1;N;;;2160;;2160 +2171;SMALL ROMAN NUMERAL TWO;Nl;0;L; 0069 0069;;;2;N;;;2161;;2161 +2172;SMALL ROMAN NUMERAL THREE;Nl;0;L; 0069 0069 0069;;;3;N;;;2162;;2162 +2173;SMALL ROMAN NUMERAL FOUR;Nl;0;L; 0069 0076;;;4;N;;;2163;;2163 +2174;SMALL ROMAN NUMERAL FIVE;Nl;0;L; 0076;;;5;N;;;2164;;2164 +2175;SMALL ROMAN NUMERAL SIX;Nl;0;L; 0076 0069;;;6;N;;;2165;;2165 +2176;SMALL ROMAN NUMERAL SEVEN;Nl;0;L; 0076 0069 0069;;;7;N;;;2166;;2166 +2177;SMALL ROMAN NUMERAL EIGHT;Nl;0;L; 0076 0069 0069 0069;;;8;N;;;2167;;2167 +2178;SMALL ROMAN NUMERAL NINE;Nl;0;L; 0069 0078;;;9;N;;;2168;;2168 +2179;SMALL ROMAN NUMERAL TEN;Nl;0;L; 0078;;;10;N;;;2169;;2169 +217A;SMALL ROMAN NUMERAL ELEVEN;Nl;0;L; 0078 0069;;;11;N;;;216A;;216A +217B;SMALL ROMAN NUMERAL TWELVE;Nl;0;L; 0078 0069 0069;;;12;N;;;216B;;216B +217C;SMALL ROMAN NUMERAL FIFTY;Nl;0;L; 006C;;;50;N;;;216C;;216C +217D;SMALL ROMAN NUMERAL ONE HUNDRED;Nl;0;L; 0063;;;100;N;;;216D;;216D +217E;SMALL ROMAN NUMERAL FIVE HUNDRED;Nl;0;L; 0064;;;500;N;;;216E;;216E +217F;SMALL ROMAN NUMERAL ONE THOUSAND;Nl;0;L; 006D;;;1000;N;;;216F;;216F +2180;ROMAN NUMERAL ONE THOUSAND C D;Nl;0;L;;;;1000;N;;;;; +2181;ROMAN NUMERAL FIVE THOUSAND;Nl;0;L;;;;5000;N;;;;; +2182;ROMAN NUMERAL TEN THOUSAND;Nl;0;L;;;;10000;N;;;;; +2183;ROMAN NUMERAL REVERSED ONE HUNDRED;Lu;0;L;;;;;N;;;;2184; +2184;LATIN SMALL LETTER REVERSED C;Ll;0;L;;;;;N;;;2183;;2183 +2185;ROMAN NUMERAL SIX LATE FORM;Nl;0;L;;;;6;N;;;;; +2186;ROMAN NUMERAL FIFTY EARLY FORM;Nl;0;L;;;;50;N;;;;; +2187;ROMAN NUMERAL FIFTY THOUSAND;Nl;0;L;;;;50000;N;;;;; +2188;ROMAN NUMERAL ONE HUNDRED THOUSAND;Nl;0;L;;;;100000;N;;;;; +2189;VULGAR FRACTION ZERO THIRDS;No;0;ON; 0030 2044 0033;;;0;N;;;;; +2190;LEFTWARDS ARROW;Sm;0;ON;;;;;N;LEFT ARROW;;;; +2191;UPWARDS ARROW;Sm;0;ON;;;;;N;UP ARROW;;;; +2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;; +2193;DOWNWARDS ARROW;Sm;0;ON;;;;;N;DOWN ARROW;;;; +2194;LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;; +2195;UP DOWN ARROW;So;0;ON;;;;;N;;;;; +2196;NORTH WEST ARROW;So;0;ON;;;;;N;UPPER LEFT ARROW;;;; +2197;NORTH EAST ARROW;So;0;ON;;;;;N;UPPER RIGHT ARROW;;;; +2198;SOUTH EAST ARROW;So;0;ON;;;;;N;LOWER RIGHT ARROW;;;; +2199;SOUTH WEST ARROW;So;0;ON;;;;;N;LOWER LEFT ARROW;;;; +219A;LEFTWARDS ARROW WITH STROKE;Sm;0;ON;2190 0338;;;;N;LEFT ARROW WITH STROKE;;;; +219B;RIGHTWARDS ARROW WITH STROKE;Sm;0;ON;2192 0338;;;;N;RIGHT ARROW WITH STROKE;;;; +219C;LEFTWARDS WAVE ARROW;So;0;ON;;;;;N;LEFT WAVE ARROW;;;; +219D;RIGHTWARDS WAVE ARROW;So;0;ON;;;;;N;RIGHT WAVE ARROW;;;; +219E;LEFTWARDS TWO HEADED ARROW;So;0;ON;;;;;N;LEFT TWO HEADED ARROW;;;; +219F;UPWARDS TWO HEADED ARROW;So;0;ON;;;;;N;UP TWO HEADED ARROW;;;; +21A0;RIGHTWARDS TWO HEADED ARROW;Sm;0;ON;;;;;N;RIGHT TWO HEADED ARROW;;;; +21A1;DOWNWARDS TWO HEADED ARROW;So;0;ON;;;;;N;DOWN TWO HEADED ARROW;;;; +21A2;LEFTWARDS ARROW WITH TAIL;So;0;ON;;;;;N;LEFT ARROW WITH TAIL;;;; +21A3;RIGHTWARDS ARROW WITH TAIL;Sm;0;ON;;;;;N;RIGHT ARROW WITH TAIL;;;; +21A4;LEFTWARDS ARROW FROM BAR;So;0;ON;;;;;N;LEFT ARROW FROM BAR;;;; +21A5;UPWARDS ARROW FROM BAR;So;0;ON;;;;;N;UP ARROW FROM BAR;;;; +21A6;RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;RIGHT ARROW FROM BAR;;;; +21A7;DOWNWARDS ARROW FROM BAR;So;0;ON;;;;;N;DOWN ARROW FROM BAR;;;; +21A8;UP DOWN ARROW WITH BASE;So;0;ON;;;;;N;;;;; +21A9;LEFTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;LEFT ARROW WITH HOOK;;;; +21AA;RIGHTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;RIGHT ARROW WITH HOOK;;;; +21AB;LEFTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;LEFT ARROW WITH LOOP;;;; +21AC;RIGHTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;RIGHT ARROW WITH LOOP;;;; +21AD;LEFT RIGHT WAVE ARROW;So;0;ON;;;;;N;;;;; +21AE;LEFT RIGHT ARROW WITH STROKE;Sm;0;ON;2194 0338;;;;N;;;;; +21AF;DOWNWARDS ZIGZAG ARROW;So;0;ON;;;;;N;DOWN ZIGZAG ARROW;;;; +21B0;UPWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP LEFT;;;; +21B1;UPWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP RIGHT;;;; +21B2;DOWNWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP LEFT;;;; +21B3;DOWNWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP RIGHT;;;; +21B4;RIGHTWARDS ARROW WITH CORNER DOWNWARDS;So;0;ON;;;;;N;RIGHT ARROW WITH CORNER DOWN;;;; +21B5;DOWNWARDS ARROW WITH CORNER LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH CORNER LEFT;;;; +21B6;ANTICLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;; +21B7;CLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;; +21B8;NORTH WEST ARROW TO LONG BAR;So;0;ON;;;;;N;UPPER LEFT ARROW TO LONG BAR;;;; +21B9;LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR OVER RIGHT ARROW TO BAR;;;; +21BA;ANTICLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;; +21BB;CLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;; +21BC;LEFTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB UP;;;; +21BD;LEFTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB DOWN;;;; +21BE;UPWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB RIGHT;;;; +21BF;UPWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB LEFT;;;; +21C0;RIGHTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB UP;;;; +21C1;RIGHTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB DOWN;;;; +21C2;DOWNWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB RIGHT;;;; +21C3;DOWNWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB LEFT;;;; +21C4;RIGHTWARDS ARROW OVER LEFTWARDS ARROW;So;0;ON;;;;;N;RIGHT ARROW OVER LEFT ARROW;;;; +21C5;UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW;So;0;ON;;;;;N;UP ARROW LEFT OF DOWN ARROW;;;; +21C6;LEFTWARDS ARROW OVER RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT ARROW OVER RIGHT ARROW;;;; +21C7;LEFTWARDS PAIRED ARROWS;So;0;ON;;;;;N;LEFT PAIRED ARROWS;;;; +21C8;UPWARDS PAIRED ARROWS;So;0;ON;;;;;N;UP PAIRED ARROWS;;;; +21C9;RIGHTWARDS PAIRED ARROWS;So;0;ON;;;;;N;RIGHT PAIRED ARROWS;;;; +21CA;DOWNWARDS PAIRED ARROWS;So;0;ON;;;;;N;DOWN PAIRED ARROWS;;;; +21CB;LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON;So;0;ON;;;;;N;LEFT HARPOON OVER RIGHT HARPOON;;;; +21CC;RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON;So;0;ON;;;;;N;RIGHT HARPOON OVER LEFT HARPOON;;;; +21CD;LEFTWARDS DOUBLE ARROW WITH STROKE;So;0;ON;21D0 0338;;;;N;LEFT DOUBLE ARROW WITH STROKE;;;; +21CE;LEFT RIGHT DOUBLE ARROW WITH STROKE;Sm;0;ON;21D4 0338;;;;N;;;;; +21CF;RIGHTWARDS DOUBLE ARROW WITH STROKE;Sm;0;ON;21D2 0338;;;;N;RIGHT DOUBLE ARROW WITH STROKE;;;; +21D0;LEFTWARDS DOUBLE ARROW;So;0;ON;;;;;N;LEFT DOUBLE ARROW;;;; +21D1;UPWARDS DOUBLE ARROW;So;0;ON;;;;;N;UP DOUBLE ARROW;;;; +21D2;RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;RIGHT DOUBLE ARROW;;;; +21D3;DOWNWARDS DOUBLE ARROW;So;0;ON;;;;;N;DOWN DOUBLE ARROW;;;; +21D4;LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +21D5;UP DOWN DOUBLE ARROW;So;0;ON;;;;;N;;;;; +21D6;NORTH WEST DOUBLE ARROW;So;0;ON;;;;;N;UPPER LEFT DOUBLE ARROW;;;; +21D7;NORTH EAST DOUBLE ARROW;So;0;ON;;;;;N;UPPER RIGHT DOUBLE ARROW;;;; +21D8;SOUTH EAST DOUBLE ARROW;So;0;ON;;;;;N;LOWER RIGHT DOUBLE ARROW;;;; +21D9;SOUTH WEST DOUBLE ARROW;So;0;ON;;;;;N;LOWER LEFT DOUBLE ARROW;;;; +21DA;LEFTWARDS TRIPLE ARROW;So;0;ON;;;;;N;LEFT TRIPLE ARROW;;;; +21DB;RIGHTWARDS TRIPLE ARROW;So;0;ON;;;;;N;RIGHT TRIPLE ARROW;;;; +21DC;LEFTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;LEFT SQUIGGLE ARROW;;;; +21DD;RIGHTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;RIGHT SQUIGGLE ARROW;;;; +21DE;UPWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;UP ARROW WITH DOUBLE STROKE;;;; +21DF;DOWNWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;DOWN ARROW WITH DOUBLE STROKE;;;; +21E0;LEFTWARDS DASHED ARROW;So;0;ON;;;;;N;LEFT DASHED ARROW;;;; +21E1;UPWARDS DASHED ARROW;So;0;ON;;;;;N;UP DASHED ARROW;;;; +21E2;RIGHTWARDS DASHED ARROW;So;0;ON;;;;;N;RIGHT DASHED ARROW;;;; +21E3;DOWNWARDS DASHED ARROW;So;0;ON;;;;;N;DOWN DASHED ARROW;;;; +21E4;LEFTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR;;;; +21E5;RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;RIGHT ARROW TO BAR;;;; +21E6;LEFTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE LEFT ARROW;;;; +21E7;UPWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE UP ARROW;;;; +21E8;RIGHTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE RIGHT ARROW;;;; +21E9;DOWNWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE DOWN ARROW;;;; +21EA;UPWARDS WHITE ARROW FROM BAR;So;0;ON;;;;;N;WHITE UP ARROW FROM BAR;;;; +21EB;UPWARDS WHITE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;; +21EC;UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;; +21ED;UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR;So;0;ON;;;;;N;;;;; +21EE;UPWARDS WHITE DOUBLE ARROW;So;0;ON;;;;;N;;;;; +21EF;UPWARDS WHITE DOUBLE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;; +21F0;RIGHTWARDS WHITE ARROW FROM WALL;So;0;ON;;;;;N;;;;; +21F1;NORTH WEST ARROW TO CORNER;So;0;ON;;;;;N;;;;; +21F2;SOUTH EAST ARROW TO CORNER;So;0;ON;;;;;N;;;;; +21F3;UP DOWN WHITE ARROW;So;0;ON;;;;;N;;;;; +21F4;RIGHT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +21F5;DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW;Sm;0;ON;;;;;N;;;;; +21F6;THREE RIGHTWARDS ARROWS;Sm;0;ON;;;;;N;;;;; +21F7;LEFTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21F8;RIGHTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21F9;LEFT RIGHT ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FA;LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FB;RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FC;LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FD;LEFTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; +21FE;RIGHTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; +21FF;LEFT RIGHT OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; +2200;FOR ALL;Sm;0;ON;;;;;N;;;;; +2201;COMPLEMENT;Sm;0;ON;;;;;Y;;;;; +2202;PARTIAL DIFFERENTIAL;Sm;0;ON;;;;;Y;;;;; +2203;THERE EXISTS;Sm;0;ON;;;;;Y;;;;; +2204;THERE DOES NOT EXIST;Sm;0;ON;2203 0338;;;;Y;;;;; +2205;EMPTY SET;Sm;0;ON;;;;;N;;;;; +2206;INCREMENT;Sm;0;ON;;;;;N;;;;; +2207;NABLA;Sm;0;ON;;;;;N;;;;; +2208;ELEMENT OF;Sm;0;ON;;;;;Y;;;;; +2209;NOT AN ELEMENT OF;Sm;0;ON;2208 0338;;;;Y;;;;; +220A;SMALL ELEMENT OF;Sm;0;ON;;;;;Y;;;;; +220B;CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;; +220C;DOES NOT CONTAIN AS MEMBER;Sm;0;ON;220B 0338;;;;Y;;;;; +220D;SMALL CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;; +220E;END OF PROOF;Sm;0;ON;;;;;N;;;;; +220F;N-ARY PRODUCT;Sm;0;ON;;;;;N;;;;; +2210;N-ARY COPRODUCT;Sm;0;ON;;;;;N;;;;; +2211;N-ARY SUMMATION;Sm;0;ON;;;;;Y;;;;; +2212;MINUS SIGN;Sm;0;ES;;;;;N;;;;; +2213;MINUS-OR-PLUS SIGN;Sm;0;ET;;;;;N;;;;; +2214;DOT PLUS;Sm;0;ON;;;;;N;;;;; +2215;DIVISION SLASH;Sm;0;ON;;;;;Y;;;;; +2216;SET MINUS;Sm;0;ON;;;;;Y;;;;; +2217;ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;; +2218;RING OPERATOR;Sm;0;ON;;;;;N;;;;; +2219;BULLET OPERATOR;Sm;0;ON;;;;;N;;;;; +221A;SQUARE ROOT;Sm;0;ON;;;;;Y;;;;; +221B;CUBE ROOT;Sm;0;ON;;;;;Y;;;;; +221C;FOURTH ROOT;Sm;0;ON;;;;;Y;;;;; +221D;PROPORTIONAL TO;Sm;0;ON;;;;;Y;;;;; +221E;INFINITY;Sm;0;ON;;;;;N;;;;; +221F;RIGHT ANGLE;Sm;0;ON;;;;;Y;;;;; +2220;ANGLE;Sm;0;ON;;;;;Y;;;;; +2221;MEASURED ANGLE;Sm;0;ON;;;;;Y;;;;; +2222;SPHERICAL ANGLE;Sm;0;ON;;;;;Y;;;;; +2223;DIVIDES;Sm;0;ON;;;;;N;;;;; +2224;DOES NOT DIVIDE;Sm;0;ON;2223 0338;;;;Y;;;;; +2225;PARALLEL TO;Sm;0;ON;;;;;N;;;;; +2226;NOT PARALLEL TO;Sm;0;ON;2225 0338;;;;Y;;;;; +2227;LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2228;LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2229;INTERSECTION;Sm;0;ON;;;;;N;;;;; +222A;UNION;Sm;0;ON;;;;;N;;;;; +222B;INTEGRAL;Sm;0;ON;;;;;Y;;;;; +222C;DOUBLE INTEGRAL;Sm;0;ON; 222B 222B;;;;Y;;;;; +222D;TRIPLE INTEGRAL;Sm;0;ON; 222B 222B 222B;;;;Y;;;;; +222E;CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; +222F;SURFACE INTEGRAL;Sm;0;ON; 222E 222E;;;;Y;;;;; +2230;VOLUME INTEGRAL;Sm;0;ON; 222E 222E 222E;;;;Y;;;;; +2231;CLOCKWISE INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2232;CLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2233;ANTICLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2234;THEREFORE;Sm;0;ON;;;;;N;;;;; +2235;BECAUSE;Sm;0;ON;;;;;N;;;;; +2236;RATIO;Sm;0;ON;;;;;N;;;;; +2237;PROPORTION;Sm;0;ON;;;;;N;;;;; +2238;DOT MINUS;Sm;0;ON;;;;;N;;;;; +2239;EXCESS;Sm;0;ON;;;;;Y;;;;; +223A;GEOMETRIC PROPORTION;Sm;0;ON;;;;;N;;;;; +223B;HOMOTHETIC;Sm;0;ON;;;;;Y;;;;; +223C;TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +223D;REVERSED TILDE;Sm;0;ON;;;;;Y;;;;; +223E;INVERTED LAZY S;Sm;0;ON;;;;;Y;;;;; +223F;SINE WAVE;Sm;0;ON;;;;;Y;;;;; +2240;WREATH PRODUCT;Sm;0;ON;;;;;Y;;;;; +2241;NOT TILDE;Sm;0;ON;223C 0338;;;;Y;;;;; +2242;MINUS TILDE;Sm;0;ON;;;;;Y;;;;; +2243;ASYMPTOTICALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2244;NOT ASYMPTOTICALLY EQUAL TO;Sm;0;ON;2243 0338;;;;Y;;;;; +2245;APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2246;APPROXIMATELY BUT NOT ACTUALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2247;NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO;Sm;0;ON;2245 0338;;;;Y;;;;; +2248;ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2249;NOT ALMOST EQUAL TO;Sm;0;ON;2248 0338;;;;Y;;;;; +224A;ALMOST EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +224B;TRIPLE TILDE;Sm;0;ON;;;;;Y;;;;; +224C;ALL EQUAL TO;Sm;0;ON;;;;;Y;;;;; +224D;EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; +224E;GEOMETRICALLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; +224F;DIFFERENCE BETWEEN;Sm;0;ON;;;;;N;;;;; +2250;APPROACHES THE LIMIT;Sm;0;ON;;;;;N;;;;; +2251;GEOMETRICALLY EQUAL TO;Sm;0;ON;;;;;N;;;;; +2252;APPROXIMATELY EQUAL TO OR THE IMAGE OF;Sm;0;ON;;;;;Y;;;;; +2253;IMAGE OF OR APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2254;COLON EQUALS;Sm;0;ON;;;;;Y;COLON EQUAL;;;; +2255;EQUALS COLON;Sm;0;ON;;;;;Y;EQUAL COLON;;;; +2256;RING IN EQUAL TO;Sm;0;ON;;;;;N;;;;; +2257;RING EQUAL TO;Sm;0;ON;;;;;N;;;;; +2258;CORRESPONDS TO;Sm;0;ON;;;;;N;;;;; +2259;ESTIMATES;Sm;0;ON;;;;;N;;;;; +225A;EQUIANGULAR TO;Sm;0;ON;;;;;N;;;;; +225B;STAR EQUALS;Sm;0;ON;;;;;N;;;;; +225C;DELTA EQUAL TO;Sm;0;ON;;;;;N;;;;; +225D;EQUAL TO BY DEFINITION;Sm;0;ON;;;;;N;;;;; +225E;MEASURED BY;Sm;0;ON;;;;;N;;;;; +225F;QUESTIONED EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2260;NOT EQUAL TO;Sm;0;ON;003D 0338;;;;Y;;;;; +2261;IDENTICAL TO;Sm;0;ON;;;;;N;;;;; +2262;NOT IDENTICAL TO;Sm;0;ON;2261 0338;;;;Y;;;;; +2263;STRICTLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; +2264;LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUAL TO;;;; +2265;GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUAL TO;;;; +2266;LESS-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OVER EQUAL TO;;;; +2267;GREATER-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OVER EQUAL TO;;;; +2268;LESS-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUAL TO;;;; +2269;GREATER-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUAL TO;;;; +226A;MUCH LESS-THAN;Sm;0;ON;;;;;Y;MUCH LESS THAN;;;; +226B;MUCH GREATER-THAN;Sm;0;ON;;;;;Y;MUCH GREATER THAN;;;; +226C;BETWEEN;Sm;0;ON;;;;;N;;;;; +226D;NOT EQUIVALENT TO;Sm;0;ON;224D 0338;;;;N;;;;; +226E;NOT LESS-THAN;Sm;0;ON;003C 0338;;;;Y;NOT LESS THAN;;;; +226F;NOT GREATER-THAN;Sm;0;ON;003E 0338;;;;Y;NOT GREATER THAN;;;; +2270;NEITHER LESS-THAN NOR EQUAL TO;Sm;0;ON;2264 0338;;;;Y;NEITHER LESS THAN NOR EQUAL TO;;;; +2271;NEITHER GREATER-THAN NOR EQUAL TO;Sm;0;ON;2265 0338;;;;Y;NEITHER GREATER THAN NOR EQUAL TO;;;; +2272;LESS-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUIVALENT TO;;;; +2273;GREATER-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUIVALENT TO;;;; +2274;NEITHER LESS-THAN NOR EQUIVALENT TO;Sm;0;ON;2272 0338;;;;Y;NEITHER LESS THAN NOR EQUIVALENT TO;;;; +2275;NEITHER GREATER-THAN NOR EQUIVALENT TO;Sm;0;ON;2273 0338;;;;Y;NEITHER GREATER THAN NOR EQUIVALENT TO;;;; +2276;LESS-THAN OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN OR GREATER THAN;;;; +2277;GREATER-THAN OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN OR LESS THAN;;;; +2278;NEITHER LESS-THAN NOR GREATER-THAN;Sm;0;ON;2276 0338;;;;Y;NEITHER LESS THAN NOR GREATER THAN;;;; +2279;NEITHER GREATER-THAN NOR LESS-THAN;Sm;0;ON;2277 0338;;;;Y;NEITHER GREATER THAN NOR LESS THAN;;;; +227A;PRECEDES;Sm;0;ON;;;;;Y;;;;; +227B;SUCCEEDS;Sm;0;ON;;;;;Y;;;;; +227C;PRECEDES OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +227D;SUCCEEDS OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +227E;PRECEDES OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +227F;SUCCEEDS OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +2280;DOES NOT PRECEDE;Sm;0;ON;227A 0338;;;;Y;;;;; +2281;DOES NOT SUCCEED;Sm;0;ON;227B 0338;;;;Y;;;;; +2282;SUBSET OF;Sm;0;ON;;;;;Y;;;;; +2283;SUPERSET OF;Sm;0;ON;;;;;Y;;;;; +2284;NOT A SUBSET OF;Sm;0;ON;2282 0338;;;;Y;;;;; +2285;NOT A SUPERSET OF;Sm;0;ON;2283 0338;;;;Y;;;;; +2286;SUBSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2287;SUPERSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2288;NEITHER A SUBSET OF NOR EQUAL TO;Sm;0;ON;2286 0338;;;;Y;;;;; +2289;NEITHER A SUPERSET OF NOR EQUAL TO;Sm;0;ON;2287 0338;;;;Y;;;;; +228A;SUBSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUBSET OF OR NOT EQUAL TO;;;; +228B;SUPERSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUPERSET OF OR NOT EQUAL TO;;;; +228C;MULTISET;Sm;0;ON;;;;;Y;;;;; +228D;MULTISET MULTIPLICATION;Sm;0;ON;;;;;N;;;;; +228E;MULTISET UNION;Sm;0;ON;;;;;N;;;;; +228F;SQUARE IMAGE OF;Sm;0;ON;;;;;Y;;;;; +2290;SQUARE ORIGINAL OF;Sm;0;ON;;;;;Y;;;;; +2291;SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2292;SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2293;SQUARE CAP;Sm;0;ON;;;;;N;;;;; +2294;SQUARE CUP;Sm;0;ON;;;;;N;;;;; +2295;CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; +2296;CIRCLED MINUS;Sm;0;ON;;;;;N;;;;; +2297;CIRCLED TIMES;Sm;0;ON;;;;;N;;;;; +2298;CIRCLED DIVISION SLASH;Sm;0;ON;;;;;Y;;;;; +2299;CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +229A;CIRCLED RING OPERATOR;Sm;0;ON;;;;;N;;;;; +229B;CIRCLED ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;; +229C;CIRCLED EQUALS;Sm;0;ON;;;;;N;;;;; +229D;CIRCLED DASH;Sm;0;ON;;;;;N;;;;; +229E;SQUARED PLUS;Sm;0;ON;;;;;N;;;;; +229F;SQUARED MINUS;Sm;0;ON;;;;;N;;;;; +22A0;SQUARED TIMES;Sm;0;ON;;;;;N;;;;; +22A1;SQUARED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +22A2;RIGHT TACK;Sm;0;ON;;;;;Y;;;;; +22A3;LEFT TACK;Sm;0;ON;;;;;Y;;;;; +22A4;DOWN TACK;Sm;0;ON;;;;;N;;;;; +22A5;UP TACK;Sm;0;ON;;;;;N;;;;; +22A6;ASSERTION;Sm;0;ON;;;;;Y;;;;; +22A7;MODELS;Sm;0;ON;;;;;Y;;;;; +22A8;TRUE;Sm;0;ON;;;;;Y;;;;; +22A9;FORCES;Sm;0;ON;;;;;Y;;;;; +22AA;TRIPLE VERTICAL BAR RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +22AB;DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +22AC;DOES NOT PROVE;Sm;0;ON;22A2 0338;;;;Y;;;;; +22AD;NOT TRUE;Sm;0;ON;22A8 0338;;;;Y;;;;; +22AE;DOES NOT FORCE;Sm;0;ON;22A9 0338;;;;Y;;;;; +22AF;NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;22AB 0338;;;;Y;;;;; +22B0;PRECEDES UNDER RELATION;Sm;0;ON;;;;;Y;;;;; +22B1;SUCCEEDS UNDER RELATION;Sm;0;ON;;;;;Y;;;;; +22B2;NORMAL SUBGROUP OF;Sm;0;ON;;;;;Y;;;;; +22B3;CONTAINS AS NORMAL SUBGROUP;Sm;0;ON;;;;;Y;;;;; +22B4;NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22B5;CONTAINS AS NORMAL SUBGROUP OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22B6;ORIGINAL OF;Sm;0;ON;;;;;Y;;;;; +22B7;IMAGE OF;Sm;0;ON;;;;;Y;;;;; +22B8;MULTIMAP;Sm;0;ON;;;;;Y;;;;; +22B9;HERMITIAN CONJUGATE MATRIX;Sm;0;ON;;;;;N;;;;; +22BA;INTERCALATE;Sm;0;ON;;;;;N;;;;; +22BB;XOR;Sm;0;ON;;;;;N;;;;; +22BC;NAND;Sm;0;ON;;;;;N;;;;; +22BD;NOR;Sm;0;ON;;;;;N;;;;; +22BE;RIGHT ANGLE WITH ARC;Sm;0;ON;;;;;Y;;;;; +22BF;RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;; +22C0;N-ARY LOGICAL AND;Sm;0;ON;;;;;N;;;;; +22C1;N-ARY LOGICAL OR;Sm;0;ON;;;;;N;;;;; +22C2;N-ARY INTERSECTION;Sm;0;ON;;;;;N;;;;; +22C3;N-ARY UNION;Sm;0;ON;;;;;N;;;;; +22C4;DIAMOND OPERATOR;Sm;0;ON;;;;;N;;;;; +22C5;DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +22C6;STAR OPERATOR;Sm;0;ON;;;;;N;;;;; +22C7;DIVISION TIMES;Sm;0;ON;;;;;N;;;;; +22C8;BOWTIE;Sm;0;ON;;;;;N;;;;; +22C9;LEFT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CA;RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CB;LEFT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CC;RIGHT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CD;REVERSED TILDE EQUALS;Sm;0;ON;;;;;Y;;;;; +22CE;CURLY LOGICAL OR;Sm;0;ON;;;;;N;;;;; +22CF;CURLY LOGICAL AND;Sm;0;ON;;;;;N;;;;; +22D0;DOUBLE SUBSET;Sm;0;ON;;;;;Y;;;;; +22D1;DOUBLE SUPERSET;Sm;0;ON;;;;;Y;;;;; +22D2;DOUBLE INTERSECTION;Sm;0;ON;;;;;N;;;;; +22D3;DOUBLE UNION;Sm;0;ON;;;;;N;;;;; +22D4;PITCHFORK;Sm;0;ON;;;;;N;;;;; +22D5;EQUAL AND PARALLEL TO;Sm;0;ON;;;;;N;;;;; +22D6;LESS-THAN WITH DOT;Sm;0;ON;;;;;Y;LESS THAN WITH DOT;;;; +22D7;GREATER-THAN WITH DOT;Sm;0;ON;;;;;Y;GREATER THAN WITH DOT;;;; +22D8;VERY MUCH LESS-THAN;Sm;0;ON;;;;;Y;VERY MUCH LESS THAN;;;; +22D9;VERY MUCH GREATER-THAN;Sm;0;ON;;;;;Y;VERY MUCH GREATER THAN;;;; +22DA;LESS-THAN EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN EQUAL TO OR GREATER THAN;;;; +22DB;GREATER-THAN EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN EQUAL TO OR LESS THAN;;;; +22DC;EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR LESS THAN;;;; +22DD;EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR GREATER THAN;;;; +22DE;EQUAL TO OR PRECEDES;Sm;0;ON;;;;;Y;;;;; +22DF;EQUAL TO OR SUCCEEDS;Sm;0;ON;;;;;Y;;;;; +22E0;DOES NOT PRECEDE OR EQUAL;Sm;0;ON;227C 0338;;;;Y;;;;; +22E1;DOES NOT SUCCEED OR EQUAL;Sm;0;ON;227D 0338;;;;Y;;;;; +22E2;NOT SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;2291 0338;;;;Y;;;;; +22E3;NOT SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;2292 0338;;;;Y;;;;; +22E4;SQUARE IMAGE OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22E5;SQUARE ORIGINAL OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22E6;LESS-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUIVALENT TO;;;; +22E7;GREATER-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUIVALENT TO;;;; +22E8;PRECEDES BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +22E9;SUCCEEDS BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +22EA;NOT NORMAL SUBGROUP OF;Sm;0;ON;22B2 0338;;;;Y;;;;; +22EB;DOES NOT CONTAIN AS NORMAL SUBGROUP;Sm;0;ON;22B3 0338;;;;Y;;;;; +22EC;NOT NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;22B4 0338;;;;Y;;;;; +22ED;DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL;Sm;0;ON;22B5 0338;;;;Y;;;;; +22EE;VERTICAL ELLIPSIS;Sm;0;ON;;;;;N;;;;; +22EF;MIDLINE HORIZONTAL ELLIPSIS;Sm;0;ON;;;;;N;;;;; +22F0;UP RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;; +22F1;DOWN RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;; +22F2;ELEMENT OF WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22F3;ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22F4;SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22F5;ELEMENT OF WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +22F6;ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22F7;SMALL ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22F8;ELEMENT OF WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +22F9;ELEMENT OF WITH TWO HORIZONTAL STROKES;Sm;0;ON;;;;;Y;;;;; +22FA;CONTAINS WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22FB;CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22FC;SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22FD;CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22FE;SMALL CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22FF;Z NOTATION BAG MEMBERSHIP;Sm;0;ON;;;;;Y;;;;; +2300;DIAMETER SIGN;So;0;ON;;;;;N;;;;; +2301;ELECTRIC ARROW;So;0;ON;;;;;N;;;;; +2302;HOUSE;So;0;ON;;;;;N;;;;; +2303;UP ARROWHEAD;So;0;ON;;;;;N;;;;; +2304;DOWN ARROWHEAD;So;0;ON;;;;;N;;;;; +2305;PROJECTIVE;So;0;ON;;;;;N;;;;; +2306;PERSPECTIVE;So;0;ON;;;;;N;;;;; +2307;WAVY LINE;So;0;ON;;;;;N;;;;; +2308;LEFT CEILING;Sm;0;ON;;;;;Y;;;;; +2309;RIGHT CEILING;Sm;0;ON;;;;;Y;;;;; +230A;LEFT FLOOR;Sm;0;ON;;;;;Y;;;;; +230B;RIGHT FLOOR;Sm;0;ON;;;;;Y;;;;; +230C;BOTTOM RIGHT CROP;So;0;ON;;;;;N;;;;; +230D;BOTTOM LEFT CROP;So;0;ON;;;;;N;;;;; +230E;TOP RIGHT CROP;So;0;ON;;;;;N;;;;; +230F;TOP LEFT CROP;So;0;ON;;;;;N;;;;; +2310;REVERSED NOT SIGN;So;0;ON;;;;;N;;;;; +2311;SQUARE LOZENGE;So;0;ON;;;;;N;;;;; +2312;ARC;So;0;ON;;;;;N;;;;; +2313;SEGMENT;So;0;ON;;;;;N;;;;; +2314;SECTOR;So;0;ON;;;;;N;;;;; +2315;TELEPHONE RECORDER;So;0;ON;;;;;N;;;;; +2316;POSITION INDICATOR;So;0;ON;;;;;N;;;;; +2317;VIEWDATA SQUARE;So;0;ON;;;;;N;;;;; +2318;PLACE OF INTEREST SIGN;So;0;ON;;;;;N;COMMAND KEY;;;; +2319;TURNED NOT SIGN;So;0;ON;;;;;N;;;;; +231A;WATCH;So;0;ON;;;;;N;;;;; +231B;HOURGLASS;So;0;ON;;;;;N;;;;; +231C;TOP LEFT CORNER;So;0;ON;;;;;N;;;;; +231D;TOP RIGHT CORNER;So;0;ON;;;;;N;;;;; +231E;BOTTOM LEFT CORNER;So;0;ON;;;;;N;;;;; +231F;BOTTOM RIGHT CORNER;So;0;ON;;;;;N;;;;; +2320;TOP HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2321;BOTTOM HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2322;FROWN;So;0;ON;;;;;N;;;;; +2323;SMILE;So;0;ON;;;;;N;;;;; +2324;UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS;So;0;ON;;;;;N;ENTER KEY;;;; +2325;OPTION KEY;So;0;ON;;;;;N;;;;; +2326;ERASE TO THE RIGHT;So;0;ON;;;;;N;DELETE TO THE RIGHT KEY;;;; +2327;X IN A RECTANGLE BOX;So;0;ON;;;;;N;CLEAR KEY;;;; +2328;KEYBOARD;So;0;ON;;;;;N;;;;; +2329;LEFT-POINTING ANGLE BRACKET;Ps;0;ON;3008;;;;Y;BRA;;;; +232A;RIGHT-POINTING ANGLE BRACKET;Pe;0;ON;3009;;;;Y;KET;;;; +232B;ERASE TO THE LEFT;So;0;ON;;;;;N;DELETE TO THE LEFT KEY;;;; +232C;BENZENE RING;So;0;ON;;;;;N;;;;; +232D;CYLINDRICITY;So;0;ON;;;;;N;;;;; +232E;ALL AROUND-PROFILE;So;0;ON;;;;;N;;;;; +232F;SYMMETRY;So;0;ON;;;;;N;;;;; +2330;TOTAL RUNOUT;So;0;ON;;;;;N;;;;; +2331;DIMENSION ORIGIN;So;0;ON;;;;;N;;;;; +2332;CONICAL TAPER;So;0;ON;;;;;N;;;;; +2333;SLOPE;So;0;ON;;;;;N;;;;; +2334;COUNTERBORE;So;0;ON;;;;;N;;;;; +2335;COUNTERSINK;So;0;ON;;;;;N;;;;; +2336;APL FUNCTIONAL SYMBOL I-BEAM;So;0;L;;;;;N;;;;; +2337;APL FUNCTIONAL SYMBOL SQUISH QUAD;So;0;L;;;;;N;;;;; +2338;APL FUNCTIONAL SYMBOL QUAD EQUAL;So;0;L;;;;;N;;;;; +2339;APL FUNCTIONAL SYMBOL QUAD DIVIDE;So;0;L;;;;;N;;;;; +233A;APL FUNCTIONAL SYMBOL QUAD DIAMOND;So;0;L;;;;;N;;;;; +233B;APL FUNCTIONAL SYMBOL QUAD JOT;So;0;L;;;;;N;;;;; +233C;APL FUNCTIONAL SYMBOL QUAD CIRCLE;So;0;L;;;;;N;;;;; +233D;APL FUNCTIONAL SYMBOL CIRCLE STILE;So;0;L;;;;;N;;;;; +233E;APL FUNCTIONAL SYMBOL CIRCLE JOT;So;0;L;;;;;N;;;;; +233F;APL FUNCTIONAL SYMBOL SLASH BAR;So;0;L;;;;;N;;;;; +2340;APL FUNCTIONAL SYMBOL BACKSLASH BAR;So;0;L;;;;;N;;;;; +2341;APL FUNCTIONAL SYMBOL QUAD SLASH;So;0;L;;;;;N;;;;; +2342;APL FUNCTIONAL SYMBOL QUAD BACKSLASH;So;0;L;;;;;N;;;;; +2343;APL FUNCTIONAL SYMBOL QUAD LESS-THAN;So;0;L;;;;;N;;;;; +2344;APL FUNCTIONAL SYMBOL QUAD GREATER-THAN;So;0;L;;;;;N;;;;; +2345;APL FUNCTIONAL SYMBOL LEFTWARDS VANE;So;0;L;;;;;N;;;;; +2346;APL FUNCTIONAL SYMBOL RIGHTWARDS VANE;So;0;L;;;;;N;;;;; +2347;APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW;So;0;L;;;;;N;;;;; +2348;APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW;So;0;L;;;;;N;;;;; +2349;APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH;So;0;L;;;;;N;;;;; +234A;APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR;So;0;L;;;;;N;;;;; +234B;APL FUNCTIONAL SYMBOL DELTA STILE;So;0;L;;;;;N;;;;; +234C;APL FUNCTIONAL SYMBOL QUAD DOWN CARET;So;0;L;;;;;N;;;;; +234D;APL FUNCTIONAL SYMBOL QUAD DELTA;So;0;L;;;;;N;;;;; +234E;APL FUNCTIONAL SYMBOL DOWN TACK JOT;So;0;L;;;;;N;;;;; +234F;APL FUNCTIONAL SYMBOL UPWARDS VANE;So;0;L;;;;;N;;;;; +2350;APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW;So;0;L;;;;;N;;;;; +2351;APL FUNCTIONAL SYMBOL UP TACK OVERBAR;So;0;L;;;;;N;;;;; +2352;APL FUNCTIONAL SYMBOL DEL STILE;So;0;L;;;;;N;;;;; +2353;APL FUNCTIONAL SYMBOL QUAD UP CARET;So;0;L;;;;;N;;;;; +2354;APL FUNCTIONAL SYMBOL QUAD DEL;So;0;L;;;;;N;;;;; +2355;APL FUNCTIONAL SYMBOL UP TACK JOT;So;0;L;;;;;N;;;;; +2356;APL FUNCTIONAL SYMBOL DOWNWARDS VANE;So;0;L;;;;;N;;;;; +2357;APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW;So;0;L;;;;;N;;;;; +2358;APL FUNCTIONAL SYMBOL QUOTE UNDERBAR;So;0;L;;;;;N;;;;; +2359;APL FUNCTIONAL SYMBOL DELTA UNDERBAR;So;0;L;;;;;N;;;;; +235A;APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR;So;0;L;;;;;N;;;;; +235B;APL FUNCTIONAL SYMBOL JOT UNDERBAR;So;0;L;;;;;N;;;;; +235C;APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR;So;0;L;;;;;N;;;;; +235D;APL FUNCTIONAL SYMBOL UP SHOE JOT;So;0;L;;;;;N;;;;; +235E;APL FUNCTIONAL SYMBOL QUOTE QUAD;So;0;L;;;;;N;;;;; +235F;APL FUNCTIONAL SYMBOL CIRCLE STAR;So;0;L;;;;;N;;;;; +2360;APL FUNCTIONAL SYMBOL QUAD COLON;So;0;L;;;;;N;;;;; +2361;APL FUNCTIONAL SYMBOL UP TACK DIAERESIS;So;0;L;;;;;N;;;;; +2362;APL FUNCTIONAL SYMBOL DEL DIAERESIS;So;0;L;;;;;N;;;;; +2363;APL FUNCTIONAL SYMBOL STAR DIAERESIS;So;0;L;;;;;N;;;;; +2364;APL FUNCTIONAL SYMBOL JOT DIAERESIS;So;0;L;;;;;N;;;;; +2365;APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS;So;0;L;;;;;N;;;;; +2366;APL FUNCTIONAL SYMBOL DOWN SHOE STILE;So;0;L;;;;;N;;;;; +2367;APL FUNCTIONAL SYMBOL LEFT SHOE STILE;So;0;L;;;;;N;;;;; +2368;APL FUNCTIONAL SYMBOL TILDE DIAERESIS;So;0;L;;;;;N;;;;; +2369;APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS;So;0;L;;;;;N;;;;; +236A;APL FUNCTIONAL SYMBOL COMMA BAR;So;0;L;;;;;N;;;;; +236B;APL FUNCTIONAL SYMBOL DEL TILDE;So;0;L;;;;;N;;;;; +236C;APL FUNCTIONAL SYMBOL ZILDE;So;0;L;;;;;N;;;;; +236D;APL FUNCTIONAL SYMBOL STILE TILDE;So;0;L;;;;;N;;;;; +236E;APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR;So;0;L;;;;;N;;;;; +236F;APL FUNCTIONAL SYMBOL QUAD NOT EQUAL;So;0;L;;;;;N;;;;; +2370;APL FUNCTIONAL SYMBOL QUAD QUESTION;So;0;L;;;;;N;;;;; +2371;APL FUNCTIONAL SYMBOL DOWN CARET TILDE;So;0;L;;;;;N;;;;; +2372;APL FUNCTIONAL SYMBOL UP CARET TILDE;So;0;L;;;;;N;;;;; +2373;APL FUNCTIONAL SYMBOL IOTA;So;0;L;;;;;N;;;;; +2374;APL FUNCTIONAL SYMBOL RHO;So;0;L;;;;;N;;;;; +2375;APL FUNCTIONAL SYMBOL OMEGA;So;0;L;;;;;N;;;;; +2376;APL FUNCTIONAL SYMBOL ALPHA UNDERBAR;So;0;L;;;;;N;;;;; +2377;APL FUNCTIONAL SYMBOL EPSILON UNDERBAR;So;0;L;;;;;N;;;;; +2378;APL FUNCTIONAL SYMBOL IOTA UNDERBAR;So;0;L;;;;;N;;;;; +2379;APL FUNCTIONAL SYMBOL OMEGA UNDERBAR;So;0;L;;;;;N;;;;; +237A;APL FUNCTIONAL SYMBOL ALPHA;So;0;L;;;;;N;;;;; +237B;NOT CHECK MARK;So;0;ON;;;;;N;;;;; +237C;RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW;Sm;0;ON;;;;;N;;;;; +237D;SHOULDERED OPEN BOX;So;0;ON;;;;;N;;;;; +237E;BELL SYMBOL;So;0;ON;;;;;N;;;;; +237F;VERTICAL LINE WITH MIDDLE DOT;So;0;ON;;;;;N;;;;; +2380;INSERTION SYMBOL;So;0;ON;;;;;N;;;;; +2381;CONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;; +2382;DISCONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;; +2383;EMPHASIS SYMBOL;So;0;ON;;;;;N;;;;; +2384;COMPOSITION SYMBOL;So;0;ON;;;;;N;;;;; +2385;WHITE SQUARE WITH CENTRE VERTICAL LINE;So;0;ON;;;;;N;;;;; +2386;ENTER SYMBOL;So;0;ON;;;;;N;;;;; +2387;ALTERNATIVE KEY SYMBOL;So;0;ON;;;;;N;;;;; +2388;HELM SYMBOL;So;0;ON;;;;;N;;;;; +2389;CIRCLED HORIZONTAL BAR WITH NOTCH;So;0;ON;;;;;N;;;;; +238A;CIRCLED TRIANGLE DOWN;So;0;ON;;;;;N;;;;; +238B;BROKEN CIRCLE WITH NORTHWEST ARROW;So;0;ON;;;;;N;;;;; +238C;UNDO SYMBOL;So;0;ON;;;;;N;;;;; +238D;MONOSTABLE SYMBOL;So;0;ON;;;;;N;;;;; +238E;HYSTERESIS SYMBOL;So;0;ON;;;;;N;;;;; +238F;OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL;So;0;ON;;;;;N;;;;; +2390;OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL;So;0;ON;;;;;N;;;;; +2391;PASSIVE-PULL-DOWN-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;; +2392;PASSIVE-PULL-UP-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;; +2393;DIRECT CURRENT SYMBOL FORM TWO;So;0;ON;;;;;N;;;;; +2394;SOFTWARE-FUNCTION SYMBOL;So;0;ON;;;;;N;;;;; +2395;APL FUNCTIONAL SYMBOL QUAD;So;0;L;;;;;N;;;;; +2396;DECIMAL SEPARATOR KEY SYMBOL;So;0;ON;;;;;N;;;;; +2397;PREVIOUS PAGE;So;0;ON;;;;;N;;;;; +2398;NEXT PAGE;So;0;ON;;;;;N;;;;; +2399;PRINT SCREEN SYMBOL;So;0;ON;;;;;N;;;;; +239A;CLEAR SCREEN SYMBOL;So;0;ON;;;;;N;;;;; +239B;LEFT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;; +239C;LEFT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;; +239D;LEFT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;; +239E;RIGHT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;; +239F;RIGHT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;; +23A0;RIGHT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;; +23A1;LEFT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;; +23A2;LEFT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; +23A3;LEFT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;; +23A4;RIGHT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;; +23A5;RIGHT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; +23A6;RIGHT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;; +23A7;LEFT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;; +23A8;LEFT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;; +23A9;LEFT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;; +23AA;CURLY BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; +23AB;RIGHT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;; +23AC;RIGHT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;; +23AD;RIGHT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;; +23AE;INTEGRAL EXTENSION;Sm;0;ON;;;;;N;;;;; +23AF;HORIZONTAL LINE EXTENSION;Sm;0;ON;;;;;N;;;;; +23B0;UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;; +23B1;UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;; +23B2;SUMMATION TOP;Sm;0;ON;;;;;N;;;;; +23B3;SUMMATION BOTTOM;Sm;0;ON;;;;;N;;;;; +23B4;TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;; +23B5;BOTTOM SQUARE BRACKET;So;0;ON;;;;;N;;;;; +23B6;BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;; +23B7;RADICAL SYMBOL BOTTOM;So;0;ON;;;;;N;;;;; +23B8;LEFT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;; +23B9;RIGHT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;; +23BA;HORIZONTAL SCAN LINE-1;So;0;ON;;;;;N;;;;; +23BB;HORIZONTAL SCAN LINE-3;So;0;ON;;;;;N;;;;; +23BC;HORIZONTAL SCAN LINE-7;So;0;ON;;;;;N;;;;; +23BD;HORIZONTAL SCAN LINE-9;So;0;ON;;;;;N;;;;; +23BE;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT;So;0;ON;;;;;N;;;;; +23BF;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT;So;0;ON;;;;;N;;;;; +23C0;DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE;So;0;ON;;;;;N;;;;; +23C1;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;; +23C2;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;; +23C3;DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; +23C4;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; +23C5;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; +23C6;DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE;So;0;ON;;;;;N;;;;; +23C7;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;; +23C8;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;; +23C9;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;;;;; +23CA;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;;;;; +23CB;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT;So;0;ON;;;;;N;;;;; +23CC;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT;So;0;ON;;;;;N;;;;; +23CD;SQUARE FOOT;So;0;ON;;;;;N;;;;; +23CE;RETURN SYMBOL;So;0;ON;;;;;N;;;;; +23CF;EJECT SYMBOL;So;0;ON;;;;;N;;;;; +23D0;VERTICAL LINE EXTENSION;So;0;ON;;;;;N;;;;; +23D1;METRICAL BREVE;So;0;ON;;;;;N;;;;; +23D2;METRICAL LONG OVER SHORT;So;0;ON;;;;;N;;;;; +23D3;METRICAL SHORT OVER LONG;So;0;ON;;;;;N;;;;; +23D4;METRICAL LONG OVER TWO SHORTS;So;0;ON;;;;;N;;;;; +23D5;METRICAL TWO SHORTS OVER LONG;So;0;ON;;;;;N;;;;; +23D6;METRICAL TWO SHORTS JOINED;So;0;ON;;;;;N;;;;; +23D7;METRICAL TRISEME;So;0;ON;;;;;N;;;;; +23D8;METRICAL TETRASEME;So;0;ON;;;;;N;;;;; +23D9;METRICAL PENTASEME;So;0;ON;;;;;N;;;;; +23DA;EARTH GROUND;So;0;ON;;;;;N;;;;; +23DB;FUSE;So;0;ON;;;;;N;;;;; +23DC;TOP PARENTHESIS;Sm;0;ON;;;;;N;;;;; +23DD;BOTTOM PARENTHESIS;Sm;0;ON;;;;;N;;;;; +23DE;TOP CURLY BRACKET;Sm;0;ON;;;;;N;;;;; +23DF;BOTTOM CURLY BRACKET;Sm;0;ON;;;;;N;;;;; +23E0;TOP TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;;;; +23E1;BOTTOM TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;;;; +23E2;WHITE TRAPEZIUM;So;0;ON;;;;;N;;;;; +23E3;BENZENE RING WITH CIRCLE;So;0;ON;;;;;N;;;;; +23E4;STRAIGHTNESS;So;0;ON;;;;;N;;;;; +23E5;FLATNESS;So;0;ON;;;;;N;;;;; +23E6;AC CURRENT;So;0;ON;;;;;N;;;;; +23E7;ELECTRICAL INTERSECTION;So;0;ON;;;;;N;;;;; +23E8;DECIMAL EXPONENT SYMBOL;So;0;ON;;;;;N;;;;; +2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;; +2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;; +2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;; +2403;SYMBOL FOR END OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR END OF TEXT;;;; +2404;SYMBOL FOR END OF TRANSMISSION;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION;;;; +2405;SYMBOL FOR ENQUIRY;So;0;ON;;;;;N;GRAPHIC FOR ENQUIRY;;;; +2406;SYMBOL FOR ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR ACKNOWLEDGE;;;; +2407;SYMBOL FOR BELL;So;0;ON;;;;;N;GRAPHIC FOR BELL;;;; +2408;SYMBOL FOR BACKSPACE;So;0;ON;;;;;N;GRAPHIC FOR BACKSPACE;;;; +2409;SYMBOL FOR HORIZONTAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR HORIZONTAL TABULATION;;;; +240A;SYMBOL FOR LINE FEED;So;0;ON;;;;;N;GRAPHIC FOR LINE FEED;;;; +240B;SYMBOL FOR VERTICAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR VERTICAL TABULATION;;;; +240C;SYMBOL FOR FORM FEED;So;0;ON;;;;;N;GRAPHIC FOR FORM FEED;;;; +240D;SYMBOL FOR CARRIAGE RETURN;So;0;ON;;;;;N;GRAPHIC FOR CARRIAGE RETURN;;;; +240E;SYMBOL FOR SHIFT OUT;So;0;ON;;;;;N;GRAPHIC FOR SHIFT OUT;;;; +240F;SYMBOL FOR SHIFT IN;So;0;ON;;;;;N;GRAPHIC FOR SHIFT IN;;;; +2410;SYMBOL FOR DATA LINK ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR DATA LINK ESCAPE;;;; +2411;SYMBOL FOR DEVICE CONTROL ONE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL ONE;;;; +2412;SYMBOL FOR DEVICE CONTROL TWO;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL TWO;;;; +2413;SYMBOL FOR DEVICE CONTROL THREE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL THREE;;;; +2414;SYMBOL FOR DEVICE CONTROL FOUR;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL FOUR;;;; +2415;SYMBOL FOR NEGATIVE ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR NEGATIVE ACKNOWLEDGE;;;; +2416;SYMBOL FOR SYNCHRONOUS IDLE;So;0;ON;;;;;N;GRAPHIC FOR SYNCHRONOUS IDLE;;;; +2417;SYMBOL FOR END OF TRANSMISSION BLOCK;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION BLOCK;;;; +2418;SYMBOL FOR CANCEL;So;0;ON;;;;;N;GRAPHIC FOR CANCEL;;;; +2419;SYMBOL FOR END OF MEDIUM;So;0;ON;;;;;N;GRAPHIC FOR END OF MEDIUM;;;; +241A;SYMBOL FOR SUBSTITUTE;So;0;ON;;;;;N;GRAPHIC FOR SUBSTITUTE;;;; +241B;SYMBOL FOR ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR ESCAPE;;;; +241C;SYMBOL FOR FILE SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR FILE SEPARATOR;;;; +241D;SYMBOL FOR GROUP SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR GROUP SEPARATOR;;;; +241E;SYMBOL FOR RECORD SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR RECORD SEPARATOR;;;; +241F;SYMBOL FOR UNIT SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR UNIT SEPARATOR;;;; +2420;SYMBOL FOR SPACE;So;0;ON;;;;;N;GRAPHIC FOR SPACE;;;; +2421;SYMBOL FOR DELETE;So;0;ON;;;;;N;GRAPHIC FOR DELETE;;;; +2422;BLANK SYMBOL;So;0;ON;;;;;N;BLANK;;;; +2423;OPEN BOX;So;0;ON;;;;;N;;;;; +2424;SYMBOL FOR NEWLINE;So;0;ON;;;;;N;GRAPHIC FOR NEWLINE;;;; +2425;SYMBOL FOR DELETE FORM TWO;So;0;ON;;;;;N;;;;; +2426;SYMBOL FOR SUBSTITUTE FORM TWO;So;0;ON;;;;;N;;;;; +2440;OCR HOOK;So;0;ON;;;;;N;;;;; +2441;OCR CHAIR;So;0;ON;;;;;N;;;;; +2442;OCR FORK;So;0;ON;;;;;N;;;;; +2443;OCR INVERTED FORK;So;0;ON;;;;;N;;;;; +2444;OCR BELT BUCKLE;So;0;ON;;;;;N;;;;; +2445;OCR BOW TIE;So;0;ON;;;;;N;;;;; +2446;OCR BRANCH BANK IDENTIFICATION;So;0;ON;;;;;N;;;;; +2447;OCR AMOUNT OF CHECK;So;0;ON;;;;;N;;;;; +2448;OCR DASH;So;0;ON;;;;;N;;;;; +2449;OCR CUSTOMER ACCOUNT NUMBER;So;0;ON;;;;;N;;;;; +244A;OCR DOUBLE BACKSLASH;So;0;ON;;;;;N;;;;; +2460;CIRCLED DIGIT ONE;No;0;ON; 0031;;1;1;N;;;;; +2461;CIRCLED DIGIT TWO;No;0;ON; 0032;;2;2;N;;;;; +2462;CIRCLED DIGIT THREE;No;0;ON; 0033;;3;3;N;;;;; +2463;CIRCLED DIGIT FOUR;No;0;ON; 0034;;4;4;N;;;;; +2464;CIRCLED DIGIT FIVE;No;0;ON; 0035;;5;5;N;;;;; +2465;CIRCLED DIGIT SIX;No;0;ON; 0036;;6;6;N;;;;; +2466;CIRCLED DIGIT SEVEN;No;0;ON; 0037;;7;7;N;;;;; +2467;CIRCLED DIGIT EIGHT;No;0;ON; 0038;;8;8;N;;;;; +2468;CIRCLED DIGIT NINE;No;0;ON; 0039;;9;9;N;;;;; +2469;CIRCLED NUMBER TEN;No;0;ON; 0031 0030;;;10;N;;;;; +246A;CIRCLED NUMBER ELEVEN;No;0;ON; 0031 0031;;;11;N;;;;; +246B;CIRCLED NUMBER TWELVE;No;0;ON; 0031 0032;;;12;N;;;;; +246C;CIRCLED NUMBER THIRTEEN;No;0;ON; 0031 0033;;;13;N;;;;; +246D;CIRCLED NUMBER FOURTEEN;No;0;ON; 0031 0034;;;14;N;;;;; +246E;CIRCLED NUMBER FIFTEEN;No;0;ON; 0031 0035;;;15;N;;;;; +246F;CIRCLED NUMBER SIXTEEN;No;0;ON; 0031 0036;;;16;N;;;;; +2470;CIRCLED NUMBER SEVENTEEN;No;0;ON; 0031 0037;;;17;N;;;;; +2471;CIRCLED NUMBER EIGHTEEN;No;0;ON; 0031 0038;;;18;N;;;;; +2472;CIRCLED NUMBER NINETEEN;No;0;ON; 0031 0039;;;19;N;;;;; +2473;CIRCLED NUMBER TWENTY;No;0;ON; 0032 0030;;;20;N;;;;; +2474;PARENTHESIZED DIGIT ONE;No;0;ON; 0028 0031 0029;;1;1;N;;;;; +2475;PARENTHESIZED DIGIT TWO;No;0;ON; 0028 0032 0029;;2;2;N;;;;; +2476;PARENTHESIZED DIGIT THREE;No;0;ON; 0028 0033 0029;;3;3;N;;;;; +2477;PARENTHESIZED DIGIT FOUR;No;0;ON; 0028 0034 0029;;4;4;N;;;;; +2478;PARENTHESIZED DIGIT FIVE;No;0;ON; 0028 0035 0029;;5;5;N;;;;; +2479;PARENTHESIZED DIGIT SIX;No;0;ON; 0028 0036 0029;;6;6;N;;;;; +247A;PARENTHESIZED DIGIT SEVEN;No;0;ON; 0028 0037 0029;;7;7;N;;;;; +247B;PARENTHESIZED DIGIT EIGHT;No;0;ON; 0028 0038 0029;;8;8;N;;;;; +247C;PARENTHESIZED DIGIT NINE;No;0;ON; 0028 0039 0029;;9;9;N;;;;; +247D;PARENTHESIZED NUMBER TEN;No;0;ON; 0028 0031 0030 0029;;;10;N;;;;; +247E;PARENTHESIZED NUMBER ELEVEN;No;0;ON; 0028 0031 0031 0029;;;11;N;;;;; +247F;PARENTHESIZED NUMBER TWELVE;No;0;ON; 0028 0031 0032 0029;;;12;N;;;;; +2480;PARENTHESIZED NUMBER THIRTEEN;No;0;ON; 0028 0031 0033 0029;;;13;N;;;;; +2481;PARENTHESIZED NUMBER FOURTEEN;No;0;ON; 0028 0031 0034 0029;;;14;N;;;;; +2482;PARENTHESIZED NUMBER FIFTEEN;No;0;ON; 0028 0031 0035 0029;;;15;N;;;;; +2483;PARENTHESIZED NUMBER SIXTEEN;No;0;ON; 0028 0031 0036 0029;;;16;N;;;;; +2484;PARENTHESIZED NUMBER SEVENTEEN;No;0;ON; 0028 0031 0037 0029;;;17;N;;;;; +2485;PARENTHESIZED NUMBER EIGHTEEN;No;0;ON; 0028 0031 0038 0029;;;18;N;;;;; +2486;PARENTHESIZED NUMBER NINETEEN;No;0;ON; 0028 0031 0039 0029;;;19;N;;;;; +2487;PARENTHESIZED NUMBER TWENTY;No;0;ON; 0028 0032 0030 0029;;;20;N;;;;; +2488;DIGIT ONE FULL STOP;No;0;EN; 0031 002E;;1;1;N;DIGIT ONE PERIOD;;;; +2489;DIGIT TWO FULL STOP;No;0;EN; 0032 002E;;2;2;N;DIGIT TWO PERIOD;;;; +248A;DIGIT THREE FULL STOP;No;0;EN; 0033 002E;;3;3;N;DIGIT THREE PERIOD;;;; +248B;DIGIT FOUR FULL STOP;No;0;EN; 0034 002E;;4;4;N;DIGIT FOUR PERIOD;;;; +248C;DIGIT FIVE FULL STOP;No;0;EN; 0035 002E;;5;5;N;DIGIT FIVE PERIOD;;;; +248D;DIGIT SIX FULL STOP;No;0;EN; 0036 002E;;6;6;N;DIGIT SIX PERIOD;;;; +248E;DIGIT SEVEN FULL STOP;No;0;EN; 0037 002E;;7;7;N;DIGIT SEVEN PERIOD;;;; +248F;DIGIT EIGHT FULL STOP;No;0;EN; 0038 002E;;8;8;N;DIGIT EIGHT PERIOD;;;; +2490;DIGIT NINE FULL STOP;No;0;EN; 0039 002E;;9;9;N;DIGIT NINE PERIOD;;;; +2491;NUMBER TEN FULL STOP;No;0;EN; 0031 0030 002E;;;10;N;NUMBER TEN PERIOD;;;; +2492;NUMBER ELEVEN FULL STOP;No;0;EN; 0031 0031 002E;;;11;N;NUMBER ELEVEN PERIOD;;;; +2493;NUMBER TWELVE FULL STOP;No;0;EN; 0031 0032 002E;;;12;N;NUMBER TWELVE PERIOD;;;; +2494;NUMBER THIRTEEN FULL STOP;No;0;EN; 0031 0033 002E;;;13;N;NUMBER THIRTEEN PERIOD;;;; +2495;NUMBER FOURTEEN FULL STOP;No;0;EN; 0031 0034 002E;;;14;N;NUMBER FOURTEEN PERIOD;;;; +2496;NUMBER FIFTEEN FULL STOP;No;0;EN; 0031 0035 002E;;;15;N;NUMBER FIFTEEN PERIOD;;;; +2497;NUMBER SIXTEEN FULL STOP;No;0;EN; 0031 0036 002E;;;16;N;NUMBER SIXTEEN PERIOD;;;; +2498;NUMBER SEVENTEEN FULL STOP;No;0;EN; 0031 0037 002E;;;17;N;NUMBER SEVENTEEN PERIOD;;;; +2499;NUMBER EIGHTEEN FULL STOP;No;0;EN; 0031 0038 002E;;;18;N;NUMBER EIGHTEEN PERIOD;;;; +249A;NUMBER NINETEEN FULL STOP;No;0;EN; 0031 0039 002E;;;19;N;NUMBER NINETEEN PERIOD;;;; +249B;NUMBER TWENTY FULL STOP;No;0;EN; 0032 0030 002E;;;20;N;NUMBER TWENTY PERIOD;;;; +249C;PARENTHESIZED LATIN SMALL LETTER A;So;0;L; 0028 0061 0029;;;;N;;;;; +249D;PARENTHESIZED LATIN SMALL LETTER B;So;0;L; 0028 0062 0029;;;;N;;;;; +249E;PARENTHESIZED LATIN SMALL LETTER C;So;0;L; 0028 0063 0029;;;;N;;;;; +249F;PARENTHESIZED LATIN SMALL LETTER D;So;0;L; 0028 0064 0029;;;;N;;;;; +24A0;PARENTHESIZED LATIN SMALL LETTER E;So;0;L; 0028 0065 0029;;;;N;;;;; +24A1;PARENTHESIZED LATIN SMALL LETTER F;So;0;L; 0028 0066 0029;;;;N;;;;; +24A2;PARENTHESIZED LATIN SMALL LETTER G;So;0;L; 0028 0067 0029;;;;N;;;;; +24A3;PARENTHESIZED LATIN SMALL LETTER H;So;0;L; 0028 0068 0029;;;;N;;;;; +24A4;PARENTHESIZED LATIN SMALL LETTER I;So;0;L; 0028 0069 0029;;;;N;;;;; +24A5;PARENTHESIZED LATIN SMALL LETTER J;So;0;L; 0028 006A 0029;;;;N;;;;; +24A6;PARENTHESIZED LATIN SMALL LETTER K;So;0;L; 0028 006B 0029;;;;N;;;;; +24A7;PARENTHESIZED LATIN SMALL LETTER L;So;0;L; 0028 006C 0029;;;;N;;;;; +24A8;PARENTHESIZED LATIN SMALL LETTER M;So;0;L; 0028 006D 0029;;;;N;;;;; +24A9;PARENTHESIZED LATIN SMALL LETTER N;So;0;L; 0028 006E 0029;;;;N;;;;; +24AA;PARENTHESIZED LATIN SMALL LETTER O;So;0;L; 0028 006F 0029;;;;N;;;;; +24AB;PARENTHESIZED LATIN SMALL LETTER P;So;0;L; 0028 0070 0029;;;;N;;;;; +24AC;PARENTHESIZED LATIN SMALL LETTER Q;So;0;L; 0028 0071 0029;;;;N;;;;; +24AD;PARENTHESIZED LATIN SMALL LETTER R;So;0;L; 0028 0072 0029;;;;N;;;;; +24AE;PARENTHESIZED LATIN SMALL LETTER S;So;0;L; 0028 0073 0029;;;;N;;;;; +24AF;PARENTHESIZED LATIN SMALL LETTER T;So;0;L; 0028 0074 0029;;;;N;;;;; +24B0;PARENTHESIZED LATIN SMALL LETTER U;So;0;L; 0028 0075 0029;;;;N;;;;; +24B1;PARENTHESIZED LATIN SMALL LETTER V;So;0;L; 0028 0076 0029;;;;N;;;;; +24B2;PARENTHESIZED LATIN SMALL LETTER W;So;0;L; 0028 0077 0029;;;;N;;;;; +24B3;PARENTHESIZED LATIN SMALL LETTER X;So;0;L; 0028 0078 0029;;;;N;;;;; +24B4;PARENTHESIZED LATIN SMALL LETTER Y;So;0;L; 0028 0079 0029;;;;N;;;;; +24B5;PARENTHESIZED LATIN SMALL LETTER Z;So;0;L; 0028 007A 0029;;;;N;;;;; +24B6;CIRCLED LATIN CAPITAL LETTER A;So;0;L; 0041;;;;N;;;;24D0; +24B7;CIRCLED LATIN CAPITAL LETTER B;So;0;L; 0042;;;;N;;;;24D1; +24B8;CIRCLED LATIN CAPITAL LETTER C;So;0;L; 0043;;;;N;;;;24D2; +24B9;CIRCLED LATIN CAPITAL LETTER D;So;0;L; 0044;;;;N;;;;24D3; +24BA;CIRCLED LATIN CAPITAL LETTER E;So;0;L; 0045;;;;N;;;;24D4; +24BB;CIRCLED LATIN CAPITAL LETTER F;So;0;L; 0046;;;;N;;;;24D5; +24BC;CIRCLED LATIN CAPITAL LETTER G;So;0;L; 0047;;;;N;;;;24D6; +24BD;CIRCLED LATIN CAPITAL LETTER H;So;0;L; 0048;;;;N;;;;24D7; +24BE;CIRCLED LATIN CAPITAL LETTER I;So;0;L; 0049;;;;N;;;;24D8; +24BF;CIRCLED LATIN CAPITAL LETTER J;So;0;L; 004A;;;;N;;;;24D9; +24C0;CIRCLED LATIN CAPITAL LETTER K;So;0;L; 004B;;;;N;;;;24DA; +24C1;CIRCLED LATIN CAPITAL LETTER L;So;0;L; 004C;;;;N;;;;24DB; +24C2;CIRCLED LATIN CAPITAL LETTER M;So;0;L; 004D;;;;N;;;;24DC; +24C3;CIRCLED LATIN CAPITAL LETTER N;So;0;L; 004E;;;;N;;;;24DD; +24C4;CIRCLED LATIN CAPITAL LETTER O;So;0;L; 004F;;;;N;;;;24DE; +24C5;CIRCLED LATIN CAPITAL LETTER P;So;0;L; 0050;;;;N;;;;24DF; +24C6;CIRCLED LATIN CAPITAL LETTER Q;So;0;L; 0051;;;;N;;;;24E0; +24C7;CIRCLED LATIN CAPITAL LETTER R;So;0;L; 0052;;;;N;;;;24E1; +24C8;CIRCLED LATIN CAPITAL LETTER S;So;0;L; 0053;;;;N;;;;24E2; +24C9;CIRCLED LATIN CAPITAL LETTER T;So;0;L; 0054;;;;N;;;;24E3; +24CA;CIRCLED LATIN CAPITAL LETTER U;So;0;L; 0055;;;;N;;;;24E4; +24CB;CIRCLED LATIN CAPITAL LETTER V;So;0;L; 0056;;;;N;;;;24E5; +24CC;CIRCLED LATIN CAPITAL LETTER W;So;0;L; 0057;;;;N;;;;24E6; +24CD;CIRCLED LATIN CAPITAL LETTER X;So;0;L; 0058;;;;N;;;;24E7; +24CE;CIRCLED LATIN CAPITAL LETTER Y;So;0;L; 0059;;;;N;;;;24E8; +24CF;CIRCLED LATIN CAPITAL LETTER Z;So;0;L; 005A;;;;N;;;;24E9; +24D0;CIRCLED LATIN SMALL LETTER A;So;0;L; 0061;;;;N;;;24B6;;24B6 +24D1;CIRCLED LATIN SMALL LETTER B;So;0;L; 0062;;;;N;;;24B7;;24B7 +24D2;CIRCLED LATIN SMALL LETTER C;So;0;L; 0063;;;;N;;;24B8;;24B8 +24D3;CIRCLED LATIN SMALL LETTER D;So;0;L; 0064;;;;N;;;24B9;;24B9 +24D4;CIRCLED LATIN SMALL LETTER E;So;0;L; 0065;;;;N;;;24BA;;24BA +24D5;CIRCLED LATIN SMALL LETTER F;So;0;L; 0066;;;;N;;;24BB;;24BB +24D6;CIRCLED LATIN SMALL LETTER G;So;0;L; 0067;;;;N;;;24BC;;24BC +24D7;CIRCLED LATIN SMALL LETTER H;So;0;L; 0068;;;;N;;;24BD;;24BD +24D8;CIRCLED LATIN SMALL LETTER I;So;0;L; 0069;;;;N;;;24BE;;24BE +24D9;CIRCLED LATIN SMALL LETTER J;So;0;L; 006A;;;;N;;;24BF;;24BF +24DA;CIRCLED LATIN SMALL LETTER K;So;0;L; 006B;;;;N;;;24C0;;24C0 +24DB;CIRCLED LATIN SMALL LETTER L;So;0;L; 006C;;;;N;;;24C1;;24C1 +24DC;CIRCLED LATIN SMALL LETTER M;So;0;L; 006D;;;;N;;;24C2;;24C2 +24DD;CIRCLED LATIN SMALL LETTER N;So;0;L; 006E;;;;N;;;24C3;;24C3 +24DE;CIRCLED LATIN SMALL LETTER O;So;0;L; 006F;;;;N;;;24C4;;24C4 +24DF;CIRCLED LATIN SMALL LETTER P;So;0;L; 0070;;;;N;;;24C5;;24C5 +24E0;CIRCLED LATIN SMALL LETTER Q;So;0;L; 0071;;;;N;;;24C6;;24C6 +24E1;CIRCLED LATIN SMALL LETTER R;So;0;L; 0072;;;;N;;;24C7;;24C7 +24E2;CIRCLED LATIN SMALL LETTER S;So;0;L; 0073;;;;N;;;24C8;;24C8 +24E3;CIRCLED LATIN SMALL LETTER T;So;0;L; 0074;;;;N;;;24C9;;24C9 +24E4;CIRCLED LATIN SMALL LETTER U;So;0;L; 0075;;;;N;;;24CA;;24CA +24E5;CIRCLED LATIN SMALL LETTER V;So;0;L; 0076;;;;N;;;24CB;;24CB +24E6;CIRCLED LATIN SMALL LETTER W;So;0;L; 0077;;;;N;;;24CC;;24CC +24E7;CIRCLED LATIN SMALL LETTER X;So;0;L; 0078;;;;N;;;24CD;;24CD +24E8;CIRCLED LATIN SMALL LETTER Y;So;0;L; 0079;;;;N;;;24CE;;24CE +24E9;CIRCLED LATIN SMALL LETTER Z;So;0;L; 007A;;;;N;;;24CF;;24CF +24EA;CIRCLED DIGIT ZERO;No;0;ON; 0030;;0;0;N;;;;; +24EB;NEGATIVE CIRCLED NUMBER ELEVEN;No;0;ON;;;;11;N;;;;; +24EC;NEGATIVE CIRCLED NUMBER TWELVE;No;0;ON;;;;12;N;;;;; +24ED;NEGATIVE CIRCLED NUMBER THIRTEEN;No;0;ON;;;;13;N;;;;; +24EE;NEGATIVE CIRCLED NUMBER FOURTEEN;No;0;ON;;;;14;N;;;;; +24EF;NEGATIVE CIRCLED NUMBER FIFTEEN;No;0;ON;;;;15;N;;;;; +24F0;NEGATIVE CIRCLED NUMBER SIXTEEN;No;0;ON;;;;16;N;;;;; +24F1;NEGATIVE CIRCLED NUMBER SEVENTEEN;No;0;ON;;;;17;N;;;;; +24F2;NEGATIVE CIRCLED NUMBER EIGHTEEN;No;0;ON;;;;18;N;;;;; +24F3;NEGATIVE CIRCLED NUMBER NINETEEN;No;0;ON;;;;19;N;;;;; +24F4;NEGATIVE CIRCLED NUMBER TWENTY;No;0;ON;;;;20;N;;;;; +24F5;DOUBLE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;;;;; +24F6;DOUBLE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;;;;; +24F7;DOUBLE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;;;;; +24F8;DOUBLE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;;;;; +24F9;DOUBLE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;;;;; +24FA;DOUBLE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;;;;; +24FB;DOUBLE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;;;;; +24FC;DOUBLE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;;;;; +24FD;DOUBLE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;;;;; +24FE;DOUBLE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;;;;; +24FF;NEGATIVE CIRCLED DIGIT ZERO;No;0;ON;;;0;0;N;;;;; +2500;BOX DRAWINGS LIGHT HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT HORIZONTAL;;;; +2501;BOX DRAWINGS HEAVY HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY HORIZONTAL;;;; +2502;BOX DRAWINGS LIGHT VERTICAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL;;;; +2503;BOX DRAWINGS HEAVY VERTICAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL;;;; +2504;BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH HORIZONTAL;;;; +2505;BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH HORIZONTAL;;;; +2506;BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH VERTICAL;;;; +2507;BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH VERTICAL;;;; +2508;BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH HORIZONTAL;;;; +2509;BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH HORIZONTAL;;;; +250A;BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH VERTICAL;;;; +250B;BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH VERTICAL;;;; +250C;BOX DRAWINGS LIGHT DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND RIGHT;;;; +250D;BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT HEAVY;;;; +250E;BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT LIGHT;;;; +250F;BOX DRAWINGS HEAVY DOWN AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND RIGHT;;;; +2510;BOX DRAWINGS LIGHT DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND LEFT;;;; +2511;BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT HEAVY;;;; +2512;BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT LIGHT;;;; +2513;BOX DRAWINGS HEAVY DOWN AND LEFT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND LEFT;;;; +2514;BOX DRAWINGS LIGHT UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT UP AND RIGHT;;;; +2515;BOX DRAWINGS UP LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT HEAVY;;;; +2516;BOX DRAWINGS UP HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT LIGHT;;;; +2517;BOX DRAWINGS HEAVY UP AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY UP AND RIGHT;;;; +2518;BOX DRAWINGS LIGHT UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT UP AND LEFT;;;; +2519;BOX DRAWINGS UP LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT HEAVY;;;; +251A;BOX DRAWINGS UP HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT LIGHT;;;; +251B;BOX DRAWINGS HEAVY UP AND LEFT;So;0;ON;;;;;N;FORMS HEAVY UP AND LEFT;;;; +251C;BOX DRAWINGS LIGHT VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND RIGHT;;;; +251D;BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND RIGHT HEAVY;;;; +251E;BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT DOWN LIGHT;;;; +251F;BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT UP LIGHT;;;; +2520;BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND RIGHT LIGHT;;;; +2521;BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT UP HEAVY;;;; +2522;BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT DOWN HEAVY;;;; +2523;BOX DRAWINGS HEAVY VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND RIGHT;;;; +2524;BOX DRAWINGS LIGHT VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND LEFT;;;; +2525;BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND LEFT HEAVY;;;; +2526;BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT DOWN LIGHT;;;; +2527;BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT UP LIGHT;;;; +2528;BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND LEFT LIGHT;;;; +2529;BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT UP HEAVY;;;; +252A;BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT DOWN HEAVY;;;; +252B;BOX DRAWINGS HEAVY VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND LEFT;;;; +252C;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOWN AND HORIZONTAL;;;; +252D;BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT DOWN LIGHT;;;; +252E;BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT DOWN LIGHT;;;; +252F;BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND HORIZONTAL HEAVY;;;; +2530;BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND HORIZONTAL LIGHT;;;; +2531;BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT DOWN HEAVY;;;; +2532;BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT DOWN HEAVY;;;; +2533;BOX DRAWINGS HEAVY DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOWN AND HORIZONTAL;;;; +2534;BOX DRAWINGS LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT UP AND HORIZONTAL;;;; +2535;BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT UP LIGHT;;;; +2536;BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT UP LIGHT;;;; +2537;BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND HORIZONTAL HEAVY;;;; +2538;BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND HORIZONTAL LIGHT;;;; +2539;BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT UP HEAVY;;;; +253A;BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT UP HEAVY;;;; +253B;BOX DRAWINGS HEAVY UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY UP AND HORIZONTAL;;;; +253C;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND HORIZONTAL;;;; +253D;BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT VERTICAL LIGHT;;;; +253E;BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT VERTICAL LIGHT;;;; +253F;BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND HORIZONTAL HEAVY;;;; +2540;BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND DOWN HORIZONTAL LIGHT;;;; +2541;BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND UP HORIZONTAL LIGHT;;;; +2542;BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND HORIZONTAL LIGHT;;;; +2543;BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT UP HEAVY AND RIGHT DOWN LIGHT;;;; +2544;BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT UP HEAVY AND LEFT DOWN LIGHT;;;; +2545;BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT DOWN HEAVY AND RIGHT UP LIGHT;;;; +2546;BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT DOWN HEAVY AND LEFT UP LIGHT;;;; +2547;BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND UP HORIZONTAL HEAVY;;;; +2548;BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND DOWN HORIZONTAL HEAVY;;;; +2549;BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT VERTICAL HEAVY;;;; +254A;BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT VERTICAL HEAVY;;;; +254B;BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND HORIZONTAL;;;; +254C;BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH HORIZONTAL;;;; +254D;BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH HORIZONTAL;;;; +254E;BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH VERTICAL;;;; +254F;BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH VERTICAL;;;; +2550;BOX DRAWINGS DOUBLE HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE HORIZONTAL;;;; +2551;BOX DRAWINGS DOUBLE VERTICAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL;;;; +2552;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND RIGHT DOUBLE;;;; +2553;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND RIGHT SINGLE;;;; +2554;BOX DRAWINGS DOUBLE DOWN AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND RIGHT;;;; +2555;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND LEFT DOUBLE;;;; +2556;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND LEFT SINGLE;;;; +2557;BOX DRAWINGS DOUBLE DOWN AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND LEFT;;;; +2558;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND RIGHT DOUBLE;;;; +2559;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND RIGHT SINGLE;;;; +255A;BOX DRAWINGS DOUBLE UP AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE UP AND RIGHT;;;; +255B;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND LEFT DOUBLE;;;; +255C;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND LEFT SINGLE;;;; +255D;BOX DRAWINGS DOUBLE UP AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE UP AND LEFT;;;; +255E;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND RIGHT DOUBLE;;;; +255F;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND RIGHT SINGLE;;;; +2560;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND RIGHT;;;; +2561;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND LEFT DOUBLE;;;; +2562;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND LEFT SINGLE;;;; +2563;BOX DRAWINGS DOUBLE VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND LEFT;;;; +2564;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND HORIZONTAL DOUBLE;;;; +2565;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND HORIZONTAL SINGLE;;;; +2566;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND HORIZONTAL;;;; +2567;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND HORIZONTAL DOUBLE;;;; +2568;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND HORIZONTAL SINGLE;;;; +2569;BOX DRAWINGS DOUBLE UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE UP AND HORIZONTAL;;;; +256A;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND HORIZONTAL DOUBLE;;;; +256B;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND HORIZONTAL SINGLE;;;; +256C;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND HORIZONTAL;;;; +256D;BOX DRAWINGS LIGHT ARC DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND RIGHT;;;; +256E;BOX DRAWINGS LIGHT ARC DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND LEFT;;;; +256F;BOX DRAWINGS LIGHT ARC UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND LEFT;;;; +2570;BOX DRAWINGS LIGHT ARC UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND RIGHT;;;; +2571;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;;;; +2572;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;;;; +2573;BOX DRAWINGS LIGHT DIAGONAL CROSS;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL CROSS;;;; +2574;BOX DRAWINGS LIGHT LEFT;So;0;ON;;;;;N;FORMS LIGHT LEFT;;;; +2575;BOX DRAWINGS LIGHT UP;So;0;ON;;;;;N;FORMS LIGHT UP;;;; +2576;BOX DRAWINGS LIGHT RIGHT;So;0;ON;;;;;N;FORMS LIGHT RIGHT;;;; +2577;BOX DRAWINGS LIGHT DOWN;So;0;ON;;;;;N;FORMS LIGHT DOWN;;;; +2578;BOX DRAWINGS HEAVY LEFT;So;0;ON;;;;;N;FORMS HEAVY LEFT;;;; +2579;BOX DRAWINGS HEAVY UP;So;0;ON;;;;;N;FORMS HEAVY UP;;;; +257A;BOX DRAWINGS HEAVY RIGHT;So;0;ON;;;;;N;FORMS HEAVY RIGHT;;;; +257B;BOX DRAWINGS HEAVY DOWN;So;0;ON;;;;;N;FORMS HEAVY DOWN;;;; +257C;BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT;So;0;ON;;;;;N;FORMS LIGHT LEFT AND HEAVY RIGHT;;;; +257D;BOX DRAWINGS LIGHT UP AND HEAVY DOWN;So;0;ON;;;;;N;FORMS LIGHT UP AND HEAVY DOWN;;;; +257E;BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT;So;0;ON;;;;;N;FORMS HEAVY LEFT AND LIGHT RIGHT;;;; +257F;BOX DRAWINGS HEAVY UP AND LIGHT DOWN;So;0;ON;;;;;N;FORMS HEAVY UP AND LIGHT DOWN;;;; +2580;UPPER HALF BLOCK;So;0;ON;;;;;N;;;;; +2581;LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2582;LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +2583;LOWER THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +2584;LOWER HALF BLOCK;So;0;ON;;;;;N;;;;; +2585;LOWER FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +2586;LOWER THREE QUARTERS BLOCK;So;0;ON;;;;;N;LOWER THREE QUARTER BLOCK;;;; +2587;LOWER SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +2588;FULL BLOCK;So;0;ON;;;;;N;;;;; +2589;LEFT SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +258A;LEFT THREE QUARTERS BLOCK;So;0;ON;;;;;N;LEFT THREE QUARTER BLOCK;;;; +258B;LEFT FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +258C;LEFT HALF BLOCK;So;0;ON;;;;;N;;;;; +258D;LEFT THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +258E;LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +258F;LEFT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2590;RIGHT HALF BLOCK;So;0;ON;;;;;N;;;;; +2591;LIGHT SHADE;So;0;ON;;;;;N;;;;; +2592;MEDIUM SHADE;So;0;ON;;;;;N;;;;; +2593;DARK SHADE;So;0;ON;;;;;N;;;;; +2594;UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2595;RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2596;QUADRANT LOWER LEFT;So;0;ON;;;;;N;;;;; +2597;QUADRANT LOWER RIGHT;So;0;ON;;;;;N;;;;; +2598;QUADRANT UPPER LEFT;So;0;ON;;;;;N;;;;; +2599;QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +259A;QUADRANT UPPER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +259B;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;; +259C;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +259D;QUADRANT UPPER RIGHT;So;0;ON;;;;;N;;;;; +259E;QUADRANT UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;; +259F;QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +25A0;BLACK SQUARE;So;0;ON;;;;;N;;;;; +25A1;WHITE SQUARE;So;0;ON;;;;;N;;;;; +25A2;WHITE SQUARE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;; +25A3;WHITE SQUARE CONTAINING BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;; +25A4;SQUARE WITH HORIZONTAL FILL;So;0;ON;;;;;N;;;;; +25A5;SQUARE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;; +25A6;SQUARE WITH ORTHOGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;; +25A7;SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL;So;0;ON;;;;;N;;;;; +25A8;SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL;So;0;ON;;;;;N;;;;; +25A9;SQUARE WITH DIAGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;; +25AA;BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;; +25AB;WHITE SMALL SQUARE;So;0;ON;;;;;N;;;;; +25AC;BLACK RECTANGLE;So;0;ON;;;;;N;;;;; +25AD;WHITE RECTANGLE;So;0;ON;;;;;N;;;;; +25AE;BLACK VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;; +25AF;WHITE VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;; +25B0;BLACK PARALLELOGRAM;So;0;ON;;;;;N;;;;; +25B1;WHITE PARALLELOGRAM;So;0;ON;;;;;N;;;;; +25B2;BLACK UP-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING TRIANGLE;;;; +25B3;WHITE UP-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE;;;; +25B4;BLACK UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING SMALL TRIANGLE;;;; +25B5;WHITE UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING SMALL TRIANGLE;;;; +25B6;BLACK RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING TRIANGLE;;;; +25B7;WHITE RIGHT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE RIGHT POINTING TRIANGLE;;;; +25B8;BLACK RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING SMALL TRIANGLE;;;; +25B9;WHITE RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE RIGHT POINTING SMALL TRIANGLE;;;; +25BA;BLACK RIGHT-POINTING POINTER;So;0;ON;;;;;N;BLACK RIGHT POINTING POINTER;;;; +25BB;WHITE RIGHT-POINTING POINTER;So;0;ON;;;;;N;WHITE RIGHT POINTING POINTER;;;; +25BC;BLACK DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING TRIANGLE;;;; +25BD;WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING TRIANGLE;;;; +25BE;BLACK DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING SMALL TRIANGLE;;;; +25BF;WHITE DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING SMALL TRIANGLE;;;; +25C0;BLACK LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING TRIANGLE;;;; +25C1;WHITE LEFT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE LEFT POINTING TRIANGLE;;;; +25C2;BLACK LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING SMALL TRIANGLE;;;; +25C3;WHITE LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE LEFT POINTING SMALL TRIANGLE;;;; +25C4;BLACK LEFT-POINTING POINTER;So;0;ON;;;;;N;BLACK LEFT POINTING POINTER;;;; +25C5;WHITE LEFT-POINTING POINTER;So;0;ON;;;;;N;WHITE LEFT POINTING POINTER;;;; +25C6;BLACK DIAMOND;So;0;ON;;;;;N;;;;; +25C7;WHITE DIAMOND;So;0;ON;;;;;N;;;;; +25C8;WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;; +25C9;FISHEYE;So;0;ON;;;;;N;;;;; +25CA;LOZENGE;So;0;ON;;;;;N;;;;; +25CB;WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25CC;DOTTED CIRCLE;So;0;ON;;;;;N;;;;; +25CD;CIRCLE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;; +25CE;BULLSEYE;So;0;ON;;;;;N;;;;; +25CF;BLACK CIRCLE;So;0;ON;;;;;N;;;;; +25D0;CIRCLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +25D1;CIRCLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; +25D2;CIRCLE WITH LOWER HALF BLACK;So;0;ON;;;;;N;;;;; +25D3;CIRCLE WITH UPPER HALF BLACK;So;0;ON;;;;;N;;;;; +25D4;CIRCLE WITH UPPER RIGHT QUADRANT BLACK;So;0;ON;;;;;N;;;;; +25D5;CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK;So;0;ON;;;;;N;;;;; +25D6;LEFT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +25D7;RIGHT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +25D8;INVERSE BULLET;So;0;ON;;;;;N;;;;; +25D9;INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25DA;UPPER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25DB;LOWER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25DC;UPPER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25DD;UPPER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25DE;LOWER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25DF;LOWER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25E0;UPPER HALF CIRCLE;So;0;ON;;;;;N;;;;; +25E1;LOWER HALF CIRCLE;So;0;ON;;;;;N;;;;; +25E2;BLACK LOWER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; +25E3;BLACK LOWER LEFT TRIANGLE;So;0;ON;;;;;N;;;;; +25E4;BLACK UPPER LEFT TRIANGLE;So;0;ON;;;;;N;;;;; +25E5;BLACK UPPER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; +25E6;WHITE BULLET;So;0;ON;;;;;N;;;;; +25E7;SQUARE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +25E8;SQUARE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; +25E9;SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +25EA;SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +25EB;WHITE SQUARE WITH VERTICAL BISECTING LINE;So;0;ON;;;;;N;;;;; +25EC;WHITE UP-POINTING TRIANGLE WITH DOT;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE WITH DOT;;;; +25ED;UP-POINTING TRIANGLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH LEFT HALF BLACK;;;; +25EE;UP-POINTING TRIANGLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH RIGHT HALF BLACK;;;; +25EF;LARGE CIRCLE;So;0;ON;;;;;N;;;;; +25F0;WHITE SQUARE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F1;WHITE SQUARE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F2;WHITE SQUARE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F3;WHITE SQUARE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F4;WHITE CIRCLE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F5;WHITE CIRCLE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F6;WHITE CIRCLE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F7;WHITE CIRCLE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F8;UPPER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;; +25F9;UPPER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;; +25FA;LOWER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;; +25FB;WHITE MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;; +25FC;BLACK MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;; +25FD;WHITE MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;; +25FE;BLACK MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;; +25FF;LOWER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;; +2600;BLACK SUN WITH RAYS;So;0;ON;;;;;N;;;;; +2601;CLOUD;So;0;ON;;;;;N;;;;; +2602;UMBRELLA;So;0;ON;;;;;N;;;;; +2603;SNOWMAN;So;0;ON;;;;;N;;;;; +2604;COMET;So;0;ON;;;;;N;;;;; +2605;BLACK STAR;So;0;ON;;;;;N;;;;; +2606;WHITE STAR;So;0;ON;;;;;N;;;;; +2607;LIGHTNING;So;0;ON;;;;;N;;;;; +2608;THUNDERSTORM;So;0;ON;;;;;N;;;;; +2609;SUN;So;0;ON;;;;;N;;;;; +260A;ASCENDING NODE;So;0;ON;;;;;N;;;;; +260B;DESCENDING NODE;So;0;ON;;;;;N;;;;; +260C;CONJUNCTION;So;0;ON;;;;;N;;;;; +260D;OPPOSITION;So;0;ON;;;;;N;;;;; +260E;BLACK TELEPHONE;So;0;ON;;;;;N;;;;; +260F;WHITE TELEPHONE;So;0;ON;;;;;N;;;;; +2610;BALLOT BOX;So;0;ON;;;;;N;;;;; +2611;BALLOT BOX WITH CHECK;So;0;ON;;;;;N;;;;; +2612;BALLOT BOX WITH X;So;0;ON;;;;;N;;;;; +2613;SALTIRE;So;0;ON;;;;;N;;;;; +2614;UMBRELLA WITH RAIN DROPS;So;0;ON;;;;;N;;;;; +2615;HOT BEVERAGE;So;0;ON;;;;;N;;;;; +2616;WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;; +2617;BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;; +2618;SHAMROCK;So;0;ON;;;;;N;;;;; +2619;REVERSED ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;; +261A;BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;; +261B;BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +261C;WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;; +261D;WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;; +261E;WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +261F;WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;; +2620;SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;; +2621;CAUTION SIGN;So;0;ON;;;;;N;;;;; +2622;RADIOACTIVE SIGN;So;0;ON;;;;;N;;;;; +2623;BIOHAZARD SIGN;So;0;ON;;;;;N;;;;; +2624;CADUCEUS;So;0;ON;;;;;N;;;;; +2625;ANKH;So;0;ON;;;;;N;;;;; +2626;ORTHODOX CROSS;So;0;ON;;;;;N;;;;; +2627;CHI RHO;So;0;ON;;;;;N;;;;; +2628;CROSS OF LORRAINE;So;0;ON;;;;;N;;;;; +2629;CROSS OF JERUSALEM;So;0;ON;;;;;N;;;;; +262A;STAR AND CRESCENT;So;0;ON;;;;;N;;;;; +262B;FARSI SYMBOL;So;0;ON;;;;;N;SYMBOL OF IRAN;;;; +262C;ADI SHAKTI;So;0;ON;;;;;N;;;;; +262D;HAMMER AND SICKLE;So;0;ON;;;;;N;;;;; +262E;PEACE SYMBOL;So;0;ON;;;;;N;;;;; +262F;YIN YANG;So;0;ON;;;;;N;;;;; +2630;TRIGRAM FOR HEAVEN;So;0;ON;;;;;N;;;;; +2631;TRIGRAM FOR LAKE;So;0;ON;;;;;N;;;;; +2632;TRIGRAM FOR FIRE;So;0;ON;;;;;N;;;;; +2633;TRIGRAM FOR THUNDER;So;0;ON;;;;;N;;;;; +2634;TRIGRAM FOR WIND;So;0;ON;;;;;N;;;;; +2635;TRIGRAM FOR WATER;So;0;ON;;;;;N;;;;; +2636;TRIGRAM FOR MOUNTAIN;So;0;ON;;;;;N;;;;; +2637;TRIGRAM FOR EARTH;So;0;ON;;;;;N;;;;; +2638;WHEEL OF DHARMA;So;0;ON;;;;;N;;;;; +2639;WHITE FROWNING FACE;So;0;ON;;;;;N;;;;; +263A;WHITE SMILING FACE;So;0;ON;;;;;N;;;;; +263B;BLACK SMILING FACE;So;0;ON;;;;;N;;;;; +263C;WHITE SUN WITH RAYS;So;0;ON;;;;;N;;;;; +263D;FIRST QUARTER MOON;So;0;ON;;;;;N;;;;; +263E;LAST QUARTER MOON;So;0;ON;;;;;N;;;;; +263F;MERCURY;So;0;ON;;;;;N;;;;; +2640;FEMALE SIGN;So;0;ON;;;;;N;;;;; +2641;EARTH;So;0;ON;;;;;N;;;;; +2642;MALE SIGN;So;0;ON;;;;;N;;;;; +2643;JUPITER;So;0;ON;;;;;N;;;;; +2644;SATURN;So;0;ON;;;;;N;;;;; +2645;URANUS;So;0;ON;;;;;N;;;;; +2646;NEPTUNE;So;0;ON;;;;;N;;;;; +2647;PLUTO;So;0;ON;;;;;N;;;;; +2648;ARIES;So;0;ON;;;;;N;;;;; +2649;TAURUS;So;0;ON;;;;;N;;;;; +264A;GEMINI;So;0;ON;;;;;N;;;;; +264B;CANCER;So;0;ON;;;;;N;;;;; +264C;LEO;So;0;ON;;;;;N;;;;; +264D;VIRGO;So;0;ON;;;;;N;;;;; +264E;LIBRA;So;0;ON;;;;;N;;;;; +264F;SCORPIUS;So;0;ON;;;;;N;;;;; +2650;SAGITTARIUS;So;0;ON;;;;;N;;;;; +2651;CAPRICORN;So;0;ON;;;;;N;;;;; +2652;AQUARIUS;So;0;ON;;;;;N;;;;; +2653;PISCES;So;0;ON;;;;;N;;;;; +2654;WHITE CHESS KING;So;0;ON;;;;;N;;;;; +2655;WHITE CHESS QUEEN;So;0;ON;;;;;N;;;;; +2656;WHITE CHESS ROOK;So;0;ON;;;;;N;;;;; +2657;WHITE CHESS BISHOP;So;0;ON;;;;;N;;;;; +2658;WHITE CHESS KNIGHT;So;0;ON;;;;;N;;;;; +2659;WHITE CHESS PAWN;So;0;ON;;;;;N;;;;; +265A;BLACK CHESS KING;So;0;ON;;;;;N;;;;; +265B;BLACK CHESS QUEEN;So;0;ON;;;;;N;;;;; +265C;BLACK CHESS ROOK;So;0;ON;;;;;N;;;;; +265D;BLACK CHESS BISHOP;So;0;ON;;;;;N;;;;; +265E;BLACK CHESS KNIGHT;So;0;ON;;;;;N;;;;; +265F;BLACK CHESS PAWN;So;0;ON;;;;;N;;;;; +2660;BLACK SPADE SUIT;So;0;ON;;;;;N;;;;; +2661;WHITE HEART SUIT;So;0;ON;;;;;N;;;;; +2662;WHITE DIAMOND SUIT;So;0;ON;;;;;N;;;;; +2663;BLACK CLUB SUIT;So;0;ON;;;;;N;;;;; +2664;WHITE SPADE SUIT;So;0;ON;;;;;N;;;;; +2665;BLACK HEART SUIT;So;0;ON;;;;;N;;;;; +2666;BLACK DIAMOND SUIT;So;0;ON;;;;;N;;;;; +2667;WHITE CLUB SUIT;So;0;ON;;;;;N;;;;; +2668;HOT SPRINGS;So;0;ON;;;;;N;;;;; +2669;QUARTER NOTE;So;0;ON;;;;;N;;;;; +266A;EIGHTH NOTE;So;0;ON;;;;;N;;;;; +266B;BEAMED EIGHTH NOTES;So;0;ON;;;;;N;BARRED EIGHTH NOTES;;;; +266C;BEAMED SIXTEENTH NOTES;So;0;ON;;;;;N;BARRED SIXTEENTH NOTES;;;; +266D;MUSIC FLAT SIGN;So;0;ON;;;;;N;FLAT;;;; +266E;MUSIC NATURAL SIGN;So;0;ON;;;;;N;NATURAL;;;; +266F;MUSIC SHARP SIGN;Sm;0;ON;;;;;N;SHARP;;;; +2670;WEST SYRIAC CROSS;So;0;ON;;;;;N;;;;; +2671;EAST SYRIAC CROSS;So;0;ON;;;;;N;;;;; +2672;UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;; +2673;RECYCLING SYMBOL FOR TYPE-1 PLASTICS;So;0;ON;;;;;N;;;;; +2674;RECYCLING SYMBOL FOR TYPE-2 PLASTICS;So;0;ON;;;;;N;;;;; +2675;RECYCLING SYMBOL FOR TYPE-3 PLASTICS;So;0;ON;;;;;N;;;;; +2676;RECYCLING SYMBOL FOR TYPE-4 PLASTICS;So;0;ON;;;;;N;;;;; +2677;RECYCLING SYMBOL FOR TYPE-5 PLASTICS;So;0;ON;;;;;N;;;;; +2678;RECYCLING SYMBOL FOR TYPE-6 PLASTICS;So;0;ON;;;;;N;;;;; +2679;RECYCLING SYMBOL FOR TYPE-7 PLASTICS;So;0;ON;;;;;N;;;;; +267A;RECYCLING SYMBOL FOR GENERIC MATERIALS;So;0;ON;;;;;N;;;;; +267B;BLACK UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;; +267C;RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;; +267D;PARTIALLY-RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;; +267E;PERMANENT PAPER SIGN;So;0;ON;;;;;N;;;;; +267F;WHEELCHAIR SYMBOL;So;0;ON;;;;;N;;;;; +2680;DIE FACE-1;So;0;ON;;;;;N;;;;; +2681;DIE FACE-2;So;0;ON;;;;;N;;;;; +2682;DIE FACE-3;So;0;ON;;;;;N;;;;; +2683;DIE FACE-4;So;0;ON;;;;;N;;;;; +2684;DIE FACE-5;So;0;ON;;;;;N;;;;; +2685;DIE FACE-6;So;0;ON;;;;;N;;;;; +2686;WHITE CIRCLE WITH DOT RIGHT;So;0;ON;;;;;N;;;;; +2687;WHITE CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;; +2688;BLACK CIRCLE WITH WHITE DOT RIGHT;So;0;ON;;;;;N;;;;; +2689;BLACK CIRCLE WITH TWO WHITE DOTS;So;0;ON;;;;;N;;;;; +268A;MONOGRAM FOR YANG;So;0;ON;;;;;N;;;;; +268B;MONOGRAM FOR YIN;So;0;ON;;;;;N;;;;; +268C;DIGRAM FOR GREATER YANG;So;0;ON;;;;;N;;;;; +268D;DIGRAM FOR LESSER YIN;So;0;ON;;;;;N;;;;; +268E;DIGRAM FOR LESSER YANG;So;0;ON;;;;;N;;;;; +268F;DIGRAM FOR GREATER YIN;So;0;ON;;;;;N;;;;; +2690;WHITE FLAG;So;0;ON;;;;;N;;;;; +2691;BLACK FLAG;So;0;ON;;;;;N;;;;; +2692;HAMMER AND PICK;So;0;ON;;;;;N;;;;; +2693;ANCHOR;So;0;ON;;;;;N;;;;; +2694;CROSSED SWORDS;So;0;ON;;;;;N;;;;; +2695;STAFF OF AESCULAPIUS;So;0;ON;;;;;N;;;;; +2696;SCALES;So;0;ON;;;;;N;;;;; +2697;ALEMBIC;So;0;ON;;;;;N;;;;; +2698;FLOWER;So;0;ON;;;;;N;;;;; +2699;GEAR;So;0;ON;;;;;N;;;;; +269A;STAFF OF HERMES;So;0;ON;;;;;N;;;;; +269B;ATOM SYMBOL;So;0;ON;;;;;N;;;;; +269C;FLEUR-DE-LIS;So;0;ON;;;;;N;;;;; +269D;OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;; +269E;THREE LINES CONVERGING RIGHT;So;0;ON;;;;;N;;;;; +269F;THREE LINES CONVERGING LEFT;So;0;ON;;;;;N;;;;; +26A0;WARNING SIGN;So;0;ON;;;;;N;;;;; +26A1;HIGH VOLTAGE SIGN;So;0;ON;;;;;N;;;;; +26A2;DOUBLED FEMALE SIGN;So;0;ON;;;;;N;;;;; +26A3;DOUBLED MALE SIGN;So;0;ON;;;;;N;;;;; +26A4;INTERLOCKED FEMALE AND MALE SIGN;So;0;ON;;;;;N;;;;; +26A5;MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;; +26A6;MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;; +26A7;MALE WITH STROKE AND MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;; +26A8;VERTICAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;; +26A9;HORIZONTAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;; +26AA;MEDIUM WHITE CIRCLE;So;0;ON;;;;;N;;;;; +26AB;MEDIUM BLACK CIRCLE;So;0;ON;;;;;N;;;;; +26AC;MEDIUM SMALL WHITE CIRCLE;So;0;L;;;;;N;;;;; +26AD;MARRIAGE SYMBOL;So;0;ON;;;;;N;;;;; +26AE;DIVORCE SYMBOL;So;0;ON;;;;;N;;;;; +26AF;UNMARRIED PARTNERSHIP SYMBOL;So;0;ON;;;;;N;;;;; +26B0;COFFIN;So;0;ON;;;;;N;;;;; +26B1;FUNERAL URN;So;0;ON;;;;;N;;;;; +26B2;NEUTER;So;0;ON;;;;;N;;;;; +26B3;CERES;So;0;ON;;;;;N;;;;; +26B4;PALLAS;So;0;ON;;;;;N;;;;; +26B5;JUNO;So;0;ON;;;;;N;;;;; +26B6;VESTA;So;0;ON;;;;;N;;;;; +26B7;CHIRON;So;0;ON;;;;;N;;;;; +26B8;BLACK MOON LILITH;So;0;ON;;;;;N;;;;; +26B9;SEXTILE;So;0;ON;;;;;N;;;;; +26BA;SEMISEXTILE;So;0;ON;;;;;N;;;;; +26BB;QUINCUNX;So;0;ON;;;;;N;;;;; +26BC;SESQUIQUADRATE;So;0;ON;;;;;N;;;;; +26BD;SOCCER BALL;So;0;ON;;;;;N;;;;; +26BE;BASEBALL;So;0;ON;;;;;N;;;;; +26BF;SQUARED KEY;So;0;ON;;;;;N;;;;; +26C0;WHITE DRAUGHTS MAN;So;0;ON;;;;;N;;;;; +26C1;WHITE DRAUGHTS KING;So;0;ON;;;;;N;;;;; +26C2;BLACK DRAUGHTS MAN;So;0;ON;;;;;N;;;;; +26C3;BLACK DRAUGHTS KING;So;0;ON;;;;;N;;;;; +26C4;SNOWMAN WITHOUT SNOW;So;0;ON;;;;;N;;;;; +26C5;SUN BEHIND CLOUD;So;0;ON;;;;;N;;;;; +26C6;RAIN;So;0;ON;;;;;N;;;;; +26C7;BLACK SNOWMAN;So;0;ON;;;;;N;;;;; +26C8;THUNDER CLOUD AND RAIN;So;0;ON;;;;;N;;;;; +26C9;TURNED WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;; +26CA;TURNED BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;; +26CB;WHITE DIAMOND IN SQUARE;So;0;ON;;;;;N;;;;; +26CC;CROSSING LANES;So;0;ON;;;;;N;;;;; +26CD;DISABLED CAR;So;0;ON;;;;;N;;;;; +26CF;PICK;So;0;ON;;;;;N;;;;; +26D0;CAR SLIDING;So;0;ON;;;;;N;;;;; +26D1;HELMET WITH WHITE CROSS;So;0;ON;;;;;N;;;;; +26D2;CIRCLED CROSSING LANES;So;0;ON;;;;;N;;;;; +26D3;CHAINS;So;0;ON;;;;;N;;;;; +26D4;NO ENTRY;So;0;ON;;;;;N;;;;; +26D5;ALTERNATE ONE-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;; +26D6;BLACK TWO-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;; +26D7;WHITE TWO-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;; +26D8;BLACK LEFT LANE MERGE;So;0;ON;;;;;N;;;;; +26D9;WHITE LEFT LANE MERGE;So;0;ON;;;;;N;;;;; +26DA;DRIVE SLOW SIGN;So;0;ON;;;;;N;;;;; +26DB;HEAVY WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;;;;; +26DC;LEFT CLOSED ENTRY;So;0;ON;;;;;N;;;;; +26DD;SQUARED SALTIRE;So;0;ON;;;;;N;;;;; +26DE;FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE;So;0;ON;;;;;N;;;;; +26DF;BLACK TRUCK;So;0;ON;;;;;N;;;;; +26E0;RESTRICTED LEFT ENTRY-1;So;0;ON;;;;;N;;;;; +26E1;RESTRICTED LEFT ENTRY-2;So;0;ON;;;;;N;;;;; +26E3;HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE;So;0;ON;;;;;N;;;;; +26E8;BLACK CROSS ON SHIELD;So;0;ON;;;;;N;;;;; +26E9;SHINTO SHRINE;So;0;ON;;;;;N;;;;; +26EA;CHURCH;So;0;ON;;;;;N;;;;; +26EB;CASTLE;So;0;ON;;;;;N;;;;; +26EC;HISTORIC SITE;So;0;ON;;;;;N;;;;; +26ED;GEAR WITHOUT HUB;So;0;ON;;;;;N;;;;; +26EE;GEAR WITH HANDLES;So;0;ON;;;;;N;;;;; +26EF;MAP SYMBOL FOR LIGHTHOUSE;So;0;ON;;;;;N;;;;; +26F0;MOUNTAIN;So;0;ON;;;;;N;;;;; +26F1;UMBRELLA ON GROUND;So;0;ON;;;;;N;;;;; +26F2;FOUNTAIN;So;0;ON;;;;;N;;;;; +26F3;FLAG IN HOLE;So;0;ON;;;;;N;;;;; +26F4;FERRY;So;0;ON;;;;;N;;;;; +26F5;SAILBOAT;So;0;ON;;;;;N;;;;; +26F6;SQUARE FOUR CORNERS;So;0;ON;;;;;N;;;;; +26F7;SKIER;So;0;ON;;;;;N;;;;; +26F8;ICE SKATE;So;0;ON;;;;;N;;;;; +26F9;PERSON WITH BALL;So;0;ON;;;;;N;;;;; +26FA;TENT;So;0;ON;;;;;N;;;;; +26FB;JAPANESE BANK SYMBOL;So;0;ON;;;;;N;;;;; +26FC;HEADSTONE GRAVEYARD SYMBOL;So;0;ON;;;;;N;;;;; +26FD;FUEL PUMP;So;0;ON;;;;;N;;;;; +26FE;CUP ON BLACK SQUARE;So;0;ON;;;;;N;;;;; +26FF;WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE;So;0;ON;;;;;N;;;;; +2701;UPPER BLADE SCISSORS;So;0;ON;;;;;N;;;;; +2702;BLACK SCISSORS;So;0;ON;;;;;N;;;;; +2703;LOWER BLADE SCISSORS;So;0;ON;;;;;N;;;;; +2704;WHITE SCISSORS;So;0;ON;;;;;N;;;;; +2706;TELEPHONE LOCATION SIGN;So;0;ON;;;;;N;;;;; +2707;TAPE DRIVE;So;0;ON;;;;;N;;;;; +2708;AIRPLANE;So;0;ON;;;;;N;;;;; +2709;ENVELOPE;So;0;ON;;;;;N;;;;; +270C;VICTORY HAND;So;0;ON;;;;;N;;;;; +270D;WRITING HAND;So;0;ON;;;;;N;;;;; +270E;LOWER RIGHT PENCIL;So;0;ON;;;;;N;;;;; +270F;PENCIL;So;0;ON;;;;;N;;;;; +2710;UPPER RIGHT PENCIL;So;0;ON;;;;;N;;;;; +2711;WHITE NIB;So;0;ON;;;;;N;;;;; +2712;BLACK NIB;So;0;ON;;;;;N;;;;; +2713;CHECK MARK;So;0;ON;;;;;N;;;;; +2714;HEAVY CHECK MARK;So;0;ON;;;;;N;;;;; +2715;MULTIPLICATION X;So;0;ON;;;;;N;;;;; +2716;HEAVY MULTIPLICATION X;So;0;ON;;;;;N;;;;; +2717;BALLOT X;So;0;ON;;;;;N;;;;; +2718;HEAVY BALLOT X;So;0;ON;;;;;N;;;;; +2719;OUTLINED GREEK CROSS;So;0;ON;;;;;N;;;;; +271A;HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;; +271B;OPEN CENTRE CROSS;So;0;ON;;;;;N;OPEN CENTER CROSS;;;; +271C;HEAVY OPEN CENTRE CROSS;So;0;ON;;;;;N;HEAVY OPEN CENTER CROSS;;;; +271D;LATIN CROSS;So;0;ON;;;;;N;;;;; +271E;SHADOWED WHITE LATIN CROSS;So;0;ON;;;;;N;;;;; +271F;OUTLINED LATIN CROSS;So;0;ON;;;;;N;;;;; +2720;MALTESE CROSS;So;0;ON;;;;;N;;;;; +2721;STAR OF DAVID;So;0;ON;;;;;N;;;;; +2722;FOUR TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2723;FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2724;HEAVY FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2725;FOUR CLUB-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2726;BLACK FOUR POINTED STAR;So;0;ON;;;;;N;;;;; +2727;WHITE FOUR POINTED STAR;So;0;ON;;;;;N;;;;; +2729;STRESS OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;; +272A;CIRCLED WHITE STAR;So;0;ON;;;;;N;;;;; +272B;OPEN CENTRE BLACK STAR;So;0;ON;;;;;N;OPEN CENTER BLACK STAR;;;; +272C;BLACK CENTRE WHITE STAR;So;0;ON;;;;;N;BLACK CENTER WHITE STAR;;;; +272D;OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;; +272E;HEAVY OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;; +272F;PINWHEEL STAR;So;0;ON;;;;;N;;;;; +2730;SHADOWED WHITE STAR;So;0;ON;;;;;N;;;;; +2731;HEAVY ASTERISK;So;0;ON;;;;;N;;;;; +2732;OPEN CENTRE ASTERISK;So;0;ON;;;;;N;OPEN CENTER ASTERISK;;;; +2733;EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2734;EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +2735;EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;; +2736;SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +2737;EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;; +2738;HEAVY EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;; +2739;TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +273A;SIXTEEN POINTED ASTERISK;So;0;ON;;;;;N;;;;; +273B;TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +273C;OPEN CENTRE TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;OPEN CENTER TEARDROP-SPOKED ASTERISK;;;; +273D;HEAVY TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +273E;SIX PETALLED BLACK AND WHITE FLORETTE;So;0;ON;;;;;N;;;;; +273F;BLACK FLORETTE;So;0;ON;;;;;N;;;;; +2740;WHITE FLORETTE;So;0;ON;;;;;N;;;;; +2741;EIGHT PETALLED OUTLINED BLACK FLORETTE;So;0;ON;;;;;N;;;;; +2742;CIRCLED OPEN CENTRE EIGHT POINTED STAR;So;0;ON;;;;;N;CIRCLED OPEN CENTER EIGHT POINTED STAR;;;; +2743;HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK;So;0;ON;;;;;N;;;;; +2744;SNOWFLAKE;So;0;ON;;;;;N;;;;; +2745;TIGHT TRIFOLIATE SNOWFLAKE;So;0;ON;;;;;N;;;;; +2746;HEAVY CHEVRON SNOWFLAKE;So;0;ON;;;;;N;;;;; +2747;SPARKLE;So;0;ON;;;;;N;;;;; +2748;HEAVY SPARKLE;So;0;ON;;;;;N;;;;; +2749;BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +274A;EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;; +274B;HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;; +274D;SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;; +274F;LOWER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2750;UPPER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2751;LOWER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2752;UPPER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2756;BLACK DIAMOND MINUS WHITE X;So;0;ON;;;;;N;;;;; +2757;HEAVY EXCLAMATION MARK SYMBOL;So;0;ON;;;;;N;;;;; +2758;LIGHT VERTICAL BAR;So;0;ON;;;;;N;;;;; +2759;MEDIUM VERTICAL BAR;So;0;ON;;;;;N;;;;; +275A;HEAVY VERTICAL BAR;So;0;ON;;;;;N;;;;; +275B;HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275C;HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275D;HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275E;HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2761;CURVED STEM PARAGRAPH SIGN ORNAMENT;So;0;ON;;;;;N;;;;; +2762;HEAVY EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2763;HEAVY HEART EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2764;HEAVY BLACK HEART;So;0;ON;;;;;N;;;;; +2765;ROTATED HEAVY BLACK HEART BULLET;So;0;ON;;;;;N;;;;; +2766;FLORAL HEART;So;0;ON;;;;;N;;;;; +2767;ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;; +2768;MEDIUM LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2769;MEDIUM RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;; +276A;MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;; +276B;MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;; +276C;MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +276D;MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +276E;HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT;Ps;0;ON;;;;;Y;;;;; +276F;HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2770;HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2771;HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2772;LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2773;LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2774;MEDIUM LEFT CURLY BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2775;MEDIUM RIGHT CURLY BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2776;DINGBAT NEGATIVE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED DIGIT ONE;;;; +2777;DINGBAT NEGATIVE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED DIGIT TWO;;;; +2778;DINGBAT NEGATIVE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED DIGIT THREE;;;; +2779;DINGBAT NEGATIVE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED DIGIT FOUR;;;; +277A;DINGBAT NEGATIVE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED DIGIT FIVE;;;; +277B;DINGBAT NEGATIVE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED DIGIT SIX;;;; +277C;DINGBAT NEGATIVE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED DIGIT SEVEN;;;; +277D;DINGBAT NEGATIVE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED DIGIT EIGHT;;;; +277E;DINGBAT NEGATIVE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED DIGIT NINE;;;; +277F;DINGBAT NEGATIVE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED NUMBER TEN;;;; +2780;DINGBAT CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;CIRCLED SANS-SERIF DIGIT ONE;;;; +2781;DINGBAT CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;CIRCLED SANS-SERIF DIGIT TWO;;;; +2782;DINGBAT CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;CIRCLED SANS-SERIF DIGIT THREE;;;; +2783;DINGBAT CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;CIRCLED SANS-SERIF DIGIT FOUR;;;; +2784;DINGBAT CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;CIRCLED SANS-SERIF DIGIT FIVE;;;; +2785;DINGBAT CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;CIRCLED SANS-SERIF DIGIT SIX;;;; +2786;DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;CIRCLED SANS-SERIF DIGIT SEVEN;;;; +2787;DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;CIRCLED SANS-SERIF DIGIT EIGHT;;;; +2788;DINGBAT CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;CIRCLED SANS-SERIF DIGIT NINE;;;; +2789;DINGBAT CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;CIRCLED SANS-SERIF NUMBER TEN;;;; +278A;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED SANS-SERIF DIGIT ONE;;;; +278B;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED SANS-SERIF DIGIT TWO;;;; +278C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED SANS-SERIF DIGIT THREE;;;; +278D;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED SANS-SERIF DIGIT FOUR;;;; +278E;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED SANS-SERIF DIGIT FIVE;;;; +278F;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED SANS-SERIF DIGIT SIX;;;; +2790;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED SANS-SERIF DIGIT SEVEN;;;; +2791;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED SANS-SERIF DIGIT EIGHT;;;; +2792;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED SANS-SERIF DIGIT NINE;;;; +2793;DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED SANS-SERIF NUMBER TEN;;;; +2794;HEAVY WIDE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WIDE-HEADED RIGHT ARROW;;;; +2798;HEAVY SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT ARROW;;;; +2799;HEAVY RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY RIGHT ARROW;;;; +279A;HEAVY NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT ARROW;;;; +279B;DRAFTING POINT RIGHTWARDS ARROW;So;0;ON;;;;;N;DRAFTING POINT RIGHT ARROW;;;; +279C;HEAVY ROUND-TIPPED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY ROUND-TIPPED RIGHT ARROW;;;; +279D;TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;TRIANGLE-HEADED RIGHT ARROW;;;; +279E;HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TRIANGLE-HEADED RIGHT ARROW;;;; +279F;DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;DASHED TRIANGLE-HEADED RIGHT ARROW;;;; +27A0;HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY DASHED TRIANGLE-HEADED RIGHT ARROW;;;; +27A1;BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK RIGHT ARROW;;;; +27A2;THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D TOP-LIGHTED RIGHT ARROWHEAD;;;; +27A3;THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D BOTTOM-LIGHTED RIGHT ARROWHEAD;;;; +27A4;BLACK RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;BLACK RIGHT ARROWHEAD;;;; +27A5;HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED DOWN AND RIGHT ARROW;;;; +27A6;HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED UP AND RIGHT ARROW;;;; +27A7;SQUAT BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;SQUAT BLACK RIGHT ARROW;;;; +27A8;HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY CONCAVE-POINTED BLACK RIGHT ARROW;;;; +27A9;RIGHT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;RIGHT-SHADED WHITE RIGHT ARROW;;;; +27AA;LEFT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT-SHADED WHITE RIGHT ARROW;;;; +27AB;BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;BACK-TILTED SHADOWED WHITE RIGHT ARROW;;;; +27AC;FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;FRONT-TILTED SHADOWED WHITE RIGHT ARROW;;;; +27AD;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27AE;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27AF;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27B1;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27B2;CIRCLED HEAVY WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;CIRCLED HEAVY WHITE RIGHT ARROW;;;; +27B3;WHITE-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;WHITE-FEATHERED RIGHT ARROW;;;; +27B4;BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED LOWER RIGHT ARROW;;;; +27B5;BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK-FEATHERED RIGHT ARROW;;;; +27B6;BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED UPPER RIGHT ARROW;;;; +27B7;HEAVY BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED LOWER RIGHT ARROW;;;; +27B8;HEAVY BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED RIGHT ARROW;;;; +27B9;HEAVY BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED UPPER RIGHT ARROW;;;; +27BA;TEARDROP-BARBED RIGHTWARDS ARROW;So;0;ON;;;;;N;TEARDROP-BARBED RIGHT ARROW;;;; +27BB;HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TEARDROP-SHANKED RIGHT ARROW;;;; +27BC;WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;WEDGE-TAILED RIGHT ARROW;;;; +27BD;HEAVY WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WEDGE-TAILED RIGHT ARROW;;;; +27BE;OPEN-OUTLINED RIGHTWARDS ARROW;So;0;ON;;;;;N;OPEN-OUTLINED RIGHT ARROW;;;; +27C0;THREE DIMENSIONAL ANGLE;Sm;0;ON;;;;;Y;;;;; +27C1;WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE;Sm;0;ON;;;;;N;;;;; +27C2;PERPENDICULAR;Sm;0;ON;;;;;N;;;;; +27C3;OPEN SUBSET;Sm;0;ON;;;;;Y;;;;; +27C4;OPEN SUPERSET;Sm;0;ON;;;;;Y;;;;; +27C5;LEFT S-SHAPED BAG DELIMITER;Ps;0;ON;;;;;Y;;;;; +27C6;RIGHT S-SHAPED BAG DELIMITER;Pe;0;ON;;;;;Y;;;;; +27C7;OR WITH DOT INSIDE;Sm;0;ON;;;;;N;;;;; +27C8;REVERSE SOLIDUS PRECEDING SUBSET;Sm;0;ON;;;;;Y;;;;; +27C9;SUPERSET PRECEDING SOLIDUS;Sm;0;ON;;;;;Y;;;;; +27CA;VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +27CC;LONG DIVISION;Sm;0;ON;;;;;Y;;;;; +27D0;WHITE DIAMOND WITH CENTRED DOT;Sm;0;ON;;;;;N;;;;; +27D1;AND WITH DOT;Sm;0;ON;;;;;N;;;;; +27D2;ELEMENT OF OPENING UPWARDS;Sm;0;ON;;;;;N;;;;; +27D3;LOWER RIGHT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;; +27D4;UPPER LEFT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;; +27D5;LEFT OUTER JOIN;Sm;0;ON;;;;;Y;;;;; +27D6;RIGHT OUTER JOIN;Sm;0;ON;;;;;Y;;;;; +27D7;FULL OUTER JOIN;Sm;0;ON;;;;;N;;;;; +27D8;LARGE UP TACK;Sm;0;ON;;;;;N;;;;; +27D9;LARGE DOWN TACK;Sm;0;ON;;;;;N;;;;; +27DA;LEFT AND RIGHT DOUBLE TURNSTILE;Sm;0;ON;;;;;N;;;;; +27DB;LEFT AND RIGHT TACK;Sm;0;ON;;;;;N;;;;; +27DC;LEFT MULTIMAP;Sm;0;ON;;;;;Y;;;;; +27DD;LONG RIGHT TACK;Sm;0;ON;;;;;Y;;;;; +27DE;LONG LEFT TACK;Sm;0;ON;;;;;Y;;;;; +27DF;UP TACK WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +27E0;LOZENGE DIVIDED BY HORIZONTAL RULE;Sm;0;ON;;;;;N;;;;; +27E1;WHITE CONCAVE-SIDED DIAMOND;Sm;0;ON;;;;;N;;;;; +27E2;WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E3;WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E4;WHITE SQUARE WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E5;WHITE SQUARE WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E6;MATHEMATICAL LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;;;;; +27E7;MATHEMATICAL RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;;;;; +27E8;MATHEMATICAL LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; +27E9;MATHEMATICAL RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; +27EA;MATHEMATICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; +27EB;MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; +27EC;MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;; +27ED;MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;; +27EE;MATHEMATICAL LEFT FLATTENED PARENTHESIS;Ps;0;ON;;;;;Y;;;;; +27EF;MATHEMATICAL RIGHT FLATTENED PARENTHESIS;Pe;0;ON;;;;;Y;;;;; +27F0;UPWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;; +27F1;DOWNWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;; +27F2;ANTICLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +27F3;CLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +27F4;RIGHT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; +27F5;LONG LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +27F6;LONG RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +27F7;LONG LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;; +27F8;LONG LEFTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +27F9;LONG RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +27FA;LONG LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +27FB;LONG LEFTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FC;LONG RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FD;LONG LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FE;LONG RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FF;LONG RIGHTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;; +2800;BRAILLE PATTERN BLANK;So;0;L;;;;;N;;;;; +2801;BRAILLE PATTERN DOTS-1;So;0;L;;;;;N;;;;; +2802;BRAILLE PATTERN DOTS-2;So;0;L;;;;;N;;;;; +2803;BRAILLE PATTERN DOTS-12;So;0;L;;;;;N;;;;; +2804;BRAILLE PATTERN DOTS-3;So;0;L;;;;;N;;;;; +2805;BRAILLE PATTERN DOTS-13;So;0;L;;;;;N;;;;; +2806;BRAILLE PATTERN DOTS-23;So;0;L;;;;;N;;;;; +2807;BRAILLE PATTERN DOTS-123;So;0;L;;;;;N;;;;; +2808;BRAILLE PATTERN DOTS-4;So;0;L;;;;;N;;;;; +2809;BRAILLE PATTERN DOTS-14;So;0;L;;;;;N;;;;; +280A;BRAILLE PATTERN DOTS-24;So;0;L;;;;;N;;;;; +280B;BRAILLE PATTERN DOTS-124;So;0;L;;;;;N;;;;; +280C;BRAILLE PATTERN DOTS-34;So;0;L;;;;;N;;;;; +280D;BRAILLE PATTERN DOTS-134;So;0;L;;;;;N;;;;; +280E;BRAILLE PATTERN DOTS-234;So;0;L;;;;;N;;;;; +280F;BRAILLE PATTERN DOTS-1234;So;0;L;;;;;N;;;;; +2810;BRAILLE PATTERN DOTS-5;So;0;L;;;;;N;;;;; +2811;BRAILLE PATTERN DOTS-15;So;0;L;;;;;N;;;;; +2812;BRAILLE PATTERN DOTS-25;So;0;L;;;;;N;;;;; +2813;BRAILLE PATTERN DOTS-125;So;0;L;;;;;N;;;;; +2814;BRAILLE PATTERN DOTS-35;So;0;L;;;;;N;;;;; +2815;BRAILLE PATTERN DOTS-135;So;0;L;;;;;N;;;;; +2816;BRAILLE PATTERN DOTS-235;So;0;L;;;;;N;;;;; +2817;BRAILLE PATTERN DOTS-1235;So;0;L;;;;;N;;;;; +2818;BRAILLE PATTERN DOTS-45;So;0;L;;;;;N;;;;; +2819;BRAILLE PATTERN DOTS-145;So;0;L;;;;;N;;;;; +281A;BRAILLE PATTERN DOTS-245;So;0;L;;;;;N;;;;; +281B;BRAILLE PATTERN DOTS-1245;So;0;L;;;;;N;;;;; +281C;BRAILLE PATTERN DOTS-345;So;0;L;;;;;N;;;;; +281D;BRAILLE PATTERN DOTS-1345;So;0;L;;;;;N;;;;; +281E;BRAILLE PATTERN DOTS-2345;So;0;L;;;;;N;;;;; +281F;BRAILLE PATTERN DOTS-12345;So;0;L;;;;;N;;;;; +2820;BRAILLE PATTERN DOTS-6;So;0;L;;;;;N;;;;; +2821;BRAILLE PATTERN DOTS-16;So;0;L;;;;;N;;;;; +2822;BRAILLE PATTERN DOTS-26;So;0;L;;;;;N;;;;; +2823;BRAILLE PATTERN DOTS-126;So;0;L;;;;;N;;;;; +2824;BRAILLE PATTERN DOTS-36;So;0;L;;;;;N;;;;; +2825;BRAILLE PATTERN DOTS-136;So;0;L;;;;;N;;;;; +2826;BRAILLE PATTERN DOTS-236;So;0;L;;;;;N;;;;; +2827;BRAILLE PATTERN DOTS-1236;So;0;L;;;;;N;;;;; +2828;BRAILLE PATTERN DOTS-46;So;0;L;;;;;N;;;;; +2829;BRAILLE PATTERN DOTS-146;So;0;L;;;;;N;;;;; +282A;BRAILLE PATTERN DOTS-246;So;0;L;;;;;N;;;;; +282B;BRAILLE PATTERN DOTS-1246;So;0;L;;;;;N;;;;; +282C;BRAILLE PATTERN DOTS-346;So;0;L;;;;;N;;;;; +282D;BRAILLE PATTERN DOTS-1346;So;0;L;;;;;N;;;;; +282E;BRAILLE PATTERN DOTS-2346;So;0;L;;;;;N;;;;; +282F;BRAILLE PATTERN DOTS-12346;So;0;L;;;;;N;;;;; +2830;BRAILLE PATTERN DOTS-56;So;0;L;;;;;N;;;;; +2831;BRAILLE PATTERN DOTS-156;So;0;L;;;;;N;;;;; +2832;BRAILLE PATTERN DOTS-256;So;0;L;;;;;N;;;;; +2833;BRAILLE PATTERN DOTS-1256;So;0;L;;;;;N;;;;; +2834;BRAILLE PATTERN DOTS-356;So;0;L;;;;;N;;;;; +2835;BRAILLE PATTERN DOTS-1356;So;0;L;;;;;N;;;;; +2836;BRAILLE PATTERN DOTS-2356;So;0;L;;;;;N;;;;; +2837;BRAILLE PATTERN DOTS-12356;So;0;L;;;;;N;;;;; +2838;BRAILLE PATTERN DOTS-456;So;0;L;;;;;N;;;;; +2839;BRAILLE PATTERN DOTS-1456;So;0;L;;;;;N;;;;; +283A;BRAILLE PATTERN DOTS-2456;So;0;L;;;;;N;;;;; +283B;BRAILLE PATTERN DOTS-12456;So;0;L;;;;;N;;;;; +283C;BRAILLE PATTERN DOTS-3456;So;0;L;;;;;N;;;;; +283D;BRAILLE PATTERN DOTS-13456;So;0;L;;;;;N;;;;; +283E;BRAILLE PATTERN DOTS-23456;So;0;L;;;;;N;;;;; +283F;BRAILLE PATTERN DOTS-123456;So;0;L;;;;;N;;;;; +2840;BRAILLE PATTERN DOTS-7;So;0;L;;;;;N;;;;; +2841;BRAILLE PATTERN DOTS-17;So;0;L;;;;;N;;;;; +2842;BRAILLE PATTERN DOTS-27;So;0;L;;;;;N;;;;; +2843;BRAILLE PATTERN DOTS-127;So;0;L;;;;;N;;;;; +2844;BRAILLE PATTERN DOTS-37;So;0;L;;;;;N;;;;; +2845;BRAILLE PATTERN DOTS-137;So;0;L;;;;;N;;;;; +2846;BRAILLE PATTERN DOTS-237;So;0;L;;;;;N;;;;; +2847;BRAILLE PATTERN DOTS-1237;So;0;L;;;;;N;;;;; +2848;BRAILLE PATTERN DOTS-47;So;0;L;;;;;N;;;;; +2849;BRAILLE PATTERN DOTS-147;So;0;L;;;;;N;;;;; +284A;BRAILLE PATTERN DOTS-247;So;0;L;;;;;N;;;;; +284B;BRAILLE PATTERN DOTS-1247;So;0;L;;;;;N;;;;; +284C;BRAILLE PATTERN DOTS-347;So;0;L;;;;;N;;;;; +284D;BRAILLE PATTERN DOTS-1347;So;0;L;;;;;N;;;;; +284E;BRAILLE PATTERN DOTS-2347;So;0;L;;;;;N;;;;; +284F;BRAILLE PATTERN DOTS-12347;So;0;L;;;;;N;;;;; +2850;BRAILLE PATTERN DOTS-57;So;0;L;;;;;N;;;;; +2851;BRAILLE PATTERN DOTS-157;So;0;L;;;;;N;;;;; +2852;BRAILLE PATTERN DOTS-257;So;0;L;;;;;N;;;;; +2853;BRAILLE PATTERN DOTS-1257;So;0;L;;;;;N;;;;; +2854;BRAILLE PATTERN DOTS-357;So;0;L;;;;;N;;;;; +2855;BRAILLE PATTERN DOTS-1357;So;0;L;;;;;N;;;;; +2856;BRAILLE PATTERN DOTS-2357;So;0;L;;;;;N;;;;; +2857;BRAILLE PATTERN DOTS-12357;So;0;L;;;;;N;;;;; +2858;BRAILLE PATTERN DOTS-457;So;0;L;;;;;N;;;;; +2859;BRAILLE PATTERN DOTS-1457;So;0;L;;;;;N;;;;; +285A;BRAILLE PATTERN DOTS-2457;So;0;L;;;;;N;;;;; +285B;BRAILLE PATTERN DOTS-12457;So;0;L;;;;;N;;;;; +285C;BRAILLE PATTERN DOTS-3457;So;0;L;;;;;N;;;;; +285D;BRAILLE PATTERN DOTS-13457;So;0;L;;;;;N;;;;; +285E;BRAILLE PATTERN DOTS-23457;So;0;L;;;;;N;;;;; +285F;BRAILLE PATTERN DOTS-123457;So;0;L;;;;;N;;;;; +2860;BRAILLE PATTERN DOTS-67;So;0;L;;;;;N;;;;; +2861;BRAILLE PATTERN DOTS-167;So;0;L;;;;;N;;;;; +2862;BRAILLE PATTERN DOTS-267;So;0;L;;;;;N;;;;; +2863;BRAILLE PATTERN DOTS-1267;So;0;L;;;;;N;;;;; +2864;BRAILLE PATTERN DOTS-367;So;0;L;;;;;N;;;;; +2865;BRAILLE PATTERN DOTS-1367;So;0;L;;;;;N;;;;; +2866;BRAILLE PATTERN DOTS-2367;So;0;L;;;;;N;;;;; +2867;BRAILLE PATTERN DOTS-12367;So;0;L;;;;;N;;;;; +2868;BRAILLE PATTERN DOTS-467;So;0;L;;;;;N;;;;; +2869;BRAILLE PATTERN DOTS-1467;So;0;L;;;;;N;;;;; +286A;BRAILLE PATTERN DOTS-2467;So;0;L;;;;;N;;;;; +286B;BRAILLE PATTERN DOTS-12467;So;0;L;;;;;N;;;;; +286C;BRAILLE PATTERN DOTS-3467;So;0;L;;;;;N;;;;; +286D;BRAILLE PATTERN DOTS-13467;So;0;L;;;;;N;;;;; +286E;BRAILLE PATTERN DOTS-23467;So;0;L;;;;;N;;;;; +286F;BRAILLE PATTERN DOTS-123467;So;0;L;;;;;N;;;;; +2870;BRAILLE PATTERN DOTS-567;So;0;L;;;;;N;;;;; +2871;BRAILLE PATTERN DOTS-1567;So;0;L;;;;;N;;;;; +2872;BRAILLE PATTERN DOTS-2567;So;0;L;;;;;N;;;;; +2873;BRAILLE PATTERN DOTS-12567;So;0;L;;;;;N;;;;; +2874;BRAILLE PATTERN DOTS-3567;So;0;L;;;;;N;;;;; +2875;BRAILLE PATTERN DOTS-13567;So;0;L;;;;;N;;;;; +2876;BRAILLE PATTERN DOTS-23567;So;0;L;;;;;N;;;;; +2877;BRAILLE PATTERN DOTS-123567;So;0;L;;;;;N;;;;; +2878;BRAILLE PATTERN DOTS-4567;So;0;L;;;;;N;;;;; +2879;BRAILLE PATTERN DOTS-14567;So;0;L;;;;;N;;;;; +287A;BRAILLE PATTERN DOTS-24567;So;0;L;;;;;N;;;;; +287B;BRAILLE PATTERN DOTS-124567;So;0;L;;;;;N;;;;; +287C;BRAILLE PATTERN DOTS-34567;So;0;L;;;;;N;;;;; +287D;BRAILLE PATTERN DOTS-134567;So;0;L;;;;;N;;;;; +287E;BRAILLE PATTERN DOTS-234567;So;0;L;;;;;N;;;;; +287F;BRAILLE PATTERN DOTS-1234567;So;0;L;;;;;N;;;;; +2880;BRAILLE PATTERN DOTS-8;So;0;L;;;;;N;;;;; +2881;BRAILLE PATTERN DOTS-18;So;0;L;;;;;N;;;;; +2882;BRAILLE PATTERN DOTS-28;So;0;L;;;;;N;;;;; +2883;BRAILLE PATTERN DOTS-128;So;0;L;;;;;N;;;;; +2884;BRAILLE PATTERN DOTS-38;So;0;L;;;;;N;;;;; +2885;BRAILLE PATTERN DOTS-138;So;0;L;;;;;N;;;;; +2886;BRAILLE PATTERN DOTS-238;So;0;L;;;;;N;;;;; +2887;BRAILLE PATTERN DOTS-1238;So;0;L;;;;;N;;;;; +2888;BRAILLE PATTERN DOTS-48;So;0;L;;;;;N;;;;; +2889;BRAILLE PATTERN DOTS-148;So;0;L;;;;;N;;;;; +288A;BRAILLE PATTERN DOTS-248;So;0;L;;;;;N;;;;; +288B;BRAILLE PATTERN DOTS-1248;So;0;L;;;;;N;;;;; +288C;BRAILLE PATTERN DOTS-348;So;0;L;;;;;N;;;;; +288D;BRAILLE PATTERN DOTS-1348;So;0;L;;;;;N;;;;; +288E;BRAILLE PATTERN DOTS-2348;So;0;L;;;;;N;;;;; +288F;BRAILLE PATTERN DOTS-12348;So;0;L;;;;;N;;;;; +2890;BRAILLE PATTERN DOTS-58;So;0;L;;;;;N;;;;; +2891;BRAILLE PATTERN DOTS-158;So;0;L;;;;;N;;;;; +2892;BRAILLE PATTERN DOTS-258;So;0;L;;;;;N;;;;; +2893;BRAILLE PATTERN DOTS-1258;So;0;L;;;;;N;;;;; +2894;BRAILLE PATTERN DOTS-358;So;0;L;;;;;N;;;;; +2895;BRAILLE PATTERN DOTS-1358;So;0;L;;;;;N;;;;; +2896;BRAILLE PATTERN DOTS-2358;So;0;L;;;;;N;;;;; +2897;BRAILLE PATTERN DOTS-12358;So;0;L;;;;;N;;;;; +2898;BRAILLE PATTERN DOTS-458;So;0;L;;;;;N;;;;; +2899;BRAILLE PATTERN DOTS-1458;So;0;L;;;;;N;;;;; +289A;BRAILLE PATTERN DOTS-2458;So;0;L;;;;;N;;;;; +289B;BRAILLE PATTERN DOTS-12458;So;0;L;;;;;N;;;;; +289C;BRAILLE PATTERN DOTS-3458;So;0;L;;;;;N;;;;; +289D;BRAILLE PATTERN DOTS-13458;So;0;L;;;;;N;;;;; +289E;BRAILLE PATTERN DOTS-23458;So;0;L;;;;;N;;;;; +289F;BRAILLE PATTERN DOTS-123458;So;0;L;;;;;N;;;;; +28A0;BRAILLE PATTERN DOTS-68;So;0;L;;;;;N;;;;; +28A1;BRAILLE PATTERN DOTS-168;So;0;L;;;;;N;;;;; +28A2;BRAILLE PATTERN DOTS-268;So;0;L;;;;;N;;;;; +28A3;BRAILLE PATTERN DOTS-1268;So;0;L;;;;;N;;;;; +28A4;BRAILLE PATTERN DOTS-368;So;0;L;;;;;N;;;;; +28A5;BRAILLE PATTERN DOTS-1368;So;0;L;;;;;N;;;;; +28A6;BRAILLE PATTERN DOTS-2368;So;0;L;;;;;N;;;;; +28A7;BRAILLE PATTERN DOTS-12368;So;0;L;;;;;N;;;;; +28A8;BRAILLE PATTERN DOTS-468;So;0;L;;;;;N;;;;; +28A9;BRAILLE PATTERN DOTS-1468;So;0;L;;;;;N;;;;; +28AA;BRAILLE PATTERN DOTS-2468;So;0;L;;;;;N;;;;; +28AB;BRAILLE PATTERN DOTS-12468;So;0;L;;;;;N;;;;; +28AC;BRAILLE PATTERN DOTS-3468;So;0;L;;;;;N;;;;; +28AD;BRAILLE PATTERN DOTS-13468;So;0;L;;;;;N;;;;; +28AE;BRAILLE PATTERN DOTS-23468;So;0;L;;;;;N;;;;; +28AF;BRAILLE PATTERN DOTS-123468;So;0;L;;;;;N;;;;; +28B0;BRAILLE PATTERN DOTS-568;So;0;L;;;;;N;;;;; +28B1;BRAILLE PATTERN DOTS-1568;So;0;L;;;;;N;;;;; +28B2;BRAILLE PATTERN DOTS-2568;So;0;L;;;;;N;;;;; +28B3;BRAILLE PATTERN DOTS-12568;So;0;L;;;;;N;;;;; +28B4;BRAILLE PATTERN DOTS-3568;So;0;L;;;;;N;;;;; +28B5;BRAILLE PATTERN DOTS-13568;So;0;L;;;;;N;;;;; +28B6;BRAILLE PATTERN DOTS-23568;So;0;L;;;;;N;;;;; +28B7;BRAILLE PATTERN DOTS-123568;So;0;L;;;;;N;;;;; +28B8;BRAILLE PATTERN DOTS-4568;So;0;L;;;;;N;;;;; +28B9;BRAILLE PATTERN DOTS-14568;So;0;L;;;;;N;;;;; +28BA;BRAILLE PATTERN DOTS-24568;So;0;L;;;;;N;;;;; +28BB;BRAILLE PATTERN DOTS-124568;So;0;L;;;;;N;;;;; +28BC;BRAILLE PATTERN DOTS-34568;So;0;L;;;;;N;;;;; +28BD;BRAILLE PATTERN DOTS-134568;So;0;L;;;;;N;;;;; +28BE;BRAILLE PATTERN DOTS-234568;So;0;L;;;;;N;;;;; +28BF;BRAILLE PATTERN DOTS-1234568;So;0;L;;;;;N;;;;; +28C0;BRAILLE PATTERN DOTS-78;So;0;L;;;;;N;;;;; +28C1;BRAILLE PATTERN DOTS-178;So;0;L;;;;;N;;;;; +28C2;BRAILLE PATTERN DOTS-278;So;0;L;;;;;N;;;;; +28C3;BRAILLE PATTERN DOTS-1278;So;0;L;;;;;N;;;;; +28C4;BRAILLE PATTERN DOTS-378;So;0;L;;;;;N;;;;; +28C5;BRAILLE PATTERN DOTS-1378;So;0;L;;;;;N;;;;; +28C6;BRAILLE PATTERN DOTS-2378;So;0;L;;;;;N;;;;; +28C7;BRAILLE PATTERN DOTS-12378;So;0;L;;;;;N;;;;; +28C8;BRAILLE PATTERN DOTS-478;So;0;L;;;;;N;;;;; +28C9;BRAILLE PATTERN DOTS-1478;So;0;L;;;;;N;;;;; +28CA;BRAILLE PATTERN DOTS-2478;So;0;L;;;;;N;;;;; +28CB;BRAILLE PATTERN DOTS-12478;So;0;L;;;;;N;;;;; +28CC;BRAILLE PATTERN DOTS-3478;So;0;L;;;;;N;;;;; +28CD;BRAILLE PATTERN DOTS-13478;So;0;L;;;;;N;;;;; +28CE;BRAILLE PATTERN DOTS-23478;So;0;L;;;;;N;;;;; +28CF;BRAILLE PATTERN DOTS-123478;So;0;L;;;;;N;;;;; +28D0;BRAILLE PATTERN DOTS-578;So;0;L;;;;;N;;;;; +28D1;BRAILLE PATTERN DOTS-1578;So;0;L;;;;;N;;;;; +28D2;BRAILLE PATTERN DOTS-2578;So;0;L;;;;;N;;;;; +28D3;BRAILLE PATTERN DOTS-12578;So;0;L;;;;;N;;;;; +28D4;BRAILLE PATTERN DOTS-3578;So;0;L;;;;;N;;;;; +28D5;BRAILLE PATTERN DOTS-13578;So;0;L;;;;;N;;;;; +28D6;BRAILLE PATTERN DOTS-23578;So;0;L;;;;;N;;;;; +28D7;BRAILLE PATTERN DOTS-123578;So;0;L;;;;;N;;;;; +28D8;BRAILLE PATTERN DOTS-4578;So;0;L;;;;;N;;;;; +28D9;BRAILLE PATTERN DOTS-14578;So;0;L;;;;;N;;;;; +28DA;BRAILLE PATTERN DOTS-24578;So;0;L;;;;;N;;;;; +28DB;BRAILLE PATTERN DOTS-124578;So;0;L;;;;;N;;;;; +28DC;BRAILLE PATTERN DOTS-34578;So;0;L;;;;;N;;;;; +28DD;BRAILLE PATTERN DOTS-134578;So;0;L;;;;;N;;;;; +28DE;BRAILLE PATTERN DOTS-234578;So;0;L;;;;;N;;;;; +28DF;BRAILLE PATTERN DOTS-1234578;So;0;L;;;;;N;;;;; +28E0;BRAILLE PATTERN DOTS-678;So;0;L;;;;;N;;;;; +28E1;BRAILLE PATTERN DOTS-1678;So;0;L;;;;;N;;;;; +28E2;BRAILLE PATTERN DOTS-2678;So;0;L;;;;;N;;;;; +28E3;BRAILLE PATTERN DOTS-12678;So;0;L;;;;;N;;;;; +28E4;BRAILLE PATTERN DOTS-3678;So;0;L;;;;;N;;;;; +28E5;BRAILLE PATTERN DOTS-13678;So;0;L;;;;;N;;;;; +28E6;BRAILLE PATTERN DOTS-23678;So;0;L;;;;;N;;;;; +28E7;BRAILLE PATTERN DOTS-123678;So;0;L;;;;;N;;;;; +28E8;BRAILLE PATTERN DOTS-4678;So;0;L;;;;;N;;;;; +28E9;BRAILLE PATTERN DOTS-14678;So;0;L;;;;;N;;;;; +28EA;BRAILLE PATTERN DOTS-24678;So;0;L;;;;;N;;;;; +28EB;BRAILLE PATTERN DOTS-124678;So;0;L;;;;;N;;;;; +28EC;BRAILLE PATTERN DOTS-34678;So;0;L;;;;;N;;;;; +28ED;BRAILLE PATTERN DOTS-134678;So;0;L;;;;;N;;;;; +28EE;BRAILLE PATTERN DOTS-234678;So;0;L;;;;;N;;;;; +28EF;BRAILLE PATTERN DOTS-1234678;So;0;L;;;;;N;;;;; +28F0;BRAILLE PATTERN DOTS-5678;So;0;L;;;;;N;;;;; +28F1;BRAILLE PATTERN DOTS-15678;So;0;L;;;;;N;;;;; +28F2;BRAILLE PATTERN DOTS-25678;So;0;L;;;;;N;;;;; +28F3;BRAILLE PATTERN DOTS-125678;So;0;L;;;;;N;;;;; +28F4;BRAILLE PATTERN DOTS-35678;So;0;L;;;;;N;;;;; +28F5;BRAILLE PATTERN DOTS-135678;So;0;L;;;;;N;;;;; +28F6;BRAILLE PATTERN DOTS-235678;So;0;L;;;;;N;;;;; +28F7;BRAILLE PATTERN DOTS-1235678;So;0;L;;;;;N;;;;; +28F8;BRAILLE PATTERN DOTS-45678;So;0;L;;;;;N;;;;; +28F9;BRAILLE PATTERN DOTS-145678;So;0;L;;;;;N;;;;; +28FA;BRAILLE PATTERN DOTS-245678;So;0;L;;;;;N;;;;; +28FB;BRAILLE PATTERN DOTS-1245678;So;0;L;;;;;N;;;;; +28FC;BRAILLE PATTERN DOTS-345678;So;0;L;;;;;N;;;;; +28FD;BRAILLE PATTERN DOTS-1345678;So;0;L;;;;;N;;;;; +28FE;BRAILLE PATTERN DOTS-2345678;So;0;L;;;;;N;;;;; +28FF;BRAILLE PATTERN DOTS-12345678;So;0;L;;;;;N;;;;; +2900;RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2901;RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2902;LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2903;RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2904;LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2905;RIGHTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2906;LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2907;RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2908;DOWNWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +2909;UPWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +290A;UPWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;; +290B;DOWNWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;; +290C;LEFTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +290D;RIGHTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +290E;LEFTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +290F;RIGHTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +2910;RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +2911;RIGHTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;; +2912;UPWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;; +2913;DOWNWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;; +2914;RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2915;RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2916;RIGHTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;; +2917;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2918;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2919;LEFTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291A;RIGHTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291B;LEFTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291C;RIGHTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291D;LEFTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +291E;RIGHTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +291F;LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +2920;RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +2921;NORTH WEST AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2922;NORTH EAST AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +2923;NORTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2924;NORTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2925;SOUTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2926;SOUTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2927;NORTH WEST ARROW AND NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2928;NORTH EAST ARROW AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2929;SOUTH EAST ARROW AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +292A;SOUTH WEST ARROW AND NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +292B;RISING DIAGONAL CROSSING FALLING DIAGONAL;Sm;0;ON;;;;;N;;;;; +292C;FALLING DIAGONAL CROSSING RISING DIAGONAL;Sm;0;ON;;;;;N;;;;; +292D;SOUTH EAST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +292E;NORTH EAST ARROW CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +292F;FALLING DIAGONAL CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2930;RISING DIAGONAL CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2931;NORTH EAST ARROW CROSSING NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +2932;NORTH WEST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2933;WAVE ARROW POINTING DIRECTLY RIGHT;Sm;0;ON;;;;;N;;;;; +2934;ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS;Sm;0;ON;;;;;N;;;;; +2935;ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS;Sm;0;ON;;;;;N;;;;; +2936;ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS;Sm;0;ON;;;;;N;;;;; +2937;ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS;Sm;0;ON;;;;;N;;;;; +2938;RIGHT-SIDE ARC CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +2939;LEFT-SIDE ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293A;TOP ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293B;BOTTOM ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293C;TOP ARC CLOCKWISE ARROW WITH MINUS;Sm;0;ON;;;;;N;;;;; +293D;TOP ARC ANTICLOCKWISE ARROW WITH PLUS;Sm;0;ON;;;;;N;;;;; +293E;LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293F;LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +2940;ANTICLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +2941;CLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +2942;RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2943;LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2944;SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2945;RIGHTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;; +2946;LEFTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;; +2947;RIGHTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;; +2948;LEFT RIGHT ARROW THROUGH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +2949;UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +294A;LEFT BARB UP RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;; +294B;LEFT BARB DOWN RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;; +294C;UP BARB RIGHT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;; +294D;UP BARB LEFT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;; +294E;LEFT BARB UP RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;; +294F;UP BARB RIGHT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;; +2950;LEFT BARB DOWN RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;; +2951;UP BARB LEFT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;; +2952;LEFTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;; +2953;RIGHTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;; +2954;UPWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;; +2955;DOWNWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;; +2956;LEFTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;; +2957;RIGHTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;; +2958;UPWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;; +2959;DOWNWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;; +295A;LEFTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;; +295B;RIGHTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;; +295C;UPWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;; +295D;DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;; +295E;LEFTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;; +295F;RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;; +2960;UPWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;; +2961;DOWNWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;; +2962;LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +2963;UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +2964;RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +2965;DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +2966;LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;; +2967;LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +2968;RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;; +2969;RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +296A;LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;; +296B;LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;; +296C;RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;; +296D;RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;; +296E;UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +296F;DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +2970;RIGHT DOUBLE ARROW WITH ROUNDED HEAD;Sm;0;ON;;;;;N;;;;; +2971;EQUALS SIGN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2972;TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2973;LEFTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2974;RIGHTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2975;RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2976;LESS-THAN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2977;LEFTWARDS ARROW THROUGH LESS-THAN;Sm;0;ON;;;;;N;;;;; +2978;GREATER-THAN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2979;SUBSET ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +297A;LEFTWARDS ARROW THROUGH SUBSET;Sm;0;ON;;;;;N;;;;; +297B;SUPERSET ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +297C;LEFT FISH TAIL;Sm;0;ON;;;;;N;;;;; +297D;RIGHT FISH TAIL;Sm;0;ON;;;;;N;;;;; +297E;UP FISH TAIL;Sm;0;ON;;;;;N;;;;; +297F;DOWN FISH TAIL;Sm;0;ON;;;;;N;;;;; +2980;TRIPLE VERTICAL BAR DELIMITER;Sm;0;ON;;;;;N;;;;; +2981;Z NOTATION SPOT;Sm;0;ON;;;;;N;;;;; +2982;Z NOTATION TYPE COLON;Sm;0;ON;;;;;N;;;;; +2983;LEFT WHITE CURLY BRACKET;Ps;0;ON;;;;;Y;;;;; +2984;RIGHT WHITE CURLY BRACKET;Pe;0;ON;;;;;Y;;;;; +2985;LEFT WHITE PARENTHESIS;Ps;0;ON;;;;;Y;;;;; +2986;RIGHT WHITE PARENTHESIS;Pe;0;ON;;;;;Y;;;;; +2987;Z NOTATION LEFT IMAGE BRACKET;Ps;0;ON;;;;;Y;;;;; +2988;Z NOTATION RIGHT IMAGE BRACKET;Pe;0;ON;;;;;Y;;;;; +2989;Z NOTATION LEFT BINDING BRACKET;Ps;0;ON;;;;;Y;;;;; +298A;Z NOTATION RIGHT BINDING BRACKET;Pe;0;ON;;;;;Y;;;;; +298B;LEFT SQUARE BRACKET WITH UNDERBAR;Ps;0;ON;;;;;Y;;;;; +298C;RIGHT SQUARE BRACKET WITH UNDERBAR;Pe;0;ON;;;;;Y;;;;; +298D;LEFT SQUARE BRACKET WITH TICK IN TOP CORNER;Ps;0;ON;;;;;Y;;;;; +298E;RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Pe;0;ON;;;;;Y;;;;; +298F;LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Ps;0;ON;;;;;Y;;;;; +2990;RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER;Pe;0;ON;;;;;Y;;;;; +2991;LEFT ANGLE BRACKET WITH DOT;Ps;0;ON;;;;;Y;;;;; +2992;RIGHT ANGLE BRACKET WITH DOT;Pe;0;ON;;;;;Y;;;;; +2993;LEFT ARC LESS-THAN BRACKET;Ps;0;ON;;;;;Y;;;;; +2994;RIGHT ARC GREATER-THAN BRACKET;Pe;0;ON;;;;;Y;;;;; +2995;DOUBLE LEFT ARC GREATER-THAN BRACKET;Ps;0;ON;;;;;Y;;;;; +2996;DOUBLE RIGHT ARC LESS-THAN BRACKET;Pe;0;ON;;;;;Y;;;;; +2997;LEFT BLACK TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;; +2998;RIGHT BLACK TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;; +2999;DOTTED FENCE;Sm;0;ON;;;;;N;;;;; +299A;VERTICAL ZIGZAG LINE;Sm;0;ON;;;;;N;;;;; +299B;MEASURED ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;; +299C;RIGHT ANGLE VARIANT WITH SQUARE;Sm;0;ON;;;;;Y;;;;; +299D;MEASURED RIGHT ANGLE WITH DOT;Sm;0;ON;;;;;Y;;;;; +299E;ANGLE WITH S INSIDE;Sm;0;ON;;;;;Y;;;;; +299F;ACUTE ANGLE;Sm;0;ON;;;;;Y;;;;; +29A0;SPHERICAL ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;; +29A1;SPHERICAL ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;; +29A2;TURNED ANGLE;Sm;0;ON;;;;;Y;;;;; +29A3;REVERSED ANGLE;Sm;0;ON;;;;;Y;;;;; +29A4;ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +29A5;REVERSED ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +29A6;OBLIQUE ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;; +29A7;OBLIQUE ANGLE OPENING DOWN;Sm;0;ON;;;;;Y;;;;; +29A8;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT;Sm;0;ON;;;;;Y;;;;; +29A9;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT;Sm;0;ON;;;;;Y;;;;; +29AA;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT;Sm;0;ON;;;;;Y;;;;; +29AB;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT;Sm;0;ON;;;;;Y;;;;; +29AC;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP;Sm;0;ON;;;;;Y;;;;; +29AD;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP;Sm;0;ON;;;;;Y;;;;; +29AE;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN;Sm;0;ON;;;;;Y;;;;; +29AF;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN;Sm;0;ON;;;;;Y;;;;; +29B0;REVERSED EMPTY SET;Sm;0;ON;;;;;N;;;;; +29B1;EMPTY SET WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +29B2;EMPTY SET WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +29B3;EMPTY SET WITH RIGHT ARROW ABOVE;Sm;0;ON;;;;;N;;;;; +29B4;EMPTY SET WITH LEFT ARROW ABOVE;Sm;0;ON;;;;;N;;;;; +29B5;CIRCLE WITH HORIZONTAL BAR;Sm;0;ON;;;;;N;;;;; +29B6;CIRCLED VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +29B7;CIRCLED PARALLEL;Sm;0;ON;;;;;N;;;;; +29B8;CIRCLED REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;; +29B9;CIRCLED PERPENDICULAR;Sm;0;ON;;;;;N;;;;; +29BA;CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +29BB;CIRCLE WITH SUPERIMPOSED X;Sm;0;ON;;;;;N;;;;; +29BC;CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN;Sm;0;ON;;;;;N;;;;; +29BD;UP ARROW THROUGH CIRCLE;Sm;0;ON;;;;;N;;;;; +29BE;CIRCLED WHITE BULLET;Sm;0;ON;;;;;N;;;;; +29BF;CIRCLED BULLET;Sm;0;ON;;;;;N;;;;; +29C0;CIRCLED LESS-THAN;Sm;0;ON;;;;;Y;;;;; +29C1;CIRCLED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +29C2;CIRCLE WITH SMALL CIRCLE TO THE RIGHT;Sm;0;ON;;;;;Y;;;;; +29C3;CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT;Sm;0;ON;;;;;Y;;;;; +29C4;SQUARED RISING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;; +29C5;SQUARED FALLING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;; +29C6;SQUARED ASTERISK;Sm;0;ON;;;;;N;;;;; +29C7;SQUARED SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +29C8;SQUARED SQUARE;Sm;0;ON;;;;;N;;;;; +29C9;TWO JOINED SQUARES;Sm;0;ON;;;;;Y;;;;; +29CA;TRIANGLE WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +29CB;TRIANGLE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +29CC;S IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +29CD;TRIANGLE WITH SERIFS AT BOTTOM;Sm;0;ON;;;;;N;;;;; +29CE;RIGHT TRIANGLE ABOVE LEFT TRIANGLE;Sm;0;ON;;;;;Y;;;;; +29CF;LEFT TRIANGLE BESIDE VERTICAL BAR;Sm;0;ON;;;;;Y;;;;; +29D0;VERTICAL BAR BESIDE RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;; +29D1;BOWTIE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D2;BOWTIE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D3;BLACK BOWTIE;Sm;0;ON;;;;;N;;;;; +29D4;TIMES WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D5;TIMES WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D6;WHITE HOURGLASS;Sm;0;ON;;;;;N;;;;; +29D7;BLACK HOURGLASS;Sm;0;ON;;;;;N;;;;; +29D8;LEFT WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;; +29D9;RIGHT WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;; +29DA;LEFT DOUBLE WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;; +29DB;RIGHT DOUBLE WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;; +29DC;INCOMPLETE INFINITY;Sm;0;ON;;;;;Y;;;;; +29DD;TIE OVER INFINITY;Sm;0;ON;;;;;N;;;;; +29DE;INFINITY NEGATED WITH VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +29DF;DOUBLE-ENDED MULTIMAP;Sm;0;ON;;;;;N;;;;; +29E0;SQUARE WITH CONTOURED OUTLINE;Sm;0;ON;;;;;N;;;;; +29E1;INCREASES AS;Sm;0;ON;;;;;Y;;;;; +29E2;SHUFFLE PRODUCT;Sm;0;ON;;;;;N;;;;; +29E3;EQUALS SIGN AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;; +29E4;EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;; +29E5;IDENTICAL TO AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;; +29E6;GLEICH STARK;Sm;0;ON;;;;;N;;;;; +29E7;THERMODYNAMIC;Sm;0;ON;;;;;N;;;;; +29E8;DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29E9;DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29EA;BLACK DIAMOND WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; +29EB;BLACK LOZENGE;Sm;0;ON;;;;;N;;;;; +29EC;WHITE CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; +29ED;BLACK CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; +29EE;ERROR-BARRED WHITE SQUARE;Sm;0;ON;;;;;N;;;;; +29EF;ERROR-BARRED BLACK SQUARE;Sm;0;ON;;;;;N;;;;; +29F0;ERROR-BARRED WHITE DIAMOND;Sm;0;ON;;;;;N;;;;; +29F1;ERROR-BARRED BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +29F2;ERROR-BARRED WHITE CIRCLE;Sm;0;ON;;;;;N;;;;; +29F3;ERROR-BARRED BLACK CIRCLE;Sm;0;ON;;;;;N;;;;; +29F4;RULE-DELAYED;Sm;0;ON;;;;;Y;;;;; +29F5;REVERSE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;; +29F6;SOLIDUS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +29F7;REVERSE SOLIDUS WITH HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +29F8;BIG SOLIDUS;Sm;0;ON;;;;;Y;;;;; +29F9;BIG REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;; +29FA;DOUBLE PLUS;Sm;0;ON;;;;;N;;;;; +29FB;TRIPLE PLUS;Sm;0;ON;;;;;N;;;;; +29FC;LEFT-POINTING CURVED ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; +29FD;RIGHT-POINTING CURVED ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; +29FE;TINY;Sm;0;ON;;;;;N;;;;; +29FF;MINY;Sm;0;ON;;;;;N;;;;; +2A00;N-ARY CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +2A01;N-ARY CIRCLED PLUS OPERATOR;Sm;0;ON;;;;;N;;;;; +2A02;N-ARY CIRCLED TIMES OPERATOR;Sm;0;ON;;;;;N;;;;; +2A03;N-ARY UNION OPERATOR WITH DOT;Sm;0;ON;;;;;N;;;;; +2A04;N-ARY UNION OPERATOR WITH PLUS;Sm;0;ON;;;;;N;;;;; +2A05;N-ARY SQUARE INTERSECTION OPERATOR;Sm;0;ON;;;;;N;;;;; +2A06;N-ARY SQUARE UNION OPERATOR;Sm;0;ON;;;;;N;;;;; +2A07;TWO LOGICAL AND OPERATOR;Sm;0;ON;;;;;N;;;;; +2A08;TWO LOGICAL OR OPERATOR;Sm;0;ON;;;;;N;;;;; +2A09;N-ARY TIMES OPERATOR;Sm;0;ON;;;;;N;;;;; +2A0A;MODULO TWO SUM;Sm;0;ON;;;;;Y;;;;; +2A0B;SUMMATION WITH INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2A0C;QUADRUPLE INTEGRAL OPERATOR;Sm;0;ON; 222B 222B 222B 222B;;;;Y;;;;; +2A0D;FINITE PART INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2A0E;INTEGRAL WITH DOUBLE STROKE;Sm;0;ON;;;;;Y;;;;; +2A0F;INTEGRAL AVERAGE WITH SLASH;Sm;0;ON;;;;;Y;;;;; +2A10;CIRCULATION FUNCTION;Sm;0;ON;;;;;Y;;;;; +2A11;ANTICLOCKWISE INTEGRATION;Sm;0;ON;;;;;Y;;;;; +2A12;LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;; +2A13;LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;; +2A14;LINE INTEGRATION NOT INCLUDING THE POLE;Sm;0;ON;;;;;Y;;;;; +2A15;INTEGRAL AROUND A POINT OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A16;QUATERNION INTEGRAL OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A17;INTEGRAL WITH LEFTWARDS ARROW WITH HOOK;Sm;0;ON;;;;;Y;;;;; +2A18;INTEGRAL WITH TIMES SIGN;Sm;0;ON;;;;;Y;;;;; +2A19;INTEGRAL WITH INTERSECTION;Sm;0;ON;;;;;Y;;;;; +2A1A;INTEGRAL WITH UNION;Sm;0;ON;;;;;Y;;;;; +2A1B;INTEGRAL WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +2A1C;INTEGRAL WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +2A1D;JOIN;Sm;0;ON;;;;;N;;;;; +2A1E;LARGE LEFT TRIANGLE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A1F;Z NOTATION SCHEMA COMPOSITION;Sm;0;ON;;;;;Y;;;;; +2A20;Z NOTATION SCHEMA PIPING;Sm;0;ON;;;;;Y;;;;; +2A21;Z NOTATION SCHEMA PROJECTION;Sm;0;ON;;;;;Y;;;;; +2A22;PLUS SIGN WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +2A23;PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE;Sm;0;ON;;;;;N;;;;; +2A24;PLUS SIGN WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;; +2A25;PLUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; +2A26;PLUS SIGN WITH TILDE BELOW;Sm;0;ON;;;;;Y;;;;; +2A27;PLUS SIGN WITH SUBSCRIPT TWO;Sm;0;ON;;;;;N;;;;; +2A28;PLUS SIGN WITH BLACK TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A29;MINUS SIGN WITH COMMA ABOVE;Sm;0;ON;;;;;Y;;;;; +2A2A;MINUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; +2A2B;MINUS SIGN WITH FALLING DOTS;Sm;0;ON;;;;;Y;;;;; +2A2C;MINUS SIGN WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;; +2A2D;PLUS SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A2E;PLUS SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A2F;VECTOR OR CROSS PRODUCT;Sm;0;ON;;;;;N;;;;; +2A30;MULTIPLICATION SIGN WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A31;MULTIPLICATION SIGN WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A32;SEMIDIRECT PRODUCT WITH BOTTOM CLOSED;Sm;0;ON;;;;;N;;;;; +2A33;SMASH PRODUCT;Sm;0;ON;;;;;N;;;;; +2A34;MULTIPLICATION SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A35;MULTIPLICATION SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A36;CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;N;;;;; +2A37;MULTIPLICATION SIGN IN DOUBLE CIRCLE;Sm;0;ON;;;;;N;;;;; +2A38;CIRCLED DIVISION SIGN;Sm;0;ON;;;;;N;;;;; +2A39;PLUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A3A;MINUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A3B;MULTIPLICATION SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A3C;INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;; +2A3D;RIGHTHAND INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;; +2A3E;Z NOTATION RELATIONAL COMPOSITION;Sm;0;ON;;;;;Y;;;;; +2A3F;AMALGAMATION OR COPRODUCT;Sm;0;ON;;;;;N;;;;; +2A40;INTERSECTION WITH DOT;Sm;0;ON;;;;;N;;;;; +2A41;UNION WITH MINUS SIGN;Sm;0;ON;;;;;N;;;;; +2A42;UNION WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +2A43;INTERSECTION WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +2A44;INTERSECTION WITH LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A45;UNION WITH LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2A46;UNION ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A47;INTERSECTION ABOVE UNION;Sm;0;ON;;;;;N;;;;; +2A48;UNION ABOVE BAR ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A49;INTERSECTION ABOVE BAR ABOVE UNION;Sm;0;ON;;;;;N;;;;; +2A4A;UNION BESIDE AND JOINED WITH UNION;Sm;0;ON;;;;;N;;;;; +2A4B;INTERSECTION BESIDE AND JOINED WITH INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A4C;CLOSED UNION WITH SERIFS;Sm;0;ON;;;;;N;;;;; +2A4D;CLOSED INTERSECTION WITH SERIFS;Sm;0;ON;;;;;N;;;;; +2A4E;DOUBLE SQUARE INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A4F;DOUBLE SQUARE UNION;Sm;0;ON;;;;;N;;;;; +2A50;CLOSED UNION WITH SERIFS AND SMASH PRODUCT;Sm;0;ON;;;;;N;;;;; +2A51;LOGICAL AND WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A52;LOGICAL OR WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A53;DOUBLE LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A54;DOUBLE LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2A55;TWO INTERSECTING LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A56;TWO INTERSECTING LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2A57;SLOPING LARGE OR;Sm;0;ON;;;;;Y;;;;; +2A58;SLOPING LARGE AND;Sm;0;ON;;;;;Y;;;;; +2A59;LOGICAL OR OVERLAPPING LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A5A;LOGICAL AND WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;; +2A5B;LOGICAL OR WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;; +2A5C;LOGICAL AND WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;; +2A5D;LOGICAL OR WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;; +2A5E;LOGICAL AND WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;; +2A5F;LOGICAL AND WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A60;LOGICAL AND WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A61;SMALL VEE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A62;LOGICAL OR WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;; +2A63;LOGICAL OR WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A64;Z NOTATION DOMAIN ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;; +2A65;Z NOTATION RANGE ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;; +2A66;EQUALS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; +2A67;IDENTICAL WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A68;TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2A69;TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2A6A;TILDE OPERATOR WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A6B;TILDE OPERATOR WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;; +2A6C;SIMILAR MINUS SIMILAR;Sm;0;ON;;;;;Y;;;;; +2A6D;CONGRUENT WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A6E;EQUALS WITH ASTERISK;Sm;0;ON;;;;;N;;;;; +2A6F;ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;Y;;;;; +2A70;APPROXIMATELY EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A71;EQUALS SIGN ABOVE PLUS SIGN;Sm;0;ON;;;;;N;;;;; +2A72;PLUS SIGN ABOVE EQUALS SIGN;Sm;0;ON;;;;;N;;;;; +2A73;EQUALS SIGN ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A74;DOUBLE COLON EQUAL;Sm;0;ON; 003A 003A 003D;;;;Y;;;;; +2A75;TWO CONSECUTIVE EQUALS SIGNS;Sm;0;ON; 003D 003D;;;;N;;;;; +2A76;THREE CONSECUTIVE EQUALS SIGNS;Sm;0;ON; 003D 003D 003D;;;;N;;;;; +2A77;EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW;Sm;0;ON;;;;;N;;;;; +2A78;EQUIVALENT WITH FOUR DOTS ABOVE;Sm;0;ON;;;;;N;;;;; +2A79;LESS-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;; +2A7A;GREATER-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;; +2A7B;LESS-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;; +2A7C;GREATER-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;; +2A7D;LESS-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A7E;GREATER-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A7F;LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A80;GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A81;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A82;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A83;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT;Sm;0;ON;;;;;Y;;;;; +2A84;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT;Sm;0;ON;;;;;Y;;;;; +2A85;LESS-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A86;GREATER-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A87;LESS-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A88;GREATER-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A89;LESS-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A8A;GREATER-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A8B;LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A8C;GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A8D;LESS-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;; +2A8E;GREATER-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;; +2A8F;LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A90;GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A91;LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;; +2A92;GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;; +2A93;LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2A94;GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2A95;SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A96;SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A97;SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A98;SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A99;DOUBLE-LINE EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A9A;DOUBLE-LINE EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A9B;DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A9C;DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A9D;SIMILAR OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A9E;SIMILAR OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A9F;SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AA0;SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AA1;DOUBLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2AA2;DOUBLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2AA3;DOUBLE NESTED LESS-THAN WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +2AA4;GREATER-THAN OVERLAPPING LESS-THAN;Sm;0;ON;;;;;N;;;;; +2AA5;GREATER-THAN BESIDE LESS-THAN;Sm;0;ON;;;;;N;;;;; +2AA6;LESS-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;; +2AA7;GREATER-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;; +2AA8;LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2AA9;GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2AAA;SMALLER THAN;Sm;0;ON;;;;;Y;;;;; +2AAB;LARGER THAN;Sm;0;ON;;;;;Y;;;;; +2AAC;SMALLER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AAD;LARGER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AAE;EQUALS SIGN WITH BUMPY ABOVE;Sm;0;ON;;;;;N;;;;; +2AAF;PRECEDES ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB0;SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB1;PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB2;SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB3;PRECEDES ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB4;SUCCEEDS ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB5;PRECEDES ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB6;SUCCEEDS ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB7;PRECEDES ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB8;SUCCEEDS ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB9;PRECEDES ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ABA;SUCCEEDS ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ABB;DOUBLE PRECEDES;Sm;0;ON;;;;;Y;;;;; +2ABC;DOUBLE SUCCEEDS;Sm;0;ON;;;;;Y;;;;; +2ABD;SUBSET WITH DOT;Sm;0;ON;;;;;Y;;;;; +2ABE;SUPERSET WITH DOT;Sm;0;ON;;;;;Y;;;;; +2ABF;SUBSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC0;SUPERSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC1;SUBSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC2;SUPERSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC3;SUBSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2AC4;SUPERSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2AC5;SUBSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AC6;SUPERSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AC7;SUBSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AC8;SUPERSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AC9;SUBSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACA;SUPERSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACB;SUBSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACC;SUPERSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACD;SQUARE LEFT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;; +2ACE;SQUARE RIGHT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;; +2ACF;CLOSED SUBSET;Sm;0;ON;;;;;Y;;;;; +2AD0;CLOSED SUPERSET;Sm;0;ON;;;;;Y;;;;; +2AD1;CLOSED SUBSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AD2;CLOSED SUPERSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AD3;SUBSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;; +2AD4;SUPERSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;; +2AD5;SUBSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;; +2AD6;SUPERSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;; +2AD7;SUPERSET BESIDE SUBSET;Sm;0;ON;;;;;N;;;;; +2AD8;SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET;Sm;0;ON;;;;;N;;;;; +2AD9;ELEMENT OF OPENING DOWNWARDS;Sm;0;ON;;;;;N;;;;; +2ADA;PITCHFORK WITH TEE TOP;Sm;0;ON;;;;;N;;;;; +2ADB;TRANSVERSAL INTERSECTION;Sm;0;ON;;;;;N;;;;; +2ADC;FORKING;Sm;0;ON;2ADD 0338;;;;Y;;;;; +2ADD;NONFORKING;Sm;0;ON;;;;;N;;;;; +2ADE;SHORT LEFT TACK;Sm;0;ON;;;;;Y;;;;; +2ADF;SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;; +2AE0;SHORT UP TACK;Sm;0;ON;;;;;N;;;;; +2AE1;PERPENDICULAR WITH S;Sm;0;ON;;;;;N;;;;; +2AE2;VERTICAL BAR TRIPLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE3;DOUBLE VERTICAL BAR LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE4;VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE5;DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE6;LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL;Sm;0;ON;;;;;Y;;;;; +2AE7;SHORT DOWN TACK WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +2AE8;SHORT UP TACK WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2AE9;SHORT UP TACK ABOVE SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;; +2AEA;DOUBLE DOWN TACK;Sm;0;ON;;;;;N;;;;; +2AEB;DOUBLE UP TACK;Sm;0;ON;;;;;N;;;;; +2AEC;DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;; +2AED;REVERSED DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;; +2AEE;DOES NOT DIVIDE WITH REVERSED NEGATION SLASH;Sm;0;ON;;;;;Y;;;;; +2AEF;VERTICAL LINE WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +2AF0;VERTICAL LINE WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;; +2AF1;DOWN TACK WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;; +2AF2;PARALLEL WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +2AF3;PARALLEL WITH TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AF4;TRIPLE VERTICAL BAR BINARY RELATION;Sm;0;ON;;;;;N;;;;; +2AF5;TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +2AF6;TRIPLE COLON OPERATOR;Sm;0;ON;;;;;N;;;;; +2AF7;TRIPLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2AF8;TRIPLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2AF9;DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AFA;DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AFB;TRIPLE SOLIDUS BINARY RELATION;Sm;0;ON;;;;;Y;;;;; +2AFC;LARGE TRIPLE VERTICAL BAR OPERATOR;Sm;0;ON;;;;;N;;;;; +2AFD;DOUBLE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AFE;WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +2AFF;N-ARY WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +2B00;NORTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;; +2B01;NORTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;; +2B02;SOUTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;; +2B03;SOUTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;; +2B04;LEFT RIGHT WHITE ARROW;So;0;ON;;;;;N;;;;; +2B05;LEFTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;; +2B06;UPWARDS BLACK ARROW;So;0;ON;;;;;N;;;;; +2B07;DOWNWARDS BLACK ARROW;So;0;ON;;;;;N;;;;; +2B08;NORTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;; +2B09;NORTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0A;SOUTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0B;SOUTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0C;LEFT RIGHT BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0D;UP DOWN BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0E;RIGHTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;; +2B0F;RIGHTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;; +2B10;LEFTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;; +2B11;LEFTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;; +2B12;SQUARE WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;; +2B13;SQUARE WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;; +2B14;SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +2B15;SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +2B16;DIAMOND WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +2B17;DIAMOND WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; +2B18;DIAMOND WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;; +2B19;DIAMOND WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;; +2B1A;DOTTED SQUARE;So;0;ON;;;;;N;;;;; +2B1B;BLACK LARGE SQUARE;So;0;ON;;;;;N;;;;; +2B1C;WHITE LARGE SQUARE;So;0;ON;;;;;N;;;;; +2B1D;BLACK VERY SMALL SQUARE;So;0;ON;;;;;N;;;;; +2B1E;WHITE VERY SMALL SQUARE;So;0;ON;;;;;N;;;;; +2B1F;BLACK PENTAGON;So;0;ON;;;;;N;;;;; +2B20;WHITE PENTAGON;So;0;ON;;;;;N;;;;; +2B21;WHITE HEXAGON;So;0;ON;;;;;N;;;;; +2B22;BLACK HEXAGON;So;0;ON;;;;;N;;;;; +2B23;HORIZONTAL BLACK HEXAGON;So;0;ON;;;;;N;;;;; +2B24;BLACK LARGE CIRCLE;So;0;ON;;;;;N;;;;; +2B25;BLACK MEDIUM DIAMOND;So;0;ON;;;;;N;;;;; +2B26;WHITE MEDIUM DIAMOND;So;0;ON;;;;;N;;;;; +2B27;BLACK MEDIUM LOZENGE;So;0;ON;;;;;N;;;;; +2B28;WHITE MEDIUM LOZENGE;So;0;ON;;;;;N;;;;; +2B29;BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;; +2B2A;BLACK SMALL LOZENGE;So;0;ON;;;;;N;;;;; +2B2B;WHITE SMALL LOZENGE;So;0;ON;;;;;N;;;;; +2B2C;BLACK HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;; +2B2D;WHITE HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;; +2B2E;BLACK VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;; +2B2F;WHITE VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;; +2B30;LEFT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +2B31;THREE LEFTWARDS ARROWS;Sm;0;ON;;;;;N;;;;; +2B32;LEFT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; +2B33;LONG LEFTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;; +2B34;LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B35;LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B36;LEFTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2B37;LEFTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +2B38;LEFTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;; +2B39;LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B3A;LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B3B;LEFTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;; +2B3C;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B3D;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B3E;LEFTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;; +2B3F;WAVE ARROW POINTING DIRECTLY LEFT;Sm;0;ON;;;;;N;;;;; +2B40;EQUALS SIGN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2B41;REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2B42;LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2B43;RIGHTWARDS ARROW THROUGH GREATER-THAN;Sm;0;ON;;;;;N;;;;; +2B44;RIGHTWARDS ARROW THROUGH SUPERSET;Sm;0;ON;;;;;N;;;;; +2B45;LEFTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;; +2B46;RIGHTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;; +2B47;REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2B48;RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2B49;TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2B4A;LEFTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2B4B;LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2B4C;RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2B50;WHITE MEDIUM STAR;So;0;ON;;;;;N;;;;; +2B51;BLACK SMALL STAR;So;0;ON;;;;;N;;;;; +2B52;WHITE SMALL STAR;So;0;ON;;;;;N;;;;; +2B53;BLACK RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;; +2B54;WHITE RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;; +2B55;HEAVY LARGE CIRCLE;So;0;ON;;;;;N;;;;; +2B56;HEAVY OVAL WITH OVAL INSIDE;So;0;ON;;;;;N;;;;; +2B57;HEAVY CIRCLE WITH CIRCLE INSIDE;So;0;ON;;;;;N;;;;; +2B58;HEAVY CIRCLE;So;0;ON;;;;;N;;;;; +2B59;HEAVY CIRCLED SALTIRE;So;0;ON;;;;;N;;;;; +2C00;GLAGOLITIC CAPITAL LETTER AZU;Lu;0;L;;;;;N;;;;2C30; +2C01;GLAGOLITIC CAPITAL LETTER BUKY;Lu;0;L;;;;;N;;;;2C31; +2C02;GLAGOLITIC CAPITAL LETTER VEDE;Lu;0;L;;;;;N;;;;2C32; +2C03;GLAGOLITIC CAPITAL LETTER GLAGOLI;Lu;0;L;;;;;N;;;;2C33; +2C04;GLAGOLITIC CAPITAL LETTER DOBRO;Lu;0;L;;;;;N;;;;2C34; +2C05;GLAGOLITIC CAPITAL LETTER YESTU;Lu;0;L;;;;;N;;;;2C35; +2C06;GLAGOLITIC CAPITAL LETTER ZHIVETE;Lu;0;L;;;;;N;;;;2C36; +2C07;GLAGOLITIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;2C37; +2C08;GLAGOLITIC CAPITAL LETTER ZEMLJA;Lu;0;L;;;;;N;;;;2C38; +2C09;GLAGOLITIC CAPITAL LETTER IZHE;Lu;0;L;;;;;N;;;;2C39; +2C0A;GLAGOLITIC CAPITAL LETTER INITIAL IZHE;Lu;0;L;;;;;N;;;;2C3A; +2C0B;GLAGOLITIC CAPITAL LETTER I;Lu;0;L;;;;;N;;;;2C3B; +2C0C;GLAGOLITIC CAPITAL LETTER DJERVI;Lu;0;L;;;;;N;;;;2C3C; +2C0D;GLAGOLITIC CAPITAL LETTER KAKO;Lu;0;L;;;;;N;;;;2C3D; +2C0E;GLAGOLITIC CAPITAL LETTER LJUDIJE;Lu;0;L;;;;;N;;;;2C3E; +2C0F;GLAGOLITIC CAPITAL LETTER MYSLITE;Lu;0;L;;;;;N;;;;2C3F; +2C10;GLAGOLITIC CAPITAL LETTER NASHI;Lu;0;L;;;;;N;;;;2C40; +2C11;GLAGOLITIC CAPITAL LETTER ONU;Lu;0;L;;;;;N;;;;2C41; +2C12;GLAGOLITIC CAPITAL LETTER POKOJI;Lu;0;L;;;;;N;;;;2C42; +2C13;GLAGOLITIC CAPITAL LETTER RITSI;Lu;0;L;;;;;N;;;;2C43; +2C14;GLAGOLITIC CAPITAL LETTER SLOVO;Lu;0;L;;;;;N;;;;2C44; +2C15;GLAGOLITIC CAPITAL LETTER TVRIDO;Lu;0;L;;;;;N;;;;2C45; +2C16;GLAGOLITIC CAPITAL LETTER UKU;Lu;0;L;;;;;N;;;;2C46; +2C17;GLAGOLITIC CAPITAL LETTER FRITU;Lu;0;L;;;;;N;;;;2C47; +2C18;GLAGOLITIC CAPITAL LETTER HERU;Lu;0;L;;;;;N;;;;2C48; +2C19;GLAGOLITIC CAPITAL LETTER OTU;Lu;0;L;;;;;N;;;;2C49; +2C1A;GLAGOLITIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;2C4A; +2C1B;GLAGOLITIC CAPITAL LETTER SHTA;Lu;0;L;;;;;N;;;;2C4B; +2C1C;GLAGOLITIC CAPITAL LETTER TSI;Lu;0;L;;;;;N;;;;2C4C; +2C1D;GLAGOLITIC CAPITAL LETTER CHRIVI;Lu;0;L;;;;;N;;;;2C4D; +2C1E;GLAGOLITIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;2C4E; +2C1F;GLAGOLITIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;;;;2C4F; +2C20;GLAGOLITIC CAPITAL LETTER YERI;Lu;0;L;;;;;N;;;;2C50; +2C21;GLAGOLITIC CAPITAL LETTER YATI;Lu;0;L;;;;;N;;;;2C51; +2C22;GLAGOLITIC CAPITAL LETTER SPIDERY HA;Lu;0;L;;;;;N;;;;2C52; +2C23;GLAGOLITIC CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;2C53; +2C24;GLAGOLITIC CAPITAL LETTER SMALL YUS;Lu;0;L;;;;;N;;;;2C54; +2C25;GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL;Lu;0;L;;;;;N;;;;2C55; +2C26;GLAGOLITIC CAPITAL LETTER YO;Lu;0;L;;;;;N;;;;2C56; +2C27;GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS;Lu;0;L;;;;;N;;;;2C57; +2C28;GLAGOLITIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;2C58; +2C29;GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS;Lu;0;L;;;;;N;;;;2C59; +2C2A;GLAGOLITIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;2C5A; +2C2B;GLAGOLITIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;2C5B; +2C2C;GLAGOLITIC CAPITAL LETTER SHTAPIC;Lu;0;L;;;;;N;;;;2C5C; +2C2D;GLAGOLITIC CAPITAL LETTER TROKUTASTI A;Lu;0;L;;;;;N;;;;2C5D; +2C2E;GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE;Lu;0;L;;;;;N;;;;2C5E; +2C30;GLAGOLITIC SMALL LETTER AZU;Ll;0;L;;;;;N;;;2C00;;2C00 +2C31;GLAGOLITIC SMALL LETTER BUKY;Ll;0;L;;;;;N;;;2C01;;2C01 +2C32;GLAGOLITIC SMALL LETTER VEDE;Ll;0;L;;;;;N;;;2C02;;2C02 +2C33;GLAGOLITIC SMALL LETTER GLAGOLI;Ll;0;L;;;;;N;;;2C03;;2C03 +2C34;GLAGOLITIC SMALL LETTER DOBRO;Ll;0;L;;;;;N;;;2C04;;2C04 +2C35;GLAGOLITIC SMALL LETTER YESTU;Ll;0;L;;;;;N;;;2C05;;2C05 +2C36;GLAGOLITIC SMALL LETTER ZHIVETE;Ll;0;L;;;;;N;;;2C06;;2C06 +2C37;GLAGOLITIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;2C07;;2C07 +2C38;GLAGOLITIC SMALL LETTER ZEMLJA;Ll;0;L;;;;;N;;;2C08;;2C08 +2C39;GLAGOLITIC SMALL LETTER IZHE;Ll;0;L;;;;;N;;;2C09;;2C09 +2C3A;GLAGOLITIC SMALL LETTER INITIAL IZHE;Ll;0;L;;;;;N;;;2C0A;;2C0A +2C3B;GLAGOLITIC SMALL LETTER I;Ll;0;L;;;;;N;;;2C0B;;2C0B +2C3C;GLAGOLITIC SMALL LETTER DJERVI;Ll;0;L;;;;;N;;;2C0C;;2C0C +2C3D;GLAGOLITIC SMALL LETTER KAKO;Ll;0;L;;;;;N;;;2C0D;;2C0D +2C3E;GLAGOLITIC SMALL LETTER LJUDIJE;Ll;0;L;;;;;N;;;2C0E;;2C0E +2C3F;GLAGOLITIC SMALL LETTER MYSLITE;Ll;0;L;;;;;N;;;2C0F;;2C0F +2C40;GLAGOLITIC SMALL LETTER NASHI;Ll;0;L;;;;;N;;;2C10;;2C10 +2C41;GLAGOLITIC SMALL LETTER ONU;Ll;0;L;;;;;N;;;2C11;;2C11 +2C42;GLAGOLITIC SMALL LETTER POKOJI;Ll;0;L;;;;;N;;;2C12;;2C12 +2C43;GLAGOLITIC SMALL LETTER RITSI;Ll;0;L;;;;;N;;;2C13;;2C13 +2C44;GLAGOLITIC SMALL LETTER SLOVO;Ll;0;L;;;;;N;;;2C14;;2C14 +2C45;GLAGOLITIC SMALL LETTER TVRIDO;Ll;0;L;;;;;N;;;2C15;;2C15 +2C46;GLAGOLITIC SMALL LETTER UKU;Ll;0;L;;;;;N;;;2C16;;2C16 +2C47;GLAGOLITIC SMALL LETTER FRITU;Ll;0;L;;;;;N;;;2C17;;2C17 +2C48;GLAGOLITIC SMALL LETTER HERU;Ll;0;L;;;;;N;;;2C18;;2C18 +2C49;GLAGOLITIC SMALL LETTER OTU;Ll;0;L;;;;;N;;;2C19;;2C19 +2C4A;GLAGOLITIC SMALL LETTER PE;Ll;0;L;;;;;N;;;2C1A;;2C1A +2C4B;GLAGOLITIC SMALL LETTER SHTA;Ll;0;L;;;;;N;;;2C1B;;2C1B +2C4C;GLAGOLITIC SMALL LETTER TSI;Ll;0;L;;;;;N;;;2C1C;;2C1C +2C4D;GLAGOLITIC SMALL LETTER CHRIVI;Ll;0;L;;;;;N;;;2C1D;;2C1D +2C4E;GLAGOLITIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;2C1E;;2C1E +2C4F;GLAGOLITIC SMALL LETTER YERU;Ll;0;L;;;;;N;;;2C1F;;2C1F +2C50;GLAGOLITIC SMALL LETTER YERI;Ll;0;L;;;;;N;;;2C20;;2C20 +2C51;GLAGOLITIC SMALL LETTER YATI;Ll;0;L;;;;;N;;;2C21;;2C21 +2C52;GLAGOLITIC SMALL LETTER SPIDERY HA;Ll;0;L;;;;;N;;;2C22;;2C22 +2C53;GLAGOLITIC SMALL LETTER YU;Ll;0;L;;;;;N;;;2C23;;2C23 +2C54;GLAGOLITIC SMALL LETTER SMALL YUS;Ll;0;L;;;;;N;;;2C24;;2C24 +2C55;GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL;Ll;0;L;;;;;N;;;2C25;;2C25 +2C56;GLAGOLITIC SMALL LETTER YO;Ll;0;L;;;;;N;;;2C26;;2C26 +2C57;GLAGOLITIC SMALL LETTER IOTATED SMALL YUS;Ll;0;L;;;;;N;;;2C27;;2C27 +2C58;GLAGOLITIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;2C28;;2C28 +2C59;GLAGOLITIC SMALL LETTER IOTATED BIG YUS;Ll;0;L;;;;;N;;;2C29;;2C29 +2C5A;GLAGOLITIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;2C2A;;2C2A +2C5B;GLAGOLITIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;2C2B;;2C2B +2C5C;GLAGOLITIC SMALL LETTER SHTAPIC;Ll;0;L;;;;;N;;;2C2C;;2C2C +2C5D;GLAGOLITIC SMALL LETTER TROKUTASTI A;Ll;0;L;;;;;N;;;2C2D;;2C2D +2C5E;GLAGOLITIC SMALL LETTER LATINATE MYSLITE;Ll;0;L;;;;;N;;;2C2E;;2C2E +2C60;LATIN CAPITAL LETTER L WITH DOUBLE BAR;Lu;0;L;;;;;N;;;;2C61; +2C61;LATIN SMALL LETTER L WITH DOUBLE BAR;Ll;0;L;;;;;N;;;2C60;;2C60 +2C62;LATIN CAPITAL LETTER L WITH MIDDLE TILDE;Lu;0;L;;;;;N;;;;026B; +2C63;LATIN CAPITAL LETTER P WITH STROKE;Lu;0;L;;;;;N;;;;1D7D; +2C64;LATIN CAPITAL LETTER R WITH TAIL;Lu;0;L;;;;;N;;;;027D; +2C65;LATIN SMALL LETTER A WITH STROKE;Ll;0;L;;;;;N;;;023A;;023A +2C66;LATIN SMALL LETTER T WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;023E;;023E +2C67;LATIN CAPITAL LETTER H WITH DESCENDER;Lu;0;L;;;;;N;;;;2C68; +2C68;LATIN SMALL LETTER H WITH DESCENDER;Ll;0;L;;;;;N;;;2C67;;2C67 +2C69;LATIN CAPITAL LETTER K WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6A; +2C6A;LATIN SMALL LETTER K WITH DESCENDER;Ll;0;L;;;;;N;;;2C69;;2C69 +2C6B;LATIN CAPITAL LETTER Z WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6C; +2C6C;LATIN SMALL LETTER Z WITH DESCENDER;Ll;0;L;;;;;N;;;2C6B;;2C6B +2C6D;LATIN CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;0251; +2C6E;LATIN CAPITAL LETTER M WITH HOOK;Lu;0;L;;;;;N;;;;0271; +2C6F;LATIN CAPITAL LETTER TURNED A;Lu;0;L;;;;;N;;;;0250; +2C70;LATIN CAPITAL LETTER TURNED ALPHA;Lu;0;L;;;;;N;;;;0252; +2C71;LATIN SMALL LETTER V WITH RIGHT HOOK;Ll;0;L;;;;;N;;;;; +2C72;LATIN CAPITAL LETTER W WITH HOOK;Lu;0;L;;;;;N;;;;2C73; +2C73;LATIN SMALL LETTER W WITH HOOK;Ll;0;L;;;;;N;;;2C72;;2C72 +2C74;LATIN SMALL LETTER V WITH CURL;Ll;0;L;;;;;N;;;;; +2C75;LATIN CAPITAL LETTER HALF H;Lu;0;L;;;;;N;;;;2C76; +2C76;LATIN SMALL LETTER HALF H;Ll;0;L;;;;;N;;;2C75;;2C75 +2C77;LATIN SMALL LETTER TAILLESS PHI;Ll;0;L;;;;;N;;;;; +2C78;LATIN SMALL LETTER E WITH NOTCH;Ll;0;L;;;;;N;;;;; +2C79;LATIN SMALL LETTER TURNED R WITH TAIL;Ll;0;L;;;;;N;;;;; +2C7A;LATIN SMALL LETTER O WITH LOW RING INSIDE;Ll;0;L;;;;;N;;;;; +2C7B;LATIN LETTER SMALL CAPITAL TURNED E;Ll;0;L;;;;;N;;;;; +2C7C;LATIN SUBSCRIPT SMALL LETTER J;Ll;0;L; 006A;;;;N;;;;; +2C7D;MODIFIER LETTER CAPITAL V;Lm;0;L; 0056;;;;N;;;;; +2C7E;LATIN CAPITAL LETTER S WITH SWASH TAIL;Lu;0;L;;;;;N;;;;023F; +2C7F;LATIN CAPITAL LETTER Z WITH SWASH TAIL;Lu;0;L;;;;;N;;;;0240; +2C80;COPTIC CAPITAL LETTER ALFA;Lu;0;L;;;;;N;;;;2C81; +2C81;COPTIC SMALL LETTER ALFA;Ll;0;L;;;;;N;;;2C80;;2C80 +2C82;COPTIC CAPITAL LETTER VIDA;Lu;0;L;;;;;N;;;;2C83; +2C83;COPTIC SMALL LETTER VIDA;Ll;0;L;;;;;N;;;2C82;;2C82 +2C84;COPTIC CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;2C85; +2C85;COPTIC SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;2C84;;2C84 +2C86;COPTIC CAPITAL LETTER DALDA;Lu;0;L;;;;;N;;;;2C87; +2C87;COPTIC SMALL LETTER DALDA;Ll;0;L;;;;;N;;;2C86;;2C86 +2C88;COPTIC CAPITAL LETTER EIE;Lu;0;L;;;;;N;;;;2C89; +2C89;COPTIC SMALL LETTER EIE;Ll;0;L;;;;;N;;;2C88;;2C88 +2C8A;COPTIC CAPITAL LETTER SOU;Lu;0;L;;;;;N;;;;2C8B; +2C8B;COPTIC SMALL LETTER SOU;Ll;0;L;;;;;N;;;2C8A;;2C8A +2C8C;COPTIC CAPITAL LETTER ZATA;Lu;0;L;;;;;N;;;;2C8D; +2C8D;COPTIC SMALL LETTER ZATA;Ll;0;L;;;;;N;;;2C8C;;2C8C +2C8E;COPTIC CAPITAL LETTER HATE;Lu;0;L;;;;;N;;;;2C8F; +2C8F;COPTIC SMALL LETTER HATE;Ll;0;L;;;;;N;;;2C8E;;2C8E +2C90;COPTIC CAPITAL LETTER THETHE;Lu;0;L;;;;;N;;;;2C91; +2C91;COPTIC SMALL LETTER THETHE;Ll;0;L;;;;;N;;;2C90;;2C90 +2C92;COPTIC CAPITAL LETTER IAUDA;Lu;0;L;;;;;N;;;;2C93; +2C93;COPTIC SMALL LETTER IAUDA;Ll;0;L;;;;;N;;;2C92;;2C92 +2C94;COPTIC CAPITAL LETTER KAPA;Lu;0;L;;;;;N;;;;2C95; +2C95;COPTIC SMALL LETTER KAPA;Ll;0;L;;;;;N;;;2C94;;2C94 +2C96;COPTIC CAPITAL LETTER LAULA;Lu;0;L;;;;;N;;;;2C97; +2C97;COPTIC SMALL LETTER LAULA;Ll;0;L;;;;;N;;;2C96;;2C96 +2C98;COPTIC CAPITAL LETTER MI;Lu;0;L;;;;;N;;;;2C99; +2C99;COPTIC SMALL LETTER MI;Ll;0;L;;;;;N;;;2C98;;2C98 +2C9A;COPTIC CAPITAL LETTER NI;Lu;0;L;;;;;N;;;;2C9B; +2C9B;COPTIC SMALL LETTER NI;Ll;0;L;;;;;N;;;2C9A;;2C9A +2C9C;COPTIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;2C9D; +2C9D;COPTIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;2C9C;;2C9C +2C9E;COPTIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;2C9F; +2C9F;COPTIC SMALL LETTER O;Ll;0;L;;;;;N;;;2C9E;;2C9E +2CA0;COPTIC CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;2CA1; +2CA1;COPTIC SMALL LETTER PI;Ll;0;L;;;;;N;;;2CA0;;2CA0 +2CA2;COPTIC CAPITAL LETTER RO;Lu;0;L;;;;;N;;;;2CA3; +2CA3;COPTIC SMALL LETTER RO;Ll;0;L;;;;;N;;;2CA2;;2CA2 +2CA4;COPTIC CAPITAL LETTER SIMA;Lu;0;L;;;;;N;;;;2CA5; +2CA5;COPTIC SMALL LETTER SIMA;Ll;0;L;;;;;N;;;2CA4;;2CA4 +2CA6;COPTIC CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;2CA7; +2CA7;COPTIC SMALL LETTER TAU;Ll;0;L;;;;;N;;;2CA6;;2CA6 +2CA8;COPTIC CAPITAL LETTER UA;Lu;0;L;;;;;N;;;;2CA9; +2CA9;COPTIC SMALL LETTER UA;Ll;0;L;;;;;N;;;2CA8;;2CA8 +2CAA;COPTIC CAPITAL LETTER FI;Lu;0;L;;;;;N;;;;2CAB; +2CAB;COPTIC SMALL LETTER FI;Ll;0;L;;;;;N;;;2CAA;;2CAA +2CAC;COPTIC CAPITAL LETTER KHI;Lu;0;L;;;;;N;;;;2CAD; +2CAD;COPTIC SMALL LETTER KHI;Ll;0;L;;;;;N;;;2CAC;;2CAC +2CAE;COPTIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;2CAF; +2CAF;COPTIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;2CAE;;2CAE +2CB0;COPTIC CAPITAL LETTER OOU;Lu;0;L;;;;;N;;;;2CB1; +2CB1;COPTIC SMALL LETTER OOU;Ll;0;L;;;;;N;;;2CB0;;2CB0 +2CB2;COPTIC CAPITAL LETTER DIALECT-P ALEF;Lu;0;L;;;;;N;;;;2CB3; +2CB3;COPTIC SMALL LETTER DIALECT-P ALEF;Ll;0;L;;;;;N;;;2CB2;;2CB2 +2CB4;COPTIC CAPITAL LETTER OLD COPTIC AIN;Lu;0;L;;;;;N;;;;2CB5; +2CB5;COPTIC SMALL LETTER OLD COPTIC AIN;Ll;0;L;;;;;N;;;2CB4;;2CB4 +2CB6;COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE;Lu;0;L;;;;;N;;;;2CB7; +2CB7;COPTIC SMALL LETTER CRYPTOGRAMMIC EIE;Ll;0;L;;;;;N;;;2CB6;;2CB6 +2CB8;COPTIC CAPITAL LETTER DIALECT-P KAPA;Lu;0;L;;;;;N;;;;2CB9; +2CB9;COPTIC SMALL LETTER DIALECT-P KAPA;Ll;0;L;;;;;N;;;2CB8;;2CB8 +2CBA;COPTIC CAPITAL LETTER DIALECT-P NI;Lu;0;L;;;;;N;;;;2CBB; +2CBB;COPTIC SMALL LETTER DIALECT-P NI;Ll;0;L;;;;;N;;;2CBA;;2CBA +2CBC;COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI;Lu;0;L;;;;;N;;;;2CBD; +2CBD;COPTIC SMALL LETTER CRYPTOGRAMMIC NI;Ll;0;L;;;;;N;;;2CBC;;2CBC +2CBE;COPTIC CAPITAL LETTER OLD COPTIC OOU;Lu;0;L;;;;;N;;;;2CBF; +2CBF;COPTIC SMALL LETTER OLD COPTIC OOU;Ll;0;L;;;;;N;;;2CBE;;2CBE +2CC0;COPTIC CAPITAL LETTER SAMPI;Lu;0;L;;;;;N;;;;2CC1; +2CC1;COPTIC SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;2CC0;;2CC0 +2CC2;COPTIC CAPITAL LETTER CROSSED SHEI;Lu;0;L;;;;;N;;;;2CC3; +2CC3;COPTIC SMALL LETTER CROSSED SHEI;Ll;0;L;;;;;N;;;2CC2;;2CC2 +2CC4;COPTIC CAPITAL LETTER OLD COPTIC SHEI;Lu;0;L;;;;;N;;;;2CC5; +2CC5;COPTIC SMALL LETTER OLD COPTIC SHEI;Ll;0;L;;;;;N;;;2CC4;;2CC4 +2CC6;COPTIC CAPITAL LETTER OLD COPTIC ESH;Lu;0;L;;;;;N;;;;2CC7; +2CC7;COPTIC SMALL LETTER OLD COPTIC ESH;Ll;0;L;;;;;N;;;2CC6;;2CC6 +2CC8;COPTIC CAPITAL LETTER AKHMIMIC KHEI;Lu;0;L;;;;;N;;;;2CC9; +2CC9;COPTIC SMALL LETTER AKHMIMIC KHEI;Ll;0;L;;;;;N;;;2CC8;;2CC8 +2CCA;COPTIC CAPITAL LETTER DIALECT-P HORI;Lu;0;L;;;;;N;;;;2CCB; +2CCB;COPTIC SMALL LETTER DIALECT-P HORI;Ll;0;L;;;;;N;;;2CCA;;2CCA +2CCC;COPTIC CAPITAL LETTER OLD COPTIC HORI;Lu;0;L;;;;;N;;;;2CCD; +2CCD;COPTIC SMALL LETTER OLD COPTIC HORI;Ll;0;L;;;;;N;;;2CCC;;2CCC +2CCE;COPTIC CAPITAL LETTER OLD COPTIC HA;Lu;0;L;;;;;N;;;;2CCF; +2CCF;COPTIC SMALL LETTER OLD COPTIC HA;Ll;0;L;;;;;N;;;2CCE;;2CCE +2CD0;COPTIC CAPITAL LETTER L-SHAPED HA;Lu;0;L;;;;;N;;;;2CD1; +2CD1;COPTIC SMALL LETTER L-SHAPED HA;Ll;0;L;;;;;N;;;2CD0;;2CD0 +2CD2;COPTIC CAPITAL LETTER OLD COPTIC HEI;Lu;0;L;;;;;N;;;;2CD3; +2CD3;COPTIC SMALL LETTER OLD COPTIC HEI;Ll;0;L;;;;;N;;;2CD2;;2CD2 +2CD4;COPTIC CAPITAL LETTER OLD COPTIC HAT;Lu;0;L;;;;;N;;;;2CD5; +2CD5;COPTIC SMALL LETTER OLD COPTIC HAT;Ll;0;L;;;;;N;;;2CD4;;2CD4 +2CD6;COPTIC CAPITAL LETTER OLD COPTIC GANGIA;Lu;0;L;;;;;N;;;;2CD7; +2CD7;COPTIC SMALL LETTER OLD COPTIC GANGIA;Ll;0;L;;;;;N;;;2CD6;;2CD6 +2CD8;COPTIC CAPITAL LETTER OLD COPTIC DJA;Lu;0;L;;;;;N;;;;2CD9; +2CD9;COPTIC SMALL LETTER OLD COPTIC DJA;Ll;0;L;;;;;N;;;2CD8;;2CD8 +2CDA;COPTIC CAPITAL LETTER OLD COPTIC SHIMA;Lu;0;L;;;;;N;;;;2CDB; +2CDB;COPTIC SMALL LETTER OLD COPTIC SHIMA;Ll;0;L;;;;;N;;;2CDA;;2CDA +2CDC;COPTIC CAPITAL LETTER OLD NUBIAN SHIMA;Lu;0;L;;;;;N;;;;2CDD; +2CDD;COPTIC SMALL LETTER OLD NUBIAN SHIMA;Ll;0;L;;;;;N;;;2CDC;;2CDC +2CDE;COPTIC CAPITAL LETTER OLD NUBIAN NGI;Lu;0;L;;;;;N;;;;2CDF; +2CDF;COPTIC SMALL LETTER OLD NUBIAN NGI;Ll;0;L;;;;;N;;;2CDE;;2CDE +2CE0;COPTIC CAPITAL LETTER OLD NUBIAN NYI;Lu;0;L;;;;;N;;;;2CE1; +2CE1;COPTIC SMALL LETTER OLD NUBIAN NYI;Ll;0;L;;;;;N;;;2CE0;;2CE0 +2CE2;COPTIC CAPITAL LETTER OLD NUBIAN WAU;Lu;0;L;;;;;N;;;;2CE3; +2CE3;COPTIC SMALL LETTER OLD NUBIAN WAU;Ll;0;L;;;;;N;;;2CE2;;2CE2 +2CE4;COPTIC SYMBOL KAI;Ll;0;L;;;;;N;;;;; +2CE5;COPTIC SYMBOL MI RO;So;0;ON;;;;;N;;;;; +2CE6;COPTIC SYMBOL PI RO;So;0;ON;;;;;N;;;;; +2CE7;COPTIC SYMBOL STAUROS;So;0;ON;;;;;N;;;;; +2CE8;COPTIC SYMBOL TAU RO;So;0;ON;;;;;N;;;;; +2CE9;COPTIC SYMBOL KHI RO;So;0;ON;;;;;N;;;;; +2CEA;COPTIC SYMBOL SHIMA SIMA;So;0;ON;;;;;N;;;;; +2CEB;COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI;Lu;0;L;;;;;N;;;;2CEC; +2CEC;COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI;Ll;0;L;;;;;N;;;2CEB;;2CEB +2CED;COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA;Lu;0;L;;;;;N;;;;2CEE; +2CEE;COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA;Ll;0;L;;;;;N;;;2CED;;2CED +2CEF;COPTIC COMBINING NI ABOVE;Mn;230;NSM;;;;;N;;;;; +2CF0;COPTIC COMBINING SPIRITUS ASPER;Mn;230;NSM;;;;;N;;;;; +2CF1;COPTIC COMBINING SPIRITUS LENIS;Mn;230;NSM;;;;;N;;;;; +2CF9;COPTIC OLD NUBIAN FULL STOP;Po;0;ON;;;;;N;;;;; +2CFA;COPTIC OLD NUBIAN DIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;; +2CFB;COPTIC OLD NUBIAN INDIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;; +2CFC;COPTIC OLD NUBIAN VERSE DIVIDER;Po;0;ON;;;;;N;;;;; +2CFD;COPTIC FRACTION ONE HALF;No;0;ON;;;;1/2;N;;;;; +2CFE;COPTIC FULL STOP;Po;0;ON;;;;;N;;;;; +2CFF;COPTIC MORPHOLOGICAL DIVIDER;Po;0;ON;;;;;N;;;;; +2D00;GEORGIAN SMALL LETTER AN;Ll;0;L;;;;;N;;;10A0;;10A0 +2D01;GEORGIAN SMALL LETTER BAN;Ll;0;L;;;;;N;;;10A1;;10A1 +2D02;GEORGIAN SMALL LETTER GAN;Ll;0;L;;;;;N;;;10A2;;10A2 +2D03;GEORGIAN SMALL LETTER DON;Ll;0;L;;;;;N;;;10A3;;10A3 +2D04;GEORGIAN SMALL LETTER EN;Ll;0;L;;;;;N;;;10A4;;10A4 +2D05;GEORGIAN SMALL LETTER VIN;Ll;0;L;;;;;N;;;10A5;;10A5 +2D06;GEORGIAN SMALL LETTER ZEN;Ll;0;L;;;;;N;;;10A6;;10A6 +2D07;GEORGIAN SMALL LETTER TAN;Ll;0;L;;;;;N;;;10A7;;10A7 +2D08;GEORGIAN SMALL LETTER IN;Ll;0;L;;;;;N;;;10A8;;10A8 +2D09;GEORGIAN SMALL LETTER KAN;Ll;0;L;;;;;N;;;10A9;;10A9 +2D0A;GEORGIAN SMALL LETTER LAS;Ll;0;L;;;;;N;;;10AA;;10AA +2D0B;GEORGIAN SMALL LETTER MAN;Ll;0;L;;;;;N;;;10AB;;10AB +2D0C;GEORGIAN SMALL LETTER NAR;Ll;0;L;;;;;N;;;10AC;;10AC +2D0D;GEORGIAN SMALL LETTER ON;Ll;0;L;;;;;N;;;10AD;;10AD +2D0E;GEORGIAN SMALL LETTER PAR;Ll;0;L;;;;;N;;;10AE;;10AE +2D0F;GEORGIAN SMALL LETTER ZHAR;Ll;0;L;;;;;N;;;10AF;;10AF +2D10;GEORGIAN SMALL LETTER RAE;Ll;0;L;;;;;N;;;10B0;;10B0 +2D11;GEORGIAN SMALL LETTER SAN;Ll;0;L;;;;;N;;;10B1;;10B1 +2D12;GEORGIAN SMALL LETTER TAR;Ll;0;L;;;;;N;;;10B2;;10B2 +2D13;GEORGIAN SMALL LETTER UN;Ll;0;L;;;;;N;;;10B3;;10B3 +2D14;GEORGIAN SMALL LETTER PHAR;Ll;0;L;;;;;N;;;10B4;;10B4 +2D15;GEORGIAN SMALL LETTER KHAR;Ll;0;L;;;;;N;;;10B5;;10B5 +2D16;GEORGIAN SMALL LETTER GHAN;Ll;0;L;;;;;N;;;10B6;;10B6 +2D17;GEORGIAN SMALL LETTER QAR;Ll;0;L;;;;;N;;;10B7;;10B7 +2D18;GEORGIAN SMALL LETTER SHIN;Ll;0;L;;;;;N;;;10B8;;10B8 +2D19;GEORGIAN SMALL LETTER CHIN;Ll;0;L;;;;;N;;;10B9;;10B9 +2D1A;GEORGIAN SMALL LETTER CAN;Ll;0;L;;;;;N;;;10BA;;10BA +2D1B;GEORGIAN SMALL LETTER JIL;Ll;0;L;;;;;N;;;10BB;;10BB +2D1C;GEORGIAN SMALL LETTER CIL;Ll;0;L;;;;;N;;;10BC;;10BC +2D1D;GEORGIAN SMALL LETTER CHAR;Ll;0;L;;;;;N;;;10BD;;10BD +2D1E;GEORGIAN SMALL LETTER XAN;Ll;0;L;;;;;N;;;10BE;;10BE +2D1F;GEORGIAN SMALL LETTER JHAN;Ll;0;L;;;;;N;;;10BF;;10BF +2D20;GEORGIAN SMALL LETTER HAE;Ll;0;L;;;;;N;;;10C0;;10C0 +2D21;GEORGIAN SMALL LETTER HE;Ll;0;L;;;;;N;;;10C1;;10C1 +2D22;GEORGIAN SMALL LETTER HIE;Ll;0;L;;;;;N;;;10C2;;10C2 +2D23;GEORGIAN SMALL LETTER WE;Ll;0;L;;;;;N;;;10C3;;10C3 +2D24;GEORGIAN SMALL LETTER HAR;Ll;0;L;;;;;N;;;10C4;;10C4 +2D25;GEORGIAN SMALL LETTER HOE;Ll;0;L;;;;;N;;;10C5;;10C5 +2D30;TIFINAGH LETTER YA;Lo;0;L;;;;;N;;;;; +2D31;TIFINAGH LETTER YAB;Lo;0;L;;;;;N;;;;; +2D32;TIFINAGH LETTER YABH;Lo;0;L;;;;;N;;;;; +2D33;TIFINAGH LETTER YAG;Lo;0;L;;;;;N;;;;; +2D34;TIFINAGH LETTER YAGHH;Lo;0;L;;;;;N;;;;; +2D35;TIFINAGH LETTER BERBER ACADEMY YAJ;Lo;0;L;;;;;N;;;;; +2D36;TIFINAGH LETTER YAJ;Lo;0;L;;;;;N;;;;; +2D37;TIFINAGH LETTER YAD;Lo;0;L;;;;;N;;;;; +2D38;TIFINAGH LETTER YADH;Lo;0;L;;;;;N;;;;; +2D39;TIFINAGH LETTER YADD;Lo;0;L;;;;;N;;;;; +2D3A;TIFINAGH LETTER YADDH;Lo;0;L;;;;;N;;;;; +2D3B;TIFINAGH LETTER YEY;Lo;0;L;;;;;N;;;;; +2D3C;TIFINAGH LETTER YAF;Lo;0;L;;;;;N;;;;; +2D3D;TIFINAGH LETTER YAK;Lo;0;L;;;;;N;;;;; +2D3E;TIFINAGH LETTER TUAREG YAK;Lo;0;L;;;;;N;;;;; +2D3F;TIFINAGH LETTER YAKHH;Lo;0;L;;;;;N;;;;; +2D40;TIFINAGH LETTER YAH;Lo;0;L;;;;;N;;;;; +2D41;TIFINAGH LETTER BERBER ACADEMY YAH;Lo;0;L;;;;;N;;;;; +2D42;TIFINAGH LETTER TUAREG YAH;Lo;0;L;;;;;N;;;;; +2D43;TIFINAGH LETTER YAHH;Lo;0;L;;;;;N;;;;; +2D44;TIFINAGH LETTER YAA;Lo;0;L;;;;;N;;;;; +2D45;TIFINAGH LETTER YAKH;Lo;0;L;;;;;N;;;;; +2D46;TIFINAGH LETTER TUAREG YAKH;Lo;0;L;;;;;N;;;;; +2D47;TIFINAGH LETTER YAQ;Lo;0;L;;;;;N;;;;; +2D48;TIFINAGH LETTER TUAREG YAQ;Lo;0;L;;;;;N;;;;; +2D49;TIFINAGH LETTER YI;Lo;0;L;;;;;N;;;;; +2D4A;TIFINAGH LETTER YAZH;Lo;0;L;;;;;N;;;;; +2D4B;TIFINAGH LETTER AHAGGAR YAZH;Lo;0;L;;;;;N;;;;; +2D4C;TIFINAGH LETTER TUAREG YAZH;Lo;0;L;;;;;N;;;;; +2D4D;TIFINAGH LETTER YAL;Lo;0;L;;;;;N;;;;; +2D4E;TIFINAGH LETTER YAM;Lo;0;L;;;;;N;;;;; +2D4F;TIFINAGH LETTER YAN;Lo;0;L;;;;;N;;;;; +2D50;TIFINAGH LETTER TUAREG YAGN;Lo;0;L;;;;;N;;;;; +2D51;TIFINAGH LETTER TUAREG YANG;Lo;0;L;;;;;N;;;;; +2D52;TIFINAGH LETTER YAP;Lo;0;L;;;;;N;;;;; +2D53;TIFINAGH LETTER YU;Lo;0;L;;;;;N;;;;; +2D54;TIFINAGH LETTER YAR;Lo;0;L;;;;;N;;;;; +2D55;TIFINAGH LETTER YARR;Lo;0;L;;;;;N;;;;; +2D56;TIFINAGH LETTER YAGH;Lo;0;L;;;;;N;;;;; +2D57;TIFINAGH LETTER TUAREG YAGH;Lo;0;L;;;;;N;;;;; +2D58;TIFINAGH LETTER AYER YAGH;Lo;0;L;;;;;N;;;;; +2D59;TIFINAGH LETTER YAS;Lo;0;L;;;;;N;;;;; +2D5A;TIFINAGH LETTER YASS;Lo;0;L;;;;;N;;;;; +2D5B;TIFINAGH LETTER YASH;Lo;0;L;;;;;N;;;;; +2D5C;TIFINAGH LETTER YAT;Lo;0;L;;;;;N;;;;; +2D5D;TIFINAGH LETTER YATH;Lo;0;L;;;;;N;;;;; +2D5E;TIFINAGH LETTER YACH;Lo;0;L;;;;;N;;;;; +2D5F;TIFINAGH LETTER YATT;Lo;0;L;;;;;N;;;;; +2D60;TIFINAGH LETTER YAV;Lo;0;L;;;;;N;;;;; +2D61;TIFINAGH LETTER YAW;Lo;0;L;;;;;N;;;;; +2D62;TIFINAGH LETTER YAY;Lo;0;L;;;;;N;;;;; +2D63;TIFINAGH LETTER YAZ;Lo;0;L;;;;;N;;;;; +2D64;TIFINAGH LETTER TAWELLEMET YAZ;Lo;0;L;;;;;N;;;;; +2D65;TIFINAGH LETTER YAZZ;Lo;0;L;;;;;N;;;;; +2D6F;TIFINAGH MODIFIER LETTER LABIALIZATION MARK;Lm;0;L; 2D61;;;;N;;;;; +2D80;ETHIOPIC SYLLABLE LOA;Lo;0;L;;;;;N;;;;; +2D81;ETHIOPIC SYLLABLE MOA;Lo;0;L;;;;;N;;;;; +2D82;ETHIOPIC SYLLABLE ROA;Lo;0;L;;;;;N;;;;; +2D83;ETHIOPIC SYLLABLE SOA;Lo;0;L;;;;;N;;;;; +2D84;ETHIOPIC SYLLABLE SHOA;Lo;0;L;;;;;N;;;;; +2D85;ETHIOPIC SYLLABLE BOA;Lo;0;L;;;;;N;;;;; +2D86;ETHIOPIC SYLLABLE TOA;Lo;0;L;;;;;N;;;;; +2D87;ETHIOPIC SYLLABLE COA;Lo;0;L;;;;;N;;;;; +2D88;ETHIOPIC SYLLABLE NOA;Lo;0;L;;;;;N;;;;; +2D89;ETHIOPIC SYLLABLE NYOA;Lo;0;L;;;;;N;;;;; +2D8A;ETHIOPIC SYLLABLE GLOTTAL OA;Lo;0;L;;;;;N;;;;; +2D8B;ETHIOPIC SYLLABLE ZOA;Lo;0;L;;;;;N;;;;; +2D8C;ETHIOPIC SYLLABLE DOA;Lo;0;L;;;;;N;;;;; +2D8D;ETHIOPIC SYLLABLE DDOA;Lo;0;L;;;;;N;;;;; +2D8E;ETHIOPIC SYLLABLE JOA;Lo;0;L;;;;;N;;;;; +2D8F;ETHIOPIC SYLLABLE THOA;Lo;0;L;;;;;N;;;;; +2D90;ETHIOPIC SYLLABLE CHOA;Lo;0;L;;;;;N;;;;; +2D91;ETHIOPIC SYLLABLE PHOA;Lo;0;L;;;;;N;;;;; +2D92;ETHIOPIC SYLLABLE POA;Lo;0;L;;;;;N;;;;; +2D93;ETHIOPIC SYLLABLE GGWA;Lo;0;L;;;;;N;;;;; +2D94;ETHIOPIC SYLLABLE GGWI;Lo;0;L;;;;;N;;;;; +2D95;ETHIOPIC SYLLABLE GGWEE;Lo;0;L;;;;;N;;;;; +2D96;ETHIOPIC SYLLABLE GGWE;Lo;0;L;;;;;N;;;;; +2DA0;ETHIOPIC SYLLABLE SSA;Lo;0;L;;;;;N;;;;; +2DA1;ETHIOPIC SYLLABLE SSU;Lo;0;L;;;;;N;;;;; +2DA2;ETHIOPIC SYLLABLE SSI;Lo;0;L;;;;;N;;;;; +2DA3;ETHIOPIC SYLLABLE SSAA;Lo;0;L;;;;;N;;;;; +2DA4;ETHIOPIC SYLLABLE SSEE;Lo;0;L;;;;;N;;;;; +2DA5;ETHIOPIC SYLLABLE SSE;Lo;0;L;;;;;N;;;;; +2DA6;ETHIOPIC SYLLABLE SSO;Lo;0;L;;;;;N;;;;; +2DA8;ETHIOPIC SYLLABLE CCA;Lo;0;L;;;;;N;;;;; +2DA9;ETHIOPIC SYLLABLE CCU;Lo;0;L;;;;;N;;;;; +2DAA;ETHIOPIC SYLLABLE CCI;Lo;0;L;;;;;N;;;;; +2DAB;ETHIOPIC SYLLABLE CCAA;Lo;0;L;;;;;N;;;;; +2DAC;ETHIOPIC SYLLABLE CCEE;Lo;0;L;;;;;N;;;;; +2DAD;ETHIOPIC SYLLABLE CCE;Lo;0;L;;;;;N;;;;; +2DAE;ETHIOPIC SYLLABLE CCO;Lo;0;L;;;;;N;;;;; +2DB0;ETHIOPIC SYLLABLE ZZA;Lo;0;L;;;;;N;;;;; +2DB1;ETHIOPIC SYLLABLE ZZU;Lo;0;L;;;;;N;;;;; +2DB2;ETHIOPIC SYLLABLE ZZI;Lo;0;L;;;;;N;;;;; +2DB3;ETHIOPIC SYLLABLE ZZAA;Lo;0;L;;;;;N;;;;; +2DB4;ETHIOPIC SYLLABLE ZZEE;Lo;0;L;;;;;N;;;;; +2DB5;ETHIOPIC SYLLABLE ZZE;Lo;0;L;;;;;N;;;;; +2DB6;ETHIOPIC SYLLABLE ZZO;Lo;0;L;;;;;N;;;;; +2DB8;ETHIOPIC SYLLABLE CCHA;Lo;0;L;;;;;N;;;;; +2DB9;ETHIOPIC SYLLABLE CCHU;Lo;0;L;;;;;N;;;;; +2DBA;ETHIOPIC SYLLABLE CCHI;Lo;0;L;;;;;N;;;;; +2DBB;ETHIOPIC SYLLABLE CCHAA;Lo;0;L;;;;;N;;;;; +2DBC;ETHIOPIC SYLLABLE CCHEE;Lo;0;L;;;;;N;;;;; +2DBD;ETHIOPIC SYLLABLE CCHE;Lo;0;L;;;;;N;;;;; +2DBE;ETHIOPIC SYLLABLE CCHO;Lo;0;L;;;;;N;;;;; +2DC0;ETHIOPIC SYLLABLE QYA;Lo;0;L;;;;;N;;;;; +2DC1;ETHIOPIC SYLLABLE QYU;Lo;0;L;;;;;N;;;;; +2DC2;ETHIOPIC SYLLABLE QYI;Lo;0;L;;;;;N;;;;; +2DC3;ETHIOPIC SYLLABLE QYAA;Lo;0;L;;;;;N;;;;; +2DC4;ETHIOPIC SYLLABLE QYEE;Lo;0;L;;;;;N;;;;; +2DC5;ETHIOPIC SYLLABLE QYE;Lo;0;L;;;;;N;;;;; +2DC6;ETHIOPIC SYLLABLE QYO;Lo;0;L;;;;;N;;;;; +2DC8;ETHIOPIC SYLLABLE KYA;Lo;0;L;;;;;N;;;;; +2DC9;ETHIOPIC SYLLABLE KYU;Lo;0;L;;;;;N;;;;; +2DCA;ETHIOPIC SYLLABLE KYI;Lo;0;L;;;;;N;;;;; +2DCB;ETHIOPIC SYLLABLE KYAA;Lo;0;L;;;;;N;;;;; +2DCC;ETHIOPIC SYLLABLE KYEE;Lo;0;L;;;;;N;;;;; +2DCD;ETHIOPIC SYLLABLE KYE;Lo;0;L;;;;;N;;;;; +2DCE;ETHIOPIC SYLLABLE KYO;Lo;0;L;;;;;N;;;;; +2DD0;ETHIOPIC SYLLABLE XYA;Lo;0;L;;;;;N;;;;; +2DD1;ETHIOPIC SYLLABLE XYU;Lo;0;L;;;;;N;;;;; +2DD2;ETHIOPIC SYLLABLE XYI;Lo;0;L;;;;;N;;;;; +2DD3;ETHIOPIC SYLLABLE XYAA;Lo;0;L;;;;;N;;;;; +2DD4;ETHIOPIC SYLLABLE XYEE;Lo;0;L;;;;;N;;;;; +2DD5;ETHIOPIC SYLLABLE XYE;Lo;0;L;;;;;N;;;;; +2DD6;ETHIOPIC SYLLABLE XYO;Lo;0;L;;;;;N;;;;; +2DD8;ETHIOPIC SYLLABLE GYA;Lo;0;L;;;;;N;;;;; +2DD9;ETHIOPIC SYLLABLE GYU;Lo;0;L;;;;;N;;;;; +2DDA;ETHIOPIC SYLLABLE GYI;Lo;0;L;;;;;N;;;;; +2DDB;ETHIOPIC SYLLABLE GYAA;Lo;0;L;;;;;N;;;;; +2DDC;ETHIOPIC SYLLABLE GYEE;Lo;0;L;;;;;N;;;;; +2DDD;ETHIOPIC SYLLABLE GYE;Lo;0;L;;;;;N;;;;; +2DDE;ETHIOPIC SYLLABLE GYO;Lo;0;L;;;;;N;;;;; +2DE0;COMBINING CYRILLIC LETTER BE;Mn;230;NSM;;;;;N;;;;; +2DE1;COMBINING CYRILLIC LETTER VE;Mn;230;NSM;;;;;N;;;;; +2DE2;COMBINING CYRILLIC LETTER GHE;Mn;230;NSM;;;;;N;;;;; +2DE3;COMBINING CYRILLIC LETTER DE;Mn;230;NSM;;;;;N;;;;; +2DE4;COMBINING CYRILLIC LETTER ZHE;Mn;230;NSM;;;;;N;;;;; +2DE5;COMBINING CYRILLIC LETTER ZE;Mn;230;NSM;;;;;N;;;;; +2DE6;COMBINING CYRILLIC LETTER KA;Mn;230;NSM;;;;;N;;;;; +2DE7;COMBINING CYRILLIC LETTER EL;Mn;230;NSM;;;;;N;;;;; +2DE8;COMBINING CYRILLIC LETTER EM;Mn;230;NSM;;;;;N;;;;; +2DE9;COMBINING CYRILLIC LETTER EN;Mn;230;NSM;;;;;N;;;;; +2DEA;COMBINING CYRILLIC LETTER O;Mn;230;NSM;;;;;N;;;;; +2DEB;COMBINING CYRILLIC LETTER PE;Mn;230;NSM;;;;;N;;;;; +2DEC;COMBINING CYRILLIC LETTER ER;Mn;230;NSM;;;;;N;;;;; +2DED;COMBINING CYRILLIC LETTER ES;Mn;230;NSM;;;;;N;;;;; +2DEE;COMBINING CYRILLIC LETTER TE;Mn;230;NSM;;;;;N;;;;; +2DEF;COMBINING CYRILLIC LETTER HA;Mn;230;NSM;;;;;N;;;;; +2DF0;COMBINING CYRILLIC LETTER TSE;Mn;230;NSM;;;;;N;;;;; +2DF1;COMBINING CYRILLIC LETTER CHE;Mn;230;NSM;;;;;N;;;;; +2DF2;COMBINING CYRILLIC LETTER SHA;Mn;230;NSM;;;;;N;;;;; +2DF3;COMBINING CYRILLIC LETTER SHCHA;Mn;230;NSM;;;;;N;;;;; +2DF4;COMBINING CYRILLIC LETTER FITA;Mn;230;NSM;;;;;N;;;;; +2DF5;COMBINING CYRILLIC LETTER ES-TE;Mn;230;NSM;;;;;N;;;;; +2DF6;COMBINING CYRILLIC LETTER A;Mn;230;NSM;;;;;N;;;;; +2DF7;COMBINING CYRILLIC LETTER IE;Mn;230;NSM;;;;;N;;;;; +2DF8;COMBINING CYRILLIC LETTER DJERV;Mn;230;NSM;;;;;N;;;;; +2DF9;COMBINING CYRILLIC LETTER MONOGRAPH UK;Mn;230;NSM;;;;;N;;;;; +2DFA;COMBINING CYRILLIC LETTER YAT;Mn;230;NSM;;;;;N;;;;; +2DFB;COMBINING CYRILLIC LETTER YU;Mn;230;NSM;;;;;N;;;;; +2DFC;COMBINING CYRILLIC LETTER IOTIFIED A;Mn;230;NSM;;;;;N;;;;; +2DFD;COMBINING CYRILLIC LETTER LITTLE YUS;Mn;230;NSM;;;;;N;;;;; +2DFE;COMBINING CYRILLIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;; +2DFF;COMBINING CYRILLIC LETTER IOTIFIED BIG YUS;Mn;230;NSM;;;;;N;;;;; +2E00;RIGHT ANGLE SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;; +2E01;RIGHT ANGLE DOTTED SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;; +2E02;LEFT SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;; +2E03;RIGHT SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;; +2E04;LEFT DOTTED SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;; +2E05;RIGHT DOTTED SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;; +2E06;RAISED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;; +2E07;RAISED DOTTED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;; +2E08;DOTTED TRANSPOSITION MARKER;Po;0;ON;;;;;N;;;;; +2E09;LEFT TRANSPOSITION BRACKET;Pi;0;ON;;;;;Y;;;;; +2E0A;RIGHT TRANSPOSITION BRACKET;Pf;0;ON;;;;;Y;;;;; +2E0B;RAISED SQUARE;Po;0;ON;;;;;N;;;;; +2E0C;LEFT RAISED OMISSION BRACKET;Pi;0;ON;;;;;Y;;;;; +2E0D;RIGHT RAISED OMISSION BRACKET;Pf;0;ON;;;;;Y;;;;; +2E0E;EDITORIAL CORONIS;Po;0;ON;;;;;N;;;;; +2E0F;PARAGRAPHOS;Po;0;ON;;;;;N;;;;; +2E10;FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;; +2E11;REVERSED FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;; +2E12;HYPODIASTOLE;Po;0;ON;;;;;N;;;;; +2E13;DOTTED OBELOS;Po;0;ON;;;;;N;;;;; +2E14;DOWNWARDS ANCORA;Po;0;ON;;;;;N;;;;; +2E15;UPWARDS ANCORA;Po;0;ON;;;;;N;;;;; +2E16;DOTTED RIGHT-POINTING ANGLE;Po;0;ON;;;;;N;;;;; +2E17;DOUBLE OBLIQUE HYPHEN;Pd;0;ON;;;;;N;;;;; +2E18;INVERTED INTERROBANG;Po;0;ON;;;;;N;;;;; +2E19;PALM BRANCH;Po;0;ON;;;;;N;;;;; +2E1A;HYPHEN WITH DIAERESIS;Pd;0;ON;;;;;N;;;;; +2E1B;TILDE WITH RING ABOVE;Po;0;ON;;;;;N;;;;; +2E1C;LEFT LOW PARAPHRASE BRACKET;Pi;0;ON;;;;;Y;;;;; +2E1D;RIGHT LOW PARAPHRASE BRACKET;Pf;0;ON;;;;;Y;;;;; +2E1E;TILDE WITH DOT ABOVE;Po;0;ON;;;;;N;;;;; +2E1F;TILDE WITH DOT BELOW;Po;0;ON;;;;;N;;;;; +2E20;LEFT VERTICAL BAR WITH QUILL;Pi;0;ON;;;;;Y;;;;; +2E21;RIGHT VERTICAL BAR WITH QUILL;Pf;0;ON;;;;;Y;;;;; +2E22;TOP LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;; +2E23;TOP RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;; +2E24;BOTTOM LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;; +2E25;BOTTOM RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;; +2E26;LEFT SIDEWAYS U BRACKET;Ps;0;ON;;;;;Y;;;;; +2E27;RIGHT SIDEWAYS U BRACKET;Pe;0;ON;;;;;Y;;;;; +2E28;LEFT DOUBLE PARENTHESIS;Ps;0;ON;;;;;Y;;;;; +2E29;RIGHT DOUBLE PARENTHESIS;Pe;0;ON;;;;;Y;;;;; +2E2A;TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +2E2B;ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;; +2E2C;SQUARED FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +2E2D;FIVE DOT MARK;Po;0;ON;;;;;N;;;;; +2E2E;REVERSED QUESTION MARK;Po;0;ON;;;;;N;;;;; +2E2F;VERTICAL TILDE;Lm;0;ON;;;;;N;;;;; +2E30;RING POINT;Po;0;ON;;;;;N;;;;; +2E31;WORD SEPARATOR MIDDLE DOT;Po;0;ON;;;;;N;;;;; +2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;; +2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;; +2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;; +2E83;CJK RADICAL SECOND TWO;So;0;ON;;;;;N;;;;; +2E84;CJK RADICAL SECOND THREE;So;0;ON;;;;;N;;;;; +2E85;CJK RADICAL PERSON;So;0;ON;;;;;N;;;;; +2E86;CJK RADICAL BOX;So;0;ON;;;;;N;;;;; +2E87;CJK RADICAL TABLE;So;0;ON;;;;;N;;;;; +2E88;CJK RADICAL KNIFE ONE;So;0;ON;;;;;N;;;;; +2E89;CJK RADICAL KNIFE TWO;So;0;ON;;;;;N;;;;; +2E8A;CJK RADICAL DIVINATION;So;0;ON;;;;;N;;;;; +2E8B;CJK RADICAL SEAL;So;0;ON;;;;;N;;;;; +2E8C;CJK RADICAL SMALL ONE;So;0;ON;;;;;N;;;;; +2E8D;CJK RADICAL SMALL TWO;So;0;ON;;;;;N;;;;; +2E8E;CJK RADICAL LAME ONE;So;0;ON;;;;;N;;;;; +2E8F;CJK RADICAL LAME TWO;So;0;ON;;;;;N;;;;; +2E90;CJK RADICAL LAME THREE;So;0;ON;;;;;N;;;;; +2E91;CJK RADICAL LAME FOUR;So;0;ON;;;;;N;;;;; +2E92;CJK RADICAL SNAKE;So;0;ON;;;;;N;;;;; +2E93;CJK RADICAL THREAD;So;0;ON;;;;;N;;;;; +2E94;CJK RADICAL SNOUT ONE;So;0;ON;;;;;N;;;;; +2E95;CJK RADICAL SNOUT TWO;So;0;ON;;;;;N;;;;; +2E96;CJK RADICAL HEART ONE;So;0;ON;;;;;N;;;;; +2E97;CJK RADICAL HEART TWO;So;0;ON;;;;;N;;;;; +2E98;CJK RADICAL HAND;So;0;ON;;;;;N;;;;; +2E99;CJK RADICAL RAP;So;0;ON;;;;;N;;;;; +2E9B;CJK RADICAL CHOKE;So;0;ON;;;;;N;;;;; +2E9C;CJK RADICAL SUN;So;0;ON;;;;;N;;;;; +2E9D;CJK RADICAL MOON;So;0;ON;;;;;N;;;;; +2E9E;CJK RADICAL DEATH;So;0;ON;;;;;N;;;;; +2E9F;CJK RADICAL MOTHER;So;0;ON; 6BCD;;;;N;;;;; +2EA0;CJK RADICAL CIVILIAN;So;0;ON;;;;;N;;;;; +2EA1;CJK RADICAL WATER ONE;So;0;ON;;;;;N;;;;; +2EA2;CJK RADICAL WATER TWO;So;0;ON;;;;;N;;;;; +2EA3;CJK RADICAL FIRE;So;0;ON;;;;;N;;;;; +2EA4;CJK RADICAL PAW ONE;So;0;ON;;;;;N;;;;; +2EA5;CJK RADICAL PAW TWO;So;0;ON;;;;;N;;;;; +2EA6;CJK RADICAL SIMPLIFIED HALF TREE TRUNK;So;0;ON;;;;;N;;;;; +2EA7;CJK RADICAL COW;So;0;ON;;;;;N;;;;; +2EA8;CJK RADICAL DOG;So;0;ON;;;;;N;;;;; +2EA9;CJK RADICAL JADE;So;0;ON;;;;;N;;;;; +2EAA;CJK RADICAL BOLT OF CLOTH;So;0;ON;;;;;N;;;;; +2EAB;CJK RADICAL EYE;So;0;ON;;;;;N;;;;; +2EAC;CJK RADICAL SPIRIT ONE;So;0;ON;;;;;N;;;;; +2EAD;CJK RADICAL SPIRIT TWO;So;0;ON;;;;;N;;;;; +2EAE;CJK RADICAL BAMBOO;So;0;ON;;;;;N;;;;; +2EAF;CJK RADICAL SILK;So;0;ON;;;;;N;;;;; +2EB0;CJK RADICAL C-SIMPLIFIED SILK;So;0;ON;;;;;N;;;;; +2EB1;CJK RADICAL NET ONE;So;0;ON;;;;;N;;;;; +2EB2;CJK RADICAL NET TWO;So;0;ON;;;;;N;;;;; +2EB3;CJK RADICAL NET THREE;So;0;ON;;;;;N;;;;; +2EB4;CJK RADICAL NET FOUR;So;0;ON;;;;;N;;;;; +2EB5;CJK RADICAL MESH;So;0;ON;;;;;N;;;;; +2EB6;CJK RADICAL SHEEP;So;0;ON;;;;;N;;;;; +2EB7;CJK RADICAL RAM;So;0;ON;;;;;N;;;;; +2EB8;CJK RADICAL EWE;So;0;ON;;;;;N;;;;; +2EB9;CJK RADICAL OLD;So;0;ON;;;;;N;;;;; +2EBA;CJK RADICAL BRUSH ONE;So;0;ON;;;;;N;;;;; +2EBB;CJK RADICAL BRUSH TWO;So;0;ON;;;;;N;;;;; +2EBC;CJK RADICAL MEAT;So;0;ON;;;;;N;;;;; +2EBD;CJK RADICAL MORTAR;So;0;ON;;;;;N;;;;; +2EBE;CJK RADICAL GRASS ONE;So;0;ON;;;;;N;;;;; +2EBF;CJK RADICAL GRASS TWO;So;0;ON;;;;;N;;;;; +2EC0;CJK RADICAL GRASS THREE;So;0;ON;;;;;N;;;;; +2EC1;CJK RADICAL TIGER;So;0;ON;;;;;N;;;;; +2EC2;CJK RADICAL CLOTHES;So;0;ON;;;;;N;;;;; +2EC3;CJK RADICAL WEST ONE;So;0;ON;;;;;N;;;;; +2EC4;CJK RADICAL WEST TWO;So;0;ON;;;;;N;;;;; +2EC5;CJK RADICAL C-SIMPLIFIED SEE;So;0;ON;;;;;N;;;;; +2EC6;CJK RADICAL SIMPLIFIED HORN;So;0;ON;;;;;N;;;;; +2EC7;CJK RADICAL HORN;So;0;ON;;;;;N;;;;; +2EC8;CJK RADICAL C-SIMPLIFIED SPEECH;So;0;ON;;;;;N;;;;; +2EC9;CJK RADICAL C-SIMPLIFIED SHELL;So;0;ON;;;;;N;;;;; +2ECA;CJK RADICAL FOOT;So;0;ON;;;;;N;;;;; +2ECB;CJK RADICAL C-SIMPLIFIED CART;So;0;ON;;;;;N;;;;; +2ECC;CJK RADICAL SIMPLIFIED WALK;So;0;ON;;;;;N;;;;; +2ECD;CJK RADICAL WALK ONE;So;0;ON;;;;;N;;;;; +2ECE;CJK RADICAL WALK TWO;So;0;ON;;;;;N;;;;; +2ECF;CJK RADICAL CITY;So;0;ON;;;;;N;;;;; +2ED0;CJK RADICAL C-SIMPLIFIED GOLD;So;0;ON;;;;;N;;;;; +2ED1;CJK RADICAL LONG ONE;So;0;ON;;;;;N;;;;; +2ED2;CJK RADICAL LONG TWO;So;0;ON;;;;;N;;;;; +2ED3;CJK RADICAL C-SIMPLIFIED LONG;So;0;ON;;;;;N;;;;; +2ED4;CJK RADICAL C-SIMPLIFIED GATE;So;0;ON;;;;;N;;;;; +2ED5;CJK RADICAL MOUND ONE;So;0;ON;;;;;N;;;;; +2ED6;CJK RADICAL MOUND TWO;So;0;ON;;;;;N;;;;; +2ED7;CJK RADICAL RAIN;So;0;ON;;;;;N;;;;; +2ED8;CJK RADICAL BLUE;So;0;ON;;;;;N;;;;; +2ED9;CJK RADICAL C-SIMPLIFIED TANNED LEATHER;So;0;ON;;;;;N;;;;; +2EDA;CJK RADICAL C-SIMPLIFIED LEAF;So;0;ON;;;;;N;;;;; +2EDB;CJK RADICAL C-SIMPLIFIED WIND;So;0;ON;;;;;N;;;;; +2EDC;CJK RADICAL C-SIMPLIFIED FLY;So;0;ON;;;;;N;;;;; +2EDD;CJK RADICAL EAT ONE;So;0;ON;;;;;N;;;;; +2EDE;CJK RADICAL EAT TWO;So;0;ON;;;;;N;;;;; +2EDF;CJK RADICAL EAT THREE;So;0;ON;;;;;N;;;;; +2EE0;CJK RADICAL C-SIMPLIFIED EAT;So;0;ON;;;;;N;;;;; +2EE1;CJK RADICAL HEAD;So;0;ON;;;;;N;;;;; +2EE2;CJK RADICAL C-SIMPLIFIED HORSE;So;0;ON;;;;;N;;;;; +2EE3;CJK RADICAL BONE;So;0;ON;;;;;N;;;;; +2EE4;CJK RADICAL GHOST;So;0;ON;;;;;N;;;;; +2EE5;CJK RADICAL C-SIMPLIFIED FISH;So;0;ON;;;;;N;;;;; +2EE6;CJK RADICAL C-SIMPLIFIED BIRD;So;0;ON;;;;;N;;;;; +2EE7;CJK RADICAL C-SIMPLIFIED SALT;So;0;ON;;;;;N;;;;; +2EE8;CJK RADICAL SIMPLIFIED WHEAT;So;0;ON;;;;;N;;;;; +2EE9;CJK RADICAL SIMPLIFIED YELLOW;So;0;ON;;;;;N;;;;; +2EEA;CJK RADICAL C-SIMPLIFIED FROG;So;0;ON;;;;;N;;;;; +2EEB;CJK RADICAL J-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;; +2EEC;CJK RADICAL C-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;; +2EED;CJK RADICAL J-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;; +2EEE;CJK RADICAL C-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;; +2EEF;CJK RADICAL J-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;; +2EF0;CJK RADICAL C-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;; +2EF1;CJK RADICAL TURTLE;So;0;ON;;;;;N;;;;; +2EF2;CJK RADICAL J-SIMPLIFIED TURTLE;So;0;ON;;;;;N;;;;; +2EF3;CJK RADICAL C-SIMPLIFIED TURTLE;So;0;ON; 9F9F;;;;N;;;;; +2F00;KANGXI RADICAL ONE;So;0;ON; 4E00;;;;N;;;;; +2F01;KANGXI RADICAL LINE;So;0;ON; 4E28;;;;N;;;;; +2F02;KANGXI RADICAL DOT;So;0;ON; 4E36;;;;N;;;;; +2F03;KANGXI RADICAL SLASH;So;0;ON; 4E3F;;;;N;;;;; +2F04;KANGXI RADICAL SECOND;So;0;ON; 4E59;;;;N;;;;; +2F05;KANGXI RADICAL HOOK;So;0;ON; 4E85;;;;N;;;;; +2F06;KANGXI RADICAL TWO;So;0;ON; 4E8C;;;;N;;;;; +2F07;KANGXI RADICAL LID;So;0;ON; 4EA0;;;;N;;;;; +2F08;KANGXI RADICAL MAN;So;0;ON; 4EBA;;;;N;;;;; +2F09;KANGXI RADICAL LEGS;So;0;ON; 513F;;;;N;;;;; +2F0A;KANGXI RADICAL ENTER;So;0;ON; 5165;;;;N;;;;; +2F0B;KANGXI RADICAL EIGHT;So;0;ON; 516B;;;;N;;;;; +2F0C;KANGXI RADICAL DOWN BOX;So;0;ON; 5182;;;;N;;;;; +2F0D;KANGXI RADICAL COVER;So;0;ON; 5196;;;;N;;;;; +2F0E;KANGXI RADICAL ICE;So;0;ON; 51AB;;;;N;;;;; +2F0F;KANGXI RADICAL TABLE;So;0;ON; 51E0;;;;N;;;;; +2F10;KANGXI RADICAL OPEN BOX;So;0;ON; 51F5;;;;N;;;;; +2F11;KANGXI RADICAL KNIFE;So;0;ON; 5200;;;;N;;;;; +2F12;KANGXI RADICAL POWER;So;0;ON; 529B;;;;N;;;;; +2F13;KANGXI RADICAL WRAP;So;0;ON; 52F9;;;;N;;;;; +2F14;KANGXI RADICAL SPOON;So;0;ON; 5315;;;;N;;;;; +2F15;KANGXI RADICAL RIGHT OPEN BOX;So;0;ON; 531A;;;;N;;;;; +2F16;KANGXI RADICAL HIDING ENCLOSURE;So;0;ON; 5338;;;;N;;;;; +2F17;KANGXI RADICAL TEN;So;0;ON; 5341;;;;N;;;;; +2F18;KANGXI RADICAL DIVINATION;So;0;ON; 535C;;;;N;;;;; +2F19;KANGXI RADICAL SEAL;So;0;ON; 5369;;;;N;;;;; +2F1A;KANGXI RADICAL CLIFF;So;0;ON; 5382;;;;N;;;;; +2F1B;KANGXI RADICAL PRIVATE;So;0;ON; 53B6;;;;N;;;;; +2F1C;KANGXI RADICAL AGAIN;So;0;ON; 53C8;;;;N;;;;; +2F1D;KANGXI RADICAL MOUTH;So;0;ON; 53E3;;;;N;;;;; +2F1E;KANGXI RADICAL ENCLOSURE;So;0;ON; 56D7;;;;N;;;;; +2F1F;KANGXI RADICAL EARTH;So;0;ON; 571F;;;;N;;;;; +2F20;KANGXI RADICAL SCHOLAR;So;0;ON; 58EB;;;;N;;;;; +2F21;KANGXI RADICAL GO;So;0;ON; 5902;;;;N;;;;; +2F22;KANGXI RADICAL GO SLOWLY;So;0;ON; 590A;;;;N;;;;; +2F23;KANGXI RADICAL EVENING;So;0;ON; 5915;;;;N;;;;; +2F24;KANGXI RADICAL BIG;So;0;ON; 5927;;;;N;;;;; +2F25;KANGXI RADICAL WOMAN;So;0;ON; 5973;;;;N;;;;; +2F26;KANGXI RADICAL CHILD;So;0;ON; 5B50;;;;N;;;;; +2F27;KANGXI RADICAL ROOF;So;0;ON; 5B80;;;;N;;;;; +2F28;KANGXI RADICAL INCH;So;0;ON; 5BF8;;;;N;;;;; +2F29;KANGXI RADICAL SMALL;So;0;ON; 5C0F;;;;N;;;;; +2F2A;KANGXI RADICAL LAME;So;0;ON; 5C22;;;;N;;;;; +2F2B;KANGXI RADICAL CORPSE;So;0;ON; 5C38;;;;N;;;;; +2F2C;KANGXI RADICAL SPROUT;So;0;ON; 5C6E;;;;N;;;;; +2F2D;KANGXI RADICAL MOUNTAIN;So;0;ON; 5C71;;;;N;;;;; +2F2E;KANGXI RADICAL RIVER;So;0;ON; 5DDB;;;;N;;;;; +2F2F;KANGXI RADICAL WORK;So;0;ON; 5DE5;;;;N;;;;; +2F30;KANGXI RADICAL ONESELF;So;0;ON; 5DF1;;;;N;;;;; +2F31;KANGXI RADICAL TURBAN;So;0;ON; 5DFE;;;;N;;;;; +2F32;KANGXI RADICAL DRY;So;0;ON; 5E72;;;;N;;;;; +2F33;KANGXI RADICAL SHORT THREAD;So;0;ON; 5E7A;;;;N;;;;; +2F34;KANGXI RADICAL DOTTED CLIFF;So;0;ON; 5E7F;;;;N;;;;; +2F35;KANGXI RADICAL LONG STRIDE;So;0;ON; 5EF4;;;;N;;;;; +2F36;KANGXI RADICAL TWO HANDS;So;0;ON; 5EFE;;;;N;;;;; +2F37;KANGXI RADICAL SHOOT;So;0;ON; 5F0B;;;;N;;;;; +2F38;KANGXI RADICAL BOW;So;0;ON; 5F13;;;;N;;;;; +2F39;KANGXI RADICAL SNOUT;So;0;ON; 5F50;;;;N;;;;; +2F3A;KANGXI RADICAL BRISTLE;So;0;ON; 5F61;;;;N;;;;; +2F3B;KANGXI RADICAL STEP;So;0;ON; 5F73;;;;N;;;;; +2F3C;KANGXI RADICAL HEART;So;0;ON; 5FC3;;;;N;;;;; +2F3D;KANGXI RADICAL HALBERD;So;0;ON; 6208;;;;N;;;;; +2F3E;KANGXI RADICAL DOOR;So;0;ON; 6236;;;;N;;;;; +2F3F;KANGXI RADICAL HAND;So;0;ON; 624B;;;;N;;;;; +2F40;KANGXI RADICAL BRANCH;So;0;ON; 652F;;;;N;;;;; +2F41;KANGXI RADICAL RAP;So;0;ON; 6534;;;;N;;;;; +2F42;KANGXI RADICAL SCRIPT;So;0;ON; 6587;;;;N;;;;; +2F43;KANGXI RADICAL DIPPER;So;0;ON; 6597;;;;N;;;;; +2F44;KANGXI RADICAL AXE;So;0;ON; 65A4;;;;N;;;;; +2F45;KANGXI RADICAL SQUARE;So;0;ON; 65B9;;;;N;;;;; +2F46;KANGXI RADICAL NOT;So;0;ON; 65E0;;;;N;;;;; +2F47;KANGXI RADICAL SUN;So;0;ON; 65E5;;;;N;;;;; +2F48;KANGXI RADICAL SAY;So;0;ON; 66F0;;;;N;;;;; +2F49;KANGXI RADICAL MOON;So;0;ON; 6708;;;;N;;;;; +2F4A;KANGXI RADICAL TREE;So;0;ON; 6728;;;;N;;;;; +2F4B;KANGXI RADICAL LACK;So;0;ON; 6B20;;;;N;;;;; +2F4C;KANGXI RADICAL STOP;So;0;ON; 6B62;;;;N;;;;; +2F4D;KANGXI RADICAL DEATH;So;0;ON; 6B79;;;;N;;;;; +2F4E;KANGXI RADICAL WEAPON;So;0;ON; 6BB3;;;;N;;;;; +2F4F;KANGXI RADICAL DO NOT;So;0;ON; 6BCB;;;;N;;;;; +2F50;KANGXI RADICAL COMPARE;So;0;ON; 6BD4;;;;N;;;;; +2F51;KANGXI RADICAL FUR;So;0;ON; 6BDB;;;;N;;;;; +2F52;KANGXI RADICAL CLAN;So;0;ON; 6C0F;;;;N;;;;; +2F53;KANGXI RADICAL STEAM;So;0;ON; 6C14;;;;N;;;;; +2F54;KANGXI RADICAL WATER;So;0;ON; 6C34;;;;N;;;;; +2F55;KANGXI RADICAL FIRE;So;0;ON; 706B;;;;N;;;;; +2F56;KANGXI RADICAL CLAW;So;0;ON; 722A;;;;N;;;;; +2F57;KANGXI RADICAL FATHER;So;0;ON; 7236;;;;N;;;;; +2F58;KANGXI RADICAL DOUBLE X;So;0;ON; 723B;;;;N;;;;; +2F59;KANGXI RADICAL HALF TREE TRUNK;So;0;ON; 723F;;;;N;;;;; +2F5A;KANGXI RADICAL SLICE;So;0;ON; 7247;;;;N;;;;; +2F5B;KANGXI RADICAL FANG;So;0;ON; 7259;;;;N;;;;; +2F5C;KANGXI RADICAL COW;So;0;ON; 725B;;;;N;;;;; +2F5D;KANGXI RADICAL DOG;So;0;ON; 72AC;;;;N;;;;; +2F5E;KANGXI RADICAL PROFOUND;So;0;ON; 7384;;;;N;;;;; +2F5F;KANGXI RADICAL JADE;So;0;ON; 7389;;;;N;;;;; +2F60;KANGXI RADICAL MELON;So;0;ON; 74DC;;;;N;;;;; +2F61;KANGXI RADICAL TILE;So;0;ON; 74E6;;;;N;;;;; +2F62;KANGXI RADICAL SWEET;So;0;ON; 7518;;;;N;;;;; +2F63;KANGXI RADICAL LIFE;So;0;ON; 751F;;;;N;;;;; +2F64;KANGXI RADICAL USE;So;0;ON; 7528;;;;N;;;;; +2F65;KANGXI RADICAL FIELD;So;0;ON; 7530;;;;N;;;;; +2F66;KANGXI RADICAL BOLT OF CLOTH;So;0;ON; 758B;;;;N;;;;; +2F67;KANGXI RADICAL SICKNESS;So;0;ON; 7592;;;;N;;;;; +2F68;KANGXI RADICAL DOTTED TENT;So;0;ON; 7676;;;;N;;;;; +2F69;KANGXI RADICAL WHITE;So;0;ON; 767D;;;;N;;;;; +2F6A;KANGXI RADICAL SKIN;So;0;ON; 76AE;;;;N;;;;; +2F6B;KANGXI RADICAL DISH;So;0;ON; 76BF;;;;N;;;;; +2F6C;KANGXI RADICAL EYE;So;0;ON; 76EE;;;;N;;;;; +2F6D;KANGXI RADICAL SPEAR;So;0;ON; 77DB;;;;N;;;;; +2F6E;KANGXI RADICAL ARROW;So;0;ON; 77E2;;;;N;;;;; +2F6F;KANGXI RADICAL STONE;So;0;ON; 77F3;;;;N;;;;; +2F70;KANGXI RADICAL SPIRIT;So;0;ON; 793A;;;;N;;;;; +2F71;KANGXI RADICAL TRACK;So;0;ON; 79B8;;;;N;;;;; +2F72;KANGXI RADICAL GRAIN;So;0;ON; 79BE;;;;N;;;;; +2F73;KANGXI RADICAL CAVE;So;0;ON; 7A74;;;;N;;;;; +2F74;KANGXI RADICAL STAND;So;0;ON; 7ACB;;;;N;;;;; +2F75;KANGXI RADICAL BAMBOO;So;0;ON; 7AF9;;;;N;;;;; +2F76;KANGXI RADICAL RICE;So;0;ON; 7C73;;;;N;;;;; +2F77;KANGXI RADICAL SILK;So;0;ON; 7CF8;;;;N;;;;; +2F78;KANGXI RADICAL JAR;So;0;ON; 7F36;;;;N;;;;; +2F79;KANGXI RADICAL NET;So;0;ON; 7F51;;;;N;;;;; +2F7A;KANGXI RADICAL SHEEP;So;0;ON; 7F8A;;;;N;;;;; +2F7B;KANGXI RADICAL FEATHER;So;0;ON; 7FBD;;;;N;;;;; +2F7C;KANGXI RADICAL OLD;So;0;ON; 8001;;;;N;;;;; +2F7D;KANGXI RADICAL AND;So;0;ON; 800C;;;;N;;;;; +2F7E;KANGXI RADICAL PLOW;So;0;ON; 8012;;;;N;;;;; +2F7F;KANGXI RADICAL EAR;So;0;ON; 8033;;;;N;;;;; +2F80;KANGXI RADICAL BRUSH;So;0;ON; 807F;;;;N;;;;; +2F81;KANGXI RADICAL MEAT;So;0;ON; 8089;;;;N;;;;; +2F82;KANGXI RADICAL MINISTER;So;0;ON; 81E3;;;;N;;;;; +2F83;KANGXI RADICAL SELF;So;0;ON; 81EA;;;;N;;;;; +2F84;KANGXI RADICAL ARRIVE;So;0;ON; 81F3;;;;N;;;;; +2F85;KANGXI RADICAL MORTAR;So;0;ON; 81FC;;;;N;;;;; +2F86;KANGXI RADICAL TONGUE;So;0;ON; 820C;;;;N;;;;; +2F87;KANGXI RADICAL OPPOSE;So;0;ON; 821B;;;;N;;;;; +2F88;KANGXI RADICAL BOAT;So;0;ON; 821F;;;;N;;;;; +2F89;KANGXI RADICAL STOPPING;So;0;ON; 826E;;;;N;;;;; +2F8A;KANGXI RADICAL COLOR;So;0;ON; 8272;;;;N;;;;; +2F8B;KANGXI RADICAL GRASS;So;0;ON; 8278;;;;N;;;;; +2F8C;KANGXI RADICAL TIGER;So;0;ON; 864D;;;;N;;;;; +2F8D;KANGXI RADICAL INSECT;So;0;ON; 866B;;;;N;;;;; +2F8E;KANGXI RADICAL BLOOD;So;0;ON; 8840;;;;N;;;;; +2F8F;KANGXI RADICAL WALK ENCLOSURE;So;0;ON; 884C;;;;N;;;;; +2F90;KANGXI RADICAL CLOTHES;So;0;ON; 8863;;;;N;;;;; +2F91;KANGXI RADICAL WEST;So;0;ON; 897E;;;;N;;;;; +2F92;KANGXI RADICAL SEE;So;0;ON; 898B;;;;N;;;;; +2F93;KANGXI RADICAL HORN;So;0;ON; 89D2;;;;N;;;;; +2F94;KANGXI RADICAL SPEECH;So;0;ON; 8A00;;;;N;;;;; +2F95;KANGXI RADICAL VALLEY;So;0;ON; 8C37;;;;N;;;;; +2F96;KANGXI RADICAL BEAN;So;0;ON; 8C46;;;;N;;;;; +2F97;KANGXI RADICAL PIG;So;0;ON; 8C55;;;;N;;;;; +2F98;KANGXI RADICAL BADGER;So;0;ON; 8C78;;;;N;;;;; +2F99;KANGXI RADICAL SHELL;So;0;ON; 8C9D;;;;N;;;;; +2F9A;KANGXI RADICAL RED;So;0;ON; 8D64;;;;N;;;;; +2F9B;KANGXI RADICAL RUN;So;0;ON; 8D70;;;;N;;;;; +2F9C;KANGXI RADICAL FOOT;So;0;ON; 8DB3;;;;N;;;;; +2F9D;KANGXI RADICAL BODY;So;0;ON; 8EAB;;;;N;;;;; +2F9E;KANGXI RADICAL CART;So;0;ON; 8ECA;;;;N;;;;; +2F9F;KANGXI RADICAL BITTER;So;0;ON; 8F9B;;;;N;;;;; +2FA0;KANGXI RADICAL MORNING;So;0;ON; 8FB0;;;;N;;;;; +2FA1;KANGXI RADICAL WALK;So;0;ON; 8FB5;;;;N;;;;; +2FA2;KANGXI RADICAL CITY;So;0;ON; 9091;;;;N;;;;; +2FA3;KANGXI RADICAL WINE;So;0;ON; 9149;;;;N;;;;; +2FA4;KANGXI RADICAL DISTINGUISH;So;0;ON; 91C6;;;;N;;;;; +2FA5;KANGXI RADICAL VILLAGE;So;0;ON; 91CC;;;;N;;;;; +2FA6;KANGXI RADICAL GOLD;So;0;ON; 91D1;;;;N;;;;; +2FA7;KANGXI RADICAL LONG;So;0;ON; 9577;;;;N;;;;; +2FA8;KANGXI RADICAL GATE;So;0;ON; 9580;;;;N;;;;; +2FA9;KANGXI RADICAL MOUND;So;0;ON; 961C;;;;N;;;;; +2FAA;KANGXI RADICAL SLAVE;So;0;ON; 96B6;;;;N;;;;; +2FAB;KANGXI RADICAL SHORT TAILED BIRD;So;0;ON; 96B9;;;;N;;;;; +2FAC;KANGXI RADICAL RAIN;So;0;ON; 96E8;;;;N;;;;; +2FAD;KANGXI RADICAL BLUE;So;0;ON; 9751;;;;N;;;;; +2FAE;KANGXI RADICAL WRONG;So;0;ON; 975E;;;;N;;;;; +2FAF;KANGXI RADICAL FACE;So;0;ON; 9762;;;;N;;;;; +2FB0;KANGXI RADICAL LEATHER;So;0;ON; 9769;;;;N;;;;; +2FB1;KANGXI RADICAL TANNED LEATHER;So;0;ON; 97CB;;;;N;;;;; +2FB2;KANGXI RADICAL LEEK;So;0;ON; 97ED;;;;N;;;;; +2FB3;KANGXI RADICAL SOUND;So;0;ON; 97F3;;;;N;;;;; +2FB4;KANGXI RADICAL LEAF;So;0;ON; 9801;;;;N;;;;; +2FB5;KANGXI RADICAL WIND;So;0;ON; 98A8;;;;N;;;;; +2FB6;KANGXI RADICAL FLY;So;0;ON; 98DB;;;;N;;;;; +2FB7;KANGXI RADICAL EAT;So;0;ON; 98DF;;;;N;;;;; +2FB8;KANGXI RADICAL HEAD;So;0;ON; 9996;;;;N;;;;; +2FB9;KANGXI RADICAL FRAGRANT;So;0;ON; 9999;;;;N;;;;; +2FBA;KANGXI RADICAL HORSE;So;0;ON; 99AC;;;;N;;;;; +2FBB;KANGXI RADICAL BONE;So;0;ON; 9AA8;;;;N;;;;; +2FBC;KANGXI RADICAL TALL;So;0;ON; 9AD8;;;;N;;;;; +2FBD;KANGXI RADICAL HAIR;So;0;ON; 9ADF;;;;N;;;;; +2FBE;KANGXI RADICAL FIGHT;So;0;ON; 9B25;;;;N;;;;; +2FBF;KANGXI RADICAL SACRIFICIAL WINE;So;0;ON; 9B2F;;;;N;;;;; +2FC0;KANGXI RADICAL CAULDRON;So;0;ON; 9B32;;;;N;;;;; +2FC1;KANGXI RADICAL GHOST;So;0;ON; 9B3C;;;;N;;;;; +2FC2;KANGXI RADICAL FISH;So;0;ON; 9B5A;;;;N;;;;; +2FC3;KANGXI RADICAL BIRD;So;0;ON; 9CE5;;;;N;;;;; +2FC4;KANGXI RADICAL SALT;So;0;ON; 9E75;;;;N;;;;; +2FC5;KANGXI RADICAL DEER;So;0;ON; 9E7F;;;;N;;;;; +2FC6;KANGXI RADICAL WHEAT;So;0;ON; 9EA5;;;;N;;;;; +2FC7;KANGXI RADICAL HEMP;So;0;ON; 9EBB;;;;N;;;;; +2FC8;KANGXI RADICAL YELLOW;So;0;ON; 9EC3;;;;N;;;;; +2FC9;KANGXI RADICAL MILLET;So;0;ON; 9ECD;;;;N;;;;; +2FCA;KANGXI RADICAL BLACK;So;0;ON; 9ED1;;;;N;;;;; +2FCB;KANGXI RADICAL EMBROIDERY;So;0;ON; 9EF9;;;;N;;;;; +2FCC;KANGXI RADICAL FROG;So;0;ON; 9EFD;;;;N;;;;; +2FCD;KANGXI RADICAL TRIPOD;So;0;ON; 9F0E;;;;N;;;;; +2FCE;KANGXI RADICAL DRUM;So;0;ON; 9F13;;;;N;;;;; +2FCF;KANGXI RADICAL RAT;So;0;ON; 9F20;;;;N;;;;; +2FD0;KANGXI RADICAL NOSE;So;0;ON; 9F3B;;;;N;;;;; +2FD1;KANGXI RADICAL EVEN;So;0;ON; 9F4A;;;;N;;;;; +2FD2;KANGXI RADICAL TOOTH;So;0;ON; 9F52;;;;N;;;;; +2FD3;KANGXI RADICAL DRAGON;So;0;ON; 9F8D;;;;N;;;;; +2FD4;KANGXI RADICAL TURTLE;So;0;ON; 9F9C;;;;N;;;;; +2FD5;KANGXI RADICAL FLUTE;So;0;ON; 9FA0;;;;N;;;;; +2FF0;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT;So;0;ON;;;;;N;;;;; +2FF1;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW;So;0;ON;;;;;N;;;;; +2FF2;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT;So;0;ON;;;;;N;;;;; +2FF3;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW;So;0;ON;;;;;N;;;;; +2FF4;IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND;So;0;ON;;;;;N;;;;; +2FF5;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE;So;0;ON;;;;;N;;;;; +2FF6;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW;So;0;ON;;;;;N;;;;; +2FF7;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT;So;0;ON;;;;;N;;;;; +2FF8;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT;So;0;ON;;;;;N;;;;; +2FF9;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT;So;0;ON;;;;;N;;;;; +2FFA;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT;So;0;ON;;;;;N;;;;; +2FFB;IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID;So;0;ON;;;;;N;;;;; +3000;IDEOGRAPHIC SPACE;Zs;0;WS; 0020;;;;N;;;;; +3001;IDEOGRAPHIC COMMA;Po;0;ON;;;;;N;;;;; +3002;IDEOGRAPHIC FULL STOP;Po;0;ON;;;;;N;IDEOGRAPHIC PERIOD;;;; +3003;DITTO MARK;Po;0;ON;;;;;N;;;;; +3004;JAPANESE INDUSTRIAL STANDARD SYMBOL;So;0;ON;;;;;N;;;;; +3005;IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;; +3006;IDEOGRAPHIC CLOSING MARK;Lo;0;L;;;;;N;;;;; +3007;IDEOGRAPHIC NUMBER ZERO;Nl;0;L;;;;0;N;;;;; +3008;LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING ANGLE BRACKET;;;; +3009;RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING ANGLE BRACKET;;;; +300A;LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING DOUBLE ANGLE BRACKET;;;; +300B;RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING DOUBLE ANGLE BRACKET;;;; +300C;LEFT CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING CORNER BRACKET;;;; +300D;RIGHT CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING CORNER BRACKET;;;; +300E;LEFT WHITE CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE CORNER BRACKET;;;; +300F;RIGHT WHITE CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE CORNER BRACKET;;;; +3010;LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING BLACK LENTICULAR BRACKET;;;; +3011;RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING BLACK LENTICULAR BRACKET;;;; +3012;POSTAL MARK;So;0;ON;;;;;N;;;;; +3013;GETA MARK;So;0;ON;;;;;N;;;;; +3014;LEFT TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING TORTOISE SHELL BRACKET;;;; +3015;RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING TORTOISE SHELL BRACKET;;;; +3016;LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE LENTICULAR BRACKET;;;; +3017;RIGHT WHITE LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE LENTICULAR BRACKET;;;; +3018;LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE TORTOISE SHELL BRACKET;;;; +3019;RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE TORTOISE SHELL BRACKET;;;; +301A;LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE SQUARE BRACKET;;;; +301B;RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE SQUARE BRACKET;;;; +301C;WAVE DASH;Pd;0;ON;;;;;N;;;;; +301D;REVERSED DOUBLE PRIME QUOTATION MARK;Ps;0;ON;;;;;N;;;;; +301E;DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;; +301F;LOW DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;; +3020;POSTAL MARK FACE;So;0;ON;;;;;N;;;;; +3021;HANGZHOU NUMERAL ONE;Nl;0;L;;;;1;N;;;;; +3022;HANGZHOU NUMERAL TWO;Nl;0;L;;;;2;N;;;;; +3023;HANGZHOU NUMERAL THREE;Nl;0;L;;;;3;N;;;;; +3024;HANGZHOU NUMERAL FOUR;Nl;0;L;;;;4;N;;;;; +3025;HANGZHOU NUMERAL FIVE;Nl;0;L;;;;5;N;;;;; +3026;HANGZHOU NUMERAL SIX;Nl;0;L;;;;6;N;;;;; +3027;HANGZHOU NUMERAL SEVEN;Nl;0;L;;;;7;N;;;;; +3028;HANGZHOU NUMERAL EIGHT;Nl;0;L;;;;8;N;;;;; +3029;HANGZHOU NUMERAL NINE;Nl;0;L;;;;9;N;;;;; +302A;IDEOGRAPHIC LEVEL TONE MARK;Mn;218;NSM;;;;;N;;;;; +302B;IDEOGRAPHIC RISING TONE MARK;Mn;228;NSM;;;;;N;;;;; +302C;IDEOGRAPHIC DEPARTING TONE MARK;Mn;232;NSM;;;;;N;;;;; +302D;IDEOGRAPHIC ENTERING TONE MARK;Mn;222;NSM;;;;;N;;;;; +302E;HANGUL SINGLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;; +302F;HANGUL DOUBLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;; +3030;WAVY DASH;Pd;0;ON;;;;;N;;;;; +3031;VERTICAL KANA REPEAT MARK;Lm;0;L;;;;;N;;;;; +3032;VERTICAL KANA REPEAT WITH VOICED SOUND MARK;Lm;0;L;;;;;N;;;;; +3033;VERTICAL KANA REPEAT MARK UPPER HALF;Lm;0;L;;;;;N;;;;; +3034;VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF;Lm;0;L;;;;;N;;;;; +3035;VERTICAL KANA REPEAT MARK LOWER HALF;Lm;0;L;;;;;N;;;;; +3036;CIRCLED POSTAL MARK;So;0;ON; 3012;;;;N;;;;; +3037;IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL;So;0;ON;;;;;N;;;;; +3038;HANGZHOU NUMERAL TEN;Nl;0;L; 5341;;;10;N;;;;; +3039;HANGZHOU NUMERAL TWENTY;Nl;0;L; 5344;;;20;N;;;;; +303A;HANGZHOU NUMERAL THIRTY;Nl;0;L; 5345;;;30;N;;;;; +303B;VERTICAL IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;; +303C;MASU MARK;Lo;0;L;;;;;N;;;;; +303D;PART ALTERNATION MARK;Po;0;ON;;;;;N;;;;; +303E;IDEOGRAPHIC VARIATION INDICATOR;So;0;ON;;;;;N;;;;; +303F;IDEOGRAPHIC HALF FILL SPACE;So;0;ON;;;;;N;;;;; +3041;HIRAGANA LETTER SMALL A;Lo;0;L;;;;;N;;;;; +3042;HIRAGANA LETTER A;Lo;0;L;;;;;N;;;;; +3043;HIRAGANA LETTER SMALL I;Lo;0;L;;;;;N;;;;; +3044;HIRAGANA LETTER I;Lo;0;L;;;;;N;;;;; +3045;HIRAGANA LETTER SMALL U;Lo;0;L;;;;;N;;;;; +3046;HIRAGANA LETTER U;Lo;0;L;;;;;N;;;;; +3047;HIRAGANA LETTER SMALL E;Lo;0;L;;;;;N;;;;; +3048;HIRAGANA LETTER E;Lo;0;L;;;;;N;;;;; +3049;HIRAGANA LETTER SMALL O;Lo;0;L;;;;;N;;;;; +304A;HIRAGANA LETTER O;Lo;0;L;;;;;N;;;;; +304B;HIRAGANA LETTER KA;Lo;0;L;;;;;N;;;;; +304C;HIRAGANA LETTER GA;Lo;0;L;304B 3099;;;;N;;;;; +304D;HIRAGANA LETTER KI;Lo;0;L;;;;;N;;;;; +304E;HIRAGANA LETTER GI;Lo;0;L;304D 3099;;;;N;;;;; +304F;HIRAGANA LETTER KU;Lo;0;L;;;;;N;;;;; +3050;HIRAGANA LETTER GU;Lo;0;L;304F 3099;;;;N;;;;; +3051;HIRAGANA LETTER KE;Lo;0;L;;;;;N;;;;; +3052;HIRAGANA LETTER GE;Lo;0;L;3051 3099;;;;N;;;;; +3053;HIRAGANA LETTER KO;Lo;0;L;;;;;N;;;;; +3054;HIRAGANA LETTER GO;Lo;0;L;3053 3099;;;;N;;;;; +3055;HIRAGANA LETTER SA;Lo;0;L;;;;;N;;;;; +3056;HIRAGANA LETTER ZA;Lo;0;L;3055 3099;;;;N;;;;; +3057;HIRAGANA LETTER SI;Lo;0;L;;;;;N;;;;; +3058;HIRAGANA LETTER ZI;Lo;0;L;3057 3099;;;;N;;;;; +3059;HIRAGANA LETTER SU;Lo;0;L;;;;;N;;;;; +305A;HIRAGANA LETTER ZU;Lo;0;L;3059 3099;;;;N;;;;; +305B;HIRAGANA LETTER SE;Lo;0;L;;;;;N;;;;; +305C;HIRAGANA LETTER ZE;Lo;0;L;305B 3099;;;;N;;;;; +305D;HIRAGANA LETTER SO;Lo;0;L;;;;;N;;;;; +305E;HIRAGANA LETTER ZO;Lo;0;L;305D 3099;;;;N;;;;; +305F;HIRAGANA LETTER TA;Lo;0;L;;;;;N;;;;; +3060;HIRAGANA LETTER DA;Lo;0;L;305F 3099;;;;N;;;;; +3061;HIRAGANA LETTER TI;Lo;0;L;;;;;N;;;;; +3062;HIRAGANA LETTER DI;Lo;0;L;3061 3099;;;;N;;;;; +3063;HIRAGANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;; +3064;HIRAGANA LETTER TU;Lo;0;L;;;;;N;;;;; +3065;HIRAGANA LETTER DU;Lo;0;L;3064 3099;;;;N;;;;; +3066;HIRAGANA LETTER TE;Lo;0;L;;;;;N;;;;; +3067;HIRAGANA LETTER DE;Lo;0;L;3066 3099;;;;N;;;;; +3068;HIRAGANA LETTER TO;Lo;0;L;;;;;N;;;;; +3069;HIRAGANA LETTER DO;Lo;0;L;3068 3099;;;;N;;;;; +306A;HIRAGANA LETTER NA;Lo;0;L;;;;;N;;;;; +306B;HIRAGANA LETTER NI;Lo;0;L;;;;;N;;;;; +306C;HIRAGANA LETTER NU;Lo;0;L;;;;;N;;;;; +306D;HIRAGANA LETTER NE;Lo;0;L;;;;;N;;;;; +306E;HIRAGANA LETTER NO;Lo;0;L;;;;;N;;;;; +306F;HIRAGANA LETTER HA;Lo;0;L;;;;;N;;;;; +3070;HIRAGANA LETTER BA;Lo;0;L;306F 3099;;;;N;;;;; +3071;HIRAGANA LETTER PA;Lo;0;L;306F 309A;;;;N;;;;; +3072;HIRAGANA LETTER HI;Lo;0;L;;;;;N;;;;; +3073;HIRAGANA LETTER BI;Lo;0;L;3072 3099;;;;N;;;;; +3074;HIRAGANA LETTER PI;Lo;0;L;3072 309A;;;;N;;;;; +3075;HIRAGANA LETTER HU;Lo;0;L;;;;;N;;;;; +3076;HIRAGANA LETTER BU;Lo;0;L;3075 3099;;;;N;;;;; +3077;HIRAGANA LETTER PU;Lo;0;L;3075 309A;;;;N;;;;; +3078;HIRAGANA LETTER HE;Lo;0;L;;;;;N;;;;; +3079;HIRAGANA LETTER BE;Lo;0;L;3078 3099;;;;N;;;;; +307A;HIRAGANA LETTER PE;Lo;0;L;3078 309A;;;;N;;;;; +307B;HIRAGANA LETTER HO;Lo;0;L;;;;;N;;;;; +307C;HIRAGANA LETTER BO;Lo;0;L;307B 3099;;;;N;;;;; +307D;HIRAGANA LETTER PO;Lo;0;L;307B 309A;;;;N;;;;; +307E;HIRAGANA LETTER MA;Lo;0;L;;;;;N;;;;; +307F;HIRAGANA LETTER MI;Lo;0;L;;;;;N;;;;; +3080;HIRAGANA LETTER MU;Lo;0;L;;;;;N;;;;; +3081;HIRAGANA LETTER ME;Lo;0;L;;;;;N;;;;; +3082;HIRAGANA LETTER MO;Lo;0;L;;;;;N;;;;; +3083;HIRAGANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;; +3084;HIRAGANA LETTER YA;Lo;0;L;;;;;N;;;;; +3085;HIRAGANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;; +3086;HIRAGANA LETTER YU;Lo;0;L;;;;;N;;;;; +3087;HIRAGANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;; +3088;HIRAGANA LETTER YO;Lo;0;L;;;;;N;;;;; +3089;HIRAGANA LETTER RA;Lo;0;L;;;;;N;;;;; +308A;HIRAGANA LETTER RI;Lo;0;L;;;;;N;;;;; +308B;HIRAGANA LETTER RU;Lo;0;L;;;;;N;;;;; +308C;HIRAGANA LETTER RE;Lo;0;L;;;;;N;;;;; +308D;HIRAGANA LETTER RO;Lo;0;L;;;;;N;;;;; +308E;HIRAGANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;; +308F;HIRAGANA LETTER WA;Lo;0;L;;;;;N;;;;; +3090;HIRAGANA LETTER WI;Lo;0;L;;;;;N;;;;; +3091;HIRAGANA LETTER WE;Lo;0;L;;;;;N;;;;; +3092;HIRAGANA LETTER WO;Lo;0;L;;;;;N;;;;; +3093;HIRAGANA LETTER N;Lo;0;L;;;;;N;;;;; +3094;HIRAGANA LETTER VU;Lo;0;L;3046 3099;;;;N;;;;; +3095;HIRAGANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;; +3096;HIRAGANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;; +3099;COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA VOICED SOUND MARK;;;; +309A;COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;;;; +309B;KATAKANA-HIRAGANA VOICED SOUND MARK;Sk;0;ON; 0020 3099;;;;N;;;;; +309C;KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Sk;0;ON; 0020 309A;;;;N;;;;; +309D;HIRAGANA ITERATION MARK;Lm;0;L;;;;;N;;;;; +309E;HIRAGANA VOICED ITERATION MARK;Lm;0;L;309D 3099;;;;N;;;;; +309F;HIRAGANA DIGRAPH YORI;Lo;0;L; 3088 308A;;;;N;;;;; +30A0;KATAKANA-HIRAGANA DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;; +30A1;KATAKANA LETTER SMALL A;Lo;0;L;;;;;N;;;;; +30A2;KATAKANA LETTER A;Lo;0;L;;;;;N;;;;; +30A3;KATAKANA LETTER SMALL I;Lo;0;L;;;;;N;;;;; +30A4;KATAKANA LETTER I;Lo;0;L;;;;;N;;;;; +30A5;KATAKANA LETTER SMALL U;Lo;0;L;;;;;N;;;;; +30A6;KATAKANA LETTER U;Lo;0;L;;;;;N;;;;; +30A7;KATAKANA LETTER SMALL E;Lo;0;L;;;;;N;;;;; +30A8;KATAKANA LETTER E;Lo;0;L;;;;;N;;;;; +30A9;KATAKANA LETTER SMALL O;Lo;0;L;;;;;N;;;;; +30AA;KATAKANA LETTER O;Lo;0;L;;;;;N;;;;; +30AB;KATAKANA LETTER KA;Lo;0;L;;;;;N;;;;; +30AC;KATAKANA LETTER GA;Lo;0;L;30AB 3099;;;;N;;;;; +30AD;KATAKANA LETTER KI;Lo;0;L;;;;;N;;;;; +30AE;KATAKANA LETTER GI;Lo;0;L;30AD 3099;;;;N;;;;; +30AF;KATAKANA LETTER KU;Lo;0;L;;;;;N;;;;; +30B0;KATAKANA LETTER GU;Lo;0;L;30AF 3099;;;;N;;;;; +30B1;KATAKANA LETTER KE;Lo;0;L;;;;;N;;;;; +30B2;KATAKANA LETTER GE;Lo;0;L;30B1 3099;;;;N;;;;; +30B3;KATAKANA LETTER KO;Lo;0;L;;;;;N;;;;; +30B4;KATAKANA LETTER GO;Lo;0;L;30B3 3099;;;;N;;;;; +30B5;KATAKANA LETTER SA;Lo;0;L;;;;;N;;;;; +30B6;KATAKANA LETTER ZA;Lo;0;L;30B5 3099;;;;N;;;;; +30B7;KATAKANA LETTER SI;Lo;0;L;;;;;N;;;;; +30B8;KATAKANA LETTER ZI;Lo;0;L;30B7 3099;;;;N;;;;; +30B9;KATAKANA LETTER SU;Lo;0;L;;;;;N;;;;; +30BA;KATAKANA LETTER ZU;Lo;0;L;30B9 3099;;;;N;;;;; +30BB;KATAKANA LETTER SE;Lo;0;L;;;;;N;;;;; +30BC;KATAKANA LETTER ZE;Lo;0;L;30BB 3099;;;;N;;;;; +30BD;KATAKANA LETTER SO;Lo;0;L;;;;;N;;;;; +30BE;KATAKANA LETTER ZO;Lo;0;L;30BD 3099;;;;N;;;;; +30BF;KATAKANA LETTER TA;Lo;0;L;;;;;N;;;;; +30C0;KATAKANA LETTER DA;Lo;0;L;30BF 3099;;;;N;;;;; +30C1;KATAKANA LETTER TI;Lo;0;L;;;;;N;;;;; +30C2;KATAKANA LETTER DI;Lo;0;L;30C1 3099;;;;N;;;;; +30C3;KATAKANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;; +30C4;KATAKANA LETTER TU;Lo;0;L;;;;;N;;;;; +30C5;KATAKANA LETTER DU;Lo;0;L;30C4 3099;;;;N;;;;; +30C6;KATAKANA LETTER TE;Lo;0;L;;;;;N;;;;; +30C7;KATAKANA LETTER DE;Lo;0;L;30C6 3099;;;;N;;;;; +30C8;KATAKANA LETTER TO;Lo;0;L;;;;;N;;;;; +30C9;KATAKANA LETTER DO;Lo;0;L;30C8 3099;;;;N;;;;; +30CA;KATAKANA LETTER NA;Lo;0;L;;;;;N;;;;; +30CB;KATAKANA LETTER NI;Lo;0;L;;;;;N;;;;; +30CC;KATAKANA LETTER NU;Lo;0;L;;;;;N;;;;; +30CD;KATAKANA LETTER NE;Lo;0;L;;;;;N;;;;; +30CE;KATAKANA LETTER NO;Lo;0;L;;;;;N;;;;; +30CF;KATAKANA LETTER HA;Lo;0;L;;;;;N;;;;; +30D0;KATAKANA LETTER BA;Lo;0;L;30CF 3099;;;;N;;;;; +30D1;KATAKANA LETTER PA;Lo;0;L;30CF 309A;;;;N;;;;; +30D2;KATAKANA LETTER HI;Lo;0;L;;;;;N;;;;; +30D3;KATAKANA LETTER BI;Lo;0;L;30D2 3099;;;;N;;;;; +30D4;KATAKANA LETTER PI;Lo;0;L;30D2 309A;;;;N;;;;; +30D5;KATAKANA LETTER HU;Lo;0;L;;;;;N;;;;; +30D6;KATAKANA LETTER BU;Lo;0;L;30D5 3099;;;;N;;;;; +30D7;KATAKANA LETTER PU;Lo;0;L;30D5 309A;;;;N;;;;; +30D8;KATAKANA LETTER HE;Lo;0;L;;;;;N;;;;; +30D9;KATAKANA LETTER BE;Lo;0;L;30D8 3099;;;;N;;;;; +30DA;KATAKANA LETTER PE;Lo;0;L;30D8 309A;;;;N;;;;; +30DB;KATAKANA LETTER HO;Lo;0;L;;;;;N;;;;; +30DC;KATAKANA LETTER BO;Lo;0;L;30DB 3099;;;;N;;;;; +30DD;KATAKANA LETTER PO;Lo;0;L;30DB 309A;;;;N;;;;; +30DE;KATAKANA LETTER MA;Lo;0;L;;;;;N;;;;; +30DF;KATAKANA LETTER MI;Lo;0;L;;;;;N;;;;; +30E0;KATAKANA LETTER MU;Lo;0;L;;;;;N;;;;; +30E1;KATAKANA LETTER ME;Lo;0;L;;;;;N;;;;; +30E2;KATAKANA LETTER MO;Lo;0;L;;;;;N;;;;; +30E3;KATAKANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;; +30E4;KATAKANA LETTER YA;Lo;0;L;;;;;N;;;;; +30E5;KATAKANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;; +30E6;KATAKANA LETTER YU;Lo;0;L;;;;;N;;;;; +30E7;KATAKANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;; +30E8;KATAKANA LETTER YO;Lo;0;L;;;;;N;;;;; +30E9;KATAKANA LETTER RA;Lo;0;L;;;;;N;;;;; +30EA;KATAKANA LETTER RI;Lo;0;L;;;;;N;;;;; +30EB;KATAKANA LETTER RU;Lo;0;L;;;;;N;;;;; +30EC;KATAKANA LETTER RE;Lo;0;L;;;;;N;;;;; +30ED;KATAKANA LETTER RO;Lo;0;L;;;;;N;;;;; +30EE;KATAKANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;; +30EF;KATAKANA LETTER WA;Lo;0;L;;;;;N;;;;; +30F0;KATAKANA LETTER WI;Lo;0;L;;;;;N;;;;; +30F1;KATAKANA LETTER WE;Lo;0;L;;;;;N;;;;; +30F2;KATAKANA LETTER WO;Lo;0;L;;;;;N;;;;; +30F3;KATAKANA LETTER N;Lo;0;L;;;;;N;;;;; +30F4;KATAKANA LETTER VU;Lo;0;L;30A6 3099;;;;N;;;;; +30F5;KATAKANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;; +30F6;KATAKANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;; +30F7;KATAKANA LETTER VA;Lo;0;L;30EF 3099;;;;N;;;;; +30F8;KATAKANA LETTER VI;Lo;0;L;30F0 3099;;;;N;;;;; +30F9;KATAKANA LETTER VE;Lo;0;L;30F1 3099;;;;N;;;;; +30FA;KATAKANA LETTER VO;Lo;0;L;30F2 3099;;;;N;;;;; +30FB;KATAKANA MIDDLE DOT;Po;0;ON;;;;;N;;;;; +30FC;KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;;;;;N;;;;; +30FD;KATAKANA ITERATION MARK;Lm;0;L;;;;;N;;;;; +30FE;KATAKANA VOICED ITERATION MARK;Lm;0;L;30FD 3099;;;;N;;;;; +30FF;KATAKANA DIGRAPH KOTO;Lo;0;L; 30B3 30C8;;;;N;;;;; +3105;BOPOMOFO LETTER B;Lo;0;L;;;;;N;;;;; +3106;BOPOMOFO LETTER P;Lo;0;L;;;;;N;;;;; +3107;BOPOMOFO LETTER M;Lo;0;L;;;;;N;;;;; +3108;BOPOMOFO LETTER F;Lo;0;L;;;;;N;;;;; +3109;BOPOMOFO LETTER D;Lo;0;L;;;;;N;;;;; +310A;BOPOMOFO LETTER T;Lo;0;L;;;;;N;;;;; +310B;BOPOMOFO LETTER N;Lo;0;L;;;;;N;;;;; +310C;BOPOMOFO LETTER L;Lo;0;L;;;;;N;;;;; +310D;BOPOMOFO LETTER G;Lo;0;L;;;;;N;;;;; +310E;BOPOMOFO LETTER K;Lo;0;L;;;;;N;;;;; +310F;BOPOMOFO LETTER H;Lo;0;L;;;;;N;;;;; +3110;BOPOMOFO LETTER J;Lo;0;L;;;;;N;;;;; +3111;BOPOMOFO LETTER Q;Lo;0;L;;;;;N;;;;; +3112;BOPOMOFO LETTER X;Lo;0;L;;;;;N;;;;; +3113;BOPOMOFO LETTER ZH;Lo;0;L;;;;;N;;;;; +3114;BOPOMOFO LETTER CH;Lo;0;L;;;;;N;;;;; +3115;BOPOMOFO LETTER SH;Lo;0;L;;;;;N;;;;; +3116;BOPOMOFO LETTER R;Lo;0;L;;;;;N;;;;; +3117;BOPOMOFO LETTER Z;Lo;0;L;;;;;N;;;;; +3118;BOPOMOFO LETTER C;Lo;0;L;;;;;N;;;;; +3119;BOPOMOFO LETTER S;Lo;0;L;;;;;N;;;;; +311A;BOPOMOFO LETTER A;Lo;0;L;;;;;N;;;;; +311B;BOPOMOFO LETTER O;Lo;0;L;;;;;N;;;;; +311C;BOPOMOFO LETTER E;Lo;0;L;;;;;N;;;;; +311D;BOPOMOFO LETTER EH;Lo;0;L;;;;;N;;;;; +311E;BOPOMOFO LETTER AI;Lo;0;L;;;;;N;;;;; +311F;BOPOMOFO LETTER EI;Lo;0;L;;;;;N;;;;; +3120;BOPOMOFO LETTER AU;Lo;0;L;;;;;N;;;;; +3121;BOPOMOFO LETTER OU;Lo;0;L;;;;;N;;;;; +3122;BOPOMOFO LETTER AN;Lo;0;L;;;;;N;;;;; +3123;BOPOMOFO LETTER EN;Lo;0;L;;;;;N;;;;; +3124;BOPOMOFO LETTER ANG;Lo;0;L;;;;;N;;;;; +3125;BOPOMOFO LETTER ENG;Lo;0;L;;;;;N;;;;; +3126;BOPOMOFO LETTER ER;Lo;0;L;;;;;N;;;;; +3127;BOPOMOFO LETTER I;Lo;0;L;;;;;N;;;;; +3128;BOPOMOFO LETTER U;Lo;0;L;;;;;N;;;;; +3129;BOPOMOFO LETTER IU;Lo;0;L;;;;;N;;;;; +312A;BOPOMOFO LETTER V;Lo;0;L;;;;;N;;;;; +312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;; +312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;; +312D;BOPOMOFO LETTER IH;Lo;0;L;;;;;N;;;;; +3131;HANGUL LETTER KIYEOK;Lo;0;L; 1100;;;;N;HANGUL LETTER GIYEOG;;;; +3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L; 1101;;;;N;HANGUL LETTER SSANG GIYEOG;;;; +3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L; 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;; +3134;HANGUL LETTER NIEUN;Lo;0;L; 1102;;;;N;;;;; +3135;HANGUL LETTER NIEUN-CIEUC;Lo;0;L; 11AC;;;;N;HANGUL LETTER NIEUN JIEUJ;;;; +3136;HANGUL LETTER NIEUN-HIEUH;Lo;0;L; 11AD;;;;N;HANGUL LETTER NIEUN HIEUH;;;; +3137;HANGUL LETTER TIKEUT;Lo;0;L; 1103;;;;N;HANGUL LETTER DIGEUD;;;; +3138;HANGUL LETTER SSANGTIKEUT;Lo;0;L; 1104;;;;N;HANGUL LETTER SSANG DIGEUD;;;; +3139;HANGUL LETTER RIEUL;Lo;0;L; 1105;;;;N;HANGUL LETTER LIEUL;;;; +313A;HANGUL LETTER RIEUL-KIYEOK;Lo;0;L; 11B0;;;;N;HANGUL LETTER LIEUL GIYEOG;;;; +313B;HANGUL LETTER RIEUL-MIEUM;Lo;0;L; 11B1;;;;N;HANGUL LETTER LIEUL MIEUM;;;; +313C;HANGUL LETTER RIEUL-PIEUP;Lo;0;L; 11B2;;;;N;HANGUL LETTER LIEUL BIEUB;;;; +313D;HANGUL LETTER RIEUL-SIOS;Lo;0;L; 11B3;;;;N;HANGUL LETTER LIEUL SIOS;;;; +313E;HANGUL LETTER RIEUL-THIEUTH;Lo;0;L; 11B4;;;;N;HANGUL LETTER LIEUL TIEUT;;;; +313F;HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L; 11B5;;;;N;HANGUL LETTER LIEUL PIEUP;;;; +3140;HANGUL LETTER RIEUL-HIEUH;Lo;0;L; 111A;;;;N;HANGUL LETTER LIEUL HIEUH;;;; +3141;HANGUL LETTER MIEUM;Lo;0;L; 1106;;;;N;;;;; +3142;HANGUL LETTER PIEUP;Lo;0;L; 1107;;;;N;HANGUL LETTER BIEUB;;;; +3143;HANGUL LETTER SSANGPIEUP;Lo;0;L; 1108;;;;N;HANGUL LETTER SSANG BIEUB;;;; +3144;HANGUL LETTER PIEUP-SIOS;Lo;0;L; 1121;;;;N;HANGUL LETTER BIEUB SIOS;;;; +3145;HANGUL LETTER SIOS;Lo;0;L; 1109;;;;N;;;;; +3146;HANGUL LETTER SSANGSIOS;Lo;0;L; 110A;;;;N;HANGUL LETTER SSANG SIOS;;;; +3147;HANGUL LETTER IEUNG;Lo;0;L; 110B;;;;N;;;;; +3148;HANGUL LETTER CIEUC;Lo;0;L; 110C;;;;N;HANGUL LETTER JIEUJ;;;; +3149;HANGUL LETTER SSANGCIEUC;Lo;0;L; 110D;;;;N;HANGUL LETTER SSANG JIEUJ;;;; +314A;HANGUL LETTER CHIEUCH;Lo;0;L; 110E;;;;N;HANGUL LETTER CIEUC;;;; +314B;HANGUL LETTER KHIEUKH;Lo;0;L; 110F;;;;N;HANGUL LETTER KIYEOK;;;; +314C;HANGUL LETTER THIEUTH;Lo;0;L; 1110;;;;N;HANGUL LETTER TIEUT;;;; +314D;HANGUL LETTER PHIEUPH;Lo;0;L; 1111;;;;N;HANGUL LETTER PIEUP;;;; +314E;HANGUL LETTER HIEUH;Lo;0;L; 1112;;;;N;;;;; +314F;HANGUL LETTER A;Lo;0;L; 1161;;;;N;;;;; +3150;HANGUL LETTER AE;Lo;0;L; 1162;;;;N;;;;; +3151;HANGUL LETTER YA;Lo;0;L; 1163;;;;N;;;;; +3152;HANGUL LETTER YAE;Lo;0;L; 1164;;;;N;;;;; +3153;HANGUL LETTER EO;Lo;0;L; 1165;;;;N;;;;; +3154;HANGUL LETTER E;Lo;0;L; 1166;;;;N;;;;; +3155;HANGUL LETTER YEO;Lo;0;L; 1167;;;;N;;;;; +3156;HANGUL LETTER YE;Lo;0;L; 1168;;;;N;;;;; +3157;HANGUL LETTER O;Lo;0;L; 1169;;;;N;;;;; +3158;HANGUL LETTER WA;Lo;0;L; 116A;;;;N;;;;; +3159;HANGUL LETTER WAE;Lo;0;L; 116B;;;;N;;;;; +315A;HANGUL LETTER OE;Lo;0;L; 116C;;;;N;;;;; +315B;HANGUL LETTER YO;Lo;0;L; 116D;;;;N;;;;; +315C;HANGUL LETTER U;Lo;0;L; 116E;;;;N;;;;; +315D;HANGUL LETTER WEO;Lo;0;L; 116F;;;;N;;;;; +315E;HANGUL LETTER WE;Lo;0;L; 1170;;;;N;;;;; +315F;HANGUL LETTER WI;Lo;0;L; 1171;;;;N;;;;; +3160;HANGUL LETTER YU;Lo;0;L; 1172;;;;N;;;;; +3161;HANGUL LETTER EU;Lo;0;L; 1173;;;;N;;;;; +3162;HANGUL LETTER YI;Lo;0;L; 1174;;;;N;;;;; +3163;HANGUL LETTER I;Lo;0;L; 1175;;;;N;;;;; +3164;HANGUL FILLER;Lo;0;L; 1160;;;;N;HANGUL CAE OM;;;; +3165;HANGUL LETTER SSANGNIEUN;Lo;0;L; 1114;;;;N;HANGUL LETTER SSANG NIEUN;;;; +3166;HANGUL LETTER NIEUN-TIKEUT;Lo;0;L; 1115;;;;N;HANGUL LETTER NIEUN DIGEUD;;;; +3167;HANGUL LETTER NIEUN-SIOS;Lo;0;L; 11C7;;;;N;HANGUL LETTER NIEUN SIOS;;;; +3168;HANGUL LETTER NIEUN-PANSIOS;Lo;0;L; 11C8;;;;N;HANGUL LETTER NIEUN BAN CHI EUM;;;; +3169;HANGUL LETTER RIEUL-KIYEOK-SIOS;Lo;0;L; 11CC;;;;N;HANGUL LETTER LIEUL GIYEOG SIOS;;;; +316A;HANGUL LETTER RIEUL-TIKEUT;Lo;0;L; 11CE;;;;N;HANGUL LETTER LIEUL DIGEUD;;;; +316B;HANGUL LETTER RIEUL-PIEUP-SIOS;Lo;0;L; 11D3;;;;N;HANGUL LETTER LIEUL BIEUB SIOS;;;; +316C;HANGUL LETTER RIEUL-PANSIOS;Lo;0;L; 11D7;;;;N;HANGUL LETTER LIEUL BAN CHI EUM;;;; +316D;HANGUL LETTER RIEUL-YEORINHIEUH;Lo;0;L; 11D9;;;;N;HANGUL LETTER LIEUL YEOLIN HIEUH;;;; +316E;HANGUL LETTER MIEUM-PIEUP;Lo;0;L; 111C;;;;N;HANGUL LETTER MIEUM BIEUB;;;; +316F;HANGUL LETTER MIEUM-SIOS;Lo;0;L; 11DD;;;;N;HANGUL LETTER MIEUM SIOS;;;; +3170;HANGUL LETTER MIEUM-PANSIOS;Lo;0;L; 11DF;;;;N;HANGUL LETTER BIEUB BAN CHI EUM;;;; +3171;HANGUL LETTER KAPYEOUNMIEUM;Lo;0;L; 111D;;;;N;HANGUL LETTER MIEUM SUN GYEONG EUM;;;; +3172;HANGUL LETTER PIEUP-KIYEOK;Lo;0;L; 111E;;;;N;HANGUL LETTER BIEUB GIYEOG;;;; +3173;HANGUL LETTER PIEUP-TIKEUT;Lo;0;L; 1120;;;;N;HANGUL LETTER BIEUB DIGEUD;;;; +3174;HANGUL LETTER PIEUP-SIOS-KIYEOK;Lo;0;L; 1122;;;;N;HANGUL LETTER BIEUB SIOS GIYEOG;;;; +3175;HANGUL LETTER PIEUP-SIOS-TIKEUT;Lo;0;L; 1123;;;;N;HANGUL LETTER BIEUB SIOS DIGEUD;;;; +3176;HANGUL LETTER PIEUP-CIEUC;Lo;0;L; 1127;;;;N;HANGUL LETTER BIEUB JIEUJ;;;; +3177;HANGUL LETTER PIEUP-THIEUTH;Lo;0;L; 1129;;;;N;HANGUL LETTER BIEUB TIEUT;;;; +3178;HANGUL LETTER KAPYEOUNPIEUP;Lo;0;L; 112B;;;;N;HANGUL LETTER BIEUB SUN GYEONG EUM;;;; +3179;HANGUL LETTER KAPYEOUNSSANGPIEUP;Lo;0;L; 112C;;;;N;HANGUL LETTER SSANG BIEUB SUN GYEONG EUM;;;; +317A;HANGUL LETTER SIOS-KIYEOK;Lo;0;L; 112D;;;;N;HANGUL LETTER SIOS GIYEOG;;;; +317B;HANGUL LETTER SIOS-NIEUN;Lo;0;L; 112E;;;;N;HANGUL LETTER SIOS NIEUN;;;; +317C;HANGUL LETTER SIOS-TIKEUT;Lo;0;L; 112F;;;;N;HANGUL LETTER SIOS DIGEUD;;;; +317D;HANGUL LETTER SIOS-PIEUP;Lo;0;L; 1132;;;;N;HANGUL LETTER SIOS BIEUB;;;; +317E;HANGUL LETTER SIOS-CIEUC;Lo;0;L; 1136;;;;N;HANGUL LETTER SIOS JIEUJ;;;; +317F;HANGUL LETTER PANSIOS;Lo;0;L; 1140;;;;N;HANGUL LETTER BAN CHI EUM;;;; +3180;HANGUL LETTER SSANGIEUNG;Lo;0;L; 1147;;;;N;HANGUL LETTER SSANG IEUNG;;;; +3181;HANGUL LETTER YESIEUNG;Lo;0;L; 114C;;;;N;HANGUL LETTER NGIEUNG;;;; +3182;HANGUL LETTER YESIEUNG-SIOS;Lo;0;L; 11F1;;;;N;HANGUL LETTER NGIEUNG SIOS;;;; +3183;HANGUL LETTER YESIEUNG-PANSIOS;Lo;0;L; 11F2;;;;N;HANGUL LETTER NGIEUNG BAN CHI EUM;;;; +3184;HANGUL LETTER KAPYEOUNPHIEUPH;Lo;0;L; 1157;;;;N;HANGUL LETTER PIEUP SUN GYEONG EUM;;;; +3185;HANGUL LETTER SSANGHIEUH;Lo;0;L; 1158;;;;N;HANGUL LETTER SSANG HIEUH;;;; +3186;HANGUL LETTER YEORINHIEUH;Lo;0;L; 1159;;;;N;HANGUL LETTER YEOLIN HIEUH;;;; +3187;HANGUL LETTER YO-YA;Lo;0;L; 1184;;;;N;HANGUL LETTER YOYA;;;; +3188;HANGUL LETTER YO-YAE;Lo;0;L; 1185;;;;N;HANGUL LETTER YOYAE;;;; +3189;HANGUL LETTER YO-I;Lo;0;L; 1188;;;;N;HANGUL LETTER YOI;;;; +318A;HANGUL LETTER YU-YEO;Lo;0;L; 1191;;;;N;HANGUL LETTER YUYEO;;;; +318B;HANGUL LETTER YU-YE;Lo;0;L; 1192;;;;N;HANGUL LETTER YUYE;;;; +318C;HANGUL LETTER YU-I;Lo;0;L; 1194;;;;N;HANGUL LETTER YUI;;;; +318D;HANGUL LETTER ARAEA;Lo;0;L; 119E;;;;N;HANGUL LETTER ALAE A;;;; +318E;HANGUL LETTER ARAEAE;Lo;0;L; 11A1;;;;N;HANGUL LETTER ALAE AE;;;; +3190;IDEOGRAPHIC ANNOTATION LINKING MARK;So;0;L;;;;;N;KANBUN TATETEN;;;; +3191;IDEOGRAPHIC ANNOTATION REVERSE MARK;So;0;L;;;;;N;KAERITEN RE;;;; +3192;IDEOGRAPHIC ANNOTATION ONE MARK;No;0;L; 4E00;;;1;N;KAERITEN ITI;;;; +3193;IDEOGRAPHIC ANNOTATION TWO MARK;No;0;L; 4E8C;;;2;N;KAERITEN NI;;;; +3194;IDEOGRAPHIC ANNOTATION THREE MARK;No;0;L; 4E09;;;3;N;KAERITEN SAN;;;; +3195;IDEOGRAPHIC ANNOTATION FOUR MARK;No;0;L; 56DB;;;4;N;KAERITEN SI;;;; +3196;IDEOGRAPHIC ANNOTATION TOP MARK;So;0;L; 4E0A;;;;N;KAERITEN ZYOU;;;; +3197;IDEOGRAPHIC ANNOTATION MIDDLE MARK;So;0;L; 4E2D;;;;N;KAERITEN TYUU;;;; +3198;IDEOGRAPHIC ANNOTATION BOTTOM MARK;So;0;L; 4E0B;;;;N;KAERITEN GE;;;; +3199;IDEOGRAPHIC ANNOTATION FIRST MARK;So;0;L; 7532;;;;N;KAERITEN KOU;;;; +319A;IDEOGRAPHIC ANNOTATION SECOND MARK;So;0;L; 4E59;;;;N;KAERITEN OTU;;;; +319B;IDEOGRAPHIC ANNOTATION THIRD MARK;So;0;L; 4E19;;;;N;KAERITEN HEI;;;; +319C;IDEOGRAPHIC ANNOTATION FOURTH MARK;So;0;L; 4E01;;;;N;KAERITEN TEI;;;; +319D;IDEOGRAPHIC ANNOTATION HEAVEN MARK;So;0;L; 5929;;;;N;KAERITEN TEN;;;; +319E;IDEOGRAPHIC ANNOTATION EARTH MARK;So;0;L; 5730;;;;N;KAERITEN TI;;;; +319F;IDEOGRAPHIC ANNOTATION MAN MARK;So;0;L; 4EBA;;;;N;KAERITEN ZIN;;;; +31A0;BOPOMOFO LETTER BU;Lo;0;L;;;;;N;;;;; +31A1;BOPOMOFO LETTER ZI;Lo;0;L;;;;;N;;;;; +31A2;BOPOMOFO LETTER JI;Lo;0;L;;;;;N;;;;; +31A3;BOPOMOFO LETTER GU;Lo;0;L;;;;;N;;;;; +31A4;BOPOMOFO LETTER EE;Lo;0;L;;;;;N;;;;; +31A5;BOPOMOFO LETTER ENN;Lo;0;L;;;;;N;;;;; +31A6;BOPOMOFO LETTER OO;Lo;0;L;;;;;N;;;;; +31A7;BOPOMOFO LETTER ONN;Lo;0;L;;;;;N;;;;; +31A8;BOPOMOFO LETTER IR;Lo;0;L;;;;;N;;;;; +31A9;BOPOMOFO LETTER ANN;Lo;0;L;;;;;N;;;;; +31AA;BOPOMOFO LETTER INN;Lo;0;L;;;;;N;;;;; +31AB;BOPOMOFO LETTER UNN;Lo;0;L;;;;;N;;;;; +31AC;BOPOMOFO LETTER IM;Lo;0;L;;;;;N;;;;; +31AD;BOPOMOFO LETTER NGG;Lo;0;L;;;;;N;;;;; +31AE;BOPOMOFO LETTER AINN;Lo;0;L;;;;;N;;;;; +31AF;BOPOMOFO LETTER AUNN;Lo;0;L;;;;;N;;;;; +31B0;BOPOMOFO LETTER AM;Lo;0;L;;;;;N;;;;; +31B1;BOPOMOFO LETTER OM;Lo;0;L;;;;;N;;;;; +31B2;BOPOMOFO LETTER ONG;Lo;0;L;;;;;N;;;;; +31B3;BOPOMOFO LETTER INNN;Lo;0;L;;;;;N;;;;; +31B4;BOPOMOFO FINAL LETTER P;Lo;0;L;;;;;N;;;;; +31B5;BOPOMOFO FINAL LETTER T;Lo;0;L;;;;;N;;;;; +31B6;BOPOMOFO FINAL LETTER K;Lo;0;L;;;;;N;;;;; +31B7;BOPOMOFO FINAL LETTER H;Lo;0;L;;;;;N;;;;; +31C0;CJK STROKE T;So;0;ON;;;;;N;;;;; +31C1;CJK STROKE WG;So;0;ON;;;;;N;;;;; +31C2;CJK STROKE XG;So;0;ON;;;;;N;;;;; +31C3;CJK STROKE BXG;So;0;ON;;;;;N;;;;; +31C4;CJK STROKE SW;So;0;ON;;;;;N;;;;; +31C5;CJK STROKE HZZ;So;0;ON;;;;;N;;;;; +31C6;CJK STROKE HZG;So;0;ON;;;;;N;;;;; +31C7;CJK STROKE HP;So;0;ON;;;;;N;;;;; +31C8;CJK STROKE HZWG;So;0;ON;;;;;N;;;;; +31C9;CJK STROKE SZWG;So;0;ON;;;;;N;;;;; +31CA;CJK STROKE HZT;So;0;ON;;;;;N;;;;; +31CB;CJK STROKE HZZP;So;0;ON;;;;;N;;;;; +31CC;CJK STROKE HPWG;So;0;ON;;;;;N;;;;; +31CD;CJK STROKE HZW;So;0;ON;;;;;N;;;;; +31CE;CJK STROKE HZZZ;So;0;ON;;;;;N;;;;; +31CF;CJK STROKE N;So;0;ON;;;;;N;;;;; +31D0;CJK STROKE H;So;0;ON;;;;;N;;;;; +31D1;CJK STROKE S;So;0;ON;;;;;N;;;;; +31D2;CJK STROKE P;So;0;ON;;;;;N;;;;; +31D3;CJK STROKE SP;So;0;ON;;;;;N;;;;; +31D4;CJK STROKE D;So;0;ON;;;;;N;;;;; +31D5;CJK STROKE HZ;So;0;ON;;;;;N;;;;; +31D6;CJK STROKE HG;So;0;ON;;;;;N;;;;; +31D7;CJK STROKE SZ;So;0;ON;;;;;N;;;;; +31D8;CJK STROKE SWZ;So;0;ON;;;;;N;;;;; +31D9;CJK STROKE ST;So;0;ON;;;;;N;;;;; +31DA;CJK STROKE SG;So;0;ON;;;;;N;;;;; +31DB;CJK STROKE PD;So;0;ON;;;;;N;;;;; +31DC;CJK STROKE PZ;So;0;ON;;;;;N;;;;; +31DD;CJK STROKE TN;So;0;ON;;;;;N;;;;; +31DE;CJK STROKE SZZ;So;0;ON;;;;;N;;;;; +31DF;CJK STROKE SWG;So;0;ON;;;;;N;;;;; +31E0;CJK STROKE HXWG;So;0;ON;;;;;N;;;;; +31E1;CJK STROKE HZZZG;So;0;ON;;;;;N;;;;; +31E2;CJK STROKE PG;So;0;ON;;;;;N;;;;; +31E3;CJK STROKE Q;So;0;ON;;;;;N;;;;; +31F0;KATAKANA LETTER SMALL KU;Lo;0;L;;;;;N;;;;; +31F1;KATAKANA LETTER SMALL SI;Lo;0;L;;;;;N;;;;; +31F2;KATAKANA LETTER SMALL SU;Lo;0;L;;;;;N;;;;; +31F3;KATAKANA LETTER SMALL TO;Lo;0;L;;;;;N;;;;; +31F4;KATAKANA LETTER SMALL NU;Lo;0;L;;;;;N;;;;; +31F5;KATAKANA LETTER SMALL HA;Lo;0;L;;;;;N;;;;; +31F6;KATAKANA LETTER SMALL HI;Lo;0;L;;;;;N;;;;; +31F7;KATAKANA LETTER SMALL HU;Lo;0;L;;;;;N;;;;; +31F8;KATAKANA LETTER SMALL HE;Lo;0;L;;;;;N;;;;; +31F9;KATAKANA LETTER SMALL HO;Lo;0;L;;;;;N;;;;; +31FA;KATAKANA LETTER SMALL MU;Lo;0;L;;;;;N;;;;; +31FB;KATAKANA LETTER SMALL RA;Lo;0;L;;;;;N;;;;; +31FC;KATAKANA LETTER SMALL RI;Lo;0;L;;;;;N;;;;; +31FD;KATAKANA LETTER SMALL RU;Lo;0;L;;;;;N;;;;; +31FE;KATAKANA LETTER SMALL RE;Lo;0;L;;;;;N;;;;; +31FF;KATAKANA LETTER SMALL RO;Lo;0;L;;;;;N;;;;; +3200;PARENTHESIZED HANGUL KIYEOK;So;0;L; 0028 1100 0029;;;;N;PARENTHESIZED HANGUL GIYEOG;;;; +3201;PARENTHESIZED HANGUL NIEUN;So;0;L; 0028 1102 0029;;;;N;;;;; +3202;PARENTHESIZED HANGUL TIKEUT;So;0;L; 0028 1103 0029;;;;N;PARENTHESIZED HANGUL DIGEUD;;;; +3203;PARENTHESIZED HANGUL RIEUL;So;0;L; 0028 1105 0029;;;;N;PARENTHESIZED HANGUL LIEUL;;;; +3204;PARENTHESIZED HANGUL MIEUM;So;0;L; 0028 1106 0029;;;;N;;;;; +3205;PARENTHESIZED HANGUL PIEUP;So;0;L; 0028 1107 0029;;;;N;PARENTHESIZED HANGUL BIEUB;;;; +3206;PARENTHESIZED HANGUL SIOS;So;0;L; 0028 1109 0029;;;;N;;;;; +3207;PARENTHESIZED HANGUL IEUNG;So;0;L; 0028 110B 0029;;;;N;;;;; +3208;PARENTHESIZED HANGUL CIEUC;So;0;L; 0028 110C 0029;;;;N;PARENTHESIZED HANGUL JIEUJ;;;; +3209;PARENTHESIZED HANGUL CHIEUCH;So;0;L; 0028 110E 0029;;;;N;PARENTHESIZED HANGUL CIEUC;;;; +320A;PARENTHESIZED HANGUL KHIEUKH;So;0;L; 0028 110F 0029;;;;N;PARENTHESIZED HANGUL KIYEOK;;;; +320B;PARENTHESIZED HANGUL THIEUTH;So;0;L; 0028 1110 0029;;;;N;PARENTHESIZED HANGUL TIEUT;;;; +320C;PARENTHESIZED HANGUL PHIEUPH;So;0;L; 0028 1111 0029;;;;N;PARENTHESIZED HANGUL PIEUP;;;; +320D;PARENTHESIZED HANGUL HIEUH;So;0;L; 0028 1112 0029;;;;N;;;;; +320E;PARENTHESIZED HANGUL KIYEOK A;So;0;L; 0028 1100 1161 0029;;;;N;PARENTHESIZED HANGUL GA;;;; +320F;PARENTHESIZED HANGUL NIEUN A;So;0;L; 0028 1102 1161 0029;;;;N;PARENTHESIZED HANGUL NA;;;; +3210;PARENTHESIZED HANGUL TIKEUT A;So;0;L; 0028 1103 1161 0029;;;;N;PARENTHESIZED HANGUL DA;;;; +3211;PARENTHESIZED HANGUL RIEUL A;So;0;L; 0028 1105 1161 0029;;;;N;PARENTHESIZED HANGUL LA;;;; +3212;PARENTHESIZED HANGUL MIEUM A;So;0;L; 0028 1106 1161 0029;;;;N;PARENTHESIZED HANGUL MA;;;; +3213;PARENTHESIZED HANGUL PIEUP A;So;0;L; 0028 1107 1161 0029;;;;N;PARENTHESIZED HANGUL BA;;;; +3214;PARENTHESIZED HANGUL SIOS A;So;0;L; 0028 1109 1161 0029;;;;N;PARENTHESIZED HANGUL SA;;;; +3215;PARENTHESIZED HANGUL IEUNG A;So;0;L; 0028 110B 1161 0029;;;;N;PARENTHESIZED HANGUL A;;;; +3216;PARENTHESIZED HANGUL CIEUC A;So;0;L; 0028 110C 1161 0029;;;;N;PARENTHESIZED HANGUL JA;;;; +3217;PARENTHESIZED HANGUL CHIEUCH A;So;0;L; 0028 110E 1161 0029;;;;N;PARENTHESIZED HANGUL CA;;;; +3218;PARENTHESIZED HANGUL KHIEUKH A;So;0;L; 0028 110F 1161 0029;;;;N;PARENTHESIZED HANGUL KA;;;; +3219;PARENTHESIZED HANGUL THIEUTH A;So;0;L; 0028 1110 1161 0029;;;;N;PARENTHESIZED HANGUL TA;;;; +321A;PARENTHESIZED HANGUL PHIEUPH A;So;0;L; 0028 1111 1161 0029;;;;N;PARENTHESIZED HANGUL PA;;;; +321B;PARENTHESIZED HANGUL HIEUH A;So;0;L; 0028 1112 1161 0029;;;;N;PARENTHESIZED HANGUL HA;;;; +321C;PARENTHESIZED HANGUL CIEUC U;So;0;L; 0028 110C 116E 0029;;;;N;PARENTHESIZED HANGUL JU;;;; +321D;PARENTHESIZED KOREAN CHARACTER OJEON;So;0;ON; 0028 110B 1169 110C 1165 11AB 0029;;;;N;;;;; +321E;PARENTHESIZED KOREAN CHARACTER O HU;So;0;ON; 0028 110B 1169 1112 116E 0029;;;;N;;;;; +3220;PARENTHESIZED IDEOGRAPH ONE;No;0;L; 0028 4E00 0029;;;1;N;;;;; +3221;PARENTHESIZED IDEOGRAPH TWO;No;0;L; 0028 4E8C 0029;;;2;N;;;;; +3222;PARENTHESIZED IDEOGRAPH THREE;No;0;L; 0028 4E09 0029;;;3;N;;;;; +3223;PARENTHESIZED IDEOGRAPH FOUR;No;0;L; 0028 56DB 0029;;;4;N;;;;; +3224;PARENTHESIZED IDEOGRAPH FIVE;No;0;L; 0028 4E94 0029;;;5;N;;;;; +3225;PARENTHESIZED IDEOGRAPH SIX;No;0;L; 0028 516D 0029;;;6;N;;;;; +3226;PARENTHESIZED IDEOGRAPH SEVEN;No;0;L; 0028 4E03 0029;;;7;N;;;;; +3227;PARENTHESIZED IDEOGRAPH EIGHT;No;0;L; 0028 516B 0029;;;8;N;;;;; +3228;PARENTHESIZED IDEOGRAPH NINE;No;0;L; 0028 4E5D 0029;;;9;N;;;;; +3229;PARENTHESIZED IDEOGRAPH TEN;No;0;L; 0028 5341 0029;;;10;N;;;;; +322A;PARENTHESIZED IDEOGRAPH MOON;So;0;L; 0028 6708 0029;;;;N;;;;; +322B;PARENTHESIZED IDEOGRAPH FIRE;So;0;L; 0028 706B 0029;;;;N;;;;; +322C;PARENTHESIZED IDEOGRAPH WATER;So;0;L; 0028 6C34 0029;;;;N;;;;; +322D;PARENTHESIZED IDEOGRAPH WOOD;So;0;L; 0028 6728 0029;;;;N;;;;; +322E;PARENTHESIZED IDEOGRAPH METAL;So;0;L; 0028 91D1 0029;;;;N;;;;; +322F;PARENTHESIZED IDEOGRAPH EARTH;So;0;L; 0028 571F 0029;;;;N;;;;; +3230;PARENTHESIZED IDEOGRAPH SUN;So;0;L; 0028 65E5 0029;;;;N;;;;; +3231;PARENTHESIZED IDEOGRAPH STOCK;So;0;L; 0028 682A 0029;;;;N;;;;; +3232;PARENTHESIZED IDEOGRAPH HAVE;So;0;L; 0028 6709 0029;;;;N;;;;; +3233;PARENTHESIZED IDEOGRAPH SOCIETY;So;0;L; 0028 793E 0029;;;;N;;;;; +3234;PARENTHESIZED IDEOGRAPH NAME;So;0;L; 0028 540D 0029;;;;N;;;;; +3235;PARENTHESIZED IDEOGRAPH SPECIAL;So;0;L; 0028 7279 0029;;;;N;;;;; +3236;PARENTHESIZED IDEOGRAPH FINANCIAL;So;0;L; 0028 8CA1 0029;;;;N;;;;; +3237;PARENTHESIZED IDEOGRAPH CONGRATULATION;So;0;L; 0028 795D 0029;;;;N;;;;; +3238;PARENTHESIZED IDEOGRAPH LABOR;So;0;L; 0028 52B4 0029;;;;N;;;;; +3239;PARENTHESIZED IDEOGRAPH REPRESENT;So;0;L; 0028 4EE3 0029;;;;N;;;;; +323A;PARENTHESIZED IDEOGRAPH CALL;So;0;L; 0028 547C 0029;;;;N;;;;; +323B;PARENTHESIZED IDEOGRAPH STUDY;So;0;L; 0028 5B66 0029;;;;N;;;;; +323C;PARENTHESIZED IDEOGRAPH SUPERVISE;So;0;L; 0028 76E3 0029;;;;N;;;;; +323D;PARENTHESIZED IDEOGRAPH ENTERPRISE;So;0;L; 0028 4F01 0029;;;;N;;;;; +323E;PARENTHESIZED IDEOGRAPH RESOURCE;So;0;L; 0028 8CC7 0029;;;;N;;;;; +323F;PARENTHESIZED IDEOGRAPH ALLIANCE;So;0;L; 0028 5354 0029;;;;N;;;;; +3240;PARENTHESIZED IDEOGRAPH FESTIVAL;So;0;L; 0028 796D 0029;;;;N;;;;; +3241;PARENTHESIZED IDEOGRAPH REST;So;0;L; 0028 4F11 0029;;;;N;;;;; +3242;PARENTHESIZED IDEOGRAPH SELF;So;0;L; 0028 81EA 0029;;;;N;;;;; +3243;PARENTHESIZED IDEOGRAPH REACH;So;0;L; 0028 81F3 0029;;;;N;;;;; +3244;CIRCLED IDEOGRAPH QUESTION;So;0;L; 554F;;;;N;;;;; +3245;CIRCLED IDEOGRAPH KINDERGARTEN;So;0;L; 5E7C;;;;N;;;;; +3246;CIRCLED IDEOGRAPH SCHOOL;So;0;L; 6587;;;;N;;;;; +3247;CIRCLED IDEOGRAPH KOTO;So;0;L; 7B8F;;;;N;;;;; +3248;CIRCLED NUMBER TEN ON BLACK SQUARE;So;0;L;;;;;N;;;;; +3249;CIRCLED NUMBER TWENTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +324A;CIRCLED NUMBER THIRTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +324B;CIRCLED NUMBER FORTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +324C;CIRCLED NUMBER FIFTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +324D;CIRCLED NUMBER SIXTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +324E;CIRCLED NUMBER SEVENTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +324F;CIRCLED NUMBER EIGHTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +3250;PARTNERSHIP SIGN;So;0;ON; 0050 0054 0045;;;;N;;;;; +3251;CIRCLED NUMBER TWENTY ONE;No;0;ON; 0032 0031;;;21;N;;;;; +3252;CIRCLED NUMBER TWENTY TWO;No;0;ON; 0032 0032;;;22;N;;;;; +3253;CIRCLED NUMBER TWENTY THREE;No;0;ON; 0032 0033;;;23;N;;;;; +3254;CIRCLED NUMBER TWENTY FOUR;No;0;ON; 0032 0034;;;24;N;;;;; +3255;CIRCLED NUMBER TWENTY FIVE;No;0;ON; 0032 0035;;;25;N;;;;; +3256;CIRCLED NUMBER TWENTY SIX;No;0;ON; 0032 0036;;;26;N;;;;; +3257;CIRCLED NUMBER TWENTY SEVEN;No;0;ON; 0032 0037;;;27;N;;;;; +3258;CIRCLED NUMBER TWENTY EIGHT;No;0;ON; 0032 0038;;;28;N;;;;; +3259;CIRCLED NUMBER TWENTY NINE;No;0;ON; 0032 0039;;;29;N;;;;; +325A;CIRCLED NUMBER THIRTY;No;0;ON; 0033 0030;;;30;N;;;;; +325B;CIRCLED NUMBER THIRTY ONE;No;0;ON; 0033 0031;;;31;N;;;;; +325C;CIRCLED NUMBER THIRTY TWO;No;0;ON; 0033 0032;;;32;N;;;;; +325D;CIRCLED NUMBER THIRTY THREE;No;0;ON; 0033 0033;;;33;N;;;;; +325E;CIRCLED NUMBER THIRTY FOUR;No;0;ON; 0033 0034;;;34;N;;;;; +325F;CIRCLED NUMBER THIRTY FIVE;No;0;ON; 0033 0035;;;35;N;;;;; +3260;CIRCLED HANGUL KIYEOK;So;0;L; 1100;;;;N;CIRCLED HANGUL GIYEOG;;;; +3261;CIRCLED HANGUL NIEUN;So;0;L; 1102;;;;N;;;;; +3262;CIRCLED HANGUL TIKEUT;So;0;L; 1103;;;;N;CIRCLED HANGUL DIGEUD;;;; +3263;CIRCLED HANGUL RIEUL;So;0;L; 1105;;;;N;CIRCLED HANGUL LIEUL;;;; +3264;CIRCLED HANGUL MIEUM;So;0;L; 1106;;;;N;;;;; +3265;CIRCLED HANGUL PIEUP;So;0;L; 1107;;;;N;CIRCLED HANGUL BIEUB;;;; +3266;CIRCLED HANGUL SIOS;So;0;L; 1109;;;;N;;;;; +3267;CIRCLED HANGUL IEUNG;So;0;L; 110B;;;;N;;;;; +3268;CIRCLED HANGUL CIEUC;So;0;L; 110C;;;;N;CIRCLED HANGUL JIEUJ;;;; +3269;CIRCLED HANGUL CHIEUCH;So;0;L; 110E;;;;N;CIRCLED HANGUL CIEUC;;;; +326A;CIRCLED HANGUL KHIEUKH;So;0;L; 110F;;;;N;CIRCLED HANGUL KIYEOK;;;; +326B;CIRCLED HANGUL THIEUTH;So;0;L; 1110;;;;N;CIRCLED HANGUL TIEUT;;;; +326C;CIRCLED HANGUL PHIEUPH;So;0;L; 1111;;;;N;CIRCLED HANGUL PIEUP;;;; +326D;CIRCLED HANGUL HIEUH;So;0;L; 1112;;;;N;;;;; +326E;CIRCLED HANGUL KIYEOK A;So;0;L; 1100 1161;;;;N;CIRCLED HANGUL GA;;;; +326F;CIRCLED HANGUL NIEUN A;So;0;L; 1102 1161;;;;N;CIRCLED HANGUL NA;;;; +3270;CIRCLED HANGUL TIKEUT A;So;0;L; 1103 1161;;;;N;CIRCLED HANGUL DA;;;; +3271;CIRCLED HANGUL RIEUL A;So;0;L; 1105 1161;;;;N;CIRCLED HANGUL LA;;;; +3272;CIRCLED HANGUL MIEUM A;So;0;L; 1106 1161;;;;N;CIRCLED HANGUL MA;;;; +3273;CIRCLED HANGUL PIEUP A;So;0;L; 1107 1161;;;;N;CIRCLED HANGUL BA;;;; +3274;CIRCLED HANGUL SIOS A;So;0;L; 1109 1161;;;;N;CIRCLED HANGUL SA;;;; +3275;CIRCLED HANGUL IEUNG A;So;0;L; 110B 1161;;;;N;CIRCLED HANGUL A;;;; +3276;CIRCLED HANGUL CIEUC A;So;0;L; 110C 1161;;;;N;CIRCLED HANGUL JA;;;; +3277;CIRCLED HANGUL CHIEUCH A;So;0;L; 110E 1161;;;;N;CIRCLED HANGUL CA;;;; +3278;CIRCLED HANGUL KHIEUKH A;So;0;L; 110F 1161;;;;N;CIRCLED HANGUL KA;;;; +3279;CIRCLED HANGUL THIEUTH A;So;0;L; 1110 1161;;;;N;CIRCLED HANGUL TA;;;; +327A;CIRCLED HANGUL PHIEUPH A;So;0;L; 1111 1161;;;;N;CIRCLED HANGUL PA;;;; +327B;CIRCLED HANGUL HIEUH A;So;0;L; 1112 1161;;;;N;CIRCLED HANGUL HA;;;; +327C;CIRCLED KOREAN CHARACTER CHAMKO;So;0;ON; 110E 1161 11B7 1100 1169;;;;N;;;;; +327D;CIRCLED KOREAN CHARACTER JUEUI;So;0;ON; 110C 116E 110B 1174;;;;N;;;;; +327E;CIRCLED HANGUL IEUNG U;So;0;ON; 110B 116E;;;;N;;;;; +327F;KOREAN STANDARD SYMBOL;So;0;L;;;;;N;;;;; +3280;CIRCLED IDEOGRAPH ONE;No;0;L; 4E00;;;1;N;;;;; +3281;CIRCLED IDEOGRAPH TWO;No;0;L; 4E8C;;;2;N;;;;; +3282;CIRCLED IDEOGRAPH THREE;No;0;L; 4E09;;;3;N;;;;; +3283;CIRCLED IDEOGRAPH FOUR;No;0;L; 56DB;;;4;N;;;;; +3284;CIRCLED IDEOGRAPH FIVE;No;0;L; 4E94;;;5;N;;;;; +3285;CIRCLED IDEOGRAPH SIX;No;0;L; 516D;;;6;N;;;;; +3286;CIRCLED IDEOGRAPH SEVEN;No;0;L; 4E03;;;7;N;;;;; +3287;CIRCLED IDEOGRAPH EIGHT;No;0;L; 516B;;;8;N;;;;; +3288;CIRCLED IDEOGRAPH NINE;No;0;L; 4E5D;;;9;N;;;;; +3289;CIRCLED IDEOGRAPH TEN;No;0;L; 5341;;;10;N;;;;; +328A;CIRCLED IDEOGRAPH MOON;So;0;L; 6708;;;;N;;;;; +328B;CIRCLED IDEOGRAPH FIRE;So;0;L; 706B;;;;N;;;;; +328C;CIRCLED IDEOGRAPH WATER;So;0;L; 6C34;;;;N;;;;; +328D;CIRCLED IDEOGRAPH WOOD;So;0;L; 6728;;;;N;;;;; +328E;CIRCLED IDEOGRAPH METAL;So;0;L; 91D1;;;;N;;;;; +328F;CIRCLED IDEOGRAPH EARTH;So;0;L; 571F;;;;N;;;;; +3290;CIRCLED IDEOGRAPH SUN;So;0;L; 65E5;;;;N;;;;; +3291;CIRCLED IDEOGRAPH STOCK;So;0;L; 682A;;;;N;;;;; +3292;CIRCLED IDEOGRAPH HAVE;So;0;L; 6709;;;;N;;;;; +3293;CIRCLED IDEOGRAPH SOCIETY;So;0;L; 793E;;;;N;;;;; +3294;CIRCLED IDEOGRAPH NAME;So;0;L; 540D;;;;N;;;;; +3295;CIRCLED IDEOGRAPH SPECIAL;So;0;L; 7279;;;;N;;;;; +3296;CIRCLED IDEOGRAPH FINANCIAL;So;0;L; 8CA1;;;;N;;;;; +3297;CIRCLED IDEOGRAPH CONGRATULATION;So;0;L; 795D;;;;N;;;;; +3298;CIRCLED IDEOGRAPH LABOR;So;0;L; 52B4;;;;N;;;;; +3299;CIRCLED IDEOGRAPH SECRET;So;0;L; 79D8;;;;N;;;;; +329A;CIRCLED IDEOGRAPH MALE;So;0;L; 7537;;;;N;;;;; +329B;CIRCLED IDEOGRAPH FEMALE;So;0;L; 5973;;;;N;;;;; +329C;CIRCLED IDEOGRAPH SUITABLE;So;0;L; 9069;;;;N;;;;; +329D;CIRCLED IDEOGRAPH EXCELLENT;So;0;L; 512A;;;;N;;;;; +329E;CIRCLED IDEOGRAPH PRINT;So;0;L; 5370;;;;N;;;;; +329F;CIRCLED IDEOGRAPH ATTENTION;So;0;L; 6CE8;;;;N;;;;; +32A0;CIRCLED IDEOGRAPH ITEM;So;0;L; 9805;;;;N;;;;; +32A1;CIRCLED IDEOGRAPH REST;So;0;L; 4F11;;;;N;;;;; +32A2;CIRCLED IDEOGRAPH COPY;So;0;L; 5199;;;;N;;;;; +32A3;CIRCLED IDEOGRAPH CORRECT;So;0;L; 6B63;;;;N;;;;; +32A4;CIRCLED IDEOGRAPH HIGH;So;0;L; 4E0A;;;;N;;;;; +32A5;CIRCLED IDEOGRAPH CENTRE;So;0;L; 4E2D;;;;N;CIRCLED IDEOGRAPH CENTER;;;; +32A6;CIRCLED IDEOGRAPH LOW;So;0;L; 4E0B;;;;N;;;;; +32A7;CIRCLED IDEOGRAPH LEFT;So;0;L; 5DE6;;;;N;;;;; +32A8;CIRCLED IDEOGRAPH RIGHT;So;0;L; 53F3;;;;N;;;;; +32A9;CIRCLED IDEOGRAPH MEDICINE;So;0;L; 533B;;;;N;;;;; +32AA;CIRCLED IDEOGRAPH RELIGION;So;0;L; 5B97;;;;N;;;;; +32AB;CIRCLED IDEOGRAPH STUDY;So;0;L; 5B66;;;;N;;;;; +32AC;CIRCLED IDEOGRAPH SUPERVISE;So;0;L; 76E3;;;;N;;;;; +32AD;CIRCLED IDEOGRAPH ENTERPRISE;So;0;L; 4F01;;;;N;;;;; +32AE;CIRCLED IDEOGRAPH RESOURCE;So;0;L; 8CC7;;;;N;;;;; +32AF;CIRCLED IDEOGRAPH ALLIANCE;So;0;L; 5354;;;;N;;;;; +32B0;CIRCLED IDEOGRAPH NIGHT;So;0;L; 591C;;;;N;;;;; +32B1;CIRCLED NUMBER THIRTY SIX;No;0;ON; 0033 0036;;;36;N;;;;; +32B2;CIRCLED NUMBER THIRTY SEVEN;No;0;ON; 0033 0037;;;37;N;;;;; +32B3;CIRCLED NUMBER THIRTY EIGHT;No;0;ON; 0033 0038;;;38;N;;;;; +32B4;CIRCLED NUMBER THIRTY NINE;No;0;ON; 0033 0039;;;39;N;;;;; +32B5;CIRCLED NUMBER FORTY;No;0;ON; 0034 0030;;;40;N;;;;; +32B6;CIRCLED NUMBER FORTY ONE;No;0;ON; 0034 0031;;;41;N;;;;; +32B7;CIRCLED NUMBER FORTY TWO;No;0;ON; 0034 0032;;;42;N;;;;; +32B8;CIRCLED NUMBER FORTY THREE;No;0;ON; 0034 0033;;;43;N;;;;; +32B9;CIRCLED NUMBER FORTY FOUR;No;0;ON; 0034 0034;;;44;N;;;;; +32BA;CIRCLED NUMBER FORTY FIVE;No;0;ON; 0034 0035;;;45;N;;;;; +32BB;CIRCLED NUMBER FORTY SIX;No;0;ON; 0034 0036;;;46;N;;;;; +32BC;CIRCLED NUMBER FORTY SEVEN;No;0;ON; 0034 0037;;;47;N;;;;; +32BD;CIRCLED NUMBER FORTY EIGHT;No;0;ON; 0034 0038;;;48;N;;;;; +32BE;CIRCLED NUMBER FORTY NINE;No;0;ON; 0034 0039;;;49;N;;;;; +32BF;CIRCLED NUMBER FIFTY;No;0;ON; 0035 0030;;;50;N;;;;; +32C0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY;So;0;L; 0031 6708;;;;N;;;;; +32C1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY;So;0;L; 0032 6708;;;;N;;;;; +32C2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH;So;0;L; 0033 6708;;;;N;;;;; +32C3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL;So;0;L; 0034 6708;;;;N;;;;; +32C4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY;So;0;L; 0035 6708;;;;N;;;;; +32C5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE;So;0;L; 0036 6708;;;;N;;;;; +32C6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY;So;0;L; 0037 6708;;;;N;;;;; +32C7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST;So;0;L; 0038 6708;;;;N;;;;; +32C8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER;So;0;L; 0039 6708;;;;N;;;;; +32C9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER;So;0;L; 0031 0030 6708;;;;N;;;;; +32CA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER;So;0;L; 0031 0031 6708;;;;N;;;;; +32CB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER;So;0;L; 0031 0032 6708;;;;N;;;;; +32CC;SQUARE HG;So;0;ON; 0048 0067;;;;N;;;;; +32CD;SQUARE ERG;So;0;ON; 0065 0072 0067;;;;N;;;;; +32CE;SQUARE EV;So;0;ON; 0065 0056;;;;N;;;;; +32CF;LIMITED LIABILITY SIGN;So;0;ON; 004C 0054 0044;;;;N;;;;; +32D0;CIRCLED KATAKANA A;So;0;L; 30A2;;;;N;;;;; +32D1;CIRCLED KATAKANA I;So;0;L; 30A4;;;;N;;;;; +32D2;CIRCLED KATAKANA U;So;0;L; 30A6;;;;N;;;;; +32D3;CIRCLED KATAKANA E;So;0;L; 30A8;;;;N;;;;; +32D4;CIRCLED KATAKANA O;So;0;L; 30AA;;;;N;;;;; +32D5;CIRCLED KATAKANA KA;So;0;L; 30AB;;;;N;;;;; +32D6;CIRCLED KATAKANA KI;So;0;L; 30AD;;;;N;;;;; +32D7;CIRCLED KATAKANA KU;So;0;L; 30AF;;;;N;;;;; +32D8;CIRCLED KATAKANA KE;So;0;L; 30B1;;;;N;;;;; +32D9;CIRCLED KATAKANA KO;So;0;L; 30B3;;;;N;;;;; +32DA;CIRCLED KATAKANA SA;So;0;L; 30B5;;;;N;;;;; +32DB;CIRCLED KATAKANA SI;So;0;L; 30B7;;;;N;;;;; +32DC;CIRCLED KATAKANA SU;So;0;L; 30B9;;;;N;;;;; +32DD;CIRCLED KATAKANA SE;So;0;L; 30BB;;;;N;;;;; +32DE;CIRCLED KATAKANA SO;So;0;L; 30BD;;;;N;;;;; +32DF;CIRCLED KATAKANA TA;So;0;L; 30BF;;;;N;;;;; +32E0;CIRCLED KATAKANA TI;So;0;L; 30C1;;;;N;;;;; +32E1;CIRCLED KATAKANA TU;So;0;L; 30C4;;;;N;;;;; +32E2;CIRCLED KATAKANA TE;So;0;L; 30C6;;;;N;;;;; +32E3;CIRCLED KATAKANA TO;So;0;L; 30C8;;;;N;;;;; +32E4;CIRCLED KATAKANA NA;So;0;L; 30CA;;;;N;;;;; +32E5;CIRCLED KATAKANA NI;So;0;L; 30CB;;;;N;;;;; +32E6;CIRCLED KATAKANA NU;So;0;L; 30CC;;;;N;;;;; +32E7;CIRCLED KATAKANA NE;So;0;L; 30CD;;;;N;;;;; +32E8;CIRCLED KATAKANA NO;So;0;L; 30CE;;;;N;;;;; +32E9;CIRCLED KATAKANA HA;So;0;L; 30CF;;;;N;;;;; +32EA;CIRCLED KATAKANA HI;So;0;L; 30D2;;;;N;;;;; +32EB;CIRCLED KATAKANA HU;So;0;L; 30D5;;;;N;;;;; +32EC;CIRCLED KATAKANA HE;So;0;L; 30D8;;;;N;;;;; +32ED;CIRCLED KATAKANA HO;So;0;L; 30DB;;;;N;;;;; +32EE;CIRCLED KATAKANA MA;So;0;L; 30DE;;;;N;;;;; +32EF;CIRCLED KATAKANA MI;So;0;L; 30DF;;;;N;;;;; +32F0;CIRCLED KATAKANA MU;So;0;L; 30E0;;;;N;;;;; +32F1;CIRCLED KATAKANA ME;So;0;L; 30E1;;;;N;;;;; +32F2;CIRCLED KATAKANA MO;So;0;L; 30E2;;;;N;;;;; +32F3;CIRCLED KATAKANA YA;So;0;L; 30E4;;;;N;;;;; +32F4;CIRCLED KATAKANA YU;So;0;L; 30E6;;;;N;;;;; +32F5;CIRCLED KATAKANA YO;So;0;L; 30E8;;;;N;;;;; +32F6;CIRCLED KATAKANA RA;So;0;L; 30E9;;;;N;;;;; +32F7;CIRCLED KATAKANA RI;So;0;L; 30EA;;;;N;;;;; +32F8;CIRCLED KATAKANA RU;So;0;L; 30EB;;;;N;;;;; +32F9;CIRCLED KATAKANA RE;So;0;L; 30EC;;;;N;;;;; +32FA;CIRCLED KATAKANA RO;So;0;L; 30ED;;;;N;;;;; +32FB;CIRCLED KATAKANA WA;So;0;L; 30EF;;;;N;;;;; +32FC;CIRCLED KATAKANA WI;So;0;L; 30F0;;;;N;;;;; +32FD;CIRCLED KATAKANA WE;So;0;L; 30F1;;;;N;;;;; +32FE;CIRCLED KATAKANA WO;So;0;L; 30F2;;;;N;;;;; +3300;SQUARE APAATO;So;0;L; 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;; +3301;SQUARE ARUHUA;So;0;L; 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;; +3302;SQUARE ANPEA;So;0;L; 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;; +3303;SQUARE AARU;So;0;L; 30A2 30FC 30EB;;;;N;SQUARED AARU;;;; +3304;SQUARE ININGU;So;0;L; 30A4 30CB 30F3 30B0;;;;N;SQUARED ININGU;;;; +3305;SQUARE INTI;So;0;L; 30A4 30F3 30C1;;;;N;SQUARED INTI;;;; +3306;SQUARE UON;So;0;L; 30A6 30A9 30F3;;;;N;SQUARED UON;;;; +3307;SQUARE ESUKUUDO;So;0;L; 30A8 30B9 30AF 30FC 30C9;;;;N;SQUARED ESUKUUDO;;;; +3308;SQUARE EEKAA;So;0;L; 30A8 30FC 30AB 30FC;;;;N;SQUARED EEKAA;;;; +3309;SQUARE ONSU;So;0;L; 30AA 30F3 30B9;;;;N;SQUARED ONSU;;;; +330A;SQUARE OOMU;So;0;L; 30AA 30FC 30E0;;;;N;SQUARED OOMU;;;; +330B;SQUARE KAIRI;So;0;L; 30AB 30A4 30EA;;;;N;SQUARED KAIRI;;;; +330C;SQUARE KARATTO;So;0;L; 30AB 30E9 30C3 30C8;;;;N;SQUARED KARATTO;;;; +330D;SQUARE KARORII;So;0;L; 30AB 30ED 30EA 30FC;;;;N;SQUARED KARORII;;;; +330E;SQUARE GARON;So;0;L; 30AC 30ED 30F3;;;;N;SQUARED GARON;;;; +330F;SQUARE GANMA;So;0;L; 30AC 30F3 30DE;;;;N;SQUARED GANMA;;;; +3310;SQUARE GIGA;So;0;L; 30AE 30AC;;;;N;SQUARED GIGA;;;; +3311;SQUARE GINII;So;0;L; 30AE 30CB 30FC;;;;N;SQUARED GINII;;;; +3312;SQUARE KYURII;So;0;L; 30AD 30E5 30EA 30FC;;;;N;SQUARED KYURII;;;; +3313;SQUARE GIRUDAA;So;0;L; 30AE 30EB 30C0 30FC;;;;N;SQUARED GIRUDAA;;;; +3314;SQUARE KIRO;So;0;L; 30AD 30ED;;;;N;SQUARED KIRO;;;; +3315;SQUARE KIROGURAMU;So;0;L; 30AD 30ED 30B0 30E9 30E0;;;;N;SQUARED KIROGURAMU;;;; +3316;SQUARE KIROMEETORU;So;0;L; 30AD 30ED 30E1 30FC 30C8 30EB;;;;N;SQUARED KIROMEETORU;;;; +3317;SQUARE KIROWATTO;So;0;L; 30AD 30ED 30EF 30C3 30C8;;;;N;SQUARED KIROWATTO;;;; +3318;SQUARE GURAMU;So;0;L; 30B0 30E9 30E0;;;;N;SQUARED GURAMU;;;; +3319;SQUARE GURAMUTON;So;0;L; 30B0 30E9 30E0 30C8 30F3;;;;N;SQUARED GURAMUTON;;;; +331A;SQUARE KURUZEIRO;So;0;L; 30AF 30EB 30BC 30A4 30ED;;;;N;SQUARED KURUZEIRO;;;; +331B;SQUARE KUROONE;So;0;L; 30AF 30ED 30FC 30CD;;;;N;SQUARED KUROONE;;;; +331C;SQUARE KEESU;So;0;L; 30B1 30FC 30B9;;;;N;SQUARED KEESU;;;; +331D;SQUARE KORUNA;So;0;L; 30B3 30EB 30CA;;;;N;SQUARED KORUNA;;;; +331E;SQUARE KOOPO;So;0;L; 30B3 30FC 30DD;;;;N;SQUARED KOOPO;;;; +331F;SQUARE SAIKURU;So;0;L; 30B5 30A4 30AF 30EB;;;;N;SQUARED SAIKURU;;;; +3320;SQUARE SANTIIMU;So;0;L; 30B5 30F3 30C1 30FC 30E0;;;;N;SQUARED SANTIIMU;;;; +3321;SQUARE SIRINGU;So;0;L; 30B7 30EA 30F3 30B0;;;;N;SQUARED SIRINGU;;;; +3322;SQUARE SENTI;So;0;L; 30BB 30F3 30C1;;;;N;SQUARED SENTI;;;; +3323;SQUARE SENTO;So;0;L; 30BB 30F3 30C8;;;;N;SQUARED SENTO;;;; +3324;SQUARE DAASU;So;0;L; 30C0 30FC 30B9;;;;N;SQUARED DAASU;;;; +3325;SQUARE DESI;So;0;L; 30C7 30B7;;;;N;SQUARED DESI;;;; +3326;SQUARE DORU;So;0;L; 30C9 30EB;;;;N;SQUARED DORU;;;; +3327;SQUARE TON;So;0;L; 30C8 30F3;;;;N;SQUARED TON;;;; +3328;SQUARE NANO;So;0;L; 30CA 30CE;;;;N;SQUARED NANO;;;; +3329;SQUARE NOTTO;So;0;L; 30CE 30C3 30C8;;;;N;SQUARED NOTTO;;;; +332A;SQUARE HAITU;So;0;L; 30CF 30A4 30C4;;;;N;SQUARED HAITU;;;; +332B;SQUARE PAASENTO;So;0;L; 30D1 30FC 30BB 30F3 30C8;;;;N;SQUARED PAASENTO;;;; +332C;SQUARE PAATU;So;0;L; 30D1 30FC 30C4;;;;N;SQUARED PAATU;;;; +332D;SQUARE BAARERU;So;0;L; 30D0 30FC 30EC 30EB;;;;N;SQUARED BAARERU;;;; +332E;SQUARE PIASUTORU;So;0;L; 30D4 30A2 30B9 30C8 30EB;;;;N;SQUARED PIASUTORU;;;; +332F;SQUARE PIKURU;So;0;L; 30D4 30AF 30EB;;;;N;SQUARED PIKURU;;;; +3330;SQUARE PIKO;So;0;L; 30D4 30B3;;;;N;SQUARED PIKO;;;; +3331;SQUARE BIRU;So;0;L; 30D3 30EB;;;;N;SQUARED BIRU;;;; +3332;SQUARE HUARADDO;So;0;L; 30D5 30A1 30E9 30C3 30C9;;;;N;SQUARED HUARADDO;;;; +3333;SQUARE HUIITO;So;0;L; 30D5 30A3 30FC 30C8;;;;N;SQUARED HUIITO;;;; +3334;SQUARE BUSSYERU;So;0;L; 30D6 30C3 30B7 30A7 30EB;;;;N;SQUARED BUSSYERU;;;; +3335;SQUARE HURAN;So;0;L; 30D5 30E9 30F3;;;;N;SQUARED HURAN;;;; +3336;SQUARE HEKUTAARU;So;0;L; 30D8 30AF 30BF 30FC 30EB;;;;N;SQUARED HEKUTAARU;;;; +3337;SQUARE PESO;So;0;L; 30DA 30BD;;;;N;SQUARED PESO;;;; +3338;SQUARE PENIHI;So;0;L; 30DA 30CB 30D2;;;;N;SQUARED PENIHI;;;; +3339;SQUARE HERUTU;So;0;L; 30D8 30EB 30C4;;;;N;SQUARED HERUTU;;;; +333A;SQUARE PENSU;So;0;L; 30DA 30F3 30B9;;;;N;SQUARED PENSU;;;; +333B;SQUARE PEEZI;So;0;L; 30DA 30FC 30B8;;;;N;SQUARED PEEZI;;;; +333C;SQUARE BEETA;So;0;L; 30D9 30FC 30BF;;;;N;SQUARED BEETA;;;; +333D;SQUARE POINTO;So;0;L; 30DD 30A4 30F3 30C8;;;;N;SQUARED POINTO;;;; +333E;SQUARE BORUTO;So;0;L; 30DC 30EB 30C8;;;;N;SQUARED BORUTO;;;; +333F;SQUARE HON;So;0;L; 30DB 30F3;;;;N;SQUARED HON;;;; +3340;SQUARE PONDO;So;0;L; 30DD 30F3 30C9;;;;N;SQUARED PONDO;;;; +3341;SQUARE HOORU;So;0;L; 30DB 30FC 30EB;;;;N;SQUARED HOORU;;;; +3342;SQUARE HOON;So;0;L; 30DB 30FC 30F3;;;;N;SQUARED HOON;;;; +3343;SQUARE MAIKURO;So;0;L; 30DE 30A4 30AF 30ED;;;;N;SQUARED MAIKURO;;;; +3344;SQUARE MAIRU;So;0;L; 30DE 30A4 30EB;;;;N;SQUARED MAIRU;;;; +3345;SQUARE MAHHA;So;0;L; 30DE 30C3 30CF;;;;N;SQUARED MAHHA;;;; +3346;SQUARE MARUKU;So;0;L; 30DE 30EB 30AF;;;;N;SQUARED MARUKU;;;; +3347;SQUARE MANSYON;So;0;L; 30DE 30F3 30B7 30E7 30F3;;;;N;SQUARED MANSYON;;;; +3348;SQUARE MIKURON;So;0;L; 30DF 30AF 30ED 30F3;;;;N;SQUARED MIKURON;;;; +3349;SQUARE MIRI;So;0;L; 30DF 30EA;;;;N;SQUARED MIRI;;;; +334A;SQUARE MIRIBAARU;So;0;L; 30DF 30EA 30D0 30FC 30EB;;;;N;SQUARED MIRIBAARU;;;; +334B;SQUARE MEGA;So;0;L; 30E1 30AC;;;;N;SQUARED MEGA;;;; +334C;SQUARE MEGATON;So;0;L; 30E1 30AC 30C8 30F3;;;;N;SQUARED MEGATON;;;; +334D;SQUARE MEETORU;So;0;L; 30E1 30FC 30C8 30EB;;;;N;SQUARED MEETORU;;;; +334E;SQUARE YAADO;So;0;L; 30E4 30FC 30C9;;;;N;SQUARED YAADO;;;; +334F;SQUARE YAARU;So;0;L; 30E4 30FC 30EB;;;;N;SQUARED YAARU;;;; +3350;SQUARE YUAN;So;0;L; 30E6 30A2 30F3;;;;N;SQUARED YUAN;;;; +3351;SQUARE RITTORU;So;0;L; 30EA 30C3 30C8 30EB;;;;N;SQUARED RITTORU;;;; +3352;SQUARE RIRA;So;0;L; 30EA 30E9;;;;N;SQUARED RIRA;;;; +3353;SQUARE RUPII;So;0;L; 30EB 30D4 30FC;;;;N;SQUARED RUPII;;;; +3354;SQUARE RUUBURU;So;0;L; 30EB 30FC 30D6 30EB;;;;N;SQUARED RUUBURU;;;; +3355;SQUARE REMU;So;0;L; 30EC 30E0;;;;N;SQUARED REMU;;;; +3356;SQUARE RENTOGEN;So;0;L; 30EC 30F3 30C8 30B2 30F3;;;;N;SQUARED RENTOGEN;;;; +3357;SQUARE WATTO;So;0;L; 30EF 30C3 30C8;;;;N;SQUARED WATTO;;;; +3358;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO;So;0;L; 0030 70B9;;;;N;;;;; +3359;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE;So;0;L; 0031 70B9;;;;N;;;;; +335A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO;So;0;L; 0032 70B9;;;;N;;;;; +335B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE;So;0;L; 0033 70B9;;;;N;;;;; +335C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR;So;0;L; 0034 70B9;;;;N;;;;; +335D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE;So;0;L; 0035 70B9;;;;N;;;;; +335E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX;So;0;L; 0036 70B9;;;;N;;;;; +335F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN;So;0;L; 0037 70B9;;;;N;;;;; +3360;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT;So;0;L; 0038 70B9;;;;N;;;;; +3361;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE;So;0;L; 0039 70B9;;;;N;;;;; +3362;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN;So;0;L; 0031 0030 70B9;;;;N;;;;; +3363;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN;So;0;L; 0031 0031 70B9;;;;N;;;;; +3364;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE;So;0;L; 0031 0032 70B9;;;;N;;;;; +3365;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN;So;0;L; 0031 0033 70B9;;;;N;;;;; +3366;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN;So;0;L; 0031 0034 70B9;;;;N;;;;; +3367;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN;So;0;L; 0031 0035 70B9;;;;N;;;;; +3368;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN;So;0;L; 0031 0036 70B9;;;;N;;;;; +3369;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN;So;0;L; 0031 0037 70B9;;;;N;;;;; +336A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN;So;0;L; 0031 0038 70B9;;;;N;;;;; +336B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN;So;0;L; 0031 0039 70B9;;;;N;;;;; +336C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY;So;0;L; 0032 0030 70B9;;;;N;;;;; +336D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE;So;0;L; 0032 0031 70B9;;;;N;;;;; +336E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO;So;0;L; 0032 0032 70B9;;;;N;;;;; +336F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE;So;0;L; 0032 0033 70B9;;;;N;;;;; +3370;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR;So;0;L; 0032 0034 70B9;;;;N;;;;; +3371;SQUARE HPA;So;0;L; 0068 0050 0061;;;;N;;;;; +3372;SQUARE DA;So;0;L; 0064 0061;;;;N;;;;; +3373;SQUARE AU;So;0;L; 0041 0055;;;;N;;;;; +3374;SQUARE BAR;So;0;L; 0062 0061 0072;;;;N;;;;; +3375;SQUARE OV;So;0;L; 006F 0056;;;;N;;;;; +3376;SQUARE PC;So;0;L; 0070 0063;;;;N;;;;; +3377;SQUARE DM;So;0;ON; 0064 006D;;;;N;;;;; +3378;SQUARE DM SQUARED;So;0;ON; 0064 006D 00B2;;;;N;;;;; +3379;SQUARE DM CUBED;So;0;ON; 0064 006D 00B3;;;;N;;;;; +337A;SQUARE IU;So;0;ON; 0049 0055;;;;N;;;;; +337B;SQUARE ERA NAME HEISEI;So;0;L; 5E73 6210;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME HEISEI;;;; +337C;SQUARE ERA NAME SYOUWA;So;0;L; 662D 548C;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME SYOUWA;;;; +337D;SQUARE ERA NAME TAISYOU;So;0;L; 5927 6B63;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME TAISYOU;;;; +337E;SQUARE ERA NAME MEIZI;So;0;L; 660E 6CBB;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME MEIZI;;;; +337F;SQUARE CORPORATION;So;0;L; 682A 5F0F 4F1A 793E;;;;N;SQUARED FOUR IDEOGRAPHS CORPORATION;;;; +3380;SQUARE PA AMPS;So;0;L; 0070 0041;;;;N;SQUARED PA AMPS;;;; +3381;SQUARE NA;So;0;L; 006E 0041;;;;N;SQUARED NA;;;; +3382;SQUARE MU A;So;0;L; 03BC 0041;;;;N;SQUARED MU A;;;; +3383;SQUARE MA;So;0;L; 006D 0041;;;;N;SQUARED MA;;;; +3384;SQUARE KA;So;0;L; 006B 0041;;;;N;SQUARED KA;;;; +3385;SQUARE KB;So;0;L; 004B 0042;;;;N;SQUARED KB;;;; +3386;SQUARE MB;So;0;L; 004D 0042;;;;N;SQUARED MB;;;; +3387;SQUARE GB;So;0;L; 0047 0042;;;;N;SQUARED GB;;;; +3388;SQUARE CAL;So;0;L; 0063 0061 006C;;;;N;SQUARED CAL;;;; +3389;SQUARE KCAL;So;0;L; 006B 0063 0061 006C;;;;N;SQUARED KCAL;;;; +338A;SQUARE PF;So;0;L; 0070 0046;;;;N;SQUARED PF;;;; +338B;SQUARE NF;So;0;L; 006E 0046;;;;N;SQUARED NF;;;; +338C;SQUARE MU F;So;0;L; 03BC 0046;;;;N;SQUARED MU F;;;; +338D;SQUARE MU G;So;0;L; 03BC 0067;;;;N;SQUARED MU G;;;; +338E;SQUARE MG;So;0;L; 006D 0067;;;;N;SQUARED MG;;;; +338F;SQUARE KG;So;0;L; 006B 0067;;;;N;SQUARED KG;;;; +3390;SQUARE HZ;So;0;L; 0048 007A;;;;N;SQUARED HZ;;;; +3391;SQUARE KHZ;So;0;L; 006B 0048 007A;;;;N;SQUARED KHZ;;;; +3392;SQUARE MHZ;So;0;L; 004D 0048 007A;;;;N;SQUARED MHZ;;;; +3393;SQUARE GHZ;So;0;L; 0047 0048 007A;;;;N;SQUARED GHZ;;;; +3394;SQUARE THZ;So;0;L; 0054 0048 007A;;;;N;SQUARED THZ;;;; +3395;SQUARE MU L;So;0;L; 03BC 2113;;;;N;SQUARED MU L;;;; +3396;SQUARE ML;So;0;L; 006D 2113;;;;N;SQUARED ML;;;; +3397;SQUARE DL;So;0;L; 0064 2113;;;;N;SQUARED DL;;;; +3398;SQUARE KL;So;0;L; 006B 2113;;;;N;SQUARED KL;;;; +3399;SQUARE FM;So;0;L; 0066 006D;;;;N;SQUARED FM;;;; +339A;SQUARE NM;So;0;L; 006E 006D;;;;N;SQUARED NM;;;; +339B;SQUARE MU M;So;0;L; 03BC 006D;;;;N;SQUARED MU M;;;; +339C;SQUARE MM;So;0;L; 006D 006D;;;;N;SQUARED MM;;;; +339D;SQUARE CM;So;0;L; 0063 006D;;;;N;SQUARED CM;;;; +339E;SQUARE KM;So;0;L; 006B 006D;;;;N;SQUARED KM;;;; +339F;SQUARE MM SQUARED;So;0;L; 006D 006D 00B2;;;;N;SQUARED MM SQUARED;;;; +33A0;SQUARE CM SQUARED;So;0;L; 0063 006D 00B2;;;;N;SQUARED CM SQUARED;;;; +33A1;SQUARE M SQUARED;So;0;L; 006D 00B2;;;;N;SQUARED M SQUARED;;;; +33A2;SQUARE KM SQUARED;So;0;L; 006B 006D 00B2;;;;N;SQUARED KM SQUARED;;;; +33A3;SQUARE MM CUBED;So;0;L; 006D 006D 00B3;;;;N;SQUARED MM CUBED;;;; +33A4;SQUARE CM CUBED;So;0;L; 0063 006D 00B3;;;;N;SQUARED CM CUBED;;;; +33A5;SQUARE M CUBED;So;0;L; 006D 00B3;;;;N;SQUARED M CUBED;;;; +33A6;SQUARE KM CUBED;So;0;L; 006B 006D 00B3;;;;N;SQUARED KM CUBED;;;; +33A7;SQUARE M OVER S;So;0;L; 006D 2215 0073;;;;N;SQUARED M OVER S;;;; +33A8;SQUARE M OVER S SQUARED;So;0;L; 006D 2215 0073 00B2;;;;N;SQUARED M OVER S SQUARED;;;; +33A9;SQUARE PA;So;0;L; 0050 0061;;;;N;SQUARED PA;;;; +33AA;SQUARE KPA;So;0;L; 006B 0050 0061;;;;N;SQUARED KPA;;;; +33AB;SQUARE MPA;So;0;L; 004D 0050 0061;;;;N;SQUARED MPA;;;; +33AC;SQUARE GPA;So;0;L; 0047 0050 0061;;;;N;SQUARED GPA;;;; +33AD;SQUARE RAD;So;0;L; 0072 0061 0064;;;;N;SQUARED RAD;;;; +33AE;SQUARE RAD OVER S;So;0;L; 0072 0061 0064 2215 0073;;;;N;SQUARED RAD OVER S;;;; +33AF;SQUARE RAD OVER S SQUARED;So;0;L; 0072 0061 0064 2215 0073 00B2;;;;N;SQUARED RAD OVER S SQUARED;;;; +33B0;SQUARE PS;So;0;L; 0070 0073;;;;N;SQUARED PS;;;; +33B1;SQUARE NS;So;0;L; 006E 0073;;;;N;SQUARED NS;;;; +33B2;SQUARE MU S;So;0;L; 03BC 0073;;;;N;SQUARED MU S;;;; +33B3;SQUARE MS;So;0;L; 006D 0073;;;;N;SQUARED MS;;;; +33B4;SQUARE PV;So;0;L; 0070 0056;;;;N;SQUARED PV;;;; +33B5;SQUARE NV;So;0;L; 006E 0056;;;;N;SQUARED NV;;;; +33B6;SQUARE MU V;So;0;L; 03BC 0056;;;;N;SQUARED MU V;;;; +33B7;SQUARE MV;So;0;L; 006D 0056;;;;N;SQUARED MV;;;; +33B8;SQUARE KV;So;0;L; 006B 0056;;;;N;SQUARED KV;;;; +33B9;SQUARE MV MEGA;So;0;L; 004D 0056;;;;N;SQUARED MV MEGA;;;; +33BA;SQUARE PW;So;0;L; 0070 0057;;;;N;SQUARED PW;;;; +33BB;SQUARE NW;So;0;L; 006E 0057;;;;N;SQUARED NW;;;; +33BC;SQUARE MU W;So;0;L; 03BC 0057;;;;N;SQUARED MU W;;;; +33BD;SQUARE MW;So;0;L; 006D 0057;;;;N;SQUARED MW;;;; +33BE;SQUARE KW;So;0;L; 006B 0057;;;;N;SQUARED KW;;;; +33BF;SQUARE MW MEGA;So;0;L; 004D 0057;;;;N;SQUARED MW MEGA;;;; +33C0;SQUARE K OHM;So;0;L; 006B 03A9;;;;N;SQUARED K OHM;;;; +33C1;SQUARE M OHM;So;0;L; 004D 03A9;;;;N;SQUARED M OHM;;;; +33C2;SQUARE AM;So;0;L; 0061 002E 006D 002E;;;;N;SQUARED AM;;;; +33C3;SQUARE BQ;So;0;L; 0042 0071;;;;N;SQUARED BQ;;;; +33C4;SQUARE CC;So;0;L; 0063 0063;;;;N;SQUARED CC;;;; +33C5;SQUARE CD;So;0;L; 0063 0064;;;;N;SQUARED CD;;;; +33C6;SQUARE C OVER KG;So;0;L; 0043 2215 006B 0067;;;;N;SQUARED C OVER KG;;;; +33C7;SQUARE CO;So;0;L; 0043 006F 002E;;;;N;SQUARED CO;;;; +33C8;SQUARE DB;So;0;L; 0064 0042;;;;N;SQUARED DB;;;; +33C9;SQUARE GY;So;0;L; 0047 0079;;;;N;SQUARED GY;;;; +33CA;SQUARE HA;So;0;L; 0068 0061;;;;N;SQUARED HA;;;; +33CB;SQUARE HP;So;0;L; 0048 0050;;;;N;SQUARED HP;;;; +33CC;SQUARE IN;So;0;L; 0069 006E;;;;N;SQUARED IN;;;; +33CD;SQUARE KK;So;0;L; 004B 004B;;;;N;SQUARED KK;;;; +33CE;SQUARE KM CAPITAL;So;0;L; 004B 004D;;;;N;SQUARED KM CAPITAL;;;; +33CF;SQUARE KT;So;0;L; 006B 0074;;;;N;SQUARED KT;;;; +33D0;SQUARE LM;So;0;L; 006C 006D;;;;N;SQUARED LM;;;; +33D1;SQUARE LN;So;0;L; 006C 006E;;;;N;SQUARED LN;;;; +33D2;SQUARE LOG;So;0;L; 006C 006F 0067;;;;N;SQUARED LOG;;;; +33D3;SQUARE LX;So;0;L; 006C 0078;;;;N;SQUARED LX;;;; +33D4;SQUARE MB SMALL;So;0;L; 006D 0062;;;;N;SQUARED MB SMALL;;;; +33D5;SQUARE MIL;So;0;L; 006D 0069 006C;;;;N;SQUARED MIL;;;; +33D6;SQUARE MOL;So;0;L; 006D 006F 006C;;;;N;SQUARED MOL;;;; +33D7;SQUARE PH;So;0;L; 0050 0048;;;;N;SQUARED PH;;;; +33D8;SQUARE PM;So;0;L; 0070 002E 006D 002E;;;;N;SQUARED PM;;;; +33D9;SQUARE PPM;So;0;L; 0050 0050 004D;;;;N;SQUARED PPM;;;; +33DA;SQUARE PR;So;0;L; 0050 0052;;;;N;SQUARED PR;;;; +33DB;SQUARE SR;So;0;L; 0073 0072;;;;N;SQUARED SR;;;; +33DC;SQUARE SV;So;0;L; 0053 0076;;;;N;SQUARED SV;;;; +33DD;SQUARE WB;So;0;L; 0057 0062;;;;N;SQUARED WB;;;; +33DE;SQUARE V OVER M;So;0;ON; 0056 2215 006D;;;;N;;;;; +33DF;SQUARE A OVER M;So;0;ON; 0041 2215 006D;;;;N;;;;; +33E0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE;So;0;L; 0031 65E5;;;;N;;;;; +33E1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO;So;0;L; 0032 65E5;;;;N;;;;; +33E2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE;So;0;L; 0033 65E5;;;;N;;;;; +33E3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR;So;0;L; 0034 65E5;;;;N;;;;; +33E4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE;So;0;L; 0035 65E5;;;;N;;;;; +33E5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX;So;0;L; 0036 65E5;;;;N;;;;; +33E6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN;So;0;L; 0037 65E5;;;;N;;;;; +33E7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT;So;0;L; 0038 65E5;;;;N;;;;; +33E8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE;So;0;L; 0039 65E5;;;;N;;;;; +33E9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN;So;0;L; 0031 0030 65E5;;;;N;;;;; +33EA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN;So;0;L; 0031 0031 65E5;;;;N;;;;; +33EB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE;So;0;L; 0031 0032 65E5;;;;N;;;;; +33EC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN;So;0;L; 0031 0033 65E5;;;;N;;;;; +33ED;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN;So;0;L; 0031 0034 65E5;;;;N;;;;; +33EE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN;So;0;L; 0031 0035 65E5;;;;N;;;;; +33EF;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN;So;0;L; 0031 0036 65E5;;;;N;;;;; +33F0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN;So;0;L; 0031 0037 65E5;;;;N;;;;; +33F1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN;So;0;L; 0031 0038 65E5;;;;N;;;;; +33F2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN;So;0;L; 0031 0039 65E5;;;;N;;;;; +33F3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY;So;0;L; 0032 0030 65E5;;;;N;;;;; +33F4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE;So;0;L; 0032 0031 65E5;;;;N;;;;; +33F5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO;So;0;L; 0032 0032 65E5;;;;N;;;;; +33F6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE;So;0;L; 0032 0033 65E5;;;;N;;;;; +33F7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR;So;0;L; 0032 0034 65E5;;;;N;;;;; +33F8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE;So;0;L; 0032 0035 65E5;;;;N;;;;; +33F9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX;So;0;L; 0032 0036 65E5;;;;N;;;;; +33FA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN;So;0;L; 0032 0037 65E5;;;;N;;;;; +33FB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT;So;0;L; 0032 0038 65E5;;;;N;;;;; +33FC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE;So;0;L; 0032 0039 65E5;;;;N;;;;; +33FD;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY;So;0;L; 0033 0030 65E5;;;;N;;;;; +33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L; 0033 0031 65E5;;;;N;;;;; +33FF;SQUARE GAL;So;0;ON; 0067 0061 006C;;;;N;;;;; +3400;;Lo;0;L;;;;;N;;;;; +4DB5;;Lo;0;L;;;;;N;;;;; +4DC0;HEXAGRAM FOR THE CREATIVE HEAVEN;So;0;ON;;;;;N;;;;; +4DC1;HEXAGRAM FOR THE RECEPTIVE EARTH;So;0;ON;;;;;N;;;;; +4DC2;HEXAGRAM FOR DIFFICULTY AT THE BEGINNING;So;0;ON;;;;;N;;;;; +4DC3;HEXAGRAM FOR YOUTHFUL FOLLY;So;0;ON;;;;;N;;;;; +4DC4;HEXAGRAM FOR WAITING;So;0;ON;;;;;N;;;;; +4DC5;HEXAGRAM FOR CONFLICT;So;0;ON;;;;;N;;;;; +4DC6;HEXAGRAM FOR THE ARMY;So;0;ON;;;;;N;;;;; +4DC7;HEXAGRAM FOR HOLDING TOGETHER;So;0;ON;;;;;N;;;;; +4DC8;HEXAGRAM FOR SMALL TAMING;So;0;ON;;;;;N;;;;; +4DC9;HEXAGRAM FOR TREADING;So;0;ON;;;;;N;;;;; +4DCA;HEXAGRAM FOR PEACE;So;0;ON;;;;;N;;;;; +4DCB;HEXAGRAM FOR STANDSTILL;So;0;ON;;;;;N;;;;; +4DCC;HEXAGRAM FOR FELLOWSHIP;So;0;ON;;;;;N;;;;; +4DCD;HEXAGRAM FOR GREAT POSSESSION;So;0;ON;;;;;N;;;;; +4DCE;HEXAGRAM FOR MODESTY;So;0;ON;;;;;N;;;;; +4DCF;HEXAGRAM FOR ENTHUSIASM;So;0;ON;;;;;N;;;;; +4DD0;HEXAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;; +4DD1;HEXAGRAM FOR WORK ON THE DECAYED;So;0;ON;;;;;N;;;;; +4DD2;HEXAGRAM FOR APPROACH;So;0;ON;;;;;N;;;;; +4DD3;HEXAGRAM FOR CONTEMPLATION;So;0;ON;;;;;N;;;;; +4DD4;HEXAGRAM FOR BITING THROUGH;So;0;ON;;;;;N;;;;; +4DD5;HEXAGRAM FOR GRACE;So;0;ON;;;;;N;;;;; +4DD6;HEXAGRAM FOR SPLITTING APART;So;0;ON;;;;;N;;;;; +4DD7;HEXAGRAM FOR RETURN;So;0;ON;;;;;N;;;;; +4DD8;HEXAGRAM FOR INNOCENCE;So;0;ON;;;;;N;;;;; +4DD9;HEXAGRAM FOR GREAT TAMING;So;0;ON;;;;;N;;;;; +4DDA;HEXAGRAM FOR MOUTH CORNERS;So;0;ON;;;;;N;;;;; +4DDB;HEXAGRAM FOR GREAT PREPONDERANCE;So;0;ON;;;;;N;;;;; +4DDC;HEXAGRAM FOR THE ABYSMAL WATER;So;0;ON;;;;;N;;;;; +4DDD;HEXAGRAM FOR THE CLINGING FIRE;So;0;ON;;;;;N;;;;; +4DDE;HEXAGRAM FOR INFLUENCE;So;0;ON;;;;;N;;;;; +4DDF;HEXAGRAM FOR DURATION;So;0;ON;;;;;N;;;;; +4DE0;HEXAGRAM FOR RETREAT;So;0;ON;;;;;N;;;;; +4DE1;HEXAGRAM FOR GREAT POWER;So;0;ON;;;;;N;;;;; +4DE2;HEXAGRAM FOR PROGRESS;So;0;ON;;;;;N;;;;; +4DE3;HEXAGRAM FOR DARKENING OF THE LIGHT;So;0;ON;;;;;N;;;;; +4DE4;HEXAGRAM FOR THE FAMILY;So;0;ON;;;;;N;;;;; +4DE5;HEXAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;; +4DE6;HEXAGRAM FOR OBSTRUCTION;So;0;ON;;;;;N;;;;; +4DE7;HEXAGRAM FOR DELIVERANCE;So;0;ON;;;;;N;;;;; +4DE8;HEXAGRAM FOR DECREASE;So;0;ON;;;;;N;;;;; +4DE9;HEXAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;; +4DEA;HEXAGRAM FOR BREAKTHROUGH;So;0;ON;;;;;N;;;;; +4DEB;HEXAGRAM FOR COMING TO MEET;So;0;ON;;;;;N;;;;; +4DEC;HEXAGRAM FOR GATHERING TOGETHER;So;0;ON;;;;;N;;;;; +4DED;HEXAGRAM FOR PUSHING UPWARD;So;0;ON;;;;;N;;;;; +4DEE;HEXAGRAM FOR OPPRESSION;So;0;ON;;;;;N;;;;; +4DEF;HEXAGRAM FOR THE WELL;So;0;ON;;;;;N;;;;; +4DF0;HEXAGRAM FOR REVOLUTION;So;0;ON;;;;;N;;;;; +4DF1;HEXAGRAM FOR THE CAULDRON;So;0;ON;;;;;N;;;;; +4DF2;HEXAGRAM FOR THE AROUSING THUNDER;So;0;ON;;;;;N;;;;; +4DF3;HEXAGRAM FOR THE KEEPING STILL MOUNTAIN;So;0;ON;;;;;N;;;;; +4DF4;HEXAGRAM FOR DEVELOPMENT;So;0;ON;;;;;N;;;;; +4DF5;HEXAGRAM FOR THE MARRYING MAIDEN;So;0;ON;;;;;N;;;;; +4DF6;HEXAGRAM FOR ABUNDANCE;So;0;ON;;;;;N;;;;; +4DF7;HEXAGRAM FOR THE WANDERER;So;0;ON;;;;;N;;;;; +4DF8;HEXAGRAM FOR THE GENTLE WIND;So;0;ON;;;;;N;;;;; +4DF9;HEXAGRAM FOR THE JOYOUS LAKE;So;0;ON;;;;;N;;;;; +4DFA;HEXAGRAM FOR DISPERSION;So;0;ON;;;;;N;;;;; +4DFB;HEXAGRAM FOR LIMITATION;So;0;ON;;;;;N;;;;; +4DFC;HEXAGRAM FOR INNER TRUTH;So;0;ON;;;;;N;;;;; +4DFD;HEXAGRAM FOR SMALL PREPONDERANCE;So;0;ON;;;;;N;;;;; +4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;; +4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;; +4E00;;Lo;0;L;;;;;N;;;;; +9FCB;;Lo;0;L;;;;;N;;;;; +A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;; +A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;; +A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;; +A003;YI SYLLABLE IP;Lo;0;L;;;;;N;;;;; +A004;YI SYLLABLE IET;Lo;0;L;;;;;N;;;;; +A005;YI SYLLABLE IEX;Lo;0;L;;;;;N;;;;; +A006;YI SYLLABLE IE;Lo;0;L;;;;;N;;;;; +A007;YI SYLLABLE IEP;Lo;0;L;;;;;N;;;;; +A008;YI SYLLABLE AT;Lo;0;L;;;;;N;;;;; +A009;YI SYLLABLE AX;Lo;0;L;;;;;N;;;;; +A00A;YI SYLLABLE A;Lo;0;L;;;;;N;;;;; +A00B;YI SYLLABLE AP;Lo;0;L;;;;;N;;;;; +A00C;YI SYLLABLE UOX;Lo;0;L;;;;;N;;;;; +A00D;YI SYLLABLE UO;Lo;0;L;;;;;N;;;;; +A00E;YI SYLLABLE UOP;Lo;0;L;;;;;N;;;;; +A00F;YI SYLLABLE OT;Lo;0;L;;;;;N;;;;; +A010;YI SYLLABLE OX;Lo;0;L;;;;;N;;;;; +A011;YI SYLLABLE O;Lo;0;L;;;;;N;;;;; +A012;YI SYLLABLE OP;Lo;0;L;;;;;N;;;;; +A013;YI SYLLABLE EX;Lo;0;L;;;;;N;;;;; +A014;YI SYLLABLE E;Lo;0;L;;;;;N;;;;; +A015;YI SYLLABLE WU;Lm;0;L;;;;;N;;;;; +A016;YI SYLLABLE BIT;Lo;0;L;;;;;N;;;;; +A017;YI SYLLABLE BIX;Lo;0;L;;;;;N;;;;; +A018;YI SYLLABLE BI;Lo;0;L;;;;;N;;;;; +A019;YI SYLLABLE BIP;Lo;0;L;;;;;N;;;;; +A01A;YI SYLLABLE BIET;Lo;0;L;;;;;N;;;;; +A01B;YI SYLLABLE BIEX;Lo;0;L;;;;;N;;;;; +A01C;YI SYLLABLE BIE;Lo;0;L;;;;;N;;;;; +A01D;YI SYLLABLE BIEP;Lo;0;L;;;;;N;;;;; +A01E;YI SYLLABLE BAT;Lo;0;L;;;;;N;;;;; +A01F;YI SYLLABLE BAX;Lo;0;L;;;;;N;;;;; +A020;YI SYLLABLE BA;Lo;0;L;;;;;N;;;;; +A021;YI SYLLABLE BAP;Lo;0;L;;;;;N;;;;; +A022;YI SYLLABLE BUOX;Lo;0;L;;;;;N;;;;; +A023;YI SYLLABLE BUO;Lo;0;L;;;;;N;;;;; +A024;YI SYLLABLE BUOP;Lo;0;L;;;;;N;;;;; +A025;YI SYLLABLE BOT;Lo;0;L;;;;;N;;;;; +A026;YI SYLLABLE BOX;Lo;0;L;;;;;N;;;;; +A027;YI SYLLABLE BO;Lo;0;L;;;;;N;;;;; +A028;YI SYLLABLE BOP;Lo;0;L;;;;;N;;;;; +A029;YI SYLLABLE BEX;Lo;0;L;;;;;N;;;;; +A02A;YI SYLLABLE BE;Lo;0;L;;;;;N;;;;; +A02B;YI SYLLABLE BEP;Lo;0;L;;;;;N;;;;; +A02C;YI SYLLABLE BUT;Lo;0;L;;;;;N;;;;; +A02D;YI SYLLABLE BUX;Lo;0;L;;;;;N;;;;; +A02E;YI SYLLABLE BU;Lo;0;L;;;;;N;;;;; +A02F;YI SYLLABLE BUP;Lo;0;L;;;;;N;;;;; +A030;YI SYLLABLE BURX;Lo;0;L;;;;;N;;;;; +A031;YI SYLLABLE BUR;Lo;0;L;;;;;N;;;;; +A032;YI SYLLABLE BYT;Lo;0;L;;;;;N;;;;; +A033;YI SYLLABLE BYX;Lo;0;L;;;;;N;;;;; +A034;YI SYLLABLE BY;Lo;0;L;;;;;N;;;;; +A035;YI SYLLABLE BYP;Lo;0;L;;;;;N;;;;; +A036;YI SYLLABLE BYRX;Lo;0;L;;;;;N;;;;; +A037;YI SYLLABLE BYR;Lo;0;L;;;;;N;;;;; +A038;YI SYLLABLE PIT;Lo;0;L;;;;;N;;;;; +A039;YI SYLLABLE PIX;Lo;0;L;;;;;N;;;;; +A03A;YI SYLLABLE PI;Lo;0;L;;;;;N;;;;; +A03B;YI SYLLABLE PIP;Lo;0;L;;;;;N;;;;; +A03C;YI SYLLABLE PIEX;Lo;0;L;;;;;N;;;;; +A03D;YI SYLLABLE PIE;Lo;0;L;;;;;N;;;;; +A03E;YI SYLLABLE PIEP;Lo;0;L;;;;;N;;;;; +A03F;YI SYLLABLE PAT;Lo;0;L;;;;;N;;;;; +A040;YI SYLLABLE PAX;Lo;0;L;;;;;N;;;;; +A041;YI SYLLABLE PA;Lo;0;L;;;;;N;;;;; +A042;YI SYLLABLE PAP;Lo;0;L;;;;;N;;;;; +A043;YI SYLLABLE PUOX;Lo;0;L;;;;;N;;;;; +A044;YI SYLLABLE PUO;Lo;0;L;;;;;N;;;;; +A045;YI SYLLABLE PUOP;Lo;0;L;;;;;N;;;;; +A046;YI SYLLABLE POT;Lo;0;L;;;;;N;;;;; +A047;YI SYLLABLE POX;Lo;0;L;;;;;N;;;;; +A048;YI SYLLABLE PO;Lo;0;L;;;;;N;;;;; +A049;YI SYLLABLE POP;Lo;0;L;;;;;N;;;;; +A04A;YI SYLLABLE PUT;Lo;0;L;;;;;N;;;;; +A04B;YI SYLLABLE PUX;Lo;0;L;;;;;N;;;;; +A04C;YI SYLLABLE PU;Lo;0;L;;;;;N;;;;; +A04D;YI SYLLABLE PUP;Lo;0;L;;;;;N;;;;; +A04E;YI SYLLABLE PURX;Lo;0;L;;;;;N;;;;; +A04F;YI SYLLABLE PUR;Lo;0;L;;;;;N;;;;; +A050;YI SYLLABLE PYT;Lo;0;L;;;;;N;;;;; +A051;YI SYLLABLE PYX;Lo;0;L;;;;;N;;;;; +A052;YI SYLLABLE PY;Lo;0;L;;;;;N;;;;; +A053;YI SYLLABLE PYP;Lo;0;L;;;;;N;;;;; +A054;YI SYLLABLE PYRX;Lo;0;L;;;;;N;;;;; +A055;YI SYLLABLE PYR;Lo;0;L;;;;;N;;;;; +A056;YI SYLLABLE BBIT;Lo;0;L;;;;;N;;;;; +A057;YI SYLLABLE BBIX;Lo;0;L;;;;;N;;;;; +A058;YI SYLLABLE BBI;Lo;0;L;;;;;N;;;;; +A059;YI SYLLABLE BBIP;Lo;0;L;;;;;N;;;;; +A05A;YI SYLLABLE BBIET;Lo;0;L;;;;;N;;;;; +A05B;YI SYLLABLE BBIEX;Lo;0;L;;;;;N;;;;; +A05C;YI SYLLABLE BBIE;Lo;0;L;;;;;N;;;;; +A05D;YI SYLLABLE BBIEP;Lo;0;L;;;;;N;;;;; +A05E;YI SYLLABLE BBAT;Lo;0;L;;;;;N;;;;; +A05F;YI SYLLABLE BBAX;Lo;0;L;;;;;N;;;;; +A060;YI SYLLABLE BBA;Lo;0;L;;;;;N;;;;; +A061;YI SYLLABLE BBAP;Lo;0;L;;;;;N;;;;; +A062;YI SYLLABLE BBUOX;Lo;0;L;;;;;N;;;;; +A063;YI SYLLABLE BBUO;Lo;0;L;;;;;N;;;;; +A064;YI SYLLABLE BBUOP;Lo;0;L;;;;;N;;;;; +A065;YI SYLLABLE BBOT;Lo;0;L;;;;;N;;;;; +A066;YI SYLLABLE BBOX;Lo;0;L;;;;;N;;;;; +A067;YI SYLLABLE BBO;Lo;0;L;;;;;N;;;;; +A068;YI SYLLABLE BBOP;Lo;0;L;;;;;N;;;;; +A069;YI SYLLABLE BBEX;Lo;0;L;;;;;N;;;;; +A06A;YI SYLLABLE BBE;Lo;0;L;;;;;N;;;;; +A06B;YI SYLLABLE BBEP;Lo;0;L;;;;;N;;;;; +A06C;YI SYLLABLE BBUT;Lo;0;L;;;;;N;;;;; +A06D;YI SYLLABLE BBUX;Lo;0;L;;;;;N;;;;; +A06E;YI SYLLABLE BBU;Lo;0;L;;;;;N;;;;; +A06F;YI SYLLABLE BBUP;Lo;0;L;;;;;N;;;;; +A070;YI SYLLABLE BBURX;Lo;0;L;;;;;N;;;;; +A071;YI SYLLABLE BBUR;Lo;0;L;;;;;N;;;;; +A072;YI SYLLABLE BBYT;Lo;0;L;;;;;N;;;;; +A073;YI SYLLABLE BBYX;Lo;0;L;;;;;N;;;;; +A074;YI SYLLABLE BBY;Lo;0;L;;;;;N;;;;; +A075;YI SYLLABLE BBYP;Lo;0;L;;;;;N;;;;; +A076;YI SYLLABLE NBIT;Lo;0;L;;;;;N;;;;; +A077;YI SYLLABLE NBIX;Lo;0;L;;;;;N;;;;; +A078;YI SYLLABLE NBI;Lo;0;L;;;;;N;;;;; +A079;YI SYLLABLE NBIP;Lo;0;L;;;;;N;;;;; +A07A;YI SYLLABLE NBIEX;Lo;0;L;;;;;N;;;;; +A07B;YI SYLLABLE NBIE;Lo;0;L;;;;;N;;;;; +A07C;YI SYLLABLE NBIEP;Lo;0;L;;;;;N;;;;; +A07D;YI SYLLABLE NBAT;Lo;0;L;;;;;N;;;;; +A07E;YI SYLLABLE NBAX;Lo;0;L;;;;;N;;;;; +A07F;YI SYLLABLE NBA;Lo;0;L;;;;;N;;;;; +A080;YI SYLLABLE NBAP;Lo;0;L;;;;;N;;;;; +A081;YI SYLLABLE NBOT;Lo;0;L;;;;;N;;;;; +A082;YI SYLLABLE NBOX;Lo;0;L;;;;;N;;;;; +A083;YI SYLLABLE NBO;Lo;0;L;;;;;N;;;;; +A084;YI SYLLABLE NBOP;Lo;0;L;;;;;N;;;;; +A085;YI SYLLABLE NBUT;Lo;0;L;;;;;N;;;;; +A086;YI SYLLABLE NBUX;Lo;0;L;;;;;N;;;;; +A087;YI SYLLABLE NBU;Lo;0;L;;;;;N;;;;; +A088;YI SYLLABLE NBUP;Lo;0;L;;;;;N;;;;; +A089;YI SYLLABLE NBURX;Lo;0;L;;;;;N;;;;; +A08A;YI SYLLABLE NBUR;Lo;0;L;;;;;N;;;;; +A08B;YI SYLLABLE NBYT;Lo;0;L;;;;;N;;;;; +A08C;YI SYLLABLE NBYX;Lo;0;L;;;;;N;;;;; +A08D;YI SYLLABLE NBY;Lo;0;L;;;;;N;;;;; +A08E;YI SYLLABLE NBYP;Lo;0;L;;;;;N;;;;; +A08F;YI SYLLABLE NBYRX;Lo;0;L;;;;;N;;;;; +A090;YI SYLLABLE NBYR;Lo;0;L;;;;;N;;;;; +A091;YI SYLLABLE HMIT;Lo;0;L;;;;;N;;;;; +A092;YI SYLLABLE HMIX;Lo;0;L;;;;;N;;;;; +A093;YI SYLLABLE HMI;Lo;0;L;;;;;N;;;;; +A094;YI SYLLABLE HMIP;Lo;0;L;;;;;N;;;;; +A095;YI SYLLABLE HMIEX;Lo;0;L;;;;;N;;;;; +A096;YI SYLLABLE HMIE;Lo;0;L;;;;;N;;;;; +A097;YI SYLLABLE HMIEP;Lo;0;L;;;;;N;;;;; +A098;YI SYLLABLE HMAT;Lo;0;L;;;;;N;;;;; +A099;YI SYLLABLE HMAX;Lo;0;L;;;;;N;;;;; +A09A;YI SYLLABLE HMA;Lo;0;L;;;;;N;;;;; +A09B;YI SYLLABLE HMAP;Lo;0;L;;;;;N;;;;; +A09C;YI SYLLABLE HMUOX;Lo;0;L;;;;;N;;;;; +A09D;YI SYLLABLE HMUO;Lo;0;L;;;;;N;;;;; +A09E;YI SYLLABLE HMUOP;Lo;0;L;;;;;N;;;;; +A09F;YI SYLLABLE HMOT;Lo;0;L;;;;;N;;;;; +A0A0;YI SYLLABLE HMOX;Lo;0;L;;;;;N;;;;; +A0A1;YI SYLLABLE HMO;Lo;0;L;;;;;N;;;;; +A0A2;YI SYLLABLE HMOP;Lo;0;L;;;;;N;;;;; +A0A3;YI SYLLABLE HMUT;Lo;0;L;;;;;N;;;;; +A0A4;YI SYLLABLE HMUX;Lo;0;L;;;;;N;;;;; +A0A5;YI SYLLABLE HMU;Lo;0;L;;;;;N;;;;; +A0A6;YI SYLLABLE HMUP;Lo;0;L;;;;;N;;;;; +A0A7;YI SYLLABLE HMURX;Lo;0;L;;;;;N;;;;; +A0A8;YI SYLLABLE HMUR;Lo;0;L;;;;;N;;;;; +A0A9;YI SYLLABLE HMYX;Lo;0;L;;;;;N;;;;; +A0AA;YI SYLLABLE HMY;Lo;0;L;;;;;N;;;;; +A0AB;YI SYLLABLE HMYP;Lo;0;L;;;;;N;;;;; +A0AC;YI SYLLABLE HMYRX;Lo;0;L;;;;;N;;;;; +A0AD;YI SYLLABLE HMYR;Lo;0;L;;;;;N;;;;; +A0AE;YI SYLLABLE MIT;Lo;0;L;;;;;N;;;;; +A0AF;YI SYLLABLE MIX;Lo;0;L;;;;;N;;;;; +A0B0;YI SYLLABLE MI;Lo;0;L;;;;;N;;;;; +A0B1;YI SYLLABLE MIP;Lo;0;L;;;;;N;;;;; +A0B2;YI SYLLABLE MIEX;Lo;0;L;;;;;N;;;;; +A0B3;YI SYLLABLE MIE;Lo;0;L;;;;;N;;;;; +A0B4;YI SYLLABLE MIEP;Lo;0;L;;;;;N;;;;; +A0B5;YI SYLLABLE MAT;Lo;0;L;;;;;N;;;;; +A0B6;YI SYLLABLE MAX;Lo;0;L;;;;;N;;;;; +A0B7;YI SYLLABLE MA;Lo;0;L;;;;;N;;;;; +A0B8;YI SYLLABLE MAP;Lo;0;L;;;;;N;;;;; +A0B9;YI SYLLABLE MUOT;Lo;0;L;;;;;N;;;;; +A0BA;YI SYLLABLE MUOX;Lo;0;L;;;;;N;;;;; +A0BB;YI SYLLABLE MUO;Lo;0;L;;;;;N;;;;; +A0BC;YI SYLLABLE MUOP;Lo;0;L;;;;;N;;;;; +A0BD;YI SYLLABLE MOT;Lo;0;L;;;;;N;;;;; +A0BE;YI SYLLABLE MOX;Lo;0;L;;;;;N;;;;; +A0BF;YI SYLLABLE MO;Lo;0;L;;;;;N;;;;; +A0C0;YI SYLLABLE MOP;Lo;0;L;;;;;N;;;;; +A0C1;YI SYLLABLE MEX;Lo;0;L;;;;;N;;;;; +A0C2;YI SYLLABLE ME;Lo;0;L;;;;;N;;;;; +A0C3;YI SYLLABLE MUT;Lo;0;L;;;;;N;;;;; +A0C4;YI SYLLABLE MUX;Lo;0;L;;;;;N;;;;; +A0C5;YI SYLLABLE MU;Lo;0;L;;;;;N;;;;; +A0C6;YI SYLLABLE MUP;Lo;0;L;;;;;N;;;;; +A0C7;YI SYLLABLE MURX;Lo;0;L;;;;;N;;;;; +A0C8;YI SYLLABLE MUR;Lo;0;L;;;;;N;;;;; +A0C9;YI SYLLABLE MYT;Lo;0;L;;;;;N;;;;; +A0CA;YI SYLLABLE MYX;Lo;0;L;;;;;N;;;;; +A0CB;YI SYLLABLE MY;Lo;0;L;;;;;N;;;;; +A0CC;YI SYLLABLE MYP;Lo;0;L;;;;;N;;;;; +A0CD;YI SYLLABLE FIT;Lo;0;L;;;;;N;;;;; +A0CE;YI SYLLABLE FIX;Lo;0;L;;;;;N;;;;; +A0CF;YI SYLLABLE FI;Lo;0;L;;;;;N;;;;; +A0D0;YI SYLLABLE FIP;Lo;0;L;;;;;N;;;;; +A0D1;YI SYLLABLE FAT;Lo;0;L;;;;;N;;;;; +A0D2;YI SYLLABLE FAX;Lo;0;L;;;;;N;;;;; +A0D3;YI SYLLABLE FA;Lo;0;L;;;;;N;;;;; +A0D4;YI SYLLABLE FAP;Lo;0;L;;;;;N;;;;; +A0D5;YI SYLLABLE FOX;Lo;0;L;;;;;N;;;;; +A0D6;YI SYLLABLE FO;Lo;0;L;;;;;N;;;;; +A0D7;YI SYLLABLE FOP;Lo;0;L;;;;;N;;;;; +A0D8;YI SYLLABLE FUT;Lo;0;L;;;;;N;;;;; +A0D9;YI SYLLABLE FUX;Lo;0;L;;;;;N;;;;; +A0DA;YI SYLLABLE FU;Lo;0;L;;;;;N;;;;; +A0DB;YI SYLLABLE FUP;Lo;0;L;;;;;N;;;;; +A0DC;YI SYLLABLE FURX;Lo;0;L;;;;;N;;;;; +A0DD;YI SYLLABLE FUR;Lo;0;L;;;;;N;;;;; +A0DE;YI SYLLABLE FYT;Lo;0;L;;;;;N;;;;; +A0DF;YI SYLLABLE FYX;Lo;0;L;;;;;N;;;;; +A0E0;YI SYLLABLE FY;Lo;0;L;;;;;N;;;;; +A0E1;YI SYLLABLE FYP;Lo;0;L;;;;;N;;;;; +A0E2;YI SYLLABLE VIT;Lo;0;L;;;;;N;;;;; +A0E3;YI SYLLABLE VIX;Lo;0;L;;;;;N;;;;; +A0E4;YI SYLLABLE VI;Lo;0;L;;;;;N;;;;; +A0E5;YI SYLLABLE VIP;Lo;0;L;;;;;N;;;;; +A0E6;YI SYLLABLE VIET;Lo;0;L;;;;;N;;;;; +A0E7;YI SYLLABLE VIEX;Lo;0;L;;;;;N;;;;; +A0E8;YI SYLLABLE VIE;Lo;0;L;;;;;N;;;;; +A0E9;YI SYLLABLE VIEP;Lo;0;L;;;;;N;;;;; +A0EA;YI SYLLABLE VAT;Lo;0;L;;;;;N;;;;; +A0EB;YI SYLLABLE VAX;Lo;0;L;;;;;N;;;;; +A0EC;YI SYLLABLE VA;Lo;0;L;;;;;N;;;;; +A0ED;YI SYLLABLE VAP;Lo;0;L;;;;;N;;;;; +A0EE;YI SYLLABLE VOT;Lo;0;L;;;;;N;;;;; +A0EF;YI SYLLABLE VOX;Lo;0;L;;;;;N;;;;; +A0F0;YI SYLLABLE VO;Lo;0;L;;;;;N;;;;; +A0F1;YI SYLLABLE VOP;Lo;0;L;;;;;N;;;;; +A0F2;YI SYLLABLE VEX;Lo;0;L;;;;;N;;;;; +A0F3;YI SYLLABLE VEP;Lo;0;L;;;;;N;;;;; +A0F4;YI SYLLABLE VUT;Lo;0;L;;;;;N;;;;; +A0F5;YI SYLLABLE VUX;Lo;0;L;;;;;N;;;;; +A0F6;YI SYLLABLE VU;Lo;0;L;;;;;N;;;;; +A0F7;YI SYLLABLE VUP;Lo;0;L;;;;;N;;;;; +A0F8;YI SYLLABLE VURX;Lo;0;L;;;;;N;;;;; +A0F9;YI SYLLABLE VUR;Lo;0;L;;;;;N;;;;; +A0FA;YI SYLLABLE VYT;Lo;0;L;;;;;N;;;;; +A0FB;YI SYLLABLE VYX;Lo;0;L;;;;;N;;;;; +A0FC;YI SYLLABLE VY;Lo;0;L;;;;;N;;;;; +A0FD;YI SYLLABLE VYP;Lo;0;L;;;;;N;;;;; +A0FE;YI SYLLABLE VYRX;Lo;0;L;;;;;N;;;;; +A0FF;YI SYLLABLE VYR;Lo;0;L;;;;;N;;;;; +A100;YI SYLLABLE DIT;Lo;0;L;;;;;N;;;;; +A101;YI SYLLABLE DIX;Lo;0;L;;;;;N;;;;; +A102;YI SYLLABLE DI;Lo;0;L;;;;;N;;;;; +A103;YI SYLLABLE DIP;Lo;0;L;;;;;N;;;;; +A104;YI SYLLABLE DIEX;Lo;0;L;;;;;N;;;;; +A105;YI SYLLABLE DIE;Lo;0;L;;;;;N;;;;; +A106;YI SYLLABLE DIEP;Lo;0;L;;;;;N;;;;; +A107;YI SYLLABLE DAT;Lo;0;L;;;;;N;;;;; +A108;YI SYLLABLE DAX;Lo;0;L;;;;;N;;;;; +A109;YI SYLLABLE DA;Lo;0;L;;;;;N;;;;; +A10A;YI SYLLABLE DAP;Lo;0;L;;;;;N;;;;; +A10B;YI SYLLABLE DUOX;Lo;0;L;;;;;N;;;;; +A10C;YI SYLLABLE DUO;Lo;0;L;;;;;N;;;;; +A10D;YI SYLLABLE DOT;Lo;0;L;;;;;N;;;;; +A10E;YI SYLLABLE DOX;Lo;0;L;;;;;N;;;;; +A10F;YI SYLLABLE DO;Lo;0;L;;;;;N;;;;; +A110;YI SYLLABLE DOP;Lo;0;L;;;;;N;;;;; +A111;YI SYLLABLE DEX;Lo;0;L;;;;;N;;;;; +A112;YI SYLLABLE DE;Lo;0;L;;;;;N;;;;; +A113;YI SYLLABLE DEP;Lo;0;L;;;;;N;;;;; +A114;YI SYLLABLE DUT;Lo;0;L;;;;;N;;;;; +A115;YI SYLLABLE DUX;Lo;0;L;;;;;N;;;;; +A116;YI SYLLABLE DU;Lo;0;L;;;;;N;;;;; +A117;YI SYLLABLE DUP;Lo;0;L;;;;;N;;;;; +A118;YI SYLLABLE DURX;Lo;0;L;;;;;N;;;;; +A119;YI SYLLABLE DUR;Lo;0;L;;;;;N;;;;; +A11A;YI SYLLABLE TIT;Lo;0;L;;;;;N;;;;; +A11B;YI SYLLABLE TIX;Lo;0;L;;;;;N;;;;; +A11C;YI SYLLABLE TI;Lo;0;L;;;;;N;;;;; +A11D;YI SYLLABLE TIP;Lo;0;L;;;;;N;;;;; +A11E;YI SYLLABLE TIEX;Lo;0;L;;;;;N;;;;; +A11F;YI SYLLABLE TIE;Lo;0;L;;;;;N;;;;; +A120;YI SYLLABLE TIEP;Lo;0;L;;;;;N;;;;; +A121;YI SYLLABLE TAT;Lo;0;L;;;;;N;;;;; +A122;YI SYLLABLE TAX;Lo;0;L;;;;;N;;;;; +A123;YI SYLLABLE TA;Lo;0;L;;;;;N;;;;; +A124;YI SYLLABLE TAP;Lo;0;L;;;;;N;;;;; +A125;YI SYLLABLE TUOT;Lo;0;L;;;;;N;;;;; +A126;YI SYLLABLE TUOX;Lo;0;L;;;;;N;;;;; +A127;YI SYLLABLE TUO;Lo;0;L;;;;;N;;;;; +A128;YI SYLLABLE TUOP;Lo;0;L;;;;;N;;;;; +A129;YI SYLLABLE TOT;Lo;0;L;;;;;N;;;;; +A12A;YI SYLLABLE TOX;Lo;0;L;;;;;N;;;;; +A12B;YI SYLLABLE TO;Lo;0;L;;;;;N;;;;; +A12C;YI SYLLABLE TOP;Lo;0;L;;;;;N;;;;; +A12D;YI SYLLABLE TEX;Lo;0;L;;;;;N;;;;; +A12E;YI SYLLABLE TE;Lo;0;L;;;;;N;;;;; +A12F;YI SYLLABLE TEP;Lo;0;L;;;;;N;;;;; +A130;YI SYLLABLE TUT;Lo;0;L;;;;;N;;;;; +A131;YI SYLLABLE TUX;Lo;0;L;;;;;N;;;;; +A132;YI SYLLABLE TU;Lo;0;L;;;;;N;;;;; +A133;YI SYLLABLE TUP;Lo;0;L;;;;;N;;;;; +A134;YI SYLLABLE TURX;Lo;0;L;;;;;N;;;;; +A135;YI SYLLABLE TUR;Lo;0;L;;;;;N;;;;; +A136;YI SYLLABLE DDIT;Lo;0;L;;;;;N;;;;; +A137;YI SYLLABLE DDIX;Lo;0;L;;;;;N;;;;; +A138;YI SYLLABLE DDI;Lo;0;L;;;;;N;;;;; +A139;YI SYLLABLE DDIP;Lo;0;L;;;;;N;;;;; +A13A;YI SYLLABLE DDIEX;Lo;0;L;;;;;N;;;;; +A13B;YI SYLLABLE DDIE;Lo;0;L;;;;;N;;;;; +A13C;YI SYLLABLE DDIEP;Lo;0;L;;;;;N;;;;; +A13D;YI SYLLABLE DDAT;Lo;0;L;;;;;N;;;;; +A13E;YI SYLLABLE DDAX;Lo;0;L;;;;;N;;;;; +A13F;YI SYLLABLE DDA;Lo;0;L;;;;;N;;;;; +A140;YI SYLLABLE DDAP;Lo;0;L;;;;;N;;;;; +A141;YI SYLLABLE DDUOX;Lo;0;L;;;;;N;;;;; +A142;YI SYLLABLE DDUO;Lo;0;L;;;;;N;;;;; +A143;YI SYLLABLE DDUOP;Lo;0;L;;;;;N;;;;; +A144;YI SYLLABLE DDOT;Lo;0;L;;;;;N;;;;; +A145;YI SYLLABLE DDOX;Lo;0;L;;;;;N;;;;; +A146;YI SYLLABLE DDO;Lo;0;L;;;;;N;;;;; +A147;YI SYLLABLE DDOP;Lo;0;L;;;;;N;;;;; +A148;YI SYLLABLE DDEX;Lo;0;L;;;;;N;;;;; +A149;YI SYLLABLE DDE;Lo;0;L;;;;;N;;;;; +A14A;YI SYLLABLE DDEP;Lo;0;L;;;;;N;;;;; +A14B;YI SYLLABLE DDUT;Lo;0;L;;;;;N;;;;; +A14C;YI SYLLABLE DDUX;Lo;0;L;;;;;N;;;;; +A14D;YI SYLLABLE DDU;Lo;0;L;;;;;N;;;;; +A14E;YI SYLLABLE DDUP;Lo;0;L;;;;;N;;;;; +A14F;YI SYLLABLE DDURX;Lo;0;L;;;;;N;;;;; +A150;YI SYLLABLE DDUR;Lo;0;L;;;;;N;;;;; +A151;YI SYLLABLE NDIT;Lo;0;L;;;;;N;;;;; +A152;YI SYLLABLE NDIX;Lo;0;L;;;;;N;;;;; +A153;YI SYLLABLE NDI;Lo;0;L;;;;;N;;;;; +A154;YI SYLLABLE NDIP;Lo;0;L;;;;;N;;;;; +A155;YI SYLLABLE NDIEX;Lo;0;L;;;;;N;;;;; +A156;YI SYLLABLE NDIE;Lo;0;L;;;;;N;;;;; +A157;YI SYLLABLE NDAT;Lo;0;L;;;;;N;;;;; +A158;YI SYLLABLE NDAX;Lo;0;L;;;;;N;;;;; +A159;YI SYLLABLE NDA;Lo;0;L;;;;;N;;;;; +A15A;YI SYLLABLE NDAP;Lo;0;L;;;;;N;;;;; +A15B;YI SYLLABLE NDOT;Lo;0;L;;;;;N;;;;; +A15C;YI SYLLABLE NDOX;Lo;0;L;;;;;N;;;;; +A15D;YI SYLLABLE NDO;Lo;0;L;;;;;N;;;;; +A15E;YI SYLLABLE NDOP;Lo;0;L;;;;;N;;;;; +A15F;YI SYLLABLE NDEX;Lo;0;L;;;;;N;;;;; +A160;YI SYLLABLE NDE;Lo;0;L;;;;;N;;;;; +A161;YI SYLLABLE NDEP;Lo;0;L;;;;;N;;;;; +A162;YI SYLLABLE NDUT;Lo;0;L;;;;;N;;;;; +A163;YI SYLLABLE NDUX;Lo;0;L;;;;;N;;;;; +A164;YI SYLLABLE NDU;Lo;0;L;;;;;N;;;;; +A165;YI SYLLABLE NDUP;Lo;0;L;;;;;N;;;;; +A166;YI SYLLABLE NDURX;Lo;0;L;;;;;N;;;;; +A167;YI SYLLABLE NDUR;Lo;0;L;;;;;N;;;;; +A168;YI SYLLABLE HNIT;Lo;0;L;;;;;N;;;;; +A169;YI SYLLABLE HNIX;Lo;0;L;;;;;N;;;;; +A16A;YI SYLLABLE HNI;Lo;0;L;;;;;N;;;;; +A16B;YI SYLLABLE HNIP;Lo;0;L;;;;;N;;;;; +A16C;YI SYLLABLE HNIET;Lo;0;L;;;;;N;;;;; +A16D;YI SYLLABLE HNIEX;Lo;0;L;;;;;N;;;;; +A16E;YI SYLLABLE HNIE;Lo;0;L;;;;;N;;;;; +A16F;YI SYLLABLE HNIEP;Lo;0;L;;;;;N;;;;; +A170;YI SYLLABLE HNAT;Lo;0;L;;;;;N;;;;; +A171;YI SYLLABLE HNAX;Lo;0;L;;;;;N;;;;; +A172;YI SYLLABLE HNA;Lo;0;L;;;;;N;;;;; +A173;YI SYLLABLE HNAP;Lo;0;L;;;;;N;;;;; +A174;YI SYLLABLE HNUOX;Lo;0;L;;;;;N;;;;; +A175;YI SYLLABLE HNUO;Lo;0;L;;;;;N;;;;; +A176;YI SYLLABLE HNOT;Lo;0;L;;;;;N;;;;; +A177;YI SYLLABLE HNOX;Lo;0;L;;;;;N;;;;; +A178;YI SYLLABLE HNOP;Lo;0;L;;;;;N;;;;; +A179;YI SYLLABLE HNEX;Lo;0;L;;;;;N;;;;; +A17A;YI SYLLABLE HNE;Lo;0;L;;;;;N;;;;; +A17B;YI SYLLABLE HNEP;Lo;0;L;;;;;N;;;;; +A17C;YI SYLLABLE HNUT;Lo;0;L;;;;;N;;;;; +A17D;YI SYLLABLE NIT;Lo;0;L;;;;;N;;;;; +A17E;YI SYLLABLE NIX;Lo;0;L;;;;;N;;;;; +A17F;YI SYLLABLE NI;Lo;0;L;;;;;N;;;;; +A180;YI SYLLABLE NIP;Lo;0;L;;;;;N;;;;; +A181;YI SYLLABLE NIEX;Lo;0;L;;;;;N;;;;; +A182;YI SYLLABLE NIE;Lo;0;L;;;;;N;;;;; +A183;YI SYLLABLE NIEP;Lo;0;L;;;;;N;;;;; +A184;YI SYLLABLE NAX;Lo;0;L;;;;;N;;;;; +A185;YI SYLLABLE NA;Lo;0;L;;;;;N;;;;; +A186;YI SYLLABLE NAP;Lo;0;L;;;;;N;;;;; +A187;YI SYLLABLE NUOX;Lo;0;L;;;;;N;;;;; +A188;YI SYLLABLE NUO;Lo;0;L;;;;;N;;;;; +A189;YI SYLLABLE NUOP;Lo;0;L;;;;;N;;;;; +A18A;YI SYLLABLE NOT;Lo;0;L;;;;;N;;;;; +A18B;YI SYLLABLE NOX;Lo;0;L;;;;;N;;;;; +A18C;YI SYLLABLE NO;Lo;0;L;;;;;N;;;;; +A18D;YI SYLLABLE NOP;Lo;0;L;;;;;N;;;;; +A18E;YI SYLLABLE NEX;Lo;0;L;;;;;N;;;;; +A18F;YI SYLLABLE NE;Lo;0;L;;;;;N;;;;; +A190;YI SYLLABLE NEP;Lo;0;L;;;;;N;;;;; +A191;YI SYLLABLE NUT;Lo;0;L;;;;;N;;;;; +A192;YI SYLLABLE NUX;Lo;0;L;;;;;N;;;;; +A193;YI SYLLABLE NU;Lo;0;L;;;;;N;;;;; +A194;YI SYLLABLE NUP;Lo;0;L;;;;;N;;;;; +A195;YI SYLLABLE NURX;Lo;0;L;;;;;N;;;;; +A196;YI SYLLABLE NUR;Lo;0;L;;;;;N;;;;; +A197;YI SYLLABLE HLIT;Lo;0;L;;;;;N;;;;; +A198;YI SYLLABLE HLIX;Lo;0;L;;;;;N;;;;; +A199;YI SYLLABLE HLI;Lo;0;L;;;;;N;;;;; +A19A;YI SYLLABLE HLIP;Lo;0;L;;;;;N;;;;; +A19B;YI SYLLABLE HLIEX;Lo;0;L;;;;;N;;;;; +A19C;YI SYLLABLE HLIE;Lo;0;L;;;;;N;;;;; +A19D;YI SYLLABLE HLIEP;Lo;0;L;;;;;N;;;;; +A19E;YI SYLLABLE HLAT;Lo;0;L;;;;;N;;;;; +A19F;YI SYLLABLE HLAX;Lo;0;L;;;;;N;;;;; +A1A0;YI SYLLABLE HLA;Lo;0;L;;;;;N;;;;; +A1A1;YI SYLLABLE HLAP;Lo;0;L;;;;;N;;;;; +A1A2;YI SYLLABLE HLUOX;Lo;0;L;;;;;N;;;;; +A1A3;YI SYLLABLE HLUO;Lo;0;L;;;;;N;;;;; +A1A4;YI SYLLABLE HLUOP;Lo;0;L;;;;;N;;;;; +A1A5;YI SYLLABLE HLOX;Lo;0;L;;;;;N;;;;; +A1A6;YI SYLLABLE HLO;Lo;0;L;;;;;N;;;;; +A1A7;YI SYLLABLE HLOP;Lo;0;L;;;;;N;;;;; +A1A8;YI SYLLABLE HLEX;Lo;0;L;;;;;N;;;;; +A1A9;YI SYLLABLE HLE;Lo;0;L;;;;;N;;;;; +A1AA;YI SYLLABLE HLEP;Lo;0;L;;;;;N;;;;; +A1AB;YI SYLLABLE HLUT;Lo;0;L;;;;;N;;;;; +A1AC;YI SYLLABLE HLUX;Lo;0;L;;;;;N;;;;; +A1AD;YI SYLLABLE HLU;Lo;0;L;;;;;N;;;;; +A1AE;YI SYLLABLE HLUP;Lo;0;L;;;;;N;;;;; +A1AF;YI SYLLABLE HLURX;Lo;0;L;;;;;N;;;;; +A1B0;YI SYLLABLE HLUR;Lo;0;L;;;;;N;;;;; +A1B1;YI SYLLABLE HLYT;Lo;0;L;;;;;N;;;;; +A1B2;YI SYLLABLE HLYX;Lo;0;L;;;;;N;;;;; +A1B3;YI SYLLABLE HLY;Lo;0;L;;;;;N;;;;; +A1B4;YI SYLLABLE HLYP;Lo;0;L;;;;;N;;;;; +A1B5;YI SYLLABLE HLYRX;Lo;0;L;;;;;N;;;;; +A1B6;YI SYLLABLE HLYR;Lo;0;L;;;;;N;;;;; +A1B7;YI SYLLABLE LIT;Lo;0;L;;;;;N;;;;; +A1B8;YI SYLLABLE LIX;Lo;0;L;;;;;N;;;;; +A1B9;YI SYLLABLE LI;Lo;0;L;;;;;N;;;;; +A1BA;YI SYLLABLE LIP;Lo;0;L;;;;;N;;;;; +A1BB;YI SYLLABLE LIET;Lo;0;L;;;;;N;;;;; +A1BC;YI SYLLABLE LIEX;Lo;0;L;;;;;N;;;;; +A1BD;YI SYLLABLE LIE;Lo;0;L;;;;;N;;;;; +A1BE;YI SYLLABLE LIEP;Lo;0;L;;;;;N;;;;; +A1BF;YI SYLLABLE LAT;Lo;0;L;;;;;N;;;;; +A1C0;YI SYLLABLE LAX;Lo;0;L;;;;;N;;;;; +A1C1;YI SYLLABLE LA;Lo;0;L;;;;;N;;;;; +A1C2;YI SYLLABLE LAP;Lo;0;L;;;;;N;;;;; +A1C3;YI SYLLABLE LUOT;Lo;0;L;;;;;N;;;;; +A1C4;YI SYLLABLE LUOX;Lo;0;L;;;;;N;;;;; +A1C5;YI SYLLABLE LUO;Lo;0;L;;;;;N;;;;; +A1C6;YI SYLLABLE LUOP;Lo;0;L;;;;;N;;;;; +A1C7;YI SYLLABLE LOT;Lo;0;L;;;;;N;;;;; +A1C8;YI SYLLABLE LOX;Lo;0;L;;;;;N;;;;; +A1C9;YI SYLLABLE LO;Lo;0;L;;;;;N;;;;; +A1CA;YI SYLLABLE LOP;Lo;0;L;;;;;N;;;;; +A1CB;YI SYLLABLE LEX;Lo;0;L;;;;;N;;;;; +A1CC;YI SYLLABLE LE;Lo;0;L;;;;;N;;;;; +A1CD;YI SYLLABLE LEP;Lo;0;L;;;;;N;;;;; +A1CE;YI SYLLABLE LUT;Lo;0;L;;;;;N;;;;; +A1CF;YI SYLLABLE LUX;Lo;0;L;;;;;N;;;;; +A1D0;YI SYLLABLE LU;Lo;0;L;;;;;N;;;;; +A1D1;YI SYLLABLE LUP;Lo;0;L;;;;;N;;;;; +A1D2;YI SYLLABLE LURX;Lo;0;L;;;;;N;;;;; +A1D3;YI SYLLABLE LUR;Lo;0;L;;;;;N;;;;; +A1D4;YI SYLLABLE LYT;Lo;0;L;;;;;N;;;;; +A1D5;YI SYLLABLE LYX;Lo;0;L;;;;;N;;;;; +A1D6;YI SYLLABLE LY;Lo;0;L;;;;;N;;;;; +A1D7;YI SYLLABLE LYP;Lo;0;L;;;;;N;;;;; +A1D8;YI SYLLABLE LYRX;Lo;0;L;;;;;N;;;;; +A1D9;YI SYLLABLE LYR;Lo;0;L;;;;;N;;;;; +A1DA;YI SYLLABLE GIT;Lo;0;L;;;;;N;;;;; +A1DB;YI SYLLABLE GIX;Lo;0;L;;;;;N;;;;; +A1DC;YI SYLLABLE GI;Lo;0;L;;;;;N;;;;; +A1DD;YI SYLLABLE GIP;Lo;0;L;;;;;N;;;;; +A1DE;YI SYLLABLE GIET;Lo;0;L;;;;;N;;;;; +A1DF;YI SYLLABLE GIEX;Lo;0;L;;;;;N;;;;; +A1E0;YI SYLLABLE GIE;Lo;0;L;;;;;N;;;;; +A1E1;YI SYLLABLE GIEP;Lo;0;L;;;;;N;;;;; +A1E2;YI SYLLABLE GAT;Lo;0;L;;;;;N;;;;; +A1E3;YI SYLLABLE GAX;Lo;0;L;;;;;N;;;;; +A1E4;YI SYLLABLE GA;Lo;0;L;;;;;N;;;;; +A1E5;YI SYLLABLE GAP;Lo;0;L;;;;;N;;;;; +A1E6;YI SYLLABLE GUOT;Lo;0;L;;;;;N;;;;; +A1E7;YI SYLLABLE GUOX;Lo;0;L;;;;;N;;;;; +A1E8;YI SYLLABLE GUO;Lo;0;L;;;;;N;;;;; +A1E9;YI SYLLABLE GUOP;Lo;0;L;;;;;N;;;;; +A1EA;YI SYLLABLE GOT;Lo;0;L;;;;;N;;;;; +A1EB;YI SYLLABLE GOX;Lo;0;L;;;;;N;;;;; +A1EC;YI SYLLABLE GO;Lo;0;L;;;;;N;;;;; +A1ED;YI SYLLABLE GOP;Lo;0;L;;;;;N;;;;; +A1EE;YI SYLLABLE GET;Lo;0;L;;;;;N;;;;; +A1EF;YI SYLLABLE GEX;Lo;0;L;;;;;N;;;;; +A1F0;YI SYLLABLE GE;Lo;0;L;;;;;N;;;;; +A1F1;YI SYLLABLE GEP;Lo;0;L;;;;;N;;;;; +A1F2;YI SYLLABLE GUT;Lo;0;L;;;;;N;;;;; +A1F3;YI SYLLABLE GUX;Lo;0;L;;;;;N;;;;; +A1F4;YI SYLLABLE GU;Lo;0;L;;;;;N;;;;; +A1F5;YI SYLLABLE GUP;Lo;0;L;;;;;N;;;;; +A1F6;YI SYLLABLE GURX;Lo;0;L;;;;;N;;;;; +A1F7;YI SYLLABLE GUR;Lo;0;L;;;;;N;;;;; +A1F8;YI SYLLABLE KIT;Lo;0;L;;;;;N;;;;; +A1F9;YI SYLLABLE KIX;Lo;0;L;;;;;N;;;;; +A1FA;YI SYLLABLE KI;Lo;0;L;;;;;N;;;;; +A1FB;YI SYLLABLE KIP;Lo;0;L;;;;;N;;;;; +A1FC;YI SYLLABLE KIEX;Lo;0;L;;;;;N;;;;; +A1FD;YI SYLLABLE KIE;Lo;0;L;;;;;N;;;;; +A1FE;YI SYLLABLE KIEP;Lo;0;L;;;;;N;;;;; +A1FF;YI SYLLABLE KAT;Lo;0;L;;;;;N;;;;; +A200;YI SYLLABLE KAX;Lo;0;L;;;;;N;;;;; +A201;YI SYLLABLE KA;Lo;0;L;;;;;N;;;;; +A202;YI SYLLABLE KAP;Lo;0;L;;;;;N;;;;; +A203;YI SYLLABLE KUOX;Lo;0;L;;;;;N;;;;; +A204;YI SYLLABLE KUO;Lo;0;L;;;;;N;;;;; +A205;YI SYLLABLE KUOP;Lo;0;L;;;;;N;;;;; +A206;YI SYLLABLE KOT;Lo;0;L;;;;;N;;;;; +A207;YI SYLLABLE KOX;Lo;0;L;;;;;N;;;;; +A208;YI SYLLABLE KO;Lo;0;L;;;;;N;;;;; +A209;YI SYLLABLE KOP;Lo;0;L;;;;;N;;;;; +A20A;YI SYLLABLE KET;Lo;0;L;;;;;N;;;;; +A20B;YI SYLLABLE KEX;Lo;0;L;;;;;N;;;;; +A20C;YI SYLLABLE KE;Lo;0;L;;;;;N;;;;; +A20D;YI SYLLABLE KEP;Lo;0;L;;;;;N;;;;; +A20E;YI SYLLABLE KUT;Lo;0;L;;;;;N;;;;; +A20F;YI SYLLABLE KUX;Lo;0;L;;;;;N;;;;; +A210;YI SYLLABLE KU;Lo;0;L;;;;;N;;;;; +A211;YI SYLLABLE KUP;Lo;0;L;;;;;N;;;;; +A212;YI SYLLABLE KURX;Lo;0;L;;;;;N;;;;; +A213;YI SYLLABLE KUR;Lo;0;L;;;;;N;;;;; +A214;YI SYLLABLE GGIT;Lo;0;L;;;;;N;;;;; +A215;YI SYLLABLE GGIX;Lo;0;L;;;;;N;;;;; +A216;YI SYLLABLE GGI;Lo;0;L;;;;;N;;;;; +A217;YI SYLLABLE GGIEX;Lo;0;L;;;;;N;;;;; +A218;YI SYLLABLE GGIE;Lo;0;L;;;;;N;;;;; +A219;YI SYLLABLE GGIEP;Lo;0;L;;;;;N;;;;; +A21A;YI SYLLABLE GGAT;Lo;0;L;;;;;N;;;;; +A21B;YI SYLLABLE GGAX;Lo;0;L;;;;;N;;;;; +A21C;YI SYLLABLE GGA;Lo;0;L;;;;;N;;;;; +A21D;YI SYLLABLE GGAP;Lo;0;L;;;;;N;;;;; +A21E;YI SYLLABLE GGUOT;Lo;0;L;;;;;N;;;;; +A21F;YI SYLLABLE GGUOX;Lo;0;L;;;;;N;;;;; +A220;YI SYLLABLE GGUO;Lo;0;L;;;;;N;;;;; +A221;YI SYLLABLE GGUOP;Lo;0;L;;;;;N;;;;; +A222;YI SYLLABLE GGOT;Lo;0;L;;;;;N;;;;; +A223;YI SYLLABLE GGOX;Lo;0;L;;;;;N;;;;; +A224;YI SYLLABLE GGO;Lo;0;L;;;;;N;;;;; +A225;YI SYLLABLE GGOP;Lo;0;L;;;;;N;;;;; +A226;YI SYLLABLE GGET;Lo;0;L;;;;;N;;;;; +A227;YI SYLLABLE GGEX;Lo;0;L;;;;;N;;;;; +A228;YI SYLLABLE GGE;Lo;0;L;;;;;N;;;;; +A229;YI SYLLABLE GGEP;Lo;0;L;;;;;N;;;;; +A22A;YI SYLLABLE GGUT;Lo;0;L;;;;;N;;;;; +A22B;YI SYLLABLE GGUX;Lo;0;L;;;;;N;;;;; +A22C;YI SYLLABLE GGU;Lo;0;L;;;;;N;;;;; +A22D;YI SYLLABLE GGUP;Lo;0;L;;;;;N;;;;; +A22E;YI SYLLABLE GGURX;Lo;0;L;;;;;N;;;;; +A22F;YI SYLLABLE GGUR;Lo;0;L;;;;;N;;;;; +A230;YI SYLLABLE MGIEX;Lo;0;L;;;;;N;;;;; +A231;YI SYLLABLE MGIE;Lo;0;L;;;;;N;;;;; +A232;YI SYLLABLE MGAT;Lo;0;L;;;;;N;;;;; +A233;YI SYLLABLE MGAX;Lo;0;L;;;;;N;;;;; +A234;YI SYLLABLE MGA;Lo;0;L;;;;;N;;;;; +A235;YI SYLLABLE MGAP;Lo;0;L;;;;;N;;;;; +A236;YI SYLLABLE MGUOX;Lo;0;L;;;;;N;;;;; +A237;YI SYLLABLE MGUO;Lo;0;L;;;;;N;;;;; +A238;YI SYLLABLE MGUOP;Lo;0;L;;;;;N;;;;; +A239;YI SYLLABLE MGOT;Lo;0;L;;;;;N;;;;; +A23A;YI SYLLABLE MGOX;Lo;0;L;;;;;N;;;;; +A23B;YI SYLLABLE MGO;Lo;0;L;;;;;N;;;;; +A23C;YI SYLLABLE MGOP;Lo;0;L;;;;;N;;;;; +A23D;YI SYLLABLE MGEX;Lo;0;L;;;;;N;;;;; +A23E;YI SYLLABLE MGE;Lo;0;L;;;;;N;;;;; +A23F;YI SYLLABLE MGEP;Lo;0;L;;;;;N;;;;; +A240;YI SYLLABLE MGUT;Lo;0;L;;;;;N;;;;; +A241;YI SYLLABLE MGUX;Lo;0;L;;;;;N;;;;; +A242;YI SYLLABLE MGU;Lo;0;L;;;;;N;;;;; +A243;YI SYLLABLE MGUP;Lo;0;L;;;;;N;;;;; +A244;YI SYLLABLE MGURX;Lo;0;L;;;;;N;;;;; +A245;YI SYLLABLE MGUR;Lo;0;L;;;;;N;;;;; +A246;YI SYLLABLE HXIT;Lo;0;L;;;;;N;;;;; +A247;YI SYLLABLE HXIX;Lo;0;L;;;;;N;;;;; +A248;YI SYLLABLE HXI;Lo;0;L;;;;;N;;;;; +A249;YI SYLLABLE HXIP;Lo;0;L;;;;;N;;;;; +A24A;YI SYLLABLE HXIET;Lo;0;L;;;;;N;;;;; +A24B;YI SYLLABLE HXIEX;Lo;0;L;;;;;N;;;;; +A24C;YI SYLLABLE HXIE;Lo;0;L;;;;;N;;;;; +A24D;YI SYLLABLE HXIEP;Lo;0;L;;;;;N;;;;; +A24E;YI SYLLABLE HXAT;Lo;0;L;;;;;N;;;;; +A24F;YI SYLLABLE HXAX;Lo;0;L;;;;;N;;;;; +A250;YI SYLLABLE HXA;Lo;0;L;;;;;N;;;;; +A251;YI SYLLABLE HXAP;Lo;0;L;;;;;N;;;;; +A252;YI SYLLABLE HXUOT;Lo;0;L;;;;;N;;;;; +A253;YI SYLLABLE HXUOX;Lo;0;L;;;;;N;;;;; +A254;YI SYLLABLE HXUO;Lo;0;L;;;;;N;;;;; +A255;YI SYLLABLE HXUOP;Lo;0;L;;;;;N;;;;; +A256;YI SYLLABLE HXOT;Lo;0;L;;;;;N;;;;; +A257;YI SYLLABLE HXOX;Lo;0;L;;;;;N;;;;; +A258;YI SYLLABLE HXO;Lo;0;L;;;;;N;;;;; +A259;YI SYLLABLE HXOP;Lo;0;L;;;;;N;;;;; +A25A;YI SYLLABLE HXEX;Lo;0;L;;;;;N;;;;; +A25B;YI SYLLABLE HXE;Lo;0;L;;;;;N;;;;; +A25C;YI SYLLABLE HXEP;Lo;0;L;;;;;N;;;;; +A25D;YI SYLLABLE NGIEX;Lo;0;L;;;;;N;;;;; +A25E;YI SYLLABLE NGIE;Lo;0;L;;;;;N;;;;; +A25F;YI SYLLABLE NGIEP;Lo;0;L;;;;;N;;;;; +A260;YI SYLLABLE NGAT;Lo;0;L;;;;;N;;;;; +A261;YI SYLLABLE NGAX;Lo;0;L;;;;;N;;;;; +A262;YI SYLLABLE NGA;Lo;0;L;;;;;N;;;;; +A263;YI SYLLABLE NGAP;Lo;0;L;;;;;N;;;;; +A264;YI SYLLABLE NGUOT;Lo;0;L;;;;;N;;;;; +A265;YI SYLLABLE NGUOX;Lo;0;L;;;;;N;;;;; +A266;YI SYLLABLE NGUO;Lo;0;L;;;;;N;;;;; +A267;YI SYLLABLE NGOT;Lo;0;L;;;;;N;;;;; +A268;YI SYLLABLE NGOX;Lo;0;L;;;;;N;;;;; +A269;YI SYLLABLE NGO;Lo;0;L;;;;;N;;;;; +A26A;YI SYLLABLE NGOP;Lo;0;L;;;;;N;;;;; +A26B;YI SYLLABLE NGEX;Lo;0;L;;;;;N;;;;; +A26C;YI SYLLABLE NGE;Lo;0;L;;;;;N;;;;; +A26D;YI SYLLABLE NGEP;Lo;0;L;;;;;N;;;;; +A26E;YI SYLLABLE HIT;Lo;0;L;;;;;N;;;;; +A26F;YI SYLLABLE HIEX;Lo;0;L;;;;;N;;;;; +A270;YI SYLLABLE HIE;Lo;0;L;;;;;N;;;;; +A271;YI SYLLABLE HAT;Lo;0;L;;;;;N;;;;; +A272;YI SYLLABLE HAX;Lo;0;L;;;;;N;;;;; +A273;YI SYLLABLE HA;Lo;0;L;;;;;N;;;;; +A274;YI SYLLABLE HAP;Lo;0;L;;;;;N;;;;; +A275;YI SYLLABLE HUOT;Lo;0;L;;;;;N;;;;; +A276;YI SYLLABLE HUOX;Lo;0;L;;;;;N;;;;; +A277;YI SYLLABLE HUO;Lo;0;L;;;;;N;;;;; +A278;YI SYLLABLE HUOP;Lo;0;L;;;;;N;;;;; +A279;YI SYLLABLE HOT;Lo;0;L;;;;;N;;;;; +A27A;YI SYLLABLE HOX;Lo;0;L;;;;;N;;;;; +A27B;YI SYLLABLE HO;Lo;0;L;;;;;N;;;;; +A27C;YI SYLLABLE HOP;Lo;0;L;;;;;N;;;;; +A27D;YI SYLLABLE HEX;Lo;0;L;;;;;N;;;;; +A27E;YI SYLLABLE HE;Lo;0;L;;;;;N;;;;; +A27F;YI SYLLABLE HEP;Lo;0;L;;;;;N;;;;; +A280;YI SYLLABLE WAT;Lo;0;L;;;;;N;;;;; +A281;YI SYLLABLE WAX;Lo;0;L;;;;;N;;;;; +A282;YI SYLLABLE WA;Lo;0;L;;;;;N;;;;; +A283;YI SYLLABLE WAP;Lo;0;L;;;;;N;;;;; +A284;YI SYLLABLE WUOX;Lo;0;L;;;;;N;;;;; +A285;YI SYLLABLE WUO;Lo;0;L;;;;;N;;;;; +A286;YI SYLLABLE WUOP;Lo;0;L;;;;;N;;;;; +A287;YI SYLLABLE WOX;Lo;0;L;;;;;N;;;;; +A288;YI SYLLABLE WO;Lo;0;L;;;;;N;;;;; +A289;YI SYLLABLE WOP;Lo;0;L;;;;;N;;;;; +A28A;YI SYLLABLE WEX;Lo;0;L;;;;;N;;;;; +A28B;YI SYLLABLE WE;Lo;0;L;;;;;N;;;;; +A28C;YI SYLLABLE WEP;Lo;0;L;;;;;N;;;;; +A28D;YI SYLLABLE ZIT;Lo;0;L;;;;;N;;;;; +A28E;YI SYLLABLE ZIX;Lo;0;L;;;;;N;;;;; +A28F;YI SYLLABLE ZI;Lo;0;L;;;;;N;;;;; +A290;YI SYLLABLE ZIP;Lo;0;L;;;;;N;;;;; +A291;YI SYLLABLE ZIEX;Lo;0;L;;;;;N;;;;; +A292;YI SYLLABLE ZIE;Lo;0;L;;;;;N;;;;; +A293;YI SYLLABLE ZIEP;Lo;0;L;;;;;N;;;;; +A294;YI SYLLABLE ZAT;Lo;0;L;;;;;N;;;;; +A295;YI SYLLABLE ZAX;Lo;0;L;;;;;N;;;;; +A296;YI SYLLABLE ZA;Lo;0;L;;;;;N;;;;; +A297;YI SYLLABLE ZAP;Lo;0;L;;;;;N;;;;; +A298;YI SYLLABLE ZUOX;Lo;0;L;;;;;N;;;;; +A299;YI SYLLABLE ZUO;Lo;0;L;;;;;N;;;;; +A29A;YI SYLLABLE ZUOP;Lo;0;L;;;;;N;;;;; +A29B;YI SYLLABLE ZOT;Lo;0;L;;;;;N;;;;; +A29C;YI SYLLABLE ZOX;Lo;0;L;;;;;N;;;;; +A29D;YI SYLLABLE ZO;Lo;0;L;;;;;N;;;;; +A29E;YI SYLLABLE ZOP;Lo;0;L;;;;;N;;;;; +A29F;YI SYLLABLE ZEX;Lo;0;L;;;;;N;;;;; +A2A0;YI SYLLABLE ZE;Lo;0;L;;;;;N;;;;; +A2A1;YI SYLLABLE ZEP;Lo;0;L;;;;;N;;;;; +A2A2;YI SYLLABLE ZUT;Lo;0;L;;;;;N;;;;; +A2A3;YI SYLLABLE ZUX;Lo;0;L;;;;;N;;;;; +A2A4;YI SYLLABLE ZU;Lo;0;L;;;;;N;;;;; +A2A5;YI SYLLABLE ZUP;Lo;0;L;;;;;N;;;;; +A2A6;YI SYLLABLE ZURX;Lo;0;L;;;;;N;;;;; +A2A7;YI SYLLABLE ZUR;Lo;0;L;;;;;N;;;;; +A2A8;YI SYLLABLE ZYT;Lo;0;L;;;;;N;;;;; +A2A9;YI SYLLABLE ZYX;Lo;0;L;;;;;N;;;;; +A2AA;YI SYLLABLE ZY;Lo;0;L;;;;;N;;;;; +A2AB;YI SYLLABLE ZYP;Lo;0;L;;;;;N;;;;; +A2AC;YI SYLLABLE ZYRX;Lo;0;L;;;;;N;;;;; +A2AD;YI SYLLABLE ZYR;Lo;0;L;;;;;N;;;;; +A2AE;YI SYLLABLE CIT;Lo;0;L;;;;;N;;;;; +A2AF;YI SYLLABLE CIX;Lo;0;L;;;;;N;;;;; +A2B0;YI SYLLABLE CI;Lo;0;L;;;;;N;;;;; +A2B1;YI SYLLABLE CIP;Lo;0;L;;;;;N;;;;; +A2B2;YI SYLLABLE CIET;Lo;0;L;;;;;N;;;;; +A2B3;YI SYLLABLE CIEX;Lo;0;L;;;;;N;;;;; +A2B4;YI SYLLABLE CIE;Lo;0;L;;;;;N;;;;; +A2B5;YI SYLLABLE CIEP;Lo;0;L;;;;;N;;;;; +A2B6;YI SYLLABLE CAT;Lo;0;L;;;;;N;;;;; +A2B7;YI SYLLABLE CAX;Lo;0;L;;;;;N;;;;; +A2B8;YI SYLLABLE CA;Lo;0;L;;;;;N;;;;; +A2B9;YI SYLLABLE CAP;Lo;0;L;;;;;N;;;;; +A2BA;YI SYLLABLE CUOX;Lo;0;L;;;;;N;;;;; +A2BB;YI SYLLABLE CUO;Lo;0;L;;;;;N;;;;; +A2BC;YI SYLLABLE CUOP;Lo;0;L;;;;;N;;;;; +A2BD;YI SYLLABLE COT;Lo;0;L;;;;;N;;;;; +A2BE;YI SYLLABLE COX;Lo;0;L;;;;;N;;;;; +A2BF;YI SYLLABLE CO;Lo;0;L;;;;;N;;;;; +A2C0;YI SYLLABLE COP;Lo;0;L;;;;;N;;;;; +A2C1;YI SYLLABLE CEX;Lo;0;L;;;;;N;;;;; +A2C2;YI SYLLABLE CE;Lo;0;L;;;;;N;;;;; +A2C3;YI SYLLABLE CEP;Lo;0;L;;;;;N;;;;; +A2C4;YI SYLLABLE CUT;Lo;0;L;;;;;N;;;;; +A2C5;YI SYLLABLE CUX;Lo;0;L;;;;;N;;;;; +A2C6;YI SYLLABLE CU;Lo;0;L;;;;;N;;;;; +A2C7;YI SYLLABLE CUP;Lo;0;L;;;;;N;;;;; +A2C8;YI SYLLABLE CURX;Lo;0;L;;;;;N;;;;; +A2C9;YI SYLLABLE CUR;Lo;0;L;;;;;N;;;;; +A2CA;YI SYLLABLE CYT;Lo;0;L;;;;;N;;;;; +A2CB;YI SYLLABLE CYX;Lo;0;L;;;;;N;;;;; +A2CC;YI SYLLABLE CY;Lo;0;L;;;;;N;;;;; +A2CD;YI SYLLABLE CYP;Lo;0;L;;;;;N;;;;; +A2CE;YI SYLLABLE CYRX;Lo;0;L;;;;;N;;;;; +A2CF;YI SYLLABLE CYR;Lo;0;L;;;;;N;;;;; +A2D0;YI SYLLABLE ZZIT;Lo;0;L;;;;;N;;;;; +A2D1;YI SYLLABLE ZZIX;Lo;0;L;;;;;N;;;;; +A2D2;YI SYLLABLE ZZI;Lo;0;L;;;;;N;;;;; +A2D3;YI SYLLABLE ZZIP;Lo;0;L;;;;;N;;;;; +A2D4;YI SYLLABLE ZZIET;Lo;0;L;;;;;N;;;;; +A2D5;YI SYLLABLE ZZIEX;Lo;0;L;;;;;N;;;;; +A2D6;YI SYLLABLE ZZIE;Lo;0;L;;;;;N;;;;; +A2D7;YI SYLLABLE ZZIEP;Lo;0;L;;;;;N;;;;; +A2D8;YI SYLLABLE ZZAT;Lo;0;L;;;;;N;;;;; +A2D9;YI SYLLABLE ZZAX;Lo;0;L;;;;;N;;;;; +A2DA;YI SYLLABLE ZZA;Lo;0;L;;;;;N;;;;; +A2DB;YI SYLLABLE ZZAP;Lo;0;L;;;;;N;;;;; +A2DC;YI SYLLABLE ZZOX;Lo;0;L;;;;;N;;;;; +A2DD;YI SYLLABLE ZZO;Lo;0;L;;;;;N;;;;; +A2DE;YI SYLLABLE ZZOP;Lo;0;L;;;;;N;;;;; +A2DF;YI SYLLABLE ZZEX;Lo;0;L;;;;;N;;;;; +A2E0;YI SYLLABLE ZZE;Lo;0;L;;;;;N;;;;; +A2E1;YI SYLLABLE ZZEP;Lo;0;L;;;;;N;;;;; +A2E2;YI SYLLABLE ZZUX;Lo;0;L;;;;;N;;;;; +A2E3;YI SYLLABLE ZZU;Lo;0;L;;;;;N;;;;; +A2E4;YI SYLLABLE ZZUP;Lo;0;L;;;;;N;;;;; +A2E5;YI SYLLABLE ZZURX;Lo;0;L;;;;;N;;;;; +A2E6;YI SYLLABLE ZZUR;Lo;0;L;;;;;N;;;;; +A2E7;YI SYLLABLE ZZYT;Lo;0;L;;;;;N;;;;; +A2E8;YI SYLLABLE ZZYX;Lo;0;L;;;;;N;;;;; +A2E9;YI SYLLABLE ZZY;Lo;0;L;;;;;N;;;;; +A2EA;YI SYLLABLE ZZYP;Lo;0;L;;;;;N;;;;; +A2EB;YI SYLLABLE ZZYRX;Lo;0;L;;;;;N;;;;; +A2EC;YI SYLLABLE ZZYR;Lo;0;L;;;;;N;;;;; +A2ED;YI SYLLABLE NZIT;Lo;0;L;;;;;N;;;;; +A2EE;YI SYLLABLE NZIX;Lo;0;L;;;;;N;;;;; +A2EF;YI SYLLABLE NZI;Lo;0;L;;;;;N;;;;; +A2F0;YI SYLLABLE NZIP;Lo;0;L;;;;;N;;;;; +A2F1;YI SYLLABLE NZIEX;Lo;0;L;;;;;N;;;;; +A2F2;YI SYLLABLE NZIE;Lo;0;L;;;;;N;;;;; +A2F3;YI SYLLABLE NZIEP;Lo;0;L;;;;;N;;;;; +A2F4;YI SYLLABLE NZAT;Lo;0;L;;;;;N;;;;; +A2F5;YI SYLLABLE NZAX;Lo;0;L;;;;;N;;;;; +A2F6;YI SYLLABLE NZA;Lo;0;L;;;;;N;;;;; +A2F7;YI SYLLABLE NZAP;Lo;0;L;;;;;N;;;;; +A2F8;YI SYLLABLE NZUOX;Lo;0;L;;;;;N;;;;; +A2F9;YI SYLLABLE NZUO;Lo;0;L;;;;;N;;;;; +A2FA;YI SYLLABLE NZOX;Lo;0;L;;;;;N;;;;; +A2FB;YI SYLLABLE NZOP;Lo;0;L;;;;;N;;;;; +A2FC;YI SYLLABLE NZEX;Lo;0;L;;;;;N;;;;; +A2FD;YI SYLLABLE NZE;Lo;0;L;;;;;N;;;;; +A2FE;YI SYLLABLE NZUX;Lo;0;L;;;;;N;;;;; +A2FF;YI SYLLABLE NZU;Lo;0;L;;;;;N;;;;; +A300;YI SYLLABLE NZUP;Lo;0;L;;;;;N;;;;; +A301;YI SYLLABLE NZURX;Lo;0;L;;;;;N;;;;; +A302;YI SYLLABLE NZUR;Lo;0;L;;;;;N;;;;; +A303;YI SYLLABLE NZYT;Lo;0;L;;;;;N;;;;; +A304;YI SYLLABLE NZYX;Lo;0;L;;;;;N;;;;; +A305;YI SYLLABLE NZY;Lo;0;L;;;;;N;;;;; +A306;YI SYLLABLE NZYP;Lo;0;L;;;;;N;;;;; +A307;YI SYLLABLE NZYRX;Lo;0;L;;;;;N;;;;; +A308;YI SYLLABLE NZYR;Lo;0;L;;;;;N;;;;; +A309;YI SYLLABLE SIT;Lo;0;L;;;;;N;;;;; +A30A;YI SYLLABLE SIX;Lo;0;L;;;;;N;;;;; +A30B;YI SYLLABLE SI;Lo;0;L;;;;;N;;;;; +A30C;YI SYLLABLE SIP;Lo;0;L;;;;;N;;;;; +A30D;YI SYLLABLE SIEX;Lo;0;L;;;;;N;;;;; +A30E;YI SYLLABLE SIE;Lo;0;L;;;;;N;;;;; +A30F;YI SYLLABLE SIEP;Lo;0;L;;;;;N;;;;; +A310;YI SYLLABLE SAT;Lo;0;L;;;;;N;;;;; +A311;YI SYLLABLE SAX;Lo;0;L;;;;;N;;;;; +A312;YI SYLLABLE SA;Lo;0;L;;;;;N;;;;; +A313;YI SYLLABLE SAP;Lo;0;L;;;;;N;;;;; +A314;YI SYLLABLE SUOX;Lo;0;L;;;;;N;;;;; +A315;YI SYLLABLE SUO;Lo;0;L;;;;;N;;;;; +A316;YI SYLLABLE SUOP;Lo;0;L;;;;;N;;;;; +A317;YI SYLLABLE SOT;Lo;0;L;;;;;N;;;;; +A318;YI SYLLABLE SOX;Lo;0;L;;;;;N;;;;; +A319;YI SYLLABLE SO;Lo;0;L;;;;;N;;;;; +A31A;YI SYLLABLE SOP;Lo;0;L;;;;;N;;;;; +A31B;YI SYLLABLE SEX;Lo;0;L;;;;;N;;;;; +A31C;YI SYLLABLE SE;Lo;0;L;;;;;N;;;;; +A31D;YI SYLLABLE SEP;Lo;0;L;;;;;N;;;;; +A31E;YI SYLLABLE SUT;Lo;0;L;;;;;N;;;;; +A31F;YI SYLLABLE SUX;Lo;0;L;;;;;N;;;;; +A320;YI SYLLABLE SU;Lo;0;L;;;;;N;;;;; +A321;YI SYLLABLE SUP;Lo;0;L;;;;;N;;;;; +A322;YI SYLLABLE SURX;Lo;0;L;;;;;N;;;;; +A323;YI SYLLABLE SUR;Lo;0;L;;;;;N;;;;; +A324;YI SYLLABLE SYT;Lo;0;L;;;;;N;;;;; +A325;YI SYLLABLE SYX;Lo;0;L;;;;;N;;;;; +A326;YI SYLLABLE SY;Lo;0;L;;;;;N;;;;; +A327;YI SYLLABLE SYP;Lo;0;L;;;;;N;;;;; +A328;YI SYLLABLE SYRX;Lo;0;L;;;;;N;;;;; +A329;YI SYLLABLE SYR;Lo;0;L;;;;;N;;;;; +A32A;YI SYLLABLE SSIT;Lo;0;L;;;;;N;;;;; +A32B;YI SYLLABLE SSIX;Lo;0;L;;;;;N;;;;; +A32C;YI SYLLABLE SSI;Lo;0;L;;;;;N;;;;; +A32D;YI SYLLABLE SSIP;Lo;0;L;;;;;N;;;;; +A32E;YI SYLLABLE SSIEX;Lo;0;L;;;;;N;;;;; +A32F;YI SYLLABLE SSIE;Lo;0;L;;;;;N;;;;; +A330;YI SYLLABLE SSIEP;Lo;0;L;;;;;N;;;;; +A331;YI SYLLABLE SSAT;Lo;0;L;;;;;N;;;;; +A332;YI SYLLABLE SSAX;Lo;0;L;;;;;N;;;;; +A333;YI SYLLABLE SSA;Lo;0;L;;;;;N;;;;; +A334;YI SYLLABLE SSAP;Lo;0;L;;;;;N;;;;; +A335;YI SYLLABLE SSOT;Lo;0;L;;;;;N;;;;; +A336;YI SYLLABLE SSOX;Lo;0;L;;;;;N;;;;; +A337;YI SYLLABLE SSO;Lo;0;L;;;;;N;;;;; +A338;YI SYLLABLE SSOP;Lo;0;L;;;;;N;;;;; +A339;YI SYLLABLE SSEX;Lo;0;L;;;;;N;;;;; +A33A;YI SYLLABLE SSE;Lo;0;L;;;;;N;;;;; +A33B;YI SYLLABLE SSEP;Lo;0;L;;;;;N;;;;; +A33C;YI SYLLABLE SSUT;Lo;0;L;;;;;N;;;;; +A33D;YI SYLLABLE SSUX;Lo;0;L;;;;;N;;;;; +A33E;YI SYLLABLE SSU;Lo;0;L;;;;;N;;;;; +A33F;YI SYLLABLE SSUP;Lo;0;L;;;;;N;;;;; +A340;YI SYLLABLE SSYT;Lo;0;L;;;;;N;;;;; +A341;YI SYLLABLE SSYX;Lo;0;L;;;;;N;;;;; +A342;YI SYLLABLE SSY;Lo;0;L;;;;;N;;;;; +A343;YI SYLLABLE SSYP;Lo;0;L;;;;;N;;;;; +A344;YI SYLLABLE SSYRX;Lo;0;L;;;;;N;;;;; +A345;YI SYLLABLE SSYR;Lo;0;L;;;;;N;;;;; +A346;YI SYLLABLE ZHAT;Lo;0;L;;;;;N;;;;; +A347;YI SYLLABLE ZHAX;Lo;0;L;;;;;N;;;;; +A348;YI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; +A349;YI SYLLABLE ZHAP;Lo;0;L;;;;;N;;;;; +A34A;YI SYLLABLE ZHUOX;Lo;0;L;;;;;N;;;;; +A34B;YI SYLLABLE ZHUO;Lo;0;L;;;;;N;;;;; +A34C;YI SYLLABLE ZHUOP;Lo;0;L;;;;;N;;;;; +A34D;YI SYLLABLE ZHOT;Lo;0;L;;;;;N;;;;; +A34E;YI SYLLABLE ZHOX;Lo;0;L;;;;;N;;;;; +A34F;YI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; +A350;YI SYLLABLE ZHOP;Lo;0;L;;;;;N;;;;; +A351;YI SYLLABLE ZHET;Lo;0;L;;;;;N;;;;; +A352;YI SYLLABLE ZHEX;Lo;0;L;;;;;N;;;;; +A353;YI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; +A354;YI SYLLABLE ZHEP;Lo;0;L;;;;;N;;;;; +A355;YI SYLLABLE ZHUT;Lo;0;L;;;;;N;;;;; +A356;YI SYLLABLE ZHUX;Lo;0;L;;;;;N;;;;; +A357;YI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; +A358;YI SYLLABLE ZHUP;Lo;0;L;;;;;N;;;;; +A359;YI SYLLABLE ZHURX;Lo;0;L;;;;;N;;;;; +A35A;YI SYLLABLE ZHUR;Lo;0;L;;;;;N;;;;; +A35B;YI SYLLABLE ZHYT;Lo;0;L;;;;;N;;;;; +A35C;YI SYLLABLE ZHYX;Lo;0;L;;;;;N;;;;; +A35D;YI SYLLABLE ZHY;Lo;0;L;;;;;N;;;;; +A35E;YI SYLLABLE ZHYP;Lo;0;L;;;;;N;;;;; +A35F;YI SYLLABLE ZHYRX;Lo;0;L;;;;;N;;;;; +A360;YI SYLLABLE ZHYR;Lo;0;L;;;;;N;;;;; +A361;YI SYLLABLE CHAT;Lo;0;L;;;;;N;;;;; +A362;YI SYLLABLE CHAX;Lo;0;L;;;;;N;;;;; +A363;YI SYLLABLE CHA;Lo;0;L;;;;;N;;;;; +A364;YI SYLLABLE CHAP;Lo;0;L;;;;;N;;;;; +A365;YI SYLLABLE CHUOT;Lo;0;L;;;;;N;;;;; +A366;YI SYLLABLE CHUOX;Lo;0;L;;;;;N;;;;; +A367;YI SYLLABLE CHUO;Lo;0;L;;;;;N;;;;; +A368;YI SYLLABLE CHUOP;Lo;0;L;;;;;N;;;;; +A369;YI SYLLABLE CHOT;Lo;0;L;;;;;N;;;;; +A36A;YI SYLLABLE CHOX;Lo;0;L;;;;;N;;;;; +A36B;YI SYLLABLE CHO;Lo;0;L;;;;;N;;;;; +A36C;YI SYLLABLE CHOP;Lo;0;L;;;;;N;;;;; +A36D;YI SYLLABLE CHET;Lo;0;L;;;;;N;;;;; +A36E;YI SYLLABLE CHEX;Lo;0;L;;;;;N;;;;; +A36F;YI SYLLABLE CHE;Lo;0;L;;;;;N;;;;; +A370;YI SYLLABLE CHEP;Lo;0;L;;;;;N;;;;; +A371;YI SYLLABLE CHUX;Lo;0;L;;;;;N;;;;; +A372;YI SYLLABLE CHU;Lo;0;L;;;;;N;;;;; +A373;YI SYLLABLE CHUP;Lo;0;L;;;;;N;;;;; +A374;YI SYLLABLE CHURX;Lo;0;L;;;;;N;;;;; +A375;YI SYLLABLE CHUR;Lo;0;L;;;;;N;;;;; +A376;YI SYLLABLE CHYT;Lo;0;L;;;;;N;;;;; +A377;YI SYLLABLE CHYX;Lo;0;L;;;;;N;;;;; +A378;YI SYLLABLE CHY;Lo;0;L;;;;;N;;;;; +A379;YI SYLLABLE CHYP;Lo;0;L;;;;;N;;;;; +A37A;YI SYLLABLE CHYRX;Lo;0;L;;;;;N;;;;; +A37B;YI SYLLABLE CHYR;Lo;0;L;;;;;N;;;;; +A37C;YI SYLLABLE RRAX;Lo;0;L;;;;;N;;;;; +A37D;YI SYLLABLE RRA;Lo;0;L;;;;;N;;;;; +A37E;YI SYLLABLE RRUOX;Lo;0;L;;;;;N;;;;; +A37F;YI SYLLABLE RRUO;Lo;0;L;;;;;N;;;;; +A380;YI SYLLABLE RROT;Lo;0;L;;;;;N;;;;; +A381;YI SYLLABLE RROX;Lo;0;L;;;;;N;;;;; +A382;YI SYLLABLE RRO;Lo;0;L;;;;;N;;;;; +A383;YI SYLLABLE RROP;Lo;0;L;;;;;N;;;;; +A384;YI SYLLABLE RRET;Lo;0;L;;;;;N;;;;; +A385;YI SYLLABLE RREX;Lo;0;L;;;;;N;;;;; +A386;YI SYLLABLE RRE;Lo;0;L;;;;;N;;;;; +A387;YI SYLLABLE RREP;Lo;0;L;;;;;N;;;;; +A388;YI SYLLABLE RRUT;Lo;0;L;;;;;N;;;;; +A389;YI SYLLABLE RRUX;Lo;0;L;;;;;N;;;;; +A38A;YI SYLLABLE RRU;Lo;0;L;;;;;N;;;;; +A38B;YI SYLLABLE RRUP;Lo;0;L;;;;;N;;;;; +A38C;YI SYLLABLE RRURX;Lo;0;L;;;;;N;;;;; +A38D;YI SYLLABLE RRUR;Lo;0;L;;;;;N;;;;; +A38E;YI SYLLABLE RRYT;Lo;0;L;;;;;N;;;;; +A38F;YI SYLLABLE RRYX;Lo;0;L;;;;;N;;;;; +A390;YI SYLLABLE RRY;Lo;0;L;;;;;N;;;;; +A391;YI SYLLABLE RRYP;Lo;0;L;;;;;N;;;;; +A392;YI SYLLABLE RRYRX;Lo;0;L;;;;;N;;;;; +A393;YI SYLLABLE RRYR;Lo;0;L;;;;;N;;;;; +A394;YI SYLLABLE NRAT;Lo;0;L;;;;;N;;;;; +A395;YI SYLLABLE NRAX;Lo;0;L;;;;;N;;;;; +A396;YI SYLLABLE NRA;Lo;0;L;;;;;N;;;;; +A397;YI SYLLABLE NRAP;Lo;0;L;;;;;N;;;;; +A398;YI SYLLABLE NROX;Lo;0;L;;;;;N;;;;; +A399;YI SYLLABLE NRO;Lo;0;L;;;;;N;;;;; +A39A;YI SYLLABLE NROP;Lo;0;L;;;;;N;;;;; +A39B;YI SYLLABLE NRET;Lo;0;L;;;;;N;;;;; +A39C;YI SYLLABLE NREX;Lo;0;L;;;;;N;;;;; +A39D;YI SYLLABLE NRE;Lo;0;L;;;;;N;;;;; +A39E;YI SYLLABLE NREP;Lo;0;L;;;;;N;;;;; +A39F;YI SYLLABLE NRUT;Lo;0;L;;;;;N;;;;; +A3A0;YI SYLLABLE NRUX;Lo;0;L;;;;;N;;;;; +A3A1;YI SYLLABLE NRU;Lo;0;L;;;;;N;;;;; +A3A2;YI SYLLABLE NRUP;Lo;0;L;;;;;N;;;;; +A3A3;YI SYLLABLE NRURX;Lo;0;L;;;;;N;;;;; +A3A4;YI SYLLABLE NRUR;Lo;0;L;;;;;N;;;;; +A3A5;YI SYLLABLE NRYT;Lo;0;L;;;;;N;;;;; +A3A6;YI SYLLABLE NRYX;Lo;0;L;;;;;N;;;;; +A3A7;YI SYLLABLE NRY;Lo;0;L;;;;;N;;;;; +A3A8;YI SYLLABLE NRYP;Lo;0;L;;;;;N;;;;; +A3A9;YI SYLLABLE NRYRX;Lo;0;L;;;;;N;;;;; +A3AA;YI SYLLABLE NRYR;Lo;0;L;;;;;N;;;;; +A3AB;YI SYLLABLE SHAT;Lo;0;L;;;;;N;;;;; +A3AC;YI SYLLABLE SHAX;Lo;0;L;;;;;N;;;;; +A3AD;YI SYLLABLE SHA;Lo;0;L;;;;;N;;;;; +A3AE;YI SYLLABLE SHAP;Lo;0;L;;;;;N;;;;; +A3AF;YI SYLLABLE SHUOX;Lo;0;L;;;;;N;;;;; +A3B0;YI SYLLABLE SHUO;Lo;0;L;;;;;N;;;;; +A3B1;YI SYLLABLE SHUOP;Lo;0;L;;;;;N;;;;; +A3B2;YI SYLLABLE SHOT;Lo;0;L;;;;;N;;;;; +A3B3;YI SYLLABLE SHOX;Lo;0;L;;;;;N;;;;; +A3B4;YI SYLLABLE SHO;Lo;0;L;;;;;N;;;;; +A3B5;YI SYLLABLE SHOP;Lo;0;L;;;;;N;;;;; +A3B6;YI SYLLABLE SHET;Lo;0;L;;;;;N;;;;; +A3B7;YI SYLLABLE SHEX;Lo;0;L;;;;;N;;;;; +A3B8;YI SYLLABLE SHE;Lo;0;L;;;;;N;;;;; +A3B9;YI SYLLABLE SHEP;Lo;0;L;;;;;N;;;;; +A3BA;YI SYLLABLE SHUT;Lo;0;L;;;;;N;;;;; +A3BB;YI SYLLABLE SHUX;Lo;0;L;;;;;N;;;;; +A3BC;YI SYLLABLE SHU;Lo;0;L;;;;;N;;;;; +A3BD;YI SYLLABLE SHUP;Lo;0;L;;;;;N;;;;; +A3BE;YI SYLLABLE SHURX;Lo;0;L;;;;;N;;;;; +A3BF;YI SYLLABLE SHUR;Lo;0;L;;;;;N;;;;; +A3C0;YI SYLLABLE SHYT;Lo;0;L;;;;;N;;;;; +A3C1;YI SYLLABLE SHYX;Lo;0;L;;;;;N;;;;; +A3C2;YI SYLLABLE SHY;Lo;0;L;;;;;N;;;;; +A3C3;YI SYLLABLE SHYP;Lo;0;L;;;;;N;;;;; +A3C4;YI SYLLABLE SHYRX;Lo;0;L;;;;;N;;;;; +A3C5;YI SYLLABLE SHYR;Lo;0;L;;;;;N;;;;; +A3C6;YI SYLLABLE RAT;Lo;0;L;;;;;N;;;;; +A3C7;YI SYLLABLE RAX;Lo;0;L;;;;;N;;;;; +A3C8;YI SYLLABLE RA;Lo;0;L;;;;;N;;;;; +A3C9;YI SYLLABLE RAP;Lo;0;L;;;;;N;;;;; +A3CA;YI SYLLABLE RUOX;Lo;0;L;;;;;N;;;;; +A3CB;YI SYLLABLE RUO;Lo;0;L;;;;;N;;;;; +A3CC;YI SYLLABLE RUOP;Lo;0;L;;;;;N;;;;; +A3CD;YI SYLLABLE ROT;Lo;0;L;;;;;N;;;;; +A3CE;YI SYLLABLE ROX;Lo;0;L;;;;;N;;;;; +A3CF;YI SYLLABLE RO;Lo;0;L;;;;;N;;;;; +A3D0;YI SYLLABLE ROP;Lo;0;L;;;;;N;;;;; +A3D1;YI SYLLABLE REX;Lo;0;L;;;;;N;;;;; +A3D2;YI SYLLABLE RE;Lo;0;L;;;;;N;;;;; +A3D3;YI SYLLABLE REP;Lo;0;L;;;;;N;;;;; +A3D4;YI SYLLABLE RUT;Lo;0;L;;;;;N;;;;; +A3D5;YI SYLLABLE RUX;Lo;0;L;;;;;N;;;;; +A3D6;YI SYLLABLE RU;Lo;0;L;;;;;N;;;;; +A3D7;YI SYLLABLE RUP;Lo;0;L;;;;;N;;;;; +A3D8;YI SYLLABLE RURX;Lo;0;L;;;;;N;;;;; +A3D9;YI SYLLABLE RUR;Lo;0;L;;;;;N;;;;; +A3DA;YI SYLLABLE RYT;Lo;0;L;;;;;N;;;;; +A3DB;YI SYLLABLE RYX;Lo;0;L;;;;;N;;;;; +A3DC;YI SYLLABLE RY;Lo;0;L;;;;;N;;;;; +A3DD;YI SYLLABLE RYP;Lo;0;L;;;;;N;;;;; +A3DE;YI SYLLABLE RYRX;Lo;0;L;;;;;N;;;;; +A3DF;YI SYLLABLE RYR;Lo;0;L;;;;;N;;;;; +A3E0;YI SYLLABLE JIT;Lo;0;L;;;;;N;;;;; +A3E1;YI SYLLABLE JIX;Lo;0;L;;;;;N;;;;; +A3E2;YI SYLLABLE JI;Lo;0;L;;;;;N;;;;; +A3E3;YI SYLLABLE JIP;Lo;0;L;;;;;N;;;;; +A3E4;YI SYLLABLE JIET;Lo;0;L;;;;;N;;;;; +A3E5;YI SYLLABLE JIEX;Lo;0;L;;;;;N;;;;; +A3E6;YI SYLLABLE JIE;Lo;0;L;;;;;N;;;;; +A3E7;YI SYLLABLE JIEP;Lo;0;L;;;;;N;;;;; +A3E8;YI SYLLABLE JUOT;Lo;0;L;;;;;N;;;;; +A3E9;YI SYLLABLE JUOX;Lo;0;L;;;;;N;;;;; +A3EA;YI SYLLABLE JUO;Lo;0;L;;;;;N;;;;; +A3EB;YI SYLLABLE JUOP;Lo;0;L;;;;;N;;;;; +A3EC;YI SYLLABLE JOT;Lo;0;L;;;;;N;;;;; +A3ED;YI SYLLABLE JOX;Lo;0;L;;;;;N;;;;; +A3EE;YI SYLLABLE JO;Lo;0;L;;;;;N;;;;; +A3EF;YI SYLLABLE JOP;Lo;0;L;;;;;N;;;;; +A3F0;YI SYLLABLE JUT;Lo;0;L;;;;;N;;;;; +A3F1;YI SYLLABLE JUX;Lo;0;L;;;;;N;;;;; +A3F2;YI SYLLABLE JU;Lo;0;L;;;;;N;;;;; +A3F3;YI SYLLABLE JUP;Lo;0;L;;;;;N;;;;; +A3F4;YI SYLLABLE JURX;Lo;0;L;;;;;N;;;;; +A3F5;YI SYLLABLE JUR;Lo;0;L;;;;;N;;;;; +A3F6;YI SYLLABLE JYT;Lo;0;L;;;;;N;;;;; +A3F7;YI SYLLABLE JYX;Lo;0;L;;;;;N;;;;; +A3F8;YI SYLLABLE JY;Lo;0;L;;;;;N;;;;; +A3F9;YI SYLLABLE JYP;Lo;0;L;;;;;N;;;;; +A3FA;YI SYLLABLE JYRX;Lo;0;L;;;;;N;;;;; +A3FB;YI SYLLABLE JYR;Lo;0;L;;;;;N;;;;; +A3FC;YI SYLLABLE QIT;Lo;0;L;;;;;N;;;;; +A3FD;YI SYLLABLE QIX;Lo;0;L;;;;;N;;;;; +A3FE;YI SYLLABLE QI;Lo;0;L;;;;;N;;;;; +A3FF;YI SYLLABLE QIP;Lo;0;L;;;;;N;;;;; +A400;YI SYLLABLE QIET;Lo;0;L;;;;;N;;;;; +A401;YI SYLLABLE QIEX;Lo;0;L;;;;;N;;;;; +A402;YI SYLLABLE QIE;Lo;0;L;;;;;N;;;;; +A403;YI SYLLABLE QIEP;Lo;0;L;;;;;N;;;;; +A404;YI SYLLABLE QUOT;Lo;0;L;;;;;N;;;;; +A405;YI SYLLABLE QUOX;Lo;0;L;;;;;N;;;;; +A406;YI SYLLABLE QUO;Lo;0;L;;;;;N;;;;; +A407;YI SYLLABLE QUOP;Lo;0;L;;;;;N;;;;; +A408;YI SYLLABLE QOT;Lo;0;L;;;;;N;;;;; +A409;YI SYLLABLE QOX;Lo;0;L;;;;;N;;;;; +A40A;YI SYLLABLE QO;Lo;0;L;;;;;N;;;;; +A40B;YI SYLLABLE QOP;Lo;0;L;;;;;N;;;;; +A40C;YI SYLLABLE QUT;Lo;0;L;;;;;N;;;;; +A40D;YI SYLLABLE QUX;Lo;0;L;;;;;N;;;;; +A40E;YI SYLLABLE QU;Lo;0;L;;;;;N;;;;; +A40F;YI SYLLABLE QUP;Lo;0;L;;;;;N;;;;; +A410;YI SYLLABLE QURX;Lo;0;L;;;;;N;;;;; +A411;YI SYLLABLE QUR;Lo;0;L;;;;;N;;;;; +A412;YI SYLLABLE QYT;Lo;0;L;;;;;N;;;;; +A413;YI SYLLABLE QYX;Lo;0;L;;;;;N;;;;; +A414;YI SYLLABLE QY;Lo;0;L;;;;;N;;;;; +A415;YI SYLLABLE QYP;Lo;0;L;;;;;N;;;;; +A416;YI SYLLABLE QYRX;Lo;0;L;;;;;N;;;;; +A417;YI SYLLABLE QYR;Lo;0;L;;;;;N;;;;; +A418;YI SYLLABLE JJIT;Lo;0;L;;;;;N;;;;; +A419;YI SYLLABLE JJIX;Lo;0;L;;;;;N;;;;; +A41A;YI SYLLABLE JJI;Lo;0;L;;;;;N;;;;; +A41B;YI SYLLABLE JJIP;Lo;0;L;;;;;N;;;;; +A41C;YI SYLLABLE JJIET;Lo;0;L;;;;;N;;;;; +A41D;YI SYLLABLE JJIEX;Lo;0;L;;;;;N;;;;; +A41E;YI SYLLABLE JJIE;Lo;0;L;;;;;N;;;;; +A41F;YI SYLLABLE JJIEP;Lo;0;L;;;;;N;;;;; +A420;YI SYLLABLE JJUOX;Lo;0;L;;;;;N;;;;; +A421;YI SYLLABLE JJUO;Lo;0;L;;;;;N;;;;; +A422;YI SYLLABLE JJUOP;Lo;0;L;;;;;N;;;;; +A423;YI SYLLABLE JJOT;Lo;0;L;;;;;N;;;;; +A424;YI SYLLABLE JJOX;Lo;0;L;;;;;N;;;;; +A425;YI SYLLABLE JJO;Lo;0;L;;;;;N;;;;; +A426;YI SYLLABLE JJOP;Lo;0;L;;;;;N;;;;; +A427;YI SYLLABLE JJUT;Lo;0;L;;;;;N;;;;; +A428;YI SYLLABLE JJUX;Lo;0;L;;;;;N;;;;; +A429;YI SYLLABLE JJU;Lo;0;L;;;;;N;;;;; +A42A;YI SYLLABLE JJUP;Lo;0;L;;;;;N;;;;; +A42B;YI SYLLABLE JJURX;Lo;0;L;;;;;N;;;;; +A42C;YI SYLLABLE JJUR;Lo;0;L;;;;;N;;;;; +A42D;YI SYLLABLE JJYT;Lo;0;L;;;;;N;;;;; +A42E;YI SYLLABLE JJYX;Lo;0;L;;;;;N;;;;; +A42F;YI SYLLABLE JJY;Lo;0;L;;;;;N;;;;; +A430;YI SYLLABLE JJYP;Lo;0;L;;;;;N;;;;; +A431;YI SYLLABLE NJIT;Lo;0;L;;;;;N;;;;; +A432;YI SYLLABLE NJIX;Lo;0;L;;;;;N;;;;; +A433;YI SYLLABLE NJI;Lo;0;L;;;;;N;;;;; +A434;YI SYLLABLE NJIP;Lo;0;L;;;;;N;;;;; +A435;YI SYLLABLE NJIET;Lo;0;L;;;;;N;;;;; +A436;YI SYLLABLE NJIEX;Lo;0;L;;;;;N;;;;; +A437;YI SYLLABLE NJIE;Lo;0;L;;;;;N;;;;; +A438;YI SYLLABLE NJIEP;Lo;0;L;;;;;N;;;;; +A439;YI SYLLABLE NJUOX;Lo;0;L;;;;;N;;;;; +A43A;YI SYLLABLE NJUO;Lo;0;L;;;;;N;;;;; +A43B;YI SYLLABLE NJOT;Lo;0;L;;;;;N;;;;; +A43C;YI SYLLABLE NJOX;Lo;0;L;;;;;N;;;;; +A43D;YI SYLLABLE NJO;Lo;0;L;;;;;N;;;;; +A43E;YI SYLLABLE NJOP;Lo;0;L;;;;;N;;;;; +A43F;YI SYLLABLE NJUX;Lo;0;L;;;;;N;;;;; +A440;YI SYLLABLE NJU;Lo;0;L;;;;;N;;;;; +A441;YI SYLLABLE NJUP;Lo;0;L;;;;;N;;;;; +A442;YI SYLLABLE NJURX;Lo;0;L;;;;;N;;;;; +A443;YI SYLLABLE NJUR;Lo;0;L;;;;;N;;;;; +A444;YI SYLLABLE NJYT;Lo;0;L;;;;;N;;;;; +A445;YI SYLLABLE NJYX;Lo;0;L;;;;;N;;;;; +A446;YI SYLLABLE NJY;Lo;0;L;;;;;N;;;;; +A447;YI SYLLABLE NJYP;Lo;0;L;;;;;N;;;;; +A448;YI SYLLABLE NJYRX;Lo;0;L;;;;;N;;;;; +A449;YI SYLLABLE NJYR;Lo;0;L;;;;;N;;;;; +A44A;YI SYLLABLE NYIT;Lo;0;L;;;;;N;;;;; +A44B;YI SYLLABLE NYIX;Lo;0;L;;;;;N;;;;; +A44C;YI SYLLABLE NYI;Lo;0;L;;;;;N;;;;; +A44D;YI SYLLABLE NYIP;Lo;0;L;;;;;N;;;;; +A44E;YI SYLLABLE NYIET;Lo;0;L;;;;;N;;;;; +A44F;YI SYLLABLE NYIEX;Lo;0;L;;;;;N;;;;; +A450;YI SYLLABLE NYIE;Lo;0;L;;;;;N;;;;; +A451;YI SYLLABLE NYIEP;Lo;0;L;;;;;N;;;;; +A452;YI SYLLABLE NYUOX;Lo;0;L;;;;;N;;;;; +A453;YI SYLLABLE NYUO;Lo;0;L;;;;;N;;;;; +A454;YI SYLLABLE NYUOP;Lo;0;L;;;;;N;;;;; +A455;YI SYLLABLE NYOT;Lo;0;L;;;;;N;;;;; +A456;YI SYLLABLE NYOX;Lo;0;L;;;;;N;;;;; +A457;YI SYLLABLE NYO;Lo;0;L;;;;;N;;;;; +A458;YI SYLLABLE NYOP;Lo;0;L;;;;;N;;;;; +A459;YI SYLLABLE NYUT;Lo;0;L;;;;;N;;;;; +A45A;YI SYLLABLE NYUX;Lo;0;L;;;;;N;;;;; +A45B;YI SYLLABLE NYU;Lo;0;L;;;;;N;;;;; +A45C;YI SYLLABLE NYUP;Lo;0;L;;;;;N;;;;; +A45D;YI SYLLABLE XIT;Lo;0;L;;;;;N;;;;; +A45E;YI SYLLABLE XIX;Lo;0;L;;;;;N;;;;; +A45F;YI SYLLABLE XI;Lo;0;L;;;;;N;;;;; +A460;YI SYLLABLE XIP;Lo;0;L;;;;;N;;;;; +A461;YI SYLLABLE XIET;Lo;0;L;;;;;N;;;;; +A462;YI SYLLABLE XIEX;Lo;0;L;;;;;N;;;;; +A463;YI SYLLABLE XIE;Lo;0;L;;;;;N;;;;; +A464;YI SYLLABLE XIEP;Lo;0;L;;;;;N;;;;; +A465;YI SYLLABLE XUOX;Lo;0;L;;;;;N;;;;; +A466;YI SYLLABLE XUO;Lo;0;L;;;;;N;;;;; +A467;YI SYLLABLE XOT;Lo;0;L;;;;;N;;;;; +A468;YI SYLLABLE XOX;Lo;0;L;;;;;N;;;;; +A469;YI SYLLABLE XO;Lo;0;L;;;;;N;;;;; +A46A;YI SYLLABLE XOP;Lo;0;L;;;;;N;;;;; +A46B;YI SYLLABLE XYT;Lo;0;L;;;;;N;;;;; +A46C;YI SYLLABLE XYX;Lo;0;L;;;;;N;;;;; +A46D;YI SYLLABLE XY;Lo;0;L;;;;;N;;;;; +A46E;YI SYLLABLE XYP;Lo;0;L;;;;;N;;;;; +A46F;YI SYLLABLE XYRX;Lo;0;L;;;;;N;;;;; +A470;YI SYLLABLE XYR;Lo;0;L;;;;;N;;;;; +A471;YI SYLLABLE YIT;Lo;0;L;;;;;N;;;;; +A472;YI SYLLABLE YIX;Lo;0;L;;;;;N;;;;; +A473;YI SYLLABLE YI;Lo;0;L;;;;;N;;;;; +A474;YI SYLLABLE YIP;Lo;0;L;;;;;N;;;;; +A475;YI SYLLABLE YIET;Lo;0;L;;;;;N;;;;; +A476;YI SYLLABLE YIEX;Lo;0;L;;;;;N;;;;; +A477;YI SYLLABLE YIE;Lo;0;L;;;;;N;;;;; +A478;YI SYLLABLE YIEP;Lo;0;L;;;;;N;;;;; +A479;YI SYLLABLE YUOT;Lo;0;L;;;;;N;;;;; +A47A;YI SYLLABLE YUOX;Lo;0;L;;;;;N;;;;; +A47B;YI SYLLABLE YUO;Lo;0;L;;;;;N;;;;; +A47C;YI SYLLABLE YUOP;Lo;0;L;;;;;N;;;;; +A47D;YI SYLLABLE YOT;Lo;0;L;;;;;N;;;;; +A47E;YI SYLLABLE YOX;Lo;0;L;;;;;N;;;;; +A47F;YI SYLLABLE YO;Lo;0;L;;;;;N;;;;; +A480;YI SYLLABLE YOP;Lo;0;L;;;;;N;;;;; +A481;YI SYLLABLE YUT;Lo;0;L;;;;;N;;;;; +A482;YI SYLLABLE YUX;Lo;0;L;;;;;N;;;;; +A483;YI SYLLABLE YU;Lo;0;L;;;;;N;;;;; +A484;YI SYLLABLE YUP;Lo;0;L;;;;;N;;;;; +A485;YI SYLLABLE YURX;Lo;0;L;;;;;N;;;;; +A486;YI SYLLABLE YUR;Lo;0;L;;;;;N;;;;; +A487;YI SYLLABLE YYT;Lo;0;L;;;;;N;;;;; +A488;YI SYLLABLE YYX;Lo;0;L;;;;;N;;;;; +A489;YI SYLLABLE YY;Lo;0;L;;;;;N;;;;; +A48A;YI SYLLABLE YYP;Lo;0;L;;;;;N;;;;; +A48B;YI SYLLABLE YYRX;Lo;0;L;;;;;N;;;;; +A48C;YI SYLLABLE YYR;Lo;0;L;;;;;N;;;;; +A490;YI RADICAL QOT;So;0;ON;;;;;N;;;;; +A491;YI RADICAL LI;So;0;ON;;;;;N;;;;; +A492;YI RADICAL KIT;So;0;ON;;;;;N;;;;; +A493;YI RADICAL NYIP;So;0;ON;;;;;N;;;;; +A494;YI RADICAL CYP;So;0;ON;;;;;N;;;;; +A495;YI RADICAL SSI;So;0;ON;;;;;N;;;;; +A496;YI RADICAL GGOP;So;0;ON;;;;;N;;;;; +A497;YI RADICAL GEP;So;0;ON;;;;;N;;;;; +A498;YI RADICAL MI;So;0;ON;;;;;N;;;;; +A499;YI RADICAL HXIT;So;0;ON;;;;;N;;;;; +A49A;YI RADICAL LYR;So;0;ON;;;;;N;;;;; +A49B;YI RADICAL BBUT;So;0;ON;;;;;N;;;;; +A49C;YI RADICAL MOP;So;0;ON;;;;;N;;;;; +A49D;YI RADICAL YO;So;0;ON;;;;;N;;;;; +A49E;YI RADICAL PUT;So;0;ON;;;;;N;;;;; +A49F;YI RADICAL HXUO;So;0;ON;;;;;N;;;;; +A4A0;YI RADICAL TAT;So;0;ON;;;;;N;;;;; +A4A1;YI RADICAL GA;So;0;ON;;;;;N;;;;; +A4A2;YI RADICAL ZUP;So;0;ON;;;;;N;;;;; +A4A3;YI RADICAL CYT;So;0;ON;;;;;N;;;;; +A4A4;YI RADICAL DDUR;So;0;ON;;;;;N;;;;; +A4A5;YI RADICAL BUR;So;0;ON;;;;;N;;;;; +A4A6;YI RADICAL GGUO;So;0;ON;;;;;N;;;;; +A4A7;YI RADICAL NYOP;So;0;ON;;;;;N;;;;; +A4A8;YI RADICAL TU;So;0;ON;;;;;N;;;;; +A4A9;YI RADICAL OP;So;0;ON;;;;;N;;;;; +A4AA;YI RADICAL JJUT;So;0;ON;;;;;N;;;;; +A4AB;YI RADICAL ZOT;So;0;ON;;;;;N;;;;; +A4AC;YI RADICAL PYT;So;0;ON;;;;;N;;;;; +A4AD;YI RADICAL HMO;So;0;ON;;;;;N;;;;; +A4AE;YI RADICAL YIT;So;0;ON;;;;;N;;;;; +A4AF;YI RADICAL VUR;So;0;ON;;;;;N;;;;; +A4B0;YI RADICAL SHY;So;0;ON;;;;;N;;;;; +A4B1;YI RADICAL VEP;So;0;ON;;;;;N;;;;; +A4B2;YI RADICAL ZA;So;0;ON;;;;;N;;;;; +A4B3;YI RADICAL JO;So;0;ON;;;;;N;;;;; +A4B4;YI RADICAL NZUP;So;0;ON;;;;;N;;;;; +A4B5;YI RADICAL JJY;So;0;ON;;;;;N;;;;; +A4B6;YI RADICAL GOT;So;0;ON;;;;;N;;;;; +A4B7;YI RADICAL JJIE;So;0;ON;;;;;N;;;;; +A4B8;YI RADICAL WO;So;0;ON;;;;;N;;;;; +A4B9;YI RADICAL DU;So;0;ON;;;;;N;;;;; +A4BA;YI RADICAL SHUR;So;0;ON;;;;;N;;;;; +A4BB;YI RADICAL LIE;So;0;ON;;;;;N;;;;; +A4BC;YI RADICAL CY;So;0;ON;;;;;N;;;;; +A4BD;YI RADICAL CUOP;So;0;ON;;;;;N;;;;; +A4BE;YI RADICAL CIP;So;0;ON;;;;;N;;;;; +A4BF;YI RADICAL HXOP;So;0;ON;;;;;N;;;;; +A4C0;YI RADICAL SHAT;So;0;ON;;;;;N;;;;; +A4C1;YI RADICAL ZUR;So;0;ON;;;;;N;;;;; +A4C2;YI RADICAL SHOP;So;0;ON;;;;;N;;;;; +A4C3;YI RADICAL CHE;So;0;ON;;;;;N;;;;; +A4C4;YI RADICAL ZZIET;So;0;ON;;;;;N;;;;; +A4C5;YI RADICAL NBIE;So;0;ON;;;;;N;;;;; +A4C6;YI RADICAL KE;So;0;ON;;;;;N;;;;; +A4D0;LISU LETTER BA;Lo;0;L;;;;;N;;;;; +A4D1;LISU LETTER PA;Lo;0;L;;;;;N;;;;; +A4D2;LISU LETTER PHA;Lo;0;L;;;;;N;;;;; +A4D3;LISU LETTER DA;Lo;0;L;;;;;N;;;;; +A4D4;LISU LETTER TA;Lo;0;L;;;;;N;;;;; +A4D5;LISU LETTER THA;Lo;0;L;;;;;N;;;;; +A4D6;LISU LETTER GA;Lo;0;L;;;;;N;;;;; +A4D7;LISU LETTER KA;Lo;0;L;;;;;N;;;;; +A4D8;LISU LETTER KHA;Lo;0;L;;;;;N;;;;; +A4D9;LISU LETTER JA;Lo;0;L;;;;;N;;;;; +A4DA;LISU LETTER CA;Lo;0;L;;;;;N;;;;; +A4DB;LISU LETTER CHA;Lo;0;L;;;;;N;;;;; +A4DC;LISU LETTER DZA;Lo;0;L;;;;;N;;;;; +A4DD;LISU LETTER TSA;Lo;0;L;;;;;N;;;;; +A4DE;LISU LETTER TSHA;Lo;0;L;;;;;N;;;;; +A4DF;LISU LETTER MA;Lo;0;L;;;;;N;;;;; +A4E0;LISU LETTER NA;Lo;0;L;;;;;N;;;;; +A4E1;LISU LETTER LA;Lo;0;L;;;;;N;;;;; +A4E2;LISU LETTER SA;Lo;0;L;;;;;N;;;;; +A4E3;LISU LETTER ZHA;Lo;0;L;;;;;N;;;;; +A4E4;LISU LETTER ZA;Lo;0;L;;;;;N;;;;; +A4E5;LISU LETTER NGA;Lo;0;L;;;;;N;;;;; +A4E6;LISU LETTER HA;Lo;0;L;;;;;N;;;;; +A4E7;LISU LETTER XA;Lo;0;L;;;;;N;;;;; +A4E8;LISU LETTER HHA;Lo;0;L;;;;;N;;;;; +A4E9;LISU LETTER FA;Lo;0;L;;;;;N;;;;; +A4EA;LISU LETTER WA;Lo;0;L;;;;;N;;;;; +A4EB;LISU LETTER SHA;Lo;0;L;;;;;N;;;;; +A4EC;LISU LETTER YA;Lo;0;L;;;;;N;;;;; +A4ED;LISU LETTER GHA;Lo;0;L;;;;;N;;;;; +A4EE;LISU LETTER A;Lo;0;L;;;;;N;;;;; +A4EF;LISU LETTER AE;Lo;0;L;;;;;N;;;;; +A4F0;LISU LETTER E;Lo;0;L;;;;;N;;;;; +A4F1;LISU LETTER EU;Lo;0;L;;;;;N;;;;; +A4F2;LISU LETTER I;Lo;0;L;;;;;N;;;;; +A4F3;LISU LETTER O;Lo;0;L;;;;;N;;;;; +A4F4;LISU LETTER U;Lo;0;L;;;;;N;;;;; +A4F5;LISU LETTER UE;Lo;0;L;;;;;N;;;;; +A4F6;LISU LETTER UH;Lo;0;L;;;;;N;;;;; +A4F7;LISU LETTER OE;Lo;0;L;;;;;N;;;;; +A4F8;LISU LETTER TONE MYA TI;Lm;0;L;;;;;N;;;;; +A4F9;LISU LETTER TONE NA PO;Lm;0;L;;;;;N;;;;; +A4FA;LISU LETTER TONE MYA CYA;Lm;0;L;;;;;N;;;;; +A4FB;LISU LETTER TONE MYA BO;Lm;0;L;;;;;N;;;;; +A4FC;LISU LETTER TONE MYA NA;Lm;0;L;;;;;N;;;;; +A4FD;LISU LETTER TONE MYA JEU;Lm;0;L;;;;;N;;;;; +A4FE;LISU PUNCTUATION COMMA;Po;0;L;;;;;N;;;;; +A4FF;LISU PUNCTUATION FULL STOP;Po;0;L;;;;;N;;;;; +A500;VAI SYLLABLE EE;Lo;0;L;;;;;N;;;;; +A501;VAI SYLLABLE EEN;Lo;0;L;;;;;N;;;;; +A502;VAI SYLLABLE HEE;Lo;0;L;;;;;N;;;;; +A503;VAI SYLLABLE WEE;Lo;0;L;;;;;N;;;;; +A504;VAI SYLLABLE WEEN;Lo;0;L;;;;;N;;;;; +A505;VAI SYLLABLE PEE;Lo;0;L;;;;;N;;;;; +A506;VAI SYLLABLE BHEE;Lo;0;L;;;;;N;;;;; +A507;VAI SYLLABLE BEE;Lo;0;L;;;;;N;;;;; +A508;VAI SYLLABLE MBEE;Lo;0;L;;;;;N;;;;; +A509;VAI SYLLABLE KPEE;Lo;0;L;;;;;N;;;;; +A50A;VAI SYLLABLE MGBEE;Lo;0;L;;;;;N;;;;; +A50B;VAI SYLLABLE GBEE;Lo;0;L;;;;;N;;;;; +A50C;VAI SYLLABLE FEE;Lo;0;L;;;;;N;;;;; +A50D;VAI SYLLABLE VEE;Lo;0;L;;;;;N;;;;; +A50E;VAI SYLLABLE TEE;Lo;0;L;;;;;N;;;;; +A50F;VAI SYLLABLE THEE;Lo;0;L;;;;;N;;;;; +A510;VAI SYLLABLE DHEE;Lo;0;L;;;;;N;;;;; +A511;VAI SYLLABLE DHHEE;Lo;0;L;;;;;N;;;;; +A512;VAI SYLLABLE LEE;Lo;0;L;;;;;N;;;;; +A513;VAI SYLLABLE REE;Lo;0;L;;;;;N;;;;; +A514;VAI SYLLABLE DEE;Lo;0;L;;;;;N;;;;; +A515;VAI SYLLABLE NDEE;Lo;0;L;;;;;N;;;;; +A516;VAI SYLLABLE SEE;Lo;0;L;;;;;N;;;;; +A517;VAI SYLLABLE SHEE;Lo;0;L;;;;;N;;;;; +A518;VAI SYLLABLE ZEE;Lo;0;L;;;;;N;;;;; +A519;VAI SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;; +A51A;VAI SYLLABLE CEE;Lo;0;L;;;;;N;;;;; +A51B;VAI SYLLABLE JEE;Lo;0;L;;;;;N;;;;; +A51C;VAI SYLLABLE NJEE;Lo;0;L;;;;;N;;;;; +A51D;VAI SYLLABLE YEE;Lo;0;L;;;;;N;;;;; +A51E;VAI SYLLABLE KEE;Lo;0;L;;;;;N;;;;; +A51F;VAI SYLLABLE NGGEE;Lo;0;L;;;;;N;;;;; +A520;VAI SYLLABLE GEE;Lo;0;L;;;;;N;;;;; +A521;VAI SYLLABLE MEE;Lo;0;L;;;;;N;;;;; +A522;VAI SYLLABLE NEE;Lo;0;L;;;;;N;;;;; +A523;VAI SYLLABLE NYEE;Lo;0;L;;;;;N;;;;; +A524;VAI SYLLABLE I;Lo;0;L;;;;;N;;;;; +A525;VAI SYLLABLE IN;Lo;0;L;;;;;N;;;;; +A526;VAI SYLLABLE HI;Lo;0;L;;;;;N;;;;; +A527;VAI SYLLABLE HIN;Lo;0;L;;;;;N;;;;; +A528;VAI SYLLABLE WI;Lo;0;L;;;;;N;;;;; +A529;VAI SYLLABLE WIN;Lo;0;L;;;;;N;;;;; +A52A;VAI SYLLABLE PI;Lo;0;L;;;;;N;;;;; +A52B;VAI SYLLABLE BHI;Lo;0;L;;;;;N;;;;; +A52C;VAI SYLLABLE BI;Lo;0;L;;;;;N;;;;; +A52D;VAI SYLLABLE MBI;Lo;0;L;;;;;N;;;;; +A52E;VAI SYLLABLE KPI;Lo;0;L;;;;;N;;;;; +A52F;VAI SYLLABLE MGBI;Lo;0;L;;;;;N;;;;; +A530;VAI SYLLABLE GBI;Lo;0;L;;;;;N;;;;; +A531;VAI SYLLABLE FI;Lo;0;L;;;;;N;;;;; +A532;VAI SYLLABLE VI;Lo;0;L;;;;;N;;;;; +A533;VAI SYLLABLE TI;Lo;0;L;;;;;N;;;;; +A534;VAI SYLLABLE THI;Lo;0;L;;;;;N;;;;; +A535;VAI SYLLABLE DHI;Lo;0;L;;;;;N;;;;; +A536;VAI SYLLABLE DHHI;Lo;0;L;;;;;N;;;;; +A537;VAI SYLLABLE LI;Lo;0;L;;;;;N;;;;; +A538;VAI SYLLABLE RI;Lo;0;L;;;;;N;;;;; +A539;VAI SYLLABLE DI;Lo;0;L;;;;;N;;;;; +A53A;VAI SYLLABLE NDI;Lo;0;L;;;;;N;;;;; +A53B;VAI SYLLABLE SI;Lo;0;L;;;;;N;;;;; +A53C;VAI SYLLABLE SHI;Lo;0;L;;;;;N;;;;; +A53D;VAI SYLLABLE ZI;Lo;0;L;;;;;N;;;;; +A53E;VAI SYLLABLE ZHI;Lo;0;L;;;;;N;;;;; +A53F;VAI SYLLABLE CI;Lo;0;L;;;;;N;;;;; +A540;VAI SYLLABLE JI;Lo;0;L;;;;;N;;;;; +A541;VAI SYLLABLE NJI;Lo;0;L;;;;;N;;;;; +A542;VAI SYLLABLE YI;Lo;0;L;;;;;N;;;;; +A543;VAI SYLLABLE KI;Lo;0;L;;;;;N;;;;; +A544;VAI SYLLABLE NGGI;Lo;0;L;;;;;N;;;;; +A545;VAI SYLLABLE GI;Lo;0;L;;;;;N;;;;; +A546;VAI SYLLABLE MI;Lo;0;L;;;;;N;;;;; +A547;VAI SYLLABLE NI;Lo;0;L;;;;;N;;;;; +A548;VAI SYLLABLE NYI;Lo;0;L;;;;;N;;;;; +A549;VAI SYLLABLE A;Lo;0;L;;;;;N;;;;; +A54A;VAI SYLLABLE AN;Lo;0;L;;;;;N;;;;; +A54B;VAI SYLLABLE NGAN;Lo;0;L;;;;;N;;;;; +A54C;VAI SYLLABLE HA;Lo;0;L;;;;;N;;;;; +A54D;VAI SYLLABLE HAN;Lo;0;L;;;;;N;;;;; +A54E;VAI SYLLABLE WA;Lo;0;L;;;;;N;;;;; +A54F;VAI SYLLABLE WAN;Lo;0;L;;;;;N;;;;; +A550;VAI SYLLABLE PA;Lo;0;L;;;;;N;;;;; +A551;VAI SYLLABLE BHA;Lo;0;L;;;;;N;;;;; +A552;VAI SYLLABLE BA;Lo;0;L;;;;;N;;;;; +A553;VAI SYLLABLE MBA;Lo;0;L;;;;;N;;;;; +A554;VAI SYLLABLE KPA;Lo;0;L;;;;;N;;;;; +A555;VAI SYLLABLE KPAN;Lo;0;L;;;;;N;;;;; +A556;VAI SYLLABLE MGBA;Lo;0;L;;;;;N;;;;; +A557;VAI SYLLABLE GBA;Lo;0;L;;;;;N;;;;; +A558;VAI SYLLABLE FA;Lo;0;L;;;;;N;;;;; +A559;VAI SYLLABLE VA;Lo;0;L;;;;;N;;;;; +A55A;VAI SYLLABLE TA;Lo;0;L;;;;;N;;;;; +A55B;VAI SYLLABLE THA;Lo;0;L;;;;;N;;;;; +A55C;VAI SYLLABLE DHA;Lo;0;L;;;;;N;;;;; +A55D;VAI SYLLABLE DHHA;Lo;0;L;;;;;N;;;;; +A55E;VAI SYLLABLE LA;Lo;0;L;;;;;N;;;;; +A55F;VAI SYLLABLE RA;Lo;0;L;;;;;N;;;;; +A560;VAI SYLLABLE DA;Lo;0;L;;;;;N;;;;; +A561;VAI SYLLABLE NDA;Lo;0;L;;;;;N;;;;; +A562;VAI SYLLABLE SA;Lo;0;L;;;;;N;;;;; +A563;VAI SYLLABLE SHA;Lo;0;L;;;;;N;;;;; +A564;VAI SYLLABLE ZA;Lo;0;L;;;;;N;;;;; +A565;VAI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; +A566;VAI SYLLABLE CA;Lo;0;L;;;;;N;;;;; +A567;VAI SYLLABLE JA;Lo;0;L;;;;;N;;;;; +A568;VAI SYLLABLE NJA;Lo;0;L;;;;;N;;;;; +A569;VAI SYLLABLE YA;Lo;0;L;;;;;N;;;;; +A56A;VAI SYLLABLE KA;Lo;0;L;;;;;N;;;;; +A56B;VAI SYLLABLE KAN;Lo;0;L;;;;;N;;;;; +A56C;VAI SYLLABLE NGGA;Lo;0;L;;;;;N;;;;; +A56D;VAI SYLLABLE GA;Lo;0;L;;;;;N;;;;; +A56E;VAI SYLLABLE MA;Lo;0;L;;;;;N;;;;; +A56F;VAI SYLLABLE NA;Lo;0;L;;;;;N;;;;; +A570;VAI SYLLABLE NYA;Lo;0;L;;;;;N;;;;; +A571;VAI SYLLABLE OO;Lo;0;L;;;;;N;;;;; +A572;VAI SYLLABLE OON;Lo;0;L;;;;;N;;;;; +A573;VAI SYLLABLE HOO;Lo;0;L;;;;;N;;;;; +A574;VAI SYLLABLE WOO;Lo;0;L;;;;;N;;;;; +A575;VAI SYLLABLE WOON;Lo;0;L;;;;;N;;;;; +A576;VAI SYLLABLE POO;Lo;0;L;;;;;N;;;;; +A577;VAI SYLLABLE BHOO;Lo;0;L;;;;;N;;;;; +A578;VAI SYLLABLE BOO;Lo;0;L;;;;;N;;;;; +A579;VAI SYLLABLE MBOO;Lo;0;L;;;;;N;;;;; +A57A;VAI SYLLABLE KPOO;Lo;0;L;;;;;N;;;;; +A57B;VAI SYLLABLE MGBOO;Lo;0;L;;;;;N;;;;; +A57C;VAI SYLLABLE GBOO;Lo;0;L;;;;;N;;;;; +A57D;VAI SYLLABLE FOO;Lo;0;L;;;;;N;;;;; +A57E;VAI SYLLABLE VOO;Lo;0;L;;;;;N;;;;; +A57F;VAI SYLLABLE TOO;Lo;0;L;;;;;N;;;;; +A580;VAI SYLLABLE THOO;Lo;0;L;;;;;N;;;;; +A581;VAI SYLLABLE DHOO;Lo;0;L;;;;;N;;;;; +A582;VAI SYLLABLE DHHOO;Lo;0;L;;;;;N;;;;; +A583;VAI SYLLABLE LOO;Lo;0;L;;;;;N;;;;; +A584;VAI SYLLABLE ROO;Lo;0;L;;;;;N;;;;; +A585;VAI SYLLABLE DOO;Lo;0;L;;;;;N;;;;; +A586;VAI SYLLABLE NDOO;Lo;0;L;;;;;N;;;;; +A587;VAI SYLLABLE SOO;Lo;0;L;;;;;N;;;;; +A588;VAI SYLLABLE SHOO;Lo;0;L;;;;;N;;;;; +A589;VAI SYLLABLE ZOO;Lo;0;L;;;;;N;;;;; +A58A;VAI SYLLABLE ZHOO;Lo;0;L;;;;;N;;;;; +A58B;VAI SYLLABLE COO;Lo;0;L;;;;;N;;;;; +A58C;VAI SYLLABLE JOO;Lo;0;L;;;;;N;;;;; +A58D;VAI SYLLABLE NJOO;Lo;0;L;;;;;N;;;;; +A58E;VAI SYLLABLE YOO;Lo;0;L;;;;;N;;;;; +A58F;VAI SYLLABLE KOO;Lo;0;L;;;;;N;;;;; +A590;VAI SYLLABLE NGGOO;Lo;0;L;;;;;N;;;;; +A591;VAI SYLLABLE GOO;Lo;0;L;;;;;N;;;;; +A592;VAI SYLLABLE MOO;Lo;0;L;;;;;N;;;;; +A593;VAI SYLLABLE NOO;Lo;0;L;;;;;N;;;;; +A594;VAI SYLLABLE NYOO;Lo;0;L;;;;;N;;;;; +A595;VAI SYLLABLE U;Lo;0;L;;;;;N;;;;; +A596;VAI SYLLABLE UN;Lo;0;L;;;;;N;;;;; +A597;VAI SYLLABLE HU;Lo;0;L;;;;;N;;;;; +A598;VAI SYLLABLE HUN;Lo;0;L;;;;;N;;;;; +A599;VAI SYLLABLE WU;Lo;0;L;;;;;N;;;;; +A59A;VAI SYLLABLE WUN;Lo;0;L;;;;;N;;;;; +A59B;VAI SYLLABLE PU;Lo;0;L;;;;;N;;;;; +A59C;VAI SYLLABLE BHU;Lo;0;L;;;;;N;;;;; +A59D;VAI SYLLABLE BU;Lo;0;L;;;;;N;;;;; +A59E;VAI SYLLABLE MBU;Lo;0;L;;;;;N;;;;; +A59F;VAI SYLLABLE KPU;Lo;0;L;;;;;N;;;;; +A5A0;VAI SYLLABLE MGBU;Lo;0;L;;;;;N;;;;; +A5A1;VAI SYLLABLE GBU;Lo;0;L;;;;;N;;;;; +A5A2;VAI SYLLABLE FU;Lo;0;L;;;;;N;;;;; +A5A3;VAI SYLLABLE VU;Lo;0;L;;;;;N;;;;; +A5A4;VAI SYLLABLE TU;Lo;0;L;;;;;N;;;;; +A5A5;VAI SYLLABLE THU;Lo;0;L;;;;;N;;;;; +A5A6;VAI SYLLABLE DHU;Lo;0;L;;;;;N;;;;; +A5A7;VAI SYLLABLE DHHU;Lo;0;L;;;;;N;;;;; +A5A8;VAI SYLLABLE LU;Lo;0;L;;;;;N;;;;; +A5A9;VAI SYLLABLE RU;Lo;0;L;;;;;N;;;;; +A5AA;VAI SYLLABLE DU;Lo;0;L;;;;;N;;;;; +A5AB;VAI SYLLABLE NDU;Lo;0;L;;;;;N;;;;; +A5AC;VAI SYLLABLE SU;Lo;0;L;;;;;N;;;;; +A5AD;VAI SYLLABLE SHU;Lo;0;L;;;;;N;;;;; +A5AE;VAI SYLLABLE ZU;Lo;0;L;;;;;N;;;;; +A5AF;VAI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; +A5B0;VAI SYLLABLE CU;Lo;0;L;;;;;N;;;;; +A5B1;VAI SYLLABLE JU;Lo;0;L;;;;;N;;;;; +A5B2;VAI SYLLABLE NJU;Lo;0;L;;;;;N;;;;; +A5B3;VAI SYLLABLE YU;Lo;0;L;;;;;N;;;;; +A5B4;VAI SYLLABLE KU;Lo;0;L;;;;;N;;;;; +A5B5;VAI SYLLABLE NGGU;Lo;0;L;;;;;N;;;;; +A5B6;VAI SYLLABLE GU;Lo;0;L;;;;;N;;;;; +A5B7;VAI SYLLABLE MU;Lo;0;L;;;;;N;;;;; +A5B8;VAI SYLLABLE NU;Lo;0;L;;;;;N;;;;; +A5B9;VAI SYLLABLE NYU;Lo;0;L;;;;;N;;;;; +A5BA;VAI SYLLABLE O;Lo;0;L;;;;;N;;;;; +A5BB;VAI SYLLABLE ON;Lo;0;L;;;;;N;;;;; +A5BC;VAI SYLLABLE NGON;Lo;0;L;;;;;N;;;;; +A5BD;VAI SYLLABLE HO;Lo;0;L;;;;;N;;;;; +A5BE;VAI SYLLABLE HON;Lo;0;L;;;;;N;;;;; +A5BF;VAI SYLLABLE WO;Lo;0;L;;;;;N;;;;; +A5C0;VAI SYLLABLE WON;Lo;0;L;;;;;N;;;;; +A5C1;VAI SYLLABLE PO;Lo;0;L;;;;;N;;;;; +A5C2;VAI SYLLABLE BHO;Lo;0;L;;;;;N;;;;; +A5C3;VAI SYLLABLE BO;Lo;0;L;;;;;N;;;;; +A5C4;VAI SYLLABLE MBO;Lo;0;L;;;;;N;;;;; +A5C5;VAI SYLLABLE KPO;Lo;0;L;;;;;N;;;;; +A5C6;VAI SYLLABLE MGBO;Lo;0;L;;;;;N;;;;; +A5C7;VAI SYLLABLE GBO;Lo;0;L;;;;;N;;;;; +A5C8;VAI SYLLABLE GBON;Lo;0;L;;;;;N;;;;; +A5C9;VAI SYLLABLE FO;Lo;0;L;;;;;N;;;;; +A5CA;VAI SYLLABLE VO;Lo;0;L;;;;;N;;;;; +A5CB;VAI SYLLABLE TO;Lo;0;L;;;;;N;;;;; +A5CC;VAI SYLLABLE THO;Lo;0;L;;;;;N;;;;; +A5CD;VAI SYLLABLE DHO;Lo;0;L;;;;;N;;;;; +A5CE;VAI SYLLABLE DHHO;Lo;0;L;;;;;N;;;;; +A5CF;VAI SYLLABLE LO;Lo;0;L;;;;;N;;;;; +A5D0;VAI SYLLABLE RO;Lo;0;L;;;;;N;;;;; +A5D1;VAI SYLLABLE DO;Lo;0;L;;;;;N;;;;; +A5D2;VAI SYLLABLE NDO;Lo;0;L;;;;;N;;;;; +A5D3;VAI SYLLABLE SO;Lo;0;L;;;;;N;;;;; +A5D4;VAI SYLLABLE SHO;Lo;0;L;;;;;N;;;;; +A5D5;VAI SYLLABLE ZO;Lo;0;L;;;;;N;;;;; +A5D6;VAI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; +A5D7;VAI SYLLABLE CO;Lo;0;L;;;;;N;;;;; +A5D8;VAI SYLLABLE JO;Lo;0;L;;;;;N;;;;; +A5D9;VAI SYLLABLE NJO;Lo;0;L;;;;;N;;;;; +A5DA;VAI SYLLABLE YO;Lo;0;L;;;;;N;;;;; +A5DB;VAI SYLLABLE KO;Lo;0;L;;;;;N;;;;; +A5DC;VAI SYLLABLE NGGO;Lo;0;L;;;;;N;;;;; +A5DD;VAI SYLLABLE GO;Lo;0;L;;;;;N;;;;; +A5DE;VAI SYLLABLE MO;Lo;0;L;;;;;N;;;;; +A5DF;VAI SYLLABLE NO;Lo;0;L;;;;;N;;;;; +A5E0;VAI SYLLABLE NYO;Lo;0;L;;;;;N;;;;; +A5E1;VAI SYLLABLE E;Lo;0;L;;;;;N;;;;; +A5E2;VAI SYLLABLE EN;Lo;0;L;;;;;N;;;;; +A5E3;VAI SYLLABLE NGEN;Lo;0;L;;;;;N;;;;; +A5E4;VAI SYLLABLE HE;Lo;0;L;;;;;N;;;;; +A5E5;VAI SYLLABLE HEN;Lo;0;L;;;;;N;;;;; +A5E6;VAI SYLLABLE WE;Lo;0;L;;;;;N;;;;; +A5E7;VAI SYLLABLE WEN;Lo;0;L;;;;;N;;;;; +A5E8;VAI SYLLABLE PE;Lo;0;L;;;;;N;;;;; +A5E9;VAI SYLLABLE BHE;Lo;0;L;;;;;N;;;;; +A5EA;VAI SYLLABLE BE;Lo;0;L;;;;;N;;;;; +A5EB;VAI SYLLABLE MBE;Lo;0;L;;;;;N;;;;; +A5EC;VAI SYLLABLE KPE;Lo;0;L;;;;;N;;;;; +A5ED;VAI SYLLABLE KPEN;Lo;0;L;;;;;N;;;;; +A5EE;VAI SYLLABLE MGBE;Lo;0;L;;;;;N;;;;; +A5EF;VAI SYLLABLE GBE;Lo;0;L;;;;;N;;;;; +A5F0;VAI SYLLABLE GBEN;Lo;0;L;;;;;N;;;;; +A5F1;VAI SYLLABLE FE;Lo;0;L;;;;;N;;;;; +A5F2;VAI SYLLABLE VE;Lo;0;L;;;;;N;;;;; +A5F3;VAI SYLLABLE TE;Lo;0;L;;;;;N;;;;; +A5F4;VAI SYLLABLE THE;Lo;0;L;;;;;N;;;;; +A5F5;VAI SYLLABLE DHE;Lo;0;L;;;;;N;;;;; +A5F6;VAI SYLLABLE DHHE;Lo;0;L;;;;;N;;;;; +A5F7;VAI SYLLABLE LE;Lo;0;L;;;;;N;;;;; +A5F8;VAI SYLLABLE RE;Lo;0;L;;;;;N;;;;; +A5F9;VAI SYLLABLE DE;Lo;0;L;;;;;N;;;;; +A5FA;VAI SYLLABLE NDE;Lo;0;L;;;;;N;;;;; +A5FB;VAI SYLLABLE SE;Lo;0;L;;;;;N;;;;; +A5FC;VAI SYLLABLE SHE;Lo;0;L;;;;;N;;;;; +A5FD;VAI SYLLABLE ZE;Lo;0;L;;;;;N;;;;; +A5FE;VAI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; +A5FF;VAI SYLLABLE CE;Lo;0;L;;;;;N;;;;; +A600;VAI SYLLABLE JE;Lo;0;L;;;;;N;;;;; +A601;VAI SYLLABLE NJE;Lo;0;L;;;;;N;;;;; +A602;VAI SYLLABLE YE;Lo;0;L;;;;;N;;;;; +A603;VAI SYLLABLE KE;Lo;0;L;;;;;N;;;;; +A604;VAI SYLLABLE NGGE;Lo;0;L;;;;;N;;;;; +A605;VAI SYLLABLE NGGEN;Lo;0;L;;;;;N;;;;; +A606;VAI SYLLABLE GE;Lo;0;L;;;;;N;;;;; +A607;VAI SYLLABLE GEN;Lo;0;L;;;;;N;;;;; +A608;VAI SYLLABLE ME;Lo;0;L;;;;;N;;;;; +A609;VAI SYLLABLE NE;Lo;0;L;;;;;N;;;;; +A60A;VAI SYLLABLE NYE;Lo;0;L;;;;;N;;;;; +A60B;VAI SYLLABLE NG;Lo;0;L;;;;;N;;;;; +A60C;VAI SYLLABLE LENGTHENER;Lm;0;L;;;;;N;;;;; +A60D;VAI COMMA;Po;0;ON;;;;;N;;;;; +A60E;VAI FULL STOP;Po;0;ON;;;;;N;;;;; +A60F;VAI QUESTION MARK;Po;0;ON;;;;;N;;;;; +A610;VAI SYLLABLE NDOLE FA;Lo;0;L;;;;;N;;;;; +A611;VAI SYLLABLE NDOLE KA;Lo;0;L;;;;;N;;;;; +A612;VAI SYLLABLE NDOLE SOO;Lo;0;L;;;;;N;;;;; +A613;VAI SYMBOL FEENG;Lo;0;L;;;;;N;;;;; +A614;VAI SYMBOL KEENG;Lo;0;L;;;;;N;;;;; +A615;VAI SYMBOL TING;Lo;0;L;;;;;N;;;;; +A616;VAI SYMBOL NII;Lo;0;L;;;;;N;;;;; +A617;VAI SYMBOL BANG;Lo;0;L;;;;;N;;;;; +A618;VAI SYMBOL FAA;Lo;0;L;;;;;N;;;;; +A619;VAI SYMBOL TAA;Lo;0;L;;;;;N;;;;; +A61A;VAI SYMBOL DANG;Lo;0;L;;;;;N;;;;; +A61B;VAI SYMBOL DOONG;Lo;0;L;;;;;N;;;;; +A61C;VAI SYMBOL KUNG;Lo;0;L;;;;;N;;;;; +A61D;VAI SYMBOL TONG;Lo;0;L;;;;;N;;;;; +A61E;VAI SYMBOL DO-O;Lo;0;L;;;;;N;;;;; +A61F;VAI SYMBOL JONG;Lo;0;L;;;;;N;;;;; +A620;VAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A621;VAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A622;VAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A623;VAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A624;VAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A625;VAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A626;VAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A627;VAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A628;VAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A629;VAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A62A;VAI SYLLABLE NDOLE MA;Lo;0;L;;;;;N;;;;; +A62B;VAI SYLLABLE NDOLE DO;Lo;0;L;;;;;N;;;;; +A640;CYRILLIC CAPITAL LETTER ZEMLYA;Lu;0;L;;;;;N;;;;A641; +A641;CYRILLIC SMALL LETTER ZEMLYA;Ll;0;L;;;;;N;;;A640;;A640 +A642;CYRILLIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;A643; +A643;CYRILLIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;A642;;A642 +A644;CYRILLIC CAPITAL LETTER REVERSED DZE;Lu;0;L;;;;;N;;;;A645; +A645;CYRILLIC SMALL LETTER REVERSED DZE;Ll;0;L;;;;;N;;;A644;;A644 +A646;CYRILLIC CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;A647; +A647;CYRILLIC SMALL LETTER IOTA;Ll;0;L;;;;;N;;;A646;;A646 +A648;CYRILLIC CAPITAL LETTER DJERV;Lu;0;L;;;;;N;;;;A649; +A649;CYRILLIC SMALL LETTER DJERV;Ll;0;L;;;;;N;;;A648;;A648 +A64A;CYRILLIC CAPITAL LETTER MONOGRAPH UK;Lu;0;L;;;;;N;;;;A64B; +A64B;CYRILLIC SMALL LETTER MONOGRAPH UK;Ll;0;L;;;;;N;;;A64A;;A64A +A64C;CYRILLIC CAPITAL LETTER BROAD OMEGA;Lu;0;L;;;;;N;;;;A64D; +A64D;CYRILLIC SMALL LETTER BROAD OMEGA;Ll;0;L;;;;;N;;;A64C;;A64C +A64E;CYRILLIC CAPITAL LETTER NEUTRAL YER;Lu;0;L;;;;;N;;;;A64F; +A64F;CYRILLIC SMALL LETTER NEUTRAL YER;Ll;0;L;;;;;N;;;A64E;;A64E +A650;CYRILLIC CAPITAL LETTER YERU WITH BACK YER;Lu;0;L;;;;;N;;;;A651; +A651;CYRILLIC SMALL LETTER YERU WITH BACK YER;Ll;0;L;;;;;N;;;A650;;A650 +A652;CYRILLIC CAPITAL LETTER IOTIFIED YAT;Lu;0;L;;;;;N;;;;A653; +A653;CYRILLIC SMALL LETTER IOTIFIED YAT;Ll;0;L;;;;;N;;;A652;;A652 +A654;CYRILLIC CAPITAL LETTER REVERSED YU;Lu;0;L;;;;;N;;;;A655; +A655;CYRILLIC SMALL LETTER REVERSED YU;Ll;0;L;;;;;N;;;A654;;A654 +A656;CYRILLIC CAPITAL LETTER IOTIFIED A;Lu;0;L;;;;;N;;;;A657; +A657;CYRILLIC SMALL LETTER IOTIFIED A;Ll;0;L;;;;;N;;;A656;;A656 +A658;CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A659; +A659;CYRILLIC SMALL LETTER CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A658;;A658 +A65A;CYRILLIC CAPITAL LETTER BLENDED YUS;Lu;0;L;;;;;N;;;;A65B; +A65B;CYRILLIC SMALL LETTER BLENDED YUS;Ll;0;L;;;;;N;;;A65A;;A65A +A65C;CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A65D; +A65D;CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A65C;;A65C +A65E;CYRILLIC CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;A65F; +A65F;CYRILLIC SMALL LETTER YN;Ll;0;L;;;;;N;;;A65E;;A65E +A662;CYRILLIC CAPITAL LETTER SOFT DE;Lu;0;L;;;;;N;;;;A663; +A663;CYRILLIC SMALL LETTER SOFT DE;Ll;0;L;;;;;N;;;A662;;A662 +A664;CYRILLIC CAPITAL LETTER SOFT EL;Lu;0;L;;;;;N;;;;A665; +A665;CYRILLIC SMALL LETTER SOFT EL;Ll;0;L;;;;;N;;;A664;;A664 +A666;CYRILLIC CAPITAL LETTER SOFT EM;Lu;0;L;;;;;N;;;;A667; +A667;CYRILLIC SMALL LETTER SOFT EM;Ll;0;L;;;;;N;;;A666;;A666 +A668;CYRILLIC CAPITAL LETTER MONOCULAR O;Lu;0;L;;;;;N;;;;A669; +A669;CYRILLIC SMALL LETTER MONOCULAR O;Ll;0;L;;;;;N;;;A668;;A668 +A66A;CYRILLIC CAPITAL LETTER BINOCULAR O;Lu;0;L;;;;;N;;;;A66B; +A66B;CYRILLIC SMALL LETTER BINOCULAR O;Ll;0;L;;;;;N;;;A66A;;A66A +A66C;CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O;Lu;0;L;;;;;N;;;;A66D; +A66D;CYRILLIC SMALL LETTER DOUBLE MONOCULAR O;Ll;0;L;;;;;N;;;A66C;;A66C +A66E;CYRILLIC LETTER MULTIOCULAR O;Lo;0;L;;;;;N;;;;; +A66F;COMBINING CYRILLIC VZMET;Mn;230;NSM;;;;;N;;;;; +A670;COMBINING CYRILLIC TEN MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +A671;COMBINING CYRILLIC HUNDRED MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +A672;COMBINING CYRILLIC THOUSAND MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +A673;SLAVONIC ASTERISK;Po;0;ON;;;;;N;;;;; +A67C;COMBINING CYRILLIC KAVYKA;Mn;230;NSM;;;;;N;;;;; +A67D;COMBINING CYRILLIC PAYEROK;Mn;230;NSM;;;;;N;;;;; +A67E;CYRILLIC KAVYKA;Po;0;ON;;;;;N;;;;; +A67F;CYRILLIC PAYEROK;Lm;0;ON;;;;;N;;;;; +A680;CYRILLIC CAPITAL LETTER DWE;Lu;0;L;;;;;N;;;;A681; +A681;CYRILLIC SMALL LETTER DWE;Ll;0;L;;;;;N;;;A680;;A680 +A682;CYRILLIC CAPITAL LETTER DZWE;Lu;0;L;;;;;N;;;;A683; +A683;CYRILLIC SMALL LETTER DZWE;Ll;0;L;;;;;N;;;A682;;A682 +A684;CYRILLIC CAPITAL LETTER ZHWE;Lu;0;L;;;;;N;;;;A685; +A685;CYRILLIC SMALL LETTER ZHWE;Ll;0;L;;;;;N;;;A684;;A684 +A686;CYRILLIC CAPITAL LETTER CCHE;Lu;0;L;;;;;N;;;;A687; +A687;CYRILLIC SMALL LETTER CCHE;Ll;0;L;;;;;N;;;A686;;A686 +A688;CYRILLIC CAPITAL LETTER DZZE;Lu;0;L;;;;;N;;;;A689; +A689;CYRILLIC SMALL LETTER DZZE;Ll;0;L;;;;;N;;;A688;;A688 +A68A;CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;A68B; +A68B;CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;A68A;;A68A +A68C;CYRILLIC CAPITAL LETTER TWE;Lu;0;L;;;;;N;;;;A68D; +A68D;CYRILLIC SMALL LETTER TWE;Ll;0;L;;;;;N;;;A68C;;A68C +A68E;CYRILLIC CAPITAL LETTER TSWE;Lu;0;L;;;;;N;;;;A68F; +A68F;CYRILLIC SMALL LETTER TSWE;Ll;0;L;;;;;N;;;A68E;;A68E +A690;CYRILLIC CAPITAL LETTER TSSE;Lu;0;L;;;;;N;;;;A691; +A691;CYRILLIC SMALL LETTER TSSE;Ll;0;L;;;;;N;;;A690;;A690 +A692;CYRILLIC CAPITAL LETTER TCHE;Lu;0;L;;;;;N;;;;A693; +A693;CYRILLIC SMALL LETTER TCHE;Ll;0;L;;;;;N;;;A692;;A692 +A694;CYRILLIC CAPITAL LETTER HWE;Lu;0;L;;;;;N;;;;A695; +A695;CYRILLIC SMALL LETTER HWE;Ll;0;L;;;;;N;;;A694;;A694 +A696;CYRILLIC CAPITAL LETTER SHWE;Lu;0;L;;;;;N;;;;A697; +A697;CYRILLIC SMALL LETTER SHWE;Ll;0;L;;;;;N;;;A696;;A696 +A6A0;BAMUM LETTER A;Lo;0;L;;;;;N;;;;; +A6A1;BAMUM LETTER KA;Lo;0;L;;;;;N;;;;; +A6A2;BAMUM LETTER U;Lo;0;L;;;;;N;;;;; +A6A3;BAMUM LETTER KU;Lo;0;L;;;;;N;;;;; +A6A4;BAMUM LETTER EE;Lo;0;L;;;;;N;;;;; +A6A5;BAMUM LETTER REE;Lo;0;L;;;;;N;;;;; +A6A6;BAMUM LETTER TAE;Lo;0;L;;;;;N;;;;; +A6A7;BAMUM LETTER O;Lo;0;L;;;;;N;;;;; +A6A8;BAMUM LETTER NYI;Lo;0;L;;;;;N;;;;; +A6A9;BAMUM LETTER I;Lo;0;L;;;;;N;;;;; +A6AA;BAMUM LETTER LA;Lo;0;L;;;;;N;;;;; +A6AB;BAMUM LETTER PA;Lo;0;L;;;;;N;;;;; +A6AC;BAMUM LETTER RII;Lo;0;L;;;;;N;;;;; +A6AD;BAMUM LETTER RIEE;Lo;0;L;;;;;N;;;;; +A6AE;BAMUM LETTER LEEEE;Lo;0;L;;;;;N;;;;; +A6AF;BAMUM LETTER MEEEE;Lo;0;L;;;;;N;;;;; +A6B0;BAMUM LETTER TAA;Lo;0;L;;;;;N;;;;; +A6B1;BAMUM LETTER NDAA;Lo;0;L;;;;;N;;;;; +A6B2;BAMUM LETTER NJAEM;Lo;0;L;;;;;N;;;;; +A6B3;BAMUM LETTER M;Lo;0;L;;;;;N;;;;; +A6B4;BAMUM LETTER SUU;Lo;0;L;;;;;N;;;;; +A6B5;BAMUM LETTER MU;Lo;0;L;;;;;N;;;;; +A6B6;BAMUM LETTER SHII;Lo;0;L;;;;;N;;;;; +A6B7;BAMUM LETTER SI;Lo;0;L;;;;;N;;;;; +A6B8;BAMUM LETTER SHEUX;Lo;0;L;;;;;N;;;;; +A6B9;BAMUM LETTER SEUX;Lo;0;L;;;;;N;;;;; +A6BA;BAMUM LETTER KYEE;Lo;0;L;;;;;N;;;;; +A6BB;BAMUM LETTER KET;Lo;0;L;;;;;N;;;;; +A6BC;BAMUM LETTER NUAE;Lo;0;L;;;;;N;;;;; +A6BD;BAMUM LETTER NU;Lo;0;L;;;;;N;;;;; +A6BE;BAMUM LETTER NJUAE;Lo;0;L;;;;;N;;;;; +A6BF;BAMUM LETTER YOQ;Lo;0;L;;;;;N;;;;; +A6C0;BAMUM LETTER SHU;Lo;0;L;;;;;N;;;;; +A6C1;BAMUM LETTER YUQ;Lo;0;L;;;;;N;;;;; +A6C2;BAMUM LETTER YA;Lo;0;L;;;;;N;;;;; +A6C3;BAMUM LETTER NSHA;Lo;0;L;;;;;N;;;;; +A6C4;BAMUM LETTER KEUX;Lo;0;L;;;;;N;;;;; +A6C5;BAMUM LETTER PEUX;Lo;0;L;;;;;N;;;;; +A6C6;BAMUM LETTER NJEE;Lo;0;L;;;;;N;;;;; +A6C7;BAMUM LETTER NTEE;Lo;0;L;;;;;N;;;;; +A6C8;BAMUM LETTER PUE;Lo;0;L;;;;;N;;;;; +A6C9;BAMUM LETTER WUE;Lo;0;L;;;;;N;;;;; +A6CA;BAMUM LETTER PEE;Lo;0;L;;;;;N;;;;; +A6CB;BAMUM LETTER FEE;Lo;0;L;;;;;N;;;;; +A6CC;BAMUM LETTER RU;Lo;0;L;;;;;N;;;;; +A6CD;BAMUM LETTER LU;Lo;0;L;;;;;N;;;;; +A6CE;BAMUM LETTER MI;Lo;0;L;;;;;N;;;;; +A6CF;BAMUM LETTER NI;Lo;0;L;;;;;N;;;;; +A6D0;BAMUM LETTER REUX;Lo;0;L;;;;;N;;;;; +A6D1;BAMUM LETTER RAE;Lo;0;L;;;;;N;;;;; +A6D2;BAMUM LETTER KEN;Lo;0;L;;;;;N;;;;; +A6D3;BAMUM LETTER NGKWAEN;Lo;0;L;;;;;N;;;;; +A6D4;BAMUM LETTER NGGA;Lo;0;L;;;;;N;;;;; +A6D5;BAMUM LETTER NGA;Lo;0;L;;;;;N;;;;; +A6D6;BAMUM LETTER SHO;Lo;0;L;;;;;N;;;;; +A6D7;BAMUM LETTER PUAE;Lo;0;L;;;;;N;;;;; +A6D8;BAMUM LETTER FU;Lo;0;L;;;;;N;;;;; +A6D9;BAMUM LETTER FOM;Lo;0;L;;;;;N;;;;; +A6DA;BAMUM LETTER WA;Lo;0;L;;;;;N;;;;; +A6DB;BAMUM LETTER NA;Lo;0;L;;;;;N;;;;; +A6DC;BAMUM LETTER LI;Lo;0;L;;;;;N;;;;; +A6DD;BAMUM LETTER PI;Lo;0;L;;;;;N;;;;; +A6DE;BAMUM LETTER LOQ;Lo;0;L;;;;;N;;;;; +A6DF;BAMUM LETTER KO;Lo;0;L;;;;;N;;;;; +A6E0;BAMUM LETTER MBEN;Lo;0;L;;;;;N;;;;; +A6E1;BAMUM LETTER REN;Lo;0;L;;;;;N;;;;; +A6E2;BAMUM LETTER MEN;Lo;0;L;;;;;N;;;;; +A6E3;BAMUM LETTER MA;Lo;0;L;;;;;N;;;;; +A6E4;BAMUM LETTER TI;Lo;0;L;;;;;N;;;;; +A6E5;BAMUM LETTER KI;Lo;0;L;;;;;N;;;;; +A6E6;BAMUM LETTER MO;Nl;0;L;;;;1;N;;;;; +A6E7;BAMUM LETTER MBAA;Nl;0;L;;;;2;N;;;;; +A6E8;BAMUM LETTER TET;Nl;0;L;;;;3;N;;;;; +A6E9;BAMUM LETTER KPA;Nl;0;L;;;;4;N;;;;; +A6EA;BAMUM LETTER TEN;Nl;0;L;;;;5;N;;;;; +A6EB;BAMUM LETTER NTUU;Nl;0;L;;;;6;N;;;;; +A6EC;BAMUM LETTER SAMBA;Nl;0;L;;;;7;N;;;;; +A6ED;BAMUM LETTER FAAMAE;Nl;0;L;;;;8;N;;;;; +A6EE;BAMUM LETTER KOVUU;Nl;0;L;;;;9;N;;;;; +A6EF;BAMUM LETTER KOGHOM;Nl;0;L;;;;0;N;;;;; +A6F0;BAMUM COMBINING MARK KOQNDON;Mn;230;NSM;;;;;N;;;;; +A6F1;BAMUM COMBINING MARK TUKWENTIS;Mn;230;NSM;;;;;N;;;;; +A6F2;BAMUM NJAEMLI;Po;0;L;;;;;N;;;;; +A6F3;BAMUM FULL STOP;Po;0;L;;;;;N;;;;; +A6F4;BAMUM COLON;Po;0;L;;;;;N;;;;; +A6F5;BAMUM COMMA;Po;0;L;;;;;N;;;;; +A6F6;BAMUM SEMICOLON;Po;0;L;;;;;N;;;;; +A6F7;BAMUM QUESTION MARK;Po;0;L;;;;;N;;;;; +A700;MODIFIER LETTER CHINESE TONE YIN PING;Sk;0;ON;;;;;N;;;;; +A701;MODIFIER LETTER CHINESE TONE YANG PING;Sk;0;ON;;;;;N;;;;; +A702;MODIFIER LETTER CHINESE TONE YIN SHANG;Sk;0;ON;;;;;N;;;;; +A703;MODIFIER LETTER CHINESE TONE YANG SHANG;Sk;0;ON;;;;;N;;;;; +A704;MODIFIER LETTER CHINESE TONE YIN QU;Sk;0;ON;;;;;N;;;;; +A705;MODIFIER LETTER CHINESE TONE YANG QU;Sk;0;ON;;;;;N;;;;; +A706;MODIFIER LETTER CHINESE TONE YIN RU;Sk;0;ON;;;;;N;;;;; +A707;MODIFIER LETTER CHINESE TONE YANG RU;Sk;0;ON;;;;;N;;;;; +A708;MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A709;MODIFIER LETTER HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A70A;MODIFIER LETTER MID DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A70B;MODIFIER LETTER LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A70C;MODIFIER LETTER EXTRA-LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A70D;MODIFIER LETTER EXTRA-HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A70E;MODIFIER LETTER HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A70F;MODIFIER LETTER MID DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A710;MODIFIER LETTER LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A711;MODIFIER LETTER EXTRA-LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A712;MODIFIER LETTER EXTRA-HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A713;MODIFIER LETTER HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A714;MODIFIER LETTER MID LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A715;MODIFIER LETTER LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A716;MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A717;MODIFIER LETTER DOT VERTICAL BAR;Lm;0;ON;;;;;N;;;;; +A718;MODIFIER LETTER DOT SLASH;Lm;0;ON;;;;;N;;;;; +A719;MODIFIER LETTER DOT HORIZONTAL BAR;Lm;0;ON;;;;;N;;;;; +A71A;MODIFIER LETTER LOWER RIGHT CORNER ANGLE;Lm;0;ON;;;;;N;;;;; +A71B;MODIFIER LETTER RAISED UP ARROW;Lm;0;ON;;;;;N;;;;; +A71C;MODIFIER LETTER RAISED DOWN ARROW;Lm;0;ON;;;;;N;;;;; +A71D;MODIFIER LETTER RAISED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;; +A71E;MODIFIER LETTER RAISED INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;; +A71F;MODIFIER LETTER LOW INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;; +A720;MODIFIER LETTER STRESS AND HIGH TONE;Sk;0;ON;;;;;N;;;;; +A721;MODIFIER LETTER STRESS AND LOW TONE;Sk;0;ON;;;;;N;;;;; +A722;LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF;Lu;0;L;;;;;N;;;;A723; +A723;LATIN SMALL LETTER EGYPTOLOGICAL ALEF;Ll;0;L;;;;;N;;;A722;;A722 +A724;LATIN CAPITAL LETTER EGYPTOLOGICAL AIN;Lu;0;L;;;;;N;;;;A725; +A725;LATIN SMALL LETTER EGYPTOLOGICAL AIN;Ll;0;L;;;;;N;;;A724;;A724 +A726;LATIN CAPITAL LETTER HENG;Lu;0;L;;;;;N;;;;A727; +A727;LATIN SMALL LETTER HENG;Ll;0;L;;;;;N;;;A726;;A726 +A728;LATIN CAPITAL LETTER TZ;Lu;0;L;;;;;N;;;;A729; +A729;LATIN SMALL LETTER TZ;Ll;0;L;;;;;N;;;A728;;A728 +A72A;LATIN CAPITAL LETTER TRESILLO;Lu;0;L;;;;;N;;;;A72B; +A72B;LATIN SMALL LETTER TRESILLO;Ll;0;L;;;;;N;;;A72A;;A72A +A72C;LATIN CAPITAL LETTER CUATRILLO;Lu;0;L;;;;;N;;;;A72D; +A72D;LATIN SMALL LETTER CUATRILLO;Ll;0;L;;;;;N;;;A72C;;A72C +A72E;LATIN CAPITAL LETTER CUATRILLO WITH COMMA;Lu;0;L;;;;;N;;;;A72F; +A72F;LATIN SMALL LETTER CUATRILLO WITH COMMA;Ll;0;L;;;;;N;;;A72E;;A72E +A730;LATIN LETTER SMALL CAPITAL F;Ll;0;L;;;;;N;;;;; +A731;LATIN LETTER SMALL CAPITAL S;Ll;0;L;;;;;N;;;;; +A732;LATIN CAPITAL LETTER AA;Lu;0;L;;;;;N;;;;A733; +A733;LATIN SMALL LETTER AA;Ll;0;L;;;;;N;;;A732;;A732 +A734;LATIN CAPITAL LETTER AO;Lu;0;L;;;;;N;;;;A735; +A735;LATIN SMALL LETTER AO;Ll;0;L;;;;;N;;;A734;;A734 +A736;LATIN CAPITAL LETTER AU;Lu;0;L;;;;;N;;;;A737; +A737;LATIN SMALL LETTER AU;Ll;0;L;;;;;N;;;A736;;A736 +A738;LATIN CAPITAL LETTER AV;Lu;0;L;;;;;N;;;;A739; +A739;LATIN SMALL LETTER AV;Ll;0;L;;;;;N;;;A738;;A738 +A73A;LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR;Lu;0;L;;;;;N;;;;A73B; +A73B;LATIN SMALL LETTER AV WITH HORIZONTAL BAR;Ll;0;L;;;;;N;;;A73A;;A73A +A73C;LATIN CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;A73D; +A73D;LATIN SMALL LETTER AY;Ll;0;L;;;;;N;;;A73C;;A73C +A73E;LATIN CAPITAL LETTER REVERSED C WITH DOT;Lu;0;L;;;;;N;;;;A73F; +A73F;LATIN SMALL LETTER REVERSED C WITH DOT;Ll;0;L;;;;;N;;;A73E;;A73E +A740;LATIN CAPITAL LETTER K WITH STROKE;Lu;0;L;;;;;N;;;;A741; +A741;LATIN SMALL LETTER K WITH STROKE;Ll;0;L;;;;;N;;;A740;;A740 +A742;LATIN CAPITAL LETTER K WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A743; +A743;LATIN SMALL LETTER K WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A742;;A742 +A744;LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A745; +A745;LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE;Ll;0;L;;;;;N;;;A744;;A744 +A746;LATIN CAPITAL LETTER BROKEN L;Lu;0;L;;;;;N;;;;A747; +A747;LATIN SMALL LETTER BROKEN L;Ll;0;L;;;;;N;;;A746;;A746 +A748;LATIN CAPITAL LETTER L WITH HIGH STROKE;Lu;0;L;;;;;N;;;;A749; +A749;LATIN SMALL LETTER L WITH HIGH STROKE;Ll;0;L;;;;;N;;;A748;;A748 +A74A;LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY;Lu;0;L;;;;;N;;;;A74B; +A74B;LATIN SMALL LETTER O WITH LONG STROKE OVERLAY;Ll;0;L;;;;;N;;;A74A;;A74A +A74C;LATIN CAPITAL LETTER O WITH LOOP;Lu;0;L;;;;;N;;;;A74D; +A74D;LATIN SMALL LETTER O WITH LOOP;Ll;0;L;;;;;N;;;A74C;;A74C +A74E;LATIN CAPITAL LETTER OO;Lu;0;L;;;;;N;;;;A74F; +A74F;LATIN SMALL LETTER OO;Ll;0;L;;;;;N;;;A74E;;A74E +A750;LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A751; +A751;LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A750;;A750 +A752;LATIN CAPITAL LETTER P WITH FLOURISH;Lu;0;L;;;;;N;;;;A753; +A753;LATIN SMALL LETTER P WITH FLOURISH;Ll;0;L;;;;;N;;;A752;;A752 +A754;LATIN CAPITAL LETTER P WITH SQUIRREL TAIL;Lu;0;L;;;;;N;;;;A755; +A755;LATIN SMALL LETTER P WITH SQUIRREL TAIL;Ll;0;L;;;;;N;;;A754;;A754 +A756;LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A757; +A757;LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A756;;A756 +A758;LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A759; +A759;LATIN SMALL LETTER Q WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A758;;A758 +A75A;LATIN CAPITAL LETTER R ROTUNDA;Lu;0;L;;;;;N;;;;A75B; +A75B;LATIN SMALL LETTER R ROTUNDA;Ll;0;L;;;;;N;;;A75A;;A75A +A75C;LATIN CAPITAL LETTER RUM ROTUNDA;Lu;0;L;;;;;N;;;;A75D; +A75D;LATIN SMALL LETTER RUM ROTUNDA;Ll;0;L;;;;;N;;;A75C;;A75C +A75E;LATIN CAPITAL LETTER V WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A75F; +A75F;LATIN SMALL LETTER V WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A75E;;A75E +A760;LATIN CAPITAL LETTER VY;Lu;0;L;;;;;N;;;;A761; +A761;LATIN SMALL LETTER VY;Ll;0;L;;;;;N;;;A760;;A760 +A762;LATIN CAPITAL LETTER VISIGOTHIC Z;Lu;0;L;;;;;N;;;;A763; +A763;LATIN SMALL LETTER VISIGOTHIC Z;Ll;0;L;;;;;N;;;A762;;A762 +A764;LATIN CAPITAL LETTER THORN WITH STROKE;Lu;0;L;;;;;N;;;;A765; +A765;LATIN SMALL LETTER THORN WITH STROKE;Ll;0;L;;;;;N;;;A764;;A764 +A766;LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A767; +A767;LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A766;;A766 +A768;LATIN CAPITAL LETTER VEND;Lu;0;L;;;;;N;;;;A769; +A769;LATIN SMALL LETTER VEND;Ll;0;L;;;;;N;;;A768;;A768 +A76A;LATIN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;A76B; +A76B;LATIN SMALL LETTER ET;Ll;0;L;;;;;N;;;A76A;;A76A +A76C;LATIN CAPITAL LETTER IS;Lu;0;L;;;;;N;;;;A76D; +A76D;LATIN SMALL LETTER IS;Ll;0;L;;;;;N;;;A76C;;A76C +A76E;LATIN CAPITAL LETTER CON;Lu;0;L;;;;;N;;;;A76F; +A76F;LATIN SMALL LETTER CON;Ll;0;L;;;;;N;;;A76E;;A76E +A770;MODIFIER LETTER US;Lm;0;L; A76F;;;;N;;;;; +A771;LATIN SMALL LETTER DUM;Ll;0;L;;;;;N;;;;; +A772;LATIN SMALL LETTER LUM;Ll;0;L;;;;;N;;;;; +A773;LATIN SMALL LETTER MUM;Ll;0;L;;;;;N;;;;; +A774;LATIN SMALL LETTER NUM;Ll;0;L;;;;;N;;;;; +A775;LATIN SMALL LETTER RUM;Ll;0;L;;;;;N;;;;; +A776;LATIN LETTER SMALL CAPITAL RUM;Ll;0;L;;;;;N;;;;; +A777;LATIN SMALL LETTER TUM;Ll;0;L;;;;;N;;;;; +A778;LATIN SMALL LETTER UM;Ll;0;L;;;;;N;;;;; +A779;LATIN CAPITAL LETTER INSULAR D;Lu;0;L;;;;;N;;;;A77A; +A77A;LATIN SMALL LETTER INSULAR D;Ll;0;L;;;;;N;;;A779;;A779 +A77B;LATIN CAPITAL LETTER INSULAR F;Lu;0;L;;;;;N;;;;A77C; +A77C;LATIN SMALL LETTER INSULAR F;Ll;0;L;;;;;N;;;A77B;;A77B +A77D;LATIN CAPITAL LETTER INSULAR G;Lu;0;L;;;;;N;;;;1D79; +A77E;LATIN CAPITAL LETTER TURNED INSULAR G;Lu;0;L;;;;;N;;;;A77F; +A77F;LATIN SMALL LETTER TURNED INSULAR G;Ll;0;L;;;;;N;;;A77E;;A77E +A780;LATIN CAPITAL LETTER TURNED L;Lu;0;L;;;;;N;;;;A781; +A781;LATIN SMALL LETTER TURNED L;Ll;0;L;;;;;N;;;A780;;A780 +A782;LATIN CAPITAL LETTER INSULAR R;Lu;0;L;;;;;N;;;;A783; +A783;LATIN SMALL LETTER INSULAR R;Ll;0;L;;;;;N;;;A782;;A782 +A784;LATIN CAPITAL LETTER INSULAR S;Lu;0;L;;;;;N;;;;A785; +A785;LATIN SMALL LETTER INSULAR S;Ll;0;L;;;;;N;;;A784;;A784 +A786;LATIN CAPITAL LETTER INSULAR T;Lu;0;L;;;;;N;;;;A787; +A787;LATIN SMALL LETTER INSULAR T;Ll;0;L;;;;;N;;;A786;;A786 +A788;MODIFIER LETTER LOW CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;;;;; +A789;MODIFIER LETTER COLON;Sk;0;L;;;;;N;;;;; +A78A;MODIFIER LETTER SHORT EQUALS SIGN;Sk;0;L;;;;;N;;;;; +A78B;LATIN CAPITAL LETTER SALTILLO;Lu;0;L;;;;;N;;;;A78C; +A78C;LATIN SMALL LETTER SALTILLO;Ll;0;L;;;;;N;;;A78B;;A78B +A7FB;LATIN EPIGRAPHIC LETTER REVERSED F;Lo;0;L;;;;;N;;;;; +A7FC;LATIN EPIGRAPHIC LETTER REVERSED P;Lo;0;L;;;;;N;;;;; +A7FD;LATIN EPIGRAPHIC LETTER INVERTED M;Lo;0;L;;;;;N;;;;; +A7FE;LATIN EPIGRAPHIC LETTER I LONGA;Lo;0;L;;;;;N;;;;; +A7FF;LATIN EPIGRAPHIC LETTER ARCHAIC M;Lo;0;L;;;;;N;;;;; +A800;SYLOTI NAGRI LETTER A;Lo;0;L;;;;;N;;;;; +A801;SYLOTI NAGRI LETTER I;Lo;0;L;;;;;N;;;;; +A802;SYLOTI NAGRI SIGN DVISVARA;Mn;0;NSM;;;;;N;;;;; +A803;SYLOTI NAGRI LETTER U;Lo;0;L;;;;;N;;;;; +A804;SYLOTI NAGRI LETTER E;Lo;0;L;;;;;N;;;;; +A805;SYLOTI NAGRI LETTER O;Lo;0;L;;;;;N;;;;; +A806;SYLOTI NAGRI SIGN HASANTA;Mn;9;NSM;;;;;N;;;;; +A807;SYLOTI NAGRI LETTER KO;Lo;0;L;;;;;N;;;;; +A808;SYLOTI NAGRI LETTER KHO;Lo;0;L;;;;;N;;;;; +A809;SYLOTI NAGRI LETTER GO;Lo;0;L;;;;;N;;;;; +A80A;SYLOTI NAGRI LETTER GHO;Lo;0;L;;;;;N;;;;; +A80B;SYLOTI NAGRI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +A80C;SYLOTI NAGRI LETTER CO;Lo;0;L;;;;;N;;;;; +A80D;SYLOTI NAGRI LETTER CHO;Lo;0;L;;;;;N;;;;; +A80E;SYLOTI NAGRI LETTER JO;Lo;0;L;;;;;N;;;;; +A80F;SYLOTI NAGRI LETTER JHO;Lo;0;L;;;;;N;;;;; +A810;SYLOTI NAGRI LETTER TTO;Lo;0;L;;;;;N;;;;; +A811;SYLOTI NAGRI LETTER TTHO;Lo;0;L;;;;;N;;;;; +A812;SYLOTI NAGRI LETTER DDO;Lo;0;L;;;;;N;;;;; +A813;SYLOTI NAGRI LETTER DDHO;Lo;0;L;;;;;N;;;;; +A814;SYLOTI NAGRI LETTER TO;Lo;0;L;;;;;N;;;;; +A815;SYLOTI NAGRI LETTER THO;Lo;0;L;;;;;N;;;;; +A816;SYLOTI NAGRI LETTER DO;Lo;0;L;;;;;N;;;;; +A817;SYLOTI NAGRI LETTER DHO;Lo;0;L;;;;;N;;;;; +A818;SYLOTI NAGRI LETTER NO;Lo;0;L;;;;;N;;;;; +A819;SYLOTI NAGRI LETTER PO;Lo;0;L;;;;;N;;;;; +A81A;SYLOTI NAGRI LETTER PHO;Lo;0;L;;;;;N;;;;; +A81B;SYLOTI NAGRI LETTER BO;Lo;0;L;;;;;N;;;;; +A81C;SYLOTI NAGRI LETTER BHO;Lo;0;L;;;;;N;;;;; +A81D;SYLOTI NAGRI LETTER MO;Lo;0;L;;;;;N;;;;; +A81E;SYLOTI NAGRI LETTER RO;Lo;0;L;;;;;N;;;;; +A81F;SYLOTI NAGRI LETTER LO;Lo;0;L;;;;;N;;;;; +A820;SYLOTI NAGRI LETTER RRO;Lo;0;L;;;;;N;;;;; +A821;SYLOTI NAGRI LETTER SO;Lo;0;L;;;;;N;;;;; +A822;SYLOTI NAGRI LETTER HO;Lo;0;L;;;;;N;;;;; +A823;SYLOTI NAGRI VOWEL SIGN A;Mc;0;L;;;;;N;;;;; +A824;SYLOTI NAGRI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +A825;SYLOTI NAGRI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +A826;SYLOTI NAGRI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +A827;SYLOTI NAGRI VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +A828;SYLOTI NAGRI POETRY MARK-1;So;0;ON;;;;;N;;;;; +A829;SYLOTI NAGRI POETRY MARK-2;So;0;ON;;;;;N;;;;; +A82A;SYLOTI NAGRI POETRY MARK-3;So;0;ON;;;;;N;;;;; +A82B;SYLOTI NAGRI POETRY MARK-4;So;0;ON;;;;;N;;;;; +A830;NORTH INDIC FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;; +A831;NORTH INDIC FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;; +A832;NORTH INDIC FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;; +A833;NORTH INDIC FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;; +A834;NORTH INDIC FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;; +A835;NORTH INDIC FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;; +A836;NORTH INDIC QUARTER MARK;So;0;L;;;;;N;;;;; +A837;NORTH INDIC PLACEHOLDER MARK;So;0;L;;;;;N;;;;; +A838;NORTH INDIC RUPEE MARK;Sc;0;ET;;;;;N;;;;; +A839;NORTH INDIC QUANTITY MARK;So;0;ET;;;;;N;;;;; +A840;PHAGS-PA LETTER KA;Lo;0;L;;;;;N;;;;; +A841;PHAGS-PA LETTER KHA;Lo;0;L;;;;;N;;;;; +A842;PHAGS-PA LETTER GA;Lo;0;L;;;;;N;;;;; +A843;PHAGS-PA LETTER NGA;Lo;0;L;;;;;N;;;;; +A844;PHAGS-PA LETTER CA;Lo;0;L;;;;;N;;;;; +A845;PHAGS-PA LETTER CHA;Lo;0;L;;;;;N;;;;; +A846;PHAGS-PA LETTER JA;Lo;0;L;;;;;N;;;;; +A847;PHAGS-PA LETTER NYA;Lo;0;L;;;;;N;;;;; +A848;PHAGS-PA LETTER TA;Lo;0;L;;;;;N;;;;; +A849;PHAGS-PA LETTER THA;Lo;0;L;;;;;N;;;;; +A84A;PHAGS-PA LETTER DA;Lo;0;L;;;;;N;;;;; +A84B;PHAGS-PA LETTER NA;Lo;0;L;;;;;N;;;;; +A84C;PHAGS-PA LETTER PA;Lo;0;L;;;;;N;;;;; +A84D;PHAGS-PA LETTER PHA;Lo;0;L;;;;;N;;;;; +A84E;PHAGS-PA LETTER BA;Lo;0;L;;;;;N;;;;; +A84F;PHAGS-PA LETTER MA;Lo;0;L;;;;;N;;;;; +A850;PHAGS-PA LETTER TSA;Lo;0;L;;;;;N;;;;; +A851;PHAGS-PA LETTER TSHA;Lo;0;L;;;;;N;;;;; +A852;PHAGS-PA LETTER DZA;Lo;0;L;;;;;N;;;;; +A853;PHAGS-PA LETTER WA;Lo;0;L;;;;;N;;;;; +A854;PHAGS-PA LETTER ZHA;Lo;0;L;;;;;N;;;;; +A855;PHAGS-PA LETTER ZA;Lo;0;L;;;;;N;;;;; +A856;PHAGS-PA LETTER SMALL A;Lo;0;L;;;;;N;;;;; +A857;PHAGS-PA LETTER YA;Lo;0;L;;;;;N;;;;; +A858;PHAGS-PA LETTER RA;Lo;0;L;;;;;N;;;;; +A859;PHAGS-PA LETTER LA;Lo;0;L;;;;;N;;;;; +A85A;PHAGS-PA LETTER SHA;Lo;0;L;;;;;N;;;;; +A85B;PHAGS-PA LETTER SA;Lo;0;L;;;;;N;;;;; +A85C;PHAGS-PA LETTER HA;Lo;0;L;;;;;N;;;;; +A85D;PHAGS-PA LETTER A;Lo;0;L;;;;;N;;;;; +A85E;PHAGS-PA LETTER I;Lo;0;L;;;;;N;;;;; +A85F;PHAGS-PA LETTER U;Lo;0;L;;;;;N;;;;; +A860;PHAGS-PA LETTER E;Lo;0;L;;;;;N;;;;; +A861;PHAGS-PA LETTER O;Lo;0;L;;;;;N;;;;; +A862;PHAGS-PA LETTER QA;Lo;0;L;;;;;N;;;;; +A863;PHAGS-PA LETTER XA;Lo;0;L;;;;;N;;;;; +A864;PHAGS-PA LETTER FA;Lo;0;L;;;;;N;;;;; +A865;PHAGS-PA LETTER GGA;Lo;0;L;;;;;N;;;;; +A866;PHAGS-PA LETTER EE;Lo;0;L;;;;;N;;;;; +A867;PHAGS-PA SUBJOINED LETTER WA;Lo;0;L;;;;;N;;;;; +A868;PHAGS-PA SUBJOINED LETTER YA;Lo;0;L;;;;;N;;;;; +A869;PHAGS-PA LETTER TTA;Lo;0;L;;;;;N;;;;; +A86A;PHAGS-PA LETTER TTHA;Lo;0;L;;;;;N;;;;; +A86B;PHAGS-PA LETTER DDA;Lo;0;L;;;;;N;;;;; +A86C;PHAGS-PA LETTER NNA;Lo;0;L;;;;;N;;;;; +A86D;PHAGS-PA LETTER ALTERNATE YA;Lo;0;L;;;;;N;;;;; +A86E;PHAGS-PA LETTER VOICELESS SHA;Lo;0;L;;;;;N;;;;; +A86F;PHAGS-PA LETTER VOICED HA;Lo;0;L;;;;;N;;;;; +A870;PHAGS-PA LETTER ASPIRATED FA;Lo;0;L;;;;;N;;;;; +A871;PHAGS-PA SUBJOINED LETTER RA;Lo;0;L;;;;;N;;;;; +A872;PHAGS-PA SUPERFIXED LETTER RA;Lo;0;L;;;;;N;;;;; +A873;PHAGS-PA LETTER CANDRABINDU;Lo;0;L;;;;;N;;;;; +A874;PHAGS-PA SINGLE HEAD MARK;Po;0;ON;;;;;N;;;;; +A875;PHAGS-PA DOUBLE HEAD MARK;Po;0;ON;;;;;N;;;;; +A876;PHAGS-PA MARK SHAD;Po;0;ON;;;;;N;;;;; +A877;PHAGS-PA MARK DOUBLE SHAD;Po;0;ON;;;;;N;;;;; +A880;SAURASHTRA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +A881;SAURASHTRA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +A882;SAURASHTRA LETTER A;Lo;0;L;;;;;N;;;;; +A883;SAURASHTRA LETTER AA;Lo;0;L;;;;;N;;;;; +A884;SAURASHTRA LETTER I;Lo;0;L;;;;;N;;;;; +A885;SAURASHTRA LETTER II;Lo;0;L;;;;;N;;;;; +A886;SAURASHTRA LETTER U;Lo;0;L;;;;;N;;;;; +A887;SAURASHTRA LETTER UU;Lo;0;L;;;;;N;;;;; +A888;SAURASHTRA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +A889;SAURASHTRA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +A88A;SAURASHTRA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +A88B;SAURASHTRA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +A88C;SAURASHTRA LETTER E;Lo;0;L;;;;;N;;;;; +A88D;SAURASHTRA LETTER EE;Lo;0;L;;;;;N;;;;; +A88E;SAURASHTRA LETTER AI;Lo;0;L;;;;;N;;;;; +A88F;SAURASHTRA LETTER O;Lo;0;L;;;;;N;;;;; +A890;SAURASHTRA LETTER OO;Lo;0;L;;;;;N;;;;; +A891;SAURASHTRA LETTER AU;Lo;0;L;;;;;N;;;;; +A892;SAURASHTRA LETTER KA;Lo;0;L;;;;;N;;;;; +A893;SAURASHTRA LETTER KHA;Lo;0;L;;;;;N;;;;; +A894;SAURASHTRA LETTER GA;Lo;0;L;;;;;N;;;;; +A895;SAURASHTRA LETTER GHA;Lo;0;L;;;;;N;;;;; +A896;SAURASHTRA LETTER NGA;Lo;0;L;;;;;N;;;;; +A897;SAURASHTRA LETTER CA;Lo;0;L;;;;;N;;;;; +A898;SAURASHTRA LETTER CHA;Lo;0;L;;;;;N;;;;; +A899;SAURASHTRA LETTER JA;Lo;0;L;;;;;N;;;;; +A89A;SAURASHTRA LETTER JHA;Lo;0;L;;;;;N;;;;; +A89B;SAURASHTRA LETTER NYA;Lo;0;L;;;;;N;;;;; +A89C;SAURASHTRA LETTER TTA;Lo;0;L;;;;;N;;;;; +A89D;SAURASHTRA LETTER TTHA;Lo;0;L;;;;;N;;;;; +A89E;SAURASHTRA LETTER DDA;Lo;0;L;;;;;N;;;;; +A89F;SAURASHTRA LETTER DDHA;Lo;0;L;;;;;N;;;;; +A8A0;SAURASHTRA LETTER NNA;Lo;0;L;;;;;N;;;;; +A8A1;SAURASHTRA LETTER TA;Lo;0;L;;;;;N;;;;; +A8A2;SAURASHTRA LETTER THA;Lo;0;L;;;;;N;;;;; +A8A3;SAURASHTRA LETTER DA;Lo;0;L;;;;;N;;;;; +A8A4;SAURASHTRA LETTER DHA;Lo;0;L;;;;;N;;;;; +A8A5;SAURASHTRA LETTER NA;Lo;0;L;;;;;N;;;;; +A8A6;SAURASHTRA LETTER PA;Lo;0;L;;;;;N;;;;; +A8A7;SAURASHTRA LETTER PHA;Lo;0;L;;;;;N;;;;; +A8A8;SAURASHTRA LETTER BA;Lo;0;L;;;;;N;;;;; +A8A9;SAURASHTRA LETTER BHA;Lo;0;L;;;;;N;;;;; +A8AA;SAURASHTRA LETTER MA;Lo;0;L;;;;;N;;;;; +A8AB;SAURASHTRA LETTER YA;Lo;0;L;;;;;N;;;;; +A8AC;SAURASHTRA LETTER RA;Lo;0;L;;;;;N;;;;; +A8AD;SAURASHTRA LETTER LA;Lo;0;L;;;;;N;;;;; +A8AE;SAURASHTRA LETTER VA;Lo;0;L;;;;;N;;;;; +A8AF;SAURASHTRA LETTER SHA;Lo;0;L;;;;;N;;;;; +A8B0;SAURASHTRA LETTER SSA;Lo;0;L;;;;;N;;;;; +A8B1;SAURASHTRA LETTER SA;Lo;0;L;;;;;N;;;;; +A8B2;SAURASHTRA LETTER HA;Lo;0;L;;;;;N;;;;; +A8B3;SAURASHTRA LETTER LLA;Lo;0;L;;;;;N;;;;; +A8B4;SAURASHTRA CONSONANT SIGN HAARU;Mc;0;L;;;;;N;;;;; +A8B5;SAURASHTRA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +A8B6;SAURASHTRA VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +A8B7;SAURASHTRA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +A8B8;SAURASHTRA VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +A8B9;SAURASHTRA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +A8BA;SAURASHTRA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +A8BB;SAURASHTRA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +A8BC;SAURASHTRA VOWEL SIGN VOCALIC L;Mc;0;L;;;;;N;;;;; +A8BD;SAURASHTRA VOWEL SIGN VOCALIC LL;Mc;0;L;;;;;N;;;;; +A8BE;SAURASHTRA VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +A8BF;SAURASHTRA VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +A8C0;SAURASHTRA VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +A8C1;SAURASHTRA VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +A8C2;SAURASHTRA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +A8C3;SAURASHTRA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +A8C4;SAURASHTRA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +A8CE;SAURASHTRA DANDA;Po;0;L;;;;;N;;;;; +A8CF;SAURASHTRA DOUBLE DANDA;Po;0;L;;;;;N;;;;; +A8D0;SAURASHTRA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A8D1;SAURASHTRA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A8D2;SAURASHTRA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A8D3;SAURASHTRA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A8D4;SAURASHTRA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A8D5;SAURASHTRA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A8D6;SAURASHTRA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A8D7;SAURASHTRA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A8D8;SAURASHTRA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A8D9;SAURASHTRA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A8E0;COMBINING DEVANAGARI DIGIT ZERO;Mn;230;NSM;;;;;N;;;;; +A8E1;COMBINING DEVANAGARI DIGIT ONE;Mn;230;NSM;;;;;N;;;;; +A8E2;COMBINING DEVANAGARI DIGIT TWO;Mn;230;NSM;;;;;N;;;;; +A8E3;COMBINING DEVANAGARI DIGIT THREE;Mn;230;NSM;;;;;N;;;;; +A8E4;COMBINING DEVANAGARI DIGIT FOUR;Mn;230;NSM;;;;;N;;;;; +A8E5;COMBINING DEVANAGARI DIGIT FIVE;Mn;230;NSM;;;;;N;;;;; +A8E6;COMBINING DEVANAGARI DIGIT SIX;Mn;230;NSM;;;;;N;;;;; +A8E7;COMBINING DEVANAGARI DIGIT SEVEN;Mn;230;NSM;;;;;N;;;;; +A8E8;COMBINING DEVANAGARI DIGIT EIGHT;Mn;230;NSM;;;;;N;;;;; +A8E9;COMBINING DEVANAGARI DIGIT NINE;Mn;230;NSM;;;;;N;;;;; +A8EA;COMBINING DEVANAGARI LETTER A;Mn;230;NSM;;;;;N;;;;; +A8EB;COMBINING DEVANAGARI LETTER U;Mn;230;NSM;;;;;N;;;;; +A8EC;COMBINING DEVANAGARI LETTER KA;Mn;230;NSM;;;;;N;;;;; +A8ED;COMBINING DEVANAGARI LETTER NA;Mn;230;NSM;;;;;N;;;;; +A8EE;COMBINING DEVANAGARI LETTER PA;Mn;230;NSM;;;;;N;;;;; +A8EF;COMBINING DEVANAGARI LETTER RA;Mn;230;NSM;;;;;N;;;;; +A8F0;COMBINING DEVANAGARI LETTER VI;Mn;230;NSM;;;;;N;;;;; +A8F1;COMBINING DEVANAGARI SIGN AVAGRAHA;Mn;230;NSM;;;;;N;;;;; +A8F2;DEVANAGARI SIGN SPACING CANDRABINDU;Lo;0;L;;;;;N;;;;; +A8F3;DEVANAGARI SIGN CANDRABINDU VIRAMA;Lo;0;L;;;;;N;;;;; +A8F4;DEVANAGARI SIGN DOUBLE CANDRABINDU VIRAMA;Lo;0;L;;;;;N;;;;; +A8F5;DEVANAGARI SIGN CANDRABINDU TWO;Lo;0;L;;;;;N;;;;; +A8F6;DEVANAGARI SIGN CANDRABINDU THREE;Lo;0;L;;;;;N;;;;; +A8F7;DEVANAGARI SIGN CANDRABINDU AVAGRAHA;Lo;0;L;;;;;N;;;;; +A8F8;DEVANAGARI SIGN PUSHPIKA;Po;0;L;;;;;N;;;;; +A8F9;DEVANAGARI GAP FILLER;Po;0;L;;;;;N;;;;; +A8FA;DEVANAGARI CARET;Po;0;L;;;;;N;;;;; +A8FB;DEVANAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;; +A900;KAYAH LI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A901;KAYAH LI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A902;KAYAH LI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A903;KAYAH LI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A904;KAYAH LI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A905;KAYAH LI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A906;KAYAH LI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A907;KAYAH LI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A908;KAYAH LI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A909;KAYAH LI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A90A;KAYAH LI LETTER KA;Lo;0;L;;;;;N;;;;; +A90B;KAYAH LI LETTER KHA;Lo;0;L;;;;;N;;;;; +A90C;KAYAH LI LETTER GA;Lo;0;L;;;;;N;;;;; +A90D;KAYAH LI LETTER NGA;Lo;0;L;;;;;N;;;;; +A90E;KAYAH LI LETTER SA;Lo;0;L;;;;;N;;;;; +A90F;KAYAH LI LETTER SHA;Lo;0;L;;;;;N;;;;; +A910;KAYAH LI LETTER ZA;Lo;0;L;;;;;N;;;;; +A911;KAYAH LI LETTER NYA;Lo;0;L;;;;;N;;;;; +A912;KAYAH LI LETTER TA;Lo;0;L;;;;;N;;;;; +A913;KAYAH LI LETTER HTA;Lo;0;L;;;;;N;;;;; +A914;KAYAH LI LETTER NA;Lo;0;L;;;;;N;;;;; +A915;KAYAH LI LETTER PA;Lo;0;L;;;;;N;;;;; +A916;KAYAH LI LETTER PHA;Lo;0;L;;;;;N;;;;; +A917;KAYAH LI LETTER MA;Lo;0;L;;;;;N;;;;; +A918;KAYAH LI LETTER DA;Lo;0;L;;;;;N;;;;; +A919;KAYAH LI LETTER BA;Lo;0;L;;;;;N;;;;; +A91A;KAYAH LI LETTER RA;Lo;0;L;;;;;N;;;;; +A91B;KAYAH LI LETTER YA;Lo;0;L;;;;;N;;;;; +A91C;KAYAH LI LETTER LA;Lo;0;L;;;;;N;;;;; +A91D;KAYAH LI LETTER WA;Lo;0;L;;;;;N;;;;; +A91E;KAYAH LI LETTER THA;Lo;0;L;;;;;N;;;;; +A91F;KAYAH LI LETTER HA;Lo;0;L;;;;;N;;;;; +A920;KAYAH LI LETTER VA;Lo;0;L;;;;;N;;;;; +A921;KAYAH LI LETTER CA;Lo;0;L;;;;;N;;;;; +A922;KAYAH LI LETTER A;Lo;0;L;;;;;N;;;;; +A923;KAYAH LI LETTER OE;Lo;0;L;;;;;N;;;;; +A924;KAYAH LI LETTER I;Lo;0;L;;;;;N;;;;; +A925;KAYAH LI LETTER OO;Lo;0;L;;;;;N;;;;; +A926;KAYAH LI VOWEL UE;Mn;0;NSM;;;;;N;;;;; +A927;KAYAH LI VOWEL E;Mn;0;NSM;;;;;N;;;;; +A928;KAYAH LI VOWEL U;Mn;0;NSM;;;;;N;;;;; +A929;KAYAH LI VOWEL EE;Mn;0;NSM;;;;;N;;;;; +A92A;KAYAH LI VOWEL O;Mn;0;NSM;;;;;N;;;;; +A92B;KAYAH LI TONE PLOPHU;Mn;220;NSM;;;;;N;;;;; +A92C;KAYAH LI TONE CALYA;Mn;220;NSM;;;;;N;;;;; +A92D;KAYAH LI TONE CALYA PLOPHU;Mn;220;NSM;;;;;N;;;;; +A92E;KAYAH LI SIGN CWI;Po;0;L;;;;;N;;;;; +A92F;KAYAH LI SIGN SHYA;Po;0;L;;;;;N;;;;; +A930;REJANG LETTER KA;Lo;0;L;;;;;N;;;;; +A931;REJANG LETTER GA;Lo;0;L;;;;;N;;;;; +A932;REJANG LETTER NGA;Lo;0;L;;;;;N;;;;; +A933;REJANG LETTER TA;Lo;0;L;;;;;N;;;;; +A934;REJANG LETTER DA;Lo;0;L;;;;;N;;;;; +A935;REJANG LETTER NA;Lo;0;L;;;;;N;;;;; +A936;REJANG LETTER PA;Lo;0;L;;;;;N;;;;; +A937;REJANG LETTER BA;Lo;0;L;;;;;N;;;;; +A938;REJANG LETTER MA;Lo;0;L;;;;;N;;;;; +A939;REJANG LETTER CA;Lo;0;L;;;;;N;;;;; +A93A;REJANG LETTER JA;Lo;0;L;;;;;N;;;;; +A93B;REJANG LETTER NYA;Lo;0;L;;;;;N;;;;; +A93C;REJANG LETTER SA;Lo;0;L;;;;;N;;;;; +A93D;REJANG LETTER RA;Lo;0;L;;;;;N;;;;; +A93E;REJANG LETTER LA;Lo;0;L;;;;;N;;;;; +A93F;REJANG LETTER YA;Lo;0;L;;;;;N;;;;; +A940;REJANG LETTER WA;Lo;0;L;;;;;N;;;;; +A941;REJANG LETTER HA;Lo;0;L;;;;;N;;;;; +A942;REJANG LETTER MBA;Lo;0;L;;;;;N;;;;; +A943;REJANG LETTER NGGA;Lo;0;L;;;;;N;;;;; +A944;REJANG LETTER NDA;Lo;0;L;;;;;N;;;;; +A945;REJANG LETTER NYJA;Lo;0;L;;;;;N;;;;; +A946;REJANG LETTER A;Lo;0;L;;;;;N;;;;; +A947;REJANG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +A948;REJANG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +A949;REJANG VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +A94A;REJANG VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +A94B;REJANG VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +A94C;REJANG VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +A94D;REJANG VOWEL SIGN EU;Mn;0;NSM;;;;;N;;;;; +A94E;REJANG VOWEL SIGN EA;Mn;0;NSM;;;;;N;;;;; +A94F;REJANG CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;; +A950;REJANG CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;; +A951;REJANG CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;; +A952;REJANG CONSONANT SIGN H;Mc;0;L;;;;;N;;;;; +A953;REJANG VIRAMA;Mc;9;L;;;;;N;;;;; +A95F;REJANG SECTION MARK;Po;0;L;;;;;N;;;;; +A960;HANGUL CHOSEONG TIKEUT-MIEUM;Lo;0;L;;;;;N;;;;; +A961;HANGUL CHOSEONG TIKEUT-PIEUP;Lo;0;L;;;;;N;;;;; +A962;HANGUL CHOSEONG TIKEUT-SIOS;Lo;0;L;;;;;N;;;;; +A963;HANGUL CHOSEONG TIKEUT-CIEUC;Lo;0;L;;;;;N;;;;; +A964;HANGUL CHOSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;;;; +A965;HANGUL CHOSEONG RIEUL-SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +A966;HANGUL CHOSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;; +A967;HANGUL CHOSEONG RIEUL-SSANGTIKEUT;Lo;0;L;;;;;N;;;;; +A968;HANGUL CHOSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;;;; +A969;HANGUL CHOSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;;;; +A96A;HANGUL CHOSEONG RIEUL-SSANGPIEUP;Lo;0;L;;;;;N;;;;; +A96B;HANGUL CHOSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +A96C;HANGUL CHOSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;;;; +A96D;HANGUL CHOSEONG RIEUL-CIEUC;Lo;0;L;;;;;N;;;;; +A96E;HANGUL CHOSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;; +A96F;HANGUL CHOSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; +A970;HANGUL CHOSEONG MIEUM-TIKEUT;Lo;0;L;;;;;N;;;;; +A971;HANGUL CHOSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;; +A972;HANGUL CHOSEONG PIEUP-SIOS-THIEUTH;Lo;0;L;;;;;N;;;;; +A973;HANGUL CHOSEONG PIEUP-KHIEUKH;Lo;0;L;;;;;N;;;;; +A974;HANGUL CHOSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; +A975;HANGUL CHOSEONG SSANGSIOS-PIEUP;Lo;0;L;;;;;N;;;;; +A976;HANGUL CHOSEONG IEUNG-RIEUL;Lo;0;L;;;;;N;;;;; +A977;HANGUL CHOSEONG IEUNG-HIEUH;Lo;0;L;;;;;N;;;;; +A978;HANGUL CHOSEONG SSANGCIEUC-HIEUH;Lo;0;L;;;;;N;;;;; +A979;HANGUL CHOSEONG SSANGTHIEUTH;Lo;0;L;;;;;N;;;;; +A97A;HANGUL CHOSEONG PHIEUPH-HIEUH;Lo;0;L;;;;;N;;;;; +A97B;HANGUL CHOSEONG HIEUH-SIOS;Lo;0;L;;;;;N;;;;; +A97C;HANGUL CHOSEONG SSANGYEORINHIEUH;Lo;0;L;;;;;N;;;;; +A980;JAVANESE SIGN PANYANGGA;Mn;0;NSM;;;;;N;;;;; +A981;JAVANESE SIGN CECAK;Mn;0;NSM;;;;;N;;;;; +A982;JAVANESE SIGN LAYAR;Mn;0;NSM;;;;;N;;;;; +A983;JAVANESE SIGN WIGNYAN;Mc;0;L;;;;;N;;;;; +A984;JAVANESE LETTER A;Lo;0;L;;;;;N;;;;; +A985;JAVANESE LETTER I KAWI;Lo;0;L;;;;;N;;;;; +A986;JAVANESE LETTER I;Lo;0;L;;;;;N;;;;; +A987;JAVANESE LETTER II;Lo;0;L;;;;;N;;;;; +A988;JAVANESE LETTER U;Lo;0;L;;;;;N;;;;; +A989;JAVANESE LETTER PA CEREK;Lo;0;L;;;;;N;;;;; +A98A;JAVANESE LETTER NGA LELET;Lo;0;L;;;;;N;;;;; +A98B;JAVANESE LETTER NGA LELET RASWADI;Lo;0;L;;;;;N;;;;; +A98C;JAVANESE LETTER E;Lo;0;L;;;;;N;;;;; +A98D;JAVANESE LETTER AI;Lo;0;L;;;;;N;;;;; +A98E;JAVANESE LETTER O;Lo;0;L;;;;;N;;;;; +A98F;JAVANESE LETTER KA;Lo;0;L;;;;;N;;;;; +A990;JAVANESE LETTER KA SASAK;Lo;0;L;;;;;N;;;;; +A991;JAVANESE LETTER KA MURDA;Lo;0;L;;;;;N;;;;; +A992;JAVANESE LETTER GA;Lo;0;L;;;;;N;;;;; +A993;JAVANESE LETTER GA MURDA;Lo;0;L;;;;;N;;;;; +A994;JAVANESE LETTER NGA;Lo;0;L;;;;;N;;;;; +A995;JAVANESE LETTER CA;Lo;0;L;;;;;N;;;;; +A996;JAVANESE LETTER CA MURDA;Lo;0;L;;;;;N;;;;; +A997;JAVANESE LETTER JA;Lo;0;L;;;;;N;;;;; +A998;JAVANESE LETTER NYA MURDA;Lo;0;L;;;;;N;;;;; +A999;JAVANESE LETTER JA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A99A;JAVANESE LETTER NYA;Lo;0;L;;;;;N;;;;; +A99B;JAVANESE LETTER TTA;Lo;0;L;;;;;N;;;;; +A99C;JAVANESE LETTER TTA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A99D;JAVANESE LETTER DDA;Lo;0;L;;;;;N;;;;; +A99E;JAVANESE LETTER DDA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A99F;JAVANESE LETTER NA MURDA;Lo;0;L;;;;;N;;;;; +A9A0;JAVANESE LETTER TA;Lo;0;L;;;;;N;;;;; +A9A1;JAVANESE LETTER TA MURDA;Lo;0;L;;;;;N;;;;; +A9A2;JAVANESE LETTER DA;Lo;0;L;;;;;N;;;;; +A9A3;JAVANESE LETTER DA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A9A4;JAVANESE LETTER NA;Lo;0;L;;;;;N;;;;; +A9A5;JAVANESE LETTER PA;Lo;0;L;;;;;N;;;;; +A9A6;JAVANESE LETTER PA MURDA;Lo;0;L;;;;;N;;;;; +A9A7;JAVANESE LETTER BA;Lo;0;L;;;;;N;;;;; +A9A8;JAVANESE LETTER BA MURDA;Lo;0;L;;;;;N;;;;; +A9A9;JAVANESE LETTER MA;Lo;0;L;;;;;N;;;;; +A9AA;JAVANESE LETTER YA;Lo;0;L;;;;;N;;;;; +A9AB;JAVANESE LETTER RA;Lo;0;L;;;;;N;;;;; +A9AC;JAVANESE LETTER RA AGUNG;Lo;0;L;;;;;N;;;;; +A9AD;JAVANESE LETTER LA;Lo;0;L;;;;;N;;;;; +A9AE;JAVANESE LETTER WA;Lo;0;L;;;;;N;;;;; +A9AF;JAVANESE LETTER SA MURDA;Lo;0;L;;;;;N;;;;; +A9B0;JAVANESE LETTER SA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A9B1;JAVANESE LETTER SA;Lo;0;L;;;;;N;;;;; +A9B2;JAVANESE LETTER HA;Lo;0;L;;;;;N;;;;; +A9B3;JAVANESE SIGN CECAK TELU;Mn;7;NSM;;;;;N;;;;; +A9B4;JAVANESE VOWEL SIGN TARUNG;Mc;0;L;;;;;N;;;;; +A9B5;JAVANESE VOWEL SIGN TOLONG;Mc;0;L;;;;;N;;;;; +A9B6;JAVANESE VOWEL SIGN WULU;Mn;0;NSM;;;;;N;;;;; +A9B7;JAVANESE VOWEL SIGN WULU MELIK;Mn;0;NSM;;;;;N;;;;; +A9B8;JAVANESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;;;; +A9B9;JAVANESE VOWEL SIGN SUKU MENDUT;Mn;0;NSM;;;;;N;;;;; +A9BA;JAVANESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;; +A9BB;JAVANESE VOWEL SIGN DIRGA MURE;Mc;0;L;;;;;N;;;;; +A9BC;JAVANESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;; +A9BD;JAVANESE CONSONANT SIGN KERET;Mc;0;L;;;;;N;;;;; +A9BE;JAVANESE CONSONANT SIGN PENGKAL;Mc;0;L;;;;;N;;;;; +A9BF;JAVANESE CONSONANT SIGN CAKRA;Mc;0;L;;;;;N;;;;; +A9C0;JAVANESE PANGKON;Mc;9;L;;;;;N;;;;; +A9C1;JAVANESE LEFT RERENGGAN;Po;0;L;;;;;N;;;;; +A9C2;JAVANESE RIGHT RERENGGAN;Po;0;L;;;;;N;;;;; +A9C3;JAVANESE PADA ANDAP;Po;0;L;;;;;N;;;;; +A9C4;JAVANESE PADA MADYA;Po;0;L;;;;;N;;;;; +A9C5;JAVANESE PADA LUHUR;Po;0;L;;;;;N;;;;; +A9C6;JAVANESE PADA WINDU;Po;0;L;;;;;N;;;;; +A9C7;JAVANESE PADA PANGKAT;Po;0;L;;;;;N;;;;; +A9C8;JAVANESE PADA LINGSA;Po;0;L;;;;;N;;;;; +A9C9;JAVANESE PADA LUNGSI;Po;0;L;;;;;N;;;;; +A9CA;JAVANESE PADA ADEG;Po;0;L;;;;;N;;;;; +A9CB;JAVANESE PADA ADEG ADEG;Po;0;L;;;;;N;;;;; +A9CC;JAVANESE PADA PISELEH;Po;0;L;;;;;N;;;;; +A9CD;JAVANESE TURNED PADA PISELEH;Po;0;L;;;;;N;;;;; +A9CF;JAVANESE PANGRANGKEP;Lm;0;L;;;;;N;;;;; +A9D0;JAVANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A9D1;JAVANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A9D2;JAVANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A9D3;JAVANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A9D4;JAVANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A9D5;JAVANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A9D6;JAVANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A9D7;JAVANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A9D8;JAVANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A9D9;JAVANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A9DE;JAVANESE PADA TIRTA TUMETES;Po;0;L;;;;;N;;;;; +A9DF;JAVANESE PADA ISEN-ISEN;Po;0;L;;;;;N;;;;; +AA00;CHAM LETTER A;Lo;0;L;;;;;N;;;;; +AA01;CHAM LETTER I;Lo;0;L;;;;;N;;;;; +AA02;CHAM LETTER U;Lo;0;L;;;;;N;;;;; +AA03;CHAM LETTER E;Lo;0;L;;;;;N;;;;; +AA04;CHAM LETTER AI;Lo;0;L;;;;;N;;;;; +AA05;CHAM LETTER O;Lo;0;L;;;;;N;;;;; +AA06;CHAM LETTER KA;Lo;0;L;;;;;N;;;;; +AA07;CHAM LETTER KHA;Lo;0;L;;;;;N;;;;; +AA08;CHAM LETTER GA;Lo;0;L;;;;;N;;;;; +AA09;CHAM LETTER GHA;Lo;0;L;;;;;N;;;;; +AA0A;CHAM LETTER NGUE;Lo;0;L;;;;;N;;;;; +AA0B;CHAM LETTER NGA;Lo;0;L;;;;;N;;;;; +AA0C;CHAM LETTER CHA;Lo;0;L;;;;;N;;;;; +AA0D;CHAM LETTER CHHA;Lo;0;L;;;;;N;;;;; +AA0E;CHAM LETTER JA;Lo;0;L;;;;;N;;;;; +AA0F;CHAM LETTER JHA;Lo;0;L;;;;;N;;;;; +AA10;CHAM LETTER NHUE;Lo;0;L;;;;;N;;;;; +AA11;CHAM LETTER NHA;Lo;0;L;;;;;N;;;;; +AA12;CHAM LETTER NHJA;Lo;0;L;;;;;N;;;;; +AA13;CHAM LETTER TA;Lo;0;L;;;;;N;;;;; +AA14;CHAM LETTER THA;Lo;0;L;;;;;N;;;;; +AA15;CHAM LETTER DA;Lo;0;L;;;;;N;;;;; +AA16;CHAM LETTER DHA;Lo;0;L;;;;;N;;;;; +AA17;CHAM LETTER NUE;Lo;0;L;;;;;N;;;;; +AA18;CHAM LETTER NA;Lo;0;L;;;;;N;;;;; +AA19;CHAM LETTER DDA;Lo;0;L;;;;;N;;;;; +AA1A;CHAM LETTER PA;Lo;0;L;;;;;N;;;;; +AA1B;CHAM LETTER PPA;Lo;0;L;;;;;N;;;;; +AA1C;CHAM LETTER PHA;Lo;0;L;;;;;N;;;;; +AA1D;CHAM LETTER BA;Lo;0;L;;;;;N;;;;; +AA1E;CHAM LETTER BHA;Lo;0;L;;;;;N;;;;; +AA1F;CHAM LETTER MUE;Lo;0;L;;;;;N;;;;; +AA20;CHAM LETTER MA;Lo;0;L;;;;;N;;;;; +AA21;CHAM LETTER BBA;Lo;0;L;;;;;N;;;;; +AA22;CHAM LETTER YA;Lo;0;L;;;;;N;;;;; +AA23;CHAM LETTER RA;Lo;0;L;;;;;N;;;;; +AA24;CHAM LETTER LA;Lo;0;L;;;;;N;;;;; +AA25;CHAM LETTER VA;Lo;0;L;;;;;N;;;;; +AA26;CHAM LETTER SSA;Lo;0;L;;;;;N;;;;; +AA27;CHAM LETTER SA;Lo;0;L;;;;;N;;;;; +AA28;CHAM LETTER HA;Lo;0;L;;;;;N;;;;; +AA29;CHAM VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +AA2A;CHAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +AA2B;CHAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +AA2C;CHAM VOWEL SIGN EI;Mn;0;NSM;;;;;N;;;;; +AA2D;CHAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +AA2E;CHAM VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;; +AA2F;CHAM VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +AA30;CHAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +AA31;CHAM VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +AA32;CHAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;; +AA33;CHAM CONSONANT SIGN YA;Mc;0;L;;;;;N;;;;; +AA34;CHAM CONSONANT SIGN RA;Mc;0;L;;;;;N;;;;; +AA35;CHAM CONSONANT SIGN LA;Mn;0;NSM;;;;;N;;;;; +AA36;CHAM CONSONANT SIGN WA;Mn;0;NSM;;;;;N;;;;; +AA40;CHAM LETTER FINAL K;Lo;0;L;;;;;N;;;;; +AA41;CHAM LETTER FINAL G;Lo;0;L;;;;;N;;;;; +AA42;CHAM LETTER FINAL NG;Lo;0;L;;;;;N;;;;; +AA43;CHAM CONSONANT SIGN FINAL NG;Mn;0;NSM;;;;;N;;;;; +AA44;CHAM LETTER FINAL CH;Lo;0;L;;;;;N;;;;; +AA45;CHAM LETTER FINAL T;Lo;0;L;;;;;N;;;;; +AA46;CHAM LETTER FINAL N;Lo;0;L;;;;;N;;;;; +AA47;CHAM LETTER FINAL P;Lo;0;L;;;;;N;;;;; +AA48;CHAM LETTER FINAL Y;Lo;0;L;;;;;N;;;;; +AA49;CHAM LETTER FINAL R;Lo;0;L;;;;;N;;;;; +AA4A;CHAM LETTER FINAL L;Lo;0;L;;;;;N;;;;; +AA4B;CHAM LETTER FINAL SS;Lo;0;L;;;;;N;;;;; +AA4C;CHAM CONSONANT SIGN FINAL M;Mn;0;NSM;;;;;N;;;;; +AA4D;CHAM CONSONANT SIGN FINAL H;Mc;0;L;;;;;N;;;;; +AA50;CHAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +AA51;CHAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +AA52;CHAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +AA53;CHAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +AA54;CHAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +AA55;CHAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +AA56;CHAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +AA57;CHAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +AA58;CHAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +AA59;CHAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +AA5C;CHAM PUNCTUATION SPIRAL;Po;0;L;;;;;N;;;;; +AA5D;CHAM PUNCTUATION DANDA;Po;0;L;;;;;N;;;;; +AA5E;CHAM PUNCTUATION DOUBLE DANDA;Po;0;L;;;;;N;;;;; +AA5F;CHAM PUNCTUATION TRIPLE DANDA;Po;0;L;;;;;N;;;;; +AA60;MYANMAR LETTER KHAMTI GA;Lo;0;L;;;;;N;;;;; +AA61;MYANMAR LETTER KHAMTI CA;Lo;0;L;;;;;N;;;;; +AA62;MYANMAR LETTER KHAMTI CHA;Lo;0;L;;;;;N;;;;; +AA63;MYANMAR LETTER KHAMTI JA;Lo;0;L;;;;;N;;;;; +AA64;MYANMAR LETTER KHAMTI JHA;Lo;0;L;;;;;N;;;;; +AA65;MYANMAR LETTER KHAMTI NYA;Lo;0;L;;;;;N;;;;; +AA66;MYANMAR LETTER KHAMTI TTA;Lo;0;L;;;;;N;;;;; +AA67;MYANMAR LETTER KHAMTI TTHA;Lo;0;L;;;;;N;;;;; +AA68;MYANMAR LETTER KHAMTI DDA;Lo;0;L;;;;;N;;;;; +AA69;MYANMAR LETTER KHAMTI DDHA;Lo;0;L;;;;;N;;;;; +AA6A;MYANMAR LETTER KHAMTI DHA;Lo;0;L;;;;;N;;;;; +AA6B;MYANMAR LETTER KHAMTI NA;Lo;0;L;;;;;N;;;;; +AA6C;MYANMAR LETTER KHAMTI SA;Lo;0;L;;;;;N;;;;; +AA6D;MYANMAR LETTER KHAMTI HA;Lo;0;L;;;;;N;;;;; +AA6E;MYANMAR LETTER KHAMTI HHA;Lo;0;L;;;;;N;;;;; +AA6F;MYANMAR LETTER KHAMTI FA;Lo;0;L;;;;;N;;;;; +AA70;MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION;Lm;0;L;;;;;N;;;;; +AA71;MYANMAR LETTER KHAMTI XA;Lo;0;L;;;;;N;;;;; +AA72;MYANMAR LETTER KHAMTI ZA;Lo;0;L;;;;;N;;;;; +AA73;MYANMAR LETTER KHAMTI RA;Lo;0;L;;;;;N;;;;; +AA74;MYANMAR LOGOGRAM KHAMTI OAY;Lo;0;L;;;;;N;;;;; +AA75;MYANMAR LOGOGRAM KHAMTI QN;Lo;0;L;;;;;N;;;;; +AA76;MYANMAR LOGOGRAM KHAMTI HM;Lo;0;L;;;;;N;;;;; +AA77;MYANMAR SYMBOL AITON EXCLAMATION;So;0;L;;;;;N;;;;; +AA78;MYANMAR SYMBOL AITON ONE;So;0;L;;;;;N;;;;; +AA79;MYANMAR SYMBOL AITON TWO;So;0;L;;;;;N;;;;; +AA7A;MYANMAR LETTER AITON RA;Lo;0;L;;;;;N;;;;; +AA7B;MYANMAR SIGN PAO KAREN TONE;Mc;0;L;;;;;N;;;;; +AA80;TAI VIET LETTER LOW KO;Lo;0;L;;;;;N;;;;; +AA81;TAI VIET LETTER HIGH KO;Lo;0;L;;;;;N;;;;; +AA82;TAI VIET LETTER LOW KHO;Lo;0;L;;;;;N;;;;; +AA83;TAI VIET LETTER HIGH KHO;Lo;0;L;;;;;N;;;;; +AA84;TAI VIET LETTER LOW KHHO;Lo;0;L;;;;;N;;;;; +AA85;TAI VIET LETTER HIGH KHHO;Lo;0;L;;;;;N;;;;; +AA86;TAI VIET LETTER LOW GO;Lo;0;L;;;;;N;;;;; +AA87;TAI VIET LETTER HIGH GO;Lo;0;L;;;;;N;;;;; +AA88;TAI VIET LETTER LOW NGO;Lo;0;L;;;;;N;;;;; +AA89;TAI VIET LETTER HIGH NGO;Lo;0;L;;;;;N;;;;; +AA8A;TAI VIET LETTER LOW CO;Lo;0;L;;;;;N;;;;; +AA8B;TAI VIET LETTER HIGH CO;Lo;0;L;;;;;N;;;;; +AA8C;TAI VIET LETTER LOW CHO;Lo;0;L;;;;;N;;;;; +AA8D;TAI VIET LETTER HIGH CHO;Lo;0;L;;;;;N;;;;; +AA8E;TAI VIET LETTER LOW SO;Lo;0;L;;;;;N;;;;; +AA8F;TAI VIET LETTER HIGH SO;Lo;0;L;;;;;N;;;;; +AA90;TAI VIET LETTER LOW NYO;Lo;0;L;;;;;N;;;;; +AA91;TAI VIET LETTER HIGH NYO;Lo;0;L;;;;;N;;;;; +AA92;TAI VIET LETTER LOW DO;Lo;0;L;;;;;N;;;;; +AA93;TAI VIET LETTER HIGH DO;Lo;0;L;;;;;N;;;;; +AA94;TAI VIET LETTER LOW TO;Lo;0;L;;;;;N;;;;; +AA95;TAI VIET LETTER HIGH TO;Lo;0;L;;;;;N;;;;; +AA96;TAI VIET LETTER LOW THO;Lo;0;L;;;;;N;;;;; +AA97;TAI VIET LETTER HIGH THO;Lo;0;L;;;;;N;;;;; +AA98;TAI VIET LETTER LOW NO;Lo;0;L;;;;;N;;;;; +AA99;TAI VIET LETTER HIGH NO;Lo;0;L;;;;;N;;;;; +AA9A;TAI VIET LETTER LOW BO;Lo;0;L;;;;;N;;;;; +AA9B;TAI VIET LETTER HIGH BO;Lo;0;L;;;;;N;;;;; +AA9C;TAI VIET LETTER LOW PO;Lo;0;L;;;;;N;;;;; +AA9D;TAI VIET LETTER HIGH PO;Lo;0;L;;;;;N;;;;; +AA9E;TAI VIET LETTER LOW PHO;Lo;0;L;;;;;N;;;;; +AA9F;TAI VIET LETTER HIGH PHO;Lo;0;L;;;;;N;;;;; +AAA0;TAI VIET LETTER LOW FO;Lo;0;L;;;;;N;;;;; +AAA1;TAI VIET LETTER HIGH FO;Lo;0;L;;;;;N;;;;; +AAA2;TAI VIET LETTER LOW MO;Lo;0;L;;;;;N;;;;; +AAA3;TAI VIET LETTER HIGH MO;Lo;0;L;;;;;N;;;;; +AAA4;TAI VIET LETTER LOW YO;Lo;0;L;;;;;N;;;;; +AAA5;TAI VIET LETTER HIGH YO;Lo;0;L;;;;;N;;;;; +AAA6;TAI VIET LETTER LOW RO;Lo;0;L;;;;;N;;;;; +AAA7;TAI VIET LETTER HIGH RO;Lo;0;L;;;;;N;;;;; +AAA8;TAI VIET LETTER LOW LO;Lo;0;L;;;;;N;;;;; +AAA9;TAI VIET LETTER HIGH LO;Lo;0;L;;;;;N;;;;; +AAAA;TAI VIET LETTER LOW VO;Lo;0;L;;;;;N;;;;; +AAAB;TAI VIET LETTER HIGH VO;Lo;0;L;;;;;N;;;;; +AAAC;TAI VIET LETTER LOW HO;Lo;0;L;;;;;N;;;;; +AAAD;TAI VIET LETTER HIGH HO;Lo;0;L;;;;;N;;;;; +AAAE;TAI VIET LETTER LOW O;Lo;0;L;;;;;N;;;;; +AAAF;TAI VIET LETTER HIGH O;Lo;0;L;;;;;N;;;;; +AAB0;TAI VIET MAI KANG;Mn;230;NSM;;;;;N;;;;; +AAB1;TAI VIET VOWEL AA;Lo;0;L;;;;;N;;;;; +AAB2;TAI VIET VOWEL I;Mn;230;NSM;;;;;N;;;;; +AAB3;TAI VIET VOWEL UE;Mn;230;NSM;;;;;N;;;;; +AAB4;TAI VIET VOWEL U;Mn;220;NSM;;;;;N;;;;; +AAB5;TAI VIET VOWEL E;Lo;0;L;;;;;N;;;;; +AAB6;TAI VIET VOWEL O;Lo;0;L;;;;;N;;;;; +AAB7;TAI VIET MAI KHIT;Mn;230;NSM;;;;;N;;;;; +AAB8;TAI VIET VOWEL IA;Mn;230;NSM;;;;;N;;;;; +AAB9;TAI VIET VOWEL UEA;Lo;0;L;;;;;N;;;;; +AABA;TAI VIET VOWEL UA;Lo;0;L;;;;;N;;;;; +AABB;TAI VIET VOWEL AUE;Lo;0;L;;;;;N;;;;; +AABC;TAI VIET VOWEL AY;Lo;0;L;;;;;N;;;;; +AABD;TAI VIET VOWEL AN;Lo;0;L;;;;;N;;;;; +AABE;TAI VIET VOWEL AM;Mn;230;NSM;;;;;N;;;;; +AABF;TAI VIET TONE MAI EK;Mn;230;NSM;;;;;N;;;;; +AAC0;TAI VIET TONE MAI NUENG;Lo;0;L;;;;;N;;;;; +AAC1;TAI VIET TONE MAI THO;Mn;230;NSM;;;;;N;;;;; +AAC2;TAI VIET TONE MAI SONG;Lo;0;L;;;;;N;;;;; +AADB;TAI VIET SYMBOL KON;Lo;0;L;;;;;N;;;;; +AADC;TAI VIET SYMBOL NUENG;Lo;0;L;;;;;N;;;;; +AADD;TAI VIET SYMBOL SAM;Lm;0;L;;;;;N;;;;; +AADE;TAI VIET SYMBOL HO HOI;Po;0;L;;;;;N;;;;; +AADF;TAI VIET SYMBOL KOI KOI;Po;0;L;;;;;N;;;;; +ABC0;MEETEI MAYEK LETTER KOK;Lo;0;L;;;;;N;;;;; +ABC1;MEETEI MAYEK LETTER SAM;Lo;0;L;;;;;N;;;;; +ABC2;MEETEI MAYEK LETTER LAI;Lo;0;L;;;;;N;;;;; +ABC3;MEETEI MAYEK LETTER MIT;Lo;0;L;;;;;N;;;;; +ABC4;MEETEI MAYEK LETTER PA;Lo;0;L;;;;;N;;;;; +ABC5;MEETEI MAYEK LETTER NA;Lo;0;L;;;;;N;;;;; +ABC6;MEETEI MAYEK LETTER CHIL;Lo;0;L;;;;;N;;;;; +ABC7;MEETEI MAYEK LETTER TIL;Lo;0;L;;;;;N;;;;; +ABC8;MEETEI MAYEK LETTER KHOU;Lo;0;L;;;;;N;;;;; +ABC9;MEETEI MAYEK LETTER NGOU;Lo;0;L;;;;;N;;;;; +ABCA;MEETEI MAYEK LETTER THOU;Lo;0;L;;;;;N;;;;; +ABCB;MEETEI MAYEK LETTER WAI;Lo;0;L;;;;;N;;;;; +ABCC;MEETEI MAYEK LETTER YANG;Lo;0;L;;;;;N;;;;; +ABCD;MEETEI MAYEK LETTER HUK;Lo;0;L;;;;;N;;;;; +ABCE;MEETEI MAYEK LETTER UN;Lo;0;L;;;;;N;;;;; +ABCF;MEETEI MAYEK LETTER I;Lo;0;L;;;;;N;;;;; +ABD0;MEETEI MAYEK LETTER PHAM;Lo;0;L;;;;;N;;;;; +ABD1;MEETEI MAYEK LETTER ATIYA;Lo;0;L;;;;;N;;;;; +ABD2;MEETEI MAYEK LETTER GOK;Lo;0;L;;;;;N;;;;; +ABD3;MEETEI MAYEK LETTER JHAM;Lo;0;L;;;;;N;;;;; +ABD4;MEETEI MAYEK LETTER RAI;Lo;0;L;;;;;N;;;;; +ABD5;MEETEI MAYEK LETTER BA;Lo;0;L;;;;;N;;;;; +ABD6;MEETEI MAYEK LETTER JIL;Lo;0;L;;;;;N;;;;; +ABD7;MEETEI MAYEK LETTER DIL;Lo;0;L;;;;;N;;;;; +ABD8;MEETEI MAYEK LETTER GHOU;Lo;0;L;;;;;N;;;;; +ABD9;MEETEI MAYEK LETTER DHOU;Lo;0;L;;;;;N;;;;; +ABDA;MEETEI MAYEK LETTER BHAM;Lo;0;L;;;;;N;;;;; +ABDB;MEETEI MAYEK LETTER KOK LONSUM;Lo;0;L;;;;;N;;;;; +ABDC;MEETEI MAYEK LETTER LAI LONSUM;Lo;0;L;;;;;N;;;;; +ABDD;MEETEI MAYEK LETTER MIT LONSUM;Lo;0;L;;;;;N;;;;; +ABDE;MEETEI MAYEK LETTER PA LONSUM;Lo;0;L;;;;;N;;;;; +ABDF;MEETEI MAYEK LETTER NA LONSUM;Lo;0;L;;;;;N;;;;; +ABE0;MEETEI MAYEK LETTER TIL LONSUM;Lo;0;L;;;;;N;;;;; +ABE1;MEETEI MAYEK LETTER NGOU LONSUM;Lo;0;L;;;;;N;;;;; +ABE2;MEETEI MAYEK LETTER I LONSUM;Lo;0;L;;;;;N;;;;; +ABE3;MEETEI MAYEK VOWEL SIGN ONAP;Mc;0;L;;;;;N;;;;; +ABE4;MEETEI MAYEK VOWEL SIGN INAP;Mc;0;L;;;;;N;;;;; +ABE5;MEETEI MAYEK VOWEL SIGN ANAP;Mn;0;NSM;;;;;N;;;;; +ABE6;MEETEI MAYEK VOWEL SIGN YENAP;Mc;0;L;;;;;N;;;;; +ABE7;MEETEI MAYEK VOWEL SIGN SOUNAP;Mc;0;L;;;;;N;;;;; +ABE8;MEETEI MAYEK VOWEL SIGN UNAP;Mn;0;NSM;;;;;N;;;;; +ABE9;MEETEI MAYEK VOWEL SIGN CHEINAP;Mc;0;L;;;;;N;;;;; +ABEA;MEETEI MAYEK VOWEL SIGN NUNG;Mc;0;L;;;;;N;;;;; +ABEB;MEETEI MAYEK CHEIKHEI;Po;0;L;;;;;N;;;;; +ABEC;MEETEI MAYEK LUM IYEK;Mc;0;L;;;;;N;;;;; +ABED;MEETEI MAYEK APUN IYEK;Mn;9;NSM;;;;;N;;;;; +ABF0;MEETEI MAYEK DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +ABF1;MEETEI MAYEK DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +ABF2;MEETEI MAYEK DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +ABF3;MEETEI MAYEK DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +ABF4;MEETEI MAYEK DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +ABF5;MEETEI MAYEK DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +ABF6;MEETEI MAYEK DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +ABF7;MEETEI MAYEK DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +ABF8;MEETEI MAYEK DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +ABF9;MEETEI MAYEK DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +AC00;;Lo;0;L;;;;;N;;;;; +D7A3;;Lo;0;L;;;;;N;;;;; +D7B0;HANGUL JUNGSEONG O-YEO;Lo;0;L;;;;;N;;;;; +D7B1;HANGUL JUNGSEONG O-O-I;Lo;0;L;;;;;N;;;;; +D7B2;HANGUL JUNGSEONG YO-A;Lo;0;L;;;;;N;;;;; +D7B3;HANGUL JUNGSEONG YO-AE;Lo;0;L;;;;;N;;;;; +D7B4;HANGUL JUNGSEONG YO-EO;Lo;0;L;;;;;N;;;;; +D7B5;HANGUL JUNGSEONG U-YEO;Lo;0;L;;;;;N;;;;; +D7B6;HANGUL JUNGSEONG U-I-I;Lo;0;L;;;;;N;;;;; +D7B7;HANGUL JUNGSEONG YU-AE;Lo;0;L;;;;;N;;;;; +D7B8;HANGUL JUNGSEONG YU-O;Lo;0;L;;;;;N;;;;; +D7B9;HANGUL JUNGSEONG EU-A;Lo;0;L;;;;;N;;;;; +D7BA;HANGUL JUNGSEONG EU-EO;Lo;0;L;;;;;N;;;;; +D7BB;HANGUL JUNGSEONG EU-E;Lo;0;L;;;;;N;;;;; +D7BC;HANGUL JUNGSEONG EU-O;Lo;0;L;;;;;N;;;;; +D7BD;HANGUL JUNGSEONG I-YA-O;Lo;0;L;;;;;N;;;;; +D7BE;HANGUL JUNGSEONG I-YAE;Lo;0;L;;;;;N;;;;; +D7BF;HANGUL JUNGSEONG I-YEO;Lo;0;L;;;;;N;;;;; +D7C0;HANGUL JUNGSEONG I-YE;Lo;0;L;;;;;N;;;;; +D7C1;HANGUL JUNGSEONG I-O-I;Lo;0;L;;;;;N;;;;; +D7C2;HANGUL JUNGSEONG I-YO;Lo;0;L;;;;;N;;;;; +D7C3;HANGUL JUNGSEONG I-YU;Lo;0;L;;;;;N;;;;; +D7C4;HANGUL JUNGSEONG I-I;Lo;0;L;;;;;N;;;;; +D7C5;HANGUL JUNGSEONG ARAEA-A;Lo;0;L;;;;;N;;;;; +D7C6;HANGUL JUNGSEONG ARAEA-E;Lo;0;L;;;;;N;;;;; +D7CB;HANGUL JONGSEONG NIEUN-RIEUL;Lo;0;L;;;;;N;;;;; +D7CC;HANGUL JONGSEONG NIEUN-CHIEUCH;Lo;0;L;;;;;N;;;;; +D7CD;HANGUL JONGSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;;;; +D7CE;HANGUL JONGSEONG SSANGTIKEUT-PIEUP;Lo;0;L;;;;;N;;;;; +D7CF;HANGUL JONGSEONG TIKEUT-PIEUP;Lo;0;L;;;;;N;;;;; +D7D0;HANGUL JONGSEONG TIKEUT-SIOS;Lo;0;L;;;;;N;;;;; +D7D1;HANGUL JONGSEONG TIKEUT-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +D7D2;HANGUL JONGSEONG TIKEUT-CIEUC;Lo;0;L;;;;;N;;;;; +D7D3;HANGUL JONGSEONG TIKEUT-CHIEUCH;Lo;0;L;;;;;N;;;;; +D7D4;HANGUL JONGSEONG TIKEUT-THIEUTH;Lo;0;L;;;;;N;;;;; +D7D5;HANGUL JONGSEONG RIEUL-SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +D7D6;HANGUL JONGSEONG RIEUL-KIYEOK-HIEUH;Lo;0;L;;;;;N;;;;; +D7D7;HANGUL JONGSEONG SSANGRIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;; +D7D8;HANGUL JONGSEONG RIEUL-MIEUM-HIEUH;Lo;0;L;;;;;N;;;;; +D7D9;HANGUL JONGSEONG RIEUL-PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;; +D7DA;HANGUL JONGSEONG RIEUL-PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; +D7DB;HANGUL JONGSEONG RIEUL-YESIEUNG;Lo;0;L;;;;;N;;;;; +D7DC;HANGUL JONGSEONG RIEUL-YEORINHIEUH-HIEUH;Lo;0;L;;;;;N;;;;; +D7DD;HANGUL JONGSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;; +D7DE;HANGUL JONGSEONG MIEUM-NIEUN;Lo;0;L;;;;;N;;;;; +D7DF;HANGUL JONGSEONG MIEUM-SSANGNIEUN;Lo;0;L;;;;;N;;;;; +D7E0;HANGUL JONGSEONG SSANGMIEUM;Lo;0;L;;;;;N;;;;; +D7E1;HANGUL JONGSEONG MIEUM-PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +D7E2;HANGUL JONGSEONG MIEUM-CIEUC;Lo;0;L;;;;;N;;;;; +D7E3;HANGUL JONGSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;; +D7E4;HANGUL JONGSEONG PIEUP-RIEUL-PHIEUPH;Lo;0;L;;;;;N;;;;; +D7E5;HANGUL JONGSEONG PIEUP-MIEUM;Lo;0;L;;;;;N;;;;; +D7E6;HANGUL JONGSEONG SSANGPIEUP;Lo;0;L;;;;;N;;;;; +D7E7;HANGUL JONGSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +D7E8;HANGUL JONGSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;; +D7E9;HANGUL JONGSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;; +D7EA;HANGUL JONGSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;; +D7EB;HANGUL JONGSEONG SIOS-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +D7EC;HANGUL JONGSEONG SSANGSIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +D7ED;HANGUL JONGSEONG SSANGSIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +D7EE;HANGUL JONGSEONG SIOS-PANSIOS;Lo;0;L;;;;;N;;;;; +D7EF;HANGUL JONGSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;; +D7F0;HANGUL JONGSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;; +D7F1;HANGUL JONGSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;; +D7F2;HANGUL JONGSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;; +D7F3;HANGUL JONGSEONG PANSIOS-PIEUP;Lo;0;L;;;;;N;;;;; +D7F4;HANGUL JONGSEONG PANSIOS-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +D7F5;HANGUL JONGSEONG YESIEUNG-MIEUM;Lo;0;L;;;;;N;;;;; +D7F6;HANGUL JONGSEONG YESIEUNG-HIEUH;Lo;0;L;;;;;N;;;;; +D7F7;HANGUL JONGSEONG CIEUC-PIEUP;Lo;0;L;;;;;N;;;;; +D7F8;HANGUL JONGSEONG CIEUC-SSANGPIEUP;Lo;0;L;;;;;N;;;;; +D7F9;HANGUL JONGSEONG SSANGCIEUC;Lo;0;L;;;;;N;;;;; +D7FA;HANGUL JONGSEONG PHIEUPH-SIOS;Lo;0;L;;;;;N;;;;; +D7FB;HANGUL JONGSEONG PHIEUPH-THIEUTH;Lo;0;L;;;;;N;;;;; +D800;;Cs;0;L;;;;;N;;;;; +DB7F;;Cs;0;L;;;;;N;;;;; +DB80;;Cs;0;L;;;;;N;;;;; +DBFF;;Cs;0;L;;;;;N;;;;; +DC00;;Cs;0;L;;;;;N;;;;; +DFFF;;Cs;0;L;;;;;N;;;;; +E000;;Co;0;L;;;;;N;;;;; +F8FF;;Co;0;L;;;;;N;;;;; +F900;CJK COMPATIBILITY IDEOGRAPH-F900;Lo;0;L;8C48;;;;N;;;;; +F901;CJK COMPATIBILITY IDEOGRAPH-F901;Lo;0;L;66F4;;;;N;;;;; +F902;CJK COMPATIBILITY IDEOGRAPH-F902;Lo;0;L;8ECA;;;;N;;;;; +F903;CJK COMPATIBILITY IDEOGRAPH-F903;Lo;0;L;8CC8;;;;N;;;;; +F904;CJK COMPATIBILITY IDEOGRAPH-F904;Lo;0;L;6ED1;;;;N;;;;; +F905;CJK COMPATIBILITY IDEOGRAPH-F905;Lo;0;L;4E32;;;;N;;;;; +F906;CJK COMPATIBILITY IDEOGRAPH-F906;Lo;0;L;53E5;;;;N;;;;; +F907;CJK COMPATIBILITY IDEOGRAPH-F907;Lo;0;L;9F9C;;;;N;;;;; +F908;CJK COMPATIBILITY IDEOGRAPH-F908;Lo;0;L;9F9C;;;;N;;;;; +F909;CJK COMPATIBILITY IDEOGRAPH-F909;Lo;0;L;5951;;;;N;;;;; +F90A;CJK COMPATIBILITY IDEOGRAPH-F90A;Lo;0;L;91D1;;;;N;;;;; +F90B;CJK COMPATIBILITY IDEOGRAPH-F90B;Lo;0;L;5587;;;;N;;;;; +F90C;CJK COMPATIBILITY IDEOGRAPH-F90C;Lo;0;L;5948;;;;N;;;;; +F90D;CJK COMPATIBILITY IDEOGRAPH-F90D;Lo;0;L;61F6;;;;N;;;;; +F90E;CJK COMPATIBILITY IDEOGRAPH-F90E;Lo;0;L;7669;;;;N;;;;; +F90F;CJK COMPATIBILITY IDEOGRAPH-F90F;Lo;0;L;7F85;;;;N;;;;; +F910;CJK COMPATIBILITY IDEOGRAPH-F910;Lo;0;L;863F;;;;N;;;;; +F911;CJK COMPATIBILITY IDEOGRAPH-F911;Lo;0;L;87BA;;;;N;;;;; +F912;CJK COMPATIBILITY IDEOGRAPH-F912;Lo;0;L;88F8;;;;N;;;;; +F913;CJK COMPATIBILITY IDEOGRAPH-F913;Lo;0;L;908F;;;;N;;;;; +F914;CJK COMPATIBILITY IDEOGRAPH-F914;Lo;0;L;6A02;;;;N;;;;; +F915;CJK COMPATIBILITY IDEOGRAPH-F915;Lo;0;L;6D1B;;;;N;;;;; +F916;CJK COMPATIBILITY IDEOGRAPH-F916;Lo;0;L;70D9;;;;N;;;;; +F917;CJK COMPATIBILITY IDEOGRAPH-F917;Lo;0;L;73DE;;;;N;;;;; +F918;CJK COMPATIBILITY IDEOGRAPH-F918;Lo;0;L;843D;;;;N;;;;; +F919;CJK COMPATIBILITY IDEOGRAPH-F919;Lo;0;L;916A;;;;N;;;;; +F91A;CJK COMPATIBILITY IDEOGRAPH-F91A;Lo;0;L;99F1;;;;N;;;;; +F91B;CJK COMPATIBILITY IDEOGRAPH-F91B;Lo;0;L;4E82;;;;N;;;;; +F91C;CJK COMPATIBILITY IDEOGRAPH-F91C;Lo;0;L;5375;;;;N;;;;; +F91D;CJK COMPATIBILITY IDEOGRAPH-F91D;Lo;0;L;6B04;;;;N;;;;; +F91E;CJK COMPATIBILITY IDEOGRAPH-F91E;Lo;0;L;721B;;;;N;;;;; +F91F;CJK COMPATIBILITY IDEOGRAPH-F91F;Lo;0;L;862D;;;;N;;;;; +F920;CJK COMPATIBILITY IDEOGRAPH-F920;Lo;0;L;9E1E;;;;N;;;;; +F921;CJK COMPATIBILITY IDEOGRAPH-F921;Lo;0;L;5D50;;;;N;;;;; +F922;CJK COMPATIBILITY IDEOGRAPH-F922;Lo;0;L;6FEB;;;;N;;;;; +F923;CJK COMPATIBILITY IDEOGRAPH-F923;Lo;0;L;85CD;;;;N;;;;; +F924;CJK COMPATIBILITY IDEOGRAPH-F924;Lo;0;L;8964;;;;N;;;;; +F925;CJK COMPATIBILITY IDEOGRAPH-F925;Lo;0;L;62C9;;;;N;;;;; +F926;CJK COMPATIBILITY IDEOGRAPH-F926;Lo;0;L;81D8;;;;N;;;;; +F927;CJK COMPATIBILITY IDEOGRAPH-F927;Lo;0;L;881F;;;;N;;;;; +F928;CJK COMPATIBILITY IDEOGRAPH-F928;Lo;0;L;5ECA;;;;N;;;;; +F929;CJK COMPATIBILITY IDEOGRAPH-F929;Lo;0;L;6717;;;;N;;;;; +F92A;CJK COMPATIBILITY IDEOGRAPH-F92A;Lo;0;L;6D6A;;;;N;;;;; +F92B;CJK COMPATIBILITY IDEOGRAPH-F92B;Lo;0;L;72FC;;;;N;;;;; +F92C;CJK COMPATIBILITY IDEOGRAPH-F92C;Lo;0;L;90CE;;;;N;;;;; +F92D;CJK COMPATIBILITY IDEOGRAPH-F92D;Lo;0;L;4F86;;;;N;;;;; +F92E;CJK COMPATIBILITY IDEOGRAPH-F92E;Lo;0;L;51B7;;;;N;;;;; +F92F;CJK COMPATIBILITY IDEOGRAPH-F92F;Lo;0;L;52DE;;;;N;;;;; +F930;CJK COMPATIBILITY IDEOGRAPH-F930;Lo;0;L;64C4;;;;N;;;;; +F931;CJK COMPATIBILITY IDEOGRAPH-F931;Lo;0;L;6AD3;;;;N;;;;; +F932;CJK COMPATIBILITY IDEOGRAPH-F932;Lo;0;L;7210;;;;N;;;;; +F933;CJK COMPATIBILITY IDEOGRAPH-F933;Lo;0;L;76E7;;;;N;;;;; +F934;CJK COMPATIBILITY IDEOGRAPH-F934;Lo;0;L;8001;;;;N;;;;; +F935;CJK COMPATIBILITY IDEOGRAPH-F935;Lo;0;L;8606;;;;N;;;;; +F936;CJK COMPATIBILITY IDEOGRAPH-F936;Lo;0;L;865C;;;;N;;;;; +F937;CJK COMPATIBILITY IDEOGRAPH-F937;Lo;0;L;8DEF;;;;N;;;;; +F938;CJK COMPATIBILITY IDEOGRAPH-F938;Lo;0;L;9732;;;;N;;;;; +F939;CJK COMPATIBILITY IDEOGRAPH-F939;Lo;0;L;9B6F;;;;N;;;;; +F93A;CJK COMPATIBILITY IDEOGRAPH-F93A;Lo;0;L;9DFA;;;;N;;;;; +F93B;CJK COMPATIBILITY IDEOGRAPH-F93B;Lo;0;L;788C;;;;N;;;;; +F93C;CJK COMPATIBILITY IDEOGRAPH-F93C;Lo;0;L;797F;;;;N;;;;; +F93D;CJK COMPATIBILITY IDEOGRAPH-F93D;Lo;0;L;7DA0;;;;N;;;;; +F93E;CJK COMPATIBILITY IDEOGRAPH-F93E;Lo;0;L;83C9;;;;N;;;;; +F93F;CJK COMPATIBILITY IDEOGRAPH-F93F;Lo;0;L;9304;;;;N;;;;; +F940;CJK COMPATIBILITY IDEOGRAPH-F940;Lo;0;L;9E7F;;;;N;;;;; +F941;CJK COMPATIBILITY IDEOGRAPH-F941;Lo;0;L;8AD6;;;;N;;;;; +F942;CJK COMPATIBILITY IDEOGRAPH-F942;Lo;0;L;58DF;;;;N;;;;; +F943;CJK COMPATIBILITY IDEOGRAPH-F943;Lo;0;L;5F04;;;;N;;;;; +F944;CJK COMPATIBILITY IDEOGRAPH-F944;Lo;0;L;7C60;;;;N;;;;; +F945;CJK COMPATIBILITY IDEOGRAPH-F945;Lo;0;L;807E;;;;N;;;;; +F946;CJK COMPATIBILITY IDEOGRAPH-F946;Lo;0;L;7262;;;;N;;;;; +F947;CJK COMPATIBILITY IDEOGRAPH-F947;Lo;0;L;78CA;;;;N;;;;; +F948;CJK COMPATIBILITY IDEOGRAPH-F948;Lo;0;L;8CC2;;;;N;;;;; +F949;CJK COMPATIBILITY IDEOGRAPH-F949;Lo;0;L;96F7;;;;N;;;;; +F94A;CJK COMPATIBILITY IDEOGRAPH-F94A;Lo;0;L;58D8;;;;N;;;;; +F94B;CJK COMPATIBILITY IDEOGRAPH-F94B;Lo;0;L;5C62;;;;N;;;;; +F94C;CJK COMPATIBILITY IDEOGRAPH-F94C;Lo;0;L;6A13;;;;N;;;;; +F94D;CJK COMPATIBILITY IDEOGRAPH-F94D;Lo;0;L;6DDA;;;;N;;;;; +F94E;CJK COMPATIBILITY IDEOGRAPH-F94E;Lo;0;L;6F0F;;;;N;;;;; +F94F;CJK COMPATIBILITY IDEOGRAPH-F94F;Lo;0;L;7D2F;;;;N;;;;; +F950;CJK COMPATIBILITY IDEOGRAPH-F950;Lo;0;L;7E37;;;;N;;;;; +F951;CJK COMPATIBILITY IDEOGRAPH-F951;Lo;0;L;964B;;;;N;;;;; +F952;CJK COMPATIBILITY IDEOGRAPH-F952;Lo;0;L;52D2;;;;N;;;;; +F953;CJK COMPATIBILITY IDEOGRAPH-F953;Lo;0;L;808B;;;;N;;;;; +F954;CJK COMPATIBILITY IDEOGRAPH-F954;Lo;0;L;51DC;;;;N;;;;; +F955;CJK COMPATIBILITY IDEOGRAPH-F955;Lo;0;L;51CC;;;;N;;;;; +F956;CJK COMPATIBILITY IDEOGRAPH-F956;Lo;0;L;7A1C;;;;N;;;;; +F957;CJK COMPATIBILITY IDEOGRAPH-F957;Lo;0;L;7DBE;;;;N;;;;; +F958;CJK COMPATIBILITY IDEOGRAPH-F958;Lo;0;L;83F1;;;;N;;;;; +F959;CJK COMPATIBILITY IDEOGRAPH-F959;Lo;0;L;9675;;;;N;;;;; +F95A;CJK COMPATIBILITY IDEOGRAPH-F95A;Lo;0;L;8B80;;;;N;;;;; +F95B;CJK COMPATIBILITY IDEOGRAPH-F95B;Lo;0;L;62CF;;;;N;;;;; +F95C;CJK COMPATIBILITY IDEOGRAPH-F95C;Lo;0;L;6A02;;;;N;;;;; +F95D;CJK COMPATIBILITY IDEOGRAPH-F95D;Lo;0;L;8AFE;;;;N;;;;; +F95E;CJK COMPATIBILITY IDEOGRAPH-F95E;Lo;0;L;4E39;;;;N;;;;; +F95F;CJK COMPATIBILITY IDEOGRAPH-F95F;Lo;0;L;5BE7;;;;N;;;;; +F960;CJK COMPATIBILITY IDEOGRAPH-F960;Lo;0;L;6012;;;;N;;;;; +F961;CJK COMPATIBILITY IDEOGRAPH-F961;Lo;0;L;7387;;;;N;;;;; +F962;CJK COMPATIBILITY IDEOGRAPH-F962;Lo;0;L;7570;;;;N;;;;; +F963;CJK COMPATIBILITY IDEOGRAPH-F963;Lo;0;L;5317;;;;N;;;;; +F964;CJK COMPATIBILITY IDEOGRAPH-F964;Lo;0;L;78FB;;;;N;;;;; +F965;CJK COMPATIBILITY IDEOGRAPH-F965;Lo;0;L;4FBF;;;;N;;;;; +F966;CJK COMPATIBILITY IDEOGRAPH-F966;Lo;0;L;5FA9;;;;N;;;;; +F967;CJK COMPATIBILITY IDEOGRAPH-F967;Lo;0;L;4E0D;;;;N;;;;; +F968;CJK COMPATIBILITY IDEOGRAPH-F968;Lo;0;L;6CCC;;;;N;;;;; +F969;CJK COMPATIBILITY IDEOGRAPH-F969;Lo;0;L;6578;;;;N;;;;; +F96A;CJK COMPATIBILITY IDEOGRAPH-F96A;Lo;0;L;7D22;;;;N;;;;; +F96B;CJK COMPATIBILITY IDEOGRAPH-F96B;Lo;0;L;53C3;;;3;N;;;;; +F96C;CJK COMPATIBILITY IDEOGRAPH-F96C;Lo;0;L;585E;;;;N;;;;; +F96D;CJK COMPATIBILITY IDEOGRAPH-F96D;Lo;0;L;7701;;;;N;;;;; +F96E;CJK COMPATIBILITY IDEOGRAPH-F96E;Lo;0;L;8449;;;;N;;;;; +F96F;CJK COMPATIBILITY IDEOGRAPH-F96F;Lo;0;L;8AAA;;;;N;;;;; +F970;CJK COMPATIBILITY IDEOGRAPH-F970;Lo;0;L;6BBA;;;;N;;;;; +F971;CJK COMPATIBILITY IDEOGRAPH-F971;Lo;0;L;8FB0;;;;N;;;;; +F972;CJK COMPATIBILITY IDEOGRAPH-F972;Lo;0;L;6C88;;;;N;;;;; +F973;CJK COMPATIBILITY IDEOGRAPH-F973;Lo;0;L;62FE;;;10;N;;;;; +F974;CJK COMPATIBILITY IDEOGRAPH-F974;Lo;0;L;82E5;;;;N;;;;; +F975;CJK COMPATIBILITY IDEOGRAPH-F975;Lo;0;L;63A0;;;;N;;;;; +F976;CJK COMPATIBILITY IDEOGRAPH-F976;Lo;0;L;7565;;;;N;;;;; +F977;CJK COMPATIBILITY IDEOGRAPH-F977;Lo;0;L;4EAE;;;;N;;;;; +F978;CJK COMPATIBILITY IDEOGRAPH-F978;Lo;0;L;5169;;;2;N;;;;; +F979;CJK COMPATIBILITY IDEOGRAPH-F979;Lo;0;L;51C9;;;;N;;;;; +F97A;CJK COMPATIBILITY IDEOGRAPH-F97A;Lo;0;L;6881;;;;N;;;;; +F97B;CJK COMPATIBILITY IDEOGRAPH-F97B;Lo;0;L;7CE7;;;;N;;;;; +F97C;CJK COMPATIBILITY IDEOGRAPH-F97C;Lo;0;L;826F;;;;N;;;;; +F97D;CJK COMPATIBILITY IDEOGRAPH-F97D;Lo;0;L;8AD2;;;;N;;;;; +F97E;CJK COMPATIBILITY IDEOGRAPH-F97E;Lo;0;L;91CF;;;;N;;;;; +F97F;CJK COMPATIBILITY IDEOGRAPH-F97F;Lo;0;L;52F5;;;;N;;;;; +F980;CJK COMPATIBILITY IDEOGRAPH-F980;Lo;0;L;5442;;;;N;;;;; +F981;CJK COMPATIBILITY IDEOGRAPH-F981;Lo;0;L;5973;;;;N;;;;; +F982;CJK COMPATIBILITY IDEOGRAPH-F982;Lo;0;L;5EEC;;;;N;;;;; +F983;CJK COMPATIBILITY IDEOGRAPH-F983;Lo;0;L;65C5;;;;N;;;;; +F984;CJK COMPATIBILITY IDEOGRAPH-F984;Lo;0;L;6FFE;;;;N;;;;; +F985;CJK COMPATIBILITY IDEOGRAPH-F985;Lo;0;L;792A;;;;N;;;;; +F986;CJK COMPATIBILITY IDEOGRAPH-F986;Lo;0;L;95AD;;;;N;;;;; +F987;CJK COMPATIBILITY IDEOGRAPH-F987;Lo;0;L;9A6A;;;;N;;;;; +F988;CJK COMPATIBILITY IDEOGRAPH-F988;Lo;0;L;9E97;;;;N;;;;; +F989;CJK COMPATIBILITY IDEOGRAPH-F989;Lo;0;L;9ECE;;;;N;;;;; +F98A;CJK COMPATIBILITY IDEOGRAPH-F98A;Lo;0;L;529B;;;;N;;;;; +F98B;CJK COMPATIBILITY IDEOGRAPH-F98B;Lo;0;L;66C6;;;;N;;;;; +F98C;CJK COMPATIBILITY IDEOGRAPH-F98C;Lo;0;L;6B77;;;;N;;;;; +F98D;CJK COMPATIBILITY IDEOGRAPH-F98D;Lo;0;L;8F62;;;;N;;;;; +F98E;CJK COMPATIBILITY IDEOGRAPH-F98E;Lo;0;L;5E74;;;;N;;;;; +F98F;CJK COMPATIBILITY IDEOGRAPH-F98F;Lo;0;L;6190;;;;N;;;;; +F990;CJK COMPATIBILITY IDEOGRAPH-F990;Lo;0;L;6200;;;;N;;;;; +F991;CJK COMPATIBILITY IDEOGRAPH-F991;Lo;0;L;649A;;;;N;;;;; +F992;CJK COMPATIBILITY IDEOGRAPH-F992;Lo;0;L;6F23;;;;N;;;;; +F993;CJK COMPATIBILITY IDEOGRAPH-F993;Lo;0;L;7149;;;;N;;;;; +F994;CJK COMPATIBILITY IDEOGRAPH-F994;Lo;0;L;7489;;;;N;;;;; +F995;CJK COMPATIBILITY IDEOGRAPH-F995;Lo;0;L;79CA;;;;N;;;;; +F996;CJK COMPATIBILITY IDEOGRAPH-F996;Lo;0;L;7DF4;;;;N;;;;; +F997;CJK COMPATIBILITY IDEOGRAPH-F997;Lo;0;L;806F;;;;N;;;;; +F998;CJK COMPATIBILITY IDEOGRAPH-F998;Lo;0;L;8F26;;;;N;;;;; +F999;CJK COMPATIBILITY IDEOGRAPH-F999;Lo;0;L;84EE;;;;N;;;;; +F99A;CJK COMPATIBILITY IDEOGRAPH-F99A;Lo;0;L;9023;;;;N;;;;; +F99B;CJK COMPATIBILITY IDEOGRAPH-F99B;Lo;0;L;934A;;;;N;;;;; +F99C;CJK COMPATIBILITY IDEOGRAPH-F99C;Lo;0;L;5217;;;;N;;;;; +F99D;CJK COMPATIBILITY IDEOGRAPH-F99D;Lo;0;L;52A3;;;;N;;;;; +F99E;CJK COMPATIBILITY IDEOGRAPH-F99E;Lo;0;L;54BD;;;;N;;;;; +F99F;CJK COMPATIBILITY IDEOGRAPH-F99F;Lo;0;L;70C8;;;;N;;;;; +F9A0;CJK COMPATIBILITY IDEOGRAPH-F9A0;Lo;0;L;88C2;;;;N;;;;; +F9A1;CJK COMPATIBILITY IDEOGRAPH-F9A1;Lo;0;L;8AAA;;;;N;;;;; +F9A2;CJK COMPATIBILITY IDEOGRAPH-F9A2;Lo;0;L;5EC9;;;;N;;;;; +F9A3;CJK COMPATIBILITY IDEOGRAPH-F9A3;Lo;0;L;5FF5;;;;N;;;;; +F9A4;CJK COMPATIBILITY IDEOGRAPH-F9A4;Lo;0;L;637B;;;;N;;;;; +F9A5;CJK COMPATIBILITY IDEOGRAPH-F9A5;Lo;0;L;6BAE;;;;N;;;;; +F9A6;CJK COMPATIBILITY IDEOGRAPH-F9A6;Lo;0;L;7C3E;;;;N;;;;; +F9A7;CJK COMPATIBILITY IDEOGRAPH-F9A7;Lo;0;L;7375;;;;N;;;;; +F9A8;CJK COMPATIBILITY IDEOGRAPH-F9A8;Lo;0;L;4EE4;;;;N;;;;; +F9A9;CJK COMPATIBILITY IDEOGRAPH-F9A9;Lo;0;L;56F9;;;;N;;;;; +F9AA;CJK COMPATIBILITY IDEOGRAPH-F9AA;Lo;0;L;5BE7;;;;N;;;;; +F9AB;CJK COMPATIBILITY IDEOGRAPH-F9AB;Lo;0;L;5DBA;;;;N;;;;; +F9AC;CJK COMPATIBILITY IDEOGRAPH-F9AC;Lo;0;L;601C;;;;N;;;;; +F9AD;CJK COMPATIBILITY IDEOGRAPH-F9AD;Lo;0;L;73B2;;;;N;;;;; +F9AE;CJK COMPATIBILITY IDEOGRAPH-F9AE;Lo;0;L;7469;;;;N;;;;; +F9AF;CJK COMPATIBILITY IDEOGRAPH-F9AF;Lo;0;L;7F9A;;;;N;;;;; +F9B0;CJK COMPATIBILITY IDEOGRAPH-F9B0;Lo;0;L;8046;;;;N;;;;; +F9B1;CJK COMPATIBILITY IDEOGRAPH-F9B1;Lo;0;L;9234;;;;N;;;;; +F9B2;CJK COMPATIBILITY IDEOGRAPH-F9B2;Lo;0;L;96F6;;;0;N;;;;; +F9B3;CJK COMPATIBILITY IDEOGRAPH-F9B3;Lo;0;L;9748;;;;N;;;;; +F9B4;CJK COMPATIBILITY IDEOGRAPH-F9B4;Lo;0;L;9818;;;;N;;;;; +F9B5;CJK COMPATIBILITY IDEOGRAPH-F9B5;Lo;0;L;4F8B;;;;N;;;;; +F9B6;CJK COMPATIBILITY IDEOGRAPH-F9B6;Lo;0;L;79AE;;;;N;;;;; +F9B7;CJK COMPATIBILITY IDEOGRAPH-F9B7;Lo;0;L;91B4;;;;N;;;;; +F9B8;CJK COMPATIBILITY IDEOGRAPH-F9B8;Lo;0;L;96B8;;;;N;;;;; +F9B9;CJK COMPATIBILITY IDEOGRAPH-F9B9;Lo;0;L;60E1;;;;N;;;;; +F9BA;CJK COMPATIBILITY IDEOGRAPH-F9BA;Lo;0;L;4E86;;;;N;;;;; +F9BB;CJK COMPATIBILITY IDEOGRAPH-F9BB;Lo;0;L;50DA;;;;N;;;;; +F9BC;CJK COMPATIBILITY IDEOGRAPH-F9BC;Lo;0;L;5BEE;;;;N;;;;; +F9BD;CJK COMPATIBILITY IDEOGRAPH-F9BD;Lo;0;L;5C3F;;;;N;;;;; +F9BE;CJK COMPATIBILITY IDEOGRAPH-F9BE;Lo;0;L;6599;;;;N;;;;; +F9BF;CJK COMPATIBILITY IDEOGRAPH-F9BF;Lo;0;L;6A02;;;;N;;;;; +F9C0;CJK COMPATIBILITY IDEOGRAPH-F9C0;Lo;0;L;71CE;;;;N;;;;; +F9C1;CJK COMPATIBILITY IDEOGRAPH-F9C1;Lo;0;L;7642;;;;N;;;;; +F9C2;CJK COMPATIBILITY IDEOGRAPH-F9C2;Lo;0;L;84FC;;;;N;;;;; +F9C3;CJK COMPATIBILITY IDEOGRAPH-F9C3;Lo;0;L;907C;;;;N;;;;; +F9C4;CJK COMPATIBILITY IDEOGRAPH-F9C4;Lo;0;L;9F8D;;;;N;;;;; +F9C5;CJK COMPATIBILITY IDEOGRAPH-F9C5;Lo;0;L;6688;;;;N;;;;; +F9C6;CJK COMPATIBILITY IDEOGRAPH-F9C6;Lo;0;L;962E;;;;N;;;;; +F9C7;CJK COMPATIBILITY IDEOGRAPH-F9C7;Lo;0;L;5289;;;;N;;;;; +F9C8;CJK COMPATIBILITY IDEOGRAPH-F9C8;Lo;0;L;677B;;;;N;;;;; +F9C9;CJK COMPATIBILITY IDEOGRAPH-F9C9;Lo;0;L;67F3;;;;N;;;;; +F9CA;CJK COMPATIBILITY IDEOGRAPH-F9CA;Lo;0;L;6D41;;;;N;;;;; +F9CB;CJK COMPATIBILITY IDEOGRAPH-F9CB;Lo;0;L;6E9C;;;;N;;;;; +F9CC;CJK COMPATIBILITY IDEOGRAPH-F9CC;Lo;0;L;7409;;;;N;;;;; +F9CD;CJK COMPATIBILITY IDEOGRAPH-F9CD;Lo;0;L;7559;;;;N;;;;; +F9CE;CJK COMPATIBILITY IDEOGRAPH-F9CE;Lo;0;L;786B;;;;N;;;;; +F9CF;CJK COMPATIBILITY IDEOGRAPH-F9CF;Lo;0;L;7D10;;;;N;;;;; +F9D0;CJK COMPATIBILITY IDEOGRAPH-F9D0;Lo;0;L;985E;;;;N;;;;; +F9D1;CJK COMPATIBILITY IDEOGRAPH-F9D1;Lo;0;L;516D;;;6;N;;;;; +F9D2;CJK COMPATIBILITY IDEOGRAPH-F9D2;Lo;0;L;622E;;;;N;;;;; +F9D3;CJK COMPATIBILITY IDEOGRAPH-F9D3;Lo;0;L;9678;;;6;N;;;;; +F9D4;CJK COMPATIBILITY IDEOGRAPH-F9D4;Lo;0;L;502B;;;;N;;;;; +F9D5;CJK COMPATIBILITY IDEOGRAPH-F9D5;Lo;0;L;5D19;;;;N;;;;; +F9D6;CJK COMPATIBILITY IDEOGRAPH-F9D6;Lo;0;L;6DEA;;;;N;;;;; +F9D7;CJK COMPATIBILITY IDEOGRAPH-F9D7;Lo;0;L;8F2A;;;;N;;;;; +F9D8;CJK COMPATIBILITY IDEOGRAPH-F9D8;Lo;0;L;5F8B;;;;N;;;;; +F9D9;CJK COMPATIBILITY IDEOGRAPH-F9D9;Lo;0;L;6144;;;;N;;;;; +F9DA;CJK COMPATIBILITY IDEOGRAPH-F9DA;Lo;0;L;6817;;;;N;;;;; +F9DB;CJK COMPATIBILITY IDEOGRAPH-F9DB;Lo;0;L;7387;;;;N;;;;; +F9DC;CJK COMPATIBILITY IDEOGRAPH-F9DC;Lo;0;L;9686;;;;N;;;;; +F9DD;CJK COMPATIBILITY IDEOGRAPH-F9DD;Lo;0;L;5229;;;;N;;;;; +F9DE;CJK COMPATIBILITY IDEOGRAPH-F9DE;Lo;0;L;540F;;;;N;;;;; +F9DF;CJK COMPATIBILITY IDEOGRAPH-F9DF;Lo;0;L;5C65;;;;N;;;;; +F9E0;CJK COMPATIBILITY IDEOGRAPH-F9E0;Lo;0;L;6613;;;;N;;;;; +F9E1;CJK COMPATIBILITY IDEOGRAPH-F9E1;Lo;0;L;674E;;;;N;;;;; +F9E2;CJK COMPATIBILITY IDEOGRAPH-F9E2;Lo;0;L;68A8;;;;N;;;;; +F9E3;CJK COMPATIBILITY IDEOGRAPH-F9E3;Lo;0;L;6CE5;;;;N;;;;; +F9E4;CJK COMPATIBILITY IDEOGRAPH-F9E4;Lo;0;L;7406;;;;N;;;;; +F9E5;CJK COMPATIBILITY IDEOGRAPH-F9E5;Lo;0;L;75E2;;;;N;;;;; +F9E6;CJK COMPATIBILITY IDEOGRAPH-F9E6;Lo;0;L;7F79;;;;N;;;;; +F9E7;CJK COMPATIBILITY IDEOGRAPH-F9E7;Lo;0;L;88CF;;;;N;;;;; +F9E8;CJK COMPATIBILITY IDEOGRAPH-F9E8;Lo;0;L;88E1;;;;N;;;;; +F9E9;CJK COMPATIBILITY IDEOGRAPH-F9E9;Lo;0;L;91CC;;;;N;;;;; +F9EA;CJK COMPATIBILITY IDEOGRAPH-F9EA;Lo;0;L;96E2;;;;N;;;;; +F9EB;CJK COMPATIBILITY IDEOGRAPH-F9EB;Lo;0;L;533F;;;;N;;;;; +F9EC;CJK COMPATIBILITY IDEOGRAPH-F9EC;Lo;0;L;6EBA;;;;N;;;;; +F9ED;CJK COMPATIBILITY IDEOGRAPH-F9ED;Lo;0;L;541D;;;;N;;;;; +F9EE;CJK COMPATIBILITY IDEOGRAPH-F9EE;Lo;0;L;71D0;;;;N;;;;; +F9EF;CJK COMPATIBILITY IDEOGRAPH-F9EF;Lo;0;L;7498;;;;N;;;;; +F9F0;CJK COMPATIBILITY IDEOGRAPH-F9F0;Lo;0;L;85FA;;;;N;;;;; +F9F1;CJK COMPATIBILITY IDEOGRAPH-F9F1;Lo;0;L;96A3;;;;N;;;;; +F9F2;CJK COMPATIBILITY IDEOGRAPH-F9F2;Lo;0;L;9C57;;;;N;;;;; +F9F3;CJK COMPATIBILITY IDEOGRAPH-F9F3;Lo;0;L;9E9F;;;;N;;;;; +F9F4;CJK COMPATIBILITY IDEOGRAPH-F9F4;Lo;0;L;6797;;;;N;;;;; +F9F5;CJK COMPATIBILITY IDEOGRAPH-F9F5;Lo;0;L;6DCB;;;;N;;;;; +F9F6;CJK COMPATIBILITY IDEOGRAPH-F9F6;Lo;0;L;81E8;;;;N;;;;; +F9F7;CJK COMPATIBILITY IDEOGRAPH-F9F7;Lo;0;L;7ACB;;;;N;;;;; +F9F8;CJK COMPATIBILITY IDEOGRAPH-F9F8;Lo;0;L;7B20;;;;N;;;;; +F9F9;CJK COMPATIBILITY IDEOGRAPH-F9F9;Lo;0;L;7C92;;;;N;;;;; +F9FA;CJK COMPATIBILITY IDEOGRAPH-F9FA;Lo;0;L;72C0;;;;N;;;;; +F9FB;CJK COMPATIBILITY IDEOGRAPH-F9FB;Lo;0;L;7099;;;;N;;;;; +F9FC;CJK COMPATIBILITY IDEOGRAPH-F9FC;Lo;0;L;8B58;;;;N;;;;; +F9FD;CJK COMPATIBILITY IDEOGRAPH-F9FD;Lo;0;L;4EC0;;;10;N;;;;; +F9FE;CJK COMPATIBILITY IDEOGRAPH-F9FE;Lo;0;L;8336;;;;N;;;;; +F9FF;CJK COMPATIBILITY IDEOGRAPH-F9FF;Lo;0;L;523A;;;;N;;;;; +FA00;CJK COMPATIBILITY IDEOGRAPH-FA00;Lo;0;L;5207;;;;N;;;;; +FA01;CJK COMPATIBILITY IDEOGRAPH-FA01;Lo;0;L;5EA6;;;;N;;;;; +FA02;CJK COMPATIBILITY IDEOGRAPH-FA02;Lo;0;L;62D3;;;;N;;;;; +FA03;CJK COMPATIBILITY IDEOGRAPH-FA03;Lo;0;L;7CD6;;;;N;;;;; +FA04;CJK COMPATIBILITY IDEOGRAPH-FA04;Lo;0;L;5B85;;;;N;;;;; +FA05;CJK COMPATIBILITY IDEOGRAPH-FA05;Lo;0;L;6D1E;;;;N;;;;; +FA06;CJK COMPATIBILITY IDEOGRAPH-FA06;Lo;0;L;66B4;;;;N;;;;; +FA07;CJK COMPATIBILITY IDEOGRAPH-FA07;Lo;0;L;8F3B;;;;N;;;;; +FA08;CJK COMPATIBILITY IDEOGRAPH-FA08;Lo;0;L;884C;;;;N;;;;; +FA09;CJK COMPATIBILITY IDEOGRAPH-FA09;Lo;0;L;964D;;;;N;;;;; +FA0A;CJK COMPATIBILITY IDEOGRAPH-FA0A;Lo;0;L;898B;;;;N;;;;; +FA0B;CJK COMPATIBILITY IDEOGRAPH-FA0B;Lo;0;L;5ED3;;;;N;;;;; +FA0C;CJK COMPATIBILITY IDEOGRAPH-FA0C;Lo;0;L;5140;;;;N;;;;; +FA0D;CJK COMPATIBILITY IDEOGRAPH-FA0D;Lo;0;L;55C0;;;;N;;;;; +FA0E;CJK COMPATIBILITY IDEOGRAPH-FA0E;Lo;0;L;;;;;N;;;;; +FA0F;CJK COMPATIBILITY IDEOGRAPH-FA0F;Lo;0;L;;;;;N;;;;; +FA10;CJK COMPATIBILITY IDEOGRAPH-FA10;Lo;0;L;585A;;;;N;;;;; +FA11;CJK COMPATIBILITY IDEOGRAPH-FA11;Lo;0;L;;;;;N;;;;; +FA12;CJK COMPATIBILITY IDEOGRAPH-FA12;Lo;0;L;6674;;;;N;;;;; +FA13;CJK COMPATIBILITY IDEOGRAPH-FA13;Lo;0;L;;;;;N;;;;; +FA14;CJK COMPATIBILITY IDEOGRAPH-FA14;Lo;0;L;;;;;N;;;;; +FA15;CJK COMPATIBILITY IDEOGRAPH-FA15;Lo;0;L;51DE;;;;N;;;;; +FA16;CJK COMPATIBILITY IDEOGRAPH-FA16;Lo;0;L;732A;;;;N;;;;; +FA17;CJK COMPATIBILITY IDEOGRAPH-FA17;Lo;0;L;76CA;;;;N;;;;; +FA18;CJK COMPATIBILITY IDEOGRAPH-FA18;Lo;0;L;793C;;;;N;;;;; +FA19;CJK COMPATIBILITY IDEOGRAPH-FA19;Lo;0;L;795E;;;;N;;;;; +FA1A;CJK COMPATIBILITY IDEOGRAPH-FA1A;Lo;0;L;7965;;;;N;;;;; +FA1B;CJK COMPATIBILITY IDEOGRAPH-FA1B;Lo;0;L;798F;;;;N;;;;; +FA1C;CJK COMPATIBILITY IDEOGRAPH-FA1C;Lo;0;L;9756;;;;N;;;;; +FA1D;CJK COMPATIBILITY IDEOGRAPH-FA1D;Lo;0;L;7CBE;;;;N;;;;; +FA1E;CJK COMPATIBILITY IDEOGRAPH-FA1E;Lo;0;L;7FBD;;;;N;;;;; +FA1F;CJK COMPATIBILITY IDEOGRAPH-FA1F;Lo;0;L;;;;;N;;;;; +FA20;CJK COMPATIBILITY IDEOGRAPH-FA20;Lo;0;L;8612;;;;N;;;;; +FA21;CJK COMPATIBILITY IDEOGRAPH-FA21;Lo;0;L;;;;;N;;;;; +FA22;CJK COMPATIBILITY IDEOGRAPH-FA22;Lo;0;L;8AF8;;;;N;;;;; +FA23;CJK COMPATIBILITY IDEOGRAPH-FA23;Lo;0;L;;;;;N;;;;; +FA24;CJK COMPATIBILITY IDEOGRAPH-FA24;Lo;0;L;;;;;N;;;;; +FA25;CJK COMPATIBILITY IDEOGRAPH-FA25;Lo;0;L;9038;;;;N;;;;; +FA26;CJK COMPATIBILITY IDEOGRAPH-FA26;Lo;0;L;90FD;;;;N;;;;; +FA27;CJK COMPATIBILITY IDEOGRAPH-FA27;Lo;0;L;;;;;N;;;;; +FA28;CJK COMPATIBILITY IDEOGRAPH-FA28;Lo;0;L;;;;;N;;;;; +FA29;CJK COMPATIBILITY IDEOGRAPH-FA29;Lo;0;L;;;;;N;;;;; +FA2A;CJK COMPATIBILITY IDEOGRAPH-FA2A;Lo;0;L;98EF;;;;N;;;;; +FA2B;CJK COMPATIBILITY IDEOGRAPH-FA2B;Lo;0;L;98FC;;;;N;;;;; +FA2C;CJK COMPATIBILITY IDEOGRAPH-FA2C;Lo;0;L;9928;;;;N;;;;; +FA2D;CJK COMPATIBILITY IDEOGRAPH-FA2D;Lo;0;L;9DB4;;;;N;;;;; +FA30;CJK COMPATIBILITY IDEOGRAPH-FA30;Lo;0;L;4FAE;;;;N;;;;; +FA31;CJK COMPATIBILITY IDEOGRAPH-FA31;Lo;0;L;50E7;;;;N;;;;; +FA32;CJK COMPATIBILITY IDEOGRAPH-FA32;Lo;0;L;514D;;;;N;;;;; +FA33;CJK COMPATIBILITY IDEOGRAPH-FA33;Lo;0;L;52C9;;;;N;;;;; +FA34;CJK COMPATIBILITY IDEOGRAPH-FA34;Lo;0;L;52E4;;;;N;;;;; +FA35;CJK COMPATIBILITY IDEOGRAPH-FA35;Lo;0;L;5351;;;;N;;;;; +FA36;CJK COMPATIBILITY IDEOGRAPH-FA36;Lo;0;L;559D;;;;N;;;;; +FA37;CJK COMPATIBILITY IDEOGRAPH-FA37;Lo;0;L;5606;;;;N;;;;; +FA38;CJK COMPATIBILITY IDEOGRAPH-FA38;Lo;0;L;5668;;;;N;;;;; +FA39;CJK COMPATIBILITY IDEOGRAPH-FA39;Lo;0;L;5840;;;;N;;;;; +FA3A;CJK COMPATIBILITY IDEOGRAPH-FA3A;Lo;0;L;58A8;;;;N;;;;; +FA3B;CJK COMPATIBILITY IDEOGRAPH-FA3B;Lo;0;L;5C64;;;;N;;;;; +FA3C;CJK COMPATIBILITY IDEOGRAPH-FA3C;Lo;0;L;5C6E;;;;N;;;;; +FA3D;CJK COMPATIBILITY IDEOGRAPH-FA3D;Lo;0;L;6094;;;;N;;;;; +FA3E;CJK COMPATIBILITY IDEOGRAPH-FA3E;Lo;0;L;6168;;;;N;;;;; +FA3F;CJK COMPATIBILITY IDEOGRAPH-FA3F;Lo;0;L;618E;;;;N;;;;; +FA40;CJK COMPATIBILITY IDEOGRAPH-FA40;Lo;0;L;61F2;;;;N;;;;; +FA41;CJK COMPATIBILITY IDEOGRAPH-FA41;Lo;0;L;654F;;;;N;;;;; +FA42;CJK COMPATIBILITY IDEOGRAPH-FA42;Lo;0;L;65E2;;;;N;;;;; +FA43;CJK COMPATIBILITY IDEOGRAPH-FA43;Lo;0;L;6691;;;;N;;;;; +FA44;CJK COMPATIBILITY IDEOGRAPH-FA44;Lo;0;L;6885;;;;N;;;;; +FA45;CJK COMPATIBILITY IDEOGRAPH-FA45;Lo;0;L;6D77;;;;N;;;;; +FA46;CJK COMPATIBILITY IDEOGRAPH-FA46;Lo;0;L;6E1A;;;;N;;;;; +FA47;CJK COMPATIBILITY IDEOGRAPH-FA47;Lo;0;L;6F22;;;;N;;;;; +FA48;CJK COMPATIBILITY IDEOGRAPH-FA48;Lo;0;L;716E;;;;N;;;;; +FA49;CJK COMPATIBILITY IDEOGRAPH-FA49;Lo;0;L;722B;;;;N;;;;; +FA4A;CJK COMPATIBILITY IDEOGRAPH-FA4A;Lo;0;L;7422;;;;N;;;;; +FA4B;CJK COMPATIBILITY IDEOGRAPH-FA4B;Lo;0;L;7891;;;;N;;;;; +FA4C;CJK COMPATIBILITY IDEOGRAPH-FA4C;Lo;0;L;793E;;;;N;;;;; +FA4D;CJK COMPATIBILITY IDEOGRAPH-FA4D;Lo;0;L;7949;;;;N;;;;; +FA4E;CJK COMPATIBILITY IDEOGRAPH-FA4E;Lo;0;L;7948;;;;N;;;;; +FA4F;CJK COMPATIBILITY IDEOGRAPH-FA4F;Lo;0;L;7950;;;;N;;;;; +FA50;CJK COMPATIBILITY IDEOGRAPH-FA50;Lo;0;L;7956;;;;N;;;;; +FA51;CJK COMPATIBILITY IDEOGRAPH-FA51;Lo;0;L;795D;;;;N;;;;; +FA52;CJK COMPATIBILITY IDEOGRAPH-FA52;Lo;0;L;798D;;;;N;;;;; +FA53;CJK COMPATIBILITY IDEOGRAPH-FA53;Lo;0;L;798E;;;;N;;;;; +FA54;CJK COMPATIBILITY IDEOGRAPH-FA54;Lo;0;L;7A40;;;;N;;;;; +FA55;CJK COMPATIBILITY IDEOGRAPH-FA55;Lo;0;L;7A81;;;;N;;;;; +FA56;CJK COMPATIBILITY IDEOGRAPH-FA56;Lo;0;L;7BC0;;;;N;;;;; +FA57;CJK COMPATIBILITY IDEOGRAPH-FA57;Lo;0;L;7DF4;;;;N;;;;; +FA58;CJK COMPATIBILITY IDEOGRAPH-FA58;Lo;0;L;7E09;;;;N;;;;; +FA59;CJK COMPATIBILITY IDEOGRAPH-FA59;Lo;0;L;7E41;;;;N;;;;; +FA5A;CJK COMPATIBILITY IDEOGRAPH-FA5A;Lo;0;L;7F72;;;;N;;;;; +FA5B;CJK COMPATIBILITY IDEOGRAPH-FA5B;Lo;0;L;8005;;;;N;;;;; +FA5C;CJK COMPATIBILITY IDEOGRAPH-FA5C;Lo;0;L;81ED;;;;N;;;;; +FA5D;CJK COMPATIBILITY IDEOGRAPH-FA5D;Lo;0;L;8279;;;;N;;;;; +FA5E;CJK COMPATIBILITY IDEOGRAPH-FA5E;Lo;0;L;8279;;;;N;;;;; +FA5F;CJK COMPATIBILITY IDEOGRAPH-FA5F;Lo;0;L;8457;;;;N;;;;; +FA60;CJK COMPATIBILITY IDEOGRAPH-FA60;Lo;0;L;8910;;;;N;;;;; +FA61;CJK COMPATIBILITY IDEOGRAPH-FA61;Lo;0;L;8996;;;;N;;;;; +FA62;CJK COMPATIBILITY IDEOGRAPH-FA62;Lo;0;L;8B01;;;;N;;;;; +FA63;CJK COMPATIBILITY IDEOGRAPH-FA63;Lo;0;L;8B39;;;;N;;;;; +FA64;CJK COMPATIBILITY IDEOGRAPH-FA64;Lo;0;L;8CD3;;;;N;;;;; +FA65;CJK COMPATIBILITY IDEOGRAPH-FA65;Lo;0;L;8D08;;;;N;;;;; +FA66;CJK COMPATIBILITY IDEOGRAPH-FA66;Lo;0;L;8FB6;;;;N;;;;; +FA67;CJK COMPATIBILITY IDEOGRAPH-FA67;Lo;0;L;9038;;;;N;;;;; +FA68;CJK COMPATIBILITY IDEOGRAPH-FA68;Lo;0;L;96E3;;;;N;;;;; +FA69;CJK COMPATIBILITY IDEOGRAPH-FA69;Lo;0;L;97FF;;;;N;;;;; +FA6A;CJK COMPATIBILITY IDEOGRAPH-FA6A;Lo;0;L;983B;;;;N;;;;; +FA6B;CJK COMPATIBILITY IDEOGRAPH-FA6B;Lo;0;L;6075;;;;N;;;;; +FA6C;CJK COMPATIBILITY IDEOGRAPH-FA6C;Lo;0;L;242EE;;;;N;;;;; +FA6D;CJK COMPATIBILITY IDEOGRAPH-FA6D;Lo;0;L;8218;;;;N;;;;; +FA70;CJK COMPATIBILITY IDEOGRAPH-FA70;Lo;0;L;4E26;;;;N;;;;; +FA71;CJK COMPATIBILITY IDEOGRAPH-FA71;Lo;0;L;51B5;;;;N;;;;; +FA72;CJK COMPATIBILITY IDEOGRAPH-FA72;Lo;0;L;5168;;;;N;;;;; +FA73;CJK COMPATIBILITY IDEOGRAPH-FA73;Lo;0;L;4F80;;;;N;;;;; +FA74;CJK COMPATIBILITY IDEOGRAPH-FA74;Lo;0;L;5145;;;;N;;;;; +FA75;CJK COMPATIBILITY IDEOGRAPH-FA75;Lo;0;L;5180;;;;N;;;;; +FA76;CJK COMPATIBILITY IDEOGRAPH-FA76;Lo;0;L;52C7;;;;N;;;;; +FA77;CJK COMPATIBILITY IDEOGRAPH-FA77;Lo;0;L;52FA;;;;N;;;;; +FA78;CJK COMPATIBILITY IDEOGRAPH-FA78;Lo;0;L;559D;;;;N;;;;; +FA79;CJK COMPATIBILITY IDEOGRAPH-FA79;Lo;0;L;5555;;;;N;;;;; +FA7A;CJK COMPATIBILITY IDEOGRAPH-FA7A;Lo;0;L;5599;;;;N;;;;; +FA7B;CJK COMPATIBILITY IDEOGRAPH-FA7B;Lo;0;L;55E2;;;;N;;;;; +FA7C;CJK COMPATIBILITY IDEOGRAPH-FA7C;Lo;0;L;585A;;;;N;;;;; +FA7D;CJK COMPATIBILITY IDEOGRAPH-FA7D;Lo;0;L;58B3;;;;N;;;;; +FA7E;CJK COMPATIBILITY IDEOGRAPH-FA7E;Lo;0;L;5944;;;;N;;;;; +FA7F;CJK COMPATIBILITY IDEOGRAPH-FA7F;Lo;0;L;5954;;;;N;;;;; +FA80;CJK COMPATIBILITY IDEOGRAPH-FA80;Lo;0;L;5A62;;;;N;;;;; +FA81;CJK COMPATIBILITY IDEOGRAPH-FA81;Lo;0;L;5B28;;;;N;;;;; +FA82;CJK COMPATIBILITY IDEOGRAPH-FA82;Lo;0;L;5ED2;;;;N;;;;; +FA83;CJK COMPATIBILITY IDEOGRAPH-FA83;Lo;0;L;5ED9;;;;N;;;;; +FA84;CJK COMPATIBILITY IDEOGRAPH-FA84;Lo;0;L;5F69;;;;N;;;;; +FA85;CJK COMPATIBILITY IDEOGRAPH-FA85;Lo;0;L;5FAD;;;;N;;;;; +FA86;CJK COMPATIBILITY IDEOGRAPH-FA86;Lo;0;L;60D8;;;;N;;;;; +FA87;CJK COMPATIBILITY IDEOGRAPH-FA87;Lo;0;L;614E;;;;N;;;;; +FA88;CJK COMPATIBILITY IDEOGRAPH-FA88;Lo;0;L;6108;;;;N;;;;; +FA89;CJK COMPATIBILITY IDEOGRAPH-FA89;Lo;0;L;618E;;;;N;;;;; +FA8A;CJK COMPATIBILITY IDEOGRAPH-FA8A;Lo;0;L;6160;;;;N;;;;; +FA8B;CJK COMPATIBILITY IDEOGRAPH-FA8B;Lo;0;L;61F2;;;;N;;;;; +FA8C;CJK COMPATIBILITY IDEOGRAPH-FA8C;Lo;0;L;6234;;;;N;;;;; +FA8D;CJK COMPATIBILITY IDEOGRAPH-FA8D;Lo;0;L;63C4;;;;N;;;;; +FA8E;CJK COMPATIBILITY IDEOGRAPH-FA8E;Lo;0;L;641C;;;;N;;;;; +FA8F;CJK COMPATIBILITY IDEOGRAPH-FA8F;Lo;0;L;6452;;;;N;;;;; +FA90;CJK COMPATIBILITY IDEOGRAPH-FA90;Lo;0;L;6556;;;;N;;;;; +FA91;CJK COMPATIBILITY IDEOGRAPH-FA91;Lo;0;L;6674;;;;N;;;;; +FA92;CJK COMPATIBILITY IDEOGRAPH-FA92;Lo;0;L;6717;;;;N;;;;; +FA93;CJK COMPATIBILITY IDEOGRAPH-FA93;Lo;0;L;671B;;;;N;;;;; +FA94;CJK COMPATIBILITY IDEOGRAPH-FA94;Lo;0;L;6756;;;;N;;;;; +FA95;CJK COMPATIBILITY IDEOGRAPH-FA95;Lo;0;L;6B79;;;;N;;;;; +FA96;CJK COMPATIBILITY IDEOGRAPH-FA96;Lo;0;L;6BBA;;;;N;;;;; +FA97;CJK COMPATIBILITY IDEOGRAPH-FA97;Lo;0;L;6D41;;;;N;;;;; +FA98;CJK COMPATIBILITY IDEOGRAPH-FA98;Lo;0;L;6EDB;;;;N;;;;; +FA99;CJK COMPATIBILITY IDEOGRAPH-FA99;Lo;0;L;6ECB;;;;N;;;;; +FA9A;CJK COMPATIBILITY IDEOGRAPH-FA9A;Lo;0;L;6F22;;;;N;;;;; +FA9B;CJK COMPATIBILITY IDEOGRAPH-FA9B;Lo;0;L;701E;;;;N;;;;; +FA9C;CJK COMPATIBILITY IDEOGRAPH-FA9C;Lo;0;L;716E;;;;N;;;;; +FA9D;CJK COMPATIBILITY IDEOGRAPH-FA9D;Lo;0;L;77A7;;;;N;;;;; +FA9E;CJK COMPATIBILITY IDEOGRAPH-FA9E;Lo;0;L;7235;;;;N;;;;; +FA9F;CJK COMPATIBILITY IDEOGRAPH-FA9F;Lo;0;L;72AF;;;;N;;;;; +FAA0;CJK COMPATIBILITY IDEOGRAPH-FAA0;Lo;0;L;732A;;;;N;;;;; +FAA1;CJK COMPATIBILITY IDEOGRAPH-FAA1;Lo;0;L;7471;;;;N;;;;; +FAA2;CJK COMPATIBILITY IDEOGRAPH-FAA2;Lo;0;L;7506;;;;N;;;;; +FAA3;CJK COMPATIBILITY IDEOGRAPH-FAA3;Lo;0;L;753B;;;;N;;;;; +FAA4;CJK COMPATIBILITY IDEOGRAPH-FAA4;Lo;0;L;761D;;;;N;;;;; +FAA5;CJK COMPATIBILITY IDEOGRAPH-FAA5;Lo;0;L;761F;;;;N;;;;; +FAA6;CJK COMPATIBILITY IDEOGRAPH-FAA6;Lo;0;L;76CA;;;;N;;;;; +FAA7;CJK COMPATIBILITY IDEOGRAPH-FAA7;Lo;0;L;76DB;;;;N;;;;; +FAA8;CJK COMPATIBILITY IDEOGRAPH-FAA8;Lo;0;L;76F4;;;;N;;;;; +FAA9;CJK COMPATIBILITY IDEOGRAPH-FAA9;Lo;0;L;774A;;;;N;;;;; +FAAA;CJK COMPATIBILITY IDEOGRAPH-FAAA;Lo;0;L;7740;;;;N;;;;; +FAAB;CJK COMPATIBILITY IDEOGRAPH-FAAB;Lo;0;L;78CC;;;;N;;;;; +FAAC;CJK COMPATIBILITY IDEOGRAPH-FAAC;Lo;0;L;7AB1;;;;N;;;;; +FAAD;CJK COMPATIBILITY IDEOGRAPH-FAAD;Lo;0;L;7BC0;;;;N;;;;; +FAAE;CJK COMPATIBILITY IDEOGRAPH-FAAE;Lo;0;L;7C7B;;;;N;;;;; +FAAF;CJK COMPATIBILITY IDEOGRAPH-FAAF;Lo;0;L;7D5B;;;;N;;;;; +FAB0;CJK COMPATIBILITY IDEOGRAPH-FAB0;Lo;0;L;7DF4;;;;N;;;;; +FAB1;CJK COMPATIBILITY IDEOGRAPH-FAB1;Lo;0;L;7F3E;;;;N;;;;; +FAB2;CJK COMPATIBILITY IDEOGRAPH-FAB2;Lo;0;L;8005;;;;N;;;;; +FAB3;CJK COMPATIBILITY IDEOGRAPH-FAB3;Lo;0;L;8352;;;;N;;;;; +FAB4;CJK COMPATIBILITY IDEOGRAPH-FAB4;Lo;0;L;83EF;;;;N;;;;; +FAB5;CJK COMPATIBILITY IDEOGRAPH-FAB5;Lo;0;L;8779;;;;N;;;;; +FAB6;CJK COMPATIBILITY IDEOGRAPH-FAB6;Lo;0;L;8941;;;;N;;;;; +FAB7;CJK COMPATIBILITY IDEOGRAPH-FAB7;Lo;0;L;8986;;;;N;;;;; +FAB8;CJK COMPATIBILITY IDEOGRAPH-FAB8;Lo;0;L;8996;;;;N;;;;; +FAB9;CJK COMPATIBILITY IDEOGRAPH-FAB9;Lo;0;L;8ABF;;;;N;;;;; +FABA;CJK COMPATIBILITY IDEOGRAPH-FABA;Lo;0;L;8AF8;;;;N;;;;; +FABB;CJK COMPATIBILITY IDEOGRAPH-FABB;Lo;0;L;8ACB;;;;N;;;;; +FABC;CJK COMPATIBILITY IDEOGRAPH-FABC;Lo;0;L;8B01;;;;N;;;;; +FABD;CJK COMPATIBILITY IDEOGRAPH-FABD;Lo;0;L;8AFE;;;;N;;;;; +FABE;CJK COMPATIBILITY IDEOGRAPH-FABE;Lo;0;L;8AED;;;;N;;;;; +FABF;CJK COMPATIBILITY IDEOGRAPH-FABF;Lo;0;L;8B39;;;;N;;;;; +FAC0;CJK COMPATIBILITY IDEOGRAPH-FAC0;Lo;0;L;8B8A;;;;N;;;;; +FAC1;CJK COMPATIBILITY IDEOGRAPH-FAC1;Lo;0;L;8D08;;;;N;;;;; +FAC2;CJK COMPATIBILITY IDEOGRAPH-FAC2;Lo;0;L;8F38;;;;N;;;;; +FAC3;CJK COMPATIBILITY IDEOGRAPH-FAC3;Lo;0;L;9072;;;;N;;;;; +FAC4;CJK COMPATIBILITY IDEOGRAPH-FAC4;Lo;0;L;9199;;;;N;;;;; +FAC5;CJK COMPATIBILITY IDEOGRAPH-FAC5;Lo;0;L;9276;;;;N;;;;; +FAC6;CJK COMPATIBILITY IDEOGRAPH-FAC6;Lo;0;L;967C;;;;N;;;;; +FAC7;CJK COMPATIBILITY IDEOGRAPH-FAC7;Lo;0;L;96E3;;;;N;;;;; +FAC8;CJK COMPATIBILITY IDEOGRAPH-FAC8;Lo;0;L;9756;;;;N;;;;; +FAC9;CJK COMPATIBILITY IDEOGRAPH-FAC9;Lo;0;L;97DB;;;;N;;;;; +FACA;CJK COMPATIBILITY IDEOGRAPH-FACA;Lo;0;L;97FF;;;;N;;;;; +FACB;CJK COMPATIBILITY IDEOGRAPH-FACB;Lo;0;L;980B;;;;N;;;;; +FACC;CJK COMPATIBILITY IDEOGRAPH-FACC;Lo;0;L;983B;;;;N;;;;; +FACD;CJK COMPATIBILITY IDEOGRAPH-FACD;Lo;0;L;9B12;;;;N;;;;; +FACE;CJK COMPATIBILITY IDEOGRAPH-FACE;Lo;0;L;9F9C;;;;N;;;;; +FACF;CJK COMPATIBILITY IDEOGRAPH-FACF;Lo;0;L;2284A;;;;N;;;;; +FAD0;CJK COMPATIBILITY IDEOGRAPH-FAD0;Lo;0;L;22844;;;;N;;;;; +FAD1;CJK COMPATIBILITY IDEOGRAPH-FAD1;Lo;0;L;233D5;;;;N;;;;; +FAD2;CJK COMPATIBILITY IDEOGRAPH-FAD2;Lo;0;L;3B9D;;;;N;;;;; +FAD3;CJK COMPATIBILITY IDEOGRAPH-FAD3;Lo;0;L;4018;;;;N;;;;; +FAD4;CJK COMPATIBILITY IDEOGRAPH-FAD4;Lo;0;L;4039;;;;N;;;;; +FAD5;CJK COMPATIBILITY IDEOGRAPH-FAD5;Lo;0;L;25249;;;;N;;;;; +FAD6;CJK COMPATIBILITY IDEOGRAPH-FAD6;Lo;0;L;25CD0;;;;N;;;;; +FAD7;CJK COMPATIBILITY IDEOGRAPH-FAD7;Lo;0;L;27ED3;;;;N;;;;; +FAD8;CJK COMPATIBILITY IDEOGRAPH-FAD8;Lo;0;L;9F43;;;;N;;;;; +FAD9;CJK COMPATIBILITY IDEOGRAPH-FAD9;Lo;0;L;9F8E;;;;N;;;;; +FB00;LATIN SMALL LIGATURE FF;Ll;0;L; 0066 0066;;;;N;;;;; +FB01;LATIN SMALL LIGATURE FI;Ll;0;L; 0066 0069;;;;N;;;;; +FB02;LATIN SMALL LIGATURE FL;Ll;0;L; 0066 006C;;;;N;;;;; +FB03;LATIN SMALL LIGATURE FFI;Ll;0;L; 0066 0066 0069;;;;N;;;;; +FB04;LATIN SMALL LIGATURE FFL;Ll;0;L; 0066 0066 006C;;;;N;;;;; +FB05;LATIN SMALL LIGATURE LONG S T;Ll;0;L; 017F 0074;;;;N;;;;; +FB06;LATIN SMALL LIGATURE ST;Ll;0;L; 0073 0074;;;;N;;;;; +FB13;ARMENIAN SMALL LIGATURE MEN NOW;Ll;0;L; 0574 0576;;;;N;;;;; +FB14;ARMENIAN SMALL LIGATURE MEN ECH;Ll;0;L; 0574 0565;;;;N;;;;; +FB15;ARMENIAN SMALL LIGATURE MEN INI;Ll;0;L; 0574 056B;;;;N;;;;; +FB16;ARMENIAN SMALL LIGATURE VEW NOW;Ll;0;L; 057E 0576;;;;N;;;;; +FB17;ARMENIAN SMALL LIGATURE MEN XEH;Ll;0;L; 0574 056D;;;;N;;;;; +FB1D;HEBREW LETTER YOD WITH HIRIQ;Lo;0;R;05D9 05B4;;;;N;;;;; +FB1E;HEBREW POINT JUDEO-SPANISH VARIKA;Mn;26;NSM;;;;;N;HEBREW POINT VARIKA;;;; +FB1F;HEBREW LIGATURE YIDDISH YOD YOD PATAH;Lo;0;R;05F2 05B7;;;;N;;;;; +FB20;HEBREW LETTER ALTERNATIVE AYIN;Lo;0;R; 05E2;;;;N;;;;; +FB21;HEBREW LETTER WIDE ALEF;Lo;0;R; 05D0;;;;N;;;;; +FB22;HEBREW LETTER WIDE DALET;Lo;0;R; 05D3;;;;N;;;;; +FB23;HEBREW LETTER WIDE HE;Lo;0;R; 05D4;;;;N;;;;; +FB24;HEBREW LETTER WIDE KAF;Lo;0;R; 05DB;;;;N;;;;; +FB25;HEBREW LETTER WIDE LAMED;Lo;0;R; 05DC;;;;N;;;;; +FB26;HEBREW LETTER WIDE FINAL MEM;Lo;0;R; 05DD;;;;N;;;;; +FB27;HEBREW LETTER WIDE RESH;Lo;0;R; 05E8;;;;N;;;;; +FB28;HEBREW LETTER WIDE TAV;Lo;0;R; 05EA;;;;N;;;;; +FB29;HEBREW LETTER ALTERNATIVE PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +FB2A;HEBREW LETTER SHIN WITH SHIN DOT;Lo;0;R;05E9 05C1;;;;N;;;;; +FB2B;HEBREW LETTER SHIN WITH SIN DOT;Lo;0;R;05E9 05C2;;;;N;;;;; +FB2C;HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT;Lo;0;R;FB49 05C1;;;;N;;;;; +FB2D;HEBREW LETTER SHIN WITH DAGESH AND SIN DOT;Lo;0;R;FB49 05C2;;;;N;;;;; +FB2E;HEBREW LETTER ALEF WITH PATAH;Lo;0;R;05D0 05B7;;;;N;;;;; +FB2F;HEBREW LETTER ALEF WITH QAMATS;Lo;0;R;05D0 05B8;;;;N;;;;; +FB30;HEBREW LETTER ALEF WITH MAPIQ;Lo;0;R;05D0 05BC;;;;N;;;;; +FB31;HEBREW LETTER BET WITH DAGESH;Lo;0;R;05D1 05BC;;;;N;;;;; +FB32;HEBREW LETTER GIMEL WITH DAGESH;Lo;0;R;05D2 05BC;;;;N;;;;; +FB33;HEBREW LETTER DALET WITH DAGESH;Lo;0;R;05D3 05BC;;;;N;;;;; +FB34;HEBREW LETTER HE WITH MAPIQ;Lo;0;R;05D4 05BC;;;;N;;;;; +FB35;HEBREW LETTER VAV WITH DAGESH;Lo;0;R;05D5 05BC;;;;N;;;;; +FB36;HEBREW LETTER ZAYIN WITH DAGESH;Lo;0;R;05D6 05BC;;;;N;;;;; +FB38;HEBREW LETTER TET WITH DAGESH;Lo;0;R;05D8 05BC;;;;N;;;;; +FB39;HEBREW LETTER YOD WITH DAGESH;Lo;0;R;05D9 05BC;;;;N;;;;; +FB3A;HEBREW LETTER FINAL KAF WITH DAGESH;Lo;0;R;05DA 05BC;;;;N;;;;; +FB3B;HEBREW LETTER KAF WITH DAGESH;Lo;0;R;05DB 05BC;;;;N;;;;; +FB3C;HEBREW LETTER LAMED WITH DAGESH;Lo;0;R;05DC 05BC;;;;N;;;;; +FB3E;HEBREW LETTER MEM WITH DAGESH;Lo;0;R;05DE 05BC;;;;N;;;;; +FB40;HEBREW LETTER NUN WITH DAGESH;Lo;0;R;05E0 05BC;;;;N;;;;; +FB41;HEBREW LETTER SAMEKH WITH DAGESH;Lo;0;R;05E1 05BC;;;;N;;;;; +FB43;HEBREW LETTER FINAL PE WITH DAGESH;Lo;0;R;05E3 05BC;;;;N;;;;; +FB44;HEBREW LETTER PE WITH DAGESH;Lo;0;R;05E4 05BC;;;;N;;;;; +FB46;HEBREW LETTER TSADI WITH DAGESH;Lo;0;R;05E6 05BC;;;;N;;;;; +FB47;HEBREW LETTER QOF WITH DAGESH;Lo;0;R;05E7 05BC;;;;N;;;;; +FB48;HEBREW LETTER RESH WITH DAGESH;Lo;0;R;05E8 05BC;;;;N;;;;; +FB49;HEBREW LETTER SHIN WITH DAGESH;Lo;0;R;05E9 05BC;;;;N;;;;; +FB4A;HEBREW LETTER TAV WITH DAGESH;Lo;0;R;05EA 05BC;;;;N;;;;; +FB4B;HEBREW LETTER VAV WITH HOLAM;Lo;0;R;05D5 05B9;;;;N;;;;; +FB4C;HEBREW LETTER BET WITH RAFE;Lo;0;R;05D1 05BF;;;;N;;;;; +FB4D;HEBREW LETTER KAF WITH RAFE;Lo;0;R;05DB 05BF;;;;N;;;;; +FB4E;HEBREW LETTER PE WITH RAFE;Lo;0;R;05E4 05BF;;;;N;;;;; +FB4F;HEBREW LIGATURE ALEF LAMED;Lo;0;R; 05D0 05DC;;;;N;;;;; +FB50;ARABIC LETTER ALEF WASLA ISOLATED FORM;Lo;0;AL; 0671;;;;N;;;;; +FB51;ARABIC LETTER ALEF WASLA FINAL FORM;Lo;0;AL; 0671;;;;N;;;;; +FB52;ARABIC LETTER BEEH ISOLATED FORM;Lo;0;AL; 067B;;;;N;;;;; +FB53;ARABIC LETTER BEEH FINAL FORM;Lo;0;AL; 067B;;;;N;;;;; +FB54;ARABIC LETTER BEEH INITIAL FORM;Lo;0;AL; 067B;;;;N;;;;; +FB55;ARABIC LETTER BEEH MEDIAL FORM;Lo;0;AL; 067B;;;;N;;;;; +FB56;ARABIC LETTER PEH ISOLATED FORM;Lo;0;AL; 067E;;;;N;;;;; +FB57;ARABIC LETTER PEH FINAL FORM;Lo;0;AL; 067E;;;;N;;;;; +FB58;ARABIC LETTER PEH INITIAL FORM;Lo;0;AL; 067E;;;;N;;;;; +FB59;ARABIC LETTER PEH MEDIAL FORM;Lo;0;AL; 067E;;;;N;;;;; +FB5A;ARABIC LETTER BEHEH ISOLATED FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5B;ARABIC LETTER BEHEH FINAL FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5C;ARABIC LETTER BEHEH INITIAL FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5D;ARABIC LETTER BEHEH MEDIAL FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5E;ARABIC LETTER TTEHEH ISOLATED FORM;Lo;0;AL; 067A;;;;N;;;;; +FB5F;ARABIC LETTER TTEHEH FINAL FORM;Lo;0;AL; 067A;;;;N;;;;; +FB60;ARABIC LETTER TTEHEH INITIAL FORM;Lo;0;AL; 067A;;;;N;;;;; +FB61;ARABIC LETTER TTEHEH MEDIAL FORM;Lo;0;AL; 067A;;;;N;;;;; +FB62;ARABIC LETTER TEHEH ISOLATED FORM;Lo;0;AL; 067F;;;;N;;;;; +FB63;ARABIC LETTER TEHEH FINAL FORM;Lo;0;AL; 067F;;;;N;;;;; +FB64;ARABIC LETTER TEHEH INITIAL FORM;Lo;0;AL; 067F;;;;N;;;;; +FB65;ARABIC LETTER TEHEH MEDIAL FORM;Lo;0;AL; 067F;;;;N;;;;; +FB66;ARABIC LETTER TTEH ISOLATED FORM;Lo;0;AL; 0679;;;;N;;;;; +FB67;ARABIC LETTER TTEH FINAL FORM;Lo;0;AL; 0679;;;;N;;;;; +FB68;ARABIC LETTER TTEH INITIAL FORM;Lo;0;AL; 0679;;;;N;;;;; +FB69;ARABIC LETTER TTEH MEDIAL FORM;Lo;0;AL; 0679;;;;N;;;;; +FB6A;ARABIC LETTER VEH ISOLATED FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6B;ARABIC LETTER VEH FINAL FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6C;ARABIC LETTER VEH INITIAL FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6D;ARABIC LETTER VEH MEDIAL FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6E;ARABIC LETTER PEHEH ISOLATED FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB6F;ARABIC LETTER PEHEH FINAL FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB70;ARABIC LETTER PEHEH INITIAL FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB71;ARABIC LETTER PEHEH MEDIAL FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB72;ARABIC LETTER DYEH ISOLATED FORM;Lo;0;AL; 0684;;;;N;;;;; +FB73;ARABIC LETTER DYEH FINAL FORM;Lo;0;AL; 0684;;;;N;;;;; +FB74;ARABIC LETTER DYEH INITIAL FORM;Lo;0;AL; 0684;;;;N;;;;; +FB75;ARABIC LETTER DYEH MEDIAL FORM;Lo;0;AL; 0684;;;;N;;;;; +FB76;ARABIC LETTER NYEH ISOLATED FORM;Lo;0;AL; 0683;;;;N;;;;; +FB77;ARABIC LETTER NYEH FINAL FORM;Lo;0;AL; 0683;;;;N;;;;; +FB78;ARABIC LETTER NYEH INITIAL FORM;Lo;0;AL; 0683;;;;N;;;;; +FB79;ARABIC LETTER NYEH MEDIAL FORM;Lo;0;AL; 0683;;;;N;;;;; +FB7A;ARABIC LETTER TCHEH ISOLATED FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7B;ARABIC LETTER TCHEH FINAL FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7C;ARABIC LETTER TCHEH INITIAL FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7D;ARABIC LETTER TCHEH MEDIAL FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7E;ARABIC LETTER TCHEHEH ISOLATED FORM;Lo;0;AL; 0687;;;;N;;;;; +FB7F;ARABIC LETTER TCHEHEH FINAL FORM;Lo;0;AL; 0687;;;;N;;;;; +FB80;ARABIC LETTER TCHEHEH INITIAL FORM;Lo;0;AL; 0687;;;;N;;;;; +FB81;ARABIC LETTER TCHEHEH MEDIAL FORM;Lo;0;AL; 0687;;;;N;;;;; +FB82;ARABIC LETTER DDAHAL ISOLATED FORM;Lo;0;AL; 068D;;;;N;;;;; +FB83;ARABIC LETTER DDAHAL FINAL FORM;Lo;0;AL; 068D;;;;N;;;;; +FB84;ARABIC LETTER DAHAL ISOLATED FORM;Lo;0;AL; 068C;;;;N;;;;; +FB85;ARABIC LETTER DAHAL FINAL FORM;Lo;0;AL; 068C;;;;N;;;;; +FB86;ARABIC LETTER DUL ISOLATED FORM;Lo;0;AL; 068E;;;;N;;;;; +FB87;ARABIC LETTER DUL FINAL FORM;Lo;0;AL; 068E;;;;N;;;;; +FB88;ARABIC LETTER DDAL ISOLATED FORM;Lo;0;AL; 0688;;;;N;;;;; +FB89;ARABIC LETTER DDAL FINAL FORM;Lo;0;AL; 0688;;;;N;;;;; +FB8A;ARABIC LETTER JEH ISOLATED FORM;Lo;0;AL; 0698;;;;N;;;;; +FB8B;ARABIC LETTER JEH FINAL FORM;Lo;0;AL; 0698;;;;N;;;;; +FB8C;ARABIC LETTER RREH ISOLATED FORM;Lo;0;AL; 0691;;;;N;;;;; +FB8D;ARABIC LETTER RREH FINAL FORM;Lo;0;AL; 0691;;;;N;;;;; +FB8E;ARABIC LETTER KEHEH ISOLATED FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB8F;ARABIC LETTER KEHEH FINAL FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB90;ARABIC LETTER KEHEH INITIAL FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB91;ARABIC LETTER KEHEH MEDIAL FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB92;ARABIC LETTER GAF ISOLATED FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB93;ARABIC LETTER GAF FINAL FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB94;ARABIC LETTER GAF INITIAL FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB95;ARABIC LETTER GAF MEDIAL FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB96;ARABIC LETTER GUEH ISOLATED FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB97;ARABIC LETTER GUEH FINAL FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB98;ARABIC LETTER GUEH INITIAL FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB99;ARABIC LETTER GUEH MEDIAL FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB9A;ARABIC LETTER NGOEH ISOLATED FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9B;ARABIC LETTER NGOEH FINAL FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9C;ARABIC LETTER NGOEH INITIAL FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9D;ARABIC LETTER NGOEH MEDIAL FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9E;ARABIC LETTER NOON GHUNNA ISOLATED FORM;Lo;0;AL; 06BA;;;;N;;;;; +FB9F;ARABIC LETTER NOON GHUNNA FINAL FORM;Lo;0;AL; 06BA;;;;N;;;;; +FBA0;ARABIC LETTER RNOON ISOLATED FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA1;ARABIC LETTER RNOON FINAL FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA2;ARABIC LETTER RNOON INITIAL FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA3;ARABIC LETTER RNOON MEDIAL FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA4;ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM;Lo;0;AL; 06C0;;;;N;;;;; +FBA5;ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM;Lo;0;AL; 06C0;;;;N;;;;; +FBA6;ARABIC LETTER HEH GOAL ISOLATED FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBA7;ARABIC LETTER HEH GOAL FINAL FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBA8;ARABIC LETTER HEH GOAL INITIAL FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBA9;ARABIC LETTER HEH GOAL MEDIAL FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBAA;ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAB;ARABIC LETTER HEH DOACHASHMEE FINAL FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAC;ARABIC LETTER HEH DOACHASHMEE INITIAL FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAD;ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAE;ARABIC LETTER YEH BARREE ISOLATED FORM;Lo;0;AL; 06D2;;;;N;;;;; +FBAF;ARABIC LETTER YEH BARREE FINAL FORM;Lo;0;AL; 06D2;;;;N;;;;; +FBB0;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 06D3;;;;N;;;;; +FBB1;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 06D3;;;;N;;;;; +FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD6;ARABIC LETTER NG MEDIAL FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD7;ARABIC LETTER U ISOLATED FORM;Lo;0;AL; 06C7;;;;N;;;;; +FBD8;ARABIC LETTER U FINAL FORM;Lo;0;AL; 06C7;;;;N;;;;; +FBD9;ARABIC LETTER OE ISOLATED FORM;Lo;0;AL; 06C6;;;;N;;;;; +FBDA;ARABIC LETTER OE FINAL FORM;Lo;0;AL; 06C6;;;;N;;;;; +FBDB;ARABIC LETTER YU ISOLATED FORM;Lo;0;AL; 06C8;;;;N;;;;; +FBDC;ARABIC LETTER YU FINAL FORM;Lo;0;AL; 06C8;;;;N;;;;; +FBDD;ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0677;;;;N;;;;; +FBDE;ARABIC LETTER VE ISOLATED FORM;Lo;0;AL; 06CB;;;;N;;;;; +FBDF;ARABIC LETTER VE FINAL FORM;Lo;0;AL; 06CB;;;;N;;;;; +FBE0;ARABIC LETTER KIRGHIZ OE ISOLATED FORM;Lo;0;AL; 06C5;;;;N;;;;; +FBE1;ARABIC LETTER KIRGHIZ OE FINAL FORM;Lo;0;AL; 06C5;;;;N;;;;; +FBE2;ARABIC LETTER KIRGHIZ YU ISOLATED FORM;Lo;0;AL; 06C9;;;;N;;;;; +FBE3;ARABIC LETTER KIRGHIZ YU FINAL FORM;Lo;0;AL; 06C9;;;;N;;;;; +FBE4;ARABIC LETTER E ISOLATED FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE5;ARABIC LETTER E FINAL FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE6;ARABIC LETTER E INITIAL FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE7;ARABIC LETTER E MEDIAL FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE8;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM;Lo;0;AL; 0649;;;;N;;;;; +FBE9;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM;Lo;0;AL; 0649;;;;N;;;;; +FBEA;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM;Lo;0;AL; 0626 0627;;;;N;;;;; +FBEB;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM;Lo;0;AL; 0626 0627;;;;N;;;;; +FBEC;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM;Lo;0;AL; 0626 06D5;;;;N;;;;; +FBED;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM;Lo;0;AL; 0626 06D5;;;;N;;;;; +FBEE;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM;Lo;0;AL; 0626 0648;;;;N;;;;; +FBEF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM;Lo;0;AL; 0626 0648;;;;N;;;;; +FBF0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM;Lo;0;AL; 0626 06C7;;;;N;;;;; +FBF1;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM;Lo;0;AL; 0626 06C7;;;;N;;;;; +FBF2;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM;Lo;0;AL; 0626 06C6;;;;N;;;;; +FBF3;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM;Lo;0;AL; 0626 06C6;;;;N;;;;; +FBF4;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM;Lo;0;AL; 0626 06C8;;;;N;;;;; +FBF5;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM;Lo;0;AL; 0626 06C8;;;;N;;;;; +FBF6;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; +FBF7;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; +FBF8;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; +FBF9;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FBFA;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FBFB;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FBFC;ARABIC LETTER FARSI YEH ISOLATED FORM;Lo;0;AL; 06CC;;;;N;;;;; +FBFD;ARABIC LETTER FARSI YEH FINAL FORM;Lo;0;AL; 06CC;;;;N;;;;; +FBFE;ARABIC LETTER FARSI YEH INITIAL FORM;Lo;0;AL; 06CC;;;;N;;;;; +FBFF;ARABIC LETTER FARSI YEH MEDIAL FORM;Lo;0;AL; 06CC;;;;N;;;;; +FC00;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM;Lo;0;AL; 0626 062C;;;;N;;;;; +FC01;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM;Lo;0;AL; 0626 062D;;;;N;;;;; +FC02;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FC03;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FC04;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM;Lo;0;AL; 0626 064A;;;;N;;;;; +FC05;ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0628 062C;;;;N;;;;; +FC06;ARABIC LIGATURE BEH WITH HAH ISOLATED FORM;Lo;0;AL; 0628 062D;;;;N;;;;; +FC07;ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM;Lo;0;AL; 0628 062E;;;;N;;;;; +FC08;ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FC09;ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0628 0649;;;;N;;;;; +FC0A;ARABIC LIGATURE BEH WITH YEH ISOLATED FORM;Lo;0;AL; 0628 064A;;;;N;;;;; +FC0B;ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM;Lo;0;AL; 062A 062C;;;;N;;;;; +FC0C;ARABIC LIGATURE TEH WITH HAH ISOLATED FORM;Lo;0;AL; 062A 062D;;;;N;;;;; +FC0D;ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM;Lo;0;AL; 062A 062E;;;;N;;;;; +FC0E;ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FC0F;ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062A 0649;;;;N;;;;; +FC10;ARABIC LIGATURE TEH WITH YEH ISOLATED FORM;Lo;0;AL; 062A 064A;;;;N;;;;; +FC11;ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM;Lo;0;AL; 062B 062C;;;;N;;;;; +FC12;ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FC13;ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062B 0649;;;;N;;;;; +FC14;ARABIC LIGATURE THEH WITH YEH ISOLATED FORM;Lo;0;AL; 062B 064A;;;;N;;;;; +FC15;ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM;Lo;0;AL; 062C 062D;;;;N;;;;; +FC16;ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM;Lo;0;AL; 062C 0645;;;;N;;;;; +FC17;ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM;Lo;0;AL; 062D 062C;;;;N;;;;; +FC18;ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM;Lo;0;AL; 062D 0645;;;;N;;;;; +FC19;ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM;Lo;0;AL; 062E 062C;;;;N;;;;; +FC1A;ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM;Lo;0;AL; 062E 062D;;;;N;;;;; +FC1B;ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM;Lo;0;AL; 062E 0645;;;;N;;;;; +FC1C;ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM;Lo;0;AL; 0633 062C;;;;N;;;;; +FC1D;ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM;Lo;0;AL; 0633 062D;;;;N;;;;; +FC1E;ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM;Lo;0;AL; 0633 062E;;;;N;;;;; +FC1F;ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM;Lo;0;AL; 0633 0645;;;;N;;;;; +FC20;ARABIC LIGATURE SAD WITH HAH ISOLATED FORM;Lo;0;AL; 0635 062D;;;;N;;;;; +FC21;ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM;Lo;0;AL; 0635 0645;;;;N;;;;; +FC22;ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM;Lo;0;AL; 0636 062C;;;;N;;;;; +FC23;ARABIC LIGATURE DAD WITH HAH ISOLATED FORM;Lo;0;AL; 0636 062D;;;;N;;;;; +FC24;ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM;Lo;0;AL; 0636 062E;;;;N;;;;; +FC25;ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM;Lo;0;AL; 0636 0645;;;;N;;;;; +FC26;ARABIC LIGATURE TAH WITH HAH ISOLATED FORM;Lo;0;AL; 0637 062D;;;;N;;;;; +FC27;ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM;Lo;0;AL; 0637 0645;;;;N;;;;; +FC28;ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM;Lo;0;AL; 0638 0645;;;;N;;;;; +FC29;ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM;Lo;0;AL; 0639 062C;;;;N;;;;; +FC2A;ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM;Lo;0;AL; 0639 0645;;;;N;;;;; +FC2B;ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM;Lo;0;AL; 063A 062C;;;;N;;;;; +FC2C;ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM;Lo;0;AL; 063A 0645;;;;N;;;;; +FC2D;ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0641 062C;;;;N;;;;; +FC2E;ARABIC LIGATURE FEH WITH HAH ISOLATED FORM;Lo;0;AL; 0641 062D;;;;N;;;;; +FC2F;ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM;Lo;0;AL; 0641 062E;;;;N;;;;; +FC30;ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0641 0645;;;;N;;;;; +FC31;ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0641 0649;;;;N;;;;; +FC32;ARABIC LIGATURE FEH WITH YEH ISOLATED FORM;Lo;0;AL; 0641 064A;;;;N;;;;; +FC33;ARABIC LIGATURE QAF WITH HAH ISOLATED FORM;Lo;0;AL; 0642 062D;;;;N;;;;; +FC34;ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM;Lo;0;AL; 0642 0645;;;;N;;;;; +FC35;ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0642 0649;;;;N;;;;; +FC36;ARABIC LIGATURE QAF WITH YEH ISOLATED FORM;Lo;0;AL; 0642 064A;;;;N;;;;; +FC37;ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM;Lo;0;AL; 0643 0627;;;;N;;;;; +FC38;ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM;Lo;0;AL; 0643 062C;;;;N;;;;; +FC39;ARABIC LIGATURE KAF WITH HAH ISOLATED FORM;Lo;0;AL; 0643 062D;;;;N;;;;; +FC3A;ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM;Lo;0;AL; 0643 062E;;;;N;;;;; +FC3B;ARABIC LIGATURE KAF WITH LAM ISOLATED FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FC3C;ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FC3D;ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0643 0649;;;;N;;;;; +FC3E;ARABIC LIGATURE KAF WITH YEH ISOLATED FORM;Lo;0;AL; 0643 064A;;;;N;;;;; +FC3F;ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM;Lo;0;AL; 0644 062C;;;;N;;;;; +FC40;ARABIC LIGATURE LAM WITH HAH ISOLATED FORM;Lo;0;AL; 0644 062D;;;;N;;;;; +FC41;ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM;Lo;0;AL; 0644 062E;;;;N;;;;; +FC42;ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FC43;ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0644 0649;;;;N;;;;; +FC44;ARABIC LIGATURE LAM WITH YEH ISOLATED FORM;Lo;0;AL; 0644 064A;;;;N;;;;; +FC45;ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM;Lo;0;AL; 0645 062C;;;;N;;;;; +FC46;ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM;Lo;0;AL; 0645 062D;;;;N;;;;; +FC47;ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM;Lo;0;AL; 0645 062E;;;;N;;;;; +FC48;ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM;Lo;0;AL; 0645 0645;;;;N;;;;; +FC49;ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0645 0649;;;;N;;;;; +FC4A;ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM;Lo;0;AL; 0645 064A;;;;N;;;;; +FC4B;ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM;Lo;0;AL; 0646 062C;;;;N;;;;; +FC4C;ARABIC LIGATURE NOON WITH HAH ISOLATED FORM;Lo;0;AL; 0646 062D;;;;N;;;;; +FC4D;ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM;Lo;0;AL; 0646 062E;;;;N;;;;; +FC4E;ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FC4F;ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0646 0649;;;;N;;;;; +FC50;ARABIC LIGATURE NOON WITH YEH ISOLATED FORM;Lo;0;AL; 0646 064A;;;;N;;;;; +FC51;ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0647 062C;;;;N;;;;; +FC52;ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0647 0645;;;;N;;;;; +FC53;ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0647 0649;;;;N;;;;; +FC54;ARABIC LIGATURE HEH WITH YEH ISOLATED FORM;Lo;0;AL; 0647 064A;;;;N;;;;; +FC55;ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM;Lo;0;AL; 064A 062C;;;;N;;;;; +FC56;ARABIC LIGATURE YEH WITH HAH ISOLATED FORM;Lo;0;AL; 064A 062D;;;;N;;;;; +FC57;ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM;Lo;0;AL; 064A 062E;;;;N;;;;; +FC58;ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FC59;ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 064A 0649;;;;N;;;;; +FC5A;ARABIC LIGATURE YEH WITH YEH ISOLATED FORM;Lo;0;AL; 064A 064A;;;;N;;;;; +FC5B;ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0630 0670;;;;N;;;;; +FC5C;ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0631 0670;;;;N;;;;; +FC5D;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0649 0670;;;;N;;;;; +FC5E;ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM;Lo;0;AL; 0020 064C 0651;;;;N;;;;; +FC5F;ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM;Lo;0;AL; 0020 064D 0651;;;;N;;;;; +FC60;ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM;Lo;0;AL; 0020 064E 0651;;;;N;;;;; +FC61;ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM;Lo;0;AL; 0020 064F 0651;;;;N;;;;; +FC62;ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM;Lo;0;AL; 0020 0650 0651;;;;N;;;;; +FC63;ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0020 0651 0670;;;;N;;;;; +FC64;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM;Lo;0;AL; 0626 0631;;;;N;;;;; +FC65;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM;Lo;0;AL; 0626 0632;;;;N;;;;; +FC66;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FC67;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM;Lo;0;AL; 0626 0646;;;;N;;;;; +FC68;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FC69;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM;Lo;0;AL; 0626 064A;;;;N;;;;; +FC6A;ARABIC LIGATURE BEH WITH REH FINAL FORM;Lo;0;AL; 0628 0631;;;;N;;;;; +FC6B;ARABIC LIGATURE BEH WITH ZAIN FINAL FORM;Lo;0;AL; 0628 0632;;;;N;;;;; +FC6C;ARABIC LIGATURE BEH WITH MEEM FINAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FC6D;ARABIC LIGATURE BEH WITH NOON FINAL FORM;Lo;0;AL; 0628 0646;;;;N;;;;; +FC6E;ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0628 0649;;;;N;;;;; +FC6F;ARABIC LIGATURE BEH WITH YEH FINAL FORM;Lo;0;AL; 0628 064A;;;;N;;;;; +FC70;ARABIC LIGATURE TEH WITH REH FINAL FORM;Lo;0;AL; 062A 0631;;;;N;;;;; +FC71;ARABIC LIGATURE TEH WITH ZAIN FINAL FORM;Lo;0;AL; 062A 0632;;;;N;;;;; +FC72;ARABIC LIGATURE TEH WITH MEEM FINAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FC73;ARABIC LIGATURE TEH WITH NOON FINAL FORM;Lo;0;AL; 062A 0646;;;;N;;;;; +FC74;ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 0649;;;;N;;;;; +FC75;ARABIC LIGATURE TEH WITH YEH FINAL FORM;Lo;0;AL; 062A 064A;;;;N;;;;; +FC76;ARABIC LIGATURE THEH WITH REH FINAL FORM;Lo;0;AL; 062B 0631;;;;N;;;;; +FC77;ARABIC LIGATURE THEH WITH ZAIN FINAL FORM;Lo;0;AL; 062B 0632;;;;N;;;;; +FC78;ARABIC LIGATURE THEH WITH MEEM FINAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FC79;ARABIC LIGATURE THEH WITH NOON FINAL FORM;Lo;0;AL; 062B 0646;;;;N;;;;; +FC7A;ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062B 0649;;;;N;;;;; +FC7B;ARABIC LIGATURE THEH WITH YEH FINAL FORM;Lo;0;AL; 062B 064A;;;;N;;;;; +FC7C;ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0641 0649;;;;N;;;;; +FC7D;ARABIC LIGATURE FEH WITH YEH FINAL FORM;Lo;0;AL; 0641 064A;;;;N;;;;; +FC7E;ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0642 0649;;;;N;;;;; +FC7F;ARABIC LIGATURE QAF WITH YEH FINAL FORM;Lo;0;AL; 0642 064A;;;;N;;;;; +FC80;ARABIC LIGATURE KAF WITH ALEF FINAL FORM;Lo;0;AL; 0643 0627;;;;N;;;;; +FC81;ARABIC LIGATURE KAF WITH LAM FINAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FC82;ARABIC LIGATURE KAF WITH MEEM FINAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FC83;ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0643 0649;;;;N;;;;; +FC84;ARABIC LIGATURE KAF WITH YEH FINAL FORM;Lo;0;AL; 0643 064A;;;;N;;;;; +FC85;ARABIC LIGATURE LAM WITH MEEM FINAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FC86;ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0644 0649;;;;N;;;;; +FC87;ARABIC LIGATURE LAM WITH YEH FINAL FORM;Lo;0;AL; 0644 064A;;;;N;;;;; +FC88;ARABIC LIGATURE MEEM WITH ALEF FINAL FORM;Lo;0;AL; 0645 0627;;;;N;;;;; +FC89;ARABIC LIGATURE MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0645 0645;;;;N;;;;; +FC8A;ARABIC LIGATURE NOON WITH REH FINAL FORM;Lo;0;AL; 0646 0631;;;;N;;;;; +FC8B;ARABIC LIGATURE NOON WITH ZAIN FINAL FORM;Lo;0;AL; 0646 0632;;;;N;;;;; +FC8C;ARABIC LIGATURE NOON WITH MEEM FINAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FC8D;ARABIC LIGATURE NOON WITH NOON FINAL FORM;Lo;0;AL; 0646 0646;;;;N;;;;; +FC8E;ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 0649;;;;N;;;;; +FC8F;ARABIC LIGATURE NOON WITH YEH FINAL FORM;Lo;0;AL; 0646 064A;;;;N;;;;; +FC90;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM;Lo;0;AL; 0649 0670;;;;N;;;;; +FC91;ARABIC LIGATURE YEH WITH REH FINAL FORM;Lo;0;AL; 064A 0631;;;;N;;;;; +FC92;ARABIC LIGATURE YEH WITH ZAIN FINAL FORM;Lo;0;AL; 064A 0632;;;;N;;;;; +FC93;ARABIC LIGATURE YEH WITH MEEM FINAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FC94;ARABIC LIGATURE YEH WITH NOON FINAL FORM;Lo;0;AL; 064A 0646;;;;N;;;;; +FC95;ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 064A 0649;;;;N;;;;; +FC96;ARABIC LIGATURE YEH WITH YEH FINAL FORM;Lo;0;AL; 064A 064A;;;;N;;;;; +FC97;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM;Lo;0;AL; 0626 062C;;;;N;;;;; +FC98;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM;Lo;0;AL; 0626 062D;;;;N;;;;; +FC99;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM;Lo;0;AL; 0626 062E;;;;N;;;;; +FC9A;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FC9B;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM;Lo;0;AL; 0626 0647;;;;N;;;;; +FC9C;ARABIC LIGATURE BEH WITH JEEM INITIAL FORM;Lo;0;AL; 0628 062C;;;;N;;;;; +FC9D;ARABIC LIGATURE BEH WITH HAH INITIAL FORM;Lo;0;AL; 0628 062D;;;;N;;;;; +FC9E;ARABIC LIGATURE BEH WITH KHAH INITIAL FORM;Lo;0;AL; 0628 062E;;;;N;;;;; +FC9F;ARABIC LIGATURE BEH WITH MEEM INITIAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FCA0;ARABIC LIGATURE BEH WITH HEH INITIAL FORM;Lo;0;AL; 0628 0647;;;;N;;;;; +FCA1;ARABIC LIGATURE TEH WITH JEEM INITIAL FORM;Lo;0;AL; 062A 062C;;;;N;;;;; +FCA2;ARABIC LIGATURE TEH WITH HAH INITIAL FORM;Lo;0;AL; 062A 062D;;;;N;;;;; +FCA3;ARABIC LIGATURE TEH WITH KHAH INITIAL FORM;Lo;0;AL; 062A 062E;;;;N;;;;; +FCA4;ARABIC LIGATURE TEH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FCA5;ARABIC LIGATURE TEH WITH HEH INITIAL FORM;Lo;0;AL; 062A 0647;;;;N;;;;; +FCA6;ARABIC LIGATURE THEH WITH MEEM INITIAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FCA7;ARABIC LIGATURE JEEM WITH HAH INITIAL FORM;Lo;0;AL; 062C 062D;;;;N;;;;; +FCA8;ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 062C 0645;;;;N;;;;; +FCA9;ARABIC LIGATURE HAH WITH JEEM INITIAL FORM;Lo;0;AL; 062D 062C;;;;N;;;;; +FCAA;ARABIC LIGATURE HAH WITH MEEM INITIAL FORM;Lo;0;AL; 062D 0645;;;;N;;;;; +FCAB;ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM;Lo;0;AL; 062E 062C;;;;N;;;;; +FCAC;ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 062E 0645;;;;N;;;;; +FCAD;ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM;Lo;0;AL; 0633 062C;;;;N;;;;; +FCAE;ARABIC LIGATURE SEEN WITH HAH INITIAL FORM;Lo;0;AL; 0633 062D;;;;N;;;;; +FCAF;ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM;Lo;0;AL; 0633 062E;;;;N;;;;; +FCB0;ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM;Lo;0;AL; 0633 0645;;;;N;;;;; +FCB1;ARABIC LIGATURE SAD WITH HAH INITIAL FORM;Lo;0;AL; 0635 062D;;;;N;;;;; +FCB2;ARABIC LIGATURE SAD WITH KHAH INITIAL FORM;Lo;0;AL; 0635 062E;;;;N;;;;; +FCB3;ARABIC LIGATURE SAD WITH MEEM INITIAL FORM;Lo;0;AL; 0635 0645;;;;N;;;;; +FCB4;ARABIC LIGATURE DAD WITH JEEM INITIAL FORM;Lo;0;AL; 0636 062C;;;;N;;;;; +FCB5;ARABIC LIGATURE DAD WITH HAH INITIAL FORM;Lo;0;AL; 0636 062D;;;;N;;;;; +FCB6;ARABIC LIGATURE DAD WITH KHAH INITIAL FORM;Lo;0;AL; 0636 062E;;;;N;;;;; +FCB7;ARABIC LIGATURE DAD WITH MEEM INITIAL FORM;Lo;0;AL; 0636 0645;;;;N;;;;; +FCB8;ARABIC LIGATURE TAH WITH HAH INITIAL FORM;Lo;0;AL; 0637 062D;;;;N;;;;; +FCB9;ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM;Lo;0;AL; 0638 0645;;;;N;;;;; +FCBA;ARABIC LIGATURE AIN WITH JEEM INITIAL FORM;Lo;0;AL; 0639 062C;;;;N;;;;; +FCBB;ARABIC LIGATURE AIN WITH MEEM INITIAL FORM;Lo;0;AL; 0639 0645;;;;N;;;;; +FCBC;ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM;Lo;0;AL; 063A 062C;;;;N;;;;; +FCBD;ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM;Lo;0;AL; 063A 0645;;;;N;;;;; +FCBE;ARABIC LIGATURE FEH WITH JEEM INITIAL FORM;Lo;0;AL; 0641 062C;;;;N;;;;; +FCBF;ARABIC LIGATURE FEH WITH HAH INITIAL FORM;Lo;0;AL; 0641 062D;;;;N;;;;; +FCC0;ARABIC LIGATURE FEH WITH KHAH INITIAL FORM;Lo;0;AL; 0641 062E;;;;N;;;;; +FCC1;ARABIC LIGATURE FEH WITH MEEM INITIAL FORM;Lo;0;AL; 0641 0645;;;;N;;;;; +FCC2;ARABIC LIGATURE QAF WITH HAH INITIAL FORM;Lo;0;AL; 0642 062D;;;;N;;;;; +FCC3;ARABIC LIGATURE QAF WITH MEEM INITIAL FORM;Lo;0;AL; 0642 0645;;;;N;;;;; +FCC4;ARABIC LIGATURE KAF WITH JEEM INITIAL FORM;Lo;0;AL; 0643 062C;;;;N;;;;; +FCC5;ARABIC LIGATURE KAF WITH HAH INITIAL FORM;Lo;0;AL; 0643 062D;;;;N;;;;; +FCC6;ARABIC LIGATURE KAF WITH KHAH INITIAL FORM;Lo;0;AL; 0643 062E;;;;N;;;;; +FCC7;ARABIC LIGATURE KAF WITH LAM INITIAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FCC8;ARABIC LIGATURE KAF WITH MEEM INITIAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FCC9;ARABIC LIGATURE LAM WITH JEEM INITIAL FORM;Lo;0;AL; 0644 062C;;;;N;;;;; +FCCA;ARABIC LIGATURE LAM WITH HAH INITIAL FORM;Lo;0;AL; 0644 062D;;;;N;;;;; +FCCB;ARABIC LIGATURE LAM WITH KHAH INITIAL FORM;Lo;0;AL; 0644 062E;;;;N;;;;; +FCCC;ARABIC LIGATURE LAM WITH MEEM INITIAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FCCD;ARABIC LIGATURE LAM WITH HEH INITIAL FORM;Lo;0;AL; 0644 0647;;;;N;;;;; +FCCE;ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062C;;;;N;;;;; +FCCF;ARABIC LIGATURE MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0645 062D;;;;N;;;;; +FCD0;ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0645 062E;;;;N;;;;; +FCD1;ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0645 0645;;;;N;;;;; +FCD2;ARABIC LIGATURE NOON WITH JEEM INITIAL FORM;Lo;0;AL; 0646 062C;;;;N;;;;; +FCD3;ARABIC LIGATURE NOON WITH HAH INITIAL FORM;Lo;0;AL; 0646 062D;;;;N;;;;; +FCD4;ARABIC LIGATURE NOON WITH KHAH INITIAL FORM;Lo;0;AL; 0646 062E;;;;N;;;;; +FCD5;ARABIC LIGATURE NOON WITH MEEM INITIAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FCD6;ARABIC LIGATURE NOON WITH HEH INITIAL FORM;Lo;0;AL; 0646 0647;;;;N;;;;; +FCD7;ARABIC LIGATURE HEH WITH JEEM INITIAL FORM;Lo;0;AL; 0647 062C;;;;N;;;;; +FCD8;ARABIC LIGATURE HEH WITH MEEM INITIAL FORM;Lo;0;AL; 0647 0645;;;;N;;;;; +FCD9;ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM;Lo;0;AL; 0647 0670;;;;N;;;;; +FCDA;ARABIC LIGATURE YEH WITH JEEM INITIAL FORM;Lo;0;AL; 064A 062C;;;;N;;;;; +FCDB;ARABIC LIGATURE YEH WITH HAH INITIAL FORM;Lo;0;AL; 064A 062D;;;;N;;;;; +FCDC;ARABIC LIGATURE YEH WITH KHAH INITIAL FORM;Lo;0;AL; 064A 062E;;;;N;;;;; +FCDD;ARABIC LIGATURE YEH WITH MEEM INITIAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FCDE;ARABIC LIGATURE YEH WITH HEH INITIAL FORM;Lo;0;AL; 064A 0647;;;;N;;;;; +FCDF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FCE0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM;Lo;0;AL; 0626 0647;;;;N;;;;; +FCE1;ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FCE2;ARABIC LIGATURE BEH WITH HEH MEDIAL FORM;Lo;0;AL; 0628 0647;;;;N;;;;; +FCE3;ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FCE4;ARABIC LIGATURE TEH WITH HEH MEDIAL FORM;Lo;0;AL; 062A 0647;;;;N;;;;; +FCE5;ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FCE6;ARABIC LIGATURE THEH WITH HEH MEDIAL FORM;Lo;0;AL; 062B 0647;;;;N;;;;; +FCE7;ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM;Lo;0;AL; 0633 0645;;;;N;;;;; +FCE8;ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM;Lo;0;AL; 0633 0647;;;;N;;;;; +FCE9;ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FCEA;ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM;Lo;0;AL; 0634 0647;;;;N;;;;; +FCEB;ARABIC LIGATURE KAF WITH LAM MEDIAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FCEC;ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FCED;ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FCEE;ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FCEF;ARABIC LIGATURE NOON WITH HEH MEDIAL FORM;Lo;0;AL; 0646 0647;;;;N;;;;; +FCF0;ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FCF1;ARABIC LIGATURE YEH WITH HEH MEDIAL FORM;Lo;0;AL; 064A 0647;;;;N;;;;; +FCF2;ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM;Lo;0;AL; 0640 064E 0651;;;;N;;;;; +FCF3;ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM;Lo;0;AL; 0640 064F 0651;;;;N;;;;; +FCF4;ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM;Lo;0;AL; 0640 0650 0651;;;;N;;;;; +FCF5;ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0637 0649;;;;N;;;;; +FCF6;ARABIC LIGATURE TAH WITH YEH ISOLATED FORM;Lo;0;AL; 0637 064A;;;;N;;;;; +FCF7;ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0639 0649;;;;N;;;;; +FCF8;ARABIC LIGATURE AIN WITH YEH ISOLATED FORM;Lo;0;AL; 0639 064A;;;;N;;;;; +FCF9;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 063A 0649;;;;N;;;;; +FCFA;ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM;Lo;0;AL; 063A 064A;;;;N;;;;; +FCFB;ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0633 0649;;;;N;;;;; +FCFC;ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM;Lo;0;AL; 0633 064A;;;;N;;;;; +FCFD;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0634 0649;;;;N;;;;; +FCFE;ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM;Lo;0;AL; 0634 064A;;;;N;;;;; +FCFF;ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062D 0649;;;;N;;;;; +FD00;ARABIC LIGATURE HAH WITH YEH ISOLATED FORM;Lo;0;AL; 062D 064A;;;;N;;;;; +FD01;ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062C 0649;;;;N;;;;; +FD02;ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM;Lo;0;AL; 062C 064A;;;;N;;;;; +FD03;ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062E 0649;;;;N;;;;; +FD04;ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM;Lo;0;AL; 062E 064A;;;;N;;;;; +FD05;ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0635 0649;;;;N;;;;; +FD06;ARABIC LIGATURE SAD WITH YEH ISOLATED FORM;Lo;0;AL; 0635 064A;;;;N;;;;; +FD07;ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0636 0649;;;;N;;;;; +FD08;ARABIC LIGATURE DAD WITH YEH ISOLATED FORM;Lo;0;AL; 0636 064A;;;;N;;;;; +FD09;ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD0A;ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD0B;ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD0C;ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FD0D;ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM;Lo;0;AL; 0634 0631;;;;N;;;;; +FD0E;ARABIC LIGATURE SEEN WITH REH ISOLATED FORM;Lo;0;AL; 0633 0631;;;;N;;;;; +FD0F;ARABIC LIGATURE SAD WITH REH ISOLATED FORM;Lo;0;AL; 0635 0631;;;;N;;;;; +FD10;ARABIC LIGATURE DAD WITH REH ISOLATED FORM;Lo;0;AL; 0636 0631;;;;N;;;;; +FD11;ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0637 0649;;;;N;;;;; +FD12;ARABIC LIGATURE TAH WITH YEH FINAL FORM;Lo;0;AL; 0637 064A;;;;N;;;;; +FD13;ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0639 0649;;;;N;;;;; +FD14;ARABIC LIGATURE AIN WITH YEH FINAL FORM;Lo;0;AL; 0639 064A;;;;N;;;;; +FD15;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 063A 0649;;;;N;;;;; +FD16;ARABIC LIGATURE GHAIN WITH YEH FINAL FORM;Lo;0;AL; 063A 064A;;;;N;;;;; +FD17;ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 0649;;;;N;;;;; +FD18;ARABIC LIGATURE SEEN WITH YEH FINAL FORM;Lo;0;AL; 0633 064A;;;;N;;;;; +FD19;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0634 0649;;;;N;;;;; +FD1A;ARABIC LIGATURE SHEEN WITH YEH FINAL FORM;Lo;0;AL; 0634 064A;;;;N;;;;; +FD1B;ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062D 0649;;;;N;;;;; +FD1C;ARABIC LIGATURE HAH WITH YEH FINAL FORM;Lo;0;AL; 062D 064A;;;;N;;;;; +FD1D;ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 0649;;;;N;;;;; +FD1E;ARABIC LIGATURE JEEM WITH YEH FINAL FORM;Lo;0;AL; 062C 064A;;;;N;;;;; +FD1F;ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062E 0649;;;;N;;;;; +FD20;ARABIC LIGATURE KHAH WITH YEH FINAL FORM;Lo;0;AL; 062E 064A;;;;N;;;;; +FD21;ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0635 0649;;;;N;;;;; +FD22;ARABIC LIGATURE SAD WITH YEH FINAL FORM;Lo;0;AL; 0635 064A;;;;N;;;;; +FD23;ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0636 0649;;;;N;;;;; +FD24;ARABIC LIGATURE DAD WITH YEH FINAL FORM;Lo;0;AL; 0636 064A;;;;N;;;;; +FD25;ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD26;ARABIC LIGATURE SHEEN WITH HAH FINAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD27;ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD28;ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FD29;ARABIC LIGATURE SHEEN WITH REH FINAL FORM;Lo;0;AL; 0634 0631;;;;N;;;;; +FD2A;ARABIC LIGATURE SEEN WITH REH FINAL FORM;Lo;0;AL; 0633 0631;;;;N;;;;; +FD2B;ARABIC LIGATURE SAD WITH REH FINAL FORM;Lo;0;AL; 0635 0631;;;;N;;;;; +FD2C;ARABIC LIGATURE DAD WITH REH FINAL FORM;Lo;0;AL; 0636 0631;;;;N;;;;; +FD2D;ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD2E;ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD2F;ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD30;ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FD31;ARABIC LIGATURE SEEN WITH HEH INITIAL FORM;Lo;0;AL; 0633 0647;;;;N;;;;; +FD32;ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM;Lo;0;AL; 0634 0647;;;;N;;;;; +FD33;ARABIC LIGATURE TAH WITH MEEM INITIAL FORM;Lo;0;AL; 0637 0645;;;;N;;;;; +FD34;ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM;Lo;0;AL; 0633 062C;;;;N;;;;; +FD35;ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM;Lo;0;AL; 0633 062D;;;;N;;;;; +FD36;ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM;Lo;0;AL; 0633 062E;;;;N;;;;; +FD37;ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD38;ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD39;ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD3A;ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM;Lo;0;AL; 0637 0645;;;;N;;;;; +FD3B;ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM;Lo;0;AL; 0638 0645;;;;N;;;;; +FD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL; 0627 064B;;;;N;;;;; +FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL; 0627 064B;;;;N;;;;; +FD3E;ORNATE LEFT PARENTHESIS;Ps;0;ON;;;;;N;;;;; +FD3F;ORNATE RIGHT PARENTHESIS;Pe;0;ON;;;;;N;;;;; +FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062C 0645;;;;N;;;;; +FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL; 062A 062D 062C;;;;N;;;;; +FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 062A 062D 062C;;;;N;;;;; +FD53;ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062D 0645;;;;N;;;;; +FD54;ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062E 0645;;;;N;;;;; +FD55;ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 062A 0645 062C;;;;N;;;;; +FD56;ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 062A 0645 062D;;;;N;;;;; +FD57;ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 062A 0645 062E;;;;N;;;;; +FD58;ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 062C 0645 062D;;;;N;;;;; +FD59;ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 062C 0645 062D;;;;N;;;;; +FD5A;ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062D 0645 064A;;;;N;;;;; +FD5B;ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062D 0645 0649;;;;N;;;;; +FD5C;ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 0633 062D 062C;;;;N;;;;; +FD5D;ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0633 062C 062D;;;;N;;;;; +FD5E;ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 062C 0649;;;;N;;;;; +FD5F;ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0633 0645 062D;;;;N;;;;; +FD60;ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0633 0645 062D;;;;N;;;;; +FD61;ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0633 0645 062C;;;;N;;;;; +FD62;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0633 0645 0645;;;;N;;;;; +FD63;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0633 0645 0645;;;;N;;;;; +FD64;ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM;Lo;0;AL; 0635 062D 062D;;;;N;;;;; +FD65;ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM;Lo;0;AL; 0635 062D 062D;;;;N;;;;; +FD66;ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0635 0645 0645;;;;N;;;;; +FD67;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM;Lo;0;AL; 0634 062D 0645;;;;N;;;;; +FD68;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0634 062D 0645;;;;N;;;;; +FD69;ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0634 062C 064A;;;;N;;;;; +FD6A;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM;Lo;0;AL; 0634 0645 062E;;;;N;;;;; +FD6B;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0634 0645 062E;;;;N;;;;; +FD6C;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0634 0645 0645;;;;N;;;;; +FD6D;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0634 0645 0645;;;;N;;;;; +FD6E;ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0636 062D 0649;;;;N;;;;; +FD6F;ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0636 062E 0645;;;;N;;;;; +FD70;ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0636 062E 0645;;;;N;;;;; +FD71;ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0637 0645 062D;;;;N;;;;; +FD72;ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0637 0645 062D;;;;N;;;;; +FD73;ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0637 0645 0645;;;;N;;;;; +FD74;ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0637 0645 064A;;;;N;;;;; +FD75;ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0639 062C 0645;;;;N;;;;; +FD76;ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0639 0645 0645;;;;N;;;;; +FD77;ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0639 0645 0645;;;;N;;;;; +FD78;ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0639 0645 0649;;;;N;;;;; +FD79;ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 063A 0645 0645;;;;N;;;;; +FD7A;ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 063A 0645 064A;;;;N;;;;; +FD7B;ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 063A 0645 0649;;;;N;;;;; +FD7C;ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0641 062E 0645;;;;N;;;;; +FD7D;ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0641 062E 0645;;;;N;;;;; +FD7E;ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0642 0645 062D;;;;N;;;;; +FD7F;ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0642 0645 0645;;;;N;;;;; +FD80;ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM;Lo;0;AL; 0644 062D 0645;;;;N;;;;; +FD81;ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0644 062D 064A;;;;N;;;;; +FD82;ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0644 062D 0649;;;;N;;;;; +FD83;ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0644 062C 062C;;;;N;;;;; +FD84;ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM;Lo;0;AL; 0644 062C 062C;;;;N;;;;; +FD85;ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0644 062E 0645;;;;N;;;;; +FD86;ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062E 0645;;;;N;;;;; +FD87;ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0644 0645 062D;;;;N;;;;; +FD88;ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0644 0645 062D;;;;N;;;;; +FD89;ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062D 062C;;;;N;;;;; +FD8A;ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062D 0645;;;;N;;;;; +FD8B;ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0645 062D 064A;;;;N;;;;; +FD8C;ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0645 062C 062D;;;;N;;;;; +FD8D;ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062C 0645;;;;N;;;;; +FD8E;ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062E 062C;;;;N;;;;; +FD8F;ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062E 0645;;;;N;;;;; +FD92;ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0645 062C 062E;;;;N;;;;; +FD93;ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0647 0645 062C;;;;N;;;;; +FD94;ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0647 0645 0645;;;;N;;;;; +FD95;ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0646 062D 0645;;;;N;;;;; +FD96;ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 062D 0649;;;;N;;;;; +FD97;ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0646 062C 0645;;;;N;;;;; +FD98;ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0646 062C 0645;;;;N;;;;; +FD99;ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 062C 0649;;;;N;;;;; +FD9A;ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0646 0645 064A;;;;N;;;;; +FD9B;ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 0645 0649;;;;N;;;;; +FD9C;ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 064A 0645 0645;;;;N;;;;; +FD9D;ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 064A 0645 0645;;;;N;;;;; +FD9E;ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0628 062E 064A;;;;N;;;;; +FD9F;ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 062A 062C 064A;;;;N;;;;; +FDA0;ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 062C 0649;;;;N;;;;; +FDA1;ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 062A 062E 064A;;;;N;;;;; +FDA2;ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 062E 0649;;;;N;;;;; +FDA3;ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062A 0645 064A;;;;N;;;;; +FDA4;ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 0645 0649;;;;N;;;;; +FDA5;ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062C 0645 064A;;;;N;;;;; +FDA6;ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 062D 0649;;;;N;;;;; +FDA7;ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 0645 0649;;;;N;;;;; +FDA8;ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 062E 0649;;;;N;;;;; +FDA9;ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0635 062D 064A;;;;N;;;;; +FDAA;ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0634 062D 064A;;;;N;;;;; +FDAB;ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0636 062D 064A;;;;N;;;;; +FDAC;ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0644 062C 064A;;;;N;;;;; +FDAD;ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0644 0645 064A;;;;N;;;;; +FDAE;ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 064A 062D 064A;;;;N;;;;; +FDAF;ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 064A 062C 064A;;;;N;;;;; +FDB0;ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 064A 0645 064A;;;;N;;;;; +FDB1;ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0645 0645 064A;;;;N;;;;; +FDB2;ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0642 0645 064A;;;;N;;;;; +FDB3;ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0646 062D 064A;;;;N;;;;; +FDB4;ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0642 0645 062D;;;;N;;;;; +FDB5;ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062D 0645;;;;N;;;;; +FDB6;ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0639 0645 064A;;;;N;;;;; +FDB7;ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0643 0645 064A;;;;N;;;;; +FDB8;ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0646 062C 062D;;;;N;;;;; +FDB9;ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0645 062E 064A;;;;N;;;;; +FDBA;ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062C 0645;;;;N;;;;; +FDBB;ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0643 0645 0645;;;;N;;;;; +FDBC;ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0644 062C 0645;;;;N;;;;; +FDBD;ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM;Lo;0;AL; 0646 062C 062D;;;;N;;;;; +FDBE;ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 062C 062D 064A;;;;N;;;;; +FDBF;ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 062D 062C 064A;;;;N;;;;; +FDC0;ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0645 062C 064A;;;;N;;;;; +FDC1;ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0641 0645 064A;;;;N;;;;; +FDC2;ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0628 062D 064A;;;;N;;;;; +FDC3;ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0643 0645 0645;;;;N;;;;; +FDC4;ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0639 062C 0645;;;;N;;;;; +FDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0635 0645 0645;;;;N;;;;; +FDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0633 062E 064A;;;;N;;;;; +FDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0646 062C 064A;;;;N;;;;; +FDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL; 0635 0644 06D2;;;;N;;;;; +FDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL; 0642 0644 06D2;;;;N;;;;; +FDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL; 0627 0644 0644 0647;;;;N;;;;; +FDF3;ARABIC LIGATURE AKBAR ISOLATED FORM;Lo;0;AL; 0627 0643 0628 0631;;;;N;;;;; +FDF4;ARABIC LIGATURE MOHAMMAD ISOLATED FORM;Lo;0;AL; 0645 062D 0645 062F;;;;N;;;;; +FDF5;ARABIC LIGATURE SALAM ISOLATED FORM;Lo;0;AL; 0635 0644 0639 0645;;;;N;;;;; +FDF6;ARABIC LIGATURE RASOUL ISOLATED FORM;Lo;0;AL; 0631 0633 0648 0644;;;;N;;;;; +FDF7;ARABIC LIGATURE ALAYHE ISOLATED FORM;Lo;0;AL; 0639 0644 064A 0647;;;;N;;;;; +FDF8;ARABIC LIGATURE WASALLAM ISOLATED FORM;Lo;0;AL; 0648 0633 0644 0645;;;;N;;;;; +FDF9;ARABIC LIGATURE SALLA ISOLATED FORM;Lo;0;AL; 0635 0644 0649;;;;N;;;;; +FDFA;ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM;Lo;0;AL; 0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;;;;N;ARABIC LETTER SALLALLAHOU ALAYHE WASALLAM;;;; +FDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL; 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;; +FDFC;RIAL SIGN;Sc;0;AL; 0631 06CC 0627 0644;;;;N;;;;; +FDFD;ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM;So;0;ON;;;;;N;;;;; +FE00;VARIATION SELECTOR-1;Mn;0;NSM;;;;;N;;;;; +FE01;VARIATION SELECTOR-2;Mn;0;NSM;;;;;N;;;;; +FE02;VARIATION SELECTOR-3;Mn;0;NSM;;;;;N;;;;; +FE03;VARIATION SELECTOR-4;Mn;0;NSM;;;;;N;;;;; +FE04;VARIATION SELECTOR-5;Mn;0;NSM;;;;;N;;;;; +FE05;VARIATION SELECTOR-6;Mn;0;NSM;;;;;N;;;;; +FE06;VARIATION SELECTOR-7;Mn;0;NSM;;;;;N;;;;; +FE07;VARIATION SELECTOR-8;Mn;0;NSM;;;;;N;;;;; +FE08;VARIATION SELECTOR-9;Mn;0;NSM;;;;;N;;;;; +FE09;VARIATION SELECTOR-10;Mn;0;NSM;;;;;N;;;;; +FE0A;VARIATION SELECTOR-11;Mn;0;NSM;;;;;N;;;;; +FE0B;VARIATION SELECTOR-12;Mn;0;NSM;;;;;N;;;;; +FE0C;VARIATION SELECTOR-13;Mn;0;NSM;;;;;N;;;;; +FE0D;VARIATION SELECTOR-14;Mn;0;NSM;;;;;N;;;;; +FE0E;VARIATION SELECTOR-15;Mn;0;NSM;;;;;N;;;;; +FE0F;VARIATION SELECTOR-16;Mn;0;NSM;;;;;N;;;;; +FE10;PRESENTATION FORM FOR VERTICAL COMMA;Po;0;ON; 002C;;;;N;;;;; +FE11;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; +FE12;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP;Po;0;ON; 3002;;;;N;;;;; +FE13;PRESENTATION FORM FOR VERTICAL COLON;Po;0;ON; 003A;;;;N;;;;; +FE14;PRESENTATION FORM FOR VERTICAL SEMICOLON;Po;0;ON; 003B;;;;N;;;;; +FE15;PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; +FE16;PRESENTATION FORM FOR VERTICAL QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; +FE17;PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET;Ps;0;ON; 3016;;;;N;;;;; +FE18;PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET;Pe;0;ON; 3017;;;;N;;;;; +FE19;PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS;Po;0;ON; 2026;;;;N;;;;; +FE20;COMBINING LIGATURE LEFT HALF;Mn;230;NSM;;;;;N;;;;; +FE21;COMBINING LIGATURE RIGHT HALF;Mn;230;NSM;;;;;N;;;;; +FE22;COMBINING DOUBLE TILDE LEFT HALF;Mn;230;NSM;;;;;N;;;;; +FE23;COMBINING DOUBLE TILDE RIGHT HALF;Mn;230;NSM;;;;;N;;;;; +FE24;COMBINING MACRON LEFT HALF;Mn;230;NSM;;;;;N;;;;; +FE25;COMBINING MACRON RIGHT HALF;Mn;230;NSM;;;;;N;;;;; +FE26;COMBINING CONJOINING MACRON;Mn;230;NSM;;;;;N;;;;; +FE30;PRESENTATION FORM FOR VERTICAL TWO DOT LEADER;Po;0;ON; 2025;;;;N;GLYPH FOR VERTICAL TWO DOT LEADER;;;; +FE31;PRESENTATION FORM FOR VERTICAL EM DASH;Pd;0;ON; 2014;;;;N;GLYPH FOR VERTICAL EM DASH;;;; +FE32;PRESENTATION FORM FOR VERTICAL EN DASH;Pd;0;ON; 2013;;;;N;GLYPH FOR VERTICAL EN DASH;;;; +FE33;PRESENTATION FORM FOR VERTICAL LOW LINE;Pc;0;ON; 005F;;;;N;GLYPH FOR VERTICAL SPACING UNDERSCORE;;;; +FE34;PRESENTATION FORM FOR VERTICAL WAVY LOW LINE;Pc;0;ON; 005F;;;;N;GLYPH FOR VERTICAL SPACING WAVY UNDERSCORE;;;; +FE35;PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS;Ps;0;ON; 0028;;;;N;GLYPH FOR VERTICAL OPENING PARENTHESIS;;;; +FE36;PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;N;GLYPH FOR VERTICAL CLOSING PARENTHESIS;;;; +FE37;PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;N;GLYPH FOR VERTICAL OPENING CURLY BRACKET;;;; +FE38;PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;N;GLYPH FOR VERTICAL CLOSING CURLY BRACKET;;;; +FE39;PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET;Ps;0;ON; 3014;;;;N;GLYPH FOR VERTICAL OPENING TORTOISE SHELL BRACKET;;;; +FE3A;PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON; 3015;;;;N;GLYPH FOR VERTICAL CLOSING TORTOISE SHELL BRACKET;;;; +FE3B;PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET;Ps;0;ON; 3010;;;;N;GLYPH FOR VERTICAL OPENING BLACK LENTICULAR BRACKET;;;; +FE3C;PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON; 3011;;;;N;GLYPH FOR VERTICAL CLOSING BLACK LENTICULAR BRACKET;;;; +FE3D;PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON; 300A;;;;N;GLYPH FOR VERTICAL OPENING DOUBLE ANGLE BRACKET;;;; +FE3E;PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON; 300B;;;;N;GLYPH FOR VERTICAL CLOSING DOUBLE ANGLE BRACKET;;;; +FE3F;PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET;Ps;0;ON; 3008;;;;N;GLYPH FOR VERTICAL OPENING ANGLE BRACKET;;;; +FE40;PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET;Pe;0;ON; 3009;;;;N;GLYPH FOR VERTICAL CLOSING ANGLE BRACKET;;;; +FE41;PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET;Ps;0;ON; 300C;;;;N;GLYPH FOR VERTICAL OPENING CORNER BRACKET;;;; +FE42;PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET;Pe;0;ON; 300D;;;;N;GLYPH FOR VERTICAL CLOSING CORNER BRACKET;;;; +FE43;PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET;Ps;0;ON; 300E;;;;N;GLYPH FOR VERTICAL OPENING WHITE CORNER BRACKET;;;; +FE44;PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET;Pe;0;ON; 300F;;;;N;GLYPH FOR VERTICAL CLOSING WHITE CORNER BRACKET;;;; +FE45;SESAME DOT;Po;0;ON;;;;;N;;;;; +FE46;WHITE SESAME DOT;Po;0;ON;;;;;N;;;;; +FE47;PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET;Ps;0;ON; 005B;;;;N;;;;; +FE48;PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET;Pe;0;ON; 005D;;;;N;;;;; +FE49;DASHED OVERLINE;Po;0;ON; 203E;;;;N;SPACING DASHED OVERSCORE;;;; +FE4A;CENTRELINE OVERLINE;Po;0;ON; 203E;;;;N;SPACING CENTERLINE OVERSCORE;;;; +FE4B;WAVY OVERLINE;Po;0;ON; 203E;;;;N;SPACING WAVY OVERSCORE;;;; +FE4C;DOUBLE WAVY OVERLINE;Po;0;ON; 203E;;;;N;SPACING DOUBLE WAVY OVERSCORE;;;; +FE4D;DASHED LOW LINE;Pc;0;ON; 005F;;;;N;SPACING DASHED UNDERSCORE;;;; +FE4E;CENTRELINE LOW LINE;Pc;0;ON; 005F;;;;N;SPACING CENTERLINE UNDERSCORE;;;; +FE4F;WAVY LOW LINE;Pc;0;ON; 005F;;;;N;SPACING WAVY UNDERSCORE;;;; +FE50;SMALL COMMA;Po;0;CS; 002C;;;;N;;;;; +FE51;SMALL IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; +FE52;SMALL FULL STOP;Po;0;CS; 002E;;;;N;SMALL PERIOD;;;; +FE54;SMALL SEMICOLON;Po;0;ON; 003B;;;;N;;;;; +FE55;SMALL COLON;Po;0;CS; 003A;;;;N;;;;; +FE56;SMALL QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; +FE57;SMALL EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; +FE58;SMALL EM DASH;Pd;0;ON; 2014;;;;N;;;;; +FE59;SMALL LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SMALL OPENING PARENTHESIS;;;; +FE5A;SMALL RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SMALL CLOSING PARENTHESIS;;;; +FE5B;SMALL LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;Y;SMALL OPENING CURLY BRACKET;;;; +FE5C;SMALL RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;Y;SMALL CLOSING CURLY BRACKET;;;; +FE5D;SMALL LEFT TORTOISE SHELL BRACKET;Ps;0;ON; 3014;;;;Y;SMALL OPENING TORTOISE SHELL BRACKET;;;; +FE5E;SMALL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON; 3015;;;;Y;SMALL CLOSING TORTOISE SHELL BRACKET;;;; +FE5F;SMALL NUMBER SIGN;Po;0;ET; 0023;;;;N;;;;; +FE60;SMALL AMPERSAND;Po;0;ON; 0026;;;;N;;;;; +FE61;SMALL ASTERISK;Po;0;ON; 002A;;;;N;;;;; +FE62;SMALL PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +FE63;SMALL HYPHEN-MINUS;Pd;0;ES; 002D;;;;N;;;;; +FE64;SMALL LESS-THAN SIGN;Sm;0;ON; 003C;;;;Y;;;;; +FE65;SMALL GREATER-THAN SIGN;Sm;0;ON; 003E;;;;Y;;;;; +FE66;SMALL EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +FE68;SMALL REVERSE SOLIDUS;Po;0;ON; 005C;;;;N;SMALL BACKSLASH;;;; +FE69;SMALL DOLLAR SIGN;Sc;0;ET; 0024;;;;N;;;;; +FE6A;SMALL PERCENT SIGN;Po;0;ET; 0025;;;;N;;;;; +FE6B;SMALL COMMERCIAL AT;Po;0;ON; 0040;;;;N;;;;; +FE70;ARABIC FATHATAN ISOLATED FORM;Lo;0;AL; 0020 064B;;;;N;ARABIC SPACING FATHATAN;;;; +FE71;ARABIC TATWEEL WITH FATHATAN ABOVE;Lo;0;AL; 0640 064B;;;;N;ARABIC FATHATAN ON TATWEEL;;;; +FE72;ARABIC DAMMATAN ISOLATED FORM;Lo;0;AL; 0020 064C;;;;N;ARABIC SPACING DAMMATAN;;;; +FE73;ARABIC TAIL FRAGMENT;Lo;0;AL;;;;;N;;;;; +FE74;ARABIC KASRATAN ISOLATED FORM;Lo;0;AL; 0020 064D;;;;N;ARABIC SPACING KASRATAN;;;; +FE76;ARABIC FATHA ISOLATED FORM;Lo;0;AL; 0020 064E;;;;N;ARABIC SPACING FATHAH;;;; +FE77;ARABIC FATHA MEDIAL FORM;Lo;0;AL; 0640 064E;;;;N;ARABIC FATHAH ON TATWEEL;;;; +FE78;ARABIC DAMMA ISOLATED FORM;Lo;0;AL; 0020 064F;;;;N;ARABIC SPACING DAMMAH;;;; +FE79;ARABIC DAMMA MEDIAL FORM;Lo;0;AL; 0640 064F;;;;N;ARABIC DAMMAH ON TATWEEL;;;; +FE7A;ARABIC KASRA ISOLATED FORM;Lo;0;AL; 0020 0650;;;;N;ARABIC SPACING KASRAH;;;; +FE7B;ARABIC KASRA MEDIAL FORM;Lo;0;AL; 0640 0650;;;;N;ARABIC KASRAH ON TATWEEL;;;; +FE7C;ARABIC SHADDA ISOLATED FORM;Lo;0;AL; 0020 0651;;;;N;ARABIC SPACING SHADDAH;;;; +FE7D;ARABIC SHADDA MEDIAL FORM;Lo;0;AL; 0640 0651;;;;N;ARABIC SHADDAH ON TATWEEL;;;; +FE7E;ARABIC SUKUN ISOLATED FORM;Lo;0;AL; 0020 0652;;;;N;ARABIC SPACING SUKUN;;;; +FE7F;ARABIC SUKUN MEDIAL FORM;Lo;0;AL; 0640 0652;;;;N;ARABIC SUKUN ON TATWEEL;;;; +FE80;ARABIC LETTER HAMZA ISOLATED FORM;Lo;0;AL; 0621;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH;;;; +FE81;ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL; 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON ALEF;;;; +FE82;ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL; 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON ALEF;;;; +FE83;ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON ALEF;;;; +FE84;ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON ALEF;;;; +FE85;ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0624;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON WAW;;;; +FE86;ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0624;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON WAW;;;; +FE87;ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL; 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER ALEF;;;; +FE88;ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL; 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER ALEF;;;; +FE89;ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON YA;;;; +FE8A;ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON YA;;;; +FE8B;ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR INITIAL ARABIC HAMZAH ON YA;;;; +FE8C;ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR MEDIAL ARABIC HAMZAH ON YA;;;; +FE8D;ARABIC LETTER ALEF ISOLATED FORM;Lo;0;AL; 0627;;;;N;GLYPH FOR ISOLATE ARABIC ALEF;;;; +FE8E;ARABIC LETTER ALEF FINAL FORM;Lo;0;AL; 0627;;;;N;GLYPH FOR FINAL ARABIC ALEF;;;; +FE8F;ARABIC LETTER BEH ISOLATED FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR ISOLATE ARABIC BAA;;;; +FE90;ARABIC LETTER BEH FINAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR FINAL ARABIC BAA;;;; +FE91;ARABIC LETTER BEH INITIAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR INITIAL ARABIC BAA;;;; +FE92;ARABIC LETTER BEH MEDIAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR MEDIAL ARABIC BAA;;;; +FE93;ARABIC LETTER TEH MARBUTA ISOLATED FORM;Lo;0;AL; 0629;;;;N;GLYPH FOR ISOLATE ARABIC TAA MARBUTAH;;;; +FE94;ARABIC LETTER TEH MARBUTA FINAL FORM;Lo;0;AL; 0629;;;;N;GLYPH FOR FINAL ARABIC TAA MARBUTAH;;;; +FE95;ARABIC LETTER TEH ISOLATED FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR ISOLATE ARABIC TAA;;;; +FE96;ARABIC LETTER TEH FINAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR FINAL ARABIC TAA;;;; +FE97;ARABIC LETTER TEH INITIAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR INITIAL ARABIC TAA;;;; +FE98;ARABIC LETTER TEH MEDIAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR MEDIAL ARABIC TAA;;;; +FE99;ARABIC LETTER THEH ISOLATED FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR ISOLATE ARABIC THAA;;;; +FE9A;ARABIC LETTER THEH FINAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR FINAL ARABIC THAA;;;; +FE9B;ARABIC LETTER THEH INITIAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR INITIAL ARABIC THAA;;;; +FE9C;ARABIC LETTER THEH MEDIAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR MEDIAL ARABIC THAA;;;; +FE9D;ARABIC LETTER JEEM ISOLATED FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR ISOLATE ARABIC JEEM;;;; +FE9E;ARABIC LETTER JEEM FINAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR FINAL ARABIC JEEM;;;; +FE9F;ARABIC LETTER JEEM INITIAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR INITIAL ARABIC JEEM;;;; +FEA0;ARABIC LETTER JEEM MEDIAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR MEDIAL ARABIC JEEM;;;; +FEA1;ARABIC LETTER HAH ISOLATED FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR ISOLATE ARABIC HAA;;;; +FEA2;ARABIC LETTER HAH FINAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR FINAL ARABIC HAA;;;; +FEA3;ARABIC LETTER HAH INITIAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR INITIAL ARABIC HAA;;;; +FEA4;ARABIC LETTER HAH MEDIAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR MEDIAL ARABIC HAA;;;; +FEA5;ARABIC LETTER KHAH ISOLATED FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR ISOLATE ARABIC KHAA;;;; +FEA6;ARABIC LETTER KHAH FINAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR FINAL ARABIC KHAA;;;; +FEA7;ARABIC LETTER KHAH INITIAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR INITIAL ARABIC KHAA;;;; +FEA8;ARABIC LETTER KHAH MEDIAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR MEDIAL ARABIC KHAA;;;; +FEA9;ARABIC LETTER DAL ISOLATED FORM;Lo;0;AL; 062F;;;;N;GLYPH FOR ISOLATE ARABIC DAL;;;; +FEAA;ARABIC LETTER DAL FINAL FORM;Lo;0;AL; 062F;;;;N;GLYPH FOR FINAL ARABIC DAL;;;; +FEAB;ARABIC LETTER THAL ISOLATED FORM;Lo;0;AL; 0630;;;;N;GLYPH FOR ISOLATE ARABIC THAL;;;; +FEAC;ARABIC LETTER THAL FINAL FORM;Lo;0;AL; 0630;;;;N;GLYPH FOR FINAL ARABIC THAL;;;; +FEAD;ARABIC LETTER REH ISOLATED FORM;Lo;0;AL; 0631;;;;N;GLYPH FOR ISOLATE ARABIC RA;;;; +FEAE;ARABIC LETTER REH FINAL FORM;Lo;0;AL; 0631;;;;N;GLYPH FOR FINAL ARABIC RA;;;; +FEAF;ARABIC LETTER ZAIN ISOLATED FORM;Lo;0;AL; 0632;;;;N;GLYPH FOR ISOLATE ARABIC ZAIN;;;; +FEB0;ARABIC LETTER ZAIN FINAL FORM;Lo;0;AL; 0632;;;;N;GLYPH FOR FINAL ARABIC ZAIN;;;; +FEB1;ARABIC LETTER SEEN ISOLATED FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR ISOLATE ARABIC SEEN;;;; +FEB2;ARABIC LETTER SEEN FINAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR FINAL ARABIC SEEN;;;; +FEB3;ARABIC LETTER SEEN INITIAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR INITIAL ARABIC SEEN;;;; +FEB4;ARABIC LETTER SEEN MEDIAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR MEDIAL ARABIC SEEN;;;; +FEB5;ARABIC LETTER SHEEN ISOLATED FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR ISOLATE ARABIC SHEEN;;;; +FEB6;ARABIC LETTER SHEEN FINAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR FINAL ARABIC SHEEN;;;; +FEB7;ARABIC LETTER SHEEN INITIAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR INITIAL ARABIC SHEEN;;;; +FEB8;ARABIC LETTER SHEEN MEDIAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR MEDIAL ARABIC SHEEN;;;; +FEB9;ARABIC LETTER SAD ISOLATED FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR ISOLATE ARABIC SAD;;;; +FEBA;ARABIC LETTER SAD FINAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR FINAL ARABIC SAD;;;; +FEBB;ARABIC LETTER SAD INITIAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR INITIAL ARABIC SAD;;;; +FEBC;ARABIC LETTER SAD MEDIAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR MEDIAL ARABIC SAD;;;; +FEBD;ARABIC LETTER DAD ISOLATED FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR ISOLATE ARABIC DAD;;;; +FEBE;ARABIC LETTER DAD FINAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR FINAL ARABIC DAD;;;; +FEBF;ARABIC LETTER DAD INITIAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR INITIAL ARABIC DAD;;;; +FEC0;ARABIC LETTER DAD MEDIAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR MEDIAL ARABIC DAD;;;; +FEC1;ARABIC LETTER TAH ISOLATED FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR ISOLATE ARABIC TAH;;;; +FEC2;ARABIC LETTER TAH FINAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR FINAL ARABIC TAH;;;; +FEC3;ARABIC LETTER TAH INITIAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR INITIAL ARABIC TAH;;;; +FEC4;ARABIC LETTER TAH MEDIAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR MEDIAL ARABIC TAH;;;; +FEC5;ARABIC LETTER ZAH ISOLATED FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR ISOLATE ARABIC DHAH;;;; +FEC6;ARABIC LETTER ZAH FINAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR FINAL ARABIC DHAH;;;; +FEC7;ARABIC LETTER ZAH INITIAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR INITIAL ARABIC DHAH;;;; +FEC8;ARABIC LETTER ZAH MEDIAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR MEDIAL ARABIC DHAH;;;; +FEC9;ARABIC LETTER AIN ISOLATED FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR ISOLATE ARABIC AIN;;;; +FECA;ARABIC LETTER AIN FINAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR FINAL ARABIC AIN;;;; +FECB;ARABIC LETTER AIN INITIAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR INITIAL ARABIC AIN;;;; +FECC;ARABIC LETTER AIN MEDIAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR MEDIAL ARABIC AIN;;;; +FECD;ARABIC LETTER GHAIN ISOLATED FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR ISOLATE ARABIC GHAIN;;;; +FECE;ARABIC LETTER GHAIN FINAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR FINAL ARABIC GHAIN;;;; +FECF;ARABIC LETTER GHAIN INITIAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR INITIAL ARABIC GHAIN;;;; +FED0;ARABIC LETTER GHAIN MEDIAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR MEDIAL ARABIC GHAIN;;;; +FED1;ARABIC LETTER FEH ISOLATED FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR ISOLATE ARABIC FA;;;; +FED2;ARABIC LETTER FEH FINAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR FINAL ARABIC FA;;;; +FED3;ARABIC LETTER FEH INITIAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR INITIAL ARABIC FA;;;; +FED4;ARABIC LETTER FEH MEDIAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR MEDIAL ARABIC FA;;;; +FED5;ARABIC LETTER QAF ISOLATED FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR ISOLATE ARABIC QAF;;;; +FED6;ARABIC LETTER QAF FINAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR FINAL ARABIC QAF;;;; +FED7;ARABIC LETTER QAF INITIAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR INITIAL ARABIC QAF;;;; +FED8;ARABIC LETTER QAF MEDIAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR MEDIAL ARABIC QAF;;;; +FED9;ARABIC LETTER KAF ISOLATED FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR ISOLATE ARABIC CAF;;;; +FEDA;ARABIC LETTER KAF FINAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR FINAL ARABIC CAF;;;; +FEDB;ARABIC LETTER KAF INITIAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR INITIAL ARABIC CAF;;;; +FEDC;ARABIC LETTER KAF MEDIAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR MEDIAL ARABIC CAF;;;; +FEDD;ARABIC LETTER LAM ISOLATED FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR ISOLATE ARABIC LAM;;;; +FEDE;ARABIC LETTER LAM FINAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR FINAL ARABIC LAM;;;; +FEDF;ARABIC LETTER LAM INITIAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR INITIAL ARABIC LAM;;;; +FEE0;ARABIC LETTER LAM MEDIAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR MEDIAL ARABIC LAM;;;; +FEE1;ARABIC LETTER MEEM ISOLATED FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR ISOLATE ARABIC MEEM;;;; +FEE2;ARABIC LETTER MEEM FINAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR FINAL ARABIC MEEM;;;; +FEE3;ARABIC LETTER MEEM INITIAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR INITIAL ARABIC MEEM;;;; +FEE4;ARABIC LETTER MEEM MEDIAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR MEDIAL ARABIC MEEM;;;; +FEE5;ARABIC LETTER NOON ISOLATED FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR ISOLATE ARABIC NOON;;;; +FEE6;ARABIC LETTER NOON FINAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR FINAL ARABIC NOON;;;; +FEE7;ARABIC LETTER NOON INITIAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR INITIAL ARABIC NOON;;;; +FEE8;ARABIC LETTER NOON MEDIAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR MEDIAL ARABIC NOON;;;; +FEE9;ARABIC LETTER HEH ISOLATED FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR ISOLATE ARABIC HA;;;; +FEEA;ARABIC LETTER HEH FINAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR FINAL ARABIC HA;;;; +FEEB;ARABIC LETTER HEH INITIAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR INITIAL ARABIC HA;;;; +FEEC;ARABIC LETTER HEH MEDIAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR MEDIAL ARABIC HA;;;; +FEED;ARABIC LETTER WAW ISOLATED FORM;Lo;0;AL; 0648;;;;N;GLYPH FOR ISOLATE ARABIC WAW;;;; +FEEE;ARABIC LETTER WAW FINAL FORM;Lo;0;AL; 0648;;;;N;GLYPH FOR FINAL ARABIC WAW;;;; +FEEF;ARABIC LETTER ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0649;;;;N;GLYPH FOR ISOLATE ARABIC ALEF MAQSURAH;;;; +FEF0;ARABIC LETTER ALEF MAKSURA FINAL FORM;Lo;0;AL; 0649;;;;N;GLYPH FOR FINAL ARABIC ALEF MAQSURAH;;;; +FEF1;ARABIC LETTER YEH ISOLATED FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR ISOLATE ARABIC YA;;;; +FEF2;ARABIC LETTER YEH FINAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR FINAL ARABIC YA;;;; +FEF3;ARABIC LETTER YEH INITIAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR INITIAL ARABIC YA;;;; +FEF4;ARABIC LETTER YEH MEDIAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR MEDIAL ARABIC YA;;;; +FEF5;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL; 0644 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON LIGATURE LAM ALEF;;;; +FEF6;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL; 0644 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON LIGATURE LAM ALEF;;;; +FEF7;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0644 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON LIGATURE LAM ALEF;;;; +FEF8;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0644 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON LIGATURE LAM ALEF;;;; +FEF9;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL; 0644 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;; +FEFA;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL; 0644 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;; +FEFB;ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM;Lo;0;AL; 0644 0627;;;;N;GLYPH FOR ISOLATE ARABIC LIGATURE LAM ALEF;;;; +FEFC;ARABIC LIGATURE LAM WITH ALEF FINAL FORM;Lo;0;AL; 0644 0627;;;;N;GLYPH FOR FINAL ARABIC LIGATURE LAM ALEF;;;; +FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; +FF01;FULLWIDTH EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; +FF02;FULLWIDTH QUOTATION MARK;Po;0;ON; 0022;;;;N;;;;; +FF03;FULLWIDTH NUMBER SIGN;Po;0;ET; 0023;;;;N;;;;; +FF04;FULLWIDTH DOLLAR SIGN;Sc;0;ET; 0024;;;;N;;;;; +FF05;FULLWIDTH PERCENT SIGN;Po;0;ET; 0025;;;;N;;;;; +FF06;FULLWIDTH AMPERSAND;Po;0;ON; 0026;;;;N;;;;; +FF07;FULLWIDTH APOSTROPHE;Po;0;ON; 0027;;;;N;;;;; +FF08;FULLWIDTH LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;FULLWIDTH OPENING PARENTHESIS;;;; +FF09;FULLWIDTH RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;FULLWIDTH CLOSING PARENTHESIS;;;; +FF0A;FULLWIDTH ASTERISK;Po;0;ON; 002A;;;;N;;;;; +FF0B;FULLWIDTH PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +FF0C;FULLWIDTH COMMA;Po;0;CS; 002C;;;;N;;;;; +FF0D;FULLWIDTH HYPHEN-MINUS;Pd;0;ES; 002D;;;;N;;;;; +FF0E;FULLWIDTH FULL STOP;Po;0;CS; 002E;;;;N;FULLWIDTH PERIOD;;;; +FF0F;FULLWIDTH SOLIDUS;Po;0;CS; 002F;;;;N;FULLWIDTH SLASH;;;; +FF10;FULLWIDTH DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +FF11;FULLWIDTH DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +FF12;FULLWIDTH DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +FF13;FULLWIDTH DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +FF14;FULLWIDTH DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +FF15;FULLWIDTH DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +FF16;FULLWIDTH DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +FF17;FULLWIDTH DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +FF18;FULLWIDTH DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +FF19;FULLWIDTH DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +FF1A;FULLWIDTH COLON;Po;0;CS; 003A;;;;N;;;;; +FF1B;FULLWIDTH SEMICOLON;Po;0;ON; 003B;;;;N;;;;; +FF1C;FULLWIDTH LESS-THAN SIGN;Sm;0;ON; 003C;;;;Y;;;;; +FF1D;FULLWIDTH EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +FF1E;FULLWIDTH GREATER-THAN SIGN;Sm;0;ON; 003E;;;;Y;;;;; +FF1F;FULLWIDTH QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; +FF20;FULLWIDTH COMMERCIAL AT;Po;0;ON; 0040;;;;N;;;;; +FF21;FULLWIDTH LATIN CAPITAL LETTER A;Lu;0;L; 0041;;;;N;;;;FF41; +FF22;FULLWIDTH LATIN CAPITAL LETTER B;Lu;0;L; 0042;;;;N;;;;FF42; +FF23;FULLWIDTH LATIN CAPITAL LETTER C;Lu;0;L; 0043;;;;N;;;;FF43; +FF24;FULLWIDTH LATIN CAPITAL LETTER D;Lu;0;L; 0044;;;;N;;;;FF44; +FF25;FULLWIDTH LATIN CAPITAL LETTER E;Lu;0;L; 0045;;;;N;;;;FF45; +FF26;FULLWIDTH LATIN CAPITAL LETTER F;Lu;0;L; 0046;;;;N;;;;FF46; +FF27;FULLWIDTH LATIN CAPITAL LETTER G;Lu;0;L; 0047;;;;N;;;;FF47; +FF28;FULLWIDTH LATIN CAPITAL LETTER H;Lu;0;L; 0048;;;;N;;;;FF48; +FF29;FULLWIDTH LATIN CAPITAL LETTER I;Lu;0;L; 0049;;;;N;;;;FF49; +FF2A;FULLWIDTH LATIN CAPITAL LETTER J;Lu;0;L; 004A;;;;N;;;;FF4A; +FF2B;FULLWIDTH LATIN CAPITAL LETTER K;Lu;0;L; 004B;;;;N;;;;FF4B; +FF2C;FULLWIDTH LATIN CAPITAL LETTER L;Lu;0;L; 004C;;;;N;;;;FF4C; +FF2D;FULLWIDTH LATIN CAPITAL LETTER M;Lu;0;L; 004D;;;;N;;;;FF4D; +FF2E;FULLWIDTH LATIN CAPITAL LETTER N;Lu;0;L; 004E;;;;N;;;;FF4E; +FF2F;FULLWIDTH LATIN CAPITAL LETTER O;Lu;0;L; 004F;;;;N;;;;FF4F; +FF30;FULLWIDTH LATIN CAPITAL LETTER P;Lu;0;L; 0050;;;;N;;;;FF50; +FF31;FULLWIDTH LATIN CAPITAL LETTER Q;Lu;0;L; 0051;;;;N;;;;FF51; +FF32;FULLWIDTH LATIN CAPITAL LETTER R;Lu;0;L; 0052;;;;N;;;;FF52; +FF33;FULLWIDTH LATIN CAPITAL LETTER S;Lu;0;L; 0053;;;;N;;;;FF53; +FF34;FULLWIDTH LATIN CAPITAL LETTER T;Lu;0;L; 0054;;;;N;;;;FF54; +FF35;FULLWIDTH LATIN CAPITAL LETTER U;Lu;0;L; 0055;;;;N;;;;FF55; +FF36;FULLWIDTH LATIN CAPITAL LETTER V;Lu;0;L; 0056;;;;N;;;;FF56; +FF37;FULLWIDTH LATIN CAPITAL LETTER W;Lu;0;L; 0057;;;;N;;;;FF57; +FF38;FULLWIDTH LATIN CAPITAL LETTER X;Lu;0;L; 0058;;;;N;;;;FF58; +FF39;FULLWIDTH LATIN CAPITAL LETTER Y;Lu;0;L; 0059;;;;N;;;;FF59; +FF3A;FULLWIDTH LATIN CAPITAL LETTER Z;Lu;0;L; 005A;;;;N;;;;FF5A; +FF3B;FULLWIDTH LEFT SQUARE BRACKET;Ps;0;ON; 005B;;;;Y;FULLWIDTH OPENING SQUARE BRACKET;;;; +FF3C;FULLWIDTH REVERSE SOLIDUS;Po;0;ON; 005C;;;;N;FULLWIDTH BACKSLASH;;;; +FF3D;FULLWIDTH RIGHT SQUARE BRACKET;Pe;0;ON; 005D;;;;Y;FULLWIDTH CLOSING SQUARE BRACKET;;;; +FF3E;FULLWIDTH CIRCUMFLEX ACCENT;Sk;0;ON; 005E;;;;N;FULLWIDTH SPACING CIRCUMFLEX;;;; +FF3F;FULLWIDTH LOW LINE;Pc;0;ON; 005F;;;;N;FULLWIDTH SPACING UNDERSCORE;;;; +FF40;FULLWIDTH GRAVE ACCENT;Sk;0;ON; 0060;;;;N;FULLWIDTH SPACING GRAVE;;;; +FF41;FULLWIDTH LATIN SMALL LETTER A;Ll;0;L; 0061;;;;N;;;FF21;;FF21 +FF42;FULLWIDTH LATIN SMALL LETTER B;Ll;0;L; 0062;;;;N;;;FF22;;FF22 +FF43;FULLWIDTH LATIN SMALL LETTER C;Ll;0;L; 0063;;;;N;;;FF23;;FF23 +FF44;FULLWIDTH LATIN SMALL LETTER D;Ll;0;L; 0064;;;;N;;;FF24;;FF24 +FF45;FULLWIDTH LATIN SMALL LETTER E;Ll;0;L; 0065;;;;N;;;FF25;;FF25 +FF46;FULLWIDTH LATIN SMALL LETTER F;Ll;0;L; 0066;;;;N;;;FF26;;FF26 +FF47;FULLWIDTH LATIN SMALL LETTER G;Ll;0;L; 0067;;;;N;;;FF27;;FF27 +FF48;FULLWIDTH LATIN SMALL LETTER H;Ll;0;L; 0068;;;;N;;;FF28;;FF28 +FF49;FULLWIDTH LATIN SMALL LETTER I;Ll;0;L; 0069;;;;N;;;FF29;;FF29 +FF4A;FULLWIDTH LATIN SMALL LETTER J;Ll;0;L; 006A;;;;N;;;FF2A;;FF2A +FF4B;FULLWIDTH LATIN SMALL LETTER K;Ll;0;L; 006B;;;;N;;;FF2B;;FF2B +FF4C;FULLWIDTH LATIN SMALL LETTER L;Ll;0;L; 006C;;;;N;;;FF2C;;FF2C +FF4D;FULLWIDTH LATIN SMALL LETTER M;Ll;0;L; 006D;;;;N;;;FF2D;;FF2D +FF4E;FULLWIDTH LATIN SMALL LETTER N;Ll;0;L; 006E;;;;N;;;FF2E;;FF2E +FF4F;FULLWIDTH LATIN SMALL LETTER O;Ll;0;L; 006F;;;;N;;;FF2F;;FF2F +FF50;FULLWIDTH LATIN SMALL LETTER P;Ll;0;L; 0070;;;;N;;;FF30;;FF30 +FF51;FULLWIDTH LATIN SMALL LETTER Q;Ll;0;L; 0071;;;;N;;;FF31;;FF31 +FF52;FULLWIDTH LATIN SMALL LETTER R;Ll;0;L; 0072;;;;N;;;FF32;;FF32 +FF53;FULLWIDTH LATIN SMALL LETTER S;Ll;0;L; 0073;;;;N;;;FF33;;FF33 +FF54;FULLWIDTH LATIN SMALL LETTER T;Ll;0;L; 0074;;;;N;;;FF34;;FF34 +FF55;FULLWIDTH LATIN SMALL LETTER U;Ll;0;L; 0075;;;;N;;;FF35;;FF35 +FF56;FULLWIDTH LATIN SMALL LETTER V;Ll;0;L; 0076;;;;N;;;FF36;;FF36 +FF57;FULLWIDTH LATIN SMALL LETTER W;Ll;0;L; 0077;;;;N;;;FF37;;FF37 +FF58;FULLWIDTH LATIN SMALL LETTER X;Ll;0;L; 0078;;;;N;;;FF38;;FF38 +FF59;FULLWIDTH LATIN SMALL LETTER Y;Ll;0;L; 0079;;;;N;;;FF39;;FF39 +FF5A;FULLWIDTH LATIN SMALL LETTER Z;Ll;0;L; 007A;;;;N;;;FF3A;;FF3A +FF5B;FULLWIDTH LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;Y;FULLWIDTH OPENING CURLY BRACKET;;;; +FF5C;FULLWIDTH VERTICAL LINE;Sm;0;ON; 007C;;;;N;FULLWIDTH VERTICAL BAR;;;; +FF5D;FULLWIDTH RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;Y;FULLWIDTH CLOSING CURLY BRACKET;;;; +FF5E;FULLWIDTH TILDE;Sm;0;ON; 007E;;;;N;FULLWIDTH SPACING TILDE;;;; +FF5F;FULLWIDTH LEFT WHITE PARENTHESIS;Ps;0;ON; 2985;;;;Y;;;;; +FF60;FULLWIDTH RIGHT WHITE PARENTHESIS;Pe;0;ON; 2986;;;;Y;;;;; +FF61;HALFWIDTH IDEOGRAPHIC FULL STOP;Po;0;ON; 3002;;;;N;HALFWIDTH IDEOGRAPHIC PERIOD;;;; +FF62;HALFWIDTH LEFT CORNER BRACKET;Ps;0;ON; 300C;;;;Y;HALFWIDTH OPENING CORNER BRACKET;;;; +FF63;HALFWIDTH RIGHT CORNER BRACKET;Pe;0;ON; 300D;;;;Y;HALFWIDTH CLOSING CORNER BRACKET;;;; +FF64;HALFWIDTH IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; +FF65;HALFWIDTH KATAKANA MIDDLE DOT;Po;0;ON; 30FB;;;;N;;;;; +FF66;HALFWIDTH KATAKANA LETTER WO;Lo;0;L; 30F2;;;;N;;;;; +FF67;HALFWIDTH KATAKANA LETTER SMALL A;Lo;0;L; 30A1;;;;N;;;;; +FF68;HALFWIDTH KATAKANA LETTER SMALL I;Lo;0;L; 30A3;;;;N;;;;; +FF69;HALFWIDTH KATAKANA LETTER SMALL U;Lo;0;L; 30A5;;;;N;;;;; +FF6A;HALFWIDTH KATAKANA LETTER SMALL E;Lo;0;L; 30A7;;;;N;;;;; +FF6B;HALFWIDTH KATAKANA LETTER SMALL O;Lo;0;L; 30A9;;;;N;;;;; +FF6C;HALFWIDTH KATAKANA LETTER SMALL YA;Lo;0;L; 30E3;;;;N;;;;; +FF6D;HALFWIDTH KATAKANA LETTER SMALL YU;Lo;0;L; 30E5;;;;N;;;;; +FF6E;HALFWIDTH KATAKANA LETTER SMALL YO;Lo;0;L; 30E7;;;;N;;;;; +FF6F;HALFWIDTH KATAKANA LETTER SMALL TU;Lo;0;L; 30C3;;;;N;;;;; +FF70;HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L; 30FC;;;;N;;;;; +FF71;HALFWIDTH KATAKANA LETTER A;Lo;0;L; 30A2;;;;N;;;;; +FF72;HALFWIDTH KATAKANA LETTER I;Lo;0;L; 30A4;;;;N;;;;; +FF73;HALFWIDTH KATAKANA LETTER U;Lo;0;L; 30A6;;;;N;;;;; +FF74;HALFWIDTH KATAKANA LETTER E;Lo;0;L; 30A8;;;;N;;;;; +FF75;HALFWIDTH KATAKANA LETTER O;Lo;0;L; 30AA;;;;N;;;;; +FF76;HALFWIDTH KATAKANA LETTER KA;Lo;0;L; 30AB;;;;N;;;;; +FF77;HALFWIDTH KATAKANA LETTER KI;Lo;0;L; 30AD;;;;N;;;;; +FF78;HALFWIDTH KATAKANA LETTER KU;Lo;0;L; 30AF;;;;N;;;;; +FF79;HALFWIDTH KATAKANA LETTER KE;Lo;0;L; 30B1;;;;N;;;;; +FF7A;HALFWIDTH KATAKANA LETTER KO;Lo;0;L; 30B3;;;;N;;;;; +FF7B;HALFWIDTH KATAKANA LETTER SA;Lo;0;L; 30B5;;;;N;;;;; +FF7C;HALFWIDTH KATAKANA LETTER SI;Lo;0;L; 30B7;;;;N;;;;; +FF7D;HALFWIDTH KATAKANA LETTER SU;Lo;0;L; 30B9;;;;N;;;;; +FF7E;HALFWIDTH KATAKANA LETTER SE;Lo;0;L; 30BB;;;;N;;;;; +FF7F;HALFWIDTH KATAKANA LETTER SO;Lo;0;L; 30BD;;;;N;;;;; +FF80;HALFWIDTH KATAKANA LETTER TA;Lo;0;L; 30BF;;;;N;;;;; +FF81;HALFWIDTH KATAKANA LETTER TI;Lo;0;L; 30C1;;;;N;;;;; +FF82;HALFWIDTH KATAKANA LETTER TU;Lo;0;L; 30C4;;;;N;;;;; +FF83;HALFWIDTH KATAKANA LETTER TE;Lo;0;L; 30C6;;;;N;;;;; +FF84;HALFWIDTH KATAKANA LETTER TO;Lo;0;L; 30C8;;;;N;;;;; +FF85;HALFWIDTH KATAKANA LETTER NA;Lo;0;L; 30CA;;;;N;;;;; +FF86;HALFWIDTH KATAKANA LETTER NI;Lo;0;L; 30CB;;;;N;;;;; +FF87;HALFWIDTH KATAKANA LETTER NU;Lo;0;L; 30CC;;;;N;;;;; +FF88;HALFWIDTH KATAKANA LETTER NE;Lo;0;L; 30CD;;;;N;;;;; +FF89;HALFWIDTH KATAKANA LETTER NO;Lo;0;L; 30CE;;;;N;;;;; +FF8A;HALFWIDTH KATAKANA LETTER HA;Lo;0;L; 30CF;;;;N;;;;; +FF8B;HALFWIDTH KATAKANA LETTER HI;Lo;0;L; 30D2;;;;N;;;;; +FF8C;HALFWIDTH KATAKANA LETTER HU;Lo;0;L; 30D5;;;;N;;;;; +FF8D;HALFWIDTH KATAKANA LETTER HE;Lo;0;L; 30D8;;;;N;;;;; +FF8E;HALFWIDTH KATAKANA LETTER HO;Lo;0;L; 30DB;;;;N;;;;; +FF8F;HALFWIDTH KATAKANA LETTER MA;Lo;0;L; 30DE;;;;N;;;;; +FF90;HALFWIDTH KATAKANA LETTER MI;Lo;0;L; 30DF;;;;N;;;;; +FF91;HALFWIDTH KATAKANA LETTER MU;Lo;0;L; 30E0;;;;N;;;;; +FF92;HALFWIDTH KATAKANA LETTER ME;Lo;0;L; 30E1;;;;N;;;;; +FF93;HALFWIDTH KATAKANA LETTER MO;Lo;0;L; 30E2;;;;N;;;;; +FF94;HALFWIDTH KATAKANA LETTER YA;Lo;0;L; 30E4;;;;N;;;;; +FF95;HALFWIDTH KATAKANA LETTER YU;Lo;0;L; 30E6;;;;N;;;;; +FF96;HALFWIDTH KATAKANA LETTER YO;Lo;0;L; 30E8;;;;N;;;;; +FF97;HALFWIDTH KATAKANA LETTER RA;Lo;0;L; 30E9;;;;N;;;;; +FF98;HALFWIDTH KATAKANA LETTER RI;Lo;0;L; 30EA;;;;N;;;;; +FF99;HALFWIDTH KATAKANA LETTER RU;Lo;0;L; 30EB;;;;N;;;;; +FF9A;HALFWIDTH KATAKANA LETTER RE;Lo;0;L; 30EC;;;;N;;;;; +FF9B;HALFWIDTH KATAKANA LETTER RO;Lo;0;L; 30ED;;;;N;;;;; +FF9C;HALFWIDTH KATAKANA LETTER WA;Lo;0;L; 30EF;;;;N;;;;; +FF9D;HALFWIDTH KATAKANA LETTER N;Lo;0;L; 30F3;;;;N;;;;; +FF9E;HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L; 3099;;;;N;;;;; +FF9F;HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L; 309A;;;;N;;;;; +FFA0;HALFWIDTH HANGUL FILLER;Lo;0;L; 3164;;;;N;HALFWIDTH HANGUL CAE OM;;;; +FFA1;HALFWIDTH HANGUL LETTER KIYEOK;Lo;0;L; 3131;;;;N;HALFWIDTH HANGUL LETTER GIYEOG;;;; +FFA2;HALFWIDTH HANGUL LETTER SSANGKIYEOK;Lo;0;L; 3132;;;;N;HALFWIDTH HANGUL LETTER SSANG GIYEOG;;;; +FFA3;HALFWIDTH HANGUL LETTER KIYEOK-SIOS;Lo;0;L; 3133;;;;N;HALFWIDTH HANGUL LETTER GIYEOG SIOS;;;; +FFA4;HALFWIDTH HANGUL LETTER NIEUN;Lo;0;L; 3134;;;;N;;;;; +FFA5;HALFWIDTH HANGUL LETTER NIEUN-CIEUC;Lo;0;L; 3135;;;;N;HALFWIDTH HANGUL LETTER NIEUN JIEUJ;;;; +FFA6;HALFWIDTH HANGUL LETTER NIEUN-HIEUH;Lo;0;L; 3136;;;;N;HALFWIDTH HANGUL LETTER NIEUN HIEUH;;;; +FFA7;HALFWIDTH HANGUL LETTER TIKEUT;Lo;0;L; 3137;;;;N;HALFWIDTH HANGUL LETTER DIGEUD;;;; +FFA8;HALFWIDTH HANGUL LETTER SSANGTIKEUT;Lo;0;L; 3138;;;;N;HALFWIDTH HANGUL LETTER SSANG DIGEUD;;;; +FFA9;HALFWIDTH HANGUL LETTER RIEUL;Lo;0;L; 3139;;;;N;HALFWIDTH HANGUL LETTER LIEUL;;;; +FFAA;HALFWIDTH HANGUL LETTER RIEUL-KIYEOK;Lo;0;L; 313A;;;;N;HALFWIDTH HANGUL LETTER LIEUL GIYEOG;;;; +FFAB;HALFWIDTH HANGUL LETTER RIEUL-MIEUM;Lo;0;L; 313B;;;;N;HALFWIDTH HANGUL LETTER LIEUL MIEUM;;;; +FFAC;HALFWIDTH HANGUL LETTER RIEUL-PIEUP;Lo;0;L; 313C;;;;N;HALFWIDTH HANGUL LETTER LIEUL BIEUB;;;; +FFAD;HALFWIDTH HANGUL LETTER RIEUL-SIOS;Lo;0;L; 313D;;;;N;HALFWIDTH HANGUL LETTER LIEUL SIOS;;;; +FFAE;HALFWIDTH HANGUL LETTER RIEUL-THIEUTH;Lo;0;L; 313E;;;;N;HALFWIDTH HANGUL LETTER LIEUL TIEUT;;;; +FFAF;HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L; 313F;;;;N;HALFWIDTH HANGUL LETTER LIEUL PIEUP;;;; +FFB0;HALFWIDTH HANGUL LETTER RIEUL-HIEUH;Lo;0;L; 3140;;;;N;HALFWIDTH HANGUL LETTER LIEUL HIEUH;;;; +FFB1;HALFWIDTH HANGUL LETTER MIEUM;Lo;0;L; 3141;;;;N;;;;; +FFB2;HALFWIDTH HANGUL LETTER PIEUP;Lo;0;L; 3142;;;;N;HALFWIDTH HANGUL LETTER BIEUB;;;; +FFB3;HALFWIDTH HANGUL LETTER SSANGPIEUP;Lo;0;L; 3143;;;;N;HALFWIDTH HANGUL LETTER SSANG BIEUB;;;; +FFB4;HALFWIDTH HANGUL LETTER PIEUP-SIOS;Lo;0;L; 3144;;;;N;HALFWIDTH HANGUL LETTER BIEUB SIOS;;;; +FFB5;HALFWIDTH HANGUL LETTER SIOS;Lo;0;L; 3145;;;;N;;;;; +FFB6;HALFWIDTH HANGUL LETTER SSANGSIOS;Lo;0;L; 3146;;;;N;HALFWIDTH HANGUL LETTER SSANG SIOS;;;; +FFB7;HALFWIDTH HANGUL LETTER IEUNG;Lo;0;L; 3147;;;;N;;;;; +FFB8;HALFWIDTH HANGUL LETTER CIEUC;Lo;0;L; 3148;;;;N;HALFWIDTH HANGUL LETTER JIEUJ;;;; +FFB9;HALFWIDTH HANGUL LETTER SSANGCIEUC;Lo;0;L; 3149;;;;N;HALFWIDTH HANGUL LETTER SSANG JIEUJ;;;; +FFBA;HALFWIDTH HANGUL LETTER CHIEUCH;Lo;0;L; 314A;;;;N;HALFWIDTH HANGUL LETTER CIEUC;;;; +FFBB;HALFWIDTH HANGUL LETTER KHIEUKH;Lo;0;L; 314B;;;;N;HALFWIDTH HANGUL LETTER KIYEOK;;;; +FFBC;HALFWIDTH HANGUL LETTER THIEUTH;Lo;0;L; 314C;;;;N;HALFWIDTH HANGUL LETTER TIEUT;;;; +FFBD;HALFWIDTH HANGUL LETTER PHIEUPH;Lo;0;L; 314D;;;;N;HALFWIDTH HANGUL LETTER PIEUP;;;; +FFBE;HALFWIDTH HANGUL LETTER HIEUH;Lo;0;L; 314E;;;;N;;;;; +FFC2;HALFWIDTH HANGUL LETTER A;Lo;0;L; 314F;;;;N;;;;; +FFC3;HALFWIDTH HANGUL LETTER AE;Lo;0;L; 3150;;;;N;;;;; +FFC4;HALFWIDTH HANGUL LETTER YA;Lo;0;L; 3151;;;;N;;;;; +FFC5;HALFWIDTH HANGUL LETTER YAE;Lo;0;L; 3152;;;;N;;;;; +FFC6;HALFWIDTH HANGUL LETTER EO;Lo;0;L; 3153;;;;N;;;;; +FFC7;HALFWIDTH HANGUL LETTER E;Lo;0;L; 3154;;;;N;;;;; +FFCA;HALFWIDTH HANGUL LETTER YEO;Lo;0;L; 3155;;;;N;;;;; +FFCB;HALFWIDTH HANGUL LETTER YE;Lo;0;L; 3156;;;;N;;;;; +FFCC;HALFWIDTH HANGUL LETTER O;Lo;0;L; 3157;;;;N;;;;; +FFCD;HALFWIDTH HANGUL LETTER WA;Lo;0;L; 3158;;;;N;;;;; +FFCE;HALFWIDTH HANGUL LETTER WAE;Lo;0;L; 3159;;;;N;;;;; +FFCF;HALFWIDTH HANGUL LETTER OE;Lo;0;L; 315A;;;;N;;;;; +FFD2;HALFWIDTH HANGUL LETTER YO;Lo;0;L; 315B;;;;N;;;;; +FFD3;HALFWIDTH HANGUL LETTER U;Lo;0;L; 315C;;;;N;;;;; +FFD4;HALFWIDTH HANGUL LETTER WEO;Lo;0;L; 315D;;;;N;;;;; +FFD5;HALFWIDTH HANGUL LETTER WE;Lo;0;L; 315E;;;;N;;;;; +FFD6;HALFWIDTH HANGUL LETTER WI;Lo;0;L; 315F;;;;N;;;;; +FFD7;HALFWIDTH HANGUL LETTER YU;Lo;0;L; 3160;;;;N;;;;; +FFDA;HALFWIDTH HANGUL LETTER EU;Lo;0;L; 3161;;;;N;;;;; +FFDB;HALFWIDTH HANGUL LETTER YI;Lo;0;L; 3162;;;;N;;;;; +FFDC;HALFWIDTH HANGUL LETTER I;Lo;0;L; 3163;;;;N;;;;; +FFE0;FULLWIDTH CENT SIGN;Sc;0;ET; 00A2;;;;N;;;;; +FFE1;FULLWIDTH POUND SIGN;Sc;0;ET; 00A3;;;;N;;;;; +FFE2;FULLWIDTH NOT SIGN;Sm;0;ON; 00AC;;;;N;;;;; +FFE3;FULLWIDTH MACRON;Sk;0;ON; 00AF;;;;N;FULLWIDTH SPACING MACRON;;;; +FFE4;FULLWIDTH BROKEN BAR;So;0;ON; 00A6;;;;N;FULLWIDTH BROKEN VERTICAL BAR;;;; +FFE5;FULLWIDTH YEN SIGN;Sc;0;ET; 00A5;;;;N;;;;; +FFE6;FULLWIDTH WON SIGN;Sc;0;ET; 20A9;;;;N;;;;; +FFE8;HALFWIDTH FORMS LIGHT VERTICAL;So;0;ON; 2502;;;;N;;;;; +FFE9;HALFWIDTH LEFTWARDS ARROW;Sm;0;ON; 2190;;;;N;;;;; +FFEA;HALFWIDTH UPWARDS ARROW;Sm;0;ON; 2191;;;;N;;;;; +FFEB;HALFWIDTH RIGHTWARDS ARROW;Sm;0;ON; 2192;;;;N;;;;; +FFEC;HALFWIDTH DOWNWARDS ARROW;Sm;0;ON; 2193;;;;N;;;;; +FFED;HALFWIDTH BLACK SQUARE;So;0;ON; 25A0;;;;N;;;;; +FFEE;HALFWIDTH WHITE CIRCLE;So;0;ON; 25CB;;;;N;;;;; +FFF9;INTERLINEAR ANNOTATION ANCHOR;Cf;0;ON;;;;;N;;;;; +FFFA;INTERLINEAR ANNOTATION SEPARATOR;Cf;0;ON;;;;;N;;;;; +FFFB;INTERLINEAR ANNOTATION TERMINATOR;Cf;0;ON;;;;;N;;;;; +FFFC;OBJECT REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; +FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; +10000;LINEAR B SYLLABLE B008 A;Lo;0;L;;;;;N;;;;; +10001;LINEAR B SYLLABLE B038 E;Lo;0;L;;;;;N;;;;; +10002;LINEAR B SYLLABLE B028 I;Lo;0;L;;;;;N;;;;; +10003;LINEAR B SYLLABLE B061 O;Lo;0;L;;;;;N;;;;; +10004;LINEAR B SYLLABLE B010 U;Lo;0;L;;;;;N;;;;; +10005;LINEAR B SYLLABLE B001 DA;Lo;0;L;;;;;N;;;;; +10006;LINEAR B SYLLABLE B045 DE;Lo;0;L;;;;;N;;;;; +10007;LINEAR B SYLLABLE B007 DI;Lo;0;L;;;;;N;;;;; +10008;LINEAR B SYLLABLE B014 DO;Lo;0;L;;;;;N;;;;; +10009;LINEAR B SYLLABLE B051 DU;Lo;0;L;;;;;N;;;;; +1000A;LINEAR B SYLLABLE B057 JA;Lo;0;L;;;;;N;;;;; +1000B;LINEAR B SYLLABLE B046 JE;Lo;0;L;;;;;N;;;;; +1000D;LINEAR B SYLLABLE B036 JO;Lo;0;L;;;;;N;;;;; +1000E;LINEAR B SYLLABLE B065 JU;Lo;0;L;;;;;N;;;;; +1000F;LINEAR B SYLLABLE B077 KA;Lo;0;L;;;;;N;;;;; +10010;LINEAR B SYLLABLE B044 KE;Lo;0;L;;;;;N;;;;; +10011;LINEAR B SYLLABLE B067 KI;Lo;0;L;;;;;N;;;;; +10012;LINEAR B SYLLABLE B070 KO;Lo;0;L;;;;;N;;;;; +10013;LINEAR B SYLLABLE B081 KU;Lo;0;L;;;;;N;;;;; +10014;LINEAR B SYLLABLE B080 MA;Lo;0;L;;;;;N;;;;; +10015;LINEAR B SYLLABLE B013 ME;Lo;0;L;;;;;N;;;;; +10016;LINEAR B SYLLABLE B073 MI;Lo;0;L;;;;;N;;;;; +10017;LINEAR B SYLLABLE B015 MO;Lo;0;L;;;;;N;;;;; +10018;LINEAR B SYLLABLE B023 MU;Lo;0;L;;;;;N;;;;; +10019;LINEAR B SYLLABLE B006 NA;Lo;0;L;;;;;N;;;;; +1001A;LINEAR B SYLLABLE B024 NE;Lo;0;L;;;;;N;;;;; +1001B;LINEAR B SYLLABLE B030 NI;Lo;0;L;;;;;N;;;;; +1001C;LINEAR B SYLLABLE B052 NO;Lo;0;L;;;;;N;;;;; +1001D;LINEAR B SYLLABLE B055 NU;Lo;0;L;;;;;N;;;;; +1001E;LINEAR B SYLLABLE B003 PA;Lo;0;L;;;;;N;;;;; +1001F;LINEAR B SYLLABLE B072 PE;Lo;0;L;;;;;N;;;;; +10020;LINEAR B SYLLABLE B039 PI;Lo;0;L;;;;;N;;;;; +10021;LINEAR B SYLLABLE B011 PO;Lo;0;L;;;;;N;;;;; +10022;LINEAR B SYLLABLE B050 PU;Lo;0;L;;;;;N;;;;; +10023;LINEAR B SYLLABLE B016 QA;Lo;0;L;;;;;N;;;;; +10024;LINEAR B SYLLABLE B078 QE;Lo;0;L;;;;;N;;;;; +10025;LINEAR B SYLLABLE B021 QI;Lo;0;L;;;;;N;;;;; +10026;LINEAR B SYLLABLE B032 QO;Lo;0;L;;;;;N;;;;; +10028;LINEAR B SYLLABLE B060 RA;Lo;0;L;;;;;N;;;;; +10029;LINEAR B SYLLABLE B027 RE;Lo;0;L;;;;;N;;;;; +1002A;LINEAR B SYLLABLE B053 RI;Lo;0;L;;;;;N;;;;; +1002B;LINEAR B SYLLABLE B002 RO;Lo;0;L;;;;;N;;;;; +1002C;LINEAR B SYLLABLE B026 RU;Lo;0;L;;;;;N;;;;; +1002D;LINEAR B SYLLABLE B031 SA;Lo;0;L;;;;;N;;;;; +1002E;LINEAR B SYLLABLE B009 SE;Lo;0;L;;;;;N;;;;; +1002F;LINEAR B SYLLABLE B041 SI;Lo;0;L;;;;;N;;;;; +10030;LINEAR B SYLLABLE B012 SO;Lo;0;L;;;;;N;;;;; +10031;LINEAR B SYLLABLE B058 SU;Lo;0;L;;;;;N;;;;; +10032;LINEAR B SYLLABLE B059 TA;Lo;0;L;;;;;N;;;;; +10033;LINEAR B SYLLABLE B004 TE;Lo;0;L;;;;;N;;;;; +10034;LINEAR B SYLLABLE B037 TI;Lo;0;L;;;;;N;;;;; +10035;LINEAR B SYLLABLE B005 TO;Lo;0;L;;;;;N;;;;; +10036;LINEAR B SYLLABLE B069 TU;Lo;0;L;;;;;N;;;;; +10037;LINEAR B SYLLABLE B054 WA;Lo;0;L;;;;;N;;;;; +10038;LINEAR B SYLLABLE B075 WE;Lo;0;L;;;;;N;;;;; +10039;LINEAR B SYLLABLE B040 WI;Lo;0;L;;;;;N;;;;; +1003A;LINEAR B SYLLABLE B042 WO;Lo;0;L;;;;;N;;;;; +1003C;LINEAR B SYLLABLE B017 ZA;Lo;0;L;;;;;N;;;;; +1003D;LINEAR B SYLLABLE B074 ZE;Lo;0;L;;;;;N;;;;; +1003F;LINEAR B SYLLABLE B020 ZO;Lo;0;L;;;;;N;;;;; +10040;LINEAR B SYLLABLE B025 A2;Lo;0;L;;;;;N;;;;; +10041;LINEAR B SYLLABLE B043 A3;Lo;0;L;;;;;N;;;;; +10042;LINEAR B SYLLABLE B085 AU;Lo;0;L;;;;;N;;;;; +10043;LINEAR B SYLLABLE B071 DWE;Lo;0;L;;;;;N;;;;; +10044;LINEAR B SYLLABLE B090 DWO;Lo;0;L;;;;;N;;;;; +10045;LINEAR B SYLLABLE B048 NWA;Lo;0;L;;;;;N;;;;; +10046;LINEAR B SYLLABLE B029 PU2;Lo;0;L;;;;;N;;;;; +10047;LINEAR B SYLLABLE B062 PTE;Lo;0;L;;;;;N;;;;; +10048;LINEAR B SYLLABLE B076 RA2;Lo;0;L;;;;;N;;;;; +10049;LINEAR B SYLLABLE B033 RA3;Lo;0;L;;;;;N;;;;; +1004A;LINEAR B SYLLABLE B068 RO2;Lo;0;L;;;;;N;;;;; +1004B;LINEAR B SYLLABLE B066 TA2;Lo;0;L;;;;;N;;;;; +1004C;LINEAR B SYLLABLE B087 TWE;Lo;0;L;;;;;N;;;;; +1004D;LINEAR B SYLLABLE B091 TWO;Lo;0;L;;;;;N;;;;; +10050;LINEAR B SYMBOL B018;Lo;0;L;;;;;N;;;;; +10051;LINEAR B SYMBOL B019;Lo;0;L;;;;;N;;;;; +10052;LINEAR B SYMBOL B022;Lo;0;L;;;;;N;;;;; +10053;LINEAR B SYMBOL B034;Lo;0;L;;;;;N;;;;; +10054;LINEAR B SYMBOL B047;Lo;0;L;;;;;N;;;;; +10055;LINEAR B SYMBOL B049;Lo;0;L;;;;;N;;;;; +10056;LINEAR B SYMBOL B056;Lo;0;L;;;;;N;;;;; +10057;LINEAR B SYMBOL B063;Lo;0;L;;;;;N;;;;; +10058;LINEAR B SYMBOL B064;Lo;0;L;;;;;N;;;;; +10059;LINEAR B SYMBOL B079;Lo;0;L;;;;;N;;;;; +1005A;LINEAR B SYMBOL B082;Lo;0;L;;;;;N;;;;; +1005B;LINEAR B SYMBOL B083;Lo;0;L;;;;;N;;;;; +1005C;LINEAR B SYMBOL B086;Lo;0;L;;;;;N;;;;; +1005D;LINEAR B SYMBOL B089;Lo;0;L;;;;;N;;;;; +10080;LINEAR B IDEOGRAM B100 MAN;Lo;0;L;;;;;N;;;;; +10081;LINEAR B IDEOGRAM B102 WOMAN;Lo;0;L;;;;;N;;;;; +10082;LINEAR B IDEOGRAM B104 DEER;Lo;0;L;;;;;N;;;;; +10083;LINEAR B IDEOGRAM B105 EQUID;Lo;0;L;;;;;N;;;;; +10084;LINEAR B IDEOGRAM B105F MARE;Lo;0;L;;;;;N;;;;; +10085;LINEAR B IDEOGRAM B105M STALLION;Lo;0;L;;;;;N;;;;; +10086;LINEAR B IDEOGRAM B106F EWE;Lo;0;L;;;;;N;;;;; +10087;LINEAR B IDEOGRAM B106M RAM;Lo;0;L;;;;;N;;;;; +10088;LINEAR B IDEOGRAM B107F SHE-GOAT;Lo;0;L;;;;;N;;;;; +10089;LINEAR B IDEOGRAM B107M HE-GOAT;Lo;0;L;;;;;N;;;;; +1008A;LINEAR B IDEOGRAM B108F SOW;Lo;0;L;;;;;N;;;;; +1008B;LINEAR B IDEOGRAM B108M BOAR;Lo;0;L;;;;;N;;;;; +1008C;LINEAR B IDEOGRAM B109F COW;Lo;0;L;;;;;N;;;;; +1008D;LINEAR B IDEOGRAM B109M BULL;Lo;0;L;;;;;N;;;;; +1008E;LINEAR B IDEOGRAM B120 WHEAT;Lo;0;L;;;;;N;;;;; +1008F;LINEAR B IDEOGRAM B121 BARLEY;Lo;0;L;;;;;N;;;;; +10090;LINEAR B IDEOGRAM B122 OLIVE;Lo;0;L;;;;;N;;;;; +10091;LINEAR B IDEOGRAM B123 SPICE;Lo;0;L;;;;;N;;;;; +10092;LINEAR B IDEOGRAM B125 CYPERUS;Lo;0;L;;;;;N;;;;; +10093;LINEAR B MONOGRAM B127 KAPO;Lo;0;L;;;;;N;;;;; +10094;LINEAR B MONOGRAM B128 KANAKO;Lo;0;L;;;;;N;;;;; +10095;LINEAR B IDEOGRAM B130 OIL;Lo;0;L;;;;;N;;;;; +10096;LINEAR B IDEOGRAM B131 WINE;Lo;0;L;;;;;N;;;;; +10097;LINEAR B IDEOGRAM B132;Lo;0;L;;;;;N;;;;; +10098;LINEAR B MONOGRAM B133 AREPA;Lo;0;L;;;;;N;;;;; +10099;LINEAR B MONOGRAM B135 MERI;Lo;0;L;;;;;N;;;;; +1009A;LINEAR B IDEOGRAM B140 BRONZE;Lo;0;L;;;;;N;;;;; +1009B;LINEAR B IDEOGRAM B141 GOLD;Lo;0;L;;;;;N;;;;; +1009C;LINEAR B IDEOGRAM B142;Lo;0;L;;;;;N;;;;; +1009D;LINEAR B IDEOGRAM B145 WOOL;Lo;0;L;;;;;N;;;;; +1009E;LINEAR B IDEOGRAM B146;Lo;0;L;;;;;N;;;;; +1009F;LINEAR B IDEOGRAM B150;Lo;0;L;;;;;N;;;;; +100A0;LINEAR B IDEOGRAM B151 HORN;Lo;0;L;;;;;N;;;;; +100A1;LINEAR B IDEOGRAM B152;Lo;0;L;;;;;N;;;;; +100A2;LINEAR B IDEOGRAM B153;Lo;0;L;;;;;N;;;;; +100A3;LINEAR B IDEOGRAM B154;Lo;0;L;;;;;N;;;;; +100A4;LINEAR B MONOGRAM B156 TURO2;Lo;0;L;;;;;N;;;;; +100A5;LINEAR B IDEOGRAM B157;Lo;0;L;;;;;N;;;;; +100A6;LINEAR B IDEOGRAM B158;Lo;0;L;;;;;N;;;;; +100A7;LINEAR B IDEOGRAM B159 CLOTH;Lo;0;L;;;;;N;;;;; +100A8;LINEAR B IDEOGRAM B160;Lo;0;L;;;;;N;;;;; +100A9;LINEAR B IDEOGRAM B161;Lo;0;L;;;;;N;;;;; +100AA;LINEAR B IDEOGRAM B162 GARMENT;Lo;0;L;;;;;N;;;;; +100AB;LINEAR B IDEOGRAM B163 ARMOUR;Lo;0;L;;;;;N;;;;; +100AC;LINEAR B IDEOGRAM B164;Lo;0;L;;;;;N;;;;; +100AD;LINEAR B IDEOGRAM B165;Lo;0;L;;;;;N;;;;; +100AE;LINEAR B IDEOGRAM B166;Lo;0;L;;;;;N;;;;; +100AF;LINEAR B IDEOGRAM B167;Lo;0;L;;;;;N;;;;; +100B0;LINEAR B IDEOGRAM B168;Lo;0;L;;;;;N;;;;; +100B1;LINEAR B IDEOGRAM B169;Lo;0;L;;;;;N;;;;; +100B2;LINEAR B IDEOGRAM B170;Lo;0;L;;;;;N;;;;; +100B3;LINEAR B IDEOGRAM B171;Lo;0;L;;;;;N;;;;; +100B4;LINEAR B IDEOGRAM B172;Lo;0;L;;;;;N;;;;; +100B5;LINEAR B IDEOGRAM B173 MONTH;Lo;0;L;;;;;N;;;;; +100B6;LINEAR B IDEOGRAM B174;Lo;0;L;;;;;N;;;;; +100B7;LINEAR B IDEOGRAM B176 TREE;Lo;0;L;;;;;N;;;;; +100B8;LINEAR B IDEOGRAM B177;Lo;0;L;;;;;N;;;;; +100B9;LINEAR B IDEOGRAM B178;Lo;0;L;;;;;N;;;;; +100BA;LINEAR B IDEOGRAM B179;Lo;0;L;;;;;N;;;;; +100BB;LINEAR B IDEOGRAM B180;Lo;0;L;;;;;N;;;;; +100BC;LINEAR B IDEOGRAM B181;Lo;0;L;;;;;N;;;;; +100BD;LINEAR B IDEOGRAM B182;Lo;0;L;;;;;N;;;;; +100BE;LINEAR B IDEOGRAM B183;Lo;0;L;;;;;N;;;;; +100BF;LINEAR B IDEOGRAM B184;Lo;0;L;;;;;N;;;;; +100C0;LINEAR B IDEOGRAM B185;Lo;0;L;;;;;N;;;;; +100C1;LINEAR B IDEOGRAM B189;Lo;0;L;;;;;N;;;;; +100C2;LINEAR B IDEOGRAM B190;Lo;0;L;;;;;N;;;;; +100C3;LINEAR B IDEOGRAM B191 HELMET;Lo;0;L;;;;;N;;;;; +100C4;LINEAR B IDEOGRAM B220 FOOTSTOOL;Lo;0;L;;;;;N;;;;; +100C5;LINEAR B IDEOGRAM B225 BATHTUB;Lo;0;L;;;;;N;;;;; +100C6;LINEAR B IDEOGRAM B230 SPEAR;Lo;0;L;;;;;N;;;;; +100C7;LINEAR B IDEOGRAM B231 ARROW;Lo;0;L;;;;;N;;;;; +100C8;LINEAR B IDEOGRAM B232;Lo;0;L;;;;;N;;;;; +100C9;LINEAR B IDEOGRAM B233 SWORD;Lo;0;L;;;;;N;;;;; +100CA;LINEAR B IDEOGRAM B234;Lo;0;L;;;;;N;;;;; +100CB;LINEAR B IDEOGRAM B236;Lo;0;L;;;;;N;;;;; +100CC;LINEAR B IDEOGRAM B240 WHEELED CHARIOT;Lo;0;L;;;;;N;;;;; +100CD;LINEAR B IDEOGRAM B241 CHARIOT;Lo;0;L;;;;;N;;;;; +100CE;LINEAR B IDEOGRAM B242 CHARIOT FRAME;Lo;0;L;;;;;N;;;;; +100CF;LINEAR B IDEOGRAM B243 WHEEL;Lo;0;L;;;;;N;;;;; +100D0;LINEAR B IDEOGRAM B245;Lo;0;L;;;;;N;;;;; +100D1;LINEAR B IDEOGRAM B246;Lo;0;L;;;;;N;;;;; +100D2;LINEAR B MONOGRAM B247 DIPTE;Lo;0;L;;;;;N;;;;; +100D3;LINEAR B IDEOGRAM B248;Lo;0;L;;;;;N;;;;; +100D4;LINEAR B IDEOGRAM B249;Lo;0;L;;;;;N;;;;; +100D5;LINEAR B IDEOGRAM B251;Lo;0;L;;;;;N;;;;; +100D6;LINEAR B IDEOGRAM B252;Lo;0;L;;;;;N;;;;; +100D7;LINEAR B IDEOGRAM B253;Lo;0;L;;;;;N;;;;; +100D8;LINEAR B IDEOGRAM B254 DART;Lo;0;L;;;;;N;;;;; +100D9;LINEAR B IDEOGRAM B255;Lo;0;L;;;;;N;;;;; +100DA;LINEAR B IDEOGRAM B256;Lo;0;L;;;;;N;;;;; +100DB;LINEAR B IDEOGRAM B257;Lo;0;L;;;;;N;;;;; +100DC;LINEAR B IDEOGRAM B258;Lo;0;L;;;;;N;;;;; +100DD;LINEAR B IDEOGRAM B259;Lo;0;L;;;;;N;;;;; +100DE;LINEAR B IDEOGRAM VESSEL B155;Lo;0;L;;;;;N;;;;; +100DF;LINEAR B IDEOGRAM VESSEL B200;Lo;0;L;;;;;N;;;;; +100E0;LINEAR B IDEOGRAM VESSEL B201;Lo;0;L;;;;;N;;;;; +100E1;LINEAR B IDEOGRAM VESSEL B202;Lo;0;L;;;;;N;;;;; +100E2;LINEAR B IDEOGRAM VESSEL B203;Lo;0;L;;;;;N;;;;; +100E3;LINEAR B IDEOGRAM VESSEL B204;Lo;0;L;;;;;N;;;;; +100E4;LINEAR B IDEOGRAM VESSEL B205;Lo;0;L;;;;;N;;;;; +100E5;LINEAR B IDEOGRAM VESSEL B206;Lo;0;L;;;;;N;;;;; +100E6;LINEAR B IDEOGRAM VESSEL B207;Lo;0;L;;;;;N;;;;; +100E7;LINEAR B IDEOGRAM VESSEL B208;Lo;0;L;;;;;N;;;;; +100E8;LINEAR B IDEOGRAM VESSEL B209;Lo;0;L;;;;;N;;;;; +100E9;LINEAR B IDEOGRAM VESSEL B210;Lo;0;L;;;;;N;;;;; +100EA;LINEAR B IDEOGRAM VESSEL B211;Lo;0;L;;;;;N;;;;; +100EB;LINEAR B IDEOGRAM VESSEL B212;Lo;0;L;;;;;N;;;;; +100EC;LINEAR B IDEOGRAM VESSEL B213;Lo;0;L;;;;;N;;;;; +100ED;LINEAR B IDEOGRAM VESSEL B214;Lo;0;L;;;;;N;;;;; +100EE;LINEAR B IDEOGRAM VESSEL B215;Lo;0;L;;;;;N;;;;; +100EF;LINEAR B IDEOGRAM VESSEL B216;Lo;0;L;;;;;N;;;;; +100F0;LINEAR B IDEOGRAM VESSEL B217;Lo;0;L;;;;;N;;;;; +100F1;LINEAR B IDEOGRAM VESSEL B218;Lo;0;L;;;;;N;;;;; +100F2;LINEAR B IDEOGRAM VESSEL B219;Lo;0;L;;;;;N;;;;; +100F3;LINEAR B IDEOGRAM VESSEL B221;Lo;0;L;;;;;N;;;;; +100F4;LINEAR B IDEOGRAM VESSEL B222;Lo;0;L;;;;;N;;;;; +100F5;LINEAR B IDEOGRAM VESSEL B226;Lo;0;L;;;;;N;;;;; +100F6;LINEAR B IDEOGRAM VESSEL B227;Lo;0;L;;;;;N;;;;; +100F7;LINEAR B IDEOGRAM VESSEL B228;Lo;0;L;;;;;N;;;;; +100F8;LINEAR B IDEOGRAM VESSEL B229;Lo;0;L;;;;;N;;;;; +100F9;LINEAR B IDEOGRAM VESSEL B250;Lo;0;L;;;;;N;;;;; +100FA;LINEAR B IDEOGRAM VESSEL B305;Lo;0;L;;;;;N;;;;; +10100;AEGEAN WORD SEPARATOR LINE;Po;0;L;;;;;N;;;;; +10101;AEGEAN WORD SEPARATOR DOT;Po;0;ON;;;;;N;;;;; +10102;AEGEAN CHECK MARK;So;0;L;;;;;N;;;;; +10107;AEGEAN NUMBER ONE;No;0;L;;;;1;N;;;;; +10108;AEGEAN NUMBER TWO;No;0;L;;;;2;N;;;;; +10109;AEGEAN NUMBER THREE;No;0;L;;;;3;N;;;;; +1010A;AEGEAN NUMBER FOUR;No;0;L;;;;4;N;;;;; +1010B;AEGEAN NUMBER FIVE;No;0;L;;;;5;N;;;;; +1010C;AEGEAN NUMBER SIX;No;0;L;;;;6;N;;;;; +1010D;AEGEAN NUMBER SEVEN;No;0;L;;;;7;N;;;;; +1010E;AEGEAN NUMBER EIGHT;No;0;L;;;;8;N;;;;; +1010F;AEGEAN NUMBER NINE;No;0;L;;;;9;N;;;;; +10110;AEGEAN NUMBER TEN;No;0;L;;;;10;N;;;;; +10111;AEGEAN NUMBER TWENTY;No;0;L;;;;20;N;;;;; +10112;AEGEAN NUMBER THIRTY;No;0;L;;;;30;N;;;;; +10113;AEGEAN NUMBER FORTY;No;0;L;;;;40;N;;;;; +10114;AEGEAN NUMBER FIFTY;No;0;L;;;;50;N;;;;; +10115;AEGEAN NUMBER SIXTY;No;0;L;;;;60;N;;;;; +10116;AEGEAN NUMBER SEVENTY;No;0;L;;;;70;N;;;;; +10117;AEGEAN NUMBER EIGHTY;No;0;L;;;;80;N;;;;; +10118;AEGEAN NUMBER NINETY;No;0;L;;;;90;N;;;;; +10119;AEGEAN NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; +1011A;AEGEAN NUMBER TWO HUNDRED;No;0;L;;;;200;N;;;;; +1011B;AEGEAN NUMBER THREE HUNDRED;No;0;L;;;;300;N;;;;; +1011C;AEGEAN NUMBER FOUR HUNDRED;No;0;L;;;;400;N;;;;; +1011D;AEGEAN NUMBER FIVE HUNDRED;No;0;L;;;;500;N;;;;; +1011E;AEGEAN NUMBER SIX HUNDRED;No;0;L;;;;600;N;;;;; +1011F;AEGEAN NUMBER SEVEN HUNDRED;No;0;L;;;;700;N;;;;; +10120;AEGEAN NUMBER EIGHT HUNDRED;No;0;L;;;;800;N;;;;; +10121;AEGEAN NUMBER NINE HUNDRED;No;0;L;;;;900;N;;;;; +10122;AEGEAN NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; +10123;AEGEAN NUMBER TWO THOUSAND;No;0;L;;;;2000;N;;;;; +10124;AEGEAN NUMBER THREE THOUSAND;No;0;L;;;;3000;N;;;;; +10125;AEGEAN NUMBER FOUR THOUSAND;No;0;L;;;;4000;N;;;;; +10126;AEGEAN NUMBER FIVE THOUSAND;No;0;L;;;;5000;N;;;;; +10127;AEGEAN NUMBER SIX THOUSAND;No;0;L;;;;6000;N;;;;; +10128;AEGEAN NUMBER SEVEN THOUSAND;No;0;L;;;;7000;N;;;;; +10129;AEGEAN NUMBER EIGHT THOUSAND;No;0;L;;;;8000;N;;;;; +1012A;AEGEAN NUMBER NINE THOUSAND;No;0;L;;;;9000;N;;;;; +1012B;AEGEAN NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;; +1012C;AEGEAN NUMBER TWENTY THOUSAND;No;0;L;;;;20000;N;;;;; +1012D;AEGEAN NUMBER THIRTY THOUSAND;No;0;L;;;;30000;N;;;;; +1012E;AEGEAN NUMBER FORTY THOUSAND;No;0;L;;;;40000;N;;;;; +1012F;AEGEAN NUMBER FIFTY THOUSAND;No;0;L;;;;50000;N;;;;; +10130;AEGEAN NUMBER SIXTY THOUSAND;No;0;L;;;;60000;N;;;;; +10131;AEGEAN NUMBER SEVENTY THOUSAND;No;0;L;;;;70000;N;;;;; +10132;AEGEAN NUMBER EIGHTY THOUSAND;No;0;L;;;;80000;N;;;;; +10133;AEGEAN NUMBER NINETY THOUSAND;No;0;L;;;;90000;N;;;;; +10137;AEGEAN WEIGHT BASE UNIT;So;0;L;;;;;N;;;;; +10138;AEGEAN WEIGHT FIRST SUBUNIT;So;0;L;;;;;N;;;;; +10139;AEGEAN WEIGHT SECOND SUBUNIT;So;0;L;;;;;N;;;;; +1013A;AEGEAN WEIGHT THIRD SUBUNIT;So;0;L;;;;;N;;;;; +1013B;AEGEAN WEIGHT FOURTH SUBUNIT;So;0;L;;;;;N;;;;; +1013C;AEGEAN DRY MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;; +1013D;AEGEAN LIQUID MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;; +1013E;AEGEAN MEASURE SECOND SUBUNIT;So;0;L;;;;;N;;;;; +1013F;AEGEAN MEASURE THIRD SUBUNIT;So;0;L;;;;;N;;;;; +10140;GREEK ACROPHONIC ATTIC ONE QUARTER;Nl;0;ON;;;;1/4;N;;;;; +10141;GREEK ACROPHONIC ATTIC ONE HALF;Nl;0;ON;;;;1/2;N;;;;; +10142;GREEK ACROPHONIC ATTIC ONE DRACHMA;Nl;0;ON;;;;1;N;;;;; +10143;GREEK ACROPHONIC ATTIC FIVE;Nl;0;ON;;;;5;N;;;;; +10144;GREEK ACROPHONIC ATTIC FIFTY;Nl;0;ON;;;;50;N;;;;; +10145;GREEK ACROPHONIC ATTIC FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +10146;GREEK ACROPHONIC ATTIC FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;; +10147;GREEK ACROPHONIC ATTIC FIFTY THOUSAND;Nl;0;ON;;;;50000;N;;;;; +10148;GREEK ACROPHONIC ATTIC FIVE TALENTS;Nl;0;ON;;;;5;N;;;;; +10149;GREEK ACROPHONIC ATTIC TEN TALENTS;Nl;0;ON;;;;10;N;;;;; +1014A;GREEK ACROPHONIC ATTIC FIFTY TALENTS;Nl;0;ON;;;;50;N;;;;; +1014B;GREEK ACROPHONIC ATTIC ONE HUNDRED TALENTS;Nl;0;ON;;;;100;N;;;;; +1014C;GREEK ACROPHONIC ATTIC FIVE HUNDRED TALENTS;Nl;0;ON;;;;500;N;;;;; +1014D;GREEK ACROPHONIC ATTIC ONE THOUSAND TALENTS;Nl;0;ON;;;;1000;N;;;;; +1014E;GREEK ACROPHONIC ATTIC FIVE THOUSAND TALENTS;Nl;0;ON;;;;5000;N;;;;; +1014F;GREEK ACROPHONIC ATTIC FIVE STATERS;Nl;0;ON;;;;5;N;;;;; +10150;GREEK ACROPHONIC ATTIC TEN STATERS;Nl;0;ON;;;;10;N;;;;; +10151;GREEK ACROPHONIC ATTIC FIFTY STATERS;Nl;0;ON;;;;50;N;;;;; +10152;GREEK ACROPHONIC ATTIC ONE HUNDRED STATERS;Nl;0;ON;;;;100;N;;;;; +10153;GREEK ACROPHONIC ATTIC FIVE HUNDRED STATERS;Nl;0;ON;;;;500;N;;;;; +10154;GREEK ACROPHONIC ATTIC ONE THOUSAND STATERS;Nl;0;ON;;;;1000;N;;;;; +10155;GREEK ACROPHONIC ATTIC TEN THOUSAND STATERS;Nl;0;ON;;;;10000;N;;;;; +10156;GREEK ACROPHONIC ATTIC FIFTY THOUSAND STATERS;Nl;0;ON;;;;50000;N;;;;; +10157;GREEK ACROPHONIC ATTIC TEN MNAS;Nl;0;ON;;;;10;N;;;;; +10158;GREEK ACROPHONIC HERAEUM ONE PLETHRON;Nl;0;ON;;;;1;N;;;;; +10159;GREEK ACROPHONIC THESPIAN ONE;Nl;0;ON;;;;1;N;;;;; +1015A;GREEK ACROPHONIC HERMIONIAN ONE;Nl;0;ON;;;;1;N;;;;; +1015B;GREEK ACROPHONIC EPIDAUREAN TWO;Nl;0;ON;;;;2;N;;;;; +1015C;GREEK ACROPHONIC THESPIAN TWO;Nl;0;ON;;;;2;N;;;;; +1015D;GREEK ACROPHONIC CYRENAIC TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;; +1015E;GREEK ACROPHONIC EPIDAUREAN TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;; +1015F;GREEK ACROPHONIC TROEZENIAN FIVE;Nl;0;ON;;;;5;N;;;;; +10160;GREEK ACROPHONIC TROEZENIAN TEN;Nl;0;ON;;;;10;N;;;;; +10161;GREEK ACROPHONIC TROEZENIAN TEN ALTERNATE FORM;Nl;0;ON;;;;10;N;;;;; +10162;GREEK ACROPHONIC HERMIONIAN TEN;Nl;0;ON;;;;10;N;;;;; +10163;GREEK ACROPHONIC MESSENIAN TEN;Nl;0;ON;;;;10;N;;;;; +10164;GREEK ACROPHONIC THESPIAN TEN;Nl;0;ON;;;;10;N;;;;; +10165;GREEK ACROPHONIC THESPIAN THIRTY;Nl;0;ON;;;;30;N;;;;; +10166;GREEK ACROPHONIC TROEZENIAN FIFTY;Nl;0;ON;;;;50;N;;;;; +10167;GREEK ACROPHONIC TROEZENIAN FIFTY ALTERNATE FORM;Nl;0;ON;;;;50;N;;;;; +10168;GREEK ACROPHONIC HERMIONIAN FIFTY;Nl;0;ON;;;;50;N;;;;; +10169;GREEK ACROPHONIC THESPIAN FIFTY;Nl;0;ON;;;;50;N;;;;; +1016A;GREEK ACROPHONIC THESPIAN ONE HUNDRED;Nl;0;ON;;;;100;N;;;;; +1016B;GREEK ACROPHONIC THESPIAN THREE HUNDRED;Nl;0;ON;;;;300;N;;;;; +1016C;GREEK ACROPHONIC EPIDAUREAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +1016D;GREEK ACROPHONIC TROEZENIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +1016E;GREEK ACROPHONIC THESPIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +1016F;GREEK ACROPHONIC CARYSTIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +10170;GREEK ACROPHONIC NAXIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +10171;GREEK ACROPHONIC THESPIAN ONE THOUSAND;Nl;0;ON;;;;1000;N;;;;; +10172;GREEK ACROPHONIC THESPIAN FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;; +10173;GREEK ACROPHONIC DELPHIC FIVE MNAS;Nl;0;ON;;;;5;N;;;;; +10174;GREEK ACROPHONIC STRATIAN FIFTY MNAS;Nl;0;ON;;;;50;N;;;;; +10175;GREEK ONE HALF SIGN;No;0;ON;;;;1/2;N;;;;; +10176;GREEK ONE HALF SIGN ALTERNATE FORM;No;0;ON;;;;1/2;N;;;;; +10177;GREEK TWO THIRDS SIGN;No;0;ON;;;;2/3;N;;;;; +10178;GREEK THREE QUARTERS SIGN;No;0;ON;;;;3/4;N;;;;; +10179;GREEK YEAR SIGN;So;0;ON;;;;;N;;;;; +1017A;GREEK TALENT SIGN;So;0;ON;;;;;N;;;;; +1017B;GREEK DRACHMA SIGN;So;0;ON;;;;;N;;;;; +1017C;GREEK OBOL SIGN;So;0;ON;;;;;N;;;;; +1017D;GREEK TWO OBOLS SIGN;So;0;ON;;;;;N;;;;; +1017E;GREEK THREE OBOLS SIGN;So;0;ON;;;;;N;;;;; +1017F;GREEK FOUR OBOLS SIGN;So;0;ON;;;;;N;;;;; +10180;GREEK FIVE OBOLS SIGN;So;0;ON;;;;;N;;;;; +10181;GREEK METRETES SIGN;So;0;ON;;;;;N;;;;; +10182;GREEK KYATHOS BASE SIGN;So;0;ON;;;;;N;;;;; +10183;GREEK LITRA SIGN;So;0;ON;;;;;N;;;;; +10184;GREEK OUNKIA SIGN;So;0;ON;;;;;N;;;;; +10185;GREEK XESTES SIGN;So;0;ON;;;;;N;;;;; +10186;GREEK ARTABE SIGN;So;0;ON;;;;;N;;;;; +10187;GREEK AROURA SIGN;So;0;ON;;;;;N;;;;; +10188;GREEK GRAMMA SIGN;So;0;ON;;;;;N;;;;; +10189;GREEK TRYBLION BASE SIGN;So;0;ON;;;;;N;;;;; +1018A;GREEK ZERO SIGN;No;0;ON;;;;0;N;;;;; +10190;ROMAN SEXTANS SIGN;So;0;ON;;;;;N;;;;; +10191;ROMAN UNCIA SIGN;So;0;ON;;;;;N;;;;; +10192;ROMAN SEMUNCIA SIGN;So;0;ON;;;;;N;;;;; +10193;ROMAN SEXTULA SIGN;So;0;ON;;;;;N;;;;; +10194;ROMAN DIMIDIA SEXTULA SIGN;So;0;ON;;;;;N;;;;; +10195;ROMAN SILIQUA SIGN;So;0;ON;;;;;N;;;;; +10196;ROMAN DENARIUS SIGN;So;0;ON;;;;;N;;;;; +10197;ROMAN QUINARIUS SIGN;So;0;ON;;;;;N;;;;; +10198;ROMAN SESTERTIUS SIGN;So;0;ON;;;;;N;;;;; +10199;ROMAN DUPONDIUS SIGN;So;0;ON;;;;;N;;;;; +1019A;ROMAN AS SIGN;So;0;ON;;;;;N;;;;; +1019B;ROMAN CENTURIAL SIGN;So;0;ON;;;;;N;;;;; +101D0;PHAISTOS DISC SIGN PEDESTRIAN;So;0;L;;;;;N;;;;; +101D1;PHAISTOS DISC SIGN PLUMED HEAD;So;0;L;;;;;N;;;;; +101D2;PHAISTOS DISC SIGN TATTOOED HEAD;So;0;L;;;;;N;;;;; +101D3;PHAISTOS DISC SIGN CAPTIVE;So;0;L;;;;;N;;;;; +101D4;PHAISTOS DISC SIGN CHILD;So;0;L;;;;;N;;;;; +101D5;PHAISTOS DISC SIGN WOMAN;So;0;L;;;;;N;;;;; +101D6;PHAISTOS DISC SIGN HELMET;So;0;L;;;;;N;;;;; +101D7;PHAISTOS DISC SIGN GAUNTLET;So;0;L;;;;;N;;;;; +101D8;PHAISTOS DISC SIGN TIARA;So;0;L;;;;;N;;;;; +101D9;PHAISTOS DISC SIGN ARROW;So;0;L;;;;;N;;;;; +101DA;PHAISTOS DISC SIGN BOW;So;0;L;;;;;N;;;;; +101DB;PHAISTOS DISC SIGN SHIELD;So;0;L;;;;;N;;;;; +101DC;PHAISTOS DISC SIGN CLUB;So;0;L;;;;;N;;;;; +101DD;PHAISTOS DISC SIGN MANACLES;So;0;L;;;;;N;;;;; +101DE;PHAISTOS DISC SIGN MATTOCK;So;0;L;;;;;N;;;;; +101DF;PHAISTOS DISC SIGN SAW;So;0;L;;;;;N;;;;; +101E0;PHAISTOS DISC SIGN LID;So;0;L;;;;;N;;;;; +101E1;PHAISTOS DISC SIGN BOOMERANG;So;0;L;;;;;N;;;;; +101E2;PHAISTOS DISC SIGN CARPENTRY PLANE;So;0;L;;;;;N;;;;; +101E3;PHAISTOS DISC SIGN DOLIUM;So;0;L;;;;;N;;;;; +101E4;PHAISTOS DISC SIGN COMB;So;0;L;;;;;N;;;;; +101E5;PHAISTOS DISC SIGN SLING;So;0;L;;;;;N;;;;; +101E6;PHAISTOS DISC SIGN COLUMN;So;0;L;;;;;N;;;;; +101E7;PHAISTOS DISC SIGN BEEHIVE;So;0;L;;;;;N;;;;; +101E8;PHAISTOS DISC SIGN SHIP;So;0;L;;;;;N;;;;; +101E9;PHAISTOS DISC SIGN HORN;So;0;L;;;;;N;;;;; +101EA;PHAISTOS DISC SIGN HIDE;So;0;L;;;;;N;;;;; +101EB;PHAISTOS DISC SIGN BULLS LEG;So;0;L;;;;;N;;;;; +101EC;PHAISTOS DISC SIGN CAT;So;0;L;;;;;N;;;;; +101ED;PHAISTOS DISC SIGN RAM;So;0;L;;;;;N;;;;; +101EE;PHAISTOS DISC SIGN EAGLE;So;0;L;;;;;N;;;;; +101EF;PHAISTOS DISC SIGN DOVE;So;0;L;;;;;N;;;;; +101F0;PHAISTOS DISC SIGN TUNNY;So;0;L;;;;;N;;;;; +101F1;PHAISTOS DISC SIGN BEE;So;0;L;;;;;N;;;;; +101F2;PHAISTOS DISC SIGN PLANE TREE;So;0;L;;;;;N;;;;; +101F3;PHAISTOS DISC SIGN VINE;So;0;L;;;;;N;;;;; +101F4;PHAISTOS DISC SIGN PAPYRUS;So;0;L;;;;;N;;;;; +101F5;PHAISTOS DISC SIGN ROSETTE;So;0;L;;;;;N;;;;; +101F6;PHAISTOS DISC SIGN LILY;So;0;L;;;;;N;;;;; +101F7;PHAISTOS DISC SIGN OX BACK;So;0;L;;;;;N;;;;; +101F8;PHAISTOS DISC SIGN FLUTE;So;0;L;;;;;N;;;;; +101F9;PHAISTOS DISC SIGN GRATER;So;0;L;;;;;N;;;;; +101FA;PHAISTOS DISC SIGN STRAINER;So;0;L;;;;;N;;;;; +101FB;PHAISTOS DISC SIGN SMALL AXE;So;0;L;;;;;N;;;;; +101FC;PHAISTOS DISC SIGN WAVY BAND;So;0;L;;;;;N;;;;; +101FD;PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE;Mn;220;NSM;;;;;N;;;;; +10280;LYCIAN LETTER A;Lo;0;L;;;;;N;;;;; +10281;LYCIAN LETTER E;Lo;0;L;;;;;N;;;;; +10282;LYCIAN LETTER B;Lo;0;L;;;;;N;;;;; +10283;LYCIAN LETTER BH;Lo;0;L;;;;;N;;;;; +10284;LYCIAN LETTER G;Lo;0;L;;;;;N;;;;; +10285;LYCIAN LETTER D;Lo;0;L;;;;;N;;;;; +10286;LYCIAN LETTER I;Lo;0;L;;;;;N;;;;; +10287;LYCIAN LETTER W;Lo;0;L;;;;;N;;;;; +10288;LYCIAN LETTER Z;Lo;0;L;;;;;N;;;;; +10289;LYCIAN LETTER TH;Lo;0;L;;;;;N;;;;; +1028A;LYCIAN LETTER J;Lo;0;L;;;;;N;;;;; +1028B;LYCIAN LETTER K;Lo;0;L;;;;;N;;;;; +1028C;LYCIAN LETTER Q;Lo;0;L;;;;;N;;;;; +1028D;LYCIAN LETTER L;Lo;0;L;;;;;N;;;;; +1028E;LYCIAN LETTER M;Lo;0;L;;;;;N;;;;; +1028F;LYCIAN LETTER N;Lo;0;L;;;;;N;;;;; +10290;LYCIAN LETTER MM;Lo;0;L;;;;;N;;;;; +10291;LYCIAN LETTER NN;Lo;0;L;;;;;N;;;;; +10292;LYCIAN LETTER U;Lo;0;L;;;;;N;;;;; +10293;LYCIAN LETTER P;Lo;0;L;;;;;N;;;;; +10294;LYCIAN LETTER KK;Lo;0;L;;;;;N;;;;; +10295;LYCIAN LETTER R;Lo;0;L;;;;;N;;;;; +10296;LYCIAN LETTER S;Lo;0;L;;;;;N;;;;; +10297;LYCIAN LETTER T;Lo;0;L;;;;;N;;;;; +10298;LYCIAN LETTER TT;Lo;0;L;;;;;N;;;;; +10299;LYCIAN LETTER AN;Lo;0;L;;;;;N;;;;; +1029A;LYCIAN LETTER EN;Lo;0;L;;;;;N;;;;; +1029B;LYCIAN LETTER H;Lo;0;L;;;;;N;;;;; +1029C;LYCIAN LETTER X;Lo;0;L;;;;;N;;;;; +102A0;CARIAN LETTER A;Lo;0;L;;;;;N;;;;; +102A1;CARIAN LETTER P2;Lo;0;L;;;;;N;;;;; +102A2;CARIAN LETTER D;Lo;0;L;;;;;N;;;;; +102A3;CARIAN LETTER L;Lo;0;L;;;;;N;;;;; +102A4;CARIAN LETTER UUU;Lo;0;L;;;;;N;;;;; +102A5;CARIAN LETTER R;Lo;0;L;;;;;N;;;;; +102A6;CARIAN LETTER LD;Lo;0;L;;;;;N;;;;; +102A7;CARIAN LETTER A2;Lo;0;L;;;;;N;;;;; +102A8;CARIAN LETTER Q;Lo;0;L;;;;;N;;;;; +102A9;CARIAN LETTER B;Lo;0;L;;;;;N;;;;; +102AA;CARIAN LETTER M;Lo;0;L;;;;;N;;;;; +102AB;CARIAN LETTER O;Lo;0;L;;;;;N;;;;; +102AC;CARIAN LETTER D2;Lo;0;L;;;;;N;;;;; +102AD;CARIAN LETTER T;Lo;0;L;;;;;N;;;;; +102AE;CARIAN LETTER SH;Lo;0;L;;;;;N;;;;; +102AF;CARIAN LETTER SH2;Lo;0;L;;;;;N;;;;; +102B0;CARIAN LETTER S;Lo;0;L;;;;;N;;;;; +102B1;CARIAN LETTER C-18;Lo;0;L;;;;;N;;;;; +102B2;CARIAN LETTER U;Lo;0;L;;;;;N;;;;; +102B3;CARIAN LETTER NN;Lo;0;L;;;;;N;;;;; +102B4;CARIAN LETTER X;Lo;0;L;;;;;N;;;;; +102B5;CARIAN LETTER N;Lo;0;L;;;;;N;;;;; +102B6;CARIAN LETTER TT2;Lo;0;L;;;;;N;;;;; +102B7;CARIAN LETTER P;Lo;0;L;;;;;N;;;;; +102B8;CARIAN LETTER SS;Lo;0;L;;;;;N;;;;; +102B9;CARIAN LETTER I;Lo;0;L;;;;;N;;;;; +102BA;CARIAN LETTER E;Lo;0;L;;;;;N;;;;; +102BB;CARIAN LETTER UUUU;Lo;0;L;;;;;N;;;;; +102BC;CARIAN LETTER K;Lo;0;L;;;;;N;;;;; +102BD;CARIAN LETTER K2;Lo;0;L;;;;;N;;;;; +102BE;CARIAN LETTER ND;Lo;0;L;;;;;N;;;;; +102BF;CARIAN LETTER UU;Lo;0;L;;;;;N;;;;; +102C0;CARIAN LETTER G;Lo;0;L;;;;;N;;;;; +102C1;CARIAN LETTER G2;Lo;0;L;;;;;N;;;;; +102C2;CARIAN LETTER ST;Lo;0;L;;;;;N;;;;; +102C3;CARIAN LETTER ST2;Lo;0;L;;;;;N;;;;; +102C4;CARIAN LETTER NG;Lo;0;L;;;;;N;;;;; +102C5;CARIAN LETTER II;Lo;0;L;;;;;N;;;;; +102C6;CARIAN LETTER C-39;Lo;0;L;;;;;N;;;;; +102C7;CARIAN LETTER TT;Lo;0;L;;;;;N;;;;; +102C8;CARIAN LETTER UUU2;Lo;0;L;;;;;N;;;;; +102C9;CARIAN LETTER RR;Lo;0;L;;;;;N;;;;; +102CA;CARIAN LETTER MB;Lo;0;L;;;;;N;;;;; +102CB;CARIAN LETTER MB2;Lo;0;L;;;;;N;;;;; +102CC;CARIAN LETTER MB3;Lo;0;L;;;;;N;;;;; +102CD;CARIAN LETTER MB4;Lo;0;L;;;;;N;;;;; +102CE;CARIAN LETTER LD2;Lo;0;L;;;;;N;;;;; +102CF;CARIAN LETTER E2;Lo;0;L;;;;;N;;;;; +102D0;CARIAN LETTER UUU3;Lo;0;L;;;;;N;;;;; +10300;OLD ITALIC LETTER A;Lo;0;L;;;;;N;;;;; +10301;OLD ITALIC LETTER BE;Lo;0;L;;;;;N;;;;; +10302;OLD ITALIC LETTER KE;Lo;0;L;;;;;N;;;;; +10303;OLD ITALIC LETTER DE;Lo;0;L;;;;;N;;;;; +10304;OLD ITALIC LETTER E;Lo;0;L;;;;;N;;;;; +10305;OLD ITALIC LETTER VE;Lo;0;L;;;;;N;;;;; +10306;OLD ITALIC LETTER ZE;Lo;0;L;;;;;N;;;;; +10307;OLD ITALIC LETTER HE;Lo;0;L;;;;;N;;;;; +10308;OLD ITALIC LETTER THE;Lo;0;L;;;;;N;;;;; +10309;OLD ITALIC LETTER I;Lo;0;L;;;;;N;;;;; +1030A;OLD ITALIC LETTER KA;Lo;0;L;;;;;N;;;;; +1030B;OLD ITALIC LETTER EL;Lo;0;L;;;;;N;;;;; +1030C;OLD ITALIC LETTER EM;Lo;0;L;;;;;N;;;;; +1030D;OLD ITALIC LETTER EN;Lo;0;L;;;;;N;;;;; +1030E;OLD ITALIC LETTER ESH;Lo;0;L;;;;;N;;;;; +1030F;OLD ITALIC LETTER O;Lo;0;L;;;;;N;;;;; +10310;OLD ITALIC LETTER PE;Lo;0;L;;;;;N;;;;; +10311;OLD ITALIC LETTER SHE;Lo;0;L;;;;;N;;;;; +10312;OLD ITALIC LETTER KU;Lo;0;L;;;;;N;;;;; +10313;OLD ITALIC LETTER ER;Lo;0;L;;;;;N;;;;; +10314;OLD ITALIC LETTER ES;Lo;0;L;;;;;N;;;;; +10315;OLD ITALIC LETTER TE;Lo;0;L;;;;;N;;;;; +10316;OLD ITALIC LETTER U;Lo;0;L;;;;;N;;;;; +10317;OLD ITALIC LETTER EKS;Lo;0;L;;;;;N;;;;; +10318;OLD ITALIC LETTER PHE;Lo;0;L;;;;;N;;;;; +10319;OLD ITALIC LETTER KHE;Lo;0;L;;;;;N;;;;; +1031A;OLD ITALIC LETTER EF;Lo;0;L;;;;;N;;;;; +1031B;OLD ITALIC LETTER ERS;Lo;0;L;;;;;N;;;;; +1031C;OLD ITALIC LETTER CHE;Lo;0;L;;;;;N;;;;; +1031D;OLD ITALIC LETTER II;Lo;0;L;;;;;N;;;;; +1031E;OLD ITALIC LETTER UU;Lo;0;L;;;;;N;;;;; +10320;OLD ITALIC NUMERAL ONE;No;0;L;;;;1;N;;;;; +10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;; +10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;; +10323;OLD ITALIC NUMERAL FIFTY;No;0;L;;;;50;N;;;;; +10330;GOTHIC LETTER AHSA;Lo;0;L;;;;;N;;;;; +10331;GOTHIC LETTER BAIRKAN;Lo;0;L;;;;;N;;;;; +10332;GOTHIC LETTER GIBA;Lo;0;L;;;;;N;;;;; +10333;GOTHIC LETTER DAGS;Lo;0;L;;;;;N;;;;; +10334;GOTHIC LETTER AIHVUS;Lo;0;L;;;;;N;;;;; +10335;GOTHIC LETTER QAIRTHRA;Lo;0;L;;;;;N;;;;; +10336;GOTHIC LETTER IUJA;Lo;0;L;;;;;N;;;;; +10337;GOTHIC LETTER HAGL;Lo;0;L;;;;;N;;;;; +10338;GOTHIC LETTER THIUTH;Lo;0;L;;;;;N;;;;; +10339;GOTHIC LETTER EIS;Lo;0;L;;;;;N;;;;; +1033A;GOTHIC LETTER KUSMA;Lo;0;L;;;;;N;;;;; +1033B;GOTHIC LETTER LAGUS;Lo;0;L;;;;;N;;;;; +1033C;GOTHIC LETTER MANNA;Lo;0;L;;;;;N;;;;; +1033D;GOTHIC LETTER NAUTHS;Lo;0;L;;;;;N;;;;; +1033E;GOTHIC LETTER JER;Lo;0;L;;;;;N;;;;; +1033F;GOTHIC LETTER URUS;Lo;0;L;;;;;N;;;;; +10340;GOTHIC LETTER PAIRTHRA;Lo;0;L;;;;;N;;;;; +10341;GOTHIC LETTER NINETY;Nl;0;L;;;;90;N;;;;; +10342;GOTHIC LETTER RAIDA;Lo;0;L;;;;;N;;;;; +10343;GOTHIC LETTER SAUIL;Lo;0;L;;;;;N;;;;; +10344;GOTHIC LETTER TEIWS;Lo;0;L;;;;;N;;;;; +10345;GOTHIC LETTER WINJA;Lo;0;L;;;;;N;;;;; +10346;GOTHIC LETTER FAIHU;Lo;0;L;;;;;N;;;;; +10347;GOTHIC LETTER IGGWS;Lo;0;L;;;;;N;;;;; +10348;GOTHIC LETTER HWAIR;Lo;0;L;;;;;N;;;;; +10349;GOTHIC LETTER OTHAL;Lo;0;L;;;;;N;;;;; +1034A;GOTHIC LETTER NINE HUNDRED;Nl;0;L;;;;900;N;;;;; +10380;UGARITIC LETTER ALPA;Lo;0;L;;;;;N;;;;; +10381;UGARITIC LETTER BETA;Lo;0;L;;;;;N;;;;; +10382;UGARITIC LETTER GAMLA;Lo;0;L;;;;;N;;;;; +10383;UGARITIC LETTER KHA;Lo;0;L;;;;;N;;;;; +10384;UGARITIC LETTER DELTA;Lo;0;L;;;;;N;;;;; +10385;UGARITIC LETTER HO;Lo;0;L;;;;;N;;;;; +10386;UGARITIC LETTER WO;Lo;0;L;;;;;N;;;;; +10387;UGARITIC LETTER ZETA;Lo;0;L;;;;;N;;;;; +10388;UGARITIC LETTER HOTA;Lo;0;L;;;;;N;;;;; +10389;UGARITIC LETTER TET;Lo;0;L;;;;;N;;;;; +1038A;UGARITIC LETTER YOD;Lo;0;L;;;;;N;;;;; +1038B;UGARITIC LETTER KAF;Lo;0;L;;;;;N;;;;; +1038C;UGARITIC LETTER SHIN;Lo;0;L;;;;;N;;;;; +1038D;UGARITIC LETTER LAMDA;Lo;0;L;;;;;N;;;;; +1038E;UGARITIC LETTER MEM;Lo;0;L;;;;;N;;;;; +1038F;UGARITIC LETTER DHAL;Lo;0;L;;;;;N;;;;; +10390;UGARITIC LETTER NUN;Lo;0;L;;;;;N;;;;; +10391;UGARITIC LETTER ZU;Lo;0;L;;;;;N;;;;; +10392;UGARITIC LETTER SAMKA;Lo;0;L;;;;;N;;;;; +10393;UGARITIC LETTER AIN;Lo;0;L;;;;;N;;;;; +10394;UGARITIC LETTER PU;Lo;0;L;;;;;N;;;;; +10395;UGARITIC LETTER SADE;Lo;0;L;;;;;N;;;;; +10396;UGARITIC LETTER QOPA;Lo;0;L;;;;;N;;;;; +10397;UGARITIC LETTER RASHA;Lo;0;L;;;;;N;;;;; +10398;UGARITIC LETTER THANNA;Lo;0;L;;;;;N;;;;; +10399;UGARITIC LETTER GHAIN;Lo;0;L;;;;;N;;;;; +1039A;UGARITIC LETTER TO;Lo;0;L;;;;;N;;;;; +1039B;UGARITIC LETTER I;Lo;0;L;;;;;N;;;;; +1039C;UGARITIC LETTER U;Lo;0;L;;;;;N;;;;; +1039D;UGARITIC LETTER SSU;Lo;0;L;;;;;N;;;;; +1039F;UGARITIC WORD DIVIDER;Po;0;L;;;;;N;;;;; +103A0;OLD PERSIAN SIGN A;Lo;0;L;;;;;N;;;;; +103A1;OLD PERSIAN SIGN I;Lo;0;L;;;;;N;;;;; +103A2;OLD PERSIAN SIGN U;Lo;0;L;;;;;N;;;;; +103A3;OLD PERSIAN SIGN KA;Lo;0;L;;;;;N;;;;; +103A4;OLD PERSIAN SIGN KU;Lo;0;L;;;;;N;;;;; +103A5;OLD PERSIAN SIGN GA;Lo;0;L;;;;;N;;;;; +103A6;OLD PERSIAN SIGN GU;Lo;0;L;;;;;N;;;;; +103A7;OLD PERSIAN SIGN XA;Lo;0;L;;;;;N;;;;; +103A8;OLD PERSIAN SIGN CA;Lo;0;L;;;;;N;;;;; +103A9;OLD PERSIAN SIGN JA;Lo;0;L;;;;;N;;;;; +103AA;OLD PERSIAN SIGN JI;Lo;0;L;;;;;N;;;;; +103AB;OLD PERSIAN SIGN TA;Lo;0;L;;;;;N;;;;; +103AC;OLD PERSIAN SIGN TU;Lo;0;L;;;;;N;;;;; +103AD;OLD PERSIAN SIGN DA;Lo;0;L;;;;;N;;;;; +103AE;OLD PERSIAN SIGN DI;Lo;0;L;;;;;N;;;;; +103AF;OLD PERSIAN SIGN DU;Lo;0;L;;;;;N;;;;; +103B0;OLD PERSIAN SIGN THA;Lo;0;L;;;;;N;;;;; +103B1;OLD PERSIAN SIGN PA;Lo;0;L;;;;;N;;;;; +103B2;OLD PERSIAN SIGN BA;Lo;0;L;;;;;N;;;;; +103B3;OLD PERSIAN SIGN FA;Lo;0;L;;;;;N;;;;; +103B4;OLD PERSIAN SIGN NA;Lo;0;L;;;;;N;;;;; +103B5;OLD PERSIAN SIGN NU;Lo;0;L;;;;;N;;;;; +103B6;OLD PERSIAN SIGN MA;Lo;0;L;;;;;N;;;;; +103B7;OLD PERSIAN SIGN MI;Lo;0;L;;;;;N;;;;; +103B8;OLD PERSIAN SIGN MU;Lo;0;L;;;;;N;;;;; +103B9;OLD PERSIAN SIGN YA;Lo;0;L;;;;;N;;;;; +103BA;OLD PERSIAN SIGN VA;Lo;0;L;;;;;N;;;;; +103BB;OLD PERSIAN SIGN VI;Lo;0;L;;;;;N;;;;; +103BC;OLD PERSIAN SIGN RA;Lo;0;L;;;;;N;;;;; +103BD;OLD PERSIAN SIGN RU;Lo;0;L;;;;;N;;;;; +103BE;OLD PERSIAN SIGN LA;Lo;0;L;;;;;N;;;;; +103BF;OLD PERSIAN SIGN SA;Lo;0;L;;;;;N;;;;; +103C0;OLD PERSIAN SIGN ZA;Lo;0;L;;;;;N;;;;; +103C1;OLD PERSIAN SIGN SHA;Lo;0;L;;;;;N;;;;; +103C2;OLD PERSIAN SIGN SSA;Lo;0;L;;;;;N;;;;; +103C3;OLD PERSIAN SIGN HA;Lo;0;L;;;;;N;;;;; +103C8;OLD PERSIAN SIGN AURAMAZDAA;Lo;0;L;;;;;N;;;;; +103C9;OLD PERSIAN SIGN AURAMAZDAA-2;Lo;0;L;;;;;N;;;;; +103CA;OLD PERSIAN SIGN AURAMAZDAAHA;Lo;0;L;;;;;N;;;;; +103CB;OLD PERSIAN SIGN XSHAAYATHIYA;Lo;0;L;;;;;N;;;;; +103CC;OLD PERSIAN SIGN DAHYAAUSH;Lo;0;L;;;;;N;;;;; +103CD;OLD PERSIAN SIGN DAHYAAUSH-2;Lo;0;L;;;;;N;;;;; +103CE;OLD PERSIAN SIGN BAGA;Lo;0;L;;;;;N;;;;; +103CF;OLD PERSIAN SIGN BUUMISH;Lo;0;L;;;;;N;;;;; +103D0;OLD PERSIAN WORD DIVIDER;Po;0;L;;;;;N;;;;; +103D1;OLD PERSIAN NUMBER ONE;Nl;0;L;;;;1;N;;;;; +103D2;OLD PERSIAN NUMBER TWO;Nl;0;L;;;;2;N;;;;; +103D3;OLD PERSIAN NUMBER TEN;Nl;0;L;;;;10;N;;;;; +103D4;OLD PERSIAN NUMBER TWENTY;Nl;0;L;;;;20;N;;;;; +103D5;OLD PERSIAN NUMBER HUNDRED;Nl;0;L;;;;100;N;;;;; +10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428; +10401;DESERET CAPITAL LETTER LONG E;Lu;0;L;;;;;N;;;;10429; +10402;DESERET CAPITAL LETTER LONG A;Lu;0;L;;;;;N;;;;1042A; +10403;DESERET CAPITAL LETTER LONG AH;Lu;0;L;;;;;N;;;;1042B; +10404;DESERET CAPITAL LETTER LONG O;Lu;0;L;;;;;N;;;;1042C; +10405;DESERET CAPITAL LETTER LONG OO;Lu;0;L;;;;;N;;;;1042D; +10406;DESERET CAPITAL LETTER SHORT I;Lu;0;L;;;;;N;;;;1042E; +10407;DESERET CAPITAL LETTER SHORT E;Lu;0;L;;;;;N;;;;1042F; +10408;DESERET CAPITAL LETTER SHORT A;Lu;0;L;;;;;N;;;;10430; +10409;DESERET CAPITAL LETTER SHORT AH;Lu;0;L;;;;;N;;;;10431; +1040A;DESERET CAPITAL LETTER SHORT O;Lu;0;L;;;;;N;;;;10432; +1040B;DESERET CAPITAL LETTER SHORT OO;Lu;0;L;;;;;N;;;;10433; +1040C;DESERET CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;10434; +1040D;DESERET CAPITAL LETTER OW;Lu;0;L;;;;;N;;;;10435; +1040E;DESERET CAPITAL LETTER WU;Lu;0;L;;;;;N;;;;10436; +1040F;DESERET CAPITAL LETTER YEE;Lu;0;L;;;;;N;;;;10437; +10410;DESERET CAPITAL LETTER H;Lu;0;L;;;;;N;;;;10438; +10411;DESERET CAPITAL LETTER PEE;Lu;0;L;;;;;N;;;;10439; +10412;DESERET CAPITAL LETTER BEE;Lu;0;L;;;;;N;;;;1043A; +10413;DESERET CAPITAL LETTER TEE;Lu;0;L;;;;;N;;;;1043B; +10414;DESERET CAPITAL LETTER DEE;Lu;0;L;;;;;N;;;;1043C; +10415;DESERET CAPITAL LETTER CHEE;Lu;0;L;;;;;N;;;;1043D; +10416;DESERET CAPITAL LETTER JEE;Lu;0;L;;;;;N;;;;1043E; +10417;DESERET CAPITAL LETTER KAY;Lu;0;L;;;;;N;;;;1043F; +10418;DESERET CAPITAL LETTER GAY;Lu;0;L;;;;;N;;;;10440; +10419;DESERET CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;10441; +1041A;DESERET CAPITAL LETTER VEE;Lu;0;L;;;;;N;;;;10442; +1041B;DESERET CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;10443; +1041C;DESERET CAPITAL LETTER THEE;Lu;0;L;;;;;N;;;;10444; +1041D;DESERET CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;10445; +1041E;DESERET CAPITAL LETTER ZEE;Lu;0;L;;;;;N;;;;10446; +1041F;DESERET CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;10447; +10420;DESERET CAPITAL LETTER ZHEE;Lu;0;L;;;;;N;;;;10448; +10421;DESERET CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;10449; +10422;DESERET CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;1044A; +10423;DESERET CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;1044B; +10424;DESERET CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;1044C; +10425;DESERET CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;1044D; +10426;DESERET CAPITAL LETTER OI;Lu;0;L;;;;;N;;;;1044E; +10427;DESERET CAPITAL LETTER EW;Lu;0;L;;;;;N;;;;1044F; +10428;DESERET SMALL LETTER LONG I;Ll;0;L;;;;;N;;;10400;;10400 +10429;DESERET SMALL LETTER LONG E;Ll;0;L;;;;;N;;;10401;;10401 +1042A;DESERET SMALL LETTER LONG A;Ll;0;L;;;;;N;;;10402;;10402 +1042B;DESERET SMALL LETTER LONG AH;Ll;0;L;;;;;N;;;10403;;10403 +1042C;DESERET SMALL LETTER LONG O;Ll;0;L;;;;;N;;;10404;;10404 +1042D;DESERET SMALL LETTER LONG OO;Ll;0;L;;;;;N;;;10405;;10405 +1042E;DESERET SMALL LETTER SHORT I;Ll;0;L;;;;;N;;;10406;;10406 +1042F;DESERET SMALL LETTER SHORT E;Ll;0;L;;;;;N;;;10407;;10407 +10430;DESERET SMALL LETTER SHORT A;Ll;0;L;;;;;N;;;10408;;10408 +10431;DESERET SMALL LETTER SHORT AH;Ll;0;L;;;;;N;;;10409;;10409 +10432;DESERET SMALL LETTER SHORT O;Ll;0;L;;;;;N;;;1040A;;1040A +10433;DESERET SMALL LETTER SHORT OO;Ll;0;L;;;;;N;;;1040B;;1040B +10434;DESERET SMALL LETTER AY;Ll;0;L;;;;;N;;;1040C;;1040C +10435;DESERET SMALL LETTER OW;Ll;0;L;;;;;N;;;1040D;;1040D +10436;DESERET SMALL LETTER WU;Ll;0;L;;;;;N;;;1040E;;1040E +10437;DESERET SMALL LETTER YEE;Ll;0;L;;;;;N;;;1040F;;1040F +10438;DESERET SMALL LETTER H;Ll;0;L;;;;;N;;;10410;;10410 +10439;DESERET SMALL LETTER PEE;Ll;0;L;;;;;N;;;10411;;10411 +1043A;DESERET SMALL LETTER BEE;Ll;0;L;;;;;N;;;10412;;10412 +1043B;DESERET SMALL LETTER TEE;Ll;0;L;;;;;N;;;10413;;10413 +1043C;DESERET SMALL LETTER DEE;Ll;0;L;;;;;N;;;10414;;10414 +1043D;DESERET SMALL LETTER CHEE;Ll;0;L;;;;;N;;;10415;;10415 +1043E;DESERET SMALL LETTER JEE;Ll;0;L;;;;;N;;;10416;;10416 +1043F;DESERET SMALL LETTER KAY;Ll;0;L;;;;;N;;;10417;;10417 +10440;DESERET SMALL LETTER GAY;Ll;0;L;;;;;N;;;10418;;10418 +10441;DESERET SMALL LETTER EF;Ll;0;L;;;;;N;;;10419;;10419 +10442;DESERET SMALL LETTER VEE;Ll;0;L;;;;;N;;;1041A;;1041A +10443;DESERET SMALL LETTER ETH;Ll;0;L;;;;;N;;;1041B;;1041B +10444;DESERET SMALL LETTER THEE;Ll;0;L;;;;;N;;;1041C;;1041C +10445;DESERET SMALL LETTER ES;Ll;0;L;;;;;N;;;1041D;;1041D +10446;DESERET SMALL LETTER ZEE;Ll;0;L;;;;;N;;;1041E;;1041E +10447;DESERET SMALL LETTER ESH;Ll;0;L;;;;;N;;;1041F;;1041F +10448;DESERET SMALL LETTER ZHEE;Ll;0;L;;;;;N;;;10420;;10420 +10449;DESERET SMALL LETTER ER;Ll;0;L;;;;;N;;;10421;;10421 +1044A;DESERET SMALL LETTER EL;Ll;0;L;;;;;N;;;10422;;10422 +1044B;DESERET SMALL LETTER EM;Ll;0;L;;;;;N;;;10423;;10423 +1044C;DESERET SMALL LETTER EN;Ll;0;L;;;;;N;;;10424;;10424 +1044D;DESERET SMALL LETTER ENG;Ll;0;L;;;;;N;;;10425;;10425 +1044E;DESERET SMALL LETTER OI;Ll;0;L;;;;;N;;;10426;;10426 +1044F;DESERET SMALL LETTER EW;Ll;0;L;;;;;N;;;10427;;10427 +10450;SHAVIAN LETTER PEEP;Lo;0;L;;;;;N;;;;; +10451;SHAVIAN LETTER TOT;Lo;0;L;;;;;N;;;;; +10452;SHAVIAN LETTER KICK;Lo;0;L;;;;;N;;;;; +10453;SHAVIAN LETTER FEE;Lo;0;L;;;;;N;;;;; +10454;SHAVIAN LETTER THIGH;Lo;0;L;;;;;N;;;;; +10455;SHAVIAN LETTER SO;Lo;0;L;;;;;N;;;;; +10456;SHAVIAN LETTER SURE;Lo;0;L;;;;;N;;;;; +10457;SHAVIAN LETTER CHURCH;Lo;0;L;;;;;N;;;;; +10458;SHAVIAN LETTER YEA;Lo;0;L;;;;;N;;;;; +10459;SHAVIAN LETTER HUNG;Lo;0;L;;;;;N;;;;; +1045A;SHAVIAN LETTER BIB;Lo;0;L;;;;;N;;;;; +1045B;SHAVIAN LETTER DEAD;Lo;0;L;;;;;N;;;;; +1045C;SHAVIAN LETTER GAG;Lo;0;L;;;;;N;;;;; +1045D;SHAVIAN LETTER VOW;Lo;0;L;;;;;N;;;;; +1045E;SHAVIAN LETTER THEY;Lo;0;L;;;;;N;;;;; +1045F;SHAVIAN LETTER ZOO;Lo;0;L;;;;;N;;;;; +10460;SHAVIAN LETTER MEASURE;Lo;0;L;;;;;N;;;;; +10461;SHAVIAN LETTER JUDGE;Lo;0;L;;;;;N;;;;; +10462;SHAVIAN LETTER WOE;Lo;0;L;;;;;N;;;;; +10463;SHAVIAN LETTER HA-HA;Lo;0;L;;;;;N;;;;; +10464;SHAVIAN LETTER LOLL;Lo;0;L;;;;;N;;;;; +10465;SHAVIAN LETTER MIME;Lo;0;L;;;;;N;;;;; +10466;SHAVIAN LETTER IF;Lo;0;L;;;;;N;;;;; +10467;SHAVIAN LETTER EGG;Lo;0;L;;;;;N;;;;; +10468;SHAVIAN LETTER ASH;Lo;0;L;;;;;N;;;;; +10469;SHAVIAN LETTER ADO;Lo;0;L;;;;;N;;;;; +1046A;SHAVIAN LETTER ON;Lo;0;L;;;;;N;;;;; +1046B;SHAVIAN LETTER WOOL;Lo;0;L;;;;;N;;;;; +1046C;SHAVIAN LETTER OUT;Lo;0;L;;;;;N;;;;; +1046D;SHAVIAN LETTER AH;Lo;0;L;;;;;N;;;;; +1046E;SHAVIAN LETTER ROAR;Lo;0;L;;;;;N;;;;; +1046F;SHAVIAN LETTER NUN;Lo;0;L;;;;;N;;;;; +10470;SHAVIAN LETTER EAT;Lo;0;L;;;;;N;;;;; +10471;SHAVIAN LETTER AGE;Lo;0;L;;;;;N;;;;; +10472;SHAVIAN LETTER ICE;Lo;0;L;;;;;N;;;;; +10473;SHAVIAN LETTER UP;Lo;0;L;;;;;N;;;;; +10474;SHAVIAN LETTER OAK;Lo;0;L;;;;;N;;;;; +10475;SHAVIAN LETTER OOZE;Lo;0;L;;;;;N;;;;; +10476;SHAVIAN LETTER OIL;Lo;0;L;;;;;N;;;;; +10477;SHAVIAN LETTER AWE;Lo;0;L;;;;;N;;;;; +10478;SHAVIAN LETTER ARE;Lo;0;L;;;;;N;;;;; +10479;SHAVIAN LETTER OR;Lo;0;L;;;;;N;;;;; +1047A;SHAVIAN LETTER AIR;Lo;0;L;;;;;N;;;;; +1047B;SHAVIAN LETTER ERR;Lo;0;L;;;;;N;;;;; +1047C;SHAVIAN LETTER ARRAY;Lo;0;L;;;;;N;;;;; +1047D;SHAVIAN LETTER EAR;Lo;0;L;;;;;N;;;;; +1047E;SHAVIAN LETTER IAN;Lo;0;L;;;;;N;;;;; +1047F;SHAVIAN LETTER YEW;Lo;0;L;;;;;N;;;;; +10480;OSMANYA LETTER ALEF;Lo;0;L;;;;;N;;;;; +10481;OSMANYA LETTER BA;Lo;0;L;;;;;N;;;;; +10482;OSMANYA LETTER TA;Lo;0;L;;;;;N;;;;; +10483;OSMANYA LETTER JA;Lo;0;L;;;;;N;;;;; +10484;OSMANYA LETTER XA;Lo;0;L;;;;;N;;;;; +10485;OSMANYA LETTER KHA;Lo;0;L;;;;;N;;;;; +10486;OSMANYA LETTER DEEL;Lo;0;L;;;;;N;;;;; +10487;OSMANYA LETTER RA;Lo;0;L;;;;;N;;;;; +10488;OSMANYA LETTER SA;Lo;0;L;;;;;N;;;;; +10489;OSMANYA LETTER SHIIN;Lo;0;L;;;;;N;;;;; +1048A;OSMANYA LETTER DHA;Lo;0;L;;;;;N;;;;; +1048B;OSMANYA LETTER CAYN;Lo;0;L;;;;;N;;;;; +1048C;OSMANYA LETTER GA;Lo;0;L;;;;;N;;;;; +1048D;OSMANYA LETTER FA;Lo;0;L;;;;;N;;;;; +1048E;OSMANYA LETTER QAAF;Lo;0;L;;;;;N;;;;; +1048F;OSMANYA LETTER KAAF;Lo;0;L;;;;;N;;;;; +10490;OSMANYA LETTER LAAN;Lo;0;L;;;;;N;;;;; +10491;OSMANYA LETTER MIIN;Lo;0;L;;;;;N;;;;; +10492;OSMANYA LETTER NUUN;Lo;0;L;;;;;N;;;;; +10493;OSMANYA LETTER WAW;Lo;0;L;;;;;N;;;;; +10494;OSMANYA LETTER HA;Lo;0;L;;;;;N;;;;; +10495;OSMANYA LETTER YA;Lo;0;L;;;;;N;;;;; +10496;OSMANYA LETTER A;Lo;0;L;;;;;N;;;;; +10497;OSMANYA LETTER E;Lo;0;L;;;;;N;;;;; +10498;OSMANYA LETTER I;Lo;0;L;;;;;N;;;;; +10499;OSMANYA LETTER O;Lo;0;L;;;;;N;;;;; +1049A;OSMANYA LETTER U;Lo;0;L;;;;;N;;;;; +1049B;OSMANYA LETTER AA;Lo;0;L;;;;;N;;;;; +1049C;OSMANYA LETTER EE;Lo;0;L;;;;;N;;;;; +1049D;OSMANYA LETTER OO;Lo;0;L;;;;;N;;;;; +104A0;OSMANYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +104A1;OSMANYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +104A2;OSMANYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +104A3;OSMANYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +104A4;OSMANYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +104A5;OSMANYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +104A6;OSMANYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +104A7;OSMANYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +104A8;OSMANYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +104A9;OSMANYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +10800;CYPRIOT SYLLABLE A;Lo;0;R;;;;;N;;;;; +10801;CYPRIOT SYLLABLE E;Lo;0;R;;;;;N;;;;; +10802;CYPRIOT SYLLABLE I;Lo;0;R;;;;;N;;;;; +10803;CYPRIOT SYLLABLE O;Lo;0;R;;;;;N;;;;; +10804;CYPRIOT SYLLABLE U;Lo;0;R;;;;;N;;;;; +10805;CYPRIOT SYLLABLE JA;Lo;0;R;;;;;N;;;;; +10808;CYPRIOT SYLLABLE JO;Lo;0;R;;;;;N;;;;; +1080A;CYPRIOT SYLLABLE KA;Lo;0;R;;;;;N;;;;; +1080B;CYPRIOT SYLLABLE KE;Lo;0;R;;;;;N;;;;; +1080C;CYPRIOT SYLLABLE KI;Lo;0;R;;;;;N;;;;; +1080D;CYPRIOT SYLLABLE KO;Lo;0;R;;;;;N;;;;; +1080E;CYPRIOT SYLLABLE KU;Lo;0;R;;;;;N;;;;; +1080F;CYPRIOT SYLLABLE LA;Lo;0;R;;;;;N;;;;; +10810;CYPRIOT SYLLABLE LE;Lo;0;R;;;;;N;;;;; +10811;CYPRIOT SYLLABLE LI;Lo;0;R;;;;;N;;;;; +10812;CYPRIOT SYLLABLE LO;Lo;0;R;;;;;N;;;;; +10813;CYPRIOT SYLLABLE LU;Lo;0;R;;;;;N;;;;; +10814;CYPRIOT SYLLABLE MA;Lo;0;R;;;;;N;;;;; +10815;CYPRIOT SYLLABLE ME;Lo;0;R;;;;;N;;;;; +10816;CYPRIOT SYLLABLE MI;Lo;0;R;;;;;N;;;;; +10817;CYPRIOT SYLLABLE MO;Lo;0;R;;;;;N;;;;; +10818;CYPRIOT SYLLABLE MU;Lo;0;R;;;;;N;;;;; +10819;CYPRIOT SYLLABLE NA;Lo;0;R;;;;;N;;;;; +1081A;CYPRIOT SYLLABLE NE;Lo;0;R;;;;;N;;;;; +1081B;CYPRIOT SYLLABLE NI;Lo;0;R;;;;;N;;;;; +1081C;CYPRIOT SYLLABLE NO;Lo;0;R;;;;;N;;;;; +1081D;CYPRIOT SYLLABLE NU;Lo;0;R;;;;;N;;;;; +1081E;CYPRIOT SYLLABLE PA;Lo;0;R;;;;;N;;;;; +1081F;CYPRIOT SYLLABLE PE;Lo;0;R;;;;;N;;;;; +10820;CYPRIOT SYLLABLE PI;Lo;0;R;;;;;N;;;;; +10821;CYPRIOT SYLLABLE PO;Lo;0;R;;;;;N;;;;; +10822;CYPRIOT SYLLABLE PU;Lo;0;R;;;;;N;;;;; +10823;CYPRIOT SYLLABLE RA;Lo;0;R;;;;;N;;;;; +10824;CYPRIOT SYLLABLE RE;Lo;0;R;;;;;N;;;;; +10825;CYPRIOT SYLLABLE RI;Lo;0;R;;;;;N;;;;; +10826;CYPRIOT SYLLABLE RO;Lo;0;R;;;;;N;;;;; +10827;CYPRIOT SYLLABLE RU;Lo;0;R;;;;;N;;;;; +10828;CYPRIOT SYLLABLE SA;Lo;0;R;;;;;N;;;;; +10829;CYPRIOT SYLLABLE SE;Lo;0;R;;;;;N;;;;; +1082A;CYPRIOT SYLLABLE SI;Lo;0;R;;;;;N;;;;; +1082B;CYPRIOT SYLLABLE SO;Lo;0;R;;;;;N;;;;; +1082C;CYPRIOT SYLLABLE SU;Lo;0;R;;;;;N;;;;; +1082D;CYPRIOT SYLLABLE TA;Lo;0;R;;;;;N;;;;; +1082E;CYPRIOT SYLLABLE TE;Lo;0;R;;;;;N;;;;; +1082F;CYPRIOT SYLLABLE TI;Lo;0;R;;;;;N;;;;; +10830;CYPRIOT SYLLABLE TO;Lo;0;R;;;;;N;;;;; +10831;CYPRIOT SYLLABLE TU;Lo;0;R;;;;;N;;;;; +10832;CYPRIOT SYLLABLE WA;Lo;0;R;;;;;N;;;;; +10833;CYPRIOT SYLLABLE WE;Lo;0;R;;;;;N;;;;; +10834;CYPRIOT SYLLABLE WI;Lo;0;R;;;;;N;;;;; +10835;CYPRIOT SYLLABLE WO;Lo;0;R;;;;;N;;;;; +10837;CYPRIOT SYLLABLE XA;Lo;0;R;;;;;N;;;;; +10838;CYPRIOT SYLLABLE XE;Lo;0;R;;;;;N;;;;; +1083C;CYPRIOT SYLLABLE ZA;Lo;0;R;;;;;N;;;;; +1083F;CYPRIOT SYLLABLE ZO;Lo;0;R;;;;;N;;;;; +10840;IMPERIAL ARAMAIC LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10841;IMPERIAL ARAMAIC LETTER BETH;Lo;0;R;;;;;N;;;;; +10842;IMPERIAL ARAMAIC LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10843;IMPERIAL ARAMAIC LETTER DALETH;Lo;0;R;;;;;N;;;;; +10844;IMPERIAL ARAMAIC LETTER HE;Lo;0;R;;;;;N;;;;; +10845;IMPERIAL ARAMAIC LETTER WAW;Lo;0;R;;;;;N;;;;; +10846;IMPERIAL ARAMAIC LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10847;IMPERIAL ARAMAIC LETTER HETH;Lo;0;R;;;;;N;;;;; +10848;IMPERIAL ARAMAIC LETTER TETH;Lo;0;R;;;;;N;;;;; +10849;IMPERIAL ARAMAIC LETTER YODH;Lo;0;R;;;;;N;;;;; +1084A;IMPERIAL ARAMAIC LETTER KAPH;Lo;0;R;;;;;N;;;;; +1084B;IMPERIAL ARAMAIC LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +1084C;IMPERIAL ARAMAIC LETTER MEM;Lo;0;R;;;;;N;;;;; +1084D;IMPERIAL ARAMAIC LETTER NUN;Lo;0;R;;;;;N;;;;; +1084E;IMPERIAL ARAMAIC LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +1084F;IMPERIAL ARAMAIC LETTER AYIN;Lo;0;R;;;;;N;;;;; +10850;IMPERIAL ARAMAIC LETTER PE;Lo;0;R;;;;;N;;;;; +10851;IMPERIAL ARAMAIC LETTER SADHE;Lo;0;R;;;;;N;;;;; +10852;IMPERIAL ARAMAIC LETTER QOPH;Lo;0;R;;;;;N;;;;; +10853;IMPERIAL ARAMAIC LETTER RESH;Lo;0;R;;;;;N;;;;; +10854;IMPERIAL ARAMAIC LETTER SHIN;Lo;0;R;;;;;N;;;;; +10855;IMPERIAL ARAMAIC LETTER TAW;Lo;0;R;;;;;N;;;;; +10857;IMPERIAL ARAMAIC SECTION SIGN;Po;0;R;;;;;N;;;;; +10858;IMPERIAL ARAMAIC NUMBER ONE;No;0;R;;;;1;N;;;;; +10859;IMPERIAL ARAMAIC NUMBER TWO;No;0;R;;;;2;N;;;;; +1085A;IMPERIAL ARAMAIC NUMBER THREE;No;0;R;;;;3;N;;;;; +1085B;IMPERIAL ARAMAIC NUMBER TEN;No;0;R;;;;10;N;;;;; +1085C;IMPERIAL ARAMAIC NUMBER TWENTY;No;0;R;;;;20;N;;;;; +1085D;IMPERIAL ARAMAIC NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +1085E;IMPERIAL ARAMAIC NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +1085F;IMPERIAL ARAMAIC NUMBER TEN THOUSAND;No;0;R;;;;10000;N;;;;; +10900;PHOENICIAN LETTER ALF;Lo;0;R;;;;;N;;;;; +10901;PHOENICIAN LETTER BET;Lo;0;R;;;;;N;;;;; +10902;PHOENICIAN LETTER GAML;Lo;0;R;;;;;N;;;;; +10903;PHOENICIAN LETTER DELT;Lo;0;R;;;;;N;;;;; +10904;PHOENICIAN LETTER HE;Lo;0;R;;;;;N;;;;; +10905;PHOENICIAN LETTER WAU;Lo;0;R;;;;;N;;;;; +10906;PHOENICIAN LETTER ZAI;Lo;0;R;;;;;N;;;;; +10907;PHOENICIAN LETTER HET;Lo;0;R;;;;;N;;;;; +10908;PHOENICIAN LETTER TET;Lo;0;R;;;;;N;;;;; +10909;PHOENICIAN LETTER YOD;Lo;0;R;;;;;N;;;;; +1090A;PHOENICIAN LETTER KAF;Lo;0;R;;;;;N;;;;; +1090B;PHOENICIAN LETTER LAMD;Lo;0;R;;;;;N;;;;; +1090C;PHOENICIAN LETTER MEM;Lo;0;R;;;;;N;;;;; +1090D;PHOENICIAN LETTER NUN;Lo;0;R;;;;;N;;;;; +1090E;PHOENICIAN LETTER SEMK;Lo;0;R;;;;;N;;;;; +1090F;PHOENICIAN LETTER AIN;Lo;0;R;;;;;N;;;;; +10910;PHOENICIAN LETTER PE;Lo;0;R;;;;;N;;;;; +10911;PHOENICIAN LETTER SADE;Lo;0;R;;;;;N;;;;; +10912;PHOENICIAN LETTER QOF;Lo;0;R;;;;;N;;;;; +10913;PHOENICIAN LETTER ROSH;Lo;0;R;;;;;N;;;;; +10914;PHOENICIAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10915;PHOENICIAN LETTER TAU;Lo;0;R;;;;;N;;;;; +10916;PHOENICIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10917;PHOENICIAN NUMBER TEN;No;0;R;;;;10;N;;;;; +10918;PHOENICIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10919;PHOENICIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +1091A;PHOENICIAN NUMBER TWO;No;0;R;;;;2;N;;;;; +1091B;PHOENICIAN NUMBER THREE;No;0;R;;;;3;N;;;;; +1091F;PHOENICIAN WORD SEPARATOR;Po;0;ON;;;;;N;;;;; +10920;LYDIAN LETTER A;Lo;0;R;;;;;N;;;;; +10921;LYDIAN LETTER B;Lo;0;R;;;;;N;;;;; +10922;LYDIAN LETTER G;Lo;0;R;;;;;N;;;;; +10923;LYDIAN LETTER D;Lo;0;R;;;;;N;;;;; +10924;LYDIAN LETTER E;Lo;0;R;;;;;N;;;;; +10925;LYDIAN LETTER V;Lo;0;R;;;;;N;;;;; +10926;LYDIAN LETTER I;Lo;0;R;;;;;N;;;;; +10927;LYDIAN LETTER Y;Lo;0;R;;;;;N;;;;; +10928;LYDIAN LETTER K;Lo;0;R;;;;;N;;;;; +10929;LYDIAN LETTER L;Lo;0;R;;;;;N;;;;; +1092A;LYDIAN LETTER M;Lo;0;R;;;;;N;;;;; +1092B;LYDIAN LETTER N;Lo;0;R;;;;;N;;;;; +1092C;LYDIAN LETTER O;Lo;0;R;;;;;N;;;;; +1092D;LYDIAN LETTER R;Lo;0;R;;;;;N;;;;; +1092E;LYDIAN LETTER SS;Lo;0;R;;;;;N;;;;; +1092F;LYDIAN LETTER T;Lo;0;R;;;;;N;;;;; +10930;LYDIAN LETTER U;Lo;0;R;;;;;N;;;;; +10931;LYDIAN LETTER F;Lo;0;R;;;;;N;;;;; +10932;LYDIAN LETTER Q;Lo;0;R;;;;;N;;;;; +10933;LYDIAN LETTER S;Lo;0;R;;;;;N;;;;; +10934;LYDIAN LETTER TT;Lo;0;R;;;;;N;;;;; +10935;LYDIAN LETTER AN;Lo;0;R;;;;;N;;;;; +10936;LYDIAN LETTER EN;Lo;0;R;;;;;N;;;;; +10937;LYDIAN LETTER LY;Lo;0;R;;;;;N;;;;; +10938;LYDIAN LETTER NN;Lo;0;R;;;;;N;;;;; +10939;LYDIAN LETTER C;Lo;0;R;;;;;N;;;;; +1093F;LYDIAN TRIANGULAR MARK;Po;0;R;;;;;N;;;;; +10A00;KHAROSHTHI LETTER A;Lo;0;R;;;;;N;;;;; +10A01;KHAROSHTHI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +10A02;KHAROSHTHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +10A03;KHAROSHTHI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +10A05;KHAROSHTHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +10A06;KHAROSHTHI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +10A0C;KHAROSHTHI VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;; +10A0D;KHAROSHTHI SIGN DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;; +10A0E;KHAROSHTHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +10A0F;KHAROSHTHI SIGN VISARGA;Mn;230;NSM;;;;;N;;;;; +10A10;KHAROSHTHI LETTER KA;Lo;0;R;;;;;N;;;;; +10A11;KHAROSHTHI LETTER KHA;Lo;0;R;;;;;N;;;;; +10A12;KHAROSHTHI LETTER GA;Lo;0;R;;;;;N;;;;; +10A13;KHAROSHTHI LETTER GHA;Lo;0;R;;;;;N;;;;; +10A15;KHAROSHTHI LETTER CA;Lo;0;R;;;;;N;;;;; +10A16;KHAROSHTHI LETTER CHA;Lo;0;R;;;;;N;;;;; +10A17;KHAROSHTHI LETTER JA;Lo;0;R;;;;;N;;;;; +10A19;KHAROSHTHI LETTER NYA;Lo;0;R;;;;;N;;;;; +10A1A;KHAROSHTHI LETTER TTA;Lo;0;R;;;;;N;;;;; +10A1B;KHAROSHTHI LETTER TTHA;Lo;0;R;;;;;N;;;;; +10A1C;KHAROSHTHI LETTER DDA;Lo;0;R;;;;;N;;;;; +10A1D;KHAROSHTHI LETTER DDHA;Lo;0;R;;;;;N;;;;; +10A1E;KHAROSHTHI LETTER NNA;Lo;0;R;;;;;N;;;;; +10A1F;KHAROSHTHI LETTER TA;Lo;0;R;;;;;N;;;;; +10A20;KHAROSHTHI LETTER THA;Lo;0;R;;;;;N;;;;; +10A21;KHAROSHTHI LETTER DA;Lo;0;R;;;;;N;;;;; +10A22;KHAROSHTHI LETTER DHA;Lo;0;R;;;;;N;;;;; +10A23;KHAROSHTHI LETTER NA;Lo;0;R;;;;;N;;;;; +10A24;KHAROSHTHI LETTER PA;Lo;0;R;;;;;N;;;;; +10A25;KHAROSHTHI LETTER PHA;Lo;0;R;;;;;N;;;;; +10A26;KHAROSHTHI LETTER BA;Lo;0;R;;;;;N;;;;; +10A27;KHAROSHTHI LETTER BHA;Lo;0;R;;;;;N;;;;; +10A28;KHAROSHTHI LETTER MA;Lo;0;R;;;;;N;;;;; +10A29;KHAROSHTHI LETTER YA;Lo;0;R;;;;;N;;;;; +10A2A;KHAROSHTHI LETTER RA;Lo;0;R;;;;;N;;;;; +10A2B;KHAROSHTHI LETTER LA;Lo;0;R;;;;;N;;;;; +10A2C;KHAROSHTHI LETTER VA;Lo;0;R;;;;;N;;;;; +10A2D;KHAROSHTHI LETTER SHA;Lo;0;R;;;;;N;;;;; +10A2E;KHAROSHTHI LETTER SSA;Lo;0;R;;;;;N;;;;; +10A2F;KHAROSHTHI LETTER SA;Lo;0;R;;;;;N;;;;; +10A30;KHAROSHTHI LETTER ZA;Lo;0;R;;;;;N;;;;; +10A31;KHAROSHTHI LETTER HA;Lo;0;R;;;;;N;;;;; +10A32;KHAROSHTHI LETTER KKA;Lo;0;R;;;;;N;;;;; +10A33;KHAROSHTHI LETTER TTTHA;Lo;0;R;;;;;N;;;;; +10A38;KHAROSHTHI SIGN BAR ABOVE;Mn;230;NSM;;;;;N;;;;; +10A39;KHAROSHTHI SIGN CAUDA;Mn;1;NSM;;;;;N;;;;; +10A3A;KHAROSHTHI SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;; +10A3F;KHAROSHTHI VIRAMA;Mn;9;NSM;;;;;N;;;;; +10A40;KHAROSHTHI DIGIT ONE;No;0;R;;;1;1;N;;;;; +10A41;KHAROSHTHI DIGIT TWO;No;0;R;;;2;2;N;;;;; +10A42;KHAROSHTHI DIGIT THREE;No;0;R;;;3;3;N;;;;; +10A43;KHAROSHTHI DIGIT FOUR;No;0;R;;;4;4;N;;;;; +10A44;KHAROSHTHI NUMBER TEN;No;0;R;;;;10;N;;;;; +10A45;KHAROSHTHI NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10A46;KHAROSHTHI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10A47;KHAROSHTHI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +10A50;KHAROSHTHI PUNCTUATION DOT;Po;0;R;;;;;N;;;;; +10A51;KHAROSHTHI PUNCTUATION SMALL CIRCLE;Po;0;R;;;;;N;;;;; +10A52;KHAROSHTHI PUNCTUATION CIRCLE;Po;0;R;;;;;N;;;;; +10A53;KHAROSHTHI PUNCTUATION CRESCENT BAR;Po;0;R;;;;;N;;;;; +10A54;KHAROSHTHI PUNCTUATION MANGALAM;Po;0;R;;;;;N;;;;; +10A55;KHAROSHTHI PUNCTUATION LOTUS;Po;0;R;;;;;N;;;;; +10A56;KHAROSHTHI PUNCTUATION DANDA;Po;0;R;;;;;N;;;;; +10A57;KHAROSHTHI PUNCTUATION DOUBLE DANDA;Po;0;R;;;;;N;;;;; +10A58;KHAROSHTHI PUNCTUATION LINES;Po;0;R;;;;;N;;;;; +10A60;OLD SOUTH ARABIAN LETTER HE;Lo;0;R;;;;;N;;;;; +10A61;OLD SOUTH ARABIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10A62;OLD SOUTH ARABIAN LETTER HETH;Lo;0;R;;;;;N;;;;; +10A63;OLD SOUTH ARABIAN LETTER MEM;Lo;0;R;;;;;N;;;;; +10A64;OLD SOUTH ARABIAN LETTER QOPH;Lo;0;R;;;;;N;;;;; +10A65;OLD SOUTH ARABIAN LETTER WAW;Lo;0;R;;;;;N;;;;; +10A66;OLD SOUTH ARABIAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10A67;OLD SOUTH ARABIAN LETTER RESH;Lo;0;R;;;;;N;;;;; +10A68;OLD SOUTH ARABIAN LETTER BETH;Lo;0;R;;;;;N;;;;; +10A69;OLD SOUTH ARABIAN LETTER TAW;Lo;0;R;;;;;N;;;;; +10A6A;OLD SOUTH ARABIAN LETTER SAT;Lo;0;R;;;;;N;;;;; +10A6B;OLD SOUTH ARABIAN LETTER KAPH;Lo;0;R;;;;;N;;;;; +10A6C;OLD SOUTH ARABIAN LETTER NUN;Lo;0;R;;;;;N;;;;; +10A6D;OLD SOUTH ARABIAN LETTER KHETH;Lo;0;R;;;;;N;;;;; +10A6E;OLD SOUTH ARABIAN LETTER SADHE;Lo;0;R;;;;;N;;;;; +10A6F;OLD SOUTH ARABIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10A70;OLD SOUTH ARABIAN LETTER FE;Lo;0;R;;;;;N;;;;; +10A71;OLD SOUTH ARABIAN LETTER ALEF;Lo;0;R;;;;;N;;;;; +10A72;OLD SOUTH ARABIAN LETTER AYN;Lo;0;R;;;;;N;;;;; +10A73;OLD SOUTH ARABIAN LETTER DHADHE;Lo;0;R;;;;;N;;;;; +10A74;OLD SOUTH ARABIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10A75;OLD SOUTH ARABIAN LETTER DALETH;Lo;0;R;;;;;N;;;;; +10A76;OLD SOUTH ARABIAN LETTER GHAYN;Lo;0;R;;;;;N;;;;; +10A77;OLD SOUTH ARABIAN LETTER TETH;Lo;0;R;;;;;N;;;;; +10A78;OLD SOUTH ARABIAN LETTER ZAYN;Lo;0;R;;;;;N;;;;; +10A79;OLD SOUTH ARABIAN LETTER DHALETH;Lo;0;R;;;;;N;;;;; +10A7A;OLD SOUTH ARABIAN LETTER YODH;Lo;0;R;;;;;N;;;;; +10A7B;OLD SOUTH ARABIAN LETTER THAW;Lo;0;R;;;;;N;;;;; +10A7C;OLD SOUTH ARABIAN LETTER THETH;Lo;0;R;;;;;N;;;;; +10A7D;OLD SOUTH ARABIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10A7E;OLD SOUTH ARABIAN NUMBER FIFTY;No;0;R;;;;50;N;;;;; +10A7F;OLD SOUTH ARABIAN NUMERIC INDICATOR;Po;0;R;;;;;N;;;;; +10B00;AVESTAN LETTER A;Lo;0;R;;;;;N;;;;; +10B01;AVESTAN LETTER AA;Lo;0;R;;;;;N;;;;; +10B02;AVESTAN LETTER AO;Lo;0;R;;;;;N;;;;; +10B03;AVESTAN LETTER AAO;Lo;0;R;;;;;N;;;;; +10B04;AVESTAN LETTER AN;Lo;0;R;;;;;N;;;;; +10B05;AVESTAN LETTER AAN;Lo;0;R;;;;;N;;;;; +10B06;AVESTAN LETTER AE;Lo;0;R;;;;;N;;;;; +10B07;AVESTAN LETTER AEE;Lo;0;R;;;;;N;;;;; +10B08;AVESTAN LETTER E;Lo;0;R;;;;;N;;;;; +10B09;AVESTAN LETTER EE;Lo;0;R;;;;;N;;;;; +10B0A;AVESTAN LETTER O;Lo;0;R;;;;;N;;;;; +10B0B;AVESTAN LETTER OO;Lo;0;R;;;;;N;;;;; +10B0C;AVESTAN LETTER I;Lo;0;R;;;;;N;;;;; +10B0D;AVESTAN LETTER II;Lo;0;R;;;;;N;;;;; +10B0E;AVESTAN LETTER U;Lo;0;R;;;;;N;;;;; +10B0F;AVESTAN LETTER UU;Lo;0;R;;;;;N;;;;; +10B10;AVESTAN LETTER KE;Lo;0;R;;;;;N;;;;; +10B11;AVESTAN LETTER XE;Lo;0;R;;;;;N;;;;; +10B12;AVESTAN LETTER XYE;Lo;0;R;;;;;N;;;;; +10B13;AVESTAN LETTER XVE;Lo;0;R;;;;;N;;;;; +10B14;AVESTAN LETTER GE;Lo;0;R;;;;;N;;;;; +10B15;AVESTAN LETTER GGE;Lo;0;R;;;;;N;;;;; +10B16;AVESTAN LETTER GHE;Lo;0;R;;;;;N;;;;; +10B17;AVESTAN LETTER CE;Lo;0;R;;;;;N;;;;; +10B18;AVESTAN LETTER JE;Lo;0;R;;;;;N;;;;; +10B19;AVESTAN LETTER TE;Lo;0;R;;;;;N;;;;; +10B1A;AVESTAN LETTER THE;Lo;0;R;;;;;N;;;;; +10B1B;AVESTAN LETTER DE;Lo;0;R;;;;;N;;;;; +10B1C;AVESTAN LETTER DHE;Lo;0;R;;;;;N;;;;; +10B1D;AVESTAN LETTER TTE;Lo;0;R;;;;;N;;;;; +10B1E;AVESTAN LETTER PE;Lo;0;R;;;;;N;;;;; +10B1F;AVESTAN LETTER FE;Lo;0;R;;;;;N;;;;; +10B20;AVESTAN LETTER BE;Lo;0;R;;;;;N;;;;; +10B21;AVESTAN LETTER BHE;Lo;0;R;;;;;N;;;;; +10B22;AVESTAN LETTER NGE;Lo;0;R;;;;;N;;;;; +10B23;AVESTAN LETTER NGYE;Lo;0;R;;;;;N;;;;; +10B24;AVESTAN LETTER NGVE;Lo;0;R;;;;;N;;;;; +10B25;AVESTAN LETTER NE;Lo;0;R;;;;;N;;;;; +10B26;AVESTAN LETTER NYE;Lo;0;R;;;;;N;;;;; +10B27;AVESTAN LETTER NNE;Lo;0;R;;;;;N;;;;; +10B28;AVESTAN LETTER ME;Lo;0;R;;;;;N;;;;; +10B29;AVESTAN LETTER HME;Lo;0;R;;;;;N;;;;; +10B2A;AVESTAN LETTER YYE;Lo;0;R;;;;;N;;;;; +10B2B;AVESTAN LETTER YE;Lo;0;R;;;;;N;;;;; +10B2C;AVESTAN LETTER VE;Lo;0;R;;;;;N;;;;; +10B2D;AVESTAN LETTER RE;Lo;0;R;;;;;N;;;;; +10B2E;AVESTAN LETTER LE;Lo;0;R;;;;;N;;;;; +10B2F;AVESTAN LETTER SE;Lo;0;R;;;;;N;;;;; +10B30;AVESTAN LETTER ZE;Lo;0;R;;;;;N;;;;; +10B31;AVESTAN LETTER SHE;Lo;0;R;;;;;N;;;;; +10B32;AVESTAN LETTER ZHE;Lo;0;R;;;;;N;;;;; +10B33;AVESTAN LETTER SHYE;Lo;0;R;;;;;N;;;;; +10B34;AVESTAN LETTER SSHE;Lo;0;R;;;;;N;;;;; +10B35;AVESTAN LETTER HE;Lo;0;R;;;;;N;;;;; +10B39;AVESTAN ABBREVIATION MARK;Po;0;ON;;;;;N;;;;; +10B3A;TINY TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3B;SMALL TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3C;LARGE TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3D;LARGE ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3E;LARGE TWO RINGS OVER ONE RING PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3F;LARGE ONE RING OVER TWO RINGS PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B40;INSCRIPTIONAL PARTHIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10B41;INSCRIPTIONAL PARTHIAN LETTER BETH;Lo;0;R;;;;;N;;;;; +10B42;INSCRIPTIONAL PARTHIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10B43;INSCRIPTIONAL PARTHIAN LETTER DALETH;Lo;0;R;;;;;N;;;;; +10B44;INSCRIPTIONAL PARTHIAN LETTER HE;Lo;0;R;;;;;N;;;;; +10B45;INSCRIPTIONAL PARTHIAN LETTER WAW;Lo;0;R;;;;;N;;;;; +10B46;INSCRIPTIONAL PARTHIAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10B47;INSCRIPTIONAL PARTHIAN LETTER HETH;Lo;0;R;;;;;N;;;;; +10B48;INSCRIPTIONAL PARTHIAN LETTER TETH;Lo;0;R;;;;;N;;;;; +10B49;INSCRIPTIONAL PARTHIAN LETTER YODH;Lo;0;R;;;;;N;;;;; +10B4A;INSCRIPTIONAL PARTHIAN LETTER KAPH;Lo;0;R;;;;;N;;;;; +10B4B;INSCRIPTIONAL PARTHIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10B4C;INSCRIPTIONAL PARTHIAN LETTER MEM;Lo;0;R;;;;;N;;;;; +10B4D;INSCRIPTIONAL PARTHIAN LETTER NUN;Lo;0;R;;;;;N;;;;; +10B4E;INSCRIPTIONAL PARTHIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10B4F;INSCRIPTIONAL PARTHIAN LETTER AYIN;Lo;0;R;;;;;N;;;;; +10B50;INSCRIPTIONAL PARTHIAN LETTER PE;Lo;0;R;;;;;N;;;;; +10B51;INSCRIPTIONAL PARTHIAN LETTER SADHE;Lo;0;R;;;;;N;;;;; +10B52;INSCRIPTIONAL PARTHIAN LETTER QOPH;Lo;0;R;;;;;N;;;;; +10B53;INSCRIPTIONAL PARTHIAN LETTER RESH;Lo;0;R;;;;;N;;;;; +10B54;INSCRIPTIONAL PARTHIAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10B55;INSCRIPTIONAL PARTHIAN LETTER TAW;Lo;0;R;;;;;N;;;;; +10B58;INSCRIPTIONAL PARTHIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10B59;INSCRIPTIONAL PARTHIAN NUMBER TWO;No;0;R;;;;2;N;;;;; +10B5A;INSCRIPTIONAL PARTHIAN NUMBER THREE;No;0;R;;;;3;N;;;;; +10B5B;INSCRIPTIONAL PARTHIAN NUMBER FOUR;No;0;R;;;;4;N;;;;; +10B5C;INSCRIPTIONAL PARTHIAN NUMBER TEN;No;0;R;;;;10;N;;;;; +10B5D;INSCRIPTIONAL PARTHIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10B5E;INSCRIPTIONAL PARTHIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10B5F;INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +10B60;INSCRIPTIONAL PAHLAVI LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10B61;INSCRIPTIONAL PAHLAVI LETTER BETH;Lo;0;R;;;;;N;;;;; +10B62;INSCRIPTIONAL PAHLAVI LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10B63;INSCRIPTIONAL PAHLAVI LETTER DALETH;Lo;0;R;;;;;N;;;;; +10B64;INSCRIPTIONAL PAHLAVI LETTER HE;Lo;0;R;;;;;N;;;;; +10B65;INSCRIPTIONAL PAHLAVI LETTER WAW-AYIN-RESH;Lo;0;R;;;;;N;;;;; +10B66;INSCRIPTIONAL PAHLAVI LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10B67;INSCRIPTIONAL PAHLAVI LETTER HETH;Lo;0;R;;;;;N;;;;; +10B68;INSCRIPTIONAL PAHLAVI LETTER TETH;Lo;0;R;;;;;N;;;;; +10B69;INSCRIPTIONAL PAHLAVI LETTER YODH;Lo;0;R;;;;;N;;;;; +10B6A;INSCRIPTIONAL PAHLAVI LETTER KAPH;Lo;0;R;;;;;N;;;;; +10B6B;INSCRIPTIONAL PAHLAVI LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10B6C;INSCRIPTIONAL PAHLAVI LETTER MEM-QOPH;Lo;0;R;;;;;N;;;;; +10B6D;INSCRIPTIONAL PAHLAVI LETTER NUN;Lo;0;R;;;;;N;;;;; +10B6E;INSCRIPTIONAL PAHLAVI LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10B6F;INSCRIPTIONAL PAHLAVI LETTER PE;Lo;0;R;;;;;N;;;;; +10B70;INSCRIPTIONAL PAHLAVI LETTER SADHE;Lo;0;R;;;;;N;;;;; +10B71;INSCRIPTIONAL PAHLAVI LETTER SHIN;Lo;0;R;;;;;N;;;;; +10B72;INSCRIPTIONAL PAHLAVI LETTER TAW;Lo;0;R;;;;;N;;;;; +10B78;INSCRIPTIONAL PAHLAVI NUMBER ONE;No;0;R;;;;1;N;;;;; +10B79;INSCRIPTIONAL PAHLAVI NUMBER TWO;No;0;R;;;;2;N;;;;; +10B7A;INSCRIPTIONAL PAHLAVI NUMBER THREE;No;0;R;;;;3;N;;;;; +10B7B;INSCRIPTIONAL PAHLAVI NUMBER FOUR;No;0;R;;;;4;N;;;;; +10B7C;INSCRIPTIONAL PAHLAVI NUMBER TEN;No;0;R;;;;10;N;;;;; +10B7D;INSCRIPTIONAL PAHLAVI NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10B7E;INSCRIPTIONAL PAHLAVI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10B7F;INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +10C00;OLD TURKIC LETTER ORKHON A;Lo;0;R;;;;;N;;;;; +10C01;OLD TURKIC LETTER YENISEI A;Lo;0;R;;;;;N;;;;; +10C02;OLD TURKIC LETTER YENISEI AE;Lo;0;R;;;;;N;;;;; +10C03;OLD TURKIC LETTER ORKHON I;Lo;0;R;;;;;N;;;;; +10C04;OLD TURKIC LETTER YENISEI I;Lo;0;R;;;;;N;;;;; +10C05;OLD TURKIC LETTER YENISEI E;Lo;0;R;;;;;N;;;;; +10C06;OLD TURKIC LETTER ORKHON O;Lo;0;R;;;;;N;;;;; +10C07;OLD TURKIC LETTER ORKHON OE;Lo;0;R;;;;;N;;;;; +10C08;OLD TURKIC LETTER YENISEI OE;Lo;0;R;;;;;N;;;;; +10C09;OLD TURKIC LETTER ORKHON AB;Lo;0;R;;;;;N;;;;; +10C0A;OLD TURKIC LETTER YENISEI AB;Lo;0;R;;;;;N;;;;; +10C0B;OLD TURKIC LETTER ORKHON AEB;Lo;0;R;;;;;N;;;;; +10C0C;OLD TURKIC LETTER YENISEI AEB;Lo;0;R;;;;;N;;;;; +10C0D;OLD TURKIC LETTER ORKHON AG;Lo;0;R;;;;;N;;;;; +10C0E;OLD TURKIC LETTER YENISEI AG;Lo;0;R;;;;;N;;;;; +10C0F;OLD TURKIC LETTER ORKHON AEG;Lo;0;R;;;;;N;;;;; +10C10;OLD TURKIC LETTER YENISEI AEG;Lo;0;R;;;;;N;;;;; +10C11;OLD TURKIC LETTER ORKHON AD;Lo;0;R;;;;;N;;;;; +10C12;OLD TURKIC LETTER YENISEI AD;Lo;0;R;;;;;N;;;;; +10C13;OLD TURKIC LETTER ORKHON AED;Lo;0;R;;;;;N;;;;; +10C14;OLD TURKIC LETTER ORKHON EZ;Lo;0;R;;;;;N;;;;; +10C15;OLD TURKIC LETTER YENISEI EZ;Lo;0;R;;;;;N;;;;; +10C16;OLD TURKIC LETTER ORKHON AY;Lo;0;R;;;;;N;;;;; +10C17;OLD TURKIC LETTER YENISEI AY;Lo;0;R;;;;;N;;;;; +10C18;OLD TURKIC LETTER ORKHON AEY;Lo;0;R;;;;;N;;;;; +10C19;OLD TURKIC LETTER YENISEI AEY;Lo;0;R;;;;;N;;;;; +10C1A;OLD TURKIC LETTER ORKHON AEK;Lo;0;R;;;;;N;;;;; +10C1B;OLD TURKIC LETTER YENISEI AEK;Lo;0;R;;;;;N;;;;; +10C1C;OLD TURKIC LETTER ORKHON OEK;Lo;0;R;;;;;N;;;;; +10C1D;OLD TURKIC LETTER YENISEI OEK;Lo;0;R;;;;;N;;;;; +10C1E;OLD TURKIC LETTER ORKHON AL;Lo;0;R;;;;;N;;;;; +10C1F;OLD TURKIC LETTER YENISEI AL;Lo;0;R;;;;;N;;;;; +10C20;OLD TURKIC LETTER ORKHON AEL;Lo;0;R;;;;;N;;;;; +10C21;OLD TURKIC LETTER ORKHON ELT;Lo;0;R;;;;;N;;;;; +10C22;OLD TURKIC LETTER ORKHON EM;Lo;0;R;;;;;N;;;;; +10C23;OLD TURKIC LETTER ORKHON AN;Lo;0;R;;;;;N;;;;; +10C24;OLD TURKIC LETTER ORKHON AEN;Lo;0;R;;;;;N;;;;; +10C25;OLD TURKIC LETTER YENISEI AEN;Lo;0;R;;;;;N;;;;; +10C26;OLD TURKIC LETTER ORKHON ENT;Lo;0;R;;;;;N;;;;; +10C27;OLD TURKIC LETTER YENISEI ENT;Lo;0;R;;;;;N;;;;; +10C28;OLD TURKIC LETTER ORKHON ENC;Lo;0;R;;;;;N;;;;; +10C29;OLD TURKIC LETTER YENISEI ENC;Lo;0;R;;;;;N;;;;; +10C2A;OLD TURKIC LETTER ORKHON ENY;Lo;0;R;;;;;N;;;;; +10C2B;OLD TURKIC LETTER YENISEI ENY;Lo;0;R;;;;;N;;;;; +10C2C;OLD TURKIC LETTER YENISEI ANG;Lo;0;R;;;;;N;;;;; +10C2D;OLD TURKIC LETTER ORKHON ENG;Lo;0;R;;;;;N;;;;; +10C2E;OLD TURKIC LETTER YENISEI AENG;Lo;0;R;;;;;N;;;;; +10C2F;OLD TURKIC LETTER ORKHON EP;Lo;0;R;;;;;N;;;;; +10C30;OLD TURKIC LETTER ORKHON OP;Lo;0;R;;;;;N;;;;; +10C31;OLD TURKIC LETTER ORKHON IC;Lo;0;R;;;;;N;;;;; +10C32;OLD TURKIC LETTER ORKHON EC;Lo;0;R;;;;;N;;;;; +10C33;OLD TURKIC LETTER YENISEI EC;Lo;0;R;;;;;N;;;;; +10C34;OLD TURKIC LETTER ORKHON AQ;Lo;0;R;;;;;N;;;;; +10C35;OLD TURKIC LETTER YENISEI AQ;Lo;0;R;;;;;N;;;;; +10C36;OLD TURKIC LETTER ORKHON IQ;Lo;0;R;;;;;N;;;;; +10C37;OLD TURKIC LETTER YENISEI IQ;Lo;0;R;;;;;N;;;;; +10C38;OLD TURKIC LETTER ORKHON OQ;Lo;0;R;;;;;N;;;;; +10C39;OLD TURKIC LETTER YENISEI OQ;Lo;0;R;;;;;N;;;;; +10C3A;OLD TURKIC LETTER ORKHON AR;Lo;0;R;;;;;N;;;;; +10C3B;OLD TURKIC LETTER YENISEI AR;Lo;0;R;;;;;N;;;;; +10C3C;OLD TURKIC LETTER ORKHON AER;Lo;0;R;;;;;N;;;;; +10C3D;OLD TURKIC LETTER ORKHON AS;Lo;0;R;;;;;N;;;;; +10C3E;OLD TURKIC LETTER ORKHON AES;Lo;0;R;;;;;N;;;;; +10C3F;OLD TURKIC LETTER ORKHON ASH;Lo;0;R;;;;;N;;;;; +10C40;OLD TURKIC LETTER YENISEI ASH;Lo;0;R;;;;;N;;;;; +10C41;OLD TURKIC LETTER ORKHON ESH;Lo;0;R;;;;;N;;;;; +10C42;OLD TURKIC LETTER YENISEI ESH;Lo;0;R;;;;;N;;;;; +10C43;OLD TURKIC LETTER ORKHON AT;Lo;0;R;;;;;N;;;;; +10C44;OLD TURKIC LETTER YENISEI AT;Lo;0;R;;;;;N;;;;; +10C45;OLD TURKIC LETTER ORKHON AET;Lo;0;R;;;;;N;;;;; +10C46;OLD TURKIC LETTER YENISEI AET;Lo;0;R;;;;;N;;;;; +10C47;OLD TURKIC LETTER ORKHON OT;Lo;0;R;;;;;N;;;;; +10C48;OLD TURKIC LETTER ORKHON BASH;Lo;0;R;;;;;N;;;;; +10E60;RUMI DIGIT ONE;No;0;AN;;;1;1;N;;;;; +10E61;RUMI DIGIT TWO;No;0;AN;;;2;2;N;;;;; +10E62;RUMI DIGIT THREE;No;0;AN;;;3;3;N;;;;; +10E63;RUMI DIGIT FOUR;No;0;AN;;;4;4;N;;;;; +10E64;RUMI DIGIT FIVE;No;0;AN;;;5;5;N;;;;; +10E65;RUMI DIGIT SIX;No;0;AN;;;6;6;N;;;;; +10E66;RUMI DIGIT SEVEN;No;0;AN;;;7;7;N;;;;; +10E67;RUMI DIGIT EIGHT;No;0;AN;;;8;8;N;;;;; +10E68;RUMI DIGIT NINE;No;0;AN;;;9;9;N;;;;; +10E69;RUMI NUMBER TEN;No;0;AN;;;;10;N;;;;; +10E6A;RUMI NUMBER TWENTY;No;0;AN;;;;20;N;;;;; +10E6B;RUMI NUMBER THIRTY;No;0;AN;;;;30;N;;;;; +10E6C;RUMI NUMBER FORTY;No;0;AN;;;;40;N;;;;; +10E6D;RUMI NUMBER FIFTY;No;0;AN;;;;50;N;;;;; +10E6E;RUMI NUMBER SIXTY;No;0;AN;;;;60;N;;;;; +10E6F;RUMI NUMBER SEVENTY;No;0;AN;;;;70;N;;;;; +10E70;RUMI NUMBER EIGHTY;No;0;AN;;;;80;N;;;;; +10E71;RUMI NUMBER NINETY;No;0;AN;;;;90;N;;;;; +10E72;RUMI NUMBER ONE HUNDRED;No;0;AN;;;;100;N;;;;; +10E73;RUMI NUMBER TWO HUNDRED;No;0;AN;;;;200;N;;;;; +10E74;RUMI NUMBER THREE HUNDRED;No;0;AN;;;;300;N;;;;; +10E75;RUMI NUMBER FOUR HUNDRED;No;0;AN;;;;400;N;;;;; +10E76;RUMI NUMBER FIVE HUNDRED;No;0;AN;;;;500;N;;;;; +10E77;RUMI NUMBER SIX HUNDRED;No;0;AN;;;;600;N;;;;; +10E78;RUMI NUMBER SEVEN HUNDRED;No;0;AN;;;;700;N;;;;; +10E79;RUMI NUMBER EIGHT HUNDRED;No;0;AN;;;;800;N;;;;; +10E7A;RUMI NUMBER NINE HUNDRED;No;0;AN;;;;900;N;;;;; +10E7B;RUMI FRACTION ONE HALF;No;0;AN;;;;1/2;N;;;;; +10E7C;RUMI FRACTION ONE QUARTER;No;0;AN;;;;1/4;N;;;;; +10E7D;RUMI FRACTION ONE THIRD;No;0;AN;;;;1/3;N;;;;; +10E7E;RUMI FRACTION TWO THIRDS;No;0;AN;;;;2/3;N;;;;; +11080;KAITHI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +11081;KAITHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11082;KAITHI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11083;KAITHI LETTER A;Lo;0;L;;;;;N;;;;; +11084;KAITHI LETTER AA;Lo;0;L;;;;;N;;;;; +11085;KAITHI LETTER I;Lo;0;L;;;;;N;;;;; +11086;KAITHI LETTER II;Lo;0;L;;;;;N;;;;; +11087;KAITHI LETTER U;Lo;0;L;;;;;N;;;;; +11088;KAITHI LETTER UU;Lo;0;L;;;;;N;;;;; +11089;KAITHI LETTER E;Lo;0;L;;;;;N;;;;; +1108A;KAITHI LETTER AI;Lo;0;L;;;;;N;;;;; +1108B;KAITHI LETTER O;Lo;0;L;;;;;N;;;;; +1108C;KAITHI LETTER AU;Lo;0;L;;;;;N;;;;; +1108D;KAITHI LETTER KA;Lo;0;L;;;;;N;;;;; +1108E;KAITHI LETTER KHA;Lo;0;L;;;;;N;;;;; +1108F;KAITHI LETTER GA;Lo;0;L;;;;;N;;;;; +11090;KAITHI LETTER GHA;Lo;0;L;;;;;N;;;;; +11091;KAITHI LETTER NGA;Lo;0;L;;;;;N;;;;; +11092;KAITHI LETTER CA;Lo;0;L;;;;;N;;;;; +11093;KAITHI LETTER CHA;Lo;0;L;;;;;N;;;;; +11094;KAITHI LETTER JA;Lo;0;L;;;;;N;;;;; +11095;KAITHI LETTER JHA;Lo;0;L;;;;;N;;;;; +11096;KAITHI LETTER NYA;Lo;0;L;;;;;N;;;;; +11097;KAITHI LETTER TTA;Lo;0;L;;;;;N;;;;; +11098;KAITHI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11099;KAITHI LETTER DDA;Lo;0;L;;;;;N;;;;; +1109A;KAITHI LETTER DDDHA;Lo;0;L;11099 110BA;;;;N;;;;; +1109B;KAITHI LETTER DDHA;Lo;0;L;;;;;N;;;;; +1109C;KAITHI LETTER RHA;Lo;0;L;1109B 110BA;;;;N;;;;; +1109D;KAITHI LETTER NNA;Lo;0;L;;;;;N;;;;; +1109E;KAITHI LETTER TA;Lo;0;L;;;;;N;;;;; +1109F;KAITHI LETTER THA;Lo;0;L;;;;;N;;;;; +110A0;KAITHI LETTER DA;Lo;0;L;;;;;N;;;;; +110A1;KAITHI LETTER DHA;Lo;0;L;;;;;N;;;;; +110A2;KAITHI LETTER NA;Lo;0;L;;;;;N;;;;; +110A3;KAITHI LETTER PA;Lo;0;L;;;;;N;;;;; +110A4;KAITHI LETTER PHA;Lo;0;L;;;;;N;;;;; +110A5;KAITHI LETTER BA;Lo;0;L;;;;;N;;;;; +110A6;KAITHI LETTER BHA;Lo;0;L;;;;;N;;;;; +110A7;KAITHI LETTER MA;Lo;0;L;;;;;N;;;;; +110A8;KAITHI LETTER YA;Lo;0;L;;;;;N;;;;; +110A9;KAITHI LETTER RA;Lo;0;L;;;;;N;;;;; +110AA;KAITHI LETTER LA;Lo;0;L;;;;;N;;;;; +110AB;KAITHI LETTER VA;Lo;0;L;110A5 110BA;;;;N;;;;; +110AC;KAITHI LETTER SHA;Lo;0;L;;;;;N;;;;; +110AD;KAITHI LETTER SSA;Lo;0;L;;;;;N;;;;; +110AE;KAITHI LETTER SA;Lo;0;L;;;;;N;;;;; +110AF;KAITHI LETTER HA;Lo;0;L;;;;;N;;;;; +110B0;KAITHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +110B1;KAITHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +110B2;KAITHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +110B3;KAITHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +110B4;KAITHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +110B5;KAITHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +110B6;KAITHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +110B7;KAITHI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +110B8;KAITHI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +110B9;KAITHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +110BA;KAITHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +110BB;KAITHI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +110BC;KAITHI ENUMERATION SIGN;Po;0;L;;;;;N;;;;; +110BD;KAITHI NUMBER SIGN;Cf;0;L;;;;;N;;;;; +110BE;KAITHI SECTION MARK;Po;0;L;;;;;N;;;;; +110BF;KAITHI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;; +110C0;KAITHI DANDA;Po;0;L;;;;;N;;;;; +110C1;KAITHI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;; +12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;; +12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;; +12003;CUNEIFORM SIGN A TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12004;CUNEIFORM SIGN A TIMES HA;Lo;0;L;;;;;N;;;;; +12005;CUNEIFORM SIGN A TIMES IGI;Lo;0;L;;;;;N;;;;; +12006;CUNEIFORM SIGN A TIMES LAGAR GUNU;Lo;0;L;;;;;N;;;;; +12007;CUNEIFORM SIGN A TIMES MUSH;Lo;0;L;;;;;N;;;;; +12008;CUNEIFORM SIGN A TIMES SAG;Lo;0;L;;;;;N;;;;; +12009;CUNEIFORM SIGN A2;Lo;0;L;;;;;N;;;;; +1200A;CUNEIFORM SIGN AB;Lo;0;L;;;;;N;;;;; +1200B;CUNEIFORM SIGN AB TIMES ASH2;Lo;0;L;;;;;N;;;;; +1200C;CUNEIFORM SIGN AB TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;; +1200D;CUNEIFORM SIGN AB TIMES GAL;Lo;0;L;;;;;N;;;;; +1200E;CUNEIFORM SIGN AB TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1200F;CUNEIFORM SIGN AB TIMES HA;Lo;0;L;;;;;N;;;;; +12010;CUNEIFORM SIGN AB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +12011;CUNEIFORM SIGN AB TIMES IMIN;Lo;0;L;;;;;N;;;;; +12012;CUNEIFORM SIGN AB TIMES LAGAB;Lo;0;L;;;;;N;;;;; +12013;CUNEIFORM SIGN AB TIMES SHESH;Lo;0;L;;;;;N;;;;; +12014;CUNEIFORM SIGN AB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;; +12015;CUNEIFORM SIGN AB GUNU;Lo;0;L;;;;;N;;;;; +12016;CUNEIFORM SIGN AB2;Lo;0;L;;;;;N;;;;; +12017;CUNEIFORM SIGN AB2 TIMES BALAG;Lo;0;L;;;;;N;;;;; +12018;CUNEIFORM SIGN AB2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12019;CUNEIFORM SIGN AB2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;; +1201A;CUNEIFORM SIGN AB2 TIMES SHA3;Lo;0;L;;;;;N;;;;; +1201B;CUNEIFORM SIGN AB2 TIMES TAK4;Lo;0;L;;;;;N;;;;; +1201C;CUNEIFORM SIGN AD;Lo;0;L;;;;;N;;;;; +1201D;CUNEIFORM SIGN AK;Lo;0;L;;;;;N;;;;; +1201E;CUNEIFORM SIGN AK TIMES ERIN2;Lo;0;L;;;;;N;;;;; +1201F;CUNEIFORM SIGN AK TIMES SHITA PLUS GISH;Lo;0;L;;;;;N;;;;; +12020;CUNEIFORM SIGN AL;Lo;0;L;;;;;N;;;;; +12021;CUNEIFORM SIGN AL TIMES AL;Lo;0;L;;;;;N;;;;; +12022;CUNEIFORM SIGN AL TIMES DIM2;Lo;0;L;;;;;N;;;;; +12023;CUNEIFORM SIGN AL TIMES GISH;Lo;0;L;;;;;N;;;;; +12024;CUNEIFORM SIGN AL TIMES HA;Lo;0;L;;;;;N;;;;; +12025;CUNEIFORM SIGN AL TIMES KAD3;Lo;0;L;;;;;N;;;;; +12026;CUNEIFORM SIGN AL TIMES KI;Lo;0;L;;;;;N;;;;; +12027;CUNEIFORM SIGN AL TIMES SHE;Lo;0;L;;;;;N;;;;; +12028;CUNEIFORM SIGN AL TIMES USH;Lo;0;L;;;;;N;;;;; +12029;CUNEIFORM SIGN ALAN;Lo;0;L;;;;;N;;;;; +1202A;CUNEIFORM SIGN ALEPH;Lo;0;L;;;;;N;;;;; +1202B;CUNEIFORM SIGN AMAR;Lo;0;L;;;;;N;;;;; +1202C;CUNEIFORM SIGN AMAR TIMES SHE;Lo;0;L;;;;;N;;;;; +1202D;CUNEIFORM SIGN AN;Lo;0;L;;;;;N;;;;; +1202E;CUNEIFORM SIGN AN OVER AN;Lo;0;L;;;;;N;;;;; +1202F;CUNEIFORM SIGN AN THREE TIMES;Lo;0;L;;;;;N;;;;; +12030;CUNEIFORM SIGN AN PLUS NAGA OPPOSING AN PLUS NAGA;Lo;0;L;;;;;N;;;;; +12031;CUNEIFORM SIGN AN PLUS NAGA SQUARED;Lo;0;L;;;;;N;;;;; +12032;CUNEIFORM SIGN ANSHE;Lo;0;L;;;;;N;;;;; +12033;CUNEIFORM SIGN APIN;Lo;0;L;;;;;N;;;;; +12034;CUNEIFORM SIGN ARAD;Lo;0;L;;;;;N;;;;; +12035;CUNEIFORM SIGN ARAD TIMES KUR;Lo;0;L;;;;;N;;;;; +12036;CUNEIFORM SIGN ARKAB;Lo;0;L;;;;;N;;;;; +12037;CUNEIFORM SIGN ASAL2;Lo;0;L;;;;;N;;;;; +12038;CUNEIFORM SIGN ASH;Lo;0;L;;;;;N;;;;; +12039;CUNEIFORM SIGN ASH ZIDA TENU;Lo;0;L;;;;;N;;;;; +1203A;CUNEIFORM SIGN ASH KABA TENU;Lo;0;L;;;;;N;;;;; +1203B;CUNEIFORM SIGN ASH OVER ASH TUG2 OVER TUG2 TUG2 OVER TUG2 PAP;Lo;0;L;;;;;N;;;;; +1203C;CUNEIFORM SIGN ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;; +1203D;CUNEIFORM SIGN ASH OVER ASH OVER ASH CROSSING ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;; +1203E;CUNEIFORM SIGN ASH2;Lo;0;L;;;;;N;;;;; +1203F;CUNEIFORM SIGN ASHGAB;Lo;0;L;;;;;N;;;;; +12040;CUNEIFORM SIGN BA;Lo;0;L;;;;;N;;;;; +12041;CUNEIFORM SIGN BAD;Lo;0;L;;;;;N;;;;; +12042;CUNEIFORM SIGN BAG3;Lo;0;L;;;;;N;;;;; +12043;CUNEIFORM SIGN BAHAR2;Lo;0;L;;;;;N;;;;; +12044;CUNEIFORM SIGN BAL;Lo;0;L;;;;;N;;;;; +12045;CUNEIFORM SIGN BAL OVER BAL;Lo;0;L;;;;;N;;;;; +12046;CUNEIFORM SIGN BALAG;Lo;0;L;;;;;N;;;;; +12047;CUNEIFORM SIGN BAR;Lo;0;L;;;;;N;;;;; +12048;CUNEIFORM SIGN BARA2;Lo;0;L;;;;;N;;;;; +12049;CUNEIFORM SIGN BI;Lo;0;L;;;;;N;;;;; +1204A;CUNEIFORM SIGN BI TIMES A;Lo;0;L;;;;;N;;;;; +1204B;CUNEIFORM SIGN BI TIMES GAR;Lo;0;L;;;;;N;;;;; +1204C;CUNEIFORM SIGN BI TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +1204D;CUNEIFORM SIGN BU;Lo;0;L;;;;;N;;;;; +1204E;CUNEIFORM SIGN BU OVER BU AB;Lo;0;L;;;;;N;;;;; +1204F;CUNEIFORM SIGN BU OVER BU UN;Lo;0;L;;;;;N;;;;; +12050;CUNEIFORM SIGN BU CROSSING BU;Lo;0;L;;;;;N;;;;; +12051;CUNEIFORM SIGN BULUG;Lo;0;L;;;;;N;;;;; +12052;CUNEIFORM SIGN BULUG OVER BULUG;Lo;0;L;;;;;N;;;;; +12053;CUNEIFORM SIGN BUR;Lo;0;L;;;;;N;;;;; +12054;CUNEIFORM SIGN BUR2;Lo;0;L;;;;;N;;;;; +12055;CUNEIFORM SIGN DA;Lo;0;L;;;;;N;;;;; +12056;CUNEIFORM SIGN DAG;Lo;0;L;;;;;N;;;;; +12057;CUNEIFORM SIGN DAG KISIM5 TIMES A PLUS MASH;Lo;0;L;;;;;N;;;;; +12058;CUNEIFORM SIGN DAG KISIM5 TIMES AMAR;Lo;0;L;;;;;N;;;;; +12059;CUNEIFORM SIGN DAG KISIM5 TIMES BALAG;Lo;0;L;;;;;N;;;;; +1205A;CUNEIFORM SIGN DAG KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;; +1205B;CUNEIFORM SIGN DAG KISIM5 TIMES GA;Lo;0;L;;;;;N;;;;; +1205C;CUNEIFORM SIGN DAG KISIM5 TIMES GA PLUS MASH;Lo;0;L;;;;;N;;;;; +1205D;CUNEIFORM SIGN DAG KISIM5 TIMES GI;Lo;0;L;;;;;N;;;;; +1205E;CUNEIFORM SIGN DAG KISIM5 TIMES GIR2;Lo;0;L;;;;;N;;;;; +1205F;CUNEIFORM SIGN DAG KISIM5 TIMES GUD;Lo;0;L;;;;;N;;;;; +12060;CUNEIFORM SIGN DAG KISIM5 TIMES HA;Lo;0;L;;;;;N;;;;; +12061;CUNEIFORM SIGN DAG KISIM5 TIMES IR;Lo;0;L;;;;;N;;;;; +12062;CUNEIFORM SIGN DAG KISIM5 TIMES IR PLUS LU;Lo;0;L;;;;;N;;;;; +12063;CUNEIFORM SIGN DAG KISIM5 TIMES KAK;Lo;0;L;;;;;N;;;;; +12064;CUNEIFORM SIGN DAG KISIM5 TIMES LA;Lo;0;L;;;;;N;;;;; +12065;CUNEIFORM SIGN DAG KISIM5 TIMES LU;Lo;0;L;;;;;N;;;;; +12066;CUNEIFORM SIGN DAG KISIM5 TIMES LU PLUS MASH2;Lo;0;L;;;;;N;;;;; +12067;CUNEIFORM SIGN DAG KISIM5 TIMES LUM;Lo;0;L;;;;;N;;;;; +12068;CUNEIFORM SIGN DAG KISIM5 TIMES NE;Lo;0;L;;;;;N;;;;; +12069;CUNEIFORM SIGN DAG KISIM5 TIMES PAP PLUS PAP;Lo;0;L;;;;;N;;;;; +1206A;CUNEIFORM SIGN DAG KISIM5 TIMES SI;Lo;0;L;;;;;N;;;;; +1206B;CUNEIFORM SIGN DAG KISIM5 TIMES TAK4;Lo;0;L;;;;;N;;;;; +1206C;CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS GIR2;Lo;0;L;;;;;N;;;;; +1206D;CUNEIFORM SIGN DAG KISIM5 TIMES USH;Lo;0;L;;;;;N;;;;; +1206E;CUNEIFORM SIGN DAM;Lo;0;L;;;;;N;;;;; +1206F;CUNEIFORM SIGN DAR;Lo;0;L;;;;;N;;;;; +12070;CUNEIFORM SIGN DARA3;Lo;0;L;;;;;N;;;;; +12071;CUNEIFORM SIGN DARA4;Lo;0;L;;;;;N;;;;; +12072;CUNEIFORM SIGN DI;Lo;0;L;;;;;N;;;;; +12073;CUNEIFORM SIGN DIB;Lo;0;L;;;;;N;;;;; +12074;CUNEIFORM SIGN DIM;Lo;0;L;;;;;N;;;;; +12075;CUNEIFORM SIGN DIM TIMES SHE;Lo;0;L;;;;;N;;;;; +12076;CUNEIFORM SIGN DIM2;Lo;0;L;;;;;N;;;;; +12077;CUNEIFORM SIGN DIN;Lo;0;L;;;;;N;;;;; +12078;CUNEIFORM SIGN DIN KASKAL U GUNU DISH;Lo;0;L;;;;;N;;;;; +12079;CUNEIFORM SIGN DISH;Lo;0;L;;;;;N;;;;; +1207A;CUNEIFORM SIGN DU;Lo;0;L;;;;;N;;;;; +1207B;CUNEIFORM SIGN DU OVER DU;Lo;0;L;;;;;N;;;;; +1207C;CUNEIFORM SIGN DU GUNU;Lo;0;L;;;;;N;;;;; +1207D;CUNEIFORM SIGN DU SHESHIG;Lo;0;L;;;;;N;;;;; +1207E;CUNEIFORM SIGN DUB;Lo;0;L;;;;;N;;;;; +1207F;CUNEIFORM SIGN DUB TIMES ESH2;Lo;0;L;;;;;N;;;;; +12080;CUNEIFORM SIGN DUB2;Lo;0;L;;;;;N;;;;; +12081;CUNEIFORM SIGN DUG;Lo;0;L;;;;;N;;;;; +12082;CUNEIFORM SIGN DUGUD;Lo;0;L;;;;;N;;;;; +12083;CUNEIFORM SIGN DUH;Lo;0;L;;;;;N;;;;; +12084;CUNEIFORM SIGN DUN;Lo;0;L;;;;;N;;;;; +12085;CUNEIFORM SIGN DUN3;Lo;0;L;;;;;N;;;;; +12086;CUNEIFORM SIGN DUN3 GUNU;Lo;0;L;;;;;N;;;;; +12087;CUNEIFORM SIGN DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;; +12088;CUNEIFORM SIGN DUN4;Lo;0;L;;;;;N;;;;; +12089;CUNEIFORM SIGN DUR2;Lo;0;L;;;;;N;;;;; +1208A;CUNEIFORM SIGN E;Lo;0;L;;;;;N;;;;; +1208B;CUNEIFORM SIGN E TIMES PAP;Lo;0;L;;;;;N;;;;; +1208C;CUNEIFORM SIGN E OVER E NUN OVER NUN;Lo;0;L;;;;;N;;;;; +1208D;CUNEIFORM SIGN E2;Lo;0;L;;;;;N;;;;; +1208E;CUNEIFORM SIGN E2 TIMES A PLUS HA PLUS DA;Lo;0;L;;;;;N;;;;; +1208F;CUNEIFORM SIGN E2 TIMES GAR;Lo;0;L;;;;;N;;;;; +12090;CUNEIFORM SIGN E2 TIMES MI;Lo;0;L;;;;;N;;;;; +12091;CUNEIFORM SIGN E2 TIMES SAL;Lo;0;L;;;;;N;;;;; +12092;CUNEIFORM SIGN E2 TIMES SHE;Lo;0;L;;;;;N;;;;; +12093;CUNEIFORM SIGN E2 TIMES U;Lo;0;L;;;;;N;;;;; +12094;CUNEIFORM SIGN EDIN;Lo;0;L;;;;;N;;;;; +12095;CUNEIFORM SIGN EGIR;Lo;0;L;;;;;N;;;;; +12096;CUNEIFORM SIGN EL;Lo;0;L;;;;;N;;;;; +12097;CUNEIFORM SIGN EN;Lo;0;L;;;;;N;;;;; +12098;CUNEIFORM SIGN EN TIMES GAN2;Lo;0;L;;;;;N;;;;; +12099;CUNEIFORM SIGN EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1209A;CUNEIFORM SIGN EN TIMES ME;Lo;0;L;;;;;N;;;;; +1209B;CUNEIFORM SIGN EN CROSSING EN;Lo;0;L;;;;;N;;;;; +1209C;CUNEIFORM SIGN EN OPPOSING EN;Lo;0;L;;;;;N;;;;; +1209D;CUNEIFORM SIGN EN SQUARED;Lo;0;L;;;;;N;;;;; +1209E;CUNEIFORM SIGN EREN;Lo;0;L;;;;;N;;;;; +1209F;CUNEIFORM SIGN ERIN2;Lo;0;L;;;;;N;;;;; +120A0;CUNEIFORM SIGN ESH2;Lo;0;L;;;;;N;;;;; +120A1;CUNEIFORM SIGN EZEN;Lo;0;L;;;;;N;;;;; +120A2;CUNEIFORM SIGN EZEN TIMES A;Lo;0;L;;;;;N;;;;; +120A3;CUNEIFORM SIGN EZEN TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;; +120A4;CUNEIFORM SIGN EZEN TIMES A PLUS LAL TIMES LAL;Lo;0;L;;;;;N;;;;; +120A5;CUNEIFORM SIGN EZEN TIMES AN;Lo;0;L;;;;;N;;;;; +120A6;CUNEIFORM SIGN EZEN TIMES BAD;Lo;0;L;;;;;N;;;;; +120A7;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;; +120A8;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;; +120A9;CUNEIFORM SIGN EZEN TIMES HA;Lo;0;L;;;;;N;;;;; +120AA;CUNEIFORM SIGN EZEN TIMES HA GUNU;Lo;0;L;;;;;N;;;;; +120AB;CUNEIFORM SIGN EZEN TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +120AC;CUNEIFORM SIGN EZEN TIMES KASKAL;Lo;0;L;;;;;N;;;;; +120AD;CUNEIFORM SIGN EZEN TIMES KASKAL SQUARED;Lo;0;L;;;;;N;;;;; +120AE;CUNEIFORM SIGN EZEN TIMES KU3;Lo;0;L;;;;;N;;;;; +120AF;CUNEIFORM SIGN EZEN TIMES LA;Lo;0;L;;;;;N;;;;; +120B0;CUNEIFORM SIGN EZEN TIMES LAL TIMES LAL;Lo;0;L;;;;;N;;;;; +120B1;CUNEIFORM SIGN EZEN TIMES LI;Lo;0;L;;;;;N;;;;; +120B2;CUNEIFORM SIGN EZEN TIMES LU;Lo;0;L;;;;;N;;;;; +120B3;CUNEIFORM SIGN EZEN TIMES U2;Lo;0;L;;;;;N;;;;; +120B4;CUNEIFORM SIGN EZEN TIMES UD;Lo;0;L;;;;;N;;;;; +120B5;CUNEIFORM SIGN GA;Lo;0;L;;;;;N;;;;; +120B6;CUNEIFORM SIGN GA GUNU;Lo;0;L;;;;;N;;;;; +120B7;CUNEIFORM SIGN GA2;Lo;0;L;;;;;N;;;;; +120B8;CUNEIFORM SIGN GA2 TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;; +120B9;CUNEIFORM SIGN GA2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;; +120BA;CUNEIFORM SIGN GA2 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;; +120BB;CUNEIFORM SIGN GA2 TIMES AB2 TENU PLUS TAB;Lo;0;L;;;;;N;;;;; +120BC;CUNEIFORM SIGN GA2 TIMES AN;Lo;0;L;;;;;N;;;;; +120BD;CUNEIFORM SIGN GA2 TIMES ASH;Lo;0;L;;;;;N;;;;; +120BE;CUNEIFORM SIGN GA2 TIMES ASH2 PLUS GAL;Lo;0;L;;;;;N;;;;; +120BF;CUNEIFORM SIGN GA2 TIMES BAD;Lo;0;L;;;;;N;;;;; +120C0;CUNEIFORM SIGN GA2 TIMES BAR PLUS RA;Lo;0;L;;;;;N;;;;; +120C1;CUNEIFORM SIGN GA2 TIMES BUR;Lo;0;L;;;;;N;;;;; +120C2;CUNEIFORM SIGN GA2 TIMES BUR PLUS RA;Lo;0;L;;;;;N;;;;; +120C3;CUNEIFORM SIGN GA2 TIMES DA;Lo;0;L;;;;;N;;;;; +120C4;CUNEIFORM SIGN GA2 TIMES DI;Lo;0;L;;;;;N;;;;; +120C5;CUNEIFORM SIGN GA2 TIMES DIM TIMES SHE;Lo;0;L;;;;;N;;;;; +120C6;CUNEIFORM SIGN GA2 TIMES DUB;Lo;0;L;;;;;N;;;;; +120C7;CUNEIFORM SIGN GA2 TIMES EL;Lo;0;L;;;;;N;;;;; +120C8;CUNEIFORM SIGN GA2 TIMES EL PLUS LA;Lo;0;L;;;;;N;;;;; +120C9;CUNEIFORM SIGN GA2 TIMES EN;Lo;0;L;;;;;N;;;;; +120CA;CUNEIFORM SIGN GA2 TIMES EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +120CB;CUNEIFORM SIGN GA2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +120CC;CUNEIFORM SIGN GA2 TIMES GAR;Lo;0;L;;;;;N;;;;; +120CD;CUNEIFORM SIGN GA2 TIMES GI;Lo;0;L;;;;;N;;;;; +120CE;CUNEIFORM SIGN GA2 TIMES GI4;Lo;0;L;;;;;N;;;;; +120CF;CUNEIFORM SIGN GA2 TIMES GI4 PLUS A;Lo;0;L;;;;;N;;;;; +120D0;CUNEIFORM SIGN GA2 TIMES GIR2 PLUS SU;Lo;0;L;;;;;N;;;;; +120D1;CUNEIFORM SIGN GA2 TIMES HA PLUS LU PLUS ESH2;Lo;0;L;;;;;N;;;;; +120D2;CUNEIFORM SIGN GA2 TIMES HAL;Lo;0;L;;;;;N;;;;; +120D3;CUNEIFORM SIGN GA2 TIMES HAL PLUS LA;Lo;0;L;;;;;N;;;;; +120D4;CUNEIFORM SIGN GA2 TIMES HI PLUS LI;Lo;0;L;;;;;N;;;;; +120D5;CUNEIFORM SIGN GA2 TIMES HUB2;Lo;0;L;;;;;N;;;;; +120D6;CUNEIFORM SIGN GA2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +120D7;CUNEIFORM SIGN GA2 TIMES ISH PLUS HU PLUS ASH;Lo;0;L;;;;;N;;;;; +120D8;CUNEIFORM SIGN GA2 TIMES KAK;Lo;0;L;;;;;N;;;;; +120D9;CUNEIFORM SIGN GA2 TIMES KASKAL;Lo;0;L;;;;;N;;;;; +120DA;CUNEIFORM SIGN GA2 TIMES KID;Lo;0;L;;;;;N;;;;; +120DB;CUNEIFORM SIGN GA2 TIMES KID PLUS LAL;Lo;0;L;;;;;N;;;;; +120DC;CUNEIFORM SIGN GA2 TIMES KU3 PLUS AN;Lo;0;L;;;;;N;;;;; +120DD;CUNEIFORM SIGN GA2 TIMES LA;Lo;0;L;;;;;N;;;;; +120DE;CUNEIFORM SIGN GA2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;; +120DF;CUNEIFORM SIGN GA2 TIMES MI;Lo;0;L;;;;;N;;;;; +120E0;CUNEIFORM SIGN GA2 TIMES NUN;Lo;0;L;;;;;N;;;;; +120E1;CUNEIFORM SIGN GA2 TIMES NUN OVER NUN;Lo;0;L;;;;;N;;;;; +120E2;CUNEIFORM SIGN GA2 TIMES PA;Lo;0;L;;;;;N;;;;; +120E3;CUNEIFORM SIGN GA2 TIMES SAL;Lo;0;L;;;;;N;;;;; +120E4;CUNEIFORM SIGN GA2 TIMES SAR;Lo;0;L;;;;;N;;;;; +120E5;CUNEIFORM SIGN GA2 TIMES SHE;Lo;0;L;;;;;N;;;;; +120E6;CUNEIFORM SIGN GA2 TIMES SHE PLUS TUR;Lo;0;L;;;;;N;;;;; +120E7;CUNEIFORM SIGN GA2 TIMES SHID;Lo;0;L;;;;;N;;;;; +120E8;CUNEIFORM SIGN GA2 TIMES SUM;Lo;0;L;;;;;N;;;;; +120E9;CUNEIFORM SIGN GA2 TIMES TAK4;Lo;0;L;;;;;N;;;;; +120EA;CUNEIFORM SIGN GA2 TIMES U;Lo;0;L;;;;;N;;;;; +120EB;CUNEIFORM SIGN GA2 TIMES UD;Lo;0;L;;;;;N;;;;; +120EC;CUNEIFORM SIGN GA2 TIMES UD PLUS DU;Lo;0;L;;;;;N;;;;; +120ED;CUNEIFORM SIGN GA2 OVER GA2;Lo;0;L;;;;;N;;;;; +120EE;CUNEIFORM SIGN GABA;Lo;0;L;;;;;N;;;;; +120EF;CUNEIFORM SIGN GABA CROSSING GABA;Lo;0;L;;;;;N;;;;; +120F0;CUNEIFORM SIGN GAD;Lo;0;L;;;;;N;;;;; +120F1;CUNEIFORM SIGN GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;; +120F2;CUNEIFORM SIGN GAL;Lo;0;L;;;;;N;;;;; +120F3;CUNEIFORM SIGN GAL GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;; +120F4;CUNEIFORM SIGN GALAM;Lo;0;L;;;;;N;;;;; +120F5;CUNEIFORM SIGN GAM;Lo;0;L;;;;;N;;;;; +120F6;CUNEIFORM SIGN GAN;Lo;0;L;;;;;N;;;;; +120F7;CUNEIFORM SIGN GAN2;Lo;0;L;;;;;N;;;;; +120F8;CUNEIFORM SIGN GAN2 TENU;Lo;0;L;;;;;N;;;;; +120F9;CUNEIFORM SIGN GAN2 OVER GAN2;Lo;0;L;;;;;N;;;;; +120FA;CUNEIFORM SIGN GAN2 CROSSING GAN2;Lo;0;L;;;;;N;;;;; +120FB;CUNEIFORM SIGN GAR;Lo;0;L;;;;;N;;;;; +120FC;CUNEIFORM SIGN GAR3;Lo;0;L;;;;;N;;;;; +120FD;CUNEIFORM SIGN GASHAN;Lo;0;L;;;;;N;;;;; +120FE;CUNEIFORM SIGN GESHTIN;Lo;0;L;;;;;N;;;;; +120FF;CUNEIFORM SIGN GESHTIN TIMES KUR;Lo;0;L;;;;;N;;;;; +12100;CUNEIFORM SIGN GI;Lo;0;L;;;;;N;;;;; +12101;CUNEIFORM SIGN GI TIMES E;Lo;0;L;;;;;N;;;;; +12102;CUNEIFORM SIGN GI TIMES U;Lo;0;L;;;;;N;;;;; +12103;CUNEIFORM SIGN GI CROSSING GI;Lo;0;L;;;;;N;;;;; +12104;CUNEIFORM SIGN GI4;Lo;0;L;;;;;N;;;;; +12105;CUNEIFORM SIGN GI4 OVER GI4;Lo;0;L;;;;;N;;;;; +12106;CUNEIFORM SIGN GI4 CROSSING GI4;Lo;0;L;;;;;N;;;;; +12107;CUNEIFORM SIGN GIDIM;Lo;0;L;;;;;N;;;;; +12108;CUNEIFORM SIGN GIR2;Lo;0;L;;;;;N;;;;; +12109;CUNEIFORM SIGN GIR2 GUNU;Lo;0;L;;;;;N;;;;; +1210A;CUNEIFORM SIGN GIR3;Lo;0;L;;;;;N;;;;; +1210B;CUNEIFORM SIGN GIR3 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;; +1210C;CUNEIFORM SIGN GIR3 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1210D;CUNEIFORM SIGN GIR3 TIMES IGI;Lo;0;L;;;;;N;;;;; +1210E;CUNEIFORM SIGN GIR3 TIMES LU PLUS IGI;Lo;0;L;;;;;N;;;;; +1210F;CUNEIFORM SIGN GIR3 TIMES PA;Lo;0;L;;;;;N;;;;; +12110;CUNEIFORM SIGN GISAL;Lo;0;L;;;;;N;;;;; +12111;CUNEIFORM SIGN GISH;Lo;0;L;;;;;N;;;;; +12112;CUNEIFORM SIGN GISH CROSSING GISH;Lo;0;L;;;;;N;;;;; +12113;CUNEIFORM SIGN GISH TIMES BAD;Lo;0;L;;;;;N;;;;; +12114;CUNEIFORM SIGN GISH TIMES TAK4;Lo;0;L;;;;;N;;;;; +12115;CUNEIFORM SIGN GISH TENU;Lo;0;L;;;;;N;;;;; +12116;CUNEIFORM SIGN GU;Lo;0;L;;;;;N;;;;; +12117;CUNEIFORM SIGN GU CROSSING GU;Lo;0;L;;;;;N;;;;; +12118;CUNEIFORM SIGN GU2;Lo;0;L;;;;;N;;;;; +12119;CUNEIFORM SIGN GU2 TIMES KAK;Lo;0;L;;;;;N;;;;; +1211A;CUNEIFORM SIGN GU2 TIMES KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +1211B;CUNEIFORM SIGN GU2 TIMES NUN;Lo;0;L;;;;;N;;;;; +1211C;CUNEIFORM SIGN GU2 TIMES SAL PLUS TUG2;Lo;0;L;;;;;N;;;;; +1211D;CUNEIFORM SIGN GU2 GUNU;Lo;0;L;;;;;N;;;;; +1211E;CUNEIFORM SIGN GUD;Lo;0;L;;;;;N;;;;; +1211F;CUNEIFORM SIGN GUD TIMES A PLUS KUR;Lo;0;L;;;;;N;;;;; +12120;CUNEIFORM SIGN GUD TIMES KUR;Lo;0;L;;;;;N;;;;; +12121;CUNEIFORM SIGN GUD OVER GUD LUGAL;Lo;0;L;;;;;N;;;;; +12122;CUNEIFORM SIGN GUL;Lo;0;L;;;;;N;;;;; +12123;CUNEIFORM SIGN GUM;Lo;0;L;;;;;N;;;;; +12124;CUNEIFORM SIGN GUM TIMES SHE;Lo;0;L;;;;;N;;;;; +12125;CUNEIFORM SIGN GUR;Lo;0;L;;;;;N;;;;; +12126;CUNEIFORM SIGN GUR7;Lo;0;L;;;;;N;;;;; +12127;CUNEIFORM SIGN GURUN;Lo;0;L;;;;;N;;;;; +12128;CUNEIFORM SIGN GURUSH;Lo;0;L;;;;;N;;;;; +12129;CUNEIFORM SIGN HA;Lo;0;L;;;;;N;;;;; +1212A;CUNEIFORM SIGN HA TENU;Lo;0;L;;;;;N;;;;; +1212B;CUNEIFORM SIGN HA GUNU;Lo;0;L;;;;;N;;;;; +1212C;CUNEIFORM SIGN HAL;Lo;0;L;;;;;N;;;;; +1212D;CUNEIFORM SIGN HI;Lo;0;L;;;;;N;;;;; +1212E;CUNEIFORM SIGN HI TIMES ASH;Lo;0;L;;;;;N;;;;; +1212F;CUNEIFORM SIGN HI TIMES ASH2;Lo;0;L;;;;;N;;;;; +12130;CUNEIFORM SIGN HI TIMES BAD;Lo;0;L;;;;;N;;;;; +12131;CUNEIFORM SIGN HI TIMES DISH;Lo;0;L;;;;;N;;;;; +12132;CUNEIFORM SIGN HI TIMES GAD;Lo;0;L;;;;;N;;;;; +12133;CUNEIFORM SIGN HI TIMES KIN;Lo;0;L;;;;;N;;;;; +12134;CUNEIFORM SIGN HI TIMES NUN;Lo;0;L;;;;;N;;;;; +12135;CUNEIFORM SIGN HI TIMES SHE;Lo;0;L;;;;;N;;;;; +12136;CUNEIFORM SIGN HI TIMES U;Lo;0;L;;;;;N;;;;; +12137;CUNEIFORM SIGN HU;Lo;0;L;;;;;N;;;;; +12138;CUNEIFORM SIGN HUB2;Lo;0;L;;;;;N;;;;; +12139;CUNEIFORM SIGN HUB2 TIMES AN;Lo;0;L;;;;;N;;;;; +1213A;CUNEIFORM SIGN HUB2 TIMES HAL;Lo;0;L;;;;;N;;;;; +1213B;CUNEIFORM SIGN HUB2 TIMES KASKAL;Lo;0;L;;;;;N;;;;; +1213C;CUNEIFORM SIGN HUB2 TIMES LISH;Lo;0;L;;;;;N;;;;; +1213D;CUNEIFORM SIGN HUB2 TIMES UD;Lo;0;L;;;;;N;;;;; +1213E;CUNEIFORM SIGN HUL2;Lo;0;L;;;;;N;;;;; +1213F;CUNEIFORM SIGN I;Lo;0;L;;;;;N;;;;; +12140;CUNEIFORM SIGN I A;Lo;0;L;;;;;N;;;;; +12141;CUNEIFORM SIGN IB;Lo;0;L;;;;;N;;;;; +12142;CUNEIFORM SIGN IDIM;Lo;0;L;;;;;N;;;;; +12143;CUNEIFORM SIGN IDIM OVER IDIM BUR;Lo;0;L;;;;;N;;;;; +12144;CUNEIFORM SIGN IDIM OVER IDIM SQUARED;Lo;0;L;;;;;N;;;;; +12145;CUNEIFORM SIGN IG;Lo;0;L;;;;;N;;;;; +12146;CUNEIFORM SIGN IGI;Lo;0;L;;;;;N;;;;; +12147;CUNEIFORM SIGN IGI DIB;Lo;0;L;;;;;N;;;;; +12148;CUNEIFORM SIGN IGI RI;Lo;0;L;;;;;N;;;;; +12149;CUNEIFORM SIGN IGI OVER IGI SHIR OVER SHIR UD OVER UD;Lo;0;L;;;;;N;;;;; +1214A;CUNEIFORM SIGN IGI GUNU;Lo;0;L;;;;;N;;;;; +1214B;CUNEIFORM SIGN IL;Lo;0;L;;;;;N;;;;; +1214C;CUNEIFORM SIGN IL TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1214D;CUNEIFORM SIGN IL2;Lo;0;L;;;;;N;;;;; +1214E;CUNEIFORM SIGN IM;Lo;0;L;;;;;N;;;;; +1214F;CUNEIFORM SIGN IM TIMES TAK4;Lo;0;L;;;;;N;;;;; +12150;CUNEIFORM SIGN IM CROSSING IM;Lo;0;L;;;;;N;;;;; +12151;CUNEIFORM SIGN IM OPPOSING IM;Lo;0;L;;;;;N;;;;; +12152;CUNEIFORM SIGN IM SQUARED;Lo;0;L;;;;;N;;;;; +12153;CUNEIFORM SIGN IMIN;Lo;0;L;;;;;N;;;;; +12154;CUNEIFORM SIGN IN;Lo;0;L;;;;;N;;;;; +12155;CUNEIFORM SIGN IR;Lo;0;L;;;;;N;;;;; +12156;CUNEIFORM SIGN ISH;Lo;0;L;;;;;N;;;;; +12157;CUNEIFORM SIGN KA;Lo;0;L;;;;;N;;;;; +12158;CUNEIFORM SIGN KA TIMES A;Lo;0;L;;;;;N;;;;; +12159;CUNEIFORM SIGN KA TIMES AD;Lo;0;L;;;;;N;;;;; +1215A;CUNEIFORM SIGN KA TIMES AD PLUS KU3;Lo;0;L;;;;;N;;;;; +1215B;CUNEIFORM SIGN KA TIMES ASH2;Lo;0;L;;;;;N;;;;; +1215C;CUNEIFORM SIGN KA TIMES BAD;Lo;0;L;;;;;N;;;;; +1215D;CUNEIFORM SIGN KA TIMES BALAG;Lo;0;L;;;;;N;;;;; +1215E;CUNEIFORM SIGN KA TIMES BAR;Lo;0;L;;;;;N;;;;; +1215F;CUNEIFORM SIGN KA TIMES BI;Lo;0;L;;;;;N;;;;; +12160;CUNEIFORM SIGN KA TIMES ERIN2;Lo;0;L;;;;;N;;;;; +12161;CUNEIFORM SIGN KA TIMES ESH2;Lo;0;L;;;;;N;;;;; +12162;CUNEIFORM SIGN KA TIMES GA;Lo;0;L;;;;;N;;;;; +12163;CUNEIFORM SIGN KA TIMES GAL;Lo;0;L;;;;;N;;;;; +12164;CUNEIFORM SIGN KA TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12165;CUNEIFORM SIGN KA TIMES GAR;Lo;0;L;;;;;N;;;;; +12166;CUNEIFORM SIGN KA TIMES GAR PLUS SHA3 PLUS A;Lo;0;L;;;;;N;;;;; +12167;CUNEIFORM SIGN KA TIMES GI;Lo;0;L;;;;;N;;;;; +12168;CUNEIFORM SIGN KA TIMES GIR2;Lo;0;L;;;;;N;;;;; +12169;CUNEIFORM SIGN KA TIMES GISH PLUS SAR;Lo;0;L;;;;;N;;;;; +1216A;CUNEIFORM SIGN KA TIMES GISH CROSSING GISH;Lo;0;L;;;;;N;;;;; +1216B;CUNEIFORM SIGN KA TIMES GU;Lo;0;L;;;;;N;;;;; +1216C;CUNEIFORM SIGN KA TIMES GUR7;Lo;0;L;;;;;N;;;;; +1216D;CUNEIFORM SIGN KA TIMES IGI;Lo;0;L;;;;;N;;;;; +1216E;CUNEIFORM SIGN KA TIMES IM;Lo;0;L;;;;;N;;;;; +1216F;CUNEIFORM SIGN KA TIMES KAK;Lo;0;L;;;;;N;;;;; +12170;CUNEIFORM SIGN KA TIMES KI;Lo;0;L;;;;;N;;;;; +12171;CUNEIFORM SIGN KA TIMES KID;Lo;0;L;;;;;N;;;;; +12172;CUNEIFORM SIGN KA TIMES LI;Lo;0;L;;;;;N;;;;; +12173;CUNEIFORM SIGN KA TIMES LU;Lo;0;L;;;;;N;;;;; +12174;CUNEIFORM SIGN KA TIMES ME;Lo;0;L;;;;;N;;;;; +12175;CUNEIFORM SIGN KA TIMES ME PLUS DU;Lo;0;L;;;;;N;;;;; +12176;CUNEIFORM SIGN KA TIMES ME PLUS GI;Lo;0;L;;;;;N;;;;; +12177;CUNEIFORM SIGN KA TIMES ME PLUS TE;Lo;0;L;;;;;N;;;;; +12178;CUNEIFORM SIGN KA TIMES MI;Lo;0;L;;;;;N;;;;; +12179;CUNEIFORM SIGN KA TIMES MI PLUS NUNUZ;Lo;0;L;;;;;N;;;;; +1217A;CUNEIFORM SIGN KA TIMES NE;Lo;0;L;;;;;N;;;;; +1217B;CUNEIFORM SIGN KA TIMES NUN;Lo;0;L;;;;;N;;;;; +1217C;CUNEIFORM SIGN KA TIMES PI;Lo;0;L;;;;;N;;;;; +1217D;CUNEIFORM SIGN KA TIMES RU;Lo;0;L;;;;;N;;;;; +1217E;CUNEIFORM SIGN KA TIMES SA;Lo;0;L;;;;;N;;;;; +1217F;CUNEIFORM SIGN KA TIMES SAR;Lo;0;L;;;;;N;;;;; +12180;CUNEIFORM SIGN KA TIMES SHA;Lo;0;L;;;;;N;;;;; +12181;CUNEIFORM SIGN KA TIMES SHE;Lo;0;L;;;;;N;;;;; +12182;CUNEIFORM SIGN KA TIMES SHID;Lo;0;L;;;;;N;;;;; +12183;CUNEIFORM SIGN KA TIMES SHU;Lo;0;L;;;;;N;;;;; +12184;CUNEIFORM SIGN KA TIMES SIG;Lo;0;L;;;;;N;;;;; +12185;CUNEIFORM SIGN KA TIMES SUHUR;Lo;0;L;;;;;N;;;;; +12186;CUNEIFORM SIGN KA TIMES TAR;Lo;0;L;;;;;N;;;;; +12187;CUNEIFORM SIGN KA TIMES U;Lo;0;L;;;;;N;;;;; +12188;CUNEIFORM SIGN KA TIMES U2;Lo;0;L;;;;;N;;;;; +12189;CUNEIFORM SIGN KA TIMES UD;Lo;0;L;;;;;N;;;;; +1218A;CUNEIFORM SIGN KA TIMES UMUM TIMES PA;Lo;0;L;;;;;N;;;;; +1218B;CUNEIFORM SIGN KA TIMES USH;Lo;0;L;;;;;N;;;;; +1218C;CUNEIFORM SIGN KA TIMES ZI;Lo;0;L;;;;;N;;;;; +1218D;CUNEIFORM SIGN KA2;Lo;0;L;;;;;N;;;;; +1218E;CUNEIFORM SIGN KA2 CROSSING KA2;Lo;0;L;;;;;N;;;;; +1218F;CUNEIFORM SIGN KAB;Lo;0;L;;;;;N;;;;; +12190;CUNEIFORM SIGN KAD2;Lo;0;L;;;;;N;;;;; +12191;CUNEIFORM SIGN KAD3;Lo;0;L;;;;;N;;;;; +12192;CUNEIFORM SIGN KAD4;Lo;0;L;;;;;N;;;;; +12193;CUNEIFORM SIGN KAD5;Lo;0;L;;;;;N;;;;; +12194;CUNEIFORM SIGN KAD5 OVER KAD5;Lo;0;L;;;;;N;;;;; +12195;CUNEIFORM SIGN KAK;Lo;0;L;;;;;N;;;;; +12196;CUNEIFORM SIGN KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +12197;CUNEIFORM SIGN KAL;Lo;0;L;;;;;N;;;;; +12198;CUNEIFORM SIGN KAL TIMES BAD;Lo;0;L;;;;;N;;;;; +12199;CUNEIFORM SIGN KAL CROSSING KAL;Lo;0;L;;;;;N;;;;; +1219A;CUNEIFORM SIGN KAM2;Lo;0;L;;;;;N;;;;; +1219B;CUNEIFORM SIGN KAM4;Lo;0;L;;;;;N;;;;; +1219C;CUNEIFORM SIGN KASKAL;Lo;0;L;;;;;N;;;;; +1219D;CUNEIFORM SIGN KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;; +1219E;CUNEIFORM SIGN KASKAL OVER KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;; +1219F;CUNEIFORM SIGN KESH2;Lo;0;L;;;;;N;;;;; +121A0;CUNEIFORM SIGN KI;Lo;0;L;;;;;N;;;;; +121A1;CUNEIFORM SIGN KI TIMES BAD;Lo;0;L;;;;;N;;;;; +121A2;CUNEIFORM SIGN KI TIMES U;Lo;0;L;;;;;N;;;;; +121A3;CUNEIFORM SIGN KI TIMES UD;Lo;0;L;;;;;N;;;;; +121A4;CUNEIFORM SIGN KID;Lo;0;L;;;;;N;;;;; +121A5;CUNEIFORM SIGN KIN;Lo;0;L;;;;;N;;;;; +121A6;CUNEIFORM SIGN KISAL;Lo;0;L;;;;;N;;;;; +121A7;CUNEIFORM SIGN KISH;Lo;0;L;;;;;N;;;;; +121A8;CUNEIFORM SIGN KISIM5;Lo;0;L;;;;;N;;;;; +121A9;CUNEIFORM SIGN KISIM5 OVER KISIM5;Lo;0;L;;;;;N;;;;; +121AA;CUNEIFORM SIGN KU;Lo;0;L;;;;;N;;;;; +121AB;CUNEIFORM SIGN KU OVER HI TIMES ASH2 KU OVER HI TIMES ASH2;Lo;0;L;;;;;N;;;;; +121AC;CUNEIFORM SIGN KU3;Lo;0;L;;;;;N;;;;; +121AD;CUNEIFORM SIGN KU4;Lo;0;L;;;;;N;;;;; +121AE;CUNEIFORM SIGN KU4 VARIANT FORM;Lo;0;L;;;;;N;;;;; +121AF;CUNEIFORM SIGN KU7;Lo;0;L;;;;;N;;;;; +121B0;CUNEIFORM SIGN KUL;Lo;0;L;;;;;N;;;;; +121B1;CUNEIFORM SIGN KUL GUNU;Lo;0;L;;;;;N;;;;; +121B2;CUNEIFORM SIGN KUN;Lo;0;L;;;;;N;;;;; +121B3;CUNEIFORM SIGN KUR;Lo;0;L;;;;;N;;;;; +121B4;CUNEIFORM SIGN KUR OPPOSING KUR;Lo;0;L;;;;;N;;;;; +121B5;CUNEIFORM SIGN KUSHU2;Lo;0;L;;;;;N;;;;; +121B6;CUNEIFORM SIGN KWU318;Lo;0;L;;;;;N;;;;; +121B7;CUNEIFORM SIGN LA;Lo;0;L;;;;;N;;;;; +121B8;CUNEIFORM SIGN LAGAB;Lo;0;L;;;;;N;;;;; +121B9;CUNEIFORM SIGN LAGAB TIMES A;Lo;0;L;;;;;N;;;;; +121BA;CUNEIFORM SIGN LAGAB TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;; +121BB;CUNEIFORM SIGN LAGAB TIMES A PLUS GAR;Lo;0;L;;;;;N;;;;; +121BC;CUNEIFORM SIGN LAGAB TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;; +121BD;CUNEIFORM SIGN LAGAB TIMES AL;Lo;0;L;;;;;N;;;;; +121BE;CUNEIFORM SIGN LAGAB TIMES AN;Lo;0;L;;;;;N;;;;; +121BF;CUNEIFORM SIGN LAGAB TIMES ASH ZIDA TENU;Lo;0;L;;;;;N;;;;; +121C0;CUNEIFORM SIGN LAGAB TIMES BAD;Lo;0;L;;;;;N;;;;; +121C1;CUNEIFORM SIGN LAGAB TIMES BI;Lo;0;L;;;;;N;;;;; +121C2;CUNEIFORM SIGN LAGAB TIMES DAR;Lo;0;L;;;;;N;;;;; +121C3;CUNEIFORM SIGN LAGAB TIMES EN;Lo;0;L;;;;;N;;;;; +121C4;CUNEIFORM SIGN LAGAB TIMES GA;Lo;0;L;;;;;N;;;;; +121C5;CUNEIFORM SIGN LAGAB TIMES GAR;Lo;0;L;;;;;N;;;;; +121C6;CUNEIFORM SIGN LAGAB TIMES GUD;Lo;0;L;;;;;N;;;;; +121C7;CUNEIFORM SIGN LAGAB TIMES GUD PLUS GUD;Lo;0;L;;;;;N;;;;; +121C8;CUNEIFORM SIGN LAGAB TIMES HA;Lo;0;L;;;;;N;;;;; +121C9;CUNEIFORM SIGN LAGAB TIMES HAL;Lo;0;L;;;;;N;;;;; +121CA;CUNEIFORM SIGN LAGAB TIMES HI TIMES NUN;Lo;0;L;;;;;N;;;;; +121CB;CUNEIFORM SIGN LAGAB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +121CC;CUNEIFORM SIGN LAGAB TIMES IM;Lo;0;L;;;;;N;;;;; +121CD;CUNEIFORM SIGN LAGAB TIMES IM PLUS HA;Lo;0;L;;;;;N;;;;; +121CE;CUNEIFORM SIGN LAGAB TIMES IM PLUS LU;Lo;0;L;;;;;N;;;;; +121CF;CUNEIFORM SIGN LAGAB TIMES KI;Lo;0;L;;;;;N;;;;; +121D0;CUNEIFORM SIGN LAGAB TIMES KIN;Lo;0;L;;;;;N;;;;; +121D1;CUNEIFORM SIGN LAGAB TIMES KU3;Lo;0;L;;;;;N;;;;; +121D2;CUNEIFORM SIGN LAGAB TIMES KUL;Lo;0;L;;;;;N;;;;; +121D3;CUNEIFORM SIGN LAGAB TIMES KUL PLUS HI PLUS A;Lo;0;L;;;;;N;;;;; +121D4;CUNEIFORM SIGN LAGAB TIMES LAGAB;Lo;0;L;;;;;N;;;;; +121D5;CUNEIFORM SIGN LAGAB TIMES LISH;Lo;0;L;;;;;N;;;;; +121D6;CUNEIFORM SIGN LAGAB TIMES LU;Lo;0;L;;;;;N;;;;; +121D7;CUNEIFORM SIGN LAGAB TIMES LUL;Lo;0;L;;;;;N;;;;; +121D8;CUNEIFORM SIGN LAGAB TIMES ME;Lo;0;L;;;;;N;;;;; +121D9;CUNEIFORM SIGN LAGAB TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;; +121DA;CUNEIFORM SIGN LAGAB TIMES MUSH;Lo;0;L;;;;;N;;;;; +121DB;CUNEIFORM SIGN LAGAB TIMES NE;Lo;0;L;;;;;N;;;;; +121DC;CUNEIFORM SIGN LAGAB TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;; +121DD;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH PLUS ERIN2;Lo;0;L;;;;;N;;;;; +121DE;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH TENU;Lo;0;L;;;;;N;;;;; +121DF;CUNEIFORM SIGN LAGAB TIMES SHU2;Lo;0;L;;;;;N;;;;; +121E0;CUNEIFORM SIGN LAGAB TIMES SHU2 PLUS SHU2;Lo;0;L;;;;;N;;;;; +121E1;CUNEIFORM SIGN LAGAB TIMES SUM;Lo;0;L;;;;;N;;;;; +121E2;CUNEIFORM SIGN LAGAB TIMES TAG;Lo;0;L;;;;;N;;;;; +121E3;CUNEIFORM SIGN LAGAB TIMES TAK4;Lo;0;L;;;;;N;;;;; +121E4;CUNEIFORM SIGN LAGAB TIMES TE PLUS A PLUS SU PLUS NA;Lo;0;L;;;;;N;;;;; +121E5;CUNEIFORM SIGN LAGAB TIMES U;Lo;0;L;;;;;N;;;;; +121E6;CUNEIFORM SIGN LAGAB TIMES U PLUS A;Lo;0;L;;;;;N;;;;; +121E7;CUNEIFORM SIGN LAGAB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;; +121E8;CUNEIFORM SIGN LAGAB TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;; +121E9;CUNEIFORM SIGN LAGAB TIMES UD;Lo;0;L;;;;;N;;;;; +121EA;CUNEIFORM SIGN LAGAB TIMES USH;Lo;0;L;;;;;N;;;;; +121EB;CUNEIFORM SIGN LAGAB SQUARED;Lo;0;L;;;;;N;;;;; +121EC;CUNEIFORM SIGN LAGAR;Lo;0;L;;;;;N;;;;; +121ED;CUNEIFORM SIGN LAGAR TIMES SHE;Lo;0;L;;;;;N;;;;; +121EE;CUNEIFORM SIGN LAGAR TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;; +121EF;CUNEIFORM SIGN LAGAR GUNU;Lo;0;L;;;;;N;;;;; +121F0;CUNEIFORM SIGN LAGAR GUNU OVER LAGAR GUNU SHE;Lo;0;L;;;;;N;;;;; +121F1;CUNEIFORM SIGN LAHSHU;Lo;0;L;;;;;N;;;;; +121F2;CUNEIFORM SIGN LAL;Lo;0;L;;;;;N;;;;; +121F3;CUNEIFORM SIGN LAL TIMES LAL;Lo;0;L;;;;;N;;;;; +121F4;CUNEIFORM SIGN LAM;Lo;0;L;;;;;N;;;;; +121F5;CUNEIFORM SIGN LAM TIMES KUR;Lo;0;L;;;;;N;;;;; +121F6;CUNEIFORM SIGN LAM TIMES KUR PLUS RU;Lo;0;L;;;;;N;;;;; +121F7;CUNEIFORM SIGN LI;Lo;0;L;;;;;N;;;;; +121F8;CUNEIFORM SIGN LIL;Lo;0;L;;;;;N;;;;; +121F9;CUNEIFORM SIGN LIMMU2;Lo;0;L;;;;;N;;;;; +121FA;CUNEIFORM SIGN LISH;Lo;0;L;;;;;N;;;;; +121FB;CUNEIFORM SIGN LU;Lo;0;L;;;;;N;;;;; +121FC;CUNEIFORM SIGN LU TIMES BAD;Lo;0;L;;;;;N;;;;; +121FD;CUNEIFORM SIGN LU2;Lo;0;L;;;;;N;;;;; +121FE;CUNEIFORM SIGN LU2 TIMES AL;Lo;0;L;;;;;N;;;;; +121FF;CUNEIFORM SIGN LU2 TIMES BAD;Lo;0;L;;;;;N;;;;; +12200;CUNEIFORM SIGN LU2 TIMES ESH2;Lo;0;L;;;;;N;;;;; +12201;CUNEIFORM SIGN LU2 TIMES ESH2 TENU;Lo;0;L;;;;;N;;;;; +12202;CUNEIFORM SIGN LU2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12203;CUNEIFORM SIGN LU2 TIMES HI TIMES BAD;Lo;0;L;;;;;N;;;;; +12204;CUNEIFORM SIGN LU2 TIMES IM;Lo;0;L;;;;;N;;;;; +12205;CUNEIFORM SIGN LU2 TIMES KAD2;Lo;0;L;;;;;N;;;;; +12206;CUNEIFORM SIGN LU2 TIMES KAD3;Lo;0;L;;;;;N;;;;; +12207;CUNEIFORM SIGN LU2 TIMES KAD3 PLUS ASH;Lo;0;L;;;;;N;;;;; +12208;CUNEIFORM SIGN LU2 TIMES KI;Lo;0;L;;;;;N;;;;; +12209;CUNEIFORM SIGN LU2 TIMES LA PLUS ASH;Lo;0;L;;;;;N;;;;; +1220A;CUNEIFORM SIGN LU2 TIMES LAGAB;Lo;0;L;;;;;N;;;;; +1220B;CUNEIFORM SIGN LU2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;; +1220C;CUNEIFORM SIGN LU2 TIMES NE;Lo;0;L;;;;;N;;;;; +1220D;CUNEIFORM SIGN LU2 TIMES NU;Lo;0;L;;;;;N;;;;; +1220E;CUNEIFORM SIGN LU2 TIMES SI PLUS ASH;Lo;0;L;;;;;N;;;;; +1220F;CUNEIFORM SIGN LU2 TIMES SIK2 PLUS BU;Lo;0;L;;;;;N;;;;; +12210;CUNEIFORM SIGN LU2 TIMES TUG2;Lo;0;L;;;;;N;;;;; +12211;CUNEIFORM SIGN LU2 TENU;Lo;0;L;;;;;N;;;;; +12212;CUNEIFORM SIGN LU2 CROSSING LU2;Lo;0;L;;;;;N;;;;; +12213;CUNEIFORM SIGN LU2 OPPOSING LU2;Lo;0;L;;;;;N;;;;; +12214;CUNEIFORM SIGN LU2 SQUARED;Lo;0;L;;;;;N;;;;; +12215;CUNEIFORM SIGN LU2 SHESHIG;Lo;0;L;;;;;N;;;;; +12216;CUNEIFORM SIGN LU3;Lo;0;L;;;;;N;;;;; +12217;CUNEIFORM SIGN LUGAL;Lo;0;L;;;;;N;;;;; +12218;CUNEIFORM SIGN LUGAL OVER LUGAL;Lo;0;L;;;;;N;;;;; +12219;CUNEIFORM SIGN LUGAL OPPOSING LUGAL;Lo;0;L;;;;;N;;;;; +1221A;CUNEIFORM SIGN LUGAL SHESHIG;Lo;0;L;;;;;N;;;;; +1221B;CUNEIFORM SIGN LUH;Lo;0;L;;;;;N;;;;; +1221C;CUNEIFORM SIGN LUL;Lo;0;L;;;;;N;;;;; +1221D;CUNEIFORM SIGN LUM;Lo;0;L;;;;;N;;;;; +1221E;CUNEIFORM SIGN LUM OVER LUM;Lo;0;L;;;;;N;;;;; +1221F;CUNEIFORM SIGN LUM OVER LUM GAR OVER GAR;Lo;0;L;;;;;N;;;;; +12220;CUNEIFORM SIGN MA;Lo;0;L;;;;;N;;;;; +12221;CUNEIFORM SIGN MA TIMES TAK4;Lo;0;L;;;;;N;;;;; +12222;CUNEIFORM SIGN MA GUNU;Lo;0;L;;;;;N;;;;; +12223;CUNEIFORM SIGN MA2;Lo;0;L;;;;;N;;;;; +12224;CUNEIFORM SIGN MAH;Lo;0;L;;;;;N;;;;; +12225;CUNEIFORM SIGN MAR;Lo;0;L;;;;;N;;;;; +12226;CUNEIFORM SIGN MASH;Lo;0;L;;;;;N;;;;; +12227;CUNEIFORM SIGN MASH2;Lo;0;L;;;;;N;;;;; +12228;CUNEIFORM SIGN ME;Lo;0;L;;;;;N;;;;; +12229;CUNEIFORM SIGN MES;Lo;0;L;;;;;N;;;;; +1222A;CUNEIFORM SIGN MI;Lo;0;L;;;;;N;;;;; +1222B;CUNEIFORM SIGN MIN;Lo;0;L;;;;;N;;;;; +1222C;CUNEIFORM SIGN MU;Lo;0;L;;;;;N;;;;; +1222D;CUNEIFORM SIGN MU OVER MU;Lo;0;L;;;;;N;;;;; +1222E;CUNEIFORM SIGN MUG;Lo;0;L;;;;;N;;;;; +1222F;CUNEIFORM SIGN MUG GUNU;Lo;0;L;;;;;N;;;;; +12230;CUNEIFORM SIGN MUNSUB;Lo;0;L;;;;;N;;;;; +12231;CUNEIFORM SIGN MURGU2;Lo;0;L;;;;;N;;;;; +12232;CUNEIFORM SIGN MUSH;Lo;0;L;;;;;N;;;;; +12233;CUNEIFORM SIGN MUSH TIMES A;Lo;0;L;;;;;N;;;;; +12234;CUNEIFORM SIGN MUSH TIMES KUR;Lo;0;L;;;;;N;;;;; +12235;CUNEIFORM SIGN MUSH TIMES ZA;Lo;0;L;;;;;N;;;;; +12236;CUNEIFORM SIGN MUSH OVER MUSH;Lo;0;L;;;;;N;;;;; +12237;CUNEIFORM SIGN MUSH OVER MUSH TIMES A PLUS NA;Lo;0;L;;;;;N;;;;; +12238;CUNEIFORM SIGN MUSH CROSSING MUSH;Lo;0;L;;;;;N;;;;; +12239;CUNEIFORM SIGN MUSH3;Lo;0;L;;;;;N;;;;; +1223A;CUNEIFORM SIGN MUSH3 TIMES A;Lo;0;L;;;;;N;;;;; +1223B;CUNEIFORM SIGN MUSH3 TIMES A PLUS DI;Lo;0;L;;;;;N;;;;; +1223C;CUNEIFORM SIGN MUSH3 TIMES DI;Lo;0;L;;;;;N;;;;; +1223D;CUNEIFORM SIGN MUSH3 GUNU;Lo;0;L;;;;;N;;;;; +1223E;CUNEIFORM SIGN NA;Lo;0;L;;;;;N;;;;; +1223F;CUNEIFORM SIGN NA2;Lo;0;L;;;;;N;;;;; +12240;CUNEIFORM SIGN NAGA;Lo;0;L;;;;;N;;;;; +12241;CUNEIFORM SIGN NAGA INVERTED;Lo;0;L;;;;;N;;;;; +12242;CUNEIFORM SIGN NAGA TIMES SHU TENU;Lo;0;L;;;;;N;;;;; +12243;CUNEIFORM SIGN NAGA OPPOSING NAGA;Lo;0;L;;;;;N;;;;; +12244;CUNEIFORM SIGN NAGAR;Lo;0;L;;;;;N;;;;; +12245;CUNEIFORM SIGN NAM NUTILLU;Lo;0;L;;;;;N;;;;; +12246;CUNEIFORM SIGN NAM;Lo;0;L;;;;;N;;;;; +12247;CUNEIFORM SIGN NAM2;Lo;0;L;;;;;N;;;;; +12248;CUNEIFORM SIGN NE;Lo;0;L;;;;;N;;;;; +12249;CUNEIFORM SIGN NE TIMES A;Lo;0;L;;;;;N;;;;; +1224A;CUNEIFORM SIGN NE TIMES UD;Lo;0;L;;;;;N;;;;; +1224B;CUNEIFORM SIGN NE SHESHIG;Lo;0;L;;;;;N;;;;; +1224C;CUNEIFORM SIGN NI;Lo;0;L;;;;;N;;;;; +1224D;CUNEIFORM SIGN NI TIMES E;Lo;0;L;;;;;N;;;;; +1224E;CUNEIFORM SIGN NI2;Lo;0;L;;;;;N;;;;; +1224F;CUNEIFORM SIGN NIM;Lo;0;L;;;;;N;;;;; +12250;CUNEIFORM SIGN NIM TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12251;CUNEIFORM SIGN NIM TIMES GAR PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;; +12252;CUNEIFORM SIGN NINDA2;Lo;0;L;;;;;N;;;;; +12253;CUNEIFORM SIGN NINDA2 TIMES AN;Lo;0;L;;;;;N;;;;; +12254;CUNEIFORM SIGN NINDA2 TIMES ASH;Lo;0;L;;;;;N;;;;; +12255;CUNEIFORM SIGN NINDA2 TIMES ASH PLUS ASH;Lo;0;L;;;;;N;;;;; +12256;CUNEIFORM SIGN NINDA2 TIMES GUD;Lo;0;L;;;;;N;;;;; +12257;CUNEIFORM SIGN NINDA2 TIMES ME PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;; +12258;CUNEIFORM SIGN NINDA2 TIMES NE;Lo;0;L;;;;;N;;;;; +12259;CUNEIFORM SIGN NINDA2 TIMES NUN;Lo;0;L;;;;;N;;;;; +1225A;CUNEIFORM SIGN NINDA2 TIMES SHE;Lo;0;L;;;;;N;;;;; +1225B;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS A AN;Lo;0;L;;;;;N;;;;; +1225C;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH;Lo;0;L;;;;;N;;;;; +1225D;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH PLUS ASH;Lo;0;L;;;;;N;;;;; +1225E;CUNEIFORM SIGN NINDA2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;; +1225F;CUNEIFORM SIGN NINDA2 TIMES USH;Lo;0;L;;;;;N;;;;; +12260;CUNEIFORM SIGN NISAG;Lo;0;L;;;;;N;;;;; +12261;CUNEIFORM SIGN NU;Lo;0;L;;;;;N;;;;; +12262;CUNEIFORM SIGN NU11;Lo;0;L;;;;;N;;;;; +12263;CUNEIFORM SIGN NUN;Lo;0;L;;;;;N;;;;; +12264;CUNEIFORM SIGN NUN LAGAR TIMES GAR;Lo;0;L;;;;;N;;;;; +12265;CUNEIFORM SIGN NUN LAGAR TIMES MASH;Lo;0;L;;;;;N;;;;; +12266;CUNEIFORM SIGN NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;; +12267;CUNEIFORM SIGN NUN LAGAR TIMES SAL OVER NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;; +12268;CUNEIFORM SIGN NUN LAGAR TIMES USH;Lo;0;L;;;;;N;;;;; +12269;CUNEIFORM SIGN NUN TENU;Lo;0;L;;;;;N;;;;; +1226A;CUNEIFORM SIGN NUN OVER NUN;Lo;0;L;;;;;N;;;;; +1226B;CUNEIFORM SIGN NUN CROSSING NUN;Lo;0;L;;;;;N;;;;; +1226C;CUNEIFORM SIGN NUN CROSSING NUN LAGAR OVER LAGAR;Lo;0;L;;;;;N;;;;; +1226D;CUNEIFORM SIGN NUNUZ;Lo;0;L;;;;;N;;;;; +1226E;CUNEIFORM SIGN NUNUZ AB2 TIMES ASHGAB;Lo;0;L;;;;;N;;;;; +1226F;CUNEIFORM SIGN NUNUZ AB2 TIMES BI;Lo;0;L;;;;;N;;;;; +12270;CUNEIFORM SIGN NUNUZ AB2 TIMES DUG;Lo;0;L;;;;;N;;;;; +12271;CUNEIFORM SIGN NUNUZ AB2 TIMES GUD;Lo;0;L;;;;;N;;;;; +12272;CUNEIFORM SIGN NUNUZ AB2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +12273;CUNEIFORM SIGN NUNUZ AB2 TIMES KAD3;Lo;0;L;;;;;N;;;;; +12274;CUNEIFORM SIGN NUNUZ AB2 TIMES LA;Lo;0;L;;;;;N;;;;; +12275;CUNEIFORM SIGN NUNUZ AB2 TIMES NE;Lo;0;L;;;;;N;;;;; +12276;CUNEIFORM SIGN NUNUZ AB2 TIMES SILA3;Lo;0;L;;;;;N;;;;; +12277;CUNEIFORM SIGN NUNUZ AB2 TIMES U2;Lo;0;L;;;;;N;;;;; +12278;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;; +12279;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI U;Lo;0;L;;;;;N;;;;; +1227A;CUNEIFORM SIGN PA;Lo;0;L;;;;;N;;;;; +1227B;CUNEIFORM SIGN PAD;Lo;0;L;;;;;N;;;;; +1227C;CUNEIFORM SIGN PAN;Lo;0;L;;;;;N;;;;; +1227D;CUNEIFORM SIGN PAP;Lo;0;L;;;;;N;;;;; +1227E;CUNEIFORM SIGN PESH2;Lo;0;L;;;;;N;;;;; +1227F;CUNEIFORM SIGN PI;Lo;0;L;;;;;N;;;;; +12280;CUNEIFORM SIGN PI TIMES A;Lo;0;L;;;;;N;;;;; +12281;CUNEIFORM SIGN PI TIMES AB;Lo;0;L;;;;;N;;;;; +12282;CUNEIFORM SIGN PI TIMES BI;Lo;0;L;;;;;N;;;;; +12283;CUNEIFORM SIGN PI TIMES BU;Lo;0;L;;;;;N;;;;; +12284;CUNEIFORM SIGN PI TIMES E;Lo;0;L;;;;;N;;;;; +12285;CUNEIFORM SIGN PI TIMES I;Lo;0;L;;;;;N;;;;; +12286;CUNEIFORM SIGN PI TIMES IB;Lo;0;L;;;;;N;;;;; +12287;CUNEIFORM SIGN PI TIMES U;Lo;0;L;;;;;N;;;;; +12288;CUNEIFORM SIGN PI TIMES U2;Lo;0;L;;;;;N;;;;; +12289;CUNEIFORM SIGN PI CROSSING PI;Lo;0;L;;;;;N;;;;; +1228A;CUNEIFORM SIGN PIRIG;Lo;0;L;;;;;N;;;;; +1228B;CUNEIFORM SIGN PIRIG TIMES KAL;Lo;0;L;;;;;N;;;;; +1228C;CUNEIFORM SIGN PIRIG TIMES UD;Lo;0;L;;;;;N;;;;; +1228D;CUNEIFORM SIGN PIRIG TIMES ZA;Lo;0;L;;;;;N;;;;; +1228E;CUNEIFORM SIGN PIRIG OPPOSING PIRIG;Lo;0;L;;;;;N;;;;; +1228F;CUNEIFORM SIGN RA;Lo;0;L;;;;;N;;;;; +12290;CUNEIFORM SIGN RAB;Lo;0;L;;;;;N;;;;; +12291;CUNEIFORM SIGN RI;Lo;0;L;;;;;N;;;;; +12292;CUNEIFORM SIGN RU;Lo;0;L;;;;;N;;;;; +12293;CUNEIFORM SIGN SA;Lo;0;L;;;;;N;;;;; +12294;CUNEIFORM SIGN SAG NUTILLU;Lo;0;L;;;;;N;;;;; +12295;CUNEIFORM SIGN SAG;Lo;0;L;;;;;N;;;;; +12296;CUNEIFORM SIGN SAG TIMES A;Lo;0;L;;;;;N;;;;; +12297;CUNEIFORM SIGN SAG TIMES DU;Lo;0;L;;;;;N;;;;; +12298;CUNEIFORM SIGN SAG TIMES DUB;Lo;0;L;;;;;N;;;;; +12299;CUNEIFORM SIGN SAG TIMES HA;Lo;0;L;;;;;N;;;;; +1229A;CUNEIFORM SIGN SAG TIMES KAK;Lo;0;L;;;;;N;;;;; +1229B;CUNEIFORM SIGN SAG TIMES KUR;Lo;0;L;;;;;N;;;;; +1229C;CUNEIFORM SIGN SAG TIMES LUM;Lo;0;L;;;;;N;;;;; +1229D;CUNEIFORM SIGN SAG TIMES MI;Lo;0;L;;;;;N;;;;; +1229E;CUNEIFORM SIGN SAG TIMES NUN;Lo;0;L;;;;;N;;;;; +1229F;CUNEIFORM SIGN SAG TIMES SAL;Lo;0;L;;;;;N;;;;; +122A0;CUNEIFORM SIGN SAG TIMES SHID;Lo;0;L;;;;;N;;;;; +122A1;CUNEIFORM SIGN SAG TIMES TAB;Lo;0;L;;;;;N;;;;; +122A2;CUNEIFORM SIGN SAG TIMES U2;Lo;0;L;;;;;N;;;;; +122A3;CUNEIFORM SIGN SAG TIMES UB;Lo;0;L;;;;;N;;;;; +122A4;CUNEIFORM SIGN SAG TIMES UM;Lo;0;L;;;;;N;;;;; +122A5;CUNEIFORM SIGN SAG TIMES UR;Lo;0;L;;;;;N;;;;; +122A6;CUNEIFORM SIGN SAG TIMES USH;Lo;0;L;;;;;N;;;;; +122A7;CUNEIFORM SIGN SAG OVER SAG;Lo;0;L;;;;;N;;;;; +122A8;CUNEIFORM SIGN SAG GUNU;Lo;0;L;;;;;N;;;;; +122A9;CUNEIFORM SIGN SAL;Lo;0;L;;;;;N;;;;; +122AA;CUNEIFORM SIGN SAL LAGAB TIMES ASH2;Lo;0;L;;;;;N;;;;; +122AB;CUNEIFORM SIGN SANGA2;Lo;0;L;;;;;N;;;;; +122AC;CUNEIFORM SIGN SAR;Lo;0;L;;;;;N;;;;; +122AD;CUNEIFORM SIGN SHA;Lo;0;L;;;;;N;;;;; +122AE;CUNEIFORM SIGN SHA3;Lo;0;L;;;;;N;;;;; +122AF;CUNEIFORM SIGN SHA3 TIMES A;Lo;0;L;;;;;N;;;;; +122B0;CUNEIFORM SIGN SHA3 TIMES BAD;Lo;0;L;;;;;N;;;;; +122B1;CUNEIFORM SIGN SHA3 TIMES GISH;Lo;0;L;;;;;N;;;;; +122B2;CUNEIFORM SIGN SHA3 TIMES NE;Lo;0;L;;;;;N;;;;; +122B3;CUNEIFORM SIGN SHA3 TIMES SHU2;Lo;0;L;;;;;N;;;;; +122B4;CUNEIFORM SIGN SHA3 TIMES TUR;Lo;0;L;;;;;N;;;;; +122B5;CUNEIFORM SIGN SHA3 TIMES U;Lo;0;L;;;;;N;;;;; +122B6;CUNEIFORM SIGN SHA3 TIMES U PLUS A;Lo;0;L;;;;;N;;;;; +122B7;CUNEIFORM SIGN SHA6;Lo;0;L;;;;;N;;;;; +122B8;CUNEIFORM SIGN SHAB6;Lo;0;L;;;;;N;;;;; +122B9;CUNEIFORM SIGN SHAR2;Lo;0;L;;;;;N;;;;; +122BA;CUNEIFORM SIGN SHE;Lo;0;L;;;;;N;;;;; +122BB;CUNEIFORM SIGN SHE HU;Lo;0;L;;;;;N;;;;; +122BC;CUNEIFORM SIGN SHE OVER SHE GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;; +122BD;CUNEIFORM SIGN SHE OVER SHE TAB OVER TAB GAR OVER GAR;Lo;0;L;;;;;N;;;;; +122BE;CUNEIFORM SIGN SHEG9;Lo;0;L;;;;;N;;;;; +122BF;CUNEIFORM SIGN SHEN;Lo;0;L;;;;;N;;;;; +122C0;CUNEIFORM SIGN SHESH;Lo;0;L;;;;;N;;;;; +122C1;CUNEIFORM SIGN SHESH2;Lo;0;L;;;;;N;;;;; +122C2;CUNEIFORM SIGN SHESHLAM;Lo;0;L;;;;;N;;;;; +122C3;CUNEIFORM SIGN SHID;Lo;0;L;;;;;N;;;;; +122C4;CUNEIFORM SIGN SHID TIMES A;Lo;0;L;;;;;N;;;;; +122C5;CUNEIFORM SIGN SHID TIMES IM;Lo;0;L;;;;;N;;;;; +122C6;CUNEIFORM SIGN SHIM;Lo;0;L;;;;;N;;;;; +122C7;CUNEIFORM SIGN SHIM TIMES A;Lo;0;L;;;;;N;;;;; +122C8;CUNEIFORM SIGN SHIM TIMES BAL;Lo;0;L;;;;;N;;;;; +122C9;CUNEIFORM SIGN SHIM TIMES BULUG;Lo;0;L;;;;;N;;;;; +122CA;CUNEIFORM SIGN SHIM TIMES DIN;Lo;0;L;;;;;N;;;;; +122CB;CUNEIFORM SIGN SHIM TIMES GAR;Lo;0;L;;;;;N;;;;; +122CC;CUNEIFORM SIGN SHIM TIMES IGI;Lo;0;L;;;;;N;;;;; +122CD;CUNEIFORM SIGN SHIM TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +122CE;CUNEIFORM SIGN SHIM TIMES KUSHU2;Lo;0;L;;;;;N;;;;; +122CF;CUNEIFORM SIGN SHIM TIMES LUL;Lo;0;L;;;;;N;;;;; +122D0;CUNEIFORM SIGN SHIM TIMES MUG;Lo;0;L;;;;;N;;;;; +122D1;CUNEIFORM SIGN SHIM TIMES SAL;Lo;0;L;;;;;N;;;;; +122D2;CUNEIFORM SIGN SHINIG;Lo;0;L;;;;;N;;;;; +122D3;CUNEIFORM SIGN SHIR;Lo;0;L;;;;;N;;;;; +122D4;CUNEIFORM SIGN SHIR TENU;Lo;0;L;;;;;N;;;;; +122D5;CUNEIFORM SIGN SHIR OVER SHIR BUR OVER BUR;Lo;0;L;;;;;N;;;;; +122D6;CUNEIFORM SIGN SHITA;Lo;0;L;;;;;N;;;;; +122D7;CUNEIFORM SIGN SHU;Lo;0;L;;;;;N;;;;; +122D8;CUNEIFORM SIGN SHU OVER INVERTED SHU;Lo;0;L;;;;;N;;;;; +122D9;CUNEIFORM SIGN SHU2;Lo;0;L;;;;;N;;;;; +122DA;CUNEIFORM SIGN SHUBUR;Lo;0;L;;;;;N;;;;; +122DB;CUNEIFORM SIGN SI;Lo;0;L;;;;;N;;;;; +122DC;CUNEIFORM SIGN SI GUNU;Lo;0;L;;;;;N;;;;; +122DD;CUNEIFORM SIGN SIG;Lo;0;L;;;;;N;;;;; +122DE;CUNEIFORM SIGN SIG4;Lo;0;L;;;;;N;;;;; +122DF;CUNEIFORM SIGN SIG4 OVER SIG4 SHU2;Lo;0;L;;;;;N;;;;; +122E0;CUNEIFORM SIGN SIK2;Lo;0;L;;;;;N;;;;; +122E1;CUNEIFORM SIGN SILA3;Lo;0;L;;;;;N;;;;; +122E2;CUNEIFORM SIGN SU;Lo;0;L;;;;;N;;;;; +122E3;CUNEIFORM SIGN SU OVER SU;Lo;0;L;;;;;N;;;;; +122E4;CUNEIFORM SIGN SUD;Lo;0;L;;;;;N;;;;; +122E5;CUNEIFORM SIGN SUD2;Lo;0;L;;;;;N;;;;; +122E6;CUNEIFORM SIGN SUHUR;Lo;0;L;;;;;N;;;;; +122E7;CUNEIFORM SIGN SUM;Lo;0;L;;;;;N;;;;; +122E8;CUNEIFORM SIGN SUMASH;Lo;0;L;;;;;N;;;;; +122E9;CUNEIFORM SIGN SUR;Lo;0;L;;;;;N;;;;; +122EA;CUNEIFORM SIGN SUR9;Lo;0;L;;;;;N;;;;; +122EB;CUNEIFORM SIGN TA;Lo;0;L;;;;;N;;;;; +122EC;CUNEIFORM SIGN TA ASTERISK;Lo;0;L;;;;;N;;;;; +122ED;CUNEIFORM SIGN TA TIMES HI;Lo;0;L;;;;;N;;;;; +122EE;CUNEIFORM SIGN TA TIMES MI;Lo;0;L;;;;;N;;;;; +122EF;CUNEIFORM SIGN TA GUNU;Lo;0;L;;;;;N;;;;; +122F0;CUNEIFORM SIGN TAB;Lo;0;L;;;;;N;;;;; +122F1;CUNEIFORM SIGN TAB OVER TAB NI OVER NI DISH OVER DISH;Lo;0;L;;;;;N;;;;; +122F2;CUNEIFORM SIGN TAB SQUARED;Lo;0;L;;;;;N;;;;; +122F3;CUNEIFORM SIGN TAG;Lo;0;L;;;;;N;;;;; +122F4;CUNEIFORM SIGN TAG TIMES BI;Lo;0;L;;;;;N;;;;; +122F5;CUNEIFORM SIGN TAG TIMES GUD;Lo;0;L;;;;;N;;;;; +122F6;CUNEIFORM SIGN TAG TIMES SHE;Lo;0;L;;;;;N;;;;; +122F7;CUNEIFORM SIGN TAG TIMES SHU;Lo;0;L;;;;;N;;;;; +122F8;CUNEIFORM SIGN TAG TIMES TUG2;Lo;0;L;;;;;N;;;;; +122F9;CUNEIFORM SIGN TAG TIMES UD;Lo;0;L;;;;;N;;;;; +122FA;CUNEIFORM SIGN TAK4;Lo;0;L;;;;;N;;;;; +122FB;CUNEIFORM SIGN TAR;Lo;0;L;;;;;N;;;;; +122FC;CUNEIFORM SIGN TE;Lo;0;L;;;;;N;;;;; +122FD;CUNEIFORM SIGN TE GUNU;Lo;0;L;;;;;N;;;;; +122FE;CUNEIFORM SIGN TI;Lo;0;L;;;;;N;;;;; +122FF;CUNEIFORM SIGN TI TENU;Lo;0;L;;;;;N;;;;; +12300;CUNEIFORM SIGN TIL;Lo;0;L;;;;;N;;;;; +12301;CUNEIFORM SIGN TIR;Lo;0;L;;;;;N;;;;; +12302;CUNEIFORM SIGN TIR TIMES TAK4;Lo;0;L;;;;;N;;;;; +12303;CUNEIFORM SIGN TIR OVER TIR;Lo;0;L;;;;;N;;;;; +12304;CUNEIFORM SIGN TIR OVER TIR GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;; +12305;CUNEIFORM SIGN TU;Lo;0;L;;;;;N;;;;; +12306;CUNEIFORM SIGN TUG2;Lo;0;L;;;;;N;;;;; +12307;CUNEIFORM SIGN TUK;Lo;0;L;;;;;N;;;;; +12308;CUNEIFORM SIGN TUM;Lo;0;L;;;;;N;;;;; +12309;CUNEIFORM SIGN TUR;Lo;0;L;;;;;N;;;;; +1230A;CUNEIFORM SIGN TUR OVER TUR ZA OVER ZA;Lo;0;L;;;;;N;;;;; +1230B;CUNEIFORM SIGN U;Lo;0;L;;;;;N;;;;; +1230C;CUNEIFORM SIGN U GUD;Lo;0;L;;;;;N;;;;; +1230D;CUNEIFORM SIGN U U U;Lo;0;L;;;;;N;;;;; +1230E;CUNEIFORM SIGN U OVER U PA OVER PA GAR OVER GAR;Lo;0;L;;;;;N;;;;; +1230F;CUNEIFORM SIGN U OVER U SUR OVER SUR;Lo;0;L;;;;;N;;;;; +12310;CUNEIFORM SIGN U OVER U U REVERSED OVER U REVERSED;Lo;0;L;;;;;N;;;;; +12311;CUNEIFORM SIGN U2;Lo;0;L;;;;;N;;;;; +12312;CUNEIFORM SIGN UB;Lo;0;L;;;;;N;;;;; +12313;CUNEIFORM SIGN UD;Lo;0;L;;;;;N;;;;; +12314;CUNEIFORM SIGN UD KUSHU2;Lo;0;L;;;;;N;;;;; +12315;CUNEIFORM SIGN UD TIMES BAD;Lo;0;L;;;;;N;;;;; +12316;CUNEIFORM SIGN UD TIMES MI;Lo;0;L;;;;;N;;;;; +12317;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;; +12318;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U GUNU;Lo;0;L;;;;;N;;;;; +12319;CUNEIFORM SIGN UD GUNU;Lo;0;L;;;;;N;;;;; +1231A;CUNEIFORM SIGN UD SHESHIG;Lo;0;L;;;;;N;;;;; +1231B;CUNEIFORM SIGN UD SHESHIG TIMES BAD;Lo;0;L;;;;;N;;;;; +1231C;CUNEIFORM SIGN UDUG;Lo;0;L;;;;;N;;;;; +1231D;CUNEIFORM SIGN UM;Lo;0;L;;;;;N;;;;; +1231E;CUNEIFORM SIGN UM TIMES LAGAB;Lo;0;L;;;;;N;;;;; +1231F;CUNEIFORM SIGN UM TIMES ME PLUS DA;Lo;0;L;;;;;N;;;;; +12320;CUNEIFORM SIGN UM TIMES SHA3;Lo;0;L;;;;;N;;;;; +12321;CUNEIFORM SIGN UM TIMES U;Lo;0;L;;;;;N;;;;; +12322;CUNEIFORM SIGN UMBIN;Lo;0;L;;;;;N;;;;; +12323;CUNEIFORM SIGN UMUM;Lo;0;L;;;;;N;;;;; +12324;CUNEIFORM SIGN UMUM TIMES KASKAL;Lo;0;L;;;;;N;;;;; +12325;CUNEIFORM SIGN UMUM TIMES PA;Lo;0;L;;;;;N;;;;; +12326;CUNEIFORM SIGN UN;Lo;0;L;;;;;N;;;;; +12327;CUNEIFORM SIGN UN GUNU;Lo;0;L;;;;;N;;;;; +12328;CUNEIFORM SIGN UR;Lo;0;L;;;;;N;;;;; +12329;CUNEIFORM SIGN UR CROSSING UR;Lo;0;L;;;;;N;;;;; +1232A;CUNEIFORM SIGN UR SHESHIG;Lo;0;L;;;;;N;;;;; +1232B;CUNEIFORM SIGN UR2;Lo;0;L;;;;;N;;;;; +1232C;CUNEIFORM SIGN UR2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;; +1232D;CUNEIFORM SIGN UR2 TIMES A PLUS NA;Lo;0;L;;;;;N;;;;; +1232E;CUNEIFORM SIGN UR2 TIMES AL;Lo;0;L;;;;;N;;;;; +1232F;CUNEIFORM SIGN UR2 TIMES HA;Lo;0;L;;;;;N;;;;; +12330;CUNEIFORM SIGN UR2 TIMES NUN;Lo;0;L;;;;;N;;;;; +12331;CUNEIFORM SIGN UR2 TIMES U2;Lo;0;L;;;;;N;;;;; +12332;CUNEIFORM SIGN UR2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;; +12333;CUNEIFORM SIGN UR2 TIMES U2 PLUS BI;Lo;0;L;;;;;N;;;;; +12334;CUNEIFORM SIGN UR4;Lo;0;L;;;;;N;;;;; +12335;CUNEIFORM SIGN URI;Lo;0;L;;;;;N;;;;; +12336;CUNEIFORM SIGN URI3;Lo;0;L;;;;;N;;;;; +12337;CUNEIFORM SIGN URU;Lo;0;L;;;;;N;;;;; +12338;CUNEIFORM SIGN URU TIMES A;Lo;0;L;;;;;N;;;;; +12339;CUNEIFORM SIGN URU TIMES ASHGAB;Lo;0;L;;;;;N;;;;; +1233A;CUNEIFORM SIGN URU TIMES BAR;Lo;0;L;;;;;N;;;;; +1233B;CUNEIFORM SIGN URU TIMES DUN;Lo;0;L;;;;;N;;;;; +1233C;CUNEIFORM SIGN URU TIMES GA;Lo;0;L;;;;;N;;;;; +1233D;CUNEIFORM SIGN URU TIMES GAL;Lo;0;L;;;;;N;;;;; +1233E;CUNEIFORM SIGN URU TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1233F;CUNEIFORM SIGN URU TIMES GAR;Lo;0;L;;;;;N;;;;; +12340;CUNEIFORM SIGN URU TIMES GU;Lo;0;L;;;;;N;;;;; +12341;CUNEIFORM SIGN URU TIMES HA;Lo;0;L;;;;;N;;;;; +12342;CUNEIFORM SIGN URU TIMES IGI;Lo;0;L;;;;;N;;;;; +12343;CUNEIFORM SIGN URU TIMES IM;Lo;0;L;;;;;N;;;;; +12344;CUNEIFORM SIGN URU TIMES ISH;Lo;0;L;;;;;N;;;;; +12345;CUNEIFORM SIGN URU TIMES KI;Lo;0;L;;;;;N;;;;; +12346;CUNEIFORM SIGN URU TIMES LUM;Lo;0;L;;;;;N;;;;; +12347;CUNEIFORM SIGN URU TIMES MIN;Lo;0;L;;;;;N;;;;; +12348;CUNEIFORM SIGN URU TIMES PA;Lo;0;L;;;;;N;;;;; +12349;CUNEIFORM SIGN URU TIMES SHE;Lo;0;L;;;;;N;;;;; +1234A;CUNEIFORM SIGN URU TIMES SIG4;Lo;0;L;;;;;N;;;;; +1234B;CUNEIFORM SIGN URU TIMES TU;Lo;0;L;;;;;N;;;;; +1234C;CUNEIFORM SIGN URU TIMES U PLUS GUD;Lo;0;L;;;;;N;;;;; +1234D;CUNEIFORM SIGN URU TIMES UD;Lo;0;L;;;;;N;;;;; +1234E;CUNEIFORM SIGN URU TIMES URUDA;Lo;0;L;;;;;N;;;;; +1234F;CUNEIFORM SIGN URUDA;Lo;0;L;;;;;N;;;;; +12350;CUNEIFORM SIGN URUDA TIMES U;Lo;0;L;;;;;N;;;;; +12351;CUNEIFORM SIGN USH;Lo;0;L;;;;;N;;;;; +12352;CUNEIFORM SIGN USH TIMES A;Lo;0;L;;;;;N;;;;; +12353;CUNEIFORM SIGN USH TIMES KU;Lo;0;L;;;;;N;;;;; +12354;CUNEIFORM SIGN USH TIMES KUR;Lo;0;L;;;;;N;;;;; +12355;CUNEIFORM SIGN USH TIMES TAK4;Lo;0;L;;;;;N;;;;; +12356;CUNEIFORM SIGN USHX;Lo;0;L;;;;;N;;;;; +12357;CUNEIFORM SIGN USH2;Lo;0;L;;;;;N;;;;; +12358;CUNEIFORM SIGN USHUMX;Lo;0;L;;;;;N;;;;; +12359;CUNEIFORM SIGN UTUKI;Lo;0;L;;;;;N;;;;; +1235A;CUNEIFORM SIGN UZ3;Lo;0;L;;;;;N;;;;; +1235B;CUNEIFORM SIGN UZ3 TIMES KASKAL;Lo;0;L;;;;;N;;;;; +1235C;CUNEIFORM SIGN UZU;Lo;0;L;;;;;N;;;;; +1235D;CUNEIFORM SIGN ZA;Lo;0;L;;;;;N;;;;; +1235E;CUNEIFORM SIGN ZA TENU;Lo;0;L;;;;;N;;;;; +1235F;CUNEIFORM SIGN ZA SQUARED TIMES KUR;Lo;0;L;;;;;N;;;;; +12360;CUNEIFORM SIGN ZAG;Lo;0;L;;;;;N;;;;; +12361;CUNEIFORM SIGN ZAMX;Lo;0;L;;;;;N;;;;; +12362;CUNEIFORM SIGN ZE2;Lo;0;L;;;;;N;;;;; +12363;CUNEIFORM SIGN ZI;Lo;0;L;;;;;N;;;;; +12364;CUNEIFORM SIGN ZI OVER ZI;Lo;0;L;;;;;N;;;;; +12365;CUNEIFORM SIGN ZI3;Lo;0;L;;;;;N;;;;; +12366;CUNEIFORM SIGN ZIB;Lo;0;L;;;;;N;;;;; +12367;CUNEIFORM SIGN ZIB KABA TENU;Lo;0;L;;;;;N;;;;; +12368;CUNEIFORM SIGN ZIG;Lo;0;L;;;;;N;;;;; +12369;CUNEIFORM SIGN ZIZ2;Lo;0;L;;;;;N;;;;; +1236A;CUNEIFORM SIGN ZU;Lo;0;L;;;;;N;;;;; +1236B;CUNEIFORM SIGN ZU5;Lo;0;L;;;;;N;;;;; +1236C;CUNEIFORM SIGN ZU5 TIMES A;Lo;0;L;;;;;N;;;;; +1236D;CUNEIFORM SIGN ZUBUR;Lo;0;L;;;;;N;;;;; +1236E;CUNEIFORM SIGN ZUM;Lo;0;L;;;;;N;;;;; +12400;CUNEIFORM NUMERIC SIGN TWO ASH;Nl;0;L;;;;2;N;;;;; +12401;CUNEIFORM NUMERIC SIGN THREE ASH;Nl;0;L;;;;3;N;;;;; +12402;CUNEIFORM NUMERIC SIGN FOUR ASH;Nl;0;L;;;;4;N;;;;; +12403;CUNEIFORM NUMERIC SIGN FIVE ASH;Nl;0;L;;;;5;N;;;;; +12404;CUNEIFORM NUMERIC SIGN SIX ASH;Nl;0;L;;;;6;N;;;;; +12405;CUNEIFORM NUMERIC SIGN SEVEN ASH;Nl;0;L;;;;7;N;;;;; +12406;CUNEIFORM NUMERIC SIGN EIGHT ASH;Nl;0;L;;;;8;N;;;;; +12407;CUNEIFORM NUMERIC SIGN NINE ASH;Nl;0;L;;;;9;N;;;;; +12408;CUNEIFORM NUMERIC SIGN THREE DISH;Nl;0;L;;;;3;N;;;;; +12409;CUNEIFORM NUMERIC SIGN FOUR DISH;Nl;0;L;;;;4;N;;;;; +1240A;CUNEIFORM NUMERIC SIGN FIVE DISH;Nl;0;L;;;;5;N;;;;; +1240B;CUNEIFORM NUMERIC SIGN SIX DISH;Nl;0;L;;;;6;N;;;;; +1240C;CUNEIFORM NUMERIC SIGN SEVEN DISH;Nl;0;L;;;;7;N;;;;; +1240D;CUNEIFORM NUMERIC SIGN EIGHT DISH;Nl;0;L;;;;8;N;;;;; +1240E;CUNEIFORM NUMERIC SIGN NINE DISH;Nl;0;L;;;;9;N;;;;; +1240F;CUNEIFORM NUMERIC SIGN FOUR U;Nl;0;L;;;;4;N;;;;; +12410;CUNEIFORM NUMERIC SIGN FIVE U;Nl;0;L;;;;5;N;;;;; +12411;CUNEIFORM NUMERIC SIGN SIX U;Nl;0;L;;;;6;N;;;;; +12412;CUNEIFORM NUMERIC SIGN SEVEN U;Nl;0;L;;;;7;N;;;;; +12413;CUNEIFORM NUMERIC SIGN EIGHT U;Nl;0;L;;;;8;N;;;;; +12414;CUNEIFORM NUMERIC SIGN NINE U;Nl;0;L;;;;9;N;;;;; +12415;CUNEIFORM NUMERIC SIGN ONE GESH2;Nl;0;L;;;;1;N;;;;; +12416;CUNEIFORM NUMERIC SIGN TWO GESH2;Nl;0;L;;;;2;N;;;;; +12417;CUNEIFORM NUMERIC SIGN THREE GESH2;Nl;0;L;;;;3;N;;;;; +12418;CUNEIFORM NUMERIC SIGN FOUR GESH2;Nl;0;L;;;;4;N;;;;; +12419;CUNEIFORM NUMERIC SIGN FIVE GESH2;Nl;0;L;;;;5;N;;;;; +1241A;CUNEIFORM NUMERIC SIGN SIX GESH2;Nl;0;L;;;;6;N;;;;; +1241B;CUNEIFORM NUMERIC SIGN SEVEN GESH2;Nl;0;L;;;;7;N;;;;; +1241C;CUNEIFORM NUMERIC SIGN EIGHT GESH2;Nl;0;L;;;;8;N;;;;; +1241D;CUNEIFORM NUMERIC SIGN NINE GESH2;Nl;0;L;;;;9;N;;;;; +1241E;CUNEIFORM NUMERIC SIGN ONE GESHU;Nl;0;L;;;;1;N;;;;; +1241F;CUNEIFORM NUMERIC SIGN TWO GESHU;Nl;0;L;;;;2;N;;;;; +12420;CUNEIFORM NUMERIC SIGN THREE GESHU;Nl;0;L;;;;3;N;;;;; +12421;CUNEIFORM NUMERIC SIGN FOUR GESHU;Nl;0;L;;;;4;N;;;;; +12422;CUNEIFORM NUMERIC SIGN FIVE GESHU;Nl;0;L;;;;5;N;;;;; +12423;CUNEIFORM NUMERIC SIGN TWO SHAR2;Nl;0;L;;;;2;N;;;;; +12424;CUNEIFORM NUMERIC SIGN THREE SHAR2;Nl;0;L;;;;3;N;;;;; +12425;CUNEIFORM NUMERIC SIGN THREE SHAR2 VARIANT FORM;Nl;0;L;;;;3;N;;;;; +12426;CUNEIFORM NUMERIC SIGN FOUR SHAR2;Nl;0;L;;;;4;N;;;;; +12427;CUNEIFORM NUMERIC SIGN FIVE SHAR2;Nl;0;L;;;;5;N;;;;; +12428;CUNEIFORM NUMERIC SIGN SIX SHAR2;Nl;0;L;;;;6;N;;;;; +12429;CUNEIFORM NUMERIC SIGN SEVEN SHAR2;Nl;0;L;;;;7;N;;;;; +1242A;CUNEIFORM NUMERIC SIGN EIGHT SHAR2;Nl;0;L;;;;8;N;;;;; +1242B;CUNEIFORM NUMERIC SIGN NINE SHAR2;Nl;0;L;;;;9;N;;;;; +1242C;CUNEIFORM NUMERIC SIGN ONE SHARU;Nl;0;L;;;;1;N;;;;; +1242D;CUNEIFORM NUMERIC SIGN TWO SHARU;Nl;0;L;;;;2;N;;;;; +1242E;CUNEIFORM NUMERIC SIGN THREE SHARU;Nl;0;L;;;;3;N;;;;; +1242F;CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM;Nl;0;L;;;;3;N;;;;; +12430;CUNEIFORM NUMERIC SIGN FOUR SHARU;Nl;0;L;;;;4;N;;;;; +12431;CUNEIFORM NUMERIC SIGN FIVE SHARU;Nl;0;L;;;;5;N;;;;; +12432;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH;Nl;0;L;;;;;N;;;;; +12433;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN;Nl;0;L;;;;;N;;;;; +12434;CUNEIFORM NUMERIC SIGN ONE BURU;Nl;0;L;;;;1;N;;;;; +12435;CUNEIFORM NUMERIC SIGN TWO BURU;Nl;0;L;;;;2;N;;;;; +12436;CUNEIFORM NUMERIC SIGN THREE BURU;Nl;0;L;;;;3;N;;;;; +12437;CUNEIFORM NUMERIC SIGN THREE BURU VARIANT FORM;Nl;0;L;;;;3;N;;;;; +12438;CUNEIFORM NUMERIC SIGN FOUR BURU;Nl;0;L;;;;4;N;;;;; +12439;CUNEIFORM NUMERIC SIGN FIVE BURU;Nl;0;L;;;;5;N;;;;; +1243A;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH16;Nl;0;L;;;;3;N;;;;; +1243B;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH21;Nl;0;L;;;;3;N;;;;; +1243C;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU;Nl;0;L;;;;4;N;;;;; +1243D;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU4;Nl;0;L;;;;4;N;;;;; +1243E;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU A;Nl;0;L;;;;4;N;;;;; +1243F;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU B;Nl;0;L;;;;4;N;;;;; +12440;CUNEIFORM NUMERIC SIGN SIX VARIANT FORM ASH9;Nl;0;L;;;;6;N;;;;; +12441;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN3;Nl;0;L;;;;7;N;;;;; +12442;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN A;Nl;0;L;;;;7;N;;;;; +12443;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN B;Nl;0;L;;;;7;N;;;;; +12444;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU;Nl;0;L;;;;8;N;;;;; +12445;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU3;Nl;0;L;;;;8;N;;;;; +12446;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU;Nl;0;L;;;;9;N;;;;; +12447;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU3;Nl;0;L;;;;9;N;;;;; +12448;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU4;Nl;0;L;;;;9;N;;;;; +12449;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU A;Nl;0;L;;;;9;N;;;;; +1244A;CUNEIFORM NUMERIC SIGN TWO ASH TENU;Nl;0;L;;;;2;N;;;;; +1244B;CUNEIFORM NUMERIC SIGN THREE ASH TENU;Nl;0;L;;;;3;N;;;;; +1244C;CUNEIFORM NUMERIC SIGN FOUR ASH TENU;Nl;0;L;;;;4;N;;;;; +1244D;CUNEIFORM NUMERIC SIGN FIVE ASH TENU;Nl;0;L;;;;5;N;;;;; +1244E;CUNEIFORM NUMERIC SIGN SIX ASH TENU;Nl;0;L;;;;6;N;;;;; +1244F;CUNEIFORM NUMERIC SIGN ONE BAN2;Nl;0;L;;;;1;N;;;;; +12450;CUNEIFORM NUMERIC SIGN TWO BAN2;Nl;0;L;;;;2;N;;;;; +12451;CUNEIFORM NUMERIC SIGN THREE BAN2;Nl;0;L;;;;3;N;;;;; +12452;CUNEIFORM NUMERIC SIGN FOUR BAN2;Nl;0;L;;;;4;N;;;;; +12453;CUNEIFORM NUMERIC SIGN FOUR BAN2 VARIANT FORM;Nl;0;L;;;;4;N;;;;; +12454;CUNEIFORM NUMERIC SIGN FIVE BAN2;Nl;0;L;;;;5;N;;;;; +12455;CUNEIFORM NUMERIC SIGN FIVE BAN2 VARIANT FORM;Nl;0;L;;;;5;N;;;;; +12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;;N;;;;; +12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;;N;;;;; +12458;CUNEIFORM NUMERIC SIGN ONE ESHE3;Nl;0;L;;;;1;N;;;;; +12459;CUNEIFORM NUMERIC SIGN TWO ESHE3;Nl;0;L;;;;2;N;;;;; +1245A;CUNEIFORM NUMERIC SIGN ONE THIRD DISH;Nl;0;L;;;;1/3;N;;;;; +1245B;CUNEIFORM NUMERIC SIGN TWO THIRDS DISH;Nl;0;L;;;;2/3;N;;;;; +1245C;CUNEIFORM NUMERIC SIGN FIVE SIXTHS DISH;Nl;0;L;;;;5/6;N;;;;; +1245D;CUNEIFORM NUMERIC SIGN ONE THIRD VARIANT FORM A;Nl;0;L;;;;1/3;N;;;;; +1245E;CUNEIFORM NUMERIC SIGN TWO THIRDS VARIANT FORM A;Nl;0;L;;;;2/3;N;;;;; +1245F;CUNEIFORM NUMERIC SIGN ONE EIGHTH ASH;Nl;0;L;;;;1/8;N;;;;; +12460;CUNEIFORM NUMERIC SIGN ONE QUARTER ASH;Nl;0;L;;;;1/4;N;;;;; +12461;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE SIXTH;Nl;0;L;;;;1/6;N;;;;; +12462;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER;Nl;0;L;;;;1/4;N;;;;; +12470;CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER;Po;0;L;;;;;N;;;;; +12471;CUNEIFORM PUNCTUATION SIGN VERTICAL COLON;Po;0;L;;;;;N;;;;; +12472;CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON;Po;0;L;;;;;N;;;;; +12473;CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON;Po;0;L;;;;;N;;;;; +13000;EGYPTIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;; +13001;EGYPTIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;; +13002;EGYPTIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;; +13003;EGYPTIAN HIEROGLYPH A004;Lo;0;L;;;;;N;;;;; +13004;EGYPTIAN HIEROGLYPH A005;Lo;0;L;;;;;N;;;;; +13005;EGYPTIAN HIEROGLYPH A005A;Lo;0;L;;;;;N;;;;; +13006;EGYPTIAN HIEROGLYPH A006;Lo;0;L;;;;;N;;;;; +13007;EGYPTIAN HIEROGLYPH A006A;Lo;0;L;;;;;N;;;;; +13008;EGYPTIAN HIEROGLYPH A006B;Lo;0;L;;;;;N;;;;; +13009;EGYPTIAN HIEROGLYPH A007;Lo;0;L;;;;;N;;;;; +1300A;EGYPTIAN HIEROGLYPH A008;Lo;0;L;;;;;N;;;;; +1300B;EGYPTIAN HIEROGLYPH A009;Lo;0;L;;;;;N;;;;; +1300C;EGYPTIAN HIEROGLYPH A010;Lo;0;L;;;;;N;;;;; +1300D;EGYPTIAN HIEROGLYPH A011;Lo;0;L;;;;;N;;;;; +1300E;EGYPTIAN HIEROGLYPH A012;Lo;0;L;;;;;N;;;;; +1300F;EGYPTIAN HIEROGLYPH A013;Lo;0;L;;;;;N;;;;; +13010;EGYPTIAN HIEROGLYPH A014;Lo;0;L;;;;;N;;;;; +13011;EGYPTIAN HIEROGLYPH A014A;Lo;0;L;;;;;N;;;;; +13012;EGYPTIAN HIEROGLYPH A015;Lo;0;L;;;;;N;;;;; +13013;EGYPTIAN HIEROGLYPH A016;Lo;0;L;;;;;N;;;;; +13014;EGYPTIAN HIEROGLYPH A017;Lo;0;L;;;;;N;;;;; +13015;EGYPTIAN HIEROGLYPH A017A;Lo;0;L;;;;;N;;;;; +13016;EGYPTIAN HIEROGLYPH A018;Lo;0;L;;;;;N;;;;; +13017;EGYPTIAN HIEROGLYPH A019;Lo;0;L;;;;;N;;;;; +13018;EGYPTIAN HIEROGLYPH A020;Lo;0;L;;;;;N;;;;; +13019;EGYPTIAN HIEROGLYPH A021;Lo;0;L;;;;;N;;;;; +1301A;EGYPTIAN HIEROGLYPH A022;Lo;0;L;;;;;N;;;;; +1301B;EGYPTIAN HIEROGLYPH A023;Lo;0;L;;;;;N;;;;; +1301C;EGYPTIAN HIEROGLYPH A024;Lo;0;L;;;;;N;;;;; +1301D;EGYPTIAN HIEROGLYPH A025;Lo;0;L;;;;;N;;;;; +1301E;EGYPTIAN HIEROGLYPH A026;Lo;0;L;;;;;N;;;;; +1301F;EGYPTIAN HIEROGLYPH A027;Lo;0;L;;;;;N;;;;; +13020;EGYPTIAN HIEROGLYPH A028;Lo;0;L;;;;;N;;;;; +13021;EGYPTIAN HIEROGLYPH A029;Lo;0;L;;;;;N;;;;; +13022;EGYPTIAN HIEROGLYPH A030;Lo;0;L;;;;;N;;;;; +13023;EGYPTIAN HIEROGLYPH A031;Lo;0;L;;;;;N;;;;; +13024;EGYPTIAN HIEROGLYPH A032;Lo;0;L;;;;;N;;;;; +13025;EGYPTIAN HIEROGLYPH A032A;Lo;0;L;;;;;N;;;;; +13026;EGYPTIAN HIEROGLYPH A033;Lo;0;L;;;;;N;;;;; +13027;EGYPTIAN HIEROGLYPH A034;Lo;0;L;;;;;N;;;;; +13028;EGYPTIAN HIEROGLYPH A035;Lo;0;L;;;;;N;;;;; +13029;EGYPTIAN HIEROGLYPH A036;Lo;0;L;;;;;N;;;;; +1302A;EGYPTIAN HIEROGLYPH A037;Lo;0;L;;;;;N;;;;; +1302B;EGYPTIAN HIEROGLYPH A038;Lo;0;L;;;;;N;;;;; +1302C;EGYPTIAN HIEROGLYPH A039;Lo;0;L;;;;;N;;;;; +1302D;EGYPTIAN HIEROGLYPH A040;Lo;0;L;;;;;N;;;;; +1302E;EGYPTIAN HIEROGLYPH A040A;Lo;0;L;;;;;N;;;;; +1302F;EGYPTIAN HIEROGLYPH A041;Lo;0;L;;;;;N;;;;; +13030;EGYPTIAN HIEROGLYPH A042;Lo;0;L;;;;;N;;;;; +13031;EGYPTIAN HIEROGLYPH A042A;Lo;0;L;;;;;N;;;;; +13032;EGYPTIAN HIEROGLYPH A043;Lo;0;L;;;;;N;;;;; +13033;EGYPTIAN HIEROGLYPH A043A;Lo;0;L;;;;;N;;;;; +13034;EGYPTIAN HIEROGLYPH A044;Lo;0;L;;;;;N;;;;; +13035;EGYPTIAN HIEROGLYPH A045;Lo;0;L;;;;;N;;;;; +13036;EGYPTIAN HIEROGLYPH A045A;Lo;0;L;;;;;N;;;;; +13037;EGYPTIAN HIEROGLYPH A046;Lo;0;L;;;;;N;;;;; +13038;EGYPTIAN HIEROGLYPH A047;Lo;0;L;;;;;N;;;;; +13039;EGYPTIAN HIEROGLYPH A048;Lo;0;L;;;;;N;;;;; +1303A;EGYPTIAN HIEROGLYPH A049;Lo;0;L;;;;;N;;;;; +1303B;EGYPTIAN HIEROGLYPH A050;Lo;0;L;;;;;N;;;;; +1303C;EGYPTIAN HIEROGLYPH A051;Lo;0;L;;;;;N;;;;; +1303D;EGYPTIAN HIEROGLYPH A052;Lo;0;L;;;;;N;;;;; +1303E;EGYPTIAN HIEROGLYPH A053;Lo;0;L;;;;;N;;;;; +1303F;EGYPTIAN HIEROGLYPH A054;Lo;0;L;;;;;N;;;;; +13040;EGYPTIAN HIEROGLYPH A055;Lo;0;L;;;;;N;;;;; +13041;EGYPTIAN HIEROGLYPH A056;Lo;0;L;;;;;N;;;;; +13042;EGYPTIAN HIEROGLYPH A057;Lo;0;L;;;;;N;;;;; +13043;EGYPTIAN HIEROGLYPH A058;Lo;0;L;;;;;N;;;;; +13044;EGYPTIAN HIEROGLYPH A059;Lo;0;L;;;;;N;;;;; +13045;EGYPTIAN HIEROGLYPH A060;Lo;0;L;;;;;N;;;;; +13046;EGYPTIAN HIEROGLYPH A061;Lo;0;L;;;;;N;;;;; +13047;EGYPTIAN HIEROGLYPH A062;Lo;0;L;;;;;N;;;;; +13048;EGYPTIAN HIEROGLYPH A063;Lo;0;L;;;;;N;;;;; +13049;EGYPTIAN HIEROGLYPH A064;Lo;0;L;;;;;N;;;;; +1304A;EGYPTIAN HIEROGLYPH A065;Lo;0;L;;;;;N;;;;; +1304B;EGYPTIAN HIEROGLYPH A066;Lo;0;L;;;;;N;;;;; +1304C;EGYPTIAN HIEROGLYPH A067;Lo;0;L;;;;;N;;;;; +1304D;EGYPTIAN HIEROGLYPH A068;Lo;0;L;;;;;N;;;;; +1304E;EGYPTIAN HIEROGLYPH A069;Lo;0;L;;;;;N;;;;; +1304F;EGYPTIAN HIEROGLYPH A070;Lo;0;L;;;;;N;;;;; +13050;EGYPTIAN HIEROGLYPH B001;Lo;0;L;;;;;N;;;;; +13051;EGYPTIAN HIEROGLYPH B002;Lo;0;L;;;;;N;;;;; +13052;EGYPTIAN HIEROGLYPH B003;Lo;0;L;;;;;N;;;;; +13053;EGYPTIAN HIEROGLYPH B004;Lo;0;L;;;;;N;;;;; +13054;EGYPTIAN HIEROGLYPH B005;Lo;0;L;;;;;N;;;;; +13055;EGYPTIAN HIEROGLYPH B005A;Lo;0;L;;;;;N;;;;; +13056;EGYPTIAN HIEROGLYPH B006;Lo;0;L;;;;;N;;;;; +13057;EGYPTIAN HIEROGLYPH B007;Lo;0;L;;;;;N;;;;; +13058;EGYPTIAN HIEROGLYPH B008;Lo;0;L;;;;;N;;;;; +13059;EGYPTIAN HIEROGLYPH B009;Lo;0;L;;;;;N;;;;; +1305A;EGYPTIAN HIEROGLYPH C001;Lo;0;L;;;;;N;;;;; +1305B;EGYPTIAN HIEROGLYPH C002;Lo;0;L;;;;;N;;;;; +1305C;EGYPTIAN HIEROGLYPH C002A;Lo;0;L;;;;;N;;;;; +1305D;EGYPTIAN HIEROGLYPH C002B;Lo;0;L;;;;;N;;;;; +1305E;EGYPTIAN HIEROGLYPH C002C;Lo;0;L;;;;;N;;;;; +1305F;EGYPTIAN HIEROGLYPH C003;Lo;0;L;;;;;N;;;;; +13060;EGYPTIAN HIEROGLYPH C004;Lo;0;L;;;;;N;;;;; +13061;EGYPTIAN HIEROGLYPH C005;Lo;0;L;;;;;N;;;;; +13062;EGYPTIAN HIEROGLYPH C006;Lo;0;L;;;;;N;;;;; +13063;EGYPTIAN HIEROGLYPH C007;Lo;0;L;;;;;N;;;;; +13064;EGYPTIAN HIEROGLYPH C008;Lo;0;L;;;;;N;;;;; +13065;EGYPTIAN HIEROGLYPH C009;Lo;0;L;;;;;N;;;;; +13066;EGYPTIAN HIEROGLYPH C010;Lo;0;L;;;;;N;;;;; +13067;EGYPTIAN HIEROGLYPH C010A;Lo;0;L;;;;;N;;;;; +13068;EGYPTIAN HIEROGLYPH C011;Lo;0;L;;;;;N;;;;; +13069;EGYPTIAN HIEROGLYPH C012;Lo;0;L;;;;;N;;;;; +1306A;EGYPTIAN HIEROGLYPH C013;Lo;0;L;;;;;N;;;;; +1306B;EGYPTIAN HIEROGLYPH C014;Lo;0;L;;;;;N;;;;; +1306C;EGYPTIAN HIEROGLYPH C015;Lo;0;L;;;;;N;;;;; +1306D;EGYPTIAN HIEROGLYPH C016;Lo;0;L;;;;;N;;;;; +1306E;EGYPTIAN HIEROGLYPH C017;Lo;0;L;;;;;N;;;;; +1306F;EGYPTIAN HIEROGLYPH C018;Lo;0;L;;;;;N;;;;; +13070;EGYPTIAN HIEROGLYPH C019;Lo;0;L;;;;;N;;;;; +13071;EGYPTIAN HIEROGLYPH C020;Lo;0;L;;;;;N;;;;; +13072;EGYPTIAN HIEROGLYPH C021;Lo;0;L;;;;;N;;;;; +13073;EGYPTIAN HIEROGLYPH C022;Lo;0;L;;;;;N;;;;; +13074;EGYPTIAN HIEROGLYPH C023;Lo;0;L;;;;;N;;;;; +13075;EGYPTIAN HIEROGLYPH C024;Lo;0;L;;;;;N;;;;; +13076;EGYPTIAN HIEROGLYPH D001;Lo;0;L;;;;;N;;;;; +13077;EGYPTIAN HIEROGLYPH D002;Lo;0;L;;;;;N;;;;; +13078;EGYPTIAN HIEROGLYPH D003;Lo;0;L;;;;;N;;;;; +13079;EGYPTIAN HIEROGLYPH D004;Lo;0;L;;;;;N;;;;; +1307A;EGYPTIAN HIEROGLYPH D005;Lo;0;L;;;;;N;;;;; +1307B;EGYPTIAN HIEROGLYPH D006;Lo;0;L;;;;;N;;;;; +1307C;EGYPTIAN HIEROGLYPH D007;Lo;0;L;;;;;N;;;;; +1307D;EGYPTIAN HIEROGLYPH D008;Lo;0;L;;;;;N;;;;; +1307E;EGYPTIAN HIEROGLYPH D008A;Lo;0;L;;;;;N;;;;; +1307F;EGYPTIAN HIEROGLYPH D009;Lo;0;L;;;;;N;;;;; +13080;EGYPTIAN HIEROGLYPH D010;Lo;0;L;;;;;N;;;;; +13081;EGYPTIAN HIEROGLYPH D011;Lo;0;L;;;;;N;;;;; +13082;EGYPTIAN HIEROGLYPH D012;Lo;0;L;;;;;N;;;;; +13083;EGYPTIAN HIEROGLYPH D013;Lo;0;L;;;;;N;;;;; +13084;EGYPTIAN HIEROGLYPH D014;Lo;0;L;;;;;N;;;;; +13085;EGYPTIAN HIEROGLYPH D015;Lo;0;L;;;;;N;;;;; +13086;EGYPTIAN HIEROGLYPH D016;Lo;0;L;;;;;N;;;;; +13087;EGYPTIAN HIEROGLYPH D017;Lo;0;L;;;;;N;;;;; +13088;EGYPTIAN HIEROGLYPH D018;Lo;0;L;;;;;N;;;;; +13089;EGYPTIAN HIEROGLYPH D019;Lo;0;L;;;;;N;;;;; +1308A;EGYPTIAN HIEROGLYPH D020;Lo;0;L;;;;;N;;;;; +1308B;EGYPTIAN HIEROGLYPH D021;Lo;0;L;;;;;N;;;;; +1308C;EGYPTIAN HIEROGLYPH D022;Lo;0;L;;;;;N;;;;; +1308D;EGYPTIAN HIEROGLYPH D023;Lo;0;L;;;;;N;;;;; +1308E;EGYPTIAN HIEROGLYPH D024;Lo;0;L;;;;;N;;;;; +1308F;EGYPTIAN HIEROGLYPH D025;Lo;0;L;;;;;N;;;;; +13090;EGYPTIAN HIEROGLYPH D026;Lo;0;L;;;;;N;;;;; +13091;EGYPTIAN HIEROGLYPH D027;Lo;0;L;;;;;N;;;;; +13092;EGYPTIAN HIEROGLYPH D027A;Lo;0;L;;;;;N;;;;; +13093;EGYPTIAN HIEROGLYPH D028;Lo;0;L;;;;;N;;;;; +13094;EGYPTIAN HIEROGLYPH D029;Lo;0;L;;;;;N;;;;; +13095;EGYPTIAN HIEROGLYPH D030;Lo;0;L;;;;;N;;;;; +13096;EGYPTIAN HIEROGLYPH D031;Lo;0;L;;;;;N;;;;; +13097;EGYPTIAN HIEROGLYPH D031A;Lo;0;L;;;;;N;;;;; +13098;EGYPTIAN HIEROGLYPH D032;Lo;0;L;;;;;N;;;;; +13099;EGYPTIAN HIEROGLYPH D033;Lo;0;L;;;;;N;;;;; +1309A;EGYPTIAN HIEROGLYPH D034;Lo;0;L;;;;;N;;;;; +1309B;EGYPTIAN HIEROGLYPH D034A;Lo;0;L;;;;;N;;;;; +1309C;EGYPTIAN HIEROGLYPH D035;Lo;0;L;;;;;N;;;;; +1309D;EGYPTIAN HIEROGLYPH D036;Lo;0;L;;;;;N;;;;; +1309E;EGYPTIAN HIEROGLYPH D037;Lo;0;L;;;;;N;;;;; +1309F;EGYPTIAN HIEROGLYPH D038;Lo;0;L;;;;;N;;;;; +130A0;EGYPTIAN HIEROGLYPH D039;Lo;0;L;;;;;N;;;;; +130A1;EGYPTIAN HIEROGLYPH D040;Lo;0;L;;;;;N;;;;; +130A2;EGYPTIAN HIEROGLYPH D041;Lo;0;L;;;;;N;;;;; +130A3;EGYPTIAN HIEROGLYPH D042;Lo;0;L;;;;;N;;;;; +130A4;EGYPTIAN HIEROGLYPH D043;Lo;0;L;;;;;N;;;;; +130A5;EGYPTIAN HIEROGLYPH D044;Lo;0;L;;;;;N;;;;; +130A6;EGYPTIAN HIEROGLYPH D045;Lo;0;L;;;;;N;;;;; +130A7;EGYPTIAN HIEROGLYPH D046;Lo;0;L;;;;;N;;;;; +130A8;EGYPTIAN HIEROGLYPH D046A;Lo;0;L;;;;;N;;;;; +130A9;EGYPTIAN HIEROGLYPH D047;Lo;0;L;;;;;N;;;;; +130AA;EGYPTIAN HIEROGLYPH D048;Lo;0;L;;;;;N;;;;; +130AB;EGYPTIAN HIEROGLYPH D048A;Lo;0;L;;;;;N;;;;; +130AC;EGYPTIAN HIEROGLYPH D049;Lo;0;L;;;;;N;;;;; +130AD;EGYPTIAN HIEROGLYPH D050;Lo;0;L;;;;;N;;;;; +130AE;EGYPTIAN HIEROGLYPH D050A;Lo;0;L;;;;;N;;;;; +130AF;EGYPTIAN HIEROGLYPH D050B;Lo;0;L;;;;;N;;;;; +130B0;EGYPTIAN HIEROGLYPH D050C;Lo;0;L;;;;;N;;;;; +130B1;EGYPTIAN HIEROGLYPH D050D;Lo;0;L;;;;;N;;;;; +130B2;EGYPTIAN HIEROGLYPH D050E;Lo;0;L;;;;;N;;;;; +130B3;EGYPTIAN HIEROGLYPH D050F;Lo;0;L;;;;;N;;;;; +130B4;EGYPTIAN HIEROGLYPH D050G;Lo;0;L;;;;;N;;;;; +130B5;EGYPTIAN HIEROGLYPH D050H;Lo;0;L;;;;;N;;;;; +130B6;EGYPTIAN HIEROGLYPH D050I;Lo;0;L;;;;;N;;;;; +130B7;EGYPTIAN HIEROGLYPH D051;Lo;0;L;;;;;N;;;;; +130B8;EGYPTIAN HIEROGLYPH D052;Lo;0;L;;;;;N;;;;; +130B9;EGYPTIAN HIEROGLYPH D052A;Lo;0;L;;;;;N;;;;; +130BA;EGYPTIAN HIEROGLYPH D053;Lo;0;L;;;;;N;;;;; +130BB;EGYPTIAN HIEROGLYPH D054;Lo;0;L;;;;;N;;;;; +130BC;EGYPTIAN HIEROGLYPH D054A;Lo;0;L;;;;;N;;;;; +130BD;EGYPTIAN HIEROGLYPH D055;Lo;0;L;;;;;N;;;;; +130BE;EGYPTIAN HIEROGLYPH D056;Lo;0;L;;;;;N;;;;; +130BF;EGYPTIAN HIEROGLYPH D057;Lo;0;L;;;;;N;;;;; +130C0;EGYPTIAN HIEROGLYPH D058;Lo;0;L;;;;;N;;;;; +130C1;EGYPTIAN HIEROGLYPH D059;Lo;0;L;;;;;N;;;;; +130C2;EGYPTIAN HIEROGLYPH D060;Lo;0;L;;;;;N;;;;; +130C3;EGYPTIAN HIEROGLYPH D061;Lo;0;L;;;;;N;;;;; +130C4;EGYPTIAN HIEROGLYPH D062;Lo;0;L;;;;;N;;;;; +130C5;EGYPTIAN HIEROGLYPH D063;Lo;0;L;;;;;N;;;;; +130C6;EGYPTIAN HIEROGLYPH D064;Lo;0;L;;;;;N;;;;; +130C7;EGYPTIAN HIEROGLYPH D065;Lo;0;L;;;;;N;;;;; +130C8;EGYPTIAN HIEROGLYPH D066;Lo;0;L;;;;;N;;;;; +130C9;EGYPTIAN HIEROGLYPH D067;Lo;0;L;;;;;N;;;;; +130CA;EGYPTIAN HIEROGLYPH D067A;Lo;0;L;;;;;N;;;;; +130CB;EGYPTIAN HIEROGLYPH D067B;Lo;0;L;;;;;N;;;;; +130CC;EGYPTIAN HIEROGLYPH D067C;Lo;0;L;;;;;N;;;;; +130CD;EGYPTIAN HIEROGLYPH D067D;Lo;0;L;;;;;N;;;;; +130CE;EGYPTIAN HIEROGLYPH D067E;Lo;0;L;;;;;N;;;;; +130CF;EGYPTIAN HIEROGLYPH D067F;Lo;0;L;;;;;N;;;;; +130D0;EGYPTIAN HIEROGLYPH D067G;Lo;0;L;;;;;N;;;;; +130D1;EGYPTIAN HIEROGLYPH D067H;Lo;0;L;;;;;N;;;;; +130D2;EGYPTIAN HIEROGLYPH E001;Lo;0;L;;;;;N;;;;; +130D3;EGYPTIAN HIEROGLYPH E002;Lo;0;L;;;;;N;;;;; +130D4;EGYPTIAN HIEROGLYPH E003;Lo;0;L;;;;;N;;;;; +130D5;EGYPTIAN HIEROGLYPH E004;Lo;0;L;;;;;N;;;;; +130D6;EGYPTIAN HIEROGLYPH E005;Lo;0;L;;;;;N;;;;; +130D7;EGYPTIAN HIEROGLYPH E006;Lo;0;L;;;;;N;;;;; +130D8;EGYPTIAN HIEROGLYPH E007;Lo;0;L;;;;;N;;;;; +130D9;EGYPTIAN HIEROGLYPH E008;Lo;0;L;;;;;N;;;;; +130DA;EGYPTIAN HIEROGLYPH E008A;Lo;0;L;;;;;N;;;;; +130DB;EGYPTIAN HIEROGLYPH E009;Lo;0;L;;;;;N;;;;; +130DC;EGYPTIAN HIEROGLYPH E009A;Lo;0;L;;;;;N;;;;; +130DD;EGYPTIAN HIEROGLYPH E010;Lo;0;L;;;;;N;;;;; +130DE;EGYPTIAN HIEROGLYPH E011;Lo;0;L;;;;;N;;;;; +130DF;EGYPTIAN HIEROGLYPH E012;Lo;0;L;;;;;N;;;;; +130E0;EGYPTIAN HIEROGLYPH E013;Lo;0;L;;;;;N;;;;; +130E1;EGYPTIAN HIEROGLYPH E014;Lo;0;L;;;;;N;;;;; +130E2;EGYPTIAN HIEROGLYPH E015;Lo;0;L;;;;;N;;;;; +130E3;EGYPTIAN HIEROGLYPH E016;Lo;0;L;;;;;N;;;;; +130E4;EGYPTIAN HIEROGLYPH E016A;Lo;0;L;;;;;N;;;;; +130E5;EGYPTIAN HIEROGLYPH E017;Lo;0;L;;;;;N;;;;; +130E6;EGYPTIAN HIEROGLYPH E017A;Lo;0;L;;;;;N;;;;; +130E7;EGYPTIAN HIEROGLYPH E018;Lo;0;L;;;;;N;;;;; +130E8;EGYPTIAN HIEROGLYPH E019;Lo;0;L;;;;;N;;;;; +130E9;EGYPTIAN HIEROGLYPH E020;Lo;0;L;;;;;N;;;;; +130EA;EGYPTIAN HIEROGLYPH E020A;Lo;0;L;;;;;N;;;;; +130EB;EGYPTIAN HIEROGLYPH E021;Lo;0;L;;;;;N;;;;; +130EC;EGYPTIAN HIEROGLYPH E022;Lo;0;L;;;;;N;;;;; +130ED;EGYPTIAN HIEROGLYPH E023;Lo;0;L;;;;;N;;;;; +130EE;EGYPTIAN HIEROGLYPH E024;Lo;0;L;;;;;N;;;;; +130EF;EGYPTIAN HIEROGLYPH E025;Lo;0;L;;;;;N;;;;; +130F0;EGYPTIAN HIEROGLYPH E026;Lo;0;L;;;;;N;;;;; +130F1;EGYPTIAN HIEROGLYPH E027;Lo;0;L;;;;;N;;;;; +130F2;EGYPTIAN HIEROGLYPH E028;Lo;0;L;;;;;N;;;;; +130F3;EGYPTIAN HIEROGLYPH E028A;Lo;0;L;;;;;N;;;;; +130F4;EGYPTIAN HIEROGLYPH E029;Lo;0;L;;;;;N;;;;; +130F5;EGYPTIAN HIEROGLYPH E030;Lo;0;L;;;;;N;;;;; +130F6;EGYPTIAN HIEROGLYPH E031;Lo;0;L;;;;;N;;;;; +130F7;EGYPTIAN HIEROGLYPH E032;Lo;0;L;;;;;N;;;;; +130F8;EGYPTIAN HIEROGLYPH E033;Lo;0;L;;;;;N;;;;; +130F9;EGYPTIAN HIEROGLYPH E034;Lo;0;L;;;;;N;;;;; +130FA;EGYPTIAN HIEROGLYPH E034A;Lo;0;L;;;;;N;;;;; +130FB;EGYPTIAN HIEROGLYPH E036;Lo;0;L;;;;;N;;;;; +130FC;EGYPTIAN HIEROGLYPH E037;Lo;0;L;;;;;N;;;;; +130FD;EGYPTIAN HIEROGLYPH E038;Lo;0;L;;;;;N;;;;; +130FE;EGYPTIAN HIEROGLYPH F001;Lo;0;L;;;;;N;;;;; +130FF;EGYPTIAN HIEROGLYPH F001A;Lo;0;L;;;;;N;;;;; +13100;EGYPTIAN HIEROGLYPH F002;Lo;0;L;;;;;N;;;;; +13101;EGYPTIAN HIEROGLYPH F003;Lo;0;L;;;;;N;;;;; +13102;EGYPTIAN HIEROGLYPH F004;Lo;0;L;;;;;N;;;;; +13103;EGYPTIAN HIEROGLYPH F005;Lo;0;L;;;;;N;;;;; +13104;EGYPTIAN HIEROGLYPH F006;Lo;0;L;;;;;N;;;;; +13105;EGYPTIAN HIEROGLYPH F007;Lo;0;L;;;;;N;;;;; +13106;EGYPTIAN HIEROGLYPH F008;Lo;0;L;;;;;N;;;;; +13107;EGYPTIAN HIEROGLYPH F009;Lo;0;L;;;;;N;;;;; +13108;EGYPTIAN HIEROGLYPH F010;Lo;0;L;;;;;N;;;;; +13109;EGYPTIAN HIEROGLYPH F011;Lo;0;L;;;;;N;;;;; +1310A;EGYPTIAN HIEROGLYPH F012;Lo;0;L;;;;;N;;;;; +1310B;EGYPTIAN HIEROGLYPH F013;Lo;0;L;;;;;N;;;;; +1310C;EGYPTIAN HIEROGLYPH F013A;Lo;0;L;;;;;N;;;;; +1310D;EGYPTIAN HIEROGLYPH F014;Lo;0;L;;;;;N;;;;; +1310E;EGYPTIAN HIEROGLYPH F015;Lo;0;L;;;;;N;;;;; +1310F;EGYPTIAN HIEROGLYPH F016;Lo;0;L;;;;;N;;;;; +13110;EGYPTIAN HIEROGLYPH F017;Lo;0;L;;;;;N;;;;; +13111;EGYPTIAN HIEROGLYPH F018;Lo;0;L;;;;;N;;;;; +13112;EGYPTIAN HIEROGLYPH F019;Lo;0;L;;;;;N;;;;; +13113;EGYPTIAN HIEROGLYPH F020;Lo;0;L;;;;;N;;;;; +13114;EGYPTIAN HIEROGLYPH F021;Lo;0;L;;;;;N;;;;; +13115;EGYPTIAN HIEROGLYPH F021A;Lo;0;L;;;;;N;;;;; +13116;EGYPTIAN HIEROGLYPH F022;Lo;0;L;;;;;N;;;;; +13117;EGYPTIAN HIEROGLYPH F023;Lo;0;L;;;;;N;;;;; +13118;EGYPTIAN HIEROGLYPH F024;Lo;0;L;;;;;N;;;;; +13119;EGYPTIAN HIEROGLYPH F025;Lo;0;L;;;;;N;;;;; +1311A;EGYPTIAN HIEROGLYPH F026;Lo;0;L;;;;;N;;;;; +1311B;EGYPTIAN HIEROGLYPH F027;Lo;0;L;;;;;N;;;;; +1311C;EGYPTIAN HIEROGLYPH F028;Lo;0;L;;;;;N;;;;; +1311D;EGYPTIAN HIEROGLYPH F029;Lo;0;L;;;;;N;;;;; +1311E;EGYPTIAN HIEROGLYPH F030;Lo;0;L;;;;;N;;;;; +1311F;EGYPTIAN HIEROGLYPH F031;Lo;0;L;;;;;N;;;;; +13120;EGYPTIAN HIEROGLYPH F031A;Lo;0;L;;;;;N;;;;; +13121;EGYPTIAN HIEROGLYPH F032;Lo;0;L;;;;;N;;;;; +13122;EGYPTIAN HIEROGLYPH F033;Lo;0;L;;;;;N;;;;; +13123;EGYPTIAN HIEROGLYPH F034;Lo;0;L;;;;;N;;;;; +13124;EGYPTIAN HIEROGLYPH F035;Lo;0;L;;;;;N;;;;; +13125;EGYPTIAN HIEROGLYPH F036;Lo;0;L;;;;;N;;;;; +13126;EGYPTIAN HIEROGLYPH F037;Lo;0;L;;;;;N;;;;; +13127;EGYPTIAN HIEROGLYPH F037A;Lo;0;L;;;;;N;;;;; +13128;EGYPTIAN HIEROGLYPH F038;Lo;0;L;;;;;N;;;;; +13129;EGYPTIAN HIEROGLYPH F038A;Lo;0;L;;;;;N;;;;; +1312A;EGYPTIAN HIEROGLYPH F039;Lo;0;L;;;;;N;;;;; +1312B;EGYPTIAN HIEROGLYPH F040;Lo;0;L;;;;;N;;;;; +1312C;EGYPTIAN HIEROGLYPH F041;Lo;0;L;;;;;N;;;;; +1312D;EGYPTIAN HIEROGLYPH F042;Lo;0;L;;;;;N;;;;; +1312E;EGYPTIAN HIEROGLYPH F043;Lo;0;L;;;;;N;;;;; +1312F;EGYPTIAN HIEROGLYPH F044;Lo;0;L;;;;;N;;;;; +13130;EGYPTIAN HIEROGLYPH F045;Lo;0;L;;;;;N;;;;; +13131;EGYPTIAN HIEROGLYPH F045A;Lo;0;L;;;;;N;;;;; +13132;EGYPTIAN HIEROGLYPH F046;Lo;0;L;;;;;N;;;;; +13133;EGYPTIAN HIEROGLYPH F046A;Lo;0;L;;;;;N;;;;; +13134;EGYPTIAN HIEROGLYPH F047;Lo;0;L;;;;;N;;;;; +13135;EGYPTIAN HIEROGLYPH F047A;Lo;0;L;;;;;N;;;;; +13136;EGYPTIAN HIEROGLYPH F048;Lo;0;L;;;;;N;;;;; +13137;EGYPTIAN HIEROGLYPH F049;Lo;0;L;;;;;N;;;;; +13138;EGYPTIAN HIEROGLYPH F050;Lo;0;L;;;;;N;;;;; +13139;EGYPTIAN HIEROGLYPH F051;Lo;0;L;;;;;N;;;;; +1313A;EGYPTIAN HIEROGLYPH F051A;Lo;0;L;;;;;N;;;;; +1313B;EGYPTIAN HIEROGLYPH F051B;Lo;0;L;;;;;N;;;;; +1313C;EGYPTIAN HIEROGLYPH F051C;Lo;0;L;;;;;N;;;;; +1313D;EGYPTIAN HIEROGLYPH F052;Lo;0;L;;;;;N;;;;; +1313E;EGYPTIAN HIEROGLYPH F053;Lo;0;L;;;;;N;;;;; +1313F;EGYPTIAN HIEROGLYPH G001;Lo;0;L;;;;;N;;;;; +13140;EGYPTIAN HIEROGLYPH G002;Lo;0;L;;;;;N;;;;; +13141;EGYPTIAN HIEROGLYPH G003;Lo;0;L;;;;;N;;;;; +13142;EGYPTIAN HIEROGLYPH G004;Lo;0;L;;;;;N;;;;; +13143;EGYPTIAN HIEROGLYPH G005;Lo;0;L;;;;;N;;;;; +13144;EGYPTIAN HIEROGLYPH G006;Lo;0;L;;;;;N;;;;; +13145;EGYPTIAN HIEROGLYPH G006A;Lo;0;L;;;;;N;;;;; +13146;EGYPTIAN HIEROGLYPH G007;Lo;0;L;;;;;N;;;;; +13147;EGYPTIAN HIEROGLYPH G007A;Lo;0;L;;;;;N;;;;; +13148;EGYPTIAN HIEROGLYPH G007B;Lo;0;L;;;;;N;;;;; +13149;EGYPTIAN HIEROGLYPH G008;Lo;0;L;;;;;N;;;;; +1314A;EGYPTIAN HIEROGLYPH G009;Lo;0;L;;;;;N;;;;; +1314B;EGYPTIAN HIEROGLYPH G010;Lo;0;L;;;;;N;;;;; +1314C;EGYPTIAN HIEROGLYPH G011;Lo;0;L;;;;;N;;;;; +1314D;EGYPTIAN HIEROGLYPH G011A;Lo;0;L;;;;;N;;;;; +1314E;EGYPTIAN HIEROGLYPH G012;Lo;0;L;;;;;N;;;;; +1314F;EGYPTIAN HIEROGLYPH G013;Lo;0;L;;;;;N;;;;; +13150;EGYPTIAN HIEROGLYPH G014;Lo;0;L;;;;;N;;;;; +13151;EGYPTIAN HIEROGLYPH G015;Lo;0;L;;;;;N;;;;; +13152;EGYPTIAN HIEROGLYPH G016;Lo;0;L;;;;;N;;;;; +13153;EGYPTIAN HIEROGLYPH G017;Lo;0;L;;;;;N;;;;; +13154;EGYPTIAN HIEROGLYPH G018;Lo;0;L;;;;;N;;;;; +13155;EGYPTIAN HIEROGLYPH G019;Lo;0;L;;;;;N;;;;; +13156;EGYPTIAN HIEROGLYPH G020;Lo;0;L;;;;;N;;;;; +13157;EGYPTIAN HIEROGLYPH G020A;Lo;0;L;;;;;N;;;;; +13158;EGYPTIAN HIEROGLYPH G021;Lo;0;L;;;;;N;;;;; +13159;EGYPTIAN HIEROGLYPH G022;Lo;0;L;;;;;N;;;;; +1315A;EGYPTIAN HIEROGLYPH G023;Lo;0;L;;;;;N;;;;; +1315B;EGYPTIAN HIEROGLYPH G024;Lo;0;L;;;;;N;;;;; +1315C;EGYPTIAN HIEROGLYPH G025;Lo;0;L;;;;;N;;;;; +1315D;EGYPTIAN HIEROGLYPH G026;Lo;0;L;;;;;N;;;;; +1315E;EGYPTIAN HIEROGLYPH G026A;Lo;0;L;;;;;N;;;;; +1315F;EGYPTIAN HIEROGLYPH G027;Lo;0;L;;;;;N;;;;; +13160;EGYPTIAN HIEROGLYPH G028;Lo;0;L;;;;;N;;;;; +13161;EGYPTIAN HIEROGLYPH G029;Lo;0;L;;;;;N;;;;; +13162;EGYPTIAN HIEROGLYPH G030;Lo;0;L;;;;;N;;;;; +13163;EGYPTIAN HIEROGLYPH G031;Lo;0;L;;;;;N;;;;; +13164;EGYPTIAN HIEROGLYPH G032;Lo;0;L;;;;;N;;;;; +13165;EGYPTIAN HIEROGLYPH G033;Lo;0;L;;;;;N;;;;; +13166;EGYPTIAN HIEROGLYPH G034;Lo;0;L;;;;;N;;;;; +13167;EGYPTIAN HIEROGLYPH G035;Lo;0;L;;;;;N;;;;; +13168;EGYPTIAN HIEROGLYPH G036;Lo;0;L;;;;;N;;;;; +13169;EGYPTIAN HIEROGLYPH G036A;Lo;0;L;;;;;N;;;;; +1316A;EGYPTIAN HIEROGLYPH G037;Lo;0;L;;;;;N;;;;; +1316B;EGYPTIAN HIEROGLYPH G037A;Lo;0;L;;;;;N;;;;; +1316C;EGYPTIAN HIEROGLYPH G038;Lo;0;L;;;;;N;;;;; +1316D;EGYPTIAN HIEROGLYPH G039;Lo;0;L;;;;;N;;;;; +1316E;EGYPTIAN HIEROGLYPH G040;Lo;0;L;;;;;N;;;;; +1316F;EGYPTIAN HIEROGLYPH G041;Lo;0;L;;;;;N;;;;; +13170;EGYPTIAN HIEROGLYPH G042;Lo;0;L;;;;;N;;;;; +13171;EGYPTIAN HIEROGLYPH G043;Lo;0;L;;;;;N;;;;; +13172;EGYPTIAN HIEROGLYPH G043A;Lo;0;L;;;;;N;;;;; +13173;EGYPTIAN HIEROGLYPH G044;Lo;0;L;;;;;N;;;;; +13174;EGYPTIAN HIEROGLYPH G045;Lo;0;L;;;;;N;;;;; +13175;EGYPTIAN HIEROGLYPH G045A;Lo;0;L;;;;;N;;;;; +13176;EGYPTIAN HIEROGLYPH G046;Lo;0;L;;;;;N;;;;; +13177;EGYPTIAN HIEROGLYPH G047;Lo;0;L;;;;;N;;;;; +13178;EGYPTIAN HIEROGLYPH G048;Lo;0;L;;;;;N;;;;; +13179;EGYPTIAN HIEROGLYPH G049;Lo;0;L;;;;;N;;;;; +1317A;EGYPTIAN HIEROGLYPH G050;Lo;0;L;;;;;N;;;;; +1317B;EGYPTIAN HIEROGLYPH G051;Lo;0;L;;;;;N;;;;; +1317C;EGYPTIAN HIEROGLYPH G052;Lo;0;L;;;;;N;;;;; +1317D;EGYPTIAN HIEROGLYPH G053;Lo;0;L;;;;;N;;;;; +1317E;EGYPTIAN HIEROGLYPH G054;Lo;0;L;;;;;N;;;;; +1317F;EGYPTIAN HIEROGLYPH H001;Lo;0;L;;;;;N;;;;; +13180;EGYPTIAN HIEROGLYPH H002;Lo;0;L;;;;;N;;;;; +13181;EGYPTIAN HIEROGLYPH H003;Lo;0;L;;;;;N;;;;; +13182;EGYPTIAN HIEROGLYPH H004;Lo;0;L;;;;;N;;;;; +13183;EGYPTIAN HIEROGLYPH H005;Lo;0;L;;;;;N;;;;; +13184;EGYPTIAN HIEROGLYPH H006;Lo;0;L;;;;;N;;;;; +13185;EGYPTIAN HIEROGLYPH H006A;Lo;0;L;;;;;N;;;;; +13186;EGYPTIAN HIEROGLYPH H007;Lo;0;L;;;;;N;;;;; +13187;EGYPTIAN HIEROGLYPH H008;Lo;0;L;;;;;N;;;;; +13188;EGYPTIAN HIEROGLYPH I001;Lo;0;L;;;;;N;;;;; +13189;EGYPTIAN HIEROGLYPH I002;Lo;0;L;;;;;N;;;;; +1318A;EGYPTIAN HIEROGLYPH I003;Lo;0;L;;;;;N;;;;; +1318B;EGYPTIAN HIEROGLYPH I004;Lo;0;L;;;;;N;;;;; +1318C;EGYPTIAN HIEROGLYPH I005;Lo;0;L;;;;;N;;;;; +1318D;EGYPTIAN HIEROGLYPH I005A;Lo;0;L;;;;;N;;;;; +1318E;EGYPTIAN HIEROGLYPH I006;Lo;0;L;;;;;N;;;;; +1318F;EGYPTIAN HIEROGLYPH I007;Lo;0;L;;;;;N;;;;; +13190;EGYPTIAN HIEROGLYPH I008;Lo;0;L;;;;;N;;;;; +13191;EGYPTIAN HIEROGLYPH I009;Lo;0;L;;;;;N;;;;; +13192;EGYPTIAN HIEROGLYPH I009A;Lo;0;L;;;;;N;;;;; +13193;EGYPTIAN HIEROGLYPH I010;Lo;0;L;;;;;N;;;;; +13194;EGYPTIAN HIEROGLYPH I010A;Lo;0;L;;;;;N;;;;; +13195;EGYPTIAN HIEROGLYPH I011;Lo;0;L;;;;;N;;;;; +13196;EGYPTIAN HIEROGLYPH I011A;Lo;0;L;;;;;N;;;;; +13197;EGYPTIAN HIEROGLYPH I012;Lo;0;L;;;;;N;;;;; +13198;EGYPTIAN HIEROGLYPH I013;Lo;0;L;;;;;N;;;;; +13199;EGYPTIAN HIEROGLYPH I014;Lo;0;L;;;;;N;;;;; +1319A;EGYPTIAN HIEROGLYPH I015;Lo;0;L;;;;;N;;;;; +1319B;EGYPTIAN HIEROGLYPH K001;Lo;0;L;;;;;N;;;;; +1319C;EGYPTIAN HIEROGLYPH K002;Lo;0;L;;;;;N;;;;; +1319D;EGYPTIAN HIEROGLYPH K003;Lo;0;L;;;;;N;;;;; +1319E;EGYPTIAN HIEROGLYPH K004;Lo;0;L;;;;;N;;;;; +1319F;EGYPTIAN HIEROGLYPH K005;Lo;0;L;;;;;N;;;;; +131A0;EGYPTIAN HIEROGLYPH K006;Lo;0;L;;;;;N;;;;; +131A1;EGYPTIAN HIEROGLYPH K007;Lo;0;L;;;;;N;;;;; +131A2;EGYPTIAN HIEROGLYPH K008;Lo;0;L;;;;;N;;;;; +131A3;EGYPTIAN HIEROGLYPH L001;Lo;0;L;;;;;N;;;;; +131A4;EGYPTIAN HIEROGLYPH L002;Lo;0;L;;;;;N;;;;; +131A5;EGYPTIAN HIEROGLYPH L002A;Lo;0;L;;;;;N;;;;; +131A6;EGYPTIAN HIEROGLYPH L003;Lo;0;L;;;;;N;;;;; +131A7;EGYPTIAN HIEROGLYPH L004;Lo;0;L;;;;;N;;;;; +131A8;EGYPTIAN HIEROGLYPH L005;Lo;0;L;;;;;N;;;;; +131A9;EGYPTIAN HIEROGLYPH L006;Lo;0;L;;;;;N;;;;; +131AA;EGYPTIAN HIEROGLYPH L006A;Lo;0;L;;;;;N;;;;; +131AB;EGYPTIAN HIEROGLYPH L007;Lo;0;L;;;;;N;;;;; +131AC;EGYPTIAN HIEROGLYPH L008;Lo;0;L;;;;;N;;;;; +131AD;EGYPTIAN HIEROGLYPH M001;Lo;0;L;;;;;N;;;;; +131AE;EGYPTIAN HIEROGLYPH M001A;Lo;0;L;;;;;N;;;;; +131AF;EGYPTIAN HIEROGLYPH M001B;Lo;0;L;;;;;N;;;;; +131B0;EGYPTIAN HIEROGLYPH M002;Lo;0;L;;;;;N;;;;; +131B1;EGYPTIAN HIEROGLYPH M003;Lo;0;L;;;;;N;;;;; +131B2;EGYPTIAN HIEROGLYPH M003A;Lo;0;L;;;;;N;;;;; +131B3;EGYPTIAN HIEROGLYPH M004;Lo;0;L;;;;;N;;;;; +131B4;EGYPTIAN HIEROGLYPH M005;Lo;0;L;;;;;N;;;;; +131B5;EGYPTIAN HIEROGLYPH M006;Lo;0;L;;;;;N;;;;; +131B6;EGYPTIAN HIEROGLYPH M007;Lo;0;L;;;;;N;;;;; +131B7;EGYPTIAN HIEROGLYPH M008;Lo;0;L;;;;;N;;;;; +131B8;EGYPTIAN HIEROGLYPH M009;Lo;0;L;;;;;N;;;;; +131B9;EGYPTIAN HIEROGLYPH M010;Lo;0;L;;;;;N;;;;; +131BA;EGYPTIAN HIEROGLYPH M010A;Lo;0;L;;;;;N;;;;; +131BB;EGYPTIAN HIEROGLYPH M011;Lo;0;L;;;;;N;;;;; +131BC;EGYPTIAN HIEROGLYPH M012;Lo;0;L;;;;;N;;;;; +131BD;EGYPTIAN HIEROGLYPH M012A;Lo;0;L;;;;;N;;;;; +131BE;EGYPTIAN HIEROGLYPH M012B;Lo;0;L;;;;;N;;;;; +131BF;EGYPTIAN HIEROGLYPH M012C;Lo;0;L;;;;;N;;;;; +131C0;EGYPTIAN HIEROGLYPH M012D;Lo;0;L;;;;;N;;;;; +131C1;EGYPTIAN HIEROGLYPH M012E;Lo;0;L;;;;;N;;;;; +131C2;EGYPTIAN HIEROGLYPH M012F;Lo;0;L;;;;;N;;;;; +131C3;EGYPTIAN HIEROGLYPH M012G;Lo;0;L;;;;;N;;;;; +131C4;EGYPTIAN HIEROGLYPH M012H;Lo;0;L;;;;;N;;;;; +131C5;EGYPTIAN HIEROGLYPH M013;Lo;0;L;;;;;N;;;;; +131C6;EGYPTIAN HIEROGLYPH M014;Lo;0;L;;;;;N;;;;; +131C7;EGYPTIAN HIEROGLYPH M015;Lo;0;L;;;;;N;;;;; +131C8;EGYPTIAN HIEROGLYPH M015A;Lo;0;L;;;;;N;;;;; +131C9;EGYPTIAN HIEROGLYPH M016;Lo;0;L;;;;;N;;;;; +131CA;EGYPTIAN HIEROGLYPH M016A;Lo;0;L;;;;;N;;;;; +131CB;EGYPTIAN HIEROGLYPH M017;Lo;0;L;;;;;N;;;;; +131CC;EGYPTIAN HIEROGLYPH M017A;Lo;0;L;;;;;N;;;;; +131CD;EGYPTIAN HIEROGLYPH M018;Lo;0;L;;;;;N;;;;; +131CE;EGYPTIAN HIEROGLYPH M019;Lo;0;L;;;;;N;;;;; +131CF;EGYPTIAN HIEROGLYPH M020;Lo;0;L;;;;;N;;;;; +131D0;EGYPTIAN HIEROGLYPH M021;Lo;0;L;;;;;N;;;;; +131D1;EGYPTIAN HIEROGLYPH M022;Lo;0;L;;;;;N;;;;; +131D2;EGYPTIAN HIEROGLYPH M022A;Lo;0;L;;;;;N;;;;; +131D3;EGYPTIAN HIEROGLYPH M023;Lo;0;L;;;;;N;;;;; +131D4;EGYPTIAN HIEROGLYPH M024;Lo;0;L;;;;;N;;;;; +131D5;EGYPTIAN HIEROGLYPH M024A;Lo;0;L;;;;;N;;;;; +131D6;EGYPTIAN HIEROGLYPH M025;Lo;0;L;;;;;N;;;;; +131D7;EGYPTIAN HIEROGLYPH M026;Lo;0;L;;;;;N;;;;; +131D8;EGYPTIAN HIEROGLYPH M027;Lo;0;L;;;;;N;;;;; +131D9;EGYPTIAN HIEROGLYPH M028;Lo;0;L;;;;;N;;;;; +131DA;EGYPTIAN HIEROGLYPH M028A;Lo;0;L;;;;;N;;;;; +131DB;EGYPTIAN HIEROGLYPH M029;Lo;0;L;;;;;N;;;;; +131DC;EGYPTIAN HIEROGLYPH M030;Lo;0;L;;;;;N;;;;; +131DD;EGYPTIAN HIEROGLYPH M031;Lo;0;L;;;;;N;;;;; +131DE;EGYPTIAN HIEROGLYPH M031A;Lo;0;L;;;;;N;;;;; +131DF;EGYPTIAN HIEROGLYPH M032;Lo;0;L;;;;;N;;;;; +131E0;EGYPTIAN HIEROGLYPH M033;Lo;0;L;;;;;N;;;;; +131E1;EGYPTIAN HIEROGLYPH M033A;Lo;0;L;;;;;N;;;;; +131E2;EGYPTIAN HIEROGLYPH M033B;Lo;0;L;;;;;N;;;;; +131E3;EGYPTIAN HIEROGLYPH M034;Lo;0;L;;;;;N;;;;; +131E4;EGYPTIAN HIEROGLYPH M035;Lo;0;L;;;;;N;;;;; +131E5;EGYPTIAN HIEROGLYPH M036;Lo;0;L;;;;;N;;;;; +131E6;EGYPTIAN HIEROGLYPH M037;Lo;0;L;;;;;N;;;;; +131E7;EGYPTIAN HIEROGLYPH M038;Lo;0;L;;;;;N;;;;; +131E8;EGYPTIAN HIEROGLYPH M039;Lo;0;L;;;;;N;;;;; +131E9;EGYPTIAN HIEROGLYPH M040;Lo;0;L;;;;;N;;;;; +131EA;EGYPTIAN HIEROGLYPH M040A;Lo;0;L;;;;;N;;;;; +131EB;EGYPTIAN HIEROGLYPH M041;Lo;0;L;;;;;N;;;;; +131EC;EGYPTIAN HIEROGLYPH M042;Lo;0;L;;;;;N;;;;; +131ED;EGYPTIAN HIEROGLYPH M043;Lo;0;L;;;;;N;;;;; +131EE;EGYPTIAN HIEROGLYPH M044;Lo;0;L;;;;;N;;;;; +131EF;EGYPTIAN HIEROGLYPH N001;Lo;0;L;;;;;N;;;;; +131F0;EGYPTIAN HIEROGLYPH N002;Lo;0;L;;;;;N;;;;; +131F1;EGYPTIAN HIEROGLYPH N003;Lo;0;L;;;;;N;;;;; +131F2;EGYPTIAN HIEROGLYPH N004;Lo;0;L;;;;;N;;;;; +131F3;EGYPTIAN HIEROGLYPH N005;Lo;0;L;;;;;N;;;;; +131F4;EGYPTIAN HIEROGLYPH N006;Lo;0;L;;;;;N;;;;; +131F5;EGYPTIAN HIEROGLYPH N007;Lo;0;L;;;;;N;;;;; +131F6;EGYPTIAN HIEROGLYPH N008;Lo;0;L;;;;;N;;;;; +131F7;EGYPTIAN HIEROGLYPH N009;Lo;0;L;;;;;N;;;;; +131F8;EGYPTIAN HIEROGLYPH N010;Lo;0;L;;;;;N;;;;; +131F9;EGYPTIAN HIEROGLYPH N011;Lo;0;L;;;;;N;;;;; +131FA;EGYPTIAN HIEROGLYPH N012;Lo;0;L;;;;;N;;;;; +131FB;EGYPTIAN HIEROGLYPH N013;Lo;0;L;;;;;N;;;;; +131FC;EGYPTIAN HIEROGLYPH N014;Lo;0;L;;;;;N;;;;; +131FD;EGYPTIAN HIEROGLYPH N015;Lo;0;L;;;;;N;;;;; +131FE;EGYPTIAN HIEROGLYPH N016;Lo;0;L;;;;;N;;;;; +131FF;EGYPTIAN HIEROGLYPH N017;Lo;0;L;;;;;N;;;;; +13200;EGYPTIAN HIEROGLYPH N018;Lo;0;L;;;;;N;;;;; +13201;EGYPTIAN HIEROGLYPH N018A;Lo;0;L;;;;;N;;;;; +13202;EGYPTIAN HIEROGLYPH N018B;Lo;0;L;;;;;N;;;;; +13203;EGYPTIAN HIEROGLYPH N019;Lo;0;L;;;;;N;;;;; +13204;EGYPTIAN HIEROGLYPH N020;Lo;0;L;;;;;N;;;;; +13205;EGYPTIAN HIEROGLYPH N021;Lo;0;L;;;;;N;;;;; +13206;EGYPTIAN HIEROGLYPH N022;Lo;0;L;;;;;N;;;;; +13207;EGYPTIAN HIEROGLYPH N023;Lo;0;L;;;;;N;;;;; +13208;EGYPTIAN HIEROGLYPH N024;Lo;0;L;;;;;N;;;;; +13209;EGYPTIAN HIEROGLYPH N025;Lo;0;L;;;;;N;;;;; +1320A;EGYPTIAN HIEROGLYPH N025A;Lo;0;L;;;;;N;;;;; +1320B;EGYPTIAN HIEROGLYPH N026;Lo;0;L;;;;;N;;;;; +1320C;EGYPTIAN HIEROGLYPH N027;Lo;0;L;;;;;N;;;;; +1320D;EGYPTIAN HIEROGLYPH N028;Lo;0;L;;;;;N;;;;; +1320E;EGYPTIAN HIEROGLYPH N029;Lo;0;L;;;;;N;;;;; +1320F;EGYPTIAN HIEROGLYPH N030;Lo;0;L;;;;;N;;;;; +13210;EGYPTIAN HIEROGLYPH N031;Lo;0;L;;;;;N;;;;; +13211;EGYPTIAN HIEROGLYPH N032;Lo;0;L;;;;;N;;;;; +13212;EGYPTIAN HIEROGLYPH N033;Lo;0;L;;;;;N;;;;; +13213;EGYPTIAN HIEROGLYPH N033A;Lo;0;L;;;;;N;;;;; +13214;EGYPTIAN HIEROGLYPH N034;Lo;0;L;;;;;N;;;;; +13215;EGYPTIAN HIEROGLYPH N034A;Lo;0;L;;;;;N;;;;; +13216;EGYPTIAN HIEROGLYPH N035;Lo;0;L;;;;;N;;;;; +13217;EGYPTIAN HIEROGLYPH N035A;Lo;0;L;;;;;N;;;;; +13218;EGYPTIAN HIEROGLYPH N036;Lo;0;L;;;;;N;;;;; +13219;EGYPTIAN HIEROGLYPH N037;Lo;0;L;;;;;N;;;;; +1321A;EGYPTIAN HIEROGLYPH N037A;Lo;0;L;;;;;N;;;;; +1321B;EGYPTIAN HIEROGLYPH N038;Lo;0;L;;;;;N;;;;; +1321C;EGYPTIAN HIEROGLYPH N039;Lo;0;L;;;;;N;;;;; +1321D;EGYPTIAN HIEROGLYPH N040;Lo;0;L;;;;;N;;;;; +1321E;EGYPTIAN HIEROGLYPH N041;Lo;0;L;;;;;N;;;;; +1321F;EGYPTIAN HIEROGLYPH N042;Lo;0;L;;;;;N;;;;; +13220;EGYPTIAN HIEROGLYPH NL001;Lo;0;L;;;;;N;;;;; +13221;EGYPTIAN HIEROGLYPH NL002;Lo;0;L;;;;;N;;;;; +13222;EGYPTIAN HIEROGLYPH NL003;Lo;0;L;;;;;N;;;;; +13223;EGYPTIAN HIEROGLYPH NL004;Lo;0;L;;;;;N;;;;; +13224;EGYPTIAN HIEROGLYPH NL005;Lo;0;L;;;;;N;;;;; +13225;EGYPTIAN HIEROGLYPH NL005A;Lo;0;L;;;;;N;;;;; +13226;EGYPTIAN HIEROGLYPH NL006;Lo;0;L;;;;;N;;;;; +13227;EGYPTIAN HIEROGLYPH NL007;Lo;0;L;;;;;N;;;;; +13228;EGYPTIAN HIEROGLYPH NL008;Lo;0;L;;;;;N;;;;; +13229;EGYPTIAN HIEROGLYPH NL009;Lo;0;L;;;;;N;;;;; +1322A;EGYPTIAN HIEROGLYPH NL010;Lo;0;L;;;;;N;;;;; +1322B;EGYPTIAN HIEROGLYPH NL011;Lo;0;L;;;;;N;;;;; +1322C;EGYPTIAN HIEROGLYPH NL012;Lo;0;L;;;;;N;;;;; +1322D;EGYPTIAN HIEROGLYPH NL013;Lo;0;L;;;;;N;;;;; +1322E;EGYPTIAN HIEROGLYPH NL014;Lo;0;L;;;;;N;;;;; +1322F;EGYPTIAN HIEROGLYPH NL015;Lo;0;L;;;;;N;;;;; +13230;EGYPTIAN HIEROGLYPH NL016;Lo;0;L;;;;;N;;;;; +13231;EGYPTIAN HIEROGLYPH NL017;Lo;0;L;;;;;N;;;;; +13232;EGYPTIAN HIEROGLYPH NL017A;Lo;0;L;;;;;N;;;;; +13233;EGYPTIAN HIEROGLYPH NL018;Lo;0;L;;;;;N;;;;; +13234;EGYPTIAN HIEROGLYPH NL019;Lo;0;L;;;;;N;;;;; +13235;EGYPTIAN HIEROGLYPH NL020;Lo;0;L;;;;;N;;;;; +13236;EGYPTIAN HIEROGLYPH NU001;Lo;0;L;;;;;N;;;;; +13237;EGYPTIAN HIEROGLYPH NU002;Lo;0;L;;;;;N;;;;; +13238;EGYPTIAN HIEROGLYPH NU003;Lo;0;L;;;;;N;;;;; +13239;EGYPTIAN HIEROGLYPH NU004;Lo;0;L;;;;;N;;;;; +1323A;EGYPTIAN HIEROGLYPH NU005;Lo;0;L;;;;;N;;;;; +1323B;EGYPTIAN HIEROGLYPH NU006;Lo;0;L;;;;;N;;;;; +1323C;EGYPTIAN HIEROGLYPH NU007;Lo;0;L;;;;;N;;;;; +1323D;EGYPTIAN HIEROGLYPH NU008;Lo;0;L;;;;;N;;;;; +1323E;EGYPTIAN HIEROGLYPH NU009;Lo;0;L;;;;;N;;;;; +1323F;EGYPTIAN HIEROGLYPH NU010;Lo;0;L;;;;;N;;;;; +13240;EGYPTIAN HIEROGLYPH NU010A;Lo;0;L;;;;;N;;;;; +13241;EGYPTIAN HIEROGLYPH NU011;Lo;0;L;;;;;N;;;;; +13242;EGYPTIAN HIEROGLYPH NU011A;Lo;0;L;;;;;N;;;;; +13243;EGYPTIAN HIEROGLYPH NU012;Lo;0;L;;;;;N;;;;; +13244;EGYPTIAN HIEROGLYPH NU013;Lo;0;L;;;;;N;;;;; +13245;EGYPTIAN HIEROGLYPH NU014;Lo;0;L;;;;;N;;;;; +13246;EGYPTIAN HIEROGLYPH NU015;Lo;0;L;;;;;N;;;;; +13247;EGYPTIAN HIEROGLYPH NU016;Lo;0;L;;;;;N;;;;; +13248;EGYPTIAN HIEROGLYPH NU017;Lo;0;L;;;;;N;;;;; +13249;EGYPTIAN HIEROGLYPH NU018;Lo;0;L;;;;;N;;;;; +1324A;EGYPTIAN HIEROGLYPH NU018A;Lo;0;L;;;;;N;;;;; +1324B;EGYPTIAN HIEROGLYPH NU019;Lo;0;L;;;;;N;;;;; +1324C;EGYPTIAN HIEROGLYPH NU020;Lo;0;L;;;;;N;;;;; +1324D;EGYPTIAN HIEROGLYPH NU021;Lo;0;L;;;;;N;;;;; +1324E;EGYPTIAN HIEROGLYPH NU022;Lo;0;L;;;;;N;;;;; +1324F;EGYPTIAN HIEROGLYPH NU022A;Lo;0;L;;;;;N;;;;; +13250;EGYPTIAN HIEROGLYPH O001;Lo;0;L;;;;;N;;;;; +13251;EGYPTIAN HIEROGLYPH O001A;Lo;0;L;;;;;N;;;;; +13252;EGYPTIAN HIEROGLYPH O002;Lo;0;L;;;;;N;;;;; +13253;EGYPTIAN HIEROGLYPH O003;Lo;0;L;;;;;N;;;;; +13254;EGYPTIAN HIEROGLYPH O004;Lo;0;L;;;;;N;;;;; +13255;EGYPTIAN HIEROGLYPH O005;Lo;0;L;;;;;N;;;;; +13256;EGYPTIAN HIEROGLYPH O005A;Lo;0;L;;;;;N;;;;; +13257;EGYPTIAN HIEROGLYPH O006;Lo;0;L;;;;;N;;;;; +13258;EGYPTIAN HIEROGLYPH O006A;Lo;0;L;;;;;N;;;;; +13259;EGYPTIAN HIEROGLYPH O006B;Lo;0;L;;;;;N;;;;; +1325A;EGYPTIAN HIEROGLYPH O006C;Lo;0;L;;;;;N;;;;; +1325B;EGYPTIAN HIEROGLYPH O006D;Lo;0;L;;;;;N;;;;; +1325C;EGYPTIAN HIEROGLYPH O006E;Lo;0;L;;;;;N;;;;; +1325D;EGYPTIAN HIEROGLYPH O006F;Lo;0;L;;;;;N;;;;; +1325E;EGYPTIAN HIEROGLYPH O007;Lo;0;L;;;;;N;;;;; +1325F;EGYPTIAN HIEROGLYPH O008;Lo;0;L;;;;;N;;;;; +13260;EGYPTIAN HIEROGLYPH O009;Lo;0;L;;;;;N;;;;; +13261;EGYPTIAN HIEROGLYPH O010;Lo;0;L;;;;;N;;;;; +13262;EGYPTIAN HIEROGLYPH O010A;Lo;0;L;;;;;N;;;;; +13263;EGYPTIAN HIEROGLYPH O010B;Lo;0;L;;;;;N;;;;; +13264;EGYPTIAN HIEROGLYPH O010C;Lo;0;L;;;;;N;;;;; +13265;EGYPTIAN HIEROGLYPH O011;Lo;0;L;;;;;N;;;;; +13266;EGYPTIAN HIEROGLYPH O012;Lo;0;L;;;;;N;;;;; +13267;EGYPTIAN HIEROGLYPH O013;Lo;0;L;;;;;N;;;;; +13268;EGYPTIAN HIEROGLYPH O014;Lo;0;L;;;;;N;;;;; +13269;EGYPTIAN HIEROGLYPH O015;Lo;0;L;;;;;N;;;;; +1326A;EGYPTIAN HIEROGLYPH O016;Lo;0;L;;;;;N;;;;; +1326B;EGYPTIAN HIEROGLYPH O017;Lo;0;L;;;;;N;;;;; +1326C;EGYPTIAN HIEROGLYPH O018;Lo;0;L;;;;;N;;;;; +1326D;EGYPTIAN HIEROGLYPH O019;Lo;0;L;;;;;N;;;;; +1326E;EGYPTIAN HIEROGLYPH O019A;Lo;0;L;;;;;N;;;;; +1326F;EGYPTIAN HIEROGLYPH O020;Lo;0;L;;;;;N;;;;; +13270;EGYPTIAN HIEROGLYPH O020A;Lo;0;L;;;;;N;;;;; +13271;EGYPTIAN HIEROGLYPH O021;Lo;0;L;;;;;N;;;;; +13272;EGYPTIAN HIEROGLYPH O022;Lo;0;L;;;;;N;;;;; +13273;EGYPTIAN HIEROGLYPH O023;Lo;0;L;;;;;N;;;;; +13274;EGYPTIAN HIEROGLYPH O024;Lo;0;L;;;;;N;;;;; +13275;EGYPTIAN HIEROGLYPH O024A;Lo;0;L;;;;;N;;;;; +13276;EGYPTIAN HIEROGLYPH O025;Lo;0;L;;;;;N;;;;; +13277;EGYPTIAN HIEROGLYPH O025A;Lo;0;L;;;;;N;;;;; +13278;EGYPTIAN HIEROGLYPH O026;Lo;0;L;;;;;N;;;;; +13279;EGYPTIAN HIEROGLYPH O027;Lo;0;L;;;;;N;;;;; +1327A;EGYPTIAN HIEROGLYPH O028;Lo;0;L;;;;;N;;;;; +1327B;EGYPTIAN HIEROGLYPH O029;Lo;0;L;;;;;N;;;;; +1327C;EGYPTIAN HIEROGLYPH O029A;Lo;0;L;;;;;N;;;;; +1327D;EGYPTIAN HIEROGLYPH O030;Lo;0;L;;;;;N;;;;; +1327E;EGYPTIAN HIEROGLYPH O030A;Lo;0;L;;;;;N;;;;; +1327F;EGYPTIAN HIEROGLYPH O031;Lo;0;L;;;;;N;;;;; +13280;EGYPTIAN HIEROGLYPH O032;Lo;0;L;;;;;N;;;;; +13281;EGYPTIAN HIEROGLYPH O033;Lo;0;L;;;;;N;;;;; +13282;EGYPTIAN HIEROGLYPH O033A;Lo;0;L;;;;;N;;;;; +13283;EGYPTIAN HIEROGLYPH O034;Lo;0;L;;;;;N;;;;; +13284;EGYPTIAN HIEROGLYPH O035;Lo;0;L;;;;;N;;;;; +13285;EGYPTIAN HIEROGLYPH O036;Lo;0;L;;;;;N;;;;; +13286;EGYPTIAN HIEROGLYPH O036A;Lo;0;L;;;;;N;;;;; +13287;EGYPTIAN HIEROGLYPH O036B;Lo;0;L;;;;;N;;;;; +13288;EGYPTIAN HIEROGLYPH O036C;Lo;0;L;;;;;N;;;;; +13289;EGYPTIAN HIEROGLYPH O036D;Lo;0;L;;;;;N;;;;; +1328A;EGYPTIAN HIEROGLYPH O037;Lo;0;L;;;;;N;;;;; +1328B;EGYPTIAN HIEROGLYPH O038;Lo;0;L;;;;;N;;;;; +1328C;EGYPTIAN HIEROGLYPH O039;Lo;0;L;;;;;N;;;;; +1328D;EGYPTIAN HIEROGLYPH O040;Lo;0;L;;;;;N;;;;; +1328E;EGYPTIAN HIEROGLYPH O041;Lo;0;L;;;;;N;;;;; +1328F;EGYPTIAN HIEROGLYPH O042;Lo;0;L;;;;;N;;;;; +13290;EGYPTIAN HIEROGLYPH O043;Lo;0;L;;;;;N;;;;; +13291;EGYPTIAN HIEROGLYPH O044;Lo;0;L;;;;;N;;;;; +13292;EGYPTIAN HIEROGLYPH O045;Lo;0;L;;;;;N;;;;; +13293;EGYPTIAN HIEROGLYPH O046;Lo;0;L;;;;;N;;;;; +13294;EGYPTIAN HIEROGLYPH O047;Lo;0;L;;;;;N;;;;; +13295;EGYPTIAN HIEROGLYPH O048;Lo;0;L;;;;;N;;;;; +13296;EGYPTIAN HIEROGLYPH O049;Lo;0;L;;;;;N;;;;; +13297;EGYPTIAN HIEROGLYPH O050;Lo;0;L;;;;;N;;;;; +13298;EGYPTIAN HIEROGLYPH O050A;Lo;0;L;;;;;N;;;;; +13299;EGYPTIAN HIEROGLYPH O050B;Lo;0;L;;;;;N;;;;; +1329A;EGYPTIAN HIEROGLYPH O051;Lo;0;L;;;;;N;;;;; +1329B;EGYPTIAN HIEROGLYPH P001;Lo;0;L;;;;;N;;;;; +1329C;EGYPTIAN HIEROGLYPH P001A;Lo;0;L;;;;;N;;;;; +1329D;EGYPTIAN HIEROGLYPH P002;Lo;0;L;;;;;N;;;;; +1329E;EGYPTIAN HIEROGLYPH P003;Lo;0;L;;;;;N;;;;; +1329F;EGYPTIAN HIEROGLYPH P003A;Lo;0;L;;;;;N;;;;; +132A0;EGYPTIAN HIEROGLYPH P004;Lo;0;L;;;;;N;;;;; +132A1;EGYPTIAN HIEROGLYPH P005;Lo;0;L;;;;;N;;;;; +132A2;EGYPTIAN HIEROGLYPH P006;Lo;0;L;;;;;N;;;;; +132A3;EGYPTIAN HIEROGLYPH P007;Lo;0;L;;;;;N;;;;; +132A4;EGYPTIAN HIEROGLYPH P008;Lo;0;L;;;;;N;;;;; +132A5;EGYPTIAN HIEROGLYPH P009;Lo;0;L;;;;;N;;;;; +132A6;EGYPTIAN HIEROGLYPH P010;Lo;0;L;;;;;N;;;;; +132A7;EGYPTIAN HIEROGLYPH P011;Lo;0;L;;;;;N;;;;; +132A8;EGYPTIAN HIEROGLYPH Q001;Lo;0;L;;;;;N;;;;; +132A9;EGYPTIAN HIEROGLYPH Q002;Lo;0;L;;;;;N;;;;; +132AA;EGYPTIAN HIEROGLYPH Q003;Lo;0;L;;;;;N;;;;; +132AB;EGYPTIAN HIEROGLYPH Q004;Lo;0;L;;;;;N;;;;; +132AC;EGYPTIAN HIEROGLYPH Q005;Lo;0;L;;;;;N;;;;; +132AD;EGYPTIAN HIEROGLYPH Q006;Lo;0;L;;;;;N;;;;; +132AE;EGYPTIAN HIEROGLYPH Q007;Lo;0;L;;;;;N;;;;; +132AF;EGYPTIAN HIEROGLYPH R001;Lo;0;L;;;;;N;;;;; +132B0;EGYPTIAN HIEROGLYPH R002;Lo;0;L;;;;;N;;;;; +132B1;EGYPTIAN HIEROGLYPH R002A;Lo;0;L;;;;;N;;;;; +132B2;EGYPTIAN HIEROGLYPH R003;Lo;0;L;;;;;N;;;;; +132B3;EGYPTIAN HIEROGLYPH R003A;Lo;0;L;;;;;N;;;;; +132B4;EGYPTIAN HIEROGLYPH R003B;Lo;0;L;;;;;N;;;;; +132B5;EGYPTIAN HIEROGLYPH R004;Lo;0;L;;;;;N;;;;; +132B6;EGYPTIAN HIEROGLYPH R005;Lo;0;L;;;;;N;;;;; +132B7;EGYPTIAN HIEROGLYPH R006;Lo;0;L;;;;;N;;;;; +132B8;EGYPTIAN HIEROGLYPH R007;Lo;0;L;;;;;N;;;;; +132B9;EGYPTIAN HIEROGLYPH R008;Lo;0;L;;;;;N;;;;; +132BA;EGYPTIAN HIEROGLYPH R009;Lo;0;L;;;;;N;;;;; +132BB;EGYPTIAN HIEROGLYPH R010;Lo;0;L;;;;;N;;;;; +132BC;EGYPTIAN HIEROGLYPH R010A;Lo;0;L;;;;;N;;;;; +132BD;EGYPTIAN HIEROGLYPH R011;Lo;0;L;;;;;N;;;;; +132BE;EGYPTIAN HIEROGLYPH R012;Lo;0;L;;;;;N;;;;; +132BF;EGYPTIAN HIEROGLYPH R013;Lo;0;L;;;;;N;;;;; +132C0;EGYPTIAN HIEROGLYPH R014;Lo;0;L;;;;;N;;;;; +132C1;EGYPTIAN HIEROGLYPH R015;Lo;0;L;;;;;N;;;;; +132C2;EGYPTIAN HIEROGLYPH R016;Lo;0;L;;;;;N;;;;; +132C3;EGYPTIAN HIEROGLYPH R016A;Lo;0;L;;;;;N;;;;; +132C4;EGYPTIAN HIEROGLYPH R017;Lo;0;L;;;;;N;;;;; +132C5;EGYPTIAN HIEROGLYPH R018;Lo;0;L;;;;;N;;;;; +132C6;EGYPTIAN HIEROGLYPH R019;Lo;0;L;;;;;N;;;;; +132C7;EGYPTIAN HIEROGLYPH R020;Lo;0;L;;;;;N;;;;; +132C8;EGYPTIAN HIEROGLYPH R021;Lo;0;L;;;;;N;;;;; +132C9;EGYPTIAN HIEROGLYPH R022;Lo;0;L;;;;;N;;;;; +132CA;EGYPTIAN HIEROGLYPH R023;Lo;0;L;;;;;N;;;;; +132CB;EGYPTIAN HIEROGLYPH R024;Lo;0;L;;;;;N;;;;; +132CC;EGYPTIAN HIEROGLYPH R025;Lo;0;L;;;;;N;;;;; +132CD;EGYPTIAN HIEROGLYPH R026;Lo;0;L;;;;;N;;;;; +132CE;EGYPTIAN HIEROGLYPH R027;Lo;0;L;;;;;N;;;;; +132CF;EGYPTIAN HIEROGLYPH R028;Lo;0;L;;;;;N;;;;; +132D0;EGYPTIAN HIEROGLYPH R029;Lo;0;L;;;;;N;;;;; +132D1;EGYPTIAN HIEROGLYPH S001;Lo;0;L;;;;;N;;;;; +132D2;EGYPTIAN HIEROGLYPH S002;Lo;0;L;;;;;N;;;;; +132D3;EGYPTIAN HIEROGLYPH S002A;Lo;0;L;;;;;N;;;;; +132D4;EGYPTIAN HIEROGLYPH S003;Lo;0;L;;;;;N;;;;; +132D5;EGYPTIAN HIEROGLYPH S004;Lo;0;L;;;;;N;;;;; +132D6;EGYPTIAN HIEROGLYPH S005;Lo;0;L;;;;;N;;;;; +132D7;EGYPTIAN HIEROGLYPH S006;Lo;0;L;;;;;N;;;;; +132D8;EGYPTIAN HIEROGLYPH S006A;Lo;0;L;;;;;N;;;;; +132D9;EGYPTIAN HIEROGLYPH S007;Lo;0;L;;;;;N;;;;; +132DA;EGYPTIAN HIEROGLYPH S008;Lo;0;L;;;;;N;;;;; +132DB;EGYPTIAN HIEROGLYPH S009;Lo;0;L;;;;;N;;;;; +132DC;EGYPTIAN HIEROGLYPH S010;Lo;0;L;;;;;N;;;;; +132DD;EGYPTIAN HIEROGLYPH S011;Lo;0;L;;;;;N;;;;; +132DE;EGYPTIAN HIEROGLYPH S012;Lo;0;L;;;;;N;;;;; +132DF;EGYPTIAN HIEROGLYPH S013;Lo;0;L;;;;;N;;;;; +132E0;EGYPTIAN HIEROGLYPH S014;Lo;0;L;;;;;N;;;;; +132E1;EGYPTIAN HIEROGLYPH S014A;Lo;0;L;;;;;N;;;;; +132E2;EGYPTIAN HIEROGLYPH S014B;Lo;0;L;;;;;N;;;;; +132E3;EGYPTIAN HIEROGLYPH S015;Lo;0;L;;;;;N;;;;; +132E4;EGYPTIAN HIEROGLYPH S016;Lo;0;L;;;;;N;;;;; +132E5;EGYPTIAN HIEROGLYPH S017;Lo;0;L;;;;;N;;;;; +132E6;EGYPTIAN HIEROGLYPH S017A;Lo;0;L;;;;;N;;;;; +132E7;EGYPTIAN HIEROGLYPH S018;Lo;0;L;;;;;N;;;;; +132E8;EGYPTIAN HIEROGLYPH S019;Lo;0;L;;;;;N;;;;; +132E9;EGYPTIAN HIEROGLYPH S020;Lo;0;L;;;;;N;;;;; +132EA;EGYPTIAN HIEROGLYPH S021;Lo;0;L;;;;;N;;;;; +132EB;EGYPTIAN HIEROGLYPH S022;Lo;0;L;;;;;N;;;;; +132EC;EGYPTIAN HIEROGLYPH S023;Lo;0;L;;;;;N;;;;; +132ED;EGYPTIAN HIEROGLYPH S024;Lo;0;L;;;;;N;;;;; +132EE;EGYPTIAN HIEROGLYPH S025;Lo;0;L;;;;;N;;;;; +132EF;EGYPTIAN HIEROGLYPH S026;Lo;0;L;;;;;N;;;;; +132F0;EGYPTIAN HIEROGLYPH S026A;Lo;0;L;;;;;N;;;;; +132F1;EGYPTIAN HIEROGLYPH S026B;Lo;0;L;;;;;N;;;;; +132F2;EGYPTIAN HIEROGLYPH S027;Lo;0;L;;;;;N;;;;; +132F3;EGYPTIAN HIEROGLYPH S028;Lo;0;L;;;;;N;;;;; +132F4;EGYPTIAN HIEROGLYPH S029;Lo;0;L;;;;;N;;;;; +132F5;EGYPTIAN HIEROGLYPH S030;Lo;0;L;;;;;N;;;;; +132F6;EGYPTIAN HIEROGLYPH S031;Lo;0;L;;;;;N;;;;; +132F7;EGYPTIAN HIEROGLYPH S032;Lo;0;L;;;;;N;;;;; +132F8;EGYPTIAN HIEROGLYPH S033;Lo;0;L;;;;;N;;;;; +132F9;EGYPTIAN HIEROGLYPH S034;Lo;0;L;;;;;N;;;;; +132FA;EGYPTIAN HIEROGLYPH S035;Lo;0;L;;;;;N;;;;; +132FB;EGYPTIAN HIEROGLYPH S035A;Lo;0;L;;;;;N;;;;; +132FC;EGYPTIAN HIEROGLYPH S036;Lo;0;L;;;;;N;;;;; +132FD;EGYPTIAN HIEROGLYPH S037;Lo;0;L;;;;;N;;;;; +132FE;EGYPTIAN HIEROGLYPH S038;Lo;0;L;;;;;N;;;;; +132FF;EGYPTIAN HIEROGLYPH S039;Lo;0;L;;;;;N;;;;; +13300;EGYPTIAN HIEROGLYPH S040;Lo;0;L;;;;;N;;;;; +13301;EGYPTIAN HIEROGLYPH S041;Lo;0;L;;;;;N;;;;; +13302;EGYPTIAN HIEROGLYPH S042;Lo;0;L;;;;;N;;;;; +13303;EGYPTIAN HIEROGLYPH S043;Lo;0;L;;;;;N;;;;; +13304;EGYPTIAN HIEROGLYPH S044;Lo;0;L;;;;;N;;;;; +13305;EGYPTIAN HIEROGLYPH S045;Lo;0;L;;;;;N;;;;; +13306;EGYPTIAN HIEROGLYPH S046;Lo;0;L;;;;;N;;;;; +13307;EGYPTIAN HIEROGLYPH T001;Lo;0;L;;;;;N;;;;; +13308;EGYPTIAN HIEROGLYPH T002;Lo;0;L;;;;;N;;;;; +13309;EGYPTIAN HIEROGLYPH T003;Lo;0;L;;;;;N;;;;; +1330A;EGYPTIAN HIEROGLYPH T003A;Lo;0;L;;;;;N;;;;; +1330B;EGYPTIAN HIEROGLYPH T004;Lo;0;L;;;;;N;;;;; +1330C;EGYPTIAN HIEROGLYPH T005;Lo;0;L;;;;;N;;;;; +1330D;EGYPTIAN HIEROGLYPH T006;Lo;0;L;;;;;N;;;;; +1330E;EGYPTIAN HIEROGLYPH T007;Lo;0;L;;;;;N;;;;; +1330F;EGYPTIAN HIEROGLYPH T007A;Lo;0;L;;;;;N;;;;; +13310;EGYPTIAN HIEROGLYPH T008;Lo;0;L;;;;;N;;;;; +13311;EGYPTIAN HIEROGLYPH T008A;Lo;0;L;;;;;N;;;;; +13312;EGYPTIAN HIEROGLYPH T009;Lo;0;L;;;;;N;;;;; +13313;EGYPTIAN HIEROGLYPH T009A;Lo;0;L;;;;;N;;;;; +13314;EGYPTIAN HIEROGLYPH T010;Lo;0;L;;;;;N;;;;; +13315;EGYPTIAN HIEROGLYPH T011;Lo;0;L;;;;;N;;;;; +13316;EGYPTIAN HIEROGLYPH T011A;Lo;0;L;;;;;N;;;;; +13317;EGYPTIAN HIEROGLYPH T012;Lo;0;L;;;;;N;;;;; +13318;EGYPTIAN HIEROGLYPH T013;Lo;0;L;;;;;N;;;;; +13319;EGYPTIAN HIEROGLYPH T014;Lo;0;L;;;;;N;;;;; +1331A;EGYPTIAN HIEROGLYPH T015;Lo;0;L;;;;;N;;;;; +1331B;EGYPTIAN HIEROGLYPH T016;Lo;0;L;;;;;N;;;;; +1331C;EGYPTIAN HIEROGLYPH T016A;Lo;0;L;;;;;N;;;;; +1331D;EGYPTIAN HIEROGLYPH T017;Lo;0;L;;;;;N;;;;; +1331E;EGYPTIAN HIEROGLYPH T018;Lo;0;L;;;;;N;;;;; +1331F;EGYPTIAN HIEROGLYPH T019;Lo;0;L;;;;;N;;;;; +13320;EGYPTIAN HIEROGLYPH T020;Lo;0;L;;;;;N;;;;; +13321;EGYPTIAN HIEROGLYPH T021;Lo;0;L;;;;;N;;;;; +13322;EGYPTIAN HIEROGLYPH T022;Lo;0;L;;;;;N;;;;; +13323;EGYPTIAN HIEROGLYPH T023;Lo;0;L;;;;;N;;;;; +13324;EGYPTIAN HIEROGLYPH T024;Lo;0;L;;;;;N;;;;; +13325;EGYPTIAN HIEROGLYPH T025;Lo;0;L;;;;;N;;;;; +13326;EGYPTIAN HIEROGLYPH T026;Lo;0;L;;;;;N;;;;; +13327;EGYPTIAN HIEROGLYPH T027;Lo;0;L;;;;;N;;;;; +13328;EGYPTIAN HIEROGLYPH T028;Lo;0;L;;;;;N;;;;; +13329;EGYPTIAN HIEROGLYPH T029;Lo;0;L;;;;;N;;;;; +1332A;EGYPTIAN HIEROGLYPH T030;Lo;0;L;;;;;N;;;;; +1332B;EGYPTIAN HIEROGLYPH T031;Lo;0;L;;;;;N;;;;; +1332C;EGYPTIAN HIEROGLYPH T032;Lo;0;L;;;;;N;;;;; +1332D;EGYPTIAN HIEROGLYPH T032A;Lo;0;L;;;;;N;;;;; +1332E;EGYPTIAN HIEROGLYPH T033;Lo;0;L;;;;;N;;;;; +1332F;EGYPTIAN HIEROGLYPH T033A;Lo;0;L;;;;;N;;;;; +13330;EGYPTIAN HIEROGLYPH T034;Lo;0;L;;;;;N;;;;; +13331;EGYPTIAN HIEROGLYPH T035;Lo;0;L;;;;;N;;;;; +13332;EGYPTIAN HIEROGLYPH T036;Lo;0;L;;;;;N;;;;; +13333;EGYPTIAN HIEROGLYPH U001;Lo;0;L;;;;;N;;;;; +13334;EGYPTIAN HIEROGLYPH U002;Lo;0;L;;;;;N;;;;; +13335;EGYPTIAN HIEROGLYPH U003;Lo;0;L;;;;;N;;;;; +13336;EGYPTIAN HIEROGLYPH U004;Lo;0;L;;;;;N;;;;; +13337;EGYPTIAN HIEROGLYPH U005;Lo;0;L;;;;;N;;;;; +13338;EGYPTIAN HIEROGLYPH U006;Lo;0;L;;;;;N;;;;; +13339;EGYPTIAN HIEROGLYPH U006A;Lo;0;L;;;;;N;;;;; +1333A;EGYPTIAN HIEROGLYPH U006B;Lo;0;L;;;;;N;;;;; +1333B;EGYPTIAN HIEROGLYPH U007;Lo;0;L;;;;;N;;;;; +1333C;EGYPTIAN HIEROGLYPH U008;Lo;0;L;;;;;N;;;;; +1333D;EGYPTIAN HIEROGLYPH U009;Lo;0;L;;;;;N;;;;; +1333E;EGYPTIAN HIEROGLYPH U010;Lo;0;L;;;;;N;;;;; +1333F;EGYPTIAN HIEROGLYPH U011;Lo;0;L;;;;;N;;;;; +13340;EGYPTIAN HIEROGLYPH U012;Lo;0;L;;;;;N;;;;; +13341;EGYPTIAN HIEROGLYPH U013;Lo;0;L;;;;;N;;;;; +13342;EGYPTIAN HIEROGLYPH U014;Lo;0;L;;;;;N;;;;; +13343;EGYPTIAN HIEROGLYPH U015;Lo;0;L;;;;;N;;;;; +13344;EGYPTIAN HIEROGLYPH U016;Lo;0;L;;;;;N;;;;; +13345;EGYPTIAN HIEROGLYPH U017;Lo;0;L;;;;;N;;;;; +13346;EGYPTIAN HIEROGLYPH U018;Lo;0;L;;;;;N;;;;; +13347;EGYPTIAN HIEROGLYPH U019;Lo;0;L;;;;;N;;;;; +13348;EGYPTIAN HIEROGLYPH U020;Lo;0;L;;;;;N;;;;; +13349;EGYPTIAN HIEROGLYPH U021;Lo;0;L;;;;;N;;;;; +1334A;EGYPTIAN HIEROGLYPH U022;Lo;0;L;;;;;N;;;;; +1334B;EGYPTIAN HIEROGLYPH U023;Lo;0;L;;;;;N;;;;; +1334C;EGYPTIAN HIEROGLYPH U023A;Lo;0;L;;;;;N;;;;; +1334D;EGYPTIAN HIEROGLYPH U024;Lo;0;L;;;;;N;;;;; +1334E;EGYPTIAN HIEROGLYPH U025;Lo;0;L;;;;;N;;;;; +1334F;EGYPTIAN HIEROGLYPH U026;Lo;0;L;;;;;N;;;;; +13350;EGYPTIAN HIEROGLYPH U027;Lo;0;L;;;;;N;;;;; +13351;EGYPTIAN HIEROGLYPH U028;Lo;0;L;;;;;N;;;;; +13352;EGYPTIAN HIEROGLYPH U029;Lo;0;L;;;;;N;;;;; +13353;EGYPTIAN HIEROGLYPH U029A;Lo;0;L;;;;;N;;;;; +13354;EGYPTIAN HIEROGLYPH U030;Lo;0;L;;;;;N;;;;; +13355;EGYPTIAN HIEROGLYPH U031;Lo;0;L;;;;;N;;;;; +13356;EGYPTIAN HIEROGLYPH U032;Lo;0;L;;;;;N;;;;; +13357;EGYPTIAN HIEROGLYPH U032A;Lo;0;L;;;;;N;;;;; +13358;EGYPTIAN HIEROGLYPH U033;Lo;0;L;;;;;N;;;;; +13359;EGYPTIAN HIEROGLYPH U034;Lo;0;L;;;;;N;;;;; +1335A;EGYPTIAN HIEROGLYPH U035;Lo;0;L;;;;;N;;;;; +1335B;EGYPTIAN HIEROGLYPH U036;Lo;0;L;;;;;N;;;;; +1335C;EGYPTIAN HIEROGLYPH U037;Lo;0;L;;;;;N;;;;; +1335D;EGYPTIAN HIEROGLYPH U038;Lo;0;L;;;;;N;;;;; +1335E;EGYPTIAN HIEROGLYPH U039;Lo;0;L;;;;;N;;;;; +1335F;EGYPTIAN HIEROGLYPH U040;Lo;0;L;;;;;N;;;;; +13360;EGYPTIAN HIEROGLYPH U041;Lo;0;L;;;;;N;;;;; +13361;EGYPTIAN HIEROGLYPH U042;Lo;0;L;;;;;N;;;;; +13362;EGYPTIAN HIEROGLYPH V001;Lo;0;L;;;;;N;;;;; +13363;EGYPTIAN HIEROGLYPH V001A;Lo;0;L;;;;;N;;;;; +13364;EGYPTIAN HIEROGLYPH V001B;Lo;0;L;;;;;N;;;;; +13365;EGYPTIAN HIEROGLYPH V001C;Lo;0;L;;;;;N;;;;; +13366;EGYPTIAN HIEROGLYPH V001D;Lo;0;L;;;;;N;;;;; +13367;EGYPTIAN HIEROGLYPH V001E;Lo;0;L;;;;;N;;;;; +13368;EGYPTIAN HIEROGLYPH V001F;Lo;0;L;;;;;N;;;;; +13369;EGYPTIAN HIEROGLYPH V001G;Lo;0;L;;;;;N;;;;; +1336A;EGYPTIAN HIEROGLYPH V001H;Lo;0;L;;;;;N;;;;; +1336B;EGYPTIAN HIEROGLYPH V001I;Lo;0;L;;;;;N;;;;; +1336C;EGYPTIAN HIEROGLYPH V002;Lo;0;L;;;;;N;;;;; +1336D;EGYPTIAN HIEROGLYPH V002A;Lo;0;L;;;;;N;;;;; +1336E;EGYPTIAN HIEROGLYPH V003;Lo;0;L;;;;;N;;;;; +1336F;EGYPTIAN HIEROGLYPH V004;Lo;0;L;;;;;N;;;;; +13370;EGYPTIAN HIEROGLYPH V005;Lo;0;L;;;;;N;;;;; +13371;EGYPTIAN HIEROGLYPH V006;Lo;0;L;;;;;N;;;;; +13372;EGYPTIAN HIEROGLYPH V007;Lo;0;L;;;;;N;;;;; +13373;EGYPTIAN HIEROGLYPH V007A;Lo;0;L;;;;;N;;;;; +13374;EGYPTIAN HIEROGLYPH V007B;Lo;0;L;;;;;N;;;;; +13375;EGYPTIAN HIEROGLYPH V008;Lo;0;L;;;;;N;;;;; +13376;EGYPTIAN HIEROGLYPH V009;Lo;0;L;;;;;N;;;;; +13377;EGYPTIAN HIEROGLYPH V010;Lo;0;L;;;;;N;;;;; +13378;EGYPTIAN HIEROGLYPH V011;Lo;0;L;;;;;N;;;;; +13379;EGYPTIAN HIEROGLYPH V011A;Lo;0;L;;;;;N;;;;; +1337A;EGYPTIAN HIEROGLYPH V011B;Lo;0;L;;;;;N;;;;; +1337B;EGYPTIAN HIEROGLYPH V011C;Lo;0;L;;;;;N;;;;; +1337C;EGYPTIAN HIEROGLYPH V012;Lo;0;L;;;;;N;;;;; +1337D;EGYPTIAN HIEROGLYPH V012A;Lo;0;L;;;;;N;;;;; +1337E;EGYPTIAN HIEROGLYPH V012B;Lo;0;L;;;;;N;;;;; +1337F;EGYPTIAN HIEROGLYPH V013;Lo;0;L;;;;;N;;;;; +13380;EGYPTIAN HIEROGLYPH V014;Lo;0;L;;;;;N;;;;; +13381;EGYPTIAN HIEROGLYPH V015;Lo;0;L;;;;;N;;;;; +13382;EGYPTIAN HIEROGLYPH V016;Lo;0;L;;;;;N;;;;; +13383;EGYPTIAN HIEROGLYPH V017;Lo;0;L;;;;;N;;;;; +13384;EGYPTIAN HIEROGLYPH V018;Lo;0;L;;;;;N;;;;; +13385;EGYPTIAN HIEROGLYPH V019;Lo;0;L;;;;;N;;;;; +13386;EGYPTIAN HIEROGLYPH V020;Lo;0;L;;;;;N;;;;; +13387;EGYPTIAN HIEROGLYPH V020A;Lo;0;L;;;;;N;;;;; +13388;EGYPTIAN HIEROGLYPH V020B;Lo;0;L;;;;;N;;;;; +13389;EGYPTIAN HIEROGLYPH V020C;Lo;0;L;;;;;N;;;;; +1338A;EGYPTIAN HIEROGLYPH V020D;Lo;0;L;;;;;N;;;;; +1338B;EGYPTIAN HIEROGLYPH V020E;Lo;0;L;;;;;N;;;;; +1338C;EGYPTIAN HIEROGLYPH V020F;Lo;0;L;;;;;N;;;;; +1338D;EGYPTIAN HIEROGLYPH V020G;Lo;0;L;;;;;N;;;;; +1338E;EGYPTIAN HIEROGLYPH V020H;Lo;0;L;;;;;N;;;;; +1338F;EGYPTIAN HIEROGLYPH V020I;Lo;0;L;;;;;N;;;;; +13390;EGYPTIAN HIEROGLYPH V020J;Lo;0;L;;;;;N;;;;; +13391;EGYPTIAN HIEROGLYPH V020K;Lo;0;L;;;;;N;;;;; +13392;EGYPTIAN HIEROGLYPH V020L;Lo;0;L;;;;;N;;;;; +13393;EGYPTIAN HIEROGLYPH V021;Lo;0;L;;;;;N;;;;; +13394;EGYPTIAN HIEROGLYPH V022;Lo;0;L;;;;;N;;;;; +13395;EGYPTIAN HIEROGLYPH V023;Lo;0;L;;;;;N;;;;; +13396;EGYPTIAN HIEROGLYPH V023A;Lo;0;L;;;;;N;;;;; +13397;EGYPTIAN HIEROGLYPH V024;Lo;0;L;;;;;N;;;;; +13398;EGYPTIAN HIEROGLYPH V025;Lo;0;L;;;;;N;;;;; +13399;EGYPTIAN HIEROGLYPH V026;Lo;0;L;;;;;N;;;;; +1339A;EGYPTIAN HIEROGLYPH V027;Lo;0;L;;;;;N;;;;; +1339B;EGYPTIAN HIEROGLYPH V028;Lo;0;L;;;;;N;;;;; +1339C;EGYPTIAN HIEROGLYPH V028A;Lo;0;L;;;;;N;;;;; +1339D;EGYPTIAN HIEROGLYPH V029;Lo;0;L;;;;;N;;;;; +1339E;EGYPTIAN HIEROGLYPH V029A;Lo;0;L;;;;;N;;;;; +1339F;EGYPTIAN HIEROGLYPH V030;Lo;0;L;;;;;N;;;;; +133A0;EGYPTIAN HIEROGLYPH V030A;Lo;0;L;;;;;N;;;;; +133A1;EGYPTIAN HIEROGLYPH V031;Lo;0;L;;;;;N;;;;; +133A2;EGYPTIAN HIEROGLYPH V031A;Lo;0;L;;;;;N;;;;; +133A3;EGYPTIAN HIEROGLYPH V032;Lo;0;L;;;;;N;;;;; +133A4;EGYPTIAN HIEROGLYPH V033;Lo;0;L;;;;;N;;;;; +133A5;EGYPTIAN HIEROGLYPH V033A;Lo;0;L;;;;;N;;;;; +133A6;EGYPTIAN HIEROGLYPH V034;Lo;0;L;;;;;N;;;;; +133A7;EGYPTIAN HIEROGLYPH V035;Lo;0;L;;;;;N;;;;; +133A8;EGYPTIAN HIEROGLYPH V036;Lo;0;L;;;;;N;;;;; +133A9;EGYPTIAN HIEROGLYPH V037;Lo;0;L;;;;;N;;;;; +133AA;EGYPTIAN HIEROGLYPH V037A;Lo;0;L;;;;;N;;;;; +133AB;EGYPTIAN HIEROGLYPH V038;Lo;0;L;;;;;N;;;;; +133AC;EGYPTIAN HIEROGLYPH V039;Lo;0;L;;;;;N;;;;; +133AD;EGYPTIAN HIEROGLYPH V040;Lo;0;L;;;;;N;;;;; +133AE;EGYPTIAN HIEROGLYPH V040A;Lo;0;L;;;;;N;;;;; +133AF;EGYPTIAN HIEROGLYPH W001;Lo;0;L;;;;;N;;;;; +133B0;EGYPTIAN HIEROGLYPH W002;Lo;0;L;;;;;N;;;;; +133B1;EGYPTIAN HIEROGLYPH W003;Lo;0;L;;;;;N;;;;; +133B2;EGYPTIAN HIEROGLYPH W003A;Lo;0;L;;;;;N;;;;; +133B3;EGYPTIAN HIEROGLYPH W004;Lo;0;L;;;;;N;;;;; +133B4;EGYPTIAN HIEROGLYPH W005;Lo;0;L;;;;;N;;;;; +133B5;EGYPTIAN HIEROGLYPH W006;Lo;0;L;;;;;N;;;;; +133B6;EGYPTIAN HIEROGLYPH W007;Lo;0;L;;;;;N;;;;; +133B7;EGYPTIAN HIEROGLYPH W008;Lo;0;L;;;;;N;;;;; +133B8;EGYPTIAN HIEROGLYPH W009;Lo;0;L;;;;;N;;;;; +133B9;EGYPTIAN HIEROGLYPH W009A;Lo;0;L;;;;;N;;;;; +133BA;EGYPTIAN HIEROGLYPH W010;Lo;0;L;;;;;N;;;;; +133BB;EGYPTIAN HIEROGLYPH W010A;Lo;0;L;;;;;N;;;;; +133BC;EGYPTIAN HIEROGLYPH W011;Lo;0;L;;;;;N;;;;; +133BD;EGYPTIAN HIEROGLYPH W012;Lo;0;L;;;;;N;;;;; +133BE;EGYPTIAN HIEROGLYPH W013;Lo;0;L;;;;;N;;;;; +133BF;EGYPTIAN HIEROGLYPH W014;Lo;0;L;;;;;N;;;;; +133C0;EGYPTIAN HIEROGLYPH W014A;Lo;0;L;;;;;N;;;;; +133C1;EGYPTIAN HIEROGLYPH W015;Lo;0;L;;;;;N;;;;; +133C2;EGYPTIAN HIEROGLYPH W016;Lo;0;L;;;;;N;;;;; +133C3;EGYPTIAN HIEROGLYPH W017;Lo;0;L;;;;;N;;;;; +133C4;EGYPTIAN HIEROGLYPH W017A;Lo;0;L;;;;;N;;;;; +133C5;EGYPTIAN HIEROGLYPH W018;Lo;0;L;;;;;N;;;;; +133C6;EGYPTIAN HIEROGLYPH W018A;Lo;0;L;;;;;N;;;;; +133C7;EGYPTIAN HIEROGLYPH W019;Lo;0;L;;;;;N;;;;; +133C8;EGYPTIAN HIEROGLYPH W020;Lo;0;L;;;;;N;;;;; +133C9;EGYPTIAN HIEROGLYPH W021;Lo;0;L;;;;;N;;;;; +133CA;EGYPTIAN HIEROGLYPH W022;Lo;0;L;;;;;N;;;;; +133CB;EGYPTIAN HIEROGLYPH W023;Lo;0;L;;;;;N;;;;; +133CC;EGYPTIAN HIEROGLYPH W024;Lo;0;L;;;;;N;;;;; +133CD;EGYPTIAN HIEROGLYPH W024A;Lo;0;L;;;;;N;;;;; +133CE;EGYPTIAN HIEROGLYPH W025;Lo;0;L;;;;;N;;;;; +133CF;EGYPTIAN HIEROGLYPH X001;Lo;0;L;;;;;N;;;;; +133D0;EGYPTIAN HIEROGLYPH X002;Lo;0;L;;;;;N;;;;; +133D1;EGYPTIAN HIEROGLYPH X003;Lo;0;L;;;;;N;;;;; +133D2;EGYPTIAN HIEROGLYPH X004;Lo;0;L;;;;;N;;;;; +133D3;EGYPTIAN HIEROGLYPH X004A;Lo;0;L;;;;;N;;;;; +133D4;EGYPTIAN HIEROGLYPH X004B;Lo;0;L;;;;;N;;;;; +133D5;EGYPTIAN HIEROGLYPH X005;Lo;0;L;;;;;N;;;;; +133D6;EGYPTIAN HIEROGLYPH X006;Lo;0;L;;;;;N;;;;; +133D7;EGYPTIAN HIEROGLYPH X006A;Lo;0;L;;;;;N;;;;; +133D8;EGYPTIAN HIEROGLYPH X007;Lo;0;L;;;;;N;;;;; +133D9;EGYPTIAN HIEROGLYPH X008;Lo;0;L;;;;;N;;;;; +133DA;EGYPTIAN HIEROGLYPH X008A;Lo;0;L;;;;;N;;;;; +133DB;EGYPTIAN HIEROGLYPH Y001;Lo;0;L;;;;;N;;;;; +133DC;EGYPTIAN HIEROGLYPH Y001A;Lo;0;L;;;;;N;;;;; +133DD;EGYPTIAN HIEROGLYPH Y002;Lo;0;L;;;;;N;;;;; +133DE;EGYPTIAN HIEROGLYPH Y003;Lo;0;L;;;;;N;;;;; +133DF;EGYPTIAN HIEROGLYPH Y004;Lo;0;L;;;;;N;;;;; +133E0;EGYPTIAN HIEROGLYPH Y005;Lo;0;L;;;;;N;;;;; +133E1;EGYPTIAN HIEROGLYPH Y006;Lo;0;L;;;;;N;;;;; +133E2;EGYPTIAN HIEROGLYPH Y007;Lo;0;L;;;;;N;;;;; +133E3;EGYPTIAN HIEROGLYPH Y008;Lo;0;L;;;;;N;;;;; +133E4;EGYPTIAN HIEROGLYPH Z001;Lo;0;L;;;;;N;;;;; +133E5;EGYPTIAN HIEROGLYPH Z002;Lo;0;L;;;;;N;;;;; +133E6;EGYPTIAN HIEROGLYPH Z002A;Lo;0;L;;;;;N;;;;; +133E7;EGYPTIAN HIEROGLYPH Z002B;Lo;0;L;;;;;N;;;;; +133E8;EGYPTIAN HIEROGLYPH Z002C;Lo;0;L;;;;;N;;;;; +133E9;EGYPTIAN HIEROGLYPH Z002D;Lo;0;L;;;;;N;;;;; +133EA;EGYPTIAN HIEROGLYPH Z003;Lo;0;L;;;;;N;;;;; +133EB;EGYPTIAN HIEROGLYPH Z003A;Lo;0;L;;;;;N;;;;; +133EC;EGYPTIAN HIEROGLYPH Z003B;Lo;0;L;;;;;N;;;;; +133ED;EGYPTIAN HIEROGLYPH Z004;Lo;0;L;;;;;N;;;;; +133EE;EGYPTIAN HIEROGLYPH Z004A;Lo;0;L;;;;;N;;;;; +133EF;EGYPTIAN HIEROGLYPH Z005;Lo;0;L;;;;;N;;;;; +133F0;EGYPTIAN HIEROGLYPH Z005A;Lo;0;L;;;;;N;;;;; +133F1;EGYPTIAN HIEROGLYPH Z006;Lo;0;L;;;;;N;;;;; +133F2;EGYPTIAN HIEROGLYPH Z007;Lo;0;L;;;;;N;;;;; +133F3;EGYPTIAN HIEROGLYPH Z008;Lo;0;L;;;;;N;;;;; +133F4;EGYPTIAN HIEROGLYPH Z009;Lo;0;L;;;;;N;;;;; +133F5;EGYPTIAN HIEROGLYPH Z010;Lo;0;L;;;;;N;;;;; +133F6;EGYPTIAN HIEROGLYPH Z011;Lo;0;L;;;;;N;;;;; +133F7;EGYPTIAN HIEROGLYPH Z012;Lo;0;L;;;;;N;;;;; +133F8;EGYPTIAN HIEROGLYPH Z013;Lo;0;L;;;;;N;;;;; +133F9;EGYPTIAN HIEROGLYPH Z014;Lo;0;L;;;;;N;;;;; +133FA;EGYPTIAN HIEROGLYPH Z015;Lo;0;L;;;;;N;;;;; +133FB;EGYPTIAN HIEROGLYPH Z015A;Lo;0;L;;;;;N;;;;; +133FC;EGYPTIAN HIEROGLYPH Z015B;Lo;0;L;;;;;N;;;;; +133FD;EGYPTIAN HIEROGLYPH Z015C;Lo;0;L;;;;;N;;;;; +133FE;EGYPTIAN HIEROGLYPH Z015D;Lo;0;L;;;;;N;;;;; +133FF;EGYPTIAN HIEROGLYPH Z015E;Lo;0;L;;;;;N;;;;; +13400;EGYPTIAN HIEROGLYPH Z015F;Lo;0;L;;;;;N;;;;; +13401;EGYPTIAN HIEROGLYPH Z015G;Lo;0;L;;;;;N;;;;; +13402;EGYPTIAN HIEROGLYPH Z015H;Lo;0;L;;;;;N;;;;; +13403;EGYPTIAN HIEROGLYPH Z015I;Lo;0;L;;;;;N;;;;; +13404;EGYPTIAN HIEROGLYPH Z016;Lo;0;L;;;;;N;;;;; +13405;EGYPTIAN HIEROGLYPH Z016A;Lo;0;L;;;;;N;;;;; +13406;EGYPTIAN HIEROGLYPH Z016B;Lo;0;L;;;;;N;;;;; +13407;EGYPTIAN HIEROGLYPH Z016C;Lo;0;L;;;;;N;;;;; +13408;EGYPTIAN HIEROGLYPH Z016D;Lo;0;L;;;;;N;;;;; +13409;EGYPTIAN HIEROGLYPH Z016E;Lo;0;L;;;;;N;;;;; +1340A;EGYPTIAN HIEROGLYPH Z016F;Lo;0;L;;;;;N;;;;; +1340B;EGYPTIAN HIEROGLYPH Z016G;Lo;0;L;;;;;N;;;;; +1340C;EGYPTIAN HIEROGLYPH Z016H;Lo;0;L;;;;;N;;;;; +1340D;EGYPTIAN HIEROGLYPH AA001;Lo;0;L;;;;;N;;;;; +1340E;EGYPTIAN HIEROGLYPH AA002;Lo;0;L;;;;;N;;;;; +1340F;EGYPTIAN HIEROGLYPH AA003;Lo;0;L;;;;;N;;;;; +13410;EGYPTIAN HIEROGLYPH AA004;Lo;0;L;;;;;N;;;;; +13411;EGYPTIAN HIEROGLYPH AA005;Lo;0;L;;;;;N;;;;; +13412;EGYPTIAN HIEROGLYPH AA006;Lo;0;L;;;;;N;;;;; +13413;EGYPTIAN HIEROGLYPH AA007;Lo;0;L;;;;;N;;;;; +13414;EGYPTIAN HIEROGLYPH AA007A;Lo;0;L;;;;;N;;;;; +13415;EGYPTIAN HIEROGLYPH AA007B;Lo;0;L;;;;;N;;;;; +13416;EGYPTIAN HIEROGLYPH AA008;Lo;0;L;;;;;N;;;;; +13417;EGYPTIAN HIEROGLYPH AA009;Lo;0;L;;;;;N;;;;; +13418;EGYPTIAN HIEROGLYPH AA010;Lo;0;L;;;;;N;;;;; +13419;EGYPTIAN HIEROGLYPH AA011;Lo;0;L;;;;;N;;;;; +1341A;EGYPTIAN HIEROGLYPH AA012;Lo;0;L;;;;;N;;;;; +1341B;EGYPTIAN HIEROGLYPH AA013;Lo;0;L;;;;;N;;;;; +1341C;EGYPTIAN HIEROGLYPH AA014;Lo;0;L;;;;;N;;;;; +1341D;EGYPTIAN HIEROGLYPH AA015;Lo;0;L;;;;;N;;;;; +1341E;EGYPTIAN HIEROGLYPH AA016;Lo;0;L;;;;;N;;;;; +1341F;EGYPTIAN HIEROGLYPH AA017;Lo;0;L;;;;;N;;;;; +13420;EGYPTIAN HIEROGLYPH AA018;Lo;0;L;;;;;N;;;;; +13421;EGYPTIAN HIEROGLYPH AA019;Lo;0;L;;;;;N;;;;; +13422;EGYPTIAN HIEROGLYPH AA020;Lo;0;L;;;;;N;;;;; +13423;EGYPTIAN HIEROGLYPH AA021;Lo;0;L;;;;;N;;;;; +13424;EGYPTIAN HIEROGLYPH AA022;Lo;0;L;;;;;N;;;;; +13425;EGYPTIAN HIEROGLYPH AA023;Lo;0;L;;;;;N;;;;; +13426;EGYPTIAN HIEROGLYPH AA024;Lo;0;L;;;;;N;;;;; +13427;EGYPTIAN HIEROGLYPH AA025;Lo;0;L;;;;;N;;;;; +13428;EGYPTIAN HIEROGLYPH AA026;Lo;0;L;;;;;N;;;;; +13429;EGYPTIAN HIEROGLYPH AA027;Lo;0;L;;;;;N;;;;; +1342A;EGYPTIAN HIEROGLYPH AA028;Lo;0;L;;;;;N;;;;; +1342B;EGYPTIAN HIEROGLYPH AA029;Lo;0;L;;;;;N;;;;; +1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;; +1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;; +1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;; +1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;; +1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;; +1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;; +1D003;BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON;So;0;L;;;;;N;;;;; +1D004;BYZANTINE MUSICAL SYMBOL OXEIA DIPLI;So;0;L;;;;;N;;;;; +1D005;BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON;So;0;L;;;;;N;;;;; +1D006;BYZANTINE MUSICAL SYMBOL VAREIA DIPLI;So;0;L;;;;;N;;;;; +1D007;BYZANTINE MUSICAL SYMBOL KATHISTI;So;0;L;;;;;N;;;;; +1D008;BYZANTINE MUSICAL SYMBOL SYRMATIKI;So;0;L;;;;;N;;;;; +1D009;BYZANTINE MUSICAL SYMBOL PARAKLITIKI;So;0;L;;;;;N;;;;; +1D00A;BYZANTINE MUSICAL SYMBOL YPOKRISIS;So;0;L;;;;;N;;;;; +1D00B;BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI;So;0;L;;;;;N;;;;; +1D00C;BYZANTINE MUSICAL SYMBOL KREMASTI;So;0;L;;;;;N;;;;; +1D00D;BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON;So;0;L;;;;;N;;;;; +1D00E;BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON;So;0;L;;;;;N;;;;; +1D00F;BYZANTINE MUSICAL SYMBOL TELEIA;So;0;L;;;;;N;;;;; +1D010;BYZANTINE MUSICAL SYMBOL KENTIMATA;So;0;L;;;;;N;;;;; +1D011;BYZANTINE MUSICAL SYMBOL APOSTROFOS;So;0;L;;;;;N;;;;; +1D012;BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI;So;0;L;;;;;N;;;;; +1D013;BYZANTINE MUSICAL SYMBOL SYNEVMA;So;0;L;;;;;N;;;;; +1D014;BYZANTINE MUSICAL SYMBOL THITA;So;0;L;;;;;N;;;;; +1D015;BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION;So;0;L;;;;;N;;;;; +1D016;BYZANTINE MUSICAL SYMBOL GORGON ARCHAION;So;0;L;;;;;N;;;;; +1D017;BYZANTINE MUSICAL SYMBOL PSILON;So;0;L;;;;;N;;;;; +1D018;BYZANTINE MUSICAL SYMBOL CHAMILON;So;0;L;;;;;N;;;;; +1D019;BYZANTINE MUSICAL SYMBOL VATHY;So;0;L;;;;;N;;;;; +1D01A;BYZANTINE MUSICAL SYMBOL ISON ARCHAION;So;0;L;;;;;N;;;;; +1D01B;BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION;So;0;L;;;;;N;;;;; +1D01C;BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION;So;0;L;;;;;N;;;;; +1D01D;BYZANTINE MUSICAL SYMBOL SAXIMATA;So;0;L;;;;;N;;;;; +1D01E;BYZANTINE MUSICAL SYMBOL PARICHON;So;0;L;;;;;N;;;;; +1D01F;BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA;So;0;L;;;;;N;;;;; +1D020;BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION;So;0;L;;;;;N;;;;; +1D021;BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION;So;0;L;;;;;N;;;;; +1D022;BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION;So;0;L;;;;;N;;;;; +1D023;BYZANTINE MUSICAL SYMBOL APOTHEMA;So;0;L;;;;;N;;;;; +1D024;BYZANTINE MUSICAL SYMBOL KLASMA;So;0;L;;;;;N;;;;; +1D025;BYZANTINE MUSICAL SYMBOL REVMA;So;0;L;;;;;N;;;;; +1D026;BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION;So;0;L;;;;;N;;;;; +1D027;BYZANTINE MUSICAL SYMBOL TINAGMA;So;0;L;;;;;N;;;;; +1D028;BYZANTINE MUSICAL SYMBOL ANATRICHISMA;So;0;L;;;;;N;;;;; +1D029;BYZANTINE MUSICAL SYMBOL SEISMA;So;0;L;;;;;N;;;;; +1D02A;BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION;So;0;L;;;;;N;;;;; +1D02B;BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU;So;0;L;;;;;N;;;;; +1D02C;BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION;So;0;L;;;;;N;;;;; +1D02D;BYZANTINE MUSICAL SYMBOL THEMA;So;0;L;;;;;N;;;;; +1D02E;BYZANTINE MUSICAL SYMBOL LEMOI;So;0;L;;;;;N;;;;; +1D02F;BYZANTINE MUSICAL SYMBOL DYO;So;0;L;;;;;N;;;;; +1D030;BYZANTINE MUSICAL SYMBOL TRIA;So;0;L;;;;;N;;;;; +1D031;BYZANTINE MUSICAL SYMBOL TESSERA;So;0;L;;;;;N;;;;; +1D032;BYZANTINE MUSICAL SYMBOL KRATIMATA;So;0;L;;;;;N;;;;; +1D033;BYZANTINE MUSICAL SYMBOL APESO EXO NEO;So;0;L;;;;;N;;;;; +1D034;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION;So;0;L;;;;;N;;;;; +1D035;BYZANTINE MUSICAL SYMBOL IMIFTHORA;So;0;L;;;;;N;;;;; +1D036;BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION;So;0;L;;;;;N;;;;; +1D037;BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON;So;0;L;;;;;N;;;;; +1D038;BYZANTINE MUSICAL SYMBOL PELASTON;So;0;L;;;;;N;;;;; +1D039;BYZANTINE MUSICAL SYMBOL PSIFISTON;So;0;L;;;;;N;;;;; +1D03A;BYZANTINE MUSICAL SYMBOL KONTEVMA;So;0;L;;;;;N;;;;; +1D03B;BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION;So;0;L;;;;;N;;;;; +1D03C;BYZANTINE MUSICAL SYMBOL RAPISMA;So;0;L;;;;;N;;;;; +1D03D;BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION;So;0;L;;;;;N;;;;; +1D03E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION;So;0;L;;;;;N;;;;; +1D03F;BYZANTINE MUSICAL SYMBOL ICHADIN;So;0;L;;;;;N;;;;; +1D040;BYZANTINE MUSICAL SYMBOL NANA;So;0;L;;;;;N;;;;; +1D041;BYZANTINE MUSICAL SYMBOL PETASMA;So;0;L;;;;;N;;;;; +1D042;BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO;So;0;L;;;;;N;;;;; +1D043;BYZANTINE MUSICAL SYMBOL TROMIKON ALLO;So;0;L;;;;;N;;;;; +1D044;BYZANTINE MUSICAL SYMBOL STRAGGISMATA;So;0;L;;;;;N;;;;; +1D045;BYZANTINE MUSICAL SYMBOL GRONTHISMATA;So;0;L;;;;;N;;;;; +1D046;BYZANTINE MUSICAL SYMBOL ISON NEO;So;0;L;;;;;N;;;;; +1D047;BYZANTINE MUSICAL SYMBOL OLIGON NEO;So;0;L;;;;;N;;;;; +1D048;BYZANTINE MUSICAL SYMBOL OXEIA NEO;So;0;L;;;;;N;;;;; +1D049;BYZANTINE MUSICAL SYMBOL PETASTI;So;0;L;;;;;N;;;;; +1D04A;BYZANTINE MUSICAL SYMBOL KOUFISMA;So;0;L;;;;;N;;;;; +1D04B;BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA;So;0;L;;;;;N;;;;; +1D04C;BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA;So;0;L;;;;;N;;;;; +1D04D;BYZANTINE MUSICAL SYMBOL PELASTON NEO;So;0;L;;;;;N;;;;; +1D04E;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO;So;0;L;;;;;N;;;;; +1D04F;BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO;So;0;L;;;;;N;;;;; +1D050;BYZANTINE MUSICAL SYMBOL YPSILI;So;0;L;;;;;N;;;;; +1D051;BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO;So;0;L;;;;;N;;;;; +1D052;BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO;So;0;L;;;;;N;;;;; +1D053;BYZANTINE MUSICAL SYMBOL YPORROI;So;0;L;;;;;N;;;;; +1D054;BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON;So;0;L;;;;;N;;;;; +1D055;BYZANTINE MUSICAL SYMBOL ELAFRON;So;0;L;;;;;N;;;;; +1D056;BYZANTINE MUSICAL SYMBOL CHAMILI;So;0;L;;;;;N;;;;; +1D057;BYZANTINE MUSICAL SYMBOL MIKRON ISON;So;0;L;;;;;N;;;;; +1D058;BYZANTINE MUSICAL SYMBOL VAREIA NEO;So;0;L;;;;;N;;;;; +1D059;BYZANTINE MUSICAL SYMBOL PIASMA NEO;So;0;L;;;;;N;;;;; +1D05A;BYZANTINE MUSICAL SYMBOL PSIFISTON NEO;So;0;L;;;;;N;;;;; +1D05B;BYZANTINE MUSICAL SYMBOL OMALON;So;0;L;;;;;N;;;;; +1D05C;BYZANTINE MUSICAL SYMBOL ANTIKENOMA;So;0;L;;;;;N;;;;; +1D05D;BYZANTINE MUSICAL SYMBOL LYGISMA;So;0;L;;;;;N;;;;; +1D05E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO;So;0;L;;;;;N;;;;; +1D05F;BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO;So;0;L;;;;;N;;;;; +1D060;BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA;So;0;L;;;;;N;;;;; +1D061;BYZANTINE MUSICAL SYMBOL KYLISMA;So;0;L;;;;;N;;;;; +1D062;BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA;So;0;L;;;;;N;;;;; +1D063;BYZANTINE MUSICAL SYMBOL TROMIKON NEO;So;0;L;;;;;N;;;;; +1D064;BYZANTINE MUSICAL SYMBOL EKSTREPTON;So;0;L;;;;;N;;;;; +1D065;BYZANTINE MUSICAL SYMBOL SYNAGMA NEO;So;0;L;;;;;N;;;;; +1D066;BYZANTINE MUSICAL SYMBOL SYRMA;So;0;L;;;;;N;;;;; +1D067;BYZANTINE MUSICAL SYMBOL CHOREVMA NEO;So;0;L;;;;;N;;;;; +1D068;BYZANTINE MUSICAL SYMBOL EPEGERMA;So;0;L;;;;;N;;;;; +1D069;BYZANTINE MUSICAL SYMBOL SEISMA NEO;So;0;L;;;;;N;;;;; +1D06A;BYZANTINE MUSICAL SYMBOL XIRON KLASMA;So;0;L;;;;;N;;;;; +1D06B;BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON;So;0;L;;;;;N;;;;; +1D06C;BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA;So;0;L;;;;;N;;;;; +1D06D;BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA;So;0;L;;;;;N;;;;; +1D06E;BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA;So;0;L;;;;;N;;;;; +1D06F;BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA;So;0;L;;;;;N;;;;; +1D070;BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA;So;0;L;;;;;N;;;;; +1D071;BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA;So;0;L;;;;;N;;;;; +1D072;BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON;So;0;L;;;;;N;;;;; +1D073;BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON;So;0;L;;;;;N;;;;; +1D074;BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON;So;0;L;;;;;N;;;;; +1D075;BYZANTINE MUSICAL SYMBOL OYRANISMA NEO;So;0;L;;;;;N;;;;; +1D076;BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO;So;0;L;;;;;N;;;;; +1D077;BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO;So;0;L;;;;;N;;;;; +1D078;BYZANTINE MUSICAL SYMBOL THEMA APLOUN;So;0;L;;;;;N;;;;; +1D079;BYZANTINE MUSICAL SYMBOL THES KAI APOTHES;So;0;L;;;;;N;;;;; +1D07A;BYZANTINE MUSICAL SYMBOL KATAVASMA;So;0;L;;;;;N;;;;; +1D07B;BYZANTINE MUSICAL SYMBOL ENDOFONON;So;0;L;;;;;N;;;;; +1D07C;BYZANTINE MUSICAL SYMBOL YFEN KATO;So;0;L;;;;;N;;;;; +1D07D;BYZANTINE MUSICAL SYMBOL YFEN ANO;So;0;L;;;;;N;;;;; +1D07E;BYZANTINE MUSICAL SYMBOL STAVROS;So;0;L;;;;;N;;;;; +1D07F;BYZANTINE MUSICAL SYMBOL KLASMA ANO;So;0;L;;;;;N;;;;; +1D080;BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION;So;0;L;;;;;N;;;;; +1D081;BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION;So;0;L;;;;;N;;;;; +1D082;BYZANTINE MUSICAL SYMBOL KRATIMA ALLO;So;0;L;;;;;N;;;;; +1D083;BYZANTINE MUSICAL SYMBOL KRATIMA NEO;So;0;L;;;;;N;;;;; +1D084;BYZANTINE MUSICAL SYMBOL APODERMA NEO;So;0;L;;;;;N;;;;; +1D085;BYZANTINE MUSICAL SYMBOL APLI;So;0;L;;;;;N;;;;; +1D086;BYZANTINE MUSICAL SYMBOL DIPLI;So;0;L;;;;;N;;;;; +1D087;BYZANTINE MUSICAL SYMBOL TRIPLI;So;0;L;;;;;N;;;;; +1D088;BYZANTINE MUSICAL SYMBOL TETRAPLI;So;0;L;;;;;N;;;;; +1D089;BYZANTINE MUSICAL SYMBOL KORONIS;So;0;L;;;;;N;;;;; +1D08A;BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU;So;0;L;;;;;N;;;;; +1D08B;BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON;So;0;L;;;;;N;;;;; +1D08C;BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON;So;0;L;;;;;N;;;;; +1D08D;BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON;So;0;L;;;;;N;;;;; +1D08E;BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU;So;0;L;;;;;N;;;;; +1D08F;BYZANTINE MUSICAL SYMBOL GORGON NEO ANO;So;0;L;;;;;N;;;;; +1D090;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA;So;0;L;;;;;N;;;;; +1D091;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;; +1D092;BYZANTINE MUSICAL SYMBOL DIGORGON;So;0;L;;;;;N;;;;; +1D093;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO;So;0;L;;;;;N;;;;; +1D094;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO;So;0;L;;;;;N;;;;; +1D095;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;; +1D096;BYZANTINE MUSICAL SYMBOL TRIGORGON;So;0;L;;;;;N;;;;; +1D097;BYZANTINE MUSICAL SYMBOL ARGON;So;0;L;;;;;N;;;;; +1D098;BYZANTINE MUSICAL SYMBOL IMIDIARGON;So;0;L;;;;;N;;;;; +1D099;BYZANTINE MUSICAL SYMBOL DIARGON;So;0;L;;;;;N;;;;; +1D09A;BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI;So;0;L;;;;;N;;;;; +1D09B;BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI;So;0;L;;;;;N;;;;; +1D09C;BYZANTINE MUSICAL SYMBOL AGOGI ARGI;So;0;L;;;;;N;;;;; +1D09D;BYZANTINE MUSICAL SYMBOL AGOGI METRIA;So;0;L;;;;;N;;;;; +1D09E;BYZANTINE MUSICAL SYMBOL AGOGI MESI;So;0;L;;;;;N;;;;; +1D09F;BYZANTINE MUSICAL SYMBOL AGOGI GORGI;So;0;L;;;;;N;;;;; +1D0A0;BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI;So;0;L;;;;;N;;;;; +1D0A1;BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI;So;0;L;;;;;N;;;;; +1D0A2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS;So;0;L;;;;;N;;;;; +1D0A3;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS;So;0;L;;;;;N;;;;; +1D0A4;BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS;So;0;L;;;;;N;;;;; +1D0A5;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS;So;0;L;;;;;N;;;;; +1D0A6;BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS;So;0;L;;;;;N;;;;; +1D0A7;BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS;So;0;L;;;;;N;;;;; +1D0A8;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS;So;0;L;;;;;N;;;;; +1D0A9;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS;So;0;L;;;;;N;;;;; +1D0AA;BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS;So;0;L;;;;;N;;;;; +1D0AB;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS;So;0;L;;;;;N;;;;; +1D0AC;BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS;So;0;L;;;;;N;;;;; +1D0AD;BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS;So;0;L;;;;;N;;;;; +1D0AE;BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS;So;0;L;;;;;N;;;;; +1D0AF;BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS;So;0;L;;;;;N;;;;; +1D0B0;BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS;So;0;L;;;;;N;;;;; +1D0B1;BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS;So;0;L;;;;;N;;;;; +1D0B2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS;So;0;L;;;;;N;;;;; +1D0B3;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS;So;0;L;;;;;N;;;;; +1D0B4;BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN;So;0;L;;;;;N;;;;; +1D0B5;BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN;So;0;L;;;;;N;;;;; +1D0B6;BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU;So;0;L;;;;;N;;;;; +1D0B7;BYZANTINE MUSICAL SYMBOL IMIFONON;So;0;L;;;;;N;;;;; +1D0B8;BYZANTINE MUSICAL SYMBOL IMIFTHORON;So;0;L;;;;;N;;;;; +1D0B9;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU;So;0;L;;;;;N;;;;; +1D0BA;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA;So;0;L;;;;;N;;;;; +1D0BB;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA;So;0;L;;;;;N;;;;; +1D0BC;BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS;So;0;L;;;;;N;;;;; +1D0BD;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI;So;0;L;;;;;N;;;;; +1D0BE;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI;So;0;L;;;;;N;;;;; +1D0BF;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE;So;0;L;;;;;N;;;;; +1D0C0;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO;So;0;L;;;;;N;;;;; +1D0C1;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO;So;0;L;;;;;N;;;;; +1D0C2;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO;So;0;L;;;;;N;;;;; +1D0C3;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS;So;0;L;;;;;N;;;;; +1D0C4;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS;So;0;L;;;;;N;;;;; +1D0C5;BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS;So;0;L;;;;;N;;;;; +1D0C6;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI;So;0;L;;;;;N;;;;; +1D0C7;BYZANTINE MUSICAL SYMBOL FTHORA NENANO;So;0;L;;;;;N;;;;; +1D0C8;BYZANTINE MUSICAL SYMBOL CHROA ZYGOS;So;0;L;;;;;N;;;;; +1D0C9;BYZANTINE MUSICAL SYMBOL CHROA KLITON;So;0;L;;;;;N;;;;; +1D0CA;BYZANTINE MUSICAL SYMBOL CHROA SPATHI;So;0;L;;;;;N;;;;; +1D0CB;BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION;So;0;L;;;;;N;;;;; +1D0CC;BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA;So;0;L;;;;;N;;;;; +1D0CD;BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION;So;0;L;;;;;N;;;;; +1D0CE;BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION;So;0;L;;;;;N;;;;; +1D0CF;BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION;So;0;L;;;;;N;;;;; +1D0D0;BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;; +1D0D1;BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;; +1D0D2;BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;; +1D0D3;BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;; +1D0D4;BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;; +1D0D5;BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;; +1D0D6;BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;; +1D0D7;BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;; +1D0D8;BYZANTINE MUSICAL SYMBOL GENIKI DIESIS;So;0;L;;;;;N;;;;; +1D0D9;BYZANTINE MUSICAL SYMBOL GENIKI YFESIS;So;0;L;;;;;N;;;;; +1D0DA;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI;So;0;L;;;;;N;;;;; +1D0DB;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI;So;0;L;;;;;N;;;;; +1D0DC;BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI;So;0;L;;;;;N;;;;; +1D0DD;BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS;So;0;L;;;;;N;;;;; +1D0DE;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS;So;0;L;;;;;N;;;;; +1D0DF;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU;So;0;L;;;;;N;;;;; +1D0E0;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU;So;0;L;;;;;N;;;;; +1D0E1;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU;So;0;L;;;;;N;;;;; +1D0E2;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS;So;0;L;;;;;N;;;;; +1D0E3;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU;So;0;L;;;;;N;;;;; +1D0E4;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU;So;0;L;;;;;N;;;;; +1D0E5;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU;So;0;L;;;;;N;;;;; +1D0E6;BYZANTINE MUSICAL SYMBOL DIGRAMMA GG;So;0;L;;;;;N;;;;; +1D0E7;BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU;So;0;L;;;;;N;;;;; +1D0E8;BYZANTINE MUSICAL SYMBOL STIGMA;So;0;L;;;;;N;;;;; +1D0E9;BYZANTINE MUSICAL SYMBOL ARKTIKO PA;So;0;L;;;;;N;;;;; +1D0EA;BYZANTINE MUSICAL SYMBOL ARKTIKO VOU;So;0;L;;;;;N;;;;; +1D0EB;BYZANTINE MUSICAL SYMBOL ARKTIKO GA;So;0;L;;;;;N;;;;; +1D0EC;BYZANTINE MUSICAL SYMBOL ARKTIKO DI;So;0;L;;;;;N;;;;; +1D0ED;BYZANTINE MUSICAL SYMBOL ARKTIKO KE;So;0;L;;;;;N;;;;; +1D0EE;BYZANTINE MUSICAL SYMBOL ARKTIKO ZO;So;0;L;;;;;N;;;;; +1D0EF;BYZANTINE MUSICAL SYMBOL ARKTIKO NI;So;0;L;;;;;N;;;;; +1D0F0;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO;So;0;L;;;;;N;;;;; +1D0F1;BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO;So;0;L;;;;;N;;;;; +1D0F2;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO;So;0;L;;;;;N;;;;; +1D0F3;BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO;So;0;L;;;;;N;;;;; +1D0F4;BYZANTINE MUSICAL SYMBOL KLASMA KATO;So;0;L;;;;;N;;;;; +1D0F5;BYZANTINE MUSICAL SYMBOL GORGON NEO KATO;So;0;L;;;;;N;;;;; +1D100;MUSICAL SYMBOL SINGLE BARLINE;So;0;L;;;;;N;;;;; +1D101;MUSICAL SYMBOL DOUBLE BARLINE;So;0;L;;;;;N;;;;; +1D102;MUSICAL SYMBOL FINAL BARLINE;So;0;L;;;;;N;;;;; +1D103;MUSICAL SYMBOL REVERSE FINAL BARLINE;So;0;L;;;;;N;;;;; +1D104;MUSICAL SYMBOL DASHED BARLINE;So;0;L;;;;;N;;;;; +1D105;MUSICAL SYMBOL SHORT BARLINE;So;0;L;;;;;N;;;;; +1D106;MUSICAL SYMBOL LEFT REPEAT SIGN;So;0;L;;;;;N;;;;; +1D107;MUSICAL SYMBOL RIGHT REPEAT SIGN;So;0;L;;;;;N;;;;; +1D108;MUSICAL SYMBOL REPEAT DOTS;So;0;L;;;;;N;;;;; +1D109;MUSICAL SYMBOL DAL SEGNO;So;0;L;;;;;N;;;;; +1D10A;MUSICAL SYMBOL DA CAPO;So;0;L;;;;;N;;;;; +1D10B;MUSICAL SYMBOL SEGNO;So;0;L;;;;;N;;;;; +1D10C;MUSICAL SYMBOL CODA;So;0;L;;;;;N;;;;; +1D10D;MUSICAL SYMBOL REPEATED FIGURE-1;So;0;L;;;;;N;;;;; +1D10E;MUSICAL SYMBOL REPEATED FIGURE-2;So;0;L;;;;;N;;;;; +1D10F;MUSICAL SYMBOL REPEATED FIGURE-3;So;0;L;;;;;N;;;;; +1D110;MUSICAL SYMBOL FERMATA;So;0;L;;;;;N;;;;; +1D111;MUSICAL SYMBOL FERMATA BELOW;So;0;L;;;;;N;;;;; +1D112;MUSICAL SYMBOL BREATH MARK;So;0;L;;;;;N;;;;; +1D113;MUSICAL SYMBOL CAESURA;So;0;L;;;;;N;;;;; +1D114;MUSICAL SYMBOL BRACE;So;0;L;;;;;N;;;;; +1D115;MUSICAL SYMBOL BRACKET;So;0;L;;;;;N;;;;; +1D116;MUSICAL SYMBOL ONE-LINE STAFF;So;0;L;;;;;N;;;;; +1D117;MUSICAL SYMBOL TWO-LINE STAFF;So;0;L;;;;;N;;;;; +1D118;MUSICAL SYMBOL THREE-LINE STAFF;So;0;L;;;;;N;;;;; +1D119;MUSICAL SYMBOL FOUR-LINE STAFF;So;0;L;;;;;N;;;;; +1D11A;MUSICAL SYMBOL FIVE-LINE STAFF;So;0;L;;;;;N;;;;; +1D11B;MUSICAL SYMBOL SIX-LINE STAFF;So;0;L;;;;;N;;;;; +1D11C;MUSICAL SYMBOL SIX-STRING FRETBOARD;So;0;L;;;;;N;;;;; +1D11D;MUSICAL SYMBOL FOUR-STRING FRETBOARD;So;0;L;;;;;N;;;;; +1D11E;MUSICAL SYMBOL G CLEF;So;0;L;;;;;N;;;;; +1D11F;MUSICAL SYMBOL G CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;; +1D120;MUSICAL SYMBOL G CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;; +1D121;MUSICAL SYMBOL C CLEF;So;0;L;;;;;N;;;;; +1D122;MUSICAL SYMBOL F CLEF;So;0;L;;;;;N;;;;; +1D123;MUSICAL SYMBOL F CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;; +1D124;MUSICAL SYMBOL F CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;; +1D125;MUSICAL SYMBOL DRUM CLEF-1;So;0;L;;;;;N;;;;; +1D126;MUSICAL SYMBOL DRUM CLEF-2;So;0;L;;;;;N;;;;; +1D129;MUSICAL SYMBOL MULTIPLE MEASURE REST;So;0;L;;;;;N;;;;; +1D12A;MUSICAL SYMBOL DOUBLE SHARP;So;0;L;;;;;N;;;;; +1D12B;MUSICAL SYMBOL DOUBLE FLAT;So;0;L;;;;;N;;;;; +1D12C;MUSICAL SYMBOL FLAT UP;So;0;L;;;;;N;;;;; +1D12D;MUSICAL SYMBOL FLAT DOWN;So;0;L;;;;;N;;;;; +1D12E;MUSICAL SYMBOL NATURAL UP;So;0;L;;;;;N;;;;; +1D12F;MUSICAL SYMBOL NATURAL DOWN;So;0;L;;;;;N;;;;; +1D130;MUSICAL SYMBOL SHARP UP;So;0;L;;;;;N;;;;; +1D131;MUSICAL SYMBOL SHARP DOWN;So;0;L;;;;;N;;;;; +1D132;MUSICAL SYMBOL QUARTER TONE SHARP;So;0;L;;;;;N;;;;; +1D133;MUSICAL SYMBOL QUARTER TONE FLAT;So;0;L;;;;;N;;;;; +1D134;MUSICAL SYMBOL COMMON TIME;So;0;L;;;;;N;;;;; +1D135;MUSICAL SYMBOL CUT TIME;So;0;L;;;;;N;;;;; +1D136;MUSICAL SYMBOL OTTAVA ALTA;So;0;L;;;;;N;;;;; +1D137;MUSICAL SYMBOL OTTAVA BASSA;So;0;L;;;;;N;;;;; +1D138;MUSICAL SYMBOL QUINDICESIMA ALTA;So;0;L;;;;;N;;;;; +1D139;MUSICAL SYMBOL QUINDICESIMA BASSA;So;0;L;;;;;N;;;;; +1D13A;MUSICAL SYMBOL MULTI REST;So;0;L;;;;;N;;;;; +1D13B;MUSICAL SYMBOL WHOLE REST;So;0;L;;;;;N;;;;; +1D13C;MUSICAL SYMBOL HALF REST;So;0;L;;;;;N;;;;; +1D13D;MUSICAL SYMBOL QUARTER REST;So;0;L;;;;;N;;;;; +1D13E;MUSICAL SYMBOL EIGHTH REST;So;0;L;;;;;N;;;;; +1D13F;MUSICAL SYMBOL SIXTEENTH REST;So;0;L;;;;;N;;;;; +1D140;MUSICAL SYMBOL THIRTY-SECOND REST;So;0;L;;;;;N;;;;; +1D141;MUSICAL SYMBOL SIXTY-FOURTH REST;So;0;L;;;;;N;;;;; +1D142;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST;So;0;L;;;;;N;;;;; +1D143;MUSICAL SYMBOL X NOTEHEAD;So;0;L;;;;;N;;;;; +1D144;MUSICAL SYMBOL PLUS NOTEHEAD;So;0;L;;;;;N;;;;; +1D145;MUSICAL SYMBOL CIRCLE X NOTEHEAD;So;0;L;;;;;N;;;;; +1D146;MUSICAL SYMBOL SQUARE NOTEHEAD WHITE;So;0;L;;;;;N;;;;; +1D147;MUSICAL SYMBOL SQUARE NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D148;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE;So;0;L;;;;;N;;;;; +1D149;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK;So;0;L;;;;;N;;;;; +1D14A;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE;So;0;L;;;;;N;;;;; +1D14B;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK;So;0;L;;;;;N;;;;; +1D14C;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE;So;0;L;;;;;N;;;;; +1D14D;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK;So;0;L;;;;;N;;;;; +1D14E;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;; +1D14F;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;; +1D150;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE;So;0;L;;;;;N;;;;; +1D151;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK;So;0;L;;;;;N;;;;; +1D152;MUSICAL SYMBOL MOON NOTEHEAD WHITE;So;0;L;;;;;N;;;;; +1D153;MUSICAL SYMBOL MOON NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D154;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;; +1D155;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;; +1D156;MUSICAL SYMBOL PARENTHESIS NOTEHEAD;So;0;L;;;;;N;;;;; +1D157;MUSICAL SYMBOL VOID NOTEHEAD;So;0;L;;;;;N;;;;; +1D158;MUSICAL SYMBOL NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D159;MUSICAL SYMBOL NULL NOTEHEAD;So;0;L;;;;;N;;;;; +1D15A;MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE;So;0;L;;;;;N;;;;; +1D15B;MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D15C;MUSICAL SYMBOL BREVE;So;0;L;;;;;N;;;;; +1D15D;MUSICAL SYMBOL WHOLE NOTE;So;0;L;;;;;N;;;;; +1D15E;MUSICAL SYMBOL HALF NOTE;So;0;L;1D157 1D165;;;;N;;;;; +1D15F;MUSICAL SYMBOL QUARTER NOTE;So;0;L;1D158 1D165;;;;N;;;;; +1D160;MUSICAL SYMBOL EIGHTH NOTE;So;0;L;1D15F 1D16E;;;;N;;;;; +1D161;MUSICAL SYMBOL SIXTEENTH NOTE;So;0;L;1D15F 1D16F;;;;N;;;;; +1D162;MUSICAL SYMBOL THIRTY-SECOND NOTE;So;0;L;1D15F 1D170;;;;N;;;;; +1D163;MUSICAL SYMBOL SIXTY-FOURTH NOTE;So;0;L;1D15F 1D171;;;;N;;;;; +1D164;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE;So;0;L;1D15F 1D172;;;;N;;;;; +1D165;MUSICAL SYMBOL COMBINING STEM;Mc;216;L;;;;;N;;;;; +1D166;MUSICAL SYMBOL COMBINING SPRECHGESANG STEM;Mc;216;L;;;;;N;;;;; +1D167;MUSICAL SYMBOL COMBINING TREMOLO-1;Mn;1;NSM;;;;;N;;;;; +1D168;MUSICAL SYMBOL COMBINING TREMOLO-2;Mn;1;NSM;;;;;N;;;;; +1D169;MUSICAL SYMBOL COMBINING TREMOLO-3;Mn;1;NSM;;;;;N;;;;; +1D16A;MUSICAL SYMBOL FINGERED TREMOLO-1;So;0;L;;;;;N;;;;; +1D16B;MUSICAL SYMBOL FINGERED TREMOLO-2;So;0;L;;;;;N;;;;; +1D16C;MUSICAL SYMBOL FINGERED TREMOLO-3;So;0;L;;;;;N;;;;; +1D16D;MUSICAL SYMBOL COMBINING AUGMENTATION DOT;Mc;226;L;;;;;N;;;;; +1D16E;MUSICAL SYMBOL COMBINING FLAG-1;Mc;216;L;;;;;N;;;;; +1D16F;MUSICAL SYMBOL COMBINING FLAG-2;Mc;216;L;;;;;N;;;;; +1D170;MUSICAL SYMBOL COMBINING FLAG-3;Mc;216;L;;;;;N;;;;; +1D171;MUSICAL SYMBOL COMBINING FLAG-4;Mc;216;L;;;;;N;;;;; +1D172;MUSICAL SYMBOL COMBINING FLAG-5;Mc;216;L;;;;;N;;;;; +1D173;MUSICAL SYMBOL BEGIN BEAM;Cf;0;BN;;;;;N;;;;; +1D174;MUSICAL SYMBOL END BEAM;Cf;0;BN;;;;;N;;;;; +1D175;MUSICAL SYMBOL BEGIN TIE;Cf;0;BN;;;;;N;;;;; +1D176;MUSICAL SYMBOL END TIE;Cf;0;BN;;;;;N;;;;; +1D177;MUSICAL SYMBOL BEGIN SLUR;Cf;0;BN;;;;;N;;;;; +1D178;MUSICAL SYMBOL END SLUR;Cf;0;BN;;;;;N;;;;; +1D179;MUSICAL SYMBOL BEGIN PHRASE;Cf;0;BN;;;;;N;;;;; +1D17A;MUSICAL SYMBOL END PHRASE;Cf;0;BN;;;;;N;;;;; +1D17B;MUSICAL SYMBOL COMBINING ACCENT;Mn;220;NSM;;;;;N;;;;; +1D17C;MUSICAL SYMBOL COMBINING STACCATO;Mn;220;NSM;;;;;N;;;;; +1D17D;MUSICAL SYMBOL COMBINING TENUTO;Mn;220;NSM;;;;;N;;;;; +1D17E;MUSICAL SYMBOL COMBINING STACCATISSIMO;Mn;220;NSM;;;;;N;;;;; +1D17F;MUSICAL SYMBOL COMBINING MARCATO;Mn;220;NSM;;;;;N;;;;; +1D180;MUSICAL SYMBOL COMBINING MARCATO-STACCATO;Mn;220;NSM;;;;;N;;;;; +1D181;MUSICAL SYMBOL COMBINING ACCENT-STACCATO;Mn;220;NSM;;;;;N;;;;; +1D182;MUSICAL SYMBOL COMBINING LOURE;Mn;220;NSM;;;;;N;;;;; +1D183;MUSICAL SYMBOL ARPEGGIATO UP;So;0;L;;;;;N;;;;; +1D184;MUSICAL SYMBOL ARPEGGIATO DOWN;So;0;L;;;;;N;;;;; +1D185;MUSICAL SYMBOL COMBINING DOIT;Mn;230;NSM;;;;;N;;;;; +1D186;MUSICAL SYMBOL COMBINING RIP;Mn;230;NSM;;;;;N;;;;; +1D187;MUSICAL SYMBOL COMBINING FLIP;Mn;230;NSM;;;;;N;;;;; +1D188;MUSICAL SYMBOL COMBINING SMEAR;Mn;230;NSM;;;;;N;;;;; +1D189;MUSICAL SYMBOL COMBINING BEND;Mn;230;NSM;;;;;N;;;;; +1D18A;MUSICAL SYMBOL COMBINING DOUBLE TONGUE;Mn;220;NSM;;;;;N;;;;; +1D18B;MUSICAL SYMBOL COMBINING TRIPLE TONGUE;Mn;220;NSM;;;;;N;;;;; +1D18C;MUSICAL SYMBOL RINFORZANDO;So;0;L;;;;;N;;;;; +1D18D;MUSICAL SYMBOL SUBITO;So;0;L;;;;;N;;;;; +1D18E;MUSICAL SYMBOL Z;So;0;L;;;;;N;;;;; +1D18F;MUSICAL SYMBOL PIANO;So;0;L;;;;;N;;;;; +1D190;MUSICAL SYMBOL MEZZO;So;0;L;;;;;N;;;;; +1D191;MUSICAL SYMBOL FORTE;So;0;L;;;;;N;;;;; +1D192;MUSICAL SYMBOL CRESCENDO;So;0;L;;;;;N;;;;; +1D193;MUSICAL SYMBOL DECRESCENDO;So;0;L;;;;;N;;;;; +1D194;MUSICAL SYMBOL GRACE NOTE SLASH;So;0;L;;;;;N;;;;; +1D195;MUSICAL SYMBOL GRACE NOTE NO SLASH;So;0;L;;;;;N;;;;; +1D196;MUSICAL SYMBOL TR;So;0;L;;;;;N;;;;; +1D197;MUSICAL SYMBOL TURN;So;0;L;;;;;N;;;;; +1D198;MUSICAL SYMBOL INVERTED TURN;So;0;L;;;;;N;;;;; +1D199;MUSICAL SYMBOL TURN SLASH;So;0;L;;;;;N;;;;; +1D19A;MUSICAL SYMBOL TURN UP;So;0;L;;;;;N;;;;; +1D19B;MUSICAL SYMBOL ORNAMENT STROKE-1;So;0;L;;;;;N;;;;; +1D19C;MUSICAL SYMBOL ORNAMENT STROKE-2;So;0;L;;;;;N;;;;; +1D19D;MUSICAL SYMBOL ORNAMENT STROKE-3;So;0;L;;;;;N;;;;; +1D19E;MUSICAL SYMBOL ORNAMENT STROKE-4;So;0;L;;;;;N;;;;; +1D19F;MUSICAL SYMBOL ORNAMENT STROKE-5;So;0;L;;;;;N;;;;; +1D1A0;MUSICAL SYMBOL ORNAMENT STROKE-6;So;0;L;;;;;N;;;;; +1D1A1;MUSICAL SYMBOL ORNAMENT STROKE-7;So;0;L;;;;;N;;;;; +1D1A2;MUSICAL SYMBOL ORNAMENT STROKE-8;So;0;L;;;;;N;;;;; +1D1A3;MUSICAL SYMBOL ORNAMENT STROKE-9;So;0;L;;;;;N;;;;; +1D1A4;MUSICAL SYMBOL ORNAMENT STROKE-10;So;0;L;;;;;N;;;;; +1D1A5;MUSICAL SYMBOL ORNAMENT STROKE-11;So;0;L;;;;;N;;;;; +1D1A6;MUSICAL SYMBOL HAUPTSTIMME;So;0;L;;;;;N;;;;; +1D1A7;MUSICAL SYMBOL NEBENSTIMME;So;0;L;;;;;N;;;;; +1D1A8;MUSICAL SYMBOL END OF STIMME;So;0;L;;;;;N;;;;; +1D1A9;MUSICAL SYMBOL DEGREE SLASH;So;0;L;;;;;N;;;;; +1D1AA;MUSICAL SYMBOL COMBINING DOWN BOW;Mn;230;NSM;;;;;N;;;;; +1D1AB;MUSICAL SYMBOL COMBINING UP BOW;Mn;230;NSM;;;;;N;;;;; +1D1AC;MUSICAL SYMBOL COMBINING HARMONIC;Mn;230;NSM;;;;;N;;;;; +1D1AD;MUSICAL SYMBOL COMBINING SNAP PIZZICATO;Mn;230;NSM;;;;;N;;;;; +1D1AE;MUSICAL SYMBOL PEDAL MARK;So;0;L;;;;;N;;;;; +1D1AF;MUSICAL SYMBOL PEDAL UP MARK;So;0;L;;;;;N;;;;; +1D1B0;MUSICAL SYMBOL HALF PEDAL MARK;So;0;L;;;;;N;;;;; +1D1B1;MUSICAL SYMBOL GLISSANDO UP;So;0;L;;;;;N;;;;; +1D1B2;MUSICAL SYMBOL GLISSANDO DOWN;So;0;L;;;;;N;;;;; +1D1B3;MUSICAL SYMBOL WITH FINGERNAILS;So;0;L;;;;;N;;;;; +1D1B4;MUSICAL SYMBOL DAMP;So;0;L;;;;;N;;;;; +1D1B5;MUSICAL SYMBOL DAMP ALL;So;0;L;;;;;N;;;;; +1D1B6;MUSICAL SYMBOL MAXIMA;So;0;L;;;;;N;;;;; +1D1B7;MUSICAL SYMBOL LONGA;So;0;L;;;;;N;;;;; +1D1B8;MUSICAL SYMBOL BREVIS;So;0;L;;;;;N;;;;; +1D1B9;MUSICAL SYMBOL SEMIBREVIS WHITE;So;0;L;;;;;N;;;;; +1D1BA;MUSICAL SYMBOL SEMIBREVIS BLACK;So;0;L;;;;;N;;;;; +1D1BB;MUSICAL SYMBOL MINIMA;So;0;L;1D1B9 1D165;;;;N;;;;; +1D1BC;MUSICAL SYMBOL MINIMA BLACK;So;0;L;1D1BA 1D165;;;;N;;;;; +1D1BD;MUSICAL SYMBOL SEMIMINIMA WHITE;So;0;L;1D1BB 1D16E;;;;N;;;;; +1D1BE;MUSICAL SYMBOL SEMIMINIMA BLACK;So;0;L;1D1BC 1D16E;;;;N;;;;; +1D1BF;MUSICAL SYMBOL FUSA WHITE;So;0;L;1D1BB 1D16F;;;;N;;;;; +1D1C0;MUSICAL SYMBOL FUSA BLACK;So;0;L;1D1BC 1D16F;;;;N;;;;; +1D1C1;MUSICAL SYMBOL LONGA PERFECTA REST;So;0;L;;;;;N;;;;; +1D1C2;MUSICAL SYMBOL LONGA IMPERFECTA REST;So;0;L;;;;;N;;;;; +1D1C3;MUSICAL SYMBOL BREVIS REST;So;0;L;;;;;N;;;;; +1D1C4;MUSICAL SYMBOL SEMIBREVIS REST;So;0;L;;;;;N;;;;; +1D1C5;MUSICAL SYMBOL MINIMA REST;So;0;L;;;;;N;;;;; +1D1C6;MUSICAL SYMBOL SEMIMINIMA REST;So;0;L;;;;;N;;;;; +1D1C7;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;; +1D1C8;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;; +1D1C9;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;; +1D1CA;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;; +1D1CB;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;; +1D1CC;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;; +1D1CD;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-2;So;0;L;;;;;N;;;;; +1D1CE;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-3;So;0;L;;;;;N;;;;; +1D1CF;MUSICAL SYMBOL CROIX;So;0;L;;;;;N;;;;; +1D1D0;MUSICAL SYMBOL GREGORIAN C CLEF;So;0;L;;;;;N;;;;; +1D1D1;MUSICAL SYMBOL GREGORIAN F CLEF;So;0;L;;;;;N;;;;; +1D1D2;MUSICAL SYMBOL SQUARE B;So;0;L;;;;;N;;;;; +1D1D3;MUSICAL SYMBOL VIRGA;So;0;L;;;;;N;;;;; +1D1D4;MUSICAL SYMBOL PODATUS;So;0;L;;;;;N;;;;; +1D1D5;MUSICAL SYMBOL CLIVIS;So;0;L;;;;;N;;;;; +1D1D6;MUSICAL SYMBOL SCANDICUS;So;0;L;;;;;N;;;;; +1D1D7;MUSICAL SYMBOL CLIMACUS;So;0;L;;;;;N;;;;; +1D1D8;MUSICAL SYMBOL TORCULUS;So;0;L;;;;;N;;;;; +1D1D9;MUSICAL SYMBOL PORRECTUS;So;0;L;;;;;N;;;;; +1D1DA;MUSICAL SYMBOL PORRECTUS FLEXUS;So;0;L;;;;;N;;;;; +1D1DB;MUSICAL SYMBOL SCANDICUS FLEXUS;So;0;L;;;;;N;;;;; +1D1DC;MUSICAL SYMBOL TORCULUS RESUPINUS;So;0;L;;;;;N;;;;; +1D1DD;MUSICAL SYMBOL PES SUBPUNCTIS;So;0;L;;;;;N;;;;; +1D200;GREEK VOCAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;; +1D201;GREEK VOCAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;; +1D202;GREEK VOCAL NOTATION SYMBOL-3;So;0;ON;;;;;N;;;;; +1D203;GREEK VOCAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;; +1D204;GREEK VOCAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;; +1D205;GREEK VOCAL NOTATION SYMBOL-6;So;0;ON;;;;;N;;;;; +1D206;GREEK VOCAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;; +1D207;GREEK VOCAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;; +1D208;GREEK VOCAL NOTATION SYMBOL-9;So;0;ON;;;;;N;;;;; +1D209;GREEK VOCAL NOTATION SYMBOL-10;So;0;ON;;;;;N;;;;; +1D20A;GREEK VOCAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;; +1D20B;GREEK VOCAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;; +1D20C;GREEK VOCAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;; +1D20D;GREEK VOCAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;; +1D20E;GREEK VOCAL NOTATION SYMBOL-15;So;0;ON;;;;;N;;;;; +1D20F;GREEK VOCAL NOTATION SYMBOL-16;So;0;ON;;;;;N;;;;; +1D210;GREEK VOCAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;; +1D211;GREEK VOCAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;; +1D212;GREEK VOCAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;; +1D213;GREEK VOCAL NOTATION SYMBOL-20;So;0;ON;;;;;N;;;;; +1D214;GREEK VOCAL NOTATION SYMBOL-21;So;0;ON;;;;;N;;;;; +1D215;GREEK VOCAL NOTATION SYMBOL-22;So;0;ON;;;;;N;;;;; +1D216;GREEK VOCAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;; +1D217;GREEK VOCAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;; +1D218;GREEK VOCAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;; +1D219;GREEK VOCAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;; +1D21A;GREEK VOCAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;; +1D21B;GREEK VOCAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;; +1D21C;GREEK VOCAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;; +1D21D;GREEK INSTRUMENTAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;; +1D21E;GREEK INSTRUMENTAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;; +1D21F;GREEK INSTRUMENTAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;; +1D220;GREEK INSTRUMENTAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;; +1D221;GREEK INSTRUMENTAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;; +1D222;GREEK INSTRUMENTAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;; +1D223;GREEK INSTRUMENTAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;; +1D224;GREEK INSTRUMENTAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;; +1D225;GREEK INSTRUMENTAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;; +1D226;GREEK INSTRUMENTAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;; +1D227;GREEK INSTRUMENTAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;; +1D228;GREEK INSTRUMENTAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;; +1D229;GREEK INSTRUMENTAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;; +1D22A;GREEK INSTRUMENTAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;; +1D22B;GREEK INSTRUMENTAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;; +1D22C;GREEK INSTRUMENTAL NOTATION SYMBOL-25;So;0;ON;;;;;N;;;;; +1D22D;GREEK INSTRUMENTAL NOTATION SYMBOL-26;So;0;ON;;;;;N;;;;; +1D22E;GREEK INSTRUMENTAL NOTATION SYMBOL-27;So;0;ON;;;;;N;;;;; +1D22F;GREEK INSTRUMENTAL NOTATION SYMBOL-29;So;0;ON;;;;;N;;;;; +1D230;GREEK INSTRUMENTAL NOTATION SYMBOL-30;So;0;ON;;;;;N;;;;; +1D231;GREEK INSTRUMENTAL NOTATION SYMBOL-32;So;0;ON;;;;;N;;;;; +1D232;GREEK INSTRUMENTAL NOTATION SYMBOL-36;So;0;ON;;;;;N;;;;; +1D233;GREEK INSTRUMENTAL NOTATION SYMBOL-37;So;0;ON;;;;;N;;;;; +1D234;GREEK INSTRUMENTAL NOTATION SYMBOL-38;So;0;ON;;;;;N;;;;; +1D235;GREEK INSTRUMENTAL NOTATION SYMBOL-39;So;0;ON;;;;;N;;;;; +1D236;GREEK INSTRUMENTAL NOTATION SYMBOL-40;So;0;ON;;;;;N;;;;; +1D237;GREEK INSTRUMENTAL NOTATION SYMBOL-42;So;0;ON;;;;;N;;;;; +1D238;GREEK INSTRUMENTAL NOTATION SYMBOL-43;So;0;ON;;;;;N;;;;; +1D239;GREEK INSTRUMENTAL NOTATION SYMBOL-45;So;0;ON;;;;;N;;;;; +1D23A;GREEK INSTRUMENTAL NOTATION SYMBOL-47;So;0;ON;;;;;N;;;;; +1D23B;GREEK INSTRUMENTAL NOTATION SYMBOL-48;So;0;ON;;;;;N;;;;; +1D23C;GREEK INSTRUMENTAL NOTATION SYMBOL-49;So;0;ON;;;;;N;;;;; +1D23D;GREEK INSTRUMENTAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;; +1D23E;GREEK INSTRUMENTAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;; +1D23F;GREEK INSTRUMENTAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;; +1D240;GREEK INSTRUMENTAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;; +1D241;GREEK INSTRUMENTAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;; +1D242;COMBINING GREEK MUSICAL TRISEME;Mn;230;NSM;;;;;N;;;;; +1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;; +1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;; +1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;N;;;;; +1D300;MONOGRAM FOR EARTH;So;0;ON;;;;;N;;;;; +1D301;DIGRAM FOR HEAVENLY EARTH;So;0;ON;;;;;N;;;;; +1D302;DIGRAM FOR HUMAN EARTH;So;0;ON;;;;;N;;;;; +1D303;DIGRAM FOR EARTHLY HEAVEN;So;0;ON;;;;;N;;;;; +1D304;DIGRAM FOR EARTHLY HUMAN;So;0;ON;;;;;N;;;;; +1D305;DIGRAM FOR EARTH;So;0;ON;;;;;N;;;;; +1D306;TETRAGRAM FOR CENTRE;So;0;ON;;;;;N;;;;; +1D307;TETRAGRAM FOR FULL CIRCLE;So;0;ON;;;;;N;;;;; +1D308;TETRAGRAM FOR MIRED;So;0;ON;;;;;N;;;;; +1D309;TETRAGRAM FOR BARRIER;So;0;ON;;;;;N;;;;; +1D30A;TETRAGRAM FOR KEEPING SMALL;So;0;ON;;;;;N;;;;; +1D30B;TETRAGRAM FOR CONTRARIETY;So;0;ON;;;;;N;;;;; +1D30C;TETRAGRAM FOR ASCENT;So;0;ON;;;;;N;;;;; +1D30D;TETRAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;; +1D30E;TETRAGRAM FOR BRANCHING OUT;So;0;ON;;;;;N;;;;; +1D30F;TETRAGRAM FOR DEFECTIVENESS OR DISTORTION;So;0;ON;;;;;N;;;;; +1D310;TETRAGRAM FOR DIVERGENCE;So;0;ON;;;;;N;;;;; +1D311;TETRAGRAM FOR YOUTHFULNESS;So;0;ON;;;;;N;;;;; +1D312;TETRAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;; +1D313;TETRAGRAM FOR PENETRATION;So;0;ON;;;;;N;;;;; +1D314;TETRAGRAM FOR REACH;So;0;ON;;;;;N;;;;; +1D315;TETRAGRAM FOR CONTACT;So;0;ON;;;;;N;;;;; +1D316;TETRAGRAM FOR HOLDING BACK;So;0;ON;;;;;N;;;;; +1D317;TETRAGRAM FOR WAITING;So;0;ON;;;;;N;;;;; +1D318;TETRAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;; +1D319;TETRAGRAM FOR ADVANCE;So;0;ON;;;;;N;;;;; +1D31A;TETRAGRAM FOR RELEASE;So;0;ON;;;;;N;;;;; +1D31B;TETRAGRAM FOR RESISTANCE;So;0;ON;;;;;N;;;;; +1D31C;TETRAGRAM FOR EASE;So;0;ON;;;;;N;;;;; +1D31D;TETRAGRAM FOR JOY;So;0;ON;;;;;N;;;;; +1D31E;TETRAGRAM FOR CONTENTION;So;0;ON;;;;;N;;;;; +1D31F;TETRAGRAM FOR ENDEAVOUR;So;0;ON;;;;;N;;;;; +1D320;TETRAGRAM FOR DUTIES;So;0;ON;;;;;N;;;;; +1D321;TETRAGRAM FOR CHANGE;So;0;ON;;;;;N;;;;; +1D322;TETRAGRAM FOR DECISIVENESS;So;0;ON;;;;;N;;;;; +1D323;TETRAGRAM FOR BOLD RESOLUTION;So;0;ON;;;;;N;;;;; +1D324;TETRAGRAM FOR PACKING;So;0;ON;;;;;N;;;;; +1D325;TETRAGRAM FOR LEGION;So;0;ON;;;;;N;;;;; +1D326;TETRAGRAM FOR CLOSENESS;So;0;ON;;;;;N;;;;; +1D327;TETRAGRAM FOR KINSHIP;So;0;ON;;;;;N;;;;; +1D328;TETRAGRAM FOR GATHERING;So;0;ON;;;;;N;;;;; +1D329;TETRAGRAM FOR STRENGTH;So;0;ON;;;;;N;;;;; +1D32A;TETRAGRAM FOR PURITY;So;0;ON;;;;;N;;;;; +1D32B;TETRAGRAM FOR FULLNESS;So;0;ON;;;;;N;;;;; +1D32C;TETRAGRAM FOR RESIDENCE;So;0;ON;;;;;N;;;;; +1D32D;TETRAGRAM FOR LAW OR MODEL;So;0;ON;;;;;N;;;;; +1D32E;TETRAGRAM FOR RESPONSE;So;0;ON;;;;;N;;;;; +1D32F;TETRAGRAM FOR GOING TO MEET;So;0;ON;;;;;N;;;;; +1D330;TETRAGRAM FOR ENCOUNTERS;So;0;ON;;;;;N;;;;; +1D331;TETRAGRAM FOR STOVE;So;0;ON;;;;;N;;;;; +1D332;TETRAGRAM FOR GREATNESS;So;0;ON;;;;;N;;;;; +1D333;TETRAGRAM FOR ENLARGEMENT;So;0;ON;;;;;N;;;;; +1D334;TETRAGRAM FOR PATTERN;So;0;ON;;;;;N;;;;; +1D335;TETRAGRAM FOR RITUAL;So;0;ON;;;;;N;;;;; +1D336;TETRAGRAM FOR FLIGHT;So;0;ON;;;;;N;;;;; +1D337;TETRAGRAM FOR VASTNESS OR WASTING;So;0;ON;;;;;N;;;;; +1D338;TETRAGRAM FOR CONSTANCY;So;0;ON;;;;;N;;;;; +1D339;TETRAGRAM FOR MEASURE;So;0;ON;;;;;N;;;;; +1D33A;TETRAGRAM FOR ETERNITY;So;0;ON;;;;;N;;;;; +1D33B;TETRAGRAM FOR UNITY;So;0;ON;;;;;N;;;;; +1D33C;TETRAGRAM FOR DIMINISHMENT;So;0;ON;;;;;N;;;;; +1D33D;TETRAGRAM FOR CLOSED MOUTH;So;0;ON;;;;;N;;;;; +1D33E;TETRAGRAM FOR GUARDEDNESS;So;0;ON;;;;;N;;;;; +1D33F;TETRAGRAM FOR GATHERING IN;So;0;ON;;;;;N;;;;; +1D340;TETRAGRAM FOR MASSING;So;0;ON;;;;;N;;;;; +1D341;TETRAGRAM FOR ACCUMULATION;So;0;ON;;;;;N;;;;; +1D342;TETRAGRAM FOR EMBELLISHMENT;So;0;ON;;;;;N;;;;; +1D343;TETRAGRAM FOR DOUBT;So;0;ON;;;;;N;;;;; +1D344;TETRAGRAM FOR WATCH;So;0;ON;;;;;N;;;;; +1D345;TETRAGRAM FOR SINKING;So;0;ON;;;;;N;;;;; +1D346;TETRAGRAM FOR INNER;So;0;ON;;;;;N;;;;; +1D347;TETRAGRAM FOR DEPARTURE;So;0;ON;;;;;N;;;;; +1D348;TETRAGRAM FOR DARKENING;So;0;ON;;;;;N;;;;; +1D349;TETRAGRAM FOR DIMMING;So;0;ON;;;;;N;;;;; +1D34A;TETRAGRAM FOR EXHAUSTION;So;0;ON;;;;;N;;;;; +1D34B;TETRAGRAM FOR SEVERANCE;So;0;ON;;;;;N;;;;; +1D34C;TETRAGRAM FOR STOPPAGE;So;0;ON;;;;;N;;;;; +1D34D;TETRAGRAM FOR HARDNESS;So;0;ON;;;;;N;;;;; +1D34E;TETRAGRAM FOR COMPLETION;So;0;ON;;;;;N;;;;; +1D34F;TETRAGRAM FOR CLOSURE;So;0;ON;;;;;N;;;;; +1D350;TETRAGRAM FOR FAILURE;So;0;ON;;;;;N;;;;; +1D351;TETRAGRAM FOR AGGRAVATION;So;0;ON;;;;;N;;;;; +1D352;TETRAGRAM FOR COMPLIANCE;So;0;ON;;;;;N;;;;; +1D353;TETRAGRAM FOR ON THE VERGE;So;0;ON;;;;;N;;;;; +1D354;TETRAGRAM FOR DIFFICULTIES;So;0;ON;;;;;N;;;;; +1D355;TETRAGRAM FOR LABOURING;So;0;ON;;;;;N;;;;; +1D356;TETRAGRAM FOR FOSTERING;So;0;ON;;;;;N;;;;; +1D360;COUNTING ROD UNIT DIGIT ONE;No;0;L;;;;1;N;;;;; +1D361;COUNTING ROD UNIT DIGIT TWO;No;0;L;;;;2;N;;;;; +1D362;COUNTING ROD UNIT DIGIT THREE;No;0;L;;;;3;N;;;;; +1D363;COUNTING ROD UNIT DIGIT FOUR;No;0;L;;;;4;N;;;;; +1D364;COUNTING ROD UNIT DIGIT FIVE;No;0;L;;;;5;N;;;;; +1D365;COUNTING ROD UNIT DIGIT SIX;No;0;L;;;;6;N;;;;; +1D366;COUNTING ROD UNIT DIGIT SEVEN;No;0;L;;;;7;N;;;;; +1D367;COUNTING ROD UNIT DIGIT EIGHT;No;0;L;;;;8;N;;;;; +1D368;COUNTING ROD UNIT DIGIT NINE;No;0;L;;;;9;N;;;;; +1D369;COUNTING ROD TENS DIGIT ONE;No;0;L;;;;10;N;;;;; +1D36A;COUNTING ROD TENS DIGIT TWO;No;0;L;;;;20;N;;;;; +1D36B;COUNTING ROD TENS DIGIT THREE;No;0;L;;;;30;N;;;;; +1D36C;COUNTING ROD TENS DIGIT FOUR;No;0;L;;;;40;N;;;;; +1D36D;COUNTING ROD TENS DIGIT FIVE;No;0;L;;;;50;N;;;;; +1D36E;COUNTING ROD TENS DIGIT SIX;No;0;L;;;;60;N;;;;; +1D36F;COUNTING ROD TENS DIGIT SEVEN;No;0;L;;;;70;N;;;;; +1D370;COUNTING ROD TENS DIGIT EIGHT;No;0;L;;;;80;N;;;;; +1D371;COUNTING ROD TENS DIGIT NINE;No;0;L;;;;90;N;;;;; +1D400;MATHEMATICAL BOLD CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D401;MATHEMATICAL BOLD CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D402;MATHEMATICAL BOLD CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D403;MATHEMATICAL BOLD CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D404;MATHEMATICAL BOLD CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D405;MATHEMATICAL BOLD CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D406;MATHEMATICAL BOLD CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D407;MATHEMATICAL BOLD CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D408;MATHEMATICAL BOLD CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D409;MATHEMATICAL BOLD CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D40A;MATHEMATICAL BOLD CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D40B;MATHEMATICAL BOLD CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D40C;MATHEMATICAL BOLD CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D40D;MATHEMATICAL BOLD CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D40E;MATHEMATICAL BOLD CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D40F;MATHEMATICAL BOLD CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D410;MATHEMATICAL BOLD CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D411;MATHEMATICAL BOLD CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D412;MATHEMATICAL BOLD CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D413;MATHEMATICAL BOLD CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D414;MATHEMATICAL BOLD CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D415;MATHEMATICAL BOLD CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D416;MATHEMATICAL BOLD CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D417;MATHEMATICAL BOLD CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D418;MATHEMATICAL BOLD CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D419;MATHEMATICAL BOLD CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D41A;MATHEMATICAL BOLD SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D41B;MATHEMATICAL BOLD SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D41C;MATHEMATICAL BOLD SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D41D;MATHEMATICAL BOLD SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D41E;MATHEMATICAL BOLD SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D41F;MATHEMATICAL BOLD SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D420;MATHEMATICAL BOLD SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D421;MATHEMATICAL BOLD SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D422;MATHEMATICAL BOLD SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D423;MATHEMATICAL BOLD SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D424;MATHEMATICAL BOLD SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D425;MATHEMATICAL BOLD SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D426;MATHEMATICAL BOLD SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D427;MATHEMATICAL BOLD SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D428;MATHEMATICAL BOLD SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D429;MATHEMATICAL BOLD SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D42A;MATHEMATICAL BOLD SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D42B;MATHEMATICAL BOLD SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D42C;MATHEMATICAL BOLD SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D42D;MATHEMATICAL BOLD SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D42E;MATHEMATICAL BOLD SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D42F;MATHEMATICAL BOLD SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D430;MATHEMATICAL BOLD SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D431;MATHEMATICAL BOLD SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D432;MATHEMATICAL BOLD SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D433;MATHEMATICAL BOLD SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D434;MATHEMATICAL ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D435;MATHEMATICAL ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D436;MATHEMATICAL ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D437;MATHEMATICAL ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D438;MATHEMATICAL ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D439;MATHEMATICAL ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D43A;MATHEMATICAL ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D43B;MATHEMATICAL ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D43C;MATHEMATICAL ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D43D;MATHEMATICAL ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D43E;MATHEMATICAL ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D43F;MATHEMATICAL ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D440;MATHEMATICAL ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D441;MATHEMATICAL ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D442;MATHEMATICAL ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D443;MATHEMATICAL ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D444;MATHEMATICAL ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D445;MATHEMATICAL ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D446;MATHEMATICAL ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D447;MATHEMATICAL ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D448;MATHEMATICAL ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D449;MATHEMATICAL ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D44A;MATHEMATICAL ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D44B;MATHEMATICAL ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D44C;MATHEMATICAL ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D44D;MATHEMATICAL ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D44E;MATHEMATICAL ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D44F;MATHEMATICAL ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D450;MATHEMATICAL ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D451;MATHEMATICAL ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D452;MATHEMATICAL ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D453;MATHEMATICAL ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D454;MATHEMATICAL ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D456;MATHEMATICAL ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D457;MATHEMATICAL ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D458;MATHEMATICAL ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D459;MATHEMATICAL ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D45A;MATHEMATICAL ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D45B;MATHEMATICAL ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D45C;MATHEMATICAL ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D45D;MATHEMATICAL ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D45E;MATHEMATICAL ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D45F;MATHEMATICAL ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D460;MATHEMATICAL ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D461;MATHEMATICAL ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D462;MATHEMATICAL ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D463;MATHEMATICAL ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D464;MATHEMATICAL ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D465;MATHEMATICAL ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D466;MATHEMATICAL ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D467;MATHEMATICAL ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D468;MATHEMATICAL BOLD ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D469;MATHEMATICAL BOLD ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D46A;MATHEMATICAL BOLD ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D46B;MATHEMATICAL BOLD ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D46C;MATHEMATICAL BOLD ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D46D;MATHEMATICAL BOLD ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D46E;MATHEMATICAL BOLD ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D46F;MATHEMATICAL BOLD ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D470;MATHEMATICAL BOLD ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D471;MATHEMATICAL BOLD ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D472;MATHEMATICAL BOLD ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D473;MATHEMATICAL BOLD ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D474;MATHEMATICAL BOLD ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D475;MATHEMATICAL BOLD ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D476;MATHEMATICAL BOLD ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D477;MATHEMATICAL BOLD ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D478;MATHEMATICAL BOLD ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D479;MATHEMATICAL BOLD ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D47A;MATHEMATICAL BOLD ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D47B;MATHEMATICAL BOLD ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D47C;MATHEMATICAL BOLD ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D47D;MATHEMATICAL BOLD ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D47E;MATHEMATICAL BOLD ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D47F;MATHEMATICAL BOLD ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D480;MATHEMATICAL BOLD ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D481;MATHEMATICAL BOLD ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D482;MATHEMATICAL BOLD ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D483;MATHEMATICAL BOLD ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D484;MATHEMATICAL BOLD ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D485;MATHEMATICAL BOLD ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D486;MATHEMATICAL BOLD ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D487;MATHEMATICAL BOLD ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D488;MATHEMATICAL BOLD ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D489;MATHEMATICAL BOLD ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D48A;MATHEMATICAL BOLD ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D48B;MATHEMATICAL BOLD ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D48C;MATHEMATICAL BOLD ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D48D;MATHEMATICAL BOLD ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D48E;MATHEMATICAL BOLD ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D48F;MATHEMATICAL BOLD ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D490;MATHEMATICAL BOLD ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D491;MATHEMATICAL BOLD ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D492;MATHEMATICAL BOLD ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D493;MATHEMATICAL BOLD ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D494;MATHEMATICAL BOLD ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D495;MATHEMATICAL BOLD ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D496;MATHEMATICAL BOLD ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D497;MATHEMATICAL BOLD ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D498;MATHEMATICAL BOLD ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D499;MATHEMATICAL BOLD ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D49A;MATHEMATICAL BOLD ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D49B;MATHEMATICAL BOLD ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D49C;MATHEMATICAL SCRIPT CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D49E;MATHEMATICAL SCRIPT CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D49F;MATHEMATICAL SCRIPT CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D4A2;MATHEMATICAL SCRIPT CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D4A5;MATHEMATICAL SCRIPT CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D4A6;MATHEMATICAL SCRIPT CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D4A9;MATHEMATICAL SCRIPT CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D4AA;MATHEMATICAL SCRIPT CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D4AB;MATHEMATICAL SCRIPT CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D4AC;MATHEMATICAL SCRIPT CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D4AE;MATHEMATICAL SCRIPT CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D4AF;MATHEMATICAL SCRIPT CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D4B0;MATHEMATICAL SCRIPT CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D4B1;MATHEMATICAL SCRIPT CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D4B2;MATHEMATICAL SCRIPT CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D4B3;MATHEMATICAL SCRIPT CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D4B4;MATHEMATICAL SCRIPT CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D4B5;MATHEMATICAL SCRIPT CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D4B6;MATHEMATICAL SCRIPT SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D4B7;MATHEMATICAL SCRIPT SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D4B8;MATHEMATICAL SCRIPT SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D4B9;MATHEMATICAL SCRIPT SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D4BB;MATHEMATICAL SCRIPT SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D4BD;MATHEMATICAL SCRIPT SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D4BE;MATHEMATICAL SCRIPT SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D4BF;MATHEMATICAL SCRIPT SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D4C0;MATHEMATICAL SCRIPT SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D4C1;MATHEMATICAL SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D4C2;MATHEMATICAL SCRIPT SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D4C3;MATHEMATICAL SCRIPT SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D4C5;MATHEMATICAL SCRIPT SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D4C6;MATHEMATICAL SCRIPT SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D4C7;MATHEMATICAL SCRIPT SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D4C8;MATHEMATICAL SCRIPT SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D4C9;MATHEMATICAL SCRIPT SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D4CA;MATHEMATICAL SCRIPT SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D4CB;MATHEMATICAL SCRIPT SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D4CC;MATHEMATICAL SCRIPT SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D4CD;MATHEMATICAL SCRIPT SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D4CE;MATHEMATICAL SCRIPT SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D4CF;MATHEMATICAL SCRIPT SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D4D0;MATHEMATICAL BOLD SCRIPT CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D4D1;MATHEMATICAL BOLD SCRIPT CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D4D2;MATHEMATICAL BOLD SCRIPT CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D4D3;MATHEMATICAL BOLD SCRIPT CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D4D4;MATHEMATICAL BOLD SCRIPT CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D4D5;MATHEMATICAL BOLD SCRIPT CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D4D6;MATHEMATICAL BOLD SCRIPT CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D4D7;MATHEMATICAL BOLD SCRIPT CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D4D8;MATHEMATICAL BOLD SCRIPT CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D4D9;MATHEMATICAL BOLD SCRIPT CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D4DA;MATHEMATICAL BOLD SCRIPT CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D4DB;MATHEMATICAL BOLD SCRIPT CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D4DC;MATHEMATICAL BOLD SCRIPT CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D4DD;MATHEMATICAL BOLD SCRIPT CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D4DE;MATHEMATICAL BOLD SCRIPT CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D4DF;MATHEMATICAL BOLD SCRIPT CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D4E0;MATHEMATICAL BOLD SCRIPT CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D4E1;MATHEMATICAL BOLD SCRIPT CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D4E2;MATHEMATICAL BOLD SCRIPT CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D4E3;MATHEMATICAL BOLD SCRIPT CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D4E4;MATHEMATICAL BOLD SCRIPT CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D4E5;MATHEMATICAL BOLD SCRIPT CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D4E6;MATHEMATICAL BOLD SCRIPT CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D4E7;MATHEMATICAL BOLD SCRIPT CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D4E8;MATHEMATICAL BOLD SCRIPT CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D4E9;MATHEMATICAL BOLD SCRIPT CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D4EA;MATHEMATICAL BOLD SCRIPT SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D4EB;MATHEMATICAL BOLD SCRIPT SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D4EC;MATHEMATICAL BOLD SCRIPT SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D4ED;MATHEMATICAL BOLD SCRIPT SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D4EE;MATHEMATICAL BOLD SCRIPT SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D4EF;MATHEMATICAL BOLD SCRIPT SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D4F0;MATHEMATICAL BOLD SCRIPT SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D4F1;MATHEMATICAL BOLD SCRIPT SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D4F2;MATHEMATICAL BOLD SCRIPT SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D4F3;MATHEMATICAL BOLD SCRIPT SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D4F4;MATHEMATICAL BOLD SCRIPT SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D4F5;MATHEMATICAL BOLD SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D4F6;MATHEMATICAL BOLD SCRIPT SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D4F7;MATHEMATICAL BOLD SCRIPT SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D4F8;MATHEMATICAL BOLD SCRIPT SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D4F9;MATHEMATICAL BOLD SCRIPT SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D4FA;MATHEMATICAL BOLD SCRIPT SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D4FB;MATHEMATICAL BOLD SCRIPT SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D4FC;MATHEMATICAL BOLD SCRIPT SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D4FD;MATHEMATICAL BOLD SCRIPT SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D4FE;MATHEMATICAL BOLD SCRIPT SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D4FF;MATHEMATICAL BOLD SCRIPT SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D500;MATHEMATICAL BOLD SCRIPT SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D501;MATHEMATICAL BOLD SCRIPT SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D502;MATHEMATICAL BOLD SCRIPT SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D503;MATHEMATICAL BOLD SCRIPT SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D504;MATHEMATICAL FRAKTUR CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D505;MATHEMATICAL FRAKTUR CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D507;MATHEMATICAL FRAKTUR CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D508;MATHEMATICAL FRAKTUR CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D509;MATHEMATICAL FRAKTUR CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D50A;MATHEMATICAL FRAKTUR CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D50D;MATHEMATICAL FRAKTUR CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D50E;MATHEMATICAL FRAKTUR CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D50F;MATHEMATICAL FRAKTUR CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D510;MATHEMATICAL FRAKTUR CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D511;MATHEMATICAL FRAKTUR CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D512;MATHEMATICAL FRAKTUR CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D513;MATHEMATICAL FRAKTUR CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D514;MATHEMATICAL FRAKTUR CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D516;MATHEMATICAL FRAKTUR CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D517;MATHEMATICAL FRAKTUR CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D518;MATHEMATICAL FRAKTUR CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D519;MATHEMATICAL FRAKTUR CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D51A;MATHEMATICAL FRAKTUR CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D51B;MATHEMATICAL FRAKTUR CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D51C;MATHEMATICAL FRAKTUR CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D51E;MATHEMATICAL FRAKTUR SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D51F;MATHEMATICAL FRAKTUR SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D520;MATHEMATICAL FRAKTUR SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D521;MATHEMATICAL FRAKTUR SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D522;MATHEMATICAL FRAKTUR SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D523;MATHEMATICAL FRAKTUR SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D524;MATHEMATICAL FRAKTUR SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D525;MATHEMATICAL FRAKTUR SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D526;MATHEMATICAL FRAKTUR SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D527;MATHEMATICAL FRAKTUR SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D528;MATHEMATICAL FRAKTUR SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D529;MATHEMATICAL FRAKTUR SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D52A;MATHEMATICAL FRAKTUR SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D52B;MATHEMATICAL FRAKTUR SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D52C;MATHEMATICAL FRAKTUR SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D52D;MATHEMATICAL FRAKTUR SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D52E;MATHEMATICAL FRAKTUR SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D52F;MATHEMATICAL FRAKTUR SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D530;MATHEMATICAL FRAKTUR SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D531;MATHEMATICAL FRAKTUR SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D532;MATHEMATICAL FRAKTUR SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D533;MATHEMATICAL FRAKTUR SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D534;MATHEMATICAL FRAKTUR SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D535;MATHEMATICAL FRAKTUR SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D536;MATHEMATICAL FRAKTUR SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D537;MATHEMATICAL FRAKTUR SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D538;MATHEMATICAL DOUBLE-STRUCK CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D539;MATHEMATICAL DOUBLE-STRUCK CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D53B;MATHEMATICAL DOUBLE-STRUCK CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D53C;MATHEMATICAL DOUBLE-STRUCK CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D53D;MATHEMATICAL DOUBLE-STRUCK CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D53E;MATHEMATICAL DOUBLE-STRUCK CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D540;MATHEMATICAL DOUBLE-STRUCK CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D541;MATHEMATICAL DOUBLE-STRUCK CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D542;MATHEMATICAL DOUBLE-STRUCK CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D543;MATHEMATICAL DOUBLE-STRUCK CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D544;MATHEMATICAL DOUBLE-STRUCK CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D546;MATHEMATICAL DOUBLE-STRUCK CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D54A;MATHEMATICAL DOUBLE-STRUCK CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D54B;MATHEMATICAL DOUBLE-STRUCK CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D54C;MATHEMATICAL DOUBLE-STRUCK CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D54D;MATHEMATICAL DOUBLE-STRUCK CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D54E;MATHEMATICAL DOUBLE-STRUCK CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D54F;MATHEMATICAL DOUBLE-STRUCK CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D550;MATHEMATICAL DOUBLE-STRUCK CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D552;MATHEMATICAL DOUBLE-STRUCK SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D553;MATHEMATICAL DOUBLE-STRUCK SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D554;MATHEMATICAL DOUBLE-STRUCK SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D555;MATHEMATICAL DOUBLE-STRUCK SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D556;MATHEMATICAL DOUBLE-STRUCK SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D557;MATHEMATICAL DOUBLE-STRUCK SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D558;MATHEMATICAL DOUBLE-STRUCK SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D559;MATHEMATICAL DOUBLE-STRUCK SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D55A;MATHEMATICAL DOUBLE-STRUCK SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D55B;MATHEMATICAL DOUBLE-STRUCK SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D55C;MATHEMATICAL DOUBLE-STRUCK SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D55D;MATHEMATICAL DOUBLE-STRUCK SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D55E;MATHEMATICAL DOUBLE-STRUCK SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D55F;MATHEMATICAL DOUBLE-STRUCK SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D560;MATHEMATICAL DOUBLE-STRUCK SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D561;MATHEMATICAL DOUBLE-STRUCK SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D562;MATHEMATICAL DOUBLE-STRUCK SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D563;MATHEMATICAL DOUBLE-STRUCK SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D564;MATHEMATICAL DOUBLE-STRUCK SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D565;MATHEMATICAL DOUBLE-STRUCK SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D566;MATHEMATICAL DOUBLE-STRUCK SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D567;MATHEMATICAL DOUBLE-STRUCK SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D568;MATHEMATICAL DOUBLE-STRUCK SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D569;MATHEMATICAL DOUBLE-STRUCK SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D56A;MATHEMATICAL DOUBLE-STRUCK SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D56B;MATHEMATICAL DOUBLE-STRUCK SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D56C;MATHEMATICAL BOLD FRAKTUR CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D56D;MATHEMATICAL BOLD FRAKTUR CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D56E;MATHEMATICAL BOLD FRAKTUR CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D56F;MATHEMATICAL BOLD FRAKTUR CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D570;MATHEMATICAL BOLD FRAKTUR CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D571;MATHEMATICAL BOLD FRAKTUR CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D572;MATHEMATICAL BOLD FRAKTUR CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D573;MATHEMATICAL BOLD FRAKTUR CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D574;MATHEMATICAL BOLD FRAKTUR CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D575;MATHEMATICAL BOLD FRAKTUR CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D576;MATHEMATICAL BOLD FRAKTUR CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D577;MATHEMATICAL BOLD FRAKTUR CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D578;MATHEMATICAL BOLD FRAKTUR CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D579;MATHEMATICAL BOLD FRAKTUR CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D57A;MATHEMATICAL BOLD FRAKTUR CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D57B;MATHEMATICAL BOLD FRAKTUR CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D57C;MATHEMATICAL BOLD FRAKTUR CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D57D;MATHEMATICAL BOLD FRAKTUR CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D57E;MATHEMATICAL BOLD FRAKTUR CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D57F;MATHEMATICAL BOLD FRAKTUR CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D580;MATHEMATICAL BOLD FRAKTUR CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D581;MATHEMATICAL BOLD FRAKTUR CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D582;MATHEMATICAL BOLD FRAKTUR CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D583;MATHEMATICAL BOLD FRAKTUR CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D584;MATHEMATICAL BOLD FRAKTUR CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D585;MATHEMATICAL BOLD FRAKTUR CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D586;MATHEMATICAL BOLD FRAKTUR SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D587;MATHEMATICAL BOLD FRAKTUR SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D588;MATHEMATICAL BOLD FRAKTUR SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D589;MATHEMATICAL BOLD FRAKTUR SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D58A;MATHEMATICAL BOLD FRAKTUR SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D58B;MATHEMATICAL BOLD FRAKTUR SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D58C;MATHEMATICAL BOLD FRAKTUR SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D58D;MATHEMATICAL BOLD FRAKTUR SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D58E;MATHEMATICAL BOLD FRAKTUR SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D58F;MATHEMATICAL BOLD FRAKTUR SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D590;MATHEMATICAL BOLD FRAKTUR SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D591;MATHEMATICAL BOLD FRAKTUR SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D592;MATHEMATICAL BOLD FRAKTUR SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D593;MATHEMATICAL BOLD FRAKTUR SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D594;MATHEMATICAL BOLD FRAKTUR SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D595;MATHEMATICAL BOLD FRAKTUR SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D596;MATHEMATICAL BOLD FRAKTUR SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D597;MATHEMATICAL BOLD FRAKTUR SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D598;MATHEMATICAL BOLD FRAKTUR SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D599;MATHEMATICAL BOLD FRAKTUR SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D59A;MATHEMATICAL BOLD FRAKTUR SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D59B;MATHEMATICAL BOLD FRAKTUR SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D59C;MATHEMATICAL BOLD FRAKTUR SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D59D;MATHEMATICAL BOLD FRAKTUR SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D59E;MATHEMATICAL BOLD FRAKTUR SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D59F;MATHEMATICAL BOLD FRAKTUR SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D5A0;MATHEMATICAL SANS-SERIF CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D5A1;MATHEMATICAL SANS-SERIF CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D5A2;MATHEMATICAL SANS-SERIF CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D5A3;MATHEMATICAL SANS-SERIF CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D5A4;MATHEMATICAL SANS-SERIF CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D5A5;MATHEMATICAL SANS-SERIF CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D5A6;MATHEMATICAL SANS-SERIF CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D5A7;MATHEMATICAL SANS-SERIF CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D5A8;MATHEMATICAL SANS-SERIF CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D5A9;MATHEMATICAL SANS-SERIF CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D5AA;MATHEMATICAL SANS-SERIF CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D5AB;MATHEMATICAL SANS-SERIF CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D5AC;MATHEMATICAL SANS-SERIF CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D5AD;MATHEMATICAL SANS-SERIF CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D5AE;MATHEMATICAL SANS-SERIF CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D5AF;MATHEMATICAL SANS-SERIF CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D5B0;MATHEMATICAL SANS-SERIF CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D5B1;MATHEMATICAL SANS-SERIF CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D5B2;MATHEMATICAL SANS-SERIF CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D5B3;MATHEMATICAL SANS-SERIF CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D5B4;MATHEMATICAL SANS-SERIF CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D5B5;MATHEMATICAL SANS-SERIF CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D5B6;MATHEMATICAL SANS-SERIF CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D5B7;MATHEMATICAL SANS-SERIF CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D5B8;MATHEMATICAL SANS-SERIF CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D5B9;MATHEMATICAL SANS-SERIF CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D5BA;MATHEMATICAL SANS-SERIF SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D5BB;MATHEMATICAL SANS-SERIF SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D5BC;MATHEMATICAL SANS-SERIF SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D5BD;MATHEMATICAL SANS-SERIF SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D5BE;MATHEMATICAL SANS-SERIF SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D5BF;MATHEMATICAL SANS-SERIF SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D5C0;MATHEMATICAL SANS-SERIF SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D5C1;MATHEMATICAL SANS-SERIF SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D5C2;MATHEMATICAL SANS-SERIF SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D5C3;MATHEMATICAL SANS-SERIF SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D5C4;MATHEMATICAL SANS-SERIF SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D5C5;MATHEMATICAL SANS-SERIF SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D5C6;MATHEMATICAL SANS-SERIF SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D5C7;MATHEMATICAL SANS-SERIF SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D5C8;MATHEMATICAL SANS-SERIF SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D5C9;MATHEMATICAL SANS-SERIF SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D5CA;MATHEMATICAL SANS-SERIF SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D5CB;MATHEMATICAL SANS-SERIF SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D5CC;MATHEMATICAL SANS-SERIF SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D5CD;MATHEMATICAL SANS-SERIF SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D5CE;MATHEMATICAL SANS-SERIF SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D5CF;MATHEMATICAL SANS-SERIF SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D5D0;MATHEMATICAL SANS-SERIF SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D5D1;MATHEMATICAL SANS-SERIF SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D5D2;MATHEMATICAL SANS-SERIF SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D5D3;MATHEMATICAL SANS-SERIF SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D5D4;MATHEMATICAL SANS-SERIF BOLD CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D5D5;MATHEMATICAL SANS-SERIF BOLD CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D5D6;MATHEMATICAL SANS-SERIF BOLD CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D5D7;MATHEMATICAL SANS-SERIF BOLD CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D5D8;MATHEMATICAL SANS-SERIF BOLD CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D5D9;MATHEMATICAL SANS-SERIF BOLD CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D5DA;MATHEMATICAL SANS-SERIF BOLD CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D5DB;MATHEMATICAL SANS-SERIF BOLD CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D5DC;MATHEMATICAL SANS-SERIF BOLD CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D5DD;MATHEMATICAL SANS-SERIF BOLD CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D5DE;MATHEMATICAL SANS-SERIF BOLD CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D5DF;MATHEMATICAL SANS-SERIF BOLD CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D5E0;MATHEMATICAL SANS-SERIF BOLD CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D5E1;MATHEMATICAL SANS-SERIF BOLD CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D5E2;MATHEMATICAL SANS-SERIF BOLD CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D5E3;MATHEMATICAL SANS-SERIF BOLD CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D5E4;MATHEMATICAL SANS-SERIF BOLD CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D5E5;MATHEMATICAL SANS-SERIF BOLD CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D5E6;MATHEMATICAL SANS-SERIF BOLD CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D5E7;MATHEMATICAL SANS-SERIF BOLD CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D5E8;MATHEMATICAL SANS-SERIF BOLD CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D5E9;MATHEMATICAL SANS-SERIF BOLD CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D5EA;MATHEMATICAL SANS-SERIF BOLD CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D5EB;MATHEMATICAL SANS-SERIF BOLD CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D5EC;MATHEMATICAL SANS-SERIF BOLD CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D5ED;MATHEMATICAL SANS-SERIF BOLD CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D5EE;MATHEMATICAL SANS-SERIF BOLD SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D5EF;MATHEMATICAL SANS-SERIF BOLD SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D5F0;MATHEMATICAL SANS-SERIF BOLD SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D5F1;MATHEMATICAL SANS-SERIF BOLD SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D5F2;MATHEMATICAL SANS-SERIF BOLD SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D5F3;MATHEMATICAL SANS-SERIF BOLD SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D5F4;MATHEMATICAL SANS-SERIF BOLD SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D5F5;MATHEMATICAL SANS-SERIF BOLD SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D5F6;MATHEMATICAL SANS-SERIF BOLD SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D5F7;MATHEMATICAL SANS-SERIF BOLD SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D5F8;MATHEMATICAL SANS-SERIF BOLD SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D5F9;MATHEMATICAL SANS-SERIF BOLD SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D5FA;MATHEMATICAL SANS-SERIF BOLD SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D5FB;MATHEMATICAL SANS-SERIF BOLD SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D5FC;MATHEMATICAL SANS-SERIF BOLD SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D5FD;MATHEMATICAL SANS-SERIF BOLD SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D5FE;MATHEMATICAL SANS-SERIF BOLD SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D5FF;MATHEMATICAL SANS-SERIF BOLD SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D600;MATHEMATICAL SANS-SERIF BOLD SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D601;MATHEMATICAL SANS-SERIF BOLD SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D602;MATHEMATICAL SANS-SERIF BOLD SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D603;MATHEMATICAL SANS-SERIF BOLD SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D604;MATHEMATICAL SANS-SERIF BOLD SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D605;MATHEMATICAL SANS-SERIF BOLD SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D606;MATHEMATICAL SANS-SERIF BOLD SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D607;MATHEMATICAL SANS-SERIF BOLD SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D608;MATHEMATICAL SANS-SERIF ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D609;MATHEMATICAL SANS-SERIF ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D60A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D60B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D60C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D60D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D60E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D60F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D610;MATHEMATICAL SANS-SERIF ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D611;MATHEMATICAL SANS-SERIF ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D612;MATHEMATICAL SANS-SERIF ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D613;MATHEMATICAL SANS-SERIF ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D614;MATHEMATICAL SANS-SERIF ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D615;MATHEMATICAL SANS-SERIF ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D616;MATHEMATICAL SANS-SERIF ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D617;MATHEMATICAL SANS-SERIF ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D618;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D619;MATHEMATICAL SANS-SERIF ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D61A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D61B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D61C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D61D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D61E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D61F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D620;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D621;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D622;MATHEMATICAL SANS-SERIF ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D623;MATHEMATICAL SANS-SERIF ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D624;MATHEMATICAL SANS-SERIF ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D625;MATHEMATICAL SANS-SERIF ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D626;MATHEMATICAL SANS-SERIF ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D627;MATHEMATICAL SANS-SERIF ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D628;MATHEMATICAL SANS-SERIF ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D629;MATHEMATICAL SANS-SERIF ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D62A;MATHEMATICAL SANS-SERIF ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D62B;MATHEMATICAL SANS-SERIF ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D62C;MATHEMATICAL SANS-SERIF ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D62D;MATHEMATICAL SANS-SERIF ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D62E;MATHEMATICAL SANS-SERIF ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D62F;MATHEMATICAL SANS-SERIF ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D630;MATHEMATICAL SANS-SERIF ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D631;MATHEMATICAL SANS-SERIF ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D632;MATHEMATICAL SANS-SERIF ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D633;MATHEMATICAL SANS-SERIF ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D634;MATHEMATICAL SANS-SERIF ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D635;MATHEMATICAL SANS-SERIF ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D636;MATHEMATICAL SANS-SERIF ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D637;MATHEMATICAL SANS-SERIF ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D638;MATHEMATICAL SANS-SERIF ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D639;MATHEMATICAL SANS-SERIF ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D63A;MATHEMATICAL SANS-SERIF ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D63B;MATHEMATICAL SANS-SERIF ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D63C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D63D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D63E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D63F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D640;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D641;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D642;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D643;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D644;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D645;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D646;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D647;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D648;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D649;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D64A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D64B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D64C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D64D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D64E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D64F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D650;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D651;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D652;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D653;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D654;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D655;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D656;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D657;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D658;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D659;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D65A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D65B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D65C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D65D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D65E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D65F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D660;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D661;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D662;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D663;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D664;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D665;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D666;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D667;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D668;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D669;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D66A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D66B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D66C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D66D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D66E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D66F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D670;MATHEMATICAL MONOSPACE CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D671;MATHEMATICAL MONOSPACE CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D672;MATHEMATICAL MONOSPACE CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D673;MATHEMATICAL MONOSPACE CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D674;MATHEMATICAL MONOSPACE CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D675;MATHEMATICAL MONOSPACE CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D676;MATHEMATICAL MONOSPACE CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D677;MATHEMATICAL MONOSPACE CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D678;MATHEMATICAL MONOSPACE CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D679;MATHEMATICAL MONOSPACE CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D67A;MATHEMATICAL MONOSPACE CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D67B;MATHEMATICAL MONOSPACE CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D67C;MATHEMATICAL MONOSPACE CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D67D;MATHEMATICAL MONOSPACE CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D67E;MATHEMATICAL MONOSPACE CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D67F;MATHEMATICAL MONOSPACE CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D680;MATHEMATICAL MONOSPACE CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D681;MATHEMATICAL MONOSPACE CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D682;MATHEMATICAL MONOSPACE CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D683;MATHEMATICAL MONOSPACE CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D684;MATHEMATICAL MONOSPACE CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D685;MATHEMATICAL MONOSPACE CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D686;MATHEMATICAL MONOSPACE CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D687;MATHEMATICAL MONOSPACE CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D688;MATHEMATICAL MONOSPACE CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D689;MATHEMATICAL MONOSPACE CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D68A;MATHEMATICAL MONOSPACE SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D68B;MATHEMATICAL MONOSPACE SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D68C;MATHEMATICAL MONOSPACE SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D68D;MATHEMATICAL MONOSPACE SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D68E;MATHEMATICAL MONOSPACE SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D68F;MATHEMATICAL MONOSPACE SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D690;MATHEMATICAL MONOSPACE SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D691;MATHEMATICAL MONOSPACE SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D692;MATHEMATICAL MONOSPACE SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D693;MATHEMATICAL MONOSPACE SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D694;MATHEMATICAL MONOSPACE SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D695;MATHEMATICAL MONOSPACE SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D696;MATHEMATICAL MONOSPACE SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D697;MATHEMATICAL MONOSPACE SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D698;MATHEMATICAL MONOSPACE SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D699;MATHEMATICAL MONOSPACE SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D69A;MATHEMATICAL MONOSPACE SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D69B;MATHEMATICAL MONOSPACE SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D69C;MATHEMATICAL MONOSPACE SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D69D;MATHEMATICAL MONOSPACE SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D69E;MATHEMATICAL MONOSPACE SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D69F;MATHEMATICAL MONOSPACE SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D6A0;MATHEMATICAL MONOSPACE SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D6A1;MATHEMATICAL MONOSPACE SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D6A2;MATHEMATICAL MONOSPACE SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D6A3;MATHEMATICAL MONOSPACE SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D6A4;MATHEMATICAL ITALIC SMALL DOTLESS I;Ll;0;L; 0131;;;;N;;;;; +1D6A5;MATHEMATICAL ITALIC SMALL DOTLESS J;Ll;0;L; 0237;;;;N;;;;; +1D6A8;MATHEMATICAL BOLD CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D6A9;MATHEMATICAL BOLD CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D6AA;MATHEMATICAL BOLD CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D6AB;MATHEMATICAL BOLD CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D6AC;MATHEMATICAL BOLD CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D6AD;MATHEMATICAL BOLD CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D6AE;MATHEMATICAL BOLD CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D6AF;MATHEMATICAL BOLD CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D6B0;MATHEMATICAL BOLD CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D6B1;MATHEMATICAL BOLD CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D6B2;MATHEMATICAL BOLD CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D6B3;MATHEMATICAL BOLD CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D6B4;MATHEMATICAL BOLD CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D6B5;MATHEMATICAL BOLD CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D6B6;MATHEMATICAL BOLD CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D6B7;MATHEMATICAL BOLD CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D6B8;MATHEMATICAL BOLD CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D6B9;MATHEMATICAL BOLD CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D6BA;MATHEMATICAL BOLD CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D6BB;MATHEMATICAL BOLD CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D6BC;MATHEMATICAL BOLD CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D6BD;MATHEMATICAL BOLD CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D6BE;MATHEMATICAL BOLD CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D6BF;MATHEMATICAL BOLD CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D6C0;MATHEMATICAL BOLD CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D6C1;MATHEMATICAL BOLD NABLA;Sm;0;L; 2207;;;;N;;;;; +1D6C2;MATHEMATICAL BOLD SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D6C3;MATHEMATICAL BOLD SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D6C4;MATHEMATICAL BOLD SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D6C5;MATHEMATICAL BOLD SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D6C6;MATHEMATICAL BOLD SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D6C7;MATHEMATICAL BOLD SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D6C8;MATHEMATICAL BOLD SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D6C9;MATHEMATICAL BOLD SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D6CA;MATHEMATICAL BOLD SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D6CB;MATHEMATICAL BOLD SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D6CC;MATHEMATICAL BOLD SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D6CD;MATHEMATICAL BOLD SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D6CE;MATHEMATICAL BOLD SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D6CF;MATHEMATICAL BOLD SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D6D0;MATHEMATICAL BOLD SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D6D1;MATHEMATICAL BOLD SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D6D2;MATHEMATICAL BOLD SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D6D3;MATHEMATICAL BOLD SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D6D4;MATHEMATICAL BOLD SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D6D5;MATHEMATICAL BOLD SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D6D6;MATHEMATICAL BOLD SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D6D7;MATHEMATICAL BOLD SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D6D8;MATHEMATICAL BOLD SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D6D9;MATHEMATICAL BOLD SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D6DA;MATHEMATICAL BOLD SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D6DB;MATHEMATICAL BOLD PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; +1D6DC;MATHEMATICAL BOLD EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D6DD;MATHEMATICAL BOLD THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D6DE;MATHEMATICAL BOLD KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D6DF;MATHEMATICAL BOLD PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D6E0;MATHEMATICAL BOLD RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D6E1;MATHEMATICAL BOLD PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D6E2;MATHEMATICAL ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D6E3;MATHEMATICAL ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D6E4;MATHEMATICAL ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D6E5;MATHEMATICAL ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D6E6;MATHEMATICAL ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D6E7;MATHEMATICAL ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D6E8;MATHEMATICAL ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D6E9;MATHEMATICAL ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D6EA;MATHEMATICAL ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D6EB;MATHEMATICAL ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D6EC;MATHEMATICAL ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D6ED;MATHEMATICAL ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D6EE;MATHEMATICAL ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D6EF;MATHEMATICAL ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D6F0;MATHEMATICAL ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D6F1;MATHEMATICAL ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D6F2;MATHEMATICAL ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D6F3;MATHEMATICAL ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D6F4;MATHEMATICAL ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D6F5;MATHEMATICAL ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D6F6;MATHEMATICAL ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D6F7;MATHEMATICAL ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D6F8;MATHEMATICAL ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D6F9;MATHEMATICAL ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D6FA;MATHEMATICAL ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D6FB;MATHEMATICAL ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; +1D6FC;MATHEMATICAL ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D6FD;MATHEMATICAL ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D6FE;MATHEMATICAL ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D6FF;MATHEMATICAL ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D700;MATHEMATICAL ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D701;MATHEMATICAL ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D702;MATHEMATICAL ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D703;MATHEMATICAL ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D704;MATHEMATICAL ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D705;MATHEMATICAL ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D706;MATHEMATICAL ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D707;MATHEMATICAL ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D708;MATHEMATICAL ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D709;MATHEMATICAL ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D70A;MATHEMATICAL ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D70B;MATHEMATICAL ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D70C;MATHEMATICAL ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D70D;MATHEMATICAL ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D70E;MATHEMATICAL ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D70F;MATHEMATICAL ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D710;MATHEMATICAL ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D711;MATHEMATICAL ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D712;MATHEMATICAL ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D713;MATHEMATICAL ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D714;MATHEMATICAL ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D715;MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; +1D716;MATHEMATICAL ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D717;MATHEMATICAL ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D718;MATHEMATICAL ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D719;MATHEMATICAL ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D71A;MATHEMATICAL ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D71B;MATHEMATICAL ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D71C;MATHEMATICAL BOLD ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D71D;MATHEMATICAL BOLD ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D71E;MATHEMATICAL BOLD ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D71F;MATHEMATICAL BOLD ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D720;MATHEMATICAL BOLD ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D721;MATHEMATICAL BOLD ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D722;MATHEMATICAL BOLD ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D723;MATHEMATICAL BOLD ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D724;MATHEMATICAL BOLD ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D725;MATHEMATICAL BOLD ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D726;MATHEMATICAL BOLD ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D727;MATHEMATICAL BOLD ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D728;MATHEMATICAL BOLD ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D729;MATHEMATICAL BOLD ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D72A;MATHEMATICAL BOLD ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D72B;MATHEMATICAL BOLD ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D72C;MATHEMATICAL BOLD ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D72D;MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D72E;MATHEMATICAL BOLD ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D72F;MATHEMATICAL BOLD ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D730;MATHEMATICAL BOLD ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D731;MATHEMATICAL BOLD ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D732;MATHEMATICAL BOLD ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D733;MATHEMATICAL BOLD ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D734;MATHEMATICAL BOLD ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D735;MATHEMATICAL BOLD ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; +1D736;MATHEMATICAL BOLD ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D737;MATHEMATICAL BOLD ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D738;MATHEMATICAL BOLD ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D739;MATHEMATICAL BOLD ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D73A;MATHEMATICAL BOLD ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D73B;MATHEMATICAL BOLD ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D73C;MATHEMATICAL BOLD ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D73D;MATHEMATICAL BOLD ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D73E;MATHEMATICAL BOLD ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D73F;MATHEMATICAL BOLD ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D740;MATHEMATICAL BOLD ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D741;MATHEMATICAL BOLD ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D742;MATHEMATICAL BOLD ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D743;MATHEMATICAL BOLD ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D744;MATHEMATICAL BOLD ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D745;MATHEMATICAL BOLD ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D746;MATHEMATICAL BOLD ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D747;MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D748;MATHEMATICAL BOLD ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D749;MATHEMATICAL BOLD ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D74A;MATHEMATICAL BOLD ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D74B;MATHEMATICAL BOLD ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D74C;MATHEMATICAL BOLD ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D74D;MATHEMATICAL BOLD ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D74E;MATHEMATICAL BOLD ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D74F;MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; +1D750;MATHEMATICAL BOLD ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D751;MATHEMATICAL BOLD ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D752;MATHEMATICAL BOLD ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D753;MATHEMATICAL BOLD ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D754;MATHEMATICAL BOLD ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D755;MATHEMATICAL BOLD ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D756;MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D757;MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D758;MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D759;MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D75A;MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D75B;MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D75C;MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D75D;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D75E;MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D75F;MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D760;MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D761;MATHEMATICAL SANS-SERIF BOLD CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D762;MATHEMATICAL SANS-SERIF BOLD CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D763;MATHEMATICAL SANS-SERIF BOLD CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D764;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D765;MATHEMATICAL SANS-SERIF BOLD CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D766;MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D767;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D768;MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D769;MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D76A;MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D76B;MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D76C;MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D76D;MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D76E;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D76F;MATHEMATICAL SANS-SERIF BOLD NABLA;Sm;0;L; 2207;;;;N;;;;; +1D770;MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D771;MATHEMATICAL SANS-SERIF BOLD SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D772;MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D773;MATHEMATICAL SANS-SERIF BOLD SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D774;MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D775;MATHEMATICAL SANS-SERIF BOLD SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D776;MATHEMATICAL SANS-SERIF BOLD SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D777;MATHEMATICAL SANS-SERIF BOLD SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D778;MATHEMATICAL SANS-SERIF BOLD SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D779;MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D77A;MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D77B;MATHEMATICAL SANS-SERIF BOLD SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D77C;MATHEMATICAL SANS-SERIF BOLD SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D77D;MATHEMATICAL SANS-SERIF BOLD SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D77E;MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D77F;MATHEMATICAL SANS-SERIF BOLD SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D780;MATHEMATICAL SANS-SERIF BOLD SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D781;MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D782;MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D783;MATHEMATICAL SANS-SERIF BOLD SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D784;MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D785;MATHEMATICAL SANS-SERIF BOLD SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D786;MATHEMATICAL SANS-SERIF BOLD SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D787;MATHEMATICAL SANS-SERIF BOLD SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D788;MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D789;MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; +1D78A;MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D78B;MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D78C;MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D78D;MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D78E;MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D78F;MATHEMATICAL SANS-SERIF BOLD PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D790;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D791;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D792;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D793;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D794;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D795;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D796;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D797;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D798;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D799;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D79A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D79B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D79C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D79D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D79E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D79F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D7A0;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D7A1;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D7A2;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D7A3;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D7A4;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D7A5;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D7A6;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D7A7;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D7A8;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D7A9;MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; +1D7AA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D7AB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D7AC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D7AD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D7AE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D7AF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D7B0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D7B1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D7B2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D7B3;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D7B4;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D7B5;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D7B6;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D7B7;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D7B8;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D7B9;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D7BA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D7BB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D7BC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D7BD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D7BE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D7BF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D7C0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D7C1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D7C2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D7C3;MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; +1D7C4;MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D7C5;MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D7C6;MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D7C7;MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D7C8;MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D7C9;MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D7CA;MATHEMATICAL BOLD CAPITAL DIGAMMA;Lu;0;L; 03DC;;;;N;;;;; +1D7CB;MATHEMATICAL BOLD SMALL DIGAMMA;Ll;0;L; 03DD;;;;N;;;;; +1D7CE;MATHEMATICAL BOLD DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7CF;MATHEMATICAL BOLD DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7D0;MATHEMATICAL BOLD DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7D1;MATHEMATICAL BOLD DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7D2;MATHEMATICAL BOLD DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7D3;MATHEMATICAL BOLD DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7D4;MATHEMATICAL BOLD DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7D5;MATHEMATICAL BOLD DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7D6;MATHEMATICAL BOLD DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7D7;MATHEMATICAL BOLD DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7D8;MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7D9;MATHEMATICAL DOUBLE-STRUCK DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7DA;MATHEMATICAL DOUBLE-STRUCK DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7DB;MATHEMATICAL DOUBLE-STRUCK DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7DC;MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7DD;MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7DE;MATHEMATICAL DOUBLE-STRUCK DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7DF;MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7E0;MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7E1;MATHEMATICAL DOUBLE-STRUCK DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7E2;MATHEMATICAL SANS-SERIF DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7E3;MATHEMATICAL SANS-SERIF DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7E4;MATHEMATICAL SANS-SERIF DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7E5;MATHEMATICAL SANS-SERIF DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7E6;MATHEMATICAL SANS-SERIF DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7E7;MATHEMATICAL SANS-SERIF DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7E8;MATHEMATICAL SANS-SERIF DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7E9;MATHEMATICAL SANS-SERIF DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7EA;MATHEMATICAL SANS-SERIF DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7EB;MATHEMATICAL SANS-SERIF DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7EC;MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7ED;MATHEMATICAL SANS-SERIF BOLD DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7EE;MATHEMATICAL SANS-SERIF BOLD DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7EF;MATHEMATICAL SANS-SERIF BOLD DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7F0;MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7F1;MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7F2;MATHEMATICAL SANS-SERIF BOLD DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7F3;MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7F4;MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7F5;MATHEMATICAL SANS-SERIF BOLD DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7F6;MATHEMATICAL MONOSPACE DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7F7;MATHEMATICAL MONOSPACE DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7F8;MATHEMATICAL MONOSPACE DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7F9;MATHEMATICAL MONOSPACE DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7FA;MATHEMATICAL MONOSPACE DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7FB;MATHEMATICAL MONOSPACE DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7FC;MATHEMATICAL MONOSPACE DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7FD;MATHEMATICAL MONOSPACE DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7FE;MATHEMATICAL MONOSPACE DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7FF;MATHEMATICAL MONOSPACE DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1F000;MAHJONG TILE EAST WIND;So;0;ON;;;;;N;;;;; +1F001;MAHJONG TILE SOUTH WIND;So;0;ON;;;;;N;;;;; +1F002;MAHJONG TILE WEST WIND;So;0;ON;;;;;N;;;;; +1F003;MAHJONG TILE NORTH WIND;So;0;ON;;;;;N;;;;; +1F004;MAHJONG TILE RED DRAGON;So;0;ON;;;;;N;;;;; +1F005;MAHJONG TILE GREEN DRAGON;So;0;ON;;;;;N;;;;; +1F006;MAHJONG TILE WHITE DRAGON;So;0;ON;;;;;N;;;;; +1F007;MAHJONG TILE ONE OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F008;MAHJONG TILE TWO OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F009;MAHJONG TILE THREE OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00A;MAHJONG TILE FOUR OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00B;MAHJONG TILE FIVE OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00C;MAHJONG TILE SIX OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00D;MAHJONG TILE SEVEN OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00E;MAHJONG TILE EIGHT OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00F;MAHJONG TILE NINE OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F010;MAHJONG TILE ONE OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F011;MAHJONG TILE TWO OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F012;MAHJONG TILE THREE OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F013;MAHJONG TILE FOUR OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F014;MAHJONG TILE FIVE OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F015;MAHJONG TILE SIX OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F016;MAHJONG TILE SEVEN OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F017;MAHJONG TILE EIGHT OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F018;MAHJONG TILE NINE OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F019;MAHJONG TILE ONE OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01A;MAHJONG TILE TWO OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01B;MAHJONG TILE THREE OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01C;MAHJONG TILE FOUR OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01D;MAHJONG TILE FIVE OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01E;MAHJONG TILE SIX OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01F;MAHJONG TILE SEVEN OF CIRCLES;So;0;ON;;;;;N;;;;; +1F020;MAHJONG TILE EIGHT OF CIRCLES;So;0;ON;;;;;N;;;;; +1F021;MAHJONG TILE NINE OF CIRCLES;So;0;ON;;;;;N;;;;; +1F022;MAHJONG TILE PLUM;So;0;ON;;;;;N;;;;; +1F023;MAHJONG TILE ORCHID;So;0;ON;;;;;N;;;;; +1F024;MAHJONG TILE BAMBOO;So;0;ON;;;;;N;;;;; +1F025;MAHJONG TILE CHRYSANTHEMUM;So;0;ON;;;;;N;;;;; +1F026;MAHJONG TILE SPRING;So;0;ON;;;;;N;;;;; +1F027;MAHJONG TILE SUMMER;So;0;ON;;;;;N;;;;; +1F028;MAHJONG TILE AUTUMN;So;0;ON;;;;;N;;;;; +1F029;MAHJONG TILE WINTER;So;0;ON;;;;;N;;;;; +1F02A;MAHJONG TILE JOKER;So;0;ON;;;;;N;;;;; +1F02B;MAHJONG TILE BACK;So;0;ON;;;;;N;;;;; +1F030;DOMINO TILE HORIZONTAL BACK;So;0;ON;;;;;N;;;;; +1F031;DOMINO TILE HORIZONTAL-00-00;So;0;ON;;;;;N;;;;; +1F032;DOMINO TILE HORIZONTAL-00-01;So;0;ON;;;;;N;;;;; +1F033;DOMINO TILE HORIZONTAL-00-02;So;0;ON;;;;;N;;;;; +1F034;DOMINO TILE HORIZONTAL-00-03;So;0;ON;;;;;N;;;;; +1F035;DOMINO TILE HORIZONTAL-00-04;So;0;ON;;;;;N;;;;; +1F036;DOMINO TILE HORIZONTAL-00-05;So;0;ON;;;;;N;;;;; +1F037;DOMINO TILE HORIZONTAL-00-06;So;0;ON;;;;;N;;;;; +1F038;DOMINO TILE HORIZONTAL-01-00;So;0;ON;;;;;N;;;;; +1F039;DOMINO TILE HORIZONTAL-01-01;So;0;ON;;;;;N;;;;; +1F03A;DOMINO TILE HORIZONTAL-01-02;So;0;ON;;;;;N;;;;; +1F03B;DOMINO TILE HORIZONTAL-01-03;So;0;ON;;;;;N;;;;; +1F03C;DOMINO TILE HORIZONTAL-01-04;So;0;ON;;;;;N;;;;; +1F03D;DOMINO TILE HORIZONTAL-01-05;So;0;ON;;;;;N;;;;; +1F03E;DOMINO TILE HORIZONTAL-01-06;So;0;ON;;;;;N;;;;; +1F03F;DOMINO TILE HORIZONTAL-02-00;So;0;ON;;;;;N;;;;; +1F040;DOMINO TILE HORIZONTAL-02-01;So;0;ON;;;;;N;;;;; +1F041;DOMINO TILE HORIZONTAL-02-02;So;0;ON;;;;;N;;;;; +1F042;DOMINO TILE HORIZONTAL-02-03;So;0;ON;;;;;N;;;;; +1F043;DOMINO TILE HORIZONTAL-02-04;So;0;ON;;;;;N;;;;; +1F044;DOMINO TILE HORIZONTAL-02-05;So;0;ON;;;;;N;;;;; +1F045;DOMINO TILE HORIZONTAL-02-06;So;0;ON;;;;;N;;;;; +1F046;DOMINO TILE HORIZONTAL-03-00;So;0;ON;;;;;N;;;;; +1F047;DOMINO TILE HORIZONTAL-03-01;So;0;ON;;;;;N;;;;; +1F048;DOMINO TILE HORIZONTAL-03-02;So;0;ON;;;;;N;;;;; +1F049;DOMINO TILE HORIZONTAL-03-03;So;0;ON;;;;;N;;;;; +1F04A;DOMINO TILE HORIZONTAL-03-04;So;0;ON;;;;;N;;;;; +1F04B;DOMINO TILE HORIZONTAL-03-05;So;0;ON;;;;;N;;;;; +1F04C;DOMINO TILE HORIZONTAL-03-06;So;0;ON;;;;;N;;;;; +1F04D;DOMINO TILE HORIZONTAL-04-00;So;0;ON;;;;;N;;;;; +1F04E;DOMINO TILE HORIZONTAL-04-01;So;0;ON;;;;;N;;;;; +1F04F;DOMINO TILE HORIZONTAL-04-02;So;0;ON;;;;;N;;;;; +1F050;DOMINO TILE HORIZONTAL-04-03;So;0;ON;;;;;N;;;;; +1F051;DOMINO TILE HORIZONTAL-04-04;So;0;ON;;;;;N;;;;; +1F052;DOMINO TILE HORIZONTAL-04-05;So;0;ON;;;;;N;;;;; +1F053;DOMINO TILE HORIZONTAL-04-06;So;0;ON;;;;;N;;;;; +1F054;DOMINO TILE HORIZONTAL-05-00;So;0;ON;;;;;N;;;;; +1F055;DOMINO TILE HORIZONTAL-05-01;So;0;ON;;;;;N;;;;; +1F056;DOMINO TILE HORIZONTAL-05-02;So;0;ON;;;;;N;;;;; +1F057;DOMINO TILE HORIZONTAL-05-03;So;0;ON;;;;;N;;;;; +1F058;DOMINO TILE HORIZONTAL-05-04;So;0;ON;;;;;N;;;;; +1F059;DOMINO TILE HORIZONTAL-05-05;So;0;ON;;;;;N;;;;; +1F05A;DOMINO TILE HORIZONTAL-05-06;So;0;ON;;;;;N;;;;; +1F05B;DOMINO TILE HORIZONTAL-06-00;So;0;ON;;;;;N;;;;; +1F05C;DOMINO TILE HORIZONTAL-06-01;So;0;ON;;;;;N;;;;; +1F05D;DOMINO TILE HORIZONTAL-06-02;So;0;ON;;;;;N;;;;; +1F05E;DOMINO TILE HORIZONTAL-06-03;So;0;ON;;;;;N;;;;; +1F05F;DOMINO TILE HORIZONTAL-06-04;So;0;ON;;;;;N;;;;; +1F060;DOMINO TILE HORIZONTAL-06-05;So;0;ON;;;;;N;;;;; +1F061;DOMINO TILE HORIZONTAL-06-06;So;0;ON;;;;;N;;;;; +1F062;DOMINO TILE VERTICAL BACK;So;0;ON;;;;;N;;;;; +1F063;DOMINO TILE VERTICAL-00-00;So;0;ON;;;;;N;;;;; +1F064;DOMINO TILE VERTICAL-00-01;So;0;ON;;;;;N;;;;; +1F065;DOMINO TILE VERTICAL-00-02;So;0;ON;;;;;N;;;;; +1F066;DOMINO TILE VERTICAL-00-03;So;0;ON;;;;;N;;;;; +1F067;DOMINO TILE VERTICAL-00-04;So;0;ON;;;;;N;;;;; +1F068;DOMINO TILE VERTICAL-00-05;So;0;ON;;;;;N;;;;; +1F069;DOMINO TILE VERTICAL-00-06;So;0;ON;;;;;N;;;;; +1F06A;DOMINO TILE VERTICAL-01-00;So;0;ON;;;;;N;;;;; +1F06B;DOMINO TILE VERTICAL-01-01;So;0;ON;;;;;N;;;;; +1F06C;DOMINO TILE VERTICAL-01-02;So;0;ON;;;;;N;;;;; +1F06D;DOMINO TILE VERTICAL-01-03;So;0;ON;;;;;N;;;;; +1F06E;DOMINO TILE VERTICAL-01-04;So;0;ON;;;;;N;;;;; +1F06F;DOMINO TILE VERTICAL-01-05;So;0;ON;;;;;N;;;;; +1F070;DOMINO TILE VERTICAL-01-06;So;0;ON;;;;;N;;;;; +1F071;DOMINO TILE VERTICAL-02-00;So;0;ON;;;;;N;;;;; +1F072;DOMINO TILE VERTICAL-02-01;So;0;ON;;;;;N;;;;; +1F073;DOMINO TILE VERTICAL-02-02;So;0;ON;;;;;N;;;;; +1F074;DOMINO TILE VERTICAL-02-03;So;0;ON;;;;;N;;;;; +1F075;DOMINO TILE VERTICAL-02-04;So;0;ON;;;;;N;;;;; +1F076;DOMINO TILE VERTICAL-02-05;So;0;ON;;;;;N;;;;; +1F077;DOMINO TILE VERTICAL-02-06;So;0;ON;;;;;N;;;;; +1F078;DOMINO TILE VERTICAL-03-00;So;0;ON;;;;;N;;;;; +1F079;DOMINO TILE VERTICAL-03-01;So;0;ON;;;;;N;;;;; +1F07A;DOMINO TILE VERTICAL-03-02;So;0;ON;;;;;N;;;;; +1F07B;DOMINO TILE VERTICAL-03-03;So;0;ON;;;;;N;;;;; +1F07C;DOMINO TILE VERTICAL-03-04;So;0;ON;;;;;N;;;;; +1F07D;DOMINO TILE VERTICAL-03-05;So;0;ON;;;;;N;;;;; +1F07E;DOMINO TILE VERTICAL-03-06;So;0;ON;;;;;N;;;;; +1F07F;DOMINO TILE VERTICAL-04-00;So;0;ON;;;;;N;;;;; +1F080;DOMINO TILE VERTICAL-04-01;So;0;ON;;;;;N;;;;; +1F081;DOMINO TILE VERTICAL-04-02;So;0;ON;;;;;N;;;;; +1F082;DOMINO TILE VERTICAL-04-03;So;0;ON;;;;;N;;;;; +1F083;DOMINO TILE VERTICAL-04-04;So;0;ON;;;;;N;;;;; +1F084;DOMINO TILE VERTICAL-04-05;So;0;ON;;;;;N;;;;; +1F085;DOMINO TILE VERTICAL-04-06;So;0;ON;;;;;N;;;;; +1F086;DOMINO TILE VERTICAL-05-00;So;0;ON;;;;;N;;;;; +1F087;DOMINO TILE VERTICAL-05-01;So;0;ON;;;;;N;;;;; +1F088;DOMINO TILE VERTICAL-05-02;So;0;ON;;;;;N;;;;; +1F089;DOMINO TILE VERTICAL-05-03;So;0;ON;;;;;N;;;;; +1F08A;DOMINO TILE VERTICAL-05-04;So;0;ON;;;;;N;;;;; +1F08B;DOMINO TILE VERTICAL-05-05;So;0;ON;;;;;N;;;;; +1F08C;DOMINO TILE VERTICAL-05-06;So;0;ON;;;;;N;;;;; +1F08D;DOMINO TILE VERTICAL-06-00;So;0;ON;;;;;N;;;;; +1F08E;DOMINO TILE VERTICAL-06-01;So;0;ON;;;;;N;;;;; +1F08F;DOMINO TILE VERTICAL-06-02;So;0;ON;;;;;N;;;;; +1F090;DOMINO TILE VERTICAL-06-03;So;0;ON;;;;;N;;;;; +1F091;DOMINO TILE VERTICAL-06-04;So;0;ON;;;;;N;;;;; +1F092;DOMINO TILE VERTICAL-06-05;So;0;ON;;;;;N;;;;; +1F093;DOMINO TILE VERTICAL-06-06;So;0;ON;;;;;N;;;;; +1F100;DIGIT ZERO FULL STOP;No;0;EN; 0030 002E;;0;0;N;;;;; +1F101;DIGIT ZERO COMMA;No;0;EN; 0030 002C;;0;0;N;;;;; +1F102;DIGIT ONE COMMA;No;0;EN; 0031 002C;;1;1;N;;;;; +1F103;DIGIT TWO COMMA;No;0;EN; 0032 002C;;2;2;N;;;;; +1F104;DIGIT THREE COMMA;No;0;EN; 0033 002C;;3;3;N;;;;; +1F105;DIGIT FOUR COMMA;No;0;EN; 0034 002C;;4;4;N;;;;; +1F106;DIGIT FIVE COMMA;No;0;EN; 0035 002C;;5;5;N;;;;; +1F107;DIGIT SIX COMMA;No;0;EN; 0036 002C;;6;6;N;;;;; +1F108;DIGIT SEVEN COMMA;No;0;EN; 0037 002C;;7;7;N;;;;; +1F109;DIGIT EIGHT COMMA;No;0;EN; 0038 002C;;8;8;N;;;;; +1F10A;DIGIT NINE COMMA;No;0;EN; 0039 002C;;9;9;N;;;;; +1F110;PARENTHESIZED LATIN CAPITAL LETTER A;So;0;L; 0028 0041 0029;;;;N;;;;; +1F111;PARENTHESIZED LATIN CAPITAL LETTER B;So;0;L; 0028 0042 0029;;;;N;;;;; +1F112;PARENTHESIZED LATIN CAPITAL LETTER C;So;0;L; 0028 0043 0029;;;;N;;;;; +1F113;PARENTHESIZED LATIN CAPITAL LETTER D;So;0;L; 0028 0044 0029;;;;N;;;;; +1F114;PARENTHESIZED LATIN CAPITAL LETTER E;So;0;L; 0028 0045 0029;;;;N;;;;; +1F115;PARENTHESIZED LATIN CAPITAL LETTER F;So;0;L; 0028 0046 0029;;;;N;;;;; +1F116;PARENTHESIZED LATIN CAPITAL LETTER G;So;0;L; 0028 0047 0029;;;;N;;;;; +1F117;PARENTHESIZED LATIN CAPITAL LETTER H;So;0;L; 0028 0048 0029;;;;N;;;;; +1F118;PARENTHESIZED LATIN CAPITAL LETTER I;So;0;L; 0028 0049 0029;;;;N;;;;; +1F119;PARENTHESIZED LATIN CAPITAL LETTER J;So;0;L; 0028 004A 0029;;;;N;;;;; +1F11A;PARENTHESIZED LATIN CAPITAL LETTER K;So;0;L; 0028 004B 0029;;;;N;;;;; +1F11B;PARENTHESIZED LATIN CAPITAL LETTER L;So;0;L; 0028 004C 0029;;;;N;;;;; +1F11C;PARENTHESIZED LATIN CAPITAL LETTER M;So;0;L; 0028 004D 0029;;;;N;;;;; +1F11D;PARENTHESIZED LATIN CAPITAL LETTER N;So;0;L; 0028 004E 0029;;;;N;;;;; +1F11E;PARENTHESIZED LATIN CAPITAL LETTER O;So;0;L; 0028 004F 0029;;;;N;;;;; +1F11F;PARENTHESIZED LATIN CAPITAL LETTER P;So;0;L; 0028 0050 0029;;;;N;;;;; +1F120;PARENTHESIZED LATIN CAPITAL LETTER Q;So;0;L; 0028 0051 0029;;;;N;;;;; +1F121;PARENTHESIZED LATIN CAPITAL LETTER R;So;0;L; 0028 0052 0029;;;;N;;;;; +1F122;PARENTHESIZED LATIN CAPITAL LETTER S;So;0;L; 0028 0053 0029;;;;N;;;;; +1F123;PARENTHESIZED LATIN CAPITAL LETTER T;So;0;L; 0028 0054 0029;;;;N;;;;; +1F124;PARENTHESIZED LATIN CAPITAL LETTER U;So;0;L; 0028 0055 0029;;;;N;;;;; +1F125;PARENTHESIZED LATIN CAPITAL LETTER V;So;0;L; 0028 0056 0029;;;;N;;;;; +1F126;PARENTHESIZED LATIN CAPITAL LETTER W;So;0;L; 0028 0057 0029;;;;N;;;;; +1F127;PARENTHESIZED LATIN CAPITAL LETTER X;So;0;L; 0028 0058 0029;;;;N;;;;; +1F128;PARENTHESIZED LATIN CAPITAL LETTER Y;So;0;L; 0028 0059 0029;;;;N;;;;; +1F129;PARENTHESIZED LATIN CAPITAL LETTER Z;So;0;L; 0028 005A 0029;;;;N;;;;; +1F12A;TORTOISE SHELL BRACKETED LATIN CAPITAL LETTER S;So;0;L; 3014 0053 3015;;;;N;;;;; +1F12B;CIRCLED ITALIC LATIN CAPITAL LETTER C;So;0;L; 0043;;;;N;;;;; +1F12C;CIRCLED ITALIC LATIN CAPITAL LETTER R;So;0;L; 0052;;;;N;;;;; +1F12D;CIRCLED CD;So;0;L; 0043 0044;;;;N;;;;; +1F12E;CIRCLED WZ;So;0;L; 0057 005A;;;;N;;;;; +1F131;SQUARED LATIN CAPITAL LETTER B;So;0;L; 0042;;;;N;;;;; +1F13D;SQUARED LATIN CAPITAL LETTER N;So;0;L; 004E;;;;N;;;;; +1F13F;SQUARED LATIN CAPITAL LETTER P;So;0;L; 0050;;;;N;;;;; +1F142;SQUARED LATIN CAPITAL LETTER S;So;0;L; 0053;;;;N;;;;; +1F146;SQUARED LATIN CAPITAL LETTER W;So;0;L; 0057;;;;N;;;;; +1F14A;SQUARED HV;So;0;L; 0048 0056;;;;N;;;;; +1F14B;SQUARED MV;So;0;L; 004D 0056;;;;N;;;;; +1F14C;SQUARED SD;So;0;L; 0053 0044;;;;N;;;;; +1F14D;SQUARED SS;So;0;L; 0053 0053;;;;N;;;;; +1F14E;SQUARED PPV;So;0;L; 0050 0050 0056;;;;N;;;;; +1F157;NEGATIVE CIRCLED LATIN CAPITAL LETTER H;So;0;L;;;;;N;;;;; +1F15F;NEGATIVE CIRCLED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;; +1F179;NEGATIVE SQUARED LATIN CAPITAL LETTER J;So;0;L;;;;;N;;;;; +1F17B;NEGATIVE SQUARED LATIN CAPITAL LETTER L;So;0;L;;;;;N;;;;; +1F17C;NEGATIVE SQUARED LATIN CAPITAL LETTER M;So;0;L;;;;;N;;;;; +1F17F;NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;; +1F18A;CROSSED NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;; +1F18B;NEGATIVE SQUARED IC;So;0;L;;;;;N;;;;; +1F18C;NEGATIVE SQUARED PA;So;0;L;;;;;N;;;;; +1F18D;NEGATIVE SQUARED SA;So;0;L;;;;;N;;;;; +1F190;SQUARE DJ;So;0;L; 0044 004A;;;;N;;;;; +1F200;SQUARE HIRAGANA HOKA;So;0;L; 307B 304B;;;;N;;;;; +1F210;SQUARED CJK UNIFIED IDEOGRAPH-624B;So;0;L; 624B;;;;N;;;;; +1F211;SQUARED CJK UNIFIED IDEOGRAPH-5B57;So;0;L; 5B57;;;;N;;;;; +1F212;SQUARED CJK UNIFIED IDEOGRAPH-53CC;So;0;L; 53CC;;;;N;;;;; +1F213;SQUARED KATAKANA DE;So;0;L; 30C7;;;;N;;;;; +1F214;SQUARED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L; 4E8C;;;;N;;;;; +1F215;SQUARED CJK UNIFIED IDEOGRAPH-591A;So;0;L; 591A;;;;N;;;;; +1F216;SQUARED CJK UNIFIED IDEOGRAPH-89E3;So;0;L; 89E3;;;;N;;;;; +1F217;SQUARED CJK UNIFIED IDEOGRAPH-5929;So;0;L; 5929;;;;N;;;;; +1F218;SQUARED CJK UNIFIED IDEOGRAPH-4EA4;So;0;L; 4EA4;;;;N;;;;; +1F219;SQUARED CJK UNIFIED IDEOGRAPH-6620;So;0;L; 6620;;;;N;;;;; +1F21A;SQUARED CJK UNIFIED IDEOGRAPH-7121;So;0;L; 7121;;;;N;;;;; +1F21B;SQUARED CJK UNIFIED IDEOGRAPH-6599;So;0;L; 6599;;;;N;;;;; +1F21C;SQUARED CJK UNIFIED IDEOGRAPH-524D;So;0;L; 524D;;;;N;;;;; +1F21D;SQUARED CJK UNIFIED IDEOGRAPH-5F8C;So;0;L; 5F8C;;;;N;;;;; +1F21E;SQUARED CJK UNIFIED IDEOGRAPH-518D;So;0;L; 518D;;;;N;;;;; +1F21F;SQUARED CJK UNIFIED IDEOGRAPH-65B0;So;0;L; 65B0;;;;N;;;;; +1F220;SQUARED CJK UNIFIED IDEOGRAPH-521D;So;0;L; 521D;;;;N;;;;; +1F221;SQUARED CJK UNIFIED IDEOGRAPH-7D42;So;0;L; 7D42;;;;N;;;;; +1F222;SQUARED CJK UNIFIED IDEOGRAPH-751F;So;0;L; 751F;;;;N;;;;; +1F223;SQUARED CJK UNIFIED IDEOGRAPH-8CA9;So;0;L; 8CA9;;;;N;;;;; +1F224;SQUARED CJK UNIFIED IDEOGRAPH-58F0;So;0;L; 58F0;;;;N;;;;; +1F225;SQUARED CJK UNIFIED IDEOGRAPH-5439;So;0;L; 5439;;;;N;;;;; +1F226;SQUARED CJK UNIFIED IDEOGRAPH-6F14;So;0;L; 6F14;;;;N;;;;; +1F227;SQUARED CJK UNIFIED IDEOGRAPH-6295;So;0;L; 6295;;;;N;;;;; +1F228;SQUARED CJK UNIFIED IDEOGRAPH-6355;So;0;L; 6355;;;;N;;;;; +1F229;SQUARED CJK UNIFIED IDEOGRAPH-4E00;So;0;L; 4E00;;;;N;;;;; +1F22A;SQUARED CJK UNIFIED IDEOGRAPH-4E09;So;0;L; 4E09;;;;N;;;;; +1F22B;SQUARED CJK UNIFIED IDEOGRAPH-904A;So;0;L; 904A;;;;N;;;;; +1F22C;SQUARED CJK UNIFIED IDEOGRAPH-5DE6;So;0;L; 5DE6;;;;N;;;;; +1F22D;SQUARED CJK UNIFIED IDEOGRAPH-4E2D;So;0;L; 4E2D;;;;N;;;;; +1F22E;SQUARED CJK UNIFIED IDEOGRAPH-53F3;So;0;L; 53F3;;;;N;;;;; +1F22F;SQUARED CJK UNIFIED IDEOGRAPH-6307;So;0;L; 6307;;;;N;;;;; +1F230;SQUARED CJK UNIFIED IDEOGRAPH-8D70;So;0;L; 8D70;;;;N;;;;; +1F231;SQUARED CJK UNIFIED IDEOGRAPH-6253;So;0;L; 6253;;;;N;;;;; +1F240;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C;So;0;L; 3014 672C 3015;;;;N;;;;; +1F241;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09;So;0;L; 3014 4E09 3015;;;;N;;;;; +1F242;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L; 3014 4E8C 3015;;;;N;;;;; +1F243;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-5B89;So;0;L; 3014 5B89 3015;;;;N;;;;; +1F244;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-70B9;So;0;L; 3014 70B9 3015;;;;N;;;;; +1F245;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6253;So;0;L; 3014 6253 3015;;;;N;;;;; +1F246;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-76D7;So;0;L; 3014 76D7 3015;;;;N;;;;; +1F247;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-52DD;So;0;L; 3014 52DD 3015;;;;N;;;;; +1F248;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557;So;0;L; 3014 6557 3015;;;;N;;;;; +20000;;Lo;0;L;;;;;N;;;;; +2A6D6;;Lo;0;L;;;;;N;;;;; +2A700;;Lo;0;L;;;;;N;;;;; +2B734;;Lo;0;L;;;;;N;;;;; +2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;; +2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;; +2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;; +2F803;CJK COMPATIBILITY IDEOGRAPH-2F803;Lo;0;L;20122;;;;N;;;;; +2F804;CJK COMPATIBILITY IDEOGRAPH-2F804;Lo;0;L;4F60;;;;N;;;;; +2F805;CJK COMPATIBILITY IDEOGRAPH-2F805;Lo;0;L;4FAE;;;;N;;;;; +2F806;CJK COMPATIBILITY IDEOGRAPH-2F806;Lo;0;L;4FBB;;;;N;;;;; +2F807;CJK COMPATIBILITY IDEOGRAPH-2F807;Lo;0;L;5002;;;;N;;;;; +2F808;CJK COMPATIBILITY IDEOGRAPH-2F808;Lo;0;L;507A;;;;N;;;;; +2F809;CJK COMPATIBILITY IDEOGRAPH-2F809;Lo;0;L;5099;;;;N;;;;; +2F80A;CJK COMPATIBILITY IDEOGRAPH-2F80A;Lo;0;L;50E7;;;;N;;;;; +2F80B;CJK COMPATIBILITY IDEOGRAPH-2F80B;Lo;0;L;50CF;;;;N;;;;; +2F80C;CJK COMPATIBILITY IDEOGRAPH-2F80C;Lo;0;L;349E;;;;N;;;;; +2F80D;CJK COMPATIBILITY IDEOGRAPH-2F80D;Lo;0;L;2063A;;;;N;;;;; +2F80E;CJK COMPATIBILITY IDEOGRAPH-2F80E;Lo;0;L;514D;;;;N;;;;; +2F80F;CJK COMPATIBILITY IDEOGRAPH-2F80F;Lo;0;L;5154;;;;N;;;;; +2F810;CJK COMPATIBILITY IDEOGRAPH-2F810;Lo;0;L;5164;;;;N;;;;; +2F811;CJK COMPATIBILITY IDEOGRAPH-2F811;Lo;0;L;5177;;;;N;;;;; +2F812;CJK COMPATIBILITY IDEOGRAPH-2F812;Lo;0;L;2051C;;;;N;;;;; +2F813;CJK COMPATIBILITY IDEOGRAPH-2F813;Lo;0;L;34B9;;;;N;;;;; +2F814;CJK COMPATIBILITY IDEOGRAPH-2F814;Lo;0;L;5167;;;;N;;;;; +2F815;CJK COMPATIBILITY IDEOGRAPH-2F815;Lo;0;L;518D;;;;N;;;;; +2F816;CJK COMPATIBILITY IDEOGRAPH-2F816;Lo;0;L;2054B;;;;N;;;;; +2F817;CJK COMPATIBILITY IDEOGRAPH-2F817;Lo;0;L;5197;;;;N;;;;; +2F818;CJK COMPATIBILITY IDEOGRAPH-2F818;Lo;0;L;51A4;;;;N;;;;; +2F819;CJK COMPATIBILITY IDEOGRAPH-2F819;Lo;0;L;4ECC;;;;N;;;;; +2F81A;CJK COMPATIBILITY IDEOGRAPH-2F81A;Lo;0;L;51AC;;;;N;;;;; +2F81B;CJK COMPATIBILITY IDEOGRAPH-2F81B;Lo;0;L;51B5;;;;N;;;;; +2F81C;CJK COMPATIBILITY IDEOGRAPH-2F81C;Lo;0;L;291DF;;;;N;;;;; +2F81D;CJK COMPATIBILITY IDEOGRAPH-2F81D;Lo;0;L;51F5;;;;N;;;;; +2F81E;CJK COMPATIBILITY IDEOGRAPH-2F81E;Lo;0;L;5203;;;;N;;;;; +2F81F;CJK COMPATIBILITY IDEOGRAPH-2F81F;Lo;0;L;34DF;;;;N;;;;; +2F820;CJK COMPATIBILITY IDEOGRAPH-2F820;Lo;0;L;523B;;;;N;;;;; +2F821;CJK COMPATIBILITY IDEOGRAPH-2F821;Lo;0;L;5246;;;;N;;;;; +2F822;CJK COMPATIBILITY IDEOGRAPH-2F822;Lo;0;L;5272;;;;N;;;;; +2F823;CJK COMPATIBILITY IDEOGRAPH-2F823;Lo;0;L;5277;;;;N;;;;; +2F824;CJK COMPATIBILITY IDEOGRAPH-2F824;Lo;0;L;3515;;;;N;;;;; +2F825;CJK COMPATIBILITY IDEOGRAPH-2F825;Lo;0;L;52C7;;;;N;;;;; +2F826;CJK COMPATIBILITY IDEOGRAPH-2F826;Lo;0;L;52C9;;;;N;;;;; +2F827;CJK COMPATIBILITY IDEOGRAPH-2F827;Lo;0;L;52E4;;;;N;;;;; +2F828;CJK COMPATIBILITY IDEOGRAPH-2F828;Lo;0;L;52FA;;;;N;;;;; +2F829;CJK COMPATIBILITY IDEOGRAPH-2F829;Lo;0;L;5305;;;;N;;;;; +2F82A;CJK COMPATIBILITY IDEOGRAPH-2F82A;Lo;0;L;5306;;;;N;;;;; +2F82B;CJK COMPATIBILITY IDEOGRAPH-2F82B;Lo;0;L;5317;;;;N;;;;; +2F82C;CJK COMPATIBILITY IDEOGRAPH-2F82C;Lo;0;L;5349;;;;N;;;;; +2F82D;CJK COMPATIBILITY IDEOGRAPH-2F82D;Lo;0;L;5351;;;;N;;;;; +2F82E;CJK COMPATIBILITY IDEOGRAPH-2F82E;Lo;0;L;535A;;;;N;;;;; +2F82F;CJK COMPATIBILITY IDEOGRAPH-2F82F;Lo;0;L;5373;;;;N;;;;; +2F830;CJK COMPATIBILITY IDEOGRAPH-2F830;Lo;0;L;537D;;;;N;;;;; +2F831;CJK COMPATIBILITY IDEOGRAPH-2F831;Lo;0;L;537F;;;;N;;;;; +2F832;CJK COMPATIBILITY IDEOGRAPH-2F832;Lo;0;L;537F;;;;N;;;;; +2F833;CJK COMPATIBILITY IDEOGRAPH-2F833;Lo;0;L;537F;;;;N;;;;; +2F834;CJK COMPATIBILITY IDEOGRAPH-2F834;Lo;0;L;20A2C;;;;N;;;;; +2F835;CJK COMPATIBILITY IDEOGRAPH-2F835;Lo;0;L;7070;;;;N;;;;; +2F836;CJK COMPATIBILITY IDEOGRAPH-2F836;Lo;0;L;53CA;;;;N;;;;; +2F837;CJK COMPATIBILITY IDEOGRAPH-2F837;Lo;0;L;53DF;;;;N;;;;; +2F838;CJK COMPATIBILITY IDEOGRAPH-2F838;Lo;0;L;20B63;;;;N;;;;; +2F839;CJK COMPATIBILITY IDEOGRAPH-2F839;Lo;0;L;53EB;;;;N;;;;; +2F83A;CJK COMPATIBILITY IDEOGRAPH-2F83A;Lo;0;L;53F1;;;;N;;;;; +2F83B;CJK COMPATIBILITY IDEOGRAPH-2F83B;Lo;0;L;5406;;;;N;;;;; +2F83C;CJK COMPATIBILITY IDEOGRAPH-2F83C;Lo;0;L;549E;;;;N;;;;; +2F83D;CJK COMPATIBILITY IDEOGRAPH-2F83D;Lo;0;L;5438;;;;N;;;;; +2F83E;CJK COMPATIBILITY IDEOGRAPH-2F83E;Lo;0;L;5448;;;;N;;;;; +2F83F;CJK COMPATIBILITY IDEOGRAPH-2F83F;Lo;0;L;5468;;;;N;;;;; +2F840;CJK COMPATIBILITY IDEOGRAPH-2F840;Lo;0;L;54A2;;;;N;;;;; +2F841;CJK COMPATIBILITY IDEOGRAPH-2F841;Lo;0;L;54F6;;;;N;;;;; +2F842;CJK COMPATIBILITY IDEOGRAPH-2F842;Lo;0;L;5510;;;;N;;;;; +2F843;CJK COMPATIBILITY IDEOGRAPH-2F843;Lo;0;L;5553;;;;N;;;;; +2F844;CJK COMPATIBILITY IDEOGRAPH-2F844;Lo;0;L;5563;;;;N;;;;; +2F845;CJK COMPATIBILITY IDEOGRAPH-2F845;Lo;0;L;5584;;;;N;;;;; +2F846;CJK COMPATIBILITY IDEOGRAPH-2F846;Lo;0;L;5584;;;;N;;;;; +2F847;CJK COMPATIBILITY IDEOGRAPH-2F847;Lo;0;L;5599;;;;N;;;;; +2F848;CJK COMPATIBILITY IDEOGRAPH-2F848;Lo;0;L;55AB;;;;N;;;;; +2F849;CJK COMPATIBILITY IDEOGRAPH-2F849;Lo;0;L;55B3;;;;N;;;;; +2F84A;CJK COMPATIBILITY IDEOGRAPH-2F84A;Lo;0;L;55C2;;;;N;;;;; +2F84B;CJK COMPATIBILITY IDEOGRAPH-2F84B;Lo;0;L;5716;;;;N;;;;; +2F84C;CJK COMPATIBILITY IDEOGRAPH-2F84C;Lo;0;L;5606;;;;N;;;;; +2F84D;CJK COMPATIBILITY IDEOGRAPH-2F84D;Lo;0;L;5717;;;;N;;;;; +2F84E;CJK COMPATIBILITY IDEOGRAPH-2F84E;Lo;0;L;5651;;;;N;;;;; +2F84F;CJK COMPATIBILITY IDEOGRAPH-2F84F;Lo;0;L;5674;;;;N;;;;; +2F850;CJK COMPATIBILITY IDEOGRAPH-2F850;Lo;0;L;5207;;;;N;;;;; +2F851;CJK COMPATIBILITY IDEOGRAPH-2F851;Lo;0;L;58EE;;;;N;;;;; +2F852;CJK COMPATIBILITY IDEOGRAPH-2F852;Lo;0;L;57CE;;;;N;;;;; +2F853;CJK COMPATIBILITY IDEOGRAPH-2F853;Lo;0;L;57F4;;;;N;;;;; +2F854;CJK COMPATIBILITY IDEOGRAPH-2F854;Lo;0;L;580D;;;;N;;;;; +2F855;CJK COMPATIBILITY IDEOGRAPH-2F855;Lo;0;L;578B;;;;N;;;;; +2F856;CJK COMPATIBILITY IDEOGRAPH-2F856;Lo;0;L;5832;;;;N;;;;; +2F857;CJK COMPATIBILITY IDEOGRAPH-2F857;Lo;0;L;5831;;;;N;;;;; +2F858;CJK COMPATIBILITY IDEOGRAPH-2F858;Lo;0;L;58AC;;;;N;;;;; +2F859;CJK COMPATIBILITY IDEOGRAPH-2F859;Lo;0;L;214E4;;;;N;;;;; +2F85A;CJK COMPATIBILITY IDEOGRAPH-2F85A;Lo;0;L;58F2;;;;N;;;;; +2F85B;CJK COMPATIBILITY IDEOGRAPH-2F85B;Lo;0;L;58F7;;;;N;;;;; +2F85C;CJK COMPATIBILITY IDEOGRAPH-2F85C;Lo;0;L;5906;;;;N;;;;; +2F85D;CJK COMPATIBILITY IDEOGRAPH-2F85D;Lo;0;L;591A;;;;N;;;;; +2F85E;CJK COMPATIBILITY IDEOGRAPH-2F85E;Lo;0;L;5922;;;;N;;;;; +2F85F;CJK COMPATIBILITY IDEOGRAPH-2F85F;Lo;0;L;5962;;;;N;;;;; +2F860;CJK COMPATIBILITY IDEOGRAPH-2F860;Lo;0;L;216A8;;;;N;;;;; +2F861;CJK COMPATIBILITY IDEOGRAPH-2F861;Lo;0;L;216EA;;;;N;;;;; +2F862;CJK COMPATIBILITY IDEOGRAPH-2F862;Lo;0;L;59EC;;;;N;;;;; +2F863;CJK COMPATIBILITY IDEOGRAPH-2F863;Lo;0;L;5A1B;;;;N;;;;; +2F864;CJK COMPATIBILITY IDEOGRAPH-2F864;Lo;0;L;5A27;;;;N;;;;; +2F865;CJK COMPATIBILITY IDEOGRAPH-2F865;Lo;0;L;59D8;;;;N;;;;; +2F866;CJK COMPATIBILITY IDEOGRAPH-2F866;Lo;0;L;5A66;;;;N;;;;; +2F867;CJK COMPATIBILITY IDEOGRAPH-2F867;Lo;0;L;36EE;;;;N;;;;; +2F868;CJK COMPATIBILITY IDEOGRAPH-2F868;Lo;0;L;36FC;;;;N;;;;; +2F869;CJK COMPATIBILITY IDEOGRAPH-2F869;Lo;0;L;5B08;;;;N;;;;; +2F86A;CJK COMPATIBILITY IDEOGRAPH-2F86A;Lo;0;L;5B3E;;;;N;;;;; +2F86B;CJK COMPATIBILITY IDEOGRAPH-2F86B;Lo;0;L;5B3E;;;;N;;;;; +2F86C;CJK COMPATIBILITY IDEOGRAPH-2F86C;Lo;0;L;219C8;;;;N;;;;; +2F86D;CJK COMPATIBILITY IDEOGRAPH-2F86D;Lo;0;L;5BC3;;;;N;;;;; +2F86E;CJK COMPATIBILITY IDEOGRAPH-2F86E;Lo;0;L;5BD8;;;;N;;;;; +2F86F;CJK COMPATIBILITY IDEOGRAPH-2F86F;Lo;0;L;5BE7;;;;N;;;;; +2F870;CJK COMPATIBILITY IDEOGRAPH-2F870;Lo;0;L;5BF3;;;;N;;;;; +2F871;CJK COMPATIBILITY IDEOGRAPH-2F871;Lo;0;L;21B18;;;;N;;;;; +2F872;CJK COMPATIBILITY IDEOGRAPH-2F872;Lo;0;L;5BFF;;;;N;;;;; +2F873;CJK COMPATIBILITY IDEOGRAPH-2F873;Lo;0;L;5C06;;;;N;;;;; +2F874;CJK COMPATIBILITY IDEOGRAPH-2F874;Lo;0;L;5F53;;;;N;;;;; +2F875;CJK COMPATIBILITY IDEOGRAPH-2F875;Lo;0;L;5C22;;;;N;;;;; +2F876;CJK COMPATIBILITY IDEOGRAPH-2F876;Lo;0;L;3781;;;;N;;;;; +2F877;CJK COMPATIBILITY IDEOGRAPH-2F877;Lo;0;L;5C60;;;;N;;;;; +2F878;CJK COMPATIBILITY IDEOGRAPH-2F878;Lo;0;L;5C6E;;;;N;;;;; +2F879;CJK COMPATIBILITY IDEOGRAPH-2F879;Lo;0;L;5CC0;;;;N;;;;; +2F87A;CJK COMPATIBILITY IDEOGRAPH-2F87A;Lo;0;L;5C8D;;;;N;;;;; +2F87B;CJK COMPATIBILITY IDEOGRAPH-2F87B;Lo;0;L;21DE4;;;;N;;;;; +2F87C;CJK COMPATIBILITY IDEOGRAPH-2F87C;Lo;0;L;5D43;;;;N;;;;; +2F87D;CJK COMPATIBILITY IDEOGRAPH-2F87D;Lo;0;L;21DE6;;;;N;;;;; +2F87E;CJK COMPATIBILITY IDEOGRAPH-2F87E;Lo;0;L;5D6E;;;;N;;;;; +2F87F;CJK COMPATIBILITY IDEOGRAPH-2F87F;Lo;0;L;5D6B;;;;N;;;;; +2F880;CJK COMPATIBILITY IDEOGRAPH-2F880;Lo;0;L;5D7C;;;;N;;;;; +2F881;CJK COMPATIBILITY IDEOGRAPH-2F881;Lo;0;L;5DE1;;;;N;;;;; +2F882;CJK COMPATIBILITY IDEOGRAPH-2F882;Lo;0;L;5DE2;;;;N;;;;; +2F883;CJK COMPATIBILITY IDEOGRAPH-2F883;Lo;0;L;382F;;;;N;;;;; +2F884;CJK COMPATIBILITY IDEOGRAPH-2F884;Lo;0;L;5DFD;;;;N;;;;; +2F885;CJK COMPATIBILITY IDEOGRAPH-2F885;Lo;0;L;5E28;;;;N;;;;; +2F886;CJK COMPATIBILITY IDEOGRAPH-2F886;Lo;0;L;5E3D;;;;N;;;;; +2F887;CJK COMPATIBILITY IDEOGRAPH-2F887;Lo;0;L;5E69;;;;N;;;;; +2F888;CJK COMPATIBILITY IDEOGRAPH-2F888;Lo;0;L;3862;;;;N;;;;; +2F889;CJK COMPATIBILITY IDEOGRAPH-2F889;Lo;0;L;22183;;;;N;;;;; +2F88A;CJK COMPATIBILITY IDEOGRAPH-2F88A;Lo;0;L;387C;;;;N;;;;; +2F88B;CJK COMPATIBILITY IDEOGRAPH-2F88B;Lo;0;L;5EB0;;;;N;;;;; +2F88C;CJK COMPATIBILITY IDEOGRAPH-2F88C;Lo;0;L;5EB3;;;;N;;;;; +2F88D;CJK COMPATIBILITY IDEOGRAPH-2F88D;Lo;0;L;5EB6;;;;N;;;;; +2F88E;CJK COMPATIBILITY IDEOGRAPH-2F88E;Lo;0;L;5ECA;;;;N;;;;; +2F88F;CJK COMPATIBILITY IDEOGRAPH-2F88F;Lo;0;L;2A392;;;;N;;;;; +2F890;CJK COMPATIBILITY IDEOGRAPH-2F890;Lo;0;L;5EFE;;;9;N;;;;; +2F891;CJK COMPATIBILITY IDEOGRAPH-2F891;Lo;0;L;22331;;;;N;;;;; +2F892;CJK COMPATIBILITY IDEOGRAPH-2F892;Lo;0;L;22331;;;;N;;;;; +2F893;CJK COMPATIBILITY IDEOGRAPH-2F893;Lo;0;L;8201;;;;N;;;;; +2F894;CJK COMPATIBILITY IDEOGRAPH-2F894;Lo;0;L;5F22;;;;N;;;;; +2F895;CJK COMPATIBILITY IDEOGRAPH-2F895;Lo;0;L;5F22;;;;N;;;;; +2F896;CJK COMPATIBILITY IDEOGRAPH-2F896;Lo;0;L;38C7;;;;N;;;;; +2F897;CJK COMPATIBILITY IDEOGRAPH-2F897;Lo;0;L;232B8;;;;N;;;;; +2F898;CJK COMPATIBILITY IDEOGRAPH-2F898;Lo;0;L;261DA;;;;N;;;;; +2F899;CJK COMPATIBILITY IDEOGRAPH-2F899;Lo;0;L;5F62;;;;N;;;;; +2F89A;CJK COMPATIBILITY IDEOGRAPH-2F89A;Lo;0;L;5F6B;;;;N;;;;; +2F89B;CJK COMPATIBILITY IDEOGRAPH-2F89B;Lo;0;L;38E3;;;;N;;;;; +2F89C;CJK COMPATIBILITY IDEOGRAPH-2F89C;Lo;0;L;5F9A;;;;N;;;;; +2F89D;CJK COMPATIBILITY IDEOGRAPH-2F89D;Lo;0;L;5FCD;;;;N;;;;; +2F89E;CJK COMPATIBILITY IDEOGRAPH-2F89E;Lo;0;L;5FD7;;;;N;;;;; +2F89F;CJK COMPATIBILITY IDEOGRAPH-2F89F;Lo;0;L;5FF9;;;;N;;;;; +2F8A0;CJK COMPATIBILITY IDEOGRAPH-2F8A0;Lo;0;L;6081;;;;N;;;;; +2F8A1;CJK COMPATIBILITY IDEOGRAPH-2F8A1;Lo;0;L;393A;;;;N;;;;; +2F8A2;CJK COMPATIBILITY IDEOGRAPH-2F8A2;Lo;0;L;391C;;;;N;;;;; +2F8A3;CJK COMPATIBILITY IDEOGRAPH-2F8A3;Lo;0;L;6094;;;;N;;;;; +2F8A4;CJK COMPATIBILITY IDEOGRAPH-2F8A4;Lo;0;L;226D4;;;;N;;;;; +2F8A5;CJK COMPATIBILITY IDEOGRAPH-2F8A5;Lo;0;L;60C7;;;;N;;;;; +2F8A6;CJK COMPATIBILITY IDEOGRAPH-2F8A6;Lo;0;L;6148;;;;N;;;;; +2F8A7;CJK COMPATIBILITY IDEOGRAPH-2F8A7;Lo;0;L;614C;;;;N;;;;; +2F8A8;CJK COMPATIBILITY IDEOGRAPH-2F8A8;Lo;0;L;614E;;;;N;;;;; +2F8A9;CJK COMPATIBILITY IDEOGRAPH-2F8A9;Lo;0;L;614C;;;;N;;;;; +2F8AA;CJK COMPATIBILITY IDEOGRAPH-2F8AA;Lo;0;L;617A;;;;N;;;;; +2F8AB;CJK COMPATIBILITY IDEOGRAPH-2F8AB;Lo;0;L;618E;;;;N;;;;; +2F8AC;CJK COMPATIBILITY IDEOGRAPH-2F8AC;Lo;0;L;61B2;;;;N;;;;; +2F8AD;CJK COMPATIBILITY IDEOGRAPH-2F8AD;Lo;0;L;61A4;;;;N;;;;; +2F8AE;CJK COMPATIBILITY IDEOGRAPH-2F8AE;Lo;0;L;61AF;;;;N;;;;; +2F8AF;CJK COMPATIBILITY IDEOGRAPH-2F8AF;Lo;0;L;61DE;;;;N;;;;; +2F8B0;CJK COMPATIBILITY IDEOGRAPH-2F8B0;Lo;0;L;61F2;;;;N;;;;; +2F8B1;CJK COMPATIBILITY IDEOGRAPH-2F8B1;Lo;0;L;61F6;;;;N;;;;; +2F8B2;CJK COMPATIBILITY IDEOGRAPH-2F8B2;Lo;0;L;6210;;;;N;;;;; +2F8B3;CJK COMPATIBILITY IDEOGRAPH-2F8B3;Lo;0;L;621B;;;;N;;;;; +2F8B4;CJK COMPATIBILITY IDEOGRAPH-2F8B4;Lo;0;L;625D;;;;N;;;;; +2F8B5;CJK COMPATIBILITY IDEOGRAPH-2F8B5;Lo;0;L;62B1;;;;N;;;;; +2F8B6;CJK COMPATIBILITY IDEOGRAPH-2F8B6;Lo;0;L;62D4;;;;N;;;;; +2F8B7;CJK COMPATIBILITY IDEOGRAPH-2F8B7;Lo;0;L;6350;;;;N;;;;; +2F8B8;CJK COMPATIBILITY IDEOGRAPH-2F8B8;Lo;0;L;22B0C;;;;N;;;;; +2F8B9;CJK COMPATIBILITY IDEOGRAPH-2F8B9;Lo;0;L;633D;;;;N;;;;; +2F8BA;CJK COMPATIBILITY IDEOGRAPH-2F8BA;Lo;0;L;62FC;;;;N;;;;; +2F8BB;CJK COMPATIBILITY IDEOGRAPH-2F8BB;Lo;0;L;6368;;;;N;;;;; +2F8BC;CJK COMPATIBILITY IDEOGRAPH-2F8BC;Lo;0;L;6383;;;;N;;;;; +2F8BD;CJK COMPATIBILITY IDEOGRAPH-2F8BD;Lo;0;L;63E4;;;;N;;;;; +2F8BE;CJK COMPATIBILITY IDEOGRAPH-2F8BE;Lo;0;L;22BF1;;;;N;;;;; +2F8BF;CJK COMPATIBILITY IDEOGRAPH-2F8BF;Lo;0;L;6422;;;;N;;;;; +2F8C0;CJK COMPATIBILITY IDEOGRAPH-2F8C0;Lo;0;L;63C5;;;;N;;;;; +2F8C1;CJK COMPATIBILITY IDEOGRAPH-2F8C1;Lo;0;L;63A9;;;;N;;;;; +2F8C2;CJK COMPATIBILITY IDEOGRAPH-2F8C2;Lo;0;L;3A2E;;;;N;;;;; +2F8C3;CJK COMPATIBILITY IDEOGRAPH-2F8C3;Lo;0;L;6469;;;;N;;;;; +2F8C4;CJK COMPATIBILITY IDEOGRAPH-2F8C4;Lo;0;L;647E;;;;N;;;;; +2F8C5;CJK COMPATIBILITY IDEOGRAPH-2F8C5;Lo;0;L;649D;;;;N;;;;; +2F8C6;CJK COMPATIBILITY IDEOGRAPH-2F8C6;Lo;0;L;6477;;;;N;;;;; +2F8C7;CJK COMPATIBILITY IDEOGRAPH-2F8C7;Lo;0;L;3A6C;;;;N;;;;; +2F8C8;CJK COMPATIBILITY IDEOGRAPH-2F8C8;Lo;0;L;654F;;;;N;;;;; +2F8C9;CJK COMPATIBILITY IDEOGRAPH-2F8C9;Lo;0;L;656C;;;;N;;;;; +2F8CA;CJK COMPATIBILITY IDEOGRAPH-2F8CA;Lo;0;L;2300A;;;;N;;;;; +2F8CB;CJK COMPATIBILITY IDEOGRAPH-2F8CB;Lo;0;L;65E3;;;;N;;;;; +2F8CC;CJK COMPATIBILITY IDEOGRAPH-2F8CC;Lo;0;L;66F8;;;;N;;;;; +2F8CD;CJK COMPATIBILITY IDEOGRAPH-2F8CD;Lo;0;L;6649;;;;N;;;;; +2F8CE;CJK COMPATIBILITY IDEOGRAPH-2F8CE;Lo;0;L;3B19;;;;N;;;;; +2F8CF;CJK COMPATIBILITY IDEOGRAPH-2F8CF;Lo;0;L;6691;;;;N;;;;; +2F8D0;CJK COMPATIBILITY IDEOGRAPH-2F8D0;Lo;0;L;3B08;;;;N;;;;; +2F8D1;CJK COMPATIBILITY IDEOGRAPH-2F8D1;Lo;0;L;3AE4;;;;N;;;;; +2F8D2;CJK COMPATIBILITY IDEOGRAPH-2F8D2;Lo;0;L;5192;;;;N;;;;; +2F8D3;CJK COMPATIBILITY IDEOGRAPH-2F8D3;Lo;0;L;5195;;;;N;;;;; +2F8D4;CJK COMPATIBILITY IDEOGRAPH-2F8D4;Lo;0;L;6700;;;;N;;;;; +2F8D5;CJK COMPATIBILITY IDEOGRAPH-2F8D5;Lo;0;L;669C;;;;N;;;;; +2F8D6;CJK COMPATIBILITY IDEOGRAPH-2F8D6;Lo;0;L;80AD;;;;N;;;;; +2F8D7;CJK COMPATIBILITY IDEOGRAPH-2F8D7;Lo;0;L;43D9;;;;N;;;;; +2F8D8;CJK COMPATIBILITY IDEOGRAPH-2F8D8;Lo;0;L;6717;;;;N;;;;; +2F8D9;CJK COMPATIBILITY IDEOGRAPH-2F8D9;Lo;0;L;671B;;;;N;;;;; +2F8DA;CJK COMPATIBILITY IDEOGRAPH-2F8DA;Lo;0;L;6721;;;;N;;;;; +2F8DB;CJK COMPATIBILITY IDEOGRAPH-2F8DB;Lo;0;L;675E;;;;N;;;;; +2F8DC;CJK COMPATIBILITY IDEOGRAPH-2F8DC;Lo;0;L;6753;;;;N;;;;; +2F8DD;CJK COMPATIBILITY IDEOGRAPH-2F8DD;Lo;0;L;233C3;;;;N;;;;; +2F8DE;CJK COMPATIBILITY IDEOGRAPH-2F8DE;Lo;0;L;3B49;;;;N;;;;; +2F8DF;CJK COMPATIBILITY IDEOGRAPH-2F8DF;Lo;0;L;67FA;;;;N;;;;; +2F8E0;CJK COMPATIBILITY IDEOGRAPH-2F8E0;Lo;0;L;6785;;;;N;;;;; +2F8E1;CJK COMPATIBILITY IDEOGRAPH-2F8E1;Lo;0;L;6852;;;;N;;;;; +2F8E2;CJK COMPATIBILITY IDEOGRAPH-2F8E2;Lo;0;L;6885;;;;N;;;;; +2F8E3;CJK COMPATIBILITY IDEOGRAPH-2F8E3;Lo;0;L;2346D;;;;N;;;;; +2F8E4;CJK COMPATIBILITY IDEOGRAPH-2F8E4;Lo;0;L;688E;;;;N;;;;; +2F8E5;CJK COMPATIBILITY IDEOGRAPH-2F8E5;Lo;0;L;681F;;;;N;;;;; +2F8E6;CJK COMPATIBILITY IDEOGRAPH-2F8E6;Lo;0;L;6914;;;;N;;;;; +2F8E7;CJK COMPATIBILITY IDEOGRAPH-2F8E7;Lo;0;L;3B9D;;;;N;;;;; +2F8E8;CJK COMPATIBILITY IDEOGRAPH-2F8E8;Lo;0;L;6942;;;;N;;;;; +2F8E9;CJK COMPATIBILITY IDEOGRAPH-2F8E9;Lo;0;L;69A3;;;;N;;;;; +2F8EA;CJK COMPATIBILITY IDEOGRAPH-2F8EA;Lo;0;L;69EA;;;;N;;;;; +2F8EB;CJK COMPATIBILITY IDEOGRAPH-2F8EB;Lo;0;L;6AA8;;;;N;;;;; +2F8EC;CJK COMPATIBILITY IDEOGRAPH-2F8EC;Lo;0;L;236A3;;;;N;;;;; +2F8ED;CJK COMPATIBILITY IDEOGRAPH-2F8ED;Lo;0;L;6ADB;;;;N;;;;; +2F8EE;CJK COMPATIBILITY IDEOGRAPH-2F8EE;Lo;0;L;3C18;;;;N;;;;; +2F8EF;CJK COMPATIBILITY IDEOGRAPH-2F8EF;Lo;0;L;6B21;;;;N;;;;; +2F8F0;CJK COMPATIBILITY IDEOGRAPH-2F8F0;Lo;0;L;238A7;;;;N;;;;; +2F8F1;CJK COMPATIBILITY IDEOGRAPH-2F8F1;Lo;0;L;6B54;;;;N;;;;; +2F8F2;CJK COMPATIBILITY IDEOGRAPH-2F8F2;Lo;0;L;3C4E;;;;N;;;;; +2F8F3;CJK COMPATIBILITY IDEOGRAPH-2F8F3;Lo;0;L;6B72;;;;N;;;;; +2F8F4;CJK COMPATIBILITY IDEOGRAPH-2F8F4;Lo;0;L;6B9F;;;;N;;;;; +2F8F5;CJK COMPATIBILITY IDEOGRAPH-2F8F5;Lo;0;L;6BBA;;;;N;;;;; +2F8F6;CJK COMPATIBILITY IDEOGRAPH-2F8F6;Lo;0;L;6BBB;;;;N;;;;; +2F8F7;CJK COMPATIBILITY IDEOGRAPH-2F8F7;Lo;0;L;23A8D;;;;N;;;;; +2F8F8;CJK COMPATIBILITY IDEOGRAPH-2F8F8;Lo;0;L;21D0B;;;;N;;;;; +2F8F9;CJK COMPATIBILITY IDEOGRAPH-2F8F9;Lo;0;L;23AFA;;;;N;;;;; +2F8FA;CJK COMPATIBILITY IDEOGRAPH-2F8FA;Lo;0;L;6C4E;;;;N;;;;; +2F8FB;CJK COMPATIBILITY IDEOGRAPH-2F8FB;Lo;0;L;23CBC;;;;N;;;;; +2F8FC;CJK COMPATIBILITY IDEOGRAPH-2F8FC;Lo;0;L;6CBF;;;;N;;;;; +2F8FD;CJK COMPATIBILITY IDEOGRAPH-2F8FD;Lo;0;L;6CCD;;;;N;;;;; +2F8FE;CJK COMPATIBILITY IDEOGRAPH-2F8FE;Lo;0;L;6C67;;;;N;;;;; +2F8FF;CJK COMPATIBILITY IDEOGRAPH-2F8FF;Lo;0;L;6D16;;;;N;;;;; +2F900;CJK COMPATIBILITY IDEOGRAPH-2F900;Lo;0;L;6D3E;;;;N;;;;; +2F901;CJK COMPATIBILITY IDEOGRAPH-2F901;Lo;0;L;6D77;;;;N;;;;; +2F902;CJK COMPATIBILITY IDEOGRAPH-2F902;Lo;0;L;6D41;;;;N;;;;; +2F903;CJK COMPATIBILITY IDEOGRAPH-2F903;Lo;0;L;6D69;;;;N;;;;; +2F904;CJK COMPATIBILITY IDEOGRAPH-2F904;Lo;0;L;6D78;;;;N;;;;; +2F905;CJK COMPATIBILITY IDEOGRAPH-2F905;Lo;0;L;6D85;;;;N;;;;; +2F906;CJK COMPATIBILITY IDEOGRAPH-2F906;Lo;0;L;23D1E;;;;N;;;;; +2F907;CJK COMPATIBILITY IDEOGRAPH-2F907;Lo;0;L;6D34;;;;N;;;;; +2F908;CJK COMPATIBILITY IDEOGRAPH-2F908;Lo;0;L;6E2F;;;;N;;;;; +2F909;CJK COMPATIBILITY IDEOGRAPH-2F909;Lo;0;L;6E6E;;;;N;;;;; +2F90A;CJK COMPATIBILITY IDEOGRAPH-2F90A;Lo;0;L;3D33;;;;N;;;;; +2F90B;CJK COMPATIBILITY IDEOGRAPH-2F90B;Lo;0;L;6ECB;;;;N;;;;; +2F90C;CJK COMPATIBILITY IDEOGRAPH-2F90C;Lo;0;L;6EC7;;;;N;;;;; +2F90D;CJK COMPATIBILITY IDEOGRAPH-2F90D;Lo;0;L;23ED1;;;;N;;;;; +2F90E;CJK COMPATIBILITY IDEOGRAPH-2F90E;Lo;0;L;6DF9;;;;N;;;;; +2F90F;CJK COMPATIBILITY IDEOGRAPH-2F90F;Lo;0;L;6F6E;;;;N;;;;; +2F910;CJK COMPATIBILITY IDEOGRAPH-2F910;Lo;0;L;23F5E;;;;N;;;;; +2F911;CJK COMPATIBILITY IDEOGRAPH-2F911;Lo;0;L;23F8E;;;;N;;;;; +2F912;CJK COMPATIBILITY IDEOGRAPH-2F912;Lo;0;L;6FC6;;;;N;;;;; +2F913;CJK COMPATIBILITY IDEOGRAPH-2F913;Lo;0;L;7039;;;;N;;;;; +2F914;CJK COMPATIBILITY IDEOGRAPH-2F914;Lo;0;L;701E;;;;N;;;;; +2F915;CJK COMPATIBILITY IDEOGRAPH-2F915;Lo;0;L;701B;;;;N;;;;; +2F916;CJK COMPATIBILITY IDEOGRAPH-2F916;Lo;0;L;3D96;;;;N;;;;; +2F917;CJK COMPATIBILITY IDEOGRAPH-2F917;Lo;0;L;704A;;;;N;;;;; +2F918;CJK COMPATIBILITY IDEOGRAPH-2F918;Lo;0;L;707D;;;;N;;;;; +2F919;CJK COMPATIBILITY IDEOGRAPH-2F919;Lo;0;L;7077;;;;N;;;;; +2F91A;CJK COMPATIBILITY IDEOGRAPH-2F91A;Lo;0;L;70AD;;;;N;;;;; +2F91B;CJK COMPATIBILITY IDEOGRAPH-2F91B;Lo;0;L;20525;;;;N;;;;; +2F91C;CJK COMPATIBILITY IDEOGRAPH-2F91C;Lo;0;L;7145;;;;N;;;;; +2F91D;CJK COMPATIBILITY IDEOGRAPH-2F91D;Lo;0;L;24263;;;;N;;;;; +2F91E;CJK COMPATIBILITY IDEOGRAPH-2F91E;Lo;0;L;719C;;;;N;;;;; +2F91F;CJK COMPATIBILITY IDEOGRAPH-2F91F;Lo;0;L;243AB;;;;N;;;;; +2F920;CJK COMPATIBILITY IDEOGRAPH-2F920;Lo;0;L;7228;;;;N;;;;; +2F921;CJK COMPATIBILITY IDEOGRAPH-2F921;Lo;0;L;7235;;;;N;;;;; +2F922;CJK COMPATIBILITY IDEOGRAPH-2F922;Lo;0;L;7250;;;;N;;;;; +2F923;CJK COMPATIBILITY IDEOGRAPH-2F923;Lo;0;L;24608;;;;N;;;;; +2F924;CJK COMPATIBILITY IDEOGRAPH-2F924;Lo;0;L;7280;;;;N;;;;; +2F925;CJK COMPATIBILITY IDEOGRAPH-2F925;Lo;0;L;7295;;;;N;;;;; +2F926;CJK COMPATIBILITY IDEOGRAPH-2F926;Lo;0;L;24735;;;;N;;;;; +2F927;CJK COMPATIBILITY IDEOGRAPH-2F927;Lo;0;L;24814;;;;N;;;;; +2F928;CJK COMPATIBILITY IDEOGRAPH-2F928;Lo;0;L;737A;;;;N;;;;; +2F929;CJK COMPATIBILITY IDEOGRAPH-2F929;Lo;0;L;738B;;;;N;;;;; +2F92A;CJK COMPATIBILITY IDEOGRAPH-2F92A;Lo;0;L;3EAC;;;;N;;;;; +2F92B;CJK COMPATIBILITY IDEOGRAPH-2F92B;Lo;0;L;73A5;;;;N;;;;; +2F92C;CJK COMPATIBILITY IDEOGRAPH-2F92C;Lo;0;L;3EB8;;;;N;;;;; +2F92D;CJK COMPATIBILITY IDEOGRAPH-2F92D;Lo;0;L;3EB8;;;;N;;;;; +2F92E;CJK COMPATIBILITY IDEOGRAPH-2F92E;Lo;0;L;7447;;;;N;;;;; +2F92F;CJK COMPATIBILITY IDEOGRAPH-2F92F;Lo;0;L;745C;;;;N;;;;; +2F930;CJK COMPATIBILITY IDEOGRAPH-2F930;Lo;0;L;7471;;;;N;;;;; +2F931;CJK COMPATIBILITY IDEOGRAPH-2F931;Lo;0;L;7485;;;;N;;;;; +2F932;CJK COMPATIBILITY IDEOGRAPH-2F932;Lo;0;L;74CA;;;;N;;;;; +2F933;CJK COMPATIBILITY IDEOGRAPH-2F933;Lo;0;L;3F1B;;;;N;;;;; +2F934;CJK COMPATIBILITY IDEOGRAPH-2F934;Lo;0;L;7524;;;;N;;;;; +2F935;CJK COMPATIBILITY IDEOGRAPH-2F935;Lo;0;L;24C36;;;;N;;;;; +2F936;CJK COMPATIBILITY IDEOGRAPH-2F936;Lo;0;L;753E;;;;N;;;;; +2F937;CJK COMPATIBILITY IDEOGRAPH-2F937;Lo;0;L;24C92;;;;N;;;;; +2F938;CJK COMPATIBILITY IDEOGRAPH-2F938;Lo;0;L;7570;;;;N;;;;; +2F939;CJK COMPATIBILITY IDEOGRAPH-2F939;Lo;0;L;2219F;;;;N;;;;; +2F93A;CJK COMPATIBILITY IDEOGRAPH-2F93A;Lo;0;L;7610;;;;N;;;;; +2F93B;CJK COMPATIBILITY IDEOGRAPH-2F93B;Lo;0;L;24FA1;;;;N;;;;; +2F93C;CJK COMPATIBILITY IDEOGRAPH-2F93C;Lo;0;L;24FB8;;;;N;;;;; +2F93D;CJK COMPATIBILITY IDEOGRAPH-2F93D;Lo;0;L;25044;;;;N;;;;; +2F93E;CJK COMPATIBILITY IDEOGRAPH-2F93E;Lo;0;L;3FFC;;;;N;;;;; +2F93F;CJK COMPATIBILITY IDEOGRAPH-2F93F;Lo;0;L;4008;;;;N;;;;; +2F940;CJK COMPATIBILITY IDEOGRAPH-2F940;Lo;0;L;76F4;;;;N;;;;; +2F941;CJK COMPATIBILITY IDEOGRAPH-2F941;Lo;0;L;250F3;;;;N;;;;; +2F942;CJK COMPATIBILITY IDEOGRAPH-2F942;Lo;0;L;250F2;;;;N;;;;; +2F943;CJK COMPATIBILITY IDEOGRAPH-2F943;Lo;0;L;25119;;;;N;;;;; +2F944;CJK COMPATIBILITY IDEOGRAPH-2F944;Lo;0;L;25133;;;;N;;;;; +2F945;CJK COMPATIBILITY IDEOGRAPH-2F945;Lo;0;L;771E;;;;N;;;;; +2F946;CJK COMPATIBILITY IDEOGRAPH-2F946;Lo;0;L;771F;;;;N;;;;; +2F947;CJK COMPATIBILITY IDEOGRAPH-2F947;Lo;0;L;771F;;;;N;;;;; +2F948;CJK COMPATIBILITY IDEOGRAPH-2F948;Lo;0;L;774A;;;;N;;;;; +2F949;CJK COMPATIBILITY IDEOGRAPH-2F949;Lo;0;L;4039;;;;N;;;;; +2F94A;CJK COMPATIBILITY IDEOGRAPH-2F94A;Lo;0;L;778B;;;;N;;;;; +2F94B;CJK COMPATIBILITY IDEOGRAPH-2F94B;Lo;0;L;4046;;;;N;;;;; +2F94C;CJK COMPATIBILITY IDEOGRAPH-2F94C;Lo;0;L;4096;;;;N;;;;; +2F94D;CJK COMPATIBILITY IDEOGRAPH-2F94D;Lo;0;L;2541D;;;;N;;;;; +2F94E;CJK COMPATIBILITY IDEOGRAPH-2F94E;Lo;0;L;784E;;;;N;;;;; +2F94F;CJK COMPATIBILITY IDEOGRAPH-2F94F;Lo;0;L;788C;;;;N;;;;; +2F950;CJK COMPATIBILITY IDEOGRAPH-2F950;Lo;0;L;78CC;;;;N;;;;; +2F951;CJK COMPATIBILITY IDEOGRAPH-2F951;Lo;0;L;40E3;;;;N;;;;; +2F952;CJK COMPATIBILITY IDEOGRAPH-2F952;Lo;0;L;25626;;;;N;;;;; +2F953;CJK COMPATIBILITY IDEOGRAPH-2F953;Lo;0;L;7956;;;;N;;;;; +2F954;CJK COMPATIBILITY IDEOGRAPH-2F954;Lo;0;L;2569A;;;;N;;;;; +2F955;CJK COMPATIBILITY IDEOGRAPH-2F955;Lo;0;L;256C5;;;;N;;;;; +2F956;CJK COMPATIBILITY IDEOGRAPH-2F956;Lo;0;L;798F;;;;N;;;;; +2F957;CJK COMPATIBILITY IDEOGRAPH-2F957;Lo;0;L;79EB;;;;N;;;;; +2F958;CJK COMPATIBILITY IDEOGRAPH-2F958;Lo;0;L;412F;;;;N;;;;; +2F959;CJK COMPATIBILITY IDEOGRAPH-2F959;Lo;0;L;7A40;;;;N;;;;; +2F95A;CJK COMPATIBILITY IDEOGRAPH-2F95A;Lo;0;L;7A4A;;;;N;;;;; +2F95B;CJK COMPATIBILITY IDEOGRAPH-2F95B;Lo;0;L;7A4F;;;;N;;;;; +2F95C;CJK COMPATIBILITY IDEOGRAPH-2F95C;Lo;0;L;2597C;;;;N;;;;; +2F95D;CJK COMPATIBILITY IDEOGRAPH-2F95D;Lo;0;L;25AA7;;;;N;;;;; +2F95E;CJK COMPATIBILITY IDEOGRAPH-2F95E;Lo;0;L;25AA7;;;;N;;;;; +2F95F;CJK COMPATIBILITY IDEOGRAPH-2F95F;Lo;0;L;7AEE;;;;N;;;;; +2F960;CJK COMPATIBILITY IDEOGRAPH-2F960;Lo;0;L;4202;;;;N;;;;; +2F961;CJK COMPATIBILITY IDEOGRAPH-2F961;Lo;0;L;25BAB;;;;N;;;;; +2F962;CJK COMPATIBILITY IDEOGRAPH-2F962;Lo;0;L;7BC6;;;;N;;;;; +2F963;CJK COMPATIBILITY IDEOGRAPH-2F963;Lo;0;L;7BC9;;;;N;;;;; +2F964;CJK COMPATIBILITY IDEOGRAPH-2F964;Lo;0;L;4227;;;;N;;;;; +2F965;CJK COMPATIBILITY IDEOGRAPH-2F965;Lo;0;L;25C80;;;;N;;;;; +2F966;CJK COMPATIBILITY IDEOGRAPH-2F966;Lo;0;L;7CD2;;;;N;;;;; +2F967;CJK COMPATIBILITY IDEOGRAPH-2F967;Lo;0;L;42A0;;;;N;;;;; +2F968;CJK COMPATIBILITY IDEOGRAPH-2F968;Lo;0;L;7CE8;;;;N;;;;; +2F969;CJK COMPATIBILITY IDEOGRAPH-2F969;Lo;0;L;7CE3;;;;N;;;;; +2F96A;CJK COMPATIBILITY IDEOGRAPH-2F96A;Lo;0;L;7D00;;;;N;;;;; +2F96B;CJK COMPATIBILITY IDEOGRAPH-2F96B;Lo;0;L;25F86;;;;N;;;;; +2F96C;CJK COMPATIBILITY IDEOGRAPH-2F96C;Lo;0;L;7D63;;;;N;;;;; +2F96D;CJK COMPATIBILITY IDEOGRAPH-2F96D;Lo;0;L;4301;;;;N;;;;; +2F96E;CJK COMPATIBILITY IDEOGRAPH-2F96E;Lo;0;L;7DC7;;;;N;;;;; +2F96F;CJK COMPATIBILITY IDEOGRAPH-2F96F;Lo;0;L;7E02;;;;N;;;;; +2F970;CJK COMPATIBILITY IDEOGRAPH-2F970;Lo;0;L;7E45;;;;N;;;;; +2F971;CJK COMPATIBILITY IDEOGRAPH-2F971;Lo;0;L;4334;;;;N;;;;; +2F972;CJK COMPATIBILITY IDEOGRAPH-2F972;Lo;0;L;26228;;;;N;;;;; +2F973;CJK COMPATIBILITY IDEOGRAPH-2F973;Lo;0;L;26247;;;;N;;;;; +2F974;CJK COMPATIBILITY IDEOGRAPH-2F974;Lo;0;L;4359;;;;N;;;;; +2F975;CJK COMPATIBILITY IDEOGRAPH-2F975;Lo;0;L;262D9;;;;N;;;;; +2F976;CJK COMPATIBILITY IDEOGRAPH-2F976;Lo;0;L;7F7A;;;;N;;;;; +2F977;CJK COMPATIBILITY IDEOGRAPH-2F977;Lo;0;L;2633E;;;;N;;;;; +2F978;CJK COMPATIBILITY IDEOGRAPH-2F978;Lo;0;L;7F95;;;;N;;;;; +2F979;CJK COMPATIBILITY IDEOGRAPH-2F979;Lo;0;L;7FFA;;;;N;;;;; +2F97A;CJK COMPATIBILITY IDEOGRAPH-2F97A;Lo;0;L;8005;;;;N;;;;; +2F97B;CJK COMPATIBILITY IDEOGRAPH-2F97B;Lo;0;L;264DA;;;;N;;;;; +2F97C;CJK COMPATIBILITY IDEOGRAPH-2F97C;Lo;0;L;26523;;;;N;;;;; +2F97D;CJK COMPATIBILITY IDEOGRAPH-2F97D;Lo;0;L;8060;;;;N;;;;; +2F97E;CJK COMPATIBILITY IDEOGRAPH-2F97E;Lo;0;L;265A8;;;;N;;;;; +2F97F;CJK COMPATIBILITY IDEOGRAPH-2F97F;Lo;0;L;8070;;;;N;;;;; +2F980;CJK COMPATIBILITY IDEOGRAPH-2F980;Lo;0;L;2335F;;;;N;;;;; +2F981;CJK COMPATIBILITY IDEOGRAPH-2F981;Lo;0;L;43D5;;;;N;;;;; +2F982;CJK COMPATIBILITY IDEOGRAPH-2F982;Lo;0;L;80B2;;;;N;;;;; +2F983;CJK COMPATIBILITY IDEOGRAPH-2F983;Lo;0;L;8103;;;;N;;;;; +2F984;CJK COMPATIBILITY IDEOGRAPH-2F984;Lo;0;L;440B;;;;N;;;;; +2F985;CJK COMPATIBILITY IDEOGRAPH-2F985;Lo;0;L;813E;;;;N;;;;; +2F986;CJK COMPATIBILITY IDEOGRAPH-2F986;Lo;0;L;5AB5;;;;N;;;;; +2F987;CJK COMPATIBILITY IDEOGRAPH-2F987;Lo;0;L;267A7;;;;N;;;;; +2F988;CJK COMPATIBILITY IDEOGRAPH-2F988;Lo;0;L;267B5;;;;N;;;;; +2F989;CJK COMPATIBILITY IDEOGRAPH-2F989;Lo;0;L;23393;;;;N;;;;; +2F98A;CJK COMPATIBILITY IDEOGRAPH-2F98A;Lo;0;L;2339C;;;;N;;;;; +2F98B;CJK COMPATIBILITY IDEOGRAPH-2F98B;Lo;0;L;8201;;;;N;;;;; +2F98C;CJK COMPATIBILITY IDEOGRAPH-2F98C;Lo;0;L;8204;;;;N;;;;; +2F98D;CJK COMPATIBILITY IDEOGRAPH-2F98D;Lo;0;L;8F9E;;;;N;;;;; +2F98E;CJK COMPATIBILITY IDEOGRAPH-2F98E;Lo;0;L;446B;;;;N;;;;; +2F98F;CJK COMPATIBILITY IDEOGRAPH-2F98F;Lo;0;L;8291;;;;N;;;;; +2F990;CJK COMPATIBILITY IDEOGRAPH-2F990;Lo;0;L;828B;;;;N;;;;; +2F991;CJK COMPATIBILITY IDEOGRAPH-2F991;Lo;0;L;829D;;;;N;;;;; +2F992;CJK COMPATIBILITY IDEOGRAPH-2F992;Lo;0;L;52B3;;;;N;;;;; +2F993;CJK COMPATIBILITY IDEOGRAPH-2F993;Lo;0;L;82B1;;;;N;;;;; +2F994;CJK COMPATIBILITY IDEOGRAPH-2F994;Lo;0;L;82B3;;;;N;;;;; +2F995;CJK COMPATIBILITY IDEOGRAPH-2F995;Lo;0;L;82BD;;;;N;;;;; +2F996;CJK COMPATIBILITY IDEOGRAPH-2F996;Lo;0;L;82E6;;;;N;;;;; +2F997;CJK COMPATIBILITY IDEOGRAPH-2F997;Lo;0;L;26B3C;;;;N;;;;; +2F998;CJK COMPATIBILITY IDEOGRAPH-2F998;Lo;0;L;82E5;;;;N;;;;; +2F999;CJK COMPATIBILITY IDEOGRAPH-2F999;Lo;0;L;831D;;;;N;;;;; +2F99A;CJK COMPATIBILITY IDEOGRAPH-2F99A;Lo;0;L;8363;;;;N;;;;; +2F99B;CJK COMPATIBILITY IDEOGRAPH-2F99B;Lo;0;L;83AD;;;;N;;;;; +2F99C;CJK COMPATIBILITY IDEOGRAPH-2F99C;Lo;0;L;8323;;;;N;;;;; +2F99D;CJK COMPATIBILITY IDEOGRAPH-2F99D;Lo;0;L;83BD;;;;N;;;;; +2F99E;CJK COMPATIBILITY IDEOGRAPH-2F99E;Lo;0;L;83E7;;;;N;;;;; +2F99F;CJK COMPATIBILITY IDEOGRAPH-2F99F;Lo;0;L;8457;;;;N;;;;; +2F9A0;CJK COMPATIBILITY IDEOGRAPH-2F9A0;Lo;0;L;8353;;;;N;;;;; +2F9A1;CJK COMPATIBILITY IDEOGRAPH-2F9A1;Lo;0;L;83CA;;;;N;;;;; +2F9A2;CJK COMPATIBILITY IDEOGRAPH-2F9A2;Lo;0;L;83CC;;;;N;;;;; +2F9A3;CJK COMPATIBILITY IDEOGRAPH-2F9A3;Lo;0;L;83DC;;;;N;;;;; +2F9A4;CJK COMPATIBILITY IDEOGRAPH-2F9A4;Lo;0;L;26C36;;;;N;;;;; +2F9A5;CJK COMPATIBILITY IDEOGRAPH-2F9A5;Lo;0;L;26D6B;;;;N;;;;; +2F9A6;CJK COMPATIBILITY IDEOGRAPH-2F9A6;Lo;0;L;26CD5;;;;N;;;;; +2F9A7;CJK COMPATIBILITY IDEOGRAPH-2F9A7;Lo;0;L;452B;;;;N;;;;; +2F9A8;CJK COMPATIBILITY IDEOGRAPH-2F9A8;Lo;0;L;84F1;;;;N;;;;; +2F9A9;CJK COMPATIBILITY IDEOGRAPH-2F9A9;Lo;0;L;84F3;;;;N;;;;; +2F9AA;CJK COMPATIBILITY IDEOGRAPH-2F9AA;Lo;0;L;8516;;;;N;;;;; +2F9AB;CJK COMPATIBILITY IDEOGRAPH-2F9AB;Lo;0;L;273CA;;;;N;;;;; +2F9AC;CJK COMPATIBILITY IDEOGRAPH-2F9AC;Lo;0;L;8564;;;;N;;;;; +2F9AD;CJK COMPATIBILITY IDEOGRAPH-2F9AD;Lo;0;L;26F2C;;;;N;;;;; +2F9AE;CJK COMPATIBILITY IDEOGRAPH-2F9AE;Lo;0;L;455D;;;;N;;;;; +2F9AF;CJK COMPATIBILITY IDEOGRAPH-2F9AF;Lo;0;L;4561;;;;N;;;;; +2F9B0;CJK COMPATIBILITY IDEOGRAPH-2F9B0;Lo;0;L;26FB1;;;;N;;;;; +2F9B1;CJK COMPATIBILITY IDEOGRAPH-2F9B1;Lo;0;L;270D2;;;;N;;;;; +2F9B2;CJK COMPATIBILITY IDEOGRAPH-2F9B2;Lo;0;L;456B;;;;N;;;;; +2F9B3;CJK COMPATIBILITY IDEOGRAPH-2F9B3;Lo;0;L;8650;;;;N;;;;; +2F9B4;CJK COMPATIBILITY IDEOGRAPH-2F9B4;Lo;0;L;865C;;;;N;;;;; +2F9B5;CJK COMPATIBILITY IDEOGRAPH-2F9B5;Lo;0;L;8667;;;;N;;;;; +2F9B6;CJK COMPATIBILITY IDEOGRAPH-2F9B6;Lo;0;L;8669;;;;N;;;;; +2F9B7;CJK COMPATIBILITY IDEOGRAPH-2F9B7;Lo;0;L;86A9;;;;N;;;;; +2F9B8;CJK COMPATIBILITY IDEOGRAPH-2F9B8;Lo;0;L;8688;;;;N;;;;; +2F9B9;CJK COMPATIBILITY IDEOGRAPH-2F9B9;Lo;0;L;870E;;;;N;;;;; +2F9BA;CJK COMPATIBILITY IDEOGRAPH-2F9BA;Lo;0;L;86E2;;;;N;;;;; +2F9BB;CJK COMPATIBILITY IDEOGRAPH-2F9BB;Lo;0;L;8779;;;;N;;;;; +2F9BC;CJK COMPATIBILITY IDEOGRAPH-2F9BC;Lo;0;L;8728;;;;N;;;;; +2F9BD;CJK COMPATIBILITY IDEOGRAPH-2F9BD;Lo;0;L;876B;;;;N;;;;; +2F9BE;CJK COMPATIBILITY IDEOGRAPH-2F9BE;Lo;0;L;8786;;;;N;;;;; +2F9BF;CJK COMPATIBILITY IDEOGRAPH-2F9BF;Lo;0;L;45D7;;;;N;;;;; +2F9C0;CJK COMPATIBILITY IDEOGRAPH-2F9C0;Lo;0;L;87E1;;;;N;;;;; +2F9C1;CJK COMPATIBILITY IDEOGRAPH-2F9C1;Lo;0;L;8801;;;;N;;;;; +2F9C2;CJK COMPATIBILITY IDEOGRAPH-2F9C2;Lo;0;L;45F9;;;;N;;;;; +2F9C3;CJK COMPATIBILITY IDEOGRAPH-2F9C3;Lo;0;L;8860;;;;N;;;;; +2F9C4;CJK COMPATIBILITY IDEOGRAPH-2F9C4;Lo;0;L;8863;;;;N;;;;; +2F9C5;CJK COMPATIBILITY IDEOGRAPH-2F9C5;Lo;0;L;27667;;;;N;;;;; +2F9C6;CJK COMPATIBILITY IDEOGRAPH-2F9C6;Lo;0;L;88D7;;;;N;;;;; +2F9C7;CJK COMPATIBILITY IDEOGRAPH-2F9C7;Lo;0;L;88DE;;;;N;;;;; +2F9C8;CJK COMPATIBILITY IDEOGRAPH-2F9C8;Lo;0;L;4635;;;;N;;;;; +2F9C9;CJK COMPATIBILITY IDEOGRAPH-2F9C9;Lo;0;L;88FA;;;;N;;;;; +2F9CA;CJK COMPATIBILITY IDEOGRAPH-2F9CA;Lo;0;L;34BB;;;;N;;;;; +2F9CB;CJK COMPATIBILITY IDEOGRAPH-2F9CB;Lo;0;L;278AE;;;;N;;;;; +2F9CC;CJK COMPATIBILITY IDEOGRAPH-2F9CC;Lo;0;L;27966;;;;N;;;;; +2F9CD;CJK COMPATIBILITY IDEOGRAPH-2F9CD;Lo;0;L;46BE;;;;N;;;;; +2F9CE;CJK COMPATIBILITY IDEOGRAPH-2F9CE;Lo;0;L;46C7;;;;N;;;;; +2F9CF;CJK COMPATIBILITY IDEOGRAPH-2F9CF;Lo;0;L;8AA0;;;;N;;;;; +2F9D0;CJK COMPATIBILITY IDEOGRAPH-2F9D0;Lo;0;L;8AED;;;;N;;;;; +2F9D1;CJK COMPATIBILITY IDEOGRAPH-2F9D1;Lo;0;L;8B8A;;;;N;;;;; +2F9D2;CJK COMPATIBILITY IDEOGRAPH-2F9D2;Lo;0;L;8C55;;;;N;;;;; +2F9D3;CJK COMPATIBILITY IDEOGRAPH-2F9D3;Lo;0;L;27CA8;;;;N;;;;; +2F9D4;CJK COMPATIBILITY IDEOGRAPH-2F9D4;Lo;0;L;8CAB;;;;N;;;;; +2F9D5;CJK COMPATIBILITY IDEOGRAPH-2F9D5;Lo;0;L;8CC1;;;;N;;;;; +2F9D6;CJK COMPATIBILITY IDEOGRAPH-2F9D6;Lo;0;L;8D1B;;;;N;;;;; +2F9D7;CJK COMPATIBILITY IDEOGRAPH-2F9D7;Lo;0;L;8D77;;;;N;;;;; +2F9D8;CJK COMPATIBILITY IDEOGRAPH-2F9D8;Lo;0;L;27F2F;;;;N;;;;; +2F9D9;CJK COMPATIBILITY IDEOGRAPH-2F9D9;Lo;0;L;20804;;;;N;;;;; +2F9DA;CJK COMPATIBILITY IDEOGRAPH-2F9DA;Lo;0;L;8DCB;;;;N;;;;; +2F9DB;CJK COMPATIBILITY IDEOGRAPH-2F9DB;Lo;0;L;8DBC;;;;N;;;;; +2F9DC;CJK COMPATIBILITY IDEOGRAPH-2F9DC;Lo;0;L;8DF0;;;;N;;;;; +2F9DD;CJK COMPATIBILITY IDEOGRAPH-2F9DD;Lo;0;L;208DE;;;;N;;;;; +2F9DE;CJK COMPATIBILITY IDEOGRAPH-2F9DE;Lo;0;L;8ED4;;;;N;;;;; +2F9DF;CJK COMPATIBILITY IDEOGRAPH-2F9DF;Lo;0;L;8F38;;;;N;;;;; +2F9E0;CJK COMPATIBILITY IDEOGRAPH-2F9E0;Lo;0;L;285D2;;;;N;;;;; +2F9E1;CJK COMPATIBILITY IDEOGRAPH-2F9E1;Lo;0;L;285ED;;;;N;;;;; +2F9E2;CJK COMPATIBILITY IDEOGRAPH-2F9E2;Lo;0;L;9094;;;;N;;;;; +2F9E3;CJK COMPATIBILITY IDEOGRAPH-2F9E3;Lo;0;L;90F1;;;;N;;;;; +2F9E4;CJK COMPATIBILITY IDEOGRAPH-2F9E4;Lo;0;L;9111;;;;N;;;;; +2F9E5;CJK COMPATIBILITY IDEOGRAPH-2F9E5;Lo;0;L;2872E;;;;N;;;;; +2F9E6;CJK COMPATIBILITY IDEOGRAPH-2F9E6;Lo;0;L;911B;;;;N;;;;; +2F9E7;CJK COMPATIBILITY IDEOGRAPH-2F9E7;Lo;0;L;9238;;;;N;;;;; +2F9E8;CJK COMPATIBILITY IDEOGRAPH-2F9E8;Lo;0;L;92D7;;;;N;;;;; +2F9E9;CJK COMPATIBILITY IDEOGRAPH-2F9E9;Lo;0;L;92D8;;;;N;;;;; +2F9EA;CJK COMPATIBILITY IDEOGRAPH-2F9EA;Lo;0;L;927C;;;;N;;;;; +2F9EB;CJK COMPATIBILITY IDEOGRAPH-2F9EB;Lo;0;L;93F9;;;;N;;;;; +2F9EC;CJK COMPATIBILITY IDEOGRAPH-2F9EC;Lo;0;L;9415;;;;N;;;;; +2F9ED;CJK COMPATIBILITY IDEOGRAPH-2F9ED;Lo;0;L;28BFA;;;;N;;;;; +2F9EE;CJK COMPATIBILITY IDEOGRAPH-2F9EE;Lo;0;L;958B;;;;N;;;;; +2F9EF;CJK COMPATIBILITY IDEOGRAPH-2F9EF;Lo;0;L;4995;;;;N;;;;; +2F9F0;CJK COMPATIBILITY IDEOGRAPH-2F9F0;Lo;0;L;95B7;;;;N;;;;; +2F9F1;CJK COMPATIBILITY IDEOGRAPH-2F9F1;Lo;0;L;28D77;;;;N;;;;; +2F9F2;CJK COMPATIBILITY IDEOGRAPH-2F9F2;Lo;0;L;49E6;;;;N;;;;; +2F9F3;CJK COMPATIBILITY IDEOGRAPH-2F9F3;Lo;0;L;96C3;;;;N;;;;; +2F9F4;CJK COMPATIBILITY IDEOGRAPH-2F9F4;Lo;0;L;5DB2;;;;N;;;;; +2F9F5;CJK COMPATIBILITY IDEOGRAPH-2F9F5;Lo;0;L;9723;;;;N;;;;; +2F9F6;CJK COMPATIBILITY IDEOGRAPH-2F9F6;Lo;0;L;29145;;;;N;;;;; +2F9F7;CJK COMPATIBILITY IDEOGRAPH-2F9F7;Lo;0;L;2921A;;;;N;;;;; +2F9F8;CJK COMPATIBILITY IDEOGRAPH-2F9F8;Lo;0;L;4A6E;;;;N;;;;; +2F9F9;CJK COMPATIBILITY IDEOGRAPH-2F9F9;Lo;0;L;4A76;;;;N;;;;; +2F9FA;CJK COMPATIBILITY IDEOGRAPH-2F9FA;Lo;0;L;97E0;;;;N;;;;; +2F9FB;CJK COMPATIBILITY IDEOGRAPH-2F9FB;Lo;0;L;2940A;;;;N;;;;; +2F9FC;CJK COMPATIBILITY IDEOGRAPH-2F9FC;Lo;0;L;4AB2;;;;N;;;;; +2F9FD;CJK COMPATIBILITY IDEOGRAPH-2F9FD;Lo;0;L;29496;;;;N;;;;; +2F9FE;CJK COMPATIBILITY IDEOGRAPH-2F9FE;Lo;0;L;980B;;;;N;;;;; +2F9FF;CJK COMPATIBILITY IDEOGRAPH-2F9FF;Lo;0;L;980B;;;;N;;;;; +2FA00;CJK COMPATIBILITY IDEOGRAPH-2FA00;Lo;0;L;9829;;;;N;;;;; +2FA01;CJK COMPATIBILITY IDEOGRAPH-2FA01;Lo;0;L;295B6;;;;N;;;;; +2FA02;CJK COMPATIBILITY IDEOGRAPH-2FA02;Lo;0;L;98E2;;;;N;;;;; +2FA03;CJK COMPATIBILITY IDEOGRAPH-2FA03;Lo;0;L;4B33;;;;N;;;;; +2FA04;CJK COMPATIBILITY IDEOGRAPH-2FA04;Lo;0;L;9929;;;;N;;;;; +2FA05;CJK COMPATIBILITY IDEOGRAPH-2FA05;Lo;0;L;99A7;;;;N;;;;; +2FA06;CJK COMPATIBILITY IDEOGRAPH-2FA06;Lo;0;L;99C2;;;;N;;;;; +2FA07;CJK COMPATIBILITY IDEOGRAPH-2FA07;Lo;0;L;99FE;;;;N;;;;; +2FA08;CJK COMPATIBILITY IDEOGRAPH-2FA08;Lo;0;L;4BCE;;;;N;;;;; +2FA09;CJK COMPATIBILITY IDEOGRAPH-2FA09;Lo;0;L;29B30;;;;N;;;;; +2FA0A;CJK COMPATIBILITY IDEOGRAPH-2FA0A;Lo;0;L;9B12;;;;N;;;;; +2FA0B;CJK COMPATIBILITY IDEOGRAPH-2FA0B;Lo;0;L;9C40;;;;N;;;;; +2FA0C;CJK COMPATIBILITY IDEOGRAPH-2FA0C;Lo;0;L;9CFD;;;;N;;;;; +2FA0D;CJK COMPATIBILITY IDEOGRAPH-2FA0D;Lo;0;L;4CCE;;;;N;;;;; +2FA0E;CJK COMPATIBILITY IDEOGRAPH-2FA0E;Lo;0;L;4CED;;;;N;;;;; +2FA0F;CJK COMPATIBILITY IDEOGRAPH-2FA0F;Lo;0;L;9D67;;;;N;;;;; +2FA10;CJK COMPATIBILITY IDEOGRAPH-2FA10;Lo;0;L;2A0CE;;;;N;;;;; +2FA11;CJK COMPATIBILITY IDEOGRAPH-2FA11;Lo;0;L;4CF8;;;;N;;;;; +2FA12;CJK COMPATIBILITY IDEOGRAPH-2FA12;Lo;0;L;2A105;;;;N;;;;; +2FA13;CJK COMPATIBILITY IDEOGRAPH-2FA13;Lo;0;L;2A20E;;;;N;;;;; +2FA14;CJK COMPATIBILITY IDEOGRAPH-2FA14;Lo;0;L;2A291;;;;N;;;;; +2FA15;CJK COMPATIBILITY IDEOGRAPH-2FA15;Lo;0;L;9EBB;;;;N;;;;; +2FA16;CJK COMPATIBILITY IDEOGRAPH-2FA16;Lo;0;L;4D56;;;;N;;;;; +2FA17;CJK COMPATIBILITY IDEOGRAPH-2FA17;Lo;0;L;9EF9;;;;N;;;;; +2FA18;CJK COMPATIBILITY IDEOGRAPH-2FA18;Lo;0;L;9EFE;;;;N;;;;; +2FA19;CJK COMPATIBILITY IDEOGRAPH-2FA19;Lo;0;L;9F05;;;;N;;;;; +2FA1A;CJK COMPATIBILITY IDEOGRAPH-2FA1A;Lo;0;L;9F0F;;;;N;;;;; +2FA1B;CJK COMPATIBILITY IDEOGRAPH-2FA1B;Lo;0;L;9F16;;;;N;;;;; +2FA1C;CJK COMPATIBILITY IDEOGRAPH-2FA1C;Lo;0;L;9F3B;;;;N;;;;; +2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;; +E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;; +E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;; +E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;; +E0022;TAG QUOTATION MARK;Cf;0;BN;;;;;N;;;;; +E0023;TAG NUMBER SIGN;Cf;0;BN;;;;;N;;;;; +E0024;TAG DOLLAR SIGN;Cf;0;BN;;;;;N;;;;; +E0025;TAG PERCENT SIGN;Cf;0;BN;;;;;N;;;;; +E0026;TAG AMPERSAND;Cf;0;BN;;;;;N;;;;; +E0027;TAG APOSTROPHE;Cf;0;BN;;;;;N;;;;; +E0028;TAG LEFT PARENTHESIS;Cf;0;BN;;;;;N;;;;; +E0029;TAG RIGHT PARENTHESIS;Cf;0;BN;;;;;N;;;;; +E002A;TAG ASTERISK;Cf;0;BN;;;;;N;;;;; +E002B;TAG PLUS SIGN;Cf;0;BN;;;;;N;;;;; +E002C;TAG COMMA;Cf;0;BN;;;;;N;;;;; +E002D;TAG HYPHEN-MINUS;Cf;0;BN;;;;;N;;;;; +E002E;TAG FULL STOP;Cf;0;BN;;;;;N;;;;; +E002F;TAG SOLIDUS;Cf;0;BN;;;;;N;;;;; +E0030;TAG DIGIT ZERO;Cf;0;BN;;;;;N;;;;; +E0031;TAG DIGIT ONE;Cf;0;BN;;;;;N;;;;; +E0032;TAG DIGIT TWO;Cf;0;BN;;;;;N;;;;; +E0033;TAG DIGIT THREE;Cf;0;BN;;;;;N;;;;; +E0034;TAG DIGIT FOUR;Cf;0;BN;;;;;N;;;;; +E0035;TAG DIGIT FIVE;Cf;0;BN;;;;;N;;;;; +E0036;TAG DIGIT SIX;Cf;0;BN;;;;;N;;;;; +E0037;TAG DIGIT SEVEN;Cf;0;BN;;;;;N;;;;; +E0038;TAG DIGIT EIGHT;Cf;0;BN;;;;;N;;;;; +E0039;TAG DIGIT NINE;Cf;0;BN;;;;;N;;;;; +E003A;TAG COLON;Cf;0;BN;;;;;N;;;;; +E003B;TAG SEMICOLON;Cf;0;BN;;;;;N;;;;; +E003C;TAG LESS-THAN SIGN;Cf;0;BN;;;;;N;;;;; +E003D;TAG EQUALS SIGN;Cf;0;BN;;;;;N;;;;; +E003E;TAG GREATER-THAN SIGN;Cf;0;BN;;;;;N;;;;; +E003F;TAG QUESTION MARK;Cf;0;BN;;;;;N;;;;; +E0040;TAG COMMERCIAL AT;Cf;0;BN;;;;;N;;;;; +E0041;TAG LATIN CAPITAL LETTER A;Cf;0;BN;;;;;N;;;;; +E0042;TAG LATIN CAPITAL LETTER B;Cf;0;BN;;;;;N;;;;; +E0043;TAG LATIN CAPITAL LETTER C;Cf;0;BN;;;;;N;;;;; +E0044;TAG LATIN CAPITAL LETTER D;Cf;0;BN;;;;;N;;;;; +E0045;TAG LATIN CAPITAL LETTER E;Cf;0;BN;;;;;N;;;;; +E0046;TAG LATIN CAPITAL LETTER F;Cf;0;BN;;;;;N;;;;; +E0047;TAG LATIN CAPITAL LETTER G;Cf;0;BN;;;;;N;;;;; +E0048;TAG LATIN CAPITAL LETTER H;Cf;0;BN;;;;;N;;;;; +E0049;TAG LATIN CAPITAL LETTER I;Cf;0;BN;;;;;N;;;;; +E004A;TAG LATIN CAPITAL LETTER J;Cf;0;BN;;;;;N;;;;; +E004B;TAG LATIN CAPITAL LETTER K;Cf;0;BN;;;;;N;;;;; +E004C;TAG LATIN CAPITAL LETTER L;Cf;0;BN;;;;;N;;;;; +E004D;TAG LATIN CAPITAL LETTER M;Cf;0;BN;;;;;N;;;;; +E004E;TAG LATIN CAPITAL LETTER N;Cf;0;BN;;;;;N;;;;; +E004F;TAG LATIN CAPITAL LETTER O;Cf;0;BN;;;;;N;;;;; +E0050;TAG LATIN CAPITAL LETTER P;Cf;0;BN;;;;;N;;;;; +E0051;TAG LATIN CAPITAL LETTER Q;Cf;0;BN;;;;;N;;;;; +E0052;TAG LATIN CAPITAL LETTER R;Cf;0;BN;;;;;N;;;;; +E0053;TAG LATIN CAPITAL LETTER S;Cf;0;BN;;;;;N;;;;; +E0054;TAG LATIN CAPITAL LETTER T;Cf;0;BN;;;;;N;;;;; +E0055;TAG LATIN CAPITAL LETTER U;Cf;0;BN;;;;;N;;;;; +E0056;TAG LATIN CAPITAL LETTER V;Cf;0;BN;;;;;N;;;;; +E0057;TAG LATIN CAPITAL LETTER W;Cf;0;BN;;;;;N;;;;; +E0058;TAG LATIN CAPITAL LETTER X;Cf;0;BN;;;;;N;;;;; +E0059;TAG LATIN CAPITAL LETTER Y;Cf;0;BN;;;;;N;;;;; +E005A;TAG LATIN CAPITAL LETTER Z;Cf;0;BN;;;;;N;;;;; +E005B;TAG LEFT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;; +E005C;TAG REVERSE SOLIDUS;Cf;0;BN;;;;;N;;;;; +E005D;TAG RIGHT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;; +E005E;TAG CIRCUMFLEX ACCENT;Cf;0;BN;;;;;N;;;;; +E005F;TAG LOW LINE;Cf;0;BN;;;;;N;;;;; +E0060;TAG GRAVE ACCENT;Cf;0;BN;;;;;N;;;;; +E0061;TAG LATIN SMALL LETTER A;Cf;0;BN;;;;;N;;;;; +E0062;TAG LATIN SMALL LETTER B;Cf;0;BN;;;;;N;;;;; +E0063;TAG LATIN SMALL LETTER C;Cf;0;BN;;;;;N;;;;; +E0064;TAG LATIN SMALL LETTER D;Cf;0;BN;;;;;N;;;;; +E0065;TAG LATIN SMALL LETTER E;Cf;0;BN;;;;;N;;;;; +E0066;TAG LATIN SMALL LETTER F;Cf;0;BN;;;;;N;;;;; +E0067;TAG LATIN SMALL LETTER G;Cf;0;BN;;;;;N;;;;; +E0068;TAG LATIN SMALL LETTER H;Cf;0;BN;;;;;N;;;;; +E0069;TAG LATIN SMALL LETTER I;Cf;0;BN;;;;;N;;;;; +E006A;TAG LATIN SMALL LETTER J;Cf;0;BN;;;;;N;;;;; +E006B;TAG LATIN SMALL LETTER K;Cf;0;BN;;;;;N;;;;; +E006C;TAG LATIN SMALL LETTER L;Cf;0;BN;;;;;N;;;;; +E006D;TAG LATIN SMALL LETTER M;Cf;0;BN;;;;;N;;;;; +E006E;TAG LATIN SMALL LETTER N;Cf;0;BN;;;;;N;;;;; +E006F;TAG LATIN SMALL LETTER O;Cf;0;BN;;;;;N;;;;; +E0070;TAG LATIN SMALL LETTER P;Cf;0;BN;;;;;N;;;;; +E0071;TAG LATIN SMALL LETTER Q;Cf;0;BN;;;;;N;;;;; +E0072;TAG LATIN SMALL LETTER R;Cf;0;BN;;;;;N;;;;; +E0073;TAG LATIN SMALL LETTER S;Cf;0;BN;;;;;N;;;;; +E0074;TAG LATIN SMALL LETTER T;Cf;0;BN;;;;;N;;;;; +E0075;TAG LATIN SMALL LETTER U;Cf;0;BN;;;;;N;;;;; +E0076;TAG LATIN SMALL LETTER V;Cf;0;BN;;;;;N;;;;; +E0077;TAG LATIN SMALL LETTER W;Cf;0;BN;;;;;N;;;;; +E0078;TAG LATIN SMALL LETTER X;Cf;0;BN;;;;;N;;;;; +E0079;TAG LATIN SMALL LETTER Y;Cf;0;BN;;;;;N;;;;; +E007A;TAG LATIN SMALL LETTER Z;Cf;0;BN;;;;;N;;;;; +E007B;TAG LEFT CURLY BRACKET;Cf;0;BN;;;;;N;;;;; +E007C;TAG VERTICAL LINE;Cf;0;BN;;;;;N;;;;; +E007D;TAG RIGHT CURLY BRACKET;Cf;0;BN;;;;;N;;;;; +E007E;TAG TILDE;Cf;0;BN;;;;;N;;;;; +E007F;CANCEL TAG;Cf;0;BN;;;;;N;;;;; +E0100;VARIATION SELECTOR-17;Mn;0;NSM;;;;;N;;;;; +E0101;VARIATION SELECTOR-18;Mn;0;NSM;;;;;N;;;;; +E0102;VARIATION SELECTOR-19;Mn;0;NSM;;;;;N;;;;; +E0103;VARIATION SELECTOR-20;Mn;0;NSM;;;;;N;;;;; +E0104;VARIATION SELECTOR-21;Mn;0;NSM;;;;;N;;;;; +E0105;VARIATION SELECTOR-22;Mn;0;NSM;;;;;N;;;;; +E0106;VARIATION SELECTOR-23;Mn;0;NSM;;;;;N;;;;; +E0107;VARIATION SELECTOR-24;Mn;0;NSM;;;;;N;;;;; +E0108;VARIATION SELECTOR-25;Mn;0;NSM;;;;;N;;;;; +E0109;VARIATION SELECTOR-26;Mn;0;NSM;;;;;N;;;;; +E010A;VARIATION SELECTOR-27;Mn;0;NSM;;;;;N;;;;; +E010B;VARIATION SELECTOR-28;Mn;0;NSM;;;;;N;;;;; +E010C;VARIATION SELECTOR-29;Mn;0;NSM;;;;;N;;;;; +E010D;VARIATION SELECTOR-30;Mn;0;NSM;;;;;N;;;;; +E010E;VARIATION SELECTOR-31;Mn;0;NSM;;;;;N;;;;; +E010F;VARIATION SELECTOR-32;Mn;0;NSM;;;;;N;;;;; +E0110;VARIATION SELECTOR-33;Mn;0;NSM;;;;;N;;;;; +E0111;VARIATION SELECTOR-34;Mn;0;NSM;;;;;N;;;;; +E0112;VARIATION SELECTOR-35;Mn;0;NSM;;;;;N;;;;; +E0113;VARIATION SELECTOR-36;Mn;0;NSM;;;;;N;;;;; +E0114;VARIATION SELECTOR-37;Mn;0;NSM;;;;;N;;;;; +E0115;VARIATION SELECTOR-38;Mn;0;NSM;;;;;N;;;;; +E0116;VARIATION SELECTOR-39;Mn;0;NSM;;;;;N;;;;; +E0117;VARIATION SELECTOR-40;Mn;0;NSM;;;;;N;;;;; +E0118;VARIATION SELECTOR-41;Mn;0;NSM;;;;;N;;;;; +E0119;VARIATION SELECTOR-42;Mn;0;NSM;;;;;N;;;;; +E011A;VARIATION SELECTOR-43;Mn;0;NSM;;;;;N;;;;; +E011B;VARIATION SELECTOR-44;Mn;0;NSM;;;;;N;;;;; +E011C;VARIATION SELECTOR-45;Mn;0;NSM;;;;;N;;;;; +E011D;VARIATION SELECTOR-46;Mn;0;NSM;;;;;N;;;;; +E011E;VARIATION SELECTOR-47;Mn;0;NSM;;;;;N;;;;; +E011F;VARIATION SELECTOR-48;Mn;0;NSM;;;;;N;;;;; +E0120;VARIATION SELECTOR-49;Mn;0;NSM;;;;;N;;;;; +E0121;VARIATION SELECTOR-50;Mn;0;NSM;;;;;N;;;;; +E0122;VARIATION SELECTOR-51;Mn;0;NSM;;;;;N;;;;; +E0123;VARIATION SELECTOR-52;Mn;0;NSM;;;;;N;;;;; +E0124;VARIATION SELECTOR-53;Mn;0;NSM;;;;;N;;;;; +E0125;VARIATION SELECTOR-54;Mn;0;NSM;;;;;N;;;;; +E0126;VARIATION SELECTOR-55;Mn;0;NSM;;;;;N;;;;; +E0127;VARIATION SELECTOR-56;Mn;0;NSM;;;;;N;;;;; +E0128;VARIATION SELECTOR-57;Mn;0;NSM;;;;;N;;;;; +E0129;VARIATION SELECTOR-58;Mn;0;NSM;;;;;N;;;;; +E012A;VARIATION SELECTOR-59;Mn;0;NSM;;;;;N;;;;; +E012B;VARIATION SELECTOR-60;Mn;0;NSM;;;;;N;;;;; +E012C;VARIATION SELECTOR-61;Mn;0;NSM;;;;;N;;;;; +E012D;VARIATION SELECTOR-62;Mn;0;NSM;;;;;N;;;;; +E012E;VARIATION SELECTOR-63;Mn;0;NSM;;;;;N;;;;; +E012F;VARIATION SELECTOR-64;Mn;0;NSM;;;;;N;;;;; +E0130;VARIATION SELECTOR-65;Mn;0;NSM;;;;;N;;;;; +E0131;VARIATION SELECTOR-66;Mn;0;NSM;;;;;N;;;;; +E0132;VARIATION SELECTOR-67;Mn;0;NSM;;;;;N;;;;; +E0133;VARIATION SELECTOR-68;Mn;0;NSM;;;;;N;;;;; +E0134;VARIATION SELECTOR-69;Mn;0;NSM;;;;;N;;;;; +E0135;VARIATION SELECTOR-70;Mn;0;NSM;;;;;N;;;;; +E0136;VARIATION SELECTOR-71;Mn;0;NSM;;;;;N;;;;; +E0137;VARIATION SELECTOR-72;Mn;0;NSM;;;;;N;;;;; +E0138;VARIATION SELECTOR-73;Mn;0;NSM;;;;;N;;;;; +E0139;VARIATION SELECTOR-74;Mn;0;NSM;;;;;N;;;;; +E013A;VARIATION SELECTOR-75;Mn;0;NSM;;;;;N;;;;; +E013B;VARIATION SELECTOR-76;Mn;0;NSM;;;;;N;;;;; +E013C;VARIATION SELECTOR-77;Mn;0;NSM;;;;;N;;;;; +E013D;VARIATION SELECTOR-78;Mn;0;NSM;;;;;N;;;;; +E013E;VARIATION SELECTOR-79;Mn;0;NSM;;;;;N;;;;; +E013F;VARIATION SELECTOR-80;Mn;0;NSM;;;;;N;;;;; +E0140;VARIATION SELECTOR-81;Mn;0;NSM;;;;;N;;;;; +E0141;VARIATION SELECTOR-82;Mn;0;NSM;;;;;N;;;;; +E0142;VARIATION SELECTOR-83;Mn;0;NSM;;;;;N;;;;; +E0143;VARIATION SELECTOR-84;Mn;0;NSM;;;;;N;;;;; +E0144;VARIATION SELECTOR-85;Mn;0;NSM;;;;;N;;;;; +E0145;VARIATION SELECTOR-86;Mn;0;NSM;;;;;N;;;;; +E0146;VARIATION SELECTOR-87;Mn;0;NSM;;;;;N;;;;; +E0147;VARIATION SELECTOR-88;Mn;0;NSM;;;;;N;;;;; +E0148;VARIATION SELECTOR-89;Mn;0;NSM;;;;;N;;;;; +E0149;VARIATION SELECTOR-90;Mn;0;NSM;;;;;N;;;;; +E014A;VARIATION SELECTOR-91;Mn;0;NSM;;;;;N;;;;; +E014B;VARIATION SELECTOR-92;Mn;0;NSM;;;;;N;;;;; +E014C;VARIATION SELECTOR-93;Mn;0;NSM;;;;;N;;;;; +E014D;VARIATION SELECTOR-94;Mn;0;NSM;;;;;N;;;;; +E014E;VARIATION SELECTOR-95;Mn;0;NSM;;;;;N;;;;; +E014F;VARIATION SELECTOR-96;Mn;0;NSM;;;;;N;;;;; +E0150;VARIATION SELECTOR-97;Mn;0;NSM;;;;;N;;;;; +E0151;VARIATION SELECTOR-98;Mn;0;NSM;;;;;N;;;;; +E0152;VARIATION SELECTOR-99;Mn;0;NSM;;;;;N;;;;; +E0153;VARIATION SELECTOR-100;Mn;0;NSM;;;;;N;;;;; +E0154;VARIATION SELECTOR-101;Mn;0;NSM;;;;;N;;;;; +E0155;VARIATION SELECTOR-102;Mn;0;NSM;;;;;N;;;;; +E0156;VARIATION SELECTOR-103;Mn;0;NSM;;;;;N;;;;; +E0157;VARIATION SELECTOR-104;Mn;0;NSM;;;;;N;;;;; +E0158;VARIATION SELECTOR-105;Mn;0;NSM;;;;;N;;;;; +E0159;VARIATION SELECTOR-106;Mn;0;NSM;;;;;N;;;;; +E015A;VARIATION SELECTOR-107;Mn;0;NSM;;;;;N;;;;; +E015B;VARIATION SELECTOR-108;Mn;0;NSM;;;;;N;;;;; +E015C;VARIATION SELECTOR-109;Mn;0;NSM;;;;;N;;;;; +E015D;VARIATION SELECTOR-110;Mn;0;NSM;;;;;N;;;;; +E015E;VARIATION SELECTOR-111;Mn;0;NSM;;;;;N;;;;; +E015F;VARIATION SELECTOR-112;Mn;0;NSM;;;;;N;;;;; +E0160;VARIATION SELECTOR-113;Mn;0;NSM;;;;;N;;;;; +E0161;VARIATION SELECTOR-114;Mn;0;NSM;;;;;N;;;;; +E0162;VARIATION SELECTOR-115;Mn;0;NSM;;;;;N;;;;; +E0163;VARIATION SELECTOR-116;Mn;0;NSM;;;;;N;;;;; +E0164;VARIATION SELECTOR-117;Mn;0;NSM;;;;;N;;;;; +E0165;VARIATION SELECTOR-118;Mn;0;NSM;;;;;N;;;;; +E0166;VARIATION SELECTOR-119;Mn;0;NSM;;;;;N;;;;; +E0167;VARIATION SELECTOR-120;Mn;0;NSM;;;;;N;;;;; +E0168;VARIATION SELECTOR-121;Mn;0;NSM;;;;;N;;;;; +E0169;VARIATION SELECTOR-122;Mn;0;NSM;;;;;N;;;;; +E016A;VARIATION SELECTOR-123;Mn;0;NSM;;;;;N;;;;; +E016B;VARIATION SELECTOR-124;Mn;0;NSM;;;;;N;;;;; +E016C;VARIATION SELECTOR-125;Mn;0;NSM;;;;;N;;;;; +E016D;VARIATION SELECTOR-126;Mn;0;NSM;;;;;N;;;;; +E016E;VARIATION SELECTOR-127;Mn;0;NSM;;;;;N;;;;; +E016F;VARIATION SELECTOR-128;Mn;0;NSM;;;;;N;;;;; +E0170;VARIATION SELECTOR-129;Mn;0;NSM;;;;;N;;;;; +E0171;VARIATION SELECTOR-130;Mn;0;NSM;;;;;N;;;;; +E0172;VARIATION SELECTOR-131;Mn;0;NSM;;;;;N;;;;; +E0173;VARIATION SELECTOR-132;Mn;0;NSM;;;;;N;;;;; +E0174;VARIATION SELECTOR-133;Mn;0;NSM;;;;;N;;;;; +E0175;VARIATION SELECTOR-134;Mn;0;NSM;;;;;N;;;;; +E0176;VARIATION SELECTOR-135;Mn;0;NSM;;;;;N;;;;; +E0177;VARIATION SELECTOR-136;Mn;0;NSM;;;;;N;;;;; +E0178;VARIATION SELECTOR-137;Mn;0;NSM;;;;;N;;;;; +E0179;VARIATION SELECTOR-138;Mn;0;NSM;;;;;N;;;;; +E017A;VARIATION SELECTOR-139;Mn;0;NSM;;;;;N;;;;; +E017B;VARIATION SELECTOR-140;Mn;0;NSM;;;;;N;;;;; +E017C;VARIATION SELECTOR-141;Mn;0;NSM;;;;;N;;;;; +E017D;VARIATION SELECTOR-142;Mn;0;NSM;;;;;N;;;;; +E017E;VARIATION SELECTOR-143;Mn;0;NSM;;;;;N;;;;; +E017F;VARIATION SELECTOR-144;Mn;0;NSM;;;;;N;;;;; +E0180;VARIATION SELECTOR-145;Mn;0;NSM;;;;;N;;;;; +E0181;VARIATION SELECTOR-146;Mn;0;NSM;;;;;N;;;;; +E0182;VARIATION SELECTOR-147;Mn;0;NSM;;;;;N;;;;; +E0183;VARIATION SELECTOR-148;Mn;0;NSM;;;;;N;;;;; +E0184;VARIATION SELECTOR-149;Mn;0;NSM;;;;;N;;;;; +E0185;VARIATION SELECTOR-150;Mn;0;NSM;;;;;N;;;;; +E0186;VARIATION SELECTOR-151;Mn;0;NSM;;;;;N;;;;; +E0187;VARIATION SELECTOR-152;Mn;0;NSM;;;;;N;;;;; +E0188;VARIATION SELECTOR-153;Mn;0;NSM;;;;;N;;;;; +E0189;VARIATION SELECTOR-154;Mn;0;NSM;;;;;N;;;;; +E018A;VARIATION SELECTOR-155;Mn;0;NSM;;;;;N;;;;; +E018B;VARIATION SELECTOR-156;Mn;0;NSM;;;;;N;;;;; +E018C;VARIATION SELECTOR-157;Mn;0;NSM;;;;;N;;;;; +E018D;VARIATION SELECTOR-158;Mn;0;NSM;;;;;N;;;;; +E018E;VARIATION SELECTOR-159;Mn;0;NSM;;;;;N;;;;; +E018F;VARIATION SELECTOR-160;Mn;0;NSM;;;;;N;;;;; +E0190;VARIATION SELECTOR-161;Mn;0;NSM;;;;;N;;;;; +E0191;VARIATION SELECTOR-162;Mn;0;NSM;;;;;N;;;;; +E0192;VARIATION SELECTOR-163;Mn;0;NSM;;;;;N;;;;; +E0193;VARIATION SELECTOR-164;Mn;0;NSM;;;;;N;;;;; +E0194;VARIATION SELECTOR-165;Mn;0;NSM;;;;;N;;;;; +E0195;VARIATION SELECTOR-166;Mn;0;NSM;;;;;N;;;;; +E0196;VARIATION SELECTOR-167;Mn;0;NSM;;;;;N;;;;; +E0197;VARIATION SELECTOR-168;Mn;0;NSM;;;;;N;;;;; +E0198;VARIATION SELECTOR-169;Mn;0;NSM;;;;;N;;;;; +E0199;VARIATION SELECTOR-170;Mn;0;NSM;;;;;N;;;;; +E019A;VARIATION SELECTOR-171;Mn;0;NSM;;;;;N;;;;; +E019B;VARIATION SELECTOR-172;Mn;0;NSM;;;;;N;;;;; +E019C;VARIATION SELECTOR-173;Mn;0;NSM;;;;;N;;;;; +E019D;VARIATION SELECTOR-174;Mn;0;NSM;;;;;N;;;;; +E019E;VARIATION SELECTOR-175;Mn;0;NSM;;;;;N;;;;; +E019F;VARIATION SELECTOR-176;Mn;0;NSM;;;;;N;;;;; +E01A0;VARIATION SELECTOR-177;Mn;0;NSM;;;;;N;;;;; +E01A1;VARIATION SELECTOR-178;Mn;0;NSM;;;;;N;;;;; +E01A2;VARIATION SELECTOR-179;Mn;0;NSM;;;;;N;;;;; +E01A3;VARIATION SELECTOR-180;Mn;0;NSM;;;;;N;;;;; +E01A4;VARIATION SELECTOR-181;Mn;0;NSM;;;;;N;;;;; +E01A5;VARIATION SELECTOR-182;Mn;0;NSM;;;;;N;;;;; +E01A6;VARIATION SELECTOR-183;Mn;0;NSM;;;;;N;;;;; +E01A7;VARIATION SELECTOR-184;Mn;0;NSM;;;;;N;;;;; +E01A8;VARIATION SELECTOR-185;Mn;0;NSM;;;;;N;;;;; +E01A9;VARIATION SELECTOR-186;Mn;0;NSM;;;;;N;;;;; +E01AA;VARIATION SELECTOR-187;Mn;0;NSM;;;;;N;;;;; +E01AB;VARIATION SELECTOR-188;Mn;0;NSM;;;;;N;;;;; +E01AC;VARIATION SELECTOR-189;Mn;0;NSM;;;;;N;;;;; +E01AD;VARIATION SELECTOR-190;Mn;0;NSM;;;;;N;;;;; +E01AE;VARIATION SELECTOR-191;Mn;0;NSM;;;;;N;;;;; +E01AF;VARIATION SELECTOR-192;Mn;0;NSM;;;;;N;;;;; +E01B0;VARIATION SELECTOR-193;Mn;0;NSM;;;;;N;;;;; +E01B1;VARIATION SELECTOR-194;Mn;0;NSM;;;;;N;;;;; +E01B2;VARIATION SELECTOR-195;Mn;0;NSM;;;;;N;;;;; +E01B3;VARIATION SELECTOR-196;Mn;0;NSM;;;;;N;;;;; +E01B4;VARIATION SELECTOR-197;Mn;0;NSM;;;;;N;;;;; +E01B5;VARIATION SELECTOR-198;Mn;0;NSM;;;;;N;;;;; +E01B6;VARIATION SELECTOR-199;Mn;0;NSM;;;;;N;;;;; +E01B7;VARIATION SELECTOR-200;Mn;0;NSM;;;;;N;;;;; +E01B8;VARIATION SELECTOR-201;Mn;0;NSM;;;;;N;;;;; +E01B9;VARIATION SELECTOR-202;Mn;0;NSM;;;;;N;;;;; +E01BA;VARIATION SELECTOR-203;Mn;0;NSM;;;;;N;;;;; +E01BB;VARIATION SELECTOR-204;Mn;0;NSM;;;;;N;;;;; +E01BC;VARIATION SELECTOR-205;Mn;0;NSM;;;;;N;;;;; +E01BD;VARIATION SELECTOR-206;Mn;0;NSM;;;;;N;;;;; +E01BE;VARIATION SELECTOR-207;Mn;0;NSM;;;;;N;;;;; +E01BF;VARIATION SELECTOR-208;Mn;0;NSM;;;;;N;;;;; +E01C0;VARIATION SELECTOR-209;Mn;0;NSM;;;;;N;;;;; +E01C1;VARIATION SELECTOR-210;Mn;0;NSM;;;;;N;;;;; +E01C2;VARIATION SELECTOR-211;Mn;0;NSM;;;;;N;;;;; +E01C3;VARIATION SELECTOR-212;Mn;0;NSM;;;;;N;;;;; +E01C4;VARIATION SELECTOR-213;Mn;0;NSM;;;;;N;;;;; +E01C5;VARIATION SELECTOR-214;Mn;0;NSM;;;;;N;;;;; +E01C6;VARIATION SELECTOR-215;Mn;0;NSM;;;;;N;;;;; +E01C7;VARIATION SELECTOR-216;Mn;0;NSM;;;;;N;;;;; +E01C8;VARIATION SELECTOR-217;Mn;0;NSM;;;;;N;;;;; +E01C9;VARIATION SELECTOR-218;Mn;0;NSM;;;;;N;;;;; +E01CA;VARIATION SELECTOR-219;Mn;0;NSM;;;;;N;;;;; +E01CB;VARIATION SELECTOR-220;Mn;0;NSM;;;;;N;;;;; +E01CC;VARIATION SELECTOR-221;Mn;0;NSM;;;;;N;;;;; +E01CD;VARIATION SELECTOR-222;Mn;0;NSM;;;;;N;;;;; +E01CE;VARIATION SELECTOR-223;Mn;0;NSM;;;;;N;;;;; +E01CF;VARIATION SELECTOR-224;Mn;0;NSM;;;;;N;;;;; +E01D0;VARIATION SELECTOR-225;Mn;0;NSM;;;;;N;;;;; +E01D1;VARIATION SELECTOR-226;Mn;0;NSM;;;;;N;;;;; +E01D2;VARIATION SELECTOR-227;Mn;0;NSM;;;;;N;;;;; +E01D3;VARIATION SELECTOR-228;Mn;0;NSM;;;;;N;;;;; +E01D4;VARIATION SELECTOR-229;Mn;0;NSM;;;;;N;;;;; +E01D5;VARIATION SELECTOR-230;Mn;0;NSM;;;;;N;;;;; +E01D6;VARIATION SELECTOR-231;Mn;0;NSM;;;;;N;;;;; +E01D7;VARIATION SELECTOR-232;Mn;0;NSM;;;;;N;;;;; +E01D8;VARIATION SELECTOR-233;Mn;0;NSM;;;;;N;;;;; +E01D9;VARIATION SELECTOR-234;Mn;0;NSM;;;;;N;;;;; +E01DA;VARIATION SELECTOR-235;Mn;0;NSM;;;;;N;;;;; +E01DB;VARIATION SELECTOR-236;Mn;0;NSM;;;;;N;;;;; +E01DC;VARIATION SELECTOR-237;Mn;0;NSM;;;;;N;;;;; +E01DD;VARIATION SELECTOR-238;Mn;0;NSM;;;;;N;;;;; +E01DE;VARIATION SELECTOR-239;Mn;0;NSM;;;;;N;;;;; +E01DF;VARIATION SELECTOR-240;Mn;0;NSM;;;;;N;;;;; +E01E0;VARIATION SELECTOR-241;Mn;0;NSM;;;;;N;;;;; +E01E1;VARIATION SELECTOR-242;Mn;0;NSM;;;;;N;;;;; +E01E2;VARIATION SELECTOR-243;Mn;0;NSM;;;;;N;;;;; +E01E3;VARIATION SELECTOR-244;Mn;0;NSM;;;;;N;;;;; +E01E4;VARIATION SELECTOR-245;Mn;0;NSM;;;;;N;;;;; +E01E5;VARIATION SELECTOR-246;Mn;0;NSM;;;;;N;;;;; +E01E6;VARIATION SELECTOR-247;Mn;0;NSM;;;;;N;;;;; +E01E7;VARIATION SELECTOR-248;Mn;0;NSM;;;;;N;;;;; +E01E8;VARIATION SELECTOR-249;Mn;0;NSM;;;;;N;;;;; +E01E9;VARIATION SELECTOR-250;Mn;0;NSM;;;;;N;;;;; +E01EA;VARIATION SELECTOR-251;Mn;0;NSM;;;;;N;;;;; +E01EB;VARIATION SELECTOR-252;Mn;0;NSM;;;;;N;;;;; +E01EC;VARIATION SELECTOR-253;Mn;0;NSM;;;;;N;;;;; +E01ED;VARIATION SELECTOR-254;Mn;0;NSM;;;;;N;;;;; +E01EE;VARIATION SELECTOR-255;Mn;0;NSM;;;;;N;;;;; +E01EF;VARIATION SELECTOR-256;Mn;0;NSM;;;;;N;;;;; +F0000;;Co;0;L;;;;;N;;;;; +FFFFD;;Co;0;L;;;;;N;;;;; +100000;;Co;0;L;;;;;N;;;;; +10FFFD;;Co;0;L;;;;;N;;;;; diff --git a/debuggers/openocd/jimtcl/auto.def b/debuggers/openocd/jimtcl/auto.def new file mode 100644 index 00000000..ddb0c1e5 --- /dev/null +++ b/debuggers/openocd/jimtcl/auto.def @@ -0,0 +1,339 @@ +# vim:se syn=tcl: +# + +# Note: modules which support options *must* be included before 'options' +use cc cc-shared cc-db cc-lib +use local + +options { + utf8 => "include support for utf8-encoded strings" + lineedit=1 => "disable line editing" + references=1 => "disable support for references" + math => "include support for math functions" + ipv6 => "include ipv6 support in the aio extension" + maintainer => {enable the [debug] command and JimPanic} + full => "Enable some optional features: ipv6, math, utf8, binary, oo, tree" + with-jim-shared shared => "build a shared library instead of a static library" + jim-regexp=1 => "prefer POSIX regex if over the the built-in (Tcl-compatible) regex" + with-jim-ext: {with-ext:"ext1 ext2 ..."} => { + Specify additional jim extensions to include. + These are enabled by default: + + aio - ANSI I/O, including open and socket + eventloop - after, vwait, update + array - Tcl-compatible array command + clock - Tcl-compatible clock command + exec - Tcl-compatible exec command + file - Tcl-compatible file command + glob - Tcl-compatible glob command + history - Tcl access to interactive history + readdir - Required for glob + package - Package management with the package command + load - Load binary extensions at runtime with load or package + posix - Posix APIs including os.fork, os.wait, pid + regexp - Tcl-compatible regexp, regsub commands + signal - Signal handling + stdlib - Built-in commands including lassign, lambda, alias + syslog - System logging with syslog + tclcompat - Tcl compatible read, gets, puts, parray, case, ... + namespace - Tcl compatible namespace support + + These are disabled by default: + + oo - Jim OO extension + tree - OO tree structure, similar to tcllib ::struct::tree + binary - Tcl-compatible 'binary' command + readline - Interface to libreadline + rlprompt - Tcl wrapper around the readline extension + mk - Interface to Metakit + tclprefix - Support for the tcl::prefix command + sqlite3 - Interface to sqlite3 + win32 - Interface to win32 + } + with-out-jim-ext: {without-ext:"default|ext1 ext2 ..."} => { + Specify jim extensions to exclude. + If 'default' is given, the default extensions will not be added. + } + with-jim-extmod: {with-mod:"ext1 ext2 ..."} => { + Specify jim extensions to build as separate modules (either C or Tcl). + Note that not all extensions can be built as loadable modules. + } + # To help out openocd with automake + install-jim=1 +} + +cc-check-types "long long" + +cc-check-includes sys/time.h sys/socket.h netinet/in.h arpa/inet.h netdb.h +cc-check-includes sys/un.h dlfcn.h unistd.h dirent.h crt_externs.h + +define LDLIBS "" + +# Haiku needs -lnetwork, Solaris needs -lnsl +if {[cc-check-function-in-lib inet_ntop {nsl network}]} { + # This does nothing if no libs are needed + cc-with [list -libs [get-define lib_inet_ntop]] + define-append LDLIBS [get-define lib_inet_ntop] +} +# Solaris needs -lsocket, Windows needs -lwsock32 +if {[cc-check-function-in-lib socket socket]} { + define-append LDLIBS [get-define lib_socket] +} + +cc-check-functions ualarm lstat fork vfork system select execvpe +cc-check-functions backtrace geteuid mkstemp realpath strptime isatty +cc-check-functions regcomp waitpid sigaction sys_signame sys_siglist +cc-check-functions syslog opendir readlink sleep usleep pipe getaddrinfo utimes +if {[cc-check-functions sysinfo]} { + cc-with {-includes sys/sysinfo.h} { + cc-check-members "struct sysinfo.uptime" + } +} + +cc-check-lfs +cc-check-functions fseeko ftello + +define TCL_LIBRARY [get-define prefix]/lib/jim + +lassign [split [get-define host] -] host_cpu host_vendor host_os +# Scrub revision from the host_os +regsub -all {[0-9.]} $host_os {} host_os + +switch -glob -- $host_os { + mingw* { + # We provide our own implementation of dlopen for mingw32 + define-feature dlopen-compat + define-feature winconsole + define TCL_PLATFORM_OS $host_os + define TCL_PLATFORM_PLATFORM windows + define TCL_PLATFORM_PATH_SEPARATOR {;} + } + default { + # Note that cygwin is considered a unix platform + define TCL_PLATFORM_OS $host_os + define TCL_PLATFORM_PLATFORM unix + define TCL_PLATFORM_PATH_SEPARATOR : + } +} + +if {[have-feature windows]} { + define LIBSOEXT dll +} else { + define LIBSOEXT so +} + +# Find some tools +cc-check-tools ar ranlib strip +define tclsh [info nameofexecutable] + +if {![cc-check-functions _NSGetEnviron]} { + msg-checking "Checking environ declared in unistd.h..." + if {[cctest -cflags -D_GNU_SOURCE -includes unistd.h -code {char **ep = environ;}]} { + define NO_ENVIRON_EXTERN + msg-result "yes" + } else { + msg-result "no" + } +} + +# Windows has a mkdir with no permission arg +cc-check-includes sys/types.h sys/stat.h +msg-checking "Checking for mkdir with one arg..." +if {[cctest -includes {sys/types.h sys/stat.h} -code {mkdir("/dummy");}]} { + define HAVE_MKDIR_ONE_ARG + msg-result yes +} else { + msg-result no +} + +set extra_objs {} +set jimregexp 0 + +if {[opt-bool utf8 full]} { + msg-result "Enabling UTF-8" + define JIM_UTF8 + incr jimregexp +} else { + define JIM_UTF8 0 +} +if {[opt-bool maintainer]} { + msg-result "Enabling maintainer settings" + define JIM_MAINTAINER +} +if {[opt-bool math full]} { + msg-result "Enabling math functions" + define JIM_MATH_FUNCTIONS + cc-check-function-in-lib sin m + define-append LDLIBS [get-define lib_sin] +} +if {[opt-bool ipv6 full]} { + msg-result "Enabling IPv6" + define JIM_IPV6 +} +if {[opt-bool lineedit full]} { + if {([cc-check-includes termios.h] && [have-feature isatty]) || [have-feature winconsole]} { + msg-result "Enabling line editing" + define USE_LINENOISE + lappend extra_objs linenoise.o + } +} +if {[opt-bool references]} { + msg-result "Enabling references" + define JIM_REFERENCES +} +if {[opt-bool shared with-jim-shared]} { + msg-result "Building shared library" +} else { + msg-result "Building static library" + define JIM_STATICLIB +} +define JIM_INSTALL [opt-bool install-jim] + +# Attributes of the extensions +# tcl=Pure Tcl extension +# static=Can't be built as a module +# optional=Not selected by default +# cpp=Is a C++ extension +global extdb +dict set extdb attrs { + aio { static } + array {} + binary { tcl } + clock {} + eventloop { static } + exec { static } + file {} + glob { tcl } + history {} + load { static } + mk { cpp optional } + namespace { static } + nshelper { tcl optional } + oo { tcl } + pack {} + package { static } + posix {} + readdir {} + readline { optional } + regexp {} + rlprompt { tcl optional } + sdl { optional } + signal { static } + sqlite3 { optional } + stdlib { tcl static } + syslog {} + tclcompat { tcl static } + tclprefix {} + tree { tcl } + win32 { optional } +} + +# Additional information about certain extensions +# dep=list of extensions which are required for this extension +# check=[expr] expression to evaluate to determine if the extension can be used +# libdep=list of 'define' symbols for dependent libraries +dict set extdb info { + binary { dep pack } + exec { check {([have-feature vfork] && [have-feature waitpid]) || [have-feature system]} } + glob { dep readdir } + load { check {[have-feature dlopen-compat] || [cc-check-function-in-lib dlopen dl]} libdep lib_dlopen } + mk { check {[check-metakit]} libdep lib_mk } + namespace { dep nshelper } + posix { check {[have-feature waitpid]} } + readdir { check {[have-feature opendir]} } + readline { check {[cc-check-function-in-lib readline readline]} libdep lib_readline} + rlprompt { dep readline } + tree { dep oo } + sdl { check {[cc-check-function-in-lib SDL_SetVideoMode SDL] && [cc-check-function-in-lib rectangleRGBA SDL_gfx]} + libdep {lib_SDL_SetVideoMode lib_rectangleRGBA} + } + signal { check {[have-feature sigaction] && [have-feature vfork]} } + sqlite3 { check {[cc-check-function-in-lib sqlite3_prepare_v2 sqlite3]} libdep lib_sqlite3_prepare_v2 } + syslog { check {[have-feature syslog]} } + tree { dep oo } + win32 { check {[have-feature windows]} } +} + +# autosetup cc-check-function-in-library can't handle C++ libraries +proc check-metakit {} { + set found 0 + msg-checking "Checking for Metakit..." + cc-with {-lang c++} { + if {[cctest -includes mk4.h -libs -lmk4 -code {c4_Storage dummy();}]} { + msg-result ok + define lib_mk -lmk4 + incr found + } else { + msg-result "not found" + } + } + return $found +} + +# Set up the withinfo array based on what the user selected +global withinfo +set withinfo(without) [join [opt-val {without-ext with-out-jim-ext}]] +set withinfo(ext) [join [opt-val {with-ext with-jim-ext}]] +set withinfo(mod) [join [opt-val {with-mod with-jim-extmod}]] +set withinfo(nodefault) 0 +if {$withinfo(without) eq "default"} { + set withinfo(without) {} + set withinfo(nodefault) 1 +} + +# Now go check everything - see autosetup/local.tcl +array set extinfo [check-extensions] + +# Now special checks +if {[have-feature windows]} { + lappend extra_objs jim-win32compat.o + + if {[llength $extinfo(module-c)] && [get-define JIM_STATICLIB]} { + user-error "cygwin/mingw require --shared for dynamic modules" + } +} + +if {[ext-get-status regexp] in {y m}} { + if {![have-feature regcomp]} { + # No regcomp means we need to use the built-in version + incr jimregexp + } +} + +if {$jimregexp || [opt-bool jim-regexp]} { + msg-result "Using built-in regexp" + define JIM_REGEXP + + # If the built-in regexp overrides the system regcomp, etc. + # jim must be built shared so that the correct symbols are found + if {[ext-get-status regexp] eq "m" && [get-define JIM_STATICLIB] && [have-feature regcomp]} { + user-error "Must use --shared with regexp module and built-in regexp" + } +} + +if {[ext-get-status load] eq "n"} { + # If we don't have load, no need to support shared objects + define SH_LINKFLAGS "" +} + +msg-result "Jim static extensions: [lsort [concat $extinfo(static-tcl) $extinfo(static-c)]]" +if {[llength $extinfo(module-tcl)]} { + msg-result "Jim Tcl extensions: [lsort $extinfo(module-tcl)]" +} +if {[llength $extinfo(module-c)]} { + msg-result "Jim dynamic extensions: [lsort $extinfo(module-c)]" +} + +define STATIC_EXTS [concat $extinfo(static-c) $extinfo(static-tcl)] +define C_EXT_OBJS [prefix jim- [suffix .o $extinfo(static-c)]] +define TCL_EXT_OBJS [suffix .o $extinfo(static-tcl)] +define C_EXT_SHOBJS [suffix .so $extinfo(module-c)] +define TCL_EXTS [suffix .tcl $extinfo(module-tcl)] +define EXTRA_OBJS $extra_objs + +make-config-header jim-config.h -auto {HAVE_LONG_LONG* JIM_UTF8} -none * +make-config-header jimautoconf.h -auto {jim_ext_* TCL_PLATFORM_* TCL_LIBRARY USE_* JIM_* _FILE_OFFSET*} +make-template Makefile.in +make-template build-jim-ext.in + +catch {exec chmod +x build-jim-ext} diff --git a/debuggers/openocd/jimtcl/autosetup/LICENSE b/debuggers/openocd/jimtcl/autosetup/LICENSE new file mode 100644 index 00000000..4fe636c9 --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/LICENSE @@ -0,0 +1,35 @@ +Unless explicitly stated, all files which form part of autosetup +are released under the following license: + +--------------------------------------------------------------------- +autosetup - A build environment "autoconfigurator" + +Copyright (c) 2010-2011, WorkWare Systems + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE WORKWARE SYSTEMS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WORKWARE +SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation +are those of the authors and should not be interpreted as representing +official policies, either expressed or implied, of WorkWare Systems. diff --git a/debuggers/openocd/jimtcl/autosetup/README.autosetup b/debuggers/openocd/jimtcl/autosetup/README.autosetup new file mode 100644 index 00000000..c50bd84c --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/README.autosetup @@ -0,0 +1 @@ +This is autosetup v0.6.5. See http://msteveb.github.com/autosetup/ diff --git a/debuggers/openocd/jimtcl/autosetup/autosetup b/debuggers/openocd/jimtcl/autosetup/autosetup new file mode 100755 index 00000000..85c61ca4 --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/autosetup @@ -0,0 +1,1898 @@ +#!/bin/sh +# Copyright (c) 2006-2011 WorkWare Systems http://www.workware.net.au/ +# All rights reserved +# vim:se syntax=tcl: +# \ +dir=`dirname "$0"`; exec "`$dir/find-tclsh`" "$0" "$@" + +set autosetup(version) 0.6.5 + +# Can be set to 1 to debug early-init problems +set autosetup(debug) 0 + +################################################################## +# +# Main flow of control, option handling +# +proc main {argv} { + global autosetup define + + # There are 3 potential directories involved: + # 1. The directory containing autosetup (this script) + # 2. The directory containing auto.def + # 3. The current directory + + # From this we need to determine: + # a. The path to this script (and related support files) + # b. The path to auto.def + # c. The build directory, where output files are created + + # This is also complicated by the fact that autosetup may + # have been run via the configure wrapper ([getenv WRAPPER] is set) + + # Here are the rules. + # a. This script is $::argv0 + # => dir, prog, exe, libdir + # b. auto.def is in the directory containing the configure wrapper, + # otherwise it is in the current directory. + # => srcdir, autodef + # c. The build directory is the current directory + # => builddir, [pwd] + + # 'misc' is needed before we can do anything, so set a temporary libdir + # in case this is the development version + set autosetup(libdir) [file dirname $::argv0]/lib + use misc + + # (a) + set autosetup(dir) [realdir [file dirname [realpath $::argv0]]] + set autosetup(prog) [file join $autosetup(dir) [file tail $::argv0]] + set autosetup(exe) [getenv WRAPPER $autosetup(prog)] + if {$autosetup(installed)} { + set autosetup(libdir) $autosetup(dir) + } else { + set autosetup(libdir) [file join $autosetup(dir) lib] + } + autosetup_add_dep $autosetup(prog) + + # (b) + if {[getenv WRAPPER ""] eq ""} { + # Invoked directly + set autosetup(srcdir) [pwd] + } else { + # Invoked via the configure wrapper + set autosetup(srcdir) [file dirname $autosetup(exe)] + } + set autosetup(autodef) [relative-path $autosetup(srcdir)/auto.def] + + # (c) + set autosetup(builddir) [pwd] + + set autosetup(argv) $argv + set autosetup(cmdline) {} + set autosetup(options) {} + set autosetup(optionhelp) {} + set autosetup(showhelp) 0 + + # Parse options + use getopt + + array set ::useropts [getopt argv] + + #"=Core Options:" + options-add { + help:=local => "display help and options. Optionally specify a module name, such as --help=system" + version => "display the version of autosetup" + ref:=text manual:=text + reference:=text => "display the autosetup command reference. 'text', 'wiki', 'asciidoc' or 'markdown'" + debug => "display debugging output as autosetup runs" + install:=. => "install autosetup to the current or given directory (in the 'autosetup/' subdirectory)" + force init:=help => "create initial auto.def, etc. Use --init=help for known types" + # Undocumented options + option-checking=1 + nopager + quiet + timing + conf: + } + + #parray ::useropts + if {[opt-bool version]} { + puts $autosetup(version) + exit 0 + } + + # autosetup --conf=alternate-auto.def + if {[opt-val conf] ne ""} { + set autosetup(autodef) [opt-val conf] + } + + # Debugging output (set this early) + incr autosetup(debug) [opt-bool debug] + incr autosetup(force) [opt-bool force] + incr autosetup(msg-quiet) [opt-bool quiet] + incr autosetup(msg-timing) [opt-bool timing] + + # If the local module exists, source it now to allow for + # project-local customisations + if {[file exists $autosetup(libdir)/local.tcl]} { + use local + } + + # Now any auto-load modules + foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] { + automf_load source $file + } + + if {[opt-val help] ne ""} { + incr autosetup(showhelp) + use help + autosetup_help [opt-val help] + } + + if {[opt-val {manual ref reference}] ne ""} { + use help + autosetup_reference [opt-val {manual ref reference}] + } + + if {[opt-val init] ne ""} { + use init + autosetup_init [opt-val init] + } + + if {[opt-val install] ne ""} { + use install + autosetup_install [opt-val install] + } + + if {![file exists $autosetup(autodef)]} { + # Check for invalid option first + options {} + user-error "No auto.def found in \"$autosetup(srcdir)\" (use [file tail $::autosetup(exe)] --init to create one)" + } + + # Parse extra arguments into autosetup(cmdline) + foreach arg $argv { + if {[regexp {([^=]*)=(.*)} $arg -> n v]} { + dict set autosetup(cmdline) $n $v + define $n $v + } else { + user-error "Unexpected parameter: $arg" + } + } + + autosetup_add_dep $autosetup(autodef) + + set cmd [file-normalize $autosetup(exe)] + foreach arg $autosetup(argv) { + append cmd " [quote-if-needed $arg]" + } + define AUTOREMAKE $cmd + + # Log how we were invoked + configlog "Invoked as: [getenv WRAPPER $::argv0] [quote-argv $autosetup(argv)]" + + # Note that auto.def is *not* loaded in the global scope + source $autosetup(autodef) + + # Could warn here if options {} was not specified + + show-notices + + if {$autosetup(debug)} { + msg-result "Writing all defines to config.log" + configlog "================ defines ======================" + foreach n [lsort [array names define]] { + configlog "define $n $define($n)" + } + } + + exit 0 +} + +# @opt-bool option ... +# +# Check each of the named, boolean options and return 1 if any of them have +# been set by the user. +# +proc opt-bool {args} { + option-check-names {*}$args + opt_bool ::useropts {*}$args +} + +# @opt-val option-list ?default=""? +# +# Returns a list containing all the values given for the non-boolean options in 'option-list'. +# There will be one entry in the list for each option given by the user, including if the +# same option was used multiple times. +# If only a single value is required, use something like: +# +## lindex [opt-val $names] end +# +# If no options were set, $default is returned (exactly, not as a list). +# +proc opt-val {names {default ""}} { + option-check-names {*}$names + join [opt_val ::useropts $names $default] +} + +proc option-check-names {args} { + foreach o $args { + if {$o ni $::autosetup(options)} { + autosetup-error "Request for undeclared option --$o" + } + } +} + +# Parse the option definition in $opts and update +# ::useropts() and ::autosetup(optionhelp) appropriately +# +proc options-add {opts {header ""}} { + global useropts autosetup + + # First weed out comment lines + set realopts {} + foreach line [split $opts \n] { + if {![string match "#*" [string trimleft $line]]} { + append realopts $line \n + } + } + set opts $realopts + + for {set i 0} {$i < [llength $opts]} {incr i} { + set opt [lindex $opts $i] + if {[string match =* $opt]} { + # This is a special heading + lappend autosetup(optionhelp) $opt "" + set header {} + continue + } + + #puts "i=$i, opt=$opt" + regexp {^([^:=]*)(:)?(=)?(.*)$} $opt -> name colon equal value + if {$name in $autosetup(options)} { + autosetup-error "Option $name already specified" + } + + #puts "$opt => $name $colon $equal $value" + + # Find the corresponding value in the user options + # and set the default if necessary + if {[string match "-*" $opt]} { + # This is a documentation-only option, like "-C " + set opthelp $opt + } elseif {$colon eq ""} { + # Boolean option + lappend autosetup(options) $name + + if {![info exists useropts($name)]} { + set useropts($name) $value + } + if {$value eq "1"} { + set opthelp "--disable-$name" + } else { + set opthelp "--$name" + } + } else { + # String option. + lappend autosetup(options) $name + + if {$equal eq "="} { + if {[info exists useropts($name)]} { + # If the user specified the option with no value, the value will be "1" + # Replace with the default + if {$useropts($name) eq "1"} { + set useropts($name) $value + } + } + set opthelp "--$name?=$value?" + } else { + set opthelp "--$name=$value" + } + } + + # Now create the help for this option if appropriate + if {[lindex $opts $i+1] eq "=>"} { + set desc [lindex $opts $i+2] + #string match \n* $desc + if {$header ne ""} { + lappend autosetup(optionhelp) $header "" + set header "" + } + # A multi-line description + lappend autosetup(optionhelp) $opthelp $desc + incr i 2 + } + } +} + +# @module-options optionlist +# +# Like 'options', but used within a module. +proc module-options {opts} { + set header "" + if {$::autosetup(showhelp) > 1 && [llength $opts]} { + set header "Module Options:" + } + options-add $opts $header + + if {$::autosetup(showhelp)} { + # Ensure that the module isn't executed on --help + # We are running under eval or source, so use break + # to prevent further execution + #return -code break -level 2 + return -code break + } +} + +proc max {a b} { + expr {$a > $b ? $a : $b} +} + +proc options-wrap-desc {text length firstprefix nextprefix initial} { + set len $initial + set space $firstprefix + foreach word [split $text] { + set word [string trim $word] + if {$word == ""} { + continue + } + if {$len && [string length $space$word] + $len >= $length} { + puts "" + set len 0 + set space $nextprefix + } + incr len [string length $space$word] + puts -nonewline $space$word + set space " " + } + if {$len} { + puts "" + } +} + +proc options-show {} { + # Determine the max option width + set max 0 + foreach {opt desc} $::autosetup(optionhelp) { + if {[string match =* $opt] || [string match \n* $desc]} { + continue + } + set max [max $max [string length $opt]] + } + set indent [string repeat " " [expr $max+4]] + set cols [getenv COLUMNS 80] + catch { + lassign [exec stty size] rows cols + } + incr cols -1 + # Now output + foreach {opt desc} $::autosetup(optionhelp) { + if {[string match =* $opt]} { + puts [string range $opt 1 end] + continue + } + puts -nonewline " [format %-${max}s $opt]" + if {[string match \n* $desc]} { + puts $desc + } else { + options-wrap-desc [string trim $desc] $cols " " $indent [expr $max + 2] + } + } +} + +# @options options-spec +# +# Specifies configuration-time options which may be selected by the user +# and checked with opt-val and opt-bool. The format of options-spec follows. +# +# A boolean option is of the form: +# +## name[=0|1] => "Description of this boolean option" +# +# The default is name=0, meaning that the option is disabled by default. +# If name=1 is used to make the option enabled by default, the description should reflect +# that with text like "Disable support for ...". +# +# An argument option (one which takes a parameter) is of the form: +# +## name:[=]value => "Description of this option" +# +# If the name:value form is used, the value must be provided with the option (as --name=myvalue). +# If the name:=value form is used, the value is optional and the given value is used as the default +# if is not provided. +# +# Undocumented options are also supported by omitting the "=> description. +# These options are not displayed with --help and can be useful for internal options or as aliases. +# +# For example, --disable-lfs is an alias for --disable=largefile: +# +## lfs=1 largefile=1 => "Disable large file support" +# +proc options {optlist} { + # Allow options as a list or args + options-add $optlist "Local Options:" + + if {$::autosetup(showhelp)} { + options-show + exit 0 + } + + # Check for invalid options + if {[opt-bool option-checking]} { + foreach o [array names ::useropts] { + if {$o ni $::autosetup(options)} { + user-error "Unknown option --$o" + } + } + } +} + +proc config_guess {} { + if {[file-isexec $::autosetup(dir)/config.guess]} { + exec-with-stderr sh $::autosetup(dir)/config.guess + if {[catch {exec-with-stderr sh $::autosetup(dir)/config.guess} alias]} { + user-error $alias + } + return $alias + } else { + configlog "No config.guess, so using uname" + string tolower [exec uname -p]-unknown-[exec uname -s][exec uname -r] + } +} + +proc config_sub {alias} { + if {[file-isexec $::autosetup(dir)/config.sub]} { + if {[catch {exec-with-stderr sh $::autosetup(dir)/config.sub $alias} alias]} { + user-error $alias + } + } + return $alias +} + +# @define name ?value=1? +# +# Defines the named variable to the given value. +# These (name, value) pairs represent the results of the configuration check +# and are available to be checked, modified and substituted. +# +proc define {name {value 1}} { + set ::define($name) $value + #dputs "$name <= $value" +} + +# @define-append name value ... +# +# Appends the given value(s) to the given 'defined' variable. +# If the variable is not defined or empty, it is set to $value. +# Otherwise the value is appended, separated by a space. +# Any extra values are similarly appended. +# If any value is already contained in the variable (as a substring) it is omitted. +# +proc define-append {name args} { + if {[get-define $name ""] ne ""} { + # Make a token attempt to avoid duplicates + foreach arg $args { + if {[string first $arg $::define($name)] == -1} { + append ::define($name) " " $arg + } + } + } else { + set ::define($name) [join $args] + } + #dputs "$name += [join $args] => $::define($name)" +} + +# @get-define name ?default=0? +# +# Returns the current value of the 'defined' variable, or $default +# if not set. +# +proc get-define {name {default 0}} { + if {[info exists ::define($name)]} { + #dputs "$name => $::define($name)" + return $::define($name) + } + #dputs "$name => $default" + return $default +} + +# @is-defined name +# +# Returns 1 if the given variable is defined. +# +proc is-defined {name} { + info exists ::define($name) +} + +# @all-defines +# +# Returns a dictionary (name value list) of all defined variables. +# +# This is suitable for use with 'dict', 'array set' or 'foreach' +# and allows for arbitrary processing of the defined variables. +# +proc all-defines {} { + array get ::define +} + + +# @get-env name default +# +# If $name was specified on the command line, return it. +# If $name was set in the environment, return it. +# Otherwise return $default. +# +proc get-env {name default} { + if {[dict exists $::autosetup(cmdline) $name]} { + return [dict get $::autosetup(cmdline) $name] + } + getenv $name $default +} + +# @env-is-set name +# +# Returns 1 if the $name was specified on the command line or in the environment. +# Note that an empty environment variable is not considered to be set. +# +proc env-is-set {name} { + if {[dict exists $::autosetup(cmdline) $name]} { + return 1 + } + if {[getenv $name ""] ne ""} { + return 1 + } + return 0 +} + +# @readfile filename ?default=""? +# +# Return the contents of the file, without the trailing newline. +# If the doesn't exist or can't be read, returns $default. +# +proc readfile {filename {default_value ""}} { + set result $default_value + catch { + set f [open $filename] + set result [read -nonewline $f] + close $f + } + return $result +} + +# @writefile filename value +# +# Creates the given file containing $value. +# Does not add an extra newline. +# +proc writefile {filename value} { + set f [open $filename w] + puts -nonewline $f $value + close $f +} + +proc quote-if-needed {str} { + if {[string match {*[\" ]*} $str]} { + return \"[string map [list \" \\" \\ \\\\] $str]\" + } + return $str +} + +proc quote-argv {argv} { + set args {} + foreach arg $argv { + lappend args [quote-if-needed $arg] + } + join $args +} + +# @suffix suf list +# +# Takes a list and returns a new list with $suf appended +# to each element +# +## suffix .c {a b c} => {a.c b.c c.c} +# +proc suffix {suf list} { + set result {} + foreach p $list { + lappend result $p$suf + } + return $result +} + +# @prefix pre list +# +# Takes a list and returns a new list with $pre prepended +# to each element +# +## prefix jim- {a.c b.c} => {jim-a.c jim-b.c} +# +proc prefix {pre list} { + set result {} + foreach p $list { + lappend result $pre$p + } + return $result +} + +# @find-executable name +# +# Searches the path for an executable with the given name. +# Note that the name may include some parameters, e.g. "cc -mbig-endian", +# in which case the parameters are ignored. +# Returns 1 if found, or 0 if not. +# +proc find-executable {name} { + # Ignore any parameters + set name [lindex $name 0] + if {$name eq ""} { + # The empty string is never a valid executable + return 0 + } + foreach p [split-path] { + dputs "Looking for $name in $p" + set exec [file join $p $name] + if {[file-isexec $exec]} { + dputs "Found $name -> $exec" + return 1 + } + } + return 0 +} + +# @find-an-executable ?-required? name ... +# +# Given a list of possible executable names, +# searches for one of these on the path. +# +# Returns the name found, or "" if none found. +# If the first parameter is '-required', an error is generated +# if no executable is found. +# +proc find-an-executable {args} { + set required 0 + if {[lindex $args 0] eq "-required"} { + set args [lrange $args 1 end] + incr required + } + foreach name $args { + if {[find-executable $name]} { + return $name + } + } + if {$required} { + if {[llength $args] == 1} { + user-error "failed to find: [join $args]" + } else { + user-error "failed to find one of: [join $args]" + } + } + return "" +} + +# @configlog msg +# +# Writes the given message to the configuration log, config.log +# +proc configlog {msg} { + if {![info exists ::autosetup(logfh)]} { + set ::autosetup(logfh) [open config.log w] + } + puts $::autosetup(logfh) $msg +} + +# @msg-checking msg +# +# Writes the message with no newline to stdout. +# +proc msg-checking {msg} { + if {$::autosetup(msg-quiet) == 0} { + maybe-show-timestamp + puts -nonewline $msg + set ::autosetup(msg-checking) 1 + } +} + +# @msg-result msg +# +# Writes the message to stdout. +# +proc msg-result {msg} { + if {$::autosetup(msg-quiet) == 0} { + maybe-show-timestamp + puts $msg + set ::autosetup(msg-checking) 0 + show-notices + } +} + +# @msg-quiet command ... +# +# msg-quiet evaluates it's arguments as a command with output +# from msg-checking and msg-result suppressed. +# +# This is useful if a check needs to run a subcheck which isn't +# of interest to the user. +proc msg-quiet {args} { + incr ::autosetup(msg-quiet) + set rc [uplevel 1 $args] + incr ::autosetup(msg-quiet) -1 + return $rc +} + +# Will be overridden by 'use misc' +proc error-stacktrace {msg} { + return $msg +} + +proc error-location {msg} { + return $msg +} + +################################################################## +# +# Debugging output +# +proc dputs {msg} { + if {$::autosetup(debug)} { + puts $msg + } +} + +################################################################## +# +# User and system warnings and errors +# +# Usage errors such as wrong command line options + +# @user-error msg +# +# Indicate incorrect usage to the user, including if required components +# or features are not found. +# autosetup exits with a non-zero return code. +# +proc user-error {msg} { + show-notices + puts stderr "Error: $msg" + puts stderr "Try: '[file tail $::autosetup(exe)] --help' for options" + exit 1 +} + +# @user-notice msg +# +# Output the given message to stderr. +# +proc user-notice {msg} { + lappend ::autosetup(notices) $msg +} + +# Incorrect usage in the auto.def file. Identify the location. +proc autosetup-error {msg} { + autosetup-full-error [error-location $msg] +} + +# Like autosetup-error, except $msg is the full error message. +proc autosetup-full-error {msg} { + show-notices + puts stderr $msg + exit 1 +} + +proc show-notices {} { + if {$::autosetup(msg-checking)} { + puts "" + set ::autosetup(msg-checking) 0 + } + flush stdout + if {[info exists ::autosetup(notices)]} { + puts stderr [join $::autosetup(notices) \n] + unset ::autosetup(notices) + } +} + +proc maybe-show-timestamp {} { + if {$::autosetup(msg-timing) && $::autosetup(msg-checking) == 0} { + puts -nonewline [format {[%6.2f] } [expr {([clock millis] - $::autosetup(start)) % 10000 / 1000.0}]] + } +} + +proc autosetup_version {} { + return "autosetup v$::autosetup(version)" +} + +################################################################## +# +# Directory/path handling +# + +proc realdir {dir} { + set oldpwd [pwd] + cd $dir + set pwd [pwd] + cd $oldpwd + return $pwd +} + +# Follow symlinks until we get to something which is not a symlink +proc realpath {path} { + while {1} { + if {[catch { + set path [file link $path] + }]} { + # Not a link + break + } + } + return $path +} + +# Convert absolute path, $path into a path relative +# to the given directory (or the current dir, if not given). +# +proc relative-path {path {pwd {}}} { + set diff 0 + set same 0 + set newf {} + set prefix {} + set path [file-normalize $path] + if {$pwd eq ""} { + set pwd [pwd] + } else { + set pwd [file-normalize $pwd] + } + + if {$path eq $pwd} { + return . + } + + # Try to make the filename relative to the current dir + foreach p [split $pwd /] f [split $path /] { + if {$p ne $f} { + incr diff + } elseif {!$diff} { + incr same + } + if {$diff} { + if {$p ne ""} { + # Add .. for sibling or parent dir + lappend prefix .. + } + if {$f ne ""} { + lappend newf $f + } + } + } + if {$same == 1 || [llength $prefix] > 3} { + return $path + } + + file join [join $prefix /] [join $newf /] +} + +# Add filename as a dependency to rerun autosetup +# The name will be normalised (converted to a full path) +# +proc autosetup_add_dep {filename} { + lappend ::autosetup(deps) [file-normalize $filename] +} + +################################################################## +# +# Library module support +# + +# @use module ... +# +# Load the given library modules. +# e.g. 'use cc cc-shared' +# +# Note that module 'X' is implemented in either 'autosetup/X.tcl' +# or 'autosetup/X/init.tcl' +# +# The latter form is useful for a complex module which requires additional +# support file. In this form, '$::usedir' is set to the module directory +# when it is loaded. +# +proc use {args} { + foreach m $args { + if {[info exists ::libmodule($m)]} { + continue + } + set ::libmodule($m) 1 + if {[info exists ::modsource($m)]} { + automf_load eval $::modsource($m) + } else { + set sources [list $::autosetup(libdir)/${m}.tcl $::autosetup(libdir)/${m}/init.tcl] + set found 0 + foreach source $sources { + if {[file exists $source]} { + incr found + break + } + } + if {$found} { + # For the convenience of the "use" source, point to the directory + # it is being loaded from + set ::usedir [file dirname $source] + automf_load source $source + autosetup_add_dep $source + } else { + autosetup-error "use: No such module: $m" + } + } + } +} + +# Load module source in the global scope by executing the given command +proc automf_load {args} { + if {[catch [list uplevel #0 $args] msg opts] ni {0 2 3}} { + autosetup-full-error [error-dump $msg $opts] + } +} + +# Initial settings +set autosetup(exe) $::argv0 +set autosetup(istcl) 1 +set autosetup(start) [clock millis] +set autosetup(installed) 0 +set autosetup(msg-checking) 0 +set autosetup(msg-quiet) 0 + +# Embedded modules are inserted below here +set autosetup(installed) 1 +# ----- module asciidoc-formatting ----- + +set modsource(asciidoc-formatting) { +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which provides text formatting +# asciidoc format + +use formatting + +proc para {text} { + regsub -all "\[ \t\n\]+" [string trim $text] " " +} +proc title {text} { + underline [para $text] = + nl +} +proc p {text} { + puts [para $text] + nl +} +proc code {text} { + foreach line [parse_code_block $text] { + puts " $line" + } + nl +} +proc codelines {lines} { + foreach line $lines { + puts " $line" + } + nl +} +proc nl {} { + puts "" +} +proc underline {text char} { + regexp "^(\[ \t\]*)(.*)" $text -> indent words + puts $text + puts $indent[string repeat $char [string length $words]] +} +proc section {text} { + underline "[para $text]" - + nl +} +proc subsection {text} { + underline "$text" ~ + nl +} +proc bullet {text} { + puts "* [para $text]" +} +proc indent {text} { + puts " :: " + puts [para $text] +} +proc defn {first args} { + set sep "" + if {$first ne ""} { + puts "${first}::" + } else { + puts " :: " + } + set defn [string trim [join $args \n]] + regsub -all "\n\n" $defn "\n ::\n" defn + puts $defn +} +} + +# ----- module formatting ----- + +set modsource(formatting) { +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which provides common text formatting + +# This is designed for documenation which looks like: +# code {...} +# or +# code { +# ... +# ... +# } +# In the second case, we need to work out the indenting +# and strip it from all lines but preserve the remaining indenting. +# Note that all lines need to be indented with the same initial +# spaces/tabs. +# +# Returns a list of lines with the indenting removed. +# +proc parse_code_block {text} { + # If the text begins with newline, take the following text, + # otherwise just return the original + if {![regexp "^\n(.*)" $text -> text]} { + return [list [string trim $text]] + } + + # And trip spaces off the end + set text [string trimright $text] + + set min 100 + # Examine each line to determine the minimum indent + foreach line [split $text \n] { + if {$line eq ""} { + # Ignore empty lines for the indent calculation + continue + } + regexp "^(\[ \t\]*)" $line -> indent + set len [string length $indent] + if {$len < $min} { + set min $len + } + } + + # Now make a list of lines with this indent removed + set lines {} + foreach line [split $text \n] { + lappend lines [string range $line $min end] + } + + # Return the result + return $lines +} +} + +# ----- module getopt ----- + +set modsource(getopt) { +# Copyright (c) 2006 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Simple getopt module + +# Parse everything out of the argv list which looks like an option +# Knows about --enable-thing and --disable-thing as alternatives for --thing=0 or --thing=1 +# Everything which doesn't look like an option, or is after --, is left unchanged +proc getopt {argvname} { + upvar $argvname argv + set nargv {} + + for {set i 0} {$i < [llength $argv]} {incr i} { + set arg [lindex $argv $i] + + #dputs arg=$arg + + if {$arg eq "--"} { + # End of options + incr i + lappend nargv {*}[lrange $argv $i end] + break + } + + if {[regexp {^--([^=][^=]+)=(.*)$} $arg -> name value]} { + lappend opts($name) $value + } elseif {[regexp {^--(enable-|disable-)?([^=]*)$} $arg -> prefix name]} { + if {$prefix eq "disable-"} { + set value 0 + } else { + set value 1 + } + lappend opts($name) $value + } else { + lappend nargv $arg + } + } + + #puts "getopt: argv=[join $argv] => [join $nargv]" + #parray opts + + set argv $nargv + + return [array get opts] +} + +proc opt_val {optarrayname options {default {}}} { + upvar $optarrayname opts + + set result {} + + foreach o $options { + if {[info exists opts($o)]} { + lappend result {*}$opts($o) + } + } + if {[llength $result] == 0} { + return $default + } + return $result +} + +proc opt_bool {optarrayname args} { + upvar $optarrayname opts + + # Support the args being passed as a list + if {[llength $args] == 1} { + set args [lindex $args 0] + } + + foreach o $args { + if {[info exists opts($o)]} { + if {"1" in $opts($o) || "yes" in $opts($o)} { + return 1 + } + } + } + return 0 +} +} + +# ----- module help ----- + +set modsource(help) { +# Copyright (c) 2010 WorkWare Systems http://workware.net.au/ +# All rights reserved + +# Module which provides usage, help and the command reference + +proc autosetup_help {what} { + use_pager + + puts "Usage: [file tail $::autosetup(exe)] \[options\] \[settings\]\n" + puts "This is [autosetup_version], a build environment \"autoconfigurator\"" + puts "See the documentation online at http://msteveb.github.com/autosetup/\n" + + if {$what eq "local"} { + if {[file exists $::autosetup(autodef)]} { + # This relies on auto.def having a call to 'options' + # which will display options and quit + source $::autosetup(autodef) + } else { + options-show + } + } else { + incr ::autosetup(showhelp) + if {[catch {use $what}]} { + user-error "Unknown module: $what" + } else { + options-show + } + } + exit 0 +} + +# If not already paged and stdout is a tty, pipe the output through the pager +# This is done by reinvoking autosetup with --nopager added +proc use_pager {} { + if {![opt-bool nopager] && [getenv PAGER ""] ne "" && [isatty? stdin] && [isatty? stdout]} { + catch { + exec [info nameofexecutable] $::argv0 --nopager {*}$::argv |& [getenv PAGER] >@stdout <@stdin + } + exit 0 + } +} + +# Outputs the autosetup references in one of several formats +proc autosetup_reference {{type text}} { + + use_pager + + switch -glob -- $type { + wiki {use wiki-formatting} + ascii* {use asciidoc-formatting} + md - markdown {use markdown-formatting} + default {use text-formatting} + } + + title "[autosetup_version] -- Command Reference" + + section {Introduction} + + p { + See http://msteveb.github.com/autosetup/ for the online documentation for 'autosetup' + } + + p { + 'autosetup' provides a number of built-in commands which + are documented below. These may be used from 'auto.def' to test + for features, define variables, create files from templates and + other similar actions. + } + + automf_command_reference + + exit 0 +} + +proc autosetup_output_block {type lines} { + if {[llength $lines]} { + switch $type { + code { + codelines $lines + } + p { + p [join $lines] + } + list { + foreach line $lines { + bullet $line + } + nl + } + } + } +} + +# Generate a command reference from inline documentation +proc automf_command_reference {} { + lappend files $::autosetup(prog) + lappend files {*}[lsort [glob -nocomplain $::autosetup(libdir)/*.tcl]] + + section "Core Commands" + set type p + set lines {} + set cmd {} + + foreach file $files { + set f [open $file] + while {![eof $f]} { + set line [gets $f] + + # Find lines starting with "# @*" and continuing through the remaining comment lines + if {![regexp {^# @(.*)} $line -> cmd]} { + continue + } + + # Synopsis or command? + if {$cmd eq "synopsis:"} { + section "Module: [file rootname [file tail $file]]" + } else { + subsection $cmd + } + + set lines {} + set type p + + # Now the description + while {![eof $f]} { + set line [gets $f] + + if {![regexp {^#(#)? ?(.*)} $line -> hash cmd]} { + break + } + if {$hash eq "#"} { + set t code + } elseif {[regexp {^- (.*)} $cmd -> cmd]} { + set t list + } else { + set t p + } + + #puts "hash=$hash, oldhash=$oldhash, lines=[llength $lines], cmd=$cmd" + + if {$t ne $type || $cmd eq ""} { + # Finish the current block + autosetup_output_block $type $lines + set lines {} + set type $t + } + if {$cmd ne ""} { + lappend lines $cmd + } + } + + autosetup_output_block $type $lines + } + close $f + } +} +} + +# ----- module init ----- + +set modsource(init) { +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module to help create auto.def and configure + +proc autosetup_init {type} { + set help 0 + if {$type in {? help}} { + incr help + } elseif {![dict exists $::autosetup(inittypes) $type]} { + puts "Unknown type, --init=$type" + incr help + } + if {$help} { + puts "Use one of the following types (e.g. --init=make)\n" + foreach type [lsort [dict keys $::autosetup(inittypes)]] { + lassign [dict get $::autosetup(inittypes) $type] desc + # XXX: Use the options-show code to wrap the description + puts [format "%-10s %s" $type $desc] + } + exit 0 + } + lassign [dict get $::autosetup(inittypes) $type] desc script + + puts "Initialising $type: $desc\n" + + # All initialisations happens in the top level srcdir + cd $::autosetup(srcdir) + + uplevel #0 $script + + exit 0 +} + +proc autosetup_add_init_type {type desc script} { + dict set ::autosetup(inittypes) $type [list $desc $script] +} + +# This is for in creating build-system init scripts +# +# If the file doesn't exist, create it containing $contents +# If the file does exist, only overwrite if --force is specified. +# +proc autosetup_check_create {filename contents} { + if {[file exists $filename]} { + if {!$::autosetup(force)} { + puts "I see $filename already exists." + return + } else { + puts "I will overwrite the existing $filename because you used --force." + } + } else { + puts "I don't see $filename, so I will create it." + } + writefile $filename $contents +} +} + +# ----- module install ----- + +set modsource(install) { +# Copyright (c) 2006-2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which can install autosetup + +proc autosetup_install {dir} { + if {[catch { + cd $dir + file mkdir autosetup + + set f [open autosetup/autosetup w] + + set publicmodules $::autosetup(libdir)/default.auto + + # First the main script, but only up until "CUT HERE" + set in [open $::autosetup(dir)/autosetup] + while {[gets $in buf] >= 0} { + if {$buf ne "##-- CUT HERE --##"} { + puts $f $buf + continue + } + + # Insert the static modules here + # i.e. those which don't contain @synopsis: + puts $f "set autosetup(installed) 1" + foreach file [lsort [glob $::autosetup(libdir)/*.tcl]] { + set buf [readfile $file] + if {[string match "*\n# @synopsis:*" $buf]} { + lappend publicmodules $file + continue + } + set modname [file rootname [file tail $file]] + puts $f "# ----- module $modname -----" + puts $f "\nset modsource($modname) \{" + puts $f $buf + puts $f "\}\n" + } + } + close $in + close $f + exec chmod 755 autosetup/autosetup + + # Install public modules + foreach file $publicmodules { + autosetup_install_file $file autosetup + } + + # Install support files + foreach file {config.guess config.sub jimsh0.c find-tclsh test-tclsh LICENSE} { + autosetup_install_file $::autosetup(dir)/$file autosetup + } + exec chmod 755 autosetup/config.sub autosetup/config.guess autosetup/find-tclsh + + writefile autosetup/README.autosetup \ + "This is [autosetup_version]. See http://msteveb.github.com/autosetup/\n" + + } error]} { + user-error "Failed to install autosetup: $error" + } + puts "Installed [autosetup_version] to autosetup/" + + # Now create 'configure' if necessary + autosetup_create_configure + + exit 0 +} + +proc autosetup_create_configure {} { + if {[file exists configure]} { + if {!$::autosetup(force)} { + # Could this be an autosetup configure? + if {![string match "*\nWRAPPER=*" [readfile configure]]} { + puts "I see configure, but not created by autosetup, so I won't overwrite it." + puts "Remove it or use --force to overwrite." + return + } + } else { + puts "I will overwrite the existing configure because you used --force." + } + } else { + puts "I don't see configure, so I will create it." + } + writefile configure \ +{#!/bin/sh +dir="`dirname "$0"`/autosetup" +WRAPPER="$0"; export WRAPPER; exec "`$dir/find-tclsh`" "$dir/autosetup" "$@" +} + catch {exec chmod 755 configure} +} + +# Append the contents of $file to filehandle $f +proc autosetup_install_append {f file} { + set in [open $file] + puts $f [read $in] + close $in +} + +proc autosetup_install_file {file dir} { + if {![file exists $file]} { + error "Missing installation file '$file'" + } + writefile [file join $dir [file tail $file]] [readfile $file]\n +} + +if {$::autosetup(installed)} { + user-error "autosetup can only be installed from development source, not from installed copy" +} +} + +# ----- module markdown-formatting ----- + +set modsource(markdown-formatting) { +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which provides text formatting +# markdown format (kramdown syntax) + +use formatting + +proc para {text} { + regsub -all "\[ \t\n\]+" [string trim $text] " " text + regsub -all {([^a-zA-Z])'([^']*)'} $text {\1**`\2`**} text + regsub -all {^'([^']*)'} $text {**`\1`**} text + regsub -all {(http[^ \t\n]*)} $text {[\1](\1)} text + return $text +} +proc title {text} { + underline [para $text] = + nl +} +proc p {text} { + puts [para $text] + nl +} +proc codelines {lines} { + puts "~~~~~~~~~~~~" + foreach line $lines { + puts $line + } + puts "~~~~~~~~~~~~" + nl +} +proc code {text} { + puts "~~~~~~~~~~~~" + foreach line [parse_code_block $text] { + puts $line + } + puts "~~~~~~~~~~~~" + nl +} +proc nl {} { + puts "" +} +proc underline {text char} { + regexp "^(\[ \t\]*)(.*)" $text -> indent words + puts $text + puts $indent[string repeat $char [string length $words]] +} +proc section {text} { + underline "[para $text]" - + nl +} +proc subsection {text} { + puts "### `$text`" + nl +} +proc bullet {text} { + puts "* [para $text]" +} +proc defn {first args} { + puts "^" + set defn [string trim [join $args \n]] + if {$first ne ""} { + puts "**${first}**" + puts -nonewline ": " + regsub -all "\n\n" $defn "\n: " defn + } + puts "$defn" +} +} + +# ----- module misc ----- + +set modsource(misc) { +# Copyright (c) 2007-2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module containing misc procs useful to modules +# Largely for platform compatibility + +set autosetup(istcl) [info exists ::tcl_library] +set autosetup(iswin) [string equal windows $tcl_platform(platform)] + +if {$autosetup(iswin)} { + # mingw/windows separates $PATH with semicolons + # and doesn't have an executable bit + proc split-path {} { + split [getenv PATH .] {;} + } + proc file-isexec {exec} { + # Basic test for windows. We ignore .bat + if {[file isfile $exec] || [file isfile $exec.exe]} { + return 1 + } + return 0 + } +} else { + # unix separates $PATH with colons and has and executable bit + proc split-path {} { + split [getenv PATH .] : + } + proc file-isexec {exec} { + file executable $exec + } +} + +# Assume that exec can return stdout and stderr +proc exec-with-stderr {args} { + exec {*}$args 2>@1 +} + +if {$autosetup(istcl)} { + # Tcl doesn't have the env command + proc getenv {name args} { + if {[info exists ::env($name)]} { + return $::env($name) + } + if {[llength $args]} { + return [lindex $args 0] + } + return -code error "environment variable \"$name\" does not exist" + } + proc isatty? {channel} { + dict exists [fconfigure $channel] -xchar + } +} else { + if {$autosetup(iswin)} { + # On Windows, backslash convert all environment variables + # (Assume that Tcl does this for us) + proc getenv {name args} { + string map {\\ /} [env $name {*}$args] + } + } else { + # Jim on unix is simple + alias getenv env + } + proc isatty? {channel} { + set tty 0 + catch { + # isatty is a recent addition to Jim Tcl + set tty [$channel isatty] + } + return $tty + } +} + +# In case 'file normalize' doesn't exist +# +proc file-normalize {path} { + if {[catch {file normalize $path} result]} { + if {$path eq ""} { + return "" + } + set oldpwd [pwd] + if {[file isdir $path]} { + cd $path + set result [pwd] + } else { + cd [file dirname $path] + set result [file join [pwd] [file tail $path]] + } + cd $oldpwd + } + return $result +} + +# If everything is working properly, the only errors which occur +# should be generated in user code (e.g. auto.def). +# By default, we only want to show the error location in user code. +# We use [info frame] to achieve this, but it works differently on Tcl and Jim. +# +# This is designed to be called for incorrect usage in auto.def, via autosetup-error +# +proc error-location {msg} { + if {$::autosetup(debug)} { + return -code error $msg + } + # Search back through the stack trace for the first error in a .def file + for {set i 1} {$i < [info level]} {incr i} { + if {$::autosetup(istcl)} { + array set info [info frame -$i] + } else { + lassign [info frame -$i] info(caller) info(file) info(line) + } + if {[string match *.def $info(file)]} { + return "[relative-path $info(file)]:$info(line): Error: $msg" + } + #puts "Skipping $info(file):$info(line)" + } + return $msg +} + +# If everything is working properly, the only errors which occur +# should be generated in user code (e.g. auto.def). +# By default, we only want to show the error location in user code. +# We use [info frame] to achieve this, but it works differently on Tcl and Jim. +# +# This is designed to be called for incorrect usage in auto.def, via autosetup-error +# +proc error-stacktrace {msg} { + if {$::autosetup(debug)} { + return -code error $msg + } + # Search back through the stack trace for the first error in a .def file + for {set i 1} {$i < [info level]} {incr i} { + if {$::autosetup(istcl)} { + array set info [info frame -$i] + } else { + lassign [info frame -$i] info(caller) info(file) info(line) + } + if {[string match *.def $info(file)]} { + return "[relative-path $info(file)]:$info(line): Error: $msg" + } + #puts "Skipping $info(file):$info(line)" + } + return $msg +} + +# Given the return from [catch {...} msg opts], returns an appropriate +# error message. A nice one for Jim and a less-nice one for Tcl. +# +# This is designed for developer errors, e.g. in module code +# +proc error-dump {msg opts} { + if {$::autosetup(istcl)} { + return "Error: [dict get $opts -errorinfo]" + } else { + return "Error: $msg\n[stackdump $opts(-errorinfo)]" + } +} +} + +# ----- module text-formatting ----- + +set modsource(text-formatting) { +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which provides text formatting + +use formatting + +proc wordwrap {text length {firstprefix ""} {nextprefix ""}} { + set len 0 + set space $firstprefix + foreach word [split $text] { + set word [string trim $word] + if {$word == ""} { + continue + } + if {$len && [string length $space$word] + $len >= $length} { + puts "" + set len 0 + set space $nextprefix + } + incr len [string length $space$word] + + # Use man-page conventions for highlighting 'quoted' and *quoted* + # single words. + # Use x^Hx for *bold* and _^Hx for 'underline'. + # + # less and more will both understand this. + # Pipe through 'col -b' to remove them. + if {[regexp {^'(.*)'([^a-zA-Z0-9_]*)$} $word -> bareword dot]} { + regsub -all . $bareword "_\b&" word + append word $dot + } elseif {[regexp {^[*](.*)[*]([^a-zA-Z0-9_]*)$} $word -> bareword dot]} { + regsub -all . $bareword "&\b&" word + append word $dot + } + puts -nonewline $space$word + set space " " + } + if {$len} { + puts "" + } +} +proc title {text} { + underline [string trim $text] = + nl +} +proc p {text} { + wordwrap $text 80 + nl +} +proc codelines {lines} { + foreach line $lines { + puts " $line" + } + nl +} +proc nl {} { + puts "" +} +proc underline {text char} { + regexp "^(\[ \t\]*)(.*)" $text -> indent words + puts $text + puts $indent[string repeat $char [string length $words]] +} +proc section {text} { + underline "[string trim $text]" - + nl +} +proc subsection {text} { + underline "$text" ~ + nl +} +proc bullet {text} { + wordwrap $text 76 " * " " " +} +proc indent {text} { + wordwrap $text 76 " " " " +} +proc defn {first args} { + if {$first ne ""} { + underline " $first" ~ + } + foreach p $args { + if {$p ne ""} { + indent $p + } + } +} +} + +# ----- module wiki-formatting ----- + +set modsource(wiki-formatting) { +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which provides text formatting +# wiki.tcl.tk format output + +use formatting + +proc joinlines {text} { + set lines {} + foreach l [split [string trim $text] \n] { + lappend lines [string trim $l] + } + join $lines +} +proc p {text} { + puts [joinlines $text] + puts "" +} +proc title {text} { + puts "*** [joinlines $text] ***" + puts "" +} +proc codelines {lines} { + puts "======" + foreach line $lines { + puts " $line" + } + puts "======" +} +proc code {text} { + puts "======" + foreach line [parse_code_block $text] { + puts " $line" + } + puts "======" +} +proc nl {} { +} +proc section {text} { + puts "'''$text'''" + puts "" +} +proc subsection {text} { + puts "''$text''" + puts "" +} +proc bullet {text} { + puts " * [joinlines $text]" +} +proc indent {text} { + puts " : [joinlines $text]" +} +proc defn {first args} { + if {$first ne ""} { + indent '''$first''' + } + + foreach p $args { + p $p + } +} +} + + +################################################################## +# +# Entry/Exit +# +if {$autosetup(debug)} { + main $argv +} +if {[catch {main $argv} msg] == 1} { + show-notices + puts stderr [error-stacktrace $msg] + if {!$autosetup(debug) && !$autosetup(istcl)} { + puts stderr "Try: '[file tail $autosetup(exe)] --debug' for a full stack trace" + } + exit 1 +} diff --git a/debuggers/openocd/jimtcl/autosetup/cc-db.tcl b/debuggers/openocd/jimtcl/autosetup/cc-db.tcl new file mode 100644 index 00000000..adaf9307 --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/cc-db.tcl @@ -0,0 +1,15 @@ +# Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# @synopsis: +# +# The 'cc-db' module provides a knowledge based of system idiosyncracies +# In general, this module can always be included + +use cc + +module-options {} + +# openbsd needs sys/types.h to detect some system headers +cc-include-needs sys/socket.h sys/types.h +cc-include-needs netinet/in.h sys/types.h diff --git a/debuggers/openocd/jimtcl/autosetup/cc-lib.tcl b/debuggers/openocd/jimtcl/autosetup/cc-lib.tcl new file mode 100644 index 00000000..4df5130e --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/cc-lib.tcl @@ -0,0 +1,161 @@ +# Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# @synopsis: +# +# Provides a library of common tests on top of the 'cc' module. + +use cc + +module-options {} + +# @cc-check-lfs +# +# The equivalent of the AC_SYS_LARGEFILE macro +# +# defines 'HAVE_LFS' if LFS is available, +# and defines '_FILE_OFFSET_BITS=64' if necessary +# +# Returns 1 if 'LFS' is available or 0 otherwise +# +proc cc-check-lfs {} { + cc-check-includes sys/types.h + msg-checking "Checking if -D_FILE_OFFSET_BITS=64 is needed..." + set lfs 1 + if {[msg-quiet cc-with {-includes sys/types.h} {cc-check-sizeof off_t}] == 8} { + msg-result no + } elseif {[msg-quiet cc-with {-includes sys/types.h -cflags -D_FILE_OFFSET_BITS=64} {cc-check-sizeof off_t}] == 8} { + define _FILE_OFFSET_BITS 64 + msg-result yes + } else { + set lfs 0 + msg-result none + } + define-feature lfs $lfs + return $lfs +} + +# @cc-check-endian +# +# The equivalent of the AC_C_BIGENDIAN macro +# +# defines 'HAVE_BIG_ENDIAN' if endian is known to be big, +# or 'HAVE_LITTLE_ENDIAN' if endian is known to be little. +# +# Returns 1 if determined, or 0 if not. +# +proc cc-check-endian {} { + cc-check-includes sys/types.h sys/param.h + set rc 0 + msg-checking "Checking endian..." + cc-with {-includes {sys/types.h sys/param.h}} { + if {[cctest -code { + #if !defined(BIG_ENDIAN) || !defined(BYTE_ORDER) + #error unknown + #elif BYTE_ORDER != BIG_ENDIAN + #error little + #endif + }]} { + define-feature big-endian + msg-result "big" + set rc 1 + } elseif {[cctest -code { + #if !defined(LITTLE_ENDIAN) || !defined(BYTE_ORDER) + #error unknown + #elif BYTE_ORDER != LITTLE_ENDIAN + #error big + #endif + }]} { + define-feature little-endian + msg-result "little" + set rc 1 + } else { + msg-result "unknown" + } + } + return $rc +} + +# @cc-check-flags flag ?...? +# +# Checks whether the given C/C++ compiler flags can be used. Defines feature +# names prefixed with 'HAVE_CFLAG' and 'HAVE_CXXFLAG' respectively, and +# appends working flags to '-cflags' and 'CFLAGS' or 'CXXFLAGS'. +proc cc-check-flags {args} { + set result 1 + array set opts [cc-get-settings] + switch -exact -- $opts(-lang) { + c++ { + set lang C++ + set prefix CXXFLAG + } + c { + set lang C + set prefix CFLAG + } + default { + autosetup-error "cc-check-flags failed with unknown language: $opts(-lang)" + } + } + foreach flag $args { + msg-checking "Checking whether the $lang compiler accepts $flag..." + if {[cctest -cflags $flag]} { + msg-result yes + define-feature $prefix$flag + cc-with [list -cflags [list $flag]] + define-append ${prefix}S $flag + } else { + msg-result no + set result 0 + } + } + return $result +} + +# @cc-check-standards ver ?...? +# +# Checks whether the C/C++ compiler accepts one of the specified '-std=$ver' +# options, and appends the first working one to '-cflags' and 'CFLAGS' or +# 'CXXFLAGS'. +proc cc-check-standards {args} { + array set opts [cc-get-settings] + foreach std $args { + if {[cc-check-flags -std=$std]} { + return $std + } + } + return "" +} + +# Checks whether $keyword is usable as alignof +proc cctest_alignof {keyword} { + msg-checking "Checking for $keyword..." + if {[cctest -code [subst -nobackslashes { + printf("minimum alignment is %d == %d\n", ${keyword}(char), ${keyword}('x')); + }]]} then { + msg-result ok + define-feature $keyword + } else { + msg-result "not found" + } +} + +# @cc-check-c11 +# +# Checks for several C11/C++11 extensions and their alternatives. Currently +# checks for '_Static_assert', '_Alignof', '__alignof__', '__alignof'. +proc cc-check-c11 {} { + msg-checking "Checking for _Static_assert..." + if {[cctest -code { + _Static_assert(1, "static assertions are available"); + }]} then { + msg-result ok + define-feature _Static_assert + } else { + msg-result "not found" + } + + cctest_alignof _Alignof + cctest_alignof __alignof__ + cctest_alignof __alignof +} diff --git a/debuggers/openocd/jimtcl/autosetup/cc-shared.tcl b/debuggers/openocd/jimtcl/autosetup/cc-shared.tcl new file mode 100644 index 00000000..b9ae29d5 --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/cc-shared.tcl @@ -0,0 +1,103 @@ +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# @synopsis: +# +# The 'cc-shared' module provides support for shared libraries and shared objects. +# It defines the following variables: +# +## SH_CFLAGS Flags to use compiling sources destined for a shared library +## SH_LDFLAGS Flags to use linking (creating) a shared library +## SH_SOPREFIX Prefix to use to set the soname when creating a shared library +## SH_SOEXT Extension for shared libs +## SH_SOEXTVER Format for versioned shared libs - %s = version +## SHOBJ_CFLAGS Flags to use compiling sources destined for a shared object +## SHOBJ_LDFLAGS Flags to use linking a shared object, undefined symbols allowed +## SHOBJ_LDFLAGS_R - as above, but all symbols must be resolved +## SH_LINKFLAGS Flags to use linking an executable which will load shared objects +## LD_LIBRARY_PATH Environment variable which specifies path to shared libraries +## STRIPLIBFLAGS Arguments to strip to strip a dynamic library + +module-options {} + +# Defaults: gcc on unix +define SHOBJ_CFLAGS -fpic +define SHOBJ_LDFLAGS -shared +define SH_CFLAGS -fpic +define SH_LDFLAGS -shared +define SH_LINKFLAGS -rdynamic +define SH_SOEXT .so +define SH_SOEXTVER .so.%s +define SH_SOPREFIX -Wl,-soname, +define LD_LIBRARY_PATH LD_LIBRARY_PATH +define STRIPLIBFLAGS --strip-unneeded + +# Note: This is a helpful reference for identifying the toolchain +# http://sourceforge.net/apps/mediawiki/predef/index.php?title=Compilers + +switch -glob -- [get-define host] { + *-*-darwin* { + define SHOBJ_CFLAGS "-dynamic -fno-common" + define SHOBJ_LDFLAGS "-bundle -undefined dynamic_lookup" + define SHOBJ_LDFLAGS_R -bundle + define SH_CFLAGS -dynamic + define SH_LDFLAGS -dynamiclib + define SH_LINKFLAGS "" + define SH_SOEXT .dylib + define SH_SOEXTVER .%s.dylib + define SH_SOPREFIX -Wl,-install_name, + define LD_LIBRARY_PATH DYLD_LIBRARY_PATH + define STRIPLIBFLAGS -x + } + *-*-ming* - *-*-cygwin - *-*-msys { + define SHOBJ_CFLAGS "" + define SHOBJ_LDFLAGS -shared + define SH_CFLAGS "" + define SH_LDFLAGS -shared + define SH_LINKFLAGS "" + define SH_SOEXT .dll + define SH_SOEXTVER .dll + define SH_SOPREFIX "" + define LD_LIBRARY_PATH PATH + } + sparc* { + if {[msg-quiet cc-check-decls __SUNPRO_C]} { + msg-result "Found sun stdio compiler" + # sun stdio compiler + # XXX: These haven't been fully tested. + define SHOBJ_CFLAGS -KPIC + define SHOBJ_LDFLAGS "-G" + define SH_CFLAGS -KPIC + define SH_LINKFLAGS -Wl,-export-dynamic + define SH_SOPREFIX -Wl,-h, + } else { + # sparc has a very small GOT table limit, so use -fPIC + define SH_CFLAGS -fPIC + define SHOBJ_CFLAGS -fPIC + } + } + *-*-solaris* { + if {[msg-quiet cc-check-decls __SUNPRO_C]} { + msg-result "Found sun stdio compiler" + # sun stdio compiler + # XXX: These haven't been fully tested. + define SHOBJ_CFLAGS -KPIC + define SHOBJ_LDFLAGS "-G" + define SH_CFLAGS -KPIC + define SH_LINKFLAGS -Wl,-export-dynamic + define SH_SOPREFIX -Wl,-h, + } + } + *-*-hpux { + # XXX: These haven't been tested + define SHOBJ_CFLAGS "+O3 +z" + define SHOBJ_LDFLAGS -b + define SH_CFLAGS +z + define SH_LINKFLAGS -Wl,+s + define LD_LIBRARY_PATH SHLIB_PATH + } +} + +if {![is-defined SHOBJ_LDFLAGS_R]} { + define SHOBJ_LDFLAGS_R [get-define SHOBJ_LDFLAGS] +} diff --git a/debuggers/openocd/jimtcl/autosetup/cc.tcl b/debuggers/openocd/jimtcl/autosetup/cc.tcl new file mode 100644 index 00000000..cd033c6d --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/cc.tcl @@ -0,0 +1,697 @@ +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# @synopsis: +# +# The 'cc' module supports checking various 'features' of the C or C++ +# compiler/linker environment. Common commands are cc-check-includes, +# cc-check-types, cc-check-functions, cc-with, make-autoconf-h and make-template. +# +# The following environment variables are used if set: +# +## CC - C compiler +## CXX - C++ compiler +## CCACHE - Set to "none" to disable automatic use of ccache +## CFLAGS - Additional C compiler flags +## CXXFLAGS - Additional C++ compiler flags +## LDFLAGS - Additional compiler flags during linking +## LIBS - Additional libraries to use (for all tests) +## CROSS - Tool prefix for cross compilation +# +# The following variables are defined from the corresponding +# environment variables if set. +# +## CPPFLAGS +## LINKFLAGS +## CC_FOR_BUILD +## LD + +use system + +module-options {} + +# Note that the return code is not meaningful +proc cc-check-something {name code} { + uplevel 1 $code +} + +# Checks for the existence of the given function by linking +# +proc cctest_function {function} { + cctest -link 1 -declare "extern void $function\(void);" -code "$function\();" +} + +# Checks for the existence of the given type by compiling +proc cctest_type {type} { + cctest -code "$type _x;" +} + +# Checks for the existence of the given type/structure member. +# e.g. "struct stat.st_mtime" +proc cctest_member {struct_member} { + lassign [split $struct_member .] struct member + cctest -code "static $struct _s; return sizeof(_s.$member);" +} + +# Checks for the existence of the given define by compiling +# +proc cctest_define {name} { + cctest -code "#ifndef $name\n#error not defined\n#endif" +} + +# Checks for the existence of the given name either as +# a macro (#define) or an rvalue (such as an enum) +# +proc cctest_decl {name} { + cctest -code "#ifndef $name\n(void)$name;\n#endif" +} + +# @cc-check-sizeof type ... +# +# Checks the size of the given types (between 1 and 32, inclusive). +# Defines a variable with the size determined, or "unknown" otherwise. +# e.g. for type 'long long', defines SIZEOF_LONG_LONG. +# Returns the size of the last type. +# +proc cc-check-sizeof {args} { + foreach type $args { + msg-checking "Checking for sizeof $type..." + set size unknown + # Try the most common sizes first + foreach i {4 8 1 2 16 32} { + if {[cctest -code "static int _x\[sizeof($type) == $i ? 1 : -1\] = { 1 };"]} { + set size $i + break + } + } + msg-result $size + set define [feature-define-name $type SIZEOF_] + define $define $size + } + # Return the last result + get-define $define +} + +# Checks for each feature in $list by using the given script. +# +# When the script is evaluated, $each is set to the feature +# being checked, and $extra is set to any additional cctest args. +# +# Returns 1 if all features were found, or 0 otherwise. +proc cc-check-some-feature {list script} { + set ret 1 + foreach each $list { + if {![check-feature $each $script]} { + set ret 0 + } + } + return $ret +} + +# @cc-check-includes includes ... +# +# Checks that the given include files can be used +proc cc-check-includes {args} { + cc-check-some-feature $args { + set with {} + if {[dict exists $::autosetup(cc-include-deps) $each]} { + set deps [dict keys [dict get $::autosetup(cc-include-deps) $each]] + msg-quiet cc-check-includes {*}$deps + foreach i $deps { + if {[have-feature $i]} { + lappend with $i + } + } + } + if {[llength $with]} { + cc-with [list -includes $with] { + cctest -includes $each + } + } else { + cctest -includes $each + } + } +} + +# @cc-include-needs include required ... +# +# Ensures that when checking for 'include', a check is first +# made for each 'required' file, and if found, it is #included +proc cc-include-needs {file args} { + foreach depfile $args { + dict set ::autosetup(cc-include-deps) $file $depfile 1 + } +} + +# @cc-check-types type ... +# +# Checks that the types exist. +proc cc-check-types {args} { + cc-check-some-feature $args { + cctest_type $each + } +} + +# @cc-check-defines define ... +# +# Checks that the given preprocessor symbol is defined +proc cc-check-defines {args} { + cc-check-some-feature $args { + cctest_define $each + } +} + +# @cc-check-decls name ... +# +# Checks that each given name is either a preprocessor symbol or rvalue +# such as an enum. Note that the define used for a decl is HAVE_DECL_xxx +# rather than HAVE_xxx +proc cc-check-decls {args} { + set ret 1 + foreach name $args { + msg-checking "Checking for $name..." + set r [cctest_decl $name] + define-feature "decl $name" $r + if {$r} { + msg-result "ok" + } else { + msg-result "not found" + set ret 0 + } + } + return $ret +} + +# @cc-check-functions function ... +# +# Checks that the given functions exist (can be linked) +proc cc-check-functions {args} { + cc-check-some-feature $args { + cctest_function $each + } +} + +# @cc-check-members type.member ... +# +# Checks that the given type/structure members exist. +# A structure member is of the form "struct stat.st_mtime" +proc cc-check-members {args} { + cc-check-some-feature $args { + cctest_member $each + } +} + +# @cc-check-function-in-lib function libs ?otherlibs? +# +# Checks that the given given function can be found in one of the libs. +# +# First checks for no library required, then checks each of the libraries +# in turn. +# +# If the function is found, the feature is defined and lib_$function is defined +# to -l$lib where the function was found, or "" if no library required. +# In addition, -l$lib is added to the LIBS define. +# +# If additional libraries may be needed for linking, they should be specified +# as $extralibs as "-lotherlib1 -lotherlib2". +# These libraries are not automatically added to LIBS. +# +# Returns 1 if found or 0 if not. +# +proc cc-check-function-in-lib {function libs {otherlibs {}}} { + msg-checking "Checking libs for $function..." + set found 0 + cc-with [list -libs $otherlibs] { + if {[cctest_function $function]} { + msg-result "none needed" + define lib_$function "" + incr found + } else { + foreach lib $libs { + cc-with [list -libs -l$lib] { + if {[cctest_function $function]} { + msg-result -l$lib + define lib_$function -l$lib + define-append LIBS -l$lib + incr found + break + } + } + } + } + } + if {$found} { + define [feature-define-name $function] + } else { + msg-result "no" + } + return $found +} + +# @cc-check-tools tool ... +# +# Checks for existence of the given compiler tools, taking +# into account any cross compilation prefix. +# +# For example, when checking for "ar", first AR is checked on the command +# line and then in the environment. If not found, "${host}-ar" or +# simply "ar" is assumed depending upon whether cross compiling. +# The path is searched for this executable, and if found AR is defined +# to the executable name. +# Note that even when cross compiling, the simple "ar" is used as a fallback, +# but a warning is generated. This is necessary for some toolchains. +# +# It is an error if the executable is not found. +# +proc cc-check-tools {args} { + foreach tool $args { + set TOOL [string toupper $tool] + set exe [get-env $TOOL [get-define cross]$tool] + if {[find-executable {*}$exe]} { + define $TOOL $exe + continue + } + if {[find-executable {*}$tool]} { + msg-result "Warning: Failed to find $exe, falling back to $tool which may be incorrect" + define $TOOL $tool + continue + } + user-error "Failed to find $exe" + } +} + +# @cc-check-progs prog ... +# +# Checks for existence of the given executables on the path. +# +# For example, when checking for "grep", the path is searched for +# the executable, 'grep', and if found GREP is defined as "grep". +# +# It the executable is not found, the variable is defined as false. +# Returns 1 if all programs were found, or 0 otherwise. +# +proc cc-check-progs {args} { + set failed 0 + foreach prog $args { + set PROG [string toupper $prog] + msg-checking "Checking for $prog..." + if {![find-executable $prog]} { + msg-result no + define $PROG false + incr failed + } else { + msg-result ok + define $PROG $prog + } + } + expr {!$failed} +} + +# Adds the given settings to $::autosetup(ccsettings) and +# returns the old settings. +# +proc cc-add-settings {settings} { + if {[llength $settings] % 2} { + autosetup-error "settings list is missing a value: $settings" + } + + set prev [cc-get-settings] + # workaround a bug in some versions of jimsh by forcing + # conversion of $prev to a list + llength $prev + + array set new $prev + + foreach {name value} $settings { + switch -exact -- $name { + -cflags - -includes { + # These are given as lists + lappend new($name) {*}$value + } + -declare { + lappend new($name) $value + } + -libs { + # Note that new libraries are added before previous libraries + set new($name) [list {*}$value {*}$new($name)] + } + -link - -lang { + set new($name) $value + } + -source - -sourcefile - -code { + # XXX: These probably are only valid directly from cctest + set new($name) $value + } + default { + autosetup-error "unknown cctest setting: $name" + } + } + } + + cc-store-settings [array get new] + + return $prev +} + +proc cc-store-settings {new} { + set ::autosetup(ccsettings) $new +} + +proc cc-get-settings {} { + return $::autosetup(ccsettings) +} + +# Similar to cc-add-settings, but each given setting +# simply replaces the existing value. +# +# Returns the previous settings +proc cc-update-settings {args} { + set prev [cc-get-settings] + cc-store-settings [dict merge $prev $args] + return $prev +} + +# @cc-with settings ?{ script }? +# +# Sets the given 'cctest' settings and then runs the tests in 'script'. +# Note that settings such as -lang replace the current setting, while +# those such as -includes are appended to the existing setting. +# +# If no script is given, the settings become the default for the remainder +# of the auto.def file. +# +## cc-with {-lang c++} { +## # This will check with the C++ compiler +## cc-check-types bool +## cc-with {-includes signal.h} { +## # This will check with the C++ compiler, signal.h and any existing includes. +## ... +## } +## # back to just the C++ compiler +## } +# +# The -libs setting is special in that newer values are added *before* earlier ones. +# +## cc-with {-libs {-lc -lm}} { +## cc-with {-libs -ldl} { +## cctest -libs -lsocket ... +## # libs will be in this order: -lsocket -ldl -lc -lm +## } +## } +proc cc-with {settings args} { + if {[llength $args] == 0} { + cc-add-settings $settings + } elseif {[llength $args] > 1} { + autosetup-error "usage: cc-with settings ?script?" + } else { + set save [cc-add-settings $settings] + set rc [catch {uplevel 1 [lindex $args 0]} result info] + cc-store-settings $save + if {$rc != 0} { + return -code [dict get $info -code] $result + } + return $result + } +} + +# @cctest ?settings? +# +# Low level C compiler checker. Compiles and or links a small C program +# according to the arguments and returns 1 if OK, or 0 if not. +# +# Supported settings are: +# +## -cflags cflags A list of flags to pass to the compiler +## -includes list A list of includes, e.g. {stdlib.h stdio.h} +## -declare code Code to declare before main() +## -link 1 Don't just compile, link too +## -lang c|c++ Use the C (default) or C++ compiler +## -libs liblist List of libraries to link, e.g. {-ldl -lm} +## -code code Code to compile in the body of main() +## -source code Compile a complete program. Ignore -includes, -declare and -code +## -sourcefile file Shorthand for -source [readfile [get-define srcdir]/$file] +# +# Unless -source or -sourcefile is specified, the C program looks like: +# +## #include /* same for remaining includes in the list */ +## +## declare-code /* any code in -declare, verbatim */ +## +## int main(void) { +## code /* any code in -code, verbatim */ +## return 0; +## } +# +# Any failures are recorded in 'config.log' +# +proc cctest {args} { + set src conftest__.c + set tmp conftest__ + + # Easiest way to merge in the settings + cc-with $args { + array set opts [cc-get-settings] + } + + if {[info exists opts(-sourcefile)]} { + set opts(-source) [readfile [get-define srcdir]/$opts(-sourcefile) "#error can't find $opts(-sourcefile)"] + } + if {[info exists opts(-source)]} { + set lines $opts(-source) + } else { + foreach i $opts(-includes) { + if {$opts(-code) ne "" && ![feature-checked $i]} { + # Compiling real code with an unchecked header file + # Quickly (and silently) check for it now + + # Remove all -includes from settings before checking + set saveopts [cc-update-settings -includes {}] + msg-quiet cc-check-includes $i + cc-store-settings $saveopts + } + if {$opts(-code) eq "" || [have-feature $i]} { + lappend source "#include <$i>" + } + } + lappend source {*}$opts(-declare) + lappend source "int main(void) {" + lappend source $opts(-code) + lappend source "return 0;" + lappend source "}" + + set lines [join $source \n] + } + + # Build the command line + set cmdline {} + lappend cmdline {*}[get-define CCACHE] + switch -exact -- $opts(-lang) { + c++ { + lappend cmdline {*}[get-define CXX] {*}[get-define CXXFLAGS] + } + c { + lappend cmdline {*}[get-define CC] {*}[get-define CFLAGS] + } + default { + autosetup-error "cctest called with unknown language: $opts(-lang)" + } + } + + if {!$opts(-link)} { + set tmp conftest__.o + lappend cmdline -c + } + lappend cmdline {*}$opts(-cflags) {*}[get-define cc-default-debug ""] + + lappend cmdline $src -o $tmp {*}$opts(-libs) + + # At this point we have the complete command line and the + # complete source to be compiled. Get the result from cache if + # we can + if {[info exists ::cc_cache($cmdline,$lines)]} { + msg-checking "(cached) " + set ok $::cc_cache($cmdline,$lines) + if {$::autosetup(debug)} { + configlog "From cache (ok=$ok): [join $cmdline]" + configlog "============" + configlog $lines + configlog "============" + } + return $ok + } + + writefile $src $lines\n + + set ok 1 + if {[catch {exec-with-stderr {*}$cmdline} result errinfo]} { + configlog "Failed: [join $cmdline]" + configlog $result + configlog "============" + configlog "The failed code was:" + configlog $lines + configlog "============" + set ok 0 + } elseif {$::autosetup(debug)} { + configlog "Compiled OK: [join $cmdline]" + configlog "============" + configlog $lines + configlog "============" + } + file delete $src + file delete $tmp + + # cache it + set ::cc_cache($cmdline,$lines) $ok + + return $ok +} + +# @make-autoconf-h outfile ?auto-patterns=HAVE_*? ?bare-patterns=SIZEOF_*? +# +# Deprecated - see make-config-header +proc make-autoconf-h {file {autopatterns {HAVE_*}} {barepatterns {SIZEOF_* HAVE_DECL_*}}} { + user-notice "*** make-autoconf-h is deprecated -- use make-config-header instead" + make-config-header $file -auto $autopatterns -bare $barepatterns +} + +# @make-config-header outfile ?-auto patternlist? ?-bare patternlist? ?-none patternlist? ?-str patternlist? ... +# +# Examines all defined variables which match the given patterns +# and writes an include file, $file, which defines each of these. +# Variables which match '-auto' are output as follows: +# - defines which have the value "0" are ignored. +# - defines which have integer values are defined as the integer value. +# - any other value is defined as a string, e.g. "value" +# Variables which match '-bare' are defined as-is. +# Variables which match '-str' are defined as a string, e.g. "value" +# Variables which match '-none' are omitted. +# +# Note that order is important. The first pattern which matches is selected +# Default behaviour is: +# +# -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* -none * +# +# If the file would be unchanged, it is not written. +proc make-config-header {file args} { + set guard _[string toupper [regsub -all {[^a-zA-Z0-9]} [file tail $file] _]] + file mkdir [file dirname $file] + set lines {} + lappend lines "#ifndef $guard" + lappend lines "#define $guard" + + # Add some defaults + lappend args -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* + + foreach n [lsort [dict keys [all-defines]]] { + set value [get-define $n] + set type [calc-define-output-type $n $args] + switch -exact -- $type { + -bare { + # Just output the value unchanged + } + -none { + continue + } + -str { + set value \"[string map [list \\ \\\\ \" \\\"] $value]\" + } + -auto { + # Automatically determine the type + if {$value eq "0"} { + lappend lines "/* #undef $n */" + continue + } + if {![string is integer -strict $value]} { + set value \"[string map [list \\ \\\\ \" \\\"] $value]\" + } + } + "" { + continue + } + default { + autosetup-error "Unknown type in make-config-header: $type" + } + } + lappend lines "#define $n $value" + } + lappend lines "#endif" + set buf [join $lines \n] + write-if-changed $file $buf { + msg-result "Created $file" + } +} + +proc calc-define-output-type {name spec} { + foreach {type patterns} $spec { + foreach pattern $patterns { + if {[string match $pattern $name]} { + return $type + } + } + } + return "" +} + +# Initialise some values from the environment or commandline or default settings +foreach i {LDFLAGS LIBS CPPFLAGS LINKFLAGS {CFLAGS "-g -O2"}} { + lassign $i var default + define $var [get-env $var $default] +} + +if {[env-is-set CC]} { + # Set by the user, so don't try anything else + set try [list [get-env CC ""]] +} else { + # Try some reasonable options + set try [list [get-define cross]cc [get-define cross]gcc] +} +define CC [find-an-executable {*}$try] +if {[get-define CC] eq ""} { + user-error "Could not find a C compiler. Tried: [join $try ", "]" +} + +define CPP [get-env CPP "[get-define CC] -E"] + +# XXX: Could avoid looking for a C++ compiler until requested +# Note that if CXX isn't found, we just set it to "false". It might not be needed. +if {[env-is-set CXX]} { + define CXX [find-an-executable -required [get-env CXX ""]] +} else { + define CXX [find-an-executable [get-define cross]c++ [get-define cross]g++ false] +} + +# CXXFLAGS default to CFLAGS if not specified +define CXXFLAGS [get-env CXXFLAGS [get-define CFLAGS]] + +# May need a CC_FOR_BUILD, so look for one +define CC_FOR_BUILD [find-an-executable [get-env CC_FOR_BUILD ""] cc gcc false] + +if {[get-define CC] eq ""} { + user-error "Could not find a C compiler. Tried: [join $try ", "]" +} + +define CCACHE [find-an-executable [get-env CCACHE ccache]] + +# Initial cctest settings +cc-store-settings {-cflags {} -includes {} -declare {} -link 0 -lang c -libs {} -code {}} +set autosetup(cc-include-deps) {} + +msg-result "C compiler...[get-define CCACHE] [get-define CC] [get-define CFLAGS]" +if {[get-define CXX] ne "false"} { + msg-result "C++ compiler...[get-define CCACHE] [get-define CXX] [get-define CXXFLAGS]" +} +msg-result "Build C compiler...[get-define CC_FOR_BUILD]" + +# On Darwin, we prefer to use -gstabs to avoid creating .dSYM directories +# but some compilers don't support -gstabs, so test for it here. +switch -glob -- [get-define host] { + *-*-darwin* { + if {[cctest -cflags {-gstabs}]} { + define cc-default-debug -gstabs + } + } +} + +if {![cc-check-includes stdlib.h]} { + user-error "Compiler does not work. See config.log" +} diff --git a/debuggers/openocd/jimtcl/autosetup/config.guess b/debuggers/openocd/jimtcl/autosetup/config.guess new file mode 100755 index 00000000..089ebccd --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/config.guess @@ -0,0 +1,1511 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +# Free Software Foundation, Inc. + +timestamp='2010-09-24' + +# This file 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 Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free +Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' HUP INT TERM + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" HUP INT PIPE TERM ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-tilera-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/debuggers/openocd/jimtcl/autosetup/config.sub b/debuggers/openocd/jimtcl/autosetup/config.sub new file mode 100755 index 00000000..a09498ff --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/config.sub @@ -0,0 +1,1743 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +# Free Software Foundation, Inc. + +timestamp='2010-09-11' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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 Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free +Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile-* | tilegx-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + # This must be matched before tile*. + tilegx*) + basic_machine=tilegx-unknown + os=-linux-gnu + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/debuggers/openocd/jimtcl/autosetup/default.auto b/debuggers/openocd/jimtcl/autosetup/default.auto new file mode 100644 index 00000000..b36e0f8d --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/default.auto @@ -0,0 +1,25 @@ +# Copyright (c) 2012 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Auto-load module for 'make' build system integration + +use init + +autosetup_add_init_type make {Simple "make" build system} { + autosetup_check_create auto.def \ +{# Initial auto.def created by 'autosetup --init=make' + +use cc + +# Add any user options here +options { +} + +make-config-header config.h +make-template Makefile.in +} + + if {![file exists Makefile.in]} { + puts "Note: I don't see Makefile.in. You will probably need to create one." + } +} diff --git a/debuggers/openocd/jimtcl/autosetup/find-tclsh b/debuggers/openocd/jimtcl/autosetup/find-tclsh new file mode 100755 index 00000000..be7cf3d6 --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/find-tclsh @@ -0,0 +1,16 @@ +#!/bin/sh +# Looks for a suitable tclsh or jimsh in the PATH +# If not found, builds a bootstrap jimsh from source +d=`dirname "$0"` +{ "$d/jimsh0" "$d/test-tclsh"; } 2>/dev/null && exit 0 +PATH="$PATH:$d"; export PATH +for tclsh in jimsh tclsh tclsh8.5 tclsh8.6; do + { $tclsh "$d/test-tclsh"; } 2>/dev/null && exit 0 +done +echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" +for cc in ${CC_FOR_BUILD:-cc} gcc; do + { $cc -o "$d/jimsh0" "$d/jimsh0.c"; } 2>/dev/null || continue + "$d/jimsh0" "$d/test-tclsh" && exit 0 +done +echo 1>&2 "No working C compiler found. Tried ${CC_FOR_BUILD:-cc} and gcc." +echo false diff --git a/debuggers/openocd/jimtcl/autosetup/jimsh0.c b/debuggers/openocd/jimtcl/autosetup/jimsh0.c new file mode 100644 index 00000000..bdc72e50 --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/jimsh0.c @@ -0,0 +1,21555 @@ +/* This is single source file, bootstrap version of Jim Tcl. See http://jim.berlios.de/ */ +#define _GNU_SOURCE +#define JIM_TCL_COMPAT +#define JIM_REFERENCES +#define JIM_ANSIC +#define JIM_REGEXP +#define HAVE_NO_AUTOCONF +#define _JIMAUTOCONF_H +#define TCL_LIBRARY "." +#define jim_ext_bootstrap +#define jim_ext_aio +#define jim_ext_readdir +#define jim_ext_glob +#define jim_ext_regexp +#define jim_ext_file +#define jim_ext_exec +#define jim_ext_clock +#define jim_ext_array +#define jim_ext_stdlib +#define jim_ext_tclcompat +#if defined(_MSC_VER) +#define TCL_PLATFORM_OS "windows" +#define TCL_PLATFORM_PLATFORM "windows" +#define TCL_PLATFORM_PATH_SEPARATOR ";" +#define HAVE_MKDIR_ONE_ARG +#define HAVE_SYSTEM +#elif defined(__MINGW32__) +#define TCL_PLATFORM_OS "mingw" +#define TCL_PLATFORM_PLATFORM "windows" +#define TCL_PLATFORM_PATH_SEPARATOR ";" +#define HAVE_MKDIR_ONE_ARG +#define HAVE_SYSTEM +#define HAVE_SYS_TIME_H +#define HAVE_DIRENT_H +#define HAVE_UNISTD_H +#else +#define TCL_PLATFORM_OS "unknown" +#define TCL_PLATFORM_PLATFORM "unix" +#define TCL_PLATFORM_PATH_SEPARATOR ":" +#define HAVE_VFORK +#define HAVE_WAITPID +#define HAVE_ISATTY +#define HAVE_SYS_TIME_H +#define HAVE_DIRENT_H +#define HAVE_UNISTD_H +#endif +#ifndef JIM_WIN32COMPAT_H +#define JIM_WIN32COMPAT_H + + + + +#if defined(_WIN32) || defined(WIN32) + +#define HAVE_DLOPEN +void *dlopen(const char *path, int mode); +int dlclose(void *handle); +void *dlsym(void *handle, const char *symbol); +char *dlerror(void); + + +#define JIM_SPRINTF_DOUBLE_NEEDS_FIX + +#ifdef _MSC_VER + + +#if _MSC_VER >= 1000 + #pragma warning(disable:4146) +#endif + +#include +#define jim_wide _int64 +#ifndef LLONG_MAX + #define LLONG_MAX 9223372036854775807I64 +#endif +#ifndef LLONG_MIN + #define LLONG_MIN (-LLONG_MAX - 1I64) +#endif +#define JIM_WIDE_MIN LLONG_MIN +#define JIM_WIDE_MAX LLONG_MAX +#define JIM_WIDE_MODIFIER "I64d" +#define strcasecmp _stricmp +#define strtoull _strtoui64 +#define snprintf _snprintf + +#include + +struct timeval { + long tv_sec; + long tv_usec; +}; + +int gettimeofday(struct timeval *tv, void *unused); + +#define HAVE_OPENDIR +struct dirent { + char *d_name; +}; + +typedef struct DIR { + long handle; + struct _finddata_t info; + struct dirent result; + char *name; +} DIR; + +DIR *opendir(const char *name); +int closedir(DIR *dir); +struct dirent *readdir(DIR *dir); +#endif + +#endif + +#endif +#ifndef UTF8_UTIL_H +#define UTF8_UTIL_H + + +#define MAX_UTF8_LEN 4 + +int utf8_fromunicode(char *p, unsigned uc); + +#ifndef JIM_UTF8 +#include + + +#define utf8_strlen(S, B) ((B) < 0 ? strlen(S) : (B)) +#define utf8_tounicode(S, CP) (*(CP) = (unsigned char)*(S), 1) +#define utf8_upper(C) toupper(C) +#define utf8_title(C) toupper(C) +#define utf8_lower(C) tolower(C) +#define utf8_index(C, I) (I) +#define utf8_charlen(C) 1 +#define utf8_prev_len(S, L) 1 + +#else + +#endif + +#endif + +#ifndef __JIM__H +#define __JIM__H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + + +#ifndef HAVE_NO_AUTOCONF +#endif + + + +#ifndef jim_wide +# ifdef HAVE_LONG_LONG +# define jim_wide long long +# ifndef LLONG_MAX +# define LLONG_MAX 9223372036854775807LL +# endif +# ifndef LLONG_MIN +# define LLONG_MIN (-LLONG_MAX - 1LL) +# endif +# define JIM_WIDE_MIN LLONG_MIN +# define JIM_WIDE_MAX LLONG_MAX +# else +# define jim_wide long +# define JIM_WIDE_MIN LONG_MIN +# define JIM_WIDE_MAX LONG_MAX +# endif + + +# ifdef HAVE_LONG_LONG +# define JIM_WIDE_MODIFIER "lld" +# else +# define JIM_WIDE_MODIFIER "ld" +# define strtoull strtoul +# endif +#endif + +#define UCHAR(c) ((unsigned char)(c)) + + +#define JIM_VERSION 73 + +#define JIM_OK 0 +#define JIM_ERR 1 +#define JIM_RETURN 2 +#define JIM_BREAK 3 +#define JIM_CONTINUE 4 +#define JIM_SIGNAL 5 +#define JIM_EXIT 6 + +#define JIM_EVAL 7 + +#define JIM_MAX_CALLFRAME_DEPTH 1000 +#define JIM_MAX_EVAL_DEPTH 2000 + +#define JIM_NONE 0 +#define JIM_ERRMSG 1 + +#define JIM_UNSHARED 4 +#define JIM_MUSTEXIST 8 + + +#define JIM_GLOBAL_ONLY 0x100 + + +#define JIM_SUBST_NOVAR 1 +#define JIM_SUBST_NOCMD 2 +#define JIM_SUBST_NOESC 4 +#define JIM_SUBST_FLAG 128 + + +#define JIM_NOTUSED(V) ((void) V) + + +#define JIM_ENUM_ABBREV 2 + + +#define JIM_CASESENS 0 +#define JIM_NOCASE 1 + + +#define JIM_PATH_LEN 1024 + + +#ifdef JIM_CRLF +#define JIM_NL "\r\n" +#else +#define JIM_NL "\n" +#endif + +#define JIM_LIBPATH "auto_path" +#define JIM_INTERACTIVE "tcl_interactive" + + +typedef struct Jim_Stack { + int len; + int maxlen; + void **vector; +} Jim_Stack; + + +typedef struct Jim_HashEntry { + void *key; + union { + void *val; + int intval; + } u; + struct Jim_HashEntry *next; +} Jim_HashEntry; + +typedef struct Jim_HashTableType { + unsigned int (*hashFunction)(const void *key); + void *(*keyDup)(void *privdata, const void *key); + void *(*valDup)(void *privdata, const void *obj); + int (*keyCompare)(void *privdata, const void *key1, const void *key2); + void (*keyDestructor)(void *privdata, void *key); + void (*valDestructor)(void *privdata, void *obj); +} Jim_HashTableType; + +typedef struct Jim_HashTable { + Jim_HashEntry **table; + const Jim_HashTableType *type; + unsigned int size; + unsigned int sizemask; + unsigned int used; + unsigned int collisions; + void *privdata; +} Jim_HashTable; + +typedef struct Jim_HashTableIterator { + Jim_HashTable *ht; + int index; + Jim_HashEntry *entry, *nextEntry; +} Jim_HashTableIterator; + + +#define JIM_HT_INITIAL_SIZE 16 + + +#define Jim_FreeEntryVal(ht, entry) \ + if ((ht)->type->valDestructor) \ + (ht)->type->valDestructor((ht)->privdata, (entry)->u.val) + +#define Jim_SetHashVal(ht, entry, _val_) do { \ + if ((ht)->type->valDup) \ + entry->u.val = (ht)->type->valDup((ht)->privdata, _val_); \ + else \ + entry->u.val = (_val_); \ +} while(0) + +#define Jim_FreeEntryKey(ht, entry) \ + if ((ht)->type->keyDestructor) \ + (ht)->type->keyDestructor((ht)->privdata, (entry)->key) + +#define Jim_SetHashKey(ht, entry, _key_) do { \ + if ((ht)->type->keyDup) \ + entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \ + else \ + entry->key = (void *)(_key_); \ +} while(0) + +#define Jim_CompareHashKeys(ht, key1, key2) \ + (((ht)->type->keyCompare) ? \ + (ht)->type->keyCompare((ht)->privdata, key1, key2) : \ + (key1) == (key2)) + +#define Jim_HashKey(ht, key) (ht)->type->hashFunction(key) + +#define Jim_GetHashEntryKey(he) ((he)->key) +#define Jim_GetHashEntryVal(he) ((he)->val) +#define Jim_GetHashTableCollisions(ht) ((ht)->collisions) +#define Jim_GetHashTableSize(ht) ((ht)->size) +#define Jim_GetHashTableUsed(ht) ((ht)->used) + + +typedef struct Jim_Obj { + int refCount; + char *bytes; + int length; + const struct Jim_ObjType *typePtr; + + union { + + jim_wide wideValue; + + int intValue; + + double doubleValue; + + void *ptr; + + struct { + void *ptr1; + void *ptr2; + } twoPtrValue; + + struct { + unsigned long callFrameId; + struct Jim_Var *varPtr; + int global; + } varValue; + + struct { + unsigned long procEpoch; + struct Jim_Obj *nsObj; + struct Jim_Cmd *cmdPtr; + } cmdValue; + + struct { + struct Jim_Obj **ele; + int len; + int maxLen; + } listValue; + + struct { + int maxLength; + int charLength; + } strValue; + + struct { + unsigned long id; + struct Jim_Reference *refPtr; + } refValue; + + struct { + struct Jim_Obj *fileNameObj; + int lineNumber; + } sourceValue; + + struct { + struct Jim_Obj *varNameObjPtr; + struct Jim_Obj *indexObjPtr; + } dictSubstValue; + + struct { + unsigned flags; + void *compre; + } regexpValue; + struct { + int line; + int argc; + } scriptLineValue; + } internalRep; + struct Jim_Obj *prevObjPtr; + struct Jim_Obj *nextObjPtr; +} Jim_Obj; + + +#define Jim_IncrRefCount(objPtr) \ + ++(objPtr)->refCount +#define Jim_DecrRefCount(interp, objPtr) \ + if (--(objPtr)->refCount <= 0) Jim_FreeObj(interp, objPtr) +#define Jim_IsShared(objPtr) \ + ((objPtr)->refCount > 1) + +#define Jim_FreeNewObj Jim_FreeObj + + +#define Jim_FreeIntRep(i,o) \ + if ((o)->typePtr && (o)->typePtr->freeIntRepProc) \ + (o)->typePtr->freeIntRepProc(i, o) + + +#define Jim_GetIntRepPtr(o) (o)->internalRep.ptr + + +#define Jim_SetIntRepPtr(o, p) \ + (o)->internalRep.ptr = (p) + + +struct Jim_Interp; + +typedef void (Jim_FreeInternalRepProc)(struct Jim_Interp *interp, + struct Jim_Obj *objPtr); +typedef void (Jim_DupInternalRepProc)(struct Jim_Interp *interp, + struct Jim_Obj *srcPtr, Jim_Obj *dupPtr); +typedef void (Jim_UpdateStringProc)(struct Jim_Obj *objPtr); + +typedef struct Jim_ObjType { + const char *name; + Jim_FreeInternalRepProc *freeIntRepProc; + Jim_DupInternalRepProc *dupIntRepProc; + Jim_UpdateStringProc *updateStringProc; + int flags; +} Jim_ObjType; + + +#define JIM_TYPE_NONE 0 +#define JIM_TYPE_REFERENCES 1 + +#define JIM_PRIV_FLAG_SHIFT 20 + + + +typedef struct Jim_CallFrame { + unsigned long id; + int level; + struct Jim_HashTable vars; + struct Jim_HashTable *staticVars; + struct Jim_CallFrame *parent; + Jim_Obj *const *argv; + int argc; + Jim_Obj *procArgsObjPtr; + Jim_Obj *procBodyObjPtr; + struct Jim_CallFrame *next; + Jim_Obj *nsObj; + Jim_Obj *fileNameObj; + int line; + Jim_Stack *localCommands; +} Jim_CallFrame; + +typedef struct Jim_Var { + Jim_Obj *objPtr; + struct Jim_CallFrame *linkFramePtr; +} Jim_Var; + + +typedef int (*Jim_CmdProc)(struct Jim_Interp *interp, int argc, + Jim_Obj *const *argv); +typedef void (*Jim_DelCmdProc)(struct Jim_Interp *interp, void *privData); + + + +typedef struct Jim_Cmd { + int inUse; + int isproc; + struct Jim_Cmd *prevCmd; + union { + struct { + + Jim_CmdProc cmdProc; + Jim_DelCmdProc delProc; + void *privData; + } native; + struct { + + Jim_Obj *argListObjPtr; + Jim_Obj *bodyObjPtr; + Jim_HashTable *staticVars; + int argListLen; + int reqArity; + int optArity; + int argsPos; + int upcall; + struct Jim_ProcArg { + Jim_Obj *nameObjPtr; + Jim_Obj *defaultObjPtr; + } *arglist; + Jim_Obj *nsObj; + } proc; + } u; +} Jim_Cmd; + + +typedef struct Jim_PrngState { + unsigned char sbox[256]; + unsigned int i, j; +} Jim_PrngState; + +typedef struct Jim_Interp { + Jim_Obj *result; + int errorLine; + Jim_Obj *errorFileNameObj; + int addStackTrace; + int maxCallFrameDepth; + int maxEvalDepth; + int evalDepth; + int returnCode; + int returnLevel; + int exitCode; + long id; + int signal_level; + jim_wide sigmask; + int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask); + Jim_CallFrame *framePtr; + Jim_CallFrame *topFramePtr; + struct Jim_HashTable commands; + unsigned long procEpoch; /* Incremented every time the result + of procedures names lookup caching + may no longer be valid. */ + unsigned long callFrameEpoch; /* Incremented every time a new + callframe is created. This id is used for the + 'ID' field contained in the Jim_CallFrame + structure. */ + int local; + Jim_Obj *liveList; + Jim_Obj *freeList; + Jim_Obj *currentScriptObj; + Jim_Obj *nullScriptObj; + Jim_Obj *emptyObj; + Jim_Obj *trueObj; + Jim_Obj *falseObj; + unsigned long referenceNextId; + struct Jim_HashTable references; + unsigned long lastCollectId; /* reference max Id of the last GC + execution. It's set to -1 while the collection + is running as sentinel to avoid to recursive + calls via the [collect] command inside + finalizers. */ + time_t lastCollectTime; + Jim_Obj *stackTrace; + Jim_Obj *errorProc; + Jim_Obj *unknown; + int unknown_called; + int errorFlag; + void *cmdPrivData; /* Used to pass the private data pointer to + a command. It is set to what the user specified + via Jim_CreateCommand(). */ + + struct Jim_CallFrame *freeFramesList; + struct Jim_HashTable assocData; + Jim_PrngState *prngState; + struct Jim_HashTable packages; + Jim_Stack *loadHandles; +} Jim_Interp; + +#define Jim_InterpIncrProcEpoch(i) (i)->procEpoch++ +#define Jim_SetResultString(i,s,l) Jim_SetResult(i, Jim_NewStringObj(i,s,l)) +#define Jim_SetResultInt(i,intval) Jim_SetResult(i, Jim_NewIntObj(i,intval)) + +#define Jim_SetResultBool(i,b) Jim_SetResultInt(i, b) +#define Jim_SetEmptyResult(i) Jim_SetResult(i, (i)->emptyObj) +#define Jim_GetResult(i) ((i)->result) +#define Jim_CmdPrivData(i) ((i)->cmdPrivData) + +#define Jim_SetResult(i,o) do { \ + Jim_Obj *_resultObjPtr_ = (o); \ + Jim_IncrRefCount(_resultObjPtr_); \ + Jim_DecrRefCount(i,(i)->result); \ + (i)->result = _resultObjPtr_; \ +} while(0) + + +#define Jim_GetId(i) (++(i)->id) + + +#define JIM_REFERENCE_TAGLEN 7 /* The tag is fixed-length, because the reference + string representation must be fixed length. */ +typedef struct Jim_Reference { + Jim_Obj *objPtr; + Jim_Obj *finalizerCmdNamePtr; + char tag[JIM_REFERENCE_TAGLEN+1]; +} Jim_Reference; + + + +#define Jim_NewEmptyStringObj(i) Jim_NewStringObj(i, "", 0) + + + +#define Jim_FreeHashTableIterator(iter) Jim_Free(iter) + +#define JIM_EXPORT + + +JIM_EXPORT void *Jim_Alloc (int size); +JIM_EXPORT void *Jim_Realloc(void *ptr, int size); +JIM_EXPORT void Jim_Free (void *ptr); +JIM_EXPORT char * Jim_StrDup (const char *s); +JIM_EXPORT char *Jim_StrDupLen(const char *s, int l); + + +JIM_EXPORT char **Jim_GetEnviron(void); +JIM_EXPORT void Jim_SetEnviron(char **env); + + +JIM_EXPORT int Jim_Eval(Jim_Interp *interp, const char *script); + + +JIM_EXPORT int Jim_EvalSource(Jim_Interp *interp, const char *filename, int lineno, const char *script); + +#define Jim_Eval_Named(I, S, F, L) Jim_EvalSource((I), (F), (L), (S)) + +JIM_EXPORT int Jim_EvalGlobal(Jim_Interp *interp, const char *script); +JIM_EXPORT int Jim_EvalFile(Jim_Interp *interp, const char *filename); +JIM_EXPORT int Jim_EvalFileGlobal(Jim_Interp *interp, const char *filename); +JIM_EXPORT int Jim_EvalObj (Jim_Interp *interp, Jim_Obj *scriptObjPtr); +JIM_EXPORT int Jim_EvalObjVector (Jim_Interp *interp, int objc, + Jim_Obj *const *objv); +JIM_EXPORT int Jim_EvalObjList(Jim_Interp *interp, Jim_Obj *listObj); +JIM_EXPORT int Jim_EvalObjPrefix(Jim_Interp *interp, Jim_Obj *prefix, + int objc, Jim_Obj *const *objv); +#define Jim_EvalPrefix(i, p, oc, ov) Jim_EvalObjPrefix((i), Jim_NewStringObj((i), (p), -1), (oc), (ov)) +JIM_EXPORT int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj); +JIM_EXPORT int Jim_SubstObj (Jim_Interp *interp, Jim_Obj *substObjPtr, + Jim_Obj **resObjPtrPtr, int flags); + + +JIM_EXPORT void Jim_InitStack(Jim_Stack *stack); +JIM_EXPORT void Jim_FreeStack(Jim_Stack *stack); +JIM_EXPORT int Jim_StackLen(Jim_Stack *stack); +JIM_EXPORT void Jim_StackPush(Jim_Stack *stack, void *element); +JIM_EXPORT void * Jim_StackPop(Jim_Stack *stack); +JIM_EXPORT void * Jim_StackPeek(Jim_Stack *stack); +JIM_EXPORT void Jim_FreeStackElements(Jim_Stack *stack, void (*freeFunc)(void *ptr)); + + +JIM_EXPORT int Jim_InitHashTable (Jim_HashTable *ht, + const Jim_HashTableType *type, void *privdata); +JIM_EXPORT void Jim_ExpandHashTable (Jim_HashTable *ht, + unsigned int size); +JIM_EXPORT int Jim_AddHashEntry (Jim_HashTable *ht, const void *key, + void *val); +JIM_EXPORT int Jim_ReplaceHashEntry (Jim_HashTable *ht, + const void *key, void *val); +JIM_EXPORT int Jim_DeleteHashEntry (Jim_HashTable *ht, + const void *key); +JIM_EXPORT int Jim_FreeHashTable (Jim_HashTable *ht); +JIM_EXPORT Jim_HashEntry * Jim_FindHashEntry (Jim_HashTable *ht, + const void *key); +JIM_EXPORT void Jim_ResizeHashTable (Jim_HashTable *ht); +JIM_EXPORT Jim_HashTableIterator *Jim_GetHashTableIterator + (Jim_HashTable *ht); +JIM_EXPORT Jim_HashEntry * Jim_NextHashEntry + (Jim_HashTableIterator *iter); + + +JIM_EXPORT Jim_Obj * Jim_NewObj (Jim_Interp *interp); +JIM_EXPORT void Jim_FreeObj (Jim_Interp *interp, Jim_Obj *objPtr); +JIM_EXPORT void Jim_InvalidateStringRep (Jim_Obj *objPtr); +JIM_EXPORT void Jim_InitStringRep (Jim_Obj *objPtr, const char *bytes, + int length); +JIM_EXPORT Jim_Obj * Jim_DuplicateObj (Jim_Interp *interp, + Jim_Obj *objPtr); +JIM_EXPORT const char * Jim_GetString(Jim_Obj *objPtr, + int *lenPtr); +JIM_EXPORT const char *Jim_String(Jim_Obj *objPtr); +JIM_EXPORT int Jim_Length(Jim_Obj *objPtr); + + +JIM_EXPORT Jim_Obj * Jim_NewStringObj (Jim_Interp *interp, + const char *s, int len); +JIM_EXPORT Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, + const char *s, int charlen); +JIM_EXPORT Jim_Obj * Jim_NewStringObjNoAlloc (Jim_Interp *interp, + char *s, int len); +JIM_EXPORT void Jim_AppendString (Jim_Interp *interp, Jim_Obj *objPtr, + const char *str, int len); +JIM_EXPORT void Jim_AppendObj (Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *appendObjPtr); +JIM_EXPORT void Jim_AppendStrings (Jim_Interp *interp, + Jim_Obj *objPtr, ...); +JIM_EXPORT int Jim_StringEqObj(Jim_Obj *aObjPtr, Jim_Obj *bObjPtr); +JIM_EXPORT int Jim_StringMatchObj (Jim_Interp *interp, Jim_Obj *patternObjPtr, + Jim_Obj *objPtr, int nocase); +JIM_EXPORT Jim_Obj * Jim_StringRangeObj (Jim_Interp *interp, + Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, + Jim_Obj *lastObjPtr); +JIM_EXPORT Jim_Obj * Jim_FormatString (Jim_Interp *interp, + Jim_Obj *fmtObjPtr, int objc, Jim_Obj *const *objv); +JIM_EXPORT Jim_Obj * Jim_ScanString (Jim_Interp *interp, Jim_Obj *strObjPtr, + Jim_Obj *fmtObjPtr, int flags); +JIM_EXPORT int Jim_CompareStringImmediate (Jim_Interp *interp, + Jim_Obj *objPtr, const char *str); +JIM_EXPORT int Jim_StringCompareObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, + Jim_Obj *secondObjPtr, int nocase); +JIM_EXPORT int Jim_StringCompareLenObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, + Jim_Obj *secondObjPtr, int nocase); +JIM_EXPORT int Jim_Utf8Length(Jim_Interp *interp, Jim_Obj *objPtr); + + +JIM_EXPORT Jim_Obj * Jim_NewReference (Jim_Interp *interp, + Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr); +JIM_EXPORT Jim_Reference * Jim_GetReference (Jim_Interp *interp, + Jim_Obj *objPtr); +JIM_EXPORT int Jim_SetFinalizer (Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *cmdNamePtr); +JIM_EXPORT int Jim_GetFinalizer (Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj **cmdNamePtrPtr); + + +JIM_EXPORT Jim_Interp * Jim_CreateInterp (void); +JIM_EXPORT void Jim_FreeInterp (Jim_Interp *i); +JIM_EXPORT int Jim_GetExitCode (Jim_Interp *interp); +JIM_EXPORT const char *Jim_ReturnCode(int code); +JIM_EXPORT void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...); + + +JIM_EXPORT void Jim_RegisterCoreCommands (Jim_Interp *interp); +JIM_EXPORT int Jim_CreateCommand (Jim_Interp *interp, + const char *cmdName, Jim_CmdProc cmdProc, void *privData, + Jim_DelCmdProc delProc); +JIM_EXPORT int Jim_DeleteCommand (Jim_Interp *interp, + const char *cmdName); +JIM_EXPORT int Jim_RenameCommand (Jim_Interp *interp, + const char *oldName, const char *newName); +JIM_EXPORT Jim_Cmd * Jim_GetCommand (Jim_Interp *interp, + Jim_Obj *objPtr, int flags); +JIM_EXPORT int Jim_SetVariable (Jim_Interp *interp, + Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr); +JIM_EXPORT int Jim_SetVariableStr (Jim_Interp *interp, + const char *name, Jim_Obj *objPtr); +JIM_EXPORT int Jim_SetGlobalVariableStr (Jim_Interp *interp, + const char *name, Jim_Obj *objPtr); +JIM_EXPORT int Jim_SetVariableStrWithStr (Jim_Interp *interp, + const char *name, const char *val); +JIM_EXPORT int Jim_SetVariableLink (Jim_Interp *interp, + Jim_Obj *nameObjPtr, Jim_Obj *targetNameObjPtr, + Jim_CallFrame *targetCallFrame); +JIM_EXPORT int Jim_CreateNamespaceVariable(Jim_Interp *interp, + Jim_Obj *varNameObj, Jim_Obj *targetNameObj); +JIM_EXPORT int Jim_DiscardNamespaceVars(Jim_Interp *interp); +JIM_EXPORT Jim_Obj * Jim_GetVariable (Jim_Interp *interp, + Jim_Obj *nameObjPtr, int flags); +JIM_EXPORT Jim_Obj * Jim_GetGlobalVariable (Jim_Interp *interp, + Jim_Obj *nameObjPtr, int flags); +JIM_EXPORT Jim_Obj * Jim_GetVariableStr (Jim_Interp *interp, + const char *name, int flags); +JIM_EXPORT Jim_Obj * Jim_GetGlobalVariableStr (Jim_Interp *interp, + const char *name, int flags); +JIM_EXPORT int Jim_UnsetVariable (Jim_Interp *interp, + Jim_Obj *nameObjPtr, int flags); + + +JIM_EXPORT Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, + Jim_Obj *levelObjPtr); + + +JIM_EXPORT int Jim_Collect (Jim_Interp *interp); +JIM_EXPORT void Jim_CollectIfNeeded (Jim_Interp *interp); + + +JIM_EXPORT int Jim_GetIndex (Jim_Interp *interp, Jim_Obj *objPtr, + int *indexPtr); + + +JIM_EXPORT Jim_Obj * Jim_NewListObj (Jim_Interp *interp, + Jim_Obj *const *elements, int len); +JIM_EXPORT void Jim_ListInsertElements (Jim_Interp *interp, + Jim_Obj *listPtr, int listindex, int objc, Jim_Obj *const *objVec); +JIM_EXPORT void Jim_ListAppendElement (Jim_Interp *interp, + Jim_Obj *listPtr, Jim_Obj *objPtr); +JIM_EXPORT void Jim_ListAppendList (Jim_Interp *interp, + Jim_Obj *listPtr, Jim_Obj *appendListPtr); +JIM_EXPORT int Jim_ListLength (Jim_Interp *interp, Jim_Obj *objPtr); +JIM_EXPORT int Jim_ListIndex (Jim_Interp *interp, Jim_Obj *listPrt, + int listindex, Jim_Obj **objPtrPtr, int seterr); +JIM_EXPORT Jim_Obj *Jim_ListGetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx); +JIM_EXPORT int Jim_SetListIndex (Jim_Interp *interp, + Jim_Obj *varNamePtr, Jim_Obj *const *indexv, int indexc, + Jim_Obj *newObjPtr); +JIM_EXPORT Jim_Obj * Jim_ConcatObj (Jim_Interp *interp, int objc, + Jim_Obj *const *objv); +JIM_EXPORT Jim_Obj *Jim_ListJoin(Jim_Interp *interp, + Jim_Obj *listObjPtr, const char *joinStr, int joinStrLen); + + +JIM_EXPORT Jim_Obj * Jim_NewDictObj (Jim_Interp *interp, + Jim_Obj *const *elements, int len); +JIM_EXPORT int Jim_DictKey (Jim_Interp *interp, Jim_Obj *dictPtr, + Jim_Obj *keyPtr, Jim_Obj **objPtrPtr, int flags); +JIM_EXPORT int Jim_DictKeysVector (Jim_Interp *interp, + Jim_Obj *dictPtr, Jim_Obj *const *keyv, int keyc, + Jim_Obj **objPtrPtr, int flags); +JIM_EXPORT int Jim_SetDictKeysVector (Jim_Interp *interp, + Jim_Obj *varNamePtr, Jim_Obj *const *keyv, int keyc, + Jim_Obj *newObjPtr, int flags); +JIM_EXPORT int Jim_DictPairs(Jim_Interp *interp, + Jim_Obj *dictPtr, Jim_Obj ***objPtrPtr, int *len); +JIM_EXPORT int Jim_DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr); +JIM_EXPORT int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj); +JIM_EXPORT int Jim_DictValues(Jim_Interp *interp, Jim_Obj *dictObjPtr, Jim_Obj *patternObjPtr); +JIM_EXPORT int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr); + + +JIM_EXPORT int Jim_GetReturnCode (Jim_Interp *interp, Jim_Obj *objPtr, + int *intPtr); + + +JIM_EXPORT int Jim_EvalExpression (Jim_Interp *interp, + Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr); +JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp, + Jim_Obj *exprObjPtr, int *boolPtr); + + +JIM_EXPORT int Jim_GetWide (Jim_Interp *interp, Jim_Obj *objPtr, + jim_wide *widePtr); +JIM_EXPORT int Jim_GetLong (Jim_Interp *interp, Jim_Obj *objPtr, + long *longPtr); +#define Jim_NewWideObj Jim_NewIntObj +JIM_EXPORT Jim_Obj * Jim_NewIntObj (Jim_Interp *interp, + jim_wide wideValue); + + +JIM_EXPORT int Jim_GetDouble(Jim_Interp *interp, Jim_Obj *objPtr, + double *doublePtr); +JIM_EXPORT void Jim_SetDouble(Jim_Interp *interp, Jim_Obj *objPtr, + double doubleValue); +JIM_EXPORT Jim_Obj * Jim_NewDoubleObj(Jim_Interp *interp, double doubleValue); + + +JIM_EXPORT const char * Jim_GetSharedString (Jim_Interp *interp, + const char *str); +JIM_EXPORT void Jim_ReleaseSharedString (Jim_Interp *interp, + const char *str); + + +JIM_EXPORT void Jim_WrongNumArgs (Jim_Interp *interp, int argc, + Jim_Obj *const *argv, const char *msg); +JIM_EXPORT int Jim_GetEnum (Jim_Interp *interp, Jim_Obj *objPtr, + const char * const *tablePtr, int *indexPtr, const char *name, int flags); +JIM_EXPORT int Jim_ScriptIsComplete (const char *s, int len, + char *stateCharPtr); +JIM_EXPORT int Jim_FindByName(const char *name, const char * const array[], size_t len); + + +typedef void (Jim_InterpDeleteProc)(Jim_Interp *interp, void *data); +JIM_EXPORT void * Jim_GetAssocData(Jim_Interp *interp, const char *key); +JIM_EXPORT int Jim_SetAssocData(Jim_Interp *interp, const char *key, + Jim_InterpDeleteProc *delProc, void *data); +JIM_EXPORT int Jim_DeleteAssocData(Jim_Interp *interp, const char *key); + + + +JIM_EXPORT int Jim_PackageProvide (Jim_Interp *interp, + const char *name, const char *ver, int flags); +JIM_EXPORT int Jim_PackageRequire (Jim_Interp *interp, + const char *name, int flags); + + +JIM_EXPORT void Jim_MakeErrorMessage (Jim_Interp *interp); + + +JIM_EXPORT int Jim_InteractivePrompt (Jim_Interp *interp); +JIM_EXPORT void Jim_HistoryLoad(const char *filename); +JIM_EXPORT void Jim_HistorySave(const char *filename); +JIM_EXPORT char *Jim_HistoryGetline(const char *prompt); +JIM_EXPORT void Jim_HistoryAdd(const char *line); +JIM_EXPORT void Jim_HistoryShow(void); + + +JIM_EXPORT int Jim_InitStaticExtensions(Jim_Interp *interp); +JIM_EXPORT int Jim_StringToWide(const char *str, jim_wide *widePtr, int base); + + +JIM_EXPORT int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName); +JIM_EXPORT void Jim_FreeLoadHandles(Jim_Interp *interp); + + +JIM_EXPORT FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command); + + + +JIM_EXPORT int Jim_IsDict(Jim_Obj *objPtr); +JIM_EXPORT int Jim_IsList(Jim_Obj *objPtr); + +#ifdef __cplusplus +} +#endif + +#endif + +#ifndef JIM_SUBCMD_H +#define JIM_SUBCMD_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define JIM_MODFLAG_HIDDEN 0x0001 +#define JIM_MODFLAG_FULLARGV 0x0002 + + + +typedef int tclmod_cmd_function(Jim_Interp *interp, int argc, Jim_Obj *const *argv); + +typedef struct { + const char *cmd; + const char *args; + tclmod_cmd_function *function; + short minargs; + short maxargs; + unsigned short flags; +} jim_subcmd_type; + +const jim_subcmd_type * +Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type *command_table, int argc, Jim_Obj *const *argv); + +int Jim_SubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv); + +int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type *ct, int argc, Jim_Obj *const *argv); + +#ifdef __cplusplus +} +#endif + +#endif +#ifndef JIMREGEXP_H +#define JIMREGEXP_H + +#ifndef _JIMAUTOCONF_H +#error Need jimautoconf.h +#endif + +#if defined(HAVE_REGCOMP) && !defined(JIM_REGEXP) + +#include + +#else + +#include + + +typedef struct { + int rm_so; + int rm_eo; +} regmatch_t; + + +typedef struct regexp { + + int re_nsub; + + + int cflags; + int err; + int regstart; + int reganch; + int regmust; + int regmlen; + int *program; + + + const char *regparse; + int p; + int proglen; + + + int eflags; + const char *start; + const char *reginput; + const char *regbol; + + + regmatch_t *pmatch; + int nmatch; +} regexp; + +typedef regexp regex_t; + +#define REG_EXTENDED 0 +#define REG_NEWLINE 1 +#define REG_ICASE 2 + +#define REG_NOTBOL 16 + +enum { + REG_NOERROR, + REG_NOMATCH, + REG_BADPAT, + REG_ERR_NULL_ARGUMENT, + REG_ERR_UNKNOWN, + REG_ERR_TOO_BIG, + REG_ERR_NOMEM, + REG_ERR_TOO_MANY_PAREN, + REG_ERR_UNMATCHED_PAREN, + REG_ERR_UNMATCHED_BRACES, + REG_ERR_BAD_COUNT, + REG_ERR_JUNK_ON_END, + REG_ERR_OPERAND_COULD_BE_EMPTY, + REG_ERR_NESTED_COUNT, + REG_ERR_INTERNAL, + REG_ERR_COUNT_FOLLOWS_NOTHING, + REG_ERR_TRAILING_BACKSLASH, + REG_ERR_CORRUPTED, + REG_ERR_NULL_CHAR, + REG_ERR_NUM +}; + +int regcomp(regex_t *preg, const char *regex, int cflags); +int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); +size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size); +void regfree(regex_t *preg); + +#endif + +#endif +int Jim_bootstrapInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "bootstrap", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + return Jim_EvalSource(interp, "bootstrap.tcl", 1, +"\n" +"\n" +"proc package {args} {}\n" +); +} +int Jim_initjimshInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "initjimsh", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + return Jim_EvalSource(interp, "initjimsh.tcl", 1, +"\n" +"\n" +"\n" +"proc _jimsh_init {} {\n" +" rename _jimsh_init {}\n" +"\n" +"\n" +" lappend p {*}[split [env JIMLIB {}] $::tcl_platform(pathSeparator)]\n" +" lappend p {*}$::auto_path\n" +" lappend p [file dirname [info nameofexecutable]]\n" +" set ::auto_path $p\n" +"\n" +" if {$::tcl_interactive && [env HOME {}] ne \"\"} {\n" +" foreach src {.jimrc jimrc.tcl} {\n" +" if {[file exists [env HOME]/$src]} {\n" +" uplevel #0 source [env HOME]/$src\n" +" break\n" +" }\n" +" }\n" +" }\n" +"}\n" +"\n" +"if {$tcl_platform(platform) eq \"windows\"} {\n" +" set jim_argv0 [string map {\\\\ /} $jim_argv0]\n" +"}\n" +"\n" +"_jimsh_init\n" +); +} +int Jim_globInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "glob", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + return Jim_EvalSource(interp, "glob.tcl", 1, +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"package require readdir\n" +"\n" +"\n" +"proc glob.globdir {dir pattern} {\n" +" set result {}\n" +" set files [readdir $dir]\n" +" lappend files . ..\n" +"\n" +" foreach name $files {\n" +" if {[string match $pattern $name]} {\n" +"\n" +" if {[string index $name 0] eq \".\" && [string index $pattern 0] ne \".\"} {\n" +" continue\n" +" }\n" +" lappend result $name\n" +" }\n" +" }\n" +"\n" +" return $result\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"proc glob.explode {pattern} {\n" +" set oldexp {}\n" +" set newexp {\"\"}\n" +"\n" +" while 1 {\n" +" set oldexp $newexp\n" +" set newexp {}\n" +" set ob [string first \\{ $pattern]\n" +" set cb [string first \\} $pattern]\n" +"\n" +" if {$ob < $cb && $ob != -1} {\n" +" set mid [string range $pattern 0 $ob-1]\n" +" set subexp [lassign [glob.explode [string range $pattern $ob+1 end]] pattern]\n" +" if {$pattern eq \"\"} {\n" +" error \"unmatched open brace in glob pattern\"\n" +" }\n" +" set pattern [string range $pattern 1 end]\n" +"\n" +" foreach subs $subexp {\n" +" foreach sub [split $subs ,] {\n" +" foreach old $oldexp {\n" +" lappend newexp $old$mid$sub\n" +" }\n" +" }\n" +" }\n" +" } elseif {$cb != -1} {\n" +" set suf [string range $pattern 0 $cb-1]\n" +" set rest [string range $pattern $cb end]\n" +" break\n" +" } else {\n" +" set suf $pattern\n" +" set rest \"\"\n" +" break\n" +" }\n" +" }\n" +"\n" +" foreach old $oldexp {\n" +" lappend newexp $old$suf\n" +" }\n" +" linsert $newexp 0 $rest\n" +"}\n" +"\n" +"\n" +"\n" +"proc glob.glob {base pattern} {\n" +" set dir [file dirname $pattern]\n" +" if {$pattern eq $dir || $pattern eq \"\"} {\n" +" return [list [file join $base $dir] $pattern]\n" +" } elseif {$pattern eq [file tail $pattern]} {\n" +" set dir \"\"\n" +" }\n" +"\n" +"\n" +" set dirlist [glob.glob $base $dir]\n" +" set pattern [file tail $pattern]\n" +"\n" +"\n" +" set result {}\n" +" foreach {realdir dir} $dirlist {\n" +" if {![file isdir $realdir]} {\n" +" continue\n" +" }\n" +" if {[string index $dir end] ne \"/\" && $dir ne \"\"} {\n" +" append dir /\n" +" }\n" +" foreach name [glob.globdir $realdir $pattern] {\n" +" lappend result [file join $realdir $name] $dir$name\n" +" }\n" +" }\n" +" return $result\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"proc glob {args} {\n" +" set nocomplain 0\n" +" set base \"\"\n" +"\n" +" set n 0\n" +" foreach arg $args {\n" +" if {[info exists param]} {\n" +" set $param $arg\n" +" unset param\n" +" incr n\n" +" continue\n" +" }\n" +" switch -glob -- $arg {\n" +" -d* {\n" +" set switch $arg\n" +" set param base\n" +" }\n" +" -n* {\n" +" set nocomplain 1\n" +" }\n" +" -t* {\n" +"\n" +" }\n" +"\n" +" -* {\n" +" return -code error \"bad option \\\"$switch\\\": must be -directory, -nocomplain, -tails, or --\"\n" +" }\n" +" -- {\n" +" incr n\n" +" break\n" +" }\n" +" * {\n" +" break\n" +" }\n" +" }\n" +" incr n\n" +" }\n" +" if {[info exists param]} {\n" +" return -code error \"missing argument to \\\"$switch\\\"\"\n" +" }\n" +" if {[llength $args] <= $n} {\n" +" return -code error \"wrong # args: should be \\\"glob ?options? pattern ?pattern ...?\\\"\"\n" +" }\n" +"\n" +" set args [lrange $args $n end]\n" +"\n" +" set result {}\n" +" foreach pattern $args {\n" +" set pattern [string map {\n" +" \\\\\\\\ \\x01 \\\\\\{ \\x02 \\\\\\} \\x03 \\\\, \\x04\n" +" } $pattern]\n" +" set patexps [lassign [glob.explode $pattern] rest]\n" +" if {$rest ne \"\"} {\n" +" return -code error \"unmatched close brace in glob pattern\"\n" +" }\n" +" foreach patexp $patexps {\n" +" set patexp [string map {\n" +" \\x01 \\\\\\\\ \\x02 \\{ \\x03 \\} \\x04 ,\n" +" } $patexp]\n" +" foreach {realname name} [glob.glob $base $patexp] {\n" +" lappend result $name\n" +" }\n" +" }\n" +" }\n" +"\n" +" if {!$nocomplain && [llength $result] == 0} {\n" +" return -code error \"no files matched glob patterns\"\n" +" }\n" +"\n" +" return $result\n" +"}\n" +); +} +int Jim_stdlibInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "stdlib", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + return Jim_EvalSource(interp, "stdlib.tcl", 1, +"\n" +"proc lambda {arglist args} {\n" +" tailcall proc [ref {} function lambda.finalizer] $arglist {*}$args\n" +"}\n" +"\n" +"proc lambda.finalizer {name val} {\n" +" rename $name {}\n" +"}\n" +"\n" +"\n" +"proc curry {args} {\n" +" alias [ref {} function lambda.finalizer] {*}$args\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"proc function {value} {\n" +" return $value\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"proc stacktrace {} {\n" +" set trace {}\n" +" foreach level [range 1 [info level]] {\n" +" lassign [info frame -$level] p f l\n" +" lappend trace $p $f $l\n" +" }\n" +" return $trace\n" +"}\n" +"\n" +"\n" +"proc stackdump {stacktrace} {\n" +" set result {}\n" +" set count 0\n" +" foreach {l f p} [lreverse $stacktrace] {\n" +" if {$count} {\n" +" append result \\n\n" +" }\n" +" incr count\n" +" if {$p ne \"\"} {\n" +" append result \"in procedure '$p' \"\n" +" if {$f ne \"\"} {\n" +" append result \"called \"\n" +" }\n" +" }\n" +" if {$f ne \"\"} {\n" +" append result \"at file \\\"$f\\\", line $l\"\n" +" }\n" +" }\n" +" return $result\n" +"}\n" +"\n" +"\n" +"\n" +"proc errorInfo {msg {stacktrace \"\"}} {\n" +" if {$stacktrace eq \"\"} {\n" +" set stacktrace [info stacktrace]\n" +" }\n" +" lassign $stacktrace p f l\n" +" if {$f ne \"\"} {\n" +" set result \"Runtime Error: $f:$l: \"\n" +" }\n" +" append result \"$msg\\n\"\n" +" append result [stackdump $stacktrace]\n" +"\n" +"\n" +" string trim $result\n" +"}\n" +"\n" +"\n" +"\n" +"proc {info nameofexecutable} {} {\n" +" if {[info exists ::jim_argv0]} {\n" +" if {[string match \"*/*\" $::jim_argv0]} {\n" +" return [file join [pwd] $::jim_argv0]\n" +" }\n" +" foreach path [split [env PATH \"\"] $::tcl_platform(pathSeparator)] {\n" +" set exec [file join [pwd] [string map {\\\\ /} $path] $::jim_argv0]\n" +" if {[file executable $exec]} {\n" +" return $exec\n" +" }\n" +" }\n" +" }\n" +" return \"\"\n" +"}\n" +"\n" +"\n" +"proc {dict with} {dictVar args script} {\n" +" upvar $dictVar dict\n" +" set keys {}\n" +" foreach {n v} [dict get $dict {*}$args] {\n" +" upvar $n var_$n\n" +" set var_$n $v\n" +" lappend keys $n\n" +" }\n" +" catch {uplevel 1 $script} msg opts\n" +" if {[info exists dict] && [dict exists $dict {*}$args]} {\n" +" foreach n $keys {\n" +" if {[info exists var_$n]} {\n" +" dict set dict {*}$args $n [set var_$n]\n" +" } else {\n" +" dict unset dict {*}$args $n\n" +" }\n" +" }\n" +" }\n" +" return {*}$opts $msg\n" +"}\n" +"\n" +"\n" +"\n" +"proc {dict merge} {dict args} {\n" +" foreach d $args {\n" +"\n" +" dict size $d\n" +" foreach {k v} $d {\n" +" dict set dict $k $v\n" +" }\n" +" }\n" +" return $dict\n" +"}\n" +); +} +int Jim_tclcompatInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "tclcompat", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + return Jim_EvalSource(interp, "tclcompat.tcl", 1, +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"set env [env]\n" +"\n" +"if {[info commands stdout] ne \"\"} {\n" +"\n" +" foreach p {gets flush close eof seek tell} {\n" +" proc $p {chan args} {p} {\n" +" tailcall $chan $p {*}$args\n" +" }\n" +" }\n" +" unset p\n" +"\n" +"\n" +"\n" +" proc puts {{-nonewline {}} {chan stdout} msg} {\n" +" if {${-nonewline} ni {-nonewline {}}} {\n" +" tailcall ${-nonewline} puts $msg\n" +" }\n" +" tailcall $chan puts {*}${-nonewline} $msg\n" +" }\n" +"\n" +"\n" +"\n" +"\n" +"\n" +" proc read {{-nonewline {}} chan} {\n" +" if {${-nonewline} ni {-nonewline {}}} {\n" +" tailcall ${-nonewline} read {*}${chan}\n" +" }\n" +" tailcall $chan read {*}${-nonewline}\n" +" }\n" +"\n" +" proc fconfigure {f args} {\n" +" foreach {n v} $args {\n" +" switch -glob -- $n {\n" +" -bl* {\n" +" $f ndelay $(!$v)\n" +" }\n" +" -bu* {\n" +" $f buffering $v\n" +" }\n" +" -tr* {\n" +"\n" +" }\n" +" default {\n" +" return -code error \"fconfigure: unknown option $n\"\n" +" }\n" +" }\n" +" }\n" +" }\n" +"}\n" +"\n" +"\n" +"proc case {var args} {\n" +"\n" +" if {[lindex $args 0] eq \"in\"} {\n" +" set args [lrange $args 1 end]\n" +" }\n" +"\n" +"\n" +" if {[llength $args] == 1} {\n" +" set args [lindex $args 0]\n" +" }\n" +"\n" +"\n" +" if {[llength $args] % 2 != 0} {\n" +" return -code error \"extra case pattern with no body\"\n" +" }\n" +"\n" +"\n" +" local proc case.checker {value pattern} {\n" +" string match $pattern $value\n" +" }\n" +"\n" +" foreach {value action} $args {\n" +" if {$value eq \"default\"} {\n" +" set do_action $action\n" +" continue\n" +" } elseif {[lsearch -bool -command case.checker $value $var]} {\n" +" set do_action $action\n" +" break\n" +" }\n" +" }\n" +"\n" +" if {[info exists do_action]} {\n" +" set rc [catch [list uplevel 1 $do_action] result opts]\n" +" if {$rc} {\n" +" incr opts(-level)\n" +" }\n" +" return {*}$opts $result\n" +" }\n" +"}\n" +"\n" +"\n" +"proc fileevent {args} {\n" +" tailcall {*}$args\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"proc parray {arrayname {pattern *} {puts puts}} {\n" +" upvar $arrayname a\n" +"\n" +" set max 0\n" +" foreach name [array names a $pattern]] {\n" +" if {[string length $name] > $max} {\n" +" set max [string length $name]\n" +" }\n" +" }\n" +" incr max [string length $arrayname]\n" +" incr max 2\n" +" foreach name [lsort [array names a $pattern]] {\n" +" $puts [format \"%-${max}s = %s\" $arrayname\\($name\\) $a($name)]\n" +" }\n" +"}\n" +"\n" +"\n" +"proc {file copy} {{force {}} source target} {\n" +" try {\n" +" if {$force ni {{} -force}} {\n" +" error \"bad option \\\"$force\\\": should be -force\"\n" +" }\n" +"\n" +" set in [open $source]\n" +"\n" +" if {$force eq \"\" && [file exists $target]} {\n" +" $in close\n" +" error \"error copying \\\"$source\\\" to \\\"$target\\\": file already exists\"\n" +" }\n" +" set out [open $target w]\n" +" $in copyto $out\n" +" $out close\n" +" } on error {msg opts} {\n" +" incr opts(-level)\n" +" return {*}$opts $msg\n" +" } finally {\n" +" catch {$in close}\n" +" }\n" +"}\n" +"\n" +"\n" +"\n" +"proc popen {cmd {mode r}} {\n" +" lassign [socket pipe] r w\n" +" try {\n" +" if {[string match \"w*\" $mode]} {\n" +" lappend cmd <@$r &\n" +" set pids [exec {*}$cmd]\n" +" $r close\n" +" set f $w\n" +" } else {\n" +" lappend cmd >@$w &\n" +" set pids [exec {*}$cmd]\n" +" $w close\n" +" set f $r\n" +" }\n" +" lambda {cmd args} {f pids} {\n" +" if {$cmd eq \"pid\"} {\n" +" return $pids\n" +" }\n" +" if {$cmd eq \"close\"} {\n" +" $f close\n" +"\n" +" foreach p $pids { os.wait $p }\n" +" return\n" +" }\n" +" tailcall $f $cmd {*}$args\n" +" }\n" +" } on error {error opts} {\n" +" $r close\n" +" $w close\n" +" error $error\n" +" }\n" +"}\n" +"\n" +"\n" +"local proc pid {{chan {}}} {\n" +" if {$chan eq \"\"} {\n" +" tailcall upcall pid\n" +" }\n" +" if {[catch {$chan tell}]} {\n" +" return -code error \"can not find channel named \\\"$chan\\\"\"\n" +" }\n" +" if {[catch {$chan pid} pids]} {\n" +" return \"\"\n" +" }\n" +" return $pids\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"proc try {args} {\n" +" set catchopts {}\n" +" while {[string match -* [lindex $args 0]]} {\n" +" set args [lassign $args opt]\n" +" if {$opt eq \"--\"} {\n" +" break\n" +" }\n" +" lappend catchopts $opt\n" +" }\n" +" if {[llength $args] == 0} {\n" +" return -code error {wrong # args: should be \"try ?options? script ?argument ...?\"}\n" +" }\n" +" set args [lassign $args script]\n" +" set code [catch -eval {*}$catchopts [list uplevel 1 $script] msg opts]\n" +"\n" +" set handled 0\n" +"\n" +" foreach {on codes vars script} $args {\n" +" switch -- $on \\\n" +" on {\n" +" if {!$handled && ($codes eq \"*\" || [info returncode $code] in $codes)} {\n" +" lassign $vars msgvar optsvar\n" +" if {$msgvar ne \"\"} {\n" +" upvar $msgvar hmsg\n" +" set hmsg $msg\n" +" }\n" +" if {$optsvar ne \"\"} {\n" +" upvar $optsvar hopts\n" +" set hopts $opts\n" +" }\n" +"\n" +" set code [catch [list uplevel 1 $script] msg opts]\n" +" incr handled\n" +" }\n" +" } \\\n" +" finally {\n" +" set finalcode [catch [list uplevel 1 $codes] finalmsg finalopts]\n" +" if {$finalcode} {\n" +"\n" +" set code $finalcode\n" +" set msg $finalmsg\n" +" set opts $finalopts\n" +" }\n" +" break\n" +" } \\\n" +" default {\n" +" return -code error \"try: expected 'on' or 'finally', got '$on'\"\n" +" }\n" +" }\n" +"\n" +" if {$code} {\n" +" incr opts(-level)\n" +" return {*}$opts $msg\n" +" }\n" +" return $msg\n" +"}\n" +"\n" +"\n" +"\n" +"proc throw {code {msg \"\"}} {\n" +" return -code $code $msg\n" +"}\n" +"\n" +"\n" +"proc {file delete force} {path} {\n" +" foreach e [readdir $path] {\n" +" file delete -force $path/$e\n" +" }\n" +" file delete $path\n" +"}\n" +); +} + + + +#include +#include +#include +#include + + +#if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_SELECT) && defined(HAVE_NETINET_IN_H) && defined(HAVE_NETDB_H) && defined(HAVE_ARPA_INET_H) +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_UN_H +#include +#endif +#else +#define JIM_ANSIC +#endif + + +#define AIO_CMD_LEN 32 +#define AIO_BUF_LEN 256 + +#ifndef HAVE_FTELLO + #define ftello ftell +#endif +#ifndef HAVE_FSEEKO + #define fseeko fseek +#endif + +#define AIO_KEEPOPEN 1 + +#if defined(JIM_IPV6) +#define IPV6 1 +#else +#define IPV6 0 +#ifndef PF_INET6 +#define PF_INET6 0 +#endif +#endif + + +typedef struct AioFile +{ + FILE *fp; + Jim_Obj *filename; + int type; + int OpenFlags; + int fd; +#ifdef O_NDELAY + int flags; +#endif + Jim_Obj *rEvent; + Jim_Obj *wEvent; + Jim_Obj *eEvent; + int addr_family; +} AioFile; + +static int JimAioSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv); +static int JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename, + const char *hdlfmt, int family, const char *mode); + + +static void JimAioSetError(Jim_Interp *interp, Jim_Obj *name) +{ + if (name) { + Jim_SetResultFormatted(interp, "%#s: %s", name, strerror(errno)); + } + else { + Jim_SetResultString(interp, strerror(errno), -1); + } +} + +static void JimAioDelProc(Jim_Interp *interp, void *privData) +{ + AioFile *af = privData; + + JIM_NOTUSED(interp); + + if (!(af->OpenFlags & AIO_KEEPOPEN)) { + fclose(af->fp); + } + + Jim_DecrRefCount(interp, af->filename); + +#ifdef jim_ext_eventloop + + if (af->rEvent) { + Jim_DeleteFileHandler(interp, af->fp); + } + if (af->wEvent) { + Jim_DeleteFileHandler(interp, af->fp); + } + if (af->eEvent) { + Jim_DeleteFileHandler(interp, af->fp); + } +#endif + Jim_Free(af); +} + +static int JimCheckStreamError(Jim_Interp *interp, AioFile *af) +{ + if (!ferror(af->fp)) { + return JIM_OK; + } + clearerr(af->fp); + + if (feof(af->fp) || errno == EAGAIN || errno == EINTR) { + return JIM_OK; + } +#ifdef ECONNRESET + if (errno == ECONNRESET) { + return JIM_OK; + } +#endif +#ifdef ECONNABORTED + if (errno != ECONNABORTED) { + return JIM_OK; + } +#endif + JimAioSetError(interp, af->filename); + return JIM_ERR; +} + +static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + char buf[AIO_BUF_LEN]; + Jim_Obj *objPtr; + int nonewline = 0; + jim_wide neededLen = -1; + + if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) { + nonewline = 1; + argv++; + argc--; + } + if (argc == 1) { + if (Jim_GetWide(interp, argv[0], &neededLen) != JIM_OK) + return JIM_ERR; + if (neededLen < 0) { + Jim_SetResultString(interp, "invalid parameter: negative len", -1); + return JIM_ERR; + } + } + else if (argc) { + return -1; + } + objPtr = Jim_NewStringObj(interp, NULL, 0); + while (neededLen != 0) { + int retval; + int readlen; + + if (neededLen == -1) { + readlen = AIO_BUF_LEN; + } + else { + readlen = (neededLen > AIO_BUF_LEN ? AIO_BUF_LEN : neededLen); + } + retval = fread(buf, 1, readlen, af->fp); + if (retval > 0) { + Jim_AppendString(interp, objPtr, buf, retval); + if (neededLen != -1) { + neededLen -= retval; + } + } + if (retval != readlen) + break; + } + + if (JimCheckStreamError(interp, af)) { + Jim_FreeNewObj(interp, objPtr); + return JIM_ERR; + } + if (nonewline) { + int len; + const char *s = Jim_GetString(objPtr, &len); + + if (len > 0 && s[len - 1] == '\n') { + objPtr->length--; + objPtr->bytes[objPtr->length] = '\0'; + } + } + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + +static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + jim_wide count = 0; + jim_wide maxlen = JIM_WIDE_MAX; + FILE *outfh = Jim_AioFilehandle(interp, argv[0]); + + if (outfh == NULL) { + return JIM_ERR; + } + + if (argc == 2) { + if (Jim_GetWide(interp, argv[1], &maxlen) != JIM_OK) { + return JIM_ERR; + } + } + + while (count < maxlen) { + int ch = fgetc(af->fp); + + if (ch == EOF || fputc(ch, outfh) == EOF) { + break; + } + count++; + } + + if (ferror(af->fp)) { + Jim_SetResultFormatted(interp, "error while reading: %s", strerror(errno)); + clearerr(af->fp); + return JIM_ERR; + } + + if (ferror(outfh)) { + Jim_SetResultFormatted(interp, "error while writing: %s", strerror(errno)); + clearerr(outfh); + return JIM_ERR; + } + + Jim_SetResultInt(interp, count); + + return JIM_OK; +} + +static int aio_cmd_gets(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + char buf[AIO_BUF_LEN]; + Jim_Obj *objPtr; + int len; + + errno = 0; + + objPtr = Jim_NewStringObj(interp, NULL, 0); + while (1) { + buf[AIO_BUF_LEN - 1] = '_'; + if (fgets(buf, AIO_BUF_LEN, af->fp) == NULL) + break; + + if (buf[AIO_BUF_LEN - 1] == '\0' && buf[AIO_BUF_LEN - 2] != '\n') { + Jim_AppendString(interp, objPtr, buf, AIO_BUF_LEN - 1); + } + else { + len = strlen(buf); + + if (len && (buf[len - 1] == '\n')) { + + len--; + } + + Jim_AppendString(interp, objPtr, buf, len); + break; + } + } + if (JimCheckStreamError(interp, af)) { + + Jim_FreeNewObj(interp, objPtr); + return JIM_ERR; + } + + if (argc) { + if (Jim_SetVariable(interp, argv[0], objPtr) != JIM_OK) { + Jim_FreeNewObj(interp, objPtr); + return JIM_ERR; + } + + len = Jim_Length(objPtr); + + if (len == 0 && feof(af->fp)) { + + len = -1; + } + Jim_SetResultInt(interp, len); + } + else { + Jim_SetResult(interp, objPtr); + } + return JIM_OK; +} + +static int aio_cmd_puts(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + int wlen; + const char *wdata; + Jim_Obj *strObj; + + if (argc == 2) { + if (!Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) { + return -1; + } + strObj = argv[1]; + } + else { + strObj = argv[0]; + } + + wdata = Jim_GetString(strObj, &wlen); + if (fwrite(wdata, 1, wlen, af->fp) == (unsigned)wlen) { + if (argc == 2 || putc('\n', af->fp) != EOF) { + return JIM_OK; + } + } + JimAioSetError(interp, af->filename); + return JIM_ERR; +} + +static int aio_cmd_isatty(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ +#ifdef HAVE_ISATTY + AioFile *af = Jim_CmdPrivData(interp); + Jim_SetResultInt(interp, isatty(fileno(af->fp))); +#else + Jim_SetResultInt(interp, 0); +#endif + + return JIM_OK; +} + + +static int aio_cmd_flush(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + if (fflush(af->fp) == EOF) { + JimAioSetError(interp, af->filename); + return JIM_ERR; + } + return JIM_OK; +} + +static int aio_cmd_eof(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + Jim_SetResultInt(interp, feof(af->fp)); + return JIM_OK; +} + +static int aio_cmd_close(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_DeleteCommand(interp, Jim_String(argv[0])); + return JIM_OK; +} + +static int aio_cmd_seek(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + int orig = SEEK_SET; + jim_wide offset; + + if (argc == 2) { + if (Jim_CompareStringImmediate(interp, argv[1], "start")) + orig = SEEK_SET; + else if (Jim_CompareStringImmediate(interp, argv[1], "current")) + orig = SEEK_CUR; + else if (Jim_CompareStringImmediate(interp, argv[1], "end")) + orig = SEEK_END; + else { + return -1; + } + } + if (Jim_GetWide(interp, argv[0], &offset) != JIM_OK) { + return JIM_ERR; + } + if (fseeko(af->fp, offset, orig) == -1) { + JimAioSetError(interp, af->filename); + return JIM_ERR; + } + return JIM_OK; +} + +static int aio_cmd_tell(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + Jim_SetResultInt(interp, ftello(af->fp)); + return JIM_OK; +} + +static int aio_cmd_filename(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + Jim_SetResult(interp, af->filename); + return JIM_OK; +} + +#ifdef O_NDELAY +static int aio_cmd_ndelay(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + int fmode = af->flags; + + if (argc) { + long nb; + + if (Jim_GetLong(interp, argv[0], &nb) != JIM_OK) { + return JIM_ERR; + } + if (nb) { + fmode |= O_NDELAY; + } + else { + fmode &= ~O_NDELAY; + } + fcntl(af->fd, F_SETFL, fmode); + af->flags = fmode; + } + Jim_SetResultInt(interp, (fmode & O_NONBLOCK) ? 1 : 0); + return JIM_OK; +} +#endif + +static int aio_cmd_buffering(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + static const char * const options[] = { + "none", + "line", + "full", + NULL + }; + enum + { + OPT_NONE, + OPT_LINE, + OPT_FULL, + }; + int option; + + if (Jim_GetEnum(interp, argv[0], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + switch (option) { + case OPT_NONE: + setvbuf(af->fp, NULL, _IONBF, 0); + break; + case OPT_LINE: + setvbuf(af->fp, NULL, _IOLBF, BUFSIZ); + break; + case OPT_FULL: + setvbuf(af->fp, NULL, _IOFBF, BUFSIZ); + break; + } + return JIM_OK; +} + +#ifdef jim_ext_eventloop +static void JimAioFileEventFinalizer(Jim_Interp *interp, void *clientData) +{ + Jim_Obj *objPtr = clientData; + + Jim_DecrRefCount(interp, objPtr); +} + +static int JimAioFileEventHandler(Jim_Interp *interp, void *clientData, int mask) +{ + Jim_Obj *objPtr = clientData; + + return Jim_EvalObjBackground(interp, objPtr); +} + +static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, Jim_Obj **scriptHandlerObj, + int argc, Jim_Obj * const *argv) +{ + int scriptlen = 0; + + if (argc == 0) { + + if (*scriptHandlerObj) { + Jim_SetResult(interp, *scriptHandlerObj); + } + return JIM_OK; + } + + if (*scriptHandlerObj) { + + Jim_DeleteFileHandler(interp, af->fp); + *scriptHandlerObj = NULL; + } + + + Jim_GetString(argv[0], &scriptlen); + if (scriptlen == 0) { + + return JIM_OK; + } + + + Jim_IncrRefCount(argv[0]); + *scriptHandlerObj = argv[0]; + + Jim_CreateFileHandler(interp, af->fp, mask, + JimAioFileEventHandler, *scriptHandlerObj, JimAioFileEventFinalizer); + + return JIM_OK; +} + +static int aio_cmd_readable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + return aio_eventinfo(interp, af, JIM_EVENT_READABLE, &af->rEvent, argc, argv); +} + +static int aio_cmd_writable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + return aio_eventinfo(interp, af, JIM_EVENT_WRITABLE, &af->wEvent, argc, argv); +} + +static int aio_cmd_onexception(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + return aio_eventinfo(interp, af, JIM_EVENT_EXCEPTION, &af->wEvent, argc, argv); +} +#endif + +static const jim_subcmd_type aio_command_table[] = { + { "read", + "?-nonewline? ?len?", + aio_cmd_read, + 0, + 2, + + }, + { "copyto", + "handle ?size?", + aio_cmd_copy, + 1, + 2, + + }, + { "gets", + "?var?", + aio_cmd_gets, + 0, + 1, + + }, + { "puts", + "?-nonewline? str", + aio_cmd_puts, + 1, + 2, + + }, + { "isatty", + NULL, + aio_cmd_isatty, + 0, + 0, + + }, + { "flush", + NULL, + aio_cmd_flush, + 0, + 0, + + }, + { "eof", + NULL, + aio_cmd_eof, + 0, + 0, + + }, + { "close", + NULL, + aio_cmd_close, + 0, + 0, + JIM_MODFLAG_FULLARGV, + + }, + { "seek", + "offset ?start|current|end", + aio_cmd_seek, + 1, + 2, + + }, + { "tell", + NULL, + aio_cmd_tell, + 0, + 0, + + }, + { "filename", + NULL, + aio_cmd_filename, + 0, + 0, + + }, +#ifdef O_NDELAY + { "ndelay", + "?0|1?", + aio_cmd_ndelay, + 0, + 1, + + }, +#endif + { "buffering", + "none|line|full", + aio_cmd_buffering, + 1, + 1, + + }, +#ifdef jim_ext_eventloop + { "readable", + "?readable-script?", + aio_cmd_readable, + 0, + 1, + + }, + { "writable", + "?writable-script?", + aio_cmd_writable, + 0, + 1, + + }, + { "onexception", + "?exception-script?", + aio_cmd_onexception, + 0, + 1, + + }, +#endif + { NULL } +}; + +static int JimAioSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, aio_command_table, argc, argv), argc, argv); +} + +static int JimAioOpenCommand(Jim_Interp *interp, int argc, + Jim_Obj *const *argv) +{ + const char *mode; + const char *filename; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "filename ?mode?"); + return JIM_ERR; + } + + mode = (argc == 3) ? Jim_String(argv[2]) : "r"; + filename = Jim_String(argv[1]); + +#ifdef jim_ext_tclcompat + + if (*filename == '|') { + Jim_Obj *evalObj[3]; + + evalObj[0] = Jim_NewStringObj(interp, "popen", -1); + evalObj[1] = Jim_NewStringObj(interp, filename + 1, -1); + evalObj[2] = Jim_NewStringObj(interp, mode, -1); + + return Jim_EvalObjVector(interp, 3, evalObj); + } +#endif + return JimMakeChannel(interp, NULL, -1, argv[1], "aio.handle%ld", 0, mode); +} + +static int JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename, + const char *hdlfmt, int family, const char *mode) +{ + AioFile *af; + char buf[AIO_CMD_LEN]; + int OpenFlags = 0; + + if (filename == NULL) { + filename = Jim_NewStringObj(interp, hdlfmt, -1); + } + + Jim_IncrRefCount(filename); + + if (fh == NULL) { + if (fd < 0) { + fh = fopen(Jim_String(filename), mode); + } + else { + fh = fdopen(fd, mode); + } + } + else { + OpenFlags = AIO_KEEPOPEN; + } + + if (fh == NULL) { + JimAioSetError(interp, filename); +#if !defined(JIM_ANSIC) + if (fd >= 0) { + close(fd); + } +#endif + Jim_DecrRefCount(interp, filename); + return JIM_ERR; + } + + + af = Jim_Alloc(sizeof(*af)); + memset(af, 0, sizeof(*af)); + af->fp = fh; + af->fd = fileno(fh); + af->filename = filename; +#ifdef FD_CLOEXEC + if ((OpenFlags & AIO_KEEPOPEN) == 0) { + fcntl(af->fd, F_SETFD, FD_CLOEXEC); + } +#endif + af->OpenFlags = OpenFlags; +#ifdef O_NDELAY + af->flags = fcntl(af->fd, F_GETFL); +#endif + af->addr_family = family; + snprintf(buf, sizeof(buf), hdlfmt, Jim_GetId(interp)); + Jim_CreateCommand(interp, buf, JimAioSubCmdProc, af, JimAioDelProc); + + Jim_SetResultString(interp, buf, -1); + + return JIM_OK; +} + + +FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command) +{ + Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG); + + if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) { + return ((AioFile *) cmdPtr->u.native.privData)->fp; + } + Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", command); + return NULL; +} + +int Jim_aioInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "aio", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL); +#ifndef JIM_ANSIC + Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL); +#endif + + + JimMakeChannel(interp, stdin, -1, NULL, "stdin", 0, "r"); + JimMakeChannel(interp, stdout, -1, NULL, "stdout", 0, "w"); + JimMakeChannel(interp, stderr, -1, NULL, "stderr", 0, "w"); + + return JIM_OK; +} + + +#include +#include +#include + + +#ifdef HAVE_DIRENT_H +#include +#endif + +int Jim_ReaddirCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *dirPath; + DIR *dirPtr; + struct dirent *entryPtr; + int nocomplain = 0; + + if (argc == 3 && Jim_CompareStringImmediate(interp, argv[1], "-nocomplain")) { + nocomplain = 1; + } + if (argc != 2 && !nocomplain) { + Jim_WrongNumArgs(interp, 1, argv, "?-nocomplain? dirPath"); + return JIM_ERR; + } + + dirPath = Jim_String(argv[1 + nocomplain]); + + dirPtr = opendir(dirPath); + if (dirPtr == NULL) { + if (nocomplain) { + return JIM_OK; + } + Jim_SetResultString(interp, strerror(errno), -1); + return JIM_ERR; + } + Jim_SetResultString(interp, strerror(errno), -1); + + Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); + + while ((entryPtr = readdir(dirPtr)) != NULL) { + if (entryPtr->d_name[0] == '.') { + if (entryPtr->d_name[1] == '\0') { + continue; + } + if ((entryPtr->d_name[1] == '.') && (entryPtr->d_name[2] == '\0')) + continue; + } + Jim_ListAppendElement(interp, Jim_GetResult(interp), Jim_NewStringObj(interp, + entryPtr->d_name, -1)); + } + closedir(dirPtr); + + return JIM_OK; +} + +int Jim_readdirInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "readdir", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "readdir", Jim_ReaddirCmd, NULL, NULL); + return JIM_OK; +} + +#include +#include + + +static void FreeRegexpInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + regfree(objPtr->internalRep.regexpValue.compre); + Jim_Free(objPtr->internalRep.regexpValue.compre); +} + +static const Jim_ObjType regexpObjType = { + "regexp", + FreeRegexpInternalRep, + NULL, + NULL, + JIM_TYPE_NONE +}; + +static regex_t *SetRegexpFromAny(Jim_Interp *interp, Jim_Obj *objPtr, unsigned flags) +{ + regex_t *compre; + const char *pattern; + int ret; + + + if (objPtr->typePtr == ®expObjType && + objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) { + + return objPtr->internalRep.regexpValue.compre; + } + + + + + pattern = Jim_String(objPtr); + compre = Jim_Alloc(sizeof(regex_t)); + + if ((ret = regcomp(compre, pattern, REG_EXTENDED | flags)) != 0) { + char buf[100]; + + regerror(ret, compre, buf, sizeof(buf)); + Jim_SetResultFormatted(interp, "couldn't compile regular expression pattern: %s", buf); + regfree(compre); + Jim_Free(compre); + return NULL; + } + + Jim_FreeIntRep(interp, objPtr); + + objPtr->typePtr = ®expObjType; + objPtr->internalRep.regexpValue.flags = flags; + objPtr->internalRep.regexpValue.compre = compre; + + return compre; +} + +int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int opt_indices = 0; + int opt_all = 0; + int opt_inline = 0; + regex_t *regex; + int match, i, j; + int offset = 0; + regmatch_t *pmatch = NULL; + int source_len; + int result = JIM_OK; + const char *pattern; + const char *source_str; + int num_matches = 0; + int num_vars; + Jim_Obj *resultListObj = NULL; + int regcomp_flags = 0; + int eflags = 0; + int option; + enum { + OPT_INDICES, OPT_NOCASE, OPT_LINE, OPT_ALL, OPT_INLINE, OPT_START, OPT_END + }; + static const char * const options[] = { + "-indices", "-nocase", "-line", "-all", "-inline", "-start", "--", NULL + }; + + if (argc < 3) { + wrongNumArgs: + Jim_WrongNumArgs(interp, 1, argv, + "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?"); + return JIM_ERR; + } + + for (i = 1; i < argc; i++) { + const char *opt = Jim_String(argv[i]); + + if (*opt != '-') { + break; + } + if (Jim_GetEnum(interp, argv[i], options, &option, "switch", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + if (option == OPT_END) { + i++; + break; + } + switch (option) { + case OPT_INDICES: + opt_indices = 1; + break; + + case OPT_NOCASE: + regcomp_flags |= REG_ICASE; + break; + + case OPT_LINE: + regcomp_flags |= REG_NEWLINE; + break; + + case OPT_ALL: + opt_all = 1; + break; + + case OPT_INLINE: + opt_inline = 1; + break; + + case OPT_START: + if (++i == argc) { + goto wrongNumArgs; + } + if (Jim_GetIndex(interp, argv[i], &offset) != JIM_OK) { + return JIM_ERR; + } + break; + } + } + if (argc - i < 2) { + goto wrongNumArgs; + } + + regex = SetRegexpFromAny(interp, argv[i], regcomp_flags); + if (!regex) { + return JIM_ERR; + } + + pattern = Jim_String(argv[i]); + source_str = Jim_GetString(argv[i + 1], &source_len); + + num_vars = argc - i - 2; + + if (opt_inline) { + if (num_vars) { + Jim_SetResultString(interp, "regexp match variables not allowed when using -inline", + -1); + result = JIM_ERR; + goto done; + } + num_vars = regex->re_nsub + 1; + } + + pmatch = Jim_Alloc((num_vars + 1) * sizeof(*pmatch)); + + if (offset) { + if (offset < 0) { + offset += source_len + 1; + } + if (offset > source_len) { + source_str += source_len; + } + else if (offset > 0) { + source_str += offset; + } + eflags |= REG_NOTBOL; + } + + if (opt_inline) { + resultListObj = Jim_NewListObj(interp, NULL, 0); + } + + next_match: + match = regexec(regex, source_str, num_vars + 1, pmatch, eflags); + if (match >= REG_BADPAT) { + char buf[100]; + + regerror(match, regex, buf, sizeof(buf)); + Jim_SetResultFormatted(interp, "error while matching pattern: %s", buf); + result = JIM_ERR; + goto done; + } + + if (match == REG_NOMATCH) { + goto done; + } + + num_matches++; + + if (opt_all && !opt_inline) { + + goto try_next_match; + } + + + j = 0; + for (i += 2; opt_inline ? j < num_vars : i < argc; i++, j++) { + Jim_Obj *resultObj; + + if (opt_indices) { + resultObj = Jim_NewListObj(interp, NULL, 0); + } + else { + resultObj = Jim_NewStringObj(interp, "", 0); + } + + if (pmatch[j].rm_so == -1) { + if (opt_indices) { + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, -1)); + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, -1)); + } + } + else { + int len = pmatch[j].rm_eo - pmatch[j].rm_so; + + if (opt_indices) { + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, + offset + pmatch[j].rm_so)); + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, + offset + pmatch[j].rm_so + len - 1)); + } + else { + Jim_AppendString(interp, resultObj, source_str + pmatch[j].rm_so, len); + } + } + + if (opt_inline) { + Jim_ListAppendElement(interp, resultListObj, resultObj); + } + else { + + result = Jim_SetVariable(interp, argv[i], resultObj); + + if (result != JIM_OK) { + Jim_FreeObj(interp, resultObj); + break; + } + } + } + + try_next_match: + if (opt_all && (pattern[0] != '^' || (regcomp_flags & REG_NEWLINE)) && *source_str) { + if (pmatch[0].rm_eo) { + offset += pmatch[0].rm_eo; + source_str += pmatch[0].rm_eo; + } + else { + source_str++; + offset++; + } + if (*source_str) { + eflags = REG_NOTBOL; + goto next_match; + } + } + + done: + if (result == JIM_OK) { + if (opt_inline) { + Jim_SetResult(interp, resultListObj); + } + else { + Jim_SetResultInt(interp, num_matches); + } + } + + Jim_Free(pmatch); + return result; +} + +#define MAX_SUB_MATCHES 50 + +int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int regcomp_flags = 0; + int regexec_flags = 0; + int opt_all = 0; + int offset = 0; + regex_t *regex; + const char *p; + int result; + regmatch_t pmatch[MAX_SUB_MATCHES + 1]; + int num_matches = 0; + + int i, j, n; + Jim_Obj *varname; + Jim_Obj *resultObj; + const char *source_str; + int source_len; + const char *replace_str; + int replace_len; + const char *pattern; + int option; + enum { + OPT_NOCASE, OPT_LINE, OPT_ALL, OPT_START, OPT_END + }; + static const char * const options[] = { + "-nocase", "-line", "-all", "-start", "--", NULL + }; + + if (argc < 4) { + wrongNumArgs: + Jim_WrongNumArgs(interp, 1, argv, + "?switches? exp string subSpec ?varName?"); + return JIM_ERR; + } + + for (i = 1; i < argc; i++) { + const char *opt = Jim_String(argv[i]); + + if (*opt != '-') { + break; + } + if (Jim_GetEnum(interp, argv[i], options, &option, "switch", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + if (option == OPT_END) { + i++; + break; + } + switch (option) { + case OPT_NOCASE: + regcomp_flags |= REG_ICASE; + break; + + case OPT_LINE: + regcomp_flags |= REG_NEWLINE; + break; + + case OPT_ALL: + opt_all = 1; + break; + + case OPT_START: + if (++i == argc) { + goto wrongNumArgs; + } + if (Jim_GetIndex(interp, argv[i], &offset) != JIM_OK) { + return JIM_ERR; + } + break; + } + } + if (argc - i != 3 && argc - i != 4) { + goto wrongNumArgs; + } + + regex = SetRegexpFromAny(interp, argv[i], regcomp_flags); + if (!regex) { + return JIM_ERR; + } + pattern = Jim_String(argv[i]); + + source_str = Jim_GetString(argv[i + 1], &source_len); + replace_str = Jim_GetString(argv[i + 2], &replace_len); + varname = argv[i + 3]; + + + resultObj = Jim_NewStringObj(interp, "", 0); + + if (offset) { + if (offset < 0) { + offset += source_len + 1; + } + if (offset > source_len) { + offset = source_len; + } + else if (offset < 0) { + offset = 0; + } + } + + + Jim_AppendString(interp, resultObj, source_str, offset); + + + n = source_len - offset; + p = source_str + offset; + do { + int match = regexec(regex, p, MAX_SUB_MATCHES, pmatch, regexec_flags); + + if (match >= REG_BADPAT) { + char buf[100]; + + regerror(match, regex, buf, sizeof(buf)); + Jim_SetResultFormatted(interp, "error while matching pattern: %s", buf); + return JIM_ERR; + } + if (match == REG_NOMATCH) { + break; + } + + num_matches++; + + Jim_AppendString(interp, resultObj, p, pmatch[0].rm_so); + + + for (j = 0; j < replace_len; j++) { + int idx; + int c = replace_str[j]; + + if (c == '&') { + idx = 0; + } + else if (c == '\\' && j < replace_len) { + c = replace_str[++j]; + if ((c >= '0') && (c <= '9')) { + idx = c - '0'; + } + else if ((c == '\\') || (c == '&')) { + Jim_AppendString(interp, resultObj, replace_str + j, 1); + continue; + } + else { + Jim_AppendString(interp, resultObj, replace_str + j - 1, 2); + continue; + } + } + else { + Jim_AppendString(interp, resultObj, replace_str + j, 1); + continue; + } + if ((idx < MAX_SUB_MATCHES) && pmatch[idx].rm_so != -1 && pmatch[idx].rm_eo != -1) { + Jim_AppendString(interp, resultObj, p + pmatch[idx].rm_so, + pmatch[idx].rm_eo - pmatch[idx].rm_so); + } + } + + p += pmatch[0].rm_eo; + n -= pmatch[0].rm_eo; + + + if (!opt_all || n == 0) { + break; + } + + + if ((regcomp_flags & REG_NEWLINE) == 0 && pattern[0] == '^') { + break; + } + + + if (pattern[0] == '\0' && n) { + + Jim_AppendString(interp, resultObj, p, 1); + p++; + n--; + } + + regexec_flags |= REG_NOTBOL; + } while (n); + + Jim_AppendString(interp, resultObj, p, -1); + + + if (argc - i == 4) { + result = Jim_SetVariable(interp, varname, resultObj); + + if (result == JIM_OK) { + Jim_SetResultInt(interp, num_matches); + } + else { + Jim_FreeObj(interp, resultObj); + } + } + else { + Jim_SetResult(interp, resultObj); + result = JIM_OK; + } + + return result; +} + +int Jim_regexpInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "regexp", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "regexp", Jim_RegexpCmd, NULL, NULL); + Jim_CreateCommand(interp, "regsub", Jim_RegsubCmd, NULL, NULL); + return JIM_OK; +} + +#include +#include +#include +#include +#include +#include + + +#ifdef HAVE_UTIMES +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#elif defined(_MSC_VER) +#include +#define F_OK 0 +#define W_OK 2 +#define R_OK 4 +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +# ifndef MAXPATHLEN +# define MAXPATHLEN JIM_PATH_LEN +# endif + + +static const char *JimGetFileType(int mode) +{ + if (S_ISREG(mode)) { + return "file"; + } + else if (S_ISDIR(mode)) { + return "directory"; + } +#ifdef S_ISCHR + else if (S_ISCHR(mode)) { + return "characterSpecial"; + } +#endif +#ifdef S_ISBLK + else if (S_ISBLK(mode)) { + return "blockSpecial"; + } +#endif +#ifdef S_ISFIFO + else if (S_ISFIFO(mode)) { + return "fifo"; + } +#endif +#ifdef S_ISLNK + else if (S_ISLNK(mode)) { + return "link"; + } +#endif +#ifdef S_ISSOCK + else if (S_ISSOCK(mode)) { + return "socket"; + } +#endif + return "unknown"; +} + + +static int set_array_int_value(Jim_Interp *interp, Jim_Obj *container, const char *key, + jim_wide value) +{ + Jim_Obj *nameobj = Jim_NewStringObj(interp, key, -1); + Jim_Obj *valobj = Jim_NewWideObj(interp, value); + + if (Jim_SetDictKeysVector(interp, container, &nameobj, 1, valobj, JIM_ERRMSG) != JIM_OK) { + Jim_FreeObj(interp, nameobj); + Jim_FreeObj(interp, valobj); + return JIM_ERR; + } + return JIM_OK; +} + +static int set_array_string_value(Jim_Interp *interp, Jim_Obj *container, const char *key, + const char *value) +{ + Jim_Obj *nameobj = Jim_NewStringObj(interp, key, -1); + Jim_Obj *valobj = Jim_NewStringObj(interp, value, -1); + + if (Jim_SetDictKeysVector(interp, container, &nameobj, 1, valobj, JIM_ERRMSG) != JIM_OK) { + Jim_FreeObj(interp, nameobj); + Jim_FreeObj(interp, valobj); + return JIM_ERR; + } + return JIM_OK; +} + +static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb) +{ + if (set_array_int_value(interp, varName, "dev", sb->st_dev) != JIM_OK) { + Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName); + return JIM_ERR; + } + set_array_int_value(interp, varName, "ino", sb->st_ino); + set_array_int_value(interp, varName, "mode", sb->st_mode); + set_array_int_value(interp, varName, "nlink", sb->st_nlink); + set_array_int_value(interp, varName, "uid", sb->st_uid); + set_array_int_value(interp, varName, "gid", sb->st_gid); + set_array_int_value(interp, varName, "size", sb->st_size); + set_array_int_value(interp, varName, "atime", sb->st_atime); + set_array_int_value(interp, varName, "mtime", sb->st_mtime); + set_array_int_value(interp, varName, "ctime", sb->st_ctime); + set_array_string_value(interp, varName, "type", JimGetFileType((int)sb->st_mode)); + + + Jim_SetResult(interp, Jim_GetVariable(interp, varName, 0)); + + return JIM_OK; +} + +static int file_cmd_dirname(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + const char *p = strrchr(path, '/'); + + if (!p && path[0] == '.' && path[1] == '.' && path[2] == '\0') { + Jim_SetResultString(interp, "..", -1); + } else if (!p) { + Jim_SetResultString(interp, ".", -1); + } + else if (p == path) { + Jim_SetResultString(interp, "/", -1); + } +#if defined(__MINGW32__) || defined(_MSC_VER) + else if (p[-1] == ':') { + + Jim_SetResultString(interp, path, p - path + 1); + } +#endif + else { + Jim_SetResultString(interp, path, p - path); + } + return JIM_OK; +} + +static int file_cmd_rootname(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + const char *lastSlash = strrchr(path, '/'); + const char *p = strrchr(path, '.'); + + if (p == NULL || (lastSlash != NULL && lastSlash > p)) { + Jim_SetResult(interp, argv[0]); + } + else { + Jim_SetResultString(interp, path, p - path); + } + return JIM_OK; +} + +static int file_cmd_extension(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + const char *lastSlash = strrchr(path, '/'); + const char *p = strrchr(path, '.'); + + if (p == NULL || (lastSlash != NULL && lastSlash >= p)) { + p = ""; + } + Jim_SetResultString(interp, p, -1); + return JIM_OK; +} + +static int file_cmd_tail(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + const char *lastSlash = strrchr(path, '/'); + + if (lastSlash) { + Jim_SetResultString(interp, lastSlash + 1, -1); + } + else { + Jim_SetResult(interp, argv[0]); + } + return JIM_OK; +} + +static int file_cmd_normalize(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ +#ifdef HAVE_REALPATH + const char *path = Jim_String(argv[0]); + char *newname = Jim_Alloc(MAXPATHLEN + 1); + + if (realpath(path, newname)) { + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, -1)); + return JIM_OK; + } + else { + Jim_Free(newname); + Jim_SetResultFormatted(interp, "can't normalize \"%#s\": %s", argv[0], strerror(errno)); + return JIM_ERR; + } +#else + Jim_SetResultString(interp, "Not implemented", -1); + return JIM_ERR; +#endif +} + +static int file_cmd_join(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + char *newname = Jim_Alloc(MAXPATHLEN + 1); + char *last = newname; + + *newname = 0; + + + for (i = 0; i < argc; i++) { + int len; + const char *part = Jim_GetString(argv[i], &len); + + if (*part == '/') { + + last = newname; + } +#if defined(__MINGW32__) || defined(_MSC_VER) + else if (strchr(part, ':')) { + + last = newname; + } +#endif + else if (part[0] == '.') { + if (part[1] == '/') { + part += 2; + len -= 2; + } + else if (part[1] == 0 && last != newname) { + + continue; + } + } + + + if (last != newname && last[-1] != '/') { + *last++ = '/'; + } + + if (len) { + if (last + len - newname >= MAXPATHLEN) { + Jim_Free(newname); + Jim_SetResultString(interp, "Path too long", -1); + return JIM_ERR; + } + memcpy(last, part, len); + last += len; + } + + + if (last > newname + 1 && last[-1] == '/') { + *--last = 0; + } + } + + *last = 0; + + + + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname)); + + return JIM_OK; +} + +static int file_access(Jim_Interp *interp, Jim_Obj *filename, int mode) +{ + const char *path = Jim_String(filename); + int rc = access(path, mode); + + Jim_SetResultBool(interp, rc != -1); + + return JIM_OK; +} + +static int file_cmd_readable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return file_access(interp, argv[0], R_OK); +} + +static int file_cmd_writable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return file_access(interp, argv[0], W_OK); +} + +static int file_cmd_executable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ +#ifdef X_OK + return file_access(interp, argv[0], X_OK); +#else + Jim_SetResultBool(interp, 1); + return JIM_OK; +#endif +} + +static int file_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return file_access(interp, argv[0], F_OK); +} + +static int file_cmd_delete(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int force = Jim_CompareStringImmediate(interp, argv[0], "-force"); + + if (force || Jim_CompareStringImmediate(interp, argv[0], "--")) { + argc++; + argv--; + } + + while (argc--) { + const char *path = Jim_String(argv[0]); + + if (unlink(path) == -1 && errno != ENOENT) { + if (rmdir(path) == -1) { + + if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) { + Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path, + strerror(errno)); + return JIM_ERR; + } + } + } + argv++; + } + return JIM_OK; +} + +#ifdef HAVE_MKDIR_ONE_ARG +#define MKDIR_DEFAULT(PATHNAME) mkdir(PATHNAME) +#else +#define MKDIR_DEFAULT(PATHNAME) mkdir(PATHNAME, 0755) +#endif + +static int mkdir_all(char *path) +{ + int ok = 1; + + + goto first; + + while (ok--) { + + { + char *slash = strrchr(path, '/'); + + if (slash && slash != path) { + *slash = 0; + if (mkdir_all(path) != 0) { + return -1; + } + *slash = '/'; + } + } + first: + if (MKDIR_DEFAULT(path) == 0) { + return 0; + } + if (errno == ENOENT) { + + continue; + } + + if (errno == EEXIST) { + struct stat sb; + + if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { + return 0; + } + + errno = EEXIST; + } + + break; + } + return -1; +} + +static int file_cmd_mkdir(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + while (argc--) { + char *path = Jim_StrDup(Jim_String(argv[0])); + int rc = mkdir_all(path); + + Jim_Free(path); + if (rc != 0) { + Jim_SetResultFormatted(interp, "can't create directory \"%#s\": %s", argv[0], + strerror(errno)); + return JIM_ERR; + } + argv++; + } + return JIM_OK; +} + +#ifdef HAVE_MKSTEMP +static int file_cmd_tempfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int fd; + char *filename; + const char *template = "/tmp/tcl.tmp.XXXXXX"; + + if (argc >= 1) { + template = Jim_String(argv[0]); + } + filename = Jim_StrDup(template); + + fd = mkstemp(filename); + if (fd < 0) { + Jim_SetResultString(interp, "Failed to create tempfile", -1); + return JIM_ERR; + } + close(fd); + + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, filename, -1)); + return JIM_OK; +} +#endif + +static int file_cmd_rename(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *source; + const char *dest; + int force = 0; + + if (argc == 3) { + if (!Jim_CompareStringImmediate(interp, argv[0], "-force")) { + return -1; + } + force++; + argv++; + argc--; + } + + source = Jim_String(argv[0]); + dest = Jim_String(argv[1]); + + if (!force && access(dest, F_OK) == 0) { + Jim_SetResultFormatted(interp, "error renaming \"%#s\" to \"%#s\": target exists", argv[0], + argv[1]); + return JIM_ERR; + } + + if (rename(source, dest) != 0) { + Jim_SetResultFormatted(interp, "error renaming \"%#s\" to \"%#s\": %s", argv[0], argv[1], + strerror(errno)); + return JIM_ERR; + } + + return JIM_OK; +} + +static int file_stat(Jim_Interp *interp, Jim_Obj *filename, struct stat *sb) +{ + const char *path = Jim_String(filename); + + if (stat(path, sb) == -1) { + Jim_SetResultFormatted(interp, "could not read \"%#s\": %s", filename, strerror(errno)); + return JIM_ERR; + } + return JIM_OK; +} + +#ifndef HAVE_LSTAT +#define lstat stat +#endif + +static int file_lstat(Jim_Interp *interp, Jim_Obj *filename, struct stat *sb) +{ + const char *path = Jim_String(filename); + + if (lstat(path, sb) == -1) { + Jim_SetResultFormatted(interp, "could not read \"%#s\": %s", filename, strerror(errno)); + return JIM_ERR; + } + return JIM_OK; +} + +static int file_cmd_atime(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultInt(interp, sb.st_atime); + return JIM_OK; +} + +static int file_cmd_mtime(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + + if (argc == 2) { +#ifdef HAVE_UTIMES + jim_wide newtime; + struct timeval times[2]; + + if (Jim_GetWide(interp, argv[1], &newtime) != JIM_OK) { + return JIM_ERR; + } + + times[1].tv_sec = times[0].tv_sec = newtime; + times[1].tv_usec = times[0].tv_usec = 0; + + if (utimes(Jim_String(argv[0]), times) != 0) { + Jim_SetResultFormatted(interp, "can't set time on \"%#s\": %s", argv[0], strerror(errno)); + return JIM_ERR; + } +#else + Jim_SetResultString(interp, "Not implemented", -1); + return JIM_ERR; +#endif + } + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultInt(interp, sb.st_mtime); + return JIM_OK; +} + +static int file_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return Jim_EvalPrefix(interp, "file copy", argc, argv); +} + +static int file_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultInt(interp, sb.st_size); + return JIM_OK; +} + +static int file_cmd_isdirectory(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + int ret = 0; + + if (file_stat(interp, argv[0], &sb) == JIM_OK) { + ret = S_ISDIR(sb.st_mode); + } + Jim_SetResultInt(interp, ret); + return JIM_OK; +} + +static int file_cmd_isfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + int ret = 0; + + if (file_stat(interp, argv[0], &sb) == JIM_OK) { + ret = S_ISREG(sb.st_mode); + } + Jim_SetResultInt(interp, ret); + return JIM_OK; +} + +#ifdef HAVE_GETEUID +static int file_cmd_owned(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + int ret = 0; + + if (file_stat(interp, argv[0], &sb) == JIM_OK) { + ret = (geteuid() == sb.st_uid); + } + Jim_SetResultInt(interp, ret); + return JIM_OK; +} +#endif + +#if defined(HAVE_READLINK) +static int file_cmd_readlink(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + char *linkValue = Jim_Alloc(MAXPATHLEN + 1); + + int linkLength = readlink(path, linkValue, MAXPATHLEN); + + if (linkLength == -1) { + Jim_Free(linkValue); + Jim_SetResultFormatted(interp, "couldn't readlink \"%#s\": %s", argv[0], strerror(errno)); + return JIM_ERR; + } + linkValue[linkLength] = 0; + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, linkValue, linkLength)); + return JIM_OK; +} +#endif + +static int file_cmd_type(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + + if (file_lstat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultString(interp, JimGetFileType((int)sb.st_mode), -1); + return JIM_OK; +} + +static int file_cmd_lstat(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + + if (file_lstat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + return StoreStatData(interp, argv[1], &sb); +} + +static int file_cmd_stat(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + return StoreStatData(interp, argv[1], &sb); +} + +static const jim_subcmd_type file_command_table[] = { + { "atime", + "name", + file_cmd_atime, + 1, + 1, + + }, + { "mtime", + "name ?time?", + file_cmd_mtime, + 1, + 2, + + }, + { "copy", + "?-force? source dest", + file_cmd_copy, + 2, + 3, + + }, + { "dirname", + "name", + file_cmd_dirname, + 1, + 1, + + }, + { "rootname", + "name", + file_cmd_rootname, + 1, + 1, + + }, + { "extension", + "name", + file_cmd_extension, + 1, + 1, + + }, + { "tail", + "name", + file_cmd_tail, + 1, + 1, + + }, + { "normalize", + "name", + file_cmd_normalize, + 1, + 1, + + }, + { "join", + "name ?name ...?", + file_cmd_join, + 1, + -1, + + }, + { "readable", + "name", + file_cmd_readable, + 1, + 1, + + }, + { "writable", + "name", + file_cmd_writable, + 1, + 1, + + }, + { "executable", + "name", + file_cmd_executable, + 1, + 1, + + }, + { "exists", + "name", + file_cmd_exists, + 1, + 1, + + }, + { "delete", + "?-force|--? name ...", + file_cmd_delete, + 1, + -1, + + }, + { "mkdir", + "dir ...", + file_cmd_mkdir, + 1, + -1, + + }, +#ifdef HAVE_MKSTEMP + { "tempfile", + "?template?", + file_cmd_tempfile, + 0, + 1, + + }, +#endif + { "rename", + "?-force? source dest", + file_cmd_rename, + 2, + 3, + + }, +#if defined(HAVE_READLINK) + { "readlink", + "name", + file_cmd_readlink, + 1, + 1, + + }, +#endif + { "size", + "name", + file_cmd_size, + 1, + 1, + + }, + { "stat", + "name var", + file_cmd_stat, + 2, + 2, + + }, + { "lstat", + "name var", + file_cmd_lstat, + 2, + 2, + + }, + { "type", + "name", + file_cmd_type, + 1, + 1, + + }, +#ifdef HAVE_GETEUID + { "owned", + "name", + file_cmd_owned, + 1, + 1, + + }, +#endif + { "isdirectory", + "name", + file_cmd_isdirectory, + 1, + 1, + + }, + { "isfile", + "name", + file_cmd_isfile, + 1, + 1, + + }, + { + NULL + } +}; + +static int Jim_CdCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "dirname"); + return JIM_ERR; + } + + path = Jim_String(argv[1]); + + if (chdir(path) != 0) { + Jim_SetResultFormatted(interp, "couldn't change working directory to \"%s\": %s", path, + strerror(errno)); + return JIM_ERR; + } + return JIM_OK; +} + +static int Jim_PwdCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const int cwd_len = 2048; + char *cwd = malloc(cwd_len); + + if (getcwd(cwd, cwd_len) == NULL) { + Jim_SetResultString(interp, "Failed to get pwd", -1); + return JIM_ERR; + } +#if defined(__MINGW32__) || defined(_MSC_VER) + { + + char *p = cwd; + while ((p = strchr(p, '\\')) != NULL) { + *p++ = '/'; + } + } +#endif + + Jim_SetResultString(interp, cwd, -1); + + free(cwd); + return JIM_OK; +} + +int Jim_fileInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "file", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "file", Jim_SubCmdProc, (void *)file_command_table, NULL); + Jim_CreateCommand(interp, "pwd", Jim_PwdCmd, NULL, NULL); + Jim_CreateCommand(interp, "cd", Jim_CdCmd, NULL, NULL); + return JIM_OK; +} + +#include +#include + + +#if (!defined(HAVE_VFORK) || !defined(HAVE_WAITPID)) && !defined(__MINGW32__) +static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *cmdlineObj = Jim_NewEmptyStringObj(interp); + int i, j; + int rc; + + + for (i = 1; i < argc; i++) { + int len; + const char *arg = Jim_GetString(argv[i], &len); + + if (i > 1) { + Jim_AppendString(interp, cmdlineObj, " ", 1); + } + if (strpbrk(arg, "\\\" ") == NULL) { + + Jim_AppendString(interp, cmdlineObj, arg, len); + continue; + } + + Jim_AppendString(interp, cmdlineObj, "\"", 1); + for (j = 0; j < len; j++) { + if (arg[j] == '\\' || arg[j] == '"') { + Jim_AppendString(interp, cmdlineObj, "\\", 1); + } + Jim_AppendString(interp, cmdlineObj, &arg[j], 1); + } + Jim_AppendString(interp, cmdlineObj, "\"", 1); + } + rc = system(Jim_String(cmdlineObj)); + + Jim_FreeNewObj(interp, cmdlineObj); + + if (rc) { + Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, 0)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, rc)); + Jim_SetGlobalVariableStr(interp, "errorCode", errorCode); + return JIM_ERR; + } + + return JIM_OK; +} + +int Jim_execInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "exec", "1.0", JIM_ERRMSG)) + return JIM_ERR; + Jim_CreateCommand(interp, "exec", Jim_ExecCmd, NULL, NULL); + return JIM_OK; +} +#else + + +#include +#include + +#if defined(__MINGW32__) + + #ifndef STRICT + #define STRICT + #endif + #define WIN32_LEAN_AND_MEAN + #include + #include + + typedef HANDLE fdtype; + typedef HANDLE pidtype; + #define JIM_BAD_FD INVALID_HANDLE_VALUE + #define JIM_BAD_PID INVALID_HANDLE_VALUE + #define JimCloseFd CloseHandle + + #define WIFEXITED(STATUS) 1 + #define WEXITSTATUS(STATUS) (STATUS) + #define WIFSIGNALED(STATUS) 0 + #define WTERMSIG(STATUS) 0 + #define WNOHANG 1 + + static fdtype JimFileno(FILE *fh); + static pidtype JimWaitPid(pidtype pid, int *status, int nohang); + static fdtype JimDupFd(fdtype infd); + static fdtype JimOpenForRead(const char *filename); + static FILE *JimFdOpenForRead(fdtype fd); + static int JimPipe(fdtype pipefd[2]); + static pidtype JimStartWinProcess(Jim_Interp *interp, char **argv, char *env, + fdtype inputId, fdtype outputId, fdtype errorId); + static int JimErrno(void); +#else + #include + #include + #include + + typedef int fdtype; + typedef int pidtype; + #define JimPipe pipe + #define JimErrno() errno + #define JIM_BAD_FD -1 + #define JIM_BAD_PID -1 + #define JimFileno fileno + #define JimReadFd read + #define JimCloseFd close + #define JimWaitPid waitpid + #define JimDupFd dup + #define JimFdOpenForRead(FD) fdopen((FD), "r") + #define JimOpenForRead(NAME) open((NAME), O_RDONLY, 0) + + #ifndef HAVE_EXECVPE + #define execvpe(ARG0, ARGV, ENV) execvp(ARG0, ARGV) + #endif +#endif + +static const char *JimStrError(void); +static char **JimSaveEnv(char **env); +static void JimRestoreEnv(char **env); +static int JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, + pidtype **pidArrayPtr, fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr); +static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr); +static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, fdtype errorId); +static fdtype JimCreateTemp(Jim_Interp *interp, const char *contents); +static fdtype JimOpenForWrite(const char *filename, int append); +static int JimRewindFd(fdtype fd); + +static void Jim_SetResultErrno(Jim_Interp *interp, const char *msg) +{ + Jim_SetResultFormatted(interp, "%s: %s", msg, JimStrError()); +} + +static const char *JimStrError(void) +{ + return strerror(JimErrno()); +} + +static void Jim_RemoveTrailingNewline(Jim_Obj *objPtr) +{ + int len; + const char *s = Jim_GetString(objPtr, &len); + + if (len > 0 && s[len - 1] == '\n') { + objPtr->length--; + objPtr->bytes[objPtr->length] = '\0'; + } +} + +static int JimAppendStreamToString(Jim_Interp *interp, fdtype fd, Jim_Obj *strObj) +{ + char buf[256]; + FILE *fh = JimFdOpenForRead(fd); + if (fh == NULL) { + return JIM_ERR; + } + + while (1) { + int retval = fread(buf, 1, sizeof(buf), fh); + if (retval > 0) { + Jim_AppendString(interp, strObj, buf, retval); + } + if (retval != sizeof(buf)) { + break; + } + } + Jim_RemoveTrailingNewline(strObj); + fclose(fh); + return JIM_OK; +} + +static void JimTrimTrailingNewline(Jim_Interp *interp) +{ + int len; + const char *p = Jim_GetString(Jim_GetResult(interp), &len); + + if (len > 0 && p[len - 1] == '\n') { + Jim_SetResultString(interp, p, len - 1); + } +} + +static char **JimBuildEnv(Jim_Interp *interp) +{ +#if defined(jim_ext_tclcompat) + int i; + int size; + int num; + int n; + char **envptr; + char *envdata; + + Jim_Obj *objPtr = Jim_GetGlobalVariableStr(interp, "env", JIM_NONE); + + if (!objPtr) { + return Jim_GetEnviron(); + } + + + + num = Jim_ListLength(interp, objPtr); + if (num % 2) { + num--; + } + size = Jim_Length(objPtr) + 2; + + envptr = Jim_Alloc(sizeof(*envptr) * (num / 2 + 1) + size); + envdata = (char *)&envptr[num / 2 + 1]; + + n = 0; + for (i = 0; i < num; i += 2) { + const char *s1, *s2; + Jim_Obj *elemObj; + + Jim_ListIndex(interp, objPtr, i, &elemObj, JIM_NONE); + s1 = Jim_String(elemObj); + Jim_ListIndex(interp, objPtr, i + 1, &elemObj, JIM_NONE); + s2 = Jim_String(elemObj); + + envptr[n] = envdata; + envdata += sprintf(envdata, "%s=%s", s1, s2); + envdata++; + n++; + } + envptr[n] = NULL; + *envdata = 0; + + return envptr; +#else + return Jim_GetEnviron(); +#endif +} + +static void JimFreeEnv(char **env, char **original_environ) +{ +#ifdef jim_ext_tclcompat + if (env != original_environ) { + Jim_Free(env); + } +#endif +} + +static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus) +{ + Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0); + int rc = JIM_ERR; + + if (WIFEXITED(waitStatus)) { + if (WEXITSTATUS(waitStatus) == 0) { + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "NONE", -1)); + rc = JIM_OK; + } + else { + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WEXITSTATUS(waitStatus))); + } + } + else { + const char *type; + const char *action; + + if (WIFSIGNALED(waitStatus)) { + type = "CHILDKILLED"; + action = "killed"; + } + else { + type = "CHILDSUSP"; + action = "suspended"; + } + + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, type, -1)); + +#ifdef jim_ext_signal + Jim_SetResultFormatted(interp, "child %s by signal %s", action, Jim_SignalId(WTERMSIG(waitStatus))); + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalId(WTERMSIG(waitStatus)), -1)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, pid)); + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalName(WTERMSIG(waitStatus)), -1)); +#else + Jim_SetResultFormatted(interp, "child %s by signal %d", action, WTERMSIG(waitStatus)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus))); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus))); +#endif + } + Jim_SetGlobalVariableStr(interp, "errorCode", errorCode); + return rc; +} + + +struct WaitInfo +{ + pidtype pid; + int status; + int flags; +}; + +struct WaitInfoTable { + struct WaitInfo *info; + int size; + int used; +}; + + +#define WI_DETACHED 2 + +#define WAIT_TABLE_GROW_BY 4 + +static void JimFreeWaitInfoTable(struct Jim_Interp *interp, void *privData) +{ + struct WaitInfoTable *table = privData; + + Jim_Free(table->info); + Jim_Free(table); +} + +static struct WaitInfoTable *JimAllocWaitInfoTable(void) +{ + struct WaitInfoTable *table = Jim_Alloc(sizeof(*table)); + table->info = NULL; + table->size = table->used = 0; + + return table; +} + +static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + fdtype outputId; /* File id for output pipe. -1 + * means command overrode. */ + fdtype errorId; /* File id for temporary file + * containing error output. */ + pidtype *pidPtr; + int numPids, result; + + if (argc > 1 && Jim_CompareStringImmediate(interp, argv[argc - 1], "&")) { + Jim_Obj *listObj; + int i; + + argc--; + numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL); + if (numPids < 0) { + return JIM_ERR; + } + + listObj = Jim_NewListObj(interp, NULL, 0); + for (i = 0; i < numPids; i++) { + Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i])); + } + Jim_SetResult(interp, listObj); + JimDetachPids(interp, numPids, pidPtr); + Jim_Free(pidPtr); + return JIM_OK; + } + + numPids = + JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, &outputId, &errorId); + + if (numPids < 0) { + return JIM_ERR; + } + + Jim_SetResultString(interp, "", 0); + + result = JIM_OK; + if (outputId != JIM_BAD_FD) { + result = JimAppendStreamToString(interp, outputId, Jim_GetResult(interp)); + if (result < 0) { + Jim_SetResultErrno(interp, "error reading from output pipe"); + } + } + + if (JimCleanupChildren(interp, numPids, pidPtr, errorId) != JIM_OK) { + result = JIM_ERR; + } + return result; +} + +static void JimReapDetachedPids(struct WaitInfoTable *table) +{ + struct WaitInfo *waitPtr; + int count; + + if (!table) { + return; + } + + for (waitPtr = table->info, count = table->used; count > 0; waitPtr++, count--) { + if (waitPtr->flags & WI_DETACHED) { + int status; + pidtype pid = JimWaitPid(waitPtr->pid, &status, WNOHANG); + if (pid != JIM_BAD_PID) { + if (waitPtr != &table->info[table->used - 1]) { + *waitPtr = table->info[table->used - 1]; + } + table->used--; + } + } + } +} + +static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr) +{ + int i; + + + for (i = 0; i < table->used; i++) { + if (pid == table->info[i].pid) { + + JimWaitPid(pid, statusPtr, 0); + + + if (i != table->used - 1) { + table->info[i] = table->info[table->used - 1]; + } + table->used--; + return pid; + } + } + + + return JIM_BAD_PID; +} + + +static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr) +{ + int j; + struct WaitInfoTable *table = Jim_CmdPrivData(interp); + + for (j = 0; j < numPids; j++) { + + int i; + for (i = 0; i < table->used; i++) { + if (pidPtr[j] == table->info[i].pid) { + table->info[i].flags |= WI_DETACHED; + break; + } + } + } +} + +static FILE *JimGetAioFilehandle(Jim_Interp *interp, const char *name) +{ + FILE *fh; + Jim_Obj *fhObj; + + fhObj = Jim_NewStringObj(interp, name, -1); + Jim_IncrRefCount(fhObj); + fh = Jim_AioFilehandle(interp, fhObj); + Jim_DecrRefCount(interp, fhObj); + + return fh; +} + +static int +JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype **pidArrayPtr, + fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr) +{ + pidtype *pidPtr = NULL; /* Points to malloc-ed array holding all + * the pids of child processes. */ + int numPids = 0; /* Actual number of processes that exist + * at *pidPtr right now. */ + int cmdCount; /* Count of number of distinct commands + * found in argc/argv. */ + const char *input = NULL; /* Describes input for pipeline, depending + * on "inputFile". NULL means take input + * from stdin/pipe. */ + +#define FILE_NAME 0 +#define FILE_APPEND 1 +#define FILE_HANDLE 2 +#define FILE_TEXT 3 + + int inputFile = FILE_NAME; /* 1 means input is name of input file. + * 2 means input is filehandle name. + * 0 means input holds actual + * text to be input to command. */ + + int outputFile = FILE_NAME; /* 0 means output is the name of output file. + * 1 means output is the name of output file, and append. + * 2 means output is filehandle name. + * All this is ignored if output is NULL + */ + int errorFile = FILE_NAME; /* 0 means error is the name of error file. + * 1 means error is the name of error file, and append. + * 2 means error is filehandle name. + * All this is ignored if error is NULL + */ + const char *output = NULL; /* Holds name of output file to pipe to, + * or NULL if output goes to stdout/pipe. */ + const char *error = NULL; /* Holds name of stderr file to pipe to, + * or NULL if stderr goes to stderr/pipe. */ + fdtype inputId = JIM_BAD_FD; + fdtype outputId = JIM_BAD_FD; + fdtype errorId = JIM_BAD_FD; + fdtype lastOutputId = JIM_BAD_FD; + fdtype pipeIds[2]; + int firstArg, lastArg; /* Indexes of first and last arguments in + * current command. */ + int lastBar; + int i; + pidtype pid; + char **save_environ; + struct WaitInfoTable *table = Jim_CmdPrivData(interp); + + + char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1)); + int arg_count = 0; + + JimReapDetachedPids(table); + + if (inPipePtr != NULL) { + *inPipePtr = JIM_BAD_FD; + } + if (outPipePtr != NULL) { + *outPipePtr = JIM_BAD_FD; + } + if (errFilePtr != NULL) { + *errFilePtr = JIM_BAD_FD; + } + pipeIds[0] = pipeIds[1] = JIM_BAD_FD; + + cmdCount = 1; + lastBar = -1; + for (i = 0; i < argc; i++) { + const char *arg = Jim_String(argv[i]); + + if (arg[0] == '<') { + inputFile = FILE_NAME; + input = arg + 1; + if (*input == '<') { + inputFile = FILE_TEXT; + input++; + } + else if (*input == '@') { + inputFile = FILE_HANDLE; + input++; + } + + if (!*input && ++i < argc) { + input = Jim_String(argv[i]); + } + } + else if (arg[0] == '>') { + int dup_error = 0; + + outputFile = FILE_NAME; + + output = arg + 1; + if (*output == '>') { + outputFile = FILE_APPEND; + output++; + } + if (*output == '&') { + + output++; + dup_error = 1; + } + if (*output == '@') { + outputFile = FILE_HANDLE; + output++; + } + if (!*output && ++i < argc) { + output = Jim_String(argv[i]); + } + if (dup_error) { + errorFile = outputFile; + error = output; + } + } + else if (arg[0] == '2' && arg[1] == '>') { + error = arg + 2; + errorFile = FILE_NAME; + + if (*error == '@') { + errorFile = FILE_HANDLE; + error++; + } + else if (*error == '>') { + errorFile = FILE_APPEND; + error++; + } + if (!*error && ++i < argc) { + error = Jim_String(argv[i]); + } + } + else { + if (strcmp(arg, "|") == 0 || strcmp(arg, "|&") == 0) { + if (i == lastBar + 1 || i == argc - 1) { + Jim_SetResultString(interp, "illegal use of | or |& in command", -1); + goto badargs; + } + lastBar = i; + cmdCount++; + } + + arg_array[arg_count++] = (char *)arg; + continue; + } + + if (i >= argc) { + Jim_SetResultFormatted(interp, "can't specify \"%s\" as last word in command", arg); + goto badargs; + } + } + + if (arg_count == 0) { + Jim_SetResultString(interp, "didn't specify command to execute", -1); +badargs: + Jim_Free(arg_array); + return -1; + } + + + save_environ = JimSaveEnv(JimBuildEnv(interp)); + + if (input != NULL) { + if (inputFile == FILE_TEXT) { + inputId = JimCreateTemp(interp, input); + if (inputId == JIM_BAD_FD) { + goto error; + } + } + else if (inputFile == FILE_HANDLE) { + + FILE *fh = JimGetAioFilehandle(interp, input); + + if (fh == NULL) { + goto error; + } + inputId = JimDupFd(JimFileno(fh)); + } + else { + inputId = JimOpenForRead(input); + if (inputId == JIM_BAD_FD) { + Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", input, JimStrError()); + goto error; + } + } + } + else if (inPipePtr != NULL) { + if (JimPipe(pipeIds) != 0) { + Jim_SetResultErrno(interp, "couldn't create input pipe for command"); + goto error; + } + inputId = pipeIds[0]; + *inPipePtr = pipeIds[1]; + pipeIds[0] = pipeIds[1] = JIM_BAD_FD; + } + + if (output != NULL) { + if (outputFile == FILE_HANDLE) { + FILE *fh = JimGetAioFilehandle(interp, output); + if (fh == NULL) { + goto error; + } + fflush(fh); + lastOutputId = JimDupFd(JimFileno(fh)); + } + else { + lastOutputId = JimOpenForWrite(output, outputFile == FILE_APPEND); + if (lastOutputId == JIM_BAD_FD) { + Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", output, JimStrError()); + goto error; + } + } + } + else if (outPipePtr != NULL) { + if (JimPipe(pipeIds) != 0) { + Jim_SetResultErrno(interp, "couldn't create output pipe"); + goto error; + } + lastOutputId = pipeIds[1]; + *outPipePtr = pipeIds[0]; + pipeIds[0] = pipeIds[1] = JIM_BAD_FD; + } + + if (error != NULL) { + if (errorFile == FILE_HANDLE) { + if (strcmp(error, "1") == 0) { + + if (lastOutputId != JIM_BAD_FD) { + errorId = JimDupFd(lastOutputId); + } + else { + + error = "stdout"; + } + } + if (errorId == JIM_BAD_FD) { + FILE *fh = JimGetAioFilehandle(interp, error); + if (fh == NULL) { + goto error; + } + fflush(fh); + errorId = JimDupFd(JimFileno(fh)); + } + } + else { + errorId = JimOpenForWrite(error, errorFile == FILE_APPEND); + if (errorId == JIM_BAD_FD) { + Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", error, JimStrError()); + goto error; + } + } + } + else if (errFilePtr != NULL) { + errorId = JimCreateTemp(interp, NULL); + if (errorId == JIM_BAD_FD) { + goto error; + } + *errFilePtr = JimDupFd(errorId); + } + + + pidPtr = Jim_Alloc(cmdCount * sizeof(*pidPtr)); + for (i = 0; i < numPids; i++) { + pidPtr[i] = JIM_BAD_PID; + } + for (firstArg = 0; firstArg < arg_count; numPids++, firstArg = lastArg + 1) { + int pipe_dup_err = 0; + fdtype origErrorId = errorId; + + for (lastArg = firstArg; lastArg < arg_count; lastArg++) { + if (arg_array[lastArg][0] == '|') { + if (arg_array[lastArg][1] == '&') { + pipe_dup_err = 1; + } + break; + } + } + + arg_array[lastArg] = NULL; + if (lastArg == arg_count) { + outputId = lastOutputId; + } + else { + if (JimPipe(pipeIds) != 0) { + Jim_SetResultErrno(interp, "couldn't create pipe"); + goto error; + } + outputId = pipeIds[1]; + } + + + +#ifdef __MINGW32__ + pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ ? save_environ[0] : NULL, inputId, outputId, errorId); + if (pid == JIM_BAD_PID) { + Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]); + goto error; + } +#else + if (table->info == NULL) { + (void)signal(SIGPIPE, SIG_IGN); + } + + + if (pipe_dup_err) { + errorId = outputId; + } + + pid = vfork(); + if (pid < 0) { + Jim_SetResultErrno(interp, "couldn't fork child process"); + goto error; + } + if (pid == 0) { + + + if (inputId != -1) dup2(inputId, 0); + if (outputId != -1) dup2(outputId, 1); + if (errorId != -1) dup2(errorId, 2); + + for (i = 3; (i <= outputId) || (i <= inputId) || (i <= errorId); i++) { + close(i); + } + + execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron()); + + + fprintf(stderr, "couldn't exec \"%s\"", arg_array[firstArg]); + _exit(127); + } +#endif + + + + if (table->used == table->size) { + table->size += WAIT_TABLE_GROW_BY; + table->info = Jim_Realloc(table->info, table->size * sizeof(*table->info)); + } + + table->info[table->used].pid = pid; + table->info[table->used].flags = 0; + table->used++; + + pidPtr[numPids] = pid; + + + errorId = origErrorId; + + + if (inputId != JIM_BAD_FD) { + JimCloseFd(inputId); + } + if (outputId != JIM_BAD_FD) { + JimCloseFd(outputId); + } + inputId = pipeIds[0]; + pipeIds[0] = pipeIds[1] = JIM_BAD_FD; + } + *pidArrayPtr = pidPtr; + + + cleanup: + if (inputId != JIM_BAD_FD) { + JimCloseFd(inputId); + } + if (lastOutputId != JIM_BAD_FD) { + JimCloseFd(lastOutputId); + } + if (errorId != JIM_BAD_FD) { + JimCloseFd(errorId); + } + Jim_Free(arg_array); + + JimRestoreEnv(save_environ); + + return numPids; + + + error: + if ((inPipePtr != NULL) && (*inPipePtr != JIM_BAD_FD)) { + JimCloseFd(*inPipePtr); + *inPipePtr = JIM_BAD_FD; + } + if ((outPipePtr != NULL) && (*outPipePtr != JIM_BAD_FD)) { + JimCloseFd(*outPipePtr); + *outPipePtr = JIM_BAD_FD; + } + if ((errFilePtr != NULL) && (*errFilePtr != JIM_BAD_FD)) { + JimCloseFd(*errFilePtr); + *errFilePtr = JIM_BAD_FD; + } + if (pipeIds[0] != JIM_BAD_FD) { + JimCloseFd(pipeIds[0]); + } + if (pipeIds[1] != JIM_BAD_FD) { + JimCloseFd(pipeIds[1]); + } + if (pidPtr != NULL) { + for (i = 0; i < numPids; i++) { + if (pidPtr[i] != JIM_BAD_PID) { + JimDetachPids(interp, 1, &pidPtr[i]); + } + } + Jim_Free(pidPtr); + } + numPids = -1; + goto cleanup; +} + + +static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, fdtype errorId) +{ + struct WaitInfoTable *table = Jim_CmdPrivData(interp); + int result = JIM_OK; + int i; + + for (i = 0; i < numPids; i++) { + int waitStatus = 0; + if (JimWaitForProcess(table, pidPtr[i], &waitStatus) != JIM_BAD_PID) { + if (JimCheckWaitStatus(interp, pidPtr[i], waitStatus) != JIM_OK) { + result = JIM_ERR; + } + } + } + Jim_Free(pidPtr); + + if (errorId != JIM_BAD_FD) { + JimRewindFd(errorId); + if (JimAppendStreamToString(interp, errorId, Jim_GetResult(interp)) != JIM_OK) { + result = JIM_ERR; + } + } + + JimTrimTrailingNewline(interp); + + return result; +} + +int Jim_execInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "exec", "1.0", JIM_ERRMSG)) + return JIM_ERR; + Jim_CreateCommand(interp, "exec", Jim_ExecCmd, JimAllocWaitInfoTable(), JimFreeWaitInfoTable); + return JIM_OK; +} + +#if defined(__MINGW32__) + + +static SECURITY_ATTRIBUTES *JimStdSecAttrs(void) +{ + static SECURITY_ATTRIBUTES secAtts; + + secAtts.nLength = sizeof(SECURITY_ATTRIBUTES); + secAtts.lpSecurityDescriptor = NULL; + secAtts.bInheritHandle = TRUE; + return &secAtts; +} + +static int JimErrno(void) +{ + switch (GetLastError()) { + case ERROR_FILE_NOT_FOUND: return ENOENT; + case ERROR_PATH_NOT_FOUND: return ENOENT; + case ERROR_TOO_MANY_OPEN_FILES: return EMFILE; + case ERROR_ACCESS_DENIED: return EACCES; + case ERROR_INVALID_HANDLE: return EBADF; + case ERROR_BAD_ENVIRONMENT: return E2BIG; + case ERROR_BAD_FORMAT: return ENOEXEC; + case ERROR_INVALID_ACCESS: return EACCES; + case ERROR_INVALID_DRIVE: return ENOENT; + case ERROR_CURRENT_DIRECTORY: return EACCES; + case ERROR_NOT_SAME_DEVICE: return EXDEV; + case ERROR_NO_MORE_FILES: return ENOENT; + case ERROR_WRITE_PROTECT: return EROFS; + case ERROR_BAD_UNIT: return ENXIO; + case ERROR_NOT_READY: return EBUSY; + case ERROR_BAD_COMMAND: return EIO; + case ERROR_CRC: return EIO; + case ERROR_BAD_LENGTH: return EIO; + case ERROR_SEEK: return EIO; + case ERROR_WRITE_FAULT: return EIO; + case ERROR_READ_FAULT: return EIO; + case ERROR_GEN_FAILURE: return EIO; + case ERROR_SHARING_VIOLATION: return EACCES; + case ERROR_LOCK_VIOLATION: return EACCES; + case ERROR_SHARING_BUFFER_EXCEEDED: return ENFILE; + case ERROR_HANDLE_DISK_FULL: return ENOSPC; + case ERROR_NOT_SUPPORTED: return ENODEV; + case ERROR_REM_NOT_LIST: return EBUSY; + case ERROR_DUP_NAME: return EEXIST; + case ERROR_BAD_NETPATH: return ENOENT; + case ERROR_NETWORK_BUSY: return EBUSY; + case ERROR_DEV_NOT_EXIST: return ENODEV; + case ERROR_TOO_MANY_CMDS: return EAGAIN; + case ERROR_ADAP_HDW_ERR: return EIO; + case ERROR_BAD_NET_RESP: return EIO; + case ERROR_UNEXP_NET_ERR: return EIO; + case ERROR_NETNAME_DELETED: return ENOENT; + case ERROR_NETWORK_ACCESS_DENIED: return EACCES; + case ERROR_BAD_DEV_TYPE: return ENODEV; + case ERROR_BAD_NET_NAME: return ENOENT; + case ERROR_TOO_MANY_NAMES: return ENFILE; + case ERROR_TOO_MANY_SESS: return EIO; + case ERROR_SHARING_PAUSED: return EAGAIN; + case ERROR_REDIR_PAUSED: return EAGAIN; + case ERROR_FILE_EXISTS: return EEXIST; + case ERROR_CANNOT_MAKE: return ENOSPC; + case ERROR_OUT_OF_STRUCTURES: return ENFILE; + case ERROR_ALREADY_ASSIGNED: return EEXIST; + case ERROR_INVALID_PASSWORD: return EPERM; + case ERROR_NET_WRITE_FAULT: return EIO; + case ERROR_NO_PROC_SLOTS: return EAGAIN; + case ERROR_DISK_CHANGE: return EXDEV; + case ERROR_BROKEN_PIPE: return EPIPE; + case ERROR_OPEN_FAILED: return ENOENT; + case ERROR_DISK_FULL: return ENOSPC; + case ERROR_NO_MORE_SEARCH_HANDLES: return EMFILE; + case ERROR_INVALID_TARGET_HANDLE: return EBADF; + case ERROR_INVALID_NAME: return ENOENT; + case ERROR_PROC_NOT_FOUND: return ESRCH; + case ERROR_WAIT_NO_CHILDREN: return ECHILD; + case ERROR_CHILD_NOT_COMPLETE: return ECHILD; + case ERROR_DIRECT_ACCESS_HANDLE: return EBADF; + case ERROR_SEEK_ON_DEVICE: return ESPIPE; + case ERROR_BUSY_DRIVE: return EAGAIN; + case ERROR_DIR_NOT_EMPTY: return EEXIST; + case ERROR_NOT_LOCKED: return EACCES; + case ERROR_BAD_PATHNAME: return ENOENT; + case ERROR_LOCK_FAILED: return EACCES; + case ERROR_ALREADY_EXISTS: return EEXIST; + case ERROR_FILENAME_EXCED_RANGE: return ENAMETOOLONG; + case ERROR_BAD_PIPE: return EPIPE; + case ERROR_PIPE_BUSY: return EAGAIN; + case ERROR_PIPE_NOT_CONNECTED: return EPIPE; + case ERROR_DIRECTORY: return ENOTDIR; + } + return EINVAL; +} + +static int JimPipe(fdtype pipefd[2]) +{ + if (CreatePipe(&pipefd[0], &pipefd[1], NULL, 0)) { + return 0; + } + return -1; +} + +static fdtype JimDupFd(fdtype infd) +{ + fdtype dupfd; + pidtype pid = GetCurrentProcess(); + + if (DuplicateHandle(pid, infd, pid, &dupfd, 0, TRUE, DUPLICATE_SAME_ACCESS)) { + return dupfd; + } + return JIM_BAD_FD; +} + +static int JimRewindFd(fdtype fd) +{ + return SetFilePointer(fd, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER ? -1 : 0; +} + +#if 0 +static int JimReadFd(fdtype fd, char *buffer, size_t len) +{ + DWORD num; + + if (ReadFile(fd, buffer, len, &num, NULL)) { + return num; + } + if (GetLastError() == ERROR_HANDLE_EOF || GetLastError() == ERROR_BROKEN_PIPE) { + return 0; + } + return -1; +} +#endif + +static FILE *JimFdOpenForRead(fdtype fd) +{ + return _fdopen(_open_osfhandle((int)fd, _O_RDONLY | _O_TEXT), "r"); +} + +static fdtype JimFileno(FILE *fh) +{ + return (fdtype)_get_osfhandle(_fileno(fh)); +} + +static fdtype JimOpenForRead(const char *filename) +{ + return CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + JimStdSecAttrs(), OPEN_EXISTING, 0, NULL); +} + +static fdtype JimOpenForWrite(const char *filename, int append) +{ + return CreateFile(filename, append ? FILE_APPEND_DATA : GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, 0, (HANDLE) NULL); +} + +static FILE *JimFdOpenForWrite(fdtype fd) +{ + return _fdopen(_open_osfhandle((int)fd, _O_TEXT), "w"); +} + +static pidtype JimWaitPid(pidtype pid, int *status, int nohang) +{ + DWORD ret = WaitForSingleObject(pid, nohang ? 0 : INFINITE); + if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED) { + + return JIM_BAD_PID; + } + GetExitCodeProcess(pid, &ret); + *status = ret; + CloseHandle(pid); + return pid; +} + +static HANDLE JimCreateTemp(Jim_Interp *interp, const char *contents) +{ + char name[MAX_PATH]; + HANDLE handle; + + if (!GetTempPath(MAX_PATH, name) || !GetTempFileName(name, "JIM", 0, name)) { + return JIM_BAD_FD; + } + + handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, JimStdSecAttrs(), + CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, + NULL); + + if (handle == INVALID_HANDLE_VALUE) { + goto error; + } + + if (contents != NULL) { + + FILE *fh = JimFdOpenForWrite(JimDupFd(handle)); + if (fh == NULL) { + goto error; + } + + if (fwrite(contents, strlen(contents), 1, fh) != 1) { + fclose(fh); + goto error; + } + fseek(fh, 0, SEEK_SET); + fclose(fh); + } + return handle; + + error: + Jim_SetResultErrno(interp, "failed to create temp file"); + CloseHandle(handle); + DeleteFile(name); + return JIM_BAD_FD; +} + +static int +JimWinFindExecutable(const char *originalName, char fullPath[MAX_PATH]) +{ + int i; + static char extensions[][5] = {".exe", "", ".bat"}; + + for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) { + lstrcpyn(fullPath, originalName, MAX_PATH - 5); + lstrcat(fullPath, extensions[i]); + + if (SearchPath(NULL, fullPath, NULL, MAX_PATH, fullPath, NULL) == 0) { + continue; + } + if (GetFileAttributes(fullPath) & FILE_ATTRIBUTE_DIRECTORY) { + continue; + } + return 0; + } + + return -1; +} + +static char **JimSaveEnv(char **env) +{ + return env; +} + +static void JimRestoreEnv(char **env) +{ + JimFreeEnv(env, Jim_GetEnviron()); +} + +static Jim_Obj * +JimWinBuildCommandLine(Jim_Interp *interp, char **argv) +{ + char *start, *special; + int quote, i; + + Jim_Obj *strObj = Jim_NewStringObj(interp, "", 0); + + for (i = 0; argv[i]; i++) { + if (i > 0) { + Jim_AppendString(interp, strObj, " ", 1); + } + + if (argv[i][0] == '\0') { + quote = 1; + } + else { + quote = 0; + for (start = argv[i]; *start != '\0'; start++) { + if (isspace(UCHAR(*start))) { + quote = 1; + break; + } + } + } + if (quote) { + Jim_AppendString(interp, strObj, "\"" , 1); + } + + start = argv[i]; + for (special = argv[i]; ; ) { + if ((*special == '\\') && (special[1] == '\\' || + special[1] == '"' || (quote && special[1] == '\0'))) { + Jim_AppendString(interp, strObj, start, special - start); + start = special; + while (1) { + special++; + if (*special == '"' || (quote && *special == '\0')) { + + Jim_AppendString(interp, strObj, start, special - start); + break; + } + if (*special != '\\') { + break; + } + } + Jim_AppendString(interp, strObj, start, special - start); + start = special; + } + if (*special == '"') { + if (special == start) { + Jim_AppendString(interp, strObj, "\"", 1); + } + else { + Jim_AppendString(interp, strObj, start, special - start); + } + Jim_AppendString(interp, strObj, "\\\"", 2); + start = special + 1; + } + if (*special == '\0') { + break; + } + special++; + } + Jim_AppendString(interp, strObj, start, special - start); + if (quote) { + Jim_AppendString(interp, strObj, "\"", 1); + } + } + return strObj; +} + +static pidtype +JimStartWinProcess(Jim_Interp *interp, char **argv, char *env, fdtype inputId, fdtype outputId, fdtype errorId) +{ + STARTUPINFO startInfo; + PROCESS_INFORMATION procInfo; + HANDLE hProcess, h; + char execPath[MAX_PATH]; + char *originalName; + pidtype pid = JIM_BAD_PID; + Jim_Obj *cmdLineObj; + + if (JimWinFindExecutable(argv[0], execPath) < 0) { + return JIM_BAD_PID; + } + originalName = argv[0]; + argv[0] = execPath; + + hProcess = GetCurrentProcess(); + cmdLineObj = JimWinBuildCommandLine(interp, argv); + + + ZeroMemory(&startInfo, sizeof(startInfo)); + startInfo.cb = sizeof(startInfo); + startInfo.dwFlags = STARTF_USESTDHANDLES; + startInfo.hStdInput = INVALID_HANDLE_VALUE; + startInfo.hStdOutput= INVALID_HANDLE_VALUE; + startInfo.hStdError = INVALID_HANDLE_VALUE; + + if (inputId == JIM_BAD_FD) { + if (CreatePipe(&startInfo.hStdInput, &h, JimStdSecAttrs(), 0) != FALSE) { + CloseHandle(h); + } + } else { + DuplicateHandle(hProcess, inputId, hProcess, &startInfo.hStdInput, + 0, TRUE, DUPLICATE_SAME_ACCESS); + } + if (startInfo.hStdInput == JIM_BAD_FD) { + goto end; + } + + if (outputId == JIM_BAD_FD) { + startInfo.hStdOutput = CreateFile("NUL:", GENERIC_WRITE, 0, + JimStdSecAttrs(), OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + } else { + DuplicateHandle(hProcess, outputId, hProcess, &startInfo.hStdOutput, + 0, TRUE, DUPLICATE_SAME_ACCESS); + } + if (startInfo.hStdOutput == JIM_BAD_FD) { + goto end; + } + + if (errorId == JIM_BAD_FD) { + + startInfo.hStdError = CreateFile("NUL:", GENERIC_WRITE, 0, + JimStdSecAttrs(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + } else { + DuplicateHandle(hProcess, errorId, hProcess, &startInfo.hStdError, + 0, TRUE, DUPLICATE_SAME_ACCESS); + } + if (startInfo.hStdError == JIM_BAD_FD) { + goto end; + } + + if (!CreateProcess(NULL, (char *)Jim_String(cmdLineObj), NULL, NULL, TRUE, + 0, env, NULL, &startInfo, &procInfo)) { + goto end; + } + + + WaitForInputIdle(procInfo.hProcess, 5000); + CloseHandle(procInfo.hThread); + + pid = procInfo.hProcess; + + end: + Jim_FreeNewObj(interp, cmdLineObj); + if (startInfo.hStdInput != JIM_BAD_FD) { + CloseHandle(startInfo.hStdInput); + } + if (startInfo.hStdOutput != JIM_BAD_FD) { + CloseHandle(startInfo.hStdOutput); + } + if (startInfo.hStdError != JIM_BAD_FD) { + CloseHandle(startInfo.hStdError); + } + return pid; +} +#else + +static int JimOpenForWrite(const char *filename, int append) +{ + return open(filename, O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC), 0666); +} + +static int JimRewindFd(int fd) +{ + return lseek(fd, 0L, SEEK_SET); +} + +static int JimCreateTemp(Jim_Interp *interp, const char *contents) +{ + char inName[] = "/tmp/tcl.tmp.XXXXXX"; + + int fd = mkstemp(inName); + if (fd == JIM_BAD_FD) { + Jim_SetResultErrno(interp, "couldn't create temp file"); + return -1; + } + unlink(inName); + if (contents) { + int length = strlen(contents); + if (write(fd, contents, length) != length) { + Jim_SetResultErrno(interp, "couldn't write temp file"); + close(fd); + return -1; + } + lseek(fd, 0L, SEEK_SET); + } + return fd; +} + +static char **JimSaveEnv(char **env) +{ + char **saveenv = Jim_GetEnviron(); + Jim_SetEnviron(env); + return saveenv; +} + +static void JimRestoreEnv(char **env) +{ + JimFreeEnv(Jim_GetEnviron(), env); + Jim_SetEnviron(env); +} +#endif +#endif + + + +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 500 +#endif + +#include +#include +#include +#include + + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + + char buf[100]; + time_t t; + long seconds; + + const char *format = "%a %b %d %H:%M:%S %Z %Y"; + + if (argc == 2 || (argc == 3 && !Jim_CompareStringImmediate(interp, argv[1], "-format"))) { + return -1; + } + + if (argc == 3) { + format = Jim_String(argv[2]); + } + + if (Jim_GetLong(interp, argv[0], &seconds) != JIM_OK) { + return JIM_ERR; + } + t = seconds; + + strftime(buf, sizeof(buf), format, localtime(&t)); + + Jim_SetResultString(interp, buf, -1); + + return JIM_OK; +} + +#ifdef HAVE_STRPTIME +static int clock_cmd_scan(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + char *pt; + struct tm tm; + time_t now = time(0); + + if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) { + return -1; + } + + + localtime_r(&now, &tm); + + pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm); + if (pt == 0 || *pt != 0) { + Jim_SetResultString(interp, "Failed to parse time according to format", -1); + return JIM_ERR; + } + + + Jim_SetResultInt(interp, mktime(&tm)); + + return JIM_OK; +} +#endif + +static int clock_cmd_seconds(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_SetResultInt(interp, time(NULL)); + + return JIM_OK; +} + +static int clock_cmd_micros(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + Jim_SetResultInt(interp, (jim_wide) tv.tv_sec * 1000000 + tv.tv_usec); + + return JIM_OK; +} + +static int clock_cmd_millis(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + Jim_SetResultInt(interp, (jim_wide) tv.tv_sec * 1000 + tv.tv_usec / 1000); + + return JIM_OK; +} + +static const jim_subcmd_type clock_command_table[] = { + { "seconds", + NULL, + clock_cmd_seconds, + 0, + 0, + + }, + { "clicks", + NULL, + clock_cmd_micros, + 0, + 0, + + }, + { "microseconds", + NULL, + clock_cmd_micros, + 0, + 0, + + }, + { "milliseconds", + NULL, + clock_cmd_millis, + 0, + 0, + + }, + { "format", + "seconds ?-format format?", + clock_cmd_format, + 1, + 3, + + }, +#ifdef HAVE_STRPTIME + { "scan", + "str -format format", + clock_cmd_scan, + 3, + 3, + + }, +#endif + { NULL } +}; + +int Jim_clockInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "clock", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "clock", Jim_SubCmdProc, (void *)clock_command_table, NULL); + return JIM_OK; +} + + +#include +#include +#include +#include +#include + + +static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + + Jim_SetResultInt(interp, Jim_GetVariable(interp, argv[0], 0) != 0); + return JIM_OK; +} + +static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + + if (!objPtr) { + return JIM_OK; + } + + if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) { + + if (Jim_IsList(objPtr)) { + if (Jim_ListLength(interp, objPtr) % 2 != 0) { + + return JIM_ERR; + } + } + else if (Jim_DictSize(interp, objPtr) < 0) { + + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + + return Jim_DictValues(interp, objPtr, argv[1]); +} + +static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + + if (!objPtr) { + return JIM_OK; + } + + return Jim_DictKeys(interp, objPtr, argc == 1 ? NULL : argv[1]); +} + +static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + int len; + Jim_Obj *resultObj; + Jim_Obj *objPtr; + Jim_Obj **dictValuesObj; + + if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) { + + Jim_UnsetVariable(interp, argv[0], JIM_NONE); + return JIM_OK; + } + + objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + + if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) { + return JIM_ERR; + } + + + resultObj = Jim_NewDictObj(interp, NULL, 0); + + for (i = 0; i < len; i += 2) { + if (!Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) { + Jim_DictAddElement(interp, resultObj, dictValuesObj[i], dictValuesObj[i + 1]); + } + } + Jim_Free(dictValuesObj); + + Jim_SetVariable(interp, argv[0], resultObj); + return JIM_OK; +} + +static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + int len = 0; + + + objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + if (objPtr) { + len = Jim_DictSize(interp, objPtr); + if (len < 0) { + return JIM_ERR; + } + } + + Jim_SetResultInt(interp, len); + + return JIM_OK; +} + +static int array_cmd_set(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + int len; + Jim_Obj *listObj = argv[1]; + Jim_Obj *dictObj; + + len = Jim_ListLength(interp, listObj); + if (len % 2) { + Jim_SetResultString(interp, "list must have an even number of elements", -1); + return JIM_ERR; + } + + dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED); + if (!dictObj) { + + return Jim_SetVariable(interp, argv[0], listObj); + } + + if (Jim_IsShared(dictObj)) { + dictObj = Jim_DuplicateObj(interp, dictObj); + } + + for (i = 0; i < len; i += 2) { + Jim_Obj *nameObj; + Jim_Obj *valueObj; + + Jim_ListIndex(interp, listObj, i, &nameObj, JIM_NONE); + Jim_ListIndex(interp, listObj, i + 1, &valueObj, JIM_NONE); + + Jim_DictAddElement(interp, dictObj, nameObj, valueObj); + } + return Jim_SetVariable(interp, argv[0], dictObj); +} + +static const jim_subcmd_type array_command_table[] = { + { "exists", + "arrayName", + array_cmd_exists, + 1, + 1, + + }, + { "get", + "arrayName ?pattern?", + array_cmd_get, + 1, + 2, + + }, + { "names", + "arrayName ?pattern?", + array_cmd_names, + 1, + 2, + + }, + { "set", + "arrayName list", + array_cmd_set, + 2, + 2, + + }, + { "size", + "arrayName", + array_cmd_size, + 1, + 1, + + }, + { "unset", + "arrayName ?pattern?", + array_cmd_unset, + 1, + 2, + + }, + { NULL + } +}; + +int Jim_arrayInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "array", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "array", Jim_SubCmdProc, (void *)array_command_table, NULL); + return JIM_OK; +} +int Jim_InitStaticExtensions(Jim_Interp *interp) +{ +extern int Jim_bootstrapInit(Jim_Interp *); +extern int Jim_aioInit(Jim_Interp *); +extern int Jim_readdirInit(Jim_Interp *); +extern int Jim_globInit(Jim_Interp *); +extern int Jim_regexpInit(Jim_Interp *); +extern int Jim_fileInit(Jim_Interp *); +extern int Jim_execInit(Jim_Interp *); +extern int Jim_clockInit(Jim_Interp *); +extern int Jim_arrayInit(Jim_Interp *); +extern int Jim_stdlibInit(Jim_Interp *); +extern int Jim_tclcompatInit(Jim_Interp *); +Jim_bootstrapInit(interp); +Jim_aioInit(interp); +Jim_readdirInit(interp); +Jim_globInit(interp); +Jim_regexpInit(interp); +Jim_fileInit(interp); +Jim_execInit(interp); +Jim_clockInit(interp); +Jim_arrayInit(interp); +Jim_stdlibInit(interp); +Jim_tclcompatInit(interp); +return JIM_OK; +} + +#define JIM_OPTIMIZATION + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_BACKTRACE +#include +#endif +#ifdef HAVE_CRT_EXTERNS_H +#include +#endif + + +#include + + + + + +#ifndef TCL_LIBRARY +#define TCL_LIBRARY "." +#endif +#ifndef TCL_PLATFORM_OS +#define TCL_PLATFORM_OS "unknown" +#endif +#ifndef TCL_PLATFORM_PLATFORM +#define TCL_PLATFORM_PLATFORM "unknown" +#endif +#ifndef TCL_PLATFORM_PATH_SEPARATOR +#define TCL_PLATFORM_PATH_SEPARATOR ":" +#endif + + + + + + + +#ifdef JIM_MAINTAINER +#define JIM_DEBUG_COMMAND +#define JIM_DEBUG_PANIC +#endif + +const char *jim_tt_name(int type); + +#ifdef JIM_DEBUG_PANIC +static void JimPanicDump(int panic_condition, const char *fmt, ...); +#define JimPanic(X) JimPanicDump X +#else +#define JimPanic(X) +#endif + + +static char JimEmptyStringRep[] = ""; + +static void JimChangeCallFrameId(Jim_Interp *interp, Jim_CallFrame *cf); +static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int flags); +static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int listindex, Jim_Obj *newObjPtr, + int flags); +static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands); +static Jim_Obj *JimExpandDictSugar(Jim_Interp *interp, Jim_Obj *objPtr); +static void SetDictSubstFromAny(Jim_Interp *interp, Jim_Obj *objPtr); +static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype, + const char *prefix, const char *const *tablePtr, const char *name); +static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj *const *argv); +static int JimGetWideNoErr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr); +static int JimSign(jim_wide w); +static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr); +static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen); +static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len); + + + +#define JimWideValue(objPtr) (objPtr)->internalRep.wideValue + +#define JimObjTypeName(O) ((O)->typePtr ? (O)->typePtr->name : "none") + +static int utf8_tounicode_case(const char *s, int *uc, int upper) +{ + int l = utf8_tounicode(s, uc); + if (upper) { + *uc = utf8_upper(*uc); + } + return l; +} + + +#define JIM_CHARSET_SCAN 2 +#define JIM_CHARSET_GLOB 0 + +static const char *JimCharsetMatch(const char *pattern, int c, int flags) +{ + int not = 0; + int pchar; + int match = 0; + int nocase = 0; + + if (flags & JIM_NOCASE) { + nocase++; + c = utf8_upper(c); + } + + if (flags & JIM_CHARSET_SCAN) { + if (*pattern == '^') { + not++; + pattern++; + } + + + if (*pattern == ']') { + goto first; + } + } + + while (*pattern && *pattern != ']') { + + if (pattern[0] == '\\') { +first: + pattern += utf8_tounicode_case(pattern, &pchar, nocase); + } + else { + + int start; + int end; + + pattern += utf8_tounicode_case(pattern, &start, nocase); + if (pattern[0] == '-' && pattern[1]) { + + pattern += utf8_tounicode(pattern, &pchar); + pattern += utf8_tounicode_case(pattern, &end, nocase); + + + if ((c >= start && c <= end) || (c >= end && c <= start)) { + match = 1; + } + continue; + } + pchar = start; + } + + if (pchar == c) { + match = 1; + } + } + if (not) { + match = !match; + } + + return match ? pattern : NULL; +} + + + +static int JimGlobMatch(const char *pattern, const char *string, int nocase) +{ + int c; + int pchar; + while (*pattern) { + switch (pattern[0]) { + case '*': + while (pattern[1] == '*') { + pattern++; + } + pattern++; + if (!pattern[0]) { + return 1; + } + while (*string) { + + if (JimGlobMatch(pattern, string, nocase)) + return 1; + string += utf8_tounicode(string, &c); + } + return 0; + + case '?': + string += utf8_tounicode(string, &c); + break; + + case '[': { + string += utf8_tounicode(string, &c); + pattern = JimCharsetMatch(pattern + 1, c, nocase ? JIM_NOCASE : 0); + if (!pattern) { + return 0; + } + if (!*pattern) { + + continue; + } + break; + } + case '\\': + if (pattern[1]) { + pattern++; + } + + default: + string += utf8_tounicode_case(string, &c, nocase); + utf8_tounicode_case(pattern, &pchar, nocase); + if (pchar != c) { + return 0; + } + break; + } + pattern += utf8_tounicode_case(pattern, &pchar, nocase); + if (!*string) { + while (*pattern == '*') { + pattern++; + } + break; + } + } + if (!*pattern && !*string) { + return 1; + } + return 0; +} + +static int JimStringCompare(const char *s1, int l1, const char *s2, int l2) +{ + if (l1 < l2) { + return memcmp(s1, s2, l1) <= 0 ? -1 : 1; + } + else if (l2 < l1) { + return memcmp(s1, s2, l2) >= 0 ? 1 : -1; + } + else { + return JimSign(memcmp(s1, s2, l1)); + } +} + +static int JimStringCompareLen(const char *s1, const char *s2, int maxchars, int nocase) +{ + while (*s1 && *s2 && maxchars) { + int c1, c2; + s1 += utf8_tounicode_case(s1, &c1, nocase); + s2 += utf8_tounicode_case(s2, &c2, nocase); + if (c1 != c2) { + return JimSign(c1 - c2); + } + maxchars--; + } + if (!maxchars) { + return 0; + } + + if (*s1) { + return 1; + } + if (*s2) { + return -1; + } + return 0; +} + +static int JimStringFirst(const char *s1, int l1, const char *s2, int l2, int idx) +{ + int i; + int l1bytelen; + + if (!l1 || !l2 || l1 > l2) { + return -1; + } + if (idx < 0) + idx = 0; + s2 += utf8_index(s2, idx); + + l1bytelen = utf8_index(s1, l1); + + for (i = idx; i <= l2 - l1; i++) { + int c; + if (memcmp(s2, s1, l1bytelen) == 0) { + return i; + } + s2 += utf8_tounicode(s2, &c); + } + return -1; +} + +static int JimStringLast(const char *s1, int l1, const char *s2, int l2) +{ + const char *p; + + if (!l1 || !l2 || l1 > l2) + return -1; + + + for (p = s2 + l2 - 1; p != s2 - 1; p--) { + if (*p == *s1 && memcmp(s1, p, l1) == 0) { + return p - s2; + } + } + return -1; +} + +#ifdef JIM_UTF8 +static int JimStringLastUtf8(const char *s1, int l1, const char *s2, int l2) +{ + int n = JimStringLast(s1, utf8_index(s1, l1), s2, utf8_index(s2, l2)); + if (n > 0) { + n = utf8_strlen(s2, n); + } + return n; +} +#endif + +int Jim_WideToString(char *buf, jim_wide wideValue) +{ + const char *fmt = "%" JIM_WIDE_MODIFIER; + + return sprintf(buf, fmt, wideValue); +} + +static int JimCheckConversion(const char *str, const char *endptr) +{ + if (str[0] == '\0' || str == endptr) { + return JIM_ERR; + } + + if (endptr[0] != '\0') { + while (*endptr) { + if (!isspace(UCHAR(*endptr))) { + return JIM_ERR; + } + endptr++; + } + } + return JIM_OK; +} + +static int JimNumberBase(const char *str, int *base, int *sign) +{ + int i = 0; + + *base = 10; + + while (isspace(UCHAR(str[i]))) { + i++; + } + + if (str[i] == '-') { + *sign = -1; + i++; + } + else { + if (str[i] == '+') { + i++; + } + *sign = 1; + } + + if (str[i] != '0') { + + return 0; + } + + + switch (str[i + 1]) { + case 'x': case 'X': *base = 16; break; + case 'o': case 'O': *base = 8; break; + case 'b': case 'B': *base = 2; break; + default: return 0; + } + i += 2; + + if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) { + + return i; + } + + return 10; +} + +static long jim_strtol(const char *str, char **endptr) +{ + int sign; + int base; + int i = JimNumberBase(str, &base, &sign); + + if (base != 10) { + long value = strtol(str + i, endptr, base); + if (endptr == NULL || *endptr != str + i) { + return value * sign; + } + } + + + return strtol(str, endptr, 10); +} + + +static jim_wide jim_strtoull(const char *str, char **endptr) +{ +#ifdef HAVE_LONG_LONG + int sign; + int base; + int i = JimNumberBase(str, &base, &sign); + + if (base != 10) { + jim_wide value = strtoull(str + i, endptr, base); + if (endptr == NULL || *endptr != str + i) { + return value * sign; + } + } + + + return strtoull(str, endptr, 10); +#else + return (unsigned long)jim_strtol(str, endptr); +#endif +} + +int Jim_StringToWide(const char *str, jim_wide * widePtr, int base) +{ + char *endptr; + + if (base) { + *widePtr = strtoull(str, &endptr, base); + } + else { + *widePtr = jim_strtoull(str, &endptr); + } + + return JimCheckConversion(str, endptr); +} + +int Jim_DoubleToString(char *buf, double doubleValue) +{ + int len; + int i; + + len = sprintf(buf, "%.12g", doubleValue); + + + for (i = 0; i < len; i++) { + if (buf[i] == '.' || buf[i] == 'e') { +#if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX) + char *e = strchr(buf, 'e'); + if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') { + + e += 2; + memmove(e, e + 1, len - (e - buf)); + return len - 1; + } +#endif + return len; + } + + if (buf[i] == 'i' || buf[i] == 'I' || buf[i] == 'n' || buf[i] == 'N') { + buf[i] = toupper(UCHAR(buf[i])); + buf[i + 3] = 0; + return i + 3; + } + } + + buf[i++] = '.'; + buf[i++] = '0'; + buf[i] = '\0'; + + return i; +} + +int Jim_StringToDouble(const char *str, double *doublePtr) +{ + char *endptr; + + + errno = 0; + + *doublePtr = strtod(str, &endptr); + + return JimCheckConversion(str, endptr); +} + +static jim_wide JimPowWide(jim_wide b, jim_wide e) +{ + jim_wide i, res = 1; + + if ((b == 0 && e != 0) || (e < 0)) + return 0; + for (i = 0; i < e; i++) { + res *= b; + } + return res; +} + +#ifdef JIM_DEBUG_PANIC +void JimPanicDump(int condition, const char *fmt, ...) +{ + va_list ap; + + if (!condition) { + return; + } + + va_start(ap, fmt); + + fprintf(stderr, JIM_NL "JIM INTERPRETER PANIC: "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, JIM_NL JIM_NL); + va_end(ap); + +#ifdef HAVE_BACKTRACE + { + void *array[40]; + int size, i; + char **strings; + + size = backtrace(array, 40); + strings = backtrace_symbols(array, size); + for (i = 0; i < size; i++) + fprintf(stderr, "[backtrace] %s" JIM_NL, strings[i]); + fprintf(stderr, "[backtrace] Include the above lines and the output" JIM_NL); + fprintf(stderr, "[backtrace] of 'nm ' in the bug report." JIM_NL); + } +#endif + + exit(1); +} +#endif + + +void *Jim_Alloc(int size) +{ + return size ? malloc(size) : NULL; +} + +void Jim_Free(void *ptr) +{ + free(ptr); +} + +void *Jim_Realloc(void *ptr, int size) +{ + return realloc(ptr, size); +} + +char *Jim_StrDup(const char *s) +{ + return strdup(s); +} + +char *Jim_StrDupLen(const char *s, int l) +{ + char *copy = Jim_Alloc(l + 1); + + memcpy(copy, s, l + 1); + copy[l] = 0; + return copy; +} + + + +static jim_wide JimClock(void) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + return (jim_wide) tv.tv_sec * 1000000 + tv.tv_usec; +} + + + +static void JimExpandHashTableIfNeeded(Jim_HashTable *ht); +static unsigned int JimHashTableNextPower(unsigned int size); +static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace); + + + + +unsigned int Jim_IntHashFunction(unsigned int key) +{ + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; +} + +unsigned int Jim_GenHashFunction(const unsigned char *buf, int len) +{ + unsigned int h = 0; + + while (len--) + h += (h << 3) + *buf++; + return h; +} + + + +static void JimResetHashTable(Jim_HashTable *ht) +{ + ht->table = NULL; + ht->size = 0; + ht->sizemask = 0; + ht->used = 0; + ht->collisions = 0; +} + + +int Jim_InitHashTable(Jim_HashTable *ht, const Jim_HashTableType *type, void *privDataPtr) +{ + JimResetHashTable(ht); + ht->type = type; + ht->privdata = privDataPtr; + return JIM_OK; +} + +void Jim_ResizeHashTable(Jim_HashTable *ht) +{ + int minimal = ht->used; + + if (minimal < JIM_HT_INITIAL_SIZE) + minimal = JIM_HT_INITIAL_SIZE; + Jim_ExpandHashTable(ht, minimal); +} + + +void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size) +{ + Jim_HashTable n; + unsigned int realsize = JimHashTableNextPower(size), i; + + if (size <= ht->used) + return; + + Jim_InitHashTable(&n, ht->type, ht->privdata); + n.size = realsize; + n.sizemask = realsize - 1; + n.table = Jim_Alloc(realsize * sizeof(Jim_HashEntry *)); + + + memset(n.table, 0, realsize * sizeof(Jim_HashEntry *)); + + n.used = ht->used; + for (i = 0; ht->used > 0; i++) { + Jim_HashEntry *he, *nextHe; + + if (ht->table[i] == NULL) + continue; + + + he = ht->table[i]; + while (he) { + unsigned int h; + + nextHe = he->next; + + h = Jim_HashKey(ht, he->key) & n.sizemask; + he->next = n.table[h]; + n.table[h] = he; + ht->used--; + + he = nextHe; + } + } + assert(ht->used == 0); + Jim_Free(ht->table); + + + *ht = n; +} + + +int Jim_AddHashEntry(Jim_HashTable *ht, const void *key, void *val) +{ + Jim_HashEntry *entry; + + entry = JimInsertHashEntry(ht, key, 0); + if (entry == NULL) + return JIM_ERR; + + + Jim_SetHashKey(ht, entry, key); + Jim_SetHashVal(ht, entry, val); + return JIM_OK; +} + + +int Jim_ReplaceHashEntry(Jim_HashTable *ht, const void *key, void *val) +{ + int existed; + Jim_HashEntry *entry; + + entry = JimInsertHashEntry(ht, key, 1); + if (entry->key) { + + Jim_FreeEntryVal(ht, entry); + existed = 1; + } + else { + + Jim_SetHashKey(ht, entry, key); + existed = 0; + } + Jim_SetHashVal(ht, entry, val); + + return existed; +} + + +int Jim_DeleteHashEntry(Jim_HashTable *ht, const void *key) +{ + unsigned int h; + Jim_HashEntry *he, *prevHe; + + if (ht->used == 0) + return JIM_ERR; + h = Jim_HashKey(ht, key) & ht->sizemask; + he = ht->table[h]; + + prevHe = NULL; + while (he) { + if (Jim_CompareHashKeys(ht, key, he->key)) { + + if (prevHe) + prevHe->next = he->next; + else + ht->table[h] = he->next; + Jim_FreeEntryKey(ht, he); + Jim_FreeEntryVal(ht, he); + Jim_Free(he); + ht->used--; + return JIM_OK; + } + prevHe = he; + he = he->next; + } + return JIM_ERR; +} + + +int Jim_FreeHashTable(Jim_HashTable *ht) +{ + unsigned int i; + + + for (i = 0; ht->used > 0; i++) { + Jim_HashEntry *he, *nextHe; + + if ((he = ht->table[i]) == NULL) + continue; + while (he) { + nextHe = he->next; + Jim_FreeEntryKey(ht, he); + Jim_FreeEntryVal(ht, he); + Jim_Free(he); + ht->used--; + he = nextHe; + } + } + + Jim_Free(ht->table); + + JimResetHashTable(ht); + return JIM_OK; +} + +Jim_HashEntry *Jim_FindHashEntry(Jim_HashTable *ht, const void *key) +{ + Jim_HashEntry *he; + unsigned int h; + + if (ht->used == 0) + return NULL; + h = Jim_HashKey(ht, key) & ht->sizemask; + he = ht->table[h]; + while (he) { + if (Jim_CompareHashKeys(ht, key, he->key)) + return he; + he = he->next; + } + return NULL; +} + +Jim_HashTableIterator *Jim_GetHashTableIterator(Jim_HashTable *ht) +{ + Jim_HashTableIterator *iter = Jim_Alloc(sizeof(*iter)); + + iter->ht = ht; + iter->index = -1; + iter->entry = NULL; + iter->nextEntry = NULL; + return iter; +} + +Jim_HashEntry *Jim_NextHashEntry(Jim_HashTableIterator *iter) +{ + while (1) { + if (iter->entry == NULL) { + iter->index++; + if (iter->index >= (signed)iter->ht->size) + break; + iter->entry = iter->ht->table[iter->index]; + } + else { + iter->entry = iter->nextEntry; + } + if (iter->entry) { + iter->nextEntry = iter->entry->next; + return iter->entry; + } + } + return NULL; +} + + + + +static void JimExpandHashTableIfNeeded(Jim_HashTable *ht) +{ + if (ht->size == 0) + Jim_ExpandHashTable(ht, JIM_HT_INITIAL_SIZE); + if (ht->size == ht->used) + Jim_ExpandHashTable(ht, ht->size * 2); +} + + +static unsigned int JimHashTableNextPower(unsigned int size) +{ + unsigned int i = JIM_HT_INITIAL_SIZE; + + if (size >= 2147483648U) + return 2147483648U; + while (1) { + if (i >= size) + return i; + i *= 2; + } +} + +static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace) +{ + unsigned int h; + Jim_HashEntry *he; + + + JimExpandHashTableIfNeeded(ht); + + + h = Jim_HashKey(ht, key) & ht->sizemask; + + he = ht->table[h]; + while (he) { + if (Jim_CompareHashKeys(ht, key, he->key)) + return replace ? he : NULL; + he = he->next; + } + + + he = Jim_Alloc(sizeof(*he)); + he->next = ht->table[h]; + ht->table[h] = he; + ht->used++; + he->key = NULL; + + return he; +} + + + +static unsigned int JimStringCopyHTHashFunction(const void *key) +{ + return Jim_GenHashFunction(key, strlen(key)); +} + +static void *JimStringCopyHTDup(void *privdata, const void *key) +{ + return strdup(key); +} + +static int JimStringCopyHTKeyCompare(void *privdata, const void *key1, const void *key2) +{ + return strcmp(key1, key2) == 0; +} + +static void JimStringCopyHTKeyDestructor(void *privdata, void *key) +{ + Jim_Free(key); +} + +static const Jim_HashTableType JimPackageHashTableType = { + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + NULL +}; + +typedef struct AssocDataValue +{ + Jim_InterpDeleteProc *delProc; + void *data; +} AssocDataValue; + +static void JimAssocDataHashTableValueDestructor(void *privdata, void *data) +{ + AssocDataValue *assocPtr = (AssocDataValue *) data; + + if (assocPtr->delProc != NULL) + assocPtr->delProc((Jim_Interp *)privdata, assocPtr->data); + Jim_Free(data); +} + +static const Jim_HashTableType JimAssocDataHashTableType = { + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + JimAssocDataHashTableValueDestructor +}; + +void Jim_InitStack(Jim_Stack *stack) +{ + stack->len = 0; + stack->maxlen = 0; + stack->vector = NULL; +} + +void Jim_FreeStack(Jim_Stack *stack) +{ + Jim_Free(stack->vector); +} + +int Jim_StackLen(Jim_Stack *stack) +{ + return stack->len; +} + +void Jim_StackPush(Jim_Stack *stack, void *element) +{ + int neededLen = stack->len + 1; + + if (neededLen > stack->maxlen) { + stack->maxlen = neededLen < 20 ? 20 : neededLen * 2; + stack->vector = Jim_Realloc(stack->vector, sizeof(void *) * stack->maxlen); + } + stack->vector[stack->len] = element; + stack->len++; +} + +void *Jim_StackPop(Jim_Stack *stack) +{ + if (stack->len == 0) + return NULL; + stack->len--; + return stack->vector[stack->len]; +} + +void *Jim_StackPeek(Jim_Stack *stack) +{ + if (stack->len == 0) + return NULL; + return stack->vector[stack->len - 1]; +} + +void Jim_FreeStackElements(Jim_Stack *stack, void (*freeFunc) (void *ptr)) +{ + int i; + + for (i = 0; i < stack->len; i++) + freeFunc(stack->vector[i]); +} + + + +#define JIM_TT_NONE 0 +#define JIM_TT_STR 1 +#define JIM_TT_ESC 2 +#define JIM_TT_VAR 3 +#define JIM_TT_DICTSUGAR 4 +#define JIM_TT_CMD 5 + +#define JIM_TT_SEP 6 +#define JIM_TT_EOL 7 +#define JIM_TT_EOF 8 + +#define JIM_TT_LINE 9 +#define JIM_TT_WORD 10 + + +#define JIM_TT_SUBEXPR_START 11 +#define JIM_TT_SUBEXPR_END 12 +#define JIM_TT_SUBEXPR_COMMA 13 +#define JIM_TT_EXPR_INT 14 +#define JIM_TT_EXPR_DOUBLE 15 + +#define JIM_TT_EXPRSUGAR 16 + + +#define JIM_TT_EXPR_OP 20 + +#define TOKEN_IS_SEP(type) (type >= JIM_TT_SEP && type <= JIM_TT_EOF) + + +#define JIM_PS_DEF 0 +#define JIM_PS_QUOTE 1 +#define JIM_PS_DICTSUGAR 2 + +struct JimParserCtx +{ + const char *p; + int len; + int linenr; + const char *tstart; + const char *tend; + int tline; + int tt; + int eof; + int state; + int comment; + char missing; + int missingline; +}; + +struct JimParseResult { + char missing; + int line; +}; + +static int JimParseScript(struct JimParserCtx *pc); +static int JimParseSep(struct JimParserCtx *pc); +static int JimParseEol(struct JimParserCtx *pc); +static int JimParseCmd(struct JimParserCtx *pc); +static int JimParseQuote(struct JimParserCtx *pc); +static int JimParseVar(struct JimParserCtx *pc); +static int JimParseBrace(struct JimParserCtx *pc); +static int JimParseStr(struct JimParserCtx *pc); +static int JimParseComment(struct JimParserCtx *pc); +static void JimParseSubCmd(struct JimParserCtx *pc); +static int JimParseSubQuote(struct JimParserCtx *pc); +static void JimParseSubCmd(struct JimParserCtx *pc); +static Jim_Obj *JimParserGetTokenObj(Jim_Interp *interp, struct JimParserCtx *pc); + +static void JimParserInit(struct JimParserCtx *pc, const char *prg, int len, int linenr) +{ + pc->p = prg; + pc->len = len; + pc->tstart = NULL; + pc->tend = NULL; + pc->tline = 0; + pc->tt = JIM_TT_NONE; + pc->eof = 0; + pc->state = JIM_PS_DEF; + pc->linenr = linenr; + pc->comment = 1; + pc->missing = ' '; + pc->missingline = linenr; +} + +static int JimParseScript(struct JimParserCtx *pc) +{ + while (1) { + if (!pc->len) { + pc->tstart = pc->p; + pc->tend = pc->p - 1; + pc->tline = pc->linenr; + pc->tt = JIM_TT_EOL; + pc->eof = 1; + return JIM_OK; + } + switch (*(pc->p)) { + case '\\': + if (*(pc->p + 1) == '\n' && pc->state == JIM_PS_DEF) { + return JimParseSep(pc); + } + pc->comment = 0; + return JimParseStr(pc); + case ' ': + case '\t': + case '\r': + case '\f': + if (pc->state == JIM_PS_DEF) + return JimParseSep(pc); + pc->comment = 0; + return JimParseStr(pc); + case '\n': + case ';': + pc->comment = 1; + if (pc->state == JIM_PS_DEF) + return JimParseEol(pc); + return JimParseStr(pc); + case '[': + pc->comment = 0; + return JimParseCmd(pc); + case '$': + pc->comment = 0; + if (JimParseVar(pc) == JIM_ERR) { + + pc->tstart = pc->tend = pc->p++; + pc->len--; + pc->tt = JIM_TT_ESC; + } + return JIM_OK; + case '#': + if (pc->comment) { + JimParseComment(pc); + continue; + } + return JimParseStr(pc); + default: + pc->comment = 0; + return JimParseStr(pc); + } + return JIM_OK; + } +} + +static int JimParseSep(struct JimParserCtx *pc) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + while (isspace(UCHAR(*pc->p)) || (*pc->p == '\\' && *(pc->p + 1) == '\n')) { + if (*pc->p == '\n') { + break; + } + if (*pc->p == '\\') { + pc->p++; + pc->len--; + pc->linenr++; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_SEP; + return JIM_OK; +} + +static int JimParseEol(struct JimParserCtx *pc) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + while (isspace(UCHAR(*pc->p)) || *pc->p == ';') { + if (*pc->p == '\n') + pc->linenr++; + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_EOL; + return JIM_OK; +} + + +static void JimParseSubBrace(struct JimParserCtx *pc) +{ + int level = 1; + + + pc->p++; + pc->len--; + while (pc->len) { + switch (*pc->p) { + case '\\': + if (pc->len > 1) { + if (*++pc->p == '\n') { + pc->linenr++; + } + pc->len--; + } + break; + + case '{': + level++; + break; + + case '}': + if (--level == 0) { + pc->tend = pc->p - 1; + pc->p++; + pc->len--; + return; + } + break; + + case '\n': + pc->linenr++; + break; + } + pc->p++; + pc->len--; + } + pc->missing = '{'; + pc->missingline = pc->tline; + pc->tend = pc->p - 1; +} + +static int JimParseSubQuote(struct JimParserCtx *pc) +{ + int tt = JIM_TT_STR; + int line = pc->tline; + + + pc->p++; + pc->len--; + while (pc->len) { + switch (*pc->p) { + case '\\': + if (pc->len > 1) { + if (*++pc->p == '\n') { + pc->linenr++; + } + pc->len--; + tt = JIM_TT_ESC; + } + break; + + case '"': + pc->tend = pc->p - 1; + pc->p++; + pc->len--; + return tt; + + case '[': + JimParseSubCmd(pc); + tt = JIM_TT_ESC; + continue; + + case '\n': + pc->linenr++; + break; + + case '$': + tt = JIM_TT_ESC; + break; + } + pc->p++; + pc->len--; + } + pc->missing = '"'; + pc->missingline = line; + pc->tend = pc->p - 1; + return tt; +} + +static void JimParseSubCmd(struct JimParserCtx *pc) +{ + int level = 1; + int startofword = 1; + int line = pc->tline; + + + pc->p++; + pc->len--; + while (pc->len) { + switch (*pc->p) { + case '\\': + if (pc->len > 1) { + if (*++pc->p == '\n') { + pc->linenr++; + } + pc->len--; + } + break; + + case '[': + level++; + break; + + case ']': + if (--level == 0) { + pc->tend = pc->p - 1; + pc->p++; + pc->len--; + return; + } + break; + + case '"': + if (startofword) { + JimParseSubQuote(pc); + continue; + } + break; + + case '{': + JimParseSubBrace(pc); + startofword = 0; + continue; + + case '\n': + pc->linenr++; + break; + } + startofword = isspace(UCHAR(*pc->p)); + pc->p++; + pc->len--; + } + pc->missing = '['; + pc->missingline = line; + pc->tend = pc->p - 1; +} + +static int JimParseBrace(struct JimParserCtx *pc) +{ + pc->tstart = pc->p + 1; + pc->tline = pc->linenr; + pc->tt = JIM_TT_STR; + JimParseSubBrace(pc); + return JIM_OK; +} + +static int JimParseCmd(struct JimParserCtx *pc) +{ + pc->tstart = pc->p + 1; + pc->tline = pc->linenr; + pc->tt = JIM_TT_CMD; + JimParseSubCmd(pc); + return JIM_OK; +} + +static int JimParseQuote(struct JimParserCtx *pc) +{ + pc->tstart = pc->p + 1; + pc->tline = pc->linenr; + pc->tt = JimParseSubQuote(pc); + return JIM_OK; +} + +static int JimParseVar(struct JimParserCtx *pc) +{ + + pc->p++; + pc->len--; + +#ifdef EXPRSUGAR_BRACKET + if (*pc->p == '[') { + + JimParseCmd(pc); + pc->tt = JIM_TT_EXPRSUGAR; + return JIM_OK; + } +#endif + + pc->tstart = pc->p; + pc->tt = JIM_TT_VAR; + pc->tline = pc->linenr; + + if (*pc->p == '{') { + pc->tstart = ++pc->p; + pc->len--; + + while (pc->len && *pc->p != '}') { + if (*pc->p == '\n') { + pc->linenr++; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + if (pc->len) { + pc->p++; + pc->len--; + } + } + else { + while (1) { + + if (pc->p[0] == ':' && pc->p[1] == ':') { + while (*pc->p == ':') { + pc->p++; + pc->len--; + } + continue; + } + if (isalnum(UCHAR(*pc->p)) || *pc->p == '_' || UCHAR(*pc->p) >= 0x80) { + pc->p++; + pc->len--; + continue; + } + break; + } + + if (*pc->p == '(') { + int count = 1; + const char *paren = NULL; + + pc->tt = JIM_TT_DICTSUGAR; + + while (count && pc->len) { + pc->p++; + pc->len--; + if (*pc->p == '\\' && pc->len >= 1) { + pc->p++; + pc->len--; + } + else if (*pc->p == '(') { + count++; + } + else if (*pc->p == ')') { + paren = pc->p; + count--; + } + } + if (count == 0) { + pc->p++; + pc->len--; + } + else if (paren) { + + paren++; + pc->len += (pc->p - paren); + pc->p = paren; + } +#ifndef EXPRSUGAR_BRACKET + if (*pc->tstart == '(') { + pc->tt = JIM_TT_EXPRSUGAR; + } +#endif + } + pc->tend = pc->p - 1; + } + if (pc->tstart == pc->p) { + pc->p--; + pc->len++; + return JIM_ERR; + } + return JIM_OK; +} + +static int JimParseStr(struct JimParserCtx *pc) +{ + if (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL || + pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR) { + + if (*pc->p == '{') { + return JimParseBrace(pc); + } + if (*pc->p == '"') { + pc->state = JIM_PS_QUOTE; + pc->p++; + pc->len--; + + pc->missingline = pc->tline; + } + } + pc->tstart = pc->p; + pc->tline = pc->linenr; + while (1) { + if (pc->len == 0) { + if (pc->state == JIM_PS_QUOTE) { + pc->missing = '"'; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + } + switch (*pc->p) { + case '\\': + if (pc->state == JIM_PS_DEF && *(pc->p + 1) == '\n') { + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + } + if (pc->len >= 2) { + if (*(pc->p + 1) == '\n') { + pc->linenr++; + } + pc->p++; + pc->len--; + } + break; + case '(': + + if (pc->len > 1 && pc->p[1] != '$') { + break; + } + case ')': + + if (*pc->p == '(' || pc->tt == JIM_TT_VAR) { + if (pc->p == pc->tstart) { + + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + } + break; + + case '$': + case '[': + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + case ' ': + case '\t': + case '\n': + case '\r': + case '\f': + case ';': + if (pc->state == JIM_PS_DEF) { + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + } + else if (*pc->p == '\n') { + pc->linenr++; + } + break; + case '"': + if (pc->state == JIM_PS_QUOTE) { + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + pc->p++; + pc->len--; + pc->state = JIM_PS_DEF; + return JIM_OK; + } + break; + } + pc->p++; + pc->len--; + } + return JIM_OK; +} + +static int JimParseComment(struct JimParserCtx *pc) +{ + while (*pc->p) { + if (*pc->p == '\n') { + pc->linenr++; + if (*(pc->p - 1) != '\\') { + pc->p++; + pc->len--; + return JIM_OK; + } + } + pc->p++; + pc->len--; + } + return JIM_OK; +} + + +static int xdigitval(int c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int odigitval(int c) +{ + if (c >= '0' && c <= '7') + return c - '0'; + return -1; +} + +static int JimEscape(char *dest, const char *s, int slen) +{ + char *p = dest; + int i, len; + + if (slen == -1) + slen = strlen(s); + + for (i = 0; i < slen; i++) { + switch (s[i]) { + case '\\': + switch (s[i + 1]) { + case 'a': + *p++ = 0x7; + i++; + break; + case 'b': + *p++ = 0x8; + i++; + break; + case 'f': + *p++ = 0xc; + i++; + break; + case 'n': + *p++ = 0xa; + i++; + break; + case 'r': + *p++ = 0xd; + i++; + break; + case 't': + *p++ = 0x9; + i++; + break; + case 'u': + case 'U': + case 'x': + { + unsigned val = 0; + int k; + int maxchars = 2; + + i++; + + if (s[i] == 'U') { + maxchars = 8; + } + else if (s[i] == 'u') { + if (s[i + 1] == '{') { + maxchars = 6; + i++; + } + else { + maxchars = 4; + } + } + + for (k = 0; k < maxchars; k++) { + int c = xdigitval(s[i + k + 1]); + if (c == -1) { + break; + } + val = (val << 4) | c; + } + + if (s[i] == '{') { + if (k == 0 || val > 0x1fffff || s[i + k + 1] != '}') { + + i--; + k = 0; + } + else { + + k++; + } + } + if (k) { + + if (s[i] == 'x') { + *p++ = val; + } + else { + p += utf8_fromunicode(p, val); + } + i += k; + break; + } + + *p++ = s[i]; + } + break; + case 'v': + *p++ = 0xb; + i++; + break; + case '\0': + *p++ = '\\'; + i++; + break; + case '\n': + + *p++ = ' '; + do { + i++; + } while (s[i + 1] == ' ' || s[i + 1] == '\t'); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + + { + int val = 0; + int c = odigitval(s[i + 1]); + + val = c; + c = odigitval(s[i + 2]); + if (c == -1) { + *p++ = val; + i++; + break; + } + val = (val * 8) + c; + c = odigitval(s[i + 3]); + if (c == -1) { + *p++ = val; + i += 2; + break; + } + val = (val * 8) + c; + *p++ = val; + i += 3; + } + break; + default: + *p++ = s[i + 1]; + i++; + break; + } + break; + default: + *p++ = s[i]; + break; + } + } + len = p - dest; + *p = '\0'; + return len; +} + +static Jim_Obj *JimParserGetTokenObj(Jim_Interp *interp, struct JimParserCtx *pc) +{ + const char *start, *end; + char *token; + int len; + + start = pc->tstart; + end = pc->tend; + if (start > end) { + len = 0; + token = Jim_Alloc(1); + token[0] = '\0'; + } + else { + len = (end - start) + 1; + token = Jim_Alloc(len + 1); + if (pc->tt != JIM_TT_ESC) { + + memcpy(token, start, len); + token[len] = '\0'; + } + else { + + len = JimEscape(token, start, len); + } + } + + return Jim_NewStringObjNoAlloc(interp, token, len); +} + +int Jim_ScriptIsComplete(const char *s, int len, char *stateCharPtr) +{ + struct JimParserCtx parser; + + JimParserInit(&parser, s, len, 1); + while (!parser.eof) { + JimParseScript(&parser); + } + if (stateCharPtr) { + *stateCharPtr = parser.missing; + } + return parser.missing == ' '; +} + +static int JimParseListSep(struct JimParserCtx *pc); +static int JimParseListStr(struct JimParserCtx *pc); +static int JimParseListQuote(struct JimParserCtx *pc); + +static int JimParseList(struct JimParserCtx *pc) +{ + if (isspace(UCHAR(*pc->p))) { + return JimParseListSep(pc); + } + switch (*pc->p) { + case '"': + return JimParseListQuote(pc); + + case '{': + return JimParseBrace(pc); + + default: + if (pc->len) { + return JimParseListStr(pc); + } + break; + } + + pc->tstart = pc->tend = pc->p; + pc->tline = pc->linenr; + pc->tt = JIM_TT_EOL; + pc->eof = 1; + return JIM_OK; +} + +static int JimParseListSep(struct JimParserCtx *pc) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + while (isspace(UCHAR(*pc->p))) { + if (*pc->p == '\n') { + pc->linenr++; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_SEP; + return JIM_OK; +} + +static int JimParseListQuote(struct JimParserCtx *pc) +{ + pc->p++; + pc->len--; + + pc->tstart = pc->p; + pc->tline = pc->linenr; + pc->tt = JIM_TT_STR; + + while (pc->len) { + switch (*pc->p) { + case '\\': + pc->tt = JIM_TT_ESC; + if (--pc->len == 0) { + + pc->tend = pc->p; + return JIM_OK; + } + pc->p++; + break; + case '\n': + pc->linenr++; + break; + case '"': + pc->tend = pc->p - 1; + pc->p++; + pc->len--; + return JIM_OK; + } + pc->p++; + pc->len--; + } + + pc->tend = pc->p - 1; + return JIM_OK; +} + +static int JimParseListStr(struct JimParserCtx *pc) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + pc->tt = JIM_TT_STR; + + while (pc->len) { + if (isspace(UCHAR(*pc->p))) { + pc->tend = pc->p - 1; + return JIM_OK; + } + if (*pc->p == '\\') { + if (--pc->len == 0) { + + pc->tend = pc->p; + return JIM_OK; + } + pc->tt = JIM_TT_ESC; + pc->p++; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + return JIM_OK; +} + + + +Jim_Obj *Jim_NewObj(Jim_Interp *interp) +{ + Jim_Obj *objPtr; + + + if (interp->freeList != NULL) { + + objPtr = interp->freeList; + interp->freeList = objPtr->nextObjPtr; + } + else { + + objPtr = Jim_Alloc(sizeof(*objPtr)); + } + + objPtr->refCount = 0; + + + objPtr->prevObjPtr = NULL; + objPtr->nextObjPtr = interp->liveList; + if (interp->liveList) + interp->liveList->prevObjPtr = objPtr; + interp->liveList = objPtr; + + return objPtr; +} + +void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr) +{ + + JimPanic((objPtr->refCount != 0, "!!!Object %p freed with bad refcount %d, type=%s", objPtr, + objPtr->refCount, objPtr->typePtr ? objPtr->typePtr->name : "")); + + + Jim_FreeIntRep(interp, objPtr); + + if (objPtr->bytes != NULL) { + if (objPtr->bytes != JimEmptyStringRep) + Jim_Free(objPtr->bytes); + } + + if (objPtr->prevObjPtr) + objPtr->prevObjPtr->nextObjPtr = objPtr->nextObjPtr; + if (objPtr->nextObjPtr) + objPtr->nextObjPtr->prevObjPtr = objPtr->prevObjPtr; + if (interp->liveList == objPtr) + interp->liveList = objPtr->nextObjPtr; + + objPtr->prevObjPtr = NULL; + objPtr->nextObjPtr = interp->freeList; + if (interp->freeList) + interp->freeList->prevObjPtr = objPtr; + interp->freeList = objPtr; + objPtr->refCount = -1; +} + + +void Jim_InvalidateStringRep(Jim_Obj *objPtr) +{ + if (objPtr->bytes != NULL) { + if (objPtr->bytes != JimEmptyStringRep) + Jim_Free(objPtr->bytes); + } + objPtr->bytes = NULL; +} + + +Jim_Obj *Jim_DuplicateObj(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_Obj *dupPtr; + + dupPtr = Jim_NewObj(interp); + if (objPtr->bytes == NULL) { + + dupPtr->bytes = NULL; + } + else if (objPtr->length == 0) { + + dupPtr->bytes = JimEmptyStringRep; + dupPtr->length = 0; + dupPtr->typePtr = NULL; + return dupPtr; + } + else { + dupPtr->bytes = Jim_Alloc(objPtr->length + 1); + dupPtr->length = objPtr->length; + + memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1); + } + + + dupPtr->typePtr = objPtr->typePtr; + if (objPtr->typePtr != NULL) { + if (objPtr->typePtr->dupIntRepProc == NULL) { + dupPtr->internalRep = objPtr->internalRep; + } + else { + + objPtr->typePtr->dupIntRepProc(interp, objPtr, dupPtr); + } + } + return dupPtr; +} + +const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr) +{ + if (objPtr->bytes == NULL) { + + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); + objPtr->typePtr->updateStringProc(objPtr); + } + if (lenPtr) + *lenPtr = objPtr->length; + return objPtr->bytes; +} + + +int Jim_Length(Jim_Obj *objPtr) +{ + if (objPtr->bytes == NULL) { + + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); + objPtr->typePtr->updateStringProc(objPtr); + } + return objPtr->length; +} + + +const char *Jim_String(Jim_Obj *objPtr) +{ + if (objPtr->bytes == NULL) { + + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); + objPtr->typePtr->updateStringProc(objPtr); + } + return objPtr->bytes; +} + +static void FreeDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); + +static const Jim_ObjType dictSubstObjType = { + "dict-substitution", + FreeDictSubstInternalRep, + DupDictSubstInternalRep, + NULL, + JIM_TYPE_NONE, +}; + +static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr); +} + +static const Jim_ObjType interpolatedObjType = { + "interpolated", + FreeInterpolatedInternalRep, + NULL, + NULL, + JIM_TYPE_NONE, +}; + +static void DupStringInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static int SetStringFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType stringObjType = { + "string", + NULL, + DupStringInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + +static void DupStringInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + JIM_NOTUSED(interp); + + dupPtr->internalRep.strValue.maxLength = srcPtr->length; + + dupPtr->internalRep.strValue.charLength = srcPtr->internalRep.strValue.charLength; +} + +static int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr->typePtr != &stringObjType) { + + if (objPtr->bytes == NULL) { + + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); + objPtr->typePtr->updateStringProc(objPtr); + } + + Jim_FreeIntRep(interp, objPtr); + + objPtr->typePtr = &stringObjType; + objPtr->internalRep.strValue.maxLength = objPtr->length; + + objPtr->internalRep.strValue.charLength = -1; + } + return JIM_OK; +} + +int Jim_Utf8Length(Jim_Interp *interp, Jim_Obj *objPtr) +{ +#ifdef JIM_UTF8 + SetStringFromAny(interp, objPtr); + + if (objPtr->internalRep.strValue.charLength < 0) { + objPtr->internalRep.strValue.charLength = utf8_strlen(objPtr->bytes, objPtr->length); + } + return objPtr->internalRep.strValue.charLength; +#else + return Jim_Length(objPtr); +#endif +} + + +Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len) +{ + Jim_Obj *objPtr = Jim_NewObj(interp); + + + if (len == -1) + len = strlen(s); + + if (len == 0) { + objPtr->bytes = JimEmptyStringRep; + objPtr->length = 0; + } + else { + objPtr->bytes = Jim_Alloc(len + 1); + objPtr->length = len; + memcpy(objPtr->bytes, s, len); + objPtr->bytes[len] = '\0'; + } + + + objPtr->typePtr = NULL; + return objPtr; +} + + +Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, const char *s, int charlen) +{ +#ifdef JIM_UTF8 + + int bytelen = utf8_index(s, charlen); + + Jim_Obj *objPtr = Jim_NewStringObj(interp, s, bytelen); + + + objPtr->typePtr = &stringObjType; + objPtr->internalRep.strValue.maxLength = bytelen; + objPtr->internalRep.strValue.charLength = charlen; + + return objPtr; +#else + return Jim_NewStringObj(interp, s, charlen); +#endif +} + +Jim_Obj *Jim_NewStringObjNoAlloc(Jim_Interp *interp, char *s, int len) +{ + Jim_Obj *objPtr = Jim_NewObj(interp); + + objPtr->bytes = s; + objPtr->length = len == -1 ? strlen(s) : len; + objPtr->typePtr = NULL; + return objPtr; +} + +static void StringAppendString(Jim_Obj *objPtr, const char *str, int len) +{ + int needlen; + + if (len == -1) + len = strlen(str); + needlen = objPtr->length + len; + if (objPtr->internalRep.strValue.maxLength < needlen || + objPtr->internalRep.strValue.maxLength == 0) { + needlen *= 2; + + if (needlen < 7) { + needlen = 7; + } + if (objPtr->bytes == JimEmptyStringRep) { + objPtr->bytes = Jim_Alloc(needlen + 1); + } + else { + objPtr->bytes = Jim_Realloc(objPtr->bytes, needlen + 1); + } + objPtr->internalRep.strValue.maxLength = needlen; + } + memcpy(objPtr->bytes + objPtr->length, str, len); + objPtr->bytes[objPtr->length + len] = '\0'; + if (objPtr->internalRep.strValue.charLength >= 0) { + + objPtr->internalRep.strValue.charLength += utf8_strlen(objPtr->bytes + objPtr->length, len); + } + objPtr->length += len; +} + + +void Jim_AppendString(Jim_Interp *interp, Jim_Obj *objPtr, const char *str, int len) +{ + JimPanic((Jim_IsShared(objPtr), "Jim_AppendString called with shared object")); + SetStringFromAny(interp, objPtr); + StringAppendString(objPtr, str, len); +} + +void Jim_AppendObj(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *appendObjPtr) +{ + int len; + const char *str; + + str = Jim_GetString(appendObjPtr, &len); + Jim_AppendString(interp, objPtr, str, len); +} + +void Jim_AppendStrings(Jim_Interp *interp, Jim_Obj *objPtr, ...) +{ + va_list ap; + + SetStringFromAny(interp, objPtr); + va_start(ap, objPtr); + while (1) { + char *s = va_arg(ap, char *); + + if (s == NULL) + break; + Jim_AppendString(interp, objPtr, s, -1); + } + va_end(ap); +} + +int Jim_StringEqObj(Jim_Obj *aObjPtr, Jim_Obj *bObjPtr) +{ + const char *aStr, *bStr; + int aLen, bLen; + + if (aObjPtr == bObjPtr) + return 1; + aStr = Jim_GetString(aObjPtr, &aLen); + bStr = Jim_GetString(bObjPtr, &bLen); + if (aLen != bLen) + return 0; + return JimStringCompare(aStr, aLen, bStr, bLen) == 0; +} + +int Jim_StringMatchObj(Jim_Interp *interp, Jim_Obj *patternObjPtr, Jim_Obj *objPtr, int nocase) +{ + return JimGlobMatch(Jim_String(patternObjPtr), Jim_String(objPtr), nocase); +} + +int Jim_StringCompareObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *secondObjPtr, int nocase) +{ + int l1, l2; + const char *s1 = Jim_GetString(firstObjPtr, &l1); + const char *s2 = Jim_GetString(secondObjPtr, &l2); + + if (nocase) { + + return JimStringCompareLen(s1, s2, -1, nocase); + } + return JimStringCompare(s1, l1, s2, l2); +} + +int Jim_StringCompareLenObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *secondObjPtr, int nocase) +{ + const char *s1 = Jim_String(firstObjPtr); + const char *s2 = Jim_String(secondObjPtr); + + return JimStringCompareLen(s1, s2, Jim_Utf8Length(interp, firstObjPtr), nocase); +} + +static int JimRelToAbsIndex(int len, int idx) +{ + if (idx < 0) + return len + idx; + return idx; +} + +static void JimRelToAbsRange(int len, int *firstPtr, int *lastPtr, int *rangeLenPtr) +{ + int rangeLen; + + if (*firstPtr > *lastPtr) { + rangeLen = 0; + } + else { + rangeLen = *lastPtr - *firstPtr + 1; + if (rangeLen) { + if (*firstPtr < 0) { + rangeLen += *firstPtr; + *firstPtr = 0; + } + if (*lastPtr >= len) { + rangeLen -= (*lastPtr - (len - 1)); + *lastPtr = len - 1; + } + } + } + if (rangeLen < 0) + rangeLen = 0; + + *rangeLenPtr = rangeLen; +} + +static int JimStringGetRange(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr, + int len, int *first, int *last, int *range) +{ + if (Jim_GetIndex(interp, firstObjPtr, first) != JIM_OK) { + return JIM_ERR; + } + if (Jim_GetIndex(interp, lastObjPtr, last) != JIM_OK) { + return JIM_ERR; + } + *first = JimRelToAbsIndex(len, *first); + *last = JimRelToAbsIndex(len, *last); + JimRelToAbsRange(len, first, last, range); + return JIM_OK; +} + +Jim_Obj *Jim_StringByteRangeObj(Jim_Interp *interp, + Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr) +{ + int first, last; + const char *str; + int rangeLen; + int bytelen; + + str = Jim_GetString(strObjPtr, &bytelen); + + if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, bytelen, &first, &last, &rangeLen) != JIM_OK) { + return NULL; + } + + if (first == 0 && rangeLen == bytelen) { + return strObjPtr; + } + return Jim_NewStringObj(interp, str + first, rangeLen); +} + +Jim_Obj *Jim_StringRangeObj(Jim_Interp *interp, + Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr) +{ +#ifdef JIM_UTF8 + int first, last; + const char *str; + int len, rangeLen; + int bytelen; + + str = Jim_GetString(strObjPtr, &bytelen); + len = Jim_Utf8Length(interp, strObjPtr); + + if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, len, &first, &last, &rangeLen) != JIM_OK) { + return NULL; + } + + if (first == 0 && rangeLen == len) { + return strObjPtr; + } + if (len == bytelen) { + + return Jim_NewStringObj(interp, str + first, rangeLen); + } + return Jim_NewStringObjUtf8(interp, str + utf8_index(str, first), rangeLen); +#else + return Jim_StringByteRangeObj(interp, strObjPtr, firstObjPtr, lastObjPtr); +#endif +} + +Jim_Obj *JimStringReplaceObj(Jim_Interp *interp, + Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr, Jim_Obj *newStrObj) +{ + int first, last; + const char *str; + int len, rangeLen; + Jim_Obj *objPtr; + + len = Jim_Utf8Length(interp, strObjPtr); + + if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, len, &first, &last, &rangeLen) != JIM_OK) { + return NULL; + } + + if (last < first) { + return strObjPtr; + } + + str = Jim_String(strObjPtr); + + + objPtr = Jim_NewStringObjUtf8(interp, str, first); + + + if (newStrObj) { + Jim_AppendObj(interp, objPtr, newStrObj); + } + + + Jim_AppendString(interp, objPtr, str + utf8_index(str, last + 1), len - last - 1); + + return objPtr; +} + +static void JimStrCopyUpperLower(char *dest, const char *str, int uc) +{ + while (*str) { + int c; + str += utf8_tounicode(str, &c); + dest += utf8_fromunicode(dest, uc ? utf8_upper(c) : utf8_lower(c)); + } + *dest = 0; +} + +static Jim_Obj *JimStringToLower(Jim_Interp *interp, Jim_Obj *strObjPtr) +{ + char *buf; + int len; + const char *str; + + SetStringFromAny(interp, strObjPtr); + + str = Jim_GetString(strObjPtr, &len); + +#ifdef JIM_UTF8 + len *= 2; +#endif + buf = Jim_Alloc(len + 1); + JimStrCopyUpperLower(buf, str, 0); + return Jim_NewStringObjNoAlloc(interp, buf, -1); +} + +static Jim_Obj *JimStringToUpper(Jim_Interp *interp, Jim_Obj *strObjPtr) +{ + char *buf; + const char *str; + int len; + + if (strObjPtr->typePtr != &stringObjType) { + SetStringFromAny(interp, strObjPtr); + } + + str = Jim_GetString(strObjPtr, &len); + +#ifdef JIM_UTF8 + len *= 2; +#endif + buf = Jim_Alloc(len + 1); + JimStrCopyUpperLower(buf, str, 1); + return Jim_NewStringObjNoAlloc(interp, buf, -1); +} + +static Jim_Obj *JimStringToTitle(Jim_Interp *interp, Jim_Obj *strObjPtr) +{ + char *buf, *p; + int len; + int c; + const char *str; + + str = Jim_GetString(strObjPtr, &len); + if (len == 0) { + return strObjPtr; + } +#ifdef JIM_UTF8 + len *= 2; +#endif + buf = p = Jim_Alloc(len + 1); + + str += utf8_tounicode(str, &c); + p += utf8_fromunicode(p, utf8_title(c)); + + JimStrCopyUpperLower(p, str, 0); + + return Jim_NewStringObjNoAlloc(interp, buf, -1); +} + +static const char *utf8_memchr(const char *str, int len, int c) +{ +#ifdef JIM_UTF8 + while (len) { + int sc; + int n = utf8_tounicode(str, &sc); + if (sc == c) { + return str; + } + str += n; + len -= n; + } + return NULL; +#else + return memchr(str, c, len); +#endif +} + +static const char *JimFindTrimLeft(const char *str, int len, const char *trimchars, int trimlen) +{ + while (len) { + int c; + int n = utf8_tounicode(str, &c); + + if (utf8_memchr(trimchars, trimlen, c) == NULL) { + + break; + } + str += n; + len -= n; + } + return str; +} + +static const char *JimFindTrimRight(const char *str, int len, const char *trimchars, int trimlen) +{ + str += len; + + while (len) { + int c; + int n = utf8_prev_len(str, len); + + len -= n; + str -= n; + + n = utf8_tounicode(str, &c); + + if (utf8_memchr(trimchars, trimlen, c) == NULL) { + return str + n; + } + } + + return NULL; +} + +static const char default_trim_chars[] = " \t\n\r"; + +static int default_trim_chars_len = sizeof(default_trim_chars); + +static Jim_Obj *JimStringTrimLeft(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr) +{ + int len; + const char *str = Jim_GetString(strObjPtr, &len); + const char *trimchars = default_trim_chars; + int trimcharslen = default_trim_chars_len; + const char *newstr; + + if (trimcharsObjPtr) { + trimchars = Jim_GetString(trimcharsObjPtr, &trimcharslen); + } + + newstr = JimFindTrimLeft(str, len, trimchars, trimcharslen); + if (newstr == str) { + return strObjPtr; + } + + return Jim_NewStringObj(interp, newstr, len - (newstr - str)); +} + +static Jim_Obj *JimStringTrimRight(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr) +{ + int len; + const char *trimchars = default_trim_chars; + int trimcharslen = default_trim_chars_len; + const char *nontrim; + + if (trimcharsObjPtr) { + trimchars = Jim_GetString(trimcharsObjPtr, &trimcharslen); + } + + SetStringFromAny(interp, strObjPtr); + + len = Jim_Length(strObjPtr); + nontrim = JimFindTrimRight(strObjPtr->bytes, len, trimchars, trimcharslen); + + if (nontrim == NULL) { + + return Jim_NewEmptyStringObj(interp); + } + if (nontrim == strObjPtr->bytes + len) { + return strObjPtr; + } + + if (Jim_IsShared(strObjPtr)) { + strObjPtr = Jim_NewStringObj(interp, strObjPtr->bytes, (nontrim - strObjPtr->bytes)); + } + else { + + strObjPtr->bytes[nontrim - strObjPtr->bytes] = 0; + strObjPtr->length = (nontrim - strObjPtr->bytes); + } + + return strObjPtr; +} + +static Jim_Obj *JimStringTrim(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr) +{ + + Jim_Obj *objPtr = JimStringTrimLeft(interp, strObjPtr, trimcharsObjPtr); + + + strObjPtr = JimStringTrimRight(interp, objPtr, trimcharsObjPtr); + + if (objPtr != strObjPtr) { + + Jim_IncrRefCount(objPtr); + Jim_DecrRefCount(interp, objPtr); + } + + return strObjPtr; +} + + +static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass, int strict) +{ + static const char * const strclassnames[] = { + "integer", "alpha", "alnum", "ascii", "digit", + "double", "lower", "upper", "space", "xdigit", + "control", "print", "graph", "punct", + NULL + }; + enum { + STR_IS_INTEGER, STR_IS_ALPHA, STR_IS_ALNUM, STR_IS_ASCII, STR_IS_DIGIT, + STR_IS_DOUBLE, STR_IS_LOWER, STR_IS_UPPER, STR_IS_SPACE, STR_IS_XDIGIT, + STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT + }; + int strclass; + int len; + int i; + const char *str; + int (*isclassfunc)(int c) = NULL; + + if (Jim_GetEnum(interp, strClass, strclassnames, &strclass, "class", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + + str = Jim_GetString(strObjPtr, &len); + if (len == 0) { + Jim_SetResultInt(interp, !strict); + return JIM_OK; + } + + switch (strclass) { + case STR_IS_INTEGER: + { + jim_wide w; + Jim_SetResultInt(interp, JimGetWideNoErr(interp, strObjPtr, &w) == JIM_OK); + return JIM_OK; + } + + case STR_IS_DOUBLE: + { + double d; + Jim_SetResultInt(interp, Jim_GetDouble(interp, strObjPtr, &d) == JIM_OK && errno != ERANGE); + return JIM_OK; + } + + case STR_IS_ALPHA: isclassfunc = isalpha; break; + case STR_IS_ALNUM: isclassfunc = isalnum; break; + case STR_IS_ASCII: isclassfunc = isascii; break; + case STR_IS_DIGIT: isclassfunc = isdigit; break; + case STR_IS_LOWER: isclassfunc = islower; break; + case STR_IS_UPPER: isclassfunc = isupper; break; + case STR_IS_SPACE: isclassfunc = isspace; break; + case STR_IS_XDIGIT: isclassfunc = isxdigit; break; + case STR_IS_CONTROL: isclassfunc = iscntrl; break; + case STR_IS_PRINT: isclassfunc = isprint; break; + case STR_IS_GRAPH: isclassfunc = isgraph; break; + case STR_IS_PUNCT: isclassfunc = ispunct; break; + default: + return JIM_ERR; + } + + for (i = 0; i < len; i++) { + if (!isclassfunc(str[i])) { + Jim_SetResultInt(interp, 0); + return JIM_OK; + } + } + Jim_SetResultInt(interp, 1); + return JIM_OK; +} + + + +static const Jim_ObjType comparedStringObjType = { + "compared-string", + NULL, + NULL, + NULL, + JIM_TYPE_REFERENCES, +}; + +int Jim_CompareStringImmediate(Jim_Interp *interp, Jim_Obj *objPtr, const char *str) +{ + if (objPtr->typePtr == &comparedStringObjType && objPtr->internalRep.ptr == str) + return 1; + else { + const char *objStr = Jim_String(objPtr); + + if (strcmp(str, objStr) != 0) + return 0; + if (objPtr->typePtr != &comparedStringObjType) { + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &comparedStringObjType; + } + objPtr->internalRep.ptr = (char *)str; + return 1; + } +} + +static int qsortCompareStringPointers(const void *a, const void *b) +{ + char *const *sa = (char *const *)a; + char *const *sb = (char *const *)b; + + return strcmp(*sa, *sb); +} + + + +static void FreeSourceInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupSourceInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); + +static const Jim_ObjType sourceObjType = { + "source", + FreeSourceInternalRep, + DupSourceInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + +void FreeSourceInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.sourceValue.fileNameObj); +} + +void DupSourceInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + dupPtr->internalRep.sourceValue = srcPtr->internalRep.sourceValue; + Jim_IncrRefCount(dupPtr->internalRep.sourceValue.fileNameObj); +} + +static void JimSetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *fileNameObj, int lineNumber) +{ + JimPanic((Jim_IsShared(objPtr), "JimSetSourceInfo called with shared object")); + JimPanic((objPtr->typePtr == &sourceObjType, "JimSetSourceInfo called with non-source object")); + Jim_IncrRefCount(fileNameObj); + objPtr->internalRep.sourceValue.fileNameObj = fileNameObj; + objPtr->internalRep.sourceValue.lineNumber = lineNumber; + objPtr->typePtr = &sourceObjType; +} + + +static const Jim_ObjType scriptLineObjType = { + "scriptline", + NULL, + NULL, + NULL, + 0, +}; + +static Jim_Obj *JimNewScriptLineObj(Jim_Interp *interp, int argc, int line) +{ + Jim_Obj *objPtr; + +#ifdef DEBUG_SHOW_SCRIPT + char buf[100]; + snprintf(buf, sizeof(buf), "line=%d, argc=%d", line, argc); + objPtr = Jim_NewStringObj(interp, buf, -1); +#else + objPtr = Jim_NewEmptyStringObj(interp); +#endif + objPtr->typePtr = &scriptLineObjType; + objPtr->internalRep.scriptLineValue.argc = argc; + objPtr->internalRep.scriptLineValue.line = line; + + return objPtr; +} + +#define JIM_CMDSTRUCT_EXPAND -1 + +static void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static int SetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, struct JimParseResult *result); + +static const Jim_ObjType scriptObjType = { + "script", + FreeScriptInternalRep, + DupScriptInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + +typedef struct ScriptToken +{ + int type; + Jim_Obj *objPtr; +} ScriptToken; + +typedef struct ScriptObj +{ + int len; + ScriptToken *token; + int substFlags; + int inUse; /* Used to share a ScriptObj. Currently + only used by Jim_EvalObj() as protection against + shimmering of the currently evaluated object. */ + Jim_Obj *fileNameObj; + int firstline; + int linenr; +} ScriptObj; + +void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + int i; + struct ScriptObj *script = (void *)objPtr->internalRep.ptr; + + script->inUse--; + if (script->inUse != 0) + return; + for (i = 0; i < script->len; i++) { + Jim_DecrRefCount(interp, script->token[i].objPtr); + } + Jim_Free(script->token); + Jim_DecrRefCount(interp, script->fileNameObj); + Jim_Free(script); +} + +void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + JIM_NOTUSED(interp); + JIM_NOTUSED(srcPtr); + + + dupPtr->typePtr = NULL; +} + +typedef struct +{ + const char *token; + int len; + int type; + int line; +} ParseToken; + +typedef struct +{ + + ParseToken *list; + int size; + int count; + ParseToken static_list[20]; +} ParseTokenList; + +static void ScriptTokenListInit(ParseTokenList *tokenlist) +{ + tokenlist->list = tokenlist->static_list; + tokenlist->size = sizeof(tokenlist->static_list) / sizeof(ParseToken); + tokenlist->count = 0; +} + +static void ScriptTokenListFree(ParseTokenList *tokenlist) +{ + if (tokenlist->list != tokenlist->static_list) { + Jim_Free(tokenlist->list); + } +} + +static void ScriptAddToken(ParseTokenList *tokenlist, const char *token, int len, int type, + int line) +{ + ParseToken *t; + + if (tokenlist->count == tokenlist->size) { + + tokenlist->size *= 2; + if (tokenlist->list != tokenlist->static_list) { + tokenlist->list = + Jim_Realloc(tokenlist->list, tokenlist->size * sizeof(*tokenlist->list)); + } + else { + + tokenlist->list = Jim_Alloc(tokenlist->size * sizeof(*tokenlist->list)); + memcpy(tokenlist->list, tokenlist->static_list, + tokenlist->count * sizeof(*tokenlist->list)); + } + } + t = &tokenlist->list[tokenlist->count++]; + t->token = token; + t->len = len; + t->type = type; + t->line = line; +} + +static int JimCountWordTokens(ParseToken *t) +{ + int expand = 1; + int count = 0; + + + if (t->type == JIM_TT_STR && !TOKEN_IS_SEP(t[1].type)) { + if ((t->len == 1 && *t->token == '*') || (t->len == 6 && strncmp(t->token, "expand", 6) == 0)) { + + expand = -1; + t++; + } + } + + + while (!TOKEN_IS_SEP(t->type)) { + t++; + count++; + } + + return count * expand; +} + +static Jim_Obj *JimMakeScriptObj(Jim_Interp *interp, const ParseToken *t) +{ + Jim_Obj *objPtr; + + if (t->type == JIM_TT_ESC && memchr(t->token, '\\', t->len) != NULL) { + + int len = t->len; + char *str = Jim_Alloc(len + 1); + len = JimEscape(str, t->token, len); + objPtr = Jim_NewStringObjNoAlloc(interp, str, len); + } + else { + objPtr = Jim_NewStringObj(interp, t->token, t->len); + } + return objPtr; +} + +static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, + ParseTokenList *tokenlist) +{ + int i; + struct ScriptToken *token; + + int lineargs = 0; + + ScriptToken *linefirst; + int count; + int linenr; + +#ifdef DEBUG_SHOW_SCRIPT_TOKENS + printf("==== Tokens ====\n"); + for (i = 0; i < tokenlist->count; i++) { + printf("[%2d]@%d %s '%.*s'\n", i, tokenlist->list[i].line, jim_tt_name(tokenlist->list[i].type), + tokenlist->list[i].len, tokenlist->list[i].token); + } +#endif + + + count = tokenlist->count; + for (i = 0; i < tokenlist->count; i++) { + if (tokenlist->list[i].type == JIM_TT_EOL) { + count++; + } + } + linenr = script->firstline = tokenlist->list[0].line; + + token = script->token = Jim_Alloc(sizeof(ScriptToken) * count); + + + linefirst = token++; + + for (i = 0; i < tokenlist->count; ) { + + int wordtokens; + + + while (tokenlist->list[i].type == JIM_TT_SEP) { + i++; + } + + wordtokens = JimCountWordTokens(tokenlist->list + i); + + if (wordtokens == 0) { + + if (lineargs) { + linefirst->type = JIM_TT_LINE; + linefirst->objPtr = JimNewScriptLineObj(interp, lineargs, linenr); + Jim_IncrRefCount(linefirst->objPtr); + + + lineargs = 0; + linefirst = token++; + } + i++; + continue; + } + else if (wordtokens != 1) { + + token->type = JIM_TT_WORD; + token->objPtr = Jim_NewIntObj(interp, wordtokens); + Jim_IncrRefCount(token->objPtr); + token++; + if (wordtokens < 0) { + + i++; + wordtokens = -wordtokens - 1; + lineargs--; + } + } + + if (lineargs == 0) { + + linenr = tokenlist->list[i].line; + } + lineargs++; + + + while (wordtokens--) { + const ParseToken *t = &tokenlist->list[i++]; + + token->type = t->type; + token->objPtr = JimMakeScriptObj(interp, t); + Jim_IncrRefCount(token->objPtr); + + JimSetSourceInfo(interp, token->objPtr, script->fileNameObj, t->line); + token++; + } + } + + if (lineargs == 0) { + token--; + } + + script->len = token - script->token; + + assert(script->len < count); + +#ifdef DEBUG_SHOW_SCRIPT + printf("==== Script (%s) ====\n", Jim_String(script->fileNameObj)); + for (i = 0; i < script->len; i++) { + const ScriptToken *t = &script->token[i]; + printf("[%2d] %s %s\n", i, jim_tt_name(t->type), Jim_String(t->objPtr)); + } +#endif + +} + +static void SubstObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, + ParseTokenList *tokenlist) +{ + int i; + struct ScriptToken *token; + + token = script->token = Jim_Alloc(sizeof(ScriptToken) * tokenlist->count); + + for (i = 0; i < tokenlist->count; i++) { + const ParseToken *t = &tokenlist->list[i]; + + + token->type = t->type; + token->objPtr = JimMakeScriptObj(interp, t); + Jim_IncrRefCount(token->objPtr); + token++; + } + + script->len = i; +} + +static int SetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, struct JimParseResult *result) +{ + int scriptTextLen; + const char *scriptText = Jim_GetString(objPtr, &scriptTextLen); + struct JimParserCtx parser; + struct ScriptObj *script; + ParseTokenList tokenlist; + int line = 1; + + + if (objPtr->typePtr == &sourceObjType) { + line = objPtr->internalRep.sourceValue.lineNumber; + } + + + ScriptTokenListInit(&tokenlist); + + JimParserInit(&parser, scriptText, scriptTextLen, line); + while (!parser.eof) { + JimParseScript(&parser); + ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, + parser.tline); + } + if (result && parser.missing != ' ') { + ScriptTokenListFree(&tokenlist); + result->missing = parser.missing; + result->line = parser.missingline; + return JIM_ERR; + } + + + ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0); + + + script = Jim_Alloc(sizeof(*script)); + memset(script, 0, sizeof(*script)); + script->inUse = 1; + if (objPtr->typePtr == &sourceObjType) { + script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; + } + else { + script->fileNameObj = interp->emptyObj; + } + Jim_IncrRefCount(script->fileNameObj); + + ScriptObjAddTokens(interp, script, &tokenlist); + + + ScriptTokenListFree(&tokenlist); + + + Jim_FreeIntRep(interp, objPtr); + Jim_SetIntRepPtr(objPtr, script); + objPtr->typePtr = &scriptObjType; + + return JIM_OK; +} + +ScriptObj *Jim_GetScript(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr == interp->emptyObj) { + + objPtr = interp->nullScriptObj; + } + + if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) { + SetScriptFromAny(interp, objPtr, NULL); + } + return (ScriptObj *) Jim_GetIntRepPtr(objPtr); +} + +static void JimIncrCmdRefCount(Jim_Cmd *cmdPtr) +{ + cmdPtr->inUse++; +} + +static void JimDecrCmdRefCount(Jim_Interp *interp, Jim_Cmd *cmdPtr) +{ + if (--cmdPtr->inUse == 0) { + if (cmdPtr->isproc) { + Jim_DecrRefCount(interp, cmdPtr->u.proc.argListObjPtr); + Jim_DecrRefCount(interp, cmdPtr->u.proc.bodyObjPtr); + Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj); + if (cmdPtr->u.proc.staticVars) { + Jim_FreeHashTable(cmdPtr->u.proc.staticVars); + Jim_Free(cmdPtr->u.proc.staticVars); + } + } + else { + + if (cmdPtr->u.native.delProc) { + cmdPtr->u.native.delProc(interp, cmdPtr->u.native.privData); + } + } + if (cmdPtr->prevCmd) { + + JimDecrCmdRefCount(interp, cmdPtr->prevCmd); + } + Jim_Free(cmdPtr); + } +} + + +static void JimVariablesHTValDestructor(void *interp, void *val) +{ + Jim_DecrRefCount(interp, ((Jim_Var *)val)->objPtr); + Jim_Free(val); +} + +static const Jim_HashTableType JimVariablesHashTableType = { + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + JimVariablesHTValDestructor +}; + +static void JimCommandsHT_ValDestructor(void *interp, void *val) +{ + JimDecrCmdRefCount(interp, val); +} + +static const Jim_HashTableType JimCommandsHashTableType = { + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + JimCommandsHT_ValDestructor +}; + + + +#ifdef jim_ext_namespace +static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj) +{ + const char *name = Jim_String(nsObj); + if (name[0] == ':' && name[1] == ':') { + + while (*++name == ':') { + } + nsObj = Jim_NewStringObj(interp, name, -1); + } + else if (Jim_Length(interp->framePtr->nsObj)) { + + nsObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj); + Jim_AppendStrings(interp, nsObj, "::", name, NULL); + } + return nsObj; +} + +static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj **objPtrPtr) +{ + Jim_Obj *objPtr = interp->emptyObj; + + if (name[0] == ':' && name[1] == ':') { + + while (*++name == ':') { + } + } + else if (Jim_Length(interp->framePtr->nsObj)) { + + objPtr = Jim_DuplicateObj(interp, interp->framePtr->nsObj); + Jim_AppendStrings(interp, objPtr, "::", name, NULL); + name = Jim_String(objPtr); + } + Jim_IncrRefCount(objPtr); + *objPtrPtr = objPtr; + return name; +} + + #define JimFreeQualifiedName(INTERP, OBJ) Jim_DecrRefCount((INTERP), (OBJ)) + +#else + + #define JimQualifyName(INTERP, NAME, DUMMY) (((NAME)[0] == ':' && (NAME)[1] == ':') ? (NAME) + 2 : (NAME)) + #define JimFreeQualifiedName(INTERP, DUMMY) (void)(DUMMY) +#endif + +static int JimCreateCommand(Jim_Interp *interp, const char *name, Jim_Cmd *cmd) +{ + Jim_HashEntry *he = Jim_FindHashEntry(&interp->commands, name); + if (he) { + + Jim_InterpIncrProcEpoch(interp); + } + + if (he && interp->local) { + + cmd->prevCmd = he->u.val; + he->u.val = cmd; + } + else { + if (he) { + + Jim_DeleteHashEntry(&interp->commands, name); + } + + Jim_AddHashEntry(&interp->commands, name, cmd); + } + return JIM_OK; +} + + +int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr, + Jim_CmdProc cmdProc, void *privData, Jim_DelCmdProc delProc) +{ + Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr)); + + + memset(cmdPtr, 0, sizeof(*cmdPtr)); + cmdPtr->inUse = 1; + cmdPtr->u.native.delProc = delProc; + cmdPtr->u.native.cmdProc = cmdProc; + cmdPtr->u.native.privData = privData; + + JimCreateCommand(interp, cmdNameStr, cmdPtr); + + return JIM_OK; +} + +static int JimCreateProcedureStatics(Jim_Interp *interp, Jim_Cmd *cmdPtr, Jim_Obj *staticsListObjPtr) +{ + int len, i; + + len = Jim_ListLength(interp, staticsListObjPtr); + if (len == 0) { + return JIM_OK; + } + + cmdPtr->u.proc.staticVars = Jim_Alloc(sizeof(Jim_HashTable)); + Jim_InitHashTable(cmdPtr->u.proc.staticVars, &JimVariablesHashTableType, interp); + for (i = 0; i < len; i++) { + Jim_Obj *objPtr = NULL, *initObjPtr = NULL, *nameObjPtr = NULL; + Jim_Var *varPtr; + int subLen; + + Jim_ListIndex(interp, staticsListObjPtr, i, &objPtr, JIM_NONE); + + subLen = Jim_ListLength(interp, objPtr); + if (subLen == 1 || subLen == 2) { + Jim_ListIndex(interp, objPtr, 0, &nameObjPtr, JIM_NONE); + if (subLen == 1) { + initObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_NONE); + if (initObjPtr == NULL) { + Jim_SetResultFormatted(interp, + "variable for initialization of static \"%#s\" not found in the local context", + nameObjPtr); + return JIM_ERR; + } + } + else { + Jim_ListIndex(interp, objPtr, 1, &initObjPtr, JIM_NONE); + } + if (JimValidName(interp, "static variable", nameObjPtr) != JIM_OK) { + return JIM_ERR; + } + + varPtr = Jim_Alloc(sizeof(*varPtr)); + varPtr->objPtr = initObjPtr; + Jim_IncrRefCount(initObjPtr); + varPtr->linkFramePtr = NULL; + if (Jim_AddHashEntry(cmdPtr->u.proc.staticVars, + Jim_String(nameObjPtr), varPtr) != JIM_OK) { + Jim_SetResultFormatted(interp, + "static variable name \"%#s\" duplicated in statics list", nameObjPtr); + Jim_DecrRefCount(interp, initObjPtr); + Jim_Free(varPtr); + return JIM_ERR; + } + } + else { + Jim_SetResultFormatted(interp, "too many fields in static specifier \"%#s\"", + objPtr); + return JIM_ERR; + } + } + return JIM_OK; +} + +static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const char *cmdname) +{ +#ifdef jim_ext_namespace + if (cmdPtr->isproc) { + + const char *pt = strrchr(cmdname, ':'); + if (pt && pt != cmdname && pt[-1] == ':') { + Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj); + cmdPtr->u.proc.nsObj = Jim_NewStringObj(interp, cmdname, pt - cmdname - 1); + Jim_IncrRefCount(cmdPtr->u.proc.nsObj); + + if (Jim_FindHashEntry(&interp->commands, pt + 1)) { + + Jim_InterpIncrProcEpoch(interp); + } + } + } +#endif +} + +static Jim_Cmd *JimCreateProcedureCmd(Jim_Interp *interp, Jim_Obj *argListObjPtr, + Jim_Obj *staticsListObjPtr, Jim_Obj *bodyObjPtr, Jim_Obj *nsObj) +{ + Jim_Cmd *cmdPtr; + int argListLen; + int i; + + argListLen = Jim_ListLength(interp, argListObjPtr); + + + cmdPtr = Jim_Alloc(sizeof(*cmdPtr) + sizeof(struct Jim_ProcArg) * argListLen); + memset(cmdPtr, 0, sizeof(*cmdPtr)); + cmdPtr->inUse = 1; + cmdPtr->isproc = 1; + cmdPtr->u.proc.argListObjPtr = argListObjPtr; + cmdPtr->u.proc.argListLen = argListLen; + cmdPtr->u.proc.bodyObjPtr = bodyObjPtr; + cmdPtr->u.proc.argsPos = -1; + cmdPtr->u.proc.arglist = (struct Jim_ProcArg *)(cmdPtr + 1); + cmdPtr->u.proc.nsObj = nsObj ? nsObj : interp->emptyObj; + Jim_IncrRefCount(argListObjPtr); + Jim_IncrRefCount(bodyObjPtr); + Jim_IncrRefCount(cmdPtr->u.proc.nsObj); + + + if (staticsListObjPtr && JimCreateProcedureStatics(interp, cmdPtr, staticsListObjPtr) != JIM_OK) { + goto err; + } + + + + for (i = 0; i < argListLen; i++) { + Jim_Obj *argPtr; + Jim_Obj *nameObjPtr; + Jim_Obj *defaultObjPtr; + int len; + + + Jim_ListIndex(interp, argListObjPtr, i, &argPtr, JIM_NONE); + len = Jim_ListLength(interp, argPtr); + if (len == 0) { + Jim_SetResultString(interp, "argument with no name", -1); +err: + JimDecrCmdRefCount(interp, cmdPtr); + return NULL; + } + if (len > 2) { + Jim_SetResultFormatted(interp, "too many fields in argument specifier \"%#s\"", argPtr); + goto err; + } + + if (len == 2) { + + Jim_ListIndex(interp, argPtr, 0, &nameObjPtr, JIM_NONE); + Jim_ListIndex(interp, argPtr, 1, &defaultObjPtr, JIM_NONE); + } + else { + + nameObjPtr = argPtr; + defaultObjPtr = NULL; + } + + + if (Jim_CompareStringImmediate(interp, nameObjPtr, "args")) { + if (cmdPtr->u.proc.argsPos >= 0) { + Jim_SetResultString(interp, "'args' specified more than once", -1); + goto err; + } + cmdPtr->u.proc.argsPos = i; + } + else { + if (len == 2) { + cmdPtr->u.proc.optArity++; + } + else { + cmdPtr->u.proc.reqArity++; + } + } + + cmdPtr->u.proc.arglist[i].nameObjPtr = nameObjPtr; + cmdPtr->u.proc.arglist[i].defaultObjPtr = defaultObjPtr; + } + + return cmdPtr; +} + +int Jim_DeleteCommand(Jim_Interp *interp, const char *name) +{ + int ret = JIM_OK; + Jim_Obj *qualifiedNameObj; + const char *qualname = JimQualifyName(interp, name, &qualifiedNameObj); + + if (Jim_DeleteHashEntry(&interp->commands, qualname) == JIM_ERR) { + Jim_SetResultFormatted(interp, "can't delete \"%s\": command doesn't exist", name); + ret = JIM_ERR; + } + else { + Jim_InterpIncrProcEpoch(interp); + } + + JimFreeQualifiedName(interp, qualifiedNameObj); + + return ret; +} + +int Jim_RenameCommand(Jim_Interp *interp, const char *oldName, const char *newName) +{ + int ret = JIM_ERR; + Jim_HashEntry *he; + Jim_Cmd *cmdPtr; + Jim_Obj *qualifiedOldNameObj; + Jim_Obj *qualifiedNewNameObj; + const char *fqold; + const char *fqnew; + + if (newName[0] == 0) { + return Jim_DeleteCommand(interp, oldName); + } + + fqold = JimQualifyName(interp, oldName, &qualifiedOldNameObj); + fqnew = JimQualifyName(interp, newName, &qualifiedNewNameObj); + + + he = Jim_FindHashEntry(&interp->commands, fqold); + if (he == NULL) { + Jim_SetResultFormatted(interp, "can't rename \"%s\": command doesn't exist", oldName); + } + else if (Jim_FindHashEntry(&interp->commands, fqnew)) { + Jim_SetResultFormatted(interp, "can't rename to \"%s\": command already exists", newName); + } + else { + + cmdPtr = he->u.val; + JimIncrCmdRefCount(cmdPtr); + JimUpdateProcNamespace(interp, cmdPtr, fqnew); + Jim_AddHashEntry(&interp->commands, fqnew, cmdPtr); + + + Jim_DeleteHashEntry(&interp->commands, fqold); + + + Jim_InterpIncrProcEpoch(interp); + + ret = JIM_OK; + } + + JimFreeQualifiedName(interp, qualifiedOldNameObj); + JimFreeQualifiedName(interp, qualifiedNewNameObj); + + return ret; +} + + +static void FreeCommandInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.cmdValue.nsObj); +} + +static void DupCommandInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + dupPtr->internalRep.cmdValue = srcPtr->internalRep.cmdValue; + dupPtr->typePtr = srcPtr->typePtr; + Jim_IncrRefCount(dupPtr->internalRep.cmdValue.nsObj); +} + +static const Jim_ObjType commandObjType = { + "command", + FreeCommandInternalRep, + DupCommandInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + +Jim_Cmd *Jim_GetCommand(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + Jim_Cmd *cmd; + + if (objPtr->typePtr != &commandObjType || + objPtr->internalRep.cmdValue.procEpoch != interp->procEpoch +#ifdef jim_ext_namespace + || !Jim_StringEqObj(objPtr->internalRep.cmdValue.nsObj, interp->framePtr->nsObj) +#endif + ) { + + + + const char *name = Jim_String(objPtr); + Jim_HashEntry *he; + + if (name[0] == ':' && name[1] == ':') { + while (*++name == ':') { + } + } +#ifdef jim_ext_namespace + else if (Jim_Length(interp->framePtr->nsObj)) { + + Jim_Obj *nameObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj); + Jim_AppendStrings(interp, nameObj, "::", name, NULL); + he = Jim_FindHashEntry(&interp->commands, Jim_String(nameObj)); + Jim_FreeNewObj(interp, nameObj); + if (he) { + goto found; + } + } +#endif + + + he = Jim_FindHashEntry(&interp->commands, name); + if (he == NULL) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr); + } + return NULL; + } +#ifdef jim_ext_namespace +found: +#endif + cmd = (Jim_Cmd *)he->u.val; + + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &commandObjType; + objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch; + objPtr->internalRep.cmdValue.cmdPtr = cmd; + objPtr->internalRep.cmdValue.nsObj = interp->framePtr->nsObj; + Jim_IncrRefCount(interp->framePtr->nsObj); + } + else { + cmd = objPtr->internalRep.cmdValue.cmdPtr; + } + while (cmd->u.proc.upcall) { + cmd = cmd->prevCmd; + } + return cmd; +} + + + +#define JIM_DICT_SUGAR 100 + +static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType variableObjType = { + "variable", + NULL, + NULL, + NULL, + JIM_TYPE_REFERENCES, +}; + +static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr) +{ + + if (nameObjPtr->typePtr != &variableObjType) { + int len; + const char *str = Jim_GetString(nameObjPtr, &len); + if (memchr(str, '\0', len)) { + Jim_SetResultFormatted(interp, "%s name contains embedded null", type); + return JIM_ERR; + } + } + return JIM_OK; +} + +static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + const char *varName; + Jim_CallFrame *framePtr; + Jim_HashEntry *he; + int global; + int len; + + + if (objPtr->typePtr == &variableObjType) { + framePtr = objPtr->internalRep.varValue.global ? interp->topFramePtr : interp->framePtr; + if (objPtr->internalRep.varValue.callFrameId == framePtr->id) { + + return JIM_OK; + } + + } + else if (objPtr->typePtr == &dictSubstObjType) { + return JIM_DICT_SUGAR; + } + else if (JimValidName(interp, "variable", objPtr) != JIM_OK) { + return JIM_ERR; + } + + + varName = Jim_GetString(objPtr, &len); + + + if (len && varName[len - 1] == ')' && strchr(varName, '(') != NULL) { + return JIM_DICT_SUGAR; + } + + if (varName[0] == ':' && varName[1] == ':') { + while (*++varName == ':') { + } + global = 1; + framePtr = interp->topFramePtr; + } + else { + global = 0; + framePtr = interp->framePtr; + } + + + he = Jim_FindHashEntry(&framePtr->vars, varName); + if (he == NULL) { + if (!global && framePtr->staticVars) { + + he = Jim_FindHashEntry(framePtr->staticVars, varName); + } + if (he == NULL) { + return JIM_ERR; + } + } + + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &variableObjType; + objPtr->internalRep.varValue.callFrameId = framePtr->id; + objPtr->internalRep.varValue.varPtr = he->u.val; + objPtr->internalRep.varValue.global = global; + return JIM_OK; +} + + +static int JimDictSugarSet(Jim_Interp *interp, Jim_Obj *ObjPtr, Jim_Obj *valObjPtr); +static Jim_Obj *JimDictSugarGet(Jim_Interp *interp, Jim_Obj *ObjPtr, int flags); + +static Jim_Var *JimCreateVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr) +{ + const char *name; + Jim_CallFrame *framePtr; + int global; + + + Jim_Var *var = Jim_Alloc(sizeof(*var)); + + var->objPtr = valObjPtr; + Jim_IncrRefCount(valObjPtr); + var->linkFramePtr = NULL; + + name = Jim_String(nameObjPtr); + if (name[0] == ':' && name[1] == ':') { + while (*++name == ':') { + } + framePtr = interp->topFramePtr; + global = 1; + } + else { + framePtr = interp->framePtr; + global = 0; + } + + + Jim_AddHashEntry(&framePtr->vars, name, var); + + + Jim_FreeIntRep(interp, nameObjPtr); + nameObjPtr->typePtr = &variableObjType; + nameObjPtr->internalRep.varValue.callFrameId = framePtr->id; + nameObjPtr->internalRep.varValue.varPtr = var; + nameObjPtr->internalRep.varValue.global = global; + + return var; +} + + +int Jim_SetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr) +{ + int err; + Jim_Var *var; + + switch (SetVariableFromAny(interp, nameObjPtr)) { + case JIM_DICT_SUGAR: + return JimDictSugarSet(interp, nameObjPtr, valObjPtr); + + case JIM_ERR: + if (JimValidName(interp, "variable", nameObjPtr) != JIM_OK) { + return JIM_ERR; + } + JimCreateVariable(interp, nameObjPtr, valObjPtr); + break; + + case JIM_OK: + var = nameObjPtr->internalRep.varValue.varPtr; + if (var->linkFramePtr == NULL) { + Jim_IncrRefCount(valObjPtr); + Jim_DecrRefCount(interp, var->objPtr); + var->objPtr = valObjPtr; + } + else { + Jim_CallFrame *savedCallFrame; + + savedCallFrame = interp->framePtr; + interp->framePtr = var->linkFramePtr; + err = Jim_SetVariable(interp, var->objPtr, valObjPtr); + interp->framePtr = savedCallFrame; + if (err != JIM_OK) + return err; + } + } + return JIM_OK; +} + +int Jim_SetVariableStr(Jim_Interp *interp, const char *name, Jim_Obj *objPtr) +{ + Jim_Obj *nameObjPtr; + int result; + + nameObjPtr = Jim_NewStringObj(interp, name, -1); + Jim_IncrRefCount(nameObjPtr); + result = Jim_SetVariable(interp, nameObjPtr, objPtr); + Jim_DecrRefCount(interp, nameObjPtr); + return result; +} + +int Jim_SetGlobalVariableStr(Jim_Interp *interp, const char *name, Jim_Obj *objPtr) +{ + Jim_CallFrame *savedFramePtr; + int result; + + savedFramePtr = interp->framePtr; + interp->framePtr = interp->topFramePtr; + result = Jim_SetVariableStr(interp, name, objPtr); + interp->framePtr = savedFramePtr; + return result; +} + +int Jim_SetVariableStrWithStr(Jim_Interp *interp, const char *name, const char *val) +{ + Jim_Obj *nameObjPtr, *valObjPtr; + int result; + + nameObjPtr = Jim_NewStringObj(interp, name, -1); + valObjPtr = Jim_NewStringObj(interp, val, -1); + Jim_IncrRefCount(nameObjPtr); + Jim_IncrRefCount(valObjPtr); + result = Jim_SetVariable(interp, nameObjPtr, valObjPtr); + Jim_DecrRefCount(interp, nameObjPtr); + Jim_DecrRefCount(interp, valObjPtr); + return result; +} + +int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr, + Jim_Obj *targetNameObjPtr, Jim_CallFrame *targetCallFrame) +{ + const char *varName; + const char *targetName; + Jim_CallFrame *framePtr; + Jim_Var *varPtr; + + + switch (SetVariableFromAny(interp, nameObjPtr)) { + case JIM_DICT_SUGAR: + + Jim_SetResultFormatted(interp, "bad variable name \"%#s\": upvar won't create a scalar variable that looks like an array element", nameObjPtr); + return JIM_ERR; + + case JIM_OK: + varPtr = nameObjPtr->internalRep.varValue.varPtr; + + if (varPtr->linkFramePtr == NULL) { + Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr); + return JIM_ERR; + } + + + varPtr->linkFramePtr = NULL; + break; + } + + + + varName = Jim_String(nameObjPtr); + + if (varName[0] == ':' && varName[1] == ':') { + while (*++varName == ':') { + } + + framePtr = interp->topFramePtr; + } + else { + framePtr = interp->framePtr; + } + + targetName = Jim_String(targetNameObjPtr); + if (targetName[0] == ':' && targetName[1] == ':') { + while (*++targetName == ':') { + } + targetNameObjPtr = Jim_NewStringObj(interp, targetName, -1); + targetCallFrame = interp->topFramePtr; + } + Jim_IncrRefCount(targetNameObjPtr); + + if (framePtr->level < targetCallFrame->level) { + Jim_SetResultFormatted(interp, + "bad variable name \"%#s\": upvar won't create namespace variable that refers to procedure variable", + nameObjPtr); + Jim_DecrRefCount(interp, targetNameObjPtr); + return JIM_ERR; + } + + + if (framePtr == targetCallFrame) { + Jim_Obj *objPtr = targetNameObjPtr; + + + while (1) { + if (strcmp(Jim_String(objPtr), varName) == 0) { + Jim_SetResultString(interp, "can't upvar from variable to itself", -1); + Jim_DecrRefCount(interp, targetNameObjPtr); + return JIM_ERR; + } + if (SetVariableFromAny(interp, objPtr) != JIM_OK) + break; + varPtr = objPtr->internalRep.varValue.varPtr; + if (varPtr->linkFramePtr != targetCallFrame) + break; + objPtr = varPtr->objPtr; + } + } + + + Jim_SetVariable(interp, nameObjPtr, targetNameObjPtr); + + nameObjPtr->internalRep.varValue.varPtr->linkFramePtr = targetCallFrame; + Jim_DecrRefCount(interp, targetNameObjPtr); + return JIM_OK; +} + +Jim_Obj *Jim_GetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) +{ + switch (SetVariableFromAny(interp, nameObjPtr)) { + case JIM_OK:{ + Jim_Var *varPtr = nameObjPtr->internalRep.varValue.varPtr; + + if (varPtr->linkFramePtr == NULL) { + return varPtr->objPtr; + } + else { + Jim_Obj *objPtr; + + + Jim_CallFrame *savedCallFrame = interp->framePtr; + + interp->framePtr = varPtr->linkFramePtr; + objPtr = Jim_GetVariable(interp, varPtr->objPtr, flags); + interp->framePtr = savedCallFrame; + if (objPtr) { + return objPtr; + } + + } + } + break; + + case JIM_DICT_SUGAR: + + return JimDictSugarGet(interp, nameObjPtr, flags); + } + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "can't read \"%#s\": no such variable", nameObjPtr); + } + return NULL; +} + +Jim_Obj *Jim_GetGlobalVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) +{ + Jim_CallFrame *savedFramePtr; + Jim_Obj *objPtr; + + savedFramePtr = interp->framePtr; + interp->framePtr = interp->topFramePtr; + objPtr = Jim_GetVariable(interp, nameObjPtr, flags); + interp->framePtr = savedFramePtr; + + return objPtr; +} + +Jim_Obj *Jim_GetVariableStr(Jim_Interp *interp, const char *name, int flags) +{ + Jim_Obj *nameObjPtr, *varObjPtr; + + nameObjPtr = Jim_NewStringObj(interp, name, -1); + Jim_IncrRefCount(nameObjPtr); + varObjPtr = Jim_GetVariable(interp, nameObjPtr, flags); + Jim_DecrRefCount(interp, nameObjPtr); + return varObjPtr; +} + +Jim_Obj *Jim_GetGlobalVariableStr(Jim_Interp *interp, const char *name, int flags) +{ + Jim_CallFrame *savedFramePtr; + Jim_Obj *objPtr; + + savedFramePtr = interp->framePtr; + interp->framePtr = interp->topFramePtr; + objPtr = Jim_GetVariableStr(interp, name, flags); + interp->framePtr = savedFramePtr; + + return objPtr; +} + +int Jim_UnsetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) +{ + Jim_Var *varPtr; + int retval; + Jim_CallFrame *framePtr; + + retval = SetVariableFromAny(interp, nameObjPtr); + if (retval == JIM_DICT_SUGAR) { + + return JimDictSugarSet(interp, nameObjPtr, NULL); + } + else if (retval == JIM_OK) { + varPtr = nameObjPtr->internalRep.varValue.varPtr; + + + if (varPtr->linkFramePtr) { + framePtr = interp->framePtr; + interp->framePtr = varPtr->linkFramePtr; + retval = Jim_UnsetVariable(interp, varPtr->objPtr, JIM_NONE); + interp->framePtr = framePtr; + } + else { + const char *name = Jim_String(nameObjPtr); + if (nameObjPtr->internalRep.varValue.global) { + name += 2; + framePtr = interp->topFramePtr; + } + else { + framePtr = interp->framePtr; + } + + retval = Jim_DeleteHashEntry(&framePtr->vars, name); + if (retval == JIM_OK) { + + JimChangeCallFrameId(interp, framePtr); + } + } + } + if (retval != JIM_OK && (flags & JIM_ERRMSG)) { + Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such variable", nameObjPtr); + } + return retval; +} + + + +static void JimDictSugarParseVarKey(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj **varPtrPtr, Jim_Obj **keyPtrPtr) +{ + const char *str, *p; + int len, keyLen; + Jim_Obj *varObjPtr, *keyObjPtr; + + str = Jim_GetString(objPtr, &len); + + p = strchr(str, '('); + JimPanic((p == NULL, "JimDictSugarParseVarKey() called for non-dict-sugar (%s)", str)); + + varObjPtr = Jim_NewStringObj(interp, str, p - str); + + p++; + keyLen = (str + len) - p; + if (str[len - 1] == ')') { + keyLen--; + } + + + keyObjPtr = Jim_NewStringObj(interp, p, keyLen); + + Jim_IncrRefCount(varObjPtr); + Jim_IncrRefCount(keyObjPtr); + *varPtrPtr = varObjPtr; + *keyPtrPtr = keyObjPtr; +} + +static int JimDictSugarSet(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *valObjPtr) +{ + int err; + + SetDictSubstFromAny(interp, objPtr); + + err = Jim_SetDictKeysVector(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, + &objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_MUSTEXIST); + + if (err == JIM_OK) { + + Jim_SetEmptyResult(interp); + } + else { + if (!valObjPtr) { + + if (Jim_GetVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, JIM_NONE)) { + Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such element in array", + objPtr); + return err; + } + } + + Jim_SetResultFormatted(interp, "can't %s \"%#s\": variable isn't array", + (valObjPtr ? "set" : "unset"), objPtr); + } + return err; +} + +static Jim_Obj *JimDictExpandArrayVariable(Jim_Interp *interp, Jim_Obj *varObjPtr, + Jim_Obj *keyObjPtr, int flags) +{ + Jim_Obj *dictObjPtr; + Jim_Obj *resObjPtr = NULL; + int ret; + + dictObjPtr = Jim_GetVariable(interp, varObjPtr, JIM_ERRMSG); + if (!dictObjPtr) { + return NULL; + } + + ret = Jim_DictKey(interp, dictObjPtr, keyObjPtr, &resObjPtr, JIM_NONE); + if (ret != JIM_OK) { + resObjPtr = NULL; + if (ret < 0) { + Jim_SetResultFormatted(interp, + "can't read \"%#s(%#s)\": variable isn't array", varObjPtr, keyObjPtr); + } + else { + Jim_SetResultFormatted(interp, + "can't read \"%#s(%#s)\": no such element in array", varObjPtr, keyObjPtr); + } + } + else if ((flags & JIM_UNSHARED) && Jim_IsShared(dictObjPtr)) { + dictObjPtr = Jim_DuplicateObj(interp, dictObjPtr); + if (Jim_SetVariable(interp, varObjPtr, dictObjPtr) != JIM_OK) { + + JimPanic((1, "SetVariable failed for JIM_UNSHARED")); + } + + Jim_DictKey(interp, dictObjPtr, keyObjPtr, &resObjPtr, JIM_NONE); + } + + return resObjPtr; +} + + +static Jim_Obj *JimDictSugarGet(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + SetDictSubstFromAny(interp, objPtr); + + return JimDictExpandArrayVariable(interp, + objPtr->internalRep.dictSubstValue.varNameObjPtr, + objPtr->internalRep.dictSubstValue.indexObjPtr, flags); +} + + + +void FreeDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr); + Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr); +} + +void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + JIM_NOTUSED(interp); + + dupPtr->internalRep.dictSubstValue.varNameObjPtr = + srcPtr->internalRep.dictSubstValue.varNameObjPtr; + dupPtr->internalRep.dictSubstValue.indexObjPtr = srcPtr->internalRep.dictSubstValue.indexObjPtr; + dupPtr->typePtr = &dictSubstObjType; +} + + +static void SetDictSubstFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr->typePtr != &dictSubstObjType) { + Jim_Obj *varObjPtr, *keyObjPtr; + + if (objPtr->typePtr == &interpolatedObjType) { + + + varObjPtr = objPtr->internalRep.dictSubstValue.varNameObjPtr; + keyObjPtr = objPtr->internalRep.dictSubstValue.indexObjPtr; + + Jim_IncrRefCount(varObjPtr); + Jim_IncrRefCount(keyObjPtr); + } + else { + JimDictSugarParseVarKey(interp, objPtr, &varObjPtr, &keyObjPtr); + } + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &dictSubstObjType; + objPtr->internalRep.dictSubstValue.varNameObjPtr = varObjPtr; + objPtr->internalRep.dictSubstValue.indexObjPtr = keyObjPtr; + } +} + +static Jim_Obj *JimExpandDictSugar(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_Obj *resObjPtr = NULL; + Jim_Obj *substKeyObjPtr = NULL; + + SetDictSubstFromAny(interp, objPtr); + + if (Jim_SubstObj(interp, objPtr->internalRep.dictSubstValue.indexObjPtr, + &substKeyObjPtr, JIM_NONE) + != JIM_OK) { + return NULL; + } + Jim_IncrRefCount(substKeyObjPtr); + resObjPtr = + JimDictExpandArrayVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, + substKeyObjPtr, 0); + Jim_DecrRefCount(interp, substKeyObjPtr); + + return resObjPtr; +} + +static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_Obj *resultObjPtr; + + if (Jim_EvalExpression(interp, objPtr, &resultObjPtr) == JIM_OK) { + + resultObjPtr->refCount--; + return resultObjPtr; + } + return NULL; +} + + +static Jim_CallFrame *JimCreateCallFrame(Jim_Interp *interp, Jim_CallFrame *parent, Jim_Obj *nsObj) +{ + Jim_CallFrame *cf; + + if (interp->freeFramesList) { + cf = interp->freeFramesList; + interp->freeFramesList = cf->next; + } + else { + cf = Jim_Alloc(sizeof(*cf)); + cf->vars.table = NULL; + } + + cf->id = interp->callFrameEpoch++; + cf->parent = parent; + cf->level = parent ? parent->level + 1 : 0; + cf->argv = NULL; + cf->argc = 0; + cf->procArgsObjPtr = NULL; + cf->procBodyObjPtr = NULL; + cf->next = NULL; + cf->staticVars = NULL; + cf->localCommands = NULL; + + cf->nsObj = nsObj; + Jim_IncrRefCount(nsObj); + if (cf->vars.table == NULL) + Jim_InitHashTable(&cf->vars, &JimVariablesHashTableType, interp); + return cf; +} + + +static void JimChangeCallFrameId(Jim_Interp *interp, Jim_CallFrame *cf) +{ + cf->id = interp->callFrameEpoch++; +} + +static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands) +{ + + if (localCommands) { + Jim_Obj *cmdNameObj; + + while ((cmdNameObj = Jim_StackPop(localCommands)) != NULL) { + Jim_HashEntry *he; + Jim_Obj *fqObjName; + + const char *fqname = JimQualifyName(interp, Jim_String(cmdNameObj), &fqObjName); + + he = Jim_FindHashEntry(&interp->commands, fqname); + + if (he) { + Jim_Cmd *cmd = he->u.val; + if (cmd->prevCmd) { + Jim_Cmd *prevCmd = cmd->prevCmd; + cmd->prevCmd = NULL; + + + JimDecrCmdRefCount(interp, cmd); + + + he->u.val = prevCmd; + } + else { + Jim_DeleteHashEntry(&interp->commands, fqname); + Jim_InterpIncrProcEpoch(interp); + } + } + Jim_DecrRefCount(interp, cmdNameObj); + JimFreeQualifiedName(interp, fqObjName); + } + Jim_FreeStack(localCommands); + Jim_Free(localCommands); + } + return JIM_OK; +} + + +#define JIM_FCF_NONE 0 +#define JIM_FCF_NOHT 1 +static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int flags) +{ + if (cf->procArgsObjPtr) + Jim_DecrRefCount(interp, cf->procArgsObjPtr); + if (cf->procBodyObjPtr) + Jim_DecrRefCount(interp, cf->procBodyObjPtr); + Jim_DecrRefCount(interp, cf->nsObj); + if (!(flags & JIM_FCF_NOHT)) + Jim_FreeHashTable(&cf->vars); + else { + int i; + Jim_HashEntry **table = cf->vars.table, *he; + + for (i = 0; i < JIM_HT_INITIAL_SIZE; i++) { + he = table[i]; + while (he != NULL) { + Jim_HashEntry *nextEntry = he->next; + Jim_Var *varPtr = (void *)he->u.val; + + Jim_DecrRefCount(interp, varPtr->objPtr); + Jim_Free(he->u.val); + Jim_Free((void *)he->key); + Jim_Free(he); + table[i] = NULL; + he = nextEntry; + } + } + cf->vars.used = 0; + } + + JimDeleteLocalProcs(interp, cf->localCommands); + + cf->next = interp->freeFramesList; + interp->freeFramesList = cf; + +} + + +#ifdef JIM_REFERENCES + +static void JimReferencesHTValDestructor(void *interp, void *val) +{ + Jim_Reference *refPtr = (void *)val; + + Jim_DecrRefCount(interp, refPtr->objPtr); + if (refPtr->finalizerCmdNamePtr != NULL) { + Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr); + } + Jim_Free(val); +} + +static unsigned int JimReferencesHTHashFunction(const void *key) +{ + + const unsigned long *widePtr = key; + unsigned int intValue = (unsigned int)*widePtr; + + return Jim_IntHashFunction(intValue); +} + +static void *JimReferencesHTKeyDup(void *privdata, const void *key) +{ + void *copy = Jim_Alloc(sizeof(unsigned long)); + + JIM_NOTUSED(privdata); + + memcpy(copy, key, sizeof(unsigned long)); + return copy; +} + +static int JimReferencesHTKeyCompare(void *privdata, const void *key1, const void *key2) +{ + JIM_NOTUSED(privdata); + + return memcmp(key1, key2, sizeof(unsigned long)) == 0; +} + +static void JimReferencesHTKeyDestructor(void *privdata, void *key) +{ + JIM_NOTUSED(privdata); + + Jim_Free(key); +} + +static const Jim_HashTableType JimReferencesHashTableType = { + JimReferencesHTHashFunction, + JimReferencesHTKeyDup, + NULL, + JimReferencesHTKeyCompare, + JimReferencesHTKeyDestructor, + JimReferencesHTValDestructor +}; + + + +#define JIM_REFERENCE_SPACE (35+JIM_REFERENCE_TAGLEN) + +static int JimFormatReference(char *buf, Jim_Reference *refPtr, unsigned long id) +{ + const char *fmt = ".%020lu>"; + + sprintf(buf, fmt, refPtr->tag, id); + return JIM_REFERENCE_SPACE; +} + +static void UpdateStringOfReference(struct Jim_Obj *objPtr); + +static const Jim_ObjType referenceObjType = { + "reference", + NULL, + NULL, + UpdateStringOfReference, + JIM_TYPE_REFERENCES, +}; + +void UpdateStringOfReference(struct Jim_Obj *objPtr) +{ + int len; + char buf[JIM_REFERENCE_SPACE + 1]; + Jim_Reference *refPtr; + + refPtr = objPtr->internalRep.refValue.refPtr; + len = JimFormatReference(buf, refPtr, objPtr->internalRep.refValue.id); + objPtr->bytes = Jim_Alloc(len + 1); + memcpy(objPtr->bytes, buf, len + 1); + objPtr->length = len; +} + +static int isrefchar(int c) +{ + return (c == '_' || isalnum(c)); +} + +static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + unsigned long value; + int i, len; + const char *str, *start, *end; + char refId[21]; + Jim_Reference *refPtr; + Jim_HashEntry *he; + char *endptr; + + + str = Jim_GetString(objPtr, &len); + + if (len < JIM_REFERENCE_SPACE) + goto badformat; + + start = str; + end = str + len - 1; + while (*start == ' ') + start++; + while (*end == ' ' && end > start) + end--; + if (end - start + 1 != JIM_REFERENCE_SPACE) + goto badformat; + + if (memcmp(start, "references, &value); + if (he == NULL) { + Jim_SetResultFormatted(interp, "invalid reference id \"%#s\"", objPtr); + return JIM_ERR; + } + refPtr = he->u.val; + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &referenceObjType; + objPtr->internalRep.refValue.id = value; + objPtr->internalRep.refValue.refPtr = refPtr; + return JIM_OK; + + badformat: + Jim_SetResultFormatted(interp, "expected reference but got \"%#s\"", objPtr); + return JIM_ERR; +} + +Jim_Obj *Jim_NewReference(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr) +{ + struct Jim_Reference *refPtr; + unsigned long id; + Jim_Obj *refObjPtr; + const char *tag; + int tagLen, i; + + + Jim_CollectIfNeeded(interp); + + refPtr = Jim_Alloc(sizeof(*refPtr)); + refPtr->objPtr = objPtr; + Jim_IncrRefCount(objPtr); + refPtr->finalizerCmdNamePtr = cmdNamePtr; + if (cmdNamePtr) + Jim_IncrRefCount(cmdNamePtr); + id = interp->referenceNextId++; + Jim_AddHashEntry(&interp->references, &id, refPtr); + refObjPtr = Jim_NewObj(interp); + refObjPtr->typePtr = &referenceObjType; + refObjPtr->bytes = NULL; + refObjPtr->internalRep.refValue.id = id; + refObjPtr->internalRep.refValue.refPtr = refPtr; + interp->referenceNextId++; + tag = Jim_GetString(tagPtr, &tagLen); + if (tagLen > JIM_REFERENCE_TAGLEN) + tagLen = JIM_REFERENCE_TAGLEN; + for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) { + if (i < tagLen && isrefchar(tag[i])) + refPtr->tag[i] = tag[i]; + else + refPtr->tag[i] = '_'; + } + refPtr->tag[JIM_REFERENCE_TAGLEN] = '\0'; + return refObjPtr; +} + +Jim_Reference *Jim_GetReference(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr->typePtr != &referenceObjType && SetReferenceFromAny(interp, objPtr) == JIM_ERR) + return NULL; + return objPtr->internalRep.refValue.refPtr; +} + +int Jim_SetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *cmdNamePtr) +{ + Jim_Reference *refPtr; + + if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL) + return JIM_ERR; + Jim_IncrRefCount(cmdNamePtr); + if (refPtr->finalizerCmdNamePtr) + Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr); + refPtr->finalizerCmdNamePtr = cmdNamePtr; + return JIM_OK; +} + +int Jim_GetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj **cmdNamePtrPtr) +{ + Jim_Reference *refPtr; + + if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL) + return JIM_ERR; + *cmdNamePtrPtr = refPtr->finalizerCmdNamePtr; + return JIM_OK; +} + + + +static const Jim_HashTableType JimRefMarkHashTableType = { + JimReferencesHTHashFunction, + JimReferencesHTKeyDup, + NULL, + JimReferencesHTKeyCompare, + JimReferencesHTKeyDestructor, + NULL +}; + + +int Jim_Collect(Jim_Interp *interp) +{ + int collected = 0; + return collected; +} + +#define JIM_COLLECT_ID_PERIOD 5000 +#define JIM_COLLECT_TIME_PERIOD 300 + +void Jim_CollectIfNeeded(Jim_Interp *interp) +{ + unsigned long elapsedId; + int elapsedTime; + + elapsedId = interp->referenceNextId - interp->lastCollectId; + elapsedTime = time(NULL) - interp->lastCollectTime; + + + if (elapsedId > JIM_COLLECT_ID_PERIOD || elapsedTime > JIM_COLLECT_TIME_PERIOD) { + Jim_Collect(interp); + } +} +#endif + +static int JimIsBigEndian(void) +{ + union { + unsigned short s; + unsigned char c[2]; + } uval = {0x0102}; + + return uval.c[0] == 1; +} + + +Jim_Interp *Jim_CreateInterp(void) +{ + Jim_Interp *i = Jim_Alloc(sizeof(*i)); + + memset(i, 0, sizeof(*i)); + + i->maxCallFrameDepth = JIM_MAX_CALLFRAME_DEPTH; + i->maxEvalDepth = JIM_MAX_EVAL_DEPTH; + i->lastCollectTime = time(NULL); + + Jim_InitHashTable(&i->commands, &JimCommandsHashTableType, i); +#ifdef JIM_REFERENCES + Jim_InitHashTable(&i->references, &JimReferencesHashTableType, i); +#endif + Jim_InitHashTable(&i->assocData, &JimAssocDataHashTableType, i); + Jim_InitHashTable(&i->packages, &JimPackageHashTableType, NULL); + i->emptyObj = Jim_NewEmptyStringObj(i); + i->trueObj = Jim_NewIntObj(i, 1); + i->falseObj = Jim_NewIntObj(i, 0); + i->framePtr = i->topFramePtr = JimCreateCallFrame(i, NULL, i->emptyObj); + i->errorFileNameObj = i->emptyObj; + i->result = i->emptyObj; + i->stackTrace = Jim_NewListObj(i, NULL, 0); + i->unknown = Jim_NewStringObj(i, "unknown", -1); + i->errorProc = i->emptyObj; + i->currentScriptObj = Jim_NewEmptyStringObj(i); + i->nullScriptObj = Jim_NewEmptyStringObj(i); + Jim_IncrRefCount(i->emptyObj); + Jim_IncrRefCount(i->errorFileNameObj); + Jim_IncrRefCount(i->result); + Jim_IncrRefCount(i->stackTrace); + Jim_IncrRefCount(i->unknown); + Jim_IncrRefCount(i->currentScriptObj); + Jim_IncrRefCount(i->nullScriptObj); + Jim_IncrRefCount(i->errorProc); + Jim_IncrRefCount(i->trueObj); + Jim_IncrRefCount(i->falseObj); + + + Jim_SetVariableStrWithStr(i, JIM_LIBPATH, TCL_LIBRARY); + Jim_SetVariableStrWithStr(i, JIM_INTERACTIVE, "0"); + + Jim_SetVariableStrWithStr(i, "tcl_platform(os)", TCL_PLATFORM_OS); + Jim_SetVariableStrWithStr(i, "tcl_platform(platform)", TCL_PLATFORM_PLATFORM); + Jim_SetVariableStrWithStr(i, "tcl_platform(pathSeparator)", TCL_PLATFORM_PATH_SEPARATOR); + Jim_SetVariableStrWithStr(i, "tcl_platform(byteOrder)", JimIsBigEndian() ? "bigEndian" : "littleEndian"); + Jim_SetVariableStrWithStr(i, "tcl_platform(threaded)", "0"); + Jim_SetVariableStr(i, "tcl_platform(pointerSize)", Jim_NewIntObj(i, sizeof(void *))); + Jim_SetVariableStr(i, "tcl_platform(wordSize)", Jim_NewIntObj(i, sizeof(jim_wide))); + + return i; +} + +void Jim_FreeInterp(Jim_Interp *i) +{ + Jim_CallFrame *cf = i->framePtr, *prevcf, *nextcf; + Jim_Obj *objPtr, *nextObjPtr; + + Jim_DecrRefCount(i, i->emptyObj); + Jim_DecrRefCount(i, i->trueObj); + Jim_DecrRefCount(i, i->falseObj); + Jim_DecrRefCount(i, i->result); + Jim_DecrRefCount(i, i->stackTrace); + Jim_DecrRefCount(i, i->errorProc); + Jim_DecrRefCount(i, i->unknown); + Jim_DecrRefCount(i, i->errorFileNameObj); + Jim_DecrRefCount(i, i->currentScriptObj); + Jim_DecrRefCount(i, i->nullScriptObj); + Jim_FreeHashTable(&i->commands); +#ifdef JIM_REFERENCES + Jim_FreeHashTable(&i->references); +#endif + Jim_FreeHashTable(&i->packages); + Jim_Free(i->prngState); + Jim_FreeHashTable(&i->assocData); + + + while (cf) { + prevcf = cf->parent; + JimFreeCallFrame(i, cf, JIM_FCF_NONE); + cf = prevcf; + } + if (i->liveList != NULL) { + objPtr = i->liveList; + + printf(JIM_NL "-------------------------------------" JIM_NL); + printf("Objects still in the free list:" JIM_NL); + while (objPtr) { + const char *type = objPtr->typePtr ? objPtr->typePtr->name : "string"; + + if (objPtr->bytes && strlen(objPtr->bytes) > 20) { + printf("%p (%d) %-10s: '%.20s...'" JIM_NL, + (void *)objPtr, objPtr->refCount, type, objPtr->bytes); + } + else { + printf("%p (%d) %-10s: '%s'" JIM_NL, + (void *)objPtr, objPtr->refCount, type, objPtr->bytes ? objPtr->bytes : "(null)"); + } + if (objPtr->typePtr == &sourceObjType) { + printf("FILE %s LINE %d" JIM_NL, + Jim_String(objPtr->internalRep.sourceValue.fileNameObj), + objPtr->internalRep.sourceValue.lineNumber); + } + objPtr = objPtr->nextObjPtr; + } + printf("-------------------------------------" JIM_NL JIM_NL); + JimPanic((1, "Live list non empty freeing the interpreter! Leak?")); + } + + objPtr = i->freeList; + while (objPtr) { + nextObjPtr = objPtr->nextObjPtr; + Jim_Free(objPtr); + objPtr = nextObjPtr; + } + + cf = i->freeFramesList; + while (cf) { + nextcf = cf->next; + if (cf->vars.table != NULL) + Jim_Free(cf->vars.table); + Jim_Free(cf); + cf = nextcf; + } +#ifdef jim_ext_load + Jim_FreeLoadHandles(i); +#endif + + + Jim_Free(i); +} + +Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr) +{ + long level; + const char *str; + Jim_CallFrame *framePtr; + + if (levelObjPtr) { + str = Jim_String(levelObjPtr); + if (str[0] == '#') { + char *endptr; + + level = jim_strtol(str + 1, &endptr); + if (str[1] == '\0' || endptr[0] != '\0') { + level = -1; + } + } + else { + if (Jim_GetLong(interp, levelObjPtr, &level) != JIM_OK || level < 0) { + level = -1; + } + else { + + level = interp->framePtr->level - level; + } + } + } + else { + str = "1"; + level = interp->framePtr->level - 1; + } + + if (level == 0) { + return interp->topFramePtr; + } + if (level > 0) { + + for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) { + if (framePtr->level == level) { + return framePtr; + } + } + } + + Jim_SetResultFormatted(interp, "bad level \"%s\"", str); + return NULL; +} + +static Jim_CallFrame *JimGetCallFrameByInteger(Jim_Interp *interp, Jim_Obj *levelObjPtr) +{ + long level; + Jim_CallFrame *framePtr; + + if (Jim_GetLong(interp, levelObjPtr, &level) == JIM_OK) { + if (level <= 0) { + + level = interp->framePtr->level + level; + } + + if (level == 0) { + return interp->topFramePtr; + } + + + for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) { + if (framePtr->level == level) { + return framePtr; + } + } + } + + Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr); + return NULL; +} + +static void JimResetStackTrace(Jim_Interp *interp) +{ + Jim_DecrRefCount(interp, interp->stackTrace); + interp->stackTrace = Jim_NewListObj(interp, NULL, 0); + Jim_IncrRefCount(interp->stackTrace); +} + +static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj) +{ + int len; + + + Jim_IncrRefCount(stackTraceObj); + Jim_DecrRefCount(interp, interp->stackTrace); + interp->stackTrace = stackTraceObj; + interp->errorFlag = 1; + + len = Jim_ListLength(interp, interp->stackTrace); + if (len >= 3) { + Jim_Obj *filenameObj; + + Jim_ListIndex(interp, interp->stackTrace, len - 2, &filenameObj, JIM_NONE); + + Jim_GetString(filenameObj, &len); + + if (!Jim_Length(filenameObj)) { + interp->addStackTrace = 1; + } + } +} + + +static void JimAppendStackTrace(Jim_Interp *interp, const char *procname, + Jim_Obj *fileNameObj, int linenr) +{ + if (strcmp(procname, "unknown") == 0) { + procname = ""; + } + if (!*procname && !Jim_Length(fileNameObj)) { + + return; + } + + if (Jim_IsShared(interp->stackTrace)) { + Jim_DecrRefCount(interp, interp->stackTrace); + interp->stackTrace = Jim_DuplicateObj(interp, interp->stackTrace); + Jim_IncrRefCount(interp->stackTrace); + } + + + if (!*procname && Jim_Length(fileNameObj)) { + + int len = Jim_ListLength(interp, interp->stackTrace); + + if (len >= 3) { + Jim_Obj *objPtr; + if (Jim_ListIndex(interp, interp->stackTrace, len - 3, &objPtr, JIM_NONE) == JIM_OK && Jim_Length(objPtr)) { + + if (Jim_ListIndex(interp, interp->stackTrace, len - 2, &objPtr, JIM_NONE) == JIM_OK && !Jim_Length(objPtr)) { + + ListSetIndex(interp, interp->stackTrace, len - 2, fileNameObj, 0); + ListSetIndex(interp, interp->stackTrace, len - 1, Jim_NewIntObj(interp, linenr), 0); + return; + } + } + } + } + + Jim_ListAppendElement(interp, interp->stackTrace, Jim_NewStringObj(interp, procname, -1)); + Jim_ListAppendElement(interp, interp->stackTrace, fileNameObj); + Jim_ListAppendElement(interp, interp->stackTrace, Jim_NewIntObj(interp, linenr)); +} + +int Jim_SetAssocData(Jim_Interp *interp, const char *key, Jim_InterpDeleteProc * delProc, + void *data) +{ + AssocDataValue *assocEntryPtr = (AssocDataValue *) Jim_Alloc(sizeof(AssocDataValue)); + + assocEntryPtr->delProc = delProc; + assocEntryPtr->data = data; + return Jim_AddHashEntry(&interp->assocData, key, assocEntryPtr); +} + +void *Jim_GetAssocData(Jim_Interp *interp, const char *key) +{ + Jim_HashEntry *entryPtr = Jim_FindHashEntry(&interp->assocData, key); + + if (entryPtr != NULL) { + AssocDataValue *assocEntryPtr = (AssocDataValue *) entryPtr->u.val; + + return assocEntryPtr->data; + } + return NULL; +} + +int Jim_DeleteAssocData(Jim_Interp *interp, const char *key) +{ + return Jim_DeleteHashEntry(&interp->assocData, key); +} + +int Jim_GetExitCode(Jim_Interp *interp) +{ + return interp->exitCode; +} + +#define JIM_INTEGER_SPACE 24 + +static void UpdateStringOfInt(struct Jim_Obj *objPtr); +static int SetIntFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags); + +static const Jim_ObjType intObjType = { + "int", + NULL, + NULL, + UpdateStringOfInt, + JIM_TYPE_NONE, +}; + +static const Jim_ObjType coercedDoubleObjType = { + "coerced-double", + NULL, + NULL, + UpdateStringOfInt, + JIM_TYPE_NONE, +}; + + +void UpdateStringOfInt(struct Jim_Obj *objPtr) +{ + int len; + char buf[JIM_INTEGER_SPACE + 1]; + + len = Jim_WideToString(buf, JimWideValue(objPtr)); + objPtr->bytes = Jim_Alloc(len + 1); + memcpy(objPtr->bytes, buf, len + 1); + objPtr->length = len; +} + +int SetIntFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + jim_wide wideValue; + const char *str; + + if (objPtr->typePtr == &coercedDoubleObjType) { + + objPtr->typePtr = &intObjType; + return JIM_OK; + } + + + str = Jim_String(objPtr); + + if (Jim_StringToWide(str, &wideValue, 0) != JIM_OK) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "expected integer but got \"%#s\"", objPtr); + } + return JIM_ERR; + } + if ((wideValue == JIM_WIDE_MIN || wideValue == JIM_WIDE_MAX) && errno == ERANGE) { + Jim_SetResultString(interp, "Integer value too big to be represented", -1); + return JIM_ERR; + } + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &intObjType; + objPtr->internalRep.wideValue = wideValue; + return JIM_OK; +} + +#ifdef JIM_OPTIMIZATION +static int JimIsWide(Jim_Obj *objPtr) +{ + return objPtr->typePtr == &intObjType; +} +#endif + +int Jim_GetWide(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr) +{ + if (objPtr->typePtr != &intObjType && SetIntFromAny(interp, objPtr, JIM_ERRMSG) == JIM_ERR) + return JIM_ERR; + *widePtr = JimWideValue(objPtr); + return JIM_OK; +} + + +static int JimGetWideNoErr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr) +{ + if (objPtr->typePtr != &intObjType && SetIntFromAny(interp, objPtr, JIM_NONE) == JIM_ERR) + return JIM_ERR; + *widePtr = JimWideValue(objPtr); + return JIM_OK; +} + +int Jim_GetLong(Jim_Interp *interp, Jim_Obj *objPtr, long *longPtr) +{ + jim_wide wideValue; + int retval; + + retval = Jim_GetWide(interp, objPtr, &wideValue); + if (retval == JIM_OK) { + *longPtr = (long)wideValue; + return JIM_OK; + } + return JIM_ERR; +} + +Jim_Obj *Jim_NewIntObj(Jim_Interp *interp, jim_wide wideValue) +{ + Jim_Obj *objPtr; + + objPtr = Jim_NewObj(interp); + objPtr->typePtr = &intObjType; + objPtr->bytes = NULL; + objPtr->internalRep.wideValue = wideValue; + return objPtr; +} + +#define JIM_DOUBLE_SPACE 30 + +static void UpdateStringOfDouble(struct Jim_Obj *objPtr); +static int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr); + +static const Jim_ObjType doubleObjType = { + "double", + NULL, + NULL, + UpdateStringOfDouble, + JIM_TYPE_NONE, +}; + +void UpdateStringOfDouble(struct Jim_Obj *objPtr) +{ + int len; + char buf[JIM_DOUBLE_SPACE + 1]; + + len = Jim_DoubleToString(buf, objPtr->internalRep.doubleValue); + objPtr->bytes = Jim_Alloc(len + 1); + memcpy(objPtr->bytes, buf, len + 1); + objPtr->length = len; +} + +int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + double doubleValue; + jim_wide wideValue; + const char *str; + + str = Jim_String(objPtr); + +#ifdef HAVE_LONG_LONG + +#define MIN_INT_IN_DOUBLE -(1LL << 53) +#define MAX_INT_IN_DOUBLE -(MIN_INT_IN_DOUBLE + 1) + + if (objPtr->typePtr == &intObjType + && JimWideValue(objPtr) >= MIN_INT_IN_DOUBLE + && JimWideValue(objPtr) <= MAX_INT_IN_DOUBLE) { + + + objPtr->typePtr = &coercedDoubleObjType; + return JIM_OK; + } + else +#endif + if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) { + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &coercedDoubleObjType; + objPtr->internalRep.wideValue = wideValue; + return JIM_OK; + } + else { + + if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) { + Jim_SetResultFormatted(interp, "expected number but got \"%#s\"", objPtr); + return JIM_ERR; + } + + Jim_FreeIntRep(interp, objPtr); + } + objPtr->typePtr = &doubleObjType; + objPtr->internalRep.doubleValue = doubleValue; + return JIM_OK; +} + +int Jim_GetDouble(Jim_Interp *interp, Jim_Obj *objPtr, double *doublePtr) +{ + if (objPtr->typePtr == &coercedDoubleObjType) { + *doublePtr = JimWideValue(objPtr); + return JIM_OK; + } + if (objPtr->typePtr != &doubleObjType && SetDoubleFromAny(interp, objPtr) == JIM_ERR) + return JIM_ERR; + + if (objPtr->typePtr == &coercedDoubleObjType) { + *doublePtr = JimWideValue(objPtr); + } + else { + *doublePtr = objPtr->internalRep.doubleValue; + } + return JIM_OK; +} + +Jim_Obj *Jim_NewDoubleObj(Jim_Interp *interp, double doubleValue) +{ + Jim_Obj *objPtr; + + objPtr = Jim_NewObj(interp); + objPtr->typePtr = &doubleObjType; + objPtr->bytes = NULL; + objPtr->internalRep.doubleValue = doubleValue; + return objPtr; +} + +static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec); +static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr); +static void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static void UpdateStringOfList(struct Jim_Obj *objPtr); +static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType listObjType = { + "list", + FreeListInternalRep, + DupListInternalRep, + UpdateStringOfList, + JIM_TYPE_NONE, +}; + +void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + int i; + + for (i = 0; i < objPtr->internalRep.listValue.len; i++) { + Jim_DecrRefCount(interp, objPtr->internalRep.listValue.ele[i]); + } + Jim_Free(objPtr->internalRep.listValue.ele); +} + +void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + int i; + + JIM_NOTUSED(interp); + + dupPtr->internalRep.listValue.len = srcPtr->internalRep.listValue.len; + dupPtr->internalRep.listValue.maxLen = srcPtr->internalRep.listValue.maxLen; + dupPtr->internalRep.listValue.ele = + Jim_Alloc(sizeof(Jim_Obj *) * srcPtr->internalRep.listValue.maxLen); + memcpy(dupPtr->internalRep.listValue.ele, srcPtr->internalRep.listValue.ele, + sizeof(Jim_Obj *) * srcPtr->internalRep.listValue.len); + for (i = 0; i < dupPtr->internalRep.listValue.len; i++) { + Jim_IncrRefCount(dupPtr->internalRep.listValue.ele[i]); + } + dupPtr->typePtr = &listObjType; +} + +#define JIM_ELESTR_SIMPLE 0 +#define JIM_ELESTR_BRACE 1 +#define JIM_ELESTR_QUOTE 2 +static int ListElementQuotingType(const char *s, int len) +{ + int i, level, blevel, trySimple = 1; + + + if (len == 0) + return JIM_ELESTR_BRACE; + if (s[0] == '"' || s[0] == '{') { + trySimple = 0; + goto testbrace; + } + for (i = 0; i < len; i++) { + switch (s[i]) { + case ' ': + case '$': + case '"': + case '[': + case ']': + case ';': + case '\\': + case '\r': + case '\n': + case '\t': + case '\f': + case '\v': + trySimple = 0; + case '{': + case '}': + goto testbrace; + } + } + return JIM_ELESTR_SIMPLE; + + testbrace: + + if (s[len - 1] == '\\') + return JIM_ELESTR_QUOTE; + level = 0; + blevel = 0; + for (i = 0; i < len; i++) { + switch (s[i]) { + case '{': + level++; + break; + case '}': + level--; + if (level < 0) + return JIM_ELESTR_QUOTE; + break; + case '[': + blevel++; + break; + case ']': + blevel--; + break; + case '\\': + if (s[i + 1] == '\n') + return JIM_ELESTR_QUOTE; + else if (s[i + 1] != '\0') + i++; + break; + } + } + if (blevel < 0) { + return JIM_ELESTR_QUOTE; + } + + if (level == 0) { + if (!trySimple) + return JIM_ELESTR_BRACE; + for (i = 0; i < len; i++) { + switch (s[i]) { + case ' ': + case '$': + case '"': + case '[': + case ']': + case ';': + case '\\': + case '\r': + case '\n': + case '\t': + case '\f': + case '\v': + return JIM_ELESTR_BRACE; + break; + } + } + return JIM_ELESTR_SIMPLE; + } + return JIM_ELESTR_QUOTE; +} + +static int BackslashQuoteString(const char *s, char *q) +{ + char *p = q; + + while (*s) { + switch (*s) { + case ' ': + case '$': + case '"': + case '[': + case ']': + case '{': + case '}': + case ';': + case '\\': + *p++ = '\\'; + *p++ = *s++; + break; + case '\n': + *p++ = '\\'; + *p++ = 'n'; + s++; + break; + case '\r': + *p++ = '\\'; + *p++ = 'r'; + s++; + break; + case '\t': + *p++ = '\\'; + *p++ = 't'; + s++; + break; + case '\f': + *p++ = '\\'; + *p++ = 'f'; + s++; + break; + case '\v': + *p++ = '\\'; + *p++ = 'v'; + s++; + break; + default: + *p++ = *s++; + break; + } + } + *p = '\0'; + + return p - q; +} + +static void JimMakeListStringRep(Jim_Obj *objPtr, Jim_Obj **objv, int objc) +{ + int i, bufLen, realLength; + const char *strRep; + char *p; + int *quotingType; + + + quotingType = Jim_Alloc(sizeof(int) * objc + 1); + bufLen = 0; + for (i = 0; i < objc; i++) { + int len; + + strRep = Jim_GetString(objv[i], &len); + quotingType[i] = ListElementQuotingType(strRep, len); + switch (quotingType[i]) { + case JIM_ELESTR_SIMPLE: + if (i != 0 || strRep[0] != '#') { + bufLen += len; + break; + } + + quotingType[i] = JIM_ELESTR_BRACE; + + case JIM_ELESTR_BRACE: + bufLen += len + 2; + break; + case JIM_ELESTR_QUOTE: + bufLen += len * 2; + break; + } + bufLen++; + } + bufLen++; + + + p = objPtr->bytes = Jim_Alloc(bufLen + 1); + realLength = 0; + for (i = 0; i < objc; i++) { + int len, qlen; + + strRep = Jim_GetString(objv[i], &len); + + switch (quotingType[i]) { + case JIM_ELESTR_SIMPLE: + memcpy(p, strRep, len); + p += len; + realLength += len; + break; + case JIM_ELESTR_BRACE: + *p++ = '{'; + memcpy(p, strRep, len); + p += len; + *p++ = '}'; + realLength += len + 2; + break; + case JIM_ELESTR_QUOTE: + if (i == 0 && strRep[0] == '#') { + *p++ = '\\'; + realLength++; + } + qlen = BackslashQuoteString(strRep, p); + p += qlen; + realLength += qlen; + break; + } + + if (i + 1 != objc) { + *p++ = ' '; + realLength++; + } + } + *p = '\0'; + objPtr->length = realLength; + Jim_Free(quotingType); +} + +static void UpdateStringOfList(struct Jim_Obj *objPtr) +{ + JimMakeListStringRep(objPtr, objPtr->internalRep.listValue.ele, objPtr->internalRep.listValue.len); +} + +static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + struct JimParserCtx parser; + const char *str; + int strLen; + Jim_Obj *fileNameObj; + int linenr; + + if (objPtr->typePtr == &listObjType) { + return JIM_OK; + } + + if (Jim_IsDict(objPtr) && !Jim_IsShared(objPtr)) { + Jim_Obj **listObjPtrPtr; + int len; + int i; + + Jim_DictPairs(interp, objPtr, &listObjPtrPtr, &len); + for (i = 0; i < len; i++) { + Jim_IncrRefCount(listObjPtrPtr[i]); + } + + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &listObjType; + objPtr->internalRep.listValue.len = len; + objPtr->internalRep.listValue.maxLen = len; + objPtr->internalRep.listValue.ele = listObjPtrPtr; + + return JIM_OK; + } + + + if (objPtr->typePtr == &sourceObjType) { + fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; + linenr = objPtr->internalRep.sourceValue.lineNumber; + } + else { + fileNameObj = interp->emptyObj; + linenr = 1; + } + Jim_IncrRefCount(fileNameObj); + + + str = Jim_GetString(objPtr, &strLen); + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &listObjType; + objPtr->internalRep.listValue.len = 0; + objPtr->internalRep.listValue.maxLen = 0; + objPtr->internalRep.listValue.ele = NULL; + + + if (strLen) { + JimParserInit(&parser, str, strLen, linenr); + while (!parser.eof) { + Jim_Obj *elementPtr; + + JimParseList(&parser); + if (parser.tt != JIM_TT_STR && parser.tt != JIM_TT_ESC) + continue; + elementPtr = JimParserGetTokenObj(interp, &parser); + JimSetSourceInfo(interp, elementPtr, fileNameObj, parser.tline); + ListAppendElement(objPtr, elementPtr); + } + } + Jim_DecrRefCount(interp, fileNameObj); + return JIM_OK; +} + +Jim_Obj *Jim_NewListObj(Jim_Interp *interp, Jim_Obj *const *elements, int len) +{ + Jim_Obj *objPtr; + + objPtr = Jim_NewObj(interp); + objPtr->typePtr = &listObjType; + objPtr->bytes = NULL; + objPtr->internalRep.listValue.ele = NULL; + objPtr->internalRep.listValue.len = 0; + objPtr->internalRep.listValue.maxLen = 0; + + if (len) { + ListInsertElements(objPtr, 0, len, elements); + } + + return objPtr; +} + +static void JimListGetElements(Jim_Interp *interp, Jim_Obj *listObj, int *listLen, + Jim_Obj ***listVec) +{ + *listLen = Jim_ListLength(interp, listObj); + *listVec = listObj->internalRep.listValue.ele; +} + + +static int JimSign(jim_wide w) +{ + if (w == 0) { + return 0; + } + else if (w < 0) { + return -1; + } + return 1; +} + + +struct lsort_info { + jmp_buf jmpbuf; + Jim_Obj *command; + Jim_Interp *interp; + enum { + JIM_LSORT_ASCII, + JIM_LSORT_NOCASE, + JIM_LSORT_INTEGER, + JIM_LSORT_COMMAND + } type; + int order; + int index; + int indexed; + int (*subfn)(Jim_Obj **, Jim_Obj **); +}; + +static struct lsort_info *sort_info; + +static int ListSortIndexHelper(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + Jim_Obj *lObj, *rObj; + + if (Jim_ListIndex(sort_info->interp, *lhsObj, sort_info->index, &lObj, JIM_ERRMSG) != JIM_OK || + Jim_ListIndex(sort_info->interp, *rhsObj, sort_info->index, &rObj, JIM_ERRMSG) != JIM_OK) { + longjmp(sort_info->jmpbuf, JIM_ERR); + } + return sort_info->subfn(&lObj, &rObj); +} + + +static int ListSortString(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + return Jim_StringCompareObj(sort_info->interp, *lhsObj, *rhsObj, 0) * sort_info->order; +} + +static int ListSortStringNoCase(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + return Jim_StringCompareObj(sort_info->interp, *lhsObj, *rhsObj, 1) * sort_info->order; +} + +static int ListSortInteger(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + jim_wide lhs = 0, rhs = 0; + + if (Jim_GetWide(sort_info->interp, *lhsObj, &lhs) != JIM_OK || + Jim_GetWide(sort_info->interp, *rhsObj, &rhs) != JIM_OK) { + longjmp(sort_info->jmpbuf, JIM_ERR); + } + + return JimSign(lhs - rhs) * sort_info->order; +} + +static int ListSortCommand(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + Jim_Obj *compare_script; + int rc; + + jim_wide ret = 0; + + + compare_script = Jim_DuplicateObj(sort_info->interp, sort_info->command); + Jim_ListAppendElement(sort_info->interp, compare_script, *lhsObj); + Jim_ListAppendElement(sort_info->interp, compare_script, *rhsObj); + + rc = Jim_EvalObj(sort_info->interp, compare_script); + + if (rc != JIM_OK || Jim_GetWide(sort_info->interp, Jim_GetResult(sort_info->interp), &ret) != JIM_OK) { + longjmp(sort_info->jmpbuf, rc); + } + + return JimSign(ret) * sort_info->order; +} + + +static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsort_info *info) +{ + struct lsort_info *prev_info; + + typedef int (qsort_comparator) (const void *, const void *); + int (*fn) (Jim_Obj **, Jim_Obj **); + Jim_Obj **vector; + int len; + int rc; + + JimPanic((Jim_IsShared(listObjPtr), "Jim_ListSortElements called with shared object")); + SetListFromAny(interp, listObjPtr); + + + prev_info = sort_info; + sort_info = info; + + vector = listObjPtr->internalRep.listValue.ele; + len = listObjPtr->internalRep.listValue.len; + switch (info->type) { + case JIM_LSORT_ASCII: + fn = ListSortString; + break; + case JIM_LSORT_NOCASE: + fn = ListSortStringNoCase; + break; + case JIM_LSORT_INTEGER: + fn = ListSortInteger; + break; + case JIM_LSORT_COMMAND: + fn = ListSortCommand; + break; + default: + fn = NULL; + JimPanic((1, "ListSort called with invalid sort type")); + } + + if (info->indexed) { + + info->subfn = fn; + fn = ListSortIndexHelper; + } + + if ((rc = setjmp(info->jmpbuf)) == 0) { + qsort(vector, len, sizeof(Jim_Obj *), (qsort_comparator *) fn); + } + Jim_InvalidateStringRep(listObjPtr); + sort_info = prev_info; + + return rc; +} + +static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec) +{ + int currentLen = listPtr->internalRep.listValue.len; + int requiredLen = currentLen + elemc; + int i; + Jim_Obj **point; + + if (requiredLen > listPtr->internalRep.listValue.maxLen) { + listPtr->internalRep.listValue.maxLen = requiredLen * 2; + + listPtr->internalRep.listValue.ele = Jim_Realloc(listPtr->internalRep.listValue.ele, + sizeof(Jim_Obj *) * listPtr->internalRep.listValue.maxLen); + } + if (idx < 0) { + idx = currentLen; + } + point = listPtr->internalRep.listValue.ele + idx; + memmove(point + elemc, point, (currentLen - idx) * sizeof(Jim_Obj *)); + for (i = 0; i < elemc; ++i) { + point[i] = elemVec[i]; + Jim_IncrRefCount(point[i]); + } + listPtr->internalRep.listValue.len += elemc; +} + +static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr) +{ + ListInsertElements(listPtr, -1, 1, &objPtr); +} + +static void ListAppendList(Jim_Obj *listPtr, Jim_Obj *appendListPtr) +{ + ListInsertElements(listPtr, -1, + appendListPtr->internalRep.listValue.len, appendListPtr->internalRep.listValue.ele); +} + +void Jim_ListAppendElement(Jim_Interp *interp, Jim_Obj *listPtr, Jim_Obj *objPtr) +{ + JimPanic((Jim_IsShared(listPtr), "Jim_ListAppendElement called with shared object")); + SetListFromAny(interp, listPtr); + Jim_InvalidateStringRep(listPtr); + ListAppendElement(listPtr, objPtr); +} + +void Jim_ListAppendList(Jim_Interp *interp, Jim_Obj *listPtr, Jim_Obj *appendListPtr) +{ + JimPanic((Jim_IsShared(listPtr), "Jim_ListAppendList called with shared object")); + SetListFromAny(interp, listPtr); + SetListFromAny(interp, appendListPtr); + Jim_InvalidateStringRep(listPtr); + ListAppendList(listPtr, appendListPtr); +} + +int Jim_ListLength(Jim_Interp *interp, Jim_Obj *objPtr) +{ + SetListFromAny(interp, objPtr); + return objPtr->internalRep.listValue.len; +} + +void Jim_ListInsertElements(Jim_Interp *interp, Jim_Obj *listPtr, int idx, + int objc, Jim_Obj *const *objVec) +{ + JimPanic((Jim_IsShared(listPtr), "Jim_ListInsertElement called with shared object")); + SetListFromAny(interp, listPtr); + if (idx >= 0 && idx > listPtr->internalRep.listValue.len) + idx = listPtr->internalRep.listValue.len; + else if (idx < 0) + idx = 0; + Jim_InvalidateStringRep(listPtr); + ListInsertElements(listPtr, idx, objc, objVec); +} + +Jim_Obj *Jim_ListGetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx) +{ + SetListFromAny(interp, listPtr); + if ((idx >= 0 && idx >= listPtr->internalRep.listValue.len) || + (idx < 0 && (-idx - 1) >= listPtr->internalRep.listValue.len)) { + return NULL; + } + if (idx < 0) + idx = listPtr->internalRep.listValue.len + idx; + return listPtr->internalRep.listValue.ele[idx]; +} + +int Jim_ListIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx, Jim_Obj **objPtrPtr, int flags) +{ + *objPtrPtr = Jim_ListGetIndex(interp, listPtr, idx); + if (*objPtrPtr == NULL) { + if (flags & JIM_ERRMSG) { + Jim_SetResultString(interp, "list index out of range", -1); + } + return JIM_ERR; + } + return JIM_OK; +} + +static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx, + Jim_Obj *newObjPtr, int flags) +{ + SetListFromAny(interp, listPtr); + if ((idx >= 0 && idx >= listPtr->internalRep.listValue.len) || + (idx < 0 && (-idx - 1) >= listPtr->internalRep.listValue.len)) { + if (flags & JIM_ERRMSG) { + Jim_SetResultString(interp, "list index out of range", -1); + } + return JIM_ERR; + } + if (idx < 0) + idx = listPtr->internalRep.listValue.len + idx; + Jim_DecrRefCount(interp, listPtr->internalRep.listValue.ele[idx]); + listPtr->internalRep.listValue.ele[idx] = newObjPtr; + Jim_IncrRefCount(newObjPtr); + return JIM_OK; +} + +int Jim_SetListIndex(Jim_Interp *interp, Jim_Obj *varNamePtr, + Jim_Obj *const *indexv, int indexc, Jim_Obj *newObjPtr) +{ + Jim_Obj *varObjPtr, *objPtr, *listObjPtr; + int shared, i, idx; + + varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG | JIM_UNSHARED); + if (objPtr == NULL) + return JIM_ERR; + if ((shared = Jim_IsShared(objPtr))) + varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr); + for (i = 0; i < indexc - 1; i++) { + listObjPtr = objPtr; + if (Jim_GetIndex(interp, indexv[i], &idx) != JIM_OK) + goto err; + if (Jim_ListIndex(interp, listObjPtr, idx, &objPtr, JIM_ERRMSG) != JIM_OK) { + goto err; + } + if (Jim_IsShared(objPtr)) { + objPtr = Jim_DuplicateObj(interp, objPtr); + ListSetIndex(interp, listObjPtr, idx, objPtr, JIM_NONE); + } + Jim_InvalidateStringRep(listObjPtr); + } + if (Jim_GetIndex(interp, indexv[indexc - 1], &idx) != JIM_OK) + goto err; + if (ListSetIndex(interp, objPtr, idx, newObjPtr, JIM_ERRMSG) == JIM_ERR) + goto err; + Jim_InvalidateStringRep(objPtr); + Jim_InvalidateStringRep(varObjPtr); + if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) + goto err; + Jim_SetResult(interp, varObjPtr); + return JIM_OK; + err: + if (shared) { + Jim_FreeNewObj(interp, varObjPtr); + } + return JIM_ERR; +} + +Jim_Obj *Jim_ListJoin(Jim_Interp *interp, Jim_Obj *listObjPtr, const char *joinStr, int joinStrLen) +{ + int i; + int listLen = Jim_ListLength(interp, listObjPtr); + Jim_Obj *resObjPtr = Jim_NewEmptyStringObj(interp); + + for (i = 0; i < listLen; ) { + Jim_Obj *objPtr; + + Jim_ListIndex(interp, listObjPtr, i, &objPtr, JIM_NONE); + Jim_AppendObj(interp, resObjPtr, objPtr); + if (++i != listLen) { + Jim_AppendString(interp, resObjPtr, joinStr, joinStrLen); + } + } + return resObjPtr; +} + +Jim_Obj *Jim_ConcatObj(Jim_Interp *interp, int objc, Jim_Obj *const *objv) +{ + int i; + + for (i = 0; i < objc; i++) { + if (!Jim_IsList(objv[i])) + break; + } + if (i == objc) { + Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); + + for (i = 0; i < objc; i++) + ListAppendList(objPtr, objv[i]); + return objPtr; + } + else { + + int len = 0, objLen; + char *bytes, *p; + + + for (i = 0; i < objc; i++) { + Jim_GetString(objv[i], &objLen); + len += objLen; + } + if (objc) + len += objc - 1; + + p = bytes = Jim_Alloc(len + 1); + for (i = 0; i < objc; i++) { + const char *s = Jim_GetString(objv[i], &objLen); + + + while (objLen && (*s == ' ' || *s == '\t' || *s == '\n')) { + s++; + objLen--; + len--; + } + + while (objLen && (s[objLen - 1] == ' ' || + s[objLen - 1] == '\n' || s[objLen - 1] == '\t')) { + + if (objLen > 1 && s[objLen - 2] == '\\') { + break; + } + objLen--; + len--; + } + memcpy(p, s, objLen); + p += objLen; + if (objLen && i + 1 != objc) { + *p++ = ' '; + } + else if (i + 1 != objc) { + len--; + } + } + *p = '\0'; + return Jim_NewStringObjNoAlloc(interp, bytes, len); + } +} + +Jim_Obj *Jim_ListRange(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *firstObjPtr, + Jim_Obj *lastObjPtr) +{ + int first, last; + int len, rangeLen; + + if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK || + Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK) + return NULL; + len = Jim_ListLength(interp, listObjPtr); + first = JimRelToAbsIndex(len, first); + last = JimRelToAbsIndex(len, last); + JimRelToAbsRange(len, &first, &last, &rangeLen); + if (first == 0 && last == len) { + return listObjPtr; + } + return Jim_NewListObj(interp, listObjPtr->internalRep.listValue.ele + first, rangeLen); +} + +static void FreeDictInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupDictInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static void UpdateStringOfDict(struct Jim_Obj *objPtr); +static int SetDictFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + + +static unsigned int JimObjectHTHashFunction(const void *key) +{ + int len; + const char *str = Jim_GetString((Jim_Obj *)key, &len); + return Jim_GenHashFunction((const unsigned char *)str, len); +} + +static int JimObjectHTKeyCompare(void *privdata, const void *key1, const void *key2) +{ + return Jim_StringEqObj((Jim_Obj *)key1, (Jim_Obj *)key2); +} + +static void JimObjectHTKeyValDestructor(void *interp, void *val) +{ + Jim_DecrRefCount(interp, (Jim_Obj *)val); +} + +static const Jim_HashTableType JimDictHashTableType = { + JimObjectHTHashFunction, + NULL, + NULL, + JimObjectHTKeyCompare, + JimObjectHTKeyValDestructor, + JimObjectHTKeyValDestructor +}; + +static const Jim_ObjType dictObjType = { + "dict", + FreeDictInternalRep, + DupDictInternalRep, + UpdateStringOfDict, + JIM_TYPE_NONE, +}; + +void FreeDictInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + JIM_NOTUSED(interp); + + Jim_FreeHashTable(objPtr->internalRep.ptr); + Jim_Free(objPtr->internalRep.ptr); +} + +void DupDictInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + Jim_HashTable *ht, *dupHt; + Jim_HashTableIterator *htiter; + Jim_HashEntry *he; + + + ht = srcPtr->internalRep.ptr; + dupHt = Jim_Alloc(sizeof(*dupHt)); + Jim_InitHashTable(dupHt, &JimDictHashTableType, interp); + if (ht->size != 0) + Jim_ExpandHashTable(dupHt, ht->size); + + htiter = Jim_GetHashTableIterator(ht); + while ((he = Jim_NextHashEntry(htiter)) != NULL) { + const Jim_Obj *keyObjPtr = he->key; + Jim_Obj *valObjPtr = he->u.val; + + Jim_IncrRefCount((Jim_Obj *)keyObjPtr); + Jim_IncrRefCount(valObjPtr); + Jim_AddHashEntry(dupHt, keyObjPtr, valObjPtr); + } + Jim_FreeHashTableIterator(htiter); + + dupPtr->internalRep.ptr = dupHt; + dupPtr->typePtr = &dictObjType; +} + +static Jim_Obj **JimDictPairs(Jim_Obj *dictPtr, int *len) +{ + Jim_HashTable *ht; + Jim_HashTableIterator *htiter; + Jim_HashEntry *he; + Jim_Obj **objv; + int i; + + ht = dictPtr->internalRep.ptr; + + + objv = Jim_Alloc((ht->used * 2) * sizeof(Jim_Obj *)); + htiter = Jim_GetHashTableIterator(ht); + i = 0; + while ((he = Jim_NextHashEntry(htiter)) != NULL) { + objv[i++] = (Jim_Obj *)he->key; + objv[i++] = he->u.val; + } + *len = i; + Jim_FreeHashTableIterator(htiter); + return objv; +} + +static void UpdateStringOfDict(struct Jim_Obj *objPtr) +{ + + int len; + Jim_Obj **objv = JimDictPairs(objPtr, &len); + + JimMakeListStringRep(objPtr, objv, len); + + Jim_Free(objv); +} + +static int SetDictFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + int listlen; + + if (objPtr->typePtr == &dictObjType) { + return JIM_OK; + } + + Jim_String(objPtr); + + + listlen = Jim_ListLength(interp, objPtr); + if (listlen % 2) { + Jim_SetResultString(interp, "missing value to go with key", -1); + return JIM_ERR; + } + else { + + Jim_HashTable *ht; + int i; + + ht = Jim_Alloc(sizeof(*ht)); + Jim_InitHashTable(ht, &JimDictHashTableType, interp); + + for (i = 0; i < listlen; i += 2) { + Jim_Obj *keyObjPtr; + Jim_Obj *valObjPtr; + + Jim_ListIndex(interp, objPtr, i, &keyObjPtr, JIM_NONE); + Jim_ListIndex(interp, objPtr, i + 1, &valObjPtr, JIM_NONE); + + Jim_IncrRefCount(keyObjPtr); + Jim_IncrRefCount(valObjPtr); + + if (Jim_AddHashEntry(ht, keyObjPtr, valObjPtr) != JIM_OK) { + Jim_HashEntry *he; + + he = Jim_FindHashEntry(ht, keyObjPtr); + Jim_DecrRefCount(interp, keyObjPtr); + + Jim_DecrRefCount(interp, (Jim_Obj *)he->u.val); + he->u.val = valObjPtr; + } + } + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &dictObjType; + objPtr->internalRep.ptr = ht; + + return JIM_OK; + } +} + + + +static int DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr) +{ + Jim_HashTable *ht = objPtr->internalRep.ptr; + + if (valueObjPtr == NULL) { + return Jim_DeleteHashEntry(ht, keyObjPtr); + } + Jim_IncrRefCount(keyObjPtr); + Jim_IncrRefCount(valueObjPtr); + if (Jim_ReplaceHashEntry(ht, keyObjPtr, valueObjPtr)) { + + Jim_DecrRefCount(interp, keyObjPtr); + } + return JIM_OK; +} + +int Jim_DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr) +{ + int retcode; + + JimPanic((Jim_IsShared(objPtr), "Jim_DictAddElement called with shared object")); + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return JIM_ERR; + } + retcode = DictAddElement(interp, objPtr, keyObjPtr, valueObjPtr); + Jim_InvalidateStringRep(objPtr); + return retcode; +} + +Jim_Obj *Jim_NewDictObj(Jim_Interp *interp, Jim_Obj *const *elements, int len) +{ + Jim_Obj *objPtr; + int i; + + JimPanic((len % 2, "Jim_NewDictObj() 'len' argument must be even")); + + objPtr = Jim_NewObj(interp); + objPtr->typePtr = &dictObjType; + objPtr->bytes = NULL; + objPtr->internalRep.ptr = Jim_Alloc(sizeof(Jim_HashTable)); + Jim_InitHashTable(objPtr->internalRep.ptr, &JimDictHashTableType, interp); + for (i = 0; i < len; i += 2) + DictAddElement(interp, objPtr, elements[i], elements[i + 1]); + return objPtr; +} + +int Jim_DictKey(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj *keyPtr, + Jim_Obj **objPtrPtr, int flags) +{ + Jim_HashEntry *he; + Jim_HashTable *ht; + + if (SetDictFromAny(interp, dictPtr) != JIM_OK) { + return -1; + } + ht = dictPtr->internalRep.ptr; + if ((he = Jim_FindHashEntry(ht, keyPtr)) == NULL) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "key \"%#s\" not known in dictionary", keyPtr); + } + return JIM_ERR; + } + *objPtrPtr = he->u.val; + return JIM_OK; +} + + +int Jim_DictPairs(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj ***objPtrPtr, int *len) +{ + if (SetDictFromAny(interp, dictPtr) != JIM_OK) { + return JIM_ERR; + } + *objPtrPtr = JimDictPairs(dictPtr, len); + + return JIM_OK; +} + + + +int Jim_DictKeysVector(Jim_Interp *interp, Jim_Obj *dictPtr, + Jim_Obj *const *keyv, int keyc, Jim_Obj **objPtrPtr, int flags) +{ + int i; + + if (keyc == 0) { + *objPtrPtr = dictPtr; + return JIM_OK; + } + + for (i = 0; i < keyc; i++) { + Jim_Obj *objPtr; + + int rc = Jim_DictKey(interp, dictPtr, keyv[i], &objPtr, flags); + if (rc != JIM_OK) { + return rc; + } + dictPtr = objPtr; + } + *objPtrPtr = dictPtr; + return JIM_OK; +} + +int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr, + Jim_Obj *const *keyv, int keyc, Jim_Obj *newObjPtr, int flags) +{ + Jim_Obj *varObjPtr, *objPtr, *dictObjPtr; + int shared, i; + + varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags); + if (objPtr == NULL) { + if (newObjPtr == NULL && (flags & JIM_MUSTEXIST)) { + + return JIM_ERR; + } + varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0); + if (Jim_SetVariable(interp, varNamePtr, objPtr) != JIM_OK) { + Jim_FreeNewObj(interp, varObjPtr); + return JIM_ERR; + } + } + if ((shared = Jim_IsShared(objPtr))) + varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr); + for (i = 0; i < keyc; i++) { + dictObjPtr = objPtr; + + + if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) { + goto err; + } + + if (i == keyc - 1) { + + if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) { + if (newObjPtr || (flags & JIM_MUSTEXIST)) { + goto err; + } + } + break; + } + + + Jim_InvalidateStringRep(dictObjPtr); + if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr, + newObjPtr ? JIM_NONE : JIM_ERRMSG) == JIM_OK) { + if (Jim_IsShared(objPtr)) { + objPtr = Jim_DuplicateObj(interp, objPtr); + DictAddElement(interp, dictObjPtr, keyv[i], objPtr); + } + } + else { + if (newObjPtr == NULL) { + goto err; + } + objPtr = Jim_NewDictObj(interp, NULL, 0); + DictAddElement(interp, dictObjPtr, keyv[i], objPtr); + } + } + Jim_InvalidateStringRep(objPtr); + Jim_InvalidateStringRep(varObjPtr); + if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) { + goto err; + } + Jim_SetResult(interp, varObjPtr); + return JIM_OK; + err: + if (shared) { + Jim_FreeNewObj(interp, varObjPtr); + } + return JIM_ERR; +} + +static void UpdateStringOfIndex(struct Jim_Obj *objPtr); +static int SetIndexFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType indexObjType = { + "index", + NULL, + NULL, + UpdateStringOfIndex, + JIM_TYPE_NONE, +}; + +void UpdateStringOfIndex(struct Jim_Obj *objPtr) +{ + int len; + char buf[JIM_INTEGER_SPACE + 1]; + + if (objPtr->internalRep.intValue >= 0) + len = sprintf(buf, "%d", objPtr->internalRep.intValue); + else if (objPtr->internalRep.intValue == -1) + len = sprintf(buf, "end"); + else { + len = sprintf(buf, "end%d", objPtr->internalRep.intValue + 1); + } + objPtr->bytes = Jim_Alloc(len + 1); + memcpy(objPtr->bytes, buf, len + 1); + objPtr->length = len; +} + +int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + int idx, end = 0; + const char *str; + char *endptr; + + + str = Jim_String(objPtr); + + + if (strncmp(str, "end", 3) == 0) { + end = 1; + str += 3; + idx = 0; + } + else { + idx = jim_strtol(str, &endptr); + + if (endptr == str) { + goto badindex; + } + str = endptr; + } + + + if (*str == '+' || *str == '-') { + int sign = (*str == '+' ? 1 : -1); + + idx += sign * jim_strtol(++str, &endptr); + if (str == endptr || *endptr) { + goto badindex; + } + str = endptr; + } + + while (isspace(UCHAR(*str))) { + str++; + } + if (*str) { + goto badindex; + } + if (end) { + if (idx > 0) { + idx = INT_MAX; + } + else { + + idx--; + } + } + else if (idx < 0) { + idx = -INT_MAX; + } + + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &indexObjType; + objPtr->internalRep.intValue = idx; + return JIM_OK; + + badindex: + Jim_SetResultFormatted(interp, + "bad index \"%#s\": must be integer?[+-]integer? or end?[+-]integer?", objPtr); + return JIM_ERR; +} + +int Jim_GetIndex(Jim_Interp *interp, Jim_Obj *objPtr, int *indexPtr) +{ + + if (objPtr->typePtr == &intObjType) { + jim_wide val = JimWideValue(objPtr); + + if (!(val < LONG_MIN) && !(val > LONG_MAX)) { + *indexPtr = (val < 0) ? -INT_MAX : (long)val;; + return JIM_OK; + } + } + if (objPtr->typePtr != &indexObjType && SetIndexFromAny(interp, objPtr) == JIM_ERR) + return JIM_ERR; + *indexPtr = objPtr->internalRep.intValue; + return JIM_OK; +} + + + +static const char * const jimReturnCodes[] = { + "ok", + "error", + "return", + "break", + "continue", + "signal", + "exit", + "eval", + NULL +}; + +#define jimReturnCodesSize (sizeof(jimReturnCodes)/sizeof(*jimReturnCodes)) + +static int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr); + +static const Jim_ObjType returnCodeObjType = { + "return-code", + NULL, + NULL, + NULL, + JIM_TYPE_NONE, +}; + +const char *Jim_ReturnCode(int code) +{ + if (code < 0 || code >= (int)jimReturnCodesSize) { + return "?"; + } + else { + return jimReturnCodes[code]; + } +} + +int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + int returnCode; + jim_wide wideValue; + + + if (JimGetWideNoErr(interp, objPtr, &wideValue) != JIM_ERR) + returnCode = (int)wideValue; + else if (Jim_GetEnum(interp, objPtr, jimReturnCodes, &returnCode, NULL, JIM_NONE) != JIM_OK) { + Jim_SetResultFormatted(interp, "expected return code but got \"%#s\"", objPtr); + return JIM_ERR; + } + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &returnCodeObjType; + objPtr->internalRep.intValue = returnCode; + return JIM_OK; +} + +int Jim_GetReturnCode(Jim_Interp *interp, Jim_Obj *objPtr, int *intPtr) +{ + if (objPtr->typePtr != &returnCodeObjType && SetReturnCodeFromAny(interp, objPtr) == JIM_ERR) + return JIM_ERR; + *intPtr = objPtr->internalRep.intValue; + return JIM_OK; +} + +static int JimParseExprOperator(struct JimParserCtx *pc); +static int JimParseExprNumber(struct JimParserCtx *pc); +static int JimParseExprIrrational(struct JimParserCtx *pc); + + + + +enum +{ + + + JIM_EXPROP_MUL = JIM_TT_EXPR_OP, + JIM_EXPROP_DIV, + JIM_EXPROP_MOD, + JIM_EXPROP_SUB, + JIM_EXPROP_ADD, + JIM_EXPROP_LSHIFT, + JIM_EXPROP_RSHIFT, + JIM_EXPROP_ROTL, + JIM_EXPROP_ROTR, + JIM_EXPROP_LT, + JIM_EXPROP_GT, + JIM_EXPROP_LTE, + JIM_EXPROP_GTE, + JIM_EXPROP_NUMEQ, + JIM_EXPROP_NUMNE, + JIM_EXPROP_BITAND, + JIM_EXPROP_BITXOR, + JIM_EXPROP_BITOR, + + + JIM_EXPROP_LOGICAND, + JIM_EXPROP_LOGICAND_LEFT, + JIM_EXPROP_LOGICAND_RIGHT, + + + JIM_EXPROP_LOGICOR, + JIM_EXPROP_LOGICOR_LEFT, + JIM_EXPROP_LOGICOR_RIGHT, + + + + JIM_EXPROP_TERNARY, + JIM_EXPROP_TERNARY_LEFT, + JIM_EXPROP_TERNARY_RIGHT, + + + JIM_EXPROP_COLON, + JIM_EXPROP_COLON_LEFT, + JIM_EXPROP_COLON_RIGHT, + + JIM_EXPROP_POW, + + + JIM_EXPROP_STREQ, + JIM_EXPROP_STRNE, + JIM_EXPROP_STRIN, + JIM_EXPROP_STRNI, + + + JIM_EXPROP_NOT, + JIM_EXPROP_BITNOT, + JIM_EXPROP_UNARYMINUS, + JIM_EXPROP_UNARYPLUS, + + + JIM_EXPROP_FUNC_FIRST, + JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST, + JIM_EXPROP_FUNC_ABS, + JIM_EXPROP_FUNC_DOUBLE, + JIM_EXPROP_FUNC_ROUND, + JIM_EXPROP_FUNC_RAND, + JIM_EXPROP_FUNC_SRAND, + + + JIM_EXPROP_FUNC_SIN, + JIM_EXPROP_FUNC_COS, + JIM_EXPROP_FUNC_TAN, + JIM_EXPROP_FUNC_ASIN, + JIM_EXPROP_FUNC_ACOS, + JIM_EXPROP_FUNC_ATAN, + JIM_EXPROP_FUNC_SINH, + JIM_EXPROP_FUNC_COSH, + JIM_EXPROP_FUNC_TANH, + JIM_EXPROP_FUNC_CEIL, + JIM_EXPROP_FUNC_FLOOR, + JIM_EXPROP_FUNC_EXP, + JIM_EXPROP_FUNC_LOG, + JIM_EXPROP_FUNC_LOG10, + JIM_EXPROP_FUNC_SQRT, + JIM_EXPROP_FUNC_POW, +}; + +struct JimExprState +{ + Jim_Obj **stack; + int stacklen; + int opcode; + int skip; +}; + + +typedef struct Jim_ExprOperator +{ + const char *name; + int precedence; + int arity; + int (*funcop) (Jim_Interp *interp, struct JimExprState * e); + int lazy; +} Jim_ExprOperator; + +static void ExprPush(struct JimExprState *e, Jim_Obj *obj) +{ + Jim_IncrRefCount(obj); + e->stack[e->stacklen++] = obj; +} + +static Jim_Obj *ExprPop(struct JimExprState *e) +{ + return e->stack[--e->stacklen]; +} + +static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprState *e) +{ + int intresult = 0; + int rc = JIM_OK; + Jim_Obj *A = ExprPop(e); + double dA, dC = 0; + jim_wide wA, wC = 0; + + if ((A->typePtr != &doubleObjType || A->bytes) && JimGetWideNoErr(interp, A, &wA) == JIM_OK) { + intresult = 1; + + switch (e->opcode) { + case JIM_EXPROP_FUNC_INT: + wC = wA; + break; + case JIM_EXPROP_FUNC_ROUND: + wC = wA; + break; + case JIM_EXPROP_FUNC_DOUBLE: + dC = wA; + intresult = 0; + break; + case JIM_EXPROP_FUNC_ABS: + wC = wA >= 0 ? wA : -wA; + break; + case JIM_EXPROP_UNARYMINUS: + wC = -wA; + break; + case JIM_EXPROP_UNARYPLUS: + wC = wA; + break; + case JIM_EXPROP_NOT: + wC = !wA; + break; + default: + abort(); + } + } + else if ((rc = Jim_GetDouble(interp, A, &dA)) == JIM_OK) { + switch (e->opcode) { + case JIM_EXPROP_FUNC_INT: + wC = dA; + intresult = 1; + break; + case JIM_EXPROP_FUNC_ROUND: + wC = dA < 0 ? (dA - 0.5) : (dA + 0.5); + intresult = 1; + break; + case JIM_EXPROP_FUNC_DOUBLE: + dC = dA; + break; + case JIM_EXPROP_FUNC_ABS: + dC = dA >= 0 ? dA : -dA; + break; + case JIM_EXPROP_UNARYMINUS: + dC = -dA; + break; + case JIM_EXPROP_UNARYPLUS: + dC = dA; + break; + case JIM_EXPROP_NOT: + wC = !dA; + intresult = 1; + break; + default: + abort(); + } + } + + if (rc == JIM_OK) { + if (intresult) { + ExprPush(e, Jim_NewIntObj(interp, wC)); + } + else { + ExprPush(e, Jim_NewDoubleObj(interp, dC)); + } + } + + Jim_DecrRefCount(interp, A); + + return rc; +} + +static double JimRandDouble(Jim_Interp *interp) +{ + unsigned long x; + JimRandomBytes(interp, &x, sizeof(x)); + + return (double)x / (unsigned long)~0; +} + +static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *A = ExprPop(e); + jim_wide wA; + + int rc = Jim_GetWide(interp, A, &wA); + if (rc == JIM_OK) { + switch (e->opcode) { + case JIM_EXPROP_BITNOT: + ExprPush(e, Jim_NewIntObj(interp, ~wA)); + break; + case JIM_EXPROP_FUNC_SRAND: + JimPrngSeed(interp, (unsigned char *)&wA, sizeof(wA)); + ExprPush(e, Jim_NewDoubleObj(interp, JimRandDouble(interp))); + break; + default: + abort(); + } + } + + Jim_DecrRefCount(interp, A); + + return rc; +} + +static int JimExprOpNone(Jim_Interp *interp, struct JimExprState *e) +{ + JimPanic((e->opcode != JIM_EXPROP_FUNC_RAND, "JimExprOpNone only support rand()")); + + ExprPush(e, Jim_NewDoubleObj(interp, JimRandDouble(interp))); + + return JIM_OK; +} + +#ifdef JIM_MATH_FUNCTIONS +static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprState *e) +{ + int rc; + Jim_Obj *A = ExprPop(e); + double dA, dC; + + rc = Jim_GetDouble(interp, A, &dA); + if (rc == JIM_OK) { + switch (e->opcode) { + case JIM_EXPROP_FUNC_SIN: + dC = sin(dA); + break; + case JIM_EXPROP_FUNC_COS: + dC = cos(dA); + break; + case JIM_EXPROP_FUNC_TAN: + dC = tan(dA); + break; + case JIM_EXPROP_FUNC_ASIN: + dC = asin(dA); + break; + case JIM_EXPROP_FUNC_ACOS: + dC = acos(dA); + break; + case JIM_EXPROP_FUNC_ATAN: + dC = atan(dA); + break; + case JIM_EXPROP_FUNC_SINH: + dC = sinh(dA); + break; + case JIM_EXPROP_FUNC_COSH: + dC = cosh(dA); + break; + case JIM_EXPROP_FUNC_TANH: + dC = tanh(dA); + break; + case JIM_EXPROP_FUNC_CEIL: + dC = ceil(dA); + break; + case JIM_EXPROP_FUNC_FLOOR: + dC = floor(dA); + break; + case JIM_EXPROP_FUNC_EXP: + dC = exp(dA); + break; + case JIM_EXPROP_FUNC_LOG: + dC = log(dA); + break; + case JIM_EXPROP_FUNC_LOG10: + dC = log10(dA); + break; + case JIM_EXPROP_FUNC_SQRT: + dC = sqrt(dA); + break; + default: + abort(); + } + ExprPush(e, Jim_NewDoubleObj(interp, dC)); + } + + Jim_DecrRefCount(interp, A); + + return rc; +} +#endif + + +static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *B = ExprPop(e); + Jim_Obj *A = ExprPop(e); + jim_wide wA, wB; + int rc = JIM_ERR; + + if (Jim_GetWide(interp, A, &wA) == JIM_OK && Jim_GetWide(interp, B, &wB) == JIM_OK) { + jim_wide wC; + + rc = JIM_OK; + + switch (e->opcode) { + case JIM_EXPROP_LSHIFT: + wC = wA << wB; + break; + case JIM_EXPROP_RSHIFT: + wC = wA >> wB; + break; + case JIM_EXPROP_BITAND: + wC = wA & wB; + break; + case JIM_EXPROP_BITXOR: + wC = wA ^ wB; + break; + case JIM_EXPROP_BITOR: + wC = wA | wB; + break; + case JIM_EXPROP_MOD: + if (wB == 0) { + wC = 0; + Jim_SetResultString(interp, "Division by zero", -1); + rc = JIM_ERR; + } + else { + int negative = 0; + + if (wB < 0) { + wB = -wB; + wA = -wA; + negative = 1; + } + wC = wA % wB; + if (wC < 0) { + wC += wB; + } + if (negative) { + wC = -wC; + } + } + break; + case JIM_EXPROP_ROTL: + case JIM_EXPROP_ROTR:{ + + unsigned long uA = (unsigned long)wA; + unsigned long uB = (unsigned long)wB; + const unsigned int S = sizeof(unsigned long) * 8; + + + uB %= S; + + if (e->opcode == JIM_EXPROP_ROTR) { + uB = S - uB; + } + wC = (unsigned long)(uA << uB) | (uA >> (S - uB)); + break; + } + default: + abort(); + } + ExprPush(e, Jim_NewIntObj(interp, wC)); + + } + + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, B); + + return rc; +} + + + +static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) +{ + int intresult = 0; + int rc = JIM_OK; + double dA, dB, dC = 0; + jim_wide wA, wB, wC = 0; + + Jim_Obj *B = ExprPop(e); + Jim_Obj *A = ExprPop(e); + + if ((A->typePtr != &doubleObjType || A->bytes) && + (B->typePtr != &doubleObjType || B->bytes) && + JimGetWideNoErr(interp, A, &wA) == JIM_OK && JimGetWideNoErr(interp, B, &wB) == JIM_OK) { + + + + intresult = 1; + + switch (e->opcode) { + case JIM_EXPROP_POW: + case JIM_EXPROP_FUNC_POW: + wC = JimPowWide(wA, wB); + break; + case JIM_EXPROP_ADD: + wC = wA + wB; + break; + case JIM_EXPROP_SUB: + wC = wA - wB; + break; + case JIM_EXPROP_MUL: + wC = wA * wB; + break; + case JIM_EXPROP_DIV: + if (wB == 0) { + Jim_SetResultString(interp, "Division by zero", -1); + rc = JIM_ERR; + } + else { + if (wB < 0) { + wB = -wB; + wA = -wA; + } + wC = wA / wB; + if (wA % wB < 0) { + wC--; + } + } + break; + case JIM_EXPROP_LT: + wC = wA < wB; + break; + case JIM_EXPROP_GT: + wC = wA > wB; + break; + case JIM_EXPROP_LTE: + wC = wA <= wB; + break; + case JIM_EXPROP_GTE: + wC = wA >= wB; + break; + case JIM_EXPROP_NUMEQ: + wC = wA == wB; + break; + case JIM_EXPROP_NUMNE: + wC = wA != wB; + break; + default: + abort(); + } + } + else if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) { + switch (e->opcode) { + case JIM_EXPROP_POW: + case JIM_EXPROP_FUNC_POW: +#ifdef JIM_MATH_FUNCTIONS + dC = pow(dA, dB); +#else + Jim_SetResultString(interp, "unsupported", -1); + rc = JIM_ERR; +#endif + break; + case JIM_EXPROP_ADD: + dC = dA + dB; + break; + case JIM_EXPROP_SUB: + dC = dA - dB; + break; + case JIM_EXPROP_MUL: + dC = dA * dB; + break; + case JIM_EXPROP_DIV: + if (dB == 0) { +#ifdef INFINITY + dC = dA < 0 ? -INFINITY : INFINITY; +#else + dC = (dA < 0 ? -1.0 : 1.0) * strtod("Inf", NULL); +#endif + } + else { + dC = dA / dB; + } + break; + case JIM_EXPROP_LT: + wC = dA < dB; + intresult = 1; + break; + case JIM_EXPROP_GT: + wC = dA > dB; + intresult = 1; + break; + case JIM_EXPROP_LTE: + wC = dA <= dB; + intresult = 1; + break; + case JIM_EXPROP_GTE: + wC = dA >= dB; + intresult = 1; + break; + case JIM_EXPROP_NUMEQ: + wC = dA == dB; + intresult = 1; + break; + case JIM_EXPROP_NUMNE: + wC = dA != dB; + intresult = 1; + break; + default: + abort(); + } + } + else { + + + + int i = Jim_StringCompareObj(interp, A, B, 0); + + intresult = 1; + + switch (e->opcode) { + case JIM_EXPROP_LT: + wC = i < 0; + break; + case JIM_EXPROP_GT: + wC = i > 0; + break; + case JIM_EXPROP_LTE: + wC = i <= 0; + break; + case JIM_EXPROP_GTE: + wC = i >= 0; + break; + case JIM_EXPROP_NUMEQ: + wC = i == 0; + break; + case JIM_EXPROP_NUMNE: + wC = i != 0; + break; + default: + rc = JIM_ERR; + break; + } + } + + if (rc == JIM_OK) { + if (intresult) { + ExprPush(e, Jim_NewIntObj(interp, wC)); + } + else { + ExprPush(e, Jim_NewDoubleObj(interp, dC)); + } + } + + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, B); + + return rc; +} + +static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj) +{ + int listlen; + int i; + + listlen = Jim_ListLength(interp, listObjPtr); + for (i = 0; i < listlen; i++) { + Jim_Obj *objPtr; + + Jim_ListIndex(interp, listObjPtr, i, &objPtr, JIM_NONE); + + if (Jim_StringEqObj(objPtr, valObj)) { + return 1; + } + } + return 0; +} + +static int JimExprOpStrBin(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *B = ExprPop(e); + Jim_Obj *A = ExprPop(e); + + jim_wide wC; + + switch (e->opcode) { + case JIM_EXPROP_STREQ: + case JIM_EXPROP_STRNE: { + int Alen, Blen; + const char *sA = Jim_GetString(A, &Alen); + const char *sB = Jim_GetString(B, &Blen); + + if (e->opcode == JIM_EXPROP_STREQ) { + wC = (Alen == Blen && memcmp(sA, sB, Alen) == 0); + } + else { + wC = (Alen != Blen || memcmp(sA, sB, Alen) != 0); + } + break; + } + case JIM_EXPROP_STRIN: + wC = JimSearchList(interp, B, A); + break; + case JIM_EXPROP_STRNI: + wC = !JimSearchList(interp, B, A); + break; + default: + abort(); + } + ExprPush(e, Jim_NewIntObj(interp, wC)); + + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, B); + + return JIM_OK; +} + +static int ExprBool(Jim_Interp *interp, Jim_Obj *obj) +{ + long l; + double d; + + if (Jim_GetLong(interp, obj, &l) == JIM_OK) { + return l != 0; + } + if (Jim_GetDouble(interp, obj, &d) == JIM_OK) { + return d != 0; + } + return -1; +} + +static int JimExprOpAndLeft(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *skip = ExprPop(e); + Jim_Obj *A = ExprPop(e); + int rc = JIM_OK; + + switch (ExprBool(interp, A)) { + case 0: + + e->skip = JimWideValue(skip); + ExprPush(e, Jim_NewIntObj(interp, 0)); + break; + + case 1: + + break; + + case -1: + + rc = JIM_ERR; + } + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, skip); + + return rc; +} + +static int JimExprOpOrLeft(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *skip = ExprPop(e); + Jim_Obj *A = ExprPop(e); + int rc = JIM_OK; + + switch (ExprBool(interp, A)) { + case 0: + + break; + + case 1: + + e->skip = JimWideValue(skip); + ExprPush(e, Jim_NewIntObj(interp, 1)); + break; + + case -1: + + rc = JIM_ERR; + break; + } + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, skip); + + return rc; +} + +static int JimExprOpAndOrRight(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *A = ExprPop(e); + int rc = JIM_OK; + + switch (ExprBool(interp, A)) { + case 0: + ExprPush(e, Jim_NewIntObj(interp, 0)); + break; + + case 1: + ExprPush(e, Jim_NewIntObj(interp, 1)); + break; + + case -1: + + rc = JIM_ERR; + break; + } + Jim_DecrRefCount(interp, A); + + return rc; +} + +static int JimExprOpTernaryLeft(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *skip = ExprPop(e); + Jim_Obj *A = ExprPop(e); + int rc = JIM_OK; + + + ExprPush(e, A); + + switch (ExprBool(interp, A)) { + case 0: + + e->skip = JimWideValue(skip); + + ExprPush(e, Jim_NewIntObj(interp, 0)); + break; + + case 1: + + break; + + case -1: + + rc = JIM_ERR; + break; + } + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, skip); + + return rc; +} + +static int JimExprOpColonLeft(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *skip = ExprPop(e); + Jim_Obj *B = ExprPop(e); + Jim_Obj *A = ExprPop(e); + + + if (ExprBool(interp, A)) { + + e->skip = JimWideValue(skip); + + ExprPush(e, B); + } + + Jim_DecrRefCount(interp, skip); + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, B); + return JIM_OK; +} + +static int JimExprOpNull(Jim_Interp *interp, struct JimExprState *e) +{ + return JIM_OK; +} + +enum +{ + LAZY_NONE, + LAZY_OP, + LAZY_LEFT, + LAZY_RIGHT +}; + +static const struct Jim_ExprOperator Jim_ExprOperators[] = { + {"*", 200, 2, JimExprOpBin, LAZY_NONE}, + {"/", 200, 2, JimExprOpBin, LAZY_NONE}, + {"%", 200, 2, JimExprOpIntBin, LAZY_NONE}, + + {"-", 100, 2, JimExprOpBin, LAZY_NONE}, + {"+", 100, 2, JimExprOpBin, LAZY_NONE}, + + {"<<", 90, 2, JimExprOpIntBin, LAZY_NONE}, + {">>", 90, 2, JimExprOpIntBin, LAZY_NONE}, + + {"<<<", 90, 2, JimExprOpIntBin, LAZY_NONE}, + {">>>", 90, 2, JimExprOpIntBin, LAZY_NONE}, + + {"<", 80, 2, JimExprOpBin, LAZY_NONE}, + {">", 80, 2, JimExprOpBin, LAZY_NONE}, + {"<=", 80, 2, JimExprOpBin, LAZY_NONE}, + {">=", 80, 2, JimExprOpBin, LAZY_NONE}, + + {"==", 70, 2, JimExprOpBin, LAZY_NONE}, + {"!=", 70, 2, JimExprOpBin, LAZY_NONE}, + + {"&", 50, 2, JimExprOpIntBin, LAZY_NONE}, + {"^", 49, 2, JimExprOpIntBin, LAZY_NONE}, + {"|", 48, 2, JimExprOpIntBin, LAZY_NONE}, + + {"&&", 10, 2, NULL, LAZY_OP}, + {NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT}, + {NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT}, + + {"||", 9, 2, NULL, LAZY_OP}, + {NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT}, + {NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT}, + + {"?", 5, 2, JimExprOpNull, LAZY_OP}, + {NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT}, + {NULL, 5, 2, JimExprOpNull, LAZY_RIGHT}, + + {":", 5, 2, JimExprOpNull, LAZY_OP}, + {NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT}, + {NULL, 5, 2, JimExprOpNull, LAZY_RIGHT}, + + {"**", 250, 2, JimExprOpBin, LAZY_NONE}, + + {"eq", 60, 2, JimExprOpStrBin, LAZY_NONE}, + {"ne", 60, 2, JimExprOpStrBin, LAZY_NONE}, + + {"in", 55, 2, JimExprOpStrBin, LAZY_NONE}, + {"ni", 55, 2, JimExprOpStrBin, LAZY_NONE}, + + {"!", 300, 1, JimExprOpNumUnary, LAZY_NONE}, + {"~", 300, 1, JimExprOpIntUnary, LAZY_NONE}, + {NULL, 300, 1, JimExprOpNumUnary, LAZY_NONE}, + {NULL, 300, 1, JimExprOpNumUnary, LAZY_NONE}, + + + + {"int", 400, 1, JimExprOpNumUnary, LAZY_NONE}, + {"abs", 400, 1, JimExprOpNumUnary, LAZY_NONE}, + {"double", 400, 1, JimExprOpNumUnary, LAZY_NONE}, + {"round", 400, 1, JimExprOpNumUnary, LAZY_NONE}, + {"rand", 400, 0, JimExprOpNone, LAZY_NONE}, + {"srand", 400, 1, JimExprOpIntUnary, LAZY_NONE}, + +#ifdef JIM_MATH_FUNCTIONS + {"sin", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"cos", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"tan", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"asin", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"acos", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"atan", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"sinh", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"cosh", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"tanh", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"ceil", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"floor", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"exp", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"log", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"log10", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"sqrt", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, + {"pow", 400, 2, JimExprOpBin, LAZY_NONE}, +#endif +}; + +#define JIM_EXPR_OPERATORS_NUM \ + (sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator)) + +static int JimParseExpression(struct JimParserCtx *pc) +{ + + while (isspace(UCHAR(*pc->p)) || (*(pc->p) == '\\' && *(pc->p + 1) == '\n')) { + if (*pc->p == '\n') { + pc->linenr++; + } + pc->p++; + pc->len--; + } + + if (pc->len == 0) { + pc->tstart = pc->tend = pc->p; + pc->tline = pc->linenr; + pc->tt = JIM_TT_EOL; + pc->eof = 1; + return JIM_OK; + } + switch (*(pc->p)) { + case '(': + pc->tt = JIM_TT_SUBEXPR_START; + goto singlechar; + case ')': + pc->tt = JIM_TT_SUBEXPR_END; + goto singlechar; + case ',': + pc->tt = JIM_TT_SUBEXPR_COMMA; +singlechar: + pc->tstart = pc->tend = pc->p; + pc->tline = pc->linenr; + pc->p++; + pc->len--; + break; + case '[': + return JimParseCmd(pc); + case '$': + if (JimParseVar(pc) == JIM_ERR) + return JimParseExprOperator(pc); + else { + + if (pc->tt == JIM_TT_EXPRSUGAR) { + return JIM_ERR; + } + return JIM_OK; + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '.': + return JimParseExprNumber(pc); + case '"': + return JimParseQuote(pc); + case '{': + return JimParseBrace(pc); + + case 'N': + case 'I': + case 'n': + case 'i': + if (JimParseExprIrrational(pc) == JIM_ERR) + return JimParseExprOperator(pc); + break; + default: + return JimParseExprOperator(pc); + break; + } + return JIM_OK; +} + +static int JimParseExprNumber(struct JimParserCtx *pc) +{ + int allowdot = 1; + int base = 10; + + + pc->tt = JIM_TT_EXPR_INT; + pc->tstart = pc->p; + pc->tline = pc->linenr; + + + if (pc->p[0] == '0') { + switch (pc->p[1]) { + case 'x': + case 'X': + base = 16; + allowdot = 0; + pc->p += 2; + pc->len -= 2; + break; + case 'o': + case 'O': + base = 8; + allowdot = 0; + pc->p += 2; + pc->len -= 2; + break; + case 'b': + case 'B': + base = 2; + allowdot = 0; + pc->p += 2; + pc->len -= 2; + break; + } + } + + while (isdigit(UCHAR(*pc->p)) + || (base == 16 && isxdigit(UCHAR(*pc->p))) + || (base == 8 && *pc->p >= '0' && *pc->p <= '7') + || (base == 2 && (*pc->p == '0' || *pc->p == '1')) + || (allowdot && *pc->p == '.') + ) { + if (*pc->p == '.') { + allowdot = 0; + pc->tt = JIM_TT_EXPR_DOUBLE; + } + pc->p++; + pc->len--; + if (base == 10 && (*pc->p == 'e' || *pc->p == 'E') && (pc->p[1] == '-' || pc->p[1] == '+' + || isdigit(UCHAR(pc->p[1])))) { + pc->p += 2; + pc->len -= 2; + pc->tt = JIM_TT_EXPR_DOUBLE; + } + } + pc->tend = pc->p - 1; + return JIM_OK; +} + +static int JimParseExprIrrational(struct JimParserCtx *pc) +{ + const char *Tokens[] = { "NaN", "nan", "NAN", "Inf", "inf", "INF", NULL }; + const char **token; + + for (token = Tokens; *token != NULL; token++) { + int len = strlen(*token); + + if (strncmp(*token, pc->p, len) == 0) { + pc->tstart = pc->p; + pc->tend = pc->p + len - 1; + pc->p += len; + pc->len -= len; + pc->tline = pc->linenr; + pc->tt = JIM_TT_EXPR_DOUBLE; + return JIM_OK; + } + } + return JIM_ERR; +} + +static int JimParseExprOperator(struct JimParserCtx *pc) +{ + int i; + int bestIdx = -1, bestLen = 0; + + + for (i = 0; i < (signed)JIM_EXPR_OPERATORS_NUM; i++) { + const char *opname; + int oplen; + + opname = Jim_ExprOperators[i].name; + if (opname == NULL) { + continue; + } + oplen = strlen(opname); + + if (strncmp(opname, pc->p, oplen) == 0 && oplen > bestLen) { + bestIdx = i + JIM_TT_EXPR_OP; + bestLen = oplen; + } + } + if (bestIdx == -1) { + return JIM_ERR; + } + + + if (bestIdx >= JIM_EXPROP_FUNC_FIRST) { + const char *p = pc->p + bestLen; + int len = pc->len - bestLen; + + while (len && isspace(UCHAR(*p))) { + len--; + p++; + } + if (*p != '(') { + return JIM_ERR; + } + } + pc->tstart = pc->p; + pc->tend = pc->p + bestLen - 1; + pc->p += bestLen; + pc->len -= bestLen; + pc->tline = pc->linenr; + + pc->tt = bestIdx; + return JIM_OK; +} + +static const struct Jim_ExprOperator *JimExprOperatorInfoByOpcode(int opcode) +{ + static Jim_ExprOperator dummy_op; + if (opcode < JIM_TT_EXPR_OP) { + return &dummy_op; + } + return &Jim_ExprOperators[opcode - JIM_TT_EXPR_OP]; +} + +const char *jim_tt_name(int type) +{ + static const char * const tt_names[JIM_TT_EXPR_OP] = + { "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", ",,,", "INT", + "DBL", "$()" }; + if (type < JIM_TT_EXPR_OP) { + return tt_names[type]; + } + else { + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(type); + static char buf[20]; + + if (op->name) { + return op->name; + } + sprintf(buf, "(%d)", type); + return buf; + } +} + +static void FreeExprInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType exprObjType = { + "expression", + FreeExprInternalRep, + DupExprInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + + +typedef struct ExprByteCode +{ + int len; + ScriptToken *token; + int inUse; +} ExprByteCode; + +static void ExprFreeByteCode(Jim_Interp *interp, ExprByteCode * expr) +{ + int i; + + for (i = 0; i < expr->len; i++) { + Jim_DecrRefCount(interp, expr->token[i].objPtr); + } + Jim_Free(expr->token); + Jim_Free(expr); +} + +static void FreeExprInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + ExprByteCode *expr = (void *)objPtr->internalRep.ptr; + + if (expr) { + if (--expr->inUse != 0) { + return; + } + + ExprFreeByteCode(interp, expr); + } +} + +static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + JIM_NOTUSED(interp); + JIM_NOTUSED(srcPtr); + + + dupPtr->typePtr = NULL; +} + + +static int ExprCheckCorrectness(ExprByteCode * expr) +{ + int i; + int stacklen = 0; + int ternary = 0; + + for (i = 0; i < expr->len; i++) { + ScriptToken *t = &expr->token[i]; + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type); + + stacklen -= op->arity; + if (stacklen < 0) { + break; + } + if (t->type == JIM_EXPROP_TERNARY || t->type == JIM_EXPROP_TERNARY_LEFT) { + ternary++; + } + else if (t->type == JIM_EXPROP_COLON || t->type == JIM_EXPROP_COLON_LEFT) { + ternary--; + } + + + stacklen++; + } + if (stacklen != 1 || ternary != 0) { + return JIM_ERR; + } + return JIM_OK; +} + +static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t) +{ + int i; + + int leftindex, arity, offset; + + + leftindex = expr->len - 1; + + arity = 1; + while (arity) { + ScriptToken *tt = &expr->token[leftindex]; + + if (tt->type >= JIM_TT_EXPR_OP) { + arity += JimExprOperatorInfoByOpcode(tt->type)->arity; + } + arity--; + if (--leftindex < 0) { + return JIM_ERR; + } + } + leftindex++; + + + memmove(&expr->token[leftindex + 2], &expr->token[leftindex], + sizeof(*expr->token) * (expr->len - leftindex)); + expr->len += 2; + offset = (expr->len - leftindex) - 1; + + expr->token[leftindex + 1].type = t->type + 1; + expr->token[leftindex + 1].objPtr = interp->emptyObj; + + expr->token[leftindex].type = JIM_TT_EXPR_INT; + expr->token[leftindex].objPtr = Jim_NewIntObj(interp, offset); + + + expr->token[expr->len].objPtr = interp->emptyObj; + expr->token[expr->len].type = t->type + 2; + expr->len++; + + + for (i = leftindex - 1; i > 0; i--) { + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(expr->token[i].type); + if (op->lazy == LAZY_LEFT) { + if (JimWideValue(expr->token[i - 1].objPtr) + i - 1 >= leftindex) { + JimWideValue(expr->token[i - 1].objPtr) += 2; + } + } + } + return JIM_OK; +} + +static int ExprAddOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t) +{ + struct ScriptToken *token = &expr->token[expr->len]; + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type); + + if (op->lazy == LAZY_OP) { + if (ExprAddLazyOperator(interp, expr, t) != JIM_OK) { + Jim_SetResultFormatted(interp, "Expression has bad operands to %s", op->name); + return JIM_ERR; + } + } + else { + token->objPtr = interp->emptyObj; + token->type = t->type; + expr->len++; + } + return JIM_OK; +} + +static int ExprTernaryGetColonLeftIndex(ExprByteCode *expr, int right_index) +{ + int ternary_count = 1; + + right_index--; + + while (right_index > 1) { + if (expr->token[right_index].type == JIM_EXPROP_TERNARY_LEFT) { + ternary_count--; + } + else if (expr->token[right_index].type == JIM_EXPROP_COLON_RIGHT) { + ternary_count++; + } + else if (expr->token[right_index].type == JIM_EXPROP_COLON_LEFT && ternary_count == 1) { + return right_index; + } + right_index--; + } + + + return -1; +} + +static int ExprTernaryGetMoveIndices(ExprByteCode *expr, int right_index, int *prev_right_index, int *prev_left_index) +{ + int i = right_index - 1; + int ternary_count = 1; + + while (i > 1) { + if (expr->token[i].type == JIM_EXPROP_TERNARY_LEFT) { + if (--ternary_count == 0 && expr->token[i - 2].type == JIM_EXPROP_COLON_RIGHT) { + *prev_right_index = i - 2; + *prev_left_index = ExprTernaryGetColonLeftIndex(expr, *prev_right_index); + return 1; + } + } + else if (expr->token[i].type == JIM_EXPROP_COLON_RIGHT) { + if (ternary_count == 0) { + return 0; + } + ternary_count++; + } + i--; + } + return 0; +} + +static void ExprTernaryReorderExpression(Jim_Interp *interp, ExprByteCode *expr) +{ + int i; + + for (i = expr->len - 1; i > 1; i--) { + int prev_right_index; + int prev_left_index; + int j; + ScriptToken tmp; + + if (expr->token[i].type != JIM_EXPROP_COLON_RIGHT) { + continue; + } + + + if (ExprTernaryGetMoveIndices(expr, i, &prev_right_index, &prev_left_index) == 0) { + continue; + } + + tmp = expr->token[prev_right_index]; + for (j = prev_right_index; j < i; j++) { + expr->token[j] = expr->token[j + 1]; + } + expr->token[i] = tmp; + + JimWideValue(expr->token[prev_left_index-1].objPtr) += (i - prev_right_index); + + + i++; + } +} + +static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *fileNameObj) +{ + Jim_Stack stack; + ExprByteCode *expr; + int ok = 1; + int i; + int prevtt = JIM_TT_NONE; + int have_ternary = 0; + + + int count = tokenlist->count - 1; + + expr = Jim_Alloc(sizeof(*expr)); + expr->inUse = 1; + expr->len = 0; + + Jim_InitStack(&stack); + + for (i = 0; i < tokenlist->count; i++) { + ParseToken *t = &tokenlist->list[i]; + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type); + + if (op->lazy == LAZY_OP) { + count += 2; + + if (t->type == JIM_EXPROP_TERNARY) { + have_ternary = 1; + } + } + } + + expr->token = Jim_Alloc(sizeof(ScriptToken) * count); + + for (i = 0; i < tokenlist->count && ok; i++) { + ParseToken *t = &tokenlist->list[i]; + + + struct ScriptToken *token = &expr->token[expr->len]; + + if (t->type == JIM_TT_EOL) { + break; + } + + switch (t->type) { + case JIM_TT_STR: + case JIM_TT_ESC: + case JIM_TT_VAR: + case JIM_TT_DICTSUGAR: + case JIM_TT_EXPRSUGAR: + case JIM_TT_CMD: + token->type = t->type; +strexpr: + token->objPtr = Jim_NewStringObj(interp, t->token, t->len); + if (t->type == JIM_TT_CMD) { + + JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line); + } + expr->len++; + break; + + case JIM_TT_EXPR_INT: + case JIM_TT_EXPR_DOUBLE: + { + char *endptr; + if (t->type == JIM_TT_EXPR_INT) { + token->objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr)); + } + else { + token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr)); + } + if (endptr != t->token + t->len) { + + Jim_FreeNewObj(interp, token->objPtr); + token->type = JIM_TT_STR; + goto strexpr; + } + token->type = t->type; + expr->len++; + } + break; + + case JIM_TT_SUBEXPR_START: + Jim_StackPush(&stack, t); + prevtt = JIM_TT_NONE; + continue; + + case JIM_TT_SUBEXPR_COMMA: + + continue; + + case JIM_TT_SUBEXPR_END: + ok = 0; + while (Jim_StackLen(&stack)) { + ParseToken *tt = Jim_StackPop(&stack); + + if (tt->type == JIM_TT_SUBEXPR_START) { + ok = 1; + break; + } + + if (ExprAddOperator(interp, expr, tt) != JIM_OK) { + goto err; + } + } + if (!ok) { + Jim_SetResultString(interp, "Unexpected close parenthesis", -1); + goto err; + } + break; + + + default:{ + + const struct Jim_ExprOperator *op; + ParseToken *tt; + + + if (prevtt == JIM_TT_NONE || prevtt >= JIM_TT_EXPR_OP) { + if (t->type == JIM_EXPROP_SUB) { + t->type = JIM_EXPROP_UNARYMINUS; + } + else if (t->type == JIM_EXPROP_ADD) { + t->type = JIM_EXPROP_UNARYPLUS; + } + } + + op = JimExprOperatorInfoByOpcode(t->type); + + + while ((tt = Jim_StackPeek(&stack)) != NULL) { + const struct Jim_ExprOperator *tt_op = + JimExprOperatorInfoByOpcode(tt->type); + + + + if (op->arity != 1 && tt_op->precedence >= op->precedence) { + if (ExprAddOperator(interp, expr, tt) != JIM_OK) { + ok = 0; + goto err; + } + Jim_StackPop(&stack); + } + else { + break; + } + } + Jim_StackPush(&stack, t); + break; + } + } + prevtt = t->type; + } + + + while (Jim_StackLen(&stack)) { + ParseToken *tt = Jim_StackPop(&stack); + + if (tt->type == JIM_TT_SUBEXPR_START) { + ok = 0; + Jim_SetResultString(interp, "Missing close parenthesis", -1); + goto err; + } + if (ExprAddOperator(interp, expr, tt) != JIM_OK) { + ok = 0; + goto err; + } + } + + if (have_ternary) { + ExprTernaryReorderExpression(interp, expr); + } + + err: + + Jim_FreeStack(&stack); + + for (i = 0; i < expr->len; i++) { + Jim_IncrRefCount(expr->token[i].objPtr); + } + + if (!ok) { + ExprFreeByteCode(interp, expr); + return NULL; + } + + return expr; +} + + +static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + int exprTextLen; + const char *exprText; + struct JimParserCtx parser; + struct ExprByteCode *expr; + ParseTokenList tokenlist; + int line; + Jim_Obj *fileNameObj; + int rc = JIM_ERR; + + + if (objPtr->typePtr == &sourceObjType) { + fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; + line = objPtr->internalRep.sourceValue.lineNumber; + } + else { + fileNameObj = interp->emptyObj; + line = 1; + } + Jim_IncrRefCount(fileNameObj); + + exprText = Jim_GetString(objPtr, &exprTextLen); + + + ScriptTokenListInit(&tokenlist); + + JimParserInit(&parser, exprText, exprTextLen, line); + while (!parser.eof) { + if (JimParseExpression(&parser) != JIM_OK) { + ScriptTokenListFree(&tokenlist); + invalidexpr: + Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr); + expr = NULL; + goto err; + } + + ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, + parser.tline); + } + +#ifdef DEBUG_SHOW_EXPR_TOKENS + { + int i; + printf("==== Expr Tokens ====\n"); + for (i = 0; i < tokenlist.count; i++) { + printf("[%2d]@%d %s '%.*s'\n", i, tokenlist.list[i].line, jim_tt_name(tokenlist.list[i].type), + tokenlist.list[i].len, tokenlist.list[i].token); + } + } +#endif + + + expr = ExprCreateByteCode(interp, &tokenlist, fileNameObj); + + + ScriptTokenListFree(&tokenlist); + + if (!expr) { + goto err; + } + +#ifdef DEBUG_SHOW_EXPR + { + int i; + + printf("==== Expr ====\n"); + for (i = 0; i < expr->len; i++) { + ScriptToken *t = &expr->token[i]; + + printf("[%2d] %s '%s'\n", i, jim_tt_name(t->type), Jim_String(t->objPtr)); + } + } +#endif + + + if (ExprCheckCorrectness(expr) != JIM_OK) { + ExprFreeByteCode(interp, expr); + goto invalidexpr; + } + + rc = JIM_OK; + + err: + + Jim_DecrRefCount(interp, fileNameObj); + Jim_FreeIntRep(interp, objPtr); + Jim_SetIntRepPtr(objPtr, expr); + objPtr->typePtr = &exprObjType; + return rc; +} + +static ExprByteCode *JimGetExpression(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr->typePtr != &exprObjType) { + if (SetExprFromAny(interp, objPtr) != JIM_OK) { + return NULL; + } + } + return (ExprByteCode *) Jim_GetIntRepPtr(objPtr); +} + +#define JIM_EE_STATICSTACK_LEN 10 + +int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr) +{ + ExprByteCode *expr; + Jim_Obj *staticStack[JIM_EE_STATICSTACK_LEN]; + int i; + int retcode = JIM_OK; + struct JimExprState e; + + expr = JimGetExpression(interp, exprObjPtr); + if (!expr) { + return JIM_ERR; + } + +#ifdef JIM_OPTIMIZATION + { + Jim_Obj *objPtr; + + + switch (expr->len) { + case 1: + if (expr->token[0].type == JIM_TT_EXPR_INT) { + *exprResultPtrPtr = expr->token[0].objPtr; + Jim_IncrRefCount(*exprResultPtrPtr); + return JIM_OK; + } + if (expr->token[0].type == JIM_TT_VAR) { + objPtr = Jim_GetVariable(interp, expr->token[0].objPtr, JIM_ERRMSG); + if (objPtr) { + *exprResultPtrPtr = objPtr; + Jim_IncrRefCount(*exprResultPtrPtr); + return JIM_OK; + } + } + break; + + case 2: + if (expr->token[1].type == JIM_EXPROP_NOT && expr->token[0].type == JIM_TT_VAR) { + jim_wide wideValue; + + objPtr = Jim_GetVariable(interp, expr->token[0].objPtr, JIM_NONE); + if (objPtr && JimIsWide(objPtr) + && Jim_GetWide(interp, objPtr, &wideValue) == JIM_OK) { + *exprResultPtrPtr = wideValue ? interp->falseObj : interp->trueObj; + Jim_IncrRefCount(*exprResultPtrPtr); + return JIM_OK; + } + } + break; + + case 3: + if (expr->token[0].type == JIM_TT_VAR && (expr->token[1].type == JIM_TT_EXPR_INT + || expr->token[1].type == JIM_TT_VAR)) { + switch (expr->token[2].type) { + case JIM_EXPROP_LT: + case JIM_EXPROP_LTE: + case JIM_EXPROP_GT: + case JIM_EXPROP_GTE: + case JIM_EXPROP_NUMEQ: + case JIM_EXPROP_NUMNE:{ + + jim_wide wideValueA; + jim_wide wideValueB; + + objPtr = Jim_GetVariable(interp, expr->token[0].objPtr, JIM_NONE); + if (objPtr && JimIsWide(objPtr) + && Jim_GetWide(interp, objPtr, &wideValueA) == JIM_OK) { + if (expr->token[1].type == JIM_TT_VAR) { + objPtr = + Jim_GetVariable(interp, expr->token[1].objPtr, + JIM_NONE); + } + else { + objPtr = expr->token[1].objPtr; + } + if (objPtr && JimIsWide(objPtr) + && Jim_GetWide(interp, objPtr, &wideValueB) == JIM_OK) { + int cmpRes; + + switch (expr->token[2].type) { + case JIM_EXPROP_LT: + cmpRes = wideValueA < wideValueB; + break; + case JIM_EXPROP_LTE: + cmpRes = wideValueA <= wideValueB; + break; + case JIM_EXPROP_GT: + cmpRes = wideValueA > wideValueB; + break; + case JIM_EXPROP_GTE: + cmpRes = wideValueA >= wideValueB; + break; + case JIM_EXPROP_NUMEQ: + cmpRes = wideValueA == wideValueB; + break; + case JIM_EXPROP_NUMNE: + cmpRes = wideValueA != wideValueB; + break; + default: + cmpRes = 0; + } + *exprResultPtrPtr = + cmpRes ? interp->trueObj : interp->falseObj; + Jim_IncrRefCount(*exprResultPtrPtr); + return JIM_OK; + } + } + } + } + } + break; + } + } +#endif + + expr->inUse++; + + + + if (expr->len > JIM_EE_STATICSTACK_LEN) + e.stack = Jim_Alloc(sizeof(Jim_Obj *) * expr->len); + else + e.stack = staticStack; + + e.stacklen = 0; + + + for (i = 0; i < expr->len && retcode == JIM_OK; i++) { + Jim_Obj *objPtr; + + switch (expr->token[i].type) { + case JIM_TT_EXPR_INT: + case JIM_TT_EXPR_DOUBLE: + case JIM_TT_STR: + ExprPush(&e, expr->token[i].objPtr); + break; + + case JIM_TT_VAR: + objPtr = Jim_GetVariable(interp, expr->token[i].objPtr, JIM_ERRMSG); + if (objPtr) { + ExprPush(&e, objPtr); + } + else { + retcode = JIM_ERR; + } + break; + + case JIM_TT_DICTSUGAR: + objPtr = JimExpandDictSugar(interp, expr->token[i].objPtr); + if (objPtr) { + ExprPush(&e, objPtr); + } + else { + retcode = JIM_ERR; + } + break; + + case JIM_TT_ESC: + retcode = Jim_SubstObj(interp, expr->token[i].objPtr, &objPtr, JIM_NONE); + if (retcode == JIM_OK) { + ExprPush(&e, objPtr); + } + break; + + case JIM_TT_CMD: + retcode = Jim_EvalObj(interp, expr->token[i].objPtr); + if (retcode == JIM_OK) { + ExprPush(&e, Jim_GetResult(interp)); + } + break; + + default:{ + + e.skip = 0; + e.opcode = expr->token[i].type; + + retcode = JimExprOperatorInfoByOpcode(e.opcode)->funcop(interp, &e); + + i += e.skip; + continue; + } + } + } + + expr->inUse--; + + if (retcode == JIM_OK) { + *exprResultPtrPtr = ExprPop(&e); + } + else { + for (i = 0; i < e.stacklen; i++) { + Jim_DecrRefCount(interp, e.stack[i]); + } + } + if (e.stack != staticStack) { + Jim_Free(e.stack); + } + return retcode; +} + +int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr) +{ + int retcode; + jim_wide wideValue; + double doubleValue; + Jim_Obj *exprResultPtr; + + retcode = Jim_EvalExpression(interp, exprObjPtr, &exprResultPtr); + if (retcode != JIM_OK) + return retcode; + + if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) { + if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK) { + Jim_DecrRefCount(interp, exprResultPtr); + return JIM_ERR; + } + else { + Jim_DecrRefCount(interp, exprResultPtr); + *boolPtr = doubleValue != 0; + return JIM_OK; + } + } + *boolPtr = wideValue != 0; + + Jim_DecrRefCount(interp, exprResultPtr); + return JIM_OK; +} + + + + +typedef struct ScanFmtPartDescr +{ + char type; + char modifier; + size_t width; + int pos; + char *arg; + char *prefix; +} ScanFmtPartDescr; + + +typedef struct ScanFmtStringObj +{ + jim_wide size; + char *stringRep; + size_t count; + size_t convCount; + size_t maxPos; + const char *error; + char *scratch; + ScanFmtPartDescr descr[1]; +} ScanFmtStringObj; + + +static void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static void UpdateStringOfScanFmt(Jim_Obj *objPtr); + +static const Jim_ObjType scanFmtStringObjType = { + "scanformatstring", + FreeScanFmtInternalRep, + DupScanFmtInternalRep, + UpdateStringOfScanFmt, + JIM_TYPE_NONE, +}; + +void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + JIM_NOTUSED(interp); + Jim_Free((char *)objPtr->internalRep.ptr); + objPtr->internalRep.ptr = 0; +} + +void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + size_t size = (size_t) ((ScanFmtStringObj *) srcPtr->internalRep.ptr)->size; + ScanFmtStringObj *newVec = (ScanFmtStringObj *) Jim_Alloc(size); + + JIM_NOTUSED(interp); + memcpy(newVec, srcPtr->internalRep.ptr, size); + dupPtr->internalRep.ptr = newVec; + dupPtr->typePtr = &scanFmtStringObjType; +} + +void UpdateStringOfScanFmt(Jim_Obj *objPtr) +{ + char *bytes = ((ScanFmtStringObj *) objPtr->internalRep.ptr)->stringRep; + + objPtr->bytes = Jim_StrDup(bytes); + objPtr->length = strlen(bytes); +} + + +static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + ScanFmtStringObj *fmtObj; + char *buffer; + int maxCount, i, approxSize, lastPos = -1; + const char *fmt = objPtr->bytes; + int maxFmtLen = objPtr->length; + const char *fmtEnd = fmt + maxFmtLen; + int curr; + + Jim_FreeIntRep(interp, objPtr); + + for (i = 0, maxCount = 0; i < maxFmtLen; ++i) + if (fmt[i] == '%') + ++maxCount; + + approxSize = sizeof(ScanFmtStringObj) + +(maxCount + 1) * sizeof(ScanFmtPartDescr) + +maxFmtLen * sizeof(char) + 3 + 1 + + maxFmtLen * sizeof(char) + 1 + + maxFmtLen * sizeof(char) + +(maxCount + 1) * sizeof(char) + +1; + fmtObj = (ScanFmtStringObj *) Jim_Alloc(approxSize); + memset(fmtObj, 0, approxSize); + fmtObj->size = approxSize; + fmtObj->maxPos = 0; + fmtObj->scratch = (char *)&fmtObj->descr[maxCount + 1]; + fmtObj->stringRep = fmtObj->scratch + maxFmtLen + 3 + 1; + memcpy(fmtObj->stringRep, fmt, maxFmtLen); + buffer = fmtObj->stringRep + maxFmtLen + 1; + objPtr->internalRep.ptr = fmtObj; + objPtr->typePtr = &scanFmtStringObjType; + for (i = 0, curr = 0; fmt < fmtEnd; ++fmt) { + int width = 0, skip; + ScanFmtPartDescr *descr = &fmtObj->descr[curr]; + + fmtObj->count++; + descr->width = 0; + + if (*fmt != '%' || fmt[1] == '%') { + descr->type = 0; + descr->prefix = &buffer[i]; + for (; fmt < fmtEnd; ++fmt) { + if (*fmt == '%') { + if (fmt[1] != '%') + break; + ++fmt; + } + buffer[i++] = *fmt; + } + buffer[i++] = 0; + } + + ++fmt; + + if (fmt >= fmtEnd) + goto done; + descr->pos = 0; + if (*fmt == '*') { + descr->pos = -1; + ++fmt; + } + else + fmtObj->convCount++; + + if (sscanf(fmt, "%d%n", &width, &skip) == 1) { + fmt += skip; + + if (descr->pos != -1 && *fmt == '$') { + int prev; + + ++fmt; + descr->pos = width; + width = 0; + + if ((lastPos == 0 && descr->pos > 0) + || (lastPos > 0 && descr->pos == 0)) { + fmtObj->error = "cannot mix \"%\" and \"%n$\" conversion specifiers"; + return JIM_ERR; + } + + for (prev = 0; prev < curr; ++prev) { + if (fmtObj->descr[prev].pos == -1) + continue; + if (fmtObj->descr[prev].pos == descr->pos) { + fmtObj->error = + "variable is assigned by multiple \"%n$\" conversion specifiers"; + return JIM_ERR; + } + } + + if (sscanf(fmt, "%d%n", &width, &skip) == 1) { + descr->width = width; + fmt += skip; + } + if (descr->pos > 0 && (size_t) descr->pos > fmtObj->maxPos) + fmtObj->maxPos = descr->pos; + } + else { + + descr->width = width; + } + } + + if (lastPos == -1) + lastPos = descr->pos; + + if (*fmt == '[') { + int swapped = 1, beg = i, end, j; + + descr->type = '['; + descr->arg = &buffer[i]; + ++fmt; + if (*fmt == '^') + buffer[i++] = *fmt++; + if (*fmt == ']') + buffer[i++] = *fmt++; + while (*fmt && *fmt != ']') + buffer[i++] = *fmt++; + if (*fmt != ']') { + fmtObj->error = "unmatched [ in format string"; + return JIM_ERR; + } + end = i; + buffer[i++] = 0; + + while (swapped) { + swapped = 0; + for (j = beg + 1; j < end - 1; ++j) { + if (buffer[j] == '-' && buffer[j - 1] > buffer[j + 1]) { + char tmp = buffer[j - 1]; + + buffer[j - 1] = buffer[j + 1]; + buffer[j + 1] = tmp; + swapped = 1; + } + } + } + } + else { + + if (strchr("hlL", *fmt) != 0) + descr->modifier = tolower((int)*fmt++); + + descr->type = *fmt; + if (strchr("efgcsndoxui", *fmt) == 0) { + fmtObj->error = "bad scan conversion character"; + return JIM_ERR; + } + else if (*fmt == 'c' && descr->width != 0) { + fmtObj->error = "field width may not be specified in %c " "conversion"; + return JIM_ERR; + } + else if (*fmt == 'u' && descr->modifier == 'l') { + fmtObj->error = "unsigned wide not supported"; + return JIM_ERR; + } + } + curr++; + } + done: + return JIM_OK; +} + + + +#define FormatGetCnvCount(_fo_) \ + ((ScanFmtStringObj*)((_fo_)->internalRep.ptr))->convCount +#define FormatGetMaxPos(_fo_) \ + ((ScanFmtStringObj*)((_fo_)->internalRep.ptr))->maxPos +#define FormatGetError(_fo_) \ + ((ScanFmtStringObj*)((_fo_)->internalRep.ptr))->error + +static Jim_Obj *JimScanAString(Jim_Interp *interp, const char *sdescr, const char *str) +{ + char *buffer = Jim_StrDup(str); + char *p = buffer; + + while (*str) { + int c; + int n; + + if (!sdescr && isspace(UCHAR(*str))) + break; + + n = utf8_tounicode(str, &c); + if (sdescr && !JimCharsetMatch(sdescr, c, JIM_CHARSET_SCAN)) + break; + while (n--) + *p++ = *str++; + } + *p = 0; + return Jim_NewStringObjNoAlloc(interp, buffer, p - buffer); +} + + +static int ScanOneEntry(Jim_Interp *interp, const char *str, int pos, int strLen, + ScanFmtStringObj * fmtObj, long idx, Jim_Obj **valObjPtr) +{ + const char *tok; + const ScanFmtPartDescr *descr = &fmtObj->descr[idx]; + size_t scanned = 0; + size_t anchor = pos; + int i; + Jim_Obj *tmpObj = NULL; + + + *valObjPtr = 0; + if (descr->prefix) { + + for (i = 0; pos < strLen && descr->prefix[i]; ++i) { + + if (isspace(UCHAR(descr->prefix[i]))) + while (pos < strLen && isspace(UCHAR(str[pos]))) + ++pos; + else if (descr->prefix[i] != str[pos]) + break; + else + ++pos; + } + if (pos >= strLen) { + return -1; + } + else if (descr->prefix[i] != 0) + return 0; + } + + if (descr->type != 'c' && descr->type != '[' && descr->type != 'n') + while (isspace(UCHAR(str[pos]))) + ++pos; + + scanned = pos - anchor; + + + if (descr->type == 'n') { + + *valObjPtr = Jim_NewIntObj(interp, anchor + scanned); + } + else if (pos >= strLen) { + + return -1; + } + else if (descr->type == 'c') { + int c; + scanned += utf8_tounicode(&str[pos], &c); + *valObjPtr = Jim_NewIntObj(interp, c); + return scanned; + } + else { + + if (descr->width > 0) { + size_t sLen = utf8_strlen(&str[pos], strLen - pos); + size_t tLen = descr->width > sLen ? sLen : descr->width; + + tmpObj = Jim_NewStringObjUtf8(interp, str + pos, tLen); + tok = tmpObj->bytes; + } + else { + + tok = &str[pos]; + } + switch (descr->type) { + case 'd': + case 'o': + case 'x': + case 'u': + case 'i':{ + char *endp; + jim_wide w; + + int base = descr->type == 'o' ? 8 + : descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10; + + + if (base == 0) { + w = jim_strtoull(tok, &endp); + } + else { + w = strtoull(tok, &endp, base); + } + + if (endp != tok) { + + *valObjPtr = Jim_NewIntObj(interp, w); + + + scanned += endp - tok; + } + else { + scanned = *tok ? 0 : -1; + } + break; + } + case 's': + case '[':{ + *valObjPtr = JimScanAString(interp, descr->arg, tok); + scanned += Jim_Length(*valObjPtr); + break; + } + case 'e': + case 'f': + case 'g':{ + char *endp; + double value = strtod(tok, &endp); + + if (endp != tok) { + + *valObjPtr = Jim_NewDoubleObj(interp, value); + + scanned += endp - tok; + } + else { + scanned = *tok ? 0 : -1; + } + break; + } + } + if (tmpObj) { + Jim_FreeNewObj(interp, tmpObj); + } + } + return scanned; +} + + +Jim_Obj *Jim_ScanString(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *fmtObjPtr, int flags) +{ + size_t i, pos; + int scanned = 1; + const char *str = Jim_String(strObjPtr); + int strLen = Jim_Utf8Length(interp, strObjPtr); + Jim_Obj *resultList = 0; + Jim_Obj **resultVec = 0; + int resultc; + Jim_Obj *emptyStr = 0; + ScanFmtStringObj *fmtObj; + + + JimPanic((fmtObjPtr->typePtr != &scanFmtStringObjType, "Jim_ScanString() for non-scan format")); + + fmtObj = (ScanFmtStringObj *) fmtObjPtr->internalRep.ptr; + + if (fmtObj->error != 0) { + if (flags & JIM_ERRMSG) + Jim_SetResultString(interp, fmtObj->error, -1); + return 0; + } + + emptyStr = Jim_NewEmptyStringObj(interp); + Jim_IncrRefCount(emptyStr); + + resultList = Jim_NewListObj(interp, NULL, 0); + if (fmtObj->maxPos > 0) { + for (i = 0; i < fmtObj->maxPos; ++i) + Jim_ListAppendElement(interp, resultList, emptyStr); + JimListGetElements(interp, resultList, &resultc, &resultVec); + } + + for (i = 0, pos = 0; i < fmtObj->count; ++i) { + ScanFmtPartDescr *descr = &(fmtObj->descr[i]); + Jim_Obj *value = 0; + + + if (descr->type == 0) + continue; + + if (scanned > 0) + scanned = ScanOneEntry(interp, str, pos, strLen, fmtObj, i, &value); + + if (scanned == -1 && i == 0) + goto eof; + + pos += scanned; + + + if (value == 0) + value = Jim_NewEmptyStringObj(interp); + + if (descr->pos == -1) { + Jim_FreeNewObj(interp, value); + } + else if (descr->pos == 0) + + Jim_ListAppendElement(interp, resultList, value); + else if (resultVec[descr->pos - 1] == emptyStr) { + + Jim_DecrRefCount(interp, resultVec[descr->pos - 1]); + Jim_IncrRefCount(value); + resultVec[descr->pos - 1] = value; + } + else { + + Jim_FreeNewObj(interp, value); + goto err; + } + } + Jim_DecrRefCount(interp, emptyStr); + return resultList; + eof: + Jim_DecrRefCount(interp, emptyStr); + Jim_FreeNewObj(interp, resultList); + return (Jim_Obj *)EOF; + err: + Jim_DecrRefCount(interp, emptyStr); + Jim_FreeNewObj(interp, resultList); + return 0; +} + + +static void JimPrngInit(Jim_Interp *interp) +{ +#define PRNG_SEED_SIZE 256 + int i; + unsigned int *seed; + time_t t = time(NULL); + + interp->prngState = Jim_Alloc(sizeof(Jim_PrngState)); + + seed = Jim_Alloc(PRNG_SEED_SIZE * sizeof(*seed)); + for (i = 0; i < PRNG_SEED_SIZE; i++) { + seed[i] = (rand() ^ t ^ clock()); + } + JimPrngSeed(interp, (unsigned char *)seed, PRNG_SEED_SIZE * sizeof(*seed)); + Jim_Free(seed); +} + + +static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len) +{ + Jim_PrngState *prng; + unsigned char *destByte = (unsigned char *)dest; + unsigned int si, sj, x; + + + if (interp->prngState == NULL) + JimPrngInit(interp); + prng = interp->prngState; + + for (x = 0; x < len; x++) { + prng->i = (prng->i + 1) & 0xff; + si = prng->sbox[prng->i]; + prng->j = (prng->j + si) & 0xff; + sj = prng->sbox[prng->j]; + prng->sbox[prng->i] = sj; + prng->sbox[prng->j] = si; + *destByte++ = prng->sbox[(si + sj) & 0xff]; + } +} + + +static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen) +{ + int i; + Jim_PrngState *prng; + + + if (interp->prngState == NULL) + JimPrngInit(interp); + prng = interp->prngState; + + + for (i = 0; i < 256; i++) + prng->sbox[i] = i; + + for (i = 0; i < seedLen; i++) { + unsigned char t; + + t = prng->sbox[i & 0xFF]; + prng->sbox[i & 0xFF] = prng->sbox[seed[i]]; + prng->sbox[seed[i]] = t; + } + prng->i = prng->j = 0; + + for (i = 0; i < 256; i += seedLen) { + JimRandomBytes(interp, seed, seedLen); + } +} + + +static int Jim_IncrCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_wide wideValue, increment = 1; + Jim_Obj *intObjPtr; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?increment?"); + return JIM_ERR; + } + if (argc == 3) { + if (Jim_GetWide(interp, argv[2], &increment) != JIM_OK) + return JIM_ERR; + } + intObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); + if (!intObjPtr) { + + wideValue = 0; + } + else if (Jim_GetWide(interp, intObjPtr, &wideValue) != JIM_OK) { + return JIM_ERR; + } + if (!intObjPtr || Jim_IsShared(intObjPtr)) { + intObjPtr = Jim_NewIntObj(interp, wideValue + increment); + if (Jim_SetVariable(interp, argv[1], intObjPtr) != JIM_OK) { + Jim_FreeNewObj(interp, intObjPtr); + return JIM_ERR; + } + } + else { + + Jim_InvalidateStringRep(intObjPtr); + JimWideValue(intObjPtr) = wideValue + increment; + + if (argv[1]->typePtr != &variableObjType) { + + Jim_SetVariable(interp, argv[1], intObjPtr); + } + } + Jim_SetResult(interp, intObjPtr); + return JIM_OK; +} + + +#define JIM_EVAL_SARGV_LEN 8 +#define JIM_EVAL_SINTV_LEN 8 + + +static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retcode; + + if (interp->unknown_called > 50) { + return JIM_ERR; + } + + + + if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL) + return JIM_ERR; + + interp->unknown_called++; + + retcode = Jim_EvalObjPrefix(interp, interp->unknown, argc, argv); + interp->unknown_called--; + + return retcode; +} + +static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv) +{ + int retcode; + Jim_Cmd *cmdPtr = Jim_GetCommand(interp, objv[0], JIM_ERRMSG); + + if (cmdPtr == NULL) { + return JimUnknown(interp, objc, objv); + } + if (interp->evalDepth == interp->maxEvalDepth) { + Jim_SetResultString(interp, "Infinite eval recursion", -1); + return JIM_ERR; + } + interp->evalDepth++; + + + JimIncrCmdRefCount(cmdPtr); + Jim_SetEmptyResult(interp); + if (cmdPtr->isproc) { + retcode = JimCallProcedure(interp, cmdPtr, objc, objv); + } + else { + interp->cmdPrivData = cmdPtr->u.native.privData; + retcode = cmdPtr->u.native.cmdProc(interp, objc, objv); + } + JimDecrCmdRefCount(interp, cmdPtr); + interp->evalDepth--; + + return retcode; +} + +int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv) +{ + int i, retcode; + + + for (i = 0; i < objc; i++) + Jim_IncrRefCount(objv[i]); + + retcode = JimInvokeCommand(interp, objc, objv); + + + for (i = 0; i < objc; i++) + Jim_DecrRefCount(interp, objv[i]); + + return retcode; +} + +int Jim_EvalObjPrefix(Jim_Interp *interp, Jim_Obj *prefix, int objc, Jim_Obj *const *objv) +{ + int ret; + Jim_Obj **nargv = Jim_Alloc((objc + 1) * sizeof(*nargv)); + + nargv[0] = prefix; + memcpy(&nargv[1], &objv[0], sizeof(nargv[0]) * objc); + ret = Jim_EvalObjVector(interp, objc + 1, nargv); + Jim_Free(nargv); + return ret; +} + +static void JimAddErrorToStack(Jim_Interp *interp, int retcode, ScriptObj *script) +{ + int rc = retcode; + + if (rc == JIM_ERR && !interp->errorFlag) { + + interp->errorFlag = 1; + Jim_IncrRefCount(script->fileNameObj); + Jim_DecrRefCount(interp, interp->errorFileNameObj); + interp->errorFileNameObj = script->fileNameObj; + interp->errorLine = script->linenr; + + JimResetStackTrace(interp); + + interp->addStackTrace++; + } + + + if (rc == JIM_ERR && interp->addStackTrace > 0) { + + + JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr); + + if (Jim_Length(script->fileNameObj)) { + interp->addStackTrace = 0; + } + + Jim_DecrRefCount(interp, interp->errorProc); + interp->errorProc = interp->emptyObj; + Jim_IncrRefCount(interp->errorProc); + } + else if (rc == JIM_RETURN && interp->returnCode == JIM_ERR) { + + } + else { + interp->addStackTrace = 0; + } +} + +static int JimSubstOneToken(Jim_Interp *interp, const ScriptToken *token, Jim_Obj **objPtrPtr) +{ + Jim_Obj *objPtr; + + switch (token->type) { + case JIM_TT_STR: + case JIM_TT_ESC: + objPtr = token->objPtr; + break; + case JIM_TT_VAR: + objPtr = Jim_GetVariable(interp, token->objPtr, JIM_ERRMSG); + break; + case JIM_TT_DICTSUGAR: + objPtr = JimExpandDictSugar(interp, token->objPtr); + break; + case JIM_TT_EXPRSUGAR: + objPtr = JimExpandExprSugar(interp, token->objPtr); + break; + case JIM_TT_CMD: + switch (Jim_EvalObj(interp, token->objPtr)) { + case JIM_OK: + case JIM_RETURN: + objPtr = interp->result; + break; + case JIM_BREAK: + + return JIM_BREAK; + case JIM_CONTINUE: + + return JIM_CONTINUE; + default: + return JIM_ERR; + } + break; + default: + JimPanic((1, + "default token type (%d) reached " "in Jim_SubstObj().", token->type)); + objPtr = NULL; + break; + } + if (objPtr) { + *objPtrPtr = objPtr; + return JIM_OK; + } + return JIM_ERR; +} + +static Jim_Obj *JimInterpolateTokens(Jim_Interp *interp, const ScriptToken * token, int tokens, int flags) +{ + int totlen = 0, i; + Jim_Obj **intv; + Jim_Obj *sintv[JIM_EVAL_SINTV_LEN]; + Jim_Obj *objPtr; + char *s; + + if (tokens <= JIM_EVAL_SINTV_LEN) + intv = sintv; + else + intv = Jim_Alloc(sizeof(Jim_Obj *) * tokens); + + for (i = 0; i < tokens; i++) { + switch (JimSubstOneToken(interp, &token[i], &intv[i])) { + case JIM_OK: + case JIM_RETURN: + break; + case JIM_BREAK: + if (flags & JIM_SUBST_FLAG) { + + tokens = i; + continue; + } + + + case JIM_CONTINUE: + if (flags & JIM_SUBST_FLAG) { + intv[i] = NULL; + continue; + } + + + default: + while (i--) { + Jim_DecrRefCount(interp, intv[i]); + } + if (intv != sintv) { + Jim_Free(intv); + } + return NULL; + } + Jim_IncrRefCount(intv[i]); + Jim_String(intv[i]); + totlen += intv[i]->length; + } + + + if (tokens == 1 && intv[0] && intv == sintv) { + Jim_DecrRefCount(interp, intv[0]); + return intv[0]; + } + + objPtr = Jim_NewStringObjNoAlloc(interp, NULL, 0); + + if (tokens == 4 && token[0].type == JIM_TT_ESC && token[1].type == JIM_TT_ESC + && token[2].type == JIM_TT_VAR) { + + objPtr->typePtr = &interpolatedObjType; + objPtr->internalRep.dictSubstValue.varNameObjPtr = token[0].objPtr; + objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2]; + Jim_IncrRefCount(intv[2]); + } + + s = objPtr->bytes = Jim_Alloc(totlen + 1); + objPtr->length = totlen; + for (i = 0; i < tokens; i++) { + if (intv[i]) { + memcpy(s, intv[i]->bytes, intv[i]->length); + s += intv[i]->length; + Jim_DecrRefCount(interp, intv[i]); + } + } + objPtr->bytes[totlen] = '\0'; + + if (intv != sintv) { + Jim_Free(intv); + } + + return objPtr; +} + + +static int JimEvalObjList(Jim_Interp *interp, Jim_Obj *listPtr) +{ + int retcode = JIM_OK; + + if (listPtr->internalRep.listValue.len) { + Jim_IncrRefCount(listPtr); + retcode = JimInvokeCommand(interp, + listPtr->internalRep.listValue.len, + listPtr->internalRep.listValue.ele); + Jim_DecrRefCount(interp, listPtr); + } + return retcode; +} + +int Jim_EvalObjList(Jim_Interp *interp, Jim_Obj *listPtr) +{ + SetListFromAny(interp, listPtr); + return JimEvalObjList(interp, listPtr); +} + +int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) +{ + int i; + ScriptObj *script; + ScriptToken *token; + int retcode = JIM_OK; + Jim_Obj *sargv[JIM_EVAL_SARGV_LEN], **argv = NULL; + Jim_Obj *prevScriptObj; + + if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) { + return JimEvalObjList(interp, scriptObjPtr); + } + + Jim_IncrRefCount(scriptObjPtr); + script = Jim_GetScript(interp, scriptObjPtr); + + Jim_SetEmptyResult(interp); + + token = script->token; + +#ifdef JIM_OPTIMIZATION + if (script->len == 0) { + Jim_DecrRefCount(interp, scriptObjPtr); + return JIM_OK; + } + if (script->len == 3 + && token[1].objPtr->typePtr == &commandObjType + && token[1].objPtr->internalRep.cmdValue.cmdPtr->isproc == 0 + && token[1].objPtr->internalRep.cmdValue.cmdPtr->u.native.cmdProc == Jim_IncrCoreCommand + && token[2].objPtr->typePtr == &variableObjType) { + + Jim_Obj *objPtr = Jim_GetVariable(interp, token[2].objPtr, JIM_NONE); + + if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) { + JimWideValue(objPtr)++; + Jim_InvalidateStringRep(objPtr); + Jim_DecrRefCount(interp, scriptObjPtr); + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + } +#endif + + script->inUse++; + + + prevScriptObj = interp->currentScriptObj; + interp->currentScriptObj = scriptObjPtr; + + interp->errorFlag = 0; + argv = sargv; + + for (i = 0; i < script->len && retcode == JIM_OK; ) { + int argc; + int j; + + + argc = token[i].objPtr->internalRep.scriptLineValue.argc; + script->linenr = token[i].objPtr->internalRep.scriptLineValue.line; + + + if (argc > JIM_EVAL_SARGV_LEN) + argv = Jim_Alloc(sizeof(Jim_Obj *) * argc); + + + i++; + + for (j = 0; j < argc; j++) { + long wordtokens = 1; + int expand = 0; + Jim_Obj *wordObjPtr = NULL; + + if (token[i].type == JIM_TT_WORD) { + wordtokens = JimWideValue(token[i++].objPtr); + if (wordtokens < 0) { + expand = 1; + wordtokens = -wordtokens; + } + } + + if (wordtokens == 1) { + + switch (token[i].type) { + case JIM_TT_ESC: + case JIM_TT_STR: + wordObjPtr = token[i].objPtr; + break; + case JIM_TT_VAR: + wordObjPtr = Jim_GetVariable(interp, token[i].objPtr, JIM_ERRMSG); + break; + case JIM_TT_EXPRSUGAR: + wordObjPtr = JimExpandExprSugar(interp, token[i].objPtr); + break; + case JIM_TT_DICTSUGAR: + wordObjPtr = JimExpandDictSugar(interp, token[i].objPtr); + break; + case JIM_TT_CMD: + retcode = Jim_EvalObj(interp, token[i].objPtr); + if (retcode == JIM_OK) { + wordObjPtr = Jim_GetResult(interp); + } + break; + default: + JimPanic((1, "default token type reached " "in Jim_EvalObj().")); + } + } + else { + wordObjPtr = JimInterpolateTokens(interp, token + i, wordtokens, JIM_NONE); + } + + if (!wordObjPtr) { + if (retcode == JIM_OK) { + retcode = JIM_ERR; + } + break; + } + + Jim_IncrRefCount(wordObjPtr); + i += wordtokens; + + if (!expand) { + argv[j] = wordObjPtr; + } + else { + + int len = Jim_ListLength(interp, wordObjPtr); + int newargc = argc + len - 1; + int k; + + if (len > 1) { + if (argv == sargv) { + if (newargc > JIM_EVAL_SARGV_LEN) { + argv = Jim_Alloc(sizeof(*argv) * newargc); + memcpy(argv, sargv, sizeof(*argv) * j); + } + } + else { + + argv = Jim_Realloc(argv, sizeof(*argv) * newargc); + } + } + + + for (k = 0; k < len; k++) { + argv[j++] = wordObjPtr->internalRep.listValue.ele[k]; + Jim_IncrRefCount(wordObjPtr->internalRep.listValue.ele[k]); + } + + Jim_DecrRefCount(interp, wordObjPtr); + + + j--; + argc += len - 1; + } + } + + if (retcode == JIM_OK && argc) { + + retcode = JimInvokeCommand(interp, argc, argv); + if (interp->signal_level && interp->sigmask) { + + retcode = JIM_SIGNAL; + } + } + + + while (j-- > 0) { + Jim_DecrRefCount(interp, argv[j]); + } + + if (argv != sargv) { + Jim_Free(argv); + argv = sargv; + } + } + + + JimAddErrorToStack(interp, retcode, script); + + + interp->currentScriptObj = prevScriptObj; + + Jim_FreeIntRep(interp, scriptObjPtr); + scriptObjPtr->typePtr = &scriptObjType; + Jim_SetIntRepPtr(scriptObjPtr, script); + Jim_DecrRefCount(interp, scriptObjPtr); + + return retcode; +} + +static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argValObj) +{ + int retcode; + + const char *varname = Jim_String(argNameObj); + if (*varname == '&') { + + Jim_Obj *objPtr; + Jim_CallFrame *savedCallFrame = interp->framePtr; + + interp->framePtr = interp->framePtr->parent; + objPtr = Jim_GetVariable(interp, argValObj, JIM_ERRMSG); + interp->framePtr = savedCallFrame; + if (!objPtr) { + return JIM_ERR; + } + + + objPtr = Jim_NewStringObj(interp, varname + 1, -1); + Jim_IncrRefCount(objPtr); + retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parent); + Jim_DecrRefCount(interp, objPtr); + } + else { + retcode = Jim_SetVariable(interp, argNameObj, argValObj); + } + return retcode; +} + +static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd) +{ + + Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0); + int i; + + for (i = 0; i < cmd->u.proc.argListLen; i++) { + Jim_AppendString(interp, argmsg, " ", 1); + + if (i == cmd->u.proc.argsPos) { + if (cmd->u.proc.arglist[i].defaultObjPtr) { + + Jim_AppendString(interp, argmsg, "?", 1); + Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].defaultObjPtr); + Jim_AppendString(interp, argmsg, " ...?", -1); + } + else { + + Jim_AppendString(interp, argmsg, "?arg...?", -1); + } + } + else { + if (cmd->u.proc.arglist[i].defaultObjPtr) { + Jim_AppendString(interp, argmsg, "?", 1); + Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].nameObjPtr); + Jim_AppendString(interp, argmsg, "?", 1); + } + else { + const char *arg = Jim_String(cmd->u.proc.arglist[i].nameObjPtr); + if (*arg == '&') { + arg++; + } + Jim_AppendString(interp, argmsg, arg, -1); + } + } + } + Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s%#s\"", procNameObj, argmsg); + Jim_FreeNewObj(interp, argmsg); +} + +#ifdef jim_ext_namespace +int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj) +{ + Jim_CallFrame *callFramePtr; + int retcode; + + + callFramePtr = JimCreateCallFrame(interp, interp->framePtr, nsObj); + callFramePtr->argv = &interp->emptyObj; + callFramePtr->argc = 0; + callFramePtr->procArgsObjPtr = NULL; + callFramePtr->procBodyObjPtr = scriptObj; + callFramePtr->staticVars = NULL; + callFramePtr->fileNameObj = interp->emptyObj; + callFramePtr->line = 0; + Jim_IncrRefCount(scriptObj); + interp->framePtr = callFramePtr; + + + if (interp->framePtr->level == interp->maxCallFrameDepth) { + Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1); + retcode = JIM_ERR; + } + else { + + retcode = Jim_EvalObj(interp, scriptObj); + } + + + interp->framePtr = interp->framePtr->parent; + if (callFramePtr->vars.size != JIM_HT_INITIAL_SIZE) { + JimFreeCallFrame(interp, callFramePtr, JIM_FCF_NONE); + } + else { + JimFreeCallFrame(interp, callFramePtr, JIM_FCF_NOHT); + } + + return retcode; +} +#endif + +static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj *const *argv) +{ + Jim_CallFrame *callFramePtr; + int i, d, retcode, optargs; + Jim_Stack *localCommands; + ScriptObj *script; + + + if (argc - 1 < cmd->u.proc.reqArity || + (cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) { + JimSetProcWrongArgs(interp, argv[0], cmd); + return JIM_ERR; + } + + if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) { + + return JIM_OK; + } + + + if (interp->framePtr->level == interp->maxCallFrameDepth) { + Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1); + return JIM_ERR; + } + + + callFramePtr = JimCreateCallFrame(interp, interp->framePtr, cmd->u.proc.nsObj); + callFramePtr->argv = argv; + callFramePtr->argc = argc; + callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr; + callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr; + callFramePtr->staticVars = cmd->u.proc.staticVars; + + + script = Jim_GetScript(interp, interp->currentScriptObj); + callFramePtr->fileNameObj = script->fileNameObj; + callFramePtr->line = script->linenr; + + Jim_IncrRefCount(cmd->u.proc.argListObjPtr); + Jim_IncrRefCount(cmd->u.proc.bodyObjPtr); + interp->framePtr = callFramePtr; + + + optargs = (argc - 1 - cmd->u.proc.reqArity); + + + i = 1; + for (d = 0; d < cmd->u.proc.argListLen; d++) { + Jim_Obj *nameObjPtr = cmd->u.proc.arglist[d].nameObjPtr; + if (d == cmd->u.proc.argsPos) { + + Jim_Obj *listObjPtr; + int argsLen = 0; + if (cmd->u.proc.reqArity + cmd->u.proc.optArity < argc - 1) { + argsLen = argc - 1 - (cmd->u.proc.reqArity + cmd->u.proc.optArity); + } + listObjPtr = Jim_NewListObj(interp, &argv[i], argsLen); + + + if (cmd->u.proc.arglist[d].defaultObjPtr) { + nameObjPtr =cmd->u.proc.arglist[d].defaultObjPtr; + } + retcode = Jim_SetVariable(interp, nameObjPtr, listObjPtr); + if (retcode != JIM_OK) { + goto badargset; + } + + i += argsLen; + continue; + } + + + if (cmd->u.proc.arglist[d].defaultObjPtr == NULL || optargs-- > 0) { + retcode = JimSetProcArg(interp, nameObjPtr, argv[i++]); + } + else { + + retcode = Jim_SetVariable(interp, nameObjPtr, cmd->u.proc.arglist[d].defaultObjPtr); + } + if (retcode != JIM_OK) { + goto badargset; + } + } + + + retcode = Jim_EvalObj(interp, cmd->u.proc.bodyObjPtr); + +badargset: + + + localCommands = callFramePtr->localCommands; + callFramePtr->localCommands = NULL; + + interp->framePtr = interp->framePtr->parent; + if (callFramePtr->vars.size != JIM_HT_INITIAL_SIZE) { + JimFreeCallFrame(interp, callFramePtr, JIM_FCF_NONE); + } + else { + JimFreeCallFrame(interp, callFramePtr, JIM_FCF_NOHT); + } + + + while (retcode == JIM_EVAL) { + Jim_Obj *resultScriptObjPtr = Jim_GetResult(interp); + + Jim_IncrRefCount(resultScriptObjPtr); + + JimPanic((!Jim_IsList(resultScriptObjPtr), "tailcall (JIM_EVAL) returned non-list")); + + retcode = JimEvalObjList(interp, resultScriptObjPtr); + if (retcode == JIM_RETURN) { + interp->returnLevel++; + } + Jim_DecrRefCount(interp, resultScriptObjPtr); + } + + if (retcode == JIM_RETURN) { + if (--interp->returnLevel <= 0) { + retcode = interp->returnCode; + interp->returnCode = JIM_OK; + interp->returnLevel = 0; + } + } + else if (retcode == JIM_ERR) { + interp->addStackTrace++; + Jim_DecrRefCount(interp, interp->errorProc); + interp->errorProc = argv[0]; + Jim_IncrRefCount(interp->errorProc); + } + + + JimDeleteLocalProcs(interp, localCommands); + + return retcode; +} + +int Jim_EvalSource(Jim_Interp *interp, const char *filename, int lineno, const char *script) +{ + int retval; + Jim_Obj *scriptObjPtr; + + scriptObjPtr = Jim_NewStringObj(interp, script, -1); + Jim_IncrRefCount(scriptObjPtr); + + if (filename) { + Jim_Obj *prevScriptObj; + + JimSetSourceInfo(interp, scriptObjPtr, Jim_NewStringObj(interp, filename, -1), lineno); + + prevScriptObj = interp->currentScriptObj; + interp->currentScriptObj = scriptObjPtr; + + retval = Jim_EvalObj(interp, scriptObjPtr); + + interp->currentScriptObj = prevScriptObj; + } + else { + retval = Jim_EvalObj(interp, scriptObjPtr); + } + Jim_DecrRefCount(interp, scriptObjPtr); + return retval; +} + +int Jim_Eval(Jim_Interp *interp, const char *script) +{ + return Jim_EvalObj(interp, Jim_NewStringObj(interp, script, -1)); +} + + +int Jim_EvalGlobal(Jim_Interp *interp, const char *script) +{ + int retval; + Jim_CallFrame *savedFramePtr = interp->framePtr; + + interp->framePtr = interp->topFramePtr; + retval = Jim_Eval(interp, script); + interp->framePtr = savedFramePtr; + + return retval; +} + +int Jim_EvalFileGlobal(Jim_Interp *interp, const char *filename) +{ + int retval; + Jim_CallFrame *savedFramePtr = interp->framePtr; + + interp->framePtr = interp->topFramePtr; + retval = Jim_EvalFile(interp, filename); + interp->framePtr = savedFramePtr; + + return retval; +} + +#include + +int Jim_EvalFile(Jim_Interp *interp, const char *filename) +{ + FILE *fp; + char *buf; + Jim_Obj *scriptObjPtr; + Jim_Obj *prevScriptObj; + struct stat sb; + int retcode; + int readlen; + struct JimParseResult result; + + if (stat(filename, &sb) != 0 || (fp = fopen(filename, "rt")) == NULL) { + Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", filename, strerror(errno)); + return JIM_ERR; + } + if (sb.st_size == 0) { + fclose(fp); + return JIM_OK; + } + + buf = Jim_Alloc(sb.st_size + 1); + readlen = fread(buf, 1, sb.st_size, fp); + if (ferror(fp)) { + fclose(fp); + Jim_Free(buf); + Jim_SetResultFormatted(interp, "failed to load file \"%s\": %s", filename, strerror(errno)); + return JIM_ERR; + } + fclose(fp); + buf[readlen] = 0; + + scriptObjPtr = Jim_NewStringObjNoAlloc(interp, buf, readlen); + JimSetSourceInfo(interp, scriptObjPtr, Jim_NewStringObj(interp, filename, -1), 1); + Jim_IncrRefCount(scriptObjPtr); + + + if (SetScriptFromAny(interp, scriptObjPtr, &result) == JIM_ERR) { + const char *msg; + char linebuf[20]; + + switch (result.missing) { + case '[': + msg = "unmatched \"[\""; + break; + case '{': + msg = "missing close-brace"; + break; + case '"': + default: + msg = "missing quote"; + break; + } + + snprintf(linebuf, sizeof(linebuf), "%d", result.line); + + Jim_SetResultFormatted(interp, "%s in \"%s\" at line %s", + msg, filename, linebuf); + Jim_DecrRefCount(interp, scriptObjPtr); + return JIM_ERR; + } + + prevScriptObj = interp->currentScriptObj; + interp->currentScriptObj = scriptObjPtr; + + retcode = Jim_EvalObj(interp, scriptObjPtr); + + + if (retcode == JIM_RETURN) { + if (--interp->returnLevel <= 0) { + retcode = interp->returnCode; + interp->returnCode = JIM_OK; + interp->returnLevel = 0; + } + } + if (retcode == JIM_ERR) { + + interp->addStackTrace++; + } + + interp->currentScriptObj = prevScriptObj; + + Jim_DecrRefCount(interp, scriptObjPtr); + + return retcode; +} + +static void JimParseSubst(struct JimParserCtx *pc, int flags) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + + if (pc->len == 0) { + pc->tend = pc->p; + pc->tt = JIM_TT_EOL; + pc->eof = 1; + return; + } + if (*pc->p == '[' && !(flags & JIM_SUBST_NOCMD)) { + JimParseCmd(pc); + return; + } + if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) { + if (JimParseVar(pc) == JIM_OK) { + return; + } + + pc->tstart = pc->p; + flags |= JIM_SUBST_NOVAR; + } + while (pc->len) { + if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) { + break; + } + if (*pc->p == '[' && !(flags & JIM_SUBST_NOCMD)) { + break; + } + if (*pc->p == '\\' && pc->len > 1) { + pc->p++; + pc->len--; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = (flags & JIM_SUBST_NOESC) ? JIM_TT_STR : JIM_TT_ESC; +} + + +static int SetSubstFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, int flags) +{ + int scriptTextLen; + const char *scriptText = Jim_GetString(objPtr, &scriptTextLen); + struct JimParserCtx parser; + struct ScriptObj *script = Jim_Alloc(sizeof(*script)); + ParseTokenList tokenlist; + + + ScriptTokenListInit(&tokenlist); + + JimParserInit(&parser, scriptText, scriptTextLen, 1); + while (1) { + JimParseSubst(&parser, flags); + if (parser.eof) { + + break; + } + ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, + parser.tline); + } + + + script->inUse = 1; + script->substFlags = flags; + script->fileNameObj = interp->emptyObj; + Jim_IncrRefCount(script->fileNameObj); + SubstObjAddTokens(interp, script, &tokenlist); + + + ScriptTokenListFree(&tokenlist); + +#ifdef DEBUG_SHOW_SUBST + { + int i; + + printf("==== Subst ====\n"); + for (i = 0; i < script->len; i++) { + printf("[%2d] %s '%s'\n", i, jim_tt_name(script->token[i].type), + Jim_String(script->token[i].objPtr)); + } + } +#endif + + + Jim_FreeIntRep(interp, objPtr); + Jim_SetIntRepPtr(objPtr, script); + objPtr->typePtr = &scriptObjType; + return JIM_OK; +} + +static ScriptObj *Jim_GetSubst(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + if (objPtr->typePtr != &scriptObjType || ((ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags != flags) + SetSubstFromAny(interp, objPtr, flags); + return (ScriptObj *) Jim_GetIntRepPtr(objPtr); +} + +int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPtr, int flags) +{ + ScriptObj *script = Jim_GetSubst(interp, substObjPtr, flags); + + Jim_IncrRefCount(substObjPtr); + script->inUse++; + + *resObjPtrPtr = JimInterpolateTokens(interp, script->token, script->len, flags); + + script->inUse--; + Jim_DecrRefCount(interp, substObjPtr); + if (*resObjPtrPtr == NULL) { + return JIM_ERR; + } + return JIM_OK; +} + +void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg) +{ + Jim_Obj *objPtr; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, argv, argc); + + if (*msg) { + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1)); + } + Jim_IncrRefCount(listObjPtr); + objPtr = Jim_ListJoin(interp, listObjPtr, " ", 1); + Jim_DecrRefCount(interp, listObjPtr); + + Jim_IncrRefCount(objPtr); + Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s\"", objPtr); + Jim_DecrRefCount(interp, objPtr); +} + +typedef void JimHashtableIteratorCallbackType(Jim_Interp *interp, Jim_Obj *listObjPtr, + Jim_HashEntry *he, int type); + +#define JimTrivialMatch(pattern) (strpbrk((pattern), "*[?\\") == NULL) + +static Jim_Obj *JimHashtablePatternMatch(Jim_Interp *interp, Jim_HashTable *ht, Jim_Obj *patternObjPtr, + JimHashtableIteratorCallbackType *callback, int type) +{ + Jim_HashEntry *he; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + + if (patternObjPtr && JimTrivialMatch(Jim_String(patternObjPtr))) { + he = Jim_FindHashEntry(ht, Jim_String(patternObjPtr)); + if (he) { + callback(interp, listObjPtr, he, type); + } + } + else { + Jim_HashTableIterator *htiter = Jim_GetHashTableIterator(ht); + while ((he = Jim_NextHashEntry(htiter)) != NULL) { + if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), he->key, 0)) { + callback(interp, listObjPtr, he, type); + } + } + Jim_FreeHashTableIterator(htiter); + } + return listObjPtr; +} + + +#define JIM_CMDLIST_COMMANDS 0 +#define JIM_CMDLIST_PROCS 1 +#define JIM_CMDLIST_CHANNELS 2 + +static void JimCommandMatch(Jim_Interp *interp, Jim_Obj *listObjPtr, + Jim_HashEntry *he, int type) +{ + Jim_Cmd *cmdPtr = (Jim_Cmd *)he->u.val; + Jim_Obj *objPtr; + + if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) { + + return; + } + + objPtr = Jim_NewStringObj(interp, he->key, -1); + Jim_IncrRefCount(objPtr); + + if (type != JIM_CMDLIST_CHANNELS || Jim_AioFilehandle(interp, objPtr)) { + Jim_ListAppendElement(interp, listObjPtr, objPtr); + } + Jim_DecrRefCount(interp, objPtr); +} + + +static Jim_Obj *JimCommandsList(Jim_Interp *interp, Jim_Obj *patternObjPtr, int type) +{ + return JimHashtablePatternMatch(interp, &interp->commands, patternObjPtr, JimCommandMatch, type); +} + + +#define JIM_VARLIST_GLOBALS 0 +#define JIM_VARLIST_LOCALS 1 +#define JIM_VARLIST_VARS 2 + +#define JIM_VARLIST_VALUES 0x1000 + +static void JimVariablesMatch(Jim_Interp *interp, Jim_Obj *listObjPtr, + Jim_HashEntry *he, int type) +{ + Jim_Var *varPtr = (Jim_Var *)he->u.val; + + if (type != JIM_VARLIST_LOCALS || varPtr->linkFramePtr == NULL) { + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, he->key, -1)); + if (type & JIM_VARLIST_VALUES) { + Jim_ListAppendElement(interp, listObjPtr, varPtr->objPtr); + } + } +} + + +static Jim_Obj *JimVariablesList(Jim_Interp *interp, Jim_Obj *patternObjPtr, int mode) +{ + if (mode == JIM_VARLIST_LOCALS && interp->framePtr == interp->topFramePtr) { + return interp->emptyObj; + } + else { + Jim_CallFrame *framePtr = (mode == JIM_VARLIST_GLOBALS) ? interp->topFramePtr : interp->framePtr; + return JimHashtablePatternMatch(interp, &framePtr->vars, patternObjPtr, JimVariablesMatch, mode); + } +} + +static int JimInfoLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr, + Jim_Obj **objPtrPtr, int info_level_cmd) +{ + Jim_CallFrame *targetCallFrame; + + targetCallFrame = JimGetCallFrameByInteger(interp, levelObjPtr); + if (targetCallFrame == NULL) { + return JIM_ERR; + } + + if (targetCallFrame == interp->topFramePtr) { + Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr); + return JIM_ERR; + } + if (info_level_cmd) { + *objPtrPtr = Jim_NewListObj(interp, targetCallFrame->argv, targetCallFrame->argc); + } + else { + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + + Jim_ListAppendElement(interp, listObj, targetCallFrame->argv[0]); + Jim_ListAppendElement(interp, listObj, targetCallFrame->fileNameObj); + Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, targetCallFrame->line)); + *objPtrPtr = listObj; + } + return JIM_OK; +} + + + +static int Jim_PutsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "?-nonewline? string"); + return JIM_ERR; + } + if (argc == 3) { + if (!Jim_CompareStringImmediate(interp, argv[1], "-nonewline")) { + Jim_SetResultString(interp, "The second argument must " "be -nonewline", -1); + return JIM_ERR; + } + else { + fputs(Jim_String(argv[2]), stdout); + } + } + else { + puts(Jim_String(argv[1])); + } + return JIM_OK; +} + + +static int JimAddMulHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int op) +{ + jim_wide wideValue, res; + double doubleValue, doubleRes; + int i; + + res = (op == JIM_EXPROP_ADD) ? 0 : 1; + + for (i = 1; i < argc; i++) { + if (Jim_GetWide(interp, argv[i], &wideValue) != JIM_OK) + goto trydouble; + if (op == JIM_EXPROP_ADD) + res += wideValue; + else + res *= wideValue; + } + Jim_SetResultInt(interp, res); + return JIM_OK; + trydouble: + doubleRes = (double)res; + for (; i < argc; i++) { + if (Jim_GetDouble(interp, argv[i], &doubleValue) != JIM_OK) + return JIM_ERR; + if (op == JIM_EXPROP_ADD) + doubleRes += doubleValue; + else + doubleRes *= doubleValue; + } + Jim_SetResult(interp, Jim_NewDoubleObj(interp, doubleRes)); + return JIM_OK; +} + + +static int JimSubDivHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int op) +{ + jim_wide wideValue, res = 0; + double doubleValue, doubleRes = 0; + int i = 2; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "number ?number ... number?"); + return JIM_ERR; + } + else if (argc == 2) { + if (Jim_GetWide(interp, argv[1], &wideValue) != JIM_OK) { + if (Jim_GetDouble(interp, argv[1], &doubleValue) != JIM_OK) { + return JIM_ERR; + } + else { + if (op == JIM_EXPROP_SUB) + doubleRes = -doubleValue; + else + doubleRes = 1.0 / doubleValue; + Jim_SetResult(interp, Jim_NewDoubleObj(interp, doubleRes)); + return JIM_OK; + } + } + if (op == JIM_EXPROP_SUB) { + res = -wideValue; + Jim_SetResultInt(interp, res); + } + else { + doubleRes = 1.0 / wideValue; + Jim_SetResult(interp, Jim_NewDoubleObj(interp, doubleRes)); + } + return JIM_OK; + } + else { + if (Jim_GetWide(interp, argv[1], &res) != JIM_OK) { + if (Jim_GetDouble(interp, argv[1], &doubleRes) + != JIM_OK) { + return JIM_ERR; + } + else { + goto trydouble; + } + } + } + for (i = 2; i < argc; i++) { + if (Jim_GetWide(interp, argv[i], &wideValue) != JIM_OK) { + doubleRes = (double)res; + goto trydouble; + } + if (op == JIM_EXPROP_SUB) + res -= wideValue; + else + res /= wideValue; + } + Jim_SetResultInt(interp, res); + return JIM_OK; + trydouble: + for (; i < argc; i++) { + if (Jim_GetDouble(interp, argv[i], &doubleValue) != JIM_OK) + return JIM_ERR; + if (op == JIM_EXPROP_SUB) + doubleRes -= doubleValue; + else + doubleRes /= doubleValue; + } + Jim_SetResult(interp, Jim_NewDoubleObj(interp, doubleRes)); + return JIM_OK; +} + + + +static int Jim_AddCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimAddMulHelper(interp, argc, argv, JIM_EXPROP_ADD); +} + + +static int Jim_MulCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimAddMulHelper(interp, argc, argv, JIM_EXPROP_MUL); +} + + +static int Jim_SubCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimSubDivHelper(interp, argc, argv, JIM_EXPROP_SUB); +} + + +static int Jim_DivCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimSubDivHelper(interp, argc, argv, JIM_EXPROP_DIV); +} + + +static int Jim_SetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?newValue?"); + return JIM_ERR; + } + if (argc == 2) { + Jim_Obj *objPtr; + + objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); + if (!objPtr) + return JIM_ERR; + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK) + return JIM_ERR; + Jim_SetResult(interp, argv[2]); + return JIM_OK; +} + +static int Jim_UnsetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i = 1; + int complain = 1; + + while (i < argc) { + if (Jim_CompareStringImmediate(interp, argv[i], "--")) { + i++; + break; + } + if (Jim_CompareStringImmediate(interp, argv[i], "-nocomplain")) { + complain = 0; + i++; + continue; + } + break; + } + + while (i < argc) { + if (Jim_UnsetVariable(interp, argv[i], complain ? JIM_ERRMSG : JIM_NONE) != JIM_OK + && complain) { + return JIM_ERR; + } + i++; + } + return JIM_OK; +} + + +static int Jim_WhileCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "condition body"); + return JIM_ERR; + } + + + while (1) { + int boolean, retval; + + if ((retval = Jim_GetBoolFromExpr(interp, argv[1], &boolean)) != JIM_OK) + return retval; + if (!boolean) + break; + + if ((retval = Jim_EvalObj(interp, argv[2])) != JIM_OK) { + switch (retval) { + case JIM_BREAK: + goto out; + break; + case JIM_CONTINUE: + continue; + break; + default: + return retval; + } + } + } + out: + Jim_SetEmptyResult(interp); + return JIM_OK; +} + + +static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retval; + int boolean = 1; + Jim_Obj *varNamePtr = NULL; + Jim_Obj *stopVarNamePtr = NULL; + + if (argc != 5) { + Jim_WrongNumArgs(interp, 1, argv, "start test next body"); + return JIM_ERR; + } + + + if ((retval = Jim_EvalObj(interp, argv[1])) != JIM_OK) { + return retval; + } + + retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean); + + +#ifdef JIM_OPTIMIZATION + if (retval == JIM_OK && boolean) { + ScriptObj *incrScript; + ExprByteCode *expr; + jim_wide stop, currentVal; + Jim_Obj *objPtr; + int cmpOffset; + + + expr = JimGetExpression(interp, argv[2]); + incrScript = Jim_GetScript(interp, argv[3]); + + + if (incrScript->len != 3 || !expr || expr->len != 3) { + goto evalstart; + } + + if (incrScript->token[1].type != JIM_TT_ESC || + expr->token[0].type != JIM_TT_VAR || + (expr->token[1].type != JIM_TT_EXPR_INT && expr->token[1].type != JIM_TT_VAR)) { + goto evalstart; + } + + if (expr->token[2].type == JIM_EXPROP_LT) { + cmpOffset = 0; + } + else if (expr->token[2].type == JIM_EXPROP_LTE) { + cmpOffset = 1; + } + else { + goto evalstart; + } + + + if (!Jim_CompareStringImmediate(interp, incrScript->token[1].objPtr, "incr")) { + goto evalstart; + } + + + if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->token[0].objPtr)) { + goto evalstart; + } + + + if (expr->token[1].type == JIM_TT_EXPR_INT) { + if (Jim_GetWide(interp, expr->token[1].objPtr, &stop) == JIM_ERR) { + goto evalstart; + } + } + else { + stopVarNamePtr = expr->token[1].objPtr; + Jim_IncrRefCount(stopVarNamePtr); + + stop = 0; + } + + + varNamePtr = expr->token[0].objPtr; + Jim_IncrRefCount(varNamePtr); + + objPtr = Jim_GetVariable(interp, varNamePtr, JIM_NONE); + if (objPtr == NULL || Jim_GetWide(interp, objPtr, ¤tVal) != JIM_OK) { + goto testcond; + } + + + while (retval == JIM_OK) { + + + + + if (stopVarNamePtr) { + objPtr = Jim_GetVariable(interp, stopVarNamePtr, JIM_NONE); + if (objPtr == NULL || Jim_GetWide(interp, objPtr, &stop) != JIM_OK) { + goto testcond; + } + } + + if (currentVal >= stop + cmpOffset) { + break; + } + + + retval = Jim_EvalObj(interp, argv[4]); + if (retval == JIM_OK || retval == JIM_CONTINUE) { + retval = JIM_OK; + + objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG); + + + if (objPtr == NULL) { + retval = JIM_ERR; + goto out; + } + if (!Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) { + currentVal = ++JimWideValue(objPtr); + Jim_InvalidateStringRep(objPtr); + } + else { + if (Jim_GetWide(interp, objPtr, ¤tVal) != JIM_OK || + Jim_SetVariable(interp, varNamePtr, Jim_NewIntObj(interp, + ++currentVal)) != JIM_OK) { + goto evalnext; + } + } + } + } + goto out; + } + evalstart: +#endif + + while (boolean && (retval == JIM_OK || retval == JIM_CONTINUE)) { + + retval = Jim_EvalObj(interp, argv[4]); + + if (retval == JIM_OK || retval == JIM_CONTINUE) { + + evalnext: + retval = Jim_EvalObj(interp, argv[3]); + if (retval == JIM_OK || retval == JIM_CONTINUE) { + + testcond: + retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean); + } + } + } + out: + if (stopVarNamePtr) { + Jim_DecrRefCount(interp, stopVarNamePtr); + } + if (varNamePtr) { + Jim_DecrRefCount(interp, varNamePtr); + } + + if (retval == JIM_CONTINUE || retval == JIM_BREAK || retval == JIM_OK) { + Jim_SetEmptyResult(interp); + return JIM_OK; + } + + return retval; +} + + +static int Jim_LoopCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retval; + jim_wide i; + jim_wide limit; + jim_wide incr = 1; + Jim_Obj *bodyObjPtr; + + if (argc != 5 && argc != 6) { + Jim_WrongNumArgs(interp, 1, argv, "var first limit ?incr? body"); + return JIM_ERR; + } + + if (Jim_GetWide(interp, argv[2], &i) != JIM_OK || + Jim_GetWide(interp, argv[3], &limit) != JIM_OK || + (argc == 6 && Jim_GetWide(interp, argv[4], &incr) != JIM_OK)) { + return JIM_ERR; + } + bodyObjPtr = (argc == 5) ? argv[4] : argv[5]; + + retval = Jim_SetVariable(interp, argv[1], argv[2]); + + while (((i < limit && incr > 0) || (i > limit && incr < 0)) && retval == JIM_OK) { + retval = Jim_EvalObj(interp, bodyObjPtr); + if (retval == JIM_OK || retval == JIM_CONTINUE) { + Jim_Obj *objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); + + retval = JIM_OK; + + + i += incr; + + if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) { + if (argv[1]->typePtr != &variableObjType) { + if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) { + return JIM_ERR; + } + } + JimWideValue(objPtr) = i; + Jim_InvalidateStringRep(objPtr); + + if (argv[1]->typePtr != &variableObjType) { + if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) { + retval = JIM_ERR; + break; + } + } + } + else { + objPtr = Jim_NewIntObj(interp, i); + retval = Jim_SetVariable(interp, argv[1], objPtr); + if (retval != JIM_OK) { + Jim_FreeNewObj(interp, objPtr); + } + } + } + } + + if (retval == JIM_OK || retval == JIM_CONTINUE || retval == JIM_BREAK) { + Jim_SetEmptyResult(interp); + return JIM_OK; + } + return retval; +} + +typedef struct { + Jim_Obj *objPtr; + int idx; +} Jim_ListIter; + +static void JimListIterInit(Jim_ListIter *iter, Jim_Obj *objPtr) +{ + iter->objPtr = objPtr; + iter->idx = 0; +} + +static Jim_Obj *JimListIterNext(Jim_Interp *interp, Jim_ListIter *iter) +{ + if (iter->idx >= Jim_ListLength(interp, iter->objPtr)) { + return NULL; + } + return iter->objPtr->internalRep.listValue.ele[iter->idx++]; +} + +static int JimListIterDone(Jim_Interp *interp, Jim_ListIter *iter) +{ + return iter->idx >= Jim_ListLength(interp, iter->objPtr); +} + + +static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int doMap) +{ + int result = JIM_ERR; + int i, numargs; + Jim_ListIter twoiters[2]; + Jim_ListIter *iters; + Jim_Obj *script; + Jim_Obj *resultObj; + + if (argc < 4 || argc % 2 != 0) { + Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script"); + return JIM_ERR; + } + script = argv[argc - 1]; + numargs = (argc - 1 - 1); + + if (numargs == 2) { + iters = twoiters; + } + else { + iters = Jim_Alloc(numargs * sizeof(*iters)); + } + for (i = 0; i < numargs; i++) { + JimListIterInit(&iters[i], argv[i + 1]); + if (i % 2 == 0 && JimListIterDone(interp, &iters[i])) { + Jim_SetResultString(interp, "foreach varlist is empty", -1); + return JIM_ERR; + } + } + + if (doMap) { + resultObj = Jim_NewListObj(interp, NULL, 0); + } + else { + resultObj = interp->emptyObj; + } + Jim_IncrRefCount(resultObj); + + while (1) { + + for (i = 0; i < numargs; i += 2) { + if (!JimListIterDone(interp, &iters[i + 1])) { + break; + } + } + if (i == numargs) { + + break; + } + + + for (i = 0; i < numargs; i += 2) { + Jim_Obj *varName; + + + JimListIterInit(&iters[i], argv[i + 1]); + while ((varName = JimListIterNext(interp, &iters[i])) != NULL) { + Jim_Obj *valObj = JimListIterNext(interp, &iters[i + 1]); + if (!valObj) { + + valObj = interp->emptyObj; + } + + Jim_IncrRefCount(valObj); + result = Jim_SetVariable(interp, varName, valObj); + Jim_DecrRefCount(interp, valObj); + if (result != JIM_OK) { + goto err; + } + } + } + switch (result = Jim_EvalObj(interp, script)) { + case JIM_OK: + if (doMap) { + Jim_ListAppendElement(interp, resultObj, interp->result); + } + break; + case JIM_CONTINUE: + break; + case JIM_BREAK: + goto out; + default: + goto err; + } + } + out: + result = JIM_OK; + Jim_SetResult(interp, resultObj); + err: + Jim_DecrRefCount(interp, resultObj); + if (numargs > 2) { + Jim_Free(iters); + } + return result; +} + + +static int Jim_ForeachCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimForeachMapHelper(interp, argc, argv, 0); +} + + +static int Jim_LmapCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimForeachMapHelper(interp, argc, argv, 1); +} + + +static int Jim_LassignCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int result = JIM_ERR; + int i; + Jim_ListIter iter; + Jim_Obj *resultObj; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varList list ?varName ...?"); + return JIM_ERR; + } + + JimListIterInit(&iter, argv[1]); + + for (i = 2; i < argc; i++) { + Jim_Obj *valObj = JimListIterNext(interp, &iter); + result = Jim_SetVariable(interp, argv[i], valObj ? valObj : interp->emptyObj); + if (result != JIM_OK) { + return result; + } + } + + resultObj = Jim_NewListObj(interp, NULL, 0); + while (!JimListIterDone(interp, &iter)) { + Jim_ListAppendElement(interp, resultObj, JimListIterNext(interp, &iter)); + } + + Jim_SetResult(interp, resultObj); + + return JIM_OK; +} + + +static int Jim_IfCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int boolean, retval, current = 1, falsebody = 0; + + if (argc >= 3) { + while (1) { + + if (current >= argc) + goto err; + if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean)) + != JIM_OK) + return retval; + + if (current >= argc) + goto err; + if (Jim_CompareStringImmediate(interp, argv[current], "then")) + current++; + + if (current >= argc) + goto err; + if (boolean) + return Jim_EvalObj(interp, argv[current]); + + if (++current >= argc) { + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + return JIM_OK; + } + falsebody = current++; + if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) { + + if (current != argc - 1) + goto err; + return Jim_EvalObj(interp, argv[current]); + } + else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif")) + continue; + + else if (falsebody != argc - 1) + goto err; + return Jim_EvalObj(interp, argv[falsebody]); + } + return JIM_OK; + } + err: + Jim_WrongNumArgs(interp, 1, argv, "condition ?then? trueBody ?elseif ...? ?else? falseBody"); + return JIM_ERR; +} + + + +int Jim_CommandMatchObj(Jim_Interp *interp, Jim_Obj *commandObj, Jim_Obj *patternObj, + Jim_Obj *stringObj, int nocase) +{ + Jim_Obj *parms[4]; + int argc = 0; + long eq; + int rc; + + parms[argc++] = commandObj; + if (nocase) { + parms[argc++] = Jim_NewStringObj(interp, "-nocase", -1); + } + parms[argc++] = patternObj; + parms[argc++] = stringObj; + + rc = Jim_EvalObjVector(interp, argc, parms); + + if (rc != JIM_OK || Jim_GetLong(interp, Jim_GetResult(interp), &eq) != JIM_OK) { + eq = -rc; + } + + return eq; +} + +enum +{ SWITCH_EXACT, SWITCH_GLOB, SWITCH_RE, SWITCH_CMD }; + + +static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int matchOpt = SWITCH_EXACT, opt = 1, patCount, i; + Jim_Obj *command = 0, *const *caseList = 0, *strObj; + Jim_Obj *script = 0; + + if (argc < 3) { + wrongnumargs: + Jim_WrongNumArgs(interp, 1, argv, "?options? string " + "pattern body ... ?default body? or " "{pattern body ?pattern body ...?}"); + return JIM_ERR; + } + for (opt = 1; opt < argc; ++opt) { + const char *option = Jim_String(argv[opt]); + + if (*option != '-') + break; + else if (strncmp(option, "--", 2) == 0) { + ++opt; + break; + } + else if (strncmp(option, "-exact", 2) == 0) + matchOpt = SWITCH_EXACT; + else if (strncmp(option, "-glob", 2) == 0) + matchOpt = SWITCH_GLOB; + else if (strncmp(option, "-regexp", 2) == 0) + matchOpt = SWITCH_RE; + else if (strncmp(option, "-command", 2) == 0) { + matchOpt = SWITCH_CMD; + if ((argc - opt) < 2) + goto wrongnumargs; + command = argv[++opt]; + } + else { + Jim_SetResultFormatted(interp, + "bad option \"%#s\": must be -exact, -glob, -regexp, -command procname or --", + argv[opt]); + return JIM_ERR; + } + if ((argc - opt) < 2) + goto wrongnumargs; + } + strObj = argv[opt++]; + patCount = argc - opt; + if (patCount == 1) { + Jim_Obj **vector; + + JimListGetElements(interp, argv[opt], &patCount, &vector); + caseList = vector; + } + else + caseList = &argv[opt]; + if (patCount == 0 || patCount % 2 != 0) + goto wrongnumargs; + for (i = 0; script == 0 && i < patCount; i += 2) { + Jim_Obj *patObj = caseList[i]; + + if (!Jim_CompareStringImmediate(interp, patObj, "default") + || i < (patCount - 2)) { + switch (matchOpt) { + case SWITCH_EXACT: + if (Jim_StringEqObj(strObj, patObj)) + script = caseList[i + 1]; + break; + case SWITCH_GLOB: + if (Jim_StringMatchObj(interp, patObj, strObj, 0)) + script = caseList[i + 1]; + break; + case SWITCH_RE: + command = Jim_NewStringObj(interp, "regexp", -1); + + case SWITCH_CMD:{ + int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, 0); + + if (argc - opt == 1) { + Jim_Obj **vector; + + JimListGetElements(interp, argv[opt], &patCount, &vector); + caseList = vector; + } + + if (rc < 0) { + return -rc; + } + if (rc) + script = caseList[i + 1]; + break; + } + } + } + else { + script = caseList[i + 1]; + } + } + for (; i < patCount && Jim_CompareStringImmediate(interp, script, "-"); i += 2) + script = caseList[i + 1]; + if (script && Jim_CompareStringImmediate(interp, script, "-")) { + Jim_SetResultFormatted(interp, "no body specified for pattern \"%#s\"", caseList[i - 2]); + return JIM_ERR; + } + Jim_SetEmptyResult(interp); + if (script) { + return Jim_EvalObj(interp, script); + } + return JIM_OK; +} + + +static int Jim_ListCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listObjPtr; + + listObjPtr = Jim_NewListObj(interp, argv + 1, argc - 1); + Jim_SetResult(interp, listObjPtr); + return JIM_OK; +} + + +static int Jim_LindexCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr, *listObjPtr; + int i; + int idx; + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "list index ?...?"); + return JIM_ERR; + } + objPtr = argv[1]; + Jim_IncrRefCount(objPtr); + for (i = 2; i < argc; i++) { + listObjPtr = objPtr; + if (Jim_GetIndex(interp, argv[i], &idx) != JIM_OK) { + Jim_DecrRefCount(interp, listObjPtr); + return JIM_ERR; + } + if (Jim_ListIndex(interp, listObjPtr, idx, &objPtr, JIM_NONE) != JIM_OK) { + Jim_DecrRefCount(interp, listObjPtr); + Jim_SetEmptyResult(interp); + return JIM_OK; + } + Jim_IncrRefCount(objPtr); + Jim_DecrRefCount(interp, listObjPtr); + } + Jim_SetResult(interp, objPtr); + Jim_DecrRefCount(interp, objPtr); + return JIM_OK; +} + + +static int Jim_LlengthCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "list"); + return JIM_ERR; + } + Jim_SetResultInt(interp, Jim_ListLength(interp, argv[1])); + return JIM_OK; +} + + +static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + static const char * const options[] = { + "-bool", "-not", "-nocase", "-exact", "-glob", "-regexp", "-all", "-inline", "-command", + NULL + }; + enum + { OPT_BOOL, OPT_NOT, OPT_NOCASE, OPT_EXACT, OPT_GLOB, OPT_REGEXP, OPT_ALL, OPT_INLINE, + OPT_COMMAND }; + int i; + int opt_bool = 0; + int opt_not = 0; + int opt_nocase = 0; + int opt_all = 0; + int opt_inline = 0; + int opt_match = OPT_EXACT; + int listlen; + int rc = JIM_OK; + Jim_Obj *listObjPtr = NULL; + Jim_Obj *commandObj = NULL; + + if (argc < 3) { + wrongargs: + Jim_WrongNumArgs(interp, 1, argv, + "?-exact|-glob|-regexp|-command 'command'? ?-bool|-inline? ?-not? ?-nocase? ?-all? list value"); + return JIM_ERR; + } + + for (i = 1; i < argc - 2; i++) { + int option; + + if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + switch (option) { + case OPT_BOOL: + opt_bool = 1; + opt_inline = 0; + break; + case OPT_NOT: + opt_not = 1; + break; + case OPT_NOCASE: + opt_nocase = 1; + break; + case OPT_INLINE: + opt_inline = 1; + opt_bool = 0; + break; + case OPT_ALL: + opt_all = 1; + break; + case OPT_COMMAND: + if (i >= argc - 2) { + goto wrongargs; + } + commandObj = argv[++i]; + + case OPT_EXACT: + case OPT_GLOB: + case OPT_REGEXP: + opt_match = option; + break; + } + } + + argv += i; + + if (opt_all) { + listObjPtr = Jim_NewListObj(interp, NULL, 0); + } + if (opt_match == OPT_REGEXP) { + commandObj = Jim_NewStringObj(interp, "regexp", -1); + } + if (commandObj) { + Jim_IncrRefCount(commandObj); + } + + listlen = Jim_ListLength(interp, argv[0]); + for (i = 0; i < listlen; i++) { + Jim_Obj *objPtr; + int eq = 0; + + Jim_ListIndex(interp, argv[0], i, &objPtr, JIM_NONE); + switch (opt_match) { + case OPT_EXACT: + eq = Jim_StringCompareObj(interp, argv[1], objPtr, opt_nocase) == 0; + break; + + case OPT_GLOB: + eq = Jim_StringMatchObj(interp, argv[1], objPtr, opt_nocase); + break; + + case OPT_REGEXP: + case OPT_COMMAND: + eq = Jim_CommandMatchObj(interp, commandObj, argv[1], objPtr, opt_nocase); + if (eq < 0) { + if (listObjPtr) { + Jim_FreeNewObj(interp, listObjPtr); + } + rc = JIM_ERR; + goto done; + } + break; + } + + + if (!eq && opt_bool && opt_not && !opt_all) { + continue; + } + + if ((!opt_bool && eq == !opt_not) || (opt_bool && (eq || opt_all))) { + + Jim_Obj *resultObj; + + if (opt_bool) { + resultObj = Jim_NewIntObj(interp, eq ^ opt_not); + } + else if (!opt_inline) { + resultObj = Jim_NewIntObj(interp, i); + } + else { + resultObj = objPtr; + } + + if (opt_all) { + Jim_ListAppendElement(interp, listObjPtr, resultObj); + } + else { + Jim_SetResult(interp, resultObj); + goto done; + } + } + } + + if (opt_all) { + Jim_SetResult(interp, listObjPtr); + } + else { + + if (opt_bool) { + Jim_SetResultBool(interp, opt_not); + } + else if (!opt_inline) { + Jim_SetResultInt(interp, -1); + } + } + + done: + if (commandObj) { + Jim_DecrRefCount(interp, commandObj); + } + return rc; +} + + +static int Jim_LappendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listObjPtr; + int shared, i; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?"); + return JIM_ERR; + } + listObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); + if (!listObjPtr) { + + listObjPtr = Jim_NewListObj(interp, NULL, 0); + if (Jim_SetVariable(interp, argv[1], listObjPtr) != JIM_OK) { + Jim_FreeNewObj(interp, listObjPtr); + return JIM_ERR; + } + } + shared = Jim_IsShared(listObjPtr); + if (shared) + listObjPtr = Jim_DuplicateObj(interp, listObjPtr); + for (i = 2; i < argc; i++) + Jim_ListAppendElement(interp, listObjPtr, argv[i]); + if (Jim_SetVariable(interp, argv[1], listObjPtr) != JIM_OK) { + if (shared) + Jim_FreeNewObj(interp, listObjPtr); + return JIM_ERR; + } + Jim_SetResult(interp, listObjPtr); + return JIM_OK; +} + + +static int Jim_LinsertCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int idx, len; + Jim_Obj *listPtr; + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "list index ?element ...?"); + return JIM_ERR; + } + listPtr = argv[1]; + if (Jim_IsShared(listPtr)) + listPtr = Jim_DuplicateObj(interp, listPtr); + if (Jim_GetIndex(interp, argv[2], &idx) != JIM_OK) + goto err; + len = Jim_ListLength(interp, listPtr); + if (idx >= len) + idx = len; + else if (idx < 0) + idx = len + idx + 1; + Jim_ListInsertElements(interp, listPtr, idx, argc - 3, &argv[3]); + Jim_SetResult(interp, listPtr); + return JIM_OK; + err: + if (listPtr != argv[1]) { + Jim_FreeNewObj(interp, listPtr); + } + return JIM_ERR; +} + + +static int Jim_LreplaceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int first, last, len, rangeLen; + Jim_Obj *listObj; + Jim_Obj *newListObj; + + if (argc < 4) { + Jim_WrongNumArgs(interp, 1, argv, "list first last ?element ...?"); + return JIM_ERR; + } + if (Jim_GetIndex(interp, argv[2], &first) != JIM_OK || + Jim_GetIndex(interp, argv[3], &last) != JIM_OK) { + return JIM_ERR; + } + + listObj = argv[1]; + len = Jim_ListLength(interp, listObj); + + first = JimRelToAbsIndex(len, first); + last = JimRelToAbsIndex(len, last); + JimRelToAbsRange(len, &first, &last, &rangeLen); + + + + if (first < len) { + + } + else if (len == 0) { + + first = 0; + } + else { + Jim_SetResultString(interp, "list doesn't contain element ", -1); + Jim_AppendObj(interp, Jim_GetResult(interp), argv[2]); + return JIM_ERR; + } + + + newListObj = Jim_NewListObj(interp, listObj->internalRep.listValue.ele, first); + + + ListInsertElements(newListObj, -1, argc - 4, argv + 4); + + + ListInsertElements(newListObj, -1, len - first - rangeLen, listObj->internalRep.listValue.ele + first + rangeLen); + + Jim_SetResult(interp, newListObj); + return JIM_OK; +} + + +static int Jim_LsetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "listVar ?index...? newVal"); + return JIM_ERR; + } + else if (argc == 3) { + if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK) + return JIM_ERR; + Jim_SetResult(interp, argv[2]); + return JIM_OK; + } + if (Jim_SetListIndex(interp, argv[1], argv + 2, argc - 3, argv[argc - 1]) + == JIM_ERR) + return JIM_ERR; + return JIM_OK; +} + + +static int Jim_LsortCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const argv[]) +{ + static const char * const options[] = { + "-ascii", "-nocase", "-increasing", "-decreasing", "-command", "-integer", "-index", NULL + }; + enum + { OPT_ASCII, OPT_NOCASE, OPT_INCREASING, OPT_DECREASING, OPT_COMMAND, OPT_INTEGER, OPT_INDEX }; + Jim_Obj *resObj; + int i; + int retCode; + + struct lsort_info info; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "?options? list"); + return JIM_ERR; + } + + info.type = JIM_LSORT_ASCII; + info.order = 1; + info.indexed = 0; + info.command = NULL; + info.interp = interp; + + for (i = 1; i < (argc - 1); i++) { + int option; + + if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ERRMSG) + != JIM_OK) + return JIM_ERR; + switch (option) { + case OPT_ASCII: + info.type = JIM_LSORT_ASCII; + break; + case OPT_NOCASE: + info.type = JIM_LSORT_NOCASE; + break; + case OPT_INTEGER: + info.type = JIM_LSORT_INTEGER; + break; + case OPT_INCREASING: + info.order = 1; + break; + case OPT_DECREASING: + info.order = -1; + break; + case OPT_COMMAND: + if (i >= (argc - 2)) { + Jim_SetResultString(interp, "\"-command\" option must be followed by comparison command", -1); + return JIM_ERR; + } + info.type = JIM_LSORT_COMMAND; + info.command = argv[i + 1]; + i++; + break; + case OPT_INDEX: + if (i >= (argc - 2)) { + Jim_SetResultString(interp, "\"-index\" option must be followed by list index", -1); + return JIM_ERR; + } + if (Jim_GetIndex(interp, argv[i + 1], &info.index) != JIM_OK) { + return JIM_ERR; + } + info.indexed = 1; + i++; + break; + } + } + resObj = Jim_DuplicateObj(interp, argv[argc - 1]); + retCode = ListSortElements(interp, resObj, &info); + if (retCode == JIM_OK) { + Jim_SetResult(interp, resObj); + } + else { + Jim_FreeNewObj(interp, resObj); + } + return retCode; +} + + +static int Jim_AppendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *stringObjPtr; + int i; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?"); + return JIM_ERR; + } + if (argc == 2) { + stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); + if (!stringObjPtr) + return JIM_ERR; + } + else { + int freeobj = 0; + stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); + if (!stringObjPtr) { + + stringObjPtr = Jim_NewEmptyStringObj(interp); + freeobj = 1; + } + else if (Jim_IsShared(stringObjPtr)) { + freeobj = 1; + stringObjPtr = Jim_DuplicateObj(interp, stringObjPtr); + } + for (i = 2; i < argc; i++) { + Jim_AppendObj(interp, stringObjPtr, argv[i]); + } + if (Jim_SetVariable(interp, argv[1], stringObjPtr) != JIM_OK) { + if (freeobj) { + Jim_FreeNewObj(interp, stringObjPtr); + } + return JIM_ERR; + } + } + Jim_SetResult(interp, stringObjPtr); + return JIM_OK; +} + + +static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ +#if !defined(JIM_DEBUG_COMMAND) + Jim_SetResultString(interp, "unsupported", -1); + return JIM_ERR; +#endif +} + + +static int Jim_EvalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int rc; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "script ?...?"); + return JIM_ERR; + } + + if (argc == 2) { + rc = Jim_EvalObj(interp, argv[1]); + } + else { + rc = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1)); + } + + if (rc == JIM_ERR) { + + interp->addStackTrace++; + } + return rc; +} + + +static int Jim_UplevelCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc >= 2) { + int retcode; + Jim_CallFrame *savedCallFrame, *targetCallFrame; + Jim_Obj *objPtr; + const char *str; + + + savedCallFrame = interp->framePtr; + + + str = Jim_String(argv[1]); + if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') { + targetCallFrame =Jim_GetCallFrameByLevel(interp, argv[1]); + argc--; + argv++; + } + else { + targetCallFrame = Jim_GetCallFrameByLevel(interp, NULL); + } + if (targetCallFrame == NULL) { + return JIM_ERR; + } + if (argc < 2) { + argv--; + Jim_WrongNumArgs(interp, 1, argv, "?level? command ?arg ...?"); + return JIM_ERR; + } + + interp->framePtr = targetCallFrame; + if (argc == 2) { + retcode = Jim_EvalObj(interp, argv[1]); + } + else { + objPtr = Jim_ConcatObj(interp, argc - 1, argv + 1); + Jim_IncrRefCount(objPtr); + retcode = Jim_EvalObj(interp, objPtr); + Jim_DecrRefCount(interp, objPtr); + } + interp->framePtr = savedCallFrame; + return retcode; + } + else { + Jim_WrongNumArgs(interp, 1, argv, "?level? command ?arg ...?"); + return JIM_ERR; + } +} + + +static int Jim_ExprCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *exprResultPtr; + int retcode; + + if (argc == 2) { + retcode = Jim_EvalExpression(interp, argv[1], &exprResultPtr); + } + else if (argc > 2) { + Jim_Obj *objPtr; + + objPtr = Jim_ConcatObj(interp, argc - 1, argv + 1); + Jim_IncrRefCount(objPtr); + retcode = Jim_EvalExpression(interp, objPtr, &exprResultPtr); + Jim_DecrRefCount(interp, objPtr); + } + else { + Jim_WrongNumArgs(interp, 1, argv, "expression ?...?"); + return JIM_ERR; + } + if (retcode != JIM_OK) + return retcode; + Jim_SetResult(interp, exprResultPtr); + Jim_DecrRefCount(interp, exprResultPtr); + return JIM_OK; +} + + +static int Jim_BreakCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + return JIM_BREAK; +} + + +static int Jim_ContinueCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + return JIM_CONTINUE; +} + + +static int Jim_ReturnCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + Jim_Obj *stackTraceObj = NULL; + Jim_Obj *errorCodeObj = NULL; + int returnCode = JIM_OK; + long level = 1; + + for (i = 1; i < argc - 1; i += 2) { + if (Jim_CompareStringImmediate(interp, argv[i], "-code")) { + if (Jim_GetReturnCode(interp, argv[i + 1], &returnCode) == JIM_ERR) { + return JIM_ERR; + } + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-errorinfo")) { + stackTraceObj = argv[i + 1]; + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-errorcode")) { + errorCodeObj = argv[i + 1]; + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-level")) { + if (Jim_GetLong(interp, argv[i + 1], &level) != JIM_OK || level < 0) { + Jim_SetResultFormatted(interp, "bad level \"%#s\"", argv[i + 1]); + return JIM_ERR; + } + } + else { + break; + } + } + + if (i != argc - 1 && i != argc) { + Jim_WrongNumArgs(interp, 1, argv, + "?-code code? ?-errorinfo stacktrace? ?-level level? ?result?"); + } + + + if (stackTraceObj && returnCode == JIM_ERR) { + JimSetStackTrace(interp, stackTraceObj); + } + + if (errorCodeObj && returnCode == JIM_ERR) { + Jim_SetGlobalVariableStr(interp, "errorCode", errorCodeObj); + } + interp->returnCode = returnCode; + interp->returnLevel = level; + + if (i == argc - 1) { + Jim_SetResult(interp, argv[i]); + } + return JIM_RETURN; +} + + +static int Jim_TailcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_SetResult(interp, Jim_NewListObj(interp, argv + 1, argc - 1)); + return JIM_EVAL; +} + +static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *cmdList; + Jim_Obj *prefixListObj = Jim_CmdPrivData(interp); + + + cmdList = Jim_DuplicateObj(interp, prefixListObj); + ListInsertElements(cmdList, -1, argc - 1, argv + 1); + + return JimEvalObjList(interp, cmdList); +} + +static void JimAliasCmdDelete(Jim_Interp *interp, void *privData) +{ + Jim_Obj *prefixListObj = privData; + Jim_DecrRefCount(interp, prefixListObj); +} + +static int Jim_AliasCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *prefixListObj; + const char *newname; + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "newname command ?args ...?"); + return JIM_ERR; + } + + prefixListObj = Jim_NewListObj(interp, argv + 2, argc - 2); + Jim_IncrRefCount(prefixListObj); + newname = Jim_String(argv[1]); + if (newname[0] == ':' && newname[1] == ':') { + while (*++newname == ':') { + } + } + + Jim_SetResult(interp, argv[1]); + + return Jim_CreateCommand(interp, newname, JimAliasCmd, prefixListObj, JimAliasCmdDelete); +} + + +static int Jim_ProcCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Cmd *cmd; + + if (argc != 4 && argc != 5) { + Jim_WrongNumArgs(interp, 1, argv, "name arglist ?statics? body"); + return JIM_ERR; + } + + if (JimValidName(interp, "procedure", argv[1]) != JIM_OK) { + return JIM_ERR; + } + + if (argc == 4) { + cmd = JimCreateProcedureCmd(interp, argv[2], NULL, argv[3], NULL); + } + else { + cmd = JimCreateProcedureCmd(interp, argv[2], argv[3], argv[4], NULL); + } + + if (cmd) { + + Jim_Obj *qualifiedCmdNameObj; + const char *cmdname = JimQualifyName(interp, Jim_String(argv[1]), &qualifiedCmdNameObj); + + JimCreateCommand(interp, cmdname, cmd); + + + JimUpdateProcNamespace(interp, cmd, cmdname); + + JimFreeQualifiedName(interp, qualifiedCmdNameObj); + + + Jim_SetResult(interp, argv[1]); + return JIM_OK; + } + return JIM_ERR; +} + + +static int Jim_LocalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retcode; + + + interp->local++; + retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); + interp->local--; + + + + if (retcode == 0) { + Jim_Obj *cmdNameObj = Jim_GetResult(interp); + + if (Jim_GetCommand(interp, cmdNameObj, JIM_ERRMSG) == NULL) { + return JIM_ERR; + } + if (interp->framePtr->localCommands == NULL) { + interp->framePtr->localCommands = Jim_Alloc(sizeof(*interp->framePtr->localCommands)); + Jim_InitStack(interp->framePtr->localCommands); + } + Jim_IncrRefCount(cmdNameObj); + Jim_StackPush(interp->framePtr->localCommands, cmdNameObj); + } + + return retcode; +} + + +static int Jim_UpcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?"); + return JIM_ERR; + } + else { + int retcode; + + Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG); + if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->prevCmd) { + Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]); + return JIM_ERR; + } + + cmdPtr->u.proc.upcall++; + JimIncrCmdRefCount(cmdPtr); + + + retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); + + + cmdPtr->u.proc.upcall--; + JimDecrCmdRefCount(interp, cmdPtr); + + return retcode; + } +} + + +static int Jim_ApplyCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "lambdaExpr ?arg ...?"); + return JIM_ERR; + } + else { + int ret; + Jim_Cmd *cmd; + Jim_Obj *argListObjPtr; + Jim_Obj *bodyObjPtr; + Jim_Obj *nsObj = NULL; + Jim_Obj **nargv; + + int len = Jim_ListLength(interp, argv[1]); + if (len != 2 && len != 3) { + Jim_SetResultFormatted(interp, "can't interpret \"%#s\" as a lambda expression", argv[1]); + return JIM_ERR; + } + + if (len == 3) { +#ifdef jim_ext_namespace + + nsObj = JimQualifyNameObj(interp, Jim_ListGetIndex(interp, argv[1], 2)); +#else + Jim_SetResultString(interp, "namespaces not enabled", -1); + return JIM_ERR; +#endif + } + argListObjPtr = Jim_ListGetIndex(interp, argv[1], 0); + bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1); + + cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj); + + if (cmd) { + + nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv)); + nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1); + Jim_IncrRefCount(nargv[0]); + memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv)); + ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv); + Jim_DecrRefCount(interp, nargv[0]); + Jim_Free(nargv); + + JimDecrCmdRefCount(interp, cmd); + return ret; + } + return JIM_ERR; + } +} + + + +static int Jim_ConcatCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_SetResult(interp, Jim_ConcatObj(interp, argc - 1, argv + 1)); + return JIM_OK; +} + + +static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + Jim_CallFrame *targetCallFrame; + + + if (argc > 3 && (argc % 2 == 0)) { + targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]); + argc--; + argv++; + } + else { + targetCallFrame = Jim_GetCallFrameByLevel(interp, NULL); + } + if (targetCallFrame == NULL) { + return JIM_ERR; + } + + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "?level? otherVar localVar ?otherVar localVar ...?"); + return JIM_ERR; + } + + + for (i = 1; i < argc; i += 2) { + if (Jim_SetVariableLink(interp, argv[i + 1], argv[i], targetCallFrame) != JIM_OK) + return JIM_ERR; + } + return JIM_OK; +} + + +static int Jim_GlobalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?varName ...?"); + return JIM_ERR; + } + + if (interp->framePtr->level == 0) + return JIM_OK; + for (i = 1; i < argc; i++) { + + const char *name = Jim_String(argv[i]); + if (name[0] != ':' || name[1] != ':') { + if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK) + return JIM_ERR; + } + } + return JIM_OK; +} + +static Jim_Obj *JimStringMap(Jim_Interp *interp, Jim_Obj *mapListObjPtr, + Jim_Obj *objPtr, int nocase) +{ + int numMaps; + const char *str, *noMatchStart = NULL; + int strLen, i; + Jim_Obj *resultObjPtr; + + numMaps = Jim_ListLength(interp, mapListObjPtr); + if (numMaps % 2) { + Jim_SetResultString(interp, "list must contain an even number of elements", -1); + return NULL; + } + + str = Jim_String(objPtr); + strLen = Jim_Utf8Length(interp, objPtr); + + + resultObjPtr = Jim_NewStringObj(interp, "", 0); + while (strLen) { + for (i = 0; i < numMaps; i += 2) { + Jim_Obj *objPtr; + const char *k; + int kl; + + Jim_ListIndex(interp, mapListObjPtr, i, &objPtr, JIM_NONE); + k = Jim_String(objPtr); + kl = Jim_Utf8Length(interp, objPtr); + + if (strLen >= kl && kl) { + int rc; + rc = JimStringCompareLen(str, k, kl, nocase); + if (rc == 0) { + if (noMatchStart) { + Jim_AppendString(interp, resultObjPtr, noMatchStart, str - noMatchStart); + noMatchStart = NULL; + } + Jim_ListIndex(interp, mapListObjPtr, i + 1, &objPtr, JIM_NONE); + Jim_AppendObj(interp, resultObjPtr, objPtr); + str += utf8_index(str, kl); + strLen -= kl; + break; + } + } + } + if (i == numMaps) { + int c; + if (noMatchStart == NULL) + noMatchStart = str; + str += utf8_tounicode(str, &c); + strLen--; + } + } + if (noMatchStart) { + Jim_AppendString(interp, resultObjPtr, noMatchStart, str - noMatchStart); + } + return resultObjPtr; +} + + +static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int len; + int opt_case = 1; + int option; + static const char * const options[] = { + "bytelength", "length", "compare", "match", "equal", "is", "byterange", "range", "replace", + "map", "repeat", "reverse", "index", "first", "last", + "trim", "trimleft", "trimright", "tolower", "toupper", "totitle", NULL + }; + enum + { + OPT_BYTELENGTH, OPT_LENGTH, OPT_COMPARE, OPT_MATCH, OPT_EQUAL, OPT_IS, OPT_BYTERANGE, OPT_RANGE, OPT_REPLACE, + OPT_MAP, OPT_REPEAT, OPT_REVERSE, OPT_INDEX, OPT_FIRST, OPT_LAST, + OPT_TRIM, OPT_TRIMLEFT, OPT_TRIMRIGHT, OPT_TOLOWER, OPT_TOUPPER, OPT_TOTITLE + }; + static const char * const nocase_options[] = { + "-nocase", NULL + }; + static const char * const nocase_length_options[] = { + "-nocase", "-length", NULL + }; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "option ?arguments ...?"); + return JIM_ERR; + } + if (Jim_GetEnum(interp, argv[1], options, &option, NULL, + JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) + return JIM_ERR; + + switch (option) { + case OPT_LENGTH: + case OPT_BYTELENGTH: + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "string"); + return JIM_ERR; + } + if (option == OPT_LENGTH) { + len = Jim_Utf8Length(interp, argv[2]); + } + else { + len = Jim_Length(argv[2]); + } + Jim_SetResultInt(interp, len); + return JIM_OK; + + case OPT_COMPARE: + case OPT_EQUAL: + { + + long opt_length = -1; + int n = argc - 4; + int i = 2; + while (n > 0) { + int subopt; + if (Jim_GetEnum(interp, argv[i++], nocase_length_options, &subopt, NULL, + JIM_ENUM_ABBREV) != JIM_OK) { +badcompareargs: + Jim_WrongNumArgs(interp, 2, argv, "?-nocase? ?-length int? string1 string2"); + return JIM_ERR; + } + if (subopt == 0) { + + opt_case = 0; + n--; + } + else { + + if (n < 2) { + goto badcompareargs; + } + if (Jim_GetLong(interp, argv[i++], &opt_length) != JIM_OK) { + return JIM_ERR; + } + n -= 2; + } + } + if (n) { + goto badcompareargs; + } + argv += argc - 2; + if (opt_length < 0 && option != OPT_COMPARE && opt_case) { + + Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1])); + } + else { + if (opt_length >= 0) { + n = JimStringCompareLen(Jim_String(argv[0]), Jim_String(argv[1]), opt_length, !opt_case); + } + else { + n = Jim_StringCompareObj(interp, argv[0], argv[1], !opt_case); + } + Jim_SetResultInt(interp, option == OPT_COMPARE ? n : n == 0); + } + return JIM_OK; + } + + case OPT_MATCH: + if (argc != 4 && + (argc != 5 || + Jim_GetEnum(interp, argv[2], nocase_options, &opt_case, NULL, + JIM_ENUM_ABBREV) != JIM_OK)) { + Jim_WrongNumArgs(interp, 2, argv, "?-nocase? pattern string"); + return JIM_ERR; + } + if (opt_case == 0) { + argv++; + } + Jim_SetResultBool(interp, Jim_StringMatchObj(interp, argv[2], argv[3], !opt_case)); + return JIM_OK; + + case OPT_MAP:{ + Jim_Obj *objPtr; + + if (argc != 4 && + (argc != 5 || + Jim_GetEnum(interp, argv[2], nocase_options, &opt_case, NULL, + JIM_ENUM_ABBREV) != JIM_OK)) { + Jim_WrongNumArgs(interp, 2, argv, "?-nocase? mapList string"); + return JIM_ERR; + } + + if (opt_case == 0) { + argv++; + } + objPtr = JimStringMap(interp, argv[2], argv[3], !opt_case); + if (objPtr == NULL) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + case OPT_RANGE: + case OPT_BYTERANGE:{ + Jim_Obj *objPtr; + + if (argc != 5) { + Jim_WrongNumArgs(interp, 2, argv, "string first last"); + return JIM_ERR; + } + if (option == OPT_RANGE) { + objPtr = Jim_StringRangeObj(interp, argv[2], argv[3], argv[4]); + } + else + { + objPtr = Jim_StringByteRangeObj(interp, argv[2], argv[3], argv[4]); + } + + if (objPtr == NULL) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + case OPT_REPLACE:{ + Jim_Obj *objPtr; + + if (argc != 5 && argc != 6) { + Jim_WrongNumArgs(interp, 2, argv, "string first last ?string?"); + return JIM_ERR; + } + objPtr = JimStringReplaceObj(interp, argv[2], argv[3], argv[4], argc == 6 ? argv[5] : NULL); + if (objPtr == NULL) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + + case OPT_REPEAT:{ + Jim_Obj *objPtr; + jim_wide count; + + if (argc != 4) { + Jim_WrongNumArgs(interp, 2, argv, "string count"); + return JIM_ERR; + } + if (Jim_GetWide(interp, argv[3], &count) != JIM_OK) { + return JIM_ERR; + } + objPtr = Jim_NewStringObj(interp, "", 0); + if (count > 0) { + while (count--) { + Jim_AppendObj(interp, objPtr, argv[2]); + } + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + case OPT_REVERSE:{ + char *buf, *p; + const char *str; + int len; + int i; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "string"); + return JIM_ERR; + } + + str = Jim_GetString(argv[2], &len); + buf = Jim_Alloc(len + 1); + p = buf + len; + *p = 0; + for (i = 0; i < len; ) { + int c; + int l = utf8_tounicode(str, &c); + memcpy(p - l, str, l); + p -= l; + i += l; + str += l; + } + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, len)); + return JIM_OK; + } + + case OPT_INDEX:{ + int idx; + const char *str; + + if (argc != 4) { + Jim_WrongNumArgs(interp, 2, argv, "string index"); + return JIM_ERR; + } + if (Jim_GetIndex(interp, argv[3], &idx) != JIM_OK) { + return JIM_ERR; + } + str = Jim_String(argv[2]); + len = Jim_Utf8Length(interp, argv[2]); + if (idx != INT_MIN && idx != INT_MAX) { + idx = JimRelToAbsIndex(len, idx); + } + if (idx < 0 || idx >= len || str == NULL) { + Jim_SetResultString(interp, "", 0); + } + else if (len == Jim_Length(argv[2])) { + + Jim_SetResultString(interp, str + idx, 1); + } + else { + int c; + int i = utf8_index(str, idx); + Jim_SetResultString(interp, str + i, utf8_tounicode(str + i, &c)); + } + return JIM_OK; + } + + case OPT_FIRST: + case OPT_LAST:{ + int idx = 0, l1, l2; + const char *s1, *s2; + + if (argc != 4 && argc != 5) { + Jim_WrongNumArgs(interp, 2, argv, "subString string ?index?"); + return JIM_ERR; + } + s1 = Jim_String(argv[2]); + s2 = Jim_String(argv[3]); + l1 = Jim_Utf8Length(interp, argv[2]); + l2 = Jim_Utf8Length(interp, argv[3]); + if (argc == 5) { + if (Jim_GetIndex(interp, argv[4], &idx) != JIM_OK) { + return JIM_ERR; + } + idx = JimRelToAbsIndex(l2, idx); + } + else if (option == OPT_LAST) { + idx = l2; + } + if (option == OPT_FIRST) { + Jim_SetResultInt(interp, JimStringFirst(s1, l1, s2, l2, idx)); + } + else { +#ifdef JIM_UTF8 + Jim_SetResultInt(interp, JimStringLastUtf8(s1, l1, s2, idx)); +#else + Jim_SetResultInt(interp, JimStringLast(s1, l1, s2, idx)); +#endif + } + return JIM_OK; + } + + case OPT_TRIM: + case OPT_TRIMLEFT: + case OPT_TRIMRIGHT:{ + Jim_Obj *trimchars; + + if (argc != 3 && argc != 4) { + Jim_WrongNumArgs(interp, 2, argv, "string ?trimchars?"); + return JIM_ERR; + } + trimchars = (argc == 4 ? argv[3] : NULL); + if (option == OPT_TRIM) { + Jim_SetResult(interp, JimStringTrim(interp, argv[2], trimchars)); + } + else if (option == OPT_TRIMLEFT) { + Jim_SetResult(interp, JimStringTrimLeft(interp, argv[2], trimchars)); + } + else if (option == OPT_TRIMRIGHT) { + Jim_SetResult(interp, JimStringTrimRight(interp, argv[2], trimchars)); + } + return JIM_OK; + } + + case OPT_TOLOWER: + case OPT_TOUPPER: + case OPT_TOTITLE: + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "string"); + return JIM_ERR; + } + if (option == OPT_TOLOWER) { + Jim_SetResult(interp, JimStringToLower(interp, argv[2])); + } + else if (option == OPT_TOUPPER) { + Jim_SetResult(interp, JimStringToUpper(interp, argv[2])); + } + else { + Jim_SetResult(interp, JimStringToTitle(interp, argv[2])); + } + return JIM_OK; + + case OPT_IS: + if (argc == 4 || (argc == 5 && Jim_CompareStringImmediate(interp, argv[3], "-strict"))) { + return JimStringIs(interp, argv[argc - 1], argv[2], argc == 5); + } + Jim_WrongNumArgs(interp, 2, argv, "class ?-strict? str"); + return JIM_ERR; + } + return JIM_OK; +} + + +static int Jim_TimeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + long i, count = 1; + jim_wide start, elapsed; + char buf[60]; + const char *fmt = "%" JIM_WIDE_MODIFIER " microseconds per iteration"; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "script ?count?"); + return JIM_ERR; + } + if (argc == 3) { + if (Jim_GetLong(interp, argv[2], &count) != JIM_OK) + return JIM_ERR; + } + if (count < 0) + return JIM_OK; + i = count; + start = JimClock(); + while (i-- > 0) { + int retval; + + retval = Jim_EvalObj(interp, argv[1]); + if (retval != JIM_OK) { + return retval; + } + } + elapsed = JimClock() - start; + sprintf(buf, fmt, count == 0 ? 0 : elapsed / count); + Jim_SetResultString(interp, buf, -1); + return JIM_OK; +} + + +static int Jim_ExitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + long exitCode = 0; + + if (argc > 2) { + Jim_WrongNumArgs(interp, 1, argv, "?exitCode?"); + return JIM_ERR; + } + if (argc == 2) { + if (Jim_GetLong(interp, argv[1], &exitCode) != JIM_OK) + return JIM_ERR; + } + interp->exitCode = exitCode; + return JIM_EXIT; +} + + +static int Jim_CatchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int exitCode = 0; + int i; + int sig = 0; + + + jim_wide ignore_mask = (1 << JIM_EXIT) | (1 << JIM_EVAL) | (1 << JIM_SIGNAL); + static const int max_ignore_code = sizeof(ignore_mask) * 8; + + Jim_SetGlobalVariableStr(interp, "errorCode", Jim_NewStringObj(interp, "NONE", -1)); + + for (i = 1; i < argc - 1; i++) { + const char *arg = Jim_String(argv[i]); + jim_wide option; + int ignore; + + + if (strcmp(arg, "--") == 0) { + i++; + break; + } + if (*arg != '-') { + break; + } + + if (strncmp(arg, "-no", 3) == 0) { + arg += 3; + ignore = 1; + } + else { + arg++; + ignore = 0; + } + + if (Jim_StringToWide(arg, &option, 10) != JIM_OK) { + option = -1; + } + if (option < 0) { + option = Jim_FindByName(arg, jimReturnCodes, jimReturnCodesSize); + } + if (option < 0) { + goto wrongargs; + } + + if (ignore) { + ignore_mask |= (1 << option); + } + else { + ignore_mask &= ~(1 << option); + } + } + + argc -= i; + if (argc < 1 || argc > 3) { + wrongargs: + Jim_WrongNumArgs(interp, 1, argv, + "?-?no?code ... --? script ?resultVarName? ?optionVarName?"); + return JIM_ERR; + } + argv += i; + + if ((ignore_mask & (1 << JIM_SIGNAL)) == 0) { + sig++; + } + + interp->signal_level += sig; + if (interp->signal_level && interp->sigmask) { + + exitCode = JIM_SIGNAL; + } + else { + exitCode = Jim_EvalObj(interp, argv[0]); + } + interp->signal_level -= sig; + + + if (exitCode >= 0 && exitCode < max_ignore_code && ((1 << exitCode) & ignore_mask)) { + + return exitCode; + } + + if (sig && exitCode == JIM_SIGNAL) { + + if (interp->signal_set_result) { + interp->signal_set_result(interp, interp->sigmask); + } + else { + Jim_SetResultInt(interp, interp->sigmask); + } + interp->sigmask = 0; + } + + if (argc >= 2) { + if (Jim_SetVariable(interp, argv[1], Jim_GetResult(interp)) != JIM_OK) { + return JIM_ERR; + } + if (argc == 3) { + Jim_Obj *optListObj = Jim_NewListObj(interp, NULL, 0); + + Jim_ListAppendElement(interp, optListObj, Jim_NewStringObj(interp, "-code", -1)); + Jim_ListAppendElement(interp, optListObj, + Jim_NewIntObj(interp, exitCode == JIM_RETURN ? interp->returnCode : exitCode)); + Jim_ListAppendElement(interp, optListObj, Jim_NewStringObj(interp, "-level", -1)); + Jim_ListAppendElement(interp, optListObj, Jim_NewIntObj(interp, interp->returnLevel)); + if (exitCode == JIM_ERR) { + Jim_Obj *errorCode; + Jim_ListAppendElement(interp, optListObj, Jim_NewStringObj(interp, "-errorinfo", + -1)); + Jim_ListAppendElement(interp, optListObj, interp->stackTrace); + + errorCode = Jim_GetGlobalVariableStr(interp, "errorCode", JIM_NONE); + if (errorCode) { + Jim_ListAppendElement(interp, optListObj, Jim_NewStringObj(interp, "-errorcode", -1)); + Jim_ListAppendElement(interp, optListObj, errorCode); + } + } + if (Jim_SetVariable(interp, argv[2], optListObj) != JIM_OK) { + return JIM_ERR; + } + } + } + Jim_SetResultInt(interp, exitCode); + return JIM_OK; +} + +#ifdef JIM_REFERENCES + + +static int Jim_RefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 3 && argc != 4) { + Jim_WrongNumArgs(interp, 1, argv, "string tag ?finalizer?"); + return JIM_ERR; + } + if (argc == 3) { + Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], NULL)); + } + else { + Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], argv[3])); + } + return JIM_OK; +} + + +static int Jim_GetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Reference *refPtr; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "reference"); + return JIM_ERR; + } + if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL) + return JIM_ERR; + Jim_SetResult(interp, refPtr->objPtr); + return JIM_OK; +} + + +static int Jim_SetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Reference *refPtr; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "reference newValue"); + return JIM_ERR; + } + if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL) + return JIM_ERR; + Jim_IncrRefCount(argv[2]); + Jim_DecrRefCount(interp, refPtr->objPtr); + refPtr->objPtr = argv[2]; + Jim_SetResult(interp, argv[2]); + return JIM_OK; +} + + +static int Jim_CollectCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + Jim_SetResultInt(interp, Jim_Collect(interp)); + + + while (interp->freeList) { + Jim_Obj *nextObjPtr = interp->freeList->nextObjPtr; + Jim_Free(interp->freeList); + interp->freeList = nextObjPtr; + } + + return JIM_OK; +} + + +static int Jim_FinalizeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "reference ?finalizerProc?"); + return JIM_ERR; + } + if (argc == 2) { + Jim_Obj *cmdNamePtr; + + if (Jim_GetFinalizer(interp, argv[1], &cmdNamePtr) != JIM_OK) + return JIM_ERR; + if (cmdNamePtr != NULL) + Jim_SetResult(interp, cmdNamePtr); + } + else { + if (Jim_SetFinalizer(interp, argv[1], argv[2]) != JIM_OK) + return JIM_ERR; + Jim_SetResult(interp, argv[2]); + } + return JIM_OK; +} + + +static int JimInfoReferences(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listObjPtr; + Jim_HashTableIterator *htiter; + Jim_HashEntry *he; + + listObjPtr = Jim_NewListObj(interp, NULL, 0); + + htiter = Jim_GetHashTableIterator(&interp->references); + while ((he = Jim_NextHashEntry(htiter)) != NULL) { + char buf[JIM_REFERENCE_SPACE + 1]; + Jim_Reference *refPtr = he->u.val; + const unsigned long *refId = he->key; + + JimFormatReference(buf, refPtr, *refId); + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, buf, -1)); + } + Jim_FreeHashTableIterator(htiter); + Jim_SetResult(interp, listObjPtr); + return JIM_OK; +} +#endif + + +static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "oldName newName"); + return JIM_ERR; + } + + if (JimValidName(interp, "new procedure", argv[2])) { + return JIM_ERR; + } + + return Jim_RenameCommand(interp, Jim_String(argv[1]), Jim_String(argv[2])); +} + +#define JIM_DICTMATCH_VALUES 0x0001 + +typedef void JimDictMatchCallbackType(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type); + +static void JimDictMatchKeys(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type) +{ + Jim_ListAppendElement(interp, listObjPtr, (Jim_Obj *)he->key); + if (type & JIM_DICTMATCH_VALUES) { + Jim_ListAppendElement(interp, listObjPtr, (Jim_Obj *)he->u.val); + } +} + +static Jim_Obj *JimDictPatternMatch(Jim_Interp *interp, Jim_HashTable *ht, Jim_Obj *patternObjPtr, + JimDictMatchCallbackType *callback, int type) +{ + Jim_HashEntry *he; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + + Jim_HashTableIterator *htiter = Jim_GetHashTableIterator(ht); + while ((he = Jim_NextHashEntry(htiter)) != NULL) { + if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), Jim_String((Jim_Obj *)he->key), 0)) { + callback(interp, listObjPtr, he, type); + } + } + Jim_FreeHashTableIterator(htiter); + + return listObjPtr; +} + + +int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObjPtr) +{ + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, JimDictPatternMatch(interp, objPtr->internalRep.ptr, patternObjPtr, JimDictMatchKeys, 0)); + return JIM_OK; +} + +int Jim_DictValues(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObjPtr) +{ + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, JimDictPatternMatch(interp, objPtr->internalRep.ptr, patternObjPtr, JimDictMatchKeys, JIM_DICTMATCH_VALUES)); + return JIM_OK; +} + +int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return -1; + } + return ((Jim_HashTable *)objPtr->internalRep.ptr)->used; +} + + +static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + int option; + static const char * const options[] = { + "create", "get", "set", "unset", "exists", "keys", "merge", "size", "with", NULL + }; + enum + { + OPT_CREATE, OPT_GET, OPT_SET, OPT_UNSET, OPT_EXIST, OPT_KEYS, OPT_MERGE, OPT_SIZE, OPT_WITH, + }; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "subcommand ?arguments ...?"); + return JIM_ERR; + } + + if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + + switch (option) { + case OPT_GET: + if (argc < 3) { + Jim_WrongNumArgs(interp, 2, argv, "varName ?key ...?"); + return JIM_ERR; + } + if (Jim_DictKeysVector(interp, argv[2], argv + 3, argc - 3, &objPtr, + JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + + case OPT_SET: + if (argc < 5) { + Jim_WrongNumArgs(interp, 2, argv, "varName key ?key ...? value"); + return JIM_ERR; + } + return Jim_SetDictKeysVector(interp, argv[2], argv + 3, argc - 4, argv[argc - 1], JIM_ERRMSG); + + case OPT_EXIST: + if (argc < 3) { + Jim_WrongNumArgs(interp, 2, argv, "varName ?key ...?"); + return JIM_ERR; + } + Jim_SetResultBool(interp, Jim_DictKeysVector(interp, argv[2], argv + 3, argc - 3, + &objPtr, JIM_ERRMSG) == JIM_OK); + return JIM_OK; + + case OPT_UNSET: + if (argc < 4) { + Jim_WrongNumArgs(interp, 2, argv, "varName key ?key ...?"); + return JIM_ERR; + } + return Jim_SetDictKeysVector(interp, argv[2], argv + 3, argc - 3, NULL, JIM_NONE); + + case OPT_KEYS: + if (argc != 3 && argc != 4) { + Jim_WrongNumArgs(interp, 2, argv, "dictVar ?pattern?"); + return JIM_ERR; + } + return Jim_DictKeys(interp, argv[2], argc == 4 ? argv[3] : NULL); + + case OPT_SIZE: { + int size; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "dictVar"); + return JIM_ERR; + } + + size = Jim_DictSize(interp, argv[2]); + if (size < 0) { + return JIM_ERR; + } + Jim_SetResultInt(interp, size); + return JIM_OK; + } + + case OPT_MERGE: + if (argc == 2) { + return JIM_OK; + } + else if (SetDictFromAny(interp, argv[2]) != JIM_OK) { + return JIM_ERR; + } + else { + return Jim_EvalPrefix(interp, "dict merge", argc - 2, argv + 2); + } + + case OPT_WITH: + if (argc < 4) { + Jim_WrongNumArgs(interp, 2, argv, "dictVar ?key ...? script"); + return JIM_ERR; + } + else if (Jim_GetVariable(interp, argv[2], JIM_ERRMSG) == NULL) { + return JIM_ERR; + } + else { + return Jim_EvalPrefix(interp, "dict with", argc - 2, argv + 2); + } + + case OPT_CREATE: + if (argc % 2) { + Jim_WrongNumArgs(interp, 2, argv, "?key value ...?"); + return JIM_ERR; + } + objPtr = Jim_NewDictObj(interp, argv + 2, argc - 2); + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + return JIM_ERR; +} + + +static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + static const char * const options[] = { + "-nobackslashes", "-nocommands", "-novariables", NULL + }; + enum + { OPT_NOBACKSLASHES, OPT_NOCOMMANDS, OPT_NOVARIABLES }; + int i; + int flags = JIM_SUBST_FLAG; + Jim_Obj *objPtr; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "?options? string"); + return JIM_ERR; + } + for (i = 1; i < (argc - 1); i++) { + int option; + + if (Jim_GetEnum(interp, argv[i], options, &option, NULL, + JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + switch (option) { + case OPT_NOBACKSLASHES: + flags |= JIM_SUBST_NOESC; + break; + case OPT_NOCOMMANDS: + flags |= JIM_SUBST_NOCMD; + break; + case OPT_NOVARIABLES: + flags |= JIM_SUBST_NOVAR; + break; + } + } + if (Jim_SubstObj(interp, argv[argc - 1], &objPtr, flags) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + + +static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int cmd; + Jim_Obj *objPtr; + int mode = 0; + + static const char * const commands[] = { + "body", "statics", "commands", "procs", "channels", "exists", "globals", "level", "frame", "locals", + "vars", "version", "patchlevel", "complete", "args", "hostname", + "script", "source", "stacktrace", "nameofexecutable", "returncodes", + "references", "alias", NULL + }; + enum + { INFO_BODY, INFO_STATICS, INFO_COMMANDS, INFO_PROCS, INFO_CHANNELS, INFO_EXISTS, INFO_GLOBALS, INFO_LEVEL, + INFO_FRAME, INFO_LOCALS, INFO_VARS, INFO_VERSION, INFO_PATCHLEVEL, INFO_COMPLETE, INFO_ARGS, + INFO_HOSTNAME, INFO_SCRIPT, INFO_SOURCE, INFO_STACKTRACE, INFO_NAMEOFEXECUTABLE, + INFO_RETURNCODES, INFO_REFERENCES, INFO_ALIAS + }; + +#ifdef jim_ext_namespace + int nons = 0; + + if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) { + + argc--; + argv++; + nons = 1; + } +#endif + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "subcommand ?args ...?"); + return JIM_ERR; + } + if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) + != JIM_OK) { + return JIM_ERR; + } + + + switch (cmd) { + case INFO_EXISTS: + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "varName"); + return JIM_ERR; + } + Jim_SetResultBool(interp, Jim_GetVariable(interp, argv[2], 0) != NULL); + break; + + case INFO_ALIAS:{ + Jim_Cmd *cmdPtr; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "command"); + return JIM_ERR; + } + if ((cmdPtr = Jim_GetCommand(interp, argv[2], JIM_ERRMSG)) == NULL) { + return JIM_ERR; + } + if (cmdPtr->isproc || cmdPtr->u.native.cmdProc != JimAliasCmd) { + Jim_SetResultFormatted(interp, "command \"%#s\" is not an alias", argv[2]); + return JIM_ERR; + } + Jim_SetResult(interp, (Jim_Obj *)cmdPtr->u.native.privData); + return JIM_OK; + } + + case INFO_CHANNELS: + mode++; +#ifndef jim_ext_aio + Jim_SetResultString(interp, "aio not enabled", -1); + return JIM_ERR; +#endif + case INFO_PROCS: + mode++; + case INFO_COMMANDS: + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "?pattern?"); + return JIM_ERR; + } +#ifdef jim_ext_namespace + if (!nons) { + if (Jim_Length(interp->framePtr->nsObj) || (argc == 3 && JimGlobMatch("::*", Jim_String(argv[2]), 0))) { + return Jim_EvalPrefix(interp, "namespace info", argc - 1, argv + 1); + } + } +#endif + Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, mode)); + break; + + case INFO_VARS: + mode++; + case INFO_LOCALS: + mode++; + case INFO_GLOBALS: + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "?pattern?"); + return JIM_ERR; + } +#ifdef jim_ext_namespace + if (!nons) { + if (Jim_Length(interp->framePtr->nsObj) || (argc == 3 && JimGlobMatch("::*", Jim_String(argv[2]), 0))) { + return Jim_EvalPrefix(interp, "namespace info", argc - 1, argv + 1); + } + } +#endif + Jim_SetResult(interp, JimVariablesList(interp, argc == 3 ? argv[2] : NULL, mode)); + break; + + case INFO_SCRIPT: + if (argc != 2) { + Jim_WrongNumArgs(interp, 2, argv, ""); + return JIM_ERR; + } + Jim_SetResult(interp, Jim_GetScript(interp, interp->currentScriptObj)->fileNameObj); + break; + + case INFO_SOURCE:{ + int line; + Jim_Obj *resObjPtr; + Jim_Obj *fileNameObj; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "source"); + return JIM_ERR; + } + if (argv[2]->typePtr == &sourceObjType) { + fileNameObj = argv[2]->internalRep.sourceValue.fileNameObj; + line = argv[2]->internalRep.sourceValue.lineNumber; + } + else if (argv[2]->typePtr == &scriptObjType) { + ScriptObj *script = Jim_GetScript(interp, argv[2]); + fileNameObj = script->fileNameObj; + line = script->firstline; + } + else { + fileNameObj = interp->emptyObj; + line = 1; + } + resObjPtr = Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, resObjPtr, fileNameObj); + Jim_ListAppendElement(interp, resObjPtr, Jim_NewIntObj(interp, line)); + Jim_SetResult(interp, resObjPtr); + break; + } + + case INFO_STACKTRACE: + Jim_SetResult(interp, interp->stackTrace); + break; + + case INFO_LEVEL: + case INFO_FRAME: + switch (argc) { + case 2: + Jim_SetResultInt(interp, interp->framePtr->level); + break; + + case 3: + if (JimInfoLevel(interp, argv[2], &objPtr, cmd == INFO_LEVEL) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + break; + + default: + Jim_WrongNumArgs(interp, 2, argv, "?levelNum?"); + return JIM_ERR; + } + break; + + case INFO_BODY: + case INFO_STATICS: + case INFO_ARGS:{ + Jim_Cmd *cmdPtr; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "procname"); + return JIM_ERR; + } + if ((cmdPtr = Jim_GetCommand(interp, argv[2], JIM_ERRMSG)) == NULL) { + return JIM_ERR; + } + if (!cmdPtr->isproc) { + Jim_SetResultFormatted(interp, "command \"%#s\" is not a procedure", argv[2]); + return JIM_ERR; + } + switch (cmd) { + case INFO_BODY: + Jim_SetResult(interp, cmdPtr->u.proc.bodyObjPtr); + break; + case INFO_ARGS: + Jim_SetResult(interp, cmdPtr->u.proc.argListObjPtr); + break; + case INFO_STATICS: + if (cmdPtr->u.proc.staticVars) { + int mode = JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES; + Jim_SetResult(interp, JimHashtablePatternMatch(interp, cmdPtr->u.proc.staticVars, + NULL, JimVariablesMatch, mode)); + } + break; + } + break; + } + + case INFO_VERSION: + case INFO_PATCHLEVEL:{ + char buf[(JIM_INTEGER_SPACE * 2) + 1]; + + sprintf(buf, "%d.%d", JIM_VERSION / 100, JIM_VERSION % 100); + Jim_SetResultString(interp, buf, -1); + break; + } + + case INFO_COMPLETE: + if (argc != 3 && argc != 4) { + Jim_WrongNumArgs(interp, 2, argv, "script ?missing?"); + return JIM_ERR; + } + else { + int len; + const char *s = Jim_GetString(argv[2], &len); + char missing; + + Jim_SetResultBool(interp, Jim_ScriptIsComplete(s, len, &missing)); + if (missing != ' ' && argc == 4) { + Jim_SetVariable(interp, argv[3], Jim_NewStringObj(interp, &missing, 1)); + } + } + break; + + case INFO_HOSTNAME: + + return Jim_Eval(interp, "os.gethostname"); + + case INFO_NAMEOFEXECUTABLE: + + return Jim_Eval(interp, "{info nameofexecutable}"); + + case INFO_RETURNCODES: + if (argc == 2) { + int i; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + for (i = 0; jimReturnCodes[i]; i++) { + Jim_ListAppendElement(interp, listObjPtr, Jim_NewIntObj(interp, i)); + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, + jimReturnCodes[i], -1)); + } + + Jim_SetResult(interp, listObjPtr); + } + else if (argc == 3) { + long code; + const char *name; + + if (Jim_GetLong(interp, argv[2], &code) != JIM_OK) { + return JIM_ERR; + } + name = Jim_ReturnCode(code); + if (*name == '?') { + Jim_SetResultInt(interp, code); + } + else { + Jim_SetResultString(interp, name, -1); + } + } + else { + Jim_WrongNumArgs(interp, 2, argv, "?code?"); + return JIM_ERR; + } + break; + case INFO_REFERENCES: +#ifdef JIM_REFERENCES + return JimInfoReferences(interp, argc, argv); +#else + Jim_SetResultString(interp, "not supported", -1); + return JIM_ERR; +#endif + } + return JIM_OK; +} + + +static int Jim_ExistsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + int result = 0; + + static const char * const options[] = { + "-command", "-proc", "-alias", "-var", NULL + }; + enum + { + OPT_COMMAND, OPT_PROC, OPT_ALIAS, OPT_VAR + }; + int option; + + if (argc == 2) { + option = OPT_VAR; + objPtr = argv[1]; + } + else if (argc == 3) { + if (Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + objPtr = argv[2]; + } + else { + Jim_WrongNumArgs(interp, 1, argv, "?option? name"); + return JIM_ERR; + } + + if (option == OPT_VAR) { + result = Jim_GetVariable(interp, objPtr, 0) != NULL; + } + else { + + Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE); + + if (cmd) { + switch (option) { + case OPT_COMMAND: + result = 1; + break; + + case OPT_ALIAS: + result = cmd->isproc == 0 && cmd->u.native.cmdProc == JimAliasCmd; + break; + + case OPT_PROC: + result = cmd->isproc; + break; + } + } + } + Jim_SetResultBool(interp, result); + return JIM_OK; +} + + +static int Jim_SplitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *str, *splitChars, *noMatchStart; + int splitLen, strLen; + Jim_Obj *resObjPtr; + int c; + int len; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "string ?splitChars?"); + return JIM_ERR; + } + + str = Jim_GetString(argv[1], &len); + if (len == 0) { + return JIM_OK; + } + strLen = Jim_Utf8Length(interp, argv[1]); + + + if (argc == 2) { + splitChars = " \n\t\r"; + splitLen = 4; + } + else { + splitChars = Jim_String(argv[2]); + splitLen = Jim_Utf8Length(interp, argv[2]); + } + + noMatchStart = str; + resObjPtr = Jim_NewListObj(interp, NULL, 0); + + + if (splitLen) { + Jim_Obj *objPtr; + while (strLen--) { + const char *sc = splitChars; + int scLen = splitLen; + int sl = utf8_tounicode(str, &c); + while (scLen--) { + int pc; + sc += utf8_tounicode(sc, &pc); + if (c == pc) { + objPtr = Jim_NewStringObj(interp, noMatchStart, (str - noMatchStart)); + Jim_ListAppendElement(interp, resObjPtr, objPtr); + noMatchStart = str + sl; + break; + } + } + str += sl; + } + objPtr = Jim_NewStringObj(interp, noMatchStart, (str - noMatchStart)); + Jim_ListAppendElement(interp, resObjPtr, objPtr); + } + else { + Jim_Obj **commonObj = NULL; +#define NUM_COMMON (128 - 9) + while (strLen--) { + int n = utf8_tounicode(str, &c); +#ifdef JIM_OPTIMIZATION + if (c >= 9 && c < 128) { + + c -= 9; + if (!commonObj) { + commonObj = Jim_Alloc(sizeof(*commonObj) * NUM_COMMON); + memset(commonObj, 0, sizeof(*commonObj) * NUM_COMMON); + } + if (!commonObj[c]) { + commonObj[c] = Jim_NewStringObj(interp, str, 1); + } + Jim_ListAppendElement(interp, resObjPtr, commonObj[c]); + str++; + continue; + } +#endif + Jim_ListAppendElement(interp, resObjPtr, Jim_NewStringObjUtf8(interp, str, 1)); + str += n; + } + Jim_Free(commonObj); + } + + Jim_SetResult(interp, resObjPtr); + return JIM_OK; +} + + +static int Jim_JoinCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *joinStr; + int joinStrLen; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?"); + return JIM_ERR; + } + + if (argc == 2) { + joinStr = " "; + joinStrLen = 1; + } + else { + joinStr = Jim_GetString(argv[2], &joinStrLen); + } + Jim_SetResult(interp, Jim_ListJoin(interp, argv[1], joinStr, joinStrLen)); + return JIM_OK; +} + + +static int Jim_FormatCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "formatString ?arg arg ...?"); + return JIM_ERR; + } + objPtr = Jim_FormatString(interp, argv[1], argc - 2, argv + 2); + if (objPtr == NULL) + return JIM_ERR; + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + + +static int Jim_ScanCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listPtr, **outVec; + int outc, i; + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "string format ?varName varName ...?"); + return JIM_ERR; + } + if (argv[2]->typePtr != &scanFmtStringObjType) + SetScanFmtFromAny(interp, argv[2]); + if (FormatGetError(argv[2]) != 0) { + Jim_SetResultString(interp, FormatGetError(argv[2]), -1); + return JIM_ERR; + } + if (argc > 3) { + int maxPos = FormatGetMaxPos(argv[2]); + int count = FormatGetCnvCount(argv[2]); + + if (maxPos > argc - 3) { + Jim_SetResultString(interp, "\"%n$\" argument index out of range", -1); + return JIM_ERR; + } + else if (count > argc - 3) { + Jim_SetResultString(interp, "different numbers of variable names and " + "field specifiers", -1); + return JIM_ERR; + } + else if (count < argc - 3) { + Jim_SetResultString(interp, "variable is not assigned by any " + "conversion specifiers", -1); + return JIM_ERR; + } + } + listPtr = Jim_ScanString(interp, argv[1], argv[2], JIM_ERRMSG); + if (listPtr == 0) + return JIM_ERR; + if (argc > 3) { + int rc = JIM_OK; + int count = 0; + + if (listPtr != 0 && listPtr != (Jim_Obj *)EOF) { + int len = Jim_ListLength(interp, listPtr); + + if (len != 0) { + JimListGetElements(interp, listPtr, &outc, &outVec); + for (i = 0; i < outc; ++i) { + if (Jim_Length(outVec[i]) > 0) { + ++count; + if (Jim_SetVariable(interp, argv[3 + i], outVec[i]) != JIM_OK) { + rc = JIM_ERR; + } + } + } + } + Jim_FreeNewObj(interp, listPtr); + } + else { + count = -1; + } + if (rc == JIM_OK) { + Jim_SetResultInt(interp, count); + } + return rc; + } + else { + if (listPtr == (Jim_Obj *)EOF) { + Jim_SetResult(interp, Jim_NewListObj(interp, 0, 0)); + return JIM_OK; + } + Jim_SetResult(interp, listPtr); + } + return JIM_OK; +} + + +static int Jim_ErrorCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "message ?stacktrace?"); + return JIM_ERR; + } + Jim_SetResult(interp, argv[1]); + if (argc == 3) { + JimSetStackTrace(interp, argv[2]); + return JIM_ERR; + } + interp->addStackTrace++; + return JIM_ERR; +} + + +static int Jim_LrangeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + + if (argc != 4) { + Jim_WrongNumArgs(interp, 1, argv, "list first last"); + return JIM_ERR; + } + if ((objPtr = Jim_ListRange(interp, argv[1], argv[2], argv[3])) == NULL) + return JIM_ERR; + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + + +static int Jim_LrepeatCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + long count; + + if (argc < 2 || Jim_GetLong(interp, argv[1], &count) != JIM_OK || count < 0) { + Jim_WrongNumArgs(interp, 1, argv, "count ?value ...?"); + return JIM_ERR; + } + + if (count == 0 || argc == 2) { + return JIM_OK; + } + + argc -= 2; + argv += 2; + + objPtr = Jim_NewListObj(interp, argv, argc); + while (--count) { + ListInsertElements(objPtr, -1, argc, argv); + } + + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + +char **Jim_GetEnviron(void) +{ +#if defined(HAVE__NSGETENVIRON) + return *_NSGetEnviron(); +#else + #if !defined(NO_ENVIRON_EXTERN) + extern char **environ; + #endif + + return environ; +#endif +} + +void Jim_SetEnviron(char **env) +{ +#if defined(HAVE__NSGETENVIRON) + *_NSGetEnviron() = env; +#else + #if !defined(NO_ENVIRON_EXTERN) + extern char **environ; + #endif + + environ = env; +#endif +} + + +static int Jim_EnvCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *key; + const char *val; + + if (argc == 1) { + char **e = Jim_GetEnviron(); + + int i; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + for (i = 0; e[i]; i++) { + const char *equals = strchr(e[i], '='); + + if (equals) { + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, e[i], + equals - e[i])); + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, equals + 1, -1)); + } + } + + Jim_SetResult(interp, listObjPtr); + return JIM_OK; + } + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?default?"); + return JIM_ERR; + } + key = Jim_String(argv[1]); + val = getenv(key); + if (val == NULL) { + if (argc < 3) { + Jim_SetResultFormatted(interp, "environment variable \"%#s\" does not exist", argv[1]); + return JIM_ERR; + } + val = Jim_String(argv[2]); + } + Jim_SetResult(interp, Jim_NewStringObj(interp, val, -1)); + return JIM_OK; +} + + +static int Jim_SourceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retval; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "fileName"); + return JIM_ERR; + } + retval = Jim_EvalFile(interp, Jim_String(argv[1])); + if (retval == JIM_RETURN) + return JIM_OK; + return retval; +} + + +static int Jim_LreverseCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *revObjPtr, **ele; + int len; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "list"); + return JIM_ERR; + } + JimListGetElements(interp, argv[1], &len, &ele); + len--; + revObjPtr = Jim_NewListObj(interp, NULL, 0); + while (len >= 0) + ListAppendElement(revObjPtr, ele[len--]); + Jim_SetResult(interp, revObjPtr); + return JIM_OK; +} + +static int JimRangeLen(jim_wide start, jim_wide end, jim_wide step) +{ + jim_wide len; + + if (step == 0) + return -1; + if (start == end) + return 0; + else if (step > 0 && start > end) + return -1; + else if (step < 0 && end > start) + return -1; + len = end - start; + if (len < 0) + len = -len; + if (step < 0) + step = -step; + len = 1 + ((len - 1) / step); + if (len > INT_MAX) + len = INT_MAX; + return (int)((len < 0) ? -1 : len); +} + + +static int Jim_RangeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_wide start = 0, end, step = 1; + int len, i; + Jim_Obj *objPtr; + + if (argc < 2 || argc > 4) { + Jim_WrongNumArgs(interp, 1, argv, "?start? end ?step?"); + return JIM_ERR; + } + if (argc == 2) { + if (Jim_GetWide(interp, argv[1], &end) != JIM_OK) + return JIM_ERR; + } + else { + if (Jim_GetWide(interp, argv[1], &start) != JIM_OK || + Jim_GetWide(interp, argv[2], &end) != JIM_OK) + return JIM_ERR; + if (argc == 4 && Jim_GetWide(interp, argv[3], &step) != JIM_OK) + return JIM_ERR; + } + if ((len = JimRangeLen(start, end, step)) == -1) { + Jim_SetResultString(interp, "Invalid (infinite?) range specified", -1); + return JIM_ERR; + } + objPtr = Jim_NewListObj(interp, NULL, 0); + for (i = 0; i < len; i++) + ListAppendElement(objPtr, Jim_NewIntObj(interp, start + i * step)); + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + + +static int Jim_RandCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_wide min = 0, max = 0, len, maxMul; + + if (argc < 1 || argc > 3) { + Jim_WrongNumArgs(interp, 1, argv, "?min? max"); + return JIM_ERR; + } + if (argc == 1) { + max = JIM_WIDE_MAX; + } else if (argc == 2) { + if (Jim_GetWide(interp, argv[1], &max) != JIM_OK) + return JIM_ERR; + } else if (argc == 3) { + if (Jim_GetWide(interp, argv[1], &min) != JIM_OK || + Jim_GetWide(interp, argv[2], &max) != JIM_OK) + return JIM_ERR; + } + len = max-min; + if (len < 0) { + Jim_SetResultString(interp, "Invalid arguments (max < min)", -1); + return JIM_ERR; + } + maxMul = JIM_WIDE_MAX - (len ? (JIM_WIDE_MAX%len) : 0); + while (1) { + jim_wide r; + + JimRandomBytes(interp, &r, sizeof(jim_wide)); + if (r < 0 || r >= maxMul) continue; + r = (len == 0) ? 0 : r%len; + Jim_SetResultInt(interp, min+r); + return JIM_OK; + } +} + +static const struct { + const char *name; + Jim_CmdProc cmdProc; +} Jim_CoreCommandsTable[] = { + {"alias", Jim_AliasCoreCommand}, + {"set", Jim_SetCoreCommand}, + {"unset", Jim_UnsetCoreCommand}, + {"puts", Jim_PutsCoreCommand}, + {"+", Jim_AddCoreCommand}, + {"*", Jim_MulCoreCommand}, + {"-", Jim_SubCoreCommand}, + {"/", Jim_DivCoreCommand}, + {"incr", Jim_IncrCoreCommand}, + {"while", Jim_WhileCoreCommand}, + {"loop", Jim_LoopCoreCommand}, + {"for", Jim_ForCoreCommand}, + {"foreach", Jim_ForeachCoreCommand}, + {"lmap", Jim_LmapCoreCommand}, + {"lassign", Jim_LassignCoreCommand}, + {"if", Jim_IfCoreCommand}, + {"switch", Jim_SwitchCoreCommand}, + {"list", Jim_ListCoreCommand}, + {"lindex", Jim_LindexCoreCommand}, + {"lset", Jim_LsetCoreCommand}, + {"lsearch", Jim_LsearchCoreCommand}, + {"llength", Jim_LlengthCoreCommand}, + {"lappend", Jim_LappendCoreCommand}, + {"linsert", Jim_LinsertCoreCommand}, + {"lreplace", Jim_LreplaceCoreCommand}, + {"lsort", Jim_LsortCoreCommand}, + {"append", Jim_AppendCoreCommand}, + {"debug", Jim_DebugCoreCommand}, + {"eval", Jim_EvalCoreCommand}, + {"uplevel", Jim_UplevelCoreCommand}, + {"expr", Jim_ExprCoreCommand}, + {"break", Jim_BreakCoreCommand}, + {"continue", Jim_ContinueCoreCommand}, + {"proc", Jim_ProcCoreCommand}, + {"concat", Jim_ConcatCoreCommand}, + {"return", Jim_ReturnCoreCommand}, + {"upvar", Jim_UpvarCoreCommand}, + {"global", Jim_GlobalCoreCommand}, + {"string", Jim_StringCoreCommand}, + {"time", Jim_TimeCoreCommand}, + {"exit", Jim_ExitCoreCommand}, + {"catch", Jim_CatchCoreCommand}, +#ifdef JIM_REFERENCES + {"ref", Jim_RefCoreCommand}, + {"getref", Jim_GetrefCoreCommand}, + {"setref", Jim_SetrefCoreCommand}, + {"finalize", Jim_FinalizeCoreCommand}, + {"collect", Jim_CollectCoreCommand}, +#endif + {"rename", Jim_RenameCoreCommand}, + {"dict", Jim_DictCoreCommand}, + {"subst", Jim_SubstCoreCommand}, + {"info", Jim_InfoCoreCommand}, + {"exists", Jim_ExistsCoreCommand}, + {"split", Jim_SplitCoreCommand}, + {"join", Jim_JoinCoreCommand}, + {"format", Jim_FormatCoreCommand}, + {"scan", Jim_ScanCoreCommand}, + {"error", Jim_ErrorCoreCommand}, + {"lrange", Jim_LrangeCoreCommand}, + {"lrepeat", Jim_LrepeatCoreCommand}, + {"env", Jim_EnvCoreCommand}, + {"source", Jim_SourceCoreCommand}, + {"lreverse", Jim_LreverseCoreCommand}, + {"range", Jim_RangeCoreCommand}, + {"rand", Jim_RandCoreCommand}, + {"tailcall", Jim_TailcallCoreCommand}, + {"local", Jim_LocalCoreCommand}, + {"upcall", Jim_UpcallCoreCommand}, + {"apply", Jim_ApplyCoreCommand}, + {NULL, NULL}, +}; + +void Jim_RegisterCoreCommands(Jim_Interp *interp) +{ + int i = 0; + + while (Jim_CoreCommandsTable[i].name != NULL) { + Jim_CreateCommand(interp, + Jim_CoreCommandsTable[i].name, Jim_CoreCommandsTable[i].cmdProc, NULL, NULL); + i++; + } +} + +void Jim_MakeErrorMessage(Jim_Interp *interp) +{ + Jim_Obj *argv[2]; + + argv[0] = Jim_NewStringObj(interp, "errorInfo", -1); + argv[1] = interp->result; + + Jim_EvalObjVector(interp, 2, argv); +} + +static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype, + const char *prefix, const char *const *tablePtr, const char *name) +{ + int count; + char **tablePtrSorted; + int i; + + for (count = 0; tablePtr[count]; count++) { + } + + if (name == NULL) { + name = "option"; + } + + Jim_SetResultFormatted(interp, "%s%s \"%s\": must be ", badtype, name, arg); + tablePtrSorted = Jim_Alloc(sizeof(char *) * count); + memcpy(tablePtrSorted, tablePtr, sizeof(char *) * count); + qsort(tablePtrSorted, count, sizeof(char *), qsortCompareStringPointers); + for (i = 0; i < count; i++) { + if (i + 1 == count && count > 1) { + Jim_AppendString(interp, Jim_GetResult(interp), "or ", -1); + } + Jim_AppendStrings(interp, Jim_GetResult(interp), prefix, tablePtrSorted[i], NULL); + if (i + 1 != count) { + Jim_AppendString(interp, Jim_GetResult(interp), ", ", -1); + } + } + Jim_Free(tablePtrSorted); +} + +int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr, + const char *const *tablePtr, int *indexPtr, const char *name, int flags) +{ + const char *bad = "bad "; + const char *const *entryPtr = NULL; + int i; + int match = -1; + int arglen; + const char *arg = Jim_GetString(objPtr, &arglen); + + *indexPtr = -1; + + for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) { + if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) { + + *indexPtr = i; + return JIM_OK; + } + if (flags & JIM_ENUM_ABBREV) { + if (strncmp(arg, *entryPtr, arglen) == 0) { + if (*arg == '-' && arglen == 1) { + break; + } + if (match >= 0) { + bad = "ambiguous "; + goto ambiguous; + } + match = i; + } + } + } + + + if (match >= 0) { + *indexPtr = match; + return JIM_OK; + } + + ambiguous: + if (flags & JIM_ERRMSG) { + JimSetFailedEnumResult(interp, arg, bad, "", tablePtr, name); + } + return JIM_ERR; +} + +int Jim_FindByName(const char *name, const char * const array[], size_t len) +{ + int i; + + for (i = 0; i < (int)len; i++) { + if (array[i] && strcmp(array[i], name) == 0) { + return i; + } + } + return -1; +} + +int Jim_IsDict(Jim_Obj *objPtr) +{ + return objPtr->typePtr == &dictObjType; +} + +int Jim_IsList(Jim_Obj *objPtr) +{ + return objPtr->typePtr == &listObjType; +} + +void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...) +{ + + int len = strlen(format); + int extra = 0; + int n = 0; + const char *params[5]; + char *buf; + va_list args; + int i; + + va_start(args, format); + + for (i = 0; i < len && n < 5; i++) { + int l; + + if (strncmp(format + i, "%s", 2) == 0) { + params[n] = va_arg(args, char *); + + l = strlen(params[n]); + } + else if (strncmp(format + i, "%#s", 3) == 0) { + Jim_Obj *objPtr = va_arg(args, Jim_Obj *); + + params[n] = Jim_GetString(objPtr, &l); + } + else { + if (format[i] == '%') { + i++; + } + continue; + } + n++; + extra += l; + } + + len += extra; + buf = Jim_Alloc(len + 1); + len = snprintf(buf, len + 1, format, params[0], params[1], params[2], params[3], params[4]); + + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, len)); +} + + +#ifndef jim_ext_package +int Jim_PackageProvide(Jim_Interp *interp, const char *name, const char *ver, int flags) +{ + return JIM_OK; +} +#endif +#ifndef jim_ext_aio +FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *fhObj) +{ + Jim_SetResultString(interp, "aio not enabled", -1); + return NULL; +} +#endif + + +#include +#include + + +static int subcmd_null(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + + return JIM_OK; +} + +static const jim_subcmd_type dummy_subcmd = { + "dummy", NULL, subcmd_null, 0, 0, JIM_MODFLAG_HIDDEN +}; + +static void add_commands(Jim_Interp *interp, const jim_subcmd_type * ct, const char *sep) +{ + const char *s = ""; + + for (; ct->cmd; ct++) { + if (!(ct->flags & JIM_MODFLAG_HIDDEN)) { + Jim_AppendStrings(interp, Jim_GetResult(interp), s, ct->cmd, NULL); + s = sep; + } + } +} + +static void bad_subcmd(Jim_Interp *interp, const jim_subcmd_type * command_table, const char *type, + Jim_Obj *cmd, Jim_Obj *subcmd) +{ + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), Jim_String(cmd), ", ", type, + " command \"", Jim_String(subcmd), "\": should be ", NULL); + add_commands(interp, command_table, ", "); +} + +static void show_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * command_table, int argc, + Jim_Obj *const *argv) +{ + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), "Usage: \"", Jim_String(argv[0]), + " command ... \", where command is one of: ", NULL); + add_commands(interp, command_table, ", "); +} + +static void add_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * ct, Jim_Obj *cmd) +{ + if (cmd) { + Jim_AppendStrings(interp, Jim_GetResult(interp), Jim_String(cmd), " ", NULL); + } + Jim_AppendStrings(interp, Jim_GetResult(interp), ct->cmd, NULL); + if (ct->args && *ct->args) { + Jim_AppendStrings(interp, Jim_GetResult(interp), " ", ct->args, NULL); + } +} + +static void set_wrong_args(Jim_Interp *interp, const jim_subcmd_type * command_table, Jim_Obj *subcmd) +{ + Jim_SetResultString(interp, "wrong # args: should be \"", -1); + add_cmd_usage(interp, command_table, subcmd); + Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL); +} + +const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type * command_table, + int argc, Jim_Obj *const *argv) +{ + const jim_subcmd_type *ct; + const jim_subcmd_type *partial = 0; + int cmdlen; + Jim_Obj *cmd; + const char *cmdstr; + const char *cmdname; + int help = 0; + + cmdname = Jim_String(argv[0]); + + if (argc < 2) { + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), "wrong # args: should be \"", cmdname, + " command ...\"\n", NULL); + Jim_AppendStrings(interp, Jim_GetResult(interp), "Use \"", cmdname, " -help ?command?\" for help", NULL); + return 0; + } + + cmd = argv[1]; + + + if (Jim_CompareStringImmediate(interp, cmd, "-help")) { + if (argc == 2) { + + show_cmd_usage(interp, command_table, argc, argv); + return &dummy_subcmd; + } + help = 1; + + + cmd = argv[2]; + } + + + if (Jim_CompareStringImmediate(interp, cmd, "-commands")) { + + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + add_commands(interp, command_table, " "); + return &dummy_subcmd; + } + + cmdstr = Jim_GetString(cmd, &cmdlen); + + for (ct = command_table; ct->cmd; ct++) { + if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) { + + break; + } + if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) { + if (partial) { + + if (help) { + + show_cmd_usage(interp, command_table, argc, argv); + return &dummy_subcmd; + } + bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]); + return 0; + } + partial = ct; + } + continue; + } + + + if (partial && !ct->cmd) { + ct = partial; + } + + if (!ct->cmd) { + + if (help) { + + show_cmd_usage(interp, command_table, argc, argv); + return &dummy_subcmd; + } + bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]); + return 0; + } + + if (help) { + Jim_SetResultString(interp, "Usage: ", -1); + + add_cmd_usage(interp, ct, argv[0]); + return &dummy_subcmd; + } + + + if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) { + Jim_SetResultString(interp, "wrong # args: should be \"", -1); + + add_cmd_usage(interp, ct, argv[0]); + Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL); + + return 0; + } + + + return ct; +} + +int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type * ct, int argc, Jim_Obj *const *argv) +{ + int ret = JIM_ERR; + + if (ct) { + if (ct->flags & JIM_MODFLAG_FULLARGV) { + ret = ct->function(interp, argc, argv); + } + else { + ret = ct->function(interp, argc - 2, argv + 2); + } + if (ret < 0) { + set_wrong_args(interp, ct, argv[0]); + ret = JIM_ERR; + } + } + return ret; +} + +int Jim_SubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const jim_subcmd_type *ct = + Jim_ParseSubCmd(interp, (const jim_subcmd_type *)Jim_CmdPrivData(interp), argc, argv); + + return Jim_CallSubCmd(interp, ct, argc, argv); +} + +#include +#include +#include +#include +#include + + +int utf8_fromunicode(char *p, unsigned uc) +{ + if (uc <= 0x7f) { + *p = uc; + return 1; + } + else if (uc <= 0x7ff) { + *p++ = 0xc0 | ((uc & 0x7c0) >> 6); + *p = 0x80 | (uc & 0x3f); + return 2; + } + else if (uc <= 0xffff) { + *p++ = 0xe0 | ((uc & 0xf000) >> 12); + *p++ = 0x80 | ((uc & 0xfc0) >> 6); + *p = 0x80 | (uc & 0x3f); + return 3; + } + + else { + *p++ = 0xf0 | ((uc & 0x1c0000) >> 18); + *p++ = 0x80 | ((uc & 0x3f000) >> 12); + *p++ = 0x80 | ((uc & 0xfc0) >> 6); + *p = 0x80 | (uc & 0x3f); + return 4; + } +} + +#include +#include + + +#define JIM_UTF_MAX 3 +#define JIM_INTEGER_SPACE 24 +#define MAX_FLOAT_WIDTH 320 + +Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_Obj *const *objv) +{ + const char *span, *format, *formatEnd, *msg; + int numBytes = 0, objIndex = 0, gotXpg = 0, gotSequential = 0; + static const char * const mixedXPG = + "cannot mix \"%\" and \"%n$\" conversion specifiers"; + static const char * const badIndex[2] = { + "not enough arguments for all format specifiers", + "\"%n$\" argument index out of range" + }; + int formatLen; + Jim_Obj *resultPtr; + + char *num_buffer = NULL; + int num_buffer_size = 0; + + span = format = Jim_GetString(fmtObjPtr, &formatLen); + formatEnd = format + formatLen; + resultPtr = Jim_NewStringObj(interp, "", 0); + + while (format != formatEnd) { + char *end; + int gotMinus, sawFlag; + int gotPrecision, useShort; + long width, precision; + int newXpg; + int ch; + int step; + int doubleType; + char pad = ' '; + char spec[2*JIM_INTEGER_SPACE + 12]; + char *p; + + int formatted_chars; + int formatted_bytes; + const char *formatted_buf; + + step = utf8_tounicode(format, &ch); + format += step; + if (ch != '%') { + numBytes += step; + continue; + } + if (numBytes) { + Jim_AppendString(interp, resultPtr, span, numBytes); + numBytes = 0; + } + + + step = utf8_tounicode(format, &ch); + if (ch == '%') { + span = format; + numBytes = step; + format += step; + continue; + } + + + newXpg = 0; + if (isdigit(ch)) { + int position = strtoul(format, &end, 10); + if (*end == '$') { + newXpg = 1; + objIndex = position - 1; + format = end + 1; + step = utf8_tounicode(format, &ch); + } + } + if (newXpg) { + if (gotSequential) { + msg = mixedXPG; + goto errorMsg; + } + gotXpg = 1; + } else { + if (gotXpg) { + msg = mixedXPG; + goto errorMsg; + } + gotSequential = 1; + } + if ((objIndex < 0) || (objIndex >= objc)) { + msg = badIndex[gotXpg]; + goto errorMsg; + } + + p = spec; + *p++ = '%'; + + gotMinus = 0; + sawFlag = 1; + do { + switch (ch) { + case '-': + gotMinus = 1; + break; + case '0': + pad = ch; + break; + case ' ': + case '+': + case '#': + break; + default: + sawFlag = 0; + continue; + } + *p++ = ch; + format += step; + step = utf8_tounicode(format, &ch); + } while (sawFlag); + + + width = 0; + if (isdigit(ch)) { + width = strtoul(format, &end, 10); + format = end; + step = utf8_tounicode(format, &ch); + } else if (ch == '*') { + if (objIndex >= objc - 1) { + msg = badIndex[gotXpg]; + goto errorMsg; + } + if (Jim_GetLong(interp, objv[objIndex], &width) != JIM_OK) { + goto error; + } + if (width < 0) { + width = -width; + if (!gotMinus) { + *p++ = '-'; + gotMinus = 1; + } + } + objIndex++; + format += step; + step = utf8_tounicode(format, &ch); + } + + + gotPrecision = precision = 0; + if (ch == '.') { + gotPrecision = 1; + format += step; + step = utf8_tounicode(format, &ch); + } + if (isdigit(ch)) { + precision = strtoul(format, &end, 10); + format = end; + step = utf8_tounicode(format, &ch); + } else if (ch == '*') { + if (objIndex >= objc - 1) { + msg = badIndex[gotXpg]; + goto errorMsg; + } + if (Jim_GetLong(interp, objv[objIndex], &precision) != JIM_OK) { + goto error; + } + + + if (precision < 0) { + precision = 0; + } + objIndex++; + format += step; + step = utf8_tounicode(format, &ch); + } + + + useShort = 0; + if (ch == 'h') { + useShort = 1; + format += step; + step = utf8_tounicode(format, &ch); + } else if (ch == 'l') { + + format += step; + step = utf8_tounicode(format, &ch); + if (ch == 'l') { + format += step; + step = utf8_tounicode(format, &ch); + } + } + + format += step; + span = format; + + + if (ch == 'i') { + ch = 'd'; + } + + doubleType = 0; + + switch (ch) { + case '\0': + msg = "format string ended in middle of field specifier"; + goto errorMsg; + case 's': { + formatted_buf = Jim_GetString(objv[objIndex], &formatted_bytes); + formatted_chars = Jim_Utf8Length(interp, objv[objIndex]); + if (gotPrecision && (precision < formatted_chars)) { + + formatted_chars = precision; + formatted_bytes = utf8_index(formatted_buf, precision); + } + break; + } + case 'c': { + jim_wide code; + + if (Jim_GetWide(interp, objv[objIndex], &code) != JIM_OK) { + goto error; + } + + formatted_bytes = utf8_fromunicode(spec, code); + formatted_buf = spec; + formatted_chars = 1; + break; + } + + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + doubleType = 1; + + case 'd': + case 'u': + case 'o': + case 'x': + case 'X': { + jim_wide w; + double d; + int length; + + + if (width) { + p += sprintf(p, "%ld", width); + } + if (gotPrecision) { + p += sprintf(p, ".%ld", precision); + } + + + if (doubleType) { + if (Jim_GetDouble(interp, objv[objIndex], &d) != JIM_OK) { + goto error; + } + length = MAX_FLOAT_WIDTH; + } + else { + if (Jim_GetWide(interp, objv[objIndex], &w) != JIM_OK) { + goto error; + } + length = JIM_INTEGER_SPACE; + if (useShort) { + *p++ = 'h'; + if (ch == 'd') { + w = (short)w; + } + else { + w = (unsigned short)w; + } + } + else { + *p++ = 'l'; +#ifdef HAVE_LONG_LONG + if (sizeof(long long) == sizeof(jim_wide)) { + *p++ = 'l'; + } +#endif + } + } + + *p++ = (char) ch; + *p = '\0'; + + + if (width > length) { + length = width; + } + if (gotPrecision) { + length += precision; + } + + + if (num_buffer_size < length + 1) { + num_buffer_size = length + 1; + num_buffer = Jim_Realloc(num_buffer, num_buffer_size); + } + + if (doubleType) { + snprintf(num_buffer, length + 1, spec, d); + } + else { + formatted_bytes = snprintf(num_buffer, length + 1, spec, w); + } + formatted_chars = formatted_bytes = strlen(num_buffer); + formatted_buf = num_buffer; + break; + } + + default: { + + spec[0] = ch; + spec[1] = '\0'; + Jim_SetResultFormatted(interp, "bad field specifier \"%s\"", spec); + goto error; + } + } + + if (!gotMinus) { + while (formatted_chars < width) { + Jim_AppendString(interp, resultPtr, &pad, 1); + formatted_chars++; + } + } + + Jim_AppendString(interp, resultPtr, formatted_buf, formatted_bytes); + + while (formatted_chars < width) { + Jim_AppendString(interp, resultPtr, &pad, 1); + formatted_chars++; + } + + objIndex += gotSequential; + } + if (numBytes) { + Jim_AppendString(interp, resultPtr, span, numBytes); + } + + Jim_Free(num_buffer); + return resultPtr; + + errorMsg: + Jim_SetResultString(interp, msg, -1); + error: + Jim_FreeNewObj(interp, resultPtr); + Jim_Free(num_buffer); + return NULL; +} +#include +#include +#include +#include + + +#if !defined(HAVE_REGCOMP) || defined(JIM_REGEXP) + + + +#define REG_MAX_PAREN 100 + + +#define END 0 +#define BOL 1 +#define EOL 2 +#define ANY 3 +#define ANYOF 4 +#define ANYBUT 5 +#define BRANCH 6 +#define BACK 7 +#define EXACTLY 8 +#define NOTHING 9 +#define REP 10 +#define REPMIN 11 +#define REPX 12 +#define REPXMIN 13 + +#define WORDA 15 +#define WORDZ 16 +#define OPENNC 19 +#define OPEN 20 + +#define CLOSE (OPEN+REG_MAX_PAREN+1) +#define CLOSE_END (CLOSE+REG_MAX_PAREN) +#define CLOSENC (CLOSE-1) + +#define REG_MAGIC 0xFADED00D + + +#define OP(preg, p) (preg->program[p]) +#define NEXT(preg, p) (preg->program[p + 1]) +#define OPERAND(p) ((p) + 2) + + + + +#define FAIL(R,M) { (R)->err = (M); return (M); } +#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?' || (c) == '{') +#define META "^$.[()|?{+*" + +#define HASWIDTH 01 +#define SIMPLE 02 +#define SPSTART 04 +#define WORST 0 + +#define MAX_REP_COUNT 1000000 + +static int reg(regex_t *preg, int paren , int *flagp ); +static int regpiece(regex_t *preg, int *flagp ); +static int regbranch(regex_t *preg, int *flagp ); +static int regatom(regex_t *preg, int *flagp ); +static int regnode(regex_t *preg, int op ); +static int regnext(regex_t *preg, int p ); +static void regc(regex_t *preg, int b ); +static int reginsert(regex_t *preg, int op, int size, int opnd ); +static void regtail_(regex_t *preg, int p, int val, int line ); +static void regoptail(regex_t *preg, int p, int val ); +#define regtail(PREG, P, VAL) regtail_(PREG, P, VAL, __LINE__) + +static int reg_range_find(const int *string, int c); +static const char *str_find(const char *string, int c, int nocase); +static int prefix_cmp(const int *prog, int proglen, const char *string, int nocase); + + +#ifdef DEBUG +static int regnarrate = 0; +static void regdump(regex_t *preg); +static const char *regprop( int op ); +#endif + + +static int str_int_len(const int *seq) +{ + int n = 0; + while (*seq++) { + n++; + } + return n; +} + +int regcomp(regex_t *preg, const char *exp, int cflags) +{ + int scan; + int longest; + unsigned len; + int flags; + +#ifdef DEBUG + fprintf(stderr, "Compiling: '%s'\n", exp); +#endif + memset(preg, 0, sizeof(*preg)); + + if (exp == NULL) + FAIL(preg, REG_ERR_NULL_ARGUMENT); + + + preg->cflags = cflags; + preg->regparse = exp; + + preg->program = NULL; + preg->proglen = 0; + + + preg->proglen = (strlen(exp) + 1) * 5; + preg->program = malloc(preg->proglen * sizeof(int)); + if (preg->program == NULL) + FAIL(preg, REG_ERR_NOMEM); + + regc(preg, REG_MAGIC); + if (reg(preg, 0, &flags) == 0) { + return preg->err; + } + + + if (preg->re_nsub >= REG_MAX_PAREN) + FAIL(preg,REG_ERR_TOO_BIG); + + + preg->regstart = 0; + preg->reganch = 0; + preg->regmust = 0; + preg->regmlen = 0; + scan = 1; + if (OP(preg, regnext(preg, scan)) == END) { + scan = OPERAND(scan); + + + if (OP(preg, scan) == EXACTLY) { + preg->regstart = preg->program[OPERAND(scan)]; + } + else if (OP(preg, scan) == BOL) + preg->reganch++; + + if (flags&SPSTART) { + longest = 0; + len = 0; + for (; scan != 0; scan = regnext(preg, scan)) { + if (OP(preg, scan) == EXACTLY) { + int plen = str_int_len(preg->program + OPERAND(scan)); + if (plen >= len) { + longest = OPERAND(scan); + len = plen; + } + } + } + preg->regmust = longest; + preg->regmlen = len; + } + } + +#ifdef DEBUG + regdump(preg); +#endif + + return 0; +} + +static int reg(regex_t *preg, int paren , int *flagp ) +{ + int ret; + int br; + int ender; + int parno = 0; + int flags; + + *flagp = HASWIDTH; + + + if (paren) { + if (preg->regparse[0] == '?' && preg->regparse[1] == ':') { + + preg->regparse += 2; + parno = -1; + } + else { + parno = ++preg->re_nsub; + } + ret = regnode(preg, OPEN+parno); + } else + ret = 0; + + + br = regbranch(preg, &flags); + if (br == 0) + return 0; + if (ret != 0) + regtail(preg, ret, br); + else + ret = br; + if (!(flags&HASWIDTH)) + *flagp &= ~HASWIDTH; + *flagp |= flags&SPSTART; + while (*preg->regparse == '|') { + preg->regparse++; + br = regbranch(preg, &flags); + if (br == 0) + return 0; + regtail(preg, ret, br); + if (!(flags&HASWIDTH)) + *flagp &= ~HASWIDTH; + *flagp |= flags&SPSTART; + } + + + ender = regnode(preg, (paren) ? CLOSE+parno : END); + regtail(preg, ret, ender); + + + for (br = ret; br != 0; br = regnext(preg, br)) + regoptail(preg, br, ender); + + + if (paren && *preg->regparse++ != ')') { + preg->err = REG_ERR_UNMATCHED_PAREN; + return 0; + } else if (!paren && *preg->regparse != '\0') { + if (*preg->regparse == ')') { + preg->err = REG_ERR_UNMATCHED_PAREN; + return 0; + } else { + preg->err = REG_ERR_JUNK_ON_END; + return 0; + } + } + + return(ret); +} + +static int regbranch(regex_t *preg, int *flagp ) +{ + int ret; + int chain; + int latest; + int flags; + + *flagp = WORST; + + ret = regnode(preg, BRANCH); + chain = 0; + while (*preg->regparse != '\0' && *preg->regparse != ')' && + *preg->regparse != '|') { + latest = regpiece(preg, &flags); + if (latest == 0) + return 0; + *flagp |= flags&HASWIDTH; + if (chain == 0) { + *flagp |= flags&SPSTART; + } + else { + regtail(preg, chain, latest); + } + chain = latest; + } + if (chain == 0) + (void) regnode(preg, NOTHING); + + return(ret); +} + +static int regpiece(regex_t *preg, int *flagp) +{ + int ret; + char op; + int next; + int flags; + int chain = 0; + int min; + int max; + + ret = regatom(preg, &flags); + if (ret == 0) + return 0; + + op = *preg->regparse; + if (!ISMULT(op)) { + *flagp = flags; + return(ret); + } + + if (!(flags&HASWIDTH) && op != '?') { + preg->err = REG_ERR_OPERAND_COULD_BE_EMPTY; + return 0; + } + + + if (op == '{') { + char *end; + + min = strtoul(preg->regparse + 1, &end, 10); + if (end == preg->regparse + 1) { + preg->err = REG_ERR_BAD_COUNT; + return 0; + } + if (*end == '}') { + max = min; + } + else { + preg->regparse = end; + max = strtoul(preg->regparse + 1, &end, 10); + if (*end != '}') { + preg->err = REG_ERR_UNMATCHED_BRACES; + return 0; + } + } + if (end == preg->regparse + 1) { + max = MAX_REP_COUNT; + } + else if (max < min || max >= 100) { + preg->err = REG_ERR_BAD_COUNT; + return 0; + } + if (min >= 100) { + preg->err = REG_ERR_BAD_COUNT; + return 0; + } + + preg->regparse = strchr(preg->regparse, '}'); + } + else { + min = (op == '+'); + max = (op == '?' ? 1 : MAX_REP_COUNT); + } + + if (preg->regparse[1] == '?') { + preg->regparse++; + next = reginsert(preg, flags & SIMPLE ? REPMIN : REPXMIN, 5, ret); + } + else { + next = reginsert(preg, flags & SIMPLE ? REP: REPX, 5, ret); + } + preg->program[ret + 2] = max; + preg->program[ret + 3] = min; + preg->program[ret + 4] = 0; + + *flagp = (min) ? (WORST|HASWIDTH) : (WORST|SPSTART); + + if (!(flags & SIMPLE)) { + int back = regnode(preg, BACK); + regtail(preg, back, ret); + regtail(preg, next, back); + } + + preg->regparse++; + if (ISMULT(*preg->regparse)) { + preg->err = REG_ERR_NESTED_COUNT; + return 0; + } + + return chain ? chain : ret; +} + +static void reg_addrange(regex_t *preg, int lower, int upper) +{ + if (lower > upper) { + reg_addrange(preg, upper, lower); + } + + regc(preg, upper - lower + 1); + regc(preg, lower); +} + +static void reg_addrange_str(regex_t *preg, const char *str) +{ + while (*str) { + reg_addrange(preg, *str, *str); + str++; + } +} + +static int reg_utf8_tounicode_case(const char *s, int *uc, int upper) +{ + int l = utf8_tounicode(s, uc); + if (upper) { + *uc = utf8_upper(*uc); + } + return l; +} + +static int hexdigitval(int c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int parse_hex(const char *s, int n, int *uc) +{ + int val = 0; + int k; + + for (k = 0; k < n; k++) { + int c = hexdigitval(*s++); + if (c == -1) { + break; + } + val = (val << 4) | c; + } + if (k) { + *uc = val; + } + return k; +} + +static int reg_decode_escape(const char *s, int *ch) +{ + int n; + const char *s0 = s; + + *ch = *s++; + + switch (*ch) { + case 'b': *ch = '\b'; break; + case 'e': *ch = 27; break; + case 'f': *ch = '\f'; break; + case 'n': *ch = '\n'; break; + case 'r': *ch = '\r'; break; + case 't': *ch = '\t'; break; + case 'v': *ch = '\v'; break; + case 'u': + if (*s == '{') { + + n = parse_hex(s + 1, 6, ch); + if (n > 0 && s[n + 1] == '}' && *ch >= 0 && *ch <= 0x1fffff) { + s += n + 2; + } + else { + + *ch = 'u'; + } + } + else if ((n = parse_hex(s, 4, ch)) > 0) { + s += n; + } + break; + case 'U': + if ((n = parse_hex(s, 8, ch)) > 0) { + s += n; + } + case 'x': + if ((n = parse_hex(s, 2, ch)) > 0) { + s += n; + } + break; + case '\0': + s--; + *ch = '\\'; + break; + } + return s - s0; +} + +static int regatom(regex_t *preg, int *flagp) +{ + int ret; + int flags; + int nocase = (preg->cflags & REG_ICASE); + + int ch; + int n = reg_utf8_tounicode_case(preg->regparse, &ch, nocase); + + *flagp = WORST; + + preg->regparse += n; + switch (ch) { + + case '^': + ret = regnode(preg, BOL); + break; + case '$': + ret = regnode(preg, EOL); + break; + case '.': + ret = regnode(preg, ANY); + *flagp |= HASWIDTH|SIMPLE; + break; + case '[': { + const char *pattern = preg->regparse; + + if (*pattern == '^') { + ret = regnode(preg, ANYBUT); + pattern++; + } else + ret = regnode(preg, ANYOF); + + + if (*pattern == ']' || *pattern == '-') { + reg_addrange(preg, *pattern, *pattern); + pattern++; + } + + while (*pattern && *pattern != ']') { + + int start; + int end; + + pattern += reg_utf8_tounicode_case(pattern, &start, nocase); + if (start == '\\') { + pattern += reg_decode_escape(pattern, &start); + if (start == 0) { + preg->err = REG_ERR_NULL_CHAR; + return 0; + } + } + if (pattern[0] == '-' && pattern[1] && pattern[1] != ']') { + + pattern += utf8_tounicode(pattern, &end); + pattern += reg_utf8_tounicode_case(pattern, &end, nocase); + if (end == '\\') { + pattern += reg_decode_escape(pattern, &end); + if (end == 0) { + preg->err = REG_ERR_NULL_CHAR; + return 0; + } + } + + reg_addrange(preg, start, end); + continue; + } + if (start == '[') { + if (strncmp(pattern, ":alpha:]", 8) == 0) { + if ((preg->cflags & REG_ICASE) == 0) { + reg_addrange(preg, 'a', 'z'); + } + reg_addrange(preg, 'A', 'Z'); + pattern += 8; + continue; + } + if (strncmp(pattern, ":alnum:]", 8) == 0) { + if ((preg->cflags & REG_ICASE) == 0) { + reg_addrange(preg, 'a', 'z'); + } + reg_addrange(preg, 'A', 'Z'); + reg_addrange(preg, '0', '9'); + pattern += 8; + continue; + } + if (strncmp(pattern, ":space:]", 8) == 0) { + reg_addrange_str(preg, " \t\r\n\f\v"); + pattern += 8; + continue; + } + } + + reg_addrange(preg, start, start); + } + regc(preg, '\0'); + + if (*pattern) { + pattern++; + } + preg->regparse = pattern; + + *flagp |= HASWIDTH|SIMPLE; + } + break; + case '(': + ret = reg(preg, 1, &flags); + if (ret == 0) + return 0; + *flagp |= flags&(HASWIDTH|SPSTART); + break; + case '\0': + case '|': + case ')': + preg->err = REG_ERR_INTERNAL; + return 0; + case '?': + case '+': + case '*': + case '{': + preg->err = REG_ERR_COUNT_FOLLOWS_NOTHING; + return 0; + case '\\': + switch (*preg->regparse++) { + case '\0': + preg->err = REG_ERR_TRAILING_BACKSLASH; + return 0; + case '<': + case 'm': + ret = regnode(preg, WORDA); + break; + case '>': + case 'M': + ret = regnode(preg, WORDZ); + break; + case 'd': + ret = regnode(preg, ANYOF); + reg_addrange(preg, '0', '9'); + regc(preg, '\0'); + *flagp |= HASWIDTH|SIMPLE; + break; + case 'w': + ret = regnode(preg, ANYOF); + if ((preg->cflags & REG_ICASE) == 0) { + reg_addrange(preg, 'a', 'z'); + } + reg_addrange(preg, 'A', 'Z'); + reg_addrange(preg, '0', '9'); + reg_addrange(preg, '_', '_'); + regc(preg, '\0'); + *flagp |= HASWIDTH|SIMPLE; + break; + case 's': + ret = regnode(preg, ANYOF); + reg_addrange_str(preg," \t\r\n\f\v"); + regc(preg, '\0'); + *flagp |= HASWIDTH|SIMPLE; + break; + + default: + + + preg->regparse--; + goto de_fault; + } + break; + de_fault: + default: { + int added = 0; + + + preg->regparse -= n; + + ret = regnode(preg, EXACTLY); + + + + while (*preg->regparse && strchr(META, *preg->regparse) == NULL) { + n = reg_utf8_tounicode_case(preg->regparse, &ch, (preg->cflags & REG_ICASE)); + if (ch == '\\' && preg->regparse[n]) { + if (strchr("<>mMwds", preg->regparse[n])) { + + break; + } + n += reg_decode_escape(preg->regparse + n, &ch); + if (ch == 0) { + preg->err = REG_ERR_NULL_CHAR; + return 0; + } + } + + + if (ISMULT(preg->regparse[n])) { + + if (added) { + + break; + } + + regc(preg, ch); + added++; + preg->regparse += n; + break; + } + + + regc(preg, ch); + added++; + preg->regparse += n; + } + regc(preg, '\0'); + + *flagp |= HASWIDTH; + if (added == 1) + *flagp |= SIMPLE; + break; + } + break; + } + + return(ret); +} + +static void reg_grow(regex_t *preg, int n) +{ + if (preg->p + n >= preg->proglen) { + preg->proglen = (preg->p + n) * 2; + preg->program = realloc(preg->program, preg->proglen * sizeof(int)); + } +} + + +static int regnode(regex_t *preg, int op) +{ + reg_grow(preg, 2); + + preg->program[preg->p++] = op; + preg->program[preg->p++] = 0; + + + return preg->p - 2; +} + +static void regc(regex_t *preg, int b ) +{ + reg_grow(preg, 1); + preg->program[preg->p++] = b; +} + +static int reginsert(regex_t *preg, int op, int size, int opnd ) +{ + reg_grow(preg, size); + + + memmove(preg->program + opnd + size, preg->program + opnd, sizeof(int) * (preg->p - opnd)); + + memset(preg->program + opnd, 0, sizeof(int) * size); + + preg->program[opnd] = op; + + preg->p += size; + + return opnd + size; +} + +static void regtail_(regex_t *preg, int p, int val, int line ) +{ + int scan; + int temp; + int offset; + + + scan = p; + for (;;) { + temp = regnext(preg, scan); + if (temp == 0) + break; + scan = temp; + } + + if (OP(preg, scan) == BACK) + offset = scan - val; + else + offset = val - scan; + + preg->program[scan + 1] = offset; +} + + +static void regoptail(regex_t *preg, int p, int val ) +{ + + if (p != 0 && OP(preg, p) == BRANCH) { + regtail(preg, OPERAND(p), val); + } +} + + +static int regtry(regex_t *preg, const char *string ); +static int regmatch(regex_t *preg, int prog); +static int regrepeat(regex_t *preg, int p, int max); + +int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) +{ + const char *s; + int scan; + + + if (preg == NULL || preg->program == NULL || string == NULL) { + return REG_ERR_NULL_ARGUMENT; + } + + + if (*preg->program != REG_MAGIC) { + return REG_ERR_CORRUPTED; + } + +#ifdef DEBUG + fprintf(stderr, "regexec: %s\n", string); + regdump(preg); +#endif + + preg->eflags = eflags; + preg->pmatch = pmatch; + preg->nmatch = nmatch; + preg->start = string; + + + for (scan = OPERAND(1); scan != 0; ) { + switch (OP(preg, scan)) { + case REP: + case REPMIN: + case REPX: + case REPXMIN: + preg->program[scan + 4] = 0; + scan += 5; + break; + + case ANYOF: + case ANYBUT: + case EXACTLY: + scan += 2; + while (preg->program[scan++]) { + } + break; + + case END: + scan = 0; + break; + + default: + scan += 2; + break; + } + } + + + if (preg->regmust != 0) { + s = string; + while ((s = str_find(s, preg->program[preg->regmust], preg->cflags & REG_ICASE)) != NULL) { + if (prefix_cmp(preg->program + preg->regmust, preg->regmlen, s, preg->cflags & REG_ICASE) >= 0) { + break; + } + s++; + } + if (s == NULL) + return REG_NOMATCH; + } + + + preg->regbol = string; + + + if (preg->reganch) { + if (eflags & REG_NOTBOL) { + + goto nextline; + } + while (1) { + if (regtry(preg, string)) { + return REG_NOERROR; + } + if (*string) { +nextline: + if (preg->cflags & REG_NEWLINE) { + + string = strchr(string, '\n'); + if (string) { + preg->regbol = ++string; + continue; + } + } + } + return REG_NOMATCH; + } + } + + + s = string; + if (preg->regstart != '\0') { + + while ((s = str_find(s, preg->regstart, preg->cflags & REG_ICASE)) != NULL) { + if (regtry(preg, s)) + return REG_NOERROR; + s++; + } + } + else + + while (1) { + if (regtry(preg, s)) + return REG_NOERROR; + if (*s == '\0') { + break; + } + else { + int c; + s += utf8_tounicode(s, &c); + } + } + + + return REG_NOMATCH; +} + + +static int regtry( regex_t *preg, const char *string ) +{ + int i; + + preg->reginput = string; + + for (i = 0; i < preg->nmatch; i++) { + preg->pmatch[i].rm_so = -1; + preg->pmatch[i].rm_eo = -1; + } + if (regmatch(preg, 1)) { + preg->pmatch[0].rm_so = string - preg->start; + preg->pmatch[0].rm_eo = preg->reginput - preg->start; + return(1); + } else + return(0); +} + +static int prefix_cmp(const int *prog, int proglen, const char *string, int nocase) +{ + const char *s = string; + while (proglen && *s) { + int ch; + int n = reg_utf8_tounicode_case(s, &ch, nocase); + if (ch != *prog) { + return -1; + } + prog++; + s += n; + proglen--; + } + if (proglen == 0) { + return s - string; + } + return -1; +} + +static int reg_range_find(const int *range, int c) +{ + while (*range) { + + if (c >= range[1] && c <= (range[0] + range[1] - 1)) { + return 1; + } + range += 2; + } + return 0; +} + +static const char *str_find(const char *string, int c, int nocase) +{ + if (nocase) { + + c = utf8_upper(c); + } + while (*string) { + int ch; + int n = reg_utf8_tounicode_case(string, &ch, nocase); + if (c == ch) { + return string; + } + string += n; + } + return NULL; +} + +static int reg_iseol(regex_t *preg, int ch) +{ + if (preg->cflags & REG_NEWLINE) { + return ch == '\0' || ch == '\n'; + } + else { + return ch == '\0'; + } +} + +static int regmatchsimplerepeat(regex_t *preg, int scan, int matchmin) +{ + int nextch = '\0'; + const char *save; + int no; + int c; + + int max = preg->program[scan + 2]; + int min = preg->program[scan + 3]; + int next = regnext(preg, scan); + + if (OP(preg, next) == EXACTLY) { + nextch = preg->program[OPERAND(next)]; + } + save = preg->reginput; + no = regrepeat(preg, scan + 5, max); + if (no < min) { + return 0; + } + if (matchmin) { + + max = no; + no = min; + } + + while (1) { + if (matchmin) { + if (no > max) { + break; + } + } + else { + if (no < min) { + break; + } + } + preg->reginput = save + utf8_index(save, no); + reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE)); + + if (reg_iseol(preg, nextch) || c == nextch) { + if (regmatch(preg, next)) { + return(1); + } + } + if (matchmin) { + + no++; + } + else { + + no--; + } + } + return(0); +} + +static int regmatchrepeat(regex_t *preg, int scan, int matchmin) +{ + int *scanpt = preg->program + scan; + + int max = scanpt[2]; + int min = scanpt[3]; + + + if (scanpt[4] < min) { + + scanpt[4]++; + if (regmatch(preg, scan + 5)) { + return 1; + } + scanpt[4]--; + return 0; + } + if (scanpt[4] > max) { + return 0; + } + + if (matchmin) { + + if (regmatch(preg, regnext(preg, scan))) { + return 1; + } + + scanpt[4]++; + if (regmatch(preg, scan + 5)) { + return 1; + } + scanpt[4]--; + return 0; + } + + if (scanpt[4] < max) { + scanpt[4]++; + if (regmatch(preg, scan + 5)) { + return 1; + } + scanpt[4]--; + } + + return regmatch(preg, regnext(preg, scan)); +} + + +static int regmatch(regex_t *preg, int prog) +{ + int scan; + int next; + + scan = prog; + +#ifdef DEBUG + if (scan != 0 && regnarrate) + fprintf(stderr, "%s(\n", regprop(scan)); +#endif + while (scan != 0) { + int n; + int c; +#ifdef DEBUG + if (regnarrate) { + fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan))); + } +#endif + next = regnext(preg, scan); + n = reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE)); + + switch (OP(preg, scan)) { + case BOL: + if (preg->reginput != preg->regbol) + return(0); + break; + case EOL: + if (!reg_iseol(preg, c)) { + return(0); + } + break; + case WORDA: + + if ((!isalnum(UCHAR(c))) && c != '_') + return(0); + + if (preg->reginput > preg->regbol && + (isalnum(UCHAR(preg->reginput[-1])) || preg->reginput[-1] == '_')) + return(0); + break; + case WORDZ: + + if (preg->reginput > preg->regbol) { + + if (reg_iseol(preg, c) || !isalnum(UCHAR(c)) || c != '_') { + c = preg->reginput[-1]; + + if (isalnum(UCHAR(c)) || c == '_') { + break; + } + } + } + + return(0); + + case ANY: + if (reg_iseol(preg, c)) + return 0; + preg->reginput += n; + break; + case EXACTLY: { + int opnd; + int len; + int slen; + + opnd = OPERAND(scan); + len = str_int_len(preg->program + opnd); + + slen = prefix_cmp(preg->program + opnd, len, preg->reginput, preg->cflags & REG_ICASE); + if (slen < 0) { + return(0); + } + preg->reginput += slen; + } + break; + case ANYOF: + if (reg_iseol(preg, c) || reg_range_find(preg->program + OPERAND(scan), c) == 0) { + return(0); + } + preg->reginput += n; + break; + case ANYBUT: + if (reg_iseol(preg, c) || reg_range_find(preg->program + OPERAND(scan), c) != 0) { + return(0); + } + preg->reginput += n; + break; + case NOTHING: + break; + case BACK: + break; + case BRANCH: { + const char *save; + + if (OP(preg, next) != BRANCH) + next = OPERAND(scan); + else { + do { + save = preg->reginput; + if (regmatch(preg, OPERAND(scan))) { + return(1); + } + preg->reginput = save; + scan = regnext(preg, scan); + } while (scan != 0 && OP(preg, scan) == BRANCH); + return(0); + + } + } + break; + case REP: + case REPMIN: + return regmatchsimplerepeat(preg, scan, OP(preg, scan) == REPMIN); + + case REPX: + case REPXMIN: + return regmatchrepeat(preg, scan, OP(preg, scan) == REPXMIN); + + case END: + return(1); + break; + + case OPENNC: + case CLOSENC: + if (regmatch(preg, next)) { + return 1; + } + return 0; + + default: + if (OP(preg, scan) >= OPEN+1 && OP(preg, scan) < CLOSE_END) { + const char *save; + + save = preg->reginput; + + if (regmatch(preg, next)) { + int no; + if (OP(preg, scan) < CLOSE) { + no = OP(preg, scan) - OPEN; + if (no < preg->nmatch && preg->pmatch[no].rm_so == -1) { + preg->pmatch[no].rm_so = save - preg->start; + } + } + else { + no = OP(preg, scan) - CLOSE; + if (no < preg->nmatch && preg->pmatch[no].rm_eo == -1) { + preg->pmatch[no].rm_eo = save - preg->start; + } + } + return(1); + } else + return(0); + } + return REG_ERR_INTERNAL; + } + + scan = next; + } + + return REG_ERR_INTERNAL; +} + +static int regrepeat(regex_t *preg, int p, int max) +{ + int count = 0; + const char *scan; + int opnd; + int ch; + int n; + + scan = preg->reginput; + opnd = OPERAND(p); + switch (OP(preg, p)) { + case ANY: + + while (!reg_iseol(preg, *scan) && count < max) { + count++; + scan++; + } + break; + case EXACTLY: + while (count < max) { + n = reg_utf8_tounicode_case(scan, &ch, preg->cflags & REG_ICASE); + if (preg->program[opnd] != ch) { + break; + } + count++; + scan += n; + } + break; + case ANYOF: + while (count < max) { + n = reg_utf8_tounicode_case(scan, &ch, preg->cflags & REG_ICASE); + if (reg_iseol(preg, ch) || reg_range_find(preg->program + opnd, ch) == 0) { + break; + } + count++; + scan += n; + } + break; + case ANYBUT: + while (count < max) { + n = reg_utf8_tounicode_case(scan, &ch, preg->cflags & REG_ICASE); + if (reg_iseol(preg, ch) || reg_range_find(preg->program + opnd, ch) != 0) { + break; + } + count++; + scan += n; + } + break; + default: + preg->err = REG_ERR_INTERNAL; + count = 0; + break; + } + preg->reginput = scan; + + return(count); +} + +static int regnext(regex_t *preg, int p ) +{ + int offset; + + offset = NEXT(preg, p); + + if (offset == 0) + return 0; + + if (OP(preg, p) == BACK) + return(p-offset); + else + return(p+offset); +} + + +size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) +{ + static const char *error_strings[] = { + "success", + "no match", + "bad pattern", + "null argument", + "unknown error", + "too big", + "out of memory", + "too many ()", + "parentheses () not balanced", + "braces {} not balanced", + "invalid repetition count(s)", + "extra characters", + "*+ of empty atom", + "nested count", + "internal error", + "count follows nothing", + "trailing backslash", + "corrupted program", + "contains null char", + }; + const char *err; + + if (errcode < 0 || errcode >= REG_ERR_NUM) { + err = "Bad error code"; + } + else { + err = error_strings[errcode]; + } + + return snprintf(errbuf, errbuf_size, "%s", err); +} + +void regfree(regex_t *preg) +{ + free(preg->program); +} + +#endif + +#if defined(_WIN32) || defined(WIN32) +#ifndef STRICT +#define STRICT +#endif +#define WIN32_LEAN_AND_MEAN +#include + +#if defined(HAVE_DLOPEN_COMPAT) +void *dlopen(const char *path, int mode) +{ + JIM_NOTUSED(mode); + + return (void *)LoadLibraryA(path); +} + +int dlclose(void *handle) +{ + FreeLibrary((HANDLE)handle); + return 0; +} + +void *dlsym(void *handle, const char *symbol) +{ + return GetProcAddress((HMODULE)handle, symbol); +} + +char *dlerror(void) +{ + static char msg[121]; + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), + LANG_NEUTRAL, msg, sizeof(msg) - 1, NULL); + return msg; +} +#endif + +#ifdef _MSC_VER + +#include + + +int gettimeofday(struct timeval *tv, void *unused) +{ + struct _timeb tb; + + _ftime(&tb); + tv->tv_sec = tb.time; + tv->tv_usec = tb.millitm * 1000; + + return 0; +} + + +DIR *opendir(const char *name) +{ + DIR *dir = 0; + + if (name && name[0]) { + size_t base_length = strlen(name); + const char *all = + strchr("/\\", name[base_length - 1]) ? "*" : "/*"; + + if ((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 && + (dir->name = (char *)Jim_Alloc(base_length + strlen(all) + 1)) != 0) { + strcat(strcpy(dir->name, name), all); + + if ((dir->handle = (long)_findfirst(dir->name, &dir->info)) != -1) + dir->result.d_name = 0; + else { + Jim_Free(dir->name); + Jim_Free(dir); + dir = 0; + } + } + else { + Jim_Free(dir); + dir = 0; + errno = ENOMEM; + } + } + else { + errno = EINVAL; + } + return dir; +} + +int closedir(DIR * dir) +{ + int result = -1; + + if (dir) { + if (dir->handle != -1) + result = _findclose(dir->handle); + Jim_Free(dir->name); + Jim_Free(dir); + } + if (result == -1) + errno = EBADF; + return result; +} + +struct dirent *readdir(DIR * dir) +{ + struct dirent *result = 0; + + if (dir && dir->handle != -1) { + if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) { + result = &dir->result; + result->d_name = dir->info.name; + } + } + else { + errno = EBADF; + } + return result; +} +#endif +#endif +#ifndef JIM_BOOTSTRAP_LIB_ONLY +#include +#include + + +#ifdef USE_LINENOISE +#include +#include "linenoise.h" +#else +#define MAX_LINE_LEN 512 +#endif + +char *Jim_HistoryGetline(const char *prompt) +{ +#ifdef USE_LINENOISE + return linenoise(prompt); +#else + char *line = malloc(MAX_LINE_LEN); + + fputs(prompt, stdout); + fflush(stdout); + + if (fgets(line, MAX_LINE_LEN, stdin) == NULL) { + free(line); + return NULL; + } + return line; +#endif +} + +void Jim_HistoryLoad(const char *filename) +{ +#ifdef USE_LINENOISE + linenoiseHistoryLoad(filename); +#endif +} + +void Jim_HistoryAdd(const char *line) +{ +#ifdef USE_LINENOISE + linenoiseHistoryAdd(line); +#endif +} + +void Jim_HistorySave(const char *filename) +{ +#ifdef USE_LINENOISE + linenoiseHistorySave(filename); +#endif +} + +void Jim_HistoryShow(void) +{ +#ifdef USE_LINENOISE + + int i; + int len; + char **history = linenoiseHistory(&len); + for (i = 0; i < len; i++) { + printf("%4d %s\n", i + 1, history[i]); + } +#endif +} + +int Jim_InteractivePrompt(Jim_Interp *interp) +{ + int retcode = JIM_OK; + char *history_file = NULL; +#ifdef USE_LINENOISE + const char *home; + + home = getenv("HOME"); + if (home && isatty(STDIN_FILENO)) { + int history_len = strlen(home) + sizeof("/.jim_history"); + history_file = Jim_Alloc(history_len); + snprintf(history_file, history_len, "%s/.jim_history", home); + Jim_HistoryLoad(history_file); + } +#endif + + printf("Welcome to Jim version %d.%d" JIM_NL, + JIM_VERSION / 100, JIM_VERSION % 100); + Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, "1"); + + while (1) { + Jim_Obj *scriptObjPtr; + const char *result; + int reslen; + char prompt[20]; + const char *str; + + if (retcode != 0) { + const char *retcodestr = Jim_ReturnCode(retcode); + + if (*retcodestr == '?') { + snprintf(prompt, sizeof(prompt) - 3, "[%d] ", retcode); + } + else { + snprintf(prompt, sizeof(prompt) - 3, "[%s] ", retcodestr); + } + } + else { + prompt[0] = '\0'; + } + strcat(prompt, ". "); + + scriptObjPtr = Jim_NewStringObj(interp, "", 0); + Jim_IncrRefCount(scriptObjPtr); + while (1) { + char state; + int len; + char *line; + + line = Jim_HistoryGetline(prompt); + if (line == NULL) { + if (errno == EINTR) { + continue; + } + Jim_DecrRefCount(interp, scriptObjPtr); + retcode = JIM_OK; + goto out; + } + if (Jim_Length(scriptObjPtr) != 0) { + Jim_AppendString(interp, scriptObjPtr, "\n", 1); + } + Jim_AppendString(interp, scriptObjPtr, line, -1); + free(line); + str = Jim_GetString(scriptObjPtr, &len); + if (len == 0) { + continue; + } + if (Jim_ScriptIsComplete(str, len, &state)) + break; + + snprintf(prompt, sizeof(prompt), "%c> ", state); + } +#ifdef USE_LINENOISE + if (strcmp(str, "h") == 0) { + + Jim_HistoryShow(); + Jim_DecrRefCount(interp, scriptObjPtr); + continue; + } + + Jim_HistoryAdd(Jim_String(scriptObjPtr)); + if (history_file) { + Jim_HistorySave(history_file); + } +#endif + retcode = Jim_EvalObj(interp, scriptObjPtr); + Jim_DecrRefCount(interp, scriptObjPtr); + + if (retcode == JIM_EXIT) { + retcode = JIM_EXIT; + break; + } + if (retcode == JIM_ERR) { + Jim_MakeErrorMessage(interp); + } + result = Jim_GetString(Jim_GetResult(interp), &reslen); + if (reslen) { + printf("%s\n", result); + } + } + out: + Jim_Free(history_file); + return retcode; +} + +#include +#include +#include + + + +extern int Jim_initjimshInit(Jim_Interp *interp); + +static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[]) +{ + int n; + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + + + for (n = 0; n < argc; n++) { + Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1); + + Jim_ListAppendElement(interp, listObj, obj); + } + + Jim_SetVariableStr(interp, "argv", listObj); + Jim_SetVariableStr(interp, "argc", Jim_NewIntObj(interp, argc)); +} + +int main(int argc, char *const argv[]) +{ + int retcode; + Jim_Interp *interp; + + if (argc > 1 && strcmp(argv[1], "--version") == 0) { + printf("%d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100); + return 0; + } + + + interp = Jim_CreateInterp(); + Jim_RegisterCoreCommands(interp); + + + if (Jim_InitStaticExtensions(interp) != JIM_OK) { + Jim_MakeErrorMessage(interp); + fprintf(stderr, "%s\n", Jim_String(Jim_GetResult(interp))); + } + + Jim_SetVariableStrWithStr(interp, "jim_argv0", argv[0]); + Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0"); + retcode = Jim_initjimshInit(interp); + + if (argc == 1) { + if (retcode == JIM_ERR) { + Jim_MakeErrorMessage(interp); + fprintf(stderr, "%s\n", Jim_String(Jim_GetResult(interp))); + } + if (retcode != JIM_EXIT) { + JimSetArgv(interp, 0, NULL); + retcode = Jim_InteractivePrompt(interp); + } + } + else { + if (argc > 2 && strcmp(argv[1], "-e") == 0) { + JimSetArgv(interp, argc - 3, argv + 3); + retcode = Jim_Eval(interp, argv[2]); + if (retcode != JIM_ERR) { + printf("%s\n", Jim_String(Jim_GetResult(interp))); + } + } + else { + Jim_SetVariableStr(interp, "argv0", Jim_NewStringObj(interp, argv[1], -1)); + JimSetArgv(interp, argc - 2, argv + 2); + retcode = Jim_EvalFile(interp, argv[1]); + } + if (retcode == JIM_ERR) { + Jim_MakeErrorMessage(interp); + fprintf(stderr, "%s\n", Jim_String(Jim_GetResult(interp))); + } + } + if (retcode == JIM_EXIT) { + retcode = Jim_GetExitCode(interp); + } + else if (retcode == JIM_ERR) { + retcode = 1; + } + else { + retcode = 0; + } + Jim_FreeInterp(interp); + return retcode; +} +#endif diff --git a/debuggers/openocd/jimtcl/autosetup/local.tcl b/debuggers/openocd/jimtcl/autosetup/local.tcl new file mode 100644 index 00000000..36aff868 --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/local.tcl @@ -0,0 +1,194 @@ +# The complex extension checking is done here. + +global withinfo +global extdb + +# Final determination of module status +dict set extdb status {} + +# Returns 1 if the extension has the attribute +proc ext-has {ext attr} { + expr {$attr in [dict get $::extdb attrs $ext]} +} + +# Returns an entry from the extension 'info' table, or $default otherwise +proc ext-get {ext key {default {}}} { + if {[dict exists $::extdb info $ext $key]} { + return [dict get $::extdb info $ext $key] + } else { + return $default + } +} + +# Set the status of the extension to the given value, and returns the value +proc ext-set-status {ext value} { + dict set ::extdb status $ext $value + return $value +} + +# Returns the status of the extension, or ? if unknown +proc ext-get-status {ext} { + if {[dict exists $::extdb status $ext]} { + return [dict get $::extdb status $ext] + } + return ? +} + +proc check-extension-status {ext required} { + global withinfo + + set status [ext-get-status $ext] + + if {$ext in $withinfo(without)} { + # Disabled without further ado + msg-result "Extension $ext...disabled" + return [ext-set-status $ext n] + } + + if {$status in {m y n}} { + return $status + } + + # required is "required" if this extension *must* be enabled + # required is "wanted" if it is not fatal for this extension + # not to be enabled + + array set depinfo {m 0 y 0 n 0} + + # Check direct dependencies + if [ext-get $ext check 1] { + # "check" conditions are met + } else { + # not met + incr depinfo(n) + } + + if {$depinfo(n) == 0} { + # Now extension dependencies + foreach i [ext-get $ext dep] { + set status [check-extension-status $i $required] + #puts "$ext: dep $i $required => $status" + incr depinfo($status) + if {$depinfo(n)} { + break + } + } + } + + #parray depinfo + + if {$depinfo(n)} { + msg-checking "Extension $ext..." + if {$required eq "required"} { + user-error "dependencies not met" + } + msg-result "disabled (dependencies)" + return [ext-set-status $ext n] + } + + # Selected as a module? + if {$ext in $withinfo(mod)} { + if {[ext-has $ext tcl]} { + # Easy, a Tcl module + msg-result "Extension $ext...tcl" + } elseif {[ext-has $ext static]} { + user-error "Extension $ext can't be a module" + } else { + msg-result "Extension $ext...module" + foreach i [ext-get $ext libdep] { + define-append LDLIBS_$ext [get-define $i ""] + } + } + return [ext-set-status $ext m] + } + + # Selected as a static extension? + if {[ext-has $ext shared]} { + user-error "Extension $ext can only be selected as a module" + } elseif {$ext in $withinfo(ext) || $required eq "$required"} { + msg-result "Extension $ext...enabled" + } elseif {$ext in $withinfo(maybe)} { + msg-result "Extension $ext...enabled (default)" + } else { + # Could be selected, but isn't (yet) + return [ext-set-status $ext x] + } + foreach i [ext-get $ext libdep] { + define-append LDLIBS [get-define $i ""] + } + return [ext-set-status $ext y] +} + +# Examines the user options (the $withinfo array) +# and the extension database ($extdb) to determine +# what is selected, and in what way. +# +# The results are available via ext-get-status +# And a dictionary is returned containing four keys: +# static-c extensions which are static C +# static-tcl extensions which are static Tcl +# module-c extensions which are C modules +# module-tcl extensions which are Tcl modules +proc check-extensions {} { + global extdb withinfo + + # Check valid extension names + foreach i [concat $withinfo(ext) $withinfo(mod)] { + if {![dict exists $extdb attrs $i]} { + user-error "Unknown extension: $i" + } + } + + set extlist [lsort [dict keys [dict get $extdb attrs]]] + + set withinfo(maybe) {} + + # Now work out the default status. We have. + # normal case, include !optional if possible + # --without=default, don't include optional + if {$withinfo(nodefault)} { + lappend withinfo(maybe) stdlib + } else { + foreach i $extlist { + if {![ext-has $i optional]} { + lappend withinfo(maybe) $i + } + } + } + + foreach i $extlist { + define LDLIBS_$i "" + } + + foreach i [concat $withinfo(ext) $withinfo(mod)] { + check-extension-status $i required + } + foreach i $withinfo(maybe) { + check-extension-status $i wanted + } + + array set extinfo {static-c {} static-tcl {} module-c {} module-tcl {}} + + foreach i $extlist { + set status [ext-get-status $i] + set tcl [ext-has $i tcl] + switch $status,$tcl { + y,1 { + define jim_ext_$i + lappend extinfo(static-tcl) $i + } + y,0 { + define jim_ext_$i + lappend extinfo(static-c) $i + # If there are any static C++ extensions, jimsh must be linked using + # the C++ compiler + if {[ext-has $i cpp]} { + define HAVE_CXX_EXTENSIONS + } + } + m,1 { lappend extinfo(module-tcl) $i } + m,0 { lappend extinfo(module-c) $i } + } + } + return [array get extinfo] +} diff --git a/debuggers/openocd/jimtcl/autosetup/system.tcl b/debuggers/openocd/jimtcl/autosetup/system.tcl new file mode 100644 index 00000000..2712e393 --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/system.tcl @@ -0,0 +1,269 @@ +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# @synopsis: +# +# This module supports common system interrogation and options +# such as --host, --build, --prefix, and setting srcdir, builddir, and EXEXT. +# +# It also support the 'feature' naming convention, where searching +# for a feature such as sys/type.h defines HAVE_SYS_TYPES_H +# +module-options { + host:host-alias => {a complete or partial cpu-vendor-opsys for the system where + the application will run (defaults to the same value as --build)} + build:build-alias => {a complete or partial cpu-vendor-opsys for the system + where the application will be built (defaults to the + result of running config.guess)} + prefix:dir => {the target directory for the build (defaults to /usr/local)} + + # These (hidden) options are supported for autoconf/automake compatibility + exec-prefix: + bindir: + sbindir: + includedir: + mandir: + infodir: + libexecdir: + datadir: + libdir: + sysconfdir: + sharedstatedir: + localstatedir: + maintainer-mode=0 + dependency-tracking=0 +} + +# Returns 1 if exists, or 0 if not +# +proc check-feature {name code} { + msg-checking "Checking for $name..." + set r [uplevel 1 $code] + define-feature $name $r + if {$r} { + msg-result "ok" + } else { + msg-result "not found" + } + return $r +} + +# @have-feature name ?default=0? +# +# Returns the value of the feature if defined, or $default if not. +# See 'feature-define-name' for how the feature name +# is translated into the define name. +# +proc have-feature {name {default 0}} { + get-define [feature-define-name $name] $default +} + +# @define-feature name ?value=1? +# +# Sets the feature 'define' to the given value. +# See 'feature-define-name' for how the feature name +# is translated into the define name. +# +proc define-feature {name {value 1}} { + define [feature-define-name $name] $value +} + +# @feature-checked name +# +# Returns 1 if the feature has been checked, whether true or not +# +proc feature-checked {name} { + is-defined [feature-define-name $name] +} + +# @feature-define-name name ?prefix=HAVE_? +# +# Converts a name to the corresponding define, +# e.g. sys/stat.h becomes HAVE_SYS_STAT_H. +# +# Converts * to P and all non-alphanumeric to underscore. +# +proc feature-define-name {name {prefix HAVE_}} { + string toupper $prefix[regsub -all {[^a-zA-Z0-9]} [regsub -all {[*]} $name p] _] +} + +# If $file doesn't exist, or it's contents are different than $buf, +# the file is written and $script is executed. +# Otherwise a "file is unchanged" message is displayed. +proc write-if-changed {file buf {script {}}} { + set old [readfile $file ""] + if {$old eq $buf && [file exists $file]} { + msg-result "$file is unchanged" + } else { + writefile $file $buf\n + uplevel 1 $script + } +} + +# @make-template template ?outfile? +# +# Reads the input file /$template and writes the output file $outfile. +# If $outfile is blank/omitted, $template should end with ".in" which +# is removed to create the output file name. +# +# Each pattern of the form @define@ is replaced the the corresponding +# define, if it exists, or left unchanged if not. +# +# The special value @srcdir@ is subsituted with the relative +# path to the source directory from the directory where the output +# file is created. Use @top_srcdir@ for the absolute path. +# +# Conditional sections may be specified as follows: +## @if name == value +## lines +## @else +## lines +## @endif +# +# Where 'name' is a defined variable name and @else is optional. +# If the expression does not match, all lines through '@endif' are ignored. +# +# The alternative forms may also be used: +## @if name +## @if name != value +# +# Where the first form is true if the variable is defined, but not empty or 0 +# +# Currently these expressions can't be nested. +# +proc make-template {template {out {}}} { + set infile [file join $::autosetup(srcdir) $template] + + if {![file exists $infile]} { + user-error "Template $template is missing" + } + + # Define this as late as possible + define AUTODEPS $::autosetup(deps) + + if {$out eq ""} { + if {[file ext $template] ne ".in"} { + autosetup-error "make_template $template has no target file and can't guess" + } + set out [file rootname $template] + } + + set outdir [file dirname $out] + + # Make sure the directory exists + file mkdir $outdir + + # Set up srcdir to be relative to the target dir + define srcdir [relative-path [file join $::autosetup(srcdir) $outdir] $outdir] + + set mapping {} + foreach {n v} [array get ::define] { + lappend mapping @$n@ $v + } + set result {} + foreach line [split [readfile $infile] \n] { + if {[info exists cond]} { + set l [string trimright $line] + if {$l eq "@endif"} { + unset cond + continue + } + if {$l eq "@else"} { + set cond [expr {!$cond}] + continue + } + if {$cond} { + lappend result $line + } + continue + } + if {[regexp {^@if\s+(\w+)(.*)} $line -> name expression]} { + lassign $expression equal value + set varval [get-define $name ""] + if {$equal eq ""} { + set cond [expr {$varval ni {"" 0}}] + } else { + set cond [expr {$varval eq $value}] + if {$equal ne "=="} { + set cond [expr {!$cond}] + } + } + continue + } + lappend result $line + } + writefile $out [string map $mapping [join $result \n]]\n + + msg-result "Created [relative-path $out] from [relative-path $template]" +} + +# build/host tuples and cross-compilation prefix +set build [opt-val build] +define build_alias $build +if {$build eq ""} { + define build [config_guess] +} else { + define build [config_sub $build] +} + +set host [opt-val host] +define host_alias $host +if {$host eq ""} { + define host [get-define build] + set cross "" +} else { + define host [config_sub $host] + set cross $host- +} +define cross [get-env CROSS $cross] + +# Do "define defaultprefix myvalue" to set the default prefix *before* the first "use" +set prefix [opt-val prefix [get-define defaultprefix /usr/local]] + +# These are for compatibility with autoconf +define target [get-define host] +define prefix $prefix +define builddir $autosetup(builddir) +define srcdir $autosetup(srcdir) +# Allow this to come from the environment +define top_srcdir [get-env top_srcdir [get-define srcdir]] + +# autoconf supports all of these +set exec_prefix [opt-val exec-prefix $prefix] +define exec_prefix $exec_prefix +foreach {name defpath} { + bindir /bin + sbindir /sbin + libexecdir /libexec + libdir /lib +} { + define $name [opt-val $name $exec_prefix$defpath] +} +foreach {name defpath} { + datadir /share + sysconfdir /etc + sharedstatedir /com + localstatedir /var + infodir /share/info + mandir /share/man + includedir /include +} { + define $name [opt-val $name $prefix$defpath] +} + +define SHELL [get-env SHELL [find-an-executable sh bash ksh]] + +# Windows vs. non-Windows +switch -glob -- [get-define host] { + *-*-ming* - *-*-cygwin - *-*-msys { + define-feature windows + define EXEEXT .exe + } + default { + define EXEEXT "" + } +} + +# Display +msg-result "Host System...[get-define host]" +msg-result "Build System...[get-define build]" diff --git a/debuggers/openocd/jimtcl/autosetup/test-tclsh b/debuggers/openocd/jimtcl/autosetup/test-tclsh new file mode 100644 index 00000000..75126d24 --- /dev/null +++ b/debuggers/openocd/jimtcl/autosetup/test-tclsh @@ -0,0 +1,20 @@ +# A small Tcl script to verify that the chosen +# interpreter works. Sometimes we might e.g. pick up +# an interpreter for a different arch. +# Outputs the full path to the interpreter + +if {[catch {info version} version] == 0} { + # This is Jim Tcl + if {$version >= 0.72} { + # Ensure that regexp works + regexp (a.*?) a + puts [info nameofexecutable] + exit 0 + } +} elseif {[catch {info tclversion} version] == 0} { + if {$version >= 8.5 && ![string match 8.5a* [info patchlevel]]} { + puts [info nameofexecutable] + exit 0 + } +} +exit 1 diff --git a/debuggers/openocd/jimtcl/bench.tcl b/debuggers/openocd/jimtcl/bench.tcl new file mode 100644 index 00000000..80f1506a --- /dev/null +++ b/debuggers/openocd/jimtcl/bench.tcl @@ -0,0 +1,586 @@ +set batchmode 0 +set benchmarks {} + +proc bench {title script} { + global benchmarks batchmode + + set Title [string range "$title " 0 20] + + set failed [catch {time $script} res] + if {$failed} { + if {!$batchmode} {puts "$Title - This test can't run on this interpreter"} + lappend benchmarks $title F + } else { + set t [expr [lindex $res 0] / 1000] + lappend benchmarks $title $t + set ts " $t" + set ts [string range $ts [expr {[string length $ts]-10}] end] + if {!$batchmode} {puts "$Title -$ts ms per iteration"} + } + catch { collect } +} + +### BUSY LOOP ################################################################## + +proc whilebusyloop {} { + set i 0 + while {$i < 1850000} { + set a 2 + incr i + } +} + +proc forbusyloop {} { + for {set i 0} {$i < 1850000} {incr i} { + set a 2 + } +} + +### FIBONACCI ################################################################## + +proc fibonacci {x} { + if {$x <= 1} { + expr 1 + } else { + expr {[fibonacci [expr {$x-1}]] + [fibonacci [expr {$x-2}]]} + } +} + +### HEAPSORT ################################################################### + +set IM 139968 +set IA 3877 +set IC 29573 + +set last 42 + +proc make_gen_random {} { + global IM IA IC + set params [list IM $IM IA $IA IC $IC] + set body [string map $params { + global last + expr {($max * [set last [expr {($last * IA + IC) % IM}]]) / IM} + }] + proc gen_random {max} $body +} + +proc heapsort {ra_name} { + upvar 1 $ra_name ra + set n [llength $ra] + set l [expr {$n / 2}] + set ir [expr {$n - 1}] + while 1 { + if {$l} { + set rra [lindex $ra [incr l -1]] + } else { + set rra [lindex $ra $ir] + lset ra $ir [lindex $ra 0] + if {[incr ir -1] == 0} { + lset ra 0 $rra + break + } + } + set i $l + set j [expr {(2 * $l) + 1}] + while {$j <= $ir} { + set tmp [lindex $ra $j] + if {$j < $ir} { + if {$tmp < [lindex $ra [expr {$j + 1}]]} { + set tmp [lindex $ra [incr j]] + } + } + if {$rra >= $tmp} { + break + } + lset ra $i $tmp + incr j [set i $j] + } + lset ra $i $rra + } +} + +proc heapsort_main {} { + set n 6100 + make_gen_random + + set data {} + for {set i 1} {$i <= $n} {incr i} { + lappend data [gen_random 1.0] + } + heapsort data +} + +### SIEVE ###################################################################### + +proc sieve {num} { + while {$num > 0} { + incr num -1 + set count 0 + for {set i 2} {$i <= 8192} {incr i} { + set flags($i) 1 + } + for {set i 2} {$i <= 8192} {incr i} { + if {$flags($i) == 1} { + # remove all multiples of prime: i + for {set k [expr {$i+$i}]} {$k <= 8192} {incr k $i} { + set flags($k) 0 + } + incr count + } + } + } + return $count +} + +proc sieve_dict {num} { + while {$num > 0} { + incr num -1 + set count 0 + for {set i 2} {$i <= 8192} {incr i} { + dict set flags $i 1 + } + for {set i 2} {$i <= 8192} {incr i} { + if {[dict get $flags $i] == 1} { + # remove all multiples of prime: i + for {set k [expr {$i+$i}]} {$k <= 8192} {incr k $i} { + dict set flags $k 0 + } + incr count + } + } + } + return $count +} + +### ARY ######################################################################## + +proc ary n { + for {set i 0} {$i < $n} {incr i} { + set x($i) $i + } + set last [expr {$n - 1}] + for {set j $last} {$j >= 0} {incr j -1} { + set y($j) $x($j) + } +} + +proc ary_dict n { + for {set i 0} {$i < $n} {incr i} { + dict set x $i $i + } + set last [expr {$n - 1}] + for {set j $last} {$j >= 0} {incr j -1} { + dict set y $j $x($j) + } +} + +### REPEAT ##################################################################### + +proc repeat {n body} { + for {set i 0} {$i < $n} {incr i} { + uplevel 1 $body + } +} + +proc use_repeat {} { + set x 0 + repeat {1000000} {incr x} +} + +### UPVAR ###################################################################### + +proc myincr varname { + upvar 1 $varname x + incr x +} + +proc upvartest {} { + set y 0 + for {set x 0} {$x < 100000} {myincr x} { + myincr y + } +} + +### NESTED LOOPS ############################################################### + +proc nestedloops {} { + set n 10 + set x 0 + incr n 1 + set a $n + while {[incr a -1]} { + set b $n + while {[incr b -1]} { + set c $n + while {[incr c -1]} { + set d $n + while {[incr d -1]} { + set e $n + while {[incr e -1]} { + set f $n + while {[incr f -1]} { + incr x + } + } + } + } + } + } +} + +### ROTATE ##################################################################### + +proc rotate {count} { + set v 1 + for {set n 0} {$n < $count} {incr n} { + set v [expr {$v <<< 1}] + } +} + +### DYNAMICALLY GENERATED CODE ################################################# + +proc dyncode {} { + for {set i 0} {$i < 100000} {incr i} { + set script "lappend foo $i" + eval $script + } +} + +proc dyncode_list {} { + for {set i 0} {$i < 100000} {incr i} { + set script [list lappend foo $i] + eval $script + } +} + +### PI DIGITS ################################################################## + +proc pi_digits {} { + set N 300 + set LEN [expr {10*$N/3}] + set result "" + + set a [string repeat " 2" $LEN] + set nines 0 + set predigit 0 + set nines {} + + set i0 [expr {$LEN+1}] + set quot0 [expr {2*$LEN+1}] + for {set j 0} {$j<$N} {incr j} { + set q 0 + set i $i0 + set quot $quot0 + set pos -1 + foreach apos $a { + set x [expr {10*$apos + $q * [incr i -1]}] + lset a [incr pos] [expr {$x % [incr quot -2]}] + set q [expr {$x / $quot}] + } + lset a end [expr {$q % 10}] + set q [expr {$q / 10}] + if {$q < 8} { + append result $predigit $nines + set nines {} + set predigit $q + } elseif {$q == 9} { + append nines 9 + } else { + append result [expr {$predigit+1}][string map {9 0} $nines] + set nines {} + set predigit 0 + } + } + #puts $result$predigit +} + +### EXPAND ##################################################################### + +proc expand {} { + for {set i 0} {$i < 100000} {incr i} { + set a [list a b c d e f] + lappend b {*}$a + } +} + +### MINLOOPS ################################################################### + +proc miniloops {} { + for {set i 0} {$i < 100000} {incr i} { + set sum 0 + for {set j 0} {$j < 10} {incr j} { + # something of more or less real + incr sum $j + } + } +} + +### wiki.tcl.tk/8566 ########################################################### + + # Internal procedure that indexes into the 2-dimensional array t, + # which corresponds to the sequence y, looking for the (i,j)th element. + + proc Index { t y i j } { + set indx [expr { ([llength $y] + 1) * ($i + 1) + ($j + 1) }] + return [lindex $t $indx] + } + + # Internal procedure that implements Levenshtein to derive the longest + # common subsequence of two lists x and y. + + proc ComputeLCS { x y } { + set t [list] + for { set i -1 } { $i < [llength $y] } { incr i } { + lappend t 0 + } + for { set i 0 } { $i < [llength $x] } { incr i } { + lappend t 0 + for { set j 0 } { $j < [llength $y] } { incr j } { + if { [string equal [lindex $x $i] [lindex $y $j]] } { + set lastT [Index $t $y [expr { $i - 1 }] [expr {$j - 1}]] + set nextT [expr {$lastT + 1}] + } else { + set lastT1 [Index $t $y $i [expr { $j - 1 }]] + set lastT2 [Index $t $y [expr { $i - 1 }] $j] + if { $lastT1 > $lastT2 } { + set nextT $lastT1 + } else { + set nextT $lastT2 + } + } + lappend t $nextT + } + } + return $t + } + + # Internal procedure that traces through the array built by ComputeLCS + # and finds a longest common subsequence -- specifically, the one that + # is lexicographically first. + + proc TraceLCS { t x y } { + set trace {} + set i [expr { [llength $x] - 1 }] + set j [expr { [llength $y] - 1 }] + set k [expr { [Index $t $y $i $j] - 1 }] + while { $i >= 0 && $j >= 0 } { + set im1 [expr { $i - 1 }] + set jm1 [expr { $j - 1 }] + if { [Index $t $y $i $j] == [Index $t $y $im1 $jm1] + 1 + && [string equal [lindex $x $i] [lindex $y $j]] } { + lappend trace xy [list $i $j] + set i $im1 + set j $jm1 + } elseif { [Index $t $y $im1 $j] > [Index $t $y $i $jm1] } { + lappend trace x $i + set i $im1 + } else { + lappend trace y $j + set j $jm1 + } + } + while { $i >= 0 } { + lappend trace x $i + incr i -1 + } + while { $j >= 0 } { + lappend trace y $j + incr j -1 + } + return $trace + } + + # list::longestCommonSubsequence::compare -- + # + # Compare two lists for the longest common subsequence + # + # Arguments: + # x, y - Two lists of strings to compare + # matched - Callback to execute on matched elements, see below + # unmatchedX - Callback to execute on unmatched elements from the + # first list, see below. + # unmatchedY - Callback to execute on unmatched elements from the + # second list, see below. + # + # Results: + # None. + # + # Side effects: + # Whatever the callbacks do. + # + # The 'compare' procedure compares the two lists of strings, x and y. + # It finds a longest common subsequence between the two. It then walks + # the lists in order and makes the following callbacks: + # + # For an element that is common to both lists, it appends the index in + # the first list, the index in the second list, and the string value of + # the element as three parameters to the 'matched' callback, and executes + # the result. + # + # For an element that is in the first list but not the second, it appends + # the index in the first list and the string value of the element as two + # parameters to the 'unmatchedX' callback and executes the result. + # + # For an element that is in the second list but not the first, it appends + # the index in the second list and the string value of the element as two + # parameters to the 'unmatchedY' callback and executes the result. + + proc compare { x y + matched + unmatchedX unmatchedY } { + set t [ComputeLCS $x $y] + set trace [TraceLCS $t $x $y] + set i [llength $trace] + while { $i > 0 } { + set indices [lindex $trace [incr i -1]] + set type [lindex $trace [incr i -1]] + switch -exact -- $type { + xy { + set c $matched + eval lappend c $indices + lappend c [lindex $x [lindex $indices 0]] + uplevel 1 $c + } + x { + set c $unmatchedX + lappend c $indices + lappend c [lindex $x $indices] + uplevel 1 $c + } + y { + set c $unmatchedY + lappend c $indices + lappend c [lindex $y $indices] + uplevel 1 $c + } + } + } + return + } + + proc umx { index value } { + global lastx + global xlines + append xlines "< " $value \n + set lastx $index + } + + proc umy { index value } { + global lasty + global ylines + append ylines "> " $value \n + set lasty $index + } + + proc matched { index1 index2 value } { + global lastx + global lasty + global xlines + global ylines + if { [info exists lastx] && [info exists lasty] } { + #puts "[expr { $lastx + 1 }],${index1}c[expr {$lasty + 1 }],${index2}" + #puts -nonewline $xlines + #puts "----" + #puts -nonewline $ylines + } elseif { [info exists lastx] } { + #puts "[expr { $lastx + 1 }],${index1}d${index2}" + #puts -nonewline $xlines + } elseif { [info exists lasty] } { + #puts "${index1}a[expr {$lasty + 1 }],${index2}" + #puts -nonewline $ylines + } + catch { unset lastx } + catch { unset xlines } + catch { unset lasty } + catch { unset ylines } + } + + # Really, we should read the first file in like this: + # set f0 [open [lindex $argv 0] r] + # set x [split [read $f0] \n] + # close $f0 + # But I'll just provide some sample lines: + +proc commonsub_test {} { + set x {} + for { set i 0 } { $i < 20 } { incr i } { + lappend x a r a d e d a b r a x + } + + # The second file, too, should be read in like this: + # set f1 [open [lindex $argv 1] r] + # set y [split [read $f1] \n] + # close $f1 + # Once again, I'll just do some sample lines. + + set y {} + for { set i 0 } { $i < 20 } { incr i } { + lappend y a b r a c a d a b r a + } + + compare $x $y matched umx umy + matched [llength $x] [llength $y] {} +} + +### MANDEL ##################################################################### + +proc mandel {xres yres infx infy supx supy} { + set incremx [expr {double($supx-$infx)/$xres}] + set incremy [expr {double($supy-$infy)/$yres}] + + for {set j 0} {$j < $yres} {incr j} { + set cim [expr {$infy+$incremy*$j}] + set line {} + for {set i 0} {$i < $xres} {incr i} { + set counter 0 + set zim 0 + set zre 0 + set cre [expr {$infx+$incremx*$i}] + while {$counter < 255} { + set dam [expr {$zre*$zre-$zim*$zim+$cre}] + set zim [expr {2*$zim*$zre+$cim}] + set zre $dam + if {$zre*$zre+$zim*$zim > 4} break + incr counter + } + # output pixel $i $j + } + } +} + +### RUN ALL #################################################################### + +if {[string compare [lindex $argv 0] "-batch"] == 0} { + set batchmode 1 + set argv [lrange $argv 1 end] +} +set ver [lindex $argv 0] + +bench {[while] busy loop} {whilebusyloop} +bench {[for] busy loop} {forbusyloop} +bench {mini loops} {miniloops} +bench {fibonacci(25)} {fibonacci 25} +bench {heapsort} {heapsort_main} +bench {sieve} {sieve 10} +bench {sieve [dict]} {sieve_dict 10} +bench {ary} {ary 100000} +bench {ary [dict]} {ary_dict 100000} +bench {repeat} {use_repeat} +bench {upvar} {upvartest} +bench {nested loops} {nestedloops} +bench {rotate} {rotate 100000} +bench {dynamic code} {dyncode} +bench {dynamic code (list)} {dyncode_list} +bench {PI digits} {pi_digits} +bench {expand} {expand} +bench {wiki.tcl.tk/8566} {commonsub_test} +bench {mandel} {mandel 60 60 -2 -1.5 1 1.5} + +if {$batchmode} { + if {$ver == ""} { + if {[catch {info patchlevel} ver]} { + set ver Jim[info version] + } + } + puts [list $ver $benchmarks] +} diff --git a/debuggers/openocd/jimtcl/binary.tcl b/debuggers/openocd/jimtcl/binary.tcl new file mode 100644 index 00000000..cc9c9ea6 --- /dev/null +++ b/debuggers/openocd/jimtcl/binary.tcl @@ -0,0 +1,254 @@ +# Implements the 'binary scan' and 'binary format' commands. +# +# (c) 2010 Steve Bennett +# +# See LICENCE in this directory for licensing. + +package require pack +package require regexp + +proc binary {cmd args} { + tailcall "binary $cmd" {*}$args +} + +proc "binary format" {formatString args} { + set bitoffset 0 + set result {} + foreach {conv t u n} [regexp -all -inline {([a-zA-Z@])(u)?([*0-9]*)} $formatString] { + if {$t in {a A}} { + set value [binary.nextarg args] + set sn [string bytelength $value] + if {$n ne "*"} { + if {$n eq ""} { + set n 1 + } + if {$n > $sn} { + # Need to pad the string with spaces or nulls + append value [string repeat [dict get {A " " a \x00} $t] $($n - $sn)] + } + } else { + set n $sn + } + if {$n} { + set bitoffset [pack result $value -str $(8 * $n) $bitoffset] + } + } elseif {[binary.intinfo $t] ne ""} { + # An integer type + lassign [binary.intinfo $t] type endian size prefix + set value [binary.nextarg args] + + if {$type ne "int"} { + set value [split $value {}] + } + set vn [llength $value] + if {$n eq "*"} { + set n $vn + } elseif {$n eq ""} { + set n 1 + set value [list $value] + } elseif {$vn < $n} { + if {$type eq "int"} { + return -code error "number of elements in list does not match count" + } else { + # Need to pad the list with zeros + lappend value {*}[lrepeat $($n - $vn) 0] + } + } elseif {$vn > $n} { + # Need to truncate the list + set value [lrange $value 0 $n-1] + } + + if {$endian eq "host"} { + set endian $($::tcl_platform(byteOrder) eq "bigEndian" ? "be" : "le") + } + foreach v $value { + set bitoffset [pack result $prefix$v -int$endian $size $bitoffset] + } + # Now pad out with zeros to the end of the current byte + if {$bitoffset % 8} { + set bitoffset [pack result 0 -int$endian $(8 - $bitoffset % 8) $bitoffset] + } + } elseif {$t eq "x"} { + if {$n eq "*"} { + return -code error {cannot use "*" in format string with "x"} + } + if {$n eq ""} { + set n 1 + } + loop i 0 $n { + set bitoffset [pack result 0 -intbe 8 $bitoffset] + } + } elseif {$t eq "@"} { + if {$n eq ""} { + return -code error {missing count for "@" field specifier} + } + if {$n eq "*"} { + set bitoffset $(8 * [string bytelength $result]) + } else { + # May need to pad it out + set max [string bytelength $result] + while {$n > $max} { + append result \x00 + incr max + } + set bitoffset $(8 * $n) + } + } elseif {$t eq "X"} { + if {$n eq "*"} { + set bitoffset 0 + } elseif {$n eq ""} { + incr bitoffset -8 + } else { + incr bitoffset $($n * -8) + } + if {$bitoffset < 0} { + set bitoffset 0 + } + } else { + return -code error "bad field specifier \"$t\"" + } + } + return $result +} + +proc "binary scan" {value formatString {args varName}} { + # Pops the next arg from the front of the list and returns it. + # Throws an error if no more args + set bitoffset 0 + set count 0 + foreach {conv t u n} [regexp -all -inline {([a-zA-Z@])(u)?([*0-9]*)} $formatString] { + set rembytes $([string bytelength $value] - $bitoffset / 8) + if {$t in {a A}} { + if {$n eq "*"} { + set n $rembytes + } elseif {$n eq ""} { + set n 1 + } + if {$n > $rembytes} { + break + } + + set var [binary.nextarg varName] + + set result [unpack $value -str $bitoffset $($n * 8)] + incr bitoffset $([string bytelength $result] * 8) + if {$t eq "A"} { + set result [string trimright $result] + } + } elseif {[binary.intinfo $t] ne ""} { + # An integer type + lassign [binary.intinfo $t] type endian size prefix + set var [binary.nextarg varName] + + if {$n eq "*"} { + set n $($rembytes * 8 / $size) + } else { + if {$n eq ""} { + set n 1 + } + } + if {$n * $size > $rembytes * 8} { + break + } + + if {$type ne "int"} { + set u u + } + if {$endian eq "host"} { + set endian $($::tcl_platform(byteOrder) eq "bigEndian" ? "be" : "le") + } + + set result {} + loop i 0 $n { + set v [unpack $value -${u}int$endian $bitoffset $size] + if {$type eq "int"} { + lappend result $v + } else { + append result [lindex {0 1 2 3 4 5 6 7 8 9 a b c d e f} $v] + } + incr bitoffset $size + } + # Now skip to the end of the current byte + if {$bitoffset % 8} { + incr bitoffset $(8 - ($bitoffset % 8)) + } + } elseif {$t eq "x"} { + # Skip bytes + if {$n eq "*"} { + set n $rembytes + } elseif {$n eq ""} { + set n 1 + } + if {$n > $rembytes} { + set n $rembytes + } + incr bitoffset $($n * 8) + continue + } elseif {$t eq "X"} { + # Back up bytes + if {$n eq "*"} { + set bitoffset 0 + continue + } + if {$n eq ""} { + set n 1 + } + if {$n * 8 > $bitoffset} { + set bitoffset 0 + continue + } + incr bitoffset -$($n * 8) + continue + } elseif {$t eq "@"} { + if {$n eq ""} { + return -code error {missing count for "@" field specifier} + } + if {$n eq "*" || $n > $rembytes + $bitoffset / 8} { + incr bitoffset $($rembytes * 8) + } elseif {$n < 0} { + set bitoffset 0 + } else { + set bitoffset $($n * 8) + } + continue + } else { + return -code error "bad field specifier \"$t\"" + } + uplevel 1 [list set $var $result] + incr count + } + return $count +} + +# Pops the next arg from the front of the list and returns it. +# Throws an error if no more args +proc binary.nextarg {&arglist} { + if {[llength $arglist] == 0} { + return -level 2 -code error "not enough arguments for all format specifiers" + } + set arglist [lassign $arglist arg] + return $arg +} + +proc binary.intinfo {type} { + set info { + c {int be 8} + s {int le 16} + t {int host 16} + S {int be 16} + i {int le 32} + I {int be 32} + n {int host 32} + w {int le 64} + W {int be 64} + m {int host 64} + h {hex le 4 0x} + H {hex be 4 0x} + b {bin le 1} + B {bin be 1} + } + if {[exists info($type)]} { + return $info($type) + } + return "" +} diff --git a/debuggers/openocd/jimtcl/bootstrap.tcl b/debuggers/openocd/jimtcl/bootstrap.tcl new file mode 100644 index 00000000..e7adf4b6 --- /dev/null +++ b/debuggers/openocd/jimtcl/bootstrap.tcl @@ -0,0 +1,3 @@ +# No need for package support in the bootstrap jimsh, but +# Tcl extensions call package require +proc package {args} {} diff --git a/debuggers/openocd/jimtcl/build-jim-ext.in b/debuggers/openocd/jimtcl/build-jim-ext.in new file mode 100644 index 00000000..9566b837 --- /dev/null +++ b/debuggers/openocd/jimtcl/build-jim-ext.in @@ -0,0 +1,255 @@ +#!/usr/bin/env jimsh + +# Separate command line arguments into options and source files +set opts {} +set sources {} + +proc usage {{msg {}}} { + puts stderr "Usage: build-jim-ext ?--notest? ?--install? ?--static? ?cc-options? ?-o modname? sources..." + if {$msg ne ""} { + puts stderr \n$msg + } + exit 1 +} + +proc readfile {filename {default_value ""}} { + set result $default_value + catch { + set f [open $filename] + set result [$f read -nonewline] + $f close + } + return $result +} + +set linker "@CC@" +set testmod 1 +set install 0 +set static 0 +set verbose 0 +set keep 0 +set includepaths {} +set libpaths {} +set libs {} +for {set i 0} {$i < [llength $argv]} {incr i} { + set arg [lindex $argv $i] + switch -glob -- $arg { + *.c { + lappend sources $arg + } + *.cpp { + lappend sources $arg + set linker "@CXX@" + } + --notest { + set testmod 0 + } + --install { + set install 1 + } + --static { + set static 1 + } + --verbose { + set verbose 1 + } + --keep { + set keep 1 + } + --help { + usage "Easily builds dynamic (loadable) modules for jim" + } + -o { + incr i + set modname [file rootname [lindex $argv $i]] + if {$modname eq ""} { + usage "Option -o requires an argument" + } + } + -I* { + lappend includepaths $arg + if {$arg eq "-I"} { + lappend includepaths [lindex $argv $i] + } + } + -L* { + lappend libpaths $arg + if {$arg eq "-L"} { + lappend libpaths [lindex $argv $i] + } + } + -l* { + lappend libs $arg + } + -* { + lappend opts $arg + } + default { + usage "Unexpected '$arg'" + } + } +} + +if {$sources eq ""} { + usage "No sources provided" +} +if {![info exists modname]} { + set modname [file rootname [file tail [lindex $sources 0]]] + # Remove jim- prefix if one exists + regsub "^jim-" $modname "" modname +} + +if {$static} { + set target libjim-$modname.a +} else { + set target $modname.so +} +puts "Building $target from $sources\n" + +# Now add the standard location after any user include paths +lappend includepaths -I@prefix@/include + +set CPPFLAGS "-D_GNU_SOURCE" + +set ljim "" +set shobj_cflags "" +set shobj_ldflags "" +if {!$static} { + set shobj_cflags "@SHOBJ_CFLAGS@" + if {"@JIM_STATICLIB@" eq "1"} { + puts stderr "Warning: libjim is static. Dynamic module may not work on some platforms.\n" + set shobj_ldflags "@SHOBJ_LDFLAGS@" + } else { + # If shared, link against the shared libjim to resolve symbols + set ljim -ljim + set shobj_ldflags "@SHOBJ_LDFLAGS_R@" + } +} + +set objs {} +foreach source $sources { + set obj [file rootname [file tail $source]].o + if {[string match *.c $source]} { + set compiler "@CC@" + } else { + set compiler "@CXX@" + } + set compile "$compiler @CFLAGS@ $CPPFLAGS $shobj_cflags $includepaths $opts -c -o $obj $source" + puts "Compile: $obj" + lappend objs $obj + flush stdout + set rc [catch { + if {$verbose} { + puts $compile + } + exec 2>jimerr.out {*}$compile + } msg] + + set errmsg [readfile jimerr.out] + file delete jimerr.out + + if {$rc} { + if {!$verbose} { + puts stderr $compile + } + puts stderr $msg + if {$errmsg ne ""} { + puts stderr $errmsg + } + file delete {*}$objs + exit 1 + } else { + if {$errmsg ne ""} { + puts $errmsg + } + } +} + +if {$static} { + set ar "@AR@ cq $target $objs" + set ranlib "@RANLIB@ $target" + + puts "Ar: $target" + set rc [catch { + file delete $target + exec {*}$ar + exec {*}$ranlib + if {$verbose} { + puts stderr $ar + } + } msg] + + file delete {*}$objs + + if {$rc} { + puts stderr $ar + puts stderr $ranlib + puts stderr $msg + file delete $target + exit 1 + } +} else { + # Add the standard location after any user lib paths + lappend libpaths -L@prefix@/lib + + set link "$linker @CFLAGS@ @LDFLAGS@ $shobj_ldflags $libpaths $opts -o $target $objs $ljim @LIBS@ $libs" + + puts "Link: $target" + set rc [catch { + if {$verbose} { + puts stderr $link + } + exec 2>jimerr.out {*}$link + } msg] + + set errmsg [readfile jimerr.out] + file delete jimerr.out + + if {!$keep} { + file delete {*}$objs + } + + if {$rc} { + file delete $target + puts stderr $link + puts stderr $msg + if {$errmsg ne ""} { + puts stderr $errmsg + } + exit 1 + } + if {$errmsg ne ""} { + puts $errmsg + } + + if {$testmod} { + # Now, is testing even possible? + # We must be running a compatible jimsh with the load command at least + set testmod 0 + set rc [catch { + # This will avoid attempting on Tcl and on jimsh without load + # How to tell if we are cross compiling? + if {[info version] > 0.73 && [exists -command load]} { + set testmod 1 + } + } msg] + } + + set rc [catch { + if {$testmod} { + puts "Test: load $target" + load $target + } + if {$install} { + set dest [env DESTDIR ""]@prefix@/lib/jim + puts "Install: $target => $dest" + file mkdir $dest + file copy $target $dest/$target + } + puts "\nSuccess!" + } msg] + if {$rc} { + puts stderr $msg + exit 1 + } +} diff --git a/debuggers/openocd/jimtcl/configure b/debuggers/openocd/jimtcl/configure new file mode 100755 index 00000000..8367bd8f --- /dev/null +++ b/debuggers/openocd/jimtcl/configure @@ -0,0 +1,3 @@ +#!/bin/sh +dir="`dirname "$0"`/autosetup" +WRAPPER="$0"; export WRAPPER; exec "`$dir/find-tclsh`" "$dir/autosetup" "$@" diff --git a/debuggers/openocd/jimtcl/configure.ac b/debuggers/openocd/jimtcl/configure.ac new file mode 100644 index 00000000..b70b5d8a --- /dev/null +++ b/debuggers/openocd/jimtcl/configure.ac @@ -0,0 +1 @@ +# Dummy configure.ac to make automake happy diff --git a/debuggers/openocd/jimtcl/examples.api/README b/debuggers/openocd/jimtcl/examples.api/README new file mode 100644 index 00000000..d3fc8be4 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples.api/README @@ -0,0 +1,36 @@ +Jim examples +============ +BSD 2-clause license, (c) 2010 Wojciech A. Koszek + + +This directory contains examples of Jim interpreter API. In order to start +working with Jim API one may just want to copy existing example .c file +into new file, modify Makefile and start working on a new program. + +Existing examples +================= + +jim_command + Simple command implementation in Jim's API. Command is then executed + in a script encoded within a program. + +jim_hello + Standard "Hello world!" program. + +jim_inline + Similar "Hello world!" program, but the result comes from a Tcl + script interpreted in Jim. Result is printed back on a terminal. + +jim_list + Will teach you how to create a list in Jim's API. Once created, + will show how to name and export it, so that variable is visible in + the script's source code. Once done, interpretation of separate + print.tcl file is presented. As a result, the script can print a + list members created from within ANSI C program. + +jim_obj + Basic object creation in Jim. + +jim_return + Similar to jim_command example, but implemented command actually + returns a value. diff --git a/debuggers/openocd/jimtcl/examples.api/jim_command.c b/debuggers/openocd/jimtcl/examples.api/jim_command.c new file mode 100644 index 00000000..43dd8f47 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples.api/jim_command.c @@ -0,0 +1,96 @@ +/*- + * Copyright (c) 2010 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include +#include +#include +#include + +#define JIM_EMBEDDED +#include + +/* + * Program which we want to get executed. + */ +#define JIM_PROGRAM "if {1 < 2} { MySampleCommand sample }" + +static int +MySampleCommandFunc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *str; + int len; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "string"); + return (JIM_ERR); + } + + str = Jim_GetString(argv[1], &len); + assert(str != NULL); + printf("%s\n", str); + + return (JIM_OK); +} + +/* + * Now we try to write big enough code to duplication our array in Jim's + * list implementation. Later, we try to load a sample script in Tcl that + * could print our list. + */ +int +main(int argc, char **argv) +{ + Jim_Interp *interp; + int error; + + /* Create an interpreter. */ + interp = Jim_CreateInterp(); + assert(interp != NULL && "couldn't create interpreter"); + + /* We register base commands, so that we actually implement Tcl. */ + Jim_RegisterCoreCommands(interp); + + /* And initialise any static extensions */ + Jim_InitStaticExtensions(interp); + + /* Register our Jim commands. */ + Jim_CreateCommand(interp, "MySampleCommand", MySampleCommandFunc, + NULL, NULL); + + /* Run a script. */ + error = Jim_Eval(interp, JIM_PROGRAM); + if (error == JIM_ERR) { + Jim_MakeErrorMessage(interp); + fprintf(stderr, "%s\n", Jim_GetString(Jim_GetResult(interp), NULL)); + Jim_FreeInterp(interp); + exit(EXIT_FAILURE); + } + + Jim_FreeInterp(interp); + return (EXIT_SUCCESS); +} diff --git a/debuggers/openocd/jimtcl/examples.api/jim_hello.c b/debuggers/openocd/jimtcl/examples.api/jim_hello.c new file mode 100644 index 00000000..831fcc76 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples.api/jim_hello.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2010 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ +#include +#include +#include + +#include + +int +main(int argc, char **argv) +{ + Jim_Interp *interp; + + interp = NULL; + + /* Create Jim instance */ + interp = Jim_CreateInterp(); + assert(interp != NULL && "couldn't create interpreter!"); + + /* We register base commands, so that we actually implement Tcl. */ + Jim_RegisterCoreCommands(interp); + + /* And initialise any static extensions */ + Jim_InitStaticExtensions(interp); + + + /* Print a string to standard output */ + Jim_Eval(interp, "puts {Hello world!}"); + + /* Free the interpreter */ + Jim_FreeInterp(interp); + return (EXIT_SUCCESS); +} diff --git a/debuggers/openocd/jimtcl/examples.api/jim_list.c b/debuggers/openocd/jimtcl/examples.api/jim_list.c new file mode 100644 index 00000000..93999fd6 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples.api/jim_list.c @@ -0,0 +1,112 @@ +/*- + * Copyright (c) 2010 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include +#include +#include +#include + +#define JIM_EMBEDDED +#include + +/* + * We have a list of sample words in 'C'.. + */ +const char *strings[] = { + "simple", + "strings", + "which", + "should", + "get", + "interpreted", + "by", + "Jim", +}; + +/* + * We have macros which let us to easily obtain of array presented above + */ +#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0])) +#define SAMPLE_OBJS ARRAY_SIZE(strings) + +/* + * Now we try to write big enough code to duplication our array in Jim's + * list implementation. Later, we try to load a sample script in Tcl that + * could print our list. + */ +int +main(int argc, char **argv) +{ + Jim_Interp *interp; + Jim_Obj *obj[SAMPLE_OBJS]; + Jim_Obj *list; + int i; + int error; + + /* Create an interpreter */ + interp = Jim_CreateInterp(); + + /* We register base commands, so that we actually implement Tcl. */ + Jim_RegisterCoreCommands(interp); + + /* And initialise any static extensions */ + Jim_InitStaticExtensions(interp); + + /* Create an empty list */ + list = Jim_NewListObj(interp, NULL, 0); + assert(list != NULL); + + /* + * For each string.. + */ + for (i = 0; i < SAMPLE_OBJS; i++) { + /* Duplicate it as an array member. */ + obj[i] = Jim_NewStringObj(interp, strings[i], -1); + assert(obj[i] != NULL); + + /* We append newly created object to the list */ + Jim_ListAppendElement(interp, list, obj[i]); + } + + /* + * We bind a Tcl's name with our list, so that Tcl script can + * identify the variable. + */ + Jim_SetVariableStr(interp, "MYLIST", list); + + /* + * Parse a script + */ + error = Jim_EvalFile(interp, "./print.tcl"); + if (error == JIM_ERR) { + Jim_MakeErrorMessage(interp); + fprintf(stderr, "%s\n", Jim_GetString(Jim_GetResult(interp), NULL)); + } + Jim_FreeInterp(interp); + return (EXIT_SUCCESS); +} diff --git a/debuggers/openocd/jimtcl/examples.api/jim_obj.c b/debuggers/openocd/jimtcl/examples.api/jim_obj.c new file mode 100644 index 00000000..607ef7cf --- /dev/null +++ b/debuggers/openocd/jimtcl/examples.api/jim_obj.c @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2010 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ +#include +#include +#include +#include + +#define JIM_EMBEDDED +#include + +#define OBJ_DESC "hello world" + +int +main(int argc, char **argv) +{ + Jim_Interp *interp; + Jim_Obj *obj; + const char *obj_desc; + int obj_size; + + obj = NULL; + obj_desc = NULL; + obj_size = -1; + + /* Create an interpreter */ + interp = Jim_CreateInterp(); + + /* We register base commands, so that we actually implement Tcl. */ + Jim_RegisterCoreCommands(interp); + + /* And initialise any static extensions */ + Jim_InitStaticExtensions(interp); + + + /* Create some empty object */ + obj = Jim_NewObj(interp); + + /* Name the object */ + Jim_InitStringRep(obj, OBJ_DESC, strlen(OBJ_DESC)) ; + + /* Obtain internal representation of an object */ + obj_desc = Jim_GetString(obj, &obj_size); + assert(obj_desc != NULL && "Jim should return NULL as a description"); + printf("Object described as '%s'; object size is %d\n", obj_desc, + obj_size); + + Jim_FreeObj(interp, obj); + Jim_FreeInterp(interp); + + return (EXIT_SUCCESS); +} diff --git a/debuggers/openocd/jimtcl/examples.api/jim_return.c b/debuggers/openocd/jimtcl/examples.api/jim_return.c new file mode 100644 index 00000000..58b8a94d --- /dev/null +++ b/debuggers/openocd/jimtcl/examples.api/jim_return.c @@ -0,0 +1,97 @@ +/*- + * Copyright (c) 2010 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include +#include +#include +#include + +#define JIM_EMBEDDED +#include + +/* + * Program which we want to get executed. + */ +#define JIM_PROGRAM "set l [CountChars Sample]; puts $l" + +/* + * Our function. + */ +static int +CountCharsFunc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *str; + int len; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "string"); + return (JIM_ERR); + } + str = Jim_GetString(argv[1], &len); + Jim_SetResult(interp, Jim_NewIntObj(interp, (jim_wide)len)); + return (JIM_OK); +} + +/* + * Now we try to write big enough code to duplication our array in Jim's + * list implementation. Later, we try to load a sample script in Tcl that + * could print our list. + */ +int +main(int argc, char **argv) +{ + Jim_Interp *interp; + int error; + + /* Create an interpreter. */ + interp = Jim_CreateInterp(); + assert(interp != NULL && "couldn't create interpreter"); + + /* We register base commands, so that we actually implement Tcl. */ + Jim_RegisterCoreCommands(interp); + + /* And initialise any static extensions */ + Jim_InitStaticExtensions(interp); + + + /* Register our Jim command. */ + Jim_CreateCommand(interp, "CountChars", CountCharsFunc, + NULL, NULL); + + /* Run a script. */ + error = Jim_Eval(interp, JIM_PROGRAM); + if (error == JIM_ERR) { + Jim_MakeErrorMessage(interp); + fprintf(stderr, "%s\n", Jim_GetString(Jim_GetResult(interp), NULL)); + Jim_FreeInterp(interp); + exit(EXIT_FAILURE); + } + + Jim_FreeInterp(interp); + return (EXIT_SUCCESS); +} diff --git a/debuggers/openocd/jimtcl/examples.api/print.tcl b/debuggers/openocd/jimtcl/examples.api/print.tcl new file mode 100644 index 00000000..e05d48b0 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples.api/print.tcl @@ -0,0 +1,5 @@ +puts "-- List present in an array constructed from C program --" +foreach {str} $MYLIST { + puts $str +} +puts "---------------------------------------------------------" diff --git a/debuggers/openocd/jimtcl/examples.ext/README b/debuggers/openocd/jimtcl/examples.ext/README new file mode 100644 index 00000000..2317481f --- /dev/null +++ b/debuggers/openocd/jimtcl/examples.ext/README @@ -0,0 +1,7 @@ +This directory contains examples of C extensions for Jim. + +In general, do: + + build-jim-ext extsource.c + +See the Makefile diff --git a/debuggers/openocd/jimtcl/examples.ext/helloworld.c b/debuggers/openocd/jimtcl/examples.ext/helloworld.c new file mode 100644 index 00000000..371a23d0 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples.ext/helloworld.c @@ -0,0 +1,24 @@ +/* + * hello.c -- A minimal Jim C extension. + */ +#include + +static int +Hello_Cmd(Jim_Interp *interp, int objc, Jim_Obj *const objv[]) +{ + Jim_SetResultString(interp, "Hello, World!", -1); + return JIM_OK; +} + +/* + * Jim_helloworldInit -- Called when Jim loads your extension. + * + * Note that the name *must* correspond exactly to the name of the extension: + * Jim_Init + */ +int +Jim_helloworldInit(Jim_Interp *interp) +{ + Jim_CreateCommand(interp, "hello", Hello_Cmd, NULL, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/examples/client-server.tcl b/debuggers/openocd/jimtcl/examples/client-server.tcl new file mode 100644 index 00000000..07407738 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/client-server.tcl @@ -0,0 +1,83 @@ +proc bgerror {msg} { + puts "bgerror: $msg" + #exit 0 +} + +proc verbose {msg} { + puts $msg +} + +if {[os.fork] == 0} { + verbose "child: waiting a bit" + + # This will be our client + + sleep .1 + + set f [socket stream localhost:9876] + fconfigure $f -buffering line + + set done 0 + + proc onread {f} { + if {[$f gets buf] > 0} { + verbose "child: read response '$buf'" + } else { + verbose "child: read got eof" + set ::done 1 + } + } + + proc onwrite {f} { + verbose "child: sending request" + $f puts -nonewline "GET / HTTP/1.0\r\n\r\n" + $f writable {} + } + + $f readable [list onread $f] + $f writable [list onwrite $f] + + alarm 10 + catch -signal { + verbose "child: in event loop" + vwait done + verbose "child: done event loop" + } + alarm 0 + $f close + exit 0 +} + +verbose "parent: opening socket" +set done 0 + +# This will be our server +set f [socket stream.server 0.0.0.0:9876] + +proc server_onread {f} { + verbose "parent: onread (server) got connection on $f" + set cfd [$f accept] + verbose "parent: onread accepted $cfd" + + verbose "parent: read request '[string trim [$cfd gets]]'" + + $cfd puts "Thanks for the request" + $cfd close + + verbose "parent: sent response" + + incr ::done +} + +$f readable [list server_onread $f] + +alarm 10 +catch -signal { + vwait done +} +alarm 0 +$f close + +sleep .5 + +return "ok" diff --git a/debuggers/openocd/jimtcl/examples/dns.tcl b/debuggers/openocd/jimtcl/examples/dns.tcl new file mode 100644 index 00000000..fb55a7ab --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/dns.tcl @@ -0,0 +1,1226 @@ +# dns.tcl - Steve Bennett +# +# Modified for Jim Tcl to: +# - use udp transport by default +# - use sendto/recvfrom +# - don't try to determine local nameservers +# - remove support for dns uris and finding local nameservers +# - remove logging calls +# (both of these in order to remove dependencies on tcllib) + +# Based on: + +# dns.tcl - Copyright (C) 2002 Pat Thoyts +# +# Provide a Tcl only Domain Name Service client. See RFC 1034 and RFC 1035 +# for information about the DNS protocol. This should insulate Tcl scripts +# from problems with using the system library resolver for slow name servers. +# +# This implementation uses TCP only for DNS queries. The protocol reccommends +# that UDP be used in these cases but Tcl does not include UDP sockets by +# default. The package should be simple to extend to use a TclUDP extension +# in the future. +# +# Support for SPF (http://spf.pobox.com/rfcs.html) will need updating +# if or when the proposed draft becomes accepted. +# +# Support added for RFC1886 - DNS Extensions to support IP version 6 +# Support added for RFC2782 - DNS RR for specifying the location of services +# Support added for RFC1995 - Incremental Zone Transfer in DNS +# +# TODO: +# - When using tcp we should make better use of the open connection and +# send multiple queries along the same connection. +# +# - We must switch to using TCP for truncated UDP packets. +# +# - Read RFC 2136 - dynamic updating of DNS +# +# ------------------------------------------------------------------------- +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# ------------------------------------------------------------------------- +# +# $Id: dns.tcl,v 1.36 2008/11/22 12:28:54 mic42 Exp $ + +package require binary +package require namespace + +namespace eval ::dns { + variable version 1.3.3-jim2 + variable rcsid {$Id: dns.tcl,v 1.36 2008/11/22 12:28:54 mic42 Exp $} + + namespace export configure resolve name address cname \ + status reset wait cleanup errorcode + + variable options + if {![info exists options]} { + array set options { + port 53 + timeout 30000 + protocol udp + search {} + nameserver {localhost} + loglevel warn + } + #variable log [logger::init dns] + #${log}::setlevel $options(loglevel) + } + + variable types + array set types { + A 1 NS 2 MD 3 MF 4 CNAME 5 SOA 6 MB 7 MG 8 MR 9 + NULL 10 WKS 11 PTR 12 HINFO 13 MINFO 14 MX 15 TXT 16 + SPF 16 AAAA 28 SRV 33 IXFR 251 AXFR 252 MAILB 253 MAILA 254 + ANY 255 * 255 + } + + variable classes + array set classes { IN 1 CS 2 CH 3 HS 4 * 255} + + variable uid + if {![info exists uid]} { + set uid 0 + } +} + +# ------------------------------------------------------------------------- + +# Description: +# Configure the DNS package. In particular the local nameserver will need +# to be set. With no options, returns a list of all current settings. +# +proc ::dns::configure {args} { + variable options + variable log + + if {[llength $args] < 1} { + set r {} + foreach opt [lsort [array names options]] { + lappend r -$opt $options($opt) + } + return $r + } + + set cget 0 + if {[llength $args] == 1} { + set cget 1 + } + + while {[string match -* [lindex $args 0]]} { + switch -glob -- [lindex $args 0] { + -n* - + -ser* { + if {$cget} { + return $options(nameserver) + } else { + set options(nameserver) [Pop args 1] + } + } + -po* { + if {$cget} { + return $options(port) + } else { + set options(port) [Pop args 1] + } + } + -ti* { + if {$cget} { + return $options(timeout) + } else { + set options(timeout) [Pop args 1] + } + } + -pr* { + if {$cget} { + return $options(protocol) + } else { + set proto [string tolower [Pop args 1]] + if {[string compare udp $proto] == 0 \ + && [string compare tcp $proto] == 0} { + return -code error "invalid protocol \"$proto\":\ + protocol must be either \"udp\" or \"tcp\"" + } + set options(protocol) $proto + } + } + -sea* { + if {$cget} { + return $options(search) + } else { + set options(search) [Pop args 1] + } + } + -log* { + if {$cget} { + return $options(loglevel) + } else { + set options(loglevel) [Pop args 1] + ${log}::setlevel $options(loglevel) + } + } + -- { Pop args ; break } + default { + set opts [join [lsort [array names options]] ", -"] + return -code error "bad option [lindex $args 0]:\ + must be one of -$opts" + } + } + Pop args + } + + return +} + +# ------------------------------------------------------------------------- + +# Description: +# Create a DNS query and send to the specified name server. Returns a token +# to be used to obtain any further information about this query. +# +proc ::dns::resolve {query args} { + variable uid + variable options + variable log + + # get a guaranteed unique and non-present token id. + set id [incr uid] + while {[info exists [set token [namespace current]::$id]]} { + set id [incr uid] + } + # FRINK: nocheck + variable $token + upvar 0 $token state + + # Setup token/state defaults. + set state(id) $id + set state(query) $query + set state(qdata) "" + set state(opcode) 0; # 0 = query, 1 = inverse query. + set state(-type) A; # DNS record type (A address) + set state(-class) IN; # IN (internet address space) + set state(-recurse) 1; # Recursion Desired + set state(-command) {}; # asynchronous handler + set state(-timeout) $options(timeout); # connection timeout default. + set state(-nameserver) $options(nameserver);# default nameserver + set state(-port) $options(port); # default namerservers port + set state(-search) $options(search); # domain search list + set state(-protocol) $options(protocol); # which protocol udp/tcp + + # Support for DNS URL's removed + + while {[string match -* [lindex $args 0]]} { + switch -glob -- [lindex $args 0] { + -n* - ns - + -ser* { set state(-nameserver) [Pop args 1] } + -po* { set state(-port) [Pop args 1] } + -ti* { set state(-timeout) [Pop args 1] } + -co* { set state(-command) [Pop args 1] } + -cl* { set state(-class) [Pop args 1] } + -ty* { set state(-type) [Pop args 1] } + -pr* { set state(-protocol) [Pop args 1] } + -sea* { set state(-search) [Pop args 1] } + -re* { set state(-recurse) [Pop args 1] } + -inv* { set state(opcode) 1 } + -status {set state(opcode) 2} + -data { set state(qdata) [Pop args 1] } + default { + set opts [join [lsort [array names state -*]] ", "] + return -code error "bad option [lindex $args 0]: \ + must be $opts" + } + } + Pop args + } + + if {$state(-nameserver) == {}} { + return -code error "no nameserver specified" + } + + # Check for reverse lookups + if {[regexp {^(?:\d{0,3}\.){3}\d{0,3}$} $state(query)]} { + set addr [lreverse [split $state(query) .]] + lappend addr in-addr arpa + set state(query) [join $addr .] + set state(-type) PTR + } + + BuildMessage $token + + if {$state(-protocol) == "tcp"} { + TcpTransmit $token + if {$state(-command) == {}} { + wait $token + } + } else { + UdpTransmit $token + wait $token + } + + return $token +} + +# ------------------------------------------------------------------------- + +# Description: +# Return a list of domain names returned as results for the last query. +# +proc ::dns::name {token} { + set r {} + Flags $token flags + array set reply [Decode $token] + + switch -exact -- $flags(opcode) { + 0 { + # QUERY + foreach answer $reply(AN) { + array set AN $answer + if {![info exists AN(type)]} {set AN(type) {}} + switch -exact -- $AN(type) { + MX - NS - PTR { + if {[info exists AN(rdata)]} {lappend r $AN(rdata)} + } + default { + if {[info exists AN(name)]} { + lappend r $AN(name) + } + } + } + } + } + + 1 { + # IQUERY + foreach answer $reply(QD) { + array set QD $answer + lappend r $QD(name) + } + } + default { + return -code error "not supported for this query type" + } + } + return $r +} + +# Description: +# Return a list of the IP addresses returned for this query. +# +proc ::dns::address {token} { + set r {} + array set reply [Decode $token] + foreach answer $reply(AN) { + array set AN $answer + + if {[info exists AN(type)]} { + switch -exact -- $AN(type) { + "A" { + lappend r $AN(rdata) + } + "AAAA" { + lappend r $AN(rdata) + } + } + } + } + return $r +} + +# Description: +# Return a list of all CNAME results returned for this query. +# +proc ::dns::cname {token} { + set r {} + array set reply [Decode $token] + foreach answer $reply(AN) { + array set AN $answer + + if {[info exists AN(type)]} { + if {$AN(type) == "CNAME"} { + lappend r $AN(rdata) + } + } + } + return $r +} + +# Description: +# Return the decoded answer records. This can be used for more complex +# queries where the answer isn't supported byb cname/address/name. +proc ::dns::result {token args} { + array set reply [eval [linsert $args 0 Decode $token]] + return $reply(AN) +} + +# ------------------------------------------------------------------------- + +# Description: +# Get the status of the request. +# +proc ::dns::status {token} { + upvar #0 $token state + return $state(status) +} + +# Description: +# Get the error message. Empty if no error. +# +proc ::dns::error {token} { + upvar #0 $token state + if {[info exists state(error)]} { + return $state(error) + } + return "" +} + +# Description +# Get the error code. This is 0 for a successful transaction. +# +proc ::dns::errorcode {token} { + upvar #0 $token state + set flags [Flags $token] + set ndx [lsearch -exact $flags errorcode] + incr ndx + return [lindex $flags $ndx] +} + +# Description: +# Reset a connection with optional reason. +# +proc ::dns::reset {token {why reset} {errormsg {}}} { + upvar #0 $token state + set state(status) $why + if {[string length $errormsg] > 0 && ![info exists state(error)]} { + set state(error) $errormsg + } + catch {fileevent $state(sock) readable {}} + Finish $token +} + +# Description: +# Wait for a request to complete and return the status. +# +proc ::dns::wait {token} { + upvar #0 $token state + + if {$state(status) == "connect"} { + vwait [subst $token](status) + } + + return $state(status) +} + +# Description: +# Remove any state associated with this token. +# +proc ::dns::cleanup {token} { + upvar #0 $token state + if {[info exists state]} { + catch {close $state(sock)} + catch {after cancel $state(after)} + unset state + } +} + +# ------------------------------------------------------------------------- + +# Description: +# Dump the raw data of the request and reply packets. +# +proc ::dns::dump {args} { + if {[llength $args] == 1} { + set type -reply + set token [lindex $args 0] + } elseif { [llength $args] == 2 } { + set type [lindex $args 0] + set token [lindex $args 1] + } else { + return -code error "wrong # args:\ + should be \"dump ?option? methodName\"" + } + + # FRINK: nocheck + variable $token + upvar 0 $token state + + set result {} + switch -glob -- $type { + -qu* - + -req* { + set result [DumpMessage $state(request)] + } + -rep* { + set result [DumpMessage $state(reply)] + } + default { + error "unrecognised option: must be one of \ + \"-query\", \"-request\" or \"-reply\"" + } + } + + return $result +} + +# Description: +# Perform a hex dump of binary data. +# +proc ::dns::DumpMessage {data} { + set result {} + binary scan $data c* r + foreach c $r { + append result [format "%02x " [expr {$c & 0xff}]] + } + return $result +} + +# ------------------------------------------------------------------------- + +# Description: +# Contruct a DNS query packet. +# +proc ::dns::BuildMessage {token} { + # FRINK: nocheck + variable $token + upvar 0 $token state + variable types + variable classes + variable options + + if {! [info exists types($state(-type))] } { + return -code error "invalid DNS query type" + } + + if {! [info exists classes($state(-class))] } { + return -code error "invalid DNS query class" + } + + set qdcount 0 + set qsection {} + set nscount 0 + set nsdata {} + + # In theory we can send multiple queries. In practice, named doesn't + # appear to like that much. If it did work we'd do this: + # foreach domain [linsert $options(search) 0 {}] ... + + + # Pack the query: QNAME QTYPE QCLASS + set qsection [PackName $state(query)] + append qsection [binary format SS \ + $types($state(-type))\ + $classes($state(-class))] + incr qdcount + + if {[string length $state(qdata)] > 0} { + set nsdata [eval [linsert $state(qdata) 0 PackRecord]] + incr nscount + } + + switch -exact -- $state(opcode) { + 0 { + # QUERY + set state(request) [binary format SSSSSS $state(id) \ + [expr {($state(opcode) << 11) | ($state(-recurse) << 8)}] \ + $qdcount 0 $nscount 0] + append state(request) $qsection $nsdata + } + 1 { + # IQUERY + set state(request) [binary format SSSSSS $state(id) \ + [expr {($state(opcode) << 11) | ($state(-recurse) << 8)}] \ + 0 $qdcount 0 0 0] + append state(request) \ + [binary format cSSI 0 \ + $types($state(-type)) $classes($state(-class)) 0] + switch -exact -- $state(-type) { + A { + append state(request) \ + [binary format Sc4 4 [split $state(query) .]] + } + PTR { + append state(request) \ + [binary format Sc4 4 [split $state(query) .]] + } + default { + return -code error "inverse query not supported for this type" + } + } + } + default { + return -code error "operation not supported" + } + } + + return +} + +# Pack a human readable dns name into a DNS resource record format. +proc ::dns::PackName {name} { + set data "" + foreach part [split [string trim $name .] .] { + set len [string length $part] + append data [binary format ca$len $len $part] + } + append data \x00 + return $data +} + +# Pack a character string - byte length prefixed +proc ::dns::PackString {text} { + set len [string length $text] + set data [binary format ca$len $len $text] + return $data +} + +# Pack up a single DNS resource record. See RFC1035: 3.2 for the format +# of each type. +# eg: PackRecord name wiki.tcl.tk type MX class IN rdata {10 mail.example.com} +# +proc ::dns::PackRecord {args} { + variable types + variable classes + array set rr {name "" type A class IN ttl 0 rdlength 0 rdata ""} + array set rr $args + set data [PackName $rr(name)] + + switch -exact -- $rr(type) { + CNAME - MB - MD - MF - MG - MR - NS - PTR { + set rr(rdata) [PackName $rr(rdata)] + } + HINFO { + array set r {CPU {} OS {}} + array set r $rr(rdata) + set rr(rdata) [PackString $r(CPU)] + append rr(rdata) [PackString $r(OS)] + } + MINFO { + array set r {RMAILBX {} EMAILBX {}} + array set r $rr(rdata) + set rr(rdata) [PackString $r(RMAILBX)] + append rr(rdata) [PackString $r(EMAILBX)] + } + MX { + foreach {pref exch} $rr(rdata) break + set rr(rdata) [binary format S $pref] + append rr(rdata) [PackName $exch] + } + TXT { + set str $rr(rdata) + set len [string length [set str $rr(rdata)]] + set rr(rdata) "" + for {set n 0} {$n < $len} {incr n} { + set s [string range $str $n [incr n 253]] + append rr(rdata) [PackString $s] + } + } + NULL {} + SOA { + array set r {MNAME {} RNAME {} + SERIAL 0 REFRESH 0 RETRY 0 EXPIRE 0 MINIMUM 0} + array set r $rr(rdata) + set rr(rdata) [PackName $r(MNAME)] + append rr(rdata) [PackName $r(RNAME)] + append rr(rdata) [binary format IIIII $r(SERIAL) \ + $r(REFRESH) $r(RETRY) $r(EXPIRE) $r(MINIMUM)] + } + } + + # append the root label and the type flag and query class. + append data [binary format SSIS $types($rr(type)) \ + $classes($rr(class)) $rr(ttl) [string length $rr(rdata)]] + append data $rr(rdata) + return $data +} + +# ------------------------------------------------------------------------- + +# Description: +# Transmit a DNS request over a tcp connection. +# +proc ::dns::TcpTransmit {token} { + # FRINK: nocheck + variable $token + upvar 0 $token state + + # setup the timeout + if {$state(-timeout) > 0} { + set state(after) [after $state(-timeout) \ + [list [namespace origin reset] \ + $token timeout\ + "operation timed out"]] + } + + # Jim Tcl has no async connect ... + + set s [socket stream $state(-nameserver):$state(-port)] + fileevent $s writable [list [namespace origin TcpConnected] $token $s] + set state(sock) $s + set state(status) connect + + return $token +} + +proc ::dns::TcpConnected {token s} { + variable $token + upvar 0 $token state + + fileevent $s writable {} + + # Jim Tcl has no async connect ... +# if {[catch {fconfigure $s -peername}]} { +# # TCP connection failed +# Finish $token "can't connect to server" +# return +# } + + fconfigure $s -blocking 0 -translation binary -buffering none + + # For TCP the message must be prefixed with a 16bit length field. + set req [binary format S [string length $state(request)]] + append req $state(request) + + puts -nonewline $s $req + + fileevent $s readable [list [namespace current]::TcpEvent $token] +} + +# ------------------------------------------------------------------------- +# Description: +# Transmit a DNS request using UDP datagrams +# +# Note: +# This requires a UDP implementation that can transmit binary data. +# As yet I have been unable to test this myself and the tcludp package +# cannot do this. +# +proc ::dns::UdpTransmit {token} { + # FRINK: nocheck + variable $token + upvar 0 $token state + + # setup the timeout + if {$state(-timeout) > 0} { + set state(after) [after $state(-timeout) \ + [list [namespace origin reset] \ + $token timeout\ + "operation timed out"]] + } + + set state(sock) [socket dgram] + #fconfigure $state(sock) -translation binary -buffering none + set state(status) connect + $state(sock) sendto $state(request) $state(-nameserver):$state(-port) + + fileevent $state(sock) readable [list [namespace current]::UdpEvent $token] + + return $token +} + +# ------------------------------------------------------------------------- + +# Description: +# Tidy up after a tcp transaction. +# +proc ::dns::Finish {token {errormsg ""}} { + # FRINK: nocheck + variable $token + upvar 0 $token state + global errorInfo errorCode + + if {[string length $errormsg] != 0} { + set state(error) $errormsg + set state(status) error + } + catch {close $state(sock)} + catch {after cancel $state(after)} + if {[info exists state(-command)] && $state(-command) != {}} { + if {[catch {eval $state(-command) {$token}} err]} { + if {[string length $errormsg] == 0} { + set state(error) [list $err $errorInfo $errorCode] + set state(status) error + } + } + if {[info exists state(-command)]} { + unset state(-command) + } + } +} + +# ------------------------------------------------------------------------- + +# Description: +# Handle end-of-file on a tcp connection. +# +proc ::dns::Eof {token} { + # FRINK: nocheck + variable $token + upvar 0 $token state + set state(status) eof + Finish $token +} + +# ------------------------------------------------------------------------- + +# Description: +# Process a DNS reply packet (protocol independent) +# +proc ::dns::Receive {token} { + # FRINK: nocheck + variable $token + upvar 0 $token state + + binary scan $state(reply) SS id flags + set status [expr {$flags & 0x000F}] + + switch -- $status { + 0 { + set state(status) ok + Finish $token + } + 1 { Finish $token "Format error - unable to interpret the query." } + 2 { Finish $token "Server failure - internal server error." } + 3 { Finish $token "Name Error - domain does not exist" } + 4 { Finish $token "Not implemented - the query type is not available." } + 5 { Finish $token "Refused - your request has been refused by the server." } + default { + Finish $token "unrecognised error code: $err" + } + } +} + +# ------------------------------------------------------------------------- + +# Description: +# file event handler for tcp socket. Wait for the reply data. +# +proc ::dns::TcpEvent {token} { + variable log + # FRINK: nocheck + variable $token + upvar 0 $token state + set s $state(sock) + + if {[eof $s]} { + Eof $token + return + } + + set status [catch {read $state(sock)} result] + if {$status != 0} { + ${log}::debug "Event error: $result" + Finish $token "error reading data: $result" + } elseif { [string length $result] >= 0 } { + if {[catch { + # Handle incomplete reads - check the size and keep reading. + if {![info exists state(size)]} { + binary scan $result S state(size) + set result [string range $result 2 end] + } + append state(reply) $result + + # check the length and flags and chop off the tcp length prefix. + if {[string length $state(reply)] >= $state(size)} { + binary scan $result S id + set id [expr {$id & 0xFFFF}] + if {$id != [expr {$state(id) & 0xFFFF}]} { + ${log}::error "received packed with incorrect id" + } + # bug #1158037 - doing this causes problems > 65535 requests! + #Receive [namespace current]::$id + Receive $token + } else { + ${log}::debug "Incomplete tcp read:\ + [string length $state(reply)] should be $state(size)" + } + } err]} { + Finish $token "Event error: $err" + } + } elseif { [eof $state(sock)] } { + Eof $token + } elseif { [fblocked $state(sock)] } { + ${log}::debug "Event blocked" + } else { + ${log}::critical "Event error: this can't happen!" + Finish $token "Event error: this can't happen!" + } +} + +# ------------------------------------------------------------------------- + +# Description: +# file event handler for udp sockets. +proc ::dns::UdpEvent {token} { + # FRINK: nocheck + variable $token + upvar 0 $token state + set s $state(sock) + + set payload [$state(sock) recvfrom 1500] + append state(reply) $payload + + binary scan $payload S id + set id [expr {$id & 0xFFFF}] + if {$id != [expr {$state(id) & 0xFFFF}]} { + ${log}::error "received packed with incorrect id" + } + # bug #1158037 - doing this causes problems > 65535 requests! + #Receive [namespace current]::$id + Receive $token +} + +# ------------------------------------------------------------------------- + +proc ::dns::Flags {token {varname {}}} { + # FRINK: nocheck + variable $token + upvar 0 $token state + + if {$varname != {}} { + upvar $varname flags + } + + array set flags {query 0 opcode 0 authoritative 0 errorcode 0 + truncated 0 recursion_desired 0 recursion_allowed 0} + + binary scan $state(reply) SSSSSS mid hdr nQD nAN nNS nAR + + set flags(response) [expr {($hdr & 0x8000) >> 15}] + set flags(opcode) [expr {($hdr & 0x7800) >> 11}] + set flags(authoritative) [expr {($hdr & 0x0400) >> 10}] + set flags(truncated) [expr {($hdr & 0x0200) >> 9}] + set flags(recursion_desired) [expr {($hdr & 0x0100) >> 8}] + set flags(recursion_allowed) [expr {($hdr & 0x0080) >> 7}] + set flags(errorcode) [expr {($hdr & 0x000F)}] + + return [array get flags] +} + +# ------------------------------------------------------------------------- + +# Description: +# Decode a DNS packet (either query or response). +# +proc ::dns::Decode {token args} { + variable log + # FRINK: nocheck + variable $token + upvar 0 $token state + + array set opts {-rdata 0 -query 0} + while {[string match -* [set option [lindex $args 0]]]} { + switch -exact -- $option { + -rdata { set opts(-rdata) 1 } + -query { set opts(-query) 1 } + default { + return -code error "bad option \"$option\":\ + must be -rdata" + } + } + Pop args + } + + if {$opts(-query)} { + binary scan $state(request) SSSSSSc* mid hdr nQD nAN nNS nAR data + } else { + binary scan $state(reply) SSSSSSc* mid hdr nQD nAN nNS nAR data + } + + set fResponse [expr {($hdr & 0x8000) >> 15}] + set fOpcode [expr {($hdr & 0x7800) >> 11}] + set fAuthoritative [expr {($hdr & 0x0400) >> 10}] + set fTrunc [expr {($hdr & 0x0200) >> 9}] + set fRecurse [expr {($hdr & 0x0100) >> 8}] + set fCanRecurse [expr {($hdr & 0x0080) >> 7}] + set fRCode [expr {($hdr & 0x000F)}] + set flags "" + + if {$fResponse} {set flags "QR"} else {set flags "Q"} + set opcodes [list QUERY IQUERY STATUS] + lappend flags [lindex $opcodes $fOpcode] + if {$fAuthoritative} {lappend flags "AA"} + if {$fTrunc} {lappend flags "TC"} + if {$fRecurse} {lappend flags "RD"} + if {$fCanRecurse} {lappend flags "RA"} + + set info "ID: $mid\ + Fl: [format 0x%02X [expr {$hdr & 0xFFFF}]] ($flags)\ + NQ: $nQD\ + NA: $nAN\ + NS: $nNS\ + AR: $nAR" + #${log}::debug $info + + set ndx 12 + set r {} + set QD [ReadQuestion $nQD $state(reply) ndx] + lappend r QD $QD + set AN [ReadAnswer $nAN $state(reply) ndx $opts(-rdata)] + lappend r AN $AN + set NS [ReadAnswer $nNS $state(reply) ndx $opts(-rdata)] + lappend r NS $NS + set AR [ReadAnswer $nAR $state(reply) ndx $opts(-rdata)] + lappend r AR $AR + return $r +} + +# ------------------------------------------------------------------------- + +proc ::dns::Expand {data} { + set r {} + binary scan $data c* d + foreach c $d { + lappend r [expr {$c & 0xFF}] + } + return $r +} + + +# ------------------------------------------------------------------------- +# Description: +# Pop the nth element off a list. Used in options processing. +# +proc ::dns::Pop {varname {nth 0}} { + upvar $varname args + set r [lindex $args $nth] + set args [lreplace $args $nth $nth] + return $r +} + +# ------------------------------------------------------------------------- + +proc ::dns::KeyOf {arrayname value {default {}}} { + upvar $arrayname array + set lst [array get array] + set ndx [lsearch -exact $lst $value] + if {$ndx != -1} { + incr ndx -1 + set r [lindex $lst $ndx] + } else { + set r $default + } + return $r +} + + +# ------------------------------------------------------------------------- +# Read the question section from a DNS message. This always starts at index +# 12 of a message but may be of variable length. +# +proc ::dns::ReadQuestion {nitems data indexvar} { + variable types + variable classes + upvar $indexvar index + set result {} + + for {set cn 0} {$cn < $nitems} {incr cn} { + set r {} + lappend r name [ReadName data $index offset] + incr index $offset + + # Read off QTYPE and QCLASS for this query. + set ndx $index + incr index 3 + binary scan [string range $data $ndx $index] SS qtype qclass + set qtype [expr {$qtype & 0xFFFF}] + set qclass [expr {$qclass & 0xFFFF}] + incr index + lappend r type [KeyOf types $qtype $qtype] \ + class [KeyOf classes $qclass $qclass] + lappend result $r + } + return $result +} + +# ------------------------------------------------------------------------- + +# Read an answer section from a DNS message. +# +proc ::dns::ReadAnswer {nitems data indexvar {raw 0}} { + variable types + variable classes + upvar $indexvar index + set result {} + + for {set cn 0} {$cn < $nitems} {incr cn} { + set r {} + lappend r name [ReadName data $index offset] + incr index $offset + + # Read off TYPE, CLASS, TTL and RDLENGTH + binary scan [string range $data $index end] SSIS type class ttl rdlength + + set type [expr {$type & 0xFFFF}] + set type [KeyOf types $type $type] + + set class [expr {$class & 0xFFFF}] + set class [KeyOf classes $class $class] + + set ttl [expr {$ttl & 0xFFFFFFFF}] + set rdlength [expr {$rdlength & 0xFFFF}] + incr index 10 + set rdata [string range $data $index [expr {$index + $rdlength - 1}]] + + if {! $raw} { + switch -- $type { + A { + set rdata [join [Expand $rdata] .] + } + AAAA { + set rdata [ip::contract [ip::ToString $rdata]] + } + NS - CNAME - PTR { + set rdata [ReadName data $index off] + } + MX { + binary scan $rdata S preference + set exchange [ReadName data [expr {$index + 2}] off] + set rdata [list $preference $exchange] + } + SRV { + set x $index + set rdata [list priority [ReadUShort data $x off]] + incr x $off + lappend rdata weight [ReadUShort data $x off] + incr x $off + lappend rdata port [ReadUShort data $x off] + incr x $off + lappend rdata target [ReadName data $x off] + incr x $off + } + TXT { + set rdata [ReadString data $index $rdlength] + } + SOA { + set x $index + set rdata [list MNAME [ReadName data $x off]] + incr x $off + lappend rdata RNAME [ReadName data $x off] + incr x $off + lappend rdata SERIAL [ReadULong data $x off] + incr x $off + lappend rdata REFRESH [ReadLong data $x off] + incr x $off + lappend rdata RETRY [ReadLong data $x off] + incr x $off + lappend rdata EXPIRE [ReadLong data $x off] + incr x $off + lappend rdata MINIMUM [ReadULong data $x off] + incr x $off + } + } + } + + incr index $rdlength + lappend r type $type class $class ttl $ttl rdlength $rdlength rdata $rdata + lappend result $r + } + return $result +} + + +# Read a 32bit integer from a DNS packet. These are compatible with +# the ReadName proc. Additionally - ReadULong takes measures to ensure +# the unsignedness of the value obtained. +# +proc ::dns::ReadLong {datavar index usedvar} { + upvar $datavar data + upvar $usedvar used + set r {} + set used 0 + if {[binary scan $data @${index}I r]} { + set used 4 + } + return $r +} + +proc ::dns::ReadULong {datavar index usedvar} { + upvar $datavar data + upvar $usedvar used + set r {} + set used 0 + if {[binary scan $data @${index}cccc b1 b2 b3 b4]} { + set used 4 + # This gets us an unsigned value. + set r [expr {($b4 & 0xFF) + (($b3 & 0xFF) << 8) + + (($b2 & 0xFF) << 16) + ($b1 << 24)}] + } + return $r +} + +proc ::dns::ReadUShort {datavar index usedvar} { + upvar $datavar data + upvar $usedvar used + set r {} + set used 0 + if {[binary scan [string range $data $index end] cc b1 b2]} { + set used 2 + # This gets us an unsigned value. + set r [expr {(($b2 & 0xff) + (($b1 & 0xff) << 8)) & 0xffff}] + } + return $r +} + +# Read off the NAME or QNAME element. This reads off each label in turn, +# dereferencing pointer labels until we have finished. The length of data +# used is passed back using the usedvar variable. +# +proc ::dns::ReadName {datavar index usedvar} { + upvar $datavar data + upvar $usedvar used + set startindex $index + + set r {} + set len 1 + set max [string length $data] + + while {$len != 0 && $index < $max} { + # Read the label length (and preread the pointer offset) + binary scan [string range $data $index end] cc len lenb + set len [expr {$len & 0xFF}] + incr index + + if {$len != 0} { + if {[expr {$len & 0xc0}]} { + binary scan [binary format cc [expr {$len & 0x3f}] [expr {$lenb & 0xff}]] S offset + incr index + lappend r [ReadName data $offset junk] + set len 0 + } else { + lappend r [string range $data $index [expr {$index + $len - 1}]] + incr index $len + } + } + } + set used [expr {$index - $startindex}] + return [join $r .] +} + +proc ::dns::ReadString {datavar index length} { + upvar $datavar data + set startindex $index + + set r {} + set max [expr {$index + $length}] + + while {$index < $max} { + binary scan [string range $data $index end] c len + set len [expr {$len & 0xFF}] + incr index + + if {$len != 0} { + append r [string range $data $index [expr {$index + $len - 1}]] + incr index $len + } + } + return $r +} + +# ------------------------------------------------------------------------- + + +package provide dns $dns::version + +# ------------------------------------------------------------------------- +# Local Variables: +# indent-tabs-mode: nil +# End: diff --git a/debuggers/openocd/jimtcl/examples/dnstest.tcl b/debuggers/openocd/jimtcl/examples/dnstest.tcl new file mode 100644 index 00000000..905ecb81 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/dnstest.tcl @@ -0,0 +1,22 @@ +lappend auto_path [pwd] +package require dns + +# Use google's DNS +dns::configure -nameserver 8.8.8.8 + +puts "Resolve with udp" +set tok [dns::resolve www.tcl.tk] +puts status=[dns::status $tok] +puts address=[dns::address $tok] +puts names=[dns::name $tok] +dns::cleanup $tok + +# Now with tcp +dns::configure -protocol tcp + +puts "Resolve with tcp" +set tok [dns::resolve www.google.com] +puts status=[dns::status $tok] +puts address=[dns::address $tok] +puts names=[dns::name $tok] +dns::cleanup $tok diff --git a/debuggers/openocd/jimtcl/examples/jtclsh.tcl b/debuggers/openocd/jimtcl/examples/jtclsh.tcl new file mode 100644 index 00000000..dc92bcae --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/jtclsh.tcl @@ -0,0 +1,36 @@ +# Simple example of how the history extension +# can be used to provide line editing and history + +# Build jimsh with the history extension and enable line editing (the default) +# ./configure --with-ext=history + +package require history + +set histfile [env HOME]/.jtclsh +history load $histfile +while 1 { + if {[history getline "jim> " cmd] < 0} { + break + } + if {$cmd eq "h"} { + history show + continue + } + # Don't bother adding single char commands to the history + if {[string length $cmd] > 1} { + history add $cmd + history save $histfile + } + # jimsh also does: + # - check for a complete command: [info complete] + # - handle other non-error return codes and changes the prompt: [info returncodes] + # - displays the complete error message: [errorInfo] + try { + set result [eval $cmd] + if {$result ne {}} { + puts $result + } + } on error msg { + puts $msg + } +} diff --git a/debuggers/openocd/jimtcl/examples/metakit.tcl b/debuggers/openocd/jimtcl/examples/metakit.tcl new file mode 100644 index 00000000..0d544d1a --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/metakit.tcl @@ -0,0 +1,112 @@ +package require mk + +# These will become subcommands of every view handle + +# Looping using cursors +proc {mk.view each} {view arrayVar script} { + upvar 1 $arrayVar array + for {set cur $view!0} {[cursor valid $cur]} {cursor incr cur} { + set array [cursor get $cur] + uplevel 1 $script + } +} + +# Shortcuts to avoid cursors for one-time operations +proc {mk.view set} {view pos args} { + tailcall cursor set $view!$pos {*}$args +} +proc {mk.view append} {view args} { + tailcall cursor set $view!end+1 {*}$args +} +proc {mk.view insert} {view pos args} { + # Note that this only inserts fresh rows and doesn't set any data + tailcall cursor insert $view!$pos {*}$args +} + +# Dump a view to stdout +proc {mk.view dump} {view} { + $view each row {puts " $row"} +} + +# ----------------------------------------------------------------------------- + +# Open an in-memory database +set db [storage] + +# Specify the view structure, creating new views and restructuring existing +# ones as necessary +$db structure firstview {key string first string} +$db structure secondview {key string second string} + +# Open them. +[$db view firstview] as fstview +# Or equivalently (using pipeline notation) +$db view secondview | as sndview + +# Use the helpers defined above to populate the first view +$fstview set 0 key foo first bar +$fstview append key hello first world +$fstview insert 0 +$fstview set 0 key metakit first example + +# Or use cursors directly. A end-X/end+X cursor moves automatically when +# the view size changes. +set cur $sndview!end+1 +cursor set $cur key foo second baz +cursor set $cur key hello second goodbye +cursor set $cur key silly second examples + +puts "First view:" +$fstview dump +puts "Second view:" +$sndview dump + +puts "\nNow trying view operations. Note that all the binary operations" +puts "are left-biased when it comes to conflicting property values.\n" + +puts "Join on key:" ;# Common subset of the two outer joins below +$fstview join $sndview key | dump +puts "Outer join on key:" ;# Will yield more rows than an inner join +$fstview join $sndview -outer key | dump +puts "Outer join on key, in reverse order:" +$sndview join $fstview -outer key | dump + +puts "Cartesian product:" +$fstview product $sndview | dump + +puts "Pairing:" +$fstview pair $sndview | dump +puts "Pairing, in reverse order:" +$sndview pair $fstview | dump + +puts "Complex pipeline (fetch rows 3,5,.. from the cartesian product and sort" +puts "them on the 'first' property):" +$fstview product $sndview | range 3 end 2 | sort first | dump +# Slice step defaults to 1. Sorting may be performed on several properties at +# a time, prepending a "-" (minus sign) will cause the sort order to be reversed. + +puts "Another one (fetch the unique key values from the cartesian product):" +$fstview product $sndview | project key | unique | dump +# Use "without" to remove certain properties. + +puts "Keys in the cartesian product not in the reverse pairing:" +[$fstview product $sndview | project key | unique] minus [$sndview pair $fstview | unique] | dump +# Union "union", intersection "intersect" and symmetric difference "different" +# are also available. They all work only if the rows are unique. + +puts "Create a subview:" +$fstview product $sndview | group subv key | as complexview | dump +# Not so informative as subviews are not displayed properly. Several grouping +# properties may be specified. +puts "Get its values for row #0:" +cursor get $complexview!0 subv | dump +puts "And flatten it back:" +$complexview flatten subv | dump + +puts "Remove a row:" +cursor remove $sndview!1 +$sndview dump +# Several rows may be removed at once by specifying a row count +puts "Clear the view:" +$sndview resize 0 +$sndview dump diff --git a/debuggers/openocd/jimtcl/examples/ootest.tcl b/debuggers/openocd/jimtcl/examples/ootest.tcl new file mode 100644 index 00000000..d3d48c3c --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/ootest.tcl @@ -0,0 +1,139 @@ +package require oo + +# Create a class, the usual bank account, with two instance variables: +class Account { + balance 0 + name "Unknown" +} + +# We have some class methods predefined +# Note we can call (e.g.) either Account.methods or 'Account methods' +puts "---- class Account ----" +puts "Account vars=[Account vars]" +puts "Account methods=[Account methods]" +puts "" + +# Now flesh out the class with some methods +# Could use 'Account method' here instead +Account method deposit {amount} { + set balance [+ $balance $amount] +} +Account method see {} { + set balance +} +Account method withdraw {amount} { + if {$amount > $balance} {error "Sorry $name, can only withdraw $balance"} + set balance [- $balance $amount] +} +Account method describe {} { + puts "I am object $self of class [$self classname]" + puts "My 'see' method returns [$self see]" + puts "My variables are:" + foreach i [$self vars] { + puts " $i=[set $i]" + } +} + +# Now an instance, initialisition some fields +set a [Account new {name "Bob Smith"}] + +puts "---- object Account ----" +# We can use class methods on the instance too +puts a.vars=[$a vars] +puts a.classname=[$a classname] + +# Now object methods +$a deposit 100 +puts "deposit 100 -> [$a see]" + +$a withdraw 40 +puts "withdraw 40 -> [$a see]" + +catch {$a withdraw 1000} res +puts "withdraw 1000 -> $res\n" + +# Tell me something about the object +$a describe +puts "" + +# Now create a new subclass +class CreditAccount Account { + limit -1000 + balance -20 +} +# Override the 'withdraw' method to allow overdrawing +CreditAccount method withdraw {amount} { + if {$balance - $amount < $limit} {error "Sorry $name, that would exceed your credit limit of [expr -$limit]"} + set balance [- $balance $amount] +} +# Override the 'describe' method, but invoke the baseclass method first +CreditAccount method describe {} { + # First invoke the base class 'describe' + super describe + if {$balance < 0} { + puts "*** Account is in debit" + } +} + +puts "---- class CreditAccount ----" +puts "CreditAccount vars=[CreditAccount vars]" +puts "CreditAccount methods=[CreditAccount methods]" +puts "" + +puts "---- object CreditAccount ----" +set b [CreditAccount new {name "John White"}] + +puts b.vars=[$b vars] +puts b.classname=[$b classname] + +puts "initial balance -> [$b see]" +$b deposit 100 +puts "deposit 100 -> [$b see]" + +$b withdraw 40 +puts "withdraw 40 -> [$b see]" + +$b withdraw 1000 +puts "withdraw 1000 -> [$b see]" +puts "" + +# Tell me something about the object +$b describe +puts "" + +# 'eval' is similar to 'dict with' for an object, except it operates +# in it's own scope. A list of variables can be imported into the object scope. +# It is useful for ad-hoc operations for which it is not worth defining a method. +set total 0 +$a eval total { incr total $balance } +incr total [$b get balance] +puts "Total of accounts [$a get name] and [$b eval {return "$name (Credit Limit: $limit)"}] is: $total" + +# Can we find all objects in the system? +# Almost. We can't really distinguish those which aren't real classes. +# This will get all references which aren't simple lambdas. +puts "---- All objects ----" +Account new {name "Terry Green" balance 20} +set x [Account] +lambda {} {dummy} +ref blah blah + +foreach r [info references] { + if {[getref $r] ne {}} { + try { + $r eval { + puts [format "Found %14s: Owner: %14s, Balance: %+5d, in object %s" [$self classname] $name $balance $self] + } + } on error msg { + puts "Not an object: $r" + } + } +} +unset r + +# And goodbye +$a destroy + +# Let the garbage collection take care of this one +unset b +collect diff --git a/debuggers/openocd/jimtcl/examples/parray.tcl b/debuggers/openocd/jimtcl/examples/parray.tcl new file mode 100644 index 00000000..8ac5d3da --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/parray.tcl @@ -0,0 +1,17 @@ +# Example of using the 'putter' function to redirect parray output + +set a {1 one 2 two 3 three} + +# Use 'curry' to create a single command from two words +stderr puts "curry" +parray a * [curry stderr puts] + +# Same thing, but an alias instead +stderr puts "\nalias" +alias stderr_puts stderr puts +parray a * stderr_puts + +# Now use a lambda to accumulate the results in a buffer +stderr puts "\nlamba" +parray a * [lambda {msg} {lappend ::lines $msg}] +stderr puts [join $lines \n] diff --git a/debuggers/openocd/jimtcl/examples/pipe.tcl b/debuggers/openocd/jimtcl/examples/pipe.tcl new file mode 100644 index 00000000..6b10dbdd --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/pipe.tcl @@ -0,0 +1,16 @@ +lassign [socket pipe] r w + +# Note, once the exec has the fh (via dup), close it +# so that the pipe data is accessible +exec ps aux >@$w & +$w close + +$r readable { + puts [$r gets] + if {[eof $r]} { + $r close + set done 1 + } +} + +vwait done diff --git a/debuggers/openocd/jimtcl/examples/popen.tcl b/debuggers/openocd/jimtcl/examples/popen.tcl new file mode 100644 index 00000000..f330fc9d --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/popen.tcl @@ -0,0 +1,20 @@ +# Internally, open "|..." calls out to popen from tclcompat.tcl +# +# This code is compatible with Tcl + +# Write to a pipe +set f [open |[list cat | sed -e "s/line/This is line/" >temp.out] w] +puts "Creating temp.out with pids: [pid $f]" +foreach n {1 2 3 4 5} { + puts $f "line $n" +} +close $f + +# Read from a pipe +set f [open "|cat temp.out"] +puts "Reading temp.out with pids: [pid $f]" +while {[gets $f buf] >= 0} { + puts $buf +} +close $f +file delete temp.out diff --git a/debuggers/openocd/jimtcl/examples/sqlite3test.tcl b/debuggers/openocd/jimtcl/examples/sqlite3test.tcl new file mode 100644 index 00000000..982dd8af --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/sqlite3test.tcl @@ -0,0 +1,10 @@ +package require sqlite3 + +set db [sqlite3.open :memory:] +$db query {CREATE TABLE plays (id, author, title)} +$db query {INSERT INTO plays (id, author, title) VALUES (1, 'Goethe', 'Faust');} +$db query {INSERT INTO plays (id, author, title) VALUES (2, 'Shakespeare', 'Hamlet');} +$db query {INSERT INTO plays (id, author, title) VALUES (3, 'Sophocles', 'Oedipus Rex');} +set res [$db query "SELECT * FROM plays"] +$db close +foreach r $res {puts $r(author)} diff --git a/debuggers/openocd/jimtcl/examples/tcp.client b/debuggers/openocd/jimtcl/examples/tcp.client new file mode 100644 index 00000000..ed8582b8 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/tcp.client @@ -0,0 +1,9 @@ +# Example of sending via a connected tcp socket + +set s [socket stream 127.0.0.1:20000] + +foreach i [range 1 20] { + $s puts "1 << $i" + + puts [$s gets] +} diff --git a/debuggers/openocd/jimtcl/examples/tcp.server b/debuggers/openocd/jimtcl/examples/tcp.server new file mode 100644 index 00000000..1240f2ba --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/tcp.server @@ -0,0 +1,39 @@ +# Example of a udp server which sends a response + +# Listen on port 20000. No host specified means 0.0.0.0 +set s [socket stream.server 20000] + +$s readable { + # Clean up children + os.wait -nohang 0 + set sock [$s accept] + + # Make this server forking so we can accept multiple + # simultaneous connections + if {[os.fork] == 0} { + $s close + + $sock buffering line + + # Get the request (max 80 chars) - need the source address + while {[$sock gets buf] >= 0} { + set buf [string trim $buf] + puts -nonewline "read '$buf'" + + try { + set result "$buf = [expr $buf]" + } on error {msg} { + set result "Error: $buf => $msg" + } + + puts ", sending '$result'" + + # Send the result back to where it came from + $sock puts $result + } + } + + $sock close +} + +vwait done diff --git a/debuggers/openocd/jimtcl/examples/timedread.tcl b/debuggers/openocd/jimtcl/examples/timedread.tcl new file mode 100644 index 00000000..cb4c9aa1 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/timedread.tcl @@ -0,0 +1,19 @@ +# Tests that SIGALRM can interrupt read +set f [open "/dev/urandom" r] + +set count 0 +set error NONE + +signal handle SIGALRM +catch -signal { + alarm 0.5 + while {1} { + incr count [string bytelength [read $f 100]] + } + alarm 0 + signal default SIGALRM +} error + +puts "Read $count bytes in 0.5 seconds: Got $error" + +$f close diff --git a/debuggers/openocd/jimtcl/examples/udp.client b/debuggers/openocd/jimtcl/examples/udp.client new file mode 100644 index 00000000..9e9ac149 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/udp.client @@ -0,0 +1,28 @@ +# Example of sending from an unconnected socket + +set s [socket dgram] + +foreach i [range 1 5] { + # Specify the address and port with sendto + $s sendto "$i + $i + 10" 127.0.0.1:20000 + + # Receive the response - max length of 100 + puts [$s recvfrom 100] +} + +$s close + +# Now sending via a connected udp socket + +set s [socket dgram 127.0.0.1:20000] +$s buffering none + +foreach i [range 5 10] { + # Socket is connected, so can just use puts here + # No need to flush because we set 'buffering none' above. + $s puts -nonewline "$i * $i" + #$s flush + + # Receive the response - max length of 100 + puts [$s recvfrom 100] +} diff --git a/debuggers/openocd/jimtcl/examples/udp.server b/debuggers/openocd/jimtcl/examples/udp.server new file mode 100644 index 00000000..03f41cde --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/udp.server @@ -0,0 +1,25 @@ +# Example of a udp server which sends a response + +# Listen on port 20000. No host specified means 0.0.0.0 +set s [socket dgram.server 20000] + +# For each request... +$s readable { + # Get the request (max 80 chars) - need the source address + set buf [$s recvfrom 80 addr] + + puts -nonewline "read '$buf' from $addr" + + try { + set result "$buf = [expr $buf]" + } on error {msg} { + set result "Error: $buf => $msg" + } + + puts ", sending '$result' to $addr" + + # Send the result back to where it came from + $s sendto $result $addr +} + +vwait done diff --git a/debuggers/openocd/jimtcl/examples/udp2.client b/debuggers/openocd/jimtcl/examples/udp2.client new file mode 100644 index 00000000..776dc2c7 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/udp2.client @@ -0,0 +1,13 @@ +# Example of sending via a connected udp socket + +set s [socket dgram 127.0.0.1:20000] + +foreach i [range 1 20] { + # Socket is connected, so can just use puts here + # But remember to flush to ensure that each message is separate + $s puts -nonewline "$i * $i" + $s flush + + # Receive the response - max length of 100 + puts [$s recvfrom 100] +} diff --git a/debuggers/openocd/jimtcl/examples/udp6.client b/debuggers/openocd/jimtcl/examples/udp6.client new file mode 100644 index 00000000..f3e680e8 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/udp6.client @@ -0,0 +1,27 @@ +# Example of sending from an unconnected ipv6 socket + +set s [socket -ipv6 dgram] + +foreach i [range 1 5] { + # Specify the address and port with sendto + $s sendto "$i + $i + 10" {[::1]:20000} + + # Receive the response - max length of 100 + puts [$s recvfrom 100] +} + +$s close + +# Now sending via a connected udp socket + +set s [socket -ipv6 dgram {[::1]:20000}] + +foreach i [range 5 10] { + # Socket is connected, so can just use puts here + # But remember to flush to ensure that each message is separate + $s puts -nonewline "$i * $i" + $s flush + + # Receive the response - max length of 100 + puts [$s recvfrom 100] +} diff --git a/debuggers/openocd/jimtcl/examples/udp6.server b/debuggers/openocd/jimtcl/examples/udp6.server new file mode 100644 index 00000000..da9b4bf8 --- /dev/null +++ b/debuggers/openocd/jimtcl/examples/udp6.server @@ -0,0 +1,26 @@ +# Example of a udp server listening on ipv6 which sends a response +# Note that on many hosts, this will also respond to ipv4 requests too + +# Listen on port 20000. +set s [socket -ipv6 dgram.server {[::]:20000}] + +# For each request... +$s readable { + # Get the request (max 80 chars) - need the source address + set buf [$s recvfrom 80 addr] + + puts -nonewline "read '$buf' from $addr" + + try { + set result "$buf = [expr $buf]" + } on error {msg} { + set result "Error: $buf => $msg" + } + + puts ", sending '$result'" + + # Send the result back to where it came from + $s sendto $result $addr +} + +vwait done diff --git a/debuggers/openocd/jimtcl/freebsd/andrew.txt b/debuggers/openocd/jimtcl/freebsd/andrew.txt new file mode 100644 index 00000000..8dbfcfc1 --- /dev/null +++ b/debuggers/openocd/jimtcl/freebsd/andrew.txt @@ -0,0 +1,65 @@ +Delivered-To: oyvindharboe@gmail.com +Received: by 10.100.7.20 with SMTP id 20cs86142ang; + Wed, 16 Jul 2008 00:45:59 -0700 (PDT) +Received: by 10.142.238.12 with SMTP id l12mr5009290wfh.204.1216194359186; + Wed, 16 Jul 2008 00:45:59 -0700 (PDT) +Return-Path: +Received: from cpanel5.proisp.no (cpanel5.proisp.no [209.85.100.29]) + by mx.google.com with ESMTP id 31si6762736wff.16.2008.07.16.00.45.57; + Wed, 16 Jul 2008 00:45:59 -0700 (PDT) +Received-SPF: fail (google.com: domain of andrew@lunn.ch does not designate 209.85.100.29 as permitted sender) client-ip=209.85.100.29; +Authentication-Results: mx.google.com; spf=hardfail (google.com: domain of andrew@lunn.ch does not designate 209.85.100.29 as permitted sender) smtp.mail=andrew@lunn.ch +Received: from londo.lunn.ch ([80.238.139.98]:48839 ident=mail) + by cpanel5.proisp.no with esmtp (Exim 4.69) + (envelope-from ) + id 1KJ1ht-00085G-Ng + for oyvind.harboe@zylin.com; Wed, 16 Jul 2008 09:45:52 +0200 +Received: from lunn by londo.lunn.ch with local (Exim 3.36 #1 (Debian)) + id 1KJ1hq-0005ss-00; Wed, 16 Jul 2008 09:45:46 +0200 +Date: Wed, 16 Jul 2008 09:45:46 +0200 +From: Andrew Lunn +To: ?yvind Harboe +Cc: jim-devel@lists.berlios.de, antirez@gmail.com, patthoyts@users.sf.net, + andrew@lunn.ch, openocd@duaneellis.com, uklein@klein-messgeraete.de, + ml-jim@qiao.in-berlin.de +Subject: Re: Change Jim Tcl license +Message-ID: <20080716074546.GC24771@lunn.ch> +References: +MIME-Version: 1.0 +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline +In-Reply-To: +User-Agent: Mutt/1.5.18 (2008-05-17) +X-Spam-Status: No, score=-2.6 +X-Spam-Score: -25 +X-Spam-Bar: -- +X-Spam-Flag: NO +X-AntiAbuse: This header was added to track abuse, please include it with any abuse report +X-AntiAbuse: Primary Hostname - cpanel5.proisp.no +X-AntiAbuse: Original Domain - zylin.com +X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] +X-AntiAbuse: Sender Address Domain - lunn.ch +X-Source: +X-Source-Args: +X-Source-Dir: + +On Wed, Jul 16, 2008 at 09:34:14AM +0200, ?yvind Harboe wrote: +> Hi all, +> +> I'm currently the maintainer of Jim Tcl trying as best as I can +> to fill Salvatore's shoes. +> +> Short story: +> +> If you have contributed to Jim Tcl, please reply to this email +> that you agree that we can switch Jim Tcl to a FreeBSD license. + +I've no problems with this, but my contributions are very minimal. + +Do you want this written down, in blood, to keep the lawyers happy? + +At a minimum i think everybody's agreement needs to be posted to a +public email list which is publicly archived etc so there is a +record of the agreement... + + Andrew diff --git a/debuggers/openocd/jimtcl/freebsd/clemens.txt b/debuggers/openocd/jimtcl/freebsd/clemens.txt new file mode 100644 index 00000000..806f7ed9 --- /dev/null +++ b/debuggers/openocd/jimtcl/freebsd/clemens.txt @@ -0,0 +1,87 @@ + +Delivered-To: oyvindharboe@gmail.com +Received: by 10.100.7.20 with SMTP id 20cs114742ang; + Wed, 16 Jul 2008 08:58:18 -0700 (PDT) +Received: by 10.114.137.2 with SMTP id k2mr325372wad.95.1216223896673; + Wed, 16 Jul 2008 08:58:16 -0700 (PDT) +Return-Path: +Received: from cpanel5.proisp.no (cpanel5.proisp.no [209.85.100.29]) + by mx.google.com with ESMTP id m28si10145125waf.16.2008.07.16.08.58.15; + Wed, 16 Jul 2008 08:58:16 -0700 (PDT) +Received-SPF: neutral (google.com: 209.85.100.29 is neither permitted nor denied by best guess record for domain of ml-jim@qiao.in-berlin.de) client-ip=209.85.100.29; +Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.100.29 is neither permitted nor denied by best guess record for domain of ml-jim@qiao.in-berlin.de) smtp.mail=ml-jim@qiao.in-berlin.de +Received: from gnu.in-berlin.de ([192.109.42.4]:58401) + by cpanel5.proisp.no with esmtps (TLSv1:AES256-SHA:256) + (Exim 4.69) + (envelope-from ) + id 1KJ9OG-0006Hf-8y + for oyvind.harboe@zylin.com; Wed, 16 Jul 2008 17:58:07 +0200 +X-Envelope-From: ml-jim@qiao.in-berlin.de +X-Envelope-To: +Received: from qiao.in-berlin.de (qiao.in-berlin.de [217.197.85.72]) + by gnu.in-berlin.de (8.13.8/8.13.8/Debian-2) with ESMTP id m6GFvxio009504 + for ; Wed, 16 Jul 2008 17:58:02 +0200 +Received: from [192.168.0.10] ([::ffff:192.168.0.10]) + by qiao.in-berlin.de with esmtp; Wed, 16 Jul 2008 18:00:04 +0200 + id 0001D68D.487E1B04.000042E7 +In-Reply-To: +References: +Mime-Version: 1.0 (Apple Message framework v753.1) +Content-Type: text/plain; charset=ISO-8859-1; delsp=yes; format=flowed +Message-Id: +Cc: jim-devel@lists.berlios.de, antirez@gmail.com, patthoyts@users.sf.net, + andrew@lunn.ch, openocd@duaneellis.com, uklein@klein-messgeraete.de +Content-Transfer-Encoding: quoted-printable +From: Clemens Hintze +Subject: Re: Change Jim Tcl license +Date: Wed, 16 Jul 2008 17:58:14 +0200 +To: "=?ISO-8859-1?Q?\"=D8yvind_Harboe\"?=" +X-Mailer: Apple Mail (2.753.1) +X-Spam-Score: (0.101) BAYES_50,RDNS_NONE +X-Scanned-By: MIMEDefang_at_IN-Berlin_e.V. on 192.109.42.4 +X-Spam-Status: No, score=-2.6 +X-Spam-Score: -25 +X-Spam-Bar: -- +X-Spam-Flag: NO +X-AntiAbuse: This header was added to track abuse, please include it with any abuse report +X-AntiAbuse: Primary Hostname - cpanel5.proisp.no +X-AntiAbuse: Original Domain - zylin.com +X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] +X-AntiAbuse: Sender Address Domain - qiao.in-berlin.de +X-Source: +X-Source-Args: +X-Source-Dir: + + +Am 16.07.2008 um 09:34 schrieb =D8yvind Harboe: + +> Hi all, + +Hi =D8yvind, + +(...) + +> If you have contributed to Jim Tcl, please reply to this email +> that you agree that we can switch Jim Tcl to a FreeBSD license. +> +> Once I have a record of all contributors agreeing to switch +> to a FreeBSD license, I'll update CVS. + +No problem with me: I agree to permit my contributions to the Jim =20 +project to be +re-licensed under a BSD compatible license. + +(...) + +> Please let me know if any of the emails below are wrong(chi is +> missing) or the list is not complete. + +After consultation with the voices in my head, I can ensure you, =20 +'chi' is also agreeing with the re-licensing, because its me too ;-) + +Thank you very much to revive Jim! :-) + +Best regards, +Clemens Hintze. + +(...)= diff --git a/debuggers/openocd/jimtcl/freebsd/duane.txt b/debuggers/openocd/jimtcl/freebsd/duane.txt new file mode 100644 index 00000000..56f962cb --- /dev/null +++ b/debuggers/openocd/jimtcl/freebsd/duane.txt @@ -0,0 +1,65 @@ +Delivered-To: oyvindharboe@gmail.com +Received: by 10.100.7.20 with SMTP id 20cs93801ang; + Wed, 16 Jul 2008 03:40:02 -0700 (PDT) +Received: by 10.142.148.10 with SMTP id v10mr5070849wfd.317.1216204801306; + Wed, 16 Jul 2008 03:40:01 -0700 (PDT) +Return-Path: +Received: from cpanel5.proisp.no (cpanel5.proisp.no [209.85.100.29]) + by mx.google.com with ESMTP id 27si9313433wff.3.2008.07.16.03.40.00; + Wed, 16 Jul 2008 03:40:01 -0700 (PDT) +Received-SPF: neutral (google.com: 209.85.100.29 is neither permitted nor denied by best guess record for domain of openocd@duaneellis.com) client-ip=209.85.100.29; +Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.100.29 is neither permitted nor denied by best guess record for domain of openocd@duaneellis.com) smtp.mail=openocd@duaneellis.com +Received: from smtpout10-04.prod.mesa1.secureserver.net ([64.202.165.238]:48803 helo=smtpout10.prod.mesa1.secureserver.net) + by cpanel5.proisp.no with smtp (Exim 4.69) + (envelope-from ) + id 1KJ4QL-0005cq-GB + for oyvind.harboe@zylin.com; Wed, 16 Jul 2008 12:39:54 +0200 +Received: (qmail 2305 invoked from network); 16 Jul 2008 10:39:56 -0000 +Received: from unknown (68.37.53.103) + by smtpout10-04.prod.mesa1.secureserver.net (64.202.165.238) with ESMTP; 16 Jul 2008 10:39:55 -0000 +Message-ID: <487DCFEC.4010104@duaneellis.com> +Date: Wed, 16 Jul 2008 06:39:40 -0400 +From: Duane Ellis +Reply-To: openocd@duaneellis.com +User-Agent: Thunderbird 2.0.0.14 (Windows/20080421) +MIME-Version: 1.0 +To: =?ISO-8859-1?Q?=D8yvind_Harboe?= +CC: jim-devel@lists.berlios.de, antirez@gmail.com, + patthoyts@users.sf.net, andrew@lunn.ch, uklein@klein-messgeraete.de, + ml-jim@qiao.in-berlin.de +Subject: Re: Change Jim Tcl license +References: +In-Reply-To: +Content-Type: text/plain; charset=ISO-8859-1; format=flowed +Content-Transfer-Encoding: 8bit +X-Spam-Status: No, score=-2.6 +X-Spam-Score: -25 +X-Spam-Bar: -- +X-Spam-Flag: NO +X-AntiAbuse: This header was added to track abuse, please include it with any abuse report +X-AntiAbuse: Primary Hostname - cpanel5.proisp.no +X-AntiAbuse: Original Domain - zylin.com +X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] +X-AntiAbuse: Sender Address Domain - duaneellis.com +X-Source: +X-Source-Args: +X-Source-Dir: + +Oyvind Harboe wrote: +> Short story: +> +> If you have contributed to Jim Tcl, please reply to this email +> that you agree that we can switch Jim Tcl to a FreeBSD license. +> +> Once I have a record of all contributors agreeing to switch +> to a FreeBSD license, I'll update CVS. +> +> +OK - from me + + --Duane. + +-Duane. + + + diff --git a/debuggers/openocd/jimtcl/freebsd/oharboe.txt b/debuggers/openocd/jimtcl/freebsd/oharboe.txt new file mode 100644 index 00000000..af4a8e84 --- /dev/null +++ b/debuggers/openocd/jimtcl/freebsd/oharboe.txt @@ -0,0 +1,85 @@ + +Received: by 10.100.7.20 with HTTP; Wed, 16 Jul 2008 10:12:05 -0700 (PDT) +Message-ID: +Date: Wed, 16 Jul 2008 19:12:05 +0200 +From: "=?ISO-8859-1?Q?=D8yvind_Harboe?=" +Sender: oyvindharboe@gmail.com +To: jim-devel@lists.berlios.de +Subject: Re: Change Jim Tcl license +In-Reply-To: +MIME-Version: 1.0 +Content-Type: text/plain; charset=ISO-8859-1 +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline +References: +Delivered-To: oyvindharboe@gmail.com +X-Google-Sender-Auth: fc18e85532eee8f2 + +For the record: + +I would like my contributions to Jim Tcl to be under a FreeBSD license too= +. + +On Wed, Jul 16, 2008 at 9:34 AM, =D8yvind Harboe = +wrote: +> Hi all, +> +> I'm currently the maintainer of Jim Tcl trying as best as I can +> to fill Salvatore's shoes. +> +> Short story: +> +> If you have contributed to Jim Tcl, please reply to this email +> that you agree that we can switch Jim Tcl to a FreeBSD license. +> +> Once I have a record of all contributors agreeing to switch +> to a FreeBSD license, I'll update CVS. +> +> Long story: +> +> The current Jim Tcl license has a problem with GPL. If you +> link GPL code and Jim Tcl, the result is no license at all. +> +> This prevents Jim Tcl from being used in GPL projects. +> +> Lately Jim Tcl has been used with OpenOCD, a GPL project, +> and the license issue must be resolved one way or another. +> +> Upon conferring with Jonathan Larmour , who +> has kindly helped out with his knowledge on the topic, I have +> concluded that the best way to rectify this is to change the +> Jim Tcl license to a FreeBSD license. See OpenOCD mailing +> list for a discussion on this if you want details. +> +> http://www.fsf.org/licensing/licenses/index_html#FreeBSD +> +> As far as I can determine, below is the complete list of contributors. +> +> +> antirez - Salvatore Sanfilippo +> patthoyts - ?? Pat Thoyts +> oharboe - =D8yvind Harboe - soyvind.harboe@zylin.com +> chi - ?? +> Andrew Lunn +> Duane Ellis +> Uwe Klein +> Clemens Hintze ml-jim@qiao.in-berlin.de +> +> Please let me know if any of the emails below are wrong(chi is +> missing) or the list is not complete. +> +> +> -- +> =D8yvind Harboe +> http://www.zylin.com/zy1000.html +> ARM7 ARM9 XScale Cortex +> JTAG debugger and flash programmer +> + + + +--=20 +=D8yvind Harboe +http://www.zylin.com/zy1000.html +ARM7 ARM9 XScale Cortex +JTAG debugger and flash programmer diff --git a/debuggers/openocd/jimtcl/freebsd/pat.txt b/debuggers/openocd/jimtcl/freebsd/pat.txt new file mode 100644 index 00000000..988a599f --- /dev/null +++ b/debuggers/openocd/jimtcl/freebsd/pat.txt @@ -0,0 +1,84 @@ + +Delivered-To: oyvindharboe@gmail.com +Received: by 10.100.7.20 with SMTP id 20cs108097ang; + Wed, 16 Jul 2008 07:49:02 -0700 (PDT) +Received: by 10.142.232.20 with SMTP id e20mr80874wfh.138.1216219741865; + Wed, 16 Jul 2008 07:49:01 -0700 (PDT) +Return-Path: +Received: from cpanel5.proisp.no (cpanel5.proisp.no [209.85.100.29]) + by mx.google.com with ESMTP id 30si10551683wff.18.2008.07.16.07.49.01; + Wed, 16 Jul 2008 07:49:01 -0700 (PDT) +Received-SPF: neutral (google.com: 209.85.100.29 is neither permitted nor denied by best guess record for domain of patthoyts@users.sourceforge.net) client-ip=209.85.100.29; +Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.100.29 is neither permitted nor denied by best guess record for domain of patthoyts@users.sourceforge.net) smtp.mail=patthoyts@users.sourceforge.net +Received: from smtp-out4.blueyonder.co.uk ([195.188.213.7]:38596) + by cpanel5.proisp.no with esmtp (Exim 4.69) + (envelope-from ) + id 1KJ8JH-0000Vd-OT + for oyvind.harboe@zylin.com; Wed, 16 Jul 2008 16:48:52 +0200 +Received: from [172.23.170.141] (helo=anti-virus02-08) + by smtp-out4.blueyonder.co.uk with smtp (Exim 4.52) + id 1KJ8JO-0007r0-Cy; Wed, 16 Jul 2008 15:48:58 +0100 +Received: from [77.102.249.21] (helo=badger.patthoyts.tk) + by asmtp-out4.blueyonder.co.uk with esmtp (Exim 4.52) + id 1KJ8J6-0000gY-VY; Wed, 16 Jul 2008 15:48:41 +0100 +Received: by badger.patthoyts.tk (Postfix, from userid 1000) + id 810535184F; Wed, 16 Jul 2008 15:48:40 +0100 (BST) +Sender: pat@badger.patthoyts.tk +To: =?iso-8859-1?q?=D8yvind_Harboe?= +Cc: jim-devel@lists.berlios.de +Subject: Re: Change Jim Tcl license +References: +X-Face: .`d#euqz@6H{";Ysmx2IVe_7M3vA+2w1X[QLk?ZO&QRauXQL{*L'$3getx}9+zK.-KWDx3. + qrlR)76MFb`6bgoGvLpLtcQKB=X~;* +Date: 16 Jul 2008 15:48:39 +0100 +In-Reply-To: +Message-ID: <87fxq97um0.fsf@badger.patthoyts.tk> +Lines: 27 +User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=iso-8859-1 +Content-Transfer-Encoding: quoted-printable +X-Spam-Status: No, score=-2.6 +X-Spam-Score: -25 +X-Spam-Bar: -- +X-Spam-Flag: NO +X-AntiAbuse: This header was added to track abuse, please include it with any abuse report +X-AntiAbuse: Primary Hostname - cpanel5.proisp.no +X-AntiAbuse: Original Domain - zylin.com +X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] +X-AntiAbuse: Sender Address Domain - users.sourceforge.net +X-Source: +X-Source-Args: +X-Source-Dir: + +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +"=D8yvind Harboe" writes: + +>If you have contributed to Jim Tcl, please reply to this email +>that you agree that we can switch Jim Tcl to a FreeBSD license. +> +>Once I have a record of all contributors agreeing to switch +>to a FreeBSD license, I'll update CVS. + +I hereby agree to permit my contributions to the Jim project to be +re-licensed under a BSD compatible license. + +- --=20 +Pat Thoyts http://www.patthoyts.tk/ +PGP fingerprint 2C 6E 98 07 2C 59 C8 97 10 CE 11 E6 04 E0 B9 DD +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.8 (SunOS) +Comment: Processed by Mailcrypt 3.5.8 + +iQCVAwUBSH4KO2B90JXwhOSJAQKtqQP9ERwSXpbP69l4JSrunG29Rhu2F3r83zu3 +GAKpFu4HwkVnIStLQ4o3tsqG9uKrVDbRMa187eSwHmlXXIMwDlkCKNsDFxvdLDZz +kbTYDibspYSw6CjwOUSTXifK9P7ho4Q7PtsRnJ8T1IMlGJlwg39Rxd+mpEO/if3q +ExIwM1aBbAs=3D +=3Du8si +-----END PGP SIGNATURE----- + diff --git a/debuggers/openocd/jimtcl/freebsd/salvatore.txt b/debuggers/openocd/jimtcl/freebsd/salvatore.txt new file mode 100644 index 00000000..5bbf973b --- /dev/null +++ b/debuggers/openocd/jimtcl/freebsd/salvatore.txt @@ -0,0 +1,88 @@ + +Delivered-To: oyvindharboe@gmail.com +Received: by 10.100.7.20 with SMTP id 20cs113143ang; + Wed, 16 Jul 2008 08:41:11 -0700 (PDT) +Received: by 10.142.140.15 with SMTP id n15mr127048wfd.84.1216222870242; + Wed, 16 Jul 2008 08:41:10 -0700 (PDT) +Return-Path: +Received: from cpanel5.proisp.no (cpanel5.proisp.no [209.85.100.29]) + by mx.google.com with ESMTP id 29si7397124wfg.0.2008.07.16.08.41.08; + Wed, 16 Jul 2008 08:41:10 -0700 (PDT) +Received-SPF: neutral (google.com: 209.85.100.29 is neither permitted nor denied by domain of antirez@gmail.com) client-ip=209.85.100.29; +Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.100.29 is neither permitted nor denied by domain of antirez@gmail.com) smtp.mail=antirez@gmail.com; dkim=pass (test mode) header.i=@gmail.com +Received: from fg-out-1718.google.com ([72.14.220.155]:16058) + by cpanel5.proisp.no with esmtp (Exim 4.69) + (envelope-from ) + id 1KJ97g-0004yX-1W + for oyvind.harboe@zylin.com; Wed, 16 Jul 2008 17:40:59 +0200 +Received: by fg-out-1718.google.com with SMTP id l27so3985052fgb.19 + for ; Wed, 16 Jul 2008 08:40:59 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=gamma; + h=domainkey-signature:received:received:message-id:date:from:to + :subject:cc:in-reply-to:mime-version:content-type + :content-transfer-encoding:content-disposition:references; + bh=/aWDZQfgMBPqomYWZ2AUKOhhGMju+bwnSBbKL8MBonA=; + b=i0P3OKDopn/vHfa5ZrUvBjuPBnj43GMw8FOXKjxM/IfvywJParYqBS2Vmlw8RTndFg + J5wwxXf5056cZu/GbKbj8xLfylFfSInVaO7OnDutA3CeX1iU35my1DU6l9W6ILkLiT1P + Azi3L27rFQrzau/s53VU/UVELc3WckWdu1a1k= +DomainKey-Signature: a=rsa-sha1; c=nofws; + d=gmail.com; s=gamma; + h=message-id:date:from:to:subject:cc:in-reply-to:mime-version + :content-type:content-transfer-encoding:content-disposition + :references; + b=ww2MIz9svJttgS8mTRBhEX8Isveugn2hl3sMcgh0hZ1+ln8YbiysxYxZkdddewWm02 + WXsWgSgwy7MIPAUK1tNjzgkZ2l789SdrAtBCmqmRWJJI+ESTqbHMz8cqW+QRVP/A9Dfm + 8+AR85DHi7SOB0mdHtq9fsavZReUdaSIgy6F4= +Received: by 10.86.80.5 with SMTP id d5mr2284433fgb.19.1216222858224; + Wed, 16 Jul 2008 08:40:58 -0700 (PDT) +Received: by 10.86.50.18 with HTTP; Wed, 16 Jul 2008 08:40:58 -0700 (PDT) +Message-ID: +Date: Wed, 16 Jul 2008 17:40:58 +0200 +From: "Salvatore Sanfilippo" +To: "=?ISO-8859-1?Q?=D8yvind_Harboe?=" +Subject: Re: Change Jim Tcl license +Cc: jim-devel@lists.berlios.de, patthoyts@users.sf.net, andrew@lunn.ch, + openocd@duaneellis.com, uklein@klein-messgeraete.de, + ml-jim@qiao.in-berlin.de +In-Reply-To: +MIME-Version: 1.0 +Content-Type: text/plain; charset=ISO-8859-1 +Content-Transfer-Encoding: 7bit +Content-Disposition: inline +References: +X-Spam-Status: No, score=-2.6 +X-Spam-Score: -25 +X-Spam-Bar: -- +X-Spam-Flag: NO +X-AntiAbuse: This header was added to track abuse, please include it with any abuse report +X-AntiAbuse: Primary Hostname - cpanel5.proisp.no +X-AntiAbuse: Original Domain - zylin.com +X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] +X-AntiAbuse: Sender Address Domain - gmail.com +X-Source: +X-Source-Args: +X-Source-Dir: + +I agree to permit my contributions to the Jim project to be +re-licensed under a BSD compatible license. + +Since I'm currently the top contributor if it's safer from +the legal point of view I can also put a tar.gz of the current +Jim source code with a BSD "LICENSE" file on my website. + +Otherwise I can sign by hand a letter and send a digitalized +image here. + +Ciao, +Salvatore + +-- +Salvatore 'antirez' Sanfilippo +http://antirez.com + +Organizations which design systems are constrained to produce designs +which are copies of the communication structures of these +organizations. + +Conway's Law diff --git a/debuggers/openocd/jimtcl/freebsd/uwe.txt b/debuggers/openocd/jimtcl/freebsd/uwe.txt new file mode 100644 index 00000000..035ca32f --- /dev/null +++ b/debuggers/openocd/jimtcl/freebsd/uwe.txt @@ -0,0 +1,73 @@ +Delivered-To: oyvindharboe@gmail.com +Received: by 10.100.7.20 with SMTP id 20cs89014ang; + Wed, 16 Jul 2008 01:58:32 -0700 (PDT) +Received: by 10.142.125.9 with SMTP id x9mr5028534wfc.123.1216198711465; + Wed, 16 Jul 2008 01:58:31 -0700 (PDT) +Return-Path: +Received: from cpanel5.proisp.no (cpanel5.proisp.no [209.85.100.29]) + by mx.google.com with ESMTP id 30si6756166wfa.10.2008.07.16.01.58.29; + Wed, 16 Jul 2008 01:58:31 -0700 (PDT) +Received-SPF: neutral (google.com: 209.85.100.29 is neither permitted nor denied by domain of wiederling@googlemail.com) client-ip=209.85.100.29; +Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.100.29 is neither permitted nor denied by domain of wiederling@googlemail.com) smtp.mail=wiederling@googlemail.com; dkim=pass (test mode) header.i=@googlemail.com +Received: from wr-out-0506.google.com ([64.233.184.233]:51225) + by cpanel5.proisp.no with esmtp (Exim 4.69) + (envelope-from ) + id 1KJ2q7-00057b-IR + for oyvind.harboe@zylin.com; Wed, 16 Jul 2008 10:58:24 +0200 +Received: by wr-out-0506.google.com with SMTP id c8so2209154wra.27 + for ; Wed, 16 Jul 2008 01:58:25 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=googlemail.com; s=gamma; + h=domainkey-signature:received:received:message-id:date:from:to + :subject:cc:in-reply-to:mime-version:content-type + :content-transfer-encoding:content-disposition:references; + bh=VxcH0g2H5iLUo27gqJiqrlY4uVbN1NFE4skyMKqysPM=; + b=JPK53r6LQ6GqBCG1kfVYyTPuPuVhlBrbzQ8oSBwpwuwwB7t3CSv+c75jRjb/n3y8mi + gN1r6noZucK9ZpRZiHxYZpHVhYFcWbZ+ZXM75H2qIFfl4YDzfgg/Ub7CzoR2LskuBsRk + DMH2LnyAYf+Om2YAKJdkoMnGbPMDMFSrNHeIc= +DomainKey-Signature: a=rsa-sha1; c=nofws; + d=googlemail.com; s=gamma; + h=message-id:date:from:to:subject:cc:in-reply-to:mime-version + :content-type:content-transfer-encoding:content-disposition + :references; + b=VAGlxpb1YGbex/eaS0tQgWvH/lWHzgD5R/rxjshVSwZJOStwqMA1F5jNQgybQFIn1F + zWoiAV81uWMzBEGYab7SGsStWLxovcBSgi9NL+XqwAkhBdrWjgFPvpBHn5PvgOOXEhGH + EGhjrY8qp2LSxhFcW3/DvgObhBBKtY1J+qzvA= +Received: by 10.90.115.17 with SMTP id n17mr1231758agc.90.1216198705850; + Wed, 16 Jul 2008 01:58:25 -0700 (PDT) +Received: by 10.90.105.18 with HTTP; Wed, 16 Jul 2008 01:58:25 -0700 (PDT) +Message-ID: <1af31b6f0807160158o295303adh43abdd34fbe8ec99@mail.gmail.com> +Date: Wed, 16 Jul 2008 10:58:25 +0200 +From: "Uwe Klein" +To: "=?ISO-8859-1?Q?=D8yvind_Harboe?=" +Subject: Re: [Jim-devel] Change Jim Tcl license +Cc: jim-devel@lists.berlios.de, patthoyts@users.sf.net, andrew@lunn.ch, + uklein@klein-messgeraete.de, antirez@gmail.com, + openocd@duaneellis.com, ml-jim@qiao.in-berlin.de +In-Reply-To: +MIME-Version: 1.0 +Content-Type: text/plain; charset=ISO-8859-1 +Content-Transfer-Encoding: 7bit +Content-Disposition: inline +References: +X-Spam-Status: No, score=-2.6 +X-Spam-Score: -25 +X-Spam-Bar: -- +X-Spam-Flag: NO +X-AntiAbuse: This header was added to track abuse, please include it with any abuse report +X-AntiAbuse: Primary Hostname - cpanel5.proisp.no +X-AntiAbuse: Original Domain - zylin.com +X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] +X-AntiAbuse: Sender Address Domain - googlemail.com +X-Source: +X-Source-Args: +X-Source-Dir: + +> If you have contributed to Jim Tcl, please reply to this email +> that you agree that we can switch Jim Tcl to a FreeBSD license. + +For Uwe Klein + +This is OK with me. + +uwe diff --git a/debuggers/openocd/jimtcl/glob.tcl b/debuggers/openocd/jimtcl/glob.tcl new file mode 100644 index 00000000..6b1ad39a --- /dev/null +++ b/debuggers/openocd/jimtcl/glob.tcl @@ -0,0 +1,185 @@ +# Implements a mostly Tcl-compatible glob command based on readdir +# +# (c) 2008 Steve Bennett +# (c) 2012 Alexander Shpilkin +# +# See LICENCE in this directory for licensing. + +package require readdir + +# Return a list of all entries in $dir that match the pattern. +proc glob.globdir {dir pattern} { + set result {} + set files [readdir $dir] + lappend files . .. + + foreach name $files { + if {[string match $pattern $name]} { + # Starting dots match only explicitly + if {[string index $name 0] eq "." && [string index $pattern 0] ne "."} { + continue + } + lappend result $name + } + } + + return $result +} + +# Return the list of patterns resulting from expanding any braced +# alternatives inside the given pattern, prepending the unprocessed +# part of the pattern. Does _not_ handle escaped braces or commas. +proc glob.explode {pattern} { + set oldexp {} + set newexp {""} + + while 1 { + set oldexp $newexp + set newexp {} + set ob [string first \{ $pattern] + set cb [string first \} $pattern] + + if {$ob < $cb && $ob != -1} { + set mid [string range $pattern 0 $ob-1] + set subexp [lassign [glob.explode [string range $pattern $ob+1 end]] pattern] + if {$pattern eq ""} { + error "unmatched open brace in glob pattern" + } + set pattern [string range $pattern 1 end] + + foreach subs $subexp { + foreach sub [split $subs ,] { + foreach old $oldexp { + lappend newexp $old$mid$sub + } + } + } + } elseif {$cb != -1} { + set suf [string range $pattern 0 $cb-1] + set rest [string range $pattern $cb end] + break + } else { + set suf $pattern + set rest "" + break + } + } + + foreach old $oldexp { + lappend newexp $old$suf + } + linsert $newexp 0 $rest +} + +# Core glob implementation. Returns a list of files/directories inside +# base matching pattern, in {realname name} pairs. +proc glob.glob {base pattern} { + set dir [file dirname $pattern] + if {$pattern eq $dir || $pattern eq ""} { + return [list [file join $base $dir] $pattern] + } elseif {$pattern eq [file tail $pattern]} { + set dir "" + } + + # Recursively expand the parent directory + set dirlist [glob.glob $base $dir] + set pattern [file tail $pattern] + + # Collect the files/directories + set result {} + foreach {realdir dir} $dirlist { + if {![file isdir $realdir]} { + continue + } + if {[string index $dir end] ne "/" && $dir ne ""} { + append dir / + } + foreach name [glob.globdir $realdir $pattern] { + lappend result [file join $realdir $name] $dir$name + } + } + return $result +} + +# Implements the Tcl glob command +# +# Usage: glob ?-nocomplain? ?-directory dir? ?--? pattern ... +# +# Patterns use 'string match' (glob) pattern matching for each +# directory level, plus support for braced alternations. +# +# e.g. glob {te[a-e]*/*.{c,tcl}} +# +# Note: files starting with . will only be returned if matching component +# of the pattern starts with . +proc glob {args} { + set nocomplain 0 + set base "" + + set n 0 + foreach arg $args { + if {[info exists param]} { + set $param $arg + unset param + incr n + continue + } + switch -glob -- $arg { + -d* { + set switch $arg + set param base + } + -n* { + set nocomplain 1 + } + -t* { + # Ignored for Tcl compatibility + } + + -* { + return -code error "bad option \"$switch\": must be -directory, -nocomplain, -tails, or --" + } + -- { + incr n + break + } + * { + break + } + } + incr n + } + if {[info exists param]} { + return -code error "missing argument to \"$switch\"" + } + if {[llength $args] <= $n} { + return -code error "wrong # args: should be \"glob ?options? pattern ?pattern ...?\"" + } + + set args [lrange $args $n end] + + set result {} + foreach pattern $args { + set pattern [string map { + \\\\ \x01 \\\{ \x02 \\\} \x03 \\, \x04 + } $pattern] + set patexps [lassign [glob.explode $pattern] rest] + if {$rest ne ""} { + return -code error "unmatched close brace in glob pattern" + } + foreach patexp $patexps { + set patexp [string map { + \x01 \\\\ \x02 \{ \x03 \} \x04 , + } $patexp] + foreach {realname name} [glob.glob $base $patexp] { + lappend result $name + } + } + } + + if {!$nocomplain && [llength $result] == 0} { + return -code error "no files matched glob patterns" + } + + return $result +} diff --git a/debuggers/openocd/jimtcl/initjimsh.tcl b/debuggers/openocd/jimtcl/initjimsh.tcl new file mode 100644 index 00000000..a764f3a7 --- /dev/null +++ b/debuggers/openocd/jimtcl/initjimsh.tcl @@ -0,0 +1,27 @@ +# This pseudo-package is loaded from jimsh to add additional +# paths to $auto_path and to source ~/.jimrc + +proc _jimsh_init {} { + rename _jimsh_init {} + + # Add to the standard auto_path + lappend p {*}[split [env JIMLIB {}] $::tcl_platform(pathSeparator)] + lappend p {*}$::auto_path + lappend p [file dirname [info nameofexecutable]] + set ::auto_path $p + + if {$::tcl_interactive && [env HOME {}] ne ""} { + foreach src {.jimrc jimrc.tcl} { + if {[file exists [env HOME]/$src]} { + uplevel #0 source [env HOME]/$src + break + } + } + } +} + +if {$tcl_platform(platform) eq "windows"} { + set jim_argv0 [string map {\\ /} $jim_argv0] +} + +_jimsh_init diff --git a/debuggers/openocd/jimtcl/jim-aio.c b/debuggers/openocd/jimtcl/jim-aio.c new file mode 100644 index 00000000..bad87b6e --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-aio.c @@ -0,0 +1,1404 @@ + +/* Jim - A small embeddable Tcl interpreter + * + * Copyright 2005 Salvatore Sanfilippo + * Copyright 2005 Clemens Hintze + * Copyright 2005 patthoyts - Pat Thoyts + * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com + * Copyright 2008 Andrew Lunn + * Copyright 2008 Duane Ellis + * Copyright 2008 Uwe Klein + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + **/ + +#include "jimautoconf.h" + +#include +#include +#include +#include + +#include "jim.h" + +#if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_SELECT) && defined(HAVE_NETINET_IN_H) && defined(HAVE_NETDB_H) && defined(HAVE_ARPA_INET_H) +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_UN_H +#include +#endif +#else +#define JIM_ANSIC +#endif + +#include "jim-eventloop.h" +#include "jim-subcmd.h" + +#define AIO_CMD_LEN 32 /* e.g. aio.handleXXXXXX */ +#define AIO_BUF_LEN 256 /* Can keep this small and rely on stdio buffering */ + +#ifndef HAVE_FTELLO + #define ftello ftell +#endif +#ifndef HAVE_FSEEKO + #define fseeko fseek +#endif + +#define AIO_KEEPOPEN 1 + +#if defined(JIM_IPV6) +#define IPV6 1 +#else +#define IPV6 0 +#ifndef PF_INET6 +#define PF_INET6 0 +#endif +#endif + +#if !defined(JIM_ANSIC) && !defined(JIM_BOOTSTRAP) +union sockaddr_any { + struct sockaddr sa; + struct sockaddr_in sin; +#if IPV6 + struct sockaddr_in6 sin6; +#endif +}; + +#ifndef HAVE_INET_NTOP +const char *inet_ntop(int af, const void *src, char *dst, int size) +{ + if (af != PF_INET) { + return NULL; + } + snprintf(dst, size, "%s", inet_ntoa(((struct sockaddr_in *)src)->sin_addr)); + return dst; +} +#endif +#endif /* JIM_BOOTSTRAP */ + +typedef struct AioFile +{ + FILE *fp; + Jim_Obj *filename; + int type; + int OpenFlags; /* AIO_KEEPOPEN? keep FILE* */ + int fd; +#ifdef O_NDELAY + int flags; +#endif + Jim_Obj *rEvent; + Jim_Obj *wEvent; + Jim_Obj *eEvent; + int addr_family; +} AioFile; + +static int JimAioSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv); +static int JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename, + const char *hdlfmt, int family, const char *mode); + +#if !defined(JIM_ANSIC) && !defined(JIM_BOOTSTRAP) +static int JimParseIPv6Address(Jim_Interp *interp, const char *hostport, union sockaddr_any *sa, int *salen) +{ +#if IPV6 + /* + * An IPv6 addr/port looks like: + * [::1] + * [::1]:2000 + * [fe80::223:6cff:fe95:bdc0%en1]:2000 + * [::]:2000 + * 2000 + * + * Note that the "any" address is ::, which is the same as when no address is specified. + */ + char *sthost = NULL; + const char *stport; + int ret = JIM_OK; + struct addrinfo req; + struct addrinfo *ai; + + stport = strrchr(hostport, ':'); + if (!stport) { + /* No : so, the whole thing is the port */ + stport = hostport; + hostport = "::"; + sthost = Jim_StrDup(hostport); + } + else { + stport++; + } + + if (*hostport == '[') { + /* This is a numeric ipv6 address */ + char *pt = strchr(++hostport, ']'); + if (pt) { + sthost = Jim_StrDupLen(hostport, pt - hostport); + } + } + + if (!sthost) { + sthost = Jim_StrDupLen(hostport, stport - hostport - 1); + } + + memset(&req, '\0', sizeof(req)); + req.ai_family = PF_INET6; + + if (getaddrinfo(sthost, NULL, &req, &ai)) { + Jim_SetResultFormatted(interp, "Not a valid address: %s", hostport); + ret = JIM_ERR; + } + else { + memcpy(&sa->sin, ai->ai_addr, ai->ai_addrlen); + *salen = ai->ai_addrlen; + + sa->sin.sin_port = htons(atoi(stport)); + + freeaddrinfo(ai); + } + Jim_Free(sthost); + + return ret; +#else + Jim_SetResultString(interp, "ipv6 not supported", -1); + return JIM_ERR; +#endif +} + +static int JimParseIpAddress(Jim_Interp *interp, const char *hostport, union sockaddr_any *sa, int *salen) +{ + /* An IPv4 addr/port looks like: + * 192.168.1.5 + * 192.168.1.5:2000 + * 2000 + * + * If the address is missing, INADDR_ANY is used. + * If the port is missing, 0 is used (only useful for server sockets). + */ + char *sthost = NULL; + const char *stport; + int ret = JIM_OK; + + stport = strrchr(hostport, ':'); + if (!stport) { + /* No : so, the whole thing is the port */ + stport = hostport; + sthost = Jim_StrDup("0.0.0.0"); + } + else { + sthost = Jim_StrDupLen(hostport, stport - hostport); + stport++; + } + + { +#ifdef HAVE_GETADDRINFO + struct addrinfo req; + struct addrinfo *ai; + memset(&req, '\0', sizeof(req)); + req.ai_family = PF_INET; + + if (getaddrinfo(sthost, NULL, &req, &ai)) { + ret = JIM_ERR; + } + else { + memcpy(&sa->sin, ai->ai_addr, ai->ai_addrlen); + *salen = ai->ai_addrlen; + freeaddrinfo(ai); + } +#else + struct hostent *he; + + ret = JIM_ERR; + + if ((he = gethostbyname(sthost)) != NULL) { + if (he->h_length == sizeof(sa->sin.sin_addr)) { + *salen = sizeof(sa->sin); + sa->sin.sin_family= he->h_addrtype; + memcpy(&sa->sin.sin_addr, he->h_addr, he->h_length); /* set address */ + ret = JIM_OK; + } + } +#endif + + sa->sin.sin_port = htons(atoi(stport)); + } + Jim_Free(sthost); + + if (ret != JIM_OK) { + Jim_SetResultFormatted(interp, "Not a valid address: %s", hostport); + } + + return ret; +} + +#ifdef HAVE_SYS_UN_H +static int JimParseDomainAddress(Jim_Interp *interp, const char *path, struct sockaddr_un *sa) +{ + sa->sun_family = PF_UNIX; + snprintf(sa->sun_path, sizeof(sa->sun_path), "%s", path); + + return JIM_OK; +} +#endif +#endif /* JIM_BOOTSTRAP */ + +static void JimAioSetError(Jim_Interp *interp, Jim_Obj *name) +{ + if (name) { + Jim_SetResultFormatted(interp, "%#s: %s", name, strerror(errno)); + } + else { + Jim_SetResultString(interp, strerror(errno), -1); + } +} + +static void JimAioDelProc(Jim_Interp *interp, void *privData) +{ + AioFile *af = privData; + + JIM_NOTUSED(interp); + + if (!(af->OpenFlags & AIO_KEEPOPEN)) { + fclose(af->fp); + } + + Jim_DecrRefCount(interp, af->filename); + +#ifdef jim_ext_eventloop + /* remove existing EventHandlers */ + if (af->rEvent) { + Jim_DeleteFileHandler(interp, af->fp); + } + if (af->wEvent) { + Jim_DeleteFileHandler(interp, af->fp); + } + if (af->eEvent) { + Jim_DeleteFileHandler(interp, af->fp); + } +#endif + Jim_Free(af); +} + +static int JimCheckStreamError(Jim_Interp *interp, AioFile *af) +{ + if (!ferror(af->fp)) { + return JIM_OK; + } + clearerr(af->fp); + /* EAGAIN and similar are not error conditions. Just treat them like eof */ + if (feof(af->fp) || errno == EAGAIN || errno == EINTR) { + return JIM_OK; + } +#ifdef ECONNRESET + if (errno == ECONNRESET) { + return JIM_OK; + } +#endif +#ifdef ECONNABORTED + if (errno != ECONNABORTED) { + return JIM_OK; + } +#endif + JimAioSetError(interp, af->filename); + return JIM_ERR; +} + +static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + char buf[AIO_BUF_LEN]; + Jim_Obj *objPtr; + int nonewline = 0; + jim_wide neededLen = -1; /* -1 is "read as much as possible" */ + + if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) { + nonewline = 1; + argv++; + argc--; + } + if (argc == 1) { + if (Jim_GetWide(interp, argv[0], &neededLen) != JIM_OK) + return JIM_ERR; + if (neededLen < 0) { + Jim_SetResultString(interp, "invalid parameter: negative len", -1); + return JIM_ERR; + } + } + else if (argc) { + return -1; + } + objPtr = Jim_NewStringObj(interp, NULL, 0); + while (neededLen != 0) { + int retval; + int readlen; + + if (neededLen == -1) { + readlen = AIO_BUF_LEN; + } + else { + readlen = (neededLen > AIO_BUF_LEN ? AIO_BUF_LEN : neededLen); + } + retval = fread(buf, 1, readlen, af->fp); + if (retval > 0) { + Jim_AppendString(interp, objPtr, buf, retval); + if (neededLen != -1) { + neededLen -= retval; + } + } + if (retval != readlen) + break; + } + /* Check for error conditions */ + if (JimCheckStreamError(interp, af)) { + Jim_FreeNewObj(interp, objPtr); + return JIM_ERR; + } + if (nonewline) { + int len; + const char *s = Jim_GetString(objPtr, &len); + + if (len > 0 && s[len - 1] == '\n') { + objPtr->length--; + objPtr->bytes[objPtr->length] = '\0'; + } + } + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + +static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + jim_wide count = 0; + jim_wide maxlen = JIM_WIDE_MAX; + FILE *outfh = Jim_AioFilehandle(interp, argv[0]); + + if (outfh == NULL) { + return JIM_ERR; + } + + if (argc == 2) { + if (Jim_GetWide(interp, argv[1], &maxlen) != JIM_OK) { + return JIM_ERR; + } + } + + while (count < maxlen) { + int ch = fgetc(af->fp); + + if (ch == EOF || fputc(ch, outfh) == EOF) { + break; + } + count++; + } + + if (ferror(af->fp)) { + Jim_SetResultFormatted(interp, "error while reading: %s", strerror(errno)); + clearerr(af->fp); + return JIM_ERR; + } + + if (ferror(outfh)) { + Jim_SetResultFormatted(interp, "error while writing: %s", strerror(errno)); + clearerr(outfh); + return JIM_ERR; + } + + Jim_SetResultInt(interp, count); + + return JIM_OK; +} + +static int aio_cmd_gets(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + char buf[AIO_BUF_LEN]; + Jim_Obj *objPtr; + int len; + + errno = 0; + + objPtr = Jim_NewStringObj(interp, NULL, 0); + while (1) { + buf[AIO_BUF_LEN - 1] = '_'; + if (fgets(buf, AIO_BUF_LEN, af->fp) == NULL) + break; + + if (buf[AIO_BUF_LEN - 1] == '\0' && buf[AIO_BUF_LEN - 2] != '\n') { + Jim_AppendString(interp, objPtr, buf, AIO_BUF_LEN - 1); + } + else { + len = strlen(buf); + + if (len && (buf[len - 1] == '\n')) { + /* strip "\n" */ + len--; + } + + Jim_AppendString(interp, objPtr, buf, len); + break; + } + } + if (JimCheckStreamError(interp, af)) { + /* I/O error */ + Jim_FreeNewObj(interp, objPtr); + return JIM_ERR; + } + + if (argc) { + if (Jim_SetVariable(interp, argv[0], objPtr) != JIM_OK) { + Jim_FreeNewObj(interp, objPtr); + return JIM_ERR; + } + + len = Jim_Length(objPtr); + + if (len == 0 && feof(af->fp)) { + /* On EOF returns -1 if varName was specified */ + len = -1; + } + Jim_SetResultInt(interp, len); + } + else { + Jim_SetResult(interp, objPtr); + } + return JIM_OK; +} + +static int aio_cmd_puts(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + int wlen; + const char *wdata; + Jim_Obj *strObj; + + if (argc == 2) { + if (!Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) { + return -1; + } + strObj = argv[1]; + } + else { + strObj = argv[0]; + } + + wdata = Jim_GetString(strObj, &wlen); + if (fwrite(wdata, 1, wlen, af->fp) == (unsigned)wlen) { + if (argc == 2 || putc('\n', af->fp) != EOF) { + return JIM_OK; + } + } + JimAioSetError(interp, af->filename); + return JIM_ERR; +} + +static int aio_cmd_isatty(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ +#ifdef HAVE_ISATTY + AioFile *af = Jim_CmdPrivData(interp); + Jim_SetResultInt(interp, isatty(fileno(af->fp))); +#else + Jim_SetResultInt(interp, 0); +#endif + + return JIM_OK; +} + +#if !defined(JIM_ANSIC) && !defined(JIM_BOOTSTRAP) +static int aio_cmd_recvfrom(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + char *buf; + union sockaddr_any sa; + long len; + socklen_t salen = sizeof(sa); + int rlen; + + if (Jim_GetLong(interp, argv[0], &len) != JIM_OK) { + return JIM_ERR; + } + + buf = Jim_Alloc(len + 1); + + rlen = recvfrom(fileno(af->fp), buf, len, 0, &sa.sa, &salen); + if (rlen < 0) { + Jim_Free(buf); + JimAioSetError(interp, NULL); + return JIM_ERR; + } + buf[rlen] = 0; + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, rlen)); + + if (argc > 1) { + /* INET6_ADDRSTRLEN is 46. Add some for [] and port */ + char addrbuf[60]; + +#if IPV6 + if (sa.sa.sa_family == PF_INET6) { + addrbuf[0] = '['; + /* Allow 9 for []:65535\0 */ + inet_ntop(sa.sa.sa_family, &sa.sin6.sin6_addr, addrbuf + 1, sizeof(addrbuf) - 9); + snprintf(addrbuf + strlen(addrbuf), 8, "]:%d", ntohs(sa.sin.sin_port)); + } + else +#endif + { + /* Allow 7 for :65535\0 */ + inet_ntop(sa.sa.sa_family, &sa.sin.sin_addr, addrbuf, sizeof(addrbuf) - 7); + snprintf(addrbuf + strlen(addrbuf), 7, ":%d", ntohs(sa.sin.sin_port)); + } + + if (Jim_SetVariable(interp, argv[1], Jim_NewStringObj(interp, addrbuf, -1)) != JIM_OK) { + return JIM_ERR; + } + } + + return JIM_OK; +} + + +static int aio_cmd_sendto(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + int wlen; + int len; + const char *wdata; + union sockaddr_any sa; + const char *addr = Jim_String(argv[1]); + int salen; + + if (IPV6 && af->addr_family == PF_INET6) { + if (JimParseIPv6Address(interp, addr, &sa, &salen) != JIM_OK) { + return JIM_ERR; + } + } + else if (JimParseIpAddress(interp, addr, &sa, &salen) != JIM_OK) { + return JIM_ERR; + } + wdata = Jim_GetString(argv[0], &wlen); + + /* Note that we don't validate the socket type. Rely on sendto() failing if appropriate */ + len = sendto(fileno(af->fp), wdata, wlen, 0, &sa.sa, salen); + if (len < 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + Jim_SetResultInt(interp, len); + return JIM_OK; +} + +static int aio_cmd_accept(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + int sock; + union sockaddr_any sa; + socklen_t addrlen = sizeof(sa); + + sock = accept(af->fd, &sa.sa, &addrlen); + if (sock < 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + + /* Create the file command */ + return JimMakeChannel(interp, NULL, sock, Jim_NewStringObj(interp, "accept", -1), + "aio.sockstream%ld", af->addr_family, "r+"); +} + +static int aio_cmd_listen(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + long backlog; + + if (Jim_GetLong(interp, argv[0], &backlog) != JIM_OK) { + return JIM_ERR; + } + + if (listen(af->fd, backlog)) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + + return JIM_OK; +} +#endif /* JIM_BOOTSTRAP */ + +static int aio_cmd_flush(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + if (fflush(af->fp) == EOF) { + JimAioSetError(interp, af->filename); + return JIM_ERR; + } + return JIM_OK; +} + +static int aio_cmd_eof(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + Jim_SetResultInt(interp, feof(af->fp)); + return JIM_OK; +} + +static int aio_cmd_close(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_DeleteCommand(interp, Jim_String(argv[0])); + return JIM_OK; +} + +static int aio_cmd_seek(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + int orig = SEEK_SET; + jim_wide offset; + + if (argc == 2) { + if (Jim_CompareStringImmediate(interp, argv[1], "start")) + orig = SEEK_SET; + else if (Jim_CompareStringImmediate(interp, argv[1], "current")) + orig = SEEK_CUR; + else if (Jim_CompareStringImmediate(interp, argv[1], "end")) + orig = SEEK_END; + else { + return -1; + } + } + if (Jim_GetWide(interp, argv[0], &offset) != JIM_OK) { + return JIM_ERR; + } + if (fseeko(af->fp, offset, orig) == -1) { + JimAioSetError(interp, af->filename); + return JIM_ERR; + } + return JIM_OK; +} + +static int aio_cmd_tell(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + Jim_SetResultInt(interp, ftello(af->fp)); + return JIM_OK; +} + +static int aio_cmd_filename(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + Jim_SetResult(interp, af->filename); + return JIM_OK; +} + +#ifdef O_NDELAY +static int aio_cmd_ndelay(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + int fmode = af->flags; + + if (argc) { + long nb; + + if (Jim_GetLong(interp, argv[0], &nb) != JIM_OK) { + return JIM_ERR; + } + if (nb) { + fmode |= O_NDELAY; + } + else { + fmode &= ~O_NDELAY; + } + fcntl(af->fd, F_SETFL, fmode); + af->flags = fmode; + } + Jim_SetResultInt(interp, (fmode & O_NONBLOCK) ? 1 : 0); + return JIM_OK; +} +#endif + +static int aio_cmd_buffering(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + static const char * const options[] = { + "none", + "line", + "full", + NULL + }; + enum + { + OPT_NONE, + OPT_LINE, + OPT_FULL, + }; + int option; + + if (Jim_GetEnum(interp, argv[0], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + switch (option) { + case OPT_NONE: + setvbuf(af->fp, NULL, _IONBF, 0); + break; + case OPT_LINE: + setvbuf(af->fp, NULL, _IOLBF, BUFSIZ); + break; + case OPT_FULL: + setvbuf(af->fp, NULL, _IOFBF, BUFSIZ); + break; + } + return JIM_OK; +} + +#ifdef jim_ext_eventloop +static void JimAioFileEventFinalizer(Jim_Interp *interp, void *clientData) +{ + Jim_Obj *objPtr = clientData; + + Jim_DecrRefCount(interp, objPtr); +} + +static int JimAioFileEventHandler(Jim_Interp *interp, void *clientData, int mask) +{ + Jim_Obj *objPtr = clientData; + + return Jim_EvalObjBackground(interp, objPtr); +} + +static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, Jim_Obj **scriptHandlerObj, + int argc, Jim_Obj * const *argv) +{ + int scriptlen = 0; + + if (argc == 0) { + /* Return current script */ + if (*scriptHandlerObj) { + Jim_SetResult(interp, *scriptHandlerObj); + } + return JIM_OK; + } + + if (*scriptHandlerObj) { + /* Delete old handler */ + Jim_DeleteFileHandler(interp, af->fp); + *scriptHandlerObj = NULL; + } + + /* Now possibly add the new script(s) */ + Jim_GetString(argv[0], &scriptlen); + if (scriptlen == 0) { + /* Empty script, so done */ + return JIM_OK; + } + + /* A new script to add */ + Jim_IncrRefCount(argv[0]); + *scriptHandlerObj = argv[0]; + + Jim_CreateFileHandler(interp, af->fp, mask, + JimAioFileEventHandler, *scriptHandlerObj, JimAioFileEventFinalizer); + + return JIM_OK; +} + +static int aio_cmd_readable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + return aio_eventinfo(interp, af, JIM_EVENT_READABLE, &af->rEvent, argc, argv); +} + +static int aio_cmd_writable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + return aio_eventinfo(interp, af, JIM_EVENT_WRITABLE, &af->wEvent, argc, argv); +} + +static int aio_cmd_onexception(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + return aio_eventinfo(interp, af, JIM_EVENT_EXCEPTION, &af->wEvent, argc, argv); +} +#endif + +static const jim_subcmd_type aio_command_table[] = { + { "read", + "?-nonewline? ?len?", + aio_cmd_read, + 0, + 2, + /* Description: Read and return bytes from the stream. To eof if no len. */ + }, + { "copyto", + "handle ?size?", + aio_cmd_copy, + 1, + 2, + /* Description: Copy up to 'size' bytes to the given filehandle, or to eof if no size. */ + }, + { "gets", + "?var?", + aio_cmd_gets, + 0, + 1, + /* Description: Read one line and return it or store it in the var */ + }, + { "puts", + "?-nonewline? str", + aio_cmd_puts, + 1, + 2, + /* Description: Write the string, with newline unless -nonewline */ + }, + { "isatty", + NULL, + aio_cmd_isatty, + 0, + 0, + /* Description: Is the file descriptor a tty? */ + }, +#if !defined(JIM_ANSIC) && !defined(JIM_BOOTSTRAP) + { "recvfrom", + "len ?addrvar?", + aio_cmd_recvfrom, + 1, + 2, + /* Description: Receive up to 'len' bytes on the socket. Sets 'addrvar' with receive address, if set */ + }, + { "sendto", + "str address", + aio_cmd_sendto, + 2, + 2, + /* Description: Send 'str' to the given address (dgram only) */ + }, + { "accept", + NULL, + aio_cmd_accept, + 0, + 0, + /* Description: Server socket only: Accept a connection and return stream */ + }, + { "listen", + "backlog", + aio_cmd_listen, + 1, + 1, + /* Description: Set the listen backlog for server socket */ + }, +#endif /* JIM_BOOTSTRAP */ + { "flush", + NULL, + aio_cmd_flush, + 0, + 0, + /* Description: Flush the stream */ + }, + { "eof", + NULL, + aio_cmd_eof, + 0, + 0, + /* Description: Returns 1 if stream is at eof */ + }, + { "close", + NULL, + aio_cmd_close, + 0, + 0, + JIM_MODFLAG_FULLARGV, + /* Description: Closes the stream */ + }, + { "seek", + "offset ?start|current|end", + aio_cmd_seek, + 1, + 2, + /* Description: Seeks in the stream (default 'current') */ + }, + { "tell", + NULL, + aio_cmd_tell, + 0, + 0, + /* Description: Returns the current seek position */ + }, + { "filename", + NULL, + aio_cmd_filename, + 0, + 0, + /* Description: Returns the original filename */ + }, +#ifdef O_NDELAY + { "ndelay", + "?0|1?", + aio_cmd_ndelay, + 0, + 1, + /* Description: Set O_NDELAY (if arg). Returns current/new setting. */ + }, +#endif + { "buffering", + "none|line|full", + aio_cmd_buffering, + 1, + 1, + /* Description: Sets buffering */ + }, +#ifdef jim_ext_eventloop + { "readable", + "?readable-script?", + aio_cmd_readable, + 0, + 1, + /* Description: Returns script, or invoke readable-script when readable, {} to remove */ + }, + { "writable", + "?writable-script?", + aio_cmd_writable, + 0, + 1, + /* Description: Returns script, or invoke writable-script when writable, {} to remove */ + }, + { "onexception", + "?exception-script?", + aio_cmd_onexception, + 0, + 1, + /* Description: Returns script, or invoke exception-script when oob data, {} to remove */ + }, +#endif + { NULL } +}; + +static int JimAioSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, aio_command_table, argc, argv), argc, argv); +} + +static int JimAioOpenCommand(Jim_Interp *interp, int argc, + Jim_Obj *const *argv) +{ + const char *mode; + const char *filename; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "filename ?mode?"); + return JIM_ERR; + } + + mode = (argc == 3) ? Jim_String(argv[2]) : "r"; + filename = Jim_String(argv[1]); + +#ifdef jim_ext_tclcompat + /* If the filename starts with '|', use popen instead */ + if (*filename == '|') { + Jim_Obj *evalObj[3]; + + evalObj[0] = Jim_NewStringObj(interp, "popen", -1); + evalObj[1] = Jim_NewStringObj(interp, filename + 1, -1); + evalObj[2] = Jim_NewStringObj(interp, mode, -1); + + return Jim_EvalObjVector(interp, 3, evalObj); + } +#endif + return JimMakeChannel(interp, NULL, -1, argv[1], "aio.handle%ld", 0, mode); +} + +/** + * Creates a channel for fh/fd/filename. + * + * If fh is not NULL, uses that as the channel (and set AIO_KEEPOPEN). + * Otherwise, if fd is >= 0, uses that as the chanel. + * Otherwise opens 'filename' with mode 'mode'. + * + * hdlfmt is a sprintf format for the filehandle. Anything with %ld at the end will do. + * mode is used for open or fdopen. + * + * Creates the command and sets the name as the current result. + */ +static int JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename, + const char *hdlfmt, int family, const char *mode) +{ + AioFile *af; + char buf[AIO_CMD_LEN]; + int OpenFlags = 0; + + if (filename == NULL) { + filename = Jim_NewStringObj(interp, hdlfmt, -1); + } + + Jim_IncrRefCount(filename); + + if (fh == NULL) { + if (fd < 0) { + fh = fopen(Jim_String(filename), mode); + } + else { + fh = fdopen(fd, mode); + } + } + else { + OpenFlags = AIO_KEEPOPEN; + } + + if (fh == NULL) { + JimAioSetError(interp, filename); +#if !defined(JIM_ANSIC) + if (fd >= 0) { + close(fd); + } +#endif + Jim_DecrRefCount(interp, filename); + return JIM_ERR; + } + + /* Create the file command */ + af = Jim_Alloc(sizeof(*af)); + memset(af, 0, sizeof(*af)); + af->fp = fh; + af->fd = fileno(fh); + af->filename = filename; +#ifdef FD_CLOEXEC + if ((OpenFlags & AIO_KEEPOPEN) == 0) { + fcntl(af->fd, F_SETFD, FD_CLOEXEC); + } +#endif + af->OpenFlags = OpenFlags; +#ifdef O_NDELAY + af->flags = fcntl(af->fd, F_GETFL); +#endif + af->addr_family = family; + snprintf(buf, sizeof(buf), hdlfmt, Jim_GetId(interp)); + Jim_CreateCommand(interp, buf, JimAioSubCmdProc, af, JimAioDelProc); + + Jim_SetResultString(interp, buf, -1); + + return JIM_OK; +} + +#if !defined(JIM_ANSIC) && !defined(JIM_BOOTSTRAP) + +static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *hdlfmt = "aio.unknown%ld"; + const char *socktypes[] = { + "unix", + "unix.server", + "dgram", + "dgram.server", + "stream", + "stream.server", + "pipe", + NULL + }; + enum + { + SOCK_UNIX, + SOCK_UNIX_SERVER, + SOCK_DGRAM_CLIENT, + SOCK_DGRAM_SERVER, + SOCK_STREAM_CLIENT, + SOCK_STREAM_SERVER, + SOCK_STREAM_PIPE, + SOCK_DGRAM6_CLIENT, + SOCK_DGRAM6_SERVER, + SOCK_STREAM6_CLIENT, + SOCK_STREAM6_SERVER, + }; + int socktype; + int sock; + const char *hostportarg = NULL; + int res; + int on = 1; + const char *mode = "r+"; + int family = PF_INET; + Jim_Obj *argv0 = argv[0]; + int ipv6 = 0; + + if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-ipv6")) { + if (!IPV6) { + Jim_SetResultString(interp, "ipv6 not supported", -1); + return JIM_ERR; + } + ipv6 = 1; + family = PF_INET6; + } + argc -= ipv6; + argv += ipv6; + + if (argc < 2) { + wrongargs: + Jim_WrongNumArgs(interp, 1, &argv0, "?-ipv6? type ?address?"); + return JIM_ERR; + } + + if (Jim_GetEnum(interp, argv[1], socktypes, &socktype, "socket type", JIM_ERRMSG) != JIM_OK) + return JIM_ERR; + + Jim_SetEmptyResult(interp); + + hdlfmt = "aio.sock%ld"; + + if (argc > 2) { + hostportarg = Jim_String(argv[2]); + } + + switch (socktype) { + case SOCK_DGRAM_CLIENT: + if (argc == 2) { + /* No address, so an unconnected dgram socket */ + sock = socket(family, SOCK_DGRAM, 0); + if (sock < 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + break; + } + /* fall through */ + case SOCK_STREAM_CLIENT: + { + union sockaddr_any sa; + int salen; + + if (argc != 3) { + goto wrongargs; + } + + if (ipv6) { + if (JimParseIPv6Address(interp, hostportarg, &sa, &salen) != JIM_OK) { + return JIM_ERR; + } + } + else if (JimParseIpAddress(interp, hostportarg, &sa, &salen) != JIM_OK) { + return JIM_ERR; + } + sock = socket(family, (socktype == SOCK_DGRAM_CLIENT) ? SOCK_DGRAM : SOCK_STREAM, 0); + if (sock < 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + res = connect(sock, &sa.sa, salen); + if (res) { + JimAioSetError(interp, argv[2]); + close(sock); + return JIM_ERR; + } + } + break; + + case SOCK_STREAM_SERVER: + case SOCK_DGRAM_SERVER: + { + union sockaddr_any sa; + int salen; + + if (argc != 3) { + goto wrongargs; + } + + if (ipv6) { + if (JimParseIPv6Address(interp, hostportarg, &sa, &salen) != JIM_OK) { + return JIM_ERR; + } + } + else if (JimParseIpAddress(interp, hostportarg, &sa, &salen) != JIM_OK) { + return JIM_ERR; + } + sock = socket(family, (socktype == SOCK_DGRAM_SERVER) ? SOCK_DGRAM : SOCK_STREAM, 0); + if (sock < 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + + /* Enable address reuse */ + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); + + res = bind(sock, &sa.sa, salen); + if (res) { + JimAioSetError(interp, argv[2]); + close(sock); + return JIM_ERR; + } + if (socktype == SOCK_STREAM_SERVER) { + res = listen(sock, 5); + if (res) { + JimAioSetError(interp, NULL); + close(sock); + return JIM_ERR; + } + } + hdlfmt = "aio.socksrv%ld"; + } + break; + +#ifdef HAVE_SYS_UN_H + case SOCK_UNIX: + { + struct sockaddr_un sa; + socklen_t len; + + if (argc != 3 || ipv6) { + goto wrongargs; + } + + if (JimParseDomainAddress(interp, hostportarg, &sa) != JIM_OK) { + JimAioSetError(interp, argv[2]); + return JIM_ERR; + } + family = PF_UNIX; + sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + len = strlen(sa.sun_path) + 1 + sizeof(sa.sun_family); + res = connect(sock, (struct sockaddr *)&sa, len); + if (res) { + JimAioSetError(interp, argv[2]); + close(sock); + return JIM_ERR; + } + hdlfmt = "aio.sockunix%ld"; + break; + } + + case SOCK_UNIX_SERVER: + { + struct sockaddr_un sa; + socklen_t len; + + if (argc != 3 || ipv6) { + goto wrongargs; + } + + if (JimParseDomainAddress(interp, hostportarg, &sa) != JIM_OK) { + JimAioSetError(interp, argv[2]); + return JIM_ERR; + } + family = PF_UNIX; + sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + len = strlen(sa.sun_path) + 1 + sizeof(sa.sun_family); + res = bind(sock, (struct sockaddr *)&sa, len); + if (res) { + JimAioSetError(interp, argv[2]); + close(sock); + return JIM_ERR; + } + res = listen(sock, 5); + if (res) { + JimAioSetError(interp, NULL); + close(sock); + return JIM_ERR; + } + hdlfmt = "aio.sockunixsrv%ld"; + break; + } +#endif + +#ifdef HAVE_PIPE + case SOCK_STREAM_PIPE: + { + int p[2]; + + if (argc != 2 || ipv6) { + goto wrongargs; + } + + if (pipe(p) < 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + + if (JimMakeChannel(interp, NULL, p[0], argv[1], "aio.pipe%ld", 0, "r") == JIM_OK) { + Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); + + if (JimMakeChannel(interp, NULL, p[1], argv[1], "aio.pipe%ld", 0, "w") == JIM_OK) { + Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + } + /* Can only be here if fdopen() failed */ + close(p[0]); + close(p[1]); + JimAioSetError(interp, NULL); + return JIM_ERR; + } + break; +#endif + default: + Jim_SetResultString(interp, "Unsupported socket type", -1); + return JIM_ERR; + } + + return JimMakeChannel(interp, NULL, sock, argv[1], hdlfmt, family, mode); +} +#endif /* JIM_BOOTSTRAP */ + +FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command) +{ + Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG); + + if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) { + return ((AioFile *) cmdPtr->u.native.privData)->fp; + } + Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", command); + return NULL; +} + +int Jim_aioInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "aio", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL); +#ifndef JIM_ANSIC + Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL); +#endif + + /* Create filehandles for stdin, stdout and stderr */ + JimMakeChannel(interp, stdin, -1, NULL, "stdin", 0, "r"); + JimMakeChannel(interp, stdout, -1, NULL, "stdout", 0, "w"); + JimMakeChannel(interp, stderr, -1, NULL, "stderr", 0, "w"); + + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-array.c b/debuggers/openocd/jimtcl/jim-array.c new file mode 100644 index 00000000..f364ec8c --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-array.c @@ -0,0 +1,243 @@ + +/* + * Implements the array command for jim + * + * (c) 2008 Steve Bennett + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + * + * Based on code originally from Tcl 6.7: + * + * Copyright 1987-1991 Regents of the University of California + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies. The University of California + * makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without + * express or implied warranty. + */ + +#include +#include +#include +#include +#include + +#include + +static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + /* Just a regular [info exists] */ + Jim_SetResultInt(interp, Jim_GetVariable(interp, argv[0], 0) != 0); + return JIM_OK; +} + +static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + + if (!objPtr) { + return JIM_OK; + } + + if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) { + /* Optimise the "all" case */ + if (Jim_IsList(objPtr)) { + if (Jim_ListLength(interp, objPtr) % 2 != 0) { + /* A list with an odd number of elements */ + return JIM_ERR; + } + } + else if (Jim_DictSize(interp, objPtr) < 0) { + /* Can't be converted to a dictionary */ + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + /* Return a list of keys and values where the keys match the pattern */ + return Jim_DictValues(interp, objPtr, argv[1]); +} + +static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + + if (!objPtr) { + return JIM_OK; + } + + return Jim_DictKeys(interp, objPtr, argc == 1 ? NULL : argv[1]); +} + +static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + int len; + Jim_Obj *resultObj; + Jim_Obj *objPtr; + Jim_Obj **dictValuesObj; + + if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) { + /* Unset the whole array */ + Jim_UnsetVariable(interp, argv[0], JIM_NONE); + return JIM_OK; + } + + objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + + if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) { + return JIM_ERR; + } + + /* Create a new object with the values which don't match */ + resultObj = Jim_NewDictObj(interp, NULL, 0); + + for (i = 0; i < len; i += 2) { + if (!Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) { + Jim_DictAddElement(interp, resultObj, dictValuesObj[i], dictValuesObj[i + 1]); + } + } + Jim_Free(dictValuesObj); + + Jim_SetVariable(interp, argv[0], resultObj); + return JIM_OK; +} + +static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + int len = 0; + + /* Not found means zero length */ + objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + if (objPtr) { + len = Jim_DictSize(interp, objPtr); + if (len < 0) { + return JIM_ERR; + } + } + + Jim_SetResultInt(interp, len); + + return JIM_OK; +} + +static int array_cmd_set(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + int len; + Jim_Obj *listObj = argv[1]; + Jim_Obj *dictObj; + + len = Jim_ListLength(interp, listObj); + if (len % 2) { + Jim_SetResultString(interp, "list must have an even number of elements", -1); + return JIM_ERR; + } + + dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED); + if (!dictObj) { + /* Doesn't exist, so just set the list directly */ + return Jim_SetVariable(interp, argv[0], listObj); + } + + if (Jim_IsShared(dictObj)) { + dictObj = Jim_DuplicateObj(interp, dictObj); + } + + for (i = 0; i < len; i += 2) { + Jim_Obj *nameObj; + Jim_Obj *valueObj; + + Jim_ListIndex(interp, listObj, i, &nameObj, JIM_NONE); + Jim_ListIndex(interp, listObj, i + 1, &valueObj, JIM_NONE); + + Jim_DictAddElement(interp, dictObj, nameObj, valueObj); + } + return Jim_SetVariable(interp, argv[0], dictObj); +} + +static const jim_subcmd_type array_command_table[] = { + { "exists", + "arrayName", + array_cmd_exists, + 1, + 1, + /* Description: Does array exist? */ + }, + { "get", + "arrayName ?pattern?", + array_cmd_get, + 1, + 2, + /* Description: Array contents as name value list */ + }, + { "names", + "arrayName ?pattern?", + array_cmd_names, + 1, + 2, + /* Description: Array keys as a list */ + }, + { "set", + "arrayName list", + array_cmd_set, + 2, + 2, + /* Description: Set array from list */ + }, + { "size", + "arrayName", + array_cmd_size, + 1, + 1, + /* Description: Number of elements in array */ + }, + { "unset", + "arrayName ?pattern?", + array_cmd_unset, + 1, + 2, + /* Description: Unset elements of an array */ + }, + { NULL + } +}; + +int Jim_arrayInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "array", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "array", Jim_SubCmdProc, (void *)array_command_table, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-clock.c b/debuggers/openocd/jimtcl/jim-clock.c new file mode 100644 index 00000000..f7911060 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-clock.c @@ -0,0 +1,165 @@ + +/* + * tcl_clock.c + * + * Implements the clock command + */ + +/* For strptime() */ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 500 +#endif + +#include +#include +#include +#include + +#include "jimautoconf.h" +#include + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + /* How big is big enough? */ + char buf[100]; + time_t t; + long seconds; + + const char *format = "%a %b %d %H:%M:%S %Z %Y"; + + if (argc == 2 || (argc == 3 && !Jim_CompareStringImmediate(interp, argv[1], "-format"))) { + return -1; + } + + if (argc == 3) { + format = Jim_String(argv[2]); + } + + if (Jim_GetLong(interp, argv[0], &seconds) != JIM_OK) { + return JIM_ERR; + } + t = seconds; + + strftime(buf, sizeof(buf), format, localtime(&t)); + + Jim_SetResultString(interp, buf, -1); + + return JIM_OK; +} + +#ifdef HAVE_STRPTIME +static int clock_cmd_scan(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + char *pt; + struct tm tm; + time_t now = time(0); + + if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) { + return -1; + } + + /* Initialise with the current date/time */ + localtime_r(&now, &tm); + + pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm); + if (pt == 0 || *pt != 0) { + Jim_SetResultString(interp, "Failed to parse time according to format", -1); + return JIM_ERR; + } + + /* Now convert into a time_t */ + Jim_SetResultInt(interp, mktime(&tm)); + + return JIM_OK; +} +#endif + +static int clock_cmd_seconds(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_SetResultInt(interp, time(NULL)); + + return JIM_OK; +} + +static int clock_cmd_micros(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + Jim_SetResultInt(interp, (jim_wide) tv.tv_sec * 1000000 + tv.tv_usec); + + return JIM_OK; +} + +static int clock_cmd_millis(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + Jim_SetResultInt(interp, (jim_wide) tv.tv_sec * 1000 + tv.tv_usec / 1000); + + return JIM_OK; +} + +static const jim_subcmd_type clock_command_table[] = { + { "seconds", + NULL, + clock_cmd_seconds, + 0, + 0, + /* Description: Returns the current time as seconds since the epoch */ + }, + { "clicks", + NULL, + clock_cmd_micros, + 0, + 0, + /* Description: Returns the current time in 'clicks' */ + }, + { "microseconds", + NULL, + clock_cmd_micros, + 0, + 0, + /* Description: Returns the current time in microseconds */ + }, + { "milliseconds", + NULL, + clock_cmd_millis, + 0, + 0, + /* Description: Returns the current time in milliseconds */ + }, + { "format", + "seconds ?-format format?", + clock_cmd_format, + 1, + 3, + /* Description: Format the given time */ + }, +#ifdef HAVE_STRPTIME + { "scan", + "str -format format", + clock_cmd_scan, + 3, + 3, + /* Description: Determine the time according to the given format */ + }, +#endif + { NULL } +}; + +int Jim_clockInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "clock", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "clock", Jim_SubCmdProc, (void *)clock_command_table, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-config.h.in b/debuggers/openocd/jimtcl/jim-config.h.in new file mode 100644 index 00000000..2394bc59 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-config.h.in @@ -0,0 +1,2 @@ +/* Public autoconf settings */ +@DEFINE_HAVE_LONG_LONG@ diff --git a/debuggers/openocd/jimtcl/jim-eventloop.c b/debuggers/openocd/jimtcl/jim-eventloop.c new file mode 100644 index 00000000..ef62284d --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-eventloop.c @@ -0,0 +1,760 @@ + +/* Jim - A small embeddable Tcl interpreter + * + * Copyright 2005 Salvatore Sanfilippo + * Copyright 2005 Clemens Hintze + * Copyright 2005 patthoyts - Pat Thoyts + * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com + * Copyright 2008 Andrew Lunn + * Copyright 2008 Duane Ellis + * Copyright 2008 Uwe Klein + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + **/ + +#include "jimautoconf.h" +#include +#include + +/* POSIX includes */ +#include +#include +#include +#include +#include + +#if defined(__MINGW32__) +#include +#include +#define msleep Sleep +#ifndef HAVE_USLEEP +#define usleep(US) msleep((US) / 1000) +#endif +#else +#include + +#ifndef HAVE_USLEEP +/* XXX: Implement this in terms of select() or nanosleep() */ +#define usleep(US) +#endif +#define msleep(MS) sleep((MS) / 1000); usleep(((MS) % 1000) * 1000); +#endif + +/* --- */ + +/* File event structure */ +typedef struct Jim_FileEvent +{ + FILE *handle; + int mask; /* one of JIM_EVENT_(READABLE|WRITABLE|EXCEPTION) */ + Jim_FileProc *fileProc; + Jim_EventFinalizerProc *finalizerProc; + void *clientData; + struct Jim_FileEvent *next; +} Jim_FileEvent; + +/* Time event structure */ +typedef struct Jim_TimeEvent +{ + jim_wide id; /* time event identifier. */ + int mode; /* restart, repetitive .. UK */ + long initialms; /* initial relativ timer value UK */ + long when_sec; /* seconds */ + long when_ms; /* milliseconds */ + Jim_TimeProc *timeProc; + Jim_EventFinalizerProc *finalizerProc; + void *clientData; + struct Jim_TimeEvent *next; +} Jim_TimeEvent; + +/* Per-interp stucture containing the state of the event loop */ +typedef struct Jim_EventLoop +{ + jim_wide timeEventNextId; + Jim_FileEvent *fileEventHead; + Jim_TimeEvent *timeEventHead; + int suppress_bgerror; /* bgerror returned break, so don't call it again */ +} Jim_EventLoop; + +static void JimAfterTimeHandler(Jim_Interp *interp, void *clientData); +static void JimAfterTimeEventFinalizer(Jim_Interp *interp, void *clientData); + +int Jim_EvalObjBackground(Jim_Interp *interp, Jim_Obj *scriptObjPtr) +{ + Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop"); + Jim_CallFrame *savedFramePtr; + int retval; + + savedFramePtr = interp->framePtr; + interp->framePtr = interp->topFramePtr; + retval = Jim_EvalObj(interp, scriptObjPtr); + interp->framePtr = savedFramePtr; + /* Try to report the error (if any) via the bgerror proc */ + if (retval != JIM_OK && !eventLoop->suppress_bgerror) { + Jim_Obj *objv[2]; + int rc = JIM_ERR; + + objv[0] = Jim_NewStringObj(interp, "bgerror", -1); + objv[1] = Jim_GetResult(interp); + Jim_IncrRefCount(objv[0]); + Jim_IncrRefCount(objv[1]); + if (Jim_GetCommand(interp, objv[0], JIM_NONE) == NULL || (rc = Jim_EvalObjVector(interp, 2, objv)) != JIM_OK) { + if (rc == JIM_BREAK) { + /* No more bgerror calls */ + eventLoop->suppress_bgerror++; + } + else { + /* Report the error to stderr. */ + Jim_MakeErrorMessage(interp); + fprintf(stderr, "%s\n", Jim_String(Jim_GetResult(interp))); + /* And reset the result */ + Jim_SetResultString(interp, "", -1); + } + } + Jim_DecrRefCount(interp, objv[0]); + Jim_DecrRefCount(interp, objv[1]); + } + return retval; +} + + +void Jim_CreateFileHandler(Jim_Interp *interp, FILE * handle, int mask, + Jim_FileProc * proc, void *clientData, Jim_EventFinalizerProc * finalizerProc) +{ + Jim_FileEvent *fe; + Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop"); + + fe = Jim_Alloc(sizeof(*fe)); + fe->handle = handle; + fe->mask = mask; + fe->fileProc = proc; + fe->finalizerProc = finalizerProc; + fe->clientData = clientData; + fe->next = eventLoop->fileEventHead; + eventLoop->fileEventHead = fe; +} + +void Jim_DeleteFileHandler(Jim_Interp *interp, FILE * handle) +{ + Jim_FileEvent *fe, *prev = NULL; + Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop"); + + fe = eventLoop->fileEventHead; + while (fe) { + if (fe->handle == handle) { + if (prev == NULL) + eventLoop->fileEventHead = fe->next; + else + prev->next = fe->next; + if (fe->finalizerProc) + fe->finalizerProc(interp, fe->clientData); + Jim_Free(fe); + return; + } + prev = fe; + fe = fe->next; + } +} + +static void JimGetTime(long *seconds, long *milliseconds) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + *seconds = tv.tv_sec; + *milliseconds = tv.tv_usec / 1000; +} + +jim_wide Jim_CreateTimeHandler(Jim_Interp *interp, jim_wide milliseconds, + Jim_TimeProc * proc, void *clientData, Jim_EventFinalizerProc * finalizerProc) +{ + Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop"); + jim_wide id = eventLoop->timeEventNextId++; + Jim_TimeEvent *te, *e, *prev; + long cur_sec, cur_ms; + + JimGetTime(&cur_sec, &cur_ms); + + te = Jim_Alloc(sizeof(*te)); + te->id = id; + te->mode = 0; + te->initialms = milliseconds; + te->when_sec = cur_sec + milliseconds / 1000; + te->when_ms = cur_ms + milliseconds % 1000; + if (te->when_ms >= 1000) { + te->when_sec++; + te->when_ms -= 1000; + } + te->timeProc = proc; + te->finalizerProc = finalizerProc; + te->clientData = clientData; + + /* Add to the appropriate place in the list */ + if (eventLoop->timeEventHead) { + prev = NULL; + for (e = eventLoop->timeEventHead; e; e = e->next) { + if (te->when_sec < e->when_sec || (te->when_sec == e->when_sec && te->when_ms < e->when_ms)) { + break; + } + prev = e; + } + if (prev) { + te->next = prev->next; + prev->next = te; + return id; + } + } + + te->next = eventLoop->timeEventHead; + eventLoop->timeEventHead = te; + + return id; +} + +static jim_wide JimParseAfterId(Jim_Obj *idObj) +{ + int len; + const char *tok = Jim_GetString(idObj, &len); + jim_wide id; + + if (strncmp(tok, "after#", 6) == 0 && Jim_StringToWide(tok + 6, &id, 10) == JIM_OK) { + /* Got an event by id */ + return id; + } + return -1; +} + +static jim_wide JimFindAfterByScript(Jim_EventLoop *eventLoop, Jim_Obj *scriptObj) +{ + Jim_TimeEvent *te; + + for (te = eventLoop->timeEventHead; te; te = te->next) { + /* Is this an 'after' event? */ + if (te->timeProc == JimAfterTimeHandler) { + if (Jim_StringEqObj(scriptObj, te->clientData)) { + return te->id; + } + } + } + return -1; /* NO event with the specified ID found */ +} + +static Jim_TimeEvent *JimFindTimeHandlerById(Jim_EventLoop *eventLoop, jim_wide id) +{ + Jim_TimeEvent *te; + + for (te = eventLoop->timeEventHead; te; te = te->next) { + if (te->id == id) { + return te; + } + } + return NULL; +} + +static Jim_TimeEvent *Jim_RemoveTimeHandler(Jim_EventLoop *eventLoop, jim_wide id) +{ + Jim_TimeEvent *te, *prev = NULL; + + for (te = eventLoop->timeEventHead; te; te = te->next) { + if (te->id == id) { + if (prev == NULL) + eventLoop->timeEventHead = te->next; + else + prev->next = te->next; + return te; + } + prev = te; + } + return NULL; +} + +static void Jim_FreeTimeHandler(Jim_Interp *interp, Jim_TimeEvent *te) +{ + if (te->finalizerProc) + te->finalizerProc(interp, te->clientData); + Jim_Free(te); +} + +jim_wide Jim_DeleteTimeHandler(Jim_Interp *interp, jim_wide id) +{ + Jim_TimeEvent *te; + Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop"); + + if (id >= eventLoop->timeEventNextId) { + return -2; /* wrong event ID */ + } + + te = Jim_RemoveTimeHandler(eventLoop, id); + if (te) { + jim_wide remain; + long cur_sec, cur_ms; + + JimGetTime(&cur_sec, &cur_ms); + + remain = (te->when_sec - cur_sec) * 1000; + remain += (te->when_ms - cur_ms); + remain = (remain < 0) ? 0 : remain; + + Jim_FreeTimeHandler(interp, te); + return remain; + } + return -1; /* NO event with the specified ID found */ +} + +/* --- POSIX version of Jim_ProcessEvents, for now the only available --- */ + +/* Process every pending time event, then every pending file event + * (that may be registered by time event callbacks just processed). + * Without special flags the function sleeps until some file event + * fires, or when the next time event occurrs (if any). + * + * If flags is 0, the function does nothing and returns. + * if flags has JIM_ALL_EVENTS set, all the kind of events are processed. + * if flags has JIM_FILE_EVENTS set, file events are processed. + * if flags has JIM_TIME_EVENTS set, time events are processed. + * if flags has JIM_DONT_WAIT set the function returns ASAP until all + * the events that's possible to process without to wait are processed. + * + * The function returns the number of events processed or -1 if + * there are no matching handlers, or -2 on error. + */ +int Jim_ProcessEvents(Jim_Interp *interp, int flags) +{ + jim_wide sleep_ms = -1; + int processed = 0; + Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop"); + Jim_FileEvent *fe = eventLoop->fileEventHead; + Jim_TimeEvent *te; + jim_wide maxId; + + if ((flags & JIM_FILE_EVENTS) == 0 || fe == NULL) { + /* No file events */ + if ((flags & JIM_TIME_EVENTS) == 0 || eventLoop->timeEventHead == NULL) { + /* No time events */ + return -1; + } + } + + /* Note that we want call select() even if there are no + * file events to process as long as we want to process time + * events, in order to sleep until the next time event is ready + * to fire. */ + + if (flags & JIM_DONT_WAIT) { + /* Wait no time */ + sleep_ms = 0; + } + else if (flags & JIM_TIME_EVENTS) { + /* The nearest timer is always at the head of the list */ + if (eventLoop->timeEventHead) { + Jim_TimeEvent *shortest = eventLoop->timeEventHead; + long now_sec, now_ms; + + /* Calculate the time missing for the nearest + * timer to fire. */ + JimGetTime(&now_sec, &now_ms); + sleep_ms = 1000 * (shortest->when_sec - now_sec) + (shortest->when_ms - now_ms); + if (sleep_ms < 0) { + sleep_ms = 1; + } + } + else { + /* Wait forever */ + sleep_ms = -1; + } + } + +#ifdef HAVE_SELECT + if (flags & JIM_FILE_EVENTS) { + int retval; + struct timeval tv, *tvp = NULL; + fd_set rfds, wfds, efds; + int maxfd = -1; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + + /* Check file events */ + while (fe != NULL) { + int fd = fileno(fe->handle); + + if (fe->mask & JIM_EVENT_READABLE) + FD_SET(fd, &rfds); + if (fe->mask & JIM_EVENT_WRITABLE) + FD_SET(fd, &wfds); + if (fe->mask & JIM_EVENT_EXCEPTION) + FD_SET(fd, &efds); + if (maxfd < fd) + maxfd = fd; + fe = fe->next; + } + + if (sleep_ms >= 0) { + tvp = &tv; + tvp->tv_sec = sleep_ms / 1000; + tvp->tv_usec = 1000 * (sleep_ms % 1000); + } + + retval = select(maxfd + 1, &rfds, &wfds, &efds, tvp); + + if (retval < 0) { + if (errno == EINVAL) { + /* This can happen on mingw32 if a non-socket filehandle is passed */ + Jim_SetResultString(interp, "non-waitable filehandle", -1); + return -2; + } + /* XXX: What about EINTR? */ + } + else if (retval > 0) { + fe = eventLoop->fileEventHead; + while (fe != NULL) { + int fd = fileno(fe->handle); + int mask = 0; + + if ((fe->mask & JIM_EVENT_READABLE) && FD_ISSET(fd, &rfds)) + mask |= JIM_EVENT_READABLE; + if (fe->mask & JIM_EVENT_WRITABLE && FD_ISSET(fd, &wfds)) + mask |= JIM_EVENT_WRITABLE; + if (fe->mask & JIM_EVENT_EXCEPTION && FD_ISSET(fd, &efds)) + mask |= JIM_EVENT_EXCEPTION; + + if (mask) { + if (fe->fileProc(interp, fe->clientData, mask) != JIM_OK) { + /* Remove the element on handler error */ + Jim_DeleteFileHandler(interp, fe->handle); + } + processed++; + /* After an event is processed our file event list + * may no longer be the same, so what we do + * is to clear the bit for this file descriptor and + * restart again from the head. */ + fe = eventLoop->fileEventHead; + FD_CLR(fd, &rfds); + FD_CLR(fd, &wfds); + FD_CLR(fd, &efds); + } + else { + fe = fe->next; + } + } + } + } +#else + if (sleep_ms > 0) { + msleep(sleep_ms); + } +#endif + + /* Check time events */ + te = eventLoop->timeEventHead; + maxId = eventLoop->timeEventNextId - 1; + while (te) { + long now_sec, now_ms; + jim_wide id; + + if (te->id > maxId) { + te = te->next; + continue; + } + JimGetTime(&now_sec, &now_ms); + if (now_sec > te->when_sec || (now_sec == te->when_sec && now_ms >= te->when_ms)) { + id = te->id; + /* Remove from the list before executing */ + Jim_RemoveTimeHandler(eventLoop, id); + te->timeProc(interp, te->clientData); + /* After an event is processed our time event list may + * no longer be the same, so we restart from head. + * Still we make sure to don't process events registered + * by event handlers itself in order to don't loop forever + * even in case an [after 0] that continuously register + * itself. To do so we saved the max ID we want to handle. */ + Jim_FreeTimeHandler(interp, te); + + te = eventLoop->timeEventHead; + processed++; + } + else { + te = te->next; + } + } + + return processed; +} + +/* ---------------------------------------------------------------------- */ + +static void JimELAssocDataDeleProc(Jim_Interp *interp, void *data) +{ + void *next; + Jim_FileEvent *fe; + Jim_TimeEvent *te; + Jim_EventLoop *eventLoop = data; + + fe = eventLoop->fileEventHead; + while (fe) { + next = fe->next; + if (fe->finalizerProc) + fe->finalizerProc(interp, fe->clientData); + Jim_Free(fe); + fe = next; + } + + te = eventLoop->timeEventHead; + while (te) { + next = te->next; + if (te->finalizerProc) + te->finalizerProc(interp, te->clientData); + Jim_Free(te); + te = next; + } + Jim_Free(data); +} + +static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_EventLoop *eventLoop = Jim_CmdPrivData(interp); + Jim_Obj *oldValue; + int rc; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "name"); + return JIM_ERR; + } + + oldValue = Jim_GetGlobalVariable(interp, argv[1], JIM_NONE); + if (oldValue) { + Jim_IncrRefCount(oldValue); + } + else { + /* If a result was left, it is an error */ + int len; + Jim_GetString(interp->result, &len); + if (len) { + return JIM_ERR; + } + } + + eventLoop->suppress_bgerror = 0; + + while ((rc = Jim_ProcessEvents(interp, JIM_ALL_EVENTS)) >= 0) { + Jim_Obj *currValue; + currValue = Jim_GetGlobalVariable(interp, argv[1], JIM_NONE); + /* Stop the loop if the vwait-ed variable changed value, + * or if was unset and now is set (or the contrary). */ + if ((oldValue && !currValue) || + (!oldValue && currValue) || + (oldValue && currValue && !Jim_StringEqObj(oldValue, currValue))) + break; + } + if (oldValue) + Jim_DecrRefCount(interp, oldValue); + + + if (rc == -2) { + return JIM_ERR; + } + + Jim_SetEmptyResult(interp); + return JIM_OK; +} + +static int JimELUpdateCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_EventLoop *eventLoop = Jim_CmdPrivData(interp); + static const char * const options[] = { + "idletasks", NULL + }; + enum { UPDATE_IDLE, UPDATE_NONE }; + int option = UPDATE_NONE; + int flags = JIM_TIME_EVENTS; + + if (argc == 1) { + flags = JIM_ALL_EVENTS; + } + else if (argc > 2 || Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + Jim_WrongNumArgs(interp, 1, argv, "?idletasks?"); + return JIM_ERR; + } + + eventLoop->suppress_bgerror = 0; + + while (Jim_ProcessEvents(interp, flags | JIM_DONT_WAIT) > 0) { + } + + return JIM_OK; +} + +static void JimAfterTimeHandler(Jim_Interp *interp, void *clientData) +{ + Jim_Obj *objPtr = clientData; + + Jim_EvalObjBackground(interp, objPtr); +} + +static void JimAfterTimeEventFinalizer(Jim_Interp *interp, void *clientData) +{ + Jim_Obj *objPtr = clientData; + + Jim_DecrRefCount(interp, objPtr); +} + +static int JimELAfterCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_EventLoop *eventLoop = Jim_CmdPrivData(interp); + jim_wide ms = 0, id; + Jim_Obj *objPtr, *idObjPtr; + static const char * const options[] = { + "cancel", "info", "idle", NULL + }; + enum + { AFTER_CANCEL, AFTER_INFO, AFTER_IDLE, AFTER_RESTART, AFTER_EXPIRE, AFTER_CREATE }; + int option = AFTER_CREATE; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "option ?arg ...?"); + return JIM_ERR; + } + if (Jim_GetWide(interp, argv[1], &ms) != JIM_OK) { + if (Jim_GetEnum(interp, argv[1], options, &option, "argument", JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + Jim_SetEmptyResult(interp); + } + else if (argc == 2) { + /* Simply a sleep */ + msleep(ms); + return JIM_OK; + } + + switch (option) { + case AFTER_IDLE: + if (argc < 3) { + Jim_WrongNumArgs(interp, 2, argv, "script ?script ...?"); + return JIM_ERR; + } + /* fall through */ + case AFTER_CREATE: { + Jim_Obj *scriptObj = Jim_ConcatObj(interp, argc - 2, argv + 2); + Jim_IncrRefCount(scriptObj); + id = Jim_CreateTimeHandler(interp, ms, JimAfterTimeHandler, scriptObj, + JimAfterTimeEventFinalizer); + objPtr = Jim_NewStringObj(interp, NULL, 0); + Jim_AppendString(interp, objPtr, "after#", -1); + idObjPtr = Jim_NewIntObj(interp, id); + Jim_IncrRefCount(idObjPtr); + Jim_AppendObj(interp, objPtr, idObjPtr); + Jim_DecrRefCount(interp, idObjPtr); + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + case AFTER_CANCEL: + if (argc < 3) { + Jim_WrongNumArgs(interp, 2, argv, "id|command"); + return JIM_ERR; + } + else { + jim_wide remain = 0; + + id = JimParseAfterId(argv[2]); + if (id < 0) { + /* Not an event id, so search by script */ + Jim_Obj *scriptObj = Jim_ConcatObj(interp, argc - 2, argv + 2); + id = JimFindAfterByScript(eventLoop, scriptObj); + Jim_FreeNewObj(interp, scriptObj); + if (id < 0) { + /* Not found */ + break; + } + } + remain = Jim_DeleteTimeHandler(interp, id); + if (remain >= 0) { + Jim_SetResultInt(interp, remain); + } + } + break; + + case AFTER_INFO: + if (argc == 2) { + Jim_TimeEvent *te = eventLoop->timeEventHead; + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + char buf[30]; + const char *fmt = "after#%" JIM_WIDE_MODIFIER; + + while (te) { + snprintf(buf, sizeof(buf), fmt, te->id); + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, buf, -1)); + te = te->next; + } + Jim_SetResult(interp, listObj); + } + else if (argc == 3) { + id = JimParseAfterId(argv[2]); + if (id >= 0) { + Jim_TimeEvent *e = JimFindTimeHandlerById(eventLoop, id); + if (e && e->timeProc == JimAfterTimeHandler) { + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, listObj, e->clientData); + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, e->initialms ? "timer" : "idle", -1)); + Jim_SetResult(interp, listObj); + return JIM_OK; + } + } + Jim_SetResultFormatted(interp, "event \"%#s\" doesn't exist", argv[2]); + return JIM_ERR; + } + else { + Jim_WrongNumArgs(interp, 2, argv, "?id?"); + return JIM_ERR; + } + break; + } + return JIM_OK; +} + +int Jim_eventloopInit(Jim_Interp *interp) +{ + Jim_EventLoop *eventLoop; + + if (Jim_PackageProvide(interp, "eventloop", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + eventLoop = Jim_Alloc(sizeof(*eventLoop)); + eventLoop->fileEventHead = NULL; + eventLoop->timeEventHead = NULL; + eventLoop->timeEventNextId = 1; + eventLoop->suppress_bgerror = 0; + Jim_SetAssocData(interp, "eventloop", JimELAssocDataDeleProc, eventLoop); + + Jim_CreateCommand(interp, "vwait", JimELVwaitCommand, eventLoop, NULL); + Jim_CreateCommand(interp, "update", JimELUpdateCommand, eventLoop, NULL); + Jim_CreateCommand(interp, "after", JimELAfterCommand, eventLoop, NULL); + + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-eventloop.h b/debuggers/openocd/jimtcl/jim-eventloop.h new file mode 100644 index 00000000..4da5408f --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-eventloop.h @@ -0,0 +1,87 @@ +/* Jim - A small embeddable Tcl interpreter + * + * Copyright 2005 Salvatore Sanfilippo + * Copyright 2005 Clemens Hintze + * Copyright 2005 patthoyts - Pat Thoyts + * Copyright 2008 oharboe - yvind Harboe - oyvind.harboe@zylin.com + * Copyright 2008 Andrew Lunn + * Copyright 2008 Duane Ellis + * Copyright 2008 Uwe Klein + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + **/ +/* ------ USAGE ------- + * + * In order to use this file from other extensions include it in every + * file where you need to call the eventloop API, also in the init + * function of your extension call Jim_ImportEventloopAPI(interp) + * after the Jim_InitExtension() call. + * + * See the UDP extension as example. + */ + + +#ifndef __JIM_EVENTLOOP_H__ +#define __JIM_EVENTLOOP_H__ + +#include + +typedef int Jim_FileProc(Jim_Interp *interp, void *clientData, int mask); +typedef int Jim_SignalProc(Jim_Interp *interp, void *clientData, void *msg); +typedef void Jim_TimeProc(Jim_Interp *interp, void *clientData); +typedef void Jim_EventFinalizerProc(Jim_Interp *interp, void *clientData); + +/* File event structure */ +#define JIM_EVENT_READABLE 1 +#define JIM_EVENT_WRITABLE 2 +#define JIM_EVENT_EXCEPTION 4 + +JIM_EXPORT void Jim_CreateFileHandler (Jim_Interp *interp, + FILE *handle, int mask, + Jim_FileProc *proc, void *clientData, + Jim_EventFinalizerProc *finalizerProc); +JIM_EXPORT void Jim_DeleteFileHandler (Jim_Interp *interp, + FILE *handle); +JIM_EXPORT jim_wide Jim_CreateTimeHandler (Jim_Interp *interp, + jim_wide milliseconds, + Jim_TimeProc *proc, void *clientData, + Jim_EventFinalizerProc *finalizerProc); +JIM_EXPORT jim_wide Jim_DeleteTimeHandler (Jim_Interp *interp, jim_wide id); + +#define JIM_FILE_EVENTS 1 +#define JIM_TIME_EVENTS 2 +#define JIM_ALL_EVENTS (JIM_FILE_EVENTS|JIM_TIME_EVENTS) +#define JIM_DONT_WAIT 4 + +JIM_EXPORT int Jim_ProcessEvents (Jim_Interp *interp, int flags); +JIM_EXPORT int Jim_EvalObjBackground (Jim_Interp *interp, Jim_Obj *scriptObjPtr); + +int Jim_eventloopInit(Jim_Interp *interp); + +#endif /* __JIM_EVENTLOOP_H__ */ diff --git a/debuggers/openocd/jimtcl/jim-exec.c b/debuggers/openocd/jimtcl/jim-exec.c new file mode 100644 index 00000000..14f6e207 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-exec.c @@ -0,0 +1,1630 @@ +/* + * (c) 2008 Steve Bennett + * + * Implements the exec command for Jim + * + * Based on code originally from Tcl 6.7 by John Ousterhout. + * From that code: + * + * The Tcl_Fork and Tcl_WaitPids procedures are based on code + * contributed by Karl Lehenbauer, Mark Diekhans and Peter + * da Silva. + * + * Copyright 1987-1991 Regents of the University of California + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies. The University of California + * makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without + * express or implied warranty. + */ + +#include +#include + +#include "jimautoconf.h" +#include + +#if (!defined(HAVE_VFORK) || !defined(HAVE_WAITPID)) && !defined(__MINGW32__) +/* Poor man's implementation of exec with system() + * The system() call *may* do command line redirection, etc. + * The standard output is not available. + * Can't redirect filehandles. + */ +static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *cmdlineObj = Jim_NewEmptyStringObj(interp); + int i, j; + int rc; + + /* Create a quoted command line */ + for (i = 1; i < argc; i++) { + int len; + const char *arg = Jim_GetString(argv[i], &len); + + if (i > 1) { + Jim_AppendString(interp, cmdlineObj, " ", 1); + } + if (strpbrk(arg, "\\\" ") == NULL) { + /* No quoting required */ + Jim_AppendString(interp, cmdlineObj, arg, len); + continue; + } + + Jim_AppendString(interp, cmdlineObj, "\"", 1); + for (j = 0; j < len; j++) { + if (arg[j] == '\\' || arg[j] == '"') { + Jim_AppendString(interp, cmdlineObj, "\\", 1); + } + Jim_AppendString(interp, cmdlineObj, &arg[j], 1); + } + Jim_AppendString(interp, cmdlineObj, "\"", 1); + } + rc = system(Jim_String(cmdlineObj)); + + Jim_FreeNewObj(interp, cmdlineObj); + + if (rc) { + Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, 0)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, rc)); + Jim_SetGlobalVariableStr(interp, "errorCode", errorCode); + return JIM_ERR; + } + + return JIM_OK; +} + +int Jim_execInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "exec", "1.0", JIM_ERRMSG)) + return JIM_ERR; + Jim_CreateCommand(interp, "exec", Jim_ExecCmd, NULL, NULL); + return JIM_OK; +} +#else +/* Full exec implementation for unix and mingw */ + +#include +#include + +#if defined(__MINGW32__) + /* XXX: Should we use this implementation for cygwin too? msvc? */ + #ifndef STRICT + #define STRICT + #endif + #define WIN32_LEAN_AND_MEAN + #include + #include + + typedef HANDLE fdtype; + typedef HANDLE pidtype; + #define JIM_BAD_FD INVALID_HANDLE_VALUE + #define JIM_BAD_PID INVALID_HANDLE_VALUE + #define JimCloseFd CloseHandle + + #define WIFEXITED(STATUS) 1 + #define WEXITSTATUS(STATUS) (STATUS) + #define WIFSIGNALED(STATUS) 0 + #define WTERMSIG(STATUS) 0 + #define WNOHANG 1 + + static fdtype JimFileno(FILE *fh); + static pidtype JimWaitPid(pidtype pid, int *status, int nohang); + static fdtype JimDupFd(fdtype infd); + static fdtype JimOpenForRead(const char *filename); + static FILE *JimFdOpenForRead(fdtype fd); + static int JimPipe(fdtype pipefd[2]); + static pidtype JimStartWinProcess(Jim_Interp *interp, char **argv, char *env, + fdtype inputId, fdtype outputId, fdtype errorId); + static int JimErrno(void); +#else + #include "jim-signal.h" + #include + #include + #include + + typedef int fdtype; + typedef int pidtype; + #define JimPipe pipe + #define JimErrno() errno + #define JIM_BAD_FD -1 + #define JIM_BAD_PID -1 + #define JimFileno fileno + #define JimReadFd read + #define JimCloseFd close + #define JimWaitPid waitpid + #define JimDupFd dup + #define JimFdOpenForRead(FD) fdopen((FD), "r") + #define JimOpenForRead(NAME) open((NAME), O_RDONLY, 0) + + #ifndef HAVE_EXECVPE + #define execvpe(ARG0, ARGV, ENV) execvp(ARG0, ARGV) + #endif +#endif + +static const char *JimStrError(void); +static char **JimSaveEnv(char **env); +static void JimRestoreEnv(char **env); +static int JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, + pidtype **pidArrayPtr, fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr); +static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr); +static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, fdtype errorId); +static fdtype JimCreateTemp(Jim_Interp *interp, const char *contents); +static fdtype JimOpenForWrite(const char *filename, int append); +static int JimRewindFd(fdtype fd); + +static void Jim_SetResultErrno(Jim_Interp *interp, const char *msg) +{ + Jim_SetResultFormatted(interp, "%s: %s", msg, JimStrError()); +} + +static const char *JimStrError(void) +{ + return strerror(JimErrno()); +} + +static void Jim_RemoveTrailingNewline(Jim_Obj *objPtr) +{ + int len; + const char *s = Jim_GetString(objPtr, &len); + + if (len > 0 && s[len - 1] == '\n') { + objPtr->length--; + objPtr->bytes[objPtr->length] = '\0'; + } +} + +/** + * Read from 'fd', append the data to strObj and close 'fd'. + * Returns JIM_OK if OK, or JIM_ERR on error. + */ +static int JimAppendStreamToString(Jim_Interp *interp, fdtype fd, Jim_Obj *strObj) +{ + char buf[256]; + FILE *fh = JimFdOpenForRead(fd); + if (fh == NULL) { + return JIM_ERR; + } + + while (1) { + int retval = fread(buf, 1, sizeof(buf), fh); + if (retval > 0) { + Jim_AppendString(interp, strObj, buf, retval); + } + if (retval != sizeof(buf)) { + break; + } + } + Jim_RemoveTrailingNewline(strObj); + fclose(fh); + return JIM_OK; +} + +/* + * If the last character of the result is a newline, then remove + * the newline character (the newline would just confuse things). + * + * Note: Ideally we could do this by just reducing the length of stringrep + * by 1, but there is no API for this :-( + */ +static void JimTrimTrailingNewline(Jim_Interp *interp) +{ + int len; + const char *p = Jim_GetString(Jim_GetResult(interp), &len); + + if (len > 0 && p[len - 1] == '\n') { + Jim_SetResultString(interp, p, len - 1); + } +} + +/** + * Builds the environment array from $::env + * + * If $::env is not set, simply returns environ. + * + * Otherwise allocates the environ array from the contents of $::env + * + * If the exec fails, memory can be freed via JimFreeEnv() + */ +static char **JimBuildEnv(Jim_Interp *interp) +{ +#if defined(jim_ext_tclcompat) + int i; + int size; + int num; + int n; + char **envptr; + char *envdata; + + Jim_Obj *objPtr = Jim_GetGlobalVariableStr(interp, "env", JIM_NONE); + + if (!objPtr) { + return Jim_GetEnviron(); + } + + /* We build the array as a single block consisting of the pointers followed by + * the strings. This has the advantage of being easy to allocate/free and being + * compatible with both unix and windows + */ + + /* Calculate the required size */ + num = Jim_ListLength(interp, objPtr); + if (num % 2) { + num--; + } + /* We need one \0 and one equal sign for each element. + * A list has at least one space for each element except the first. + * We need one extra char for the extra null terminator and one for the equal sign. + */ + size = Jim_Length(objPtr) + 2; + + envptr = Jim_Alloc(sizeof(*envptr) * (num / 2 + 1) + size); + envdata = (char *)&envptr[num / 2 + 1]; + + n = 0; + for (i = 0; i < num; i += 2) { + const char *s1, *s2; + Jim_Obj *elemObj; + + Jim_ListIndex(interp, objPtr, i, &elemObj, JIM_NONE); + s1 = Jim_String(elemObj); + Jim_ListIndex(interp, objPtr, i + 1, &elemObj, JIM_NONE); + s2 = Jim_String(elemObj); + + envptr[n] = envdata; + envdata += sprintf(envdata, "%s=%s", s1, s2); + envdata++; + n++; + } + envptr[n] = NULL; + *envdata = 0; + + return envptr; +#else + return Jim_GetEnviron(); +#endif +} + +/** + * Frees the environment allocated by JimBuildEnv() + * + * Must pass original_environ. + */ +static void JimFreeEnv(char **env, char **original_environ) +{ +#ifdef jim_ext_tclcompat + if (env != original_environ) { + Jim_Free(env); + } +#endif +} + +/* + * Create error messages for unusual process exits. An + * extra newline gets appended to each error message, but + * it gets removed below (in the same fashion that an + * extra newline in the command's output is removed). + */ +static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus) +{ + Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0); + int rc = JIM_ERR; + + if (WIFEXITED(waitStatus)) { + if (WEXITSTATUS(waitStatus) == 0) { + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "NONE", -1)); + rc = JIM_OK; + } + else { + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WEXITSTATUS(waitStatus))); + } + } + else { + const char *type; + const char *action; + + if (WIFSIGNALED(waitStatus)) { + type = "CHILDKILLED"; + action = "killed"; + } + else { + type = "CHILDSUSP"; + action = "suspended"; + } + + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, type, -1)); + +#ifdef jim_ext_signal + Jim_SetResultFormatted(interp, "child %s by signal %s", action, Jim_SignalId(WTERMSIG(waitStatus))); + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalId(WTERMSIG(waitStatus)), -1)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, pid)); + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalName(WTERMSIG(waitStatus)), -1)); +#else + Jim_SetResultFormatted(interp, "child %s by signal %d", action, WTERMSIG(waitStatus)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus))); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus))); +#endif + } + Jim_SetGlobalVariableStr(interp, "errorCode", errorCode); + return rc; +} + +/* + * Data structures of the following type are used by JimFork and + * JimWaitPids to keep track of child processes. + */ + +struct WaitInfo +{ + pidtype pid; /* Process id of child. */ + int status; /* Status returned when child exited or suspended. */ + int flags; /* Various flag bits; see below for definitions. */ +}; + +struct WaitInfoTable { + struct WaitInfo *info; + int size; + int used; +}; + +/* + * Flag bits in WaitInfo structures: + * + * WI_DETACHED - Non-zero means no-one cares about the + * process anymore. Ignore it until it + * exits, then forget about it. + */ + +#define WI_DETACHED 2 + +#define WAIT_TABLE_GROW_BY 4 + +static void JimFreeWaitInfoTable(struct Jim_Interp *interp, void *privData) +{ + struct WaitInfoTable *table = privData; + + Jim_Free(table->info); + Jim_Free(table); +} + +static struct WaitInfoTable *JimAllocWaitInfoTable(void) +{ + struct WaitInfoTable *table = Jim_Alloc(sizeof(*table)); + table->info = NULL; + table->size = table->used = 0; + + return table; +} + +/* + * The main [exec] command + */ +static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + fdtype outputId; /* File id for output pipe. -1 + * means command overrode. */ + fdtype errorId; /* File id for temporary file + * containing error output. */ + pidtype *pidPtr; + int numPids, result; + + /* + * See if the command is to be run in background; if so, create + * the command, detach it, and return. + */ + if (argc > 1 && Jim_CompareStringImmediate(interp, argv[argc - 1], "&")) { + Jim_Obj *listObj; + int i; + + argc--; + numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL); + if (numPids < 0) { + return JIM_ERR; + } + /* The return value is a list of the pids */ + listObj = Jim_NewListObj(interp, NULL, 0); + for (i = 0; i < numPids; i++) { + Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i])); + } + Jim_SetResult(interp, listObj); + JimDetachPids(interp, numPids, pidPtr); + Jim_Free(pidPtr); + return JIM_OK; + } + + /* + * Create the command's pipeline. + */ + numPids = + JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, &outputId, &errorId); + + if (numPids < 0) { + return JIM_ERR; + } + + /* + * Read the child's output (if any) and put it into the result. + */ + Jim_SetResultString(interp, "", 0); + + result = JIM_OK; + if (outputId != JIM_BAD_FD) { + result = JimAppendStreamToString(interp, outputId, Jim_GetResult(interp)); + if (result < 0) { + Jim_SetResultErrno(interp, "error reading from output pipe"); + } + } + + if (JimCleanupChildren(interp, numPids, pidPtr, errorId) != JIM_OK) { + result = JIM_ERR; + } + return result; +} + +static void JimReapDetachedPids(struct WaitInfoTable *table) +{ + struct WaitInfo *waitPtr; + int count; + + if (!table) { + return; + } + + for (waitPtr = table->info, count = table->used; count > 0; waitPtr++, count--) { + if (waitPtr->flags & WI_DETACHED) { + int status; + pidtype pid = JimWaitPid(waitPtr->pid, &status, WNOHANG); + if (pid != JIM_BAD_PID) { + if (waitPtr != &table->info[table->used - 1]) { + *waitPtr = table->info[table->used - 1]; + } + table->used--; + } + } + } +} + +/** + * Does waitpid() on the given pid, and then removes the + * entry from the wait table. + * + * Returns the pid if OK and updates *statusPtr with the status, + * or JIM_BAD_PID if the pid was not in the table. + */ +static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr) +{ + int i; + + /* Find it in the table */ + for (i = 0; i < table->used; i++) { + if (pid == table->info[i].pid) { + /* wait for it */ + JimWaitPid(pid, statusPtr, 0); + + /* Remove it from the table */ + if (i != table->used - 1) { + table->info[i] = table->info[table->used - 1]; + } + table->used--; + return pid; + } + } + + /* Not found */ + return JIM_BAD_PID; +} + +/* + *---------------------------------------------------------------------- + * + * JimDetachPids -- + * + * This procedure is called to indicate that one or more child + * processes have been placed in background and are no longer + * cared about. These children can be cleaned up with JimReapDetachedPids(). + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr) +{ + int j; + struct WaitInfoTable *table = Jim_CmdPrivData(interp); + + for (j = 0; j < numPids; j++) { + /* Find it in the table */ + int i; + for (i = 0; i < table->used; i++) { + if (pidPtr[j] == table->info[i].pid) { + table->info[i].flags |= WI_DETACHED; + break; + } + } + } +} + +static FILE *JimGetAioFilehandle(Jim_Interp *interp, const char *name) +{ + FILE *fh; + Jim_Obj *fhObj; + + fhObj = Jim_NewStringObj(interp, name, -1); + Jim_IncrRefCount(fhObj); + fh = Jim_AioFilehandle(interp, fhObj); + Jim_DecrRefCount(interp, fhObj); + + return fh; +} + +/* + *---------------------------------------------------------------------- + * + * JimCreatePipeline -- + * + * Given an argc/argv array, instantiate a pipeline of processes + * as described by the argv. + * + * Results: + * The return value is a count of the number of new processes + * created, or -1 if an error occurred while creating the pipeline. + * *pidArrayPtr is filled in with the address of a dynamically + * allocated array giving the ids of all of the processes. It + * is up to the caller to free this array when it isn't needed + * anymore. If inPipePtr is non-NULL, *inPipePtr is filled in + * with the file id for the input pipe for the pipeline (if any): + * the caller must eventually close this file. If outPipePtr + * isn't NULL, then *outPipePtr is filled in with the file id + * for the output pipe from the pipeline: the caller must close + * this file. If errFilePtr isn't NULL, then *errFilePtr is filled + * with a file id that may be used to read error output after the + * pipeline completes. + * + * Side effects: + * Processes and pipes are created. + * + *---------------------------------------------------------------------- + */ +static int +JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype **pidArrayPtr, + fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr) +{ + pidtype *pidPtr = NULL; /* Points to malloc-ed array holding all + * the pids of child processes. */ + int numPids = 0; /* Actual number of processes that exist + * at *pidPtr right now. */ + int cmdCount; /* Count of number of distinct commands + * found in argc/argv. */ + const char *input = NULL; /* Describes input for pipeline, depending + * on "inputFile". NULL means take input + * from stdin/pipe. */ + +#define FILE_NAME 0 /* input/output: filename */ +#define FILE_APPEND 1 /* output only: filename, append */ +#define FILE_HANDLE 2 /* input/output: filehandle */ +#define FILE_TEXT 3 /* input only: input is actual text */ + + int inputFile = FILE_NAME; /* 1 means input is name of input file. + * 2 means input is filehandle name. + * 0 means input holds actual + * text to be input to command. */ + + int outputFile = FILE_NAME; /* 0 means output is the name of output file. + * 1 means output is the name of output file, and append. + * 2 means output is filehandle name. + * All this is ignored if output is NULL + */ + int errorFile = FILE_NAME; /* 0 means error is the name of error file. + * 1 means error is the name of error file, and append. + * 2 means error is filehandle name. + * All this is ignored if error is NULL + */ + const char *output = NULL; /* Holds name of output file to pipe to, + * or NULL if output goes to stdout/pipe. */ + const char *error = NULL; /* Holds name of stderr file to pipe to, + * or NULL if stderr goes to stderr/pipe. */ + fdtype inputId = JIM_BAD_FD; + /* Readable file id input to current command in + * pipeline (could be file or pipe). JIM_BAD_FD + * means use stdin. */ + fdtype outputId = JIM_BAD_FD; + /* Writable file id for output from current + * command in pipeline (could be file or pipe). + * JIM_BAD_FD means use stdout. */ + fdtype errorId = JIM_BAD_FD; + /* Writable file id for all standard error + * output from all commands in pipeline. JIM_BAD_FD + * means use stderr. */ + fdtype lastOutputId = JIM_BAD_FD; + /* Write file id for output from last command + * in pipeline (could be file or pipe). + * -1 means use stdout. */ + fdtype pipeIds[2]; /* File ids for pipe that's being created. */ + int firstArg, lastArg; /* Indexes of first and last arguments in + * current command. */ + int lastBar; + int i; + pidtype pid; + char **save_environ; + struct WaitInfoTable *table = Jim_CmdPrivData(interp); + + /* Holds the args which will be used to exec */ + char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1)); + int arg_count = 0; + + JimReapDetachedPids(table); + + if (inPipePtr != NULL) { + *inPipePtr = JIM_BAD_FD; + } + if (outPipePtr != NULL) { + *outPipePtr = JIM_BAD_FD; + } + if (errFilePtr != NULL) { + *errFilePtr = JIM_BAD_FD; + } + pipeIds[0] = pipeIds[1] = JIM_BAD_FD; + + /* + * First, scan through all the arguments to figure out the structure + * of the pipeline. Count the number of distinct processes (it's the + * number of "|" arguments). If there are "<", "<<", or ">" arguments + * then make note of input and output redirection and remove these + * arguments and the arguments that follow them. + */ + cmdCount = 1; + lastBar = -1; + for (i = 0; i < argc; i++) { + const char *arg = Jim_String(argv[i]); + + if (arg[0] == '<') { + inputFile = FILE_NAME; + input = arg + 1; + if (*input == '<') { + inputFile = FILE_TEXT; + input++; + } + else if (*input == '@') { + inputFile = FILE_HANDLE; + input++; + } + + if (!*input && ++i < argc) { + input = Jim_String(argv[i]); + } + } + else if (arg[0] == '>') { + int dup_error = 0; + + outputFile = FILE_NAME; + + output = arg + 1; + if (*output == '>') { + outputFile = FILE_APPEND; + output++; + } + if (*output == '&') { + /* Redirect stderr too */ + output++; + dup_error = 1; + } + if (*output == '@') { + outputFile = FILE_HANDLE; + output++; + } + if (!*output && ++i < argc) { + output = Jim_String(argv[i]); + } + if (dup_error) { + errorFile = outputFile; + error = output; + } + } + else if (arg[0] == '2' && arg[1] == '>') { + error = arg + 2; + errorFile = FILE_NAME; + + if (*error == '@') { + errorFile = FILE_HANDLE; + error++; + } + else if (*error == '>') { + errorFile = FILE_APPEND; + error++; + } + if (!*error && ++i < argc) { + error = Jim_String(argv[i]); + } + } + else { + if (strcmp(arg, "|") == 0 || strcmp(arg, "|&") == 0) { + if (i == lastBar + 1 || i == argc - 1) { + Jim_SetResultString(interp, "illegal use of | or |& in command", -1); + goto badargs; + } + lastBar = i; + cmdCount++; + } + /* Either |, |& or a "normal" arg, so store it in the arg array */ + arg_array[arg_count++] = (char *)arg; + continue; + } + + if (i >= argc) { + Jim_SetResultFormatted(interp, "can't specify \"%s\" as last word in command", arg); + goto badargs; + } + } + + if (arg_count == 0) { + Jim_SetResultString(interp, "didn't specify command to execute", -1); +badargs: + Jim_Free(arg_array); + return -1; + } + + /* Must do this before vfork(), so do it now */ + save_environ = JimSaveEnv(JimBuildEnv(interp)); + + /* + * Set up the redirected input source for the pipeline, if + * so requested. + */ + if (input != NULL) { + if (inputFile == FILE_TEXT) { + /* + * Immediate data in command. Create temporary file and + * put data into file. + */ + inputId = JimCreateTemp(interp, input); + if (inputId == JIM_BAD_FD) { + goto error; + } + } + else if (inputFile == FILE_HANDLE) { + /* Should be a file descriptor */ + FILE *fh = JimGetAioFilehandle(interp, input); + + if (fh == NULL) { + goto error; + } + inputId = JimDupFd(JimFileno(fh)); + } + else { + /* + * File redirection. Just open the file. + */ + inputId = JimOpenForRead(input); + if (inputId == JIM_BAD_FD) { + Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", input, JimStrError()); + goto error; + } + } + } + else if (inPipePtr != NULL) { + if (JimPipe(pipeIds) != 0) { + Jim_SetResultErrno(interp, "couldn't create input pipe for command"); + goto error; + } + inputId = pipeIds[0]; + *inPipePtr = pipeIds[1]; + pipeIds[0] = pipeIds[1] = JIM_BAD_FD; + } + + /* + * Set up the redirected output sink for the pipeline from one + * of two places, if requested. + */ + if (output != NULL) { + if (outputFile == FILE_HANDLE) { + FILE *fh = JimGetAioFilehandle(interp, output); + if (fh == NULL) { + goto error; + } + fflush(fh); + lastOutputId = JimDupFd(JimFileno(fh)); + } + else { + /* + * Output is to go to a file. + */ + lastOutputId = JimOpenForWrite(output, outputFile == FILE_APPEND); + if (lastOutputId == JIM_BAD_FD) { + Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", output, JimStrError()); + goto error; + } + } + } + else if (outPipePtr != NULL) { + /* + * Output is to go to a pipe. + */ + if (JimPipe(pipeIds) != 0) { + Jim_SetResultErrno(interp, "couldn't create output pipe"); + goto error; + } + lastOutputId = pipeIds[1]; + *outPipePtr = pipeIds[0]; + pipeIds[0] = pipeIds[1] = JIM_BAD_FD; + } + /* If we are redirecting stderr with 2>filename or 2>@fileId, then we ignore errFilePtr */ + if (error != NULL) { + if (errorFile == FILE_HANDLE) { + if (strcmp(error, "1") == 0) { + /* Special 2>@1 */ + if (lastOutputId != JIM_BAD_FD) { + errorId = JimDupFd(lastOutputId); + } + else { + /* No redirection of stdout, so just use 2>@stdout */ + error = "stdout"; + } + } + if (errorId == JIM_BAD_FD) { + FILE *fh = JimGetAioFilehandle(interp, error); + if (fh == NULL) { + goto error; + } + fflush(fh); + errorId = JimDupFd(JimFileno(fh)); + } + } + else { + /* + * Output is to go to a file. + */ + errorId = JimOpenForWrite(error, errorFile == FILE_APPEND); + if (errorId == JIM_BAD_FD) { + Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", error, JimStrError()); + goto error; + } + } + } + else if (errFilePtr != NULL) { + /* + * Set up the standard error output sink for the pipeline, if + * requested. Use a temporary file which is opened, then deleted. + * Could potentially just use pipe, but if it filled up it could + * cause the pipeline to deadlock: we'd be waiting for processes + * to complete before reading stderr, and processes couldn't complete + * because stderr was backed up. + */ + errorId = JimCreateTemp(interp, NULL); + if (errorId == JIM_BAD_FD) { + goto error; + } + *errFilePtr = JimDupFd(errorId); + } + + /* + * Scan through the argc array, forking off a process for each + * group of arguments between "|" arguments. + */ + + pidPtr = Jim_Alloc(cmdCount * sizeof(*pidPtr)); + for (i = 0; i < numPids; i++) { + pidPtr[i] = JIM_BAD_PID; + } + for (firstArg = 0; firstArg < arg_count; numPids++, firstArg = lastArg + 1) { + int pipe_dup_err = 0; + fdtype origErrorId = errorId; + + for (lastArg = firstArg; lastArg < arg_count; lastArg++) { + if (arg_array[lastArg][0] == '|') { + if (arg_array[lastArg][1] == '&') { + pipe_dup_err = 1; + } + break; + } + } + /* Replace | with NULL for execv() */ + arg_array[lastArg] = NULL; + if (lastArg == arg_count) { + outputId = lastOutputId; + } + else { + if (JimPipe(pipeIds) != 0) { + Jim_SetResultErrno(interp, "couldn't create pipe"); + goto error; + } + outputId = pipeIds[1]; + } + + /* Now fork the child */ + +#ifdef __MINGW32__ + pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ ? save_environ[0] : NULL, inputId, outputId, errorId); + if (pid == JIM_BAD_PID) { + Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]); + goto error; + } +#else + /* + * Disable SIGPIPE signals: if they were allowed, this process + * might go away unexpectedly if children misbehave. This code + * can potentially interfere with other application code that + * expects to handle SIGPIPEs; what's really needed is an + * arbiter for signals to allow them to be "shared". + */ + if (table->info == NULL) { + (void)signal(SIGPIPE, SIG_IGN); + } + + /* Need to do this befor vfork() */ + if (pipe_dup_err) { + errorId = outputId; + } + + /* + * Make a new process and enter it into the table if the fork + * is successful. + */ + pid = vfork(); + if (pid < 0) { + Jim_SetResultErrno(interp, "couldn't fork child process"); + goto error; + } + if (pid == 0) { + /* Child */ + + if (inputId != -1) dup2(inputId, 0); + if (outputId != -1) dup2(outputId, 1); + if (errorId != -1) dup2(errorId, 2); + + for (i = 3; (i <= outputId) || (i <= inputId) || (i <= errorId); i++) { + close(i); + } + + execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron()); + + /* Need to prep an error message before vfork(), just in case */ + fprintf(stderr, "couldn't exec \"%s\"", arg_array[firstArg]); + _exit(127); + } +#endif + + /* parent */ + + /* + * Enlarge the wait table if there isn't enough space for a new + * entry. + */ + if (table->used == table->size) { + table->size += WAIT_TABLE_GROW_BY; + table->info = Jim_Realloc(table->info, table->size * sizeof(*table->info)); + } + + table->info[table->used].pid = pid; + table->info[table->used].flags = 0; + table->used++; + + pidPtr[numPids] = pid; + + /* Restore in case of pipe_dup_err */ + errorId = origErrorId; + + /* + * Close off our copies of file descriptors that were set up for + * this child, then set up the input for the next child. + */ + + if (inputId != JIM_BAD_FD) { + JimCloseFd(inputId); + } + if (outputId != JIM_BAD_FD) { + JimCloseFd(outputId); + } + inputId = pipeIds[0]; + pipeIds[0] = pipeIds[1] = JIM_BAD_FD; + } + *pidArrayPtr = pidPtr; + + /* + * All done. Cleanup open files lying around and then return. + */ + + cleanup: + if (inputId != JIM_BAD_FD) { + JimCloseFd(inputId); + } + if (lastOutputId != JIM_BAD_FD) { + JimCloseFd(lastOutputId); + } + if (errorId != JIM_BAD_FD) { + JimCloseFd(errorId); + } + Jim_Free(arg_array); + + JimRestoreEnv(save_environ); + + return numPids; + + /* + * An error occurred. There could have been extra files open, such + * as pipes between children. Clean them all up. Detach any child + * processes that have been created. + */ + + error: + if ((inPipePtr != NULL) && (*inPipePtr != JIM_BAD_FD)) { + JimCloseFd(*inPipePtr); + *inPipePtr = JIM_BAD_FD; + } + if ((outPipePtr != NULL) && (*outPipePtr != JIM_BAD_FD)) { + JimCloseFd(*outPipePtr); + *outPipePtr = JIM_BAD_FD; + } + if ((errFilePtr != NULL) && (*errFilePtr != JIM_BAD_FD)) { + JimCloseFd(*errFilePtr); + *errFilePtr = JIM_BAD_FD; + } + if (pipeIds[0] != JIM_BAD_FD) { + JimCloseFd(pipeIds[0]); + } + if (pipeIds[1] != JIM_BAD_FD) { + JimCloseFd(pipeIds[1]); + } + if (pidPtr != NULL) { + for (i = 0; i < numPids; i++) { + if (pidPtr[i] != JIM_BAD_PID) { + JimDetachPids(interp, 1, &pidPtr[i]); + } + } + Jim_Free(pidPtr); + } + numPids = -1; + goto cleanup; +} + +/* + *---------------------------------------------------------------------- + * + * JimCleanupChildren -- + * + * This is a utility procedure used to wait for child processes + * to exit, record information about abnormal exits, and then + * collect any stderr output generated by them. + * + * Results: + * The return value is a standard Tcl result. If anything at + * weird happened with the child processes, JIM_ERROR is returned + * and a message is left in interp->result. + * + * Side effects: + * If the last character of interp->result is a newline, then it + * is removed. File errorId gets closed, and pidPtr is freed + * back to the storage allocator. + * + *---------------------------------------------------------------------- + */ + +static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, fdtype errorId) +{ + struct WaitInfoTable *table = Jim_CmdPrivData(interp); + int result = JIM_OK; + int i; + + for (i = 0; i < numPids; i++) { + int waitStatus = 0; + if (JimWaitForProcess(table, pidPtr[i], &waitStatus) != JIM_BAD_PID) { + if (JimCheckWaitStatus(interp, pidPtr[i], waitStatus) != JIM_OK) { + result = JIM_ERR; + } + } + } + Jim_Free(pidPtr); + + /* + * Read the standard error file. If there's anything there, + * then add the file's contents to the result + * string. + */ + if (errorId != JIM_BAD_FD) { + JimRewindFd(errorId); + if (JimAppendStreamToString(interp, errorId, Jim_GetResult(interp)) != JIM_OK) { + result = JIM_ERR; + } + } + + JimTrimTrailingNewline(interp); + + return result; +} + +int Jim_execInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "exec", "1.0", JIM_ERRMSG)) + return JIM_ERR; + Jim_CreateCommand(interp, "exec", Jim_ExecCmd, JimAllocWaitInfoTable(), JimFreeWaitInfoTable); + return JIM_OK; +} + +#if defined(__MINGW32__) +/* Windows-specific (mingw) implementation */ + +static SECURITY_ATTRIBUTES *JimStdSecAttrs(void) +{ + static SECURITY_ATTRIBUTES secAtts; + + secAtts.nLength = sizeof(SECURITY_ATTRIBUTES); + secAtts.lpSecurityDescriptor = NULL; + secAtts.bInheritHandle = TRUE; + return &secAtts; +} + +static int JimErrno(void) +{ + switch (GetLastError()) { + case ERROR_FILE_NOT_FOUND: return ENOENT; + case ERROR_PATH_NOT_FOUND: return ENOENT; + case ERROR_TOO_MANY_OPEN_FILES: return EMFILE; + case ERROR_ACCESS_DENIED: return EACCES; + case ERROR_INVALID_HANDLE: return EBADF; + case ERROR_BAD_ENVIRONMENT: return E2BIG; + case ERROR_BAD_FORMAT: return ENOEXEC; + case ERROR_INVALID_ACCESS: return EACCES; + case ERROR_INVALID_DRIVE: return ENOENT; + case ERROR_CURRENT_DIRECTORY: return EACCES; + case ERROR_NOT_SAME_DEVICE: return EXDEV; + case ERROR_NO_MORE_FILES: return ENOENT; + case ERROR_WRITE_PROTECT: return EROFS; + case ERROR_BAD_UNIT: return ENXIO; + case ERROR_NOT_READY: return EBUSY; + case ERROR_BAD_COMMAND: return EIO; + case ERROR_CRC: return EIO; + case ERROR_BAD_LENGTH: return EIO; + case ERROR_SEEK: return EIO; + case ERROR_WRITE_FAULT: return EIO; + case ERROR_READ_FAULT: return EIO; + case ERROR_GEN_FAILURE: return EIO; + case ERROR_SHARING_VIOLATION: return EACCES; + case ERROR_LOCK_VIOLATION: return EACCES; + case ERROR_SHARING_BUFFER_EXCEEDED: return ENFILE; + case ERROR_HANDLE_DISK_FULL: return ENOSPC; + case ERROR_NOT_SUPPORTED: return ENODEV; + case ERROR_REM_NOT_LIST: return EBUSY; + case ERROR_DUP_NAME: return EEXIST; + case ERROR_BAD_NETPATH: return ENOENT; + case ERROR_NETWORK_BUSY: return EBUSY; + case ERROR_DEV_NOT_EXIST: return ENODEV; + case ERROR_TOO_MANY_CMDS: return EAGAIN; + case ERROR_ADAP_HDW_ERR: return EIO; + case ERROR_BAD_NET_RESP: return EIO; + case ERROR_UNEXP_NET_ERR: return EIO; + case ERROR_NETNAME_DELETED: return ENOENT; + case ERROR_NETWORK_ACCESS_DENIED: return EACCES; + case ERROR_BAD_DEV_TYPE: return ENODEV; + case ERROR_BAD_NET_NAME: return ENOENT; + case ERROR_TOO_MANY_NAMES: return ENFILE; + case ERROR_TOO_MANY_SESS: return EIO; + case ERROR_SHARING_PAUSED: return EAGAIN; + case ERROR_REDIR_PAUSED: return EAGAIN; + case ERROR_FILE_EXISTS: return EEXIST; + case ERROR_CANNOT_MAKE: return ENOSPC; + case ERROR_OUT_OF_STRUCTURES: return ENFILE; + case ERROR_ALREADY_ASSIGNED: return EEXIST; + case ERROR_INVALID_PASSWORD: return EPERM; + case ERROR_NET_WRITE_FAULT: return EIO; + case ERROR_NO_PROC_SLOTS: return EAGAIN; + case ERROR_DISK_CHANGE: return EXDEV; + case ERROR_BROKEN_PIPE: return EPIPE; + case ERROR_OPEN_FAILED: return ENOENT; + case ERROR_DISK_FULL: return ENOSPC; + case ERROR_NO_MORE_SEARCH_HANDLES: return EMFILE; + case ERROR_INVALID_TARGET_HANDLE: return EBADF; + case ERROR_INVALID_NAME: return ENOENT; + case ERROR_PROC_NOT_FOUND: return ESRCH; + case ERROR_WAIT_NO_CHILDREN: return ECHILD; + case ERROR_CHILD_NOT_COMPLETE: return ECHILD; + case ERROR_DIRECT_ACCESS_HANDLE: return EBADF; + case ERROR_SEEK_ON_DEVICE: return ESPIPE; + case ERROR_BUSY_DRIVE: return EAGAIN; + case ERROR_DIR_NOT_EMPTY: return EEXIST; + case ERROR_NOT_LOCKED: return EACCES; + case ERROR_BAD_PATHNAME: return ENOENT; + case ERROR_LOCK_FAILED: return EACCES; + case ERROR_ALREADY_EXISTS: return EEXIST; + case ERROR_FILENAME_EXCED_RANGE: return ENAMETOOLONG; + case ERROR_BAD_PIPE: return EPIPE; + case ERROR_PIPE_BUSY: return EAGAIN; + case ERROR_PIPE_NOT_CONNECTED: return EPIPE; + case ERROR_DIRECTORY: return ENOTDIR; + } + return EINVAL; +} + +static int JimPipe(fdtype pipefd[2]) +{ + if (CreatePipe(&pipefd[0], &pipefd[1], NULL, 0)) { + return 0; + } + return -1; +} + +static fdtype JimDupFd(fdtype infd) +{ + fdtype dupfd; + pidtype pid = GetCurrentProcess(); + + if (DuplicateHandle(pid, infd, pid, &dupfd, 0, TRUE, DUPLICATE_SAME_ACCESS)) { + return dupfd; + } + return JIM_BAD_FD; +} + +static int JimRewindFd(fdtype fd) +{ + return SetFilePointer(fd, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER ? -1 : 0; +} + +#if 0 +static int JimReadFd(fdtype fd, char *buffer, size_t len) +{ + DWORD num; + + if (ReadFile(fd, buffer, len, &num, NULL)) { + return num; + } + if (GetLastError() == ERROR_HANDLE_EOF || GetLastError() == ERROR_BROKEN_PIPE) { + return 0; + } + return -1; +} +#endif + +static FILE *JimFdOpenForRead(fdtype fd) +{ + return _fdopen(_open_osfhandle((int)fd, _O_RDONLY | _O_TEXT), "r"); +} + +static fdtype JimFileno(FILE *fh) +{ + return (fdtype)_get_osfhandle(_fileno(fh)); +} + +static fdtype JimOpenForRead(const char *filename) +{ + return CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + JimStdSecAttrs(), OPEN_EXISTING, 0, NULL); +} + +static fdtype JimOpenForWrite(const char *filename, int append) +{ + return CreateFile(filename, append ? FILE_APPEND_DATA : GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, 0, (HANDLE) NULL); +} + +static FILE *JimFdOpenForWrite(fdtype fd) +{ + return _fdopen(_open_osfhandle((int)fd, _O_TEXT), "w"); +} + +static pidtype JimWaitPid(pidtype pid, int *status, int nohang) +{ + DWORD ret = WaitForSingleObject(pid, nohang ? 0 : INFINITE); + if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED) { + /* WAIT_TIMEOUT can only happend with WNOHANG */ + return JIM_BAD_PID; + } + GetExitCodeProcess(pid, &ret); + *status = ret; + CloseHandle(pid); + return pid; +} + +static HANDLE JimCreateTemp(Jim_Interp *interp, const char *contents) +{ + char name[MAX_PATH]; + HANDLE handle; + + if (!GetTempPath(MAX_PATH, name) || !GetTempFileName(name, "JIM", 0, name)) { + return JIM_BAD_FD; + } + + handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, JimStdSecAttrs(), + CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, + NULL); + + if (handle == INVALID_HANDLE_VALUE) { + goto error; + } + + if (contents != NULL) { + /* Use fdopen() to get automatic text-mode translation */ + FILE *fh = JimFdOpenForWrite(JimDupFd(handle)); + if (fh == NULL) { + goto error; + } + + if (fwrite(contents, strlen(contents), 1, fh) != 1) { + fclose(fh); + goto error; + } + fseek(fh, 0, SEEK_SET); + fclose(fh); + } + return handle; + + error: + Jim_SetResultErrno(interp, "failed to create temp file"); + CloseHandle(handle); + DeleteFile(name); + return JIM_BAD_FD; +} + +static int +JimWinFindExecutable(const char *originalName, char fullPath[MAX_PATH]) +{ + int i; + static char extensions[][5] = {".exe", "", ".bat"}; + + for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) { + lstrcpyn(fullPath, originalName, MAX_PATH - 5); + lstrcat(fullPath, extensions[i]); + + if (SearchPath(NULL, fullPath, NULL, MAX_PATH, fullPath, NULL) == 0) { + continue; + } + if (GetFileAttributes(fullPath) & FILE_ATTRIBUTE_DIRECTORY) { + continue; + } + return 0; + } + + return -1; +} + +static char **JimSaveEnv(char **env) +{ + return env; +} + +static void JimRestoreEnv(char **env) +{ + JimFreeEnv(env, Jim_GetEnviron()); +} + +static Jim_Obj * +JimWinBuildCommandLine(Jim_Interp *interp, char **argv) +{ + char *start, *special; + int quote, i; + + Jim_Obj *strObj = Jim_NewStringObj(interp, "", 0); + + for (i = 0; argv[i]; i++) { + if (i > 0) { + Jim_AppendString(interp, strObj, " ", 1); + } + + if (argv[i][0] == '\0') { + quote = 1; + } + else { + quote = 0; + for (start = argv[i]; *start != '\0'; start++) { + if (isspace(UCHAR(*start))) { + quote = 1; + break; + } + } + } + if (quote) { + Jim_AppendString(interp, strObj, "\"" , 1); + } + + start = argv[i]; + for (special = argv[i]; ; ) { + if ((*special == '\\') && (special[1] == '\\' || + special[1] == '"' || (quote && special[1] == '\0'))) { + Jim_AppendString(interp, strObj, start, special - start); + start = special; + while (1) { + special++; + if (*special == '"' || (quote && *special == '\0')) { + /* + * N backslashes followed a quote -> insert + * N * 2 + 1 backslashes then a quote. + */ + + Jim_AppendString(interp, strObj, start, special - start); + break; + } + if (*special != '\\') { + break; + } + } + Jim_AppendString(interp, strObj, start, special - start); + start = special; + } + if (*special == '"') { + if (special == start) { + Jim_AppendString(interp, strObj, "\"", 1); + } + else { + Jim_AppendString(interp, strObj, start, special - start); + } + Jim_AppendString(interp, strObj, "\\\"", 2); + start = special + 1; + } + if (*special == '\0') { + break; + } + special++; + } + Jim_AppendString(interp, strObj, start, special - start); + if (quote) { + Jim_AppendString(interp, strObj, "\"", 1); + } + } + return strObj; +} + +static pidtype +JimStartWinProcess(Jim_Interp *interp, char **argv, char *env, fdtype inputId, fdtype outputId, fdtype errorId) +{ + STARTUPINFO startInfo; + PROCESS_INFORMATION procInfo; + HANDLE hProcess, h; + char execPath[MAX_PATH]; + char *originalName; + pidtype pid = JIM_BAD_PID; + Jim_Obj *cmdLineObj; + + if (JimWinFindExecutable(argv[0], execPath) < 0) { + return JIM_BAD_PID; + } + originalName = argv[0]; + argv[0] = execPath; + + hProcess = GetCurrentProcess(); + cmdLineObj = JimWinBuildCommandLine(interp, argv); + + /* + * STARTF_USESTDHANDLES must be used to pass handles to child process. + * Using SetStdHandle() and/or dup2() only works when a console mode + * parent process is spawning an attached console mode child process. + */ + + ZeroMemory(&startInfo, sizeof(startInfo)); + startInfo.cb = sizeof(startInfo); + startInfo.dwFlags = STARTF_USESTDHANDLES; + startInfo.hStdInput = INVALID_HANDLE_VALUE; + startInfo.hStdOutput= INVALID_HANDLE_VALUE; + startInfo.hStdError = INVALID_HANDLE_VALUE; + + /* + * Duplicate all the handles which will be passed off as stdin, stdout + * and stderr of the child process. The duplicate handles are set to + * be inheritable, so the child process can use them. + */ + if (inputId == JIM_BAD_FD) { + if (CreatePipe(&startInfo.hStdInput, &h, JimStdSecAttrs(), 0) != FALSE) { + CloseHandle(h); + } + } else { + DuplicateHandle(hProcess, inputId, hProcess, &startInfo.hStdInput, + 0, TRUE, DUPLICATE_SAME_ACCESS); + } + if (startInfo.hStdInput == JIM_BAD_FD) { + goto end; + } + + if (outputId == JIM_BAD_FD) { + startInfo.hStdOutput = CreateFile("NUL:", GENERIC_WRITE, 0, + JimStdSecAttrs(), OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + } else { + DuplicateHandle(hProcess, outputId, hProcess, &startInfo.hStdOutput, + 0, TRUE, DUPLICATE_SAME_ACCESS); + } + if (startInfo.hStdOutput == JIM_BAD_FD) { + goto end; + } + + if (errorId == JIM_BAD_FD) { + /* + * If handle was not set, errors should be sent to an infinitely + * deep sink. + */ + + startInfo.hStdError = CreateFile("NUL:", GENERIC_WRITE, 0, + JimStdSecAttrs(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + } else { + DuplicateHandle(hProcess, errorId, hProcess, &startInfo.hStdError, + 0, TRUE, DUPLICATE_SAME_ACCESS); + } + if (startInfo.hStdError == JIM_BAD_FD) { + goto end; + } + + if (!CreateProcess(NULL, (char *)Jim_String(cmdLineObj), NULL, NULL, TRUE, + 0, env, NULL, &startInfo, &procInfo)) { + goto end; + } + + /* + * "When an application spawns a process repeatedly, a new thread + * instance will be created for each process but the previous + * instances may not be cleaned up. This results in a significant + * virtual memory loss each time the process is spawned. If there + * is a WaitForInputIdle() call between CreateProcess() and + * CloseHandle(), the problem does not occur." PSS ID Number: Q124121 + */ + + WaitForInputIdle(procInfo.hProcess, 5000); + CloseHandle(procInfo.hThread); + + pid = procInfo.hProcess; + + end: + Jim_FreeNewObj(interp, cmdLineObj); + if (startInfo.hStdInput != JIM_BAD_FD) { + CloseHandle(startInfo.hStdInput); + } + if (startInfo.hStdOutput != JIM_BAD_FD) { + CloseHandle(startInfo.hStdOutput); + } + if (startInfo.hStdError != JIM_BAD_FD) { + CloseHandle(startInfo.hStdError); + } + return pid; +} +#else +/* Unix-specific implementation */ +static int JimOpenForWrite(const char *filename, int append) +{ + return open(filename, O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC), 0666); +} + +static int JimRewindFd(int fd) +{ + return lseek(fd, 0L, SEEK_SET); +} + +static int JimCreateTemp(Jim_Interp *interp, const char *contents) +{ + char inName[] = "/tmp/tcl.tmp.XXXXXX"; + + int fd = mkstemp(inName); + if (fd == JIM_BAD_FD) { + Jim_SetResultErrno(interp, "couldn't create temp file"); + return -1; + } + unlink(inName); + if (contents) { + int length = strlen(contents); + if (write(fd, contents, length) != length) { + Jim_SetResultErrno(interp, "couldn't write temp file"); + close(fd); + return -1; + } + lseek(fd, 0L, SEEK_SET); + } + return fd; +} + +static char **JimSaveEnv(char **env) +{ + char **saveenv = Jim_GetEnviron(); + Jim_SetEnviron(env); + return saveenv; +} + +static void JimRestoreEnv(char **env) +{ + JimFreeEnv(Jim_GetEnviron(), env); + Jim_SetEnviron(env); +} +#endif +#endif diff --git a/debuggers/openocd/jimtcl/jim-file.c b/debuggers/openocd/jimtcl/jim-file.c new file mode 100644 index 00000000..6b834a29 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-file.c @@ -0,0 +1,958 @@ +/* + * Implements the file command for jim + * + * (c) 2008 Steve Bennett + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + * + * Based on code originally from Tcl 6.7: + * + * Copyright 1987-1991 Regents of the University of California + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies. The University of California + * makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without + * express or implied warranty. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef HAVE_UTIMES +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#elif defined(_MSC_VER) +#include +#define F_OK 0 +#define W_OK 2 +#define R_OK 4 +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +# ifndef MAXPATHLEN +# define MAXPATHLEN JIM_PATH_LEN +# endif + +/* + *---------------------------------------------------------------------- + * + * JimGetFileType -- + * + * Given a mode word, returns a string identifying the type of a + * file. + * + * Results: + * A static text string giving the file type from mode. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static const char *JimGetFileType(int mode) +{ + if (S_ISREG(mode)) { + return "file"; + } + else if (S_ISDIR(mode)) { + return "directory"; + } +#ifdef S_ISCHR + else if (S_ISCHR(mode)) { + return "characterSpecial"; + } +#endif +#ifdef S_ISBLK + else if (S_ISBLK(mode)) { + return "blockSpecial"; + } +#endif +#ifdef S_ISFIFO + else if (S_ISFIFO(mode)) { + return "fifo"; + } +#endif +#ifdef S_ISLNK + else if (S_ISLNK(mode)) { + return "link"; + } +#endif +#ifdef S_ISSOCK + else if (S_ISSOCK(mode)) { + return "socket"; + } +#endif + return "unknown"; +} + +/* + *---------------------------------------------------------------------- + * + * StoreStatData -- + * + * This is a utility procedure that breaks out the fields of a + * "stat" structure and stores them in textual form into the + * elements of an associative array. + * + * Results: + * Returns a standard Tcl return value. If an error occurs then + * a message is left in interp->result. + * + * Side effects: + * Elements of the associative array given by "varName" are modified. + * + *---------------------------------------------------------------------- + */ + +static int set_array_int_value(Jim_Interp *interp, Jim_Obj *container, const char *key, + jim_wide value) +{ + Jim_Obj *nameobj = Jim_NewStringObj(interp, key, -1); + Jim_Obj *valobj = Jim_NewWideObj(interp, value); + + if (Jim_SetDictKeysVector(interp, container, &nameobj, 1, valobj, JIM_ERRMSG) != JIM_OK) { + Jim_FreeObj(interp, nameobj); + Jim_FreeObj(interp, valobj); + return JIM_ERR; + } + return JIM_OK; +} + +static int set_array_string_value(Jim_Interp *interp, Jim_Obj *container, const char *key, + const char *value) +{ + Jim_Obj *nameobj = Jim_NewStringObj(interp, key, -1); + Jim_Obj *valobj = Jim_NewStringObj(interp, value, -1); + + if (Jim_SetDictKeysVector(interp, container, &nameobj, 1, valobj, JIM_ERRMSG) != JIM_OK) { + Jim_FreeObj(interp, nameobj); + Jim_FreeObj(interp, valobj); + return JIM_ERR; + } + return JIM_OK; +} + +static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb) +{ + if (set_array_int_value(interp, varName, "dev", sb->st_dev) != JIM_OK) { + Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName); + return JIM_ERR; + } + set_array_int_value(interp, varName, "ino", sb->st_ino); + set_array_int_value(interp, varName, "mode", sb->st_mode); + set_array_int_value(interp, varName, "nlink", sb->st_nlink); + set_array_int_value(interp, varName, "uid", sb->st_uid); + set_array_int_value(interp, varName, "gid", sb->st_gid); + set_array_int_value(interp, varName, "size", sb->st_size); + set_array_int_value(interp, varName, "atime", sb->st_atime); + set_array_int_value(interp, varName, "mtime", sb->st_mtime); + set_array_int_value(interp, varName, "ctime", sb->st_ctime); + set_array_string_value(interp, varName, "type", JimGetFileType((int)sb->st_mode)); + + /* And also return the value */ + Jim_SetResult(interp, Jim_GetVariable(interp, varName, 0)); + + return JIM_OK; +} + +static int file_cmd_dirname(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + const char *p = strrchr(path, '/'); + + if (!p && path[0] == '.' && path[1] == '.' && path[2] == '\0') { + Jim_SetResultString(interp, "..", -1); + } else if (!p) { + Jim_SetResultString(interp, ".", -1); + } + else if (p == path) { + Jim_SetResultString(interp, "/", -1); + } +#if defined(__MINGW32__) || defined(_MSC_VER) + else if (p[-1] == ':') { + /* z:/dir => z:/ */ + Jim_SetResultString(interp, path, p - path + 1); + } +#endif + else { + Jim_SetResultString(interp, path, p - path); + } + return JIM_OK; +} + +static int file_cmd_rootname(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + const char *lastSlash = strrchr(path, '/'); + const char *p = strrchr(path, '.'); + + if (p == NULL || (lastSlash != NULL && lastSlash > p)) { + Jim_SetResult(interp, argv[0]); + } + else { + Jim_SetResultString(interp, path, p - path); + } + return JIM_OK; +} + +static int file_cmd_extension(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + const char *lastSlash = strrchr(path, '/'); + const char *p = strrchr(path, '.'); + + if (p == NULL || (lastSlash != NULL && lastSlash >= p)) { + p = ""; + } + Jim_SetResultString(interp, p, -1); + return JIM_OK; +} + +static int file_cmd_tail(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + const char *lastSlash = strrchr(path, '/'); + + if (lastSlash) { + Jim_SetResultString(interp, lastSlash + 1, -1); + } + else { + Jim_SetResult(interp, argv[0]); + } + return JIM_OK; +} + +static int file_cmd_normalize(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ +#ifdef HAVE_REALPATH + const char *path = Jim_String(argv[0]); + char *newname = Jim_Alloc(MAXPATHLEN + 1); + + if (realpath(path, newname)) { + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, -1)); + return JIM_OK; + } + else { + Jim_Free(newname); + Jim_SetResultFormatted(interp, "can't normalize \"%#s\": %s", argv[0], strerror(errno)); + return JIM_ERR; + } +#else + Jim_SetResultString(interp, "Not implemented", -1); + return JIM_ERR; +#endif +} + +static int file_cmd_join(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + char *newname = Jim_Alloc(MAXPATHLEN + 1); + char *last = newname; + + *newname = 0; + + /* Simple implementation for now */ + for (i = 0; i < argc; i++) { + int len; + const char *part = Jim_GetString(argv[i], &len); + + if (*part == '/') { + /* Absolute component, so go back to the start */ + last = newname; + } +#if defined(__MINGW32__) || defined(_MSC_VER) + else if (strchr(part, ':')) { + /* Absolute compontent on mingw, so go back to the start */ + last = newname; + } +#endif + else if (part[0] == '.') { + if (part[1] == '/') { + part += 2; + len -= 2; + } + else if (part[1] == 0 && last != newname) { + /* Adding '.' to an existing path does nothing */ + continue; + } + } + + /* Add a slash if needed */ + if (last != newname && last[-1] != '/') { + *last++ = '/'; + } + + if (len) { + if (last + len - newname >= MAXPATHLEN) { + Jim_Free(newname); + Jim_SetResultString(interp, "Path too long", -1); + return JIM_ERR; + } + memcpy(last, part, len); + last += len; + } + + /* Remove a slash if needed */ + if (last > newname + 1 && last[-1] == '/') { + *--last = 0; + } + } + + *last = 0; + + /* Probably need to handle some special cases ... */ + + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname)); + + return JIM_OK; +} + +static int file_access(Jim_Interp *interp, Jim_Obj *filename, int mode) +{ + const char *path = Jim_String(filename); + int rc = access(path, mode); + + Jim_SetResultBool(interp, rc != -1); + + return JIM_OK; +} + +static int file_cmd_readable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return file_access(interp, argv[0], R_OK); +} + +static int file_cmd_writable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return file_access(interp, argv[0], W_OK); +} + +static int file_cmd_executable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ +#ifdef X_OK + return file_access(interp, argv[0], X_OK); +#else + /* XXX: X_OK doesn't work under Windows. + * In any case, may need to add .exe, etc. so just lie! + */ + Jim_SetResultBool(interp, 1); + return JIM_OK; +#endif +} + +static int file_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return file_access(interp, argv[0], F_OK); +} + +static int file_cmd_delete(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int force = Jim_CompareStringImmediate(interp, argv[0], "-force"); + + if (force || Jim_CompareStringImmediate(interp, argv[0], "--")) { + argc++; + argv--; + } + + while (argc--) { + const char *path = Jim_String(argv[0]); + + if (unlink(path) == -1 && errno != ENOENT) { + if (rmdir(path) == -1) { + /* Maybe try using the script helper */ + if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) { + Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path, + strerror(errno)); + return JIM_ERR; + } + } + } + argv++; + } + return JIM_OK; +} + +#ifdef HAVE_MKDIR_ONE_ARG +#define MKDIR_DEFAULT(PATHNAME) mkdir(PATHNAME) +#else +#define MKDIR_DEFAULT(PATHNAME) mkdir(PATHNAME, 0755) +#endif + +/** + * Create directory, creating all intermediate paths if necessary. + * + * Returns 0 if OK or -1 on failure (and sets errno) + * + * Note: The path may be modified. + */ +static int mkdir_all(char *path) +{ + int ok = 1; + + /* First time just try to make the dir */ + goto first; + + while (ok--) { + /* Must have failed the first time, so recursively make the parent and try again */ + { + char *slash = strrchr(path, '/'); + + if (slash && slash != path) { + *slash = 0; + if (mkdir_all(path) != 0) { + return -1; + } + *slash = '/'; + } + } + first: + if (MKDIR_DEFAULT(path) == 0) { + return 0; + } + if (errno == ENOENT) { + /* Create the parent and try again */ + continue; + } + /* Maybe it already exists as a directory */ + if (errno == EEXIST) { + struct stat sb; + + if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { + return 0; + } + /* Restore errno */ + errno = EEXIST; + } + /* Failed */ + break; + } + return -1; +} + +static int file_cmd_mkdir(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + while (argc--) { + char *path = Jim_StrDup(Jim_String(argv[0])); + int rc = mkdir_all(path); + + Jim_Free(path); + if (rc != 0) { + Jim_SetResultFormatted(interp, "can't create directory \"%#s\": %s", argv[0], + strerror(errno)); + return JIM_ERR; + } + argv++; + } + return JIM_OK; +} + +#ifdef HAVE_MKSTEMP +static int file_cmd_tempfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int fd; + char *filename; + const char *template = "/tmp/tcl.tmp.XXXXXX"; + + if (argc >= 1) { + template = Jim_String(argv[0]); + } + filename = Jim_StrDup(template); + + fd = mkstemp(filename); + if (fd < 0) { + Jim_SetResultString(interp, "Failed to create tempfile", -1); + return JIM_ERR; + } + close(fd); + + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, filename, -1)); + return JIM_OK; +} +#endif + +static int file_cmd_rename(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *source; + const char *dest; + int force = 0; + + if (argc == 3) { + if (!Jim_CompareStringImmediate(interp, argv[0], "-force")) { + return -1; + } + force++; + argv++; + argc--; + } + + source = Jim_String(argv[0]); + dest = Jim_String(argv[1]); + + if (!force && access(dest, F_OK) == 0) { + Jim_SetResultFormatted(interp, "error renaming \"%#s\" to \"%#s\": target exists", argv[0], + argv[1]); + return JIM_ERR; + } + + if (rename(source, dest) != 0) { + Jim_SetResultFormatted(interp, "error renaming \"%#s\" to \"%#s\": %s", argv[0], argv[1], + strerror(errno)); + return JIM_ERR; + } + + return JIM_OK; +} + +static int file_stat(Jim_Interp *interp, Jim_Obj *filename, struct stat *sb) +{ + const char *path = Jim_String(filename); + + if (stat(path, sb) == -1) { + Jim_SetResultFormatted(interp, "could not read \"%#s\": %s", filename, strerror(errno)); + return JIM_ERR; + } + return JIM_OK; +} + +#ifndef HAVE_LSTAT +#define lstat stat +#endif + +static int file_lstat(Jim_Interp *interp, Jim_Obj *filename, struct stat *sb) +{ + const char *path = Jim_String(filename); + + if (lstat(path, sb) == -1) { + Jim_SetResultFormatted(interp, "could not read \"%#s\": %s", filename, strerror(errno)); + return JIM_ERR; + } + return JIM_OK; +} + +static int file_cmd_atime(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultInt(interp, sb.st_atime); + return JIM_OK; +} + +static int file_cmd_mtime(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + + if (argc == 2) { +#ifdef HAVE_UTIMES + jim_wide newtime; + struct timeval times[2]; + + if (Jim_GetWide(interp, argv[1], &newtime) != JIM_OK) { + return JIM_ERR; + } + + times[1].tv_sec = times[0].tv_sec = newtime; + times[1].tv_usec = times[0].tv_usec = 0; + + if (utimes(Jim_String(argv[0]), times) != 0) { + Jim_SetResultFormatted(interp, "can't set time on \"%#s\": %s", argv[0], strerror(errno)); + return JIM_ERR; + } +#else + Jim_SetResultString(interp, "Not implemented", -1); + return JIM_ERR; +#endif + } + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultInt(interp, sb.st_mtime); + return JIM_OK; +} + +static int file_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return Jim_EvalPrefix(interp, "file copy", argc, argv); +} + +static int file_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultInt(interp, sb.st_size); + return JIM_OK; +} + +static int file_cmd_isdirectory(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + int ret = 0; + + if (file_stat(interp, argv[0], &sb) == JIM_OK) { + ret = S_ISDIR(sb.st_mode); + } + Jim_SetResultInt(interp, ret); + return JIM_OK; +} + +static int file_cmd_isfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + int ret = 0; + + if (file_stat(interp, argv[0], &sb) == JIM_OK) { + ret = S_ISREG(sb.st_mode); + } + Jim_SetResultInt(interp, ret); + return JIM_OK; +} + +#ifdef HAVE_GETEUID +static int file_cmd_owned(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + int ret = 0; + + if (file_stat(interp, argv[0], &sb) == JIM_OK) { + ret = (geteuid() == sb.st_uid); + } + Jim_SetResultInt(interp, ret); + return JIM_OK; +} +#endif + +#if defined(HAVE_READLINK) +static int file_cmd_readlink(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + char *linkValue = Jim_Alloc(MAXPATHLEN + 1); + + int linkLength = readlink(path, linkValue, MAXPATHLEN); + + if (linkLength == -1) { + Jim_Free(linkValue); + Jim_SetResultFormatted(interp, "couldn't readlink \"%#s\": %s", argv[0], strerror(errno)); + return JIM_ERR; + } + linkValue[linkLength] = 0; + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, linkValue, linkLength)); + return JIM_OK; +} +#endif + +static int file_cmd_type(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + + if (file_lstat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultString(interp, JimGetFileType((int)sb.st_mode), -1); + return JIM_OK; +} + +static int file_cmd_lstat(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + + if (file_lstat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + return StoreStatData(interp, argv[1], &sb); +} + +static int file_cmd_stat(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; + + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + return StoreStatData(interp, argv[1], &sb); +} + +static const jim_subcmd_type file_command_table[] = { + { "atime", + "name", + file_cmd_atime, + 1, + 1, + /* Description: Last access time */ + }, + { "mtime", + "name ?time?", + file_cmd_mtime, + 1, + 2, + /* Description: Get or set last modification time */ + }, + { "copy", + "?-force? source dest", + file_cmd_copy, + 2, + 3, + /* Description: Copy source file to destination file */ + }, + { "dirname", + "name", + file_cmd_dirname, + 1, + 1, + /* Description: Directory part of the name */ + }, + { "rootname", + "name", + file_cmd_rootname, + 1, + 1, + /* Description: Name without any extension */ + }, + { "extension", + "name", + file_cmd_extension, + 1, + 1, + /* Description: Last extension including the dot */ + }, + { "tail", + "name", + file_cmd_tail, + 1, + 1, + /* Description: Last component of the name */ + }, + { "normalize", + "name", + file_cmd_normalize, + 1, + 1, + /* Description: Normalized path of name */ + }, + { "join", + "name ?name ...?", + file_cmd_join, + 1, + -1, + /* Description: Join multiple path components */ + }, + { "readable", + "name", + file_cmd_readable, + 1, + 1, + /* Description: Is file readable */ + }, + { "writable", + "name", + file_cmd_writable, + 1, + 1, + /* Description: Is file writable */ + }, + { "executable", + "name", + file_cmd_executable, + 1, + 1, + /* Description: Is file executable */ + }, + { "exists", + "name", + file_cmd_exists, + 1, + 1, + /* Description: Does file exist */ + }, + { "delete", + "?-force|--? name ...", + file_cmd_delete, + 1, + -1, + /* Description: Deletes the files or directories (must be empty unless -force) */ + }, + { "mkdir", + "dir ...", + file_cmd_mkdir, + 1, + -1, + /* Description: Creates the directories */ + }, +#ifdef HAVE_MKSTEMP + { "tempfile", + "?template?", + file_cmd_tempfile, + 0, + 1, + /* Description: Creates a temporary filename */ + }, +#endif + { "rename", + "?-force? source dest", + file_cmd_rename, + 2, + 3, + /* Description: Renames a file */ + }, +#if defined(HAVE_READLINK) + { "readlink", + "name", + file_cmd_readlink, + 1, + 1, + /* Description: Value of the symbolic link */ + }, +#endif + { "size", + "name", + file_cmd_size, + 1, + 1, + /* Description: Size of file */ + }, + { "stat", + "name var", + file_cmd_stat, + 2, + 2, + /* Description: Stores results of stat in var array */ + }, + { "lstat", + "name var", + file_cmd_lstat, + 2, + 2, + /* Description: Stores results of lstat in var array */ + }, + { "type", + "name", + file_cmd_type, + 1, + 1, + /* Description: Returns type of the file */ + }, +#ifdef HAVE_GETEUID + { "owned", + "name", + file_cmd_owned, + 1, + 1, + /* Description: Returns 1 if owned by the current owner */ + }, +#endif + { "isdirectory", + "name", + file_cmd_isdirectory, + 1, + 1, + /* Description: Returns 1 if name is a directory */ + }, + { "isfile", + "name", + file_cmd_isfile, + 1, + 1, + /* Description: Returns 1 if name is a file */ + }, + { + NULL + } +}; + +static int Jim_CdCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "dirname"); + return JIM_ERR; + } + + path = Jim_String(argv[1]); + + if (chdir(path) != 0) { + Jim_SetResultFormatted(interp, "couldn't change working directory to \"%s\": %s", path, + strerror(errno)); + return JIM_ERR; + } + return JIM_OK; +} + +static int Jim_PwdCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const int cwd_len = 2048; + char *cwd = malloc(cwd_len); + + if (getcwd(cwd, cwd_len) == NULL) { + Jim_SetResultString(interp, "Failed to get pwd", -1); + return JIM_ERR; + } +#if defined(__MINGW32__) || defined(_MSC_VER) + { + /* Try to keep backlashes out of paths */ + char *p = cwd; + while ((p = strchr(p, '\\')) != NULL) { + *p++ = '/'; + } + } +#endif + + Jim_SetResultString(interp, cwd, -1); + + free(cwd); + return JIM_OK; +} + +int Jim_fileInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "file", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "file", Jim_SubCmdProc, (void *)file_command_table, NULL); + Jim_CreateCommand(interp, "pwd", Jim_PwdCmd, NULL, NULL); + Jim_CreateCommand(interp, "cd", Jim_CdCmd, NULL, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-format.c b/debuggers/openocd/jimtcl/jim-format.c new file mode 100644 index 00000000..bf149a2f --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-format.c @@ -0,0 +1,432 @@ +/* + * Implements the internals of the format command for jim + * + * The FreeBSD license + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + * + * Based on code originally from Tcl 8.5: + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * Copyright (c) 1999 by Scriptics Corporation. + * + * See the file "tcl.license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ +#include +#include + +#include +#include "utf8.h" + +#define JIM_UTF_MAX 3 +#define JIM_INTEGER_SPACE 24 +#define MAX_FLOAT_WIDTH 320 + +/** + * Apply the printf-like format in fmtObjPtr with the given arguments. + * + * Returns a new object with zero reference count if OK, or NULL on error. + */ +Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_Obj *const *objv) +{ + const char *span, *format, *formatEnd, *msg; + int numBytes = 0, objIndex = 0, gotXpg = 0, gotSequential = 0; + static const char * const mixedXPG = + "cannot mix \"%\" and \"%n$\" conversion specifiers"; + static const char * const badIndex[2] = { + "not enough arguments for all format specifiers", + "\"%n$\" argument index out of range" + }; + int formatLen; + Jim_Obj *resultPtr; + + /* A single buffer is used to store numeric fields (with sprintf()) + * This buffer is allocated/reallocated as necessary + */ + char *num_buffer = NULL; + int num_buffer_size = 0; + + span = format = Jim_GetString(fmtObjPtr, &formatLen); + formatEnd = format + formatLen; + resultPtr = Jim_NewStringObj(interp, "", 0); + + while (format != formatEnd) { + char *end; + int gotMinus, sawFlag; + int gotPrecision, useShort; + long width, precision; + int newXpg; + int ch; + int step; + int doubleType; + char pad = ' '; + char spec[2*JIM_INTEGER_SPACE + 12]; + char *p; + + int formatted_chars; + int formatted_bytes; + const char *formatted_buf; + + step = utf8_tounicode(format, &ch); + format += step; + if (ch != '%') { + numBytes += step; + continue; + } + if (numBytes) { + Jim_AppendString(interp, resultPtr, span, numBytes); + numBytes = 0; + } + + /* + * Saw a % : process the format specifier. + * + * Step 0. Handle special case of escaped format marker (i.e., %%). + */ + + step = utf8_tounicode(format, &ch); + if (ch == '%') { + span = format; + numBytes = step; + format += step; + continue; + } + + /* + * Step 1. XPG3 position specifier + */ + + newXpg = 0; + if (isdigit(ch)) { + int position = strtoul(format, &end, 10); + if (*end == '$') { + newXpg = 1; + objIndex = position - 1; + format = end + 1; + step = utf8_tounicode(format, &ch); + } + } + if (newXpg) { + if (gotSequential) { + msg = mixedXPG; + goto errorMsg; + } + gotXpg = 1; + } else { + if (gotXpg) { + msg = mixedXPG; + goto errorMsg; + } + gotSequential = 1; + } + if ((objIndex < 0) || (objIndex >= objc)) { + msg = badIndex[gotXpg]; + goto errorMsg; + } + + /* + * Step 2. Set of flags. Also build up the sprintf spec. + */ + p = spec; + *p++ = '%'; + + gotMinus = 0; + sawFlag = 1; + do { + switch (ch) { + case '-': + gotMinus = 1; + break; + case '0': + pad = ch; + break; + case ' ': + case '+': + case '#': + break; + default: + sawFlag = 0; + continue; + } + *p++ = ch; + format += step; + step = utf8_tounicode(format, &ch); + } while (sawFlag); + + /* + * Step 3. Minimum field width. + */ + + width = 0; + if (isdigit(ch)) { + width = strtoul(format, &end, 10); + format = end; + step = utf8_tounicode(format, &ch); + } else if (ch == '*') { + if (objIndex >= objc - 1) { + msg = badIndex[gotXpg]; + goto errorMsg; + } + if (Jim_GetLong(interp, objv[objIndex], &width) != JIM_OK) { + goto error; + } + if (width < 0) { + width = -width; + if (!gotMinus) { + *p++ = '-'; + gotMinus = 1; + } + } + objIndex++; + format += step; + step = utf8_tounicode(format, &ch); + } + + /* + * Step 4. Precision. + */ + + gotPrecision = precision = 0; + if (ch == '.') { + gotPrecision = 1; + format += step; + step = utf8_tounicode(format, &ch); + } + if (isdigit(ch)) { + precision = strtoul(format, &end, 10); + format = end; + step = utf8_tounicode(format, &ch); + } else if (ch == '*') { + if (objIndex >= objc - 1) { + msg = badIndex[gotXpg]; + goto errorMsg; + } + if (Jim_GetLong(interp, objv[objIndex], &precision) != JIM_OK) { + goto error; + } + + /* + * TODO: Check this truncation logic. + */ + + if (precision < 0) { + precision = 0; + } + objIndex++; + format += step; + step = utf8_tounicode(format, &ch); + } + + /* + * Step 5. Length modifier. + */ + + useShort = 0; + if (ch == 'h') { + useShort = 1; + format += step; + step = utf8_tounicode(format, &ch); + } else if (ch == 'l') { + /* Just for compatibility. All non-short integers are wide. */ + format += step; + step = utf8_tounicode(format, &ch); + if (ch == 'l') { + format += step; + step = utf8_tounicode(format, &ch); + } + } + + format += step; + span = format; + + /* + * Step 6. The actual conversion character. + */ + + if (ch == 'i') { + ch = 'd'; + } + + doubleType = 0; + + /* Each valid conversion will set: + * formatted_buf - the result to be added + * formatted_chars - the length of formatted_buf in characters + * formatted_bytes - the length of formatted_buf in bytes + */ + switch (ch) { + case '\0': + msg = "format string ended in middle of field specifier"; + goto errorMsg; + case 's': { + formatted_buf = Jim_GetString(objv[objIndex], &formatted_bytes); + formatted_chars = Jim_Utf8Length(interp, objv[objIndex]); + if (gotPrecision && (precision < formatted_chars)) { + /* Need to build a (null terminated) truncated string */ + formatted_chars = precision; + formatted_bytes = utf8_index(formatted_buf, precision); + } + break; + } + case 'c': { + jim_wide code; + + if (Jim_GetWide(interp, objv[objIndex], &code) != JIM_OK) { + goto error; + } + /* Just store the value in the 'spec' buffer */ + formatted_bytes = utf8_fromunicode(spec, code); + formatted_buf = spec; + formatted_chars = 1; + break; + } + + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + doubleType = 1; + /* fall through */ + case 'd': + case 'u': + case 'o': + case 'x': + case 'X': { + jim_wide w; + double d; + int length; + + /* Fill in the width and precision */ + if (width) { + p += sprintf(p, "%ld", width); + } + if (gotPrecision) { + p += sprintf(p, ".%ld", precision); + } + + /* Now the modifier, and get the actual value here */ + if (doubleType) { + if (Jim_GetDouble(interp, objv[objIndex], &d) != JIM_OK) { + goto error; + } + length = MAX_FLOAT_WIDTH; + } + else { + if (Jim_GetWide(interp, objv[objIndex], &w) != JIM_OK) { + goto error; + } + length = JIM_INTEGER_SPACE; + if (useShort) { + *p++ = 'h'; + if (ch == 'd') { + w = (short)w; + } + else { + w = (unsigned short)w; + } + } + else { + *p++ = 'l'; +#ifdef HAVE_LONG_LONG + if (sizeof(long long) == sizeof(jim_wide)) { + *p++ = 'l'; + } +#endif + } + } + + *p++ = (char) ch; + *p = '\0'; + + /* Adjust length for width and precision */ + if (width > length) { + length = width; + } + if (gotPrecision) { + length += precision; + } + + /* Increase the size of the buffer if needed */ + if (num_buffer_size < length + 1) { + num_buffer_size = length + 1; + num_buffer = Jim_Realloc(num_buffer, num_buffer_size); + } + + if (doubleType) { + snprintf(num_buffer, length + 1, spec, d); + } + else { + formatted_bytes = snprintf(num_buffer, length + 1, spec, w); + } + formatted_chars = formatted_bytes = strlen(num_buffer); + formatted_buf = num_buffer; + break; + } + + default: { + /* Just reuse the 'spec' buffer */ + spec[0] = ch; + spec[1] = '\0'; + Jim_SetResultFormatted(interp, "bad field specifier \"%s\"", spec); + goto error; + } + } + + if (!gotMinus) { + while (formatted_chars < width) { + Jim_AppendString(interp, resultPtr, &pad, 1); + formatted_chars++; + } + } + + Jim_AppendString(interp, resultPtr, formatted_buf, formatted_bytes); + + while (formatted_chars < width) { + Jim_AppendString(interp, resultPtr, &pad, 1); + formatted_chars++; + } + + objIndex += gotSequential; + } + if (numBytes) { + Jim_AppendString(interp, resultPtr, span, numBytes); + } + + Jim_Free(num_buffer); + return resultPtr; + + errorMsg: + Jim_SetResultString(interp, msg, -1); + error: + Jim_FreeNewObj(interp, resultPtr); + Jim_Free(num_buffer); + return NULL; +} diff --git a/debuggers/openocd/jimtcl/jim-history.c b/debuggers/openocd/jimtcl/jim-history.c new file mode 100644 index 00000000..370769d5 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-history.c @@ -0,0 +1,122 @@ +#include +#include +#include + +#include "jim.h" +#include "jimautoconf.h" +#include "jim-subcmd.h" + +static int history_cmd_getline(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + char *line = Jim_HistoryGetline(Jim_String(argv[0])); + + /* On EOF returns -1 if varName was specified, or the empty string. */ + if (line == NULL) { + if (argc == 2) { + Jim_SetResultInt(interp, -1); + } + return JIM_OK; + } + + objPtr = Jim_NewStringObjNoAlloc(interp, line, -1); + + /* Returns the length of the string if varName was specified */ + if (argc == 2) { + if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) { + Jim_FreeNewObj(interp, objPtr); + return JIM_ERR; + } + Jim_SetResultInt(interp, Jim_Length(objPtr)); + } + else { + Jim_SetResult(interp, objPtr); + } + return JIM_OK; +} + +static int history_cmd_load(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_HistoryLoad(Jim_String(argv[0])); + return JIM_OK; +} + +static int history_cmd_save(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_HistorySave(Jim_String(argv[0])); + return JIM_OK; +} + +static int history_cmd_add(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_HistoryAdd(Jim_String(argv[0])); + return JIM_OK; +} + +static int history_cmd_show(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_HistoryShow(); + return JIM_OK; +} + +static const jim_subcmd_type history_command_table[] = { + { "getline", + "prompt ?varname?", + history_cmd_getline, + 1, + 2, + /* Description: Reads one line from the user. Similar to gets. */ + }, + { "load", + "filename", + history_cmd_load, + 1, + 1, + /* Description: Loads history from the given file, if possible */ + }, + { "save", + "filename", + history_cmd_save, + 1, + 1, + /* Description: Saves history to the given file */ + }, + { "add", + "line", + history_cmd_add, + 1, + 1, + /* Description: Adds the line to the history ands saves */ + }, + { "show", + NULL, + history_cmd_show, + 0, + 0, + /* Description: Displays the history */ + }, + { NULL } +}; + +static int JimHistorySubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, history_command_table, argc, argv), argc, argv); +} + +static void JimHistoryDelProc(Jim_Interp *interp, void *privData) +{ + Jim_Free(privData); +} + +int Jim_historyInit(Jim_Interp *interp) +{ + void **history; + if (Jim_PackageProvide(interp, "history", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + history = Jim_Alloc(sizeof(*history)); + *history = NULL; + + Jim_CreateCommand(interp, "history", JimHistorySubCmdProc, history, JimHistoryDelProc); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-interactive.c b/debuggers/openocd/jimtcl/jim-interactive.c new file mode 100644 index 00000000..c0f16dac --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-interactive.c @@ -0,0 +1,172 @@ +#include +#include + +#include "jimautoconf.h" +#include + +#ifdef USE_LINENOISE +#include +#include "linenoise.h" +#else +#define MAX_LINE_LEN 512 +#endif + +/** + * Returns an allocated line, or NULL if EOF. + */ +char *Jim_HistoryGetline(const char *prompt) +{ +#ifdef USE_LINENOISE + return linenoise(prompt); +#else + char *line = malloc(MAX_LINE_LEN); + + fputs(prompt, stdout); + fflush(stdout); + + if (fgets(line, MAX_LINE_LEN, stdin) == NULL) { + free(line); + return NULL; + } + return line; +#endif +} + +void Jim_HistoryLoad(const char *filename) +{ +#ifdef USE_LINENOISE + linenoiseHistoryLoad(filename); +#endif +} + +void Jim_HistoryAdd(const char *line) +{ +#ifdef USE_LINENOISE + linenoiseHistoryAdd(line); +#endif +} + +void Jim_HistorySave(const char *filename) +{ +#ifdef USE_LINENOISE + linenoiseHistorySave(filename); +#endif +} + +void Jim_HistoryShow(void) +{ +#ifdef USE_LINENOISE + /* built-in history command */ + int i; + int len; + char **history = linenoiseHistory(&len); + for (i = 0; i < len; i++) { + printf("%4d %s\n", i + 1, history[i]); + } +#endif +} + +int Jim_InteractivePrompt(Jim_Interp *interp) +{ + int retcode = JIM_OK; + char *history_file = NULL; +#ifdef USE_LINENOISE + const char *home; + + home = getenv("HOME"); + if (home && isatty(STDIN_FILENO)) { + int history_len = strlen(home) + sizeof("/.jim_history"); + history_file = Jim_Alloc(history_len); + snprintf(history_file, history_len, "%s/.jim_history", home); + Jim_HistoryLoad(history_file); + } +#endif + + printf("Welcome to Jim version %d.%d" JIM_NL, + JIM_VERSION / 100, JIM_VERSION % 100); + Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, "1"); + + while (1) { + Jim_Obj *scriptObjPtr; + const char *result; + int reslen; + char prompt[20]; + const char *str; + + if (retcode != 0) { + const char *retcodestr = Jim_ReturnCode(retcode); + + if (*retcodestr == '?') { + snprintf(prompt, sizeof(prompt) - 3, "[%d] ", retcode); + } + else { + snprintf(prompt, sizeof(prompt) - 3, "[%s] ", retcodestr); + } + } + else { + prompt[0] = '\0'; + } + strcat(prompt, ". "); + + scriptObjPtr = Jim_NewStringObj(interp, "", 0); + Jim_IncrRefCount(scriptObjPtr); + while (1) { + char state; + int len; + char *line; + + line = Jim_HistoryGetline(prompt); + if (line == NULL) { + if (errno == EINTR) { + continue; + } + Jim_DecrRefCount(interp, scriptObjPtr); + retcode = JIM_OK; + goto out; + } + if (Jim_Length(scriptObjPtr) != 0) { + Jim_AppendString(interp, scriptObjPtr, "\n", 1); + } + Jim_AppendString(interp, scriptObjPtr, line, -1); + free(line); + str = Jim_GetString(scriptObjPtr, &len); + if (len == 0) { + continue; + } + if (Jim_ScriptIsComplete(str, len, &state)) + break; + + snprintf(prompt, sizeof(prompt), "%c> ", state); + } +#ifdef USE_LINENOISE + if (strcmp(str, "h") == 0) { + /* built-in history command */ + Jim_HistoryShow(); + Jim_DecrRefCount(interp, scriptObjPtr); + continue; + } + + Jim_HistoryAdd(Jim_String(scriptObjPtr)); + if (history_file) { + Jim_HistorySave(history_file); + } +#endif + retcode = Jim_EvalObj(interp, scriptObjPtr); + Jim_DecrRefCount(interp, scriptObjPtr); + + if (retcode == JIM_EXIT) { + retcode = JIM_EXIT; + break; + } + if (retcode == JIM_ERR) { + Jim_MakeErrorMessage(interp); + } + result = Jim_GetString(Jim_GetResult(interp), &reslen); + if (reslen) { + printf("%s\n", result); + } + } + out: + Jim_Free(history_file); + return retcode; +} diff --git a/debuggers/openocd/jimtcl/jim-load.c b/debuggers/openocd/jimtcl/jim-load.c new file mode 100644 index 00000000..f9255dce --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-load.c @@ -0,0 +1,128 @@ +#include + +#include "jimautoconf.h" +#include + +/* ----------------------------------------------------------------------------- + * Dynamic libraries support (WIN32 not supported) + * ---------------------------------------------------------------------------*/ + +#if defined(HAVE_DLOPEN) || defined(HAVE_DLOPEN_COMPAT) + +#ifdef HAVE_DLFCN_H +#include +#endif + +#ifndef RTLD_NOW + #define RTLD_NOW 0 +#endif +#ifndef RTLD_LOCAL + #define RTLD_LOCAL 0 +#endif + +/** + * Note that Jim_LoadLibrary() requires a path to an existing file. + * + * If it is necessary to search JIM_LIBPATH, use Jim_PackageRequire() instead. + */ +int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName) +{ + void *handle = dlopen(pathName, RTLD_NOW | RTLD_LOCAL); + if (handle == NULL) { + Jim_SetResultFormatted(interp, "error loading extension \"%s\": %s", pathName, + dlerror()); + } + else { + /* We use a unique init symbol depending on the extension name. + * This is done for compatibility between static and dynamic extensions. + * For extension readline.so, the init symbol is "Jim_readlineInit" + */ + const char *pt; + const char *pkgname; + int pkgnamelen; + char initsym[40]; + typedef int jim_module_init_func_type(Jim_Interp *); + jim_module_init_func_type *onload; + + pt = strrchr(pathName, '/'); + if (pt) { + pkgname = pt + 1; + } + else { + pkgname = pathName; + } + pt = strchr(pkgname, '.'); + if (pt) { + pkgnamelen = pt - pkgname; + } + else { + pkgnamelen = strlen(pkgname); + } + snprintf(initsym, sizeof(initsym), "Jim_%.*sInit", pkgnamelen, pkgname); + + if ((onload = (jim_module_init_func_type *)dlsym(handle, initsym)) == NULL) { + Jim_SetResultFormatted(interp, + "No %s symbol found in extension %s", initsym, pathName); + } + else if (onload(interp) != JIM_ERR) { + /* Add this handle to the stack of handles to be freed */ + if (!interp->loadHandles) { + interp->loadHandles = Jim_Alloc(sizeof(*interp->loadHandles)); + Jim_InitStack(interp->loadHandles); + } + Jim_StackPush(interp->loadHandles, handle); + + Jim_SetEmptyResult(interp); + + return JIM_OK; + } + } + if (handle) { + dlclose(handle); + } + return JIM_ERR; +} + +static void JimFreeOneLoadHandle(void *handle) +{ + dlclose(handle); +} + +void Jim_FreeLoadHandles(Jim_Interp *interp) +{ + if (interp->loadHandles) { + Jim_FreeStackElements(interp->loadHandles, JimFreeOneLoadHandle); + Jim_Free(interp->loadHandles); + } +} + +#else /* JIM_DYNLIB */ +int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName) +{ + JIM_NOTUSED(interp); + JIM_NOTUSED(pathName); + + Jim_SetResultString(interp, "the Jim binary has no support for [load]", -1); + return JIM_ERR; +} + +void Jim_FreeLoadHandles(Jim_Interp *interp) +{ +} +#endif /* JIM_DYNLIB */ + +/* [load] */ +static int Jim_LoadCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "libaryFile"); + return JIM_ERR; + } + return Jim_LoadLibrary(interp, Jim_String(argv[1])); +} + +int Jim_loadInit(Jim_Interp *interp) +{ + Jim_CreateCommand(interp, "load", Jim_LoadCoreCommand, NULL, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-mk.cpp b/debuggers/openocd/jimtcl/jim-mk.cpp new file mode 100644 index 00000000..8ff1b329 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-mk.cpp @@ -0,0 +1,2276 @@ +#include +#include +#include +#include + +#include "jim.h" +#include "jimautoconf.h" +#include "jim-subcmd.h" + +extern "C" { /* The whole file is essentially C */ + +#define MK_PROPERTY_BINARY 'B' +#define MK_PROPERTY_INT 'I' +#define MK_PROPERTY_LONG 'L' +#define MK_PROPERTY_FLOAT 'F' +#define MK_PROPERTY_DOUBLE 'D' +#define MK_PROPERTY_STRING 'S' +#define MK_PROPERTY_VIEW 'V' + +#define MK_MODE_ORIGINAL -1 +#define MK_MODE_READONLY 0 +#define MK_MODE_READWRITE 1 +#define MK_MODE_EXTEND 2 + +#define MK_CMD_LEN 32 +#define JIM_CURSOR_SPACE (35+JIM_REFERENCE_TAGLEN + 1 + 20) +#define JIM_POSITION_SPACE 32 +#define MK_VERSION_SPACE 16 +#define JIM_MK_DESCR_LEN 64 /* Default, will be reallocated if needed */ + +#define isnamech(c) ( (c) && !strchr(":,[^]!", (c)) ) + +#ifndef max +#define max(x, y) ((x) >= (y) ? (x) : (y)) +#endif + +/* utilities */ +static int JimCheckMkName(Jim_Interp *interp, Jim_Obj *name, const char *type); +static const char *JimMkTypeName(char type); +static Jim_Obj *JimFromMkDescription(Jim_Interp *interp, const char *descr, const char **endPtr); +static int JimToMkDescription(Jim_Interp *interp, Jim_Obj *obj, char **descrPtr); +static Jim_Obj *JimGetMkValue(Jim_Interp *interp, c4_Cursor cur, const c4_Property &prop); +static int JimSetMkValue(Jim_Interp *interp, c4_Cursor cur, const c4_Property &prop, Jim_Obj *obj); + +static int JimPipelineBoundary(int argc, Jim_Obj *const *argv); + +/* property object */ +static Jim_Obj *JimNewPropertyObj (Jim_Interp *interp, c4_Property prop); +static int JimGetProperty (Jim_Interp *interp, Jim_Obj *obj, + c4_View view, const char *what, const c4_Property **propPtr); +static int JimGetPropertyTyped (Jim_Interp *interp, Jim_Obj *obj, + char type, const c4_Property **propPtr); +static int JimGetNewProperty (Jim_Interp *interp, Jim_Obj *obj, + c4_View view, char type, const c4_Property **propPtr); +static int JimGetProperties (Jim_Interp *interp, int objc, Jim_Obj *const *objv, + c4_View view, c4_View *propsPtr); +static Jim_Obj *JimViewPropertiesList (Jim_Interp *interp, c4_View view); + +/* cursor object */ +static int JimGetPosition (Jim_Interp *interp, Jim_Obj *obj, c4_View view, int *indexPtr); +static int JimGetCursor (Jim_Interp *interp, Jim_Obj *obj, c4_Cursor *curPtr); +static int JimGetCursorView (Jim_Interp *interp, Jim_Obj *obj, + Jim_Obj **viewObjPtr); +static int JimCursorPos (Jim_Interp *interp, Jim_Obj *obj, Jim_Obj **posObjPtr); +static int JimIncrCursor (Jim_Interp *interp, Jim_Obj *obj, int offset); +static int JimSeekCursor (Jim_Interp *interp, Jim_Obj *obj, Jim_Obj *posObj); + +/* Also accepts JIM_ERRMSG */ +#define JIM_CURSOR_GET (1 << JIM_PRIV_FLAG_SHIFT) +#define JIM_CURSOR_SET (2 << JIM_PRIV_FLAG_SHIFT) +#define JIM_CURSOR_INSERT (4 << JIM_PRIV_FLAG_SHIFT) + +static int JimCheckCursor (Jim_Interp *interp, Jim_Obj *curObj, int flags); + +/* view handle */ +static Jim_Obj *JimNewViewObj (Jim_Interp *interp, c4_View view); +static int JimGetView (Jim_Interp *interp, Jim_Obj *obj, c4_View *viewPtr); +static void JimPinView (Jim_Interp *interp, Jim_Obj *obj); + +/* ------------------------------------------------------------------------- + * Utilities + * ------------------------------------------------------------------------- */ + +static int JimCheckMkName(Jim_Interp *interp, Jim_Obj *name, const char *type) +{ + const char *s; + int i, len; + + s = Jim_GetString(name, &len); + + if (len > 0 && s[0] == '-') + goto err; + for (i = 0; i < len; i++) { + if (!isnamech(s[i])) + goto err; + } + + return JIM_OK; + + err: + Jim_SetResultFormatted(interp, "expected %s name but got \"%#s\"", type ? type : "property", name); + return JIM_ERR; +} + +static const char *const jim_mktype_options[] = { + "-integer", + "-long", + "-float", + "-double", + "-string", + "-subview", + /* FIXME "-binary", */ + 0 +}; + +static const char *const jim_mktype_names[] = { + "integer", + "long", + "float", + "double", + "string", + "subview", + /* FIXME "binary", */ + 0 +}; + +static const char jim_mktype_types[] = { + MK_PROPERTY_INT, + MK_PROPERTY_LONG, + MK_PROPERTY_FLOAT, + MK_PROPERTY_DOUBLE, + MK_PROPERTY_STRING, + MK_PROPERTY_VIEW, + /* MK_PROPERTY_BINARY, */ +}; + +#define JIM_MKTYPES ((int)(sizeof(jim_mktype_types) / sizeof(jim_mktype_types[0]))) + +static const char *JimMkTypeName(char type) +{ + int i; + + for (i = 0; i < JIM_MKTYPES; i++) { + if (type == jim_mktype_types[i]) + return jim_mktype_names[i]; + } + return "(unknown type)"; +} + +static Jim_Obj *JimFromMkDescription(Jim_Interp *interp, const char *descr, const char **endPtr) +{ + Jim_Obj *result; + const char *delim; + + result = Jim_NewListObj(interp, NULL, 0); + for (;;) { + if (*descr == ']') { + descr++; + break; + } + else if (*descr == '\0') + break; + else if (*descr == ',') + descr++; + + delim = strpbrk(descr, ",:[]"); + /* JimPanic((!delim, "Invalid Metakit description string")); */ + + Jim_ListAppendElement(interp, result, + Jim_NewStringObj(interp, descr, delim - descr)); + + if (delim[0] == '[') { + Jim_ListAppendElement(interp, result, + JimFromMkDescription(interp, delim + 1, &descr)); + } + else if (delim[0] == ':') { + Jim_ListAppendElement(interp, result, + Jim_NewStringObj(interp, JimMkTypeName(delim[1]), -1)); + descr = delim + 2; + } + else { + /* Seems that Metakit never generates descriptions without type + * tags, but let's handle this just to be safe + */ + + Jim_ListAppendElement(interp, result, + Jim_NewStringObj(interp, JimMkTypeName(MK_PROPERTY_STRING), -1)); + } + } + + if (endPtr) + *endPtr = descr; + return result; +} + +/* This allocates the buffer once per user call and stores it in a static + * variable. Recursive calls are distinguished by descrPtr == NULL. + */ +static int JimToMkDescription(Jim_Interp *interp, Jim_Obj *descrObj, char **descrPtr) +{ + static char *descr, *outPtr; + static int bufSize; + + #define ENLARGE(size) do { \ + if ((descr - outPtr) + (size) > bufSize) { \ + bufSize = max(2*bufSize, (descr - outPtr) + (size)); \ + descr = (char *)Jim_Realloc(descr, bufSize); \ + } \ + } while(0) + + int i, count; + Jim_Obj *name, *struc; + + const char *rep; + int len; + + count = Jim_ListLength(interp, descrObj); + if (count % 2) { + Jim_SetResultString(interp, + "view description must have an even number of elements", -1); + return JIM_ERR; + } + + if (descrPtr) { + descr = (char *)Jim_Alloc(bufSize = JIM_MK_DESCR_LEN); + outPtr = descr; + } + + for (i = 0; i < count; i += 2) { + Jim_ListIndex(interp, descrObj, i, &name, 0); + Jim_ListIndex(interp, descrObj, i + 1, &struc, 0); + + if (JimCheckMkName(interp, name, NULL) != JIM_OK) + goto err; + + rep = Jim_GetString(name, &len); + ENLARGE(len + 3); /* At least :T, or [], */ + memcpy(outPtr, rep, len); + outPtr += len; + + if (Jim_ListLength(interp, struc) == 1) { + int idx; + + if (Jim_GetEnum(interp, struc, jim_mktype_names, &idx, + "property type", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) + goto err; + + *outPtr++ = ':'; + *outPtr++ = jim_mktype_types[idx]; + } + else { + *outPtr++ = '['; + + if (JimToMkDescription(interp, struc, NULL) != JIM_OK) + goto err; + + ENLARGE(2); /* bracket, comma */ + *outPtr++ = ']'; + } + + *outPtr++ = ','; + } + *(--outPtr) = '\0'; + + #undef ENLARGE + + if (descrPtr) { + *descrPtr = (char *)Jim_Realloc(descr, strlen(descr) + 1); + descr = NULL; /* Safety measure */ + } + + return JIM_OK; + + err: + + if (descrPtr) + Jim_Free(descr); + + return JIM_ERR; +} + +static Jim_Obj *JimGetMkValue(Jim_Interp *interp, c4_Cursor cur, const c4_Property &prop) +{ + switch (prop.Type()) { + case MK_PROPERTY_INT: + return Jim_NewIntObj(interp, ((c4_IntProp &)prop).Get(*cur)); + case MK_PROPERTY_LONG: + return Jim_NewIntObj(interp, ((c4_LongProp &)prop).Get(*cur)); + case MK_PROPERTY_FLOAT: + return Jim_NewDoubleObj(interp, ((c4_FloatProp &)prop).Get(*cur)); + case MK_PROPERTY_DOUBLE: + return Jim_NewDoubleObj(interp, ((c4_DoubleProp &)prop).Get(*cur)); + case MK_PROPERTY_STRING: + return Jim_NewStringObj(interp, ((c4_StringProp &)prop).Get(*cur), -1); + case MK_PROPERTY_VIEW: + return JimNewViewObj(interp, ((c4_ViewProp &)prop).Get(*cur)); + + case MK_PROPERTY_BINARY: + /* FIXME */ + default: + /* FIXME Something more meaningful here? */ + return Jim_NewEmptyStringObj(interp); + } +} + +static int JimSetMkValue(Jim_Interp *interp, c4_Cursor cur, const c4_Property &prop, Jim_Obj *obj) +{ + switch (prop.Type()) { + case MK_PROPERTY_INT: { + jim_wide value; + + if (Jim_GetWide(interp, obj, &value) != JIM_OK) + return JIM_ERR; + + ((c4_IntProp &)prop).Set(*cur, value); + return JIM_OK; + } + case MK_PROPERTY_LONG: { + jim_wide value; + + if (Jim_GetWide(interp, obj, &value) != JIM_OK) + return JIM_ERR; + + ((c4_LongProp &)prop).Set(*cur, value); + return JIM_OK; + } + case MK_PROPERTY_FLOAT: { + double value; + + if (Jim_GetDouble(interp, obj, &value) != JIM_OK) + return JIM_ERR; + + ((c4_FloatProp &)prop).Set(*cur, value); + return JIM_OK; + } + case MK_PROPERTY_DOUBLE: { + double value; + + if (Jim_GetDouble(interp, obj, &value) != JIM_OK) + return JIM_ERR; + + ((c4_DoubleProp &)prop).Set(*cur, value); + return JIM_OK; + } + case MK_PROPERTY_STRING: { + int len; + const char *rep; + + rep = Jim_GetString(obj, &len); + if (len != (int)strlen(rep)) { + Jim_SetResultString(interp, "null characters are not allowed in Metakit strings", -1); + return JIM_ERR; + } + + ((c4_StringProp &)prop).Set(*cur, rep); + return JIM_OK; + } + case MK_PROPERTY_VIEW: { + c4_View value; + + if (JimGetView(interp, obj, &value) != JIM_OK) + return JIM_ERR; + + ((c4_ViewProp &)prop).Set(*cur, value); + } + case MK_PROPERTY_BINARY: + /* FIXME */ + default: + Jim_SetResultString(interp, "unsupported Metakit type", -1); + return JIM_ERR; + } +} + +static int JimPipelineBoundary(int argc, Jim_Obj *const *argv) { + const char *rep; + int pipe, len; + + for (pipe = 0; pipe < argc; pipe++) { + rep = Jim_GetString(argv[pipe], &len); + if (len == 1 && rep[0] == '|') + break; + } + return pipe; +} + +/* ------------------------------------------------------------------------- + * Property object + * ------------------------------------------------------------------------- */ + +#define JimPropertyValue(o) ((c4_Property *)((o)->internalRep.ptr)) + +static void FreePropertyInternalRep(Jim_Interp *interp, Jim_Obj *obj) +{ + delete JimPropertyValue(obj); +} + +static void DupPropertyInternalRep(Jim_Interp *interp, Jim_Obj *oldObj, Jim_Obj *newObj) +{ + newObj->internalRep.ptr = new c4_Property(*JimPropertyValue(oldObj)); + newObj->typePtr = oldObj->typePtr; +} + +static void UpdateStringOfProperty(Jim_Obj* obj) +{ + const char *name = JimPropertyValue(obj)->Name(); + int len = strlen(name); + + obj->bytes = (char *) Jim_Alloc(len + 1); + memcpy(obj->bytes, name, len + 1); + obj->length = len; +} + +static Jim_ObjType propertyObjType = { + "mk.property", + FreePropertyInternalRep, + DupPropertyInternalRep, + UpdateStringOfProperty, + JIM_TYPE_NONE +}; + +static int JimGetProperty(Jim_Interp *interp, Jim_Obj *obj, c4_View view, const char *name, const c4_Property **propPtr) +{ + int index; + + if (obj->typePtr == &propertyObjType) { + index = view.FindProperty(JimPropertyValue(obj)->GetId()); + } + else { + if (JimCheckMkName(interp, obj, name) != JIM_OK) + return JIM_ERR; + index = view.FindPropIndexByName(Jim_String(obj)); + } + + if (index != -1) { + *propPtr = &view.NthProperty(index); + return JIM_OK; + } + else { + Jim_SetResultFormatted(interp, "%s \"%#s\" does not exist", + name ? name : "property", obj); + return JIM_ERR; + } +} + +static int JimGetPropertyTyped(Jim_Interp *interp, Jim_Obj *obj, char type, const c4_Property **propPtr) +{ + c4_Property *prop; + + if (obj->typePtr == &propertyObjType) { + if (JimPropertyValue(obj)->Type() != type) { + /* coerce the property type */ + + prop = new c4_Property(type, JimPropertyValue(obj)->Name()); + delete JimPropertyValue(obj); + obj->internalRep.ptr = prop; + } + } + else { + if (JimCheckMkName(interp, obj, NULL) != JIM_OK) + return JIM_ERR; + + prop = new c4_Property(type, Jim_String(obj)); + + Jim_FreeIntRep(interp, obj); + obj->typePtr = &propertyObjType; + obj->internalRep.ptr = (void *)prop; + } + + *propPtr = JimPropertyValue(obj); + return JIM_OK; +} + +static int JimGetNewProperty(Jim_Interp *interp, Jim_Obj *obj, c4_View view, char type, const c4_Property **propPtr) +{ + const c4_Property *newp, *prop; + + if (JimGetPropertyTyped(interp, obj, type, &newp) != JIM_OK) + return JIM_ERR; + + prop = &view.NthProperty(view.AddProperty(*newp)); + + if (prop->Type() != newp->Type()) { + Jim_SetResultFormatted(interp, "property \"%#s\" is %s, not %s", + obj, JimMkTypeName(prop->Type()), JimMkTypeName(newp->Type())); + return JIM_ERR; + } + + *propPtr = prop; + return JIM_OK; +} + +static int JimGetProperties(Jim_Interp *interp, int objc, Jim_Obj *const *objv, c4_View view, c4_View *propsPtr) +{ + int i; + const c4_Property *prop; + c4_View props; + + for (i = 0; i < objc; i++) { + if (JimGetProperty(interp, objv[i], view, NULL, &prop) != JIM_OK) + return JIM_ERR; + + props.AddProperty(*prop); + } + + *propsPtr = props; + return JIM_OK; +} + +static Jim_Obj *JimNewPropertyObj(Jim_Interp *interp, c4_Property prop) +{ + Jim_Obj *obj; + + obj = Jim_NewObj(interp); + obj->typePtr = &propertyObjType; + obj->bytes = NULL; + obj->internalRep.ptr = new c4_Property(prop); + return obj; +} + +/* ------------------------------------------------------------------------- + * Cursor object + * ------------------------------------------------------------------------- */ + +/* Position ---------------------------------------------------------------- */ + +/* A normal position if endFlag == 0; otherwise an offset from end+1 (!) */ +typedef struct MkPosition { + int index; + int endFlag; +} MkPosition; + +/* This is mostly the same as SetIndexFromAny, but preserves more information + * and allows multiple [+-]integer parts. + */ +static int GetPosition(Jim_Interp *interp, Jim_Obj *obj, MkPosition *posPtr) +{ + MkPosition pos; + const char *rep; + char *end; + int sign, offset; + + rep = Jim_String(obj); + + if (strncmp(rep, "end", 3) == 0) { + pos.endFlag = 1; + pos.index = -1; + + rep += 3; + } + else { + pos.endFlag = 0; + pos.index = strtol(rep, &end, 10); + if (end == rep) + goto err; + + rep = end; + } + + while ((rep[0] == '+') || (rep[0] == '-')) { + sign = (rep[0] == '+' ? 1 : -1); + rep++; + + offset = strtol(rep, &end, 10); + if (end == rep) + goto err; + + pos.index += sign * offset; + rep = end; + } + + while (isspace(UCHAR(*rep))) + rep++; + if (*rep != '\0') + goto err; + + *posPtr = pos; + return JIM_OK; + + err: + Jim_SetResultFormatted(interp, "expected cursor position but got \"%#s\"", obj); + return JIM_ERR; +} + +static int PositionIndex(const MkPosition *posPtr, c4_View view) +{ + if (posPtr->endFlag) + return view.GetSize() + posPtr->index; + else + return posPtr->index; +} + +static int JimGetPosition(Jim_Interp *interp, Jim_Obj *obj, c4_View view, int *indexPtr) +{ + MkPosition pos; + + if (GetPosition(interp, obj, &pos) != JIM_OK) + return JIM_ERR; + + *indexPtr = PositionIndex(&pos, view); + return JIM_OK; +} + +/* Cursor type ------------------------------------------------------------- */ + +typedef struct MkCursor { + MkPosition pos; + Jim_Obj *viewObj; +} MkCursor; + +#define JimCursorValue(obj) ((MkCursor *)(obj->internalRep.ptr)) +static void FreeCursorInternalRep(Jim_Interp *interp, Jim_Obj *obj) +{ + Jim_DecrRefCount(interp, JimCursorValue(obj)->viewObj); + Jim_Free(obj->internalRep.ptr); +} + +static void DupCursorInternalRep(Jim_Interp *interp, Jim_Obj *oldObj, Jim_Obj *newObj) +{ + newObj->internalRep.ptr = Jim_Alloc(sizeof(MkCursor)); + *JimCursorValue(newObj) = *JimCursorValue(oldObj); + Jim_IncrRefCount(JimCursorValue(oldObj)->viewObj); + + newObj->typePtr = oldObj->typePtr; +} + +static void UpdateStringOfCursor(Jim_Obj *obj) +{ + char buf[JIM_CURSOR_SPACE + 1]; + MkCursor *curPtr = JimCursorValue(obj); + int idx, len; + + len = snprintf(buf, JIM_CURSOR_SPACE + 1, "%s!", Jim_String(curPtr->viewObj)); + + if (curPtr->pos.endFlag) { + idx = curPtr->pos.index + 1; + if (idx == 0) + len += snprintf(buf + len, JIM_CURSOR_SPACE + 1 - len, "end"); + else + len += snprintf(buf + len, JIM_CURSOR_SPACE + 1 - len, "end%+d", idx); + } + else { + len += snprintf(buf + len, JIM_CURSOR_SPACE + 1 - len, "%d", + curPtr->pos.index); + } + + obj->bytes = (char *)Jim_Alloc(len + 1); + memcpy(obj->bytes, buf, len + 1); + obj->length = len; +} + +static Jim_ObjType cursorObjType = { + "mk.cursor", + FreeCursorInternalRep, + DupCursorInternalRep, + UpdateStringOfCursor, + JIM_TYPE_REFERENCES +}; + +static int SetCursorFromAny(Jim_Interp *interp, Jim_Obj *obj) +{ + const char *rep, *delim; + int len; + Jim_Obj *posObj; + MkCursor cur; + + rep = Jim_GetString(obj, &len); + delim = strrchr(rep, '!'); + + if (!delim) { + Jim_SetResultFormatted(interp, "expected cursor but got \"%#s\"", obj); + return JIM_ERR; + } + + cur.viewObj = Jim_NewStringObj(interp, rep, delim - rep); + posObj = Jim_NewStringObj(interp, delim + 1, len - (delim - rep) - 1); + + if (GetPosition(interp, posObj, &cur.pos) != JIM_OK) { + Jim_FreeNewObj(interp, posObj); + Jim_FreeNewObj(interp, cur.viewObj); + return JIM_ERR; + } + + Jim_FreeIntRep(interp, obj); + Jim_FreeNewObj(interp, posObj); + Jim_IncrRefCount(cur.viewObj); + + obj->typePtr = &cursorObjType; + obj->internalRep.ptr = Jim_Alloc(sizeof(MkCursor)); + *JimCursorValue(obj) = cur; + + return JIM_OK; +} + +/* Functions --------------------------------------------------------------- */ + +static int JimCursorPos(Jim_Interp *interp, Jim_Obj *obj, Jim_Obj **posObjPtr) +{ + if (obj->typePtr != &cursorObjType && SetCursorFromAny(interp, obj) != JIM_OK) + return JIM_ERR; + + *posObjPtr = Jim_NewStringObj(interp, strrchr(Jim_String(obj), '!') + 1, -1); + return JIM_OK; +} + +static int JimGetCursorView(Jim_Interp *interp, Jim_Obj *obj, Jim_Obj **viewObjPtr) +{ + if (obj->typePtr != &cursorObjType && SetCursorFromAny(interp, obj) != JIM_OK) + return JIM_ERR; + + *viewObjPtr = JimCursorValue(obj)->viewObj; + return JIM_OK; +} + +static int JimGetCursor(Jim_Interp *interp, Jim_Obj *obj, c4_Cursor *curPtr) +{ + c4_View view; + + if (obj->typePtr != &cursorObjType && SetCursorFromAny(interp, obj) != JIM_OK) + return JIM_ERR; + if (JimGetView(interp, JimCursorValue(obj)->viewObj, &view) != JIM_OK) + return JIM_ERR; + + if (curPtr) + *curPtr = &view[PositionIndex(&JimCursorValue(obj)->pos, view)]; + return JIM_OK; +} + +static int JimIncrCursor(Jim_Interp *interp, Jim_Obj *obj, int offset) +{ + /* JimPanic((Jim_IsShared(obj), "JimIncrCursor called with shared object")) */ + + if (obj->typePtr != &cursorObjType && SetCursorFromAny(interp, obj) != JIM_OK) + return JIM_ERR; + + Jim_InvalidateStringRep(obj); + JimCursorValue(obj)->pos.index += offset; + return JIM_OK; +} + +static int JimSeekCursor(Jim_Interp *interp, Jim_Obj *obj, Jim_Obj *posObj) +{ + /* JimPanic((Jim_IsShared(obj), "JimSeekCursor called with shared object")) */ + + if (obj->typePtr != &cursorObjType && SetCursorFromAny(interp, obj) != JIM_OK) + return JIM_ERR; + + Jim_InvalidateStringRep(obj); + return GetPosition(interp, posObj, &JimCursorValue(obj)->pos); +} + +static int JimCheckCursor(Jim_Interp *interp, Jim_Obj *curObj, int flags) +{ + static c4_View nullView; + + c4_Cursor cur = &nullView[0]; + int size; + + if (JimGetCursor(interp, curObj, &cur) != JIM_OK) + return JIM_ERR; + size = (*cur).Container().GetSize(); + + if ((flags & JIM_CURSOR_GET) && (cur._index < 0 || cur._index >= size)) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, + "cursor \"%#s\" does not point to an existing row", curObj); + } + return JIM_ERR; + } + else if ((flags & JIM_CURSOR_SET) && cur._index < 0) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, + "cursor \"%#s\" points before start of view", curObj); + } + return JIM_ERR; + } + else if ((flags & JIM_CURSOR_INSERT) && (cur._index < 0 || cur._index > size)) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, + "cursor \"%#s\" does not point to a valid insert position", curObj); + } + return JIM_ERR; + } + + return JIM_OK; +} + +/* Records ----------------------------------------------------------------- */ + +static int cursor_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + c4_View view; + c4_Cursor cur = &view[0]; + + if (JimGetCursor(interp, argv[0], &cur) != JIM_OK) + return JIM_ERR; + if (JimCheckCursor(interp, argv[0], JIM_ERRMSG | JIM_CURSOR_GET) != JIM_OK) + return JIM_ERR; + + view = (*cur).Container(); + + if (argc == 1) { /* Return all properties */ + int i, count; + Jim_Obj *result; + + result = Jim_NewListObj(interp, NULL, 0); + count = view.NumProperties(); + + for (i = 0; i < count; i++) { + c4_Property prop = view.NthProperty(i); + + Jim_ListAppendElement(interp, result, JimNewPropertyObj(interp, prop)); + Jim_ListAppendElement(interp, result, JimGetMkValue(interp, cur, prop)); + } + + Jim_SetResult(interp, result); + return JIM_OK; + } + else { /* Return a single property */ + const c4_Property *propPtr; + int pipe; + + pipe = JimPipelineBoundary(argc, argv); + if (pipe == 2) { + /* No type annotation, existing property */ + if (JimGetProperty(interp, argv[1], view, NULL, &propPtr) != JIM_OK) + return JIM_ERR; + } + else if (pipe == 3) { + /* Explicit type annotation; the property may be new */ + int idx; + + if (Jim_GetEnum(interp, argv[1], jim_mktype_options, &idx, + "property type", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) + return JIM_ERR; + if (JimGetNewProperty(interp, argv[2], view, jim_mktype_types[idx], &propPtr) != JIM_OK) + return JIM_ERR; + } + else { + Jim_WrongNumArgs(interp, 0, NULL, "cursor get ?-type? ?prop?"); + return JIM_ERR; + } + + Jim_SetResult(interp, JimGetMkValue(interp, cur, *propPtr)); + + if (pipe == argc) + return JIM_OK; + else + return Jim_EvalObjPrefix(interp, Jim_GetResult(interp), argc - pipe - 1, argv + pipe + 1); + } +} + +static int cursor_cmd_set(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + c4_View view; + c4_Cursor cur = &view[0]; + const c4_Property *propPtr; + int i, oldSize; + + if (JimGetCursor(interp, argv[0], &cur) != JIM_OK) + return JIM_ERR; + if (JimCheckCursor(interp, argv[0], JIM_ERRMSG | JIM_CURSOR_SET) != JIM_OK) + return JIM_ERR; + + view = (*cur).Container(); + oldSize = view.GetSize(); + + if (cur._index >= oldSize) + view.SetSize(cur._index + 1); + + if (argc == 2) { + /* Update everything except subviews from a dictionary in argv[1]. + * No new properties are permitted. + */ + + int objc; + Jim_Obj **objv; + + if (Jim_DictPairs(interp, argv[1], &objv, &objc) != JIM_OK) + goto err; + + for (i = 0; i < objc; i += 2) { + if (JimGetProperty(interp, objv[i], view, NULL, &propPtr) != JIM_OK || + JimSetMkValue(interp, cur, *propPtr, objv[i+1]) != JIM_OK) + { + Jim_Free(objv); + goto err; + } + } + } + else { + /* Update everything from argv[1..]. New properties are permitted if + * explicitly typed. + */ + + for (i = 1; i < argc; i += 2) { + if (Jim_String(argv[i])[0] == '-') { + int idx; + + if (i + 2 >= argc) { + Jim_WrongNumArgs(interp, 2, argv, "?-type? prop value ?...?"); + goto err; + } + + if (Jim_GetEnum(interp, argv[i], jim_mktype_options, &idx, + "property type", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) + goto err; + if (JimGetNewProperty(interp, argv[i+1], view, jim_mktype_types[idx], &propPtr) != JIM_OK) + goto err; + i++; + } + else { + if (i + 1 >= argc) { + Jim_WrongNumArgs(interp, 2, argv, "?-type? prop value ?...?"); + goto err; + } + + if (JimGetProperty(interp, argv[i], view, NULL, &propPtr) != JIM_OK) + goto err; + } + + if (JimSetMkValue(interp, cur, *propPtr, argv[i+1]) != JIM_OK) + goto err; + } + } + + return JIM_OK; + + err: + view.SetSize(oldSize); + return JIM_ERR; +} + +static int cursor_cmd_insert(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + c4_View view; + c4_Cursor cur = &view[0]; + jim_wide count; + + if (JimGetCursor(interp, argv[0], &cur) != JIM_OK) + return JIM_ERR; + if (JimCheckCursor(interp, argv[0], JIM_ERRMSG | JIM_CURSOR_INSERT) != JIM_OK) + return JIM_ERR; + + view = (*cur).Container(); + + if (argc == 1) + count = 1; + else { + if (Jim_GetWide(interp, argv[1], &count) != JIM_OK) + return JIM_ERR; + } + + if (count > 0) { + c4_Row empty; + view.InsertAt(cur._index, empty, (int)count); + } + + Jim_SetEmptyResult(interp); + return JIM_OK; +} + +static int cursor_cmd_remove(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + c4_View view; + c4_Cursor cur = &view[0]; + int pos; + jim_wide count; + + if (JimGetCursor(interp, argv[0], &cur) != JIM_OK) + return JIM_ERR; + if (JimCheckCursor(interp, argv[0], JIM_ERRMSG | JIM_CURSOR_SET) != JIM_OK) + return JIM_ERR; + + view = (*cur).Container(); + pos = cur._index; + + if (argc == 1) + count = 1; + else { + if (Jim_GetWide(interp, argv[1], &count) != JIM_OK) + return JIM_ERR; + } + + if (pos + count < view.GetSize()) + count = view.GetSize() - pos; + + if (pos < view.GetSize()) + view.RemoveAt(pos, (int)count); + + return JIM_OK; +} + +/* Attributes -------------------------------------------------------------- */ + +static int cursor_cmd_view(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *viewObj; + + if (JimGetCursorView(interp, argv[0], &viewObj) != JIM_OK) + return JIM_ERR; + + JimPinView(interp, viewObj); + Jim_SetResult(interp, viewObj); + return JIM_OK; +} + +/* Positioning ------------------------------------------------------------- */ + +static int cursor_cmd_tell(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc == 1) { + Jim_Obj *result; + + if (JimCursorPos(interp, argv[0], &result) != JIM_OK) + return JIM_ERR; + Jim_SetResult(interp, result); + } + else { + static c4_View nullView; + c4_Cursor cur = &nullView[0]; + + if (!Jim_CompareStringImmediate(interp, argv[0], "-absolute")) { + Jim_SetResultFormatted(interp, + "bad option \"%#s\": must be -absolute", argv[0]); + return JIM_ERR; + } + + if (JimGetCursor(interp, argv[1], &cur) != JIM_OK) + return JIM_ERR; + + Jim_SetResultInt(interp, cur._index); + } + + return JIM_OK; +} + +static int cursor_cmd_validfor(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + static const char *options[] = { + "get", "set", "insert", "remove", 0 + }; + static int optflags[] = { + JIM_CURSOR_GET, + JIM_CURSOR_SET, + JIM_CURSOR_INSERT, + JIM_CURSOR_SET + }; + + int idx; + + if (argc == 1) + idx = 0; + else { + if (Jim_GetEnum(interp, argv[0], options, &idx, NULL, + JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) + return JIM_ERR; + } + + if (JimGetCursor(interp, argv[argc-1], NULL) != JIM_OK) + return JIM_ERR; + + Jim_SetResultBool(interp, JimCheckCursor(interp, argv[argc-1], optflags[idx]) == JIM_OK); + return JIM_OK; +} + +static int cursor_cmd_seek(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *curObj; + + curObj = Jim_GetVariable(interp, argv[0], JIM_ERRMSG | JIM_UNSHARED); + if (curObj == NULL) + return JIM_ERR; + + if (JimSeekCursor(interp, curObj, argv[1]) != JIM_OK) + return JIM_ERR; + + Jim_SetResult(interp, curObj); + return JIM_OK; +} + +static int cursor_cmd_incr(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *curObj; + jim_wide offset; + + if (argc == 1) + offset = 1; + else { + if (Jim_GetWide(interp, argv[1], &offset) != JIM_OK) + return JIM_ERR; + } + + curObj = Jim_GetVariable(interp, argv[0], JIM_ERRMSG | JIM_UNSHARED); + if (curObj == NULL) + return JIM_ERR; + + if (JimIncrCursor(interp, curObj, (int)offset) != JIM_OK) + return JIM_ERR; + + Jim_SetResult(interp, curObj); + return JIM_OK; +} + +/* Command table ----------------------------------------------------------- */ + +static const jim_subcmd_type cursor_command_table[] = { + + /* Records */ + + { "get", "cur ?-type? ?prop?", + cursor_cmd_get, + 1, -1, + 0, + /*"Get the whole record or a specific property at the cursor"*/ + }, + { "set", "cur [dict | ?-type? field value ?...?]", + cursor_cmd_set, + 1, -1, + 0, + /*"Update the record at the cursor"*/ + }, + { "insert", "cur ?count?", + cursor_cmd_insert, + 1, 2, + 0, + /*"Insert a specified number of empty rows at the cursor (default 1)"*/ + }, + { "remove", "cur ?count?", + cursor_cmd_remove, + 1, 2, + 0, + /*"Remove a specified number of rows at the cursor (default 1)"*/ + }, + + /* Attributes */ + + { "view", "cur", + cursor_cmd_view, + 1, 1, + 0, + /*"Get the view the cursor points into"*/ + }, + + /* Positioning */ + + { "tell", "?-absolute? cur", + cursor_cmd_tell, + 1, 2, + 0, + /*"Get the position of the cursor"*/ + }, + { "validfor", "?command? cur", + cursor_cmd_validfor, + 1, 2, + 0, + /*"Checks if the cursor is valid for get (default), set or insert commands"*/ + }, + { "seek", "curVar index", + cursor_cmd_seek, + 2, 2, + 0, + /*"Seek to the specified index in the view"*/ + }, + { "incr", "curVar ?offset?", + cursor_cmd_incr, + 1, 2, + 0, + /*"Move the cursor offset records from its current position (default 1)"*/ + }, + + { 0 } +}; + +static int JimCursorCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *cmdObj; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "command ..."); + return JIM_ERR; + } + + cmdObj = Jim_NewStringObj(interp, "cursor ", -1); + Jim_AppendObj(interp, cmdObj, argv[1]); + + if (Jim_GetCommand(interp, cmdObj, 0) != NULL) + return Jim_EvalObjPrefix(interp, cmdObj, argc - 2, argv + 2); + else { + Jim_FreeNewObj(interp, cmdObj); + return Jim_CallSubCmd(interp, + Jim_ParseSubCmd(interp, cursor_command_table, argc, argv), argc, argv); + } +} + +/* ------------------------------------------------------------------------- + * View handle + * ------------------------------------------------------------------------- */ + +/* Views aren't really Jim objects; instead, they are Tk-style commands with + * oo.tcl-like lifetime management. Additionally, all views are initially + * created as one-shot, meaning that they die after one command. Call + * JimPinView to make a view object persistent. + * + * It is valid to rename a view in the Tcl land, but by doing this you take + * the responsibility of destroying the object when it's no longer needed. + * Any cursors that pointed into the view become invalid. + */ + +static int JimViewSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv); +static int JimOneShotViewSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv); + +/* Unary operations -------------------------------------------------------- */ + +#define UNOP(name, Method) \ +static int view_cmd_##name(Jim_Interp *interp, int argc, Jim_Obj *const *argv) \ +{ \ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); \ + \ + Jim_SetResult(interp, JimNewViewObj(interp, viewPtr->Method())); \ + return JIM_OK; \ +} + +UNOP(copy, Duplicate) +UNOP(clone, Clone) +UNOP(unique, Unique) + +#undef UNOP + +static int view_cmd_blocked(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); + + if (viewPtr->GetSize() != 1 || + strcmp(viewPtr->NthProperty(0).Name(), "_B") != 0 || + viewPtr->NthProperty(0).Type() != MK_PROPERTY_VIEW) + { + Jim_SetResultString(interp, + "blocked view must have exactly one subview property called _B", -1); + return JIM_ERR; + } + + Jim_SetResult(interp, JimNewViewObj(interp, viewPtr->Blocked())); + return JIM_OK; +} + +/* Binary operations ------------------------------------------------------- */ + +#define BINOP(name, Method) \ +static int view_cmd_##name(Jim_Interp *interp, int argc, Jim_Obj *const *argv) \ +{ \ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); \ + c4_View otherView; \ + \ + if (JimGetView(interp, argv[0], &otherView) != JIM_OK) \ + return JIM_ERR; \ + \ + Jim_SetResult(interp, JimNewViewObj(interp, viewPtr->Method(otherView))); \ + return JIM_OK; \ +} + +BINOP(pair, Pair) +BINOP(concat, Concat) +BINOP(product, Product) + +BINOP(union, Union) +BINOP(intersect, Intersect) +BINOP(minus, Minus) +BINOP(different, Different) + +#undef BINOP + +/* Projections ------------------------------------------------------------- */ + +static int view_cmd_project(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); + c4_View props; + + if (JimGetProperties(interp, argc, argv, *viewPtr, &props) != JIM_OK) + return JIM_ERR; + + Jim_SetResult(interp, JimNewViewObj(interp, viewPtr->Project(props))); + return JIM_OK; +} + +static int view_cmd_without(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); + c4_View props; + + if (JimGetProperties(interp, argc, argv, *viewPtr, &props) != JIM_OK) + return JIM_ERR; + + Jim_SetResult(interp, JimNewViewObj(interp, viewPtr->ProjectWithout(props))); + return JIM_OK; +} + +static int view_cmd_range(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); + int start, end; + jim_wide step; + + if (JimGetPosition(interp, argv[0], *viewPtr, &start) != JIM_OK || + JimGetPosition(interp, argv[1], *viewPtr, &end) != JIM_OK) + { + return JIM_ERR; + } + + if (argc == 2) + step = 1; + else if (Jim_GetWide(interp, argv[2], &step) != JIM_OK) + return JIM_ERR; + + Jim_SetResult(interp, JimNewViewObj(interp, viewPtr->Slice(start, end + 1, (int)step))); + return JIM_OK; +} + +/* Ordering ---------------------------------------------------------------- */ + +static int view_cmd_sort(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); + c4_View sortProps, revProps; + const c4_Property *propPtr; + int i, len; + + const char *rep; + int reverse; + Jim_Obj *propObj; + + /* Special case: property names may be preceded with a dash. Use + * a temporary object in this case. + */ + + for (i = 0; i < argc; i++) { + propObj = argv[i]; + + rep = Jim_GetString(argv[i], &len); + reverse = (len > 0 && rep[0] == '-'); + + if (reverse) + propObj = Jim_NewStringObj(interp, rep + 1, len - 1); + + if (JimGetProperty(interp, propObj, *viewPtr, NULL, &propPtr) != JIM_OK) { + if (reverse) + Jim_FreeNewObj(interp, propObj); + return JIM_ERR; + } + + sortProps.AddProperty(*propPtr); + if (reverse) { + revProps.AddProperty(*propPtr); + Jim_FreeNewObj(interp, propObj); + } + } + + if (sortProps.GetSize() == 0) + Jim_SetResult(interp, JimNewViewObj(interp, viewPtr->Sort())); + else if (revProps.GetSize() == 0) + Jim_SetResult(interp, JimNewViewObj(interp, viewPtr->SortOn(sortProps))); + else + Jim_SetResult(interp, JimNewViewObj(interp, viewPtr->SortOnReverse(sortProps, revProps))); + + return JIM_OK; +} + +/* Metakit core seems to be doing something similar for SortOn, but neither + * Ordered nor Hash use it, for unknown reason. + */ + +static int BubbleProperties(Jim_Interp *interp, c4_View orig, int objc, Jim_Obj *const *objv, c4_View *projPtr) +{ + c4_View proj; + const c4_Property *propPtr; + int i, count; + + for (i = 0; i < objc; i++) { + if (JimGetProperty(interp, objv[i], orig, NULL, &propPtr) != JIM_OK) + return JIM_ERR; + proj.AddProperty(*propPtr); + } + + count = orig.NumProperties(); + for (i = 0; i < count; i++) + proj.AddProperty(orig.NthProperty(i)); + + *projPtr = proj; + return JIM_OK; +} + +static int view_cmd_ordered(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); + c4_View proj; + + if (BubbleProperties(interp, *viewPtr, argc, argv, &proj) != JIM_OK) + return JIM_ERR; + + Jim_SetResult(interp, JimNewViewObj(interp, proj.Ordered(argc))); + return JIM_OK; +} + +static int view_cmd_hash(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); + c4_View hash, proj; + + if (JimGetView(interp, argv[0], &hash) != JIM_OK) + return JIM_ERR; + + if (hash.GetSize() != 2 || + strcmp(hash.NthProperty(0).Name(), "_H") != 0 || + hash.NthProperty(0).Type() != MK_PROPERTY_INT || + strcmp(hash.NthProperty(1).Name(), "_R") != 0 || + hash.NthProperty(1).Type() != MK_PROPERTY_INT) /* Ouch. */ + { + Jim_SetResultString(interp, + "hash view must be laid out as {_H integer _R integer}", -1); + return JIM_ERR; + } + + if (BubbleProperties(interp, *viewPtr, argc - 1, argv + 1, &proj) != JIM_OK) + return JIM_ERR; + + Jim_SetResult(interp, JimNewViewObj(interp, proj.Hash(hash, argc - 1))); + return JIM_OK; +} + +/* Relational operations --------------------------------------------------- */ + +static int view_cmd_join(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); + c4_View other, props; + int outer, off; + + if (JimGetView(interp, argv[0], &other) != JIM_OK) + return JIM_ERR; + + off = 1; outer = 0; + if (Jim_CompareStringImmediate(interp, argv[1], "-outer")) { + off++; outer = 1; + } + + if (JimGetProperties(interp, argc - off, argv + off, *viewPtr, &props) != JIM_OK) + return JIM_ERR; + + Jim_SetResult(interp, JimNewViewObj(interp, viewPtr->Join(props, other, outer))); + return JIM_OK; +} + +static int view_cmd_group(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); + const c4_Property *subviewPtr; + c4_View props; + + if (JimGetPropertyTyped(interp, argv[0], MK_PROPERTY_VIEW, &subviewPtr) != JIM_OK) + return JIM_ERR; + + if (JimGetProperties(interp, argc - 1, argv + 1, *viewPtr, &props) != JIM_OK) + return JIM_ERR; + + Jim_SetResult(interp, JimNewViewObj(interp, viewPtr->GroupBy(props, *(c4_ViewProp *)subviewPtr))); + return JIM_OK; +} + +static int view_cmd_flatten(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); + const c4_Property *subviewPtr; + + if (JimGetProperty(interp, argv[0], *viewPtr, NULL, &subviewPtr) != JIM_OK) + return JIM_ERR; + + if (subviewPtr->Type() != MK_PROPERTY_VIEW) { + Jim_SetResultFormatted(interp, "expected a subview property but got %s one", + JimMkTypeName(subviewPtr->Type())); + return JIM_ERR; + } + + Jim_SetResult(interp, JimNewViewObj(interp, viewPtr->JoinProp(*(c4_ViewProp *)subviewPtr))); + return JIM_OK; +} + +/* View queries ------------------------------------------------------------ */ + +static int view_cmd_properties(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *) Jim_CmdPrivData(interp); + Jim_SetResult(interp, JimViewPropertiesList(interp, *viewPtr)); + return JIM_OK; +} + +static int view_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *) Jim_CmdPrivData(interp); + Jim_SetResultInt(interp, viewPtr->GetSize()); + return JIM_OK; +} + +static int view_cmd_resize(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + c4_View *view = (c4_View *) Jim_CmdPrivData(interp); + jim_wide size; + + if (Jim_GetWide(interp, argv[0], &size) != JIM_OK) + return JIM_ERR; + if (size < 0 || size > INT_MAX) { + Jim_SetResultFormatted(interp, + "view size \"%#s\" is out of range", argv[0]); + return JIM_ERR; + } + + view->SetSize((int)size); + Jim_SetResult(interp, argv[0]); + return JIM_OK; +} + +static int view_cmd_type(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const c4_View *viewPtr = (const c4_View *)Jim_CmdPrivData(interp); + + if (argc == 1) { + const c4_Property *propPtr; + + if (JimGetProperty(interp, argv[0], *viewPtr, NULL, &propPtr) != JIM_OK) + return JIM_ERR; + + Jim_SetResultString(interp, JimMkTypeName(propPtr->Type()), -1); + } + else { + Jim_Obj *result; + int i, count; + + result = Jim_NewListObj(interp, NULL, 0); + count = viewPtr->NumProperties(); + + for (i = 0; i < count; i++) { + c4_Property prop = viewPtr->NthProperty(i); + Jim_ListAppendElement(interp, result, JimNewPropertyObj(interp, prop)); + Jim_ListAppendElement(interp, result, + Jim_NewStringObj(interp, JimMkTypeName(prop.Type()), -1)); + } + + Jim_SetResult(interp, result); + } + + return JIM_OK; +} + +/* View lifetime ----------------------------------------------------------- */ + +static int view_cmd_pin(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + JimPinView(interp, argv[0]); + Jim_SetResult(interp, argv[0]); + return JIM_OK; +} + +static int view_cmd_as(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + JimPinView(interp, argv[0]); + Jim_SetVariable(interp, argv[2], argv[0]); + Jim_SetResult(interp, argv[0]); + return JIM_OK; +} + +static int view_cmd_destroy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_DeleteCommand(interp, Jim_String(argv[0])); + return JIM_OK; +} + +/* Command table ----------------------------------------------------------- */ + +static const jim_subcmd_type view_command_table[] = { + + /* Unary operations */ + + { "copy", "", + view_cmd_copy, + 0, 0, + 0, + /*"Create a copy of the view with exactly the same data"*/ + }, + { "clone", "", + view_cmd_clone, + 0, 0, + 0, + /*"Create an empty view with the same properties as this one"*/ + }, + { "unique", "", + view_cmd_unique, + 0, 0, + 0, + /*"Derived view without any duplicate rows (read-only, no change notifications)"*/ + }, + { "blocked", "", + view_cmd_blocked, + 0, 0, + 0, + /*"Build a scalable \"blocked\" out of a view with a single subview property called _B"*/ + }, + + /* Binary operations */ + + #define BINOP(name, descr) \ + { #name, "otherView", \ + view_cmd_##name, \ + 1, 1, 0, \ + } + + BINOP(pair, "Pairwise concatenation of two views"), + BINOP(concat, "Concatenation of two views; unlike union, doesn't remove duplicates"), + BINOP(product, "Cartesian product of two views, i.e. every row in view paired with every row in otherView"), + + /* Set operations */ + + #define SETOP(name, descr) BINOP(name, descr "; works only if all the rows are unique") + + SETOP(union, "Set union of two views (read-only, no change notifications)"), + SETOP(intersect, "Set intersection of two views"), + SETOP(different, "Symmetric difference of two views"), + SETOP(minus, "Set minus, i.e. all rows from view not in otherView"), + + #undef SETOP + + #undef BINOP + + /* Projections and selections */ + + { "project", "prop ?prop ...?", + view_cmd_project, + 1, -1, + 0, + /*"View projection: only the specified properties, in the specified order"*/ + }, + { "without", "prop ?prop ...?", + view_cmd_without, + 1, -1, + 0, + /*"View projection: remove the specified properties"*/ + }, + { "range", "first last ?step?", + view_cmd_range, + 2, 3, + 0, + /*"Range or slice of the view (read-write, no change notifications)"*/ + }, + + /* Ordering */ + + { "sort", "?[prop|-prop] ...?", + view_cmd_sort, + 0, -1, + 0, + /*"Derived view sorted on the specified properties (in order), or on all properties"*/ + }, + { "ordered", "prop ?prop ...?", + view_cmd_ordered, + 1, -1, + 0, + /*"Consider the underlying view ordered on the specified properties"*/ + }, + { "hash", "hashView prop ?prop ...?", + view_cmd_hash, + 2, -1, + 0, + /*"Mapped view maintaining a hash table on the key consisting of the specified properties"*/ + }, + + /* Relational operations */ + + { "join", "view ?-outer? prop ?prop ...?", + view_cmd_join, + 2, -1, + 0, + /*"Relational join with view on the specified properties"*/ + }, + { "group", "subviewName prop ?prop ...?", + view_cmd_group, + 1, -1, + 0, + /*"Group rows with equal specified properties, move all other properties into subview"*/ + }, + { "flatten", "subviewProp", + view_cmd_flatten, + 1, 1, + 0, + /*"Flatten the specified subview; the inverse of group"*/ + }, + + /* Attributes */ + + { "properties", "", + view_cmd_properties, + 0, 0, + 0, + /*"List the properties in this view"*/ + }, + { "size", "", + view_cmd_size, + 0, 0, + 0, + /*"Return the number of records in the view"*/ + }, + { "resize", "newSize", + view_cmd_resize, + 1, 1, + 0, + /*"Set the number of records in the view"*/ + }, + { "type", "?prop?", + view_cmd_type, + 0, 1, + 0, + /*"Return the type of an existing property, or of all properties"*/ + }, + + /* Lifetime management */ + + { "pin", "", + view_cmd_pin, + 0, 0, + JIM_MODFLAG_FULLARGV, + /*"Marks the view as persistent"*/ + }, + { "as", "varName", + view_cmd_as, + 1, 1, + JIM_MODFLAG_FULLARGV, + /*"Marks the view as persistent and assigns it to the given variable"*/ + }, + { "destroy", "", + view_cmd_destroy, + 0, 0, + JIM_MODFLAG_FULLARGV, + /*"Destroys the view explicitly"*/ + }, + + { 0 } +}; + +static void JimViewDelProc(Jim_Interp *interp, void *privData) +{ + delete (c4_View *)privData; +} + +static int JimViewSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int pipe, result; + Jim_Obj *cmdObj; + + pipe = JimPipelineBoundary(argc, argv); + + if (pipe < 1) { + Jim_WrongNumArgs(interp, 1, argv, "command ..."); + return JIM_ERR; + } + + /* Check for a Tcl command first, and try builtins afterwards. + * We have to do it in this order so that Jim_ParseSubCmd isn't too greedy + * about abbreviations, and still it can't now detect ambigous abbrevs + * properly :( Tcl commands cannot be abbreviated at all. + */ + + cmdObj = Jim_NewStringObj(interp, "mk.view ", -1); + Jim_AppendObj(interp, cmdObj, argv[1]); + + /* The command will be cached even though we discard the result */ + if (Jim_GetCommand(interp, cmdObj, 0) != NULL) { + /* Shuffle the arguments: $view cmd args... => {mk.view cmd} $view args... */ + + Jim_Obj **objv = (Jim_Obj **)Jim_Alloc(pipe * sizeof(Jim_Obj *)); + objv[0] = cmdObj; + objv[1] = argv[0]; + memcpy(objv + 2, argv + 2, (pipe - 2) * sizeof(Jim_Obj *)); + + result = Jim_EvalObjVector(interp, pipe, objv); + + Jim_Free(objv); + } else { + Jim_FreeNewObj(interp, cmdObj); + result = Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, view_command_table, pipe, argv), pipe, argv); + } + + if (result != JIM_OK || pipe == argc) + return result; + else + return Jim_EvalObjPrefix(interp, Jim_GetResult(interp), argc - pipe - 1, argv + pipe + 1); +} + +static int JimOneShotViewSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int result; + Jim_Cmd *cmd; + + result = JimViewSubCmdProc(interp, argc, argv); + + cmd = Jim_GetCommand(interp, argv[0], 0); + if (cmd && !cmd->isproc && cmd->u.native.cmdProc == JimOneShotViewSubCmdProc) + Jim_DeleteCommand(interp, Jim_String(argv[0])); + + return result; +} + +static int JimViewFinalizerProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + /* We won't succeed here if the user renamed the command, and this is right */ + Jim_DeleteCommand(interp, Jim_String(argv[1])); + return JIM_OK; +} + +static Jim_Obj *JimNewViewObj(Jim_Interp *interp, c4_View view) { + Jim_Obj *tag, *ref; + + tag = Jim_NewStringObj(interp, "mk.view", -1); + ref = Jim_NewReference(interp, tag, tag, Jim_NewStringObj(interp, "mk.view.finalizer", -1)); + Jim_CreateCommand(interp, Jim_String(ref), + JimOneShotViewSubCmdProc, new c4_View(view), JimViewDelProc); + + return ref; +} + +static int JimGetView(Jim_Interp *interp, Jim_Obj *obj, c4_View *viewPtr) +{ + Jim_Cmd *cmd = Jim_GetCommand(interp, obj, 0); + + if (cmd == NULL || cmd->isproc || cmd->u.native.delProc != JimViewDelProc) { + Jim_SetResultFormatted(interp, "invalid view object \"%#s\"", obj); + return JIM_ERR; + } + + *viewPtr = *(c4_View *)cmd->u.native.privData; + return JIM_OK; +} + +/* Only call this against known view objects. */ +static void JimPinView(Jim_Interp *interp, Jim_Obj *obj) +{ + Jim_Cmd *cmd = Jim_GetCommand(interp, obj, 0); + /* JimPanic((cmd == NULL, "JimPinView called against non-view")) + JimPanic((cmd->u.native.delProc != JimViewDelProc, "JimPinView called against non-view")) */ + cmd->u.native.cmdProc = JimViewSubCmdProc; +} + +static Jim_Obj *JimViewPropertiesList(Jim_Interp *interp, c4_View view) +{ + int i, count; + Jim_Obj *result; + + result = Jim_NewListObj(interp, NULL, 0); + count = view.NumProperties(); + + for (i = 0; i < count; i++) { + Jim_ListAppendElement(interp, result, Jim_NewStringObj(interp, + view.NthProperty(i).Name(), -1)); + } + + return result; +} + +/* ---------------------------------------------------------------------------- + * Storage handle + * ---------------------------------------------------------------------------- */ + +/* These are also commands, like views, but must be managed explicitly by the + * user. Quite like file handles, actually. + */ + +typedef struct MkStorage { + unsigned flags; + Jim_Obj *filename; + c4_Storage storage; + c4_Cursor content; +} MkStorage; + +#define JIM_MKFLAG_INMEMORY 0x0001 +#define JIM_MKFLAG_READONLY 0x0002 +#define JIM_MKFLAG_EXTEND 0x0004 +#define JIM_MKFLAG_AUTOCOMMIT 0x0008 + +/* Attributes -------------------------------------------------------------- */ + +static int storage_cmd_autocommit(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + MkStorage *mk = (MkStorage *)Jim_CmdPrivData(interp); + + if (argc == 1) { + jim_wide flag; + + if (Jim_GetWide(interp, argv[0], &flag) != JIM_OK) + return JIM_ERR; + + if (flag) + mk->flags |= JIM_MKFLAG_AUTOCOMMIT; + else + mk->flags &= ~JIM_MKFLAG_AUTOCOMMIT; + mk->storage.AutoCommit(flag); + } + + Jim_SetResultBool(interp, (mk->flags & JIM_MKFLAG_AUTOCOMMIT) != 0); + return JIM_OK; +} + +static int storage_cmd_readonly(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + MkStorage *mk = (MkStorage *)Jim_CmdPrivData(interp); + + Jim_SetResultBool(interp, (mk->flags & JIM_MKFLAG_READONLY) != 0); + return JIM_OK; +} + +/* Views ------------------------------------------------------------------- */ + +static int storage_cmd_views(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + MkStorage *mk = (MkStorage *)Jim_CmdPrivData(interp); + + Jim_SetResult(interp, JimViewPropertiesList(interp, mk->storage)); + return JIM_OK; +} + +static int storage_cmd_view(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + MkStorage *mk = (MkStorage *)Jim_CmdPrivData(interp); + const c4_Property *propPtr; + + if (JimGetProperty(interp, argv[0], mk->storage, "view", &propPtr) != JIM_OK) + return JIM_ERR; + Jim_SetResult(interp, JimGetMkValue(interp, mk->content, *propPtr)); + + if (argc == 1) + return JIM_OK; + else { + if (!Jim_CompareStringImmediate(interp, argv[1], "|")) { + Jim_SetResultFormatted(interp, + "expected start of a pipeline but got \"%#s\"", argv[1]); + return JIM_ERR; + } + return Jim_EvalObjPrefix(interp, Jim_GetResult(interp), argc - 2, argv + 2); + } +} + +static int storage_cmd_structure(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + MkStorage *mk = (MkStorage *)Jim_CmdPrivData(interp); + + if (argc < 2) { /* Query */ + const char *name; + + if (argc == 0) + name = NULL; + else { + const c4_Property *propPtr; + + if (JimGetProperty(interp, argv[0], mk->storage, "view", &propPtr) != JIM_OK) + return JIM_ERR; + name = propPtr->Name(); + } + + Jim_SetResult(interp, JimFromMkDescription(interp, + mk->storage.Description(name), NULL)); + } + else { /* Modify */ + char *descr; + const char *name; + int len, dlen; + + if (JimCheckMkName(interp, argv[0], "view") != JIM_OK) + return JIM_ERR; + name = Jim_GetString(argv[0], &len); + + if (JimToMkDescription(interp, argv[1], &descr) != JIM_OK) + return JIM_ERR; + dlen = strlen(descr); + + descr = (char *)Jim_Realloc(descr, dlen + len + 2); + memmove(descr + len + 1, descr, dlen); + memcpy(descr, name, len); + descr[len] = '['; + descr[len + 1 + dlen] = ']'; + descr[len + 1 + dlen + 1] = '\0'; + + mk->storage.GetAs(descr); + + Jim_Free(descr); + } + + return JIM_OK; +} + +/* Store operations -------------------------------------------------------- */ + +static int storage_cmd_commit(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + MkStorage *mk = (MkStorage *)Jim_CmdPrivData(interp); + + if (mk->flags & JIM_MKFLAG_INMEMORY) { + Jim_SetResultString(interp, "cannot commit an in-memory storage", -1); + return JIM_ERR; + } + else if (mk->flags & JIM_MKFLAG_READONLY) { + Jim_SetResultString(interp, "cannot commit a read-only storage", -1); + return JIM_ERR; + } + + if (mk->storage.Commit(0)) { + Jim_SetEmptyResult(interp); + return JIM_OK; + } + else { + Jim_SetResultString(interp, "I/O error during commit", -1); + return JIM_ERR; + } +} + +static int storage_cmd_rollback(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + MkStorage *mk = (MkStorage *)Jim_CmdPrivData(interp); + + if (mk->flags & JIM_MKFLAG_INMEMORY) { + Jim_SetResultString(interp, "cannot rollback an in-memory storage", -1); + return JIM_ERR; + } + + if (mk->storage.Rollback(0)) { + Jim_SetEmptyResult(interp); + return JIM_OK; + } + else { + Jim_SetResultString(interp, "I/O error during rollback", -1); + return JIM_ERR; + } +} + +static int storage_cmd_close(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return Jim_DeleteCommand(interp, Jim_String(argv[0])); +} + +/* Command table ----------------------------------------------------------- */ + +static const jim_subcmd_type storage_command_table[] = { + + /* Options */ + + { "autocommit", "?value?", + storage_cmd_autocommit, + 0, 1, + 0, + /*"Query or modify the auto-commit option of this storage"*/ + }, + { "readonly", "", + storage_cmd_readonly, + 0, 0, + 0, + /*"Returns the read-only status of this storage"*/ + }, + + /* Views */ + + { "views", "", + storage_cmd_views, + 0, 0, + 0, + /*"Returns the list of views stored here"*/ + }, + { "view", "viewName", + storage_cmd_view, + 1, -1, + 0, + /*"Retrieve the view specified by viewName"*/ + }, + { "structure", "?viewName? ?description?", + storage_cmd_structure, + 0, 2, + 0, + /*"Query or modify the structure of this storage"*/ + }, + + /* Store operations */ + + { "commit", "", + storage_cmd_commit, + 0, 0, + 0, + /*"Commit the changes to disk"*/ + }, + { "rollback", "", + storage_cmd_rollback, + 0, 0, + 0, + /*"Revert to the saved state"*/ + }, + { "close", "", + storage_cmd_close, + 0, 0, + JIM_MODFLAG_FULLARGV, + /*"Close this storage"*/ + }, + + { 0 } +}; + +static void JimStorageDelProc(Jim_Interp *interp, void *privData) +{ + MkStorage *mk = (MkStorage *)privData; + + mk->storage.~c4_Storage(); + mk->content.~c4_Cursor(); + Jim_DecrRefCount(interp, mk->filename); + Jim_Free(mk); +} + +static int JimStorageSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *cmdObj; + + cmdObj = Jim_NewStringObj(interp, "mk.storage ", -1); + Jim_AppendObj(interp, cmdObj, argv[1]); + + if (Jim_GetCommand(interp, cmdObj, 0) != NULL) { + int result; + + Jim_Obj **objv = (Jim_Obj **)Jim_Alloc(argc * sizeof(Jim_Obj *)); + objv[0] = cmdObj; + objv[1] = argv[0]; + memcpy(objv + 2, argv + 2, (argc - 2) * sizeof(Jim_Obj *)); + + result = Jim_EvalObjVector(interp, argc, objv); + + Jim_Free(objv); + return result; + } else { + Jim_FreeNewObj(interp, cmdObj); + return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, + storage_command_table, argc, argv), argc, argv); + } +} + +/* ------------------------------------------------------------------------- + * storage ?options? ?filename? + * + * Creates a new metakit storage object, optionally backed by a file. + * + * Options apply only when filename is given; these include: + * + * -readonly Open the file in read-only mode + * -original Open the file in read-only mode, discarding possible extends + * -extend Open the file in extend mode + * -nocommit Do not commit the changes when the storage is closed + * ------------------------------------------------------------------------- */ + +static int JimStorageCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + MkStorage *mk; + char buf[MK_CMD_LEN]; + int i, mode; + + static const char *const options[] = { + "-readonly", + "-original", + "-extend", + "-nocommit", + 0 + }; + enum { + OPT_READONLY, + OPT_ORIGINAL, + OPT_EXTEND, + OPT_NOCOMMIT + }; + int option; + + mk = (MkStorage *)Jim_Alloc(sizeof(MkStorage)); + mk->flags = JIM_MKFLAG_AUTOCOMMIT; + mode = MK_MODE_READWRITE; + for (i = 1; i < argc - 1; i++ ) { + if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { + Jim_Free(mk); + return JIM_ERR; + } + + switch (option) { + case OPT_READONLY: + if (mode != MK_MODE_READWRITE) + goto modeconflict; + + mode = MK_MODE_READONLY; + mk->flags |= JIM_MKFLAG_READONLY; + break; + + case OPT_ORIGINAL: + if (mode != MK_MODE_READWRITE) + goto modeconflict; + + mode = MK_MODE_ORIGINAL; + mk->flags |= JIM_MKFLAG_READONLY; + break; + + case OPT_EXTEND: + if (mode != MK_MODE_READWRITE) + goto modeconflict; + + mode = MK_MODE_EXTEND; + mk->flags |= JIM_MKFLAG_EXTEND; + break; + + case OPT_NOCOMMIT: + mk->flags &= ~JIM_MKFLAG_AUTOCOMMIT; + break; + } + } + + if (argc > 1) { + new(&mk->storage) c4_Storage(Jim_String(argv[argc-1]), mode); + + if (!mk->storage.Strategy().IsValid()) { + mk->storage.~c4_Storage(); + Jim_Free(mk); + Jim_SetResultFormatted(interp, "could not open storage \"%#s\"", argv[argc-1]); + return JIM_ERR; + } + + mk->filename = argv[argc-1]; + + if ((mk->flags & JIM_MKFLAG_AUTOCOMMIT) && !(mk->flags & JIM_MKFLAG_READONLY)) + mk->storage.AutoCommit(1); + } + else { + mk->flags |= JIM_MKFLAG_INMEMORY; + + new(&mk->storage) c4_Storage(); + mk->filename = Jim_NewEmptyStringObj(interp); + } + new(&mk->content) c4_Cursor(&mk->storage[0]); + Jim_IncrRefCount(mk->filename); + + snprintf(buf, sizeof(buf), "mk.handle%ld", Jim_GetId(interp)); + Jim_CreateCommand(interp, buf, JimStorageSubCmdProc, mk, JimStorageDelProc); + Jim_SetResultString(interp, buf, -1); + return JIM_OK; + + modeconflict: + Jim_Free(mk); + Jim_SetResultString(interp, "only one of -readonly, -original and -extend may be specified", -1); + return JIM_ERR; +} + +/* ------------------------------------------------------------------------- + * Initialization code + * ------------------------------------------------------------------------- */ + +int Jim_mkInit(Jim_Interp *interp) +{ + char version[MK_VERSION_SPACE]; + + snprintf(version, MK_VERSION_SPACE, "%d.%d.%d", + d4_MetakitLibraryVersion / 100, + d4_MetakitLibraryVersion % 100 / 10, + d4_MetakitLibraryVersion % 10); + + if (Jim_PackageProvide(interp, "mk", version, JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "storage", JimStorageCommand, NULL, NULL); + Jim_CreateCommand(interp, "cursor", JimCursorCommand, NULL, NULL); + Jim_CreateCommand(interp, "mk.view.finalizer", JimViewFinalizerProc, NULL, NULL); + + return JIM_OK; +} + +} /* extern "C" */ diff --git a/debuggers/openocd/jimtcl/jim-namespace.c b/debuggers/openocd/jimtcl/jim-namespace.c new file mode 100644 index 00000000..3413705a --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-namespace.c @@ -0,0 +1,335 @@ +/* + * Support for namespaces in jim + * + * (c) 2011 Steve Bennett + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + * + * Based on code originally from Tcl 6.7: + * + * Copyright 1987-1991 Regents of the University of California + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies. The University of California + * makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without + * express or implied warranty. + */ + +#include +#include +#include +#include +#include + +#include "jim.h" +#include "jimautoconf.h" +#include "jim-subcmd.h" + +/* ----------------------------------------------------------------------------- + * Namespace support + * ---------------------------------------------------------------------------*/ + +/** + * nsObj is a canonical namespace name (.e.g. "" for root, "abc" for ::abc) + * + * The given name is appended to the namespace name to produce a complete canonical name. + * + * e.g. "" "abc" => abc + * "" "::abc" => abc + * "" "abc::def" => abc::def + * "abc" "def" => abc::def + * "abc" "::def" => def + * + */ +Jim_Obj *JimCanonicalNamespace(Jim_Interp *interp, Jim_Obj *nsObj, Jim_Obj *nameObj) +{ + Jim_Obj *objPtr; + const char *name = Jim_String(nameObj); + assert(nameObj->refCount != 0); + assert(nsObj->refCount != 0); + if (name[0] == ':' && name[1] == ':') { + /* Absolute namespace */ + while (*++name == ':') { + } + return Jim_NewStringObj(interp, name, -1); + } + if (Jim_Length(nsObj) == 0) { + /* Relative to the global namespace */ + return nameObj; + } + /* Relative to non-global namespace */ + objPtr = Jim_DuplicateObj(interp, nsObj); + Jim_AppendString(interp, objPtr, "::", 2); + Jim_AppendObj(interp, objPtr, nameObj); + return objPtr; +} + +int Jim_CreateNamespaceVariable(Jim_Interp *interp, Jim_Obj *varNameObj, Jim_Obj *targetNameObj) +{ + int rc; + Jim_IncrRefCount(varNameObj); + Jim_IncrRefCount(targetNameObj); + + /* push non-namespace vars if in namespace eval? */ + rc = Jim_SetVariableLink(interp, varNameObj, targetNameObj, interp->topFramePtr); + + Jim_DecrRefCount(interp, varNameObj); + Jim_DecrRefCount(interp, targetNameObj); + + return rc; +} + +/** + * Returns the parent of the given namespace. + * + * ::bob::tom => ::bob + * bob::tom => bob + * ::bob => :: + * bob => "" + * :: => "" + * "" => "" + */ +Jim_Obj *Jim_NamespaceQualifiers(Jim_Interp *interp, Jim_Obj *ns) +{ + const char *name = Jim_String(ns); + const char *pt = strrchr(name, ':'); + if (pt && pt != name && pt[-1] == ':') { + return Jim_NewStringObj(interp, name, pt - name - 1); + } + else { + return interp->emptyObj; + } +} + +Jim_Obj *Jim_NamespaceTail(Jim_Interp *interp, Jim_Obj *ns) +{ + const char *name = Jim_String(ns); + const char *pt = strrchr(name, ':'); + if (pt && pt != name && pt[-1] == ':') { + return Jim_NewStringObj(interp, pt + 1, -1); + } + else { + return ns; + } +} + +static Jim_Obj *JimNamespaceCurrent(Jim_Interp *interp) +{ + Jim_Obj *objPtr = Jim_NewStringObj(interp, "::", 2); + Jim_AppendObj(interp, objPtr, interp->framePtr->nsObj); + return objPtr; +} + +static int JimVariableCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retcode = JIM_OK; + + if (argc > 3) { + Jim_WrongNumArgs(interp, 1, argv, "name ?value?"); + return JIM_ERR; + } + if (argc > 1) { + Jim_Obj *targetNameObj; + Jim_Obj *localNameObj; + +#if 0 + /* XXX should we give an error on dict sugar syntax? */ + if (JimValidName(interp, "variable", argv[1]) != JIM_OK) { + return JIM_ERR; + } +#endif + + targetNameObj = JimCanonicalNamespace(interp, interp->framePtr->nsObj, argv[1]); + + localNameObj = Jim_NamespaceTail(interp, argv[1]); + Jim_IncrRefCount(localNameObj); + if (interp->framePtr->level != 0 || Jim_Length(interp->framePtr->nsObj) != 0) { + Jim_CreateNamespaceVariable(interp, localNameObj, targetNameObj); + } + + /* Set the variable via the local name */ + if (argc > 2) { + retcode = Jim_SetVariable(interp, localNameObj, argv[2]); + } + Jim_DecrRefCount(interp, localNameObj); + } + return retcode; +} + +/* XXX: Temporary */ +static int Jim_EvalEnsemble(Jim_Interp *interp, const char *basecmd, const char *subcmd, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *prefixObj = Jim_NewStringObj(interp, basecmd, -1); + + Jim_AppendString(interp, prefixObj, " ", 1); + Jim_AppendString(interp, prefixObj, subcmd, -1); + + return Jim_EvalObjPrefix(interp, prefixObj, argc, argv); +} + +static int JimNamespaceCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *nsObj; + Jim_Obj *objPtr; + int option; + static const char * const options[] = { + "eval", "current", "canonical", "qualifiers", "parent", "tail", "delete", + "origin", "code", "inscope", "import", "export", + "which", "upvar", NULL + }; + enum + { + OPT_EVAL, OPT_CURRENT, OPT_CANONICAL, OPT_QUALIFIERS, OPT_PARENT, OPT_TAIL, OPT_DELETE, + OPT_ORIGIN, OPT_CODE, OPT_INSCOPE, OPT_IMPORT, OPT_EXPORT, + OPT_WHICH, OPT_UPVAR, + }; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "subcommand ?arg ...?"); + return JIM_ERR; + } + + if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + + switch (option) { + case OPT_EVAL: + if (argc < 4) { + Jim_WrongNumArgs(interp, 2, argv, "name arg ?arg...?"); + return JIM_ERR; + } + if (argc == 4) { + objPtr = argv[3]; + } + else { + objPtr = Jim_ConcatObj(interp, argc - 3, argv + 3); + } + + nsObj = JimCanonicalNamespace(interp, interp->framePtr->nsObj, argv[2]); + return Jim_EvalNamespace(interp, objPtr, nsObj); + + case OPT_CURRENT: + if (argc != 2) { + Jim_WrongNumArgs(interp, 2, argv, ""); + return JIM_ERR; + } + Jim_SetResult(interp, JimNamespaceCurrent(interp)); + return JIM_OK; + + case OPT_CANONICAL: + if (argc > 4) { + Jim_WrongNumArgs(interp, 2, argv, "?current? ?name?"); + return JIM_ERR; + } + if (argc == 2) { + Jim_SetResult(interp, interp->framePtr->nsObj); + } + else if (argc == 3) { + Jim_SetResult(interp, JimCanonicalNamespace(interp, interp->framePtr->nsObj, argv[2])); + } + else { + Jim_SetResult(interp, JimCanonicalNamespace(interp, argv[2], argv[3])); + } + return JIM_OK; + + case OPT_QUALIFIERS: + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "string"); + return JIM_ERR; + } + Jim_SetResult(interp, Jim_NamespaceQualifiers(interp, argv[2])); + return JIM_OK; + + case OPT_EXPORT: + return JIM_OK; + + case OPT_TAIL: + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "string"); + return JIM_ERR; + } + Jim_SetResult(interp, Jim_NamespaceTail(interp, argv[2])); + return JIM_OK; + + case OPT_PARENT: + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "?name?"); + return JIM_ERR; + } + else { + const char *name; + + if (argc == 3) { + objPtr = argv[2]; + } + else { + objPtr = interp->framePtr->nsObj; + } + if (Jim_Length(objPtr) == 0 || Jim_CompareStringImmediate(interp, objPtr, "::")) { + return JIM_OK; + } + objPtr = Jim_NamespaceQualifiers(interp, objPtr); + + name = Jim_String(objPtr); + + if (name[0] != ':' || name[1] != ':') { + /* Make it fully scoped */ + Jim_SetResultString(interp, "::", 2); + Jim_AppendObj(interp, Jim_GetResult(interp), objPtr); + Jim_IncrRefCount(objPtr); + Jim_DecrRefCount(interp, objPtr); + } + else { + Jim_SetResult(interp, objPtr); + } + } + return JIM_OK; + } + + /* Implemented as a Tcl helper proc. + * Note that calling a proc will change the current namespace, + * so helper procs must call [uplevel namespace canon] to get the callers + * namespace. + */ + return Jim_EvalEnsemble(interp, "namespace", options[option], argc - 2, argv + 2); +} + +int Jim_namespaceInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "namespace", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "namespace", JimNamespaceCmd, NULL, NULL); + Jim_CreateCommand(interp, "variable", JimVariableCmd, NULL, NULL); + return JIM_OK; +} + diff --git a/debuggers/openocd/jimtcl/jim-pack.c b/debuggers/openocd/jimtcl/jim-pack.c new file mode 100644 index 00000000..88bf2c16 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-pack.c @@ -0,0 +1,380 @@ +#include +#include + +/* Provides the [pack] and [unpack] commands to pack and unpack + * a binary string to/from arbitrary width integers and strings. + * + * This may be used to implement the [binary] command. + */ + +/** + * Big endian bit test. + * + * Considers 'bitvect' as a big endian bit stream and returns + * bit 'b' as zero or non-zero. + */ +static int JimTestBitBigEndian(const unsigned char *bitvec, int b) +{ + div_t pos = div(b, 8); + return bitvec[pos.quot] & (1 << (7 - pos.rem)); +} + +/** + * Little endian bit test. + * + * Considers 'bitvect' as a little endian bit stream and returns + * bit 'b' as zero or non-zero. + */ +static int JimTestBitLittleEndian(const unsigned char *bitvec, int b) +{ + div_t pos = div(b, 8); + return bitvec[pos.quot] & (1 << pos.rem); +} + +/** + * Sign extends the given value, 'n' of width 'width' bits. + * + * For example, sign extending 0x80 with a width of 8, produces -128 + */ +static jim_wide JimSignExtend(jim_wide n, int width) +{ + if (width == sizeof(jim_wide) * 8) { + /* Can't sign extend the maximum size integer */ + return n; + } + if (n & ((jim_wide)1 << (width - 1))) { + /* Need to extend */ + n -= ((jim_wide)1 << width); + } + + return n; +} + +/** + * Big endian integer extraction. + * + * Considers 'bitvect' as a big endian bit stream. + * Returns an integer of the given width (in bits) + * starting at the given position (in bits). + * + * The pos/width must represent bits inside bitvec, + * and the width be no more than the width of jim_wide. + */ +static jim_wide JimBitIntBigEndian(const unsigned char *bitvec, int pos, int width) +{ + jim_wide result = 0; + int i; + + /* Aligned, byte extraction */ + if (pos % 8 == 0 && width % 8 == 0) { + for (i = 0; i < width; i += 8) { + result = (result << 8) + bitvec[(pos + i) / 8]; + } + return result; + } + + /* Unaligned */ + for (i = 0; i < width; i++) { + if (JimTestBitBigEndian(bitvec, pos + width - i - 1)) { + result |= ((jim_wide)1 << i); + } + } + + return result; +} + +/** + * Little endian integer extraction. + * + * Like JimBitIntBigEndian() but considers 'bitvect' as a little endian bit stream. + */ +static jim_wide JimBitIntLittleEndian(const unsigned char *bitvec, int pos, int width) +{ + jim_wide result = 0; + int i; + + /* Aligned, byte extraction */ + if (pos % 8 == 0 && width % 8 == 0) { + for (i = 0; i < width; i += 8) { + result += (jim_wide)bitvec[(pos + i) / 8] << i; + } + return result; + } + + /* Unaligned */ + for (i = 0; i < width; i++) { + if (JimTestBitLittleEndian(bitvec, pos + i)) { + result |= ((jim_wide)1 << i); + } + } + + return result; +} + +/** + * Big endian bit set. + * + * Considers 'bitvect' as a big endian bit stream and sets + * bit 'b' to 'bit' + */ +static void JimSetBitBigEndian(unsigned char *bitvec, int b, int bit) +{ + div_t pos = div(b, 8); + if (bit) { + bitvec[pos.quot] |= (1 << (7 - pos.rem)); + } + else { + bitvec[pos.quot] &= ~(1 << (7 - pos.rem)); + } +} + +/** + * Little endian bit set. + * + * Considers 'bitvect' as a little endian bit stream and sets + * bit 'b' to 'bit' + */ +static void JimSetBitLittleEndian(unsigned char *bitvec, int b, int bit) +{ + div_t pos = div(b, 8); + if (bit) { + bitvec[pos.quot] |= (1 << pos.rem); + } + else { + bitvec[pos.quot] &= ~(1 << pos.rem); + } +} + +/** + * Big endian integer packing. + * + * Considers 'bitvect' as a big endian bit stream. + * Packs integer 'value' of the given width (in bits) + * starting at the given position (in bits). + * + * The pos/width must represent bits inside bitvec, + * and the width be no more than the width of jim_wide. + */ +static void JimSetBitsIntBigEndian(unsigned char *bitvec, jim_wide value, int pos, int width) +{ + int i; + + /* Common fast option */ + if (pos % 8 == 0 && width == 8) { + bitvec[pos / 8] = value; + return; + } + + for (i = 0; i < width; i++) { + int bit = !!(value & ((jim_wide)1 << i)); + JimSetBitBigEndian(bitvec, pos + width - i - 1, bit); + } +} + +/** + * Little endian version of JimSetBitsIntBigEndian() + */ +static void JimSetBitsIntLittleEndian(unsigned char *bitvec, jim_wide value, int pos, int width) +{ + int i; + + /* Common fast option */ + if (pos % 8 == 0 && width == 8) { + bitvec[pos / 8] = value; + return; + } + + for (i = 0; i < width; i++) { + int bit = !!(value & ((jim_wide)1 << i)); + JimSetBitLittleEndian(bitvec, pos + i, bit); + } +} + +/** + * [unpack] + * + * Usage: unpack binvalue -intbe|-intle|-uintbe|-uintle|-str bitpos bitwidth + * + * Unpacks bits from $binvalue at bit position $bitpos and with $bitwidth. + * Interprets the value according to the type and returns it. + */ +static int Jim_UnpackCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int option; + static const char * const options[] = { "-intbe", "-intle", "-uintbe", "-uintle", "-str", NULL }; + enum { OPT_INTBE, OPT_INTLE, OPT_UINTBE, OPT_UINTLE, OPT_STR, }; + jim_wide pos; + jim_wide width; + + if (argc != 5) { + Jim_WrongNumArgs(interp, 1, argv, "binvalue -intbe|-intle|-uintbe|-uintle|-str bitpos bitwidth"); + return JIM_ERR; + } + if (Jim_GetEnum(interp, argv[2], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + + if (Jim_GetWide(interp, argv[3], &pos) != JIM_OK) { + return JIM_ERR; + } + if (Jim_GetWide(interp, argv[4], &width) != JIM_OK) { + return JIM_ERR; + } + + if (option == OPT_STR) { + int len; + const char *str = Jim_GetString(argv[1], &len); + + if (width % 8 || pos % 8) { + Jim_SetResultString(interp, "string field is not on a byte boundary", -1); + return JIM_ERR; + } + + if (pos >= 0 && width > 0 && pos < len * 8) { + if (pos + width > len * 8) { + width = len * 8 - pos; + } + Jim_SetResultString(interp, str + pos / 8, width / 8); + } + return JIM_OK; + } + else { + int len; + const unsigned char *str = (const unsigned char *)Jim_GetString(argv[1], &len); + jim_wide result = 0; + + if (width > sizeof(jim_wide) * 8) { + Jim_SetResultFormatted(interp, "int field is too wide: %#s", argv[4]); + return JIM_ERR; + } + + if (pos >= 0 && width > 0 && pos < len * 8) { + if (pos + width > len * 8) { + width = len * 8 - pos; + } + if (option == OPT_INTBE || option == OPT_UINTBE) { + result = JimBitIntBigEndian(str, pos, width); + } + else { + result = JimBitIntLittleEndian(str, pos, width); + } + if (option == OPT_INTBE || option == OPT_INTLE) { + result = JimSignExtend(result, width); + } + } + Jim_SetResultInt(interp, result); + return JIM_OK; + } +} + +/** + * [pack] + * + * Usage: pack varname value -intle|-intbe|-str width ?bitoffset? + * + * Packs the binary representation of 'value' into the variable of the given name. + * The value is packed according to the given type, width and bitoffset. + * The variable is created if necessary (like [append]) + * Ihe variable is expanded if necessary + */ +static int Jim_PackCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int option; + static const char * const options[] = { "-intle", "-intbe", "-str", NULL }; + enum { OPT_LE, OPT_BE, OPT_STR }; + jim_wide pos = 0; + jim_wide width; + jim_wide value; + Jim_Obj *stringObjPtr; + int len; + int freeobj = 0; + + if (argc != 5 && argc != 6) { + Jim_WrongNumArgs(interp, 1, argv, "varName value -intle|-intbe|-str bitwidth ?bitoffset?"); + return JIM_ERR; + } + if (Jim_GetEnum(interp, argv[3], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + if (option != OPT_STR && Jim_GetWide(interp, argv[2], &value) != JIM_OK) { + return JIM_ERR; + } + if (Jim_GetWide(interp, argv[4], &width) != JIM_OK) { + return JIM_ERR; + } + if (width <= 0 || (option == OPT_STR && width % 8) || (option != OPT_STR && width > sizeof(jim_wide) * 8)) { + Jim_SetResultFormatted(interp, "bad bitwidth: %#s", argv[5]); + return JIM_ERR; + } + if (argc == 6) { + if (Jim_GetWide(interp, argv[5], &pos) != JIM_OK) { + return JIM_ERR; + } + if (pos < 0 || (option == OPT_STR && pos % 8)) { + Jim_SetResultFormatted(interp, "bad bitoffset: %#s", argv[5]); + return JIM_ERR; + } + } + + stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); + if (!stringObjPtr) { + /* Create the string if it doesn't exist */ + stringObjPtr = Jim_NewEmptyStringObj(interp); + freeobj = 1; + } + else if (Jim_IsShared(stringObjPtr)) { + freeobj = 1; + stringObjPtr = Jim_DuplicateObj(interp, stringObjPtr); + } + + len = Jim_Length(stringObjPtr) * 8; + + /* Extend the string as necessary first */ + while (len < pos + width) { + Jim_AppendString(interp, stringObjPtr, "", 1); + len += 8; + } + + Jim_SetResultInt(interp, pos + width); + + /* Now set the bits. Note that the the string *must* have no non-string rep + * since we are writing the bytes directly. + */ + Jim_AppendString(interp, stringObjPtr, "", 0); + + if (option == OPT_BE) { + JimSetBitsIntBigEndian((unsigned char *)stringObjPtr->bytes, value, pos, width); + } + else if (option == OPT_LE) { + JimSetBitsIntLittleEndian((unsigned char *)stringObjPtr->bytes, value, pos, width); + } + else { + pos /= 8; + width /= 8; + + if (width > Jim_Length(argv[2])) { + width = Jim_Length(argv[2]); + } + memcpy(stringObjPtr->bytes + pos, Jim_GetString(argv[2], NULL), width); + /* No padding is needed since the string is already extended */ + } + + if (Jim_SetVariable(interp, argv[1], stringObjPtr) != JIM_OK) { + if (freeobj) { + Jim_FreeNewObj(interp, stringObjPtr); + return JIM_ERR; + } + } + return JIM_OK; +} + +int Jim_packInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "pack", "1.0", JIM_ERRMSG)) { + return JIM_ERR; + } + + Jim_CreateCommand(interp, "unpack", Jim_UnpackCmd, NULL, NULL); + Jim_CreateCommand(interp, "pack", Jim_PackCmd, NULL, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-package.c b/debuggers/openocd/jimtcl/jim-package.c new file mode 100644 index 00000000..d9f50a93 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-package.c @@ -0,0 +1,269 @@ +#include + +#include "jimautoconf.h" +#include + +#ifdef HAVE_UNISTD_H +#include +#else +#define R_OK 4 +#endif + +/* All packages have a fixed, dummy version */ +static const char *package_version_1 = "1.0"; + +/* ----------------------------------------------------------------------------- + * Packages handling + * ---------------------------------------------------------------------------*/ + +int Jim_PackageProvide(Jim_Interp *interp, const char *name, const char *ver, int flags) +{ + /* If the package was already provided returns an error. */ + Jim_HashEntry *he = Jim_FindHashEntry(&interp->packages, name); + + /* An empty result means the automatic entry. This can be replaced */ + if (he && *(const char *)he->u.val) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "package \"%s\" was already provided", name); + } + return JIM_ERR; + } + if (he) { + Jim_DeleteHashEntry(&interp->packages, name); + } + Jim_AddHashEntry(&interp->packages, name, (char *)ver); + return JIM_OK; +} + +static char *JimFindPackage(Jim_Interp *interp, char **prefixes, int prefixc, const char *pkgName) +{ + int i; + char *buf = Jim_Alloc(JIM_PATH_LEN); + + for (i = 0; i < prefixc; i++) { + if (prefixes[i] == NULL) + continue; + + /* Loadable modules are tried first */ +#ifdef jim_ext_load + snprintf(buf, JIM_PATH_LEN, "%s/%s.so", prefixes[i], pkgName); + if (access(buf, R_OK) == 0) { + return buf; + } +#endif + if (strcmp(prefixes[i], ".") == 0) { + snprintf(buf, JIM_PATH_LEN, "%s.tcl", pkgName); + } + else { + snprintf(buf, JIM_PATH_LEN, "%s/%s.tcl", prefixes[i], pkgName); + } + + if (access(buf, R_OK) == 0) { + return buf; + } + } + Jim_Free(buf); + return NULL; +} + +/* Search for a suitable package under every dir specified by JIM_LIBPATH, + * and load it if possible. If a suitable package was loaded with success + * JIM_OK is returned, otherwise JIM_ERR is returned. */ +static int JimLoadPackage(Jim_Interp *interp, const char *name, int flags) +{ + Jim_Obj *libPathObjPtr; + char **prefixes, *path; + int prefixc, i, retCode = JIM_ERR; + + libPathObjPtr = Jim_GetGlobalVariableStr(interp, JIM_LIBPATH, JIM_NONE); + if (libPathObjPtr == NULL) { + prefixc = 0; + libPathObjPtr = NULL; + } + else { + Jim_IncrRefCount(libPathObjPtr); + prefixc = Jim_ListLength(interp, libPathObjPtr); + } + + prefixes = Jim_Alloc(sizeof(char *) * prefixc); + for (i = 0; i < prefixc; i++) { + Jim_Obj *prefixObjPtr; + + if (Jim_ListIndex(interp, libPathObjPtr, i, &prefixObjPtr, JIM_NONE) != JIM_OK) { + prefixes[i] = NULL; + continue; + } + prefixes[i] = Jim_StrDup(Jim_String(prefixObjPtr)); + } + + /* Scan every directory for the the first match */ + path = JimFindPackage(interp, prefixes, prefixc, name); + if (path != NULL) { + char *p = strrchr(path, '.'); + + /* Note: Even if the file fails to load, we consider the package loaded. + * This prevents issues with recursion. + * Use a dummy version of "" to signify this case. + */ + Jim_PackageProvide(interp, name, "", 0); + + /* Try to load/source it */ + if (p && strcmp(p, ".tcl") == 0) { + retCode = Jim_EvalFileGlobal(interp, path); + } +#ifdef jim_ext_load + else { + retCode = Jim_LoadLibrary(interp, path); + } +#endif + if (retCode != JIM_OK) { + /* Upon failure, remove the dummy entry */ + Jim_DeleteHashEntry(&interp->packages, name); + } + Jim_Free(path); + } + for (i = 0; i < prefixc; i++) + Jim_Free(prefixes[i]); + Jim_Free(prefixes); + if (libPathObjPtr) + Jim_DecrRefCount(interp, libPathObjPtr); + return retCode; +} + +int Jim_PackageRequire(Jim_Interp *interp, const char *name, int flags) +{ + Jim_HashEntry *he; + + /* Start with an empty error string */ + Jim_SetResultString(interp, "", 0); + + he = Jim_FindHashEntry(&interp->packages, name); + if (he == NULL) { + /* Try to load the package. */ + int retcode = JimLoadPackage(interp, name, flags); + if (retcode != JIM_OK) { + if (flags & JIM_ERRMSG) { + int len; + + Jim_GetString(Jim_GetResult(interp), &len); + Jim_SetResultFormatted(interp, "%#s%sCan't load package %s", + Jim_GetResult(interp), len ? "\n" : "", name); + } + return retcode; + } + + /* In case the package did no 'package provide' */ + Jim_PackageProvide(interp, name, "1.0", 0); + + /* Now it must exist */ + he = Jim_FindHashEntry(&interp->packages, name); + } + + Jim_SetResultString(interp, he->u.val, -1); + return JIM_OK; +} + +/* + *---------------------------------------------------------------------- + * + * package provide name ?version? + * + * This procedure is invoked to declare that + * a particular package is now present in an interpreter. + * The package must not already be provided in the interpreter. + * + * Results: + * Returns JIM_OK and sets results as "1.0" (the given version is ignored) + * + *---------------------------------------------------------------------- + */ +static int package_cmd_provide(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return Jim_PackageProvide(interp, Jim_String(argv[0]), package_version_1, JIM_ERRMSG); +} + +/* + *---------------------------------------------------------------------- + * + * package require name ?version? + * + * This procedure is load a given package. + * Note that the version is ignored. + * + * Results: + * Returns JIM_OK and sets the package version. + * + *---------------------------------------------------------------------- + */ +static int package_cmd_require(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + /* package require failing is important enough to add to the stack */ + interp->addStackTrace++; + + return Jim_PackageRequire(interp, Jim_String(argv[0]), JIM_ERRMSG); +} + +/* + *---------------------------------------------------------------------- + * + * package list + * + * Returns a list of known packages + * + * Results: + * Returns JIM_OK and sets a list of known packages. + * + *---------------------------------------------------------------------- + */ +static int package_cmd_list(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_HashTableIterator *htiter; + Jim_HashEntry *he; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + htiter = Jim_GetHashTableIterator(&interp->packages); + while ((he = Jim_NextHashEntry(htiter)) != NULL) { + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, he->key, -1)); + } + Jim_FreeHashTableIterator(htiter); + + Jim_SetResult(interp, listObjPtr); + + return JIM_OK; +} + +static const jim_subcmd_type package_command_table[] = { + { + "provide", + "name ?version?", + package_cmd_provide, + 1, + 2, + /* Description: Indicates that the current script provides the given package */ + }, + { + "require", + "name ?version?", + package_cmd_require, + 1, + 2, + /* Description: Loads the given package by looking in standard places */ + }, + { + "list", + NULL, + package_cmd_list, + 0, + 0, + /* Description: Lists all known packages */ + }, + { + NULL + } +}; + +int Jim_packageInit(Jim_Interp *interp) +{ + Jim_CreateCommand(interp, "package", Jim_SubCmdProc, (void *)package_command_table, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-posix.c b/debuggers/openocd/jimtcl/jim-posix.c new file mode 100644 index 00000000..5c1ae7f9 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-posix.c @@ -0,0 +1,245 @@ +/* + * Jim - POSIX extension + * + * Copyright 2005 Salvatore Sanfilippo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "jimautoconf.h" +#include + +#ifdef HAVE_SYS_SYSINFO_H +#include +#endif + +static void Jim_PosixSetError(Jim_Interp *interp) +{ + Jim_SetResultString(interp, strerror(errno), -1); +} + +#if defined(HAVE_FORK) +static int Jim_PosixForkCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + pid_t pid; + + JIM_NOTUSED(argv); + + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + if ((pid = fork()) == -1) { + Jim_PosixSetError(interp); + return JIM_ERR; + } + Jim_SetResultInt(interp, (jim_wide) pid); + return JIM_OK; +} +#endif + +/* + * os.wait ?-nohang? pid + * + * An interface to waitpid(2) + * + * Returns a 3 element list. + * + * If -nohang is specified, and the process is still alive, returns + * + * {0 none 0} + * + * If the process does not exist or has already been waited for, returns: + * + * {-1 error } + * + * If the process exited normally, returns: + * + * { exit } + * + * If the process terminated on a signal, returns: + * + * { signal } + * + * Otherwise (core dump, stopped, continued, ...), returns: + * + * { other 0} + */ +static int Jim_PosixWaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int nohang = 0; + long pid; + int status; + Jim_Obj *listObj; + const char *type; + int value; + + if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-nohang")) { + nohang = 1; + } + if (argc != nohang + 2) { + Jim_WrongNumArgs(interp, 1, argv, "?-nohang? pid"); + return JIM_ERR; + } + if (Jim_GetLong(interp, argv[nohang + 1], &pid) != JIM_OK) { + return JIM_ERR; + } + + pid = waitpid(pid, &status, nohang ? WNOHANG : 0); + listObj = Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, pid)); + if (pid < 0) { + type = "error"; + value = errno; + } + else if (pid == 0) { + type = "none"; + value = 0; + } + else if (WIFEXITED(status)) { + type = "exit"; + value = WEXITSTATUS(status); + } + else if (WIFSIGNALED(status)) { + type = "signal"; + value = WTERMSIG(status); + } + else { + type = "other"; + value = 0; + } + + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, type, -1)); + if (pid < 0) { + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, strerror(value), -1)); + } + else { + Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value)); + } + Jim_SetResult(interp, listObj); + return JIM_OK; +} + +static int Jim_PosixGetidsCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objv[8]; + + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + objv[0] = Jim_NewStringObj(interp, "uid", -1); + objv[1] = Jim_NewIntObj(interp, getuid()); + objv[2] = Jim_NewStringObj(interp, "euid", -1); + objv[3] = Jim_NewIntObj(interp, geteuid()); + objv[4] = Jim_NewStringObj(interp, "gid", -1); + objv[5] = Jim_NewIntObj(interp, getgid()); + objv[6] = Jim_NewStringObj(interp, "egid", -1); + objv[7] = Jim_NewIntObj(interp, getegid()); + Jim_SetResult(interp, Jim_NewListObj(interp, objv, 8)); + return JIM_OK; +} + +#define JIM_HOST_NAME_MAX 1024 +static int Jim_PosixGethostnameCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + char *buf; + int rc = JIM_OK; + + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + buf = Jim_Alloc(JIM_HOST_NAME_MAX); + if (gethostname(buf, JIM_HOST_NAME_MAX) == -1) { + Jim_PosixSetError(interp); + rc = JIM_ERR; + } + else { + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, -1)); + } + return rc; +} + +static int Jim_PosixUptimeCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ +#ifdef HAVE_STRUCT_SYSINFO_UPTIME + struct sysinfo info; + + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + + if (sysinfo(&info) == -1) { + Jim_PosixSetError(interp); + return JIM_ERR; + } + + Jim_SetResultInt(interp, info.uptime); +#else + Jim_SetResultInt(interp, (long)time(NULL)); +#endif + return JIM_OK; +} + +static int Jim_PosixPidCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + + Jim_SetResultInt(interp, getpid()); + return JIM_OK; +} + +int Jim_posixInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "posix", "1.0", JIM_ERRMSG)) + return JIM_ERR; + +#ifdef HAVE_FORK + Jim_CreateCommand(interp, "os.fork", Jim_PosixForkCommand, NULL, NULL); +#endif + Jim_CreateCommand(interp, "os.wait", Jim_PosixWaitCommand, NULL, NULL); + Jim_CreateCommand(interp, "os.getids", Jim_PosixGetidsCommand, NULL, NULL); + Jim_CreateCommand(interp, "os.gethostname", Jim_PosixGethostnameCommand, NULL, NULL); + Jim_CreateCommand(interp, "os.uptime", Jim_PosixUptimeCommand, NULL, NULL); + Jim_CreateCommand(interp, "pid", Jim_PosixPidCommand, NULL, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-readdir.c b/debuggers/openocd/jimtcl/jim-readdir.c new file mode 100644 index 00000000..a4056924 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-readdir.c @@ -0,0 +1,122 @@ + +/* + * Tcl readdir command. + * + * (c) 2008 Steve Bennett + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + * + * Based on original work by: + *----------------------------------------------------------------------------- + * Copyright 1991-1994 Karl Lehenbauer and Mark Diekhans. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies. Karl Lehenbauer and + * Mark Diekhans make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + *----------------------------------------------------------------------------- + */ + +#include +#include +#include + +#include +#include + +#ifdef HAVE_DIRENT_H +#include +#endif + +/* + *----------------------------------------------------------------------------- + * + * Jim_ReaddirCmd -- + * Implements the rename TCL command: + * readdir ?-nocomplain? dirPath + * + * Results: + * Standard TCL result. + *----------------------------------------------------------------------------- + */ +int Jim_ReaddirCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *dirPath; + DIR *dirPtr; + struct dirent *entryPtr; + int nocomplain = 0; + + if (argc == 3 && Jim_CompareStringImmediate(interp, argv[1], "-nocomplain")) { + nocomplain = 1; + } + if (argc != 2 && !nocomplain) { + Jim_WrongNumArgs(interp, 1, argv, "?-nocomplain? dirPath"); + return JIM_ERR; + } + + dirPath = Jim_String(argv[1 + nocomplain]); + + dirPtr = opendir(dirPath); + if (dirPtr == NULL) { + if (nocomplain) { + return JIM_OK; + } + Jim_SetResultString(interp, strerror(errno), -1); + return JIM_ERR; + } + Jim_SetResultString(interp, strerror(errno), -1); + + Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); + + while ((entryPtr = readdir(dirPtr)) != NULL) { + if (entryPtr->d_name[0] == '.') { + if (entryPtr->d_name[1] == '\0') { + continue; + } + if ((entryPtr->d_name[1] == '.') && (entryPtr->d_name[2] == '\0')) + continue; + } + Jim_ListAppendElement(interp, Jim_GetResult(interp), Jim_NewStringObj(interp, + entryPtr->d_name, -1)); + } + closedir(dirPtr); + + return JIM_OK; +} + +int Jim_readdirInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "readdir", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "readdir", Jim_ReaddirCmd, NULL, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-readline.c b/debuggers/openocd/jimtcl/jim-readline.c new file mode 100644 index 00000000..39051b03 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-readline.c @@ -0,0 +1,74 @@ +/* + * Jim - Readline bindings for Jim + * + * Copyright 2005 Salvatore Sanfilippo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + */ + +#include + +#include +#include + +static int JimRlReadlineCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + char *line; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "prompt"); + return JIM_ERR; + } + line = readline(Jim_String(argv[1])); + if (!line) { + return JIM_EXIT; + } + Jim_SetResult(interp, Jim_NewStringObj(interp, line, -1)); + return JIM_OK; +} + +static int JimRlAddHistoryCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "string"); + return JIM_ERR; + } + add_history(Jim_String(argv[1])); + return JIM_OK; +} + +int Jim_readlineInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "readline", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "readline.readline", JimRlReadlineCommand, NULL, NULL); + Jim_CreateCommand(interp, "readline.addhistory", JimRlAddHistoryCommand, NULL, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-regexp.c b/debuggers/openocd/jimtcl/jim-regexp.c new file mode 100644 index 00000000..de28b939 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-regexp.c @@ -0,0 +1,566 @@ +/* + * Implements the regexp and regsub commands for Jim + * + * (c) 2008 Steve Bennett + * + * Uses C library regcomp()/regexec() for the matching. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + * + * Based on code originally from Tcl 6.7: + * + * Copyright 1987-1991 Regents of the University of California + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies. The University of California + * makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without + * express or implied warranty. + */ + +#include +#include + +#include "jimautoconf.h" +#include "jim.h" +#include "jimregexp.h" + +static void FreeRegexpInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + regfree(objPtr->internalRep.regexpValue.compre); + Jim_Free(objPtr->internalRep.regexpValue.compre); +} + +static const Jim_ObjType regexpObjType = { + "regexp", + FreeRegexpInternalRep, + NULL, + NULL, + JIM_TYPE_NONE +}; + +static regex_t *SetRegexpFromAny(Jim_Interp *interp, Jim_Obj *objPtr, unsigned flags) +{ + regex_t *compre; + const char *pattern; + int ret; + + /* Check if the object is already an uptodate variable */ + if (objPtr->typePtr == ®expObjType && + objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) { + /* nothing to do */ + return objPtr->internalRep.regexpValue.compre; + } + + /* Not a regexp or the flags do not match */ + + /* Get the string representation */ + pattern = Jim_String(objPtr); + compre = Jim_Alloc(sizeof(regex_t)); + + if ((ret = regcomp(compre, pattern, REG_EXTENDED | flags)) != 0) { + char buf[100]; + + regerror(ret, compre, buf, sizeof(buf)); + Jim_SetResultFormatted(interp, "couldn't compile regular expression pattern: %s", buf); + regfree(compre); + Jim_Free(compre); + return NULL; + } + + Jim_FreeIntRep(interp, objPtr); + + objPtr->typePtr = ®expObjType; + objPtr->internalRep.regexpValue.flags = flags; + objPtr->internalRep.regexpValue.compre = compre; + + return compre; +} + +int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int opt_indices = 0; + int opt_all = 0; + int opt_inline = 0; + regex_t *regex; + int match, i, j; + int offset = 0; + regmatch_t *pmatch = NULL; + int source_len; + int result = JIM_OK; + const char *pattern; + const char *source_str; + int num_matches = 0; + int num_vars; + Jim_Obj *resultListObj = NULL; + int regcomp_flags = 0; + int eflags = 0; + int option; + enum { + OPT_INDICES, OPT_NOCASE, OPT_LINE, OPT_ALL, OPT_INLINE, OPT_START, OPT_END + }; + static const char * const options[] = { + "-indices", "-nocase", "-line", "-all", "-inline", "-start", "--", NULL + }; + + if (argc < 3) { + wrongNumArgs: + Jim_WrongNumArgs(interp, 1, argv, + "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?"); + return JIM_ERR; + } + + for (i = 1; i < argc; i++) { + const char *opt = Jim_String(argv[i]); + + if (*opt != '-') { + break; + } + if (Jim_GetEnum(interp, argv[i], options, &option, "switch", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + if (option == OPT_END) { + i++; + break; + } + switch (option) { + case OPT_INDICES: + opt_indices = 1; + break; + + case OPT_NOCASE: + regcomp_flags |= REG_ICASE; + break; + + case OPT_LINE: + regcomp_flags |= REG_NEWLINE; + break; + + case OPT_ALL: + opt_all = 1; + break; + + case OPT_INLINE: + opt_inline = 1; + break; + + case OPT_START: + if (++i == argc) { + goto wrongNumArgs; + } + if (Jim_GetIndex(interp, argv[i], &offset) != JIM_OK) { + return JIM_ERR; + } + break; + } + } + if (argc - i < 2) { + goto wrongNumArgs; + } + + regex = SetRegexpFromAny(interp, argv[i], regcomp_flags); + if (!regex) { + return JIM_ERR; + } + + pattern = Jim_String(argv[i]); + source_str = Jim_GetString(argv[i + 1], &source_len); + + num_vars = argc - i - 2; + + if (opt_inline) { + if (num_vars) { + Jim_SetResultString(interp, "regexp match variables not allowed when using -inline", + -1); + result = JIM_ERR; + goto done; + } + num_vars = regex->re_nsub + 1; + } + + pmatch = Jim_Alloc((num_vars + 1) * sizeof(*pmatch)); + + /* If an offset has been specified, adjust for that now. + * If it points past the end of the string, point to the terminating null + */ + if (offset) { + if (offset < 0) { + offset += source_len + 1; + } + if (offset > source_len) { + source_str += source_len; + } + else if (offset > 0) { + source_str += offset; + } + eflags |= REG_NOTBOL; + } + + if (opt_inline) { + resultListObj = Jim_NewListObj(interp, NULL, 0); + } + + next_match: + match = regexec(regex, source_str, num_vars + 1, pmatch, eflags); + if (match >= REG_BADPAT) { + char buf[100]; + + regerror(match, regex, buf, sizeof(buf)); + Jim_SetResultFormatted(interp, "error while matching pattern: %s", buf); + result = JIM_ERR; + goto done; + } + + if (match == REG_NOMATCH) { + goto done; + } + + num_matches++; + + if (opt_all && !opt_inline) { + /* Just count the number of matches, so skip the substitution h */ + goto try_next_match; + } + + /* + * If additional variable names have been specified, return + * index information in those variables. + */ + + j = 0; + for (i += 2; opt_inline ? j < num_vars : i < argc; i++, j++) { + Jim_Obj *resultObj; + + if (opt_indices) { + resultObj = Jim_NewListObj(interp, NULL, 0); + } + else { + resultObj = Jim_NewStringObj(interp, "", 0); + } + + if (pmatch[j].rm_so == -1) { + if (opt_indices) { + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, -1)); + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, -1)); + } + } + else { + int len = pmatch[j].rm_eo - pmatch[j].rm_so; + + if (opt_indices) { + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, + offset + pmatch[j].rm_so)); + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, + offset + pmatch[j].rm_so + len - 1)); + } + else { + Jim_AppendString(interp, resultObj, source_str + pmatch[j].rm_so, len); + } + } + + if (opt_inline) { + Jim_ListAppendElement(interp, resultListObj, resultObj); + } + else { + /* And now set the result variable */ + result = Jim_SetVariable(interp, argv[i], resultObj); + + if (result != JIM_OK) { + Jim_FreeObj(interp, resultObj); + break; + } + } + } + + try_next_match: + if (opt_all && (pattern[0] != '^' || (regcomp_flags & REG_NEWLINE)) && *source_str) { + if (pmatch[0].rm_eo) { + offset += pmatch[0].rm_eo; + source_str += pmatch[0].rm_eo; + } + else { + source_str++; + offset++; + } + if (*source_str) { + eflags = REG_NOTBOL; + goto next_match; + } + } + + done: + if (result == JIM_OK) { + if (opt_inline) { + Jim_SetResult(interp, resultListObj); + } + else { + Jim_SetResultInt(interp, num_matches); + } + } + + Jim_Free(pmatch); + return result; +} + +#define MAX_SUB_MATCHES 50 + +int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int regcomp_flags = 0; + int regexec_flags = 0; + int opt_all = 0; + int offset = 0; + regex_t *regex; + const char *p; + int result; + regmatch_t pmatch[MAX_SUB_MATCHES + 1]; + int num_matches = 0; + + int i, j, n; + Jim_Obj *varname; + Jim_Obj *resultObj; + const char *source_str; + int source_len; + const char *replace_str; + int replace_len; + const char *pattern; + int option; + enum { + OPT_NOCASE, OPT_LINE, OPT_ALL, OPT_START, OPT_END + }; + static const char * const options[] = { + "-nocase", "-line", "-all", "-start", "--", NULL + }; + + if (argc < 4) { + wrongNumArgs: + Jim_WrongNumArgs(interp, 1, argv, + "?switches? exp string subSpec ?varName?"); + return JIM_ERR; + } + + for (i = 1; i < argc; i++) { + const char *opt = Jim_String(argv[i]); + + if (*opt != '-') { + break; + } + if (Jim_GetEnum(interp, argv[i], options, &option, "switch", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + if (option == OPT_END) { + i++; + break; + } + switch (option) { + case OPT_NOCASE: + regcomp_flags |= REG_ICASE; + break; + + case OPT_LINE: + regcomp_flags |= REG_NEWLINE; + break; + + case OPT_ALL: + opt_all = 1; + break; + + case OPT_START: + if (++i == argc) { + goto wrongNumArgs; + } + if (Jim_GetIndex(interp, argv[i], &offset) != JIM_OK) { + return JIM_ERR; + } + break; + } + } + if (argc - i != 3 && argc - i != 4) { + goto wrongNumArgs; + } + + regex = SetRegexpFromAny(interp, argv[i], regcomp_flags); + if (!regex) { + return JIM_ERR; + } + pattern = Jim_String(argv[i]); + + source_str = Jim_GetString(argv[i + 1], &source_len); + replace_str = Jim_GetString(argv[i + 2], &replace_len); + varname = argv[i + 3]; + + /* Create the result string */ + resultObj = Jim_NewStringObj(interp, "", 0); + + /* If an offset has been specified, adjust for that now. + * If it points past the end of the string, point to the terminating null + */ + if (offset) { + if (offset < 0) { + offset += source_len + 1; + } + if (offset > source_len) { + offset = source_len; + } + else if (offset < 0) { + offset = 0; + } + } + + /* Copy the part before -start */ + Jim_AppendString(interp, resultObj, source_str, offset); + + /* + * The following loop is to handle multiple matches within the + * same source string; each iteration handles one match and its + * corresponding substitution. If "-all" hasn't been specified + * then the loop body only gets executed once. + */ + + n = source_len - offset; + p = source_str + offset; + do { + int match = regexec(regex, p, MAX_SUB_MATCHES, pmatch, regexec_flags); + + if (match >= REG_BADPAT) { + char buf[100]; + + regerror(match, regex, buf, sizeof(buf)); + Jim_SetResultFormatted(interp, "error while matching pattern: %s", buf); + return JIM_ERR; + } + if (match == REG_NOMATCH) { + break; + } + + num_matches++; + + /* + * Copy the portion of the source string before the match to the + * result variable. + */ + Jim_AppendString(interp, resultObj, p, pmatch[0].rm_so); + + /* + * Append the subSpec (replace_str) argument to the variable, making appropriate + * substitutions. This code is a bit hairy because of the backslash + * conventions and because the code saves up ranges of characters in + * subSpec to reduce the number of calls to Jim_SetVar. + */ + + for (j = 0; j < replace_len; j++) { + int idx; + int c = replace_str[j]; + + if (c == '&') { + idx = 0; + } + else if (c == '\\' && j < replace_len) { + c = replace_str[++j]; + if ((c >= '0') && (c <= '9')) { + idx = c - '0'; + } + else if ((c == '\\') || (c == '&')) { + Jim_AppendString(interp, resultObj, replace_str + j, 1); + continue; + } + else { + Jim_AppendString(interp, resultObj, replace_str + j - 1, 2); + continue; + } + } + else { + Jim_AppendString(interp, resultObj, replace_str + j, 1); + continue; + } + if ((idx < MAX_SUB_MATCHES) && pmatch[idx].rm_so != -1 && pmatch[idx].rm_eo != -1) { + Jim_AppendString(interp, resultObj, p + pmatch[idx].rm_so, + pmatch[idx].rm_eo - pmatch[idx].rm_so); + } + } + + p += pmatch[0].rm_eo; + n -= pmatch[0].rm_eo; + + /* If -all is not specified, or there is no source left, we are done */ + if (!opt_all || n == 0) { + break; + } + + /* An anchored pattern without -line must be done */ + if ((regcomp_flags & REG_NEWLINE) == 0 && pattern[0] == '^') { + break; + } + + /* If the pattern is empty, need to step forwards */ + if (pattern[0] == '\0' && n) { + /* Need to copy the char we are moving over */ + Jim_AppendString(interp, resultObj, p, 1); + p++; + n--; + } + + regexec_flags |= REG_NOTBOL; + } while (n); + + /* + * Copy the portion of the string after the last match to the + * result variable. + */ + Jim_AppendString(interp, resultObj, p, -1); + + /* And now set or return the result variable */ + if (argc - i == 4) { + result = Jim_SetVariable(interp, varname, resultObj); + + if (result == JIM_OK) { + Jim_SetResultInt(interp, num_matches); + } + else { + Jim_FreeObj(interp, resultObj); + } + } + else { + Jim_SetResult(interp, resultObj); + result = JIM_OK; + } + + return result; +} + +int Jim_regexpInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "regexp", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "regexp", Jim_RegexpCmd, NULL, NULL); + Jim_CreateCommand(interp, "regsub", Jim_RegsubCmd, NULL, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-sdl.c b/debuggers/openocd/jimtcl/jim-sdl.c new file mode 100644 index 00000000..1af7dfa2 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-sdl.c @@ -0,0 +1,247 @@ +/* + * Jim - SDL extension + * + * Copyright 2005 Salvatore Sanfilippo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define AIO_CMD_LEN 128 + +typedef struct JimSdlSurface +{ + SDL_Surface *screen; +} JimSdlSurface; + +static void JimSdlSetError(Jim_Interp *interp) +{ + Jim_SetResultString(interp, SDL_GetError(), -1); +} + +static void JimSdlDelProc(Jim_Interp *interp, void *privData) +{ + JimSdlSurface *jss = privData; + + JIM_NOTUSED(interp); + + SDL_FreeSurface(jss->screen); + Jim_Free(jss); +} + +/* Calls to commands created via [sdl.surface] are implemented by this + * C command. */ +static int JimSdlHandlerCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + JimSdlSurface *jss = Jim_CmdPrivData(interp); + int option; + static const char * const options[] = { + "free", "flip", "pixel", "rectangle", "box", "line", "aaline", + "circle", "aacircle", "fcircle", NULL + }; + enum + { OPT_FREE, OPT_FLIP, OPT_PIXEL, OPT_RECTANGLE, OPT_BOX, OPT_LINE, + OPT_AALINE, OPT_CIRCLE, OPT_AACIRCLE, OPT_FCIRCLE + }; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?"); + return JIM_ERR; + } + if (Jim_GetEnum(interp, argv[1], options, &option, "SDL surface method", JIM_ERRMSG) != JIM_OK) + return JIM_ERR; + if (option == OPT_PIXEL) { + /* PIXEL */ + long x, y, red, green, blue, alpha = 255; + + if (argc != 7 && argc != 8) { + Jim_WrongNumArgs(interp, 2, argv, "x y red green blue ?alpha?"); + return JIM_ERR; + } + if (Jim_GetLong(interp, argv[2], &x) != JIM_OK || + Jim_GetLong(interp, argv[3], &y) != JIM_OK || + Jim_GetLong(interp, argv[4], &red) != JIM_OK || + Jim_GetLong(interp, argv[5], &green) != JIM_OK || + Jim_GetLong(interp, argv[6], &blue) != JIM_OK) { + return JIM_ERR; + } + if (argc == 8 && Jim_GetLong(interp, argv[7], &alpha) != JIM_OK) + return JIM_ERR; + pixelRGBA(jss->screen, x, y, red, green, blue, alpha); + return JIM_OK; + } + else if (option == OPT_RECTANGLE || option == OPT_BOX || + option == OPT_LINE || option == OPT_AALINE) { + /* RECTANGLE, BOX, LINE, AALINE */ + long x1, y1, x2, y2, red, green, blue, alpha = 255; + + if (argc != 9 && argc != 10) { + Jim_WrongNumArgs(interp, 2, argv, "x y red green blue ?alpha?"); + return JIM_ERR; + } + if (Jim_GetLong(interp, argv[2], &x1) != JIM_OK || + Jim_GetLong(interp, argv[3], &y1) != JIM_OK || + Jim_GetLong(interp, argv[4], &x2) != JIM_OK || + Jim_GetLong(interp, argv[5], &y2) != JIM_OK || + Jim_GetLong(interp, argv[6], &red) != JIM_OK || + Jim_GetLong(interp, argv[7], &green) != JIM_OK || + Jim_GetLong(interp, argv[8], &blue) != JIM_OK) { + return JIM_ERR; + } + if (argc == 10 && Jim_GetLong(interp, argv[9], &alpha) != JIM_OK) + return JIM_ERR; + switch (option) { + case OPT_RECTANGLE: + rectangleRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha); + break; + case OPT_BOX: + boxRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha); + break; + case OPT_LINE: + lineRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha); + break; + case OPT_AALINE: + aalineRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha); + break; + } + return JIM_OK; + } + else if (option == OPT_CIRCLE || option == OPT_AACIRCLE || option == OPT_FCIRCLE) { + /* CIRCLE, AACIRCLE, FCIRCLE */ + long x, y, radius, red, green, blue, alpha = 255; + + if (argc != 8 && argc != 9) { + Jim_WrongNumArgs(interp, 2, argv, "x y radius red green blue ?alpha?"); + return JIM_ERR; + } + if (Jim_GetLong(interp, argv[2], &x) != JIM_OK || + Jim_GetLong(interp, argv[3], &y) != JIM_OK || + Jim_GetLong(interp, argv[4], &radius) != JIM_OK || + Jim_GetLong(interp, argv[5], &red) != JIM_OK || + Jim_GetLong(interp, argv[6], &green) != JIM_OK || + Jim_GetLong(interp, argv[7], &blue) != JIM_OK) { + return JIM_ERR; + } + if (argc == 9 && Jim_GetLong(interp, argv[8], &alpha) != JIM_OK) + return JIM_ERR; + switch (option) { + case OPT_CIRCLE: + circleRGBA(jss->screen, x, y, radius, red, green, blue, alpha); + break; + case OPT_AACIRCLE: + aacircleRGBA(jss->screen, x, y, radius, red, green, blue, alpha); + break; + case OPT_FCIRCLE: + filledCircleRGBA(jss->screen, x, y, radius, red, green, blue, alpha); + break; + } + return JIM_OK; + } + else if (option == OPT_FREE) { + /* FREE */ + if (argc != 2) { + Jim_WrongNumArgs(interp, 2, argv, ""); + return JIM_ERR; + } + Jim_DeleteCommand(interp, Jim_String(argv[0])); + return JIM_OK; + } + else if (option == OPT_FLIP) { + /* FLIP */ + if (argc != 2) { + Jim_WrongNumArgs(interp, 2, argv, ""); + return JIM_ERR; + } + SDL_Flip(jss->screen); + return JIM_OK; + } + return JIM_OK; +} + +static int JimSdlSurfaceCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + JimSdlSurface *jss; + char buf[AIO_CMD_LEN]; + Jim_Obj *objPtr; + long screenId, xres, yres; + SDL_Surface *screen; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "xres yres"); + return JIM_ERR; + } + if (Jim_GetLong(interp, argv[1], &xres) != JIM_OK || + Jim_GetLong(interp, argv[2], &yres) != JIM_OK) + return JIM_ERR; + + /* Try to create the surface */ + screen = SDL_SetVideoMode(xres, yres, 32, SDL_SWSURFACE | SDL_ANYFORMAT); + if (screen == NULL) { + JimSdlSetError(interp); + return JIM_ERR; + } + /* Get the next file id */ + if (Jim_EvalGlobal(interp, "if {[catch {incr sdl.surfaceId}]} {set sdl.surfaceId 0}") != JIM_OK) + return JIM_ERR; + objPtr = Jim_GetVariableStr(interp, "sdl.surfaceId", JIM_ERRMSG); + if (objPtr == NULL) + return JIM_ERR; + if (Jim_GetLong(interp, objPtr, &screenId) != JIM_OK) + return JIM_ERR; + + /* Create the SDL screen command */ + jss = Jim_Alloc(sizeof(*jss)); + jss->screen = screen; + sprintf(buf, "sdl.surface%ld", screenId); + Jim_CreateCommand(interp, buf, JimSdlHandlerCommand, jss, JimSdlDelProc); + Jim_SetResultString(interp, buf, -1); + return JIM_OK; +} + +int Jim_sdlInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "sdl", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + JimSdlSetError(interp); + return JIM_ERR; + } + atexit(SDL_Quit); + Jim_CreateCommand(interp, "sdl.screen", JimSdlSurfaceCommand, NULL, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-signal.c b/debuggers/openocd/jimtcl/jim-signal.c new file mode 100644 index 00000000..065c0f9b --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-signal.c @@ -0,0 +1,513 @@ + +/* + * jim-signal.c + * + */ + +#include +#include +#include +#include + +#include "jimautoconf.h" +#include +#include + +#define MAX_SIGNALS (sizeof(jim_wide) * 8) + +static jim_wide *sigloc; +static jim_wide sigsblocked; +static struct sigaction *sa_old; +static int signal_handling[MAX_SIGNALS]; + +/* Make sure to do this as a wide, not int */ +#define sig_to_bit(SIG) ((jim_wide)1 << (SIG)) + +static void signal_handler(int sig) +{ + /* We just remember which signals occurred. Jim_Eval() will + * notice this as soon as it can and throw an error + */ + *sigloc |= sig_to_bit(sig); +} + +static void signal_ignorer(int sig) +{ + /* We just remember which signals occurred */ + sigsblocked |= sig_to_bit(sig); +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_SignalId -- + * + * Return a textual identifier for a signal number. + * + * Results: + * This procedure returns a machine-readable textual identifier + * that corresponds to sig. The identifier is the same as the + * #define name in signal.h. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +#define CHECK_SIG(NAME) if (sig == NAME) return #NAME + +const char *Jim_SignalId(int sig) +{ + CHECK_SIG(SIGABRT); + CHECK_SIG(SIGALRM); + CHECK_SIG(SIGBUS); + CHECK_SIG(SIGCHLD); + CHECK_SIG(SIGCONT); + CHECK_SIG(SIGFPE); + CHECK_SIG(SIGHUP); + CHECK_SIG(SIGILL); + CHECK_SIG(SIGINT); +#ifdef SIGIO + CHECK_SIG(SIGIO); +#endif + CHECK_SIG(SIGKILL); + CHECK_SIG(SIGPIPE); + CHECK_SIG(SIGPROF); + CHECK_SIG(SIGQUIT); + CHECK_SIG(SIGSEGV); + CHECK_SIG(SIGSTOP); + CHECK_SIG(SIGSYS); + CHECK_SIG(SIGTERM); + CHECK_SIG(SIGTRAP); + CHECK_SIG(SIGTSTP); + CHECK_SIG(SIGTTIN); + CHECK_SIG(SIGTTOU); + CHECK_SIG(SIGURG); + CHECK_SIG(SIGUSR1); + CHECK_SIG(SIGUSR2); + CHECK_SIG(SIGVTALRM); + CHECK_SIG(SIGWINCH); + CHECK_SIG(SIGXCPU); + CHECK_SIG(SIGXFSZ); +#ifdef SIGPWR + CHECK_SIG(SIGPWR); +#endif +#ifdef SIGCLD + CHECK_SIG(SIGCLD); +#endif +#ifdef SIGEMT + CHECK_SIG(SIGEMT); +#endif +#ifdef SIGLOST + CHECK_SIG(SIGLOST); +#endif +#ifdef SIGPOLL + CHECK_SIG(SIGPOLL); +#endif +#ifdef SIGINFO + CHECK_SIG(SIGINFO); +#endif + return "unknown signal"; +} + +const char *Jim_SignalName(int sig) +{ +#ifdef HAVE_SYS_SIGLIST + if (sig >= 0 && sig < NSIG) { + return sys_siglist[sig]; + } +#endif + return Jim_SignalId(sig); +} + +/** + * Given the name of a signal, returns the signal value if found, + * or returns -1 (and sets an error) if not found. + * We accept -SIGINT, SIGINT, INT or any lowercase version or a number, + * either positive or negative. + */ +static int find_signal_by_name(Jim_Interp *interp, const char *name) +{ + int i; + const char *pt = name; + + /* Remove optional - and SIG from the front of the name */ + if (*pt == '-') { + pt++; + } + if (strncasecmp(name, "sig", 3) == 0) { + pt += 3; + } + if (isdigit(UCHAR(pt[0]))) { + i = atoi(pt); + if (i > 0 && i < MAX_SIGNALS) { + return i; + } + } + else { + for (i = 1; i < MAX_SIGNALS; i++) { + /* Jim_SignalId() returns names such as SIGINT, and + * returns "unknown signal id" if unknown, so this will work + */ + if (strcasecmp(Jim_SignalId(i) + 3, pt) == 0) { + return i; + } + } + } + Jim_SetResultString(interp, "unknown signal ", -1); + Jim_AppendString(interp, Jim_GetResult(interp), name, -1); + + return -1; +} + +#define SIGNAL_ACTION_HANDLE 1 +#define SIGNAL_ACTION_IGNORE -1 +#define SIGNAL_ACTION_DEFAULT 0 + +static int do_signal_cmd(Jim_Interp *interp, int action, int argc, Jim_Obj *const *argv) +{ + struct sigaction sa; + int i; + + if (argc == 0) { + Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); + for (i = 1; i < MAX_SIGNALS; i++) { + if (signal_handling[i] == action) { + /* Add signal name to the list */ + Jim_ListAppendElement(interp, Jim_GetResult(interp), + Jim_NewStringObj(interp, Jim_SignalId(i), -1)); + } + } + return JIM_OK; + } + + /* Catch all the signals we care about */ + if (action != SIGNAL_ACTION_DEFAULT) { + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + if (action == SIGNAL_ACTION_HANDLE) { + sa.sa_handler = signal_handler; + } + else { + sa.sa_handler = signal_ignorer; + } + } + + /* Iterate through the provided signals */ + for (i = 0; i < argc; i++) { + int sig = find_signal_by_name(interp, Jim_String(argv[i])); + + if (sig < 0) { + return JIM_ERR; + } + if (action != signal_handling[sig]) { + /* Need to change the action for this signal */ + switch (action) { + case SIGNAL_ACTION_HANDLE: + case SIGNAL_ACTION_IGNORE: + if (signal_handling[sig] == SIGNAL_ACTION_DEFAULT) { + if (!sa_old) { + /* Allocate the structure the first time through */ + sa_old = Jim_Alloc(sizeof(*sa_old) * MAX_SIGNALS); + } + sigaction(sig, &sa, &sa_old[sig]); + } + else { + sigaction(sig, &sa, 0); + } + break; + + case SIGNAL_ACTION_DEFAULT: + /* Restore old handler */ + if (sa_old) { + sigaction(sig, &sa_old[sig], 0); + } + } + signal_handling[sig] = action; + } + } + + return JIM_OK; +} + +static int signal_cmd_handle(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return do_signal_cmd(interp, SIGNAL_ACTION_HANDLE, argc, argv); +} + +static int signal_cmd_ignore(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return do_signal_cmd(interp, SIGNAL_ACTION_IGNORE, argc, argv); +} + +static int signal_cmd_default(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return do_signal_cmd(interp, SIGNAL_ACTION_DEFAULT, argc, argv); +} + +static int signal_set_sigmask_result(Jim_Interp *interp, jim_wide sigmask) +{ + int i; + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + + for (i = 0; i < MAX_SIGNALS; i++) { + if (sigmask & sig_to_bit(i)) { + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, Jim_SignalId(i), -1)); + } + } + Jim_SetResult(interp, listObj); + return JIM_OK; +} + +static int signal_cmd_check(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int clear = 0; + jim_wide mask = 0; + jim_wide blocked; + + if (argc > 0 && Jim_CompareStringImmediate(interp, argv[0], "-clear")) { + clear++; + } + if (argc > clear) { + int i; + + /* Signals specified */ + for (i = clear; i < argc; i++) { + int sig = find_signal_by_name(interp, Jim_String(argv[i])); + + if (sig < 0 || sig >= MAX_SIGNALS) { + return -1; + } + mask |= sig_to_bit(sig); + } + } + else { + /* No signals specified, so check/clear all */ + mask = ~mask; + } + + if ((sigsblocked & mask) == 0) { + /* No matching signals, so empty result and nothing to do */ + return JIM_OK; + } + /* Be careful we don't have a race condition where signals are cleared but not returned */ + blocked = sigsblocked & mask; + if (clear) { + sigsblocked &= ~blocked; + } + /* Set the result */ + signal_set_sigmask_result(interp, blocked); + return JIM_OK; +} + +static int signal_cmd_throw(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int sig = SIGINT; + + if (argc == 1) { + if ((sig = find_signal_by_name(interp, Jim_String(argv[0]))) < 0) { + return JIM_ERR; + } + } + + /* If the signal is ignored (blocked) ... */ + if (signal_handling[sig] == SIGNAL_ACTION_IGNORE) { + sigsblocked |= sig_to_bit(sig); + return JIM_OK; + } + + /* Just set the signal */ + interp->sigmask |= sig_to_bit(sig); + + /* Set the canonical name of the signal as the result */ + Jim_SetResultString(interp, Jim_SignalId(sig), -1); + + /* And simply say we caught the signal */ + return JIM_SIGNAL; +} + +/* + *----------------------------------------------------------------------------- + * + * Jim_SignalCmd -- + * Implements the TCL signal command: + * signal handle|ignore|default|throw ?signals ...? + * signal throw signal + * + * Specifies which signals are handled by Tcl code. + * If the one of the given signals is caught, it causes a JIM_SIGNAL + * exception to be thrown which can be caught by catch. + * + * Use 'signal ignore' to ignore the signal(s) + * Use 'signal default' to go back to the default behaviour + * Use 'signal throw signal' to raise the given signal + * + * If no arguments are given, returns the list of signals which are being handled + * + * Results: + * Standard TCL results. + * + *----------------------------------------------------------------------------- + */ +static const jim_subcmd_type signal_command_table[] = { + { "handle", + "?signals ...?", + signal_cmd_handle, + 0, + -1, + /* Description: Lists handled signals, or adds to handled signals */ + }, + { "ignore", + "?signals ...?", + signal_cmd_ignore, + 0, + -1, + /* Description: Lists ignored signals, or adds to ignored signals */ + }, + { "default", + "?signals ...?", + signal_cmd_default, + 0, + -1, + /* Description: Lists defaulted signals, or adds to defaulted signals */ + }, + { "check", + "?-clear? ?signals ...?", + signal_cmd_check, + 0, + -1, + /* Description: Returns ignored signals which have occurred, and optionally clearing them */ + }, + { "throw", + "?signal?", + signal_cmd_throw, + 0, + 1, + /* Description: Raises the given signal (default SIGINT) */ + }, + { NULL } +}; + +static int Jim_AlarmCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int ret; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "seconds"); + return JIM_ERR; + } + else { +#ifdef HAVE_UALARM + double t; + + ret = Jim_GetDouble(interp, argv[1], &t); + if (ret == JIM_OK) { + if (t < 1) { + ualarm(t * 1e6, 0); + } + else { + alarm(t); + } + } +#else + long t; + + ret = Jim_GetLong(interp, argv[1], &t); + if (ret == JIM_OK) { + alarm(t); + } +#endif + } + + return ret; +} + +static int Jim_SleepCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int ret; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "seconds"); + return JIM_ERR; + } + else { + double t; + + ret = Jim_GetDouble(interp, argv[1], &t); + if (ret == JIM_OK) { +#ifdef HAVE_USLEEP + if (t < 1) { + usleep(t * 1e6); + } + else +#endif + sleep(t); + } + } + + return ret; +} + +static int Jim_KillCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int sig; + long pid; + Jim_Obj *pidObj; + const char *signame; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "?SIG|-0? pid"); + return JIM_ERR; + } + + if (argc == 2) { + signame = "SIGTERM"; + pidObj = argv[1]; + } + else { + signame = Jim_String(argv[1]); + pidObj = argv[2]; + } + + /* Special 'kill -0 pid' to determine if a pid exists */ + if (strcmp(signame, "-0") == 0 || strcmp(signame, "0") == 0) { + sig = 0; + } + else { + sig = find_signal_by_name(interp, signame); + if (sig < 0) { + return JIM_ERR; + } + } + + if (Jim_GetLong(interp, pidObj, &pid) != JIM_OK) { + return JIM_ERR; + } + + if (kill(pid, sig) == 0) { + return JIM_OK; + } + + Jim_SetResultString(interp, "kill: Failed to deliver signal", -1); + return JIM_ERR; +} + +int Jim_signalInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "signal", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + /* Teach the jim core how to set a result from a sigmask */ + interp->signal_set_result = signal_set_sigmask_result; + + /* Make sure we know where to store the signals which occur */ + sigloc = &interp->sigmask; + + Jim_CreateCommand(interp, "signal", Jim_SubCmdProc, (void *)signal_command_table, NULL); + Jim_CreateCommand(interp, "alarm", Jim_AlarmCmd, 0, 0); + Jim_CreateCommand(interp, "kill", Jim_KillCmd, 0, 0); + + /* Sleep is slightly dubious here */ + Jim_CreateCommand(interp, "sleep", Jim_SleepCmd, 0, 0); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-signal.h b/debuggers/openocd/jimtcl/jim-signal.h new file mode 100644 index 00000000..92e080d8 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-signal.h @@ -0,0 +1,24 @@ +#ifndef JIM_SIGNAL_H +#define JIM_SIGNAL_H + +/* + *---------------------------------------------------------------------- + * + * Tcl_SignalId -- + * + * Return a textual identifier for a signal number. + * + * Results: + * This procedure returns a machine-readable textual identifier + * that corresponds to sig. The identifier is the same as the + * #define name in signal.h. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +const char *Jim_SignalId(int sig); +const char *Jim_SignalName(int sig); + +#endif diff --git a/debuggers/openocd/jimtcl/jim-sqlite3.c b/debuggers/openocd/jimtcl/jim-sqlite3.c new file mode 100644 index 00000000..62d8fa9f --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-sqlite3.c @@ -0,0 +1,300 @@ +/* + * Jim - Sqlite bindings + * + * Copyright 2005 Salvatore Sanfilippo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + */ + +#include +#include +#include + +#include + +typedef struct JimSqliteHandle +{ + sqlite3 *db; +} JimSqliteHandle; + +static void JimSqliteDelProc(Jim_Interp *interp, void *privData) +{ + JimSqliteHandle *sh = privData; + + JIM_NOTUSED(interp); + + sqlite3_close(sh->db); + Jim_Free(sh); +} + +static char *JimSqliteQuoteString(const char *str, int len, int *newLenPtr) +{ + int i, newLen, c = 0; + const char *s; + char *d, *buf; + + for (i = 0; i < len; i++) + if (str[i] == '\'') + c++; + newLen = len + c; + s = str; + d = buf = Jim_Alloc(newLen); + while (len--) { + if (*s == '\'') + *d++ = '\''; + *d++ = *s++; + } + *newLenPtr = newLen; + return buf; +} + +static Jim_Obj *JimSqliteFormatQuery(Jim_Interp *interp, Jim_Obj *fmtObjPtr, + int objc, Jim_Obj *const *objv) +{ + const char *fmt; + int fmtLen; + Jim_Obj *resObjPtr; + + fmt = Jim_GetString(fmtObjPtr, &fmtLen); + resObjPtr = Jim_NewStringObj(interp, "", 0); + while (fmtLen) { + const char *p = fmt; + char spec[2]; + + while (*fmt != '%' && fmtLen) { + fmt++; + fmtLen--; + } + Jim_AppendString(interp, resObjPtr, p, fmt - p); + if (fmtLen == 0) + break; + fmt++; + fmtLen--; /* skip '%' */ + if (*fmt != '%') { + if (objc == 0) { + Jim_FreeNewObj(interp, resObjPtr); + Jim_SetResultString(interp, "not enough arguments for all format specifiers", -1); + return NULL; + } + else { + objc--; + } + } + switch (*fmt) { + case 's': + { + const char *str; + char *quoted; + int len, newLen; + + str = Jim_GetString(objv[0], &len); + quoted = JimSqliteQuoteString(str, len, &newLen); + Jim_AppendString(interp, resObjPtr, quoted, newLen); + Jim_Free(quoted); + } + objv++; + break; + case '%': + Jim_AppendString(interp, resObjPtr, "%", 1); + break; + default: + spec[0] = *fmt; + spec[1] = '\0'; + Jim_FreeNewObj(interp, resObjPtr); + Jim_SetResultFormatted(interp, + "bad field specifier \"%s\", only %%s and %%%% are valid", spec); + return NULL; + } + fmt++; + fmtLen--; + } + return resObjPtr; +} + +/* Calls to [sqlite.open] create commands that are implemented by this + * C command. */ +static int JimSqliteHandlerCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + JimSqliteHandle *sh = Jim_CmdPrivData(interp); + int option; + static const char * const options[] = { + "close", "query", "lastid", "changes", NULL + }; + enum + { OPT_CLOSE, OPT_QUERY, OPT_LASTID, OPT_CHANGES }; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?"); + return JIM_ERR; + } + if (Jim_GetEnum(interp, argv[1], options, &option, "Sqlite method", JIM_ERRMSG) != JIM_OK) + return JIM_ERR; + /* CLOSE */ + if (option == OPT_CLOSE) { + if (argc != 2) { + Jim_WrongNumArgs(interp, 2, argv, ""); + return JIM_ERR; + } + Jim_DeleteCommand(interp, Jim_String(argv[0])); + return JIM_OK; + } + else if (option == OPT_QUERY) { + /* QUERY */ + Jim_Obj *objPtr, *rowsListPtr; + sqlite3_stmt *stmt; + const char *query, *tail; + int columns, rows, len; + char *nullstr; + + if (argc >= 4 && Jim_CompareStringImmediate(interp, argv[2], "-null")) { + nullstr = Jim_StrDup(Jim_String(argv[3])); + argv += 2; + argc -= 2; + } + else { + nullstr = Jim_StrDup(""); + } + if (argc < 3) { + Jim_WrongNumArgs(interp, 2, argv, "query ?args?"); + Jim_Free(nullstr); + return JIM_ERR; + } + objPtr = JimSqliteFormatQuery(interp, argv[2], argc - 3, argv + 3); + if (objPtr == NULL) { + Jim_Free(nullstr); + return JIM_ERR; + } + query = Jim_GetString(objPtr, &len); + Jim_IncrRefCount(objPtr); + /* Compile the query into VM code */ + if (sqlite3_prepare_v2(sh->db, query, len, &stmt, &tail) != SQLITE_OK) { + Jim_DecrRefCount(interp, objPtr); + Jim_SetResultString(interp, sqlite3_errmsg(sh->db), -1); + Jim_Free(nullstr); + return JIM_ERR; + } + Jim_DecrRefCount(interp, objPtr); /* query no longer needed. */ + /* Build a list of rows (that are lists in turn) */ + rowsListPtr = Jim_NewListObj(interp, NULL, 0); + Jim_IncrRefCount(rowsListPtr); + rows = 0; + columns = sqlite3_column_count(stmt); + while (sqlite3_step(stmt) == SQLITE_ROW) { + int i; + + objPtr = Jim_NewListObj(interp, NULL, 0); + for (i = 0; i < columns; i++) { + Jim_Obj *vObj = NULL; + + Jim_ListAppendElement(interp, objPtr, + Jim_NewStringObj(interp, sqlite3_column_name(stmt, i), -1)); + switch (sqlite3_column_type(stmt, i)) { + case SQLITE_NULL: + vObj = Jim_NewStringObj(interp, nullstr, -1); + break; + case SQLITE_INTEGER: + vObj = Jim_NewIntObj(interp, sqlite3_column_int(stmt, i)); + break; + case SQLITE_FLOAT: + vObj = Jim_NewDoubleObj(interp, sqlite3_column_double(stmt, i)); + break; + case SQLITE_TEXT: + case SQLITE_BLOB: + vObj = Jim_NewStringObj(interp, + sqlite3_column_blob(stmt, i), sqlite3_column_bytes(stmt, i)); + break; + } + Jim_ListAppendElement(interp, objPtr, vObj); + } + Jim_ListAppendElement(interp, rowsListPtr, objPtr); + rows++; + } + /* Finalize */ + Jim_Free(nullstr); + if (sqlite3_finalize(stmt) != SQLITE_OK) { + Jim_DecrRefCount(interp, rowsListPtr); + Jim_SetResultString(interp, sqlite3_errmsg(sh->db), -1); + return JIM_ERR; + } + Jim_SetResult(interp, rowsListPtr); + Jim_DecrRefCount(interp, rowsListPtr); + } + else if (option == OPT_LASTID) { + if (argc != 2) { + Jim_WrongNumArgs(interp, 2, argv, ""); + return JIM_ERR; + } + Jim_SetResult(interp, Jim_NewIntObj(interp, sqlite3_last_insert_rowid(sh->db))); + return JIM_OK; + } + else if (option == OPT_CHANGES) { + if (argc != 2) { + Jim_WrongNumArgs(interp, 2, argv, ""); + return JIM_ERR; + } + Jim_SetResult(interp, Jim_NewIntObj(interp, sqlite3_changes(sh->db))); + return JIM_OK; + } + return JIM_OK; +} + +static int JimSqliteOpenCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + sqlite3 *db; + JimSqliteHandle *sh; + char buf[60]; + int r; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "dbname"); + return JIM_ERR; + } + r = sqlite3_open(Jim_String(argv[1]), &db); + if (r != SQLITE_OK) { + Jim_SetResultString(interp, sqlite3_errmsg(db), -1); + sqlite3_close(db); + return JIM_ERR; + } + /* Create the file command */ + sh = Jim_Alloc(sizeof(*sh)); + sh->db = db; + snprintf(buf, sizeof(buf), "sqlite.handle%ld", Jim_GetId(interp)); + Jim_CreateCommand(interp, buf, JimSqliteHandlerCommand, sh, JimSqliteDelProc); + Jim_SetResultString(interp, buf, -1); + return JIM_OK; +} + +int Jim_sqlite3Init(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "sqlite3", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + Jim_CreateCommand(interp, "sqlite3.open", JimSqliteOpenCommand, NULL, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-subcmd.c b/debuggers/openocd/jimtcl/jim-subcmd.c new file mode 100644 index 00000000..bd6e0506 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-subcmd.c @@ -0,0 +1,199 @@ +#include +#include + +#include + +/** + * Implements the common 'commands' subcommand + */ +static int subcmd_null(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + /* Nothing to do, since the result has already been created */ + return JIM_OK; +} + +/** + * Do-nothing command to support -commands and -usage + */ +static const jim_subcmd_type dummy_subcmd = { + "dummy", NULL, subcmd_null, 0, 0, JIM_MODFLAG_HIDDEN +}; + +static void add_commands(Jim_Interp *interp, const jim_subcmd_type * ct, const char *sep) +{ + const char *s = ""; + + for (; ct->cmd; ct++) { + if (!(ct->flags & JIM_MODFLAG_HIDDEN)) { + Jim_AppendStrings(interp, Jim_GetResult(interp), s, ct->cmd, NULL); + s = sep; + } + } +} + +static void bad_subcmd(Jim_Interp *interp, const jim_subcmd_type * command_table, const char *type, + Jim_Obj *cmd, Jim_Obj *subcmd) +{ + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), Jim_String(cmd), ", ", type, + " command \"", Jim_String(subcmd), "\": should be ", NULL); + add_commands(interp, command_table, ", "); +} + +static void show_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * command_table, int argc, + Jim_Obj *const *argv) +{ + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), "Usage: \"", Jim_String(argv[0]), + " command ... \", where command is one of: ", NULL); + add_commands(interp, command_table, ", "); +} + +static void add_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * ct, Jim_Obj *cmd) +{ + if (cmd) { + Jim_AppendStrings(interp, Jim_GetResult(interp), Jim_String(cmd), " ", NULL); + } + Jim_AppendStrings(interp, Jim_GetResult(interp), ct->cmd, NULL); + if (ct->args && *ct->args) { + Jim_AppendStrings(interp, Jim_GetResult(interp), " ", ct->args, NULL); + } +} + +static void set_wrong_args(Jim_Interp *interp, const jim_subcmd_type * command_table, Jim_Obj *subcmd) +{ + Jim_SetResultString(interp, "wrong # args: should be \"", -1); + add_cmd_usage(interp, command_table, subcmd); + Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL); +} + +const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type * command_table, + int argc, Jim_Obj *const *argv) +{ + const jim_subcmd_type *ct; + const jim_subcmd_type *partial = 0; + int cmdlen; + Jim_Obj *cmd; + const char *cmdstr; + const char *cmdname; + int help = 0; + + cmdname = Jim_String(argv[0]); + + if (argc < 2) { + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), "wrong # args: should be \"", cmdname, + " command ...\"\n", NULL); + Jim_AppendStrings(interp, Jim_GetResult(interp), "Use \"", cmdname, " -help ?command?\" for help", NULL); + return 0; + } + + cmd = argv[1]; + + /* Check for the help command */ + if (Jim_CompareStringImmediate(interp, cmd, "-help")) { + if (argc == 2) { + /* Usage for the command, not the subcommand */ + show_cmd_usage(interp, command_table, argc, argv); + return &dummy_subcmd; + } + help = 1; + + /* Skip the 'help' command */ + cmd = argv[2]; + } + + /* Check for special builtin '-commands' command first */ + if (Jim_CompareStringImmediate(interp, cmd, "-commands")) { + /* Build the result here */ + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + add_commands(interp, command_table, " "); + return &dummy_subcmd; + } + + cmdstr = Jim_GetString(cmd, &cmdlen); + + for (ct = command_table; ct->cmd; ct++) { + if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) { + /* Found an exact match */ + break; + } + if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) { + if (partial) { + /* Ambiguous */ + if (help) { + /* Just show the top level help here */ + show_cmd_usage(interp, command_table, argc, argv); + return &dummy_subcmd; + } + bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]); + return 0; + } + partial = ct; + } + continue; + } + + /* If we had an unambiguous partial match */ + if (partial && !ct->cmd) { + ct = partial; + } + + if (!ct->cmd) { + /* No matching command */ + if (help) { + /* Just show the top level help here */ + show_cmd_usage(interp, command_table, argc, argv); + return &dummy_subcmd; + } + bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]); + return 0; + } + + if (help) { + Jim_SetResultString(interp, "Usage: ", -1); + /* subcmd */ + add_cmd_usage(interp, ct, argv[0]); + return &dummy_subcmd; + } + + /* Check the number of args */ + if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) { + Jim_SetResultString(interp, "wrong # args: should be \"", -1); + /* subcmd */ + add_cmd_usage(interp, ct, argv[0]); + Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL); + + return 0; + } + + /* Good command */ + return ct; +} + +int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type * ct, int argc, Jim_Obj *const *argv) +{ + int ret = JIM_ERR; + + if (ct) { + if (ct->flags & JIM_MODFLAG_FULLARGV) { + ret = ct->function(interp, argc, argv); + } + else { + ret = ct->function(interp, argc - 2, argv + 2); + } + if (ret < 0) { + set_wrong_args(interp, ct, argv[0]); + ret = JIM_ERR; + } + } + return ret; +} + +int Jim_SubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const jim_subcmd_type *ct = + Jim_ParseSubCmd(interp, (const jim_subcmd_type *)Jim_CmdPrivData(interp), argc, argv); + + return Jim_CallSubCmd(interp, ct, argc, argv); +} diff --git a/debuggers/openocd/jimtcl/jim-subcmd.h b/debuggers/openocd/jimtcl/jim-subcmd.h new file mode 100644 index 00000000..f10f5f62 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-subcmd.h @@ -0,0 +1,77 @@ +/* Provides a common approach to implementing Tcl commands + * which implement subcommands + */ +#ifndef JIM_SUBCMD_H +#define JIM_SUBCMD_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define JIM_MODFLAG_HIDDEN 0x0001 /* Don't show the subcommand in usage or commands */ +#define JIM_MODFLAG_FULLARGV 0x0002 /* Subcmd proc gets called with full argv */ + +/* Custom flags start at 0x0100 */ + +/** + * Returns JIM_OK if OK, JIM_ERR (etc.) on error, break, continue, etc. + * Returns -1 if invalid args. + */ +typedef int tclmod_cmd_function(Jim_Interp *interp, int argc, Jim_Obj *const *argv); + +typedef struct { + const char *cmd; /* Name of the (sub)command */ + const char *args; /* Textual description of allowed args */ + tclmod_cmd_function *function; /* Function implementing the subcommand */ + short minargs; /* Minimum required arguments */ + short maxargs; /* Maximum allowed arguments or -1 if no limit */ + unsigned short flags; /* JIM_MODFLAG_... plus custom flags */ +} jim_subcmd_type; + +/** + * Looks up the appropriate subcommand in the given command table and return + * the command function which implements the subcommand. + * NULL will be returned and an appropriate error will be set if the subcommand or + * arguments are invalid. + * + * Typical usage is: + * { + * const jim_subcmd_type *ct = Jim_ParseSubCmd(interp, command_table, argc, argv); + * + * return Jim_CallSubCmd(interp, ct, argc, argv); + * } + * + */ +const jim_subcmd_type * +Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type *command_table, int argc, Jim_Obj *const *argv); + +/** + * Parses the args against the given command table and executes the subcommand if found + * or sets an appropriate error if the subcommand or arguments is invalid. + * + * Can be used directly with Jim_CreateCommand() where the ClientData is the command table. + * + * e.g. Jim_CreateCommand(interp, "mycmd", Jim_SubCmdProc, command_table, NULL); + */ +int Jim_SubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv); + +/** + * Invokes the given subcmd with the given args as returned + * by Jim_ParseSubCmd() + * + * If ct is NULL, returns JIM_ERR, leaving any message. + * Otherwise invokes ct->function + * + * If ct->function returns -1, sets an error message and returns JIM_ERR. + * Otherwise returns the result of ct->function. + */ +int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type *ct, int argc, Jim_Obj *const *argv); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/debuggers/openocd/jimtcl/jim-syslog.c b/debuggers/openocd/jimtcl/jim-syslog.c new file mode 100644 index 00000000..bd373b84 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-syslog.c @@ -0,0 +1,189 @@ + +/* Syslog interface for tcl + * Copyright Victor Wagner at + * http://www.ice.ru/~vitus/works/tcl.html#syslog + * + * Slightly modified by Steve Bennett + * Ported to Jim by Steve Bennett + */ +#include +#include + +#include + +typedef struct +{ + int logOpened; + int facility; + int options; + char ident[32]; +} SyslogInfo; + +#ifndef LOG_AUTHPRIV +# define LOG_AUTHPRIV LOG_AUTH +#endif + +static const char * const facilities[] = { + [LOG_AUTHPRIV] = "authpriv", + [LOG_CRON] = "cron", + [LOG_DAEMON] = "daemon", + [LOG_KERN] = "kernel", + [LOG_LPR] = "lpr", + [LOG_MAIL] = "mail", + [LOG_NEWS] = "news", + [LOG_SYSLOG] = "syslog", + [LOG_USER] = "user", + [LOG_UUCP] = "uucp", + [LOG_LOCAL0] = "local0", + [LOG_LOCAL1] = "local1", + [LOG_LOCAL2] = "local2", + [LOG_LOCAL3] = "local3", + [LOG_LOCAL4] = "local4", + [LOG_LOCAL5] = "local5", + [LOG_LOCAL6] = "local6", + [LOG_LOCAL7] = "local7", +}; + +static const char * const priorities[] = { + [LOG_EMERG] = "emerg", + [LOG_ALERT] = "alert", + [LOG_CRIT] = "crit", + [LOG_ERR] = "error", + [LOG_WARNING] = "warning", + [LOG_NOTICE] = "notice", + [LOG_INFO] = "info", + [LOG_DEBUG] = "debug", +}; + +/** + * Deletes the syslog command. + */ +static void Jim_SyslogCmdDelete(Jim_Interp *interp, void *privData) +{ + SyslogInfo *info = (SyslogInfo *) privData; + + if (info->logOpened) { + closelog(); + } + Jim_Free(info); +} + +/* Syslog_Log - + * implements syslog tcl command. General format: syslog ?options? level text + * options -facility -ident -options + * + * syslog ?-facility cron|daemon|...? ?-ident string? ?-options int? ?debug|info|...? text + */ +int Jim_SyslogCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int priority = LOG_INFO; + int i = 1; + SyslogInfo *info = Jim_CmdPrivData(interp); + + if (argc <= 1) { + wrongargs: + Jim_WrongNumArgs(interp, 1, argv, + "?-facility cron|daemon|...? ?-ident string? ?-options int? ?debug|info|...? message"); + return JIM_ERR; + } + while (i < argc - 1) { + if (Jim_CompareStringImmediate(interp, argv[i], "-facility")) { + int entry = + Jim_FindByName(Jim_String(argv[i + 1]), facilities, + sizeof(facilities) / sizeof(*facilities)); + if (entry < 0) { + Jim_SetResultString(interp, "Unknown facility", -1); + return JIM_ERR; + } + if (info->facility != entry) { + info->facility = entry; + if (info->logOpened) { + closelog(); + info->logOpened = 0; + } + } + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-options")) { + long tmp; + + if (Jim_GetLong(interp, argv[i + 1], &tmp) == JIM_ERR) { + return JIM_ERR; + } + info->options = tmp; + if (info->logOpened) { + closelog(); + info->logOpened = 0; + } + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-ident")) { + strncpy(info->ident, Jim_String(argv[i + 1]), sizeof(info->ident)); + info->ident[sizeof(info->ident) - 1] = 0; + if (info->logOpened) { + closelog(); + info->logOpened = 0; + } + } + else { + break; + } + i += 2; + } + + /* There should be either 0, 1 or 2 args left */ + if (i == argc) { + /* No args, but they have set some options, so OK */ + return JIM_OK; + } + + if (i < argc - 1) { + priority = + Jim_FindByName(Jim_String(argv[i]), priorities, + sizeof(priorities) / sizeof(*priorities)); + if (priority < 0) { + Jim_SetResultString(interp, "Unknown priority", -1); + return JIM_ERR; + } + i++; + } + + if (i != argc - 1) { + goto wrongargs; + } + if (!info->logOpened) { + if (!info->ident[0]) { + Jim_Obj *argv0 = Jim_GetGlobalVariableStr(interp, "argv0", JIM_NONE); + + if (argv0) { + strncpy(info->ident, Jim_String(argv0), sizeof(info->ident)); + } + else { + strcpy(info->ident, "Tcl script"); + } + info->ident[sizeof(info->ident) - 1] = 0; + } + openlog(info->ident, info->options, info->facility); + info->logOpened = 1; + } + syslog(priority, "%s", Jim_String(argv[i])); + + return JIM_OK; +} + +int Jim_syslogInit(Jim_Interp *interp) +{ + SyslogInfo *info; + + if (Jim_PackageProvide(interp, "syslog", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + info = Jim_Alloc(sizeof(*info)); + + info->logOpened = 0; + info->options = 0; + info->facility = LOG_USER; + info->ident[0] = 0; + + Jim_CreateCommand(interp, "syslog", Jim_SyslogCmd, info, Jim_SyslogCmdDelete); + + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-tclprefix.c b/debuggers/openocd/jimtcl/jim-tclprefix.c new file mode 100644 index 00000000..e041cc63 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-tclprefix.c @@ -0,0 +1,198 @@ +/* + * Implements the tcl::prefix command for Jim Tcl + * + * (c) 2011 Steve Bennett + * + * See LICENSE for license details. + */ + +#include +#include "utf8.h" + +/** + * Returns the common initial length of the two strings. + */ +static int JimStringCommonLength(const char *str1, int charlen1, const char *str2, int charlen2) +{ + int maxlen = 0; + while (charlen1-- && charlen2--) { + int c1; + int c2; + str1 += utf8_tounicode(str1, &c1); + str2 += utf8_tounicode(str2, &c2); + if (c1 != c2) { + break; + } + maxlen++; + } + return maxlen; +} + +/* [tcl::prefix] + */ +static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + Jim_Obj *stringObj; + int option; + static const char * const options[] = { "match", "all", "longest", NULL }; + enum { OPT_MATCH, OPT_ALL, OPT_LONGEST }; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "subcommand ?arg ...?"); + return JIM_ERR; + } + if (Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) + return JIM_ERR; + + switch (option) { + case OPT_MATCH:{ + int i; + int ret; + int tablesize; + const char **table; + Jim_Obj *tableObj; + Jim_Obj *errorObj = NULL; + Jim_Obj *messageObj = NULL; + static const char * const matchoptions[] = { "-error", "-exact", "-message", NULL }; + enum { OPT_MATCH_ERROR, OPT_MATCH_EXACT, OPT_MATCH_MESSAGE }; + int flags = JIM_ERRMSG | JIM_ENUM_ABBREV; + + if (argc < 4) { + Jim_WrongNumArgs(interp, 2, argv, "?options? table string"); + return JIM_ERR; + } + tableObj = argv[argc - 2]; + stringObj = argv[argc - 1]; + argc -= 2; + for (i = 2; i < argc; i++) { + int matchoption; + if (Jim_GetEnum(interp, argv[i], matchoptions, &matchoption, "option", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) + return JIM_ERR; + switch (matchoption) { + case OPT_MATCH_EXACT: + flags &= ~JIM_ENUM_ABBREV; + break; + + case OPT_MATCH_ERROR: + if (++i == argc) { + Jim_SetResultString(interp, "missing error options", -1); + return JIM_ERR; + } + errorObj = argv[i]; + if (Jim_Length(errorObj) % 2) { + Jim_SetResultString(interp, "error options must have an even number of elements", -1); + return JIM_ERR; + } + break; + + case OPT_MATCH_MESSAGE: + if (++i == argc) { + Jim_SetResultString(interp, "missing message", -1); + return JIM_ERR; + } + messageObj = argv[i]; + break; + } + } + /* Do the match */ + tablesize = Jim_ListLength(interp, tableObj); + table = Jim_Alloc((tablesize + 1) * sizeof(*table)); + for (i = 0; i < tablesize; i++) { + Jim_ListIndex(interp, tableObj, i, &objPtr, JIM_NONE); + table[i] = Jim_String(objPtr); + } + table[i] = NULL; + + ret = Jim_GetEnum(interp, stringObj, table, &i, messageObj ? Jim_String(messageObj) : NULL, flags); + Jim_Free(table); + if (ret == JIM_OK) { + Jim_ListIndex(interp, tableObj, i, &objPtr, JIM_NONE); + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + if (tablesize == 0) { + Jim_SetResultFormatted(interp, "bad option \"%#s\": no valid options", stringObj); + return JIM_ERR; + } + if (errorObj) { + if (Jim_Length(errorObj) == 0) { + Jim_SetEmptyResult(interp); + return JIM_OK; + } + /* Do this the easy way. Build a list to evaluate */ + objPtr = Jim_NewStringObj(interp, "return -level 0 -code error", -1); + Jim_ListAppendList(interp, objPtr, errorObj); + Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); + return Jim_EvalObjList(interp, objPtr); + } + return JIM_ERR; + } + break; + + case OPT_ALL: + if (argc != 4) { + Jim_WrongNumArgs(interp, 2, argv, "table string"); + return JIM_ERR; + } + else { + int i; + int listlen = Jim_ListLength(interp, argv[2]); + objPtr = Jim_NewListObj(interp, NULL, 0); + for (i = 0; i < listlen; i++) { + Jim_Obj *valObj = Jim_ListGetIndex(interp, argv[2], i); + if (Jim_StringCompareLenObj(interp, argv[3], valObj, 0) == 0) { + Jim_ListAppendElement(interp, objPtr, valObj); + } + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + case OPT_LONGEST: + if (argc != 4) { + Jim_WrongNumArgs(interp, 2, argv, "table string"); + return JIM_ERR; + } + else if (Jim_ListLength(interp, argv[2])) { + const char *longeststr = NULL; + int longestlen = 0; + + stringObj = argv[3]; + + int i; + int listlen = Jim_ListLength(interp, argv[2]); + for (i = 0; i < listlen; i++) { + Jim_Obj *valObj = Jim_ListGetIndex(interp, argv[2], i); + + if (Jim_StringCompareLenObj(interp, stringObj, valObj, 0)) { + /* Does not begin with 'string' */ + continue; + } + + if (longeststr == NULL) { + longestlen = Jim_Utf8Length(interp, valObj); + longeststr = Jim_String(valObj); + } + else { + longestlen = JimStringCommonLength(longeststr, longestlen, Jim_String(valObj), Jim_Utf8Length(interp, valObj)); + } + } + if (longeststr) { + Jim_SetResultString(interp, longeststr, longestlen); + } + return JIM_OK; + } + } + return JIM_ERR; +} + +int Jim_tclprefixInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "tclprefix", "1.0", JIM_ERRMSG)) { + return JIM_ERR; + } + + Jim_CreateCommand(interp, "tcl::prefix", Jim_TclPrefixCoreCommand, NULL, NULL); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-win32.c b/debuggers/openocd/jimtcl/jim-win32.c new file mode 100644 index 00000000..89cedd4d --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-win32.c @@ -0,0 +1,510 @@ +/* + * WIN32 extension + * + * Copyright (C) 2005 Pat Thoyts + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + */ + +#include + +/* Apparently windows.h and cygwin don't mix, but we seem to get + * away with it here. Use at your own risk under cygwin + */ +#if defined(__CYGWIN__) +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#include +#include +#include +#include + +#if _MSC_VER >= 1000 +#pragma comment(lib, "shell32") +#pragma comment(lib, "user32") +#pragma comment(lib, "advapi32") +#pragma comment(lib, "psapi") +#endif /* _MSC_VER >= 1000 */ + +static Jim_Obj * +Win32ErrorObj(Jim_Interp *interp, const char * szPrefix, DWORD dwError) +{ + Jim_Obj *msgObj = NULL; + char * lpBuffer = NULL; + DWORD dwLen = 0; + + dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, LANG_NEUTRAL, + (char *)&lpBuffer, 0, NULL); + if (dwLen < 1) { + dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, + "code 0x%1!08X!%n", 0, LANG_NEUTRAL, + (char *)&lpBuffer, 0, (va_list *)&dwError); + } + + msgObj = Jim_NewStringObj(interp, szPrefix, -1); + if (dwLen > 0) { + char *p = lpBuffer + dwLen - 1; /* remove cr-lf at end */ + for ( ; p && *p && isspace(UCHAR(*p)); p--) + ; + *++p = 0; + Jim_AppendString(interp, msgObj, ": ", 2); + Jim_AppendString(interp, msgObj, lpBuffer, -1); + } + LocalFree((HLOCAL)lpBuffer); + return msgObj; +} + +/* win32.ShellExecute verb file args */ +static int +Win32_ShellExecute(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + int r; + const char *verb, *file, *parm = NULL; + char cwd[MAX_PATH + 1]; + + if (objc < 3 || objc > 4) { + Jim_WrongNumArgs(interp, 1, objv, "verb path ?parameters?"); + return JIM_ERR; + } + verb = Jim_String(objv[1]); + file = Jim_String(objv[2]); + GetCurrentDirectoryA(MAX_PATH + 1, cwd); + if (objc == 4) + parm = Jim_String(objv[3]); + r = (int)ShellExecuteA(NULL, verb, file, parm, cwd, SW_SHOWNORMAL); + if (r < 33) + Jim_SetResult(interp, + Win32ErrorObj(interp, "ShellExecute", GetLastError())); + return (r < 33) ? JIM_ERR : JIM_OK; +} + + +/* win32.FindWindow title ?class? */ +static int +Win32_FindWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + const char *title = NULL, *class = NULL; + HWND hwnd = NULL; + int r = JIM_OK; + + if (objc < 2 || objc > 3) { + Jim_WrongNumArgs(interp, 1, objv, "title ?class?"); + return JIM_ERR; + } + title = Jim_String(objv[1]); + if (objc == 3) + class = Jim_String(objv[2]); + hwnd = FindWindowA(class, title); + + if (hwnd == NULL) { + Jim_SetResult(interp, + Win32ErrorObj(interp, "FindWindow", GetLastError())); + r = JIM_ERR; + } else { + Jim_SetResult(interp, Jim_NewIntObj(interp, (long)hwnd)); + } + return r; +} + +/* win32.CloseWindow windowHandle */ +static int +Win32_CloseWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + long hwnd; + + if (objc != 2) { + Jim_WrongNumArgs(interp, 1, objv, "?windowHandle?"); + return JIM_ERR; + } + if (Jim_GetLong(interp, objv[1], &hwnd) != JIM_OK) + return JIM_ERR; + if (!CloseWindow((HWND)hwnd)) { + Jim_SetResult(interp, + Win32ErrorObj(interp, "CloseWindow", GetLastError())); + return JIM_ERR; + } + return JIM_OK; +} + +static int +Win32_GetActiveWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + Jim_SetResult(interp, Jim_NewIntObj(interp, (DWORD)GetActiveWindow())); + return JIM_OK; +} + +static int +Win32_SetActiveWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + HWND hwnd, old; + int r = JIM_OK; + + if (objc != 2) { + Jim_WrongNumArgs(interp, 1, objv, "windowHandle"); + return JIM_ERR; + } + r = Jim_GetLong(interp, objv[1], (long *)&hwnd); + if (r == JIM_OK) { + old = SetActiveWindow(hwnd); + if (old == NULL) { + Jim_SetResult(interp, + Win32ErrorObj(interp, "SetActiveWindow", GetLastError())); + r = JIM_ERR; + } else { + Jim_SetResult(interp, Jim_NewIntObj(interp, (long)old)); + } + } + return r; +} + +static int +Win32_SetForegroundWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + HWND hwnd; + int r = JIM_OK; + + if (objc != 2) { + Jim_WrongNumArgs(interp, 1, objv, "windowHandle"); + return JIM_ERR; + } + r = Jim_GetLong(interp, objv[1], (long *)&hwnd); + if (r == JIM_OK) { + if (!SetForegroundWindow(hwnd)) { + Jim_SetResult(interp, + Win32ErrorObj(interp, "SetForegroundWindow", GetLastError())); + r = JIM_ERR; + } + } + return r; +} + +static int +Win32_Beep(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + long freq, duration; + int r = JIM_OK; + + if (objc != 3) { + Jim_WrongNumArgs(interp, 1, objv, "freq duration"); + return JIM_ERR; + } + r = Jim_GetLong(interp, objv[1], &freq); + if (r == JIM_OK) + r = Jim_GetLong(interp, objv[2], &duration); + if (freq < 0x25) freq = 0x25; + if (freq > 0x7fff) freq = 0x7fff; + if (r == JIM_OK) { + if (!Beep(freq, duration)) { + Jim_SetResult(interp, + Win32ErrorObj(interp, "Beep", GetLastError())); + r = JIM_ERR; + } + } + return r; +} + +static int +Win32_GetComputerName(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + char name[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD size = MAX_COMPUTERNAME_LENGTH; + int r = JIM_OK; + + if (objc != 1) { + Jim_WrongNumArgs(interp, 1, objv, ""); + return JIM_ERR; + } + + if (GetComputerNameA(name, &size)) { + Jim_Obj *nameObj = Jim_NewStringObj(interp, name, size); + Jim_SetResult(interp, nameObj); + } else { + Jim_SetResult(interp, + Win32ErrorObj(interp, "GetComputerName", GetLastError())); + r = JIM_ERR; + } + + return r; +} + +static int +Win32_GetUserName(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + char name[UNLEN + 1]; + DWORD size = UNLEN; + int r = JIM_OK; + + if (objc != 1) { + Jim_WrongNumArgs(interp, 1, objv, ""); + return JIM_ERR; + } + + if (GetUserNameA(name, &size)) { + Jim_Obj *nameObj = Jim_NewStringObj(interp, name, size); + Jim_SetResult(interp, nameObj); + } else { + Jim_SetResult(interp, + Win32ErrorObj(interp, "GetUserName", GetLastError())); + r = JIM_ERR; + } + + return r; +} + +static int +Win32_GetModuleFileName(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + HMODULE hModule = NULL; + char path[MAX_PATH]; + DWORD len = 0; + + if (objc > 2) { + Jim_WrongNumArgs(interp, 1, objv, "?moduleid?"); + return JIM_ERR; + } + + if (objc == 2) { + if (Jim_GetLong(interp, objv[1], (long *)&hModule) != JIM_OK) { + return JIM_ERR; + } + } + + len = GetModuleFileNameA(hModule, path, MAX_PATH); + if (len != 0) { + Jim_Obj *pathObj = Jim_NewStringObj(interp, path, len); + Jim_SetResult(interp, pathObj); + } else { + Jim_SetResult(interp, + Win32ErrorObj(interp, "GetModuleFileName", GetLastError())); + return JIM_ERR; + } + + return JIM_OK; +} + +static int +Win32_GetVersion(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + Jim_SetResult(interp, Jim_NewIntObj(interp, GetVersion())); + return JIM_OK; +} + +static int +Win32_GetTickCount(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + Jim_SetResult(interp, Jim_NewIntObj(interp, GetTickCount())); + return JIM_OK; +} + +static int +Win32_GetSystemTime(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + Jim_Obj *a[16]; + size_t n = 0; + SYSTEMTIME t; + GetSystemTime(&t); + +#define JIMADD(name) \ + a[n++] = Jim_NewStringObj(interp, #name, -1); \ + a[n++] = Jim_NewIntObj(interp, t.w ## name ) + + JIMADD(Year); + JIMADD(Month); + JIMADD(DayOfWeek); + JIMADD(Day); + JIMADD(Hour); + JIMADD(Minute); + JIMADD(Second); + JIMADD(Milliseconds); +#undef JIMADD + + Jim_SetResult(interp, Jim_NewListObj(interp, a, n)); + return JIM_OK; +} + +/* function not available on mingw or cygwin */ +#if !defined(__MINGW32__) && !defined(__CYGWIN__) +// FIX ME: win2k+ so should do version checks really. +static int +Win32_GetPerformanceInfo(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + Jim_Obj *a[26]; + size_t n = 0; + PERFORMANCE_INFORMATION pi; + + if (!GetPerformanceInfo(&pi, sizeof(pi))) { + Jim_SetResult(interp, + Win32ErrorObj(interp, "GetPerformanceInfo", GetLastError())); + return JIM_ERR; + } + +#define JIMADD(name) \ + a[n++] = Jim_NewStringObj(interp, #name, -1); \ + a[n++] = Jim_NewIntObj(interp, pi. name ) + + JIMADD(CommitTotal); + JIMADD(CommitLimit); + JIMADD(CommitPeak); + JIMADD(PhysicalTotal); + JIMADD(PhysicalAvailable); + JIMADD(SystemCache); + JIMADD(KernelTotal); + JIMADD(KernelPaged); + JIMADD(KernelNonpaged); + JIMADD(PageSize); + JIMADD(HandleCount); + JIMADD(ProcessCount); + JIMADD(ThreadCount); +#undef JIMADD + + Jim_SetResult(interp, Jim_NewListObj(interp, a, n)); + return JIM_OK; +} +#endif + +static int +Win32_SetComputerName(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + int r = JIM_OK; + const char *name; + if (objc != 2) { + Jim_WrongNumArgs(interp, 1, objv, "computername"); + return JIM_ERR; + } + name = Jim_String(objv[1]); + if (!SetComputerNameA(name)) { + Jim_SetResult(interp, + Win32ErrorObj(interp, "SetComputerName", GetLastError())); + r = JIM_ERR; + } + return r; +} + +static int +Win32_GetModuleHandle(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + HMODULE hModule = NULL; + const char *name = NULL; + + if (objc < 1 || objc > 2) { + Jim_WrongNumArgs(interp, 1, objv, "?name?"); + return JIM_ERR; + } + if (objc == 2) + name = Jim_String(objv[1]); + hModule = GetModuleHandleA(name); + if (hModule == NULL) { + Jim_SetResult(interp, + Win32ErrorObj(interp, "GetModuleHandle", GetLastError())); + return JIM_ERR; + } + Jim_SetResult(interp, Jim_NewIntObj(interp, (unsigned long)hModule)); + return JIM_OK; +} + +static int +Win32_LoadLibrary(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + HMODULE hLib = NULL; + if (objc != 2) { + Jim_WrongNumArgs(interp, 1, objv, "path"); + return JIM_ERR; + } + hLib = LoadLibraryA(Jim_String(objv[1])); + if (hLib == NULL) { + Jim_SetResult(interp, + Win32ErrorObj(interp, "LoadLibrary", GetLastError())); + return JIM_ERR; + } + Jim_SetResult(interp, Jim_NewIntObj(interp, (unsigned long)hLib)); + return JIM_OK; +} + +static int +Win32_FreeLibrary(Jim_Interp *interp, int objc, Jim_Obj * const *objv) +{ + HMODULE hModule = NULL; + int r = JIM_OK; + + if (objc != 2) { + Jim_WrongNumArgs(interp, 1, objv, "hmodule"); + return JIM_ERR; + } + + r = Jim_GetLong(interp, objv[1], (long *)&hModule); + if (r == JIM_OK) { + if (!FreeLibrary(hModule)) { + Jim_SetResult(interp, + Win32ErrorObj(interp, "FreeLibrary", GetLastError())); + r = JIM_ERR; + } + } + + return r; +} + + +/* ---------------------------------------------------------------------- */ + +int +Jim_win32Init(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "win32", "1.0", JIM_ERRMSG)) + return JIM_ERR; + +#define CMD(name) \ + Jim_CreateCommand(interp, "win32." #name , Win32_ ## name , NULL, NULL) + + CMD(ShellExecute); + CMD(FindWindow); + CMD(CloseWindow); + CMD(GetActiveWindow); + CMD(SetActiveWindow); + CMD(SetForegroundWindow); + CMD(Beep); + CMD(GetComputerName); + CMD(SetComputerName); + CMD(GetUserName); + CMD(GetModuleFileName); + CMD(GetVersion); + CMD(GetTickCount); + CMD(GetSystemTime); +#if !defined(__MINGW32__) && !defined(__CYGWIN__) + CMD(GetPerformanceInfo); +#endif + CMD(GetModuleHandle); + CMD(LoadLibrary); + CMD(FreeLibrary); + + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/jim-win32compat.c b/debuggers/openocd/jimtcl/jim-win32compat.c new file mode 100644 index 00000000..94bd8317 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-win32compat.c @@ -0,0 +1,132 @@ +#include "jim.h" +#include "jimautoconf.h" + +#if defined(_WIN32) || defined(WIN32) +#ifndef STRICT +#define STRICT +#endif +#define WIN32_LEAN_AND_MEAN +#include + +#if defined(HAVE_DLOPEN_COMPAT) +void *dlopen(const char *path, int mode) +{ + JIM_NOTUSED(mode); + + return (void *)LoadLibraryA(path); +} + +int dlclose(void *handle) +{ + FreeLibrary((HANDLE)handle); + return 0; +} + +void *dlsym(void *handle, const char *symbol) +{ + return GetProcAddress((HMODULE)handle, symbol); +} + +char *dlerror(void) +{ + static char msg[121]; + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), + LANG_NEUTRAL, msg, sizeof(msg) - 1, NULL); + return msg; +} +#endif + +#ifdef _MSC_VER + +#include + +/* POSIX gettimeofday() compatibility for WIN32 */ +int gettimeofday(struct timeval *tv, void *unused) +{ + struct _timeb tb; + + _ftime(&tb); + tv->tv_sec = tb.time; + tv->tv_usec = tb.millitm * 1000; + + return 0; +} + +/* Posix dirent.h compatiblity layer for WIN32. + * Copyright Kevlin Henney, 1997, 2003. All rights reserved. + * Copyright Salvatore Sanfilippo ,2005. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose is hereby granted without fee, provided + * that this copyright and permissions notice appear in all copies and + * derivatives. + * + * This software is supplied "as is" without express or implied warranty. + * This software was modified by Salvatore Sanfilippo for the Jim Interpreter. + */ + +DIR *opendir(const char *name) +{ + DIR *dir = 0; + + if (name && name[0]) { + size_t base_length = strlen(name); + const char *all = /* search pattern must end with suitable wildcard */ + strchr("/\\", name[base_length - 1]) ? "*" : "/*"; + + if ((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 && + (dir->name = (char *)Jim_Alloc(base_length + strlen(all) + 1)) != 0) { + strcat(strcpy(dir->name, name), all); + + if ((dir->handle = (long)_findfirst(dir->name, &dir->info)) != -1) + dir->result.d_name = 0; + else { /* rollback */ + Jim_Free(dir->name); + Jim_Free(dir); + dir = 0; + } + } + else { /* rollback */ + Jim_Free(dir); + dir = 0; + errno = ENOMEM; + } + } + else { + errno = EINVAL; + } + return dir; +} + +int closedir(DIR * dir) +{ + int result = -1; + + if (dir) { + if (dir->handle != -1) + result = _findclose(dir->handle); + Jim_Free(dir->name); + Jim_Free(dir); + } + if (result == -1) /* map all errors to EBADF */ + errno = EBADF; + return result; +} + +struct dirent *readdir(DIR * dir) +{ + struct dirent *result = 0; + + if (dir && dir->handle != -1) { + if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) { + result = &dir->result; + result->d_name = dir->info.name; + } + } + else { + errno = EBADF; + } + return result; +} +#endif +#endif diff --git a/debuggers/openocd/jimtcl/jim-win32compat.h b/debuggers/openocd/jimtcl/jim-win32compat.h new file mode 100644 index 00000000..717642c1 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim-win32compat.h @@ -0,0 +1,68 @@ +#ifndef JIM_WIN32COMPAT_H +#define JIM_WIN32COMPAT_H + +/* Compatibility for Windows (mingw and msvc, not cygwin */ + +/* Note that at this point we don't yet have access to jimautoconf.h */ +#if defined(_WIN32) || defined(WIN32) + +#define HAVE_DLOPEN +void *dlopen(const char *path, int mode); +int dlclose(void *handle); +void *dlsym(void *handle, const char *symbol); +char *dlerror(void); + +/* MS CRT always uses three digits after 'e' */ +#define JIM_SPRINTF_DOUBLE_NEEDS_FIX + +#ifdef _MSC_VER +/* These are msvc vs gcc */ + +#if _MSC_VER >= 1000 + #pragma warning(disable:4146) +#endif + +#include +#define jim_wide _int64 +#ifndef LLONG_MAX + #define LLONG_MAX 9223372036854775807I64 +#endif +#ifndef LLONG_MIN + #define LLONG_MIN (-LLONG_MAX - 1I64) +#endif +#define JIM_WIDE_MIN LLONG_MIN +#define JIM_WIDE_MAX LLONG_MAX +#define JIM_WIDE_MODIFIER "I64d" +#define strcasecmp _stricmp +#define strtoull _strtoui64 +#define snprintf _snprintf + +#include + +struct timeval { + long tv_sec; + long tv_usec; +}; + +int gettimeofday(struct timeval *tv, void *unused); + +#define HAVE_OPENDIR +struct dirent { + char *d_name; +}; + +typedef struct DIR { + long handle; /* -1 for failed rewind */ + struct _finddata_t info; + struct dirent result; /* d_name null iff first time */ + char *name; /* null-terminated char string */ +} DIR; + +DIR *opendir(const char *name); +int closedir(DIR *dir); +struct dirent *readdir(DIR *dir); +#endif /* _MSC_VER */ + +#endif /* WIN32 */ + +#endif diff --git a/debuggers/openocd/jimtcl/jim.c b/debuggers/openocd/jimtcl/jim.c new file mode 100644 index 00000000..b2d58532 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim.c @@ -0,0 +1,15241 @@ + +/* Jim - A small embeddable Tcl interpreter + * + * Copyright 2005 Salvatore Sanfilippo + * Copyright 2005 Clemens Hintze + * Copyright 2005 patthoyts - Pat Thoyts + * Copyright 2008,2009 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com + * Copyright 2008 Andrew Lunn + * Copyright 2008 Duane Ellis + * Copyright 2008 Uwe Klein + * Copyright 2008 Steve Bennett + * Copyright 2009 Nico Coesel + * Copyright 2009 Zachary T Welch zw@superlucidity.net + * Copyright 2009 David Brownell + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + **/ +#define JIM_OPTIMIZATION /* comment to avoid optimizations and reduce size */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "jim.h" +#include "jimautoconf.h" +#include "utf8.h" + +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_BACKTRACE +#include +#endif +#ifdef HAVE_CRT_EXTERNS_H +#include +#endif + +/* For INFINITY, even if math functions are not enabled */ +#include + +/* We may decide to switch to using $[...] after all, so leave it as an option */ +/*#define EXPRSUGAR_BRACKET*/ + +/* For the no-autoconf case */ +#ifndef TCL_LIBRARY +#define TCL_LIBRARY "." +#endif +#ifndef TCL_PLATFORM_OS +#define TCL_PLATFORM_OS "unknown" +#endif +#ifndef TCL_PLATFORM_PLATFORM +#define TCL_PLATFORM_PLATFORM "unknown" +#endif +#ifndef TCL_PLATFORM_PATH_SEPARATOR +#define TCL_PLATFORM_PATH_SEPARATOR ":" +#endif + +/*#define DEBUG_SHOW_SCRIPT*/ +/*#define DEBUG_SHOW_SCRIPT_TOKENS*/ +/*#define DEBUG_SHOW_SUBST*/ +/*#define DEBUG_SHOW_EXPR*/ +/*#define DEBUG_SHOW_EXPR_TOKENS*/ +/*#define JIM_DEBUG_GC*/ +#ifdef JIM_MAINTAINER +#define JIM_DEBUG_COMMAND +#define JIM_DEBUG_PANIC +#endif + +/* Maximum size of an integer */ +#define JIM_INTEGER_SPACE 24 + +const char *jim_tt_name(int type); + +#ifdef JIM_DEBUG_PANIC +static void JimPanicDump(int panic_condition, const char *fmt, ...); +#define JimPanic(X) JimPanicDump X +#else +#define JimPanic(X) +#endif + +/* ----------------------------------------------------------------------------- + * Global variables + * ---------------------------------------------------------------------------*/ + +/* A shared empty string for the objects string representation. + * Jim_InvalidateStringRep knows about it and doesn't try to free it. */ +static char JimEmptyStringRep[] = ""; + +/* ----------------------------------------------------------------------------- + * Required prototypes of not exported functions + * ---------------------------------------------------------------------------*/ +static void JimChangeCallFrameId(Jim_Interp *interp, Jim_CallFrame *cf); +static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int flags); +static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int listindex, Jim_Obj *newObjPtr, + int flags); +static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands); +static Jim_Obj *JimExpandDictSugar(Jim_Interp *interp, Jim_Obj *objPtr); +static void SetDictSubstFromAny(Jim_Interp *interp, Jim_Obj *objPtr); +static Jim_Obj **JimDictPairs(Jim_Obj *dictPtr, int *len); +static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype, + const char *prefix, const char *const *tablePtr, const char *name); +static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj *const *argv); +static int JimGetWideNoErr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr); +static int JimSign(jim_wide w); +static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr); +static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen); +static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len); + + +/* Fast access to the int (wide) value of an object which is known to be of int type */ +#define JimWideValue(objPtr) (objPtr)->internalRep.wideValue + +#define JimObjTypeName(O) ((O)->typePtr ? (O)->typePtr->name : "none") + +static int utf8_tounicode_case(const char *s, int *uc, int upper) +{ + int l = utf8_tounicode(s, uc); + if (upper) { + *uc = utf8_upper(*uc); + } + return l; +} + +/* These can be used in addition to JIM_CASESENS/JIM_NOCASE */ +#define JIM_CHARSET_SCAN 2 +#define JIM_CHARSET_GLOB 0 + +/** + * pattern points to a string like "[^a-z\ub5]" + * + * The pattern may contain trailing chars, which are ignored. + * + * The pattern is matched against unicode char 'c'. + * + * If (flags & JIM_NOCASE), case is ignored when matching. + * If (flags & JIM_CHARSET_SCAN), the considers ^ and ] special at the start + * of the charset, per scan, rather than glob/string match. + * + * If the unicode char 'c' matches that set, returns a pointer to the ']' character, + * or the null character if the ']' is missing. + * + * Returns NULL on no match. + */ +static const char *JimCharsetMatch(const char *pattern, int c, int flags) +{ + int not = 0; + int pchar; + int match = 0; + int nocase = 0; + + if (flags & JIM_NOCASE) { + nocase++; + c = utf8_upper(c); + } + + if (flags & JIM_CHARSET_SCAN) { + if (*pattern == '^') { + not++; + pattern++; + } + + /* Special case. If the first char is ']', it is part of the set */ + if (*pattern == ']') { + goto first; + } + } + + while (*pattern && *pattern != ']') { + /* Exact match */ + if (pattern[0] == '\\') { +first: + pattern += utf8_tounicode_case(pattern, &pchar, nocase); + } + else { + /* Is this a range? a-z */ + int start; + int end; + + pattern += utf8_tounicode_case(pattern, &start, nocase); + if (pattern[0] == '-' && pattern[1]) { + /* skip '-' */ + pattern += utf8_tounicode(pattern, &pchar); + pattern += utf8_tounicode_case(pattern, &end, nocase); + + /* Handle reversed range too */ + if ((c >= start && c <= end) || (c >= end && c <= start)) { + match = 1; + } + continue; + } + pchar = start; + } + + if (pchar == c) { + match = 1; + } + } + if (not) { + match = !match; + } + + return match ? pattern : NULL; +} + +/* Glob-style pattern matching. */ + +/* Note: string *must* be valid UTF-8 sequences + */ +static int JimGlobMatch(const char *pattern, const char *string, int nocase) +{ + int c; + int pchar; + while (*pattern) { + switch (pattern[0]) { + case '*': + while (pattern[1] == '*') { + pattern++; + } + pattern++; + if (!pattern[0]) { + return 1; /* match */ + } + while (*string) { + /* Recursive call - Does the remaining pattern match anywhere? */ + if (JimGlobMatch(pattern, string, nocase)) + return 1; /* match */ + string += utf8_tounicode(string, &c); + } + return 0; /* no match */ + + case '?': + string += utf8_tounicode(string, &c); + break; + + case '[': { + string += utf8_tounicode(string, &c); + pattern = JimCharsetMatch(pattern + 1, c, nocase ? JIM_NOCASE : 0); + if (!pattern) { + return 0; + } + if (!*pattern) { + /* Ran out of pattern (no ']') */ + continue; + } + break; + } + case '\\': + if (pattern[1]) { + pattern++; + } + /* fall through */ + default: + string += utf8_tounicode_case(string, &c, nocase); + utf8_tounicode_case(pattern, &pchar, nocase); + if (pchar != c) { + return 0; + } + break; + } + pattern += utf8_tounicode_case(pattern, &pchar, nocase); + if (!*string) { + while (*pattern == '*') { + pattern++; + } + break; + } + } + if (!*pattern && !*string) { + return 1; + } + return 0; +} + +/** + * string comparison works on binary data. + * + * Note that the lengths are byte lengths, not char lengths. + */ +static int JimStringCompare(const char *s1, int l1, const char *s2, int l2) +{ + if (l1 < l2) { + return memcmp(s1, s2, l1) <= 0 ? -1 : 1; + } + else if (l2 < l1) { + return memcmp(s1, s2, l2) >= 0 ? 1 : -1; + } + else { + return JimSign(memcmp(s1, s2, l1)); + } +} + +/** + * Compare null terminated strings, up to a maximum of 'maxchars' characters, + * (or end of string if 'maxchars' is -1). + * + * Returns -1, 0, 1 for s1 < s2, s1 == s2, s1 > s2 respectively. + */ +static int JimStringCompareLen(const char *s1, const char *s2, int maxchars, int nocase) +{ + while (*s1 && *s2 && maxchars) { + int c1, c2; + s1 += utf8_tounicode_case(s1, &c1, nocase); + s2 += utf8_tounicode_case(s2, &c2, nocase); + if (c1 != c2) { + return JimSign(c1 - c2); + } + maxchars--; + } + if (!maxchars) { + return 0; + } + /* One string or both terminated */ + if (*s1) { + return 1; + } + if (*s2) { + return -1; + } + return 0; +} + +/* Search 's1' inside 's2', starting to search from char 'index' of 's2'. + * The index of the first occurrence of s1 in s2 is returned. + * If s1 is not found inside s2, -1 is returned. */ +static int JimStringFirst(const char *s1, int l1, const char *s2, int l2, int idx) +{ + int i; + int l1bytelen; + + if (!l1 || !l2 || l1 > l2) { + return -1; + } + if (idx < 0) + idx = 0; + s2 += utf8_index(s2, idx); + + l1bytelen = utf8_index(s1, l1); + + for (i = idx; i <= l2 - l1; i++) { + int c; + if (memcmp(s2, s1, l1bytelen) == 0) { + return i; + } + s2 += utf8_tounicode(s2, &c); + } + return -1; +} + +/** + * Note: Lengths and return value are in bytes, not chars. + */ +static int JimStringLast(const char *s1, int l1, const char *s2, int l2) +{ + const char *p; + + if (!l1 || !l2 || l1 > l2) + return -1; + + /* Now search for the needle */ + for (p = s2 + l2 - 1; p != s2 - 1; p--) { + if (*p == *s1 && memcmp(s1, p, l1) == 0) { + return p - s2; + } + } + return -1; +} + +#ifdef JIM_UTF8 +/** + * Note: Lengths and return value are in chars. + */ +static int JimStringLastUtf8(const char *s1, int l1, const char *s2, int l2) +{ + int n = JimStringLast(s1, utf8_index(s1, l1), s2, utf8_index(s2, l2)); + if (n > 0) { + n = utf8_strlen(s2, n); + } + return n; +} +#endif + +static int JimWideToString(char *buf, jim_wide wideValue) +{ + int pos = 0; + + if (wideValue == 0) { + buf[pos++] = '0'; + } + else { + char tmp[JIM_INTEGER_SPACE]; + int num = 0; + int i; + + if (wideValue < 0) { + buf[pos++] = '-'; + /* -106 % 10 may be -6 or 4! */ + i = wideValue % 10; + tmp[num++] = (i > 0) ? (10 - i) : -i; + wideValue /= -10; + } + + while (wideValue) { + tmp[num++] = wideValue % 10; + wideValue /= 10; + } + + for (i = 0; i < num; i++) { + buf[pos++] = '0' + tmp[num - i - 1]; + } + } + buf[pos] = 0; + + return pos; +} + +/** + * After an strtol()/strtod()-like conversion, + * check whether something was converted and that + * the only thing left is white space. + * + * Returns JIM_OK or JIM_ERR. + */ +static int JimCheckConversion(const char *str, const char *endptr) +{ + if (str[0] == '\0' || str == endptr) { + return JIM_ERR; + } + + if (endptr[0] != '\0') { + while (*endptr) { + if (!isspace(UCHAR(*endptr))) { + return JIM_ERR; + } + endptr++; + } + } + return JIM_OK; +} + +/* Parses the front of a number to determine it's sign and base + * Returns the index to start parsing according to the given base + */ +static int JimNumberBase(const char *str, int *base, int *sign) +{ + int i = 0; + + *base = 10; + + while (isspace(UCHAR(str[i]))) { + i++; + } + + if (str[i] == '-') { + *sign = -1; + i++; + } + else { + if (str[i] == '+') { + i++; + } + *sign = 1; + } + + if (str[i] != '0') { + /* base 10 */ + return 0; + } + + /* We have 0, so see if we can convert it */ + switch (str[i + 1]) { + case 'x': case 'X': *base = 16; break; + case 'o': case 'O': *base = 8; break; + case 'b': case 'B': *base = 2; break; + default: return 0; + } + i += 2; + /* Ensure that (e.g.) 0x-5 fails to parse */ + if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) { + /* Parse according to this base */ + return i; + } + /* Parse as base 10 */ + return 10; +} + +/* Converts a number as per strtol(..., 0) except leading zeros do *not* + * imply octal. Instead, decimal is assumed unless the number begins with 0x, 0o or 0b + */ +static long jim_strtol(const char *str, char **endptr) +{ + int sign; + int base; + int i = JimNumberBase(str, &base, &sign); + + if (base != 10) { + long value = strtol(str + i, endptr, base); + if (endptr == NULL || *endptr != str + i) { + return value * sign; + } + } + + /* Can just do a regular base-10 conversion */ + return strtol(str, endptr, 10); +} + + +/* Converts a number as per strtoull(..., 0) except leading zeros do *not* + * imply octal. Instead, decimal is assumed unless the number begins with 0x, 0o or 0b + */ +static jim_wide jim_strtoull(const char *str, char **endptr) +{ +#ifdef HAVE_LONG_LONG + int sign; + int base; + int i = JimNumberBase(str, &base, &sign); + + if (base != 10) { + jim_wide value = strtoull(str + i, endptr, base); + if (endptr == NULL || *endptr != str + i) { + return value * sign; + } + } + + /* Can just do a regular base-10 conversion */ + return strtoull(str, endptr, 10); +#else + return (unsigned long)jim_strtol(str, endptr); +#endif +} + +int Jim_StringToWide(const char *str, jim_wide * widePtr, int base) +{ + char *endptr; + + if (base) { + *widePtr = strtoull(str, &endptr, base); + } + else { + *widePtr = jim_strtoull(str, &endptr); + } + + return JimCheckConversion(str, endptr); +} + +int Jim_DoubleToString(char *buf, double doubleValue) +{ + int len; + int i; + + len = sprintf(buf, "%.12g", doubleValue); + + /* Add a final ".0" if necessary */ + for (i = 0; i < len; i++) { + if (buf[i] == '.' || buf[i] == 'e') { +#if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX) + /* If 'buf' ends in e-0nn or e+0nn, remove + * the 0 after the + or - and reduce the length by 1 + */ + char *e = strchr(buf, 'e'); + if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') { + /* Move it up */ + e += 2; + memmove(e, e + 1, len - (e - buf)); + return len - 1; + } +#endif + return len; + } + /* inf or Infinity -> Inf, nan -> Nan */ + if (buf[i] == 'i' || buf[i] == 'I' || buf[i] == 'n' || buf[i] == 'N') { + buf[i] = toupper(UCHAR(buf[i])); + buf[i + 3] = 0; + return i + 3; + } + } + + buf[i++] = '.'; + buf[i++] = '0'; + buf[i] = '\0'; + + return i; +} + +int Jim_StringToDouble(const char *str, double *doublePtr) +{ + char *endptr; + + /* Callers can check for underflow via ERANGE */ + errno = 0; + + *doublePtr = strtod(str, &endptr); + + return JimCheckConversion(str, endptr); +} + +static jim_wide JimPowWide(jim_wide b, jim_wide e) +{ + jim_wide i, res = 1; + + if ((b == 0 && e != 0) || (e < 0)) + return 0; + for (i = 0; i < e; i++) { + res *= b; + } + return res; +} + +/* ----------------------------------------------------------------------------- + * Special functions + * ---------------------------------------------------------------------------*/ +#ifdef JIM_DEBUG_PANIC +void JimPanicDump(int condition, const char *fmt, ...) +{ + va_list ap; + + if (!condition) { + return; + } + + va_start(ap, fmt); + + fprintf(stderr, JIM_NL "JIM INTERPRETER PANIC: "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, JIM_NL JIM_NL); + va_end(ap); + +#ifdef HAVE_BACKTRACE + { + void *array[40]; + int size, i; + char **strings; + + size = backtrace(array, 40); + strings = backtrace_symbols(array, size); + for (i = 0; i < size; i++) + fprintf(stderr, "[backtrace] %s" JIM_NL, strings[i]); + fprintf(stderr, "[backtrace] Include the above lines and the output" JIM_NL); + fprintf(stderr, "[backtrace] of 'nm ' in the bug report." JIM_NL); + } +#endif + + exit(1); +} +#endif + +/* ----------------------------------------------------------------------------- + * Memory allocation + * ---------------------------------------------------------------------------*/ + +void *Jim_Alloc(int size) +{ + return size ? malloc(size) : NULL; +} + +void Jim_Free(void *ptr) +{ + free(ptr); +} + +void *Jim_Realloc(void *ptr, int size) +{ + return realloc(ptr, size); +} + +char *Jim_StrDup(const char *s) +{ + return strdup(s); +} + +char *Jim_StrDupLen(const char *s, int l) +{ + char *copy = Jim_Alloc(l + 1); + + memcpy(copy, s, l + 1); + copy[l] = 0; /* Just to be sure, original could be substring */ + return copy; +} + +/* ----------------------------------------------------------------------------- + * Time related functions + * ---------------------------------------------------------------------------*/ + +/* Returns microseconds of CPU used since start. */ +static jim_wide JimClock(void) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + return (jim_wide) tv.tv_sec * 1000000 + tv.tv_usec; +} + +/* ----------------------------------------------------------------------------- + * Hash Tables + * ---------------------------------------------------------------------------*/ + +/* -------------------------- private prototypes ---------------------------- */ +static void JimExpandHashTableIfNeeded(Jim_HashTable *ht); +static unsigned int JimHashTableNextPower(unsigned int size); +static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace); + +/* -------------------------- hash functions -------------------------------- */ + +/* Thomas Wang's 32 bit Mix Function */ +unsigned int Jim_IntHashFunction(unsigned int key) +{ + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; +} + +/* Generic hash function (we are using to multiply by 9 and add the byte + * as Tcl) */ +unsigned int Jim_GenHashFunction(const unsigned char *buf, int len) +{ + unsigned int h = 0; + + while (len--) + h += (h << 3) + *buf++; + return h; +} + +/* ----------------------------- API implementation ------------------------- */ + +/* reset a hashtable already initialized with ht_init(). + * NOTE: This function should only called by ht_destroy(). */ +static void JimResetHashTable(Jim_HashTable *ht) +{ + ht->table = NULL; + ht->size = 0; + ht->sizemask = 0; + ht->used = 0; + ht->collisions = 0; +} + +static void JimInitHashTableIterator(Jim_HashTable *ht, Jim_HashTableIterator *iter) +{ + iter->ht = ht; + iter->index = -1; + iter->entry = NULL; + iter->nextEntry = NULL; +} + +/* Initialize the hash table */ +int Jim_InitHashTable(Jim_HashTable *ht, const Jim_HashTableType *type, void *privDataPtr) +{ + JimResetHashTable(ht); + ht->type = type; + ht->privdata = privDataPtr; + return JIM_OK; +} + +/* Resize the table to the minimal size that contains all the elements, + * but with the invariant of a USER/BUCKETS ration near to <= 1 */ +void Jim_ResizeHashTable(Jim_HashTable *ht) +{ + int minimal = ht->used; + + if (minimal < JIM_HT_INITIAL_SIZE) + minimal = JIM_HT_INITIAL_SIZE; + Jim_ExpandHashTable(ht, minimal); +} + +/* Expand or create the hashtable */ +void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size) +{ + Jim_HashTable n; /* the new hashtable */ + unsigned int realsize = JimHashTableNextPower(size), i; + + /* the size is invalid if it is smaller than the number of + * elements already inside the hashtable */ + if (size <= ht->used) + return; + + Jim_InitHashTable(&n, ht->type, ht->privdata); + n.size = realsize; + n.sizemask = realsize - 1; + n.table = Jim_Alloc(realsize * sizeof(Jim_HashEntry *)); + + /* Initialize all the pointers to NULL */ + memset(n.table, 0, realsize * sizeof(Jim_HashEntry *)); + + /* Copy all the elements from the old to the new table: + * note that if the old hash table is empty ht->used is zero, + * so Jim_ExpandHashTable just creates an empty hash table. */ + n.used = ht->used; + for (i = 0; ht->used > 0; i++) { + Jim_HashEntry *he, *nextHe; + + if (ht->table[i] == NULL) + continue; + + /* For each hash entry on this slot... */ + he = ht->table[i]; + while (he) { + unsigned int h; + + nextHe = he->next; + /* Get the new element index */ + h = Jim_HashKey(ht, he->key) & n.sizemask; + he->next = n.table[h]; + n.table[h] = he; + ht->used--; + /* Pass to the next element */ + he = nextHe; + } + } + assert(ht->used == 0); + Jim_Free(ht->table); + + /* Remap the new hashtable in the old */ + *ht = n; +} + +/* Add an element to the target hash table */ +int Jim_AddHashEntry(Jim_HashTable *ht, const void *key, void *val) +{ + Jim_HashEntry *entry; + + /* Get the index of the new element, or -1 if + * the element already exists. */ + entry = JimInsertHashEntry(ht, key, 0); + if (entry == NULL) + return JIM_ERR; + + /* Set the hash entry fields. */ + Jim_SetHashKey(ht, entry, key); + Jim_SetHashVal(ht, entry, val); + return JIM_OK; +} + +/* Add an element, discarding the old if the key already exists */ +int Jim_ReplaceHashEntry(Jim_HashTable *ht, const void *key, void *val) +{ + int existed; + Jim_HashEntry *entry; + + /* Get the index of the new element, or -1 if + * the element already exists. */ + entry = JimInsertHashEntry(ht, key, 1); + if (entry->key) { + /* It already exists, so replace the value */ + Jim_FreeEntryVal(ht, entry); + existed = 1; + } + else { + /* Doesn't exist, so set the key */ + Jim_SetHashKey(ht, entry, key); + existed = 0; + } + Jim_SetHashVal(ht, entry, val); + + return existed; +} + +/* Search and remove an element */ +int Jim_DeleteHashEntry(Jim_HashTable *ht, const void *key) +{ + unsigned int h; + Jim_HashEntry *he, *prevHe; + + if (ht->used == 0) + return JIM_ERR; + h = Jim_HashKey(ht, key) & ht->sizemask; + he = ht->table[h]; + + prevHe = NULL; + while (he) { + if (Jim_CompareHashKeys(ht, key, he->key)) { + /* Unlink the element from the list */ + if (prevHe) + prevHe->next = he->next; + else + ht->table[h] = he->next; + Jim_FreeEntryKey(ht, he); + Jim_FreeEntryVal(ht, he); + Jim_Free(he); + ht->used--; + return JIM_OK; + } + prevHe = he; + he = he->next; + } + return JIM_ERR; /* not found */ +} + +/* Destroy an entire hash table */ +int Jim_FreeHashTable(Jim_HashTable *ht) +{ + unsigned int i; + + /* Free all the elements */ + for (i = 0; ht->used > 0; i++) { + Jim_HashEntry *he, *nextHe; + + if ((he = ht->table[i]) == NULL) + continue; + while (he) { + nextHe = he->next; + Jim_FreeEntryKey(ht, he); + Jim_FreeEntryVal(ht, he); + Jim_Free(he); + ht->used--; + he = nextHe; + } + } + /* Free the table and the allocated cache structure */ + Jim_Free(ht->table); + /* Re-initialize the table */ + JimResetHashTable(ht); + return JIM_OK; /* never fails */ +} + +Jim_HashEntry *Jim_FindHashEntry(Jim_HashTable *ht, const void *key) +{ + Jim_HashEntry *he; + unsigned int h; + + if (ht->used == 0) + return NULL; + h = Jim_HashKey(ht, key) & ht->sizemask; + he = ht->table[h]; + while (he) { + if (Jim_CompareHashKeys(ht, key, he->key)) + return he; + he = he->next; + } + return NULL; +} + +Jim_HashTableIterator *Jim_GetHashTableIterator(Jim_HashTable *ht) +{ + Jim_HashTableIterator *iter = Jim_Alloc(sizeof(*iter)); + JimInitHashTableIterator(ht, iter); + return iter; +} + +Jim_HashEntry *Jim_NextHashEntry(Jim_HashTableIterator *iter) +{ + while (1) { + if (iter->entry == NULL) { + iter->index++; + if (iter->index >= (signed)iter->ht->size) + break; + iter->entry = iter->ht->table[iter->index]; + } + else { + iter->entry = iter->nextEntry; + } + if (iter->entry) { + /* We need to save the 'next' here, the iterator user + * may delete the entry we are returning. */ + iter->nextEntry = iter->entry->next; + return iter->entry; + } + } + return NULL; +} + +/* ------------------------- private functions ------------------------------ */ + +/* Expand the hash table if needed */ +static void JimExpandHashTableIfNeeded(Jim_HashTable *ht) +{ + /* If the hash table is empty expand it to the intial size, + * if the table is "full" dobule its size. */ + if (ht->size == 0) + Jim_ExpandHashTable(ht, JIM_HT_INITIAL_SIZE); + if (ht->size == ht->used) + Jim_ExpandHashTable(ht, ht->size * 2); +} + +/* Our hash table capability is a power of two */ +static unsigned int JimHashTableNextPower(unsigned int size) +{ + unsigned int i = JIM_HT_INITIAL_SIZE; + + if (size >= 2147483648U) + return 2147483648U; + while (1) { + if (i >= size) + return i; + i *= 2; + } +} + +/* Returns the index of a free slot that can be populated with + * an hash entry for the given 'key'. + * If the key already exists, -1 is returned. */ +static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace) +{ + unsigned int h; + Jim_HashEntry *he; + + /* Expand the hashtable if needed */ + JimExpandHashTableIfNeeded(ht); + + /* Compute the key hash value */ + h = Jim_HashKey(ht, key) & ht->sizemask; + /* Search if this slot does not already contain the given key */ + he = ht->table[h]; + while (he) { + if (Jim_CompareHashKeys(ht, key, he->key)) + return replace ? he : NULL; + he = he->next; + } + + /* Allocates the memory and stores key */ + he = Jim_Alloc(sizeof(*he)); + he->next = ht->table[h]; + ht->table[h] = he; + ht->used++; + he->key = NULL; + + return he; +} + +/* ----------------------- StringCopy Hash Table Type ------------------------*/ + +static unsigned int JimStringCopyHTHashFunction(const void *key) +{ + return Jim_GenHashFunction(key, strlen(key)); +} + +static void *JimStringCopyHTDup(void *privdata, const void *key) +{ + return strdup(key); +} + +static int JimStringCopyHTKeyCompare(void *privdata, const void *key1, const void *key2) +{ + return strcmp(key1, key2) == 0; +} + +static void JimStringCopyHTKeyDestructor(void *privdata, void *key) +{ + Jim_Free(key); +} + +static const Jim_HashTableType JimPackageHashTableType = { + JimStringCopyHTHashFunction, /* hash function */ + JimStringCopyHTDup, /* key dup */ + NULL, /* val dup */ + JimStringCopyHTKeyCompare, /* key compare */ + JimStringCopyHTKeyDestructor, /* key destructor */ + NULL /* val destructor */ +}; + +typedef struct AssocDataValue +{ + Jim_InterpDeleteProc *delProc; + void *data; +} AssocDataValue; + +static void JimAssocDataHashTableValueDestructor(void *privdata, void *data) +{ + AssocDataValue *assocPtr = (AssocDataValue *) data; + + if (assocPtr->delProc != NULL) + assocPtr->delProc((Jim_Interp *)privdata, assocPtr->data); + Jim_Free(data); +} + +static const Jim_HashTableType JimAssocDataHashTableType = { + JimStringCopyHTHashFunction, /* hash function */ + JimStringCopyHTDup, /* key dup */ + NULL, /* val dup */ + JimStringCopyHTKeyCompare, /* key compare */ + JimStringCopyHTKeyDestructor, /* key destructor */ + JimAssocDataHashTableValueDestructor /* val destructor */ +}; + +/* ----------------------------------------------------------------------------- + * Stack - This is a simple generic stack implementation. It is used for + * example in the 'expr' expression compiler. + * ---------------------------------------------------------------------------*/ +void Jim_InitStack(Jim_Stack *stack) +{ + stack->len = 0; + stack->maxlen = 0; + stack->vector = NULL; +} + +void Jim_FreeStack(Jim_Stack *stack) +{ + Jim_Free(stack->vector); +} + +int Jim_StackLen(Jim_Stack *stack) +{ + return stack->len; +} + +void Jim_StackPush(Jim_Stack *stack, void *element) +{ + int neededLen = stack->len + 1; + + if (neededLen > stack->maxlen) { + stack->maxlen = neededLen < 20 ? 20 : neededLen * 2; + stack->vector = Jim_Realloc(stack->vector, sizeof(void *) * stack->maxlen); + } + stack->vector[stack->len] = element; + stack->len++; +} + +void *Jim_StackPop(Jim_Stack *stack) +{ + if (stack->len == 0) + return NULL; + stack->len--; + return stack->vector[stack->len]; +} + +void *Jim_StackPeek(Jim_Stack *stack) +{ + if (stack->len == 0) + return NULL; + return stack->vector[stack->len - 1]; +} + +void Jim_FreeStackElements(Jim_Stack *stack, void (*freeFunc) (void *ptr)) +{ + int i; + + for (i = 0; i < stack->len; i++) + freeFunc(stack->vector[i]); +} + +/* ----------------------------------------------------------------------------- + * Parser + * ---------------------------------------------------------------------------*/ + +/* Token types */ +#define JIM_TT_NONE 0 /* No token returned */ +#define JIM_TT_STR 1 /* simple string */ +#define JIM_TT_ESC 2 /* string that needs escape chars conversion */ +#define JIM_TT_VAR 3 /* var substitution */ +#define JIM_TT_DICTSUGAR 4 /* Syntax sugar for [dict get], $foo(bar) */ +#define JIM_TT_CMD 5 /* command substitution */ +/* Note: Keep these three together for TOKEN_IS_SEP() */ +#define JIM_TT_SEP 6 /* word separator. arg is # of tokens. -ve if {*} */ +#define JIM_TT_EOL 7 /* line separator */ +#define JIM_TT_EOF 8 /* end of script */ + +#define JIM_TT_LINE 9 /* special 'start-of-line' token. arg is # of arguments to the command. -ve if {*} */ +#define JIM_TT_WORD 10 /* special 'start-of-word' token. arg is # of tokens to combine. -ve if {*} */ + +/* Additional token types needed for expressions */ +#define JIM_TT_SUBEXPR_START 11 +#define JIM_TT_SUBEXPR_END 12 +#define JIM_TT_SUBEXPR_COMMA 13 +#define JIM_TT_EXPR_INT 14 +#define JIM_TT_EXPR_DOUBLE 15 + +#define JIM_TT_EXPRSUGAR 16 /* $(expression) */ + +/* Operator token types start here */ +#define JIM_TT_EXPR_OP 20 + +#define TOKEN_IS_SEP(type) (type >= JIM_TT_SEP && type <= JIM_TT_EOF) + +/* Parser states */ +#define JIM_PS_DEF 0 /* Default state */ +#define JIM_PS_QUOTE 1 /* Inside "" */ +#define JIM_PS_DICTSUGAR 2 /* Tokenising abc(def) into 4 separate tokens */ + +/* Parser context structure. The same context is used both to parse + * Tcl scripts and lists. */ +struct JimParserCtx +{ + const char *p; /* Pointer to the point of the program we are parsing */ + int len; /* Remaining length */ + int linenr; /* Current line number */ + const char *tstart; + const char *tend; /* Returned token is at tstart-tend in 'prg'. */ + int tline; /* Line number of the returned token */ + int tt; /* Token type */ + int eof; /* Non zero if EOF condition is true. */ + int state; /* Parser state */ + int comment; /* Non zero if the next chars may be a comment. */ + char missing; /* At end of parse, ' ' if complete, '{' if braces incomplete, '"' if quotes incomplete */ + int missingline; /* Line number starting the missing token */ +}; + +/** + * Results of missing quotes, braces, etc. from parsing. + */ +struct JimParseResult { + char missing; /* From JimParserCtx.missing */ + int line; /* From JimParserCtx.missingline */ +}; + +static int JimParseScript(struct JimParserCtx *pc); +static int JimParseSep(struct JimParserCtx *pc); +static int JimParseEol(struct JimParserCtx *pc); +static int JimParseCmd(struct JimParserCtx *pc); +static int JimParseQuote(struct JimParserCtx *pc); +static int JimParseVar(struct JimParserCtx *pc); +static int JimParseBrace(struct JimParserCtx *pc); +static int JimParseStr(struct JimParserCtx *pc); +static int JimParseComment(struct JimParserCtx *pc); +static void JimParseSubCmd(struct JimParserCtx *pc); +static int JimParseSubQuote(struct JimParserCtx *pc); +static void JimParseSubCmd(struct JimParserCtx *pc); +static Jim_Obj *JimParserGetTokenObj(Jim_Interp *interp, struct JimParserCtx *pc); + +/* Initialize a parser context. + * 'prg' is a pointer to the program text, linenr is the line + * number of the first line contained in the program. */ +static void JimParserInit(struct JimParserCtx *pc, const char *prg, int len, int linenr) +{ + pc->p = prg; + pc->len = len; + pc->tstart = NULL; + pc->tend = NULL; + pc->tline = 0; + pc->tt = JIM_TT_NONE; + pc->eof = 0; + pc->state = JIM_PS_DEF; + pc->linenr = linenr; + pc->comment = 1; + pc->missing = ' '; + pc->missingline = linenr; +} + +static int JimParseScript(struct JimParserCtx *pc) +{ + while (1) { /* the while is used to reiterate with continue if needed */ + if (!pc->len) { + pc->tstart = pc->p; + pc->tend = pc->p - 1; + pc->tline = pc->linenr; + pc->tt = JIM_TT_EOL; + pc->eof = 1; + return JIM_OK; + } + switch (*(pc->p)) { + case '\\': + if (*(pc->p + 1) == '\n' && pc->state == JIM_PS_DEF) { + return JimParseSep(pc); + } + pc->comment = 0; + return JimParseStr(pc); + case ' ': + case '\t': + case '\r': + case '\f': + if (pc->state == JIM_PS_DEF) + return JimParseSep(pc); + pc->comment = 0; + return JimParseStr(pc); + case '\n': + case ';': + pc->comment = 1; + if (pc->state == JIM_PS_DEF) + return JimParseEol(pc); + return JimParseStr(pc); + case '[': + pc->comment = 0; + return JimParseCmd(pc); + case '$': + pc->comment = 0; + if (JimParseVar(pc) == JIM_ERR) { + /* An orphan $. Create as a separate token */ + pc->tstart = pc->tend = pc->p++; + pc->len--; + pc->tt = JIM_TT_ESC; + } + return JIM_OK; + case '#': + if (pc->comment) { + JimParseComment(pc); + continue; + } + return JimParseStr(pc); + default: + pc->comment = 0; + return JimParseStr(pc); + } + return JIM_OK; + } +} + +static int JimParseSep(struct JimParserCtx *pc) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + while (isspace(UCHAR(*pc->p)) || (*pc->p == '\\' && *(pc->p + 1) == '\n')) { + if (*pc->p == '\n') { + break; + } + if (*pc->p == '\\') { + pc->p++; + pc->len--; + pc->linenr++; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_SEP; + return JIM_OK; +} + +static int JimParseEol(struct JimParserCtx *pc) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + while (isspace(UCHAR(*pc->p)) || *pc->p == ';') { + if (*pc->p == '\n') + pc->linenr++; + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_EOL; + return JIM_OK; +} + +/* +** Here are the rules for parsing: +** {braced expression} +** - Count open and closing braces +** - Backslash escapes meaning of braces +** +** "quoted expression" +** - First double quote at start of word terminates the expression +** - Backslash escapes quote and bracket +** - [commands brackets] are counted/nested +** - command rules apply within [brackets], not quoting rules (i.e. quotes have their own rules) +** +** [command expression] +** - Count open and closing brackets +** - Backslash escapes quote, bracket and brace +** - [commands brackets] are counted/nested +** - "quoted expressions" are parsed according to quoting rules +** - {braced expressions} are parsed according to brace rules +** +** For everything, backslash escapes the next char, newline increments current line +*/ + +/** + * Parses a braced expression starting at pc->p. + * + * Positions the parser at the end of the braced expression, + * sets pc->tend and possibly pc->missing. + */ +static void JimParseSubBrace(struct JimParserCtx *pc) +{ + int level = 1; + + /* Skip the brace */ + pc->p++; + pc->len--; + while (pc->len) { + switch (*pc->p) { + case '\\': + if (pc->len > 1) { + if (*++pc->p == '\n') { + pc->linenr++; + } + pc->len--; + } + break; + + case '{': + level++; + break; + + case '}': + if (--level == 0) { + pc->tend = pc->p - 1; + pc->p++; + pc->len--; + return; + } + break; + + case '\n': + pc->linenr++; + break; + } + pc->p++; + pc->len--; + } + pc->missing = '{'; + pc->missingline = pc->tline; + pc->tend = pc->p - 1; +} + +/** + * Parses a quoted expression starting at pc->p. + * + * Positions the parser at the end of the quoted expression, + * sets pc->tend and possibly pc->missing. + * + * Returns the type of the token of the string, + * either JIM_TT_ESC (if it contains values which need to be [subst]ed) + * or JIM_TT_STR. + */ +static int JimParseSubQuote(struct JimParserCtx *pc) +{ + int tt = JIM_TT_STR; + int line = pc->tline; + + /* Skip the quote */ + pc->p++; + pc->len--; + while (pc->len) { + switch (*pc->p) { + case '\\': + if (pc->len > 1) { + if (*++pc->p == '\n') { + pc->linenr++; + } + pc->len--; + tt = JIM_TT_ESC; + } + break; + + case '"': + pc->tend = pc->p - 1; + pc->p++; + pc->len--; + return tt; + + case '[': + JimParseSubCmd(pc); + tt = JIM_TT_ESC; + continue; + + case '\n': + pc->linenr++; + break; + + case '$': + tt = JIM_TT_ESC; + break; + } + pc->p++; + pc->len--; + } + pc->missing = '"'; + pc->missingline = line; + pc->tend = pc->p - 1; + return tt; +} + +/** + * Parses a [command] expression starting at pc->p. + * + * Positions the parser at the end of the command expression, + * sets pc->tend and possibly pc->missing. + */ +static void JimParseSubCmd(struct JimParserCtx *pc) +{ + int level = 1; + int startofword = 1; + int line = pc->tline; + + /* Skip the bracket */ + pc->p++; + pc->len--; + while (pc->len) { + switch (*pc->p) { + case '\\': + if (pc->len > 1) { + if (*++pc->p == '\n') { + pc->linenr++; + } + pc->len--; + } + break; + + case '[': + level++; + break; + + case ']': + if (--level == 0) { + pc->tend = pc->p - 1; + pc->p++; + pc->len--; + return; + } + break; + + case '"': + if (startofword) { + JimParseSubQuote(pc); + continue; + } + break; + + case '{': + JimParseSubBrace(pc); + startofword = 0; + continue; + + case '\n': + pc->linenr++; + break; + } + startofword = isspace(UCHAR(*pc->p)); + pc->p++; + pc->len--; + } + pc->missing = '['; + pc->missingline = line; + pc->tend = pc->p - 1; +} + +static int JimParseBrace(struct JimParserCtx *pc) +{ + pc->tstart = pc->p + 1; + pc->tline = pc->linenr; + pc->tt = JIM_TT_STR; + JimParseSubBrace(pc); + return JIM_OK; +} + +static int JimParseCmd(struct JimParserCtx *pc) +{ + pc->tstart = pc->p + 1; + pc->tline = pc->linenr; + pc->tt = JIM_TT_CMD; + JimParseSubCmd(pc); + return JIM_OK; +} + +static int JimParseQuote(struct JimParserCtx *pc) +{ + pc->tstart = pc->p + 1; + pc->tline = pc->linenr; + pc->tt = JimParseSubQuote(pc); + return JIM_OK; +} + +static int JimParseVar(struct JimParserCtx *pc) +{ + /* skip the $ */ + pc->p++; + pc->len--; + +#ifdef EXPRSUGAR_BRACKET + if (*pc->p == '[') { + /* Parse $[...] expr shorthand syntax */ + JimParseCmd(pc); + pc->tt = JIM_TT_EXPRSUGAR; + return JIM_OK; + } +#endif + + pc->tstart = pc->p; + pc->tt = JIM_TT_VAR; + pc->tline = pc->linenr; + + if (*pc->p == '{') { + pc->tstart = ++pc->p; + pc->len--; + + while (pc->len && *pc->p != '}') { + if (*pc->p == '\n') { + pc->linenr++; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + if (pc->len) { + pc->p++; + pc->len--; + } + } + else { + while (1) { + /* Skip double colon, but not single colon! */ + if (pc->p[0] == ':' && pc->p[1] == ':') { + while (*pc->p == ':') { + pc->p++; + pc->len--; + } + continue; + } + /* Note that any char >= 0x80 must be part of a utf-8 char. + * We consider all unicode points outside of ASCII as letters + */ + if (isalnum(UCHAR(*pc->p)) || *pc->p == '_' || UCHAR(*pc->p) >= 0x80) { + pc->p++; + pc->len--; + continue; + } + break; + } + /* Parse [dict get] syntax sugar. */ + if (*pc->p == '(') { + int count = 1; + const char *paren = NULL; + + pc->tt = JIM_TT_DICTSUGAR; + + while (count && pc->len) { + pc->p++; + pc->len--; + if (*pc->p == '\\' && pc->len >= 1) { + pc->p++; + pc->len--; + } + else if (*pc->p == '(') { + count++; + } + else if (*pc->p == ')') { + paren = pc->p; + count--; + } + } + if (count == 0) { + pc->p++; + pc->len--; + } + else if (paren) { + /* Did not find a matching paren. Back up */ + paren++; + pc->len += (pc->p - paren); + pc->p = paren; + } +#ifndef EXPRSUGAR_BRACKET + if (*pc->tstart == '(') { + pc->tt = JIM_TT_EXPRSUGAR; + } +#endif + } + pc->tend = pc->p - 1; + } + /* Check if we parsed just the '$' character. + * That's not a variable so an error is returned + * to tell the state machine to consider this '$' just + * a string. */ + if (pc->tstart == pc->p) { + pc->p--; + pc->len++; + return JIM_ERR; + } + return JIM_OK; +} + +static int JimParseStr(struct JimParserCtx *pc) +{ + if (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL || + pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR) { + /* Starting a new word */ + if (*pc->p == '{') { + return JimParseBrace(pc); + } + if (*pc->p == '"') { + pc->state = JIM_PS_QUOTE; + pc->p++; + pc->len--; + /* In case the end quote is missing */ + pc->missingline = pc->tline; + } + } + pc->tstart = pc->p; + pc->tline = pc->linenr; + while (1) { + if (pc->len == 0) { + if (pc->state == JIM_PS_QUOTE) { + pc->missing = '"'; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + } + switch (*pc->p) { + case '\\': + if (pc->state == JIM_PS_DEF && *(pc->p + 1) == '\n') { + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + } + if (pc->len >= 2) { + if (*(pc->p + 1) == '\n') { + pc->linenr++; + } + pc->p++; + pc->len--; + } + break; + case '(': + /* If the following token is not '$' just keep going */ + if (pc->len > 1 && pc->p[1] != '$') { + break; + } + case ')': + /* Only need a separate ')' token if the previous was a var */ + if (*pc->p == '(' || pc->tt == JIM_TT_VAR) { + if (pc->p == pc->tstart) { + /* At the start of the token, so just return this char */ + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + } + break; + + case '$': + case '[': + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + case ' ': + case '\t': + case '\n': + case '\r': + case '\f': + case ';': + if (pc->state == JIM_PS_DEF) { + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + } + else if (*pc->p == '\n') { + pc->linenr++; + } + break; + case '"': + if (pc->state == JIM_PS_QUOTE) { + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + pc->p++; + pc->len--; + pc->state = JIM_PS_DEF; + return JIM_OK; + } + break; + } + pc->p++; + pc->len--; + } + return JIM_OK; /* unreached */ +} + +static int JimParseComment(struct JimParserCtx *pc) +{ + while (*pc->p) { + if (*pc->p == '\n') { + pc->linenr++; + if (*(pc->p - 1) != '\\') { + pc->p++; + pc->len--; + return JIM_OK; + } + } + pc->p++; + pc->len--; + } + return JIM_OK; +} + +/* xdigitval and odigitval are helper functions for JimEscape() */ +static int xdigitval(int c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int odigitval(int c) +{ + if (c >= '0' && c <= '7') + return c - '0'; + return -1; +} + +/* Perform Tcl escape substitution of 's', storing the result + * string into 'dest'. The escaped string is guaranteed to + * be the same length or shorted than the source string. + * Slen is the length of the string at 's', if it's -1 the string + * length will be calculated by the function. + * + * The function returns the length of the resulting string. */ +static int JimEscape(char *dest, const char *s, int slen) +{ + char *p = dest; + int i, len; + + if (slen == -1) + slen = strlen(s); + + for (i = 0; i < slen; i++) { + switch (s[i]) { + case '\\': + switch (s[i + 1]) { + case 'a': + *p++ = 0x7; + i++; + break; + case 'b': + *p++ = 0x8; + i++; + break; + case 'f': + *p++ = 0xc; + i++; + break; + case 'n': + *p++ = 0xa; + i++; + break; + case 'r': + *p++ = 0xd; + i++; + break; + case 't': + *p++ = 0x9; + i++; + break; + case 'u': + case 'U': + case 'x': + /* A unicode or hex sequence. + * \x Expect 1-2 hex chars and convert to hex. + * \u Expect 1-4 hex chars and convert to utf-8. + * \U Expect 1-8 hex chars and convert to utf-8. + * \u{NNN} supports 1-6 hex chars and convert to utf-8. + * An invalid sequence means simply the escaped char. + */ + { + unsigned val = 0; + int k; + int maxchars = 2; + + i++; + + if (s[i] == 'U') { + maxchars = 8; + } + else if (s[i] == 'u') { + if (s[i + 1] == '{') { + maxchars = 6; + i++; + } + else { + maxchars = 4; + } + } + + for (k = 0; k < maxchars; k++) { + int c = xdigitval(s[i + k + 1]); + if (c == -1) { + break; + } + val = (val << 4) | c; + } + /* The \u{nnn} syntax supports up to 21 bit codepoints. */ + if (s[i] == '{') { + if (k == 0 || val > 0x1fffff || s[i + k + 1] != '}') { + /* Back up */ + i--; + k = 0; + } + else { + /* Skip the closing brace */ + k++; + } + } + if (k) { + /* Got a valid sequence, so convert */ + if (s[i] == 'x') { + *p++ = val; + } + else { + p += utf8_fromunicode(p, val); + } + i += k; + break; + } + /* Not a valid codepoint, just an escaped char */ + *p++ = s[i]; + } + break; + case 'v': + *p++ = 0xb; + i++; + break; + case '\0': + *p++ = '\\'; + i++; + break; + case '\n': + /* Replace all spaces and tabs after backslash newline with a single space*/ + *p++ = ' '; + do { + i++; + } while (s[i + 1] == ' ' || s[i + 1] == '\t'); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + /* octal escape */ + { + int val = 0; + int c = odigitval(s[i + 1]); + + val = c; + c = odigitval(s[i + 2]); + if (c == -1) { + *p++ = val; + i++; + break; + } + val = (val * 8) + c; + c = odigitval(s[i + 3]); + if (c == -1) { + *p++ = val; + i += 2; + break; + } + val = (val * 8) + c; + *p++ = val; + i += 3; + } + break; + default: + *p++ = s[i + 1]; + i++; + break; + } + break; + default: + *p++ = s[i]; + break; + } + } + len = p - dest; + *p = '\0'; + return len; +} + +/* Returns a dynamically allocated copy of the current token in the + * parser context. The function performs conversion of escapes if + * the token is of type JIM_TT_ESC. + * + * Note that after the conversion, tokens that are grouped with + * braces in the source code, are always recognizable from the + * identical string obtained in a different way from the type. + * + * For example the string: + * + * {*}$a + * + * will return as first token "*", of type JIM_TT_STR + * + * While the string: + * + * *$a + * + * will return as first token "*", of type JIM_TT_ESC + */ +static Jim_Obj *JimParserGetTokenObj(Jim_Interp *interp, struct JimParserCtx *pc) +{ + const char *start, *end; + char *token; + int len; + + start = pc->tstart; + end = pc->tend; + if (start > end) { + len = 0; + token = Jim_Alloc(1); + token[0] = '\0'; + } + else { + len = (end - start) + 1; + token = Jim_Alloc(len + 1); + if (pc->tt != JIM_TT_ESC) { + /* No escape conversion needed? Just copy it. */ + memcpy(token, start, len); + token[len] = '\0'; + } + else { + /* Else convert the escape chars. */ + len = JimEscape(token, start, len); + } + } + + return Jim_NewStringObjNoAlloc(interp, token, len); +} + +/* Parses the given string to determine if it represents a complete script. + * + * This is useful for interactive shells implementation, for [info complete]. + * + * If 'stateCharPtr' != NULL, the function stores ' ' on complete script, + * '{' on scripts incomplete missing one or more '}' to be balanced. + * '[' on scripts incomplete missing one or more ']' to be balanced. + * '"' on scripts incomplete missing a '"' char. + * + * If the script is complete, 1 is returned, otherwise 0. + */ +int Jim_ScriptIsComplete(const char *s, int len, char *stateCharPtr) +{ + struct JimParserCtx parser; + + JimParserInit(&parser, s, len, 1); + while (!parser.eof) { + JimParseScript(&parser); + } + if (stateCharPtr) { + *stateCharPtr = parser.missing; + } + return parser.missing == ' '; +} + +/* ----------------------------------------------------------------------------- + * Tcl Lists parsing + * ---------------------------------------------------------------------------*/ +static int JimParseListSep(struct JimParserCtx *pc); +static int JimParseListStr(struct JimParserCtx *pc); +static int JimParseListQuote(struct JimParserCtx *pc); + +static int JimParseList(struct JimParserCtx *pc) +{ + if (isspace(UCHAR(*pc->p))) { + return JimParseListSep(pc); + } + switch (*pc->p) { + case '"': + return JimParseListQuote(pc); + + case '{': + return JimParseBrace(pc); + + default: + if (pc->len) { + return JimParseListStr(pc); + } + break; + } + + pc->tstart = pc->tend = pc->p; + pc->tline = pc->linenr; + pc->tt = JIM_TT_EOL; + pc->eof = 1; + return JIM_OK; +} + +static int JimParseListSep(struct JimParserCtx *pc) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + while (isspace(UCHAR(*pc->p))) { + if (*pc->p == '\n') { + pc->linenr++; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_SEP; + return JIM_OK; +} + +static int JimParseListQuote(struct JimParserCtx *pc) +{ + pc->p++; + pc->len--; + + pc->tstart = pc->p; + pc->tline = pc->linenr; + pc->tt = JIM_TT_STR; + + while (pc->len) { + switch (*pc->p) { + case '\\': + pc->tt = JIM_TT_ESC; + if (--pc->len == 0) { + /* Trailing backslash */ + pc->tend = pc->p; + return JIM_OK; + } + pc->p++; + break; + case '\n': + pc->linenr++; + break; + case '"': + pc->tend = pc->p - 1; + pc->p++; + pc->len--; + return JIM_OK; + } + pc->p++; + pc->len--; + } + + pc->tend = pc->p - 1; + return JIM_OK; +} + +static int JimParseListStr(struct JimParserCtx *pc) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + pc->tt = JIM_TT_STR; + + while (pc->len) { + if (isspace(UCHAR(*pc->p))) { + pc->tend = pc->p - 1; + return JIM_OK; + } + if (*pc->p == '\\') { + if (--pc->len == 0) { + /* Trailing backslash */ + pc->tend = pc->p; + return JIM_OK; + } + pc->tt = JIM_TT_ESC; + pc->p++; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + return JIM_OK; +} + +/* ----------------------------------------------------------------------------- + * Jim_Obj related functions + * ---------------------------------------------------------------------------*/ + +/* Return a new initialized object. */ +Jim_Obj *Jim_NewObj(Jim_Interp *interp) +{ + Jim_Obj *objPtr; + + /* -- Check if there are objects in the free list -- */ + if (interp->freeList != NULL) { + /* -- Unlink the object from the free list -- */ + objPtr = interp->freeList; + interp->freeList = objPtr->nextObjPtr; + } + else { + /* -- No ready to use objects: allocate a new one -- */ + objPtr = Jim_Alloc(sizeof(*objPtr)); + } + + /* Object is returned with refCount of 0. Every + * kind of GC implemented should take care to don't try + * to scan objects with refCount == 0. */ + objPtr->refCount = 0; + /* All the other fields are left not initialized to save time. + * The caller will probably want to set them to the right + * value anyway. */ + + /* -- Put the object into the live list -- */ + objPtr->prevObjPtr = NULL; + objPtr->nextObjPtr = interp->liveList; + if (interp->liveList) + interp->liveList->prevObjPtr = objPtr; + interp->liveList = objPtr; + + return objPtr; +} + +/* Free an object. Actually objects are never freed, but + * just moved to the free objects list, where they will be + * reused by Jim_NewObj(). */ +void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr) +{ + /* Check if the object was already freed, panic. */ + JimPanic((objPtr->refCount != 0, "!!!Object %p freed with bad refcount %d, type=%s", objPtr, + objPtr->refCount, objPtr->typePtr ? objPtr->typePtr->name : "")); + + /* Free the internal representation */ + Jim_FreeIntRep(interp, objPtr); + /* Free the string representation */ + if (objPtr->bytes != NULL) { + if (objPtr->bytes != JimEmptyStringRep) + Jim_Free(objPtr->bytes); + } + /* Unlink the object from the live objects list */ + if (objPtr->prevObjPtr) + objPtr->prevObjPtr->nextObjPtr = objPtr->nextObjPtr; + if (objPtr->nextObjPtr) + objPtr->nextObjPtr->prevObjPtr = objPtr->prevObjPtr; + if (interp->liveList == objPtr) + interp->liveList = objPtr->nextObjPtr; + /* Link the object into the free objects list */ + objPtr->prevObjPtr = NULL; + objPtr->nextObjPtr = interp->freeList; + if (interp->freeList) + interp->freeList->prevObjPtr = objPtr; + interp->freeList = objPtr; + objPtr->refCount = -1; +} + +/* Invalidate the string representation of an object. */ +void Jim_InvalidateStringRep(Jim_Obj *objPtr) +{ + if (objPtr->bytes != NULL) { + if (objPtr->bytes != JimEmptyStringRep) + Jim_Free(objPtr->bytes); + } + objPtr->bytes = NULL; +} + +/* Duplicate an object. The returned object has refcount = 0. */ +Jim_Obj *Jim_DuplicateObj(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_Obj *dupPtr; + + dupPtr = Jim_NewObj(interp); + if (objPtr->bytes == NULL) { + /* Object does not have a valid string representation. */ + dupPtr->bytes = NULL; + } + else if (objPtr->length == 0) { + /* Zero length, so don't even bother with the type-specific dup, since all zero length objects look the same */ + dupPtr->bytes = JimEmptyStringRep; + dupPtr->length = 0; + dupPtr->typePtr = NULL; + return dupPtr; + } + else { + dupPtr->bytes = Jim_Alloc(objPtr->length + 1); + dupPtr->length = objPtr->length; + /* Copy the null byte too */ + memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1); + } + + /* By default, the new object has the same type as the old object */ + dupPtr->typePtr = objPtr->typePtr; + if (objPtr->typePtr != NULL) { + if (objPtr->typePtr->dupIntRepProc == NULL) { + dupPtr->internalRep = objPtr->internalRep; + } + else { + /* The dup proc may set a different type, e.g. NULL */ + objPtr->typePtr->dupIntRepProc(interp, objPtr, dupPtr); + } + } + return dupPtr; +} + +/* Return the string representation for objPtr. If the object + * string representation is invalid, calls the method to create + * a new one starting from the internal representation of the object. */ +const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr) +{ + if (objPtr->bytes == NULL) { + /* Invalid string repr. Generate it. */ + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); + objPtr->typePtr->updateStringProc(objPtr); + } + if (lenPtr) + *lenPtr = objPtr->length; + return objPtr->bytes; +} + +/* Just returns the length of the object's string rep */ +int Jim_Length(Jim_Obj *objPtr) +{ + if (objPtr->bytes == NULL) { + /* Invalid string repr. Generate it. */ + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); + objPtr->typePtr->updateStringProc(objPtr); + } + return objPtr->length; +} + +/* Just returns the length of the object's string rep */ +const char *Jim_String(Jim_Obj *objPtr) +{ + if (objPtr->bytes == NULL) { + /* Invalid string repr. Generate it. */ + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); + objPtr->typePtr->updateStringProc(objPtr); + } + return objPtr->bytes; +} + +static void FreeDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); + +static const Jim_ObjType dictSubstObjType = { + "dict-substitution", + FreeDictSubstInternalRep, + DupDictSubstInternalRep, + NULL, + JIM_TYPE_NONE, +}; + +static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr); +} + +static const Jim_ObjType interpolatedObjType = { + "interpolated", + FreeInterpolatedInternalRep, + NULL, + NULL, + JIM_TYPE_NONE, +}; + +/* ----------------------------------------------------------------------------- + * String Object + * ---------------------------------------------------------------------------*/ +static void DupStringInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static int SetStringFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType stringObjType = { + "string", + NULL, + DupStringInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + +static void DupStringInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + JIM_NOTUSED(interp); + + /* This is a bit subtle: the only caller of this function + * should be Jim_DuplicateObj(), that will copy the + * string representaion. After the copy, the duplicated + * object will not have more room in teh buffer than + * srcPtr->length bytes. So we just set it to length. */ + dupPtr->internalRep.strValue.maxLength = srcPtr->length; + + dupPtr->internalRep.strValue.charLength = srcPtr->internalRep.strValue.charLength; +} + +static int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr->typePtr != &stringObjType) { + /* Get a fresh string representation. */ + if (objPtr->bytes == NULL) { + /* Invalid string repr. Generate it. */ + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); + objPtr->typePtr->updateStringProc(objPtr); + } + /* Free any other internal representation. */ + Jim_FreeIntRep(interp, objPtr); + /* Set it as string, i.e. just set the maxLength field. */ + objPtr->typePtr = &stringObjType; + objPtr->internalRep.strValue.maxLength = objPtr->length; + /* Don't know the utf-8 length yet */ + objPtr->internalRep.strValue.charLength = -1; + } + return JIM_OK; +} + +/** + * Returns the length of the object string in chars, not bytes. + * + * These may be different for a utf-8 string. + */ +int Jim_Utf8Length(Jim_Interp *interp, Jim_Obj *objPtr) +{ +#ifdef JIM_UTF8 + SetStringFromAny(interp, objPtr); + + if (objPtr->internalRep.strValue.charLength < 0) { + objPtr->internalRep.strValue.charLength = utf8_strlen(objPtr->bytes, objPtr->length); + } + return objPtr->internalRep.strValue.charLength; +#else + return Jim_Length(objPtr); +#endif +} + +/* len is in bytes -- see also Jim_NewStringObjUtf8() */ +Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len) +{ + Jim_Obj *objPtr = Jim_NewObj(interp); + + /* Need to find out how many bytes the string requires */ + if (len == -1) + len = strlen(s); + /* Alloc/Set the string rep. */ + if (len == 0) { + objPtr->bytes = JimEmptyStringRep; + objPtr->length = 0; + } + else { + objPtr->bytes = Jim_Alloc(len + 1); + objPtr->length = len; + memcpy(objPtr->bytes, s, len); + objPtr->bytes[len] = '\0'; + } + + /* No typePtr field for the vanilla string object. */ + objPtr->typePtr = NULL; + return objPtr; +} + +/* charlen is in characters -- see also Jim_NewStringObj() */ +Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, const char *s, int charlen) +{ +#ifdef JIM_UTF8 + /* Need to find out how many bytes the string requires */ + int bytelen = utf8_index(s, charlen); + + Jim_Obj *objPtr = Jim_NewStringObj(interp, s, bytelen); + + /* Remember the utf8 length, so set the type */ + objPtr->typePtr = &stringObjType; + objPtr->internalRep.strValue.maxLength = bytelen; + objPtr->internalRep.strValue.charLength = charlen; + + return objPtr; +#else + return Jim_NewStringObj(interp, s, charlen); +#endif +} + +/* This version does not try to duplicate the 's' pointer, but + * use it directly. */ +Jim_Obj *Jim_NewStringObjNoAlloc(Jim_Interp *interp, char *s, int len) +{ + Jim_Obj *objPtr = Jim_NewObj(interp); + + objPtr->bytes = s; + objPtr->length = len == -1 ? strlen(s) : len; + objPtr->typePtr = NULL; + return objPtr; +} + +/* Low-level string append. Use it only against objects + * of type "string". */ +static void StringAppendString(Jim_Obj *objPtr, const char *str, int len) +{ + int needlen; + + if (len == -1) + len = strlen(str); + needlen = objPtr->length + len; + if (objPtr->internalRep.strValue.maxLength < needlen || + objPtr->internalRep.strValue.maxLength == 0) { + needlen *= 2; + /* Inefficient to malloc() for less than 8 bytes */ + if (needlen < 7) { + needlen = 7; + } + if (objPtr->bytes == JimEmptyStringRep) { + objPtr->bytes = Jim_Alloc(needlen + 1); + } + else { + objPtr->bytes = Jim_Realloc(objPtr->bytes, needlen + 1); + } + objPtr->internalRep.strValue.maxLength = needlen; + } + memcpy(objPtr->bytes + objPtr->length, str, len); + objPtr->bytes[objPtr->length + len] = '\0'; + if (objPtr->internalRep.strValue.charLength >= 0) { + /* Update the utf-8 char length */ + objPtr->internalRep.strValue.charLength += utf8_strlen(objPtr->bytes + objPtr->length, len); + } + objPtr->length += len; +} + +/* Higher level API to append strings to objects. */ +void Jim_AppendString(Jim_Interp *interp, Jim_Obj *objPtr, const char *str, int len) +{ + JimPanic((Jim_IsShared(objPtr), "Jim_AppendString called with shared object")); + SetStringFromAny(interp, objPtr); + StringAppendString(objPtr, str, len); +} + +void Jim_AppendObj(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *appendObjPtr) +{ + int len; + const char *str; + + str = Jim_GetString(appendObjPtr, &len); + Jim_AppendString(interp, objPtr, str, len); +} + +void Jim_AppendStrings(Jim_Interp *interp, Jim_Obj *objPtr, ...) +{ + va_list ap; + + SetStringFromAny(interp, objPtr); + va_start(ap, objPtr); + while (1) { + char *s = va_arg(ap, char *); + + if (s == NULL) + break; + Jim_AppendString(interp, objPtr, s, -1); + } + va_end(ap); +} + +int Jim_StringEqObj(Jim_Obj *aObjPtr, Jim_Obj *bObjPtr) +{ + const char *aStr, *bStr; + int aLen, bLen; + + if (aObjPtr == bObjPtr) + return 1; + aStr = Jim_GetString(aObjPtr, &aLen); + bStr = Jim_GetString(bObjPtr, &bLen); + if (aLen != bLen) + return 0; + return JimStringCompare(aStr, aLen, bStr, bLen) == 0; +} + +int Jim_StringMatchObj(Jim_Interp *interp, Jim_Obj *patternObjPtr, Jim_Obj *objPtr, int nocase) +{ + return JimGlobMatch(Jim_String(patternObjPtr), Jim_String(objPtr), nocase); +} + +int Jim_StringCompareObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *secondObjPtr, int nocase) +{ + int l1, l2; + const char *s1 = Jim_GetString(firstObjPtr, &l1); + const char *s2 = Jim_GetString(secondObjPtr, &l2); + + if (nocase) { + /* Do a character compare for nocase */ + return JimStringCompareLen(s1, s2, -1, nocase); + } + return JimStringCompare(s1, l1, s2, l2); +} + +/** + * Like Jim_StringCompareObj() except compares to a maximum of the length of firstObjPtr. + */ +int Jim_StringCompareLenObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *secondObjPtr, int nocase) +{ + const char *s1 = Jim_String(firstObjPtr); + const char *s2 = Jim_String(secondObjPtr); + + return JimStringCompareLen(s1, s2, Jim_Utf8Length(interp, firstObjPtr), nocase); +} + +/* Convert a range, as returned by Jim_GetRange(), into + * an absolute index into an object of the specified length. + * This function may return negative values, or values + * bigger or equal to the length of the list if the index + * is out of range. */ +static int JimRelToAbsIndex(int len, int idx) +{ + if (idx < 0) + return len + idx; + return idx; +} + +/* Convert a pair of index (*firstPtr, *lastPtr) as normalized by JimRelToAbsIndex(), + * into form suitable for implementation of commands like [string range] and [lrange]. + * + * The resulting range is guaranteed to address valid elements of + * the structure. + * + */ +static void JimRelToAbsRange(int len, int *firstPtr, int *lastPtr, int *rangeLenPtr) +{ + int rangeLen; + + if (*firstPtr > *lastPtr) { + rangeLen = 0; + } + else { + rangeLen = *lastPtr - *firstPtr + 1; + if (rangeLen) { + if (*firstPtr < 0) { + rangeLen += *firstPtr; + *firstPtr = 0; + } + if (*lastPtr >= len) { + rangeLen -= (*lastPtr - (len - 1)); + *lastPtr = len - 1; + } + } + } + if (rangeLen < 0) + rangeLen = 0; + + *rangeLenPtr = rangeLen; +} + +static int JimStringGetRange(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr, + int len, int *first, int *last, int *range) +{ + if (Jim_GetIndex(interp, firstObjPtr, first) != JIM_OK) { + return JIM_ERR; + } + if (Jim_GetIndex(interp, lastObjPtr, last) != JIM_OK) { + return JIM_ERR; + } + *first = JimRelToAbsIndex(len, *first); + *last = JimRelToAbsIndex(len, *last); + JimRelToAbsRange(len, first, last, range); + return JIM_OK; +} + +Jim_Obj *Jim_StringByteRangeObj(Jim_Interp *interp, + Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr) +{ + int first, last; + const char *str; + int rangeLen; + int bytelen; + + str = Jim_GetString(strObjPtr, &bytelen); + + if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, bytelen, &first, &last, &rangeLen) != JIM_OK) { + return NULL; + } + + if (first == 0 && rangeLen == bytelen) { + return strObjPtr; + } + return Jim_NewStringObj(interp, str + first, rangeLen); +} + +Jim_Obj *Jim_StringRangeObj(Jim_Interp *interp, + Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr) +{ +#ifdef JIM_UTF8 + int first, last; + const char *str; + int len, rangeLen; + int bytelen; + + str = Jim_GetString(strObjPtr, &bytelen); + len = Jim_Utf8Length(interp, strObjPtr); + + if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, len, &first, &last, &rangeLen) != JIM_OK) { + return NULL; + } + + if (first == 0 && rangeLen == len) { + return strObjPtr; + } + if (len == bytelen) { + /* ASCII optimisation */ + return Jim_NewStringObj(interp, str + first, rangeLen); + } + return Jim_NewStringObjUtf8(interp, str + utf8_index(str, first), rangeLen); +#else + return Jim_StringByteRangeObj(interp, strObjPtr, firstObjPtr, lastObjPtr); +#endif +} + +Jim_Obj *JimStringReplaceObj(Jim_Interp *interp, + Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr, Jim_Obj *newStrObj) +{ + int first, last; + const char *str; + int len, rangeLen; + Jim_Obj *objPtr; + + len = Jim_Utf8Length(interp, strObjPtr); + + if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, len, &first, &last, &rangeLen) != JIM_OK) { + return NULL; + } + + if (last < first) { + return strObjPtr; + } + + str = Jim_String(strObjPtr); + + /* Before part */ + objPtr = Jim_NewStringObjUtf8(interp, str, first); + + /* Replacement */ + if (newStrObj) { + Jim_AppendObj(interp, objPtr, newStrObj); + } + + /* After part */ + Jim_AppendString(interp, objPtr, str + utf8_index(str, last + 1), len - last - 1); + + return objPtr; +} + +static void JimStrCopyUpperLower(char *dest, const char *str, int uc) +{ + while (*str) { + int c; + str += utf8_tounicode(str, &c); + dest += utf8_fromunicode(dest, uc ? utf8_upper(c) : utf8_lower(c)); + } + *dest = 0; +} + +static Jim_Obj *JimStringToLower(Jim_Interp *interp, Jim_Obj *strObjPtr) +{ + char *buf; + int len; + const char *str; + + SetStringFromAny(interp, strObjPtr); + + str = Jim_GetString(strObjPtr, &len); + +#ifdef JIM_UTF8 + /* Case mapping can change the utf-8 length of the string. + * But at worst it will be by one extra byte per char + */ + len *= 2; +#endif + buf = Jim_Alloc(len + 1); + JimStrCopyUpperLower(buf, str, 0); + return Jim_NewStringObjNoAlloc(interp, buf, -1); +} + +static Jim_Obj *JimStringToUpper(Jim_Interp *interp, Jim_Obj *strObjPtr) +{ + char *buf; + const char *str; + int len; + + if (strObjPtr->typePtr != &stringObjType) { + SetStringFromAny(interp, strObjPtr); + } + + str = Jim_GetString(strObjPtr, &len); + +#ifdef JIM_UTF8 + /* Case mapping can change the utf-8 length of the string. + * But at worst it will be by one extra byte per char + */ + len *= 2; +#endif + buf = Jim_Alloc(len + 1); + JimStrCopyUpperLower(buf, str, 1); + return Jim_NewStringObjNoAlloc(interp, buf, -1); +} + +static Jim_Obj *JimStringToTitle(Jim_Interp *interp, Jim_Obj *strObjPtr) +{ + char *buf, *p; + int len; + int c; + const char *str; + + str = Jim_GetString(strObjPtr, &len); + if (len == 0) { + return strObjPtr; + } +#ifdef JIM_UTF8 + /* Case mapping can change the utf-8 length of the string. + * But at worst it will be by one extra byte per char + */ + len *= 2; +#endif + buf = p = Jim_Alloc(len + 1); + + str += utf8_tounicode(str, &c); + p += utf8_fromunicode(p, utf8_title(c)); + + JimStrCopyUpperLower(p, str, 0); + + return Jim_NewStringObjNoAlloc(interp, buf, -1); +} + +/* Similar to memchr() except searches a UTF-8 string 'str' of byte length 'len' + * for unicode character 'c'. + * Returns the position if found or NULL if not + */ +static const char *utf8_memchr(const char *str, int len, int c) +{ +#ifdef JIM_UTF8 + while (len) { + int sc; + int n = utf8_tounicode(str, &sc); + if (sc == c) { + return str; + } + str += n; + len -= n; + } + return NULL; +#else + return memchr(str, c, len); +#endif +} + +/** + * Searches for the first non-trim char in string (str, len) + * + * If none is found, returns just past the last char. + * + * Lengths are in bytes. + */ +static const char *JimFindTrimLeft(const char *str, int len, const char *trimchars, int trimlen) +{ + while (len) { + int c; + int n = utf8_tounicode(str, &c); + + if (utf8_memchr(trimchars, trimlen, c) == NULL) { + /* Not a trim char, so stop */ + break; + } + str += n; + len -= n; + } + return str; +} + +/** + * Searches backwards for a non-trim char in string (str, len). + * + * Returns a pointer to just after the non-trim char, or NULL if not found. + * + * Lengths are in bytes. + */ +static const char *JimFindTrimRight(const char *str, int len, const char *trimchars, int trimlen) +{ + str += len; + + while (len) { + int c; + int n = utf8_prev_len(str, len); + + len -= n; + str -= n; + + n = utf8_tounicode(str, &c); + + if (utf8_memchr(trimchars, trimlen, c) == NULL) { + return str + n; + } + } + + return NULL; +} + +static const char default_trim_chars[] = " \t\n\r"; +/* sizeof() here includes the null byte */ +static int default_trim_chars_len = sizeof(default_trim_chars); + +static Jim_Obj *JimStringTrimLeft(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr) +{ + int len; + const char *str = Jim_GetString(strObjPtr, &len); + const char *trimchars = default_trim_chars; + int trimcharslen = default_trim_chars_len; + const char *newstr; + + if (trimcharsObjPtr) { + trimchars = Jim_GetString(trimcharsObjPtr, &trimcharslen); + } + + newstr = JimFindTrimLeft(str, len, trimchars, trimcharslen); + if (newstr == str) { + return strObjPtr; + } + + return Jim_NewStringObj(interp, newstr, len - (newstr - str)); +} + +static Jim_Obj *JimStringTrimRight(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr) +{ + int len; + const char *trimchars = default_trim_chars; + int trimcharslen = default_trim_chars_len; + const char *nontrim; + + if (trimcharsObjPtr) { + trimchars = Jim_GetString(trimcharsObjPtr, &trimcharslen); + } + + SetStringFromAny(interp, strObjPtr); + + len = Jim_Length(strObjPtr); + nontrim = JimFindTrimRight(strObjPtr->bytes, len, trimchars, trimcharslen); + + if (nontrim == NULL) { + /* All trim, so return a zero-length string */ + return Jim_NewEmptyStringObj(interp); + } + if (nontrim == strObjPtr->bytes + len) { + return strObjPtr; + } + + if (Jim_IsShared(strObjPtr)) { + strObjPtr = Jim_NewStringObj(interp, strObjPtr->bytes, (nontrim - strObjPtr->bytes)); + } + else { + /* Can modify this string in place */ + strObjPtr->bytes[nontrim - strObjPtr->bytes] = 0; + strObjPtr->length = (nontrim - strObjPtr->bytes); + } + + return strObjPtr; +} + +static Jim_Obj *JimStringTrim(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr) +{ + /* First trim left. */ + Jim_Obj *objPtr = JimStringTrimLeft(interp, strObjPtr, trimcharsObjPtr); + + /* Now trim right */ + strObjPtr = JimStringTrimRight(interp, objPtr, trimcharsObjPtr); + + if (objPtr != strObjPtr) { + /* Note that we don't want this object to be leaked */ + Jim_IncrRefCount(objPtr); + Jim_DecrRefCount(interp, objPtr); + } + + return strObjPtr; +} + + +static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass, int strict) +{ + static const char * const strclassnames[] = { + "integer", "alpha", "alnum", "ascii", "digit", + "double", "lower", "upper", "space", "xdigit", + "control", "print", "graph", "punct", + NULL + }; + enum { + STR_IS_INTEGER, STR_IS_ALPHA, STR_IS_ALNUM, STR_IS_ASCII, STR_IS_DIGIT, + STR_IS_DOUBLE, STR_IS_LOWER, STR_IS_UPPER, STR_IS_SPACE, STR_IS_XDIGIT, + STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT + }; + int strclass; + int len; + int i; + const char *str; + int (*isclassfunc)(int c) = NULL; + + if (Jim_GetEnum(interp, strClass, strclassnames, &strclass, "class", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + + str = Jim_GetString(strObjPtr, &len); + if (len == 0) { + Jim_SetResultInt(interp, !strict); + return JIM_OK; + } + + switch (strclass) { + case STR_IS_INTEGER: + { + jim_wide w; + Jim_SetResultInt(interp, JimGetWideNoErr(interp, strObjPtr, &w) == JIM_OK); + return JIM_OK; + } + + case STR_IS_DOUBLE: + { + double d; + Jim_SetResultInt(interp, Jim_GetDouble(interp, strObjPtr, &d) == JIM_OK && errno != ERANGE); + return JIM_OK; + } + + case STR_IS_ALPHA: isclassfunc = isalpha; break; + case STR_IS_ALNUM: isclassfunc = isalnum; break; + case STR_IS_ASCII: isclassfunc = isascii; break; + case STR_IS_DIGIT: isclassfunc = isdigit; break; + case STR_IS_LOWER: isclassfunc = islower; break; + case STR_IS_UPPER: isclassfunc = isupper; break; + case STR_IS_SPACE: isclassfunc = isspace; break; + case STR_IS_XDIGIT: isclassfunc = isxdigit; break; + case STR_IS_CONTROL: isclassfunc = iscntrl; break; + case STR_IS_PRINT: isclassfunc = isprint; break; + case STR_IS_GRAPH: isclassfunc = isgraph; break; + case STR_IS_PUNCT: isclassfunc = ispunct; break; + default: + return JIM_ERR; + } + + for (i = 0; i < len; i++) { + if (!isclassfunc(str[i])) { + Jim_SetResultInt(interp, 0); + return JIM_OK; + } + } + Jim_SetResultInt(interp, 1); + return JIM_OK; +} + +/* ----------------------------------------------------------------------------- + * Compared String Object + * ---------------------------------------------------------------------------*/ + +/* This is strange object that allows to compare a C literal string + * with a Jim object in very short time if the same comparison is done + * multiple times. For example every time the [if] command is executed, + * Jim has to check if a given argument is "else". This comparions if + * the code has no errors are true most of the times, so we can cache + * inside the object the pointer of the string of the last matching + * comparison. Because most C compilers perform literal sharing, + * so that: char *x = "foo", char *y = "foo", will lead to x == y, + * this works pretty well even if comparisons are at different places + * inside the C code. */ + +static const Jim_ObjType comparedStringObjType = { + "compared-string", + NULL, + NULL, + NULL, + JIM_TYPE_REFERENCES, +}; + +/* The only way this object is exposed to the API is via the following + * function. Returns true if the string and the object string repr. + * are the same, otherwise zero is returned. + * + * Note: this isn't binary safe, but it hardly needs to be.*/ +int Jim_CompareStringImmediate(Jim_Interp *interp, Jim_Obj *objPtr, const char *str) +{ + if (objPtr->typePtr == &comparedStringObjType && objPtr->internalRep.ptr == str) + return 1; + else { + const char *objStr = Jim_String(objPtr); + + if (strcmp(str, objStr) != 0) + return 0; + if (objPtr->typePtr != &comparedStringObjType) { + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &comparedStringObjType; + } + objPtr->internalRep.ptr = (char *)str; /*ATTENTION: const cast */ + return 1; + } +} + +static int qsortCompareStringPointers(const void *a, const void *b) +{ + char *const *sa = (char *const *)a; + char *const *sb = (char *const *)b; + + return strcmp(*sa, *sb); +} + + +/* ----------------------------------------------------------------------------- + * Source Object + * + * This object is just a string from the language point of view, but + * in the internal representation it contains the filename and line number + * where this given token was read. This information is used by + * Jim_EvalObj() if the object passed happens to be of type "source". + * + * This allows to propagate the information about line numbers and file + * names and give error messages with absolute line numbers. + * + * Note that this object uses shared strings for filenames, and the + * pointer to the filename together with the line number is taken into + * the space for the "inline" internal representation of the Jim_Object, + * so there is almost memory zero-overhead. + * + * Also the object will be converted to something else if the given + * token it represents in the source file is not something to be + * evaluated (not a script), and will be specialized in some other way, + * so the time overhead is also null. + * ---------------------------------------------------------------------------*/ + +static void FreeSourceInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupSourceInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); + +static const Jim_ObjType sourceObjType = { + "source", + FreeSourceInternalRep, + DupSourceInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + +void FreeSourceInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.sourceValue.fileNameObj); +} + +void DupSourceInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + dupPtr->internalRep.sourceValue = srcPtr->internalRep.sourceValue; + Jim_IncrRefCount(dupPtr->internalRep.sourceValue.fileNameObj); +} + +static void JimSetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *fileNameObj, int lineNumber) +{ + JimPanic((Jim_IsShared(objPtr), "JimSetSourceInfo called with shared object")); + JimPanic((objPtr->typePtr == &sourceObjType, "JimSetSourceInfo called with non-source object")); + Jim_IncrRefCount(fileNameObj); + objPtr->internalRep.sourceValue.fileNameObj = fileNameObj; + objPtr->internalRep.sourceValue.lineNumber = lineNumber; + objPtr->typePtr = &sourceObjType; +} + +/* ----------------------------------------------------------------------------- + * Script Object + * ---------------------------------------------------------------------------*/ + +static const Jim_ObjType scriptLineObjType = { + "scriptline", + NULL, + NULL, + NULL, + 0, +}; + +static Jim_Obj *JimNewScriptLineObj(Jim_Interp *interp, int argc, int line) +{ + Jim_Obj *objPtr; + +#ifdef DEBUG_SHOW_SCRIPT + char buf[100]; + snprintf(buf, sizeof(buf), "line=%d, argc=%d", line, argc); + objPtr = Jim_NewStringObj(interp, buf, -1); +#else + objPtr = Jim_NewEmptyStringObj(interp); +#endif + objPtr->typePtr = &scriptLineObjType; + objPtr->internalRep.scriptLineValue.argc = argc; + objPtr->internalRep.scriptLineValue.line = line; + + return objPtr; +} + +#define JIM_CMDSTRUCT_EXPAND -1 + +static void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static int SetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, struct JimParseResult *result); + +static const Jim_ObjType scriptObjType = { + "script", + FreeScriptInternalRep, + DupScriptInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + +/* The ScriptToken structure represents every token into a scriptObj. + * Every token contains an associated Jim_Obj that can be specialized + * by commands operating on it. */ +typedef struct ScriptToken +{ + int type; + Jim_Obj *objPtr; +} ScriptToken; + +/* This is the script object internal representation. An array of + * ScriptToken structures, including a pre-computed representation of the + * command length and arguments. + * + * For example the script: + * + * puts hello + * set $i $x$y [foo]BAR + * + * will produce a ScriptObj with the following Tokens: + * + * LIN 2 + * ESC puts + * ESC hello + * LIN 4 + * ESC set + * VAR i + * WRD 2 + * VAR x + * VAR y + * WRD 2 + * CMD foo + * ESC BAR + * + * "puts hello" has two args (LIN 2), composed of single tokens. + * (Note that the WRD token is omitted for the common case of a single token.) + * + * "set $i $x$y [foo]BAR" has four (LIN 4) args, the first word + * has 1 token (ESC SET), and the last has two tokens (WRD 2 CMD foo ESC BAR) + * + * The precomputation of the command structure makes Jim_Eval() faster, + * and simpler because there aren't dynamic lengths / allocations. + * + * -- {expand}/{*} handling -- + * + * Expand is handled in a special way. + * + * If a "word" begins with {*}, the word token count is -ve. + * + * For example the command: + * + * list {*}{a b} + * + * Will produce the following cmdstruct array: + * + * LIN 2 + * ESC list + * WRD -1 + * STR a b + * + * Note that the 'LIN' token also contains the source information for the + * first word of the line for error reporting purposes + * + * -- the substFlags field of the structure -- + * + * The scriptObj structure is used to represent both "script" objects + * and "subst" objects. In the second case, the there are no LIN and WRD + * tokens. Instead SEP and EOL tokens are added as-is. + * In addition, the field 'substFlags' is used to represent the flags used to turn + * the string into the internal representation used to perform the + * substitution. If this flags are not what the application requires + * the scriptObj is created again. For example the script: + * + * subst -nocommands $string + * subst -novariables $string + * + * Will recreate the internal representation of the $string object + * two times. + */ +typedef struct ScriptObj +{ + int len; /* Length as number of tokens. */ + ScriptToken *token; /* Tokens array. */ + int substFlags; /* flags used for the compilation of "subst" objects */ + int inUse; /* Used to share a ScriptObj. Currently + only used by Jim_EvalObj() as protection against + shimmering of the currently evaluated object. */ + Jim_Obj *fileNameObj; + int firstline; /* Line number of the first line */ + int linenr; /* Line number of the current line */ +} ScriptObj; + +void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + int i; + struct ScriptObj *script = (void *)objPtr->internalRep.ptr; + + script->inUse--; + if (script->inUse != 0) + return; + for (i = 0; i < script->len; i++) { + Jim_DecrRefCount(interp, script->token[i].objPtr); + } + Jim_Free(script->token); + Jim_DecrRefCount(interp, script->fileNameObj); + Jim_Free(script); +} + +void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + JIM_NOTUSED(interp); + JIM_NOTUSED(srcPtr); + + /* Just returns an simple string. */ + dupPtr->typePtr = NULL; +} + +/* A simple parser token. + * All the simple tokens for the script point into the same script string rep. + */ +typedef struct +{ + const char *token; /* Pointer to the start of the token */ + int len; /* Length of this token */ + int type; /* Token type */ + int line; /* Line number */ +} ParseToken; + +/* A list of parsed tokens representing a script. + * Tokens are added to this list as the script is parsed. + * It grows as needed. + */ +typedef struct +{ + /* Start with a statically allocated list of tokens which will be expanded with realloc if needed */ + ParseToken *list; /* Array of tokens */ + int size; /* Current size of the list */ + int count; /* Number of entries used */ + ParseToken static_list[20]; /* Small initial token space to avoid allocation */ +} ParseTokenList; + +static void ScriptTokenListInit(ParseTokenList *tokenlist) +{ + tokenlist->list = tokenlist->static_list; + tokenlist->size = sizeof(tokenlist->static_list) / sizeof(ParseToken); + tokenlist->count = 0; +} + +static void ScriptTokenListFree(ParseTokenList *tokenlist) +{ + if (tokenlist->list != tokenlist->static_list) { + Jim_Free(tokenlist->list); + } +} + +/** + * Adds the new token to the tokenlist. + * The token has the given length, type and line number. + * The token list is resized as necessary. + */ +static void ScriptAddToken(ParseTokenList *tokenlist, const char *token, int len, int type, + int line) +{ + ParseToken *t; + + if (tokenlist->count == tokenlist->size) { + /* Resize the list */ + tokenlist->size *= 2; + if (tokenlist->list != tokenlist->static_list) { + tokenlist->list = + Jim_Realloc(tokenlist->list, tokenlist->size * sizeof(*tokenlist->list)); + } + else { + /* The list needs to become allocated */ + tokenlist->list = Jim_Alloc(tokenlist->size * sizeof(*tokenlist->list)); + memcpy(tokenlist->list, tokenlist->static_list, + tokenlist->count * sizeof(*tokenlist->list)); + } + } + t = &tokenlist->list[tokenlist->count++]; + t->token = token; + t->len = len; + t->type = type; + t->line = line; +} + +/* Counts the number of adjoining non-separator. + * + * Returns -ve if the first token is the expansion + * operator (in which case the count doesn't include + * that token). + */ +static int JimCountWordTokens(ParseToken *t) +{ + int expand = 1; + int count = 0; + + /* Is the first word {*} or {expand}? */ + if (t->type == JIM_TT_STR && !TOKEN_IS_SEP(t[1].type)) { + if ((t->len == 1 && *t->token == '*') || (t->len == 6 && strncmp(t->token, "expand", 6) == 0)) { + /* Create an expand token */ + expand = -1; + t++; + } + } + + /* Now count non-separator words */ + while (!TOKEN_IS_SEP(t->type)) { + t++; + count++; + } + + return count * expand; +} + +/** + * Create a script/subst object from the given token. + */ +static Jim_Obj *JimMakeScriptObj(Jim_Interp *interp, const ParseToken *t) +{ + Jim_Obj *objPtr; + + if (t->type == JIM_TT_ESC && memchr(t->token, '\\', t->len) != NULL) { + /* Convert the backlash escapes . */ + int len = t->len; + char *str = Jim_Alloc(len + 1); + len = JimEscape(str, t->token, len); + objPtr = Jim_NewStringObjNoAlloc(interp, str, len); + } + else { + /* REVIST: Strictly, JIM_TT_STR should replace + * with a single space. This is currently not done. + */ + objPtr = Jim_NewStringObj(interp, t->token, t->len); + } + return objPtr; +} + +/** + * Takes a tokenlist and creates the allocated list of script tokens + * in script->token, of length script->len. + * + * Unnecessary tokens are discarded, and LINE and WORD tokens are inserted + * as required. + * + * Also sets script->line to the line number of the first token + */ +static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, + ParseTokenList *tokenlist) +{ + int i; + struct ScriptToken *token; + /* Number of tokens so far for the current command */ + int lineargs = 0; + /* This is the first token for the current command */ + ScriptToken *linefirst; + int count; + int linenr; + +#ifdef DEBUG_SHOW_SCRIPT_TOKENS + printf("==== Tokens ====\n"); + for (i = 0; i < tokenlist->count; i++) { + printf("[%2d]@%d %s '%.*s'\n", i, tokenlist->list[i].line, jim_tt_name(tokenlist->list[i].type), + tokenlist->list[i].len, tokenlist->list[i].token); + } +#endif + + /* May need up to one extra script token for each EOL in the worst case */ + count = tokenlist->count; + for (i = 0; i < tokenlist->count; i++) { + if (tokenlist->list[i].type == JIM_TT_EOL) { + count++; + } + } + linenr = script->firstline = tokenlist->list[0].line; + + token = script->token = Jim_Alloc(sizeof(ScriptToken) * count); + + /* This is the first token for the current command */ + linefirst = token++; + + for (i = 0; i < tokenlist->count; ) { + /* Look ahead to find out how many tokens make up the next word */ + int wordtokens; + + /* Skip any leading separators */ + while (tokenlist->list[i].type == JIM_TT_SEP) { + i++; + } + + wordtokens = JimCountWordTokens(tokenlist->list + i); + + if (wordtokens == 0) { + /* None, so at end of line */ + if (lineargs) { + linefirst->type = JIM_TT_LINE; + linefirst->objPtr = JimNewScriptLineObj(interp, lineargs, linenr); + Jim_IncrRefCount(linefirst->objPtr); + + /* Reset for new line */ + lineargs = 0; + linefirst = token++; + } + i++; + continue; + } + else if (wordtokens != 1) { + /* More than 1, or {expand}, so insert a WORD token */ + token->type = JIM_TT_WORD; + token->objPtr = Jim_NewIntObj(interp, wordtokens); + Jim_IncrRefCount(token->objPtr); + token++; + if (wordtokens < 0) { + /* Skip the expand token */ + i++; + wordtokens = -wordtokens - 1; + lineargs--; + } + } + + if (lineargs == 0) { + /* First real token on the line, so record the line number */ + linenr = tokenlist->list[i].line; + } + lineargs++; + + /* Add each non-separator word token to the line */ + while (wordtokens--) { + const ParseToken *t = &tokenlist->list[i++]; + + token->type = t->type; + token->objPtr = JimMakeScriptObj(interp, t); + Jim_IncrRefCount(token->objPtr); + + /* Every object is initially a string, but the + * internal type may be specialized during execution of the + * script. */ + JimSetSourceInfo(interp, token->objPtr, script->fileNameObj, t->line); + token++; + } + } + + if (lineargs == 0) { + token--; + } + + script->len = token - script->token; + + assert(script->len < count); + +#ifdef DEBUG_SHOW_SCRIPT + printf("==== Script (%s) ====\n", Jim_String(script->fileNameObj)); + for (i = 0; i < script->len; i++) { + const ScriptToken *t = &script->token[i]; + printf("[%2d] %s %s\n", i, jim_tt_name(t->type), Jim_String(t->objPtr)); + } +#endif + +} + +/** + * Similar to ScriptObjAddTokens(), but for subst objects. + */ +static void SubstObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, + ParseTokenList *tokenlist) +{ + int i; + struct ScriptToken *token; + + token = script->token = Jim_Alloc(sizeof(ScriptToken) * tokenlist->count); + + for (i = 0; i < tokenlist->count; i++) { + const ParseToken *t = &tokenlist->list[i]; + + /* Create a token for 't' */ + token->type = t->type; + token->objPtr = JimMakeScriptObj(interp, t); + Jim_IncrRefCount(token->objPtr); + token++; + } + + script->len = i; +} + +/* This method takes the string representation of an object + * as a Tcl script, and generates the pre-parsed internal representation + * of the script. */ +static int SetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, struct JimParseResult *result) +{ + int scriptTextLen; + const char *scriptText = Jim_GetString(objPtr, &scriptTextLen); + struct JimParserCtx parser; + struct ScriptObj *script; + ParseTokenList tokenlist; + int line = 1; + + /* Try to get information about filename / line number */ + if (objPtr->typePtr == &sourceObjType) { + line = objPtr->internalRep.sourceValue.lineNumber; + } + + /* Initially parse the script into tokens (in tokenlist) */ + ScriptTokenListInit(&tokenlist); + + JimParserInit(&parser, scriptText, scriptTextLen, line); + while (!parser.eof) { + JimParseScript(&parser); + ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, + parser.tline); + } + if (result && parser.missing != ' ') { + ScriptTokenListFree(&tokenlist); + result->missing = parser.missing; + result->line = parser.missingline; + return JIM_ERR; + } + + /* Add a final EOF token */ + ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0); + + /* Create the "real" script tokens from the initial token list */ + script = Jim_Alloc(sizeof(*script)); + memset(script, 0, sizeof(*script)); + script->inUse = 1; + if (objPtr->typePtr == &sourceObjType) { + script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; + } + else { + script->fileNameObj = interp->emptyObj; + } + Jim_IncrRefCount(script->fileNameObj); + + ScriptObjAddTokens(interp, script, &tokenlist); + + /* No longer need the token list */ + ScriptTokenListFree(&tokenlist); + + /* Free the old internal rep and set the new one. */ + Jim_FreeIntRep(interp, objPtr); + Jim_SetIntRepPtr(objPtr, script); + objPtr->typePtr = &scriptObjType; + + return JIM_OK; +} + +ScriptObj *Jim_GetScript(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr == interp->emptyObj) { + /* Avoid converting emptyObj to a script. use nullScriptObj instead. */ + objPtr = interp->nullScriptObj; + } + + if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) { + SetScriptFromAny(interp, objPtr, NULL); + } + return (ScriptObj *) Jim_GetIntRepPtr(objPtr); +} + +/* ----------------------------------------------------------------------------- + * Commands + * ---------------------------------------------------------------------------*/ +static void JimIncrCmdRefCount(Jim_Cmd *cmdPtr) +{ + cmdPtr->inUse++; +} + +static void JimDecrCmdRefCount(Jim_Interp *interp, Jim_Cmd *cmdPtr) +{ + if (--cmdPtr->inUse == 0) { + if (cmdPtr->isproc) { + Jim_DecrRefCount(interp, cmdPtr->u.proc.argListObjPtr); + Jim_DecrRefCount(interp, cmdPtr->u.proc.bodyObjPtr); + Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj); + if (cmdPtr->u.proc.staticVars) { + Jim_FreeHashTable(cmdPtr->u.proc.staticVars); + Jim_Free(cmdPtr->u.proc.staticVars); + } + } + else { + /* native (C) */ + if (cmdPtr->u.native.delProc) { + cmdPtr->u.native.delProc(interp, cmdPtr->u.native.privData); + } + } + if (cmdPtr->prevCmd) { + /* Delete any pushed command too */ + JimDecrCmdRefCount(interp, cmdPtr->prevCmd); + } + Jim_Free(cmdPtr); + } +} + +/* Variables HashTable Type. + * + * Keys are dynamic allocated strings, Values are Jim_Var structures. + */ + +/* Variables HashTable Type. + * + * Keys are dynamic allocated strings, Values are Jim_Var structures. */ +static void JimVariablesHTValDestructor(void *interp, void *val) +{ + Jim_DecrRefCount(interp, ((Jim_Var *)val)->objPtr); + Jim_Free(val); +} + +static const Jim_HashTableType JimVariablesHashTableType = { + JimStringCopyHTHashFunction, /* hash function */ + JimStringCopyHTDup, /* key dup */ + NULL, /* val dup */ + JimStringCopyHTKeyCompare, /* key compare */ + JimStringCopyHTKeyDestructor, /* key destructor */ + JimVariablesHTValDestructor /* val destructor */ +}; + +/* Commands HashTable Type. + * + * Keys are dynamic allocated strings, Values are Jim_Cmd structures. */ +static void JimCommandsHT_ValDestructor(void *interp, void *val) +{ + JimDecrCmdRefCount(interp, val); +} + +static const Jim_HashTableType JimCommandsHashTableType = { + JimStringCopyHTHashFunction, /* hash function */ + JimStringCopyHTDup, /* key dup */ + NULL, /* val dup */ + JimStringCopyHTKeyCompare, /* key compare */ + JimStringCopyHTKeyDestructor, /* key destructor */ + JimCommandsHT_ValDestructor /* val destructor */ +}; + +/* ------------------------- Commands related functions --------------------- */ + +#ifdef jim_ext_namespace +/** + * Returns the "unscoped" version of the given namespace. + * That is, the fully qualfied name without the leading :: + * The returned value is either nsObj, or an object with a zero ref count. + */ +static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj) +{ + const char *name = Jim_String(nsObj); + if (name[0] == ':' && name[1] == ':') { + /* This command is being defined in the global namespace */ + while (*++name == ':') { + } + nsObj = Jim_NewStringObj(interp, name, -1); + } + else if (Jim_Length(interp->framePtr->nsObj)) { + /* This command is being defined in a non-global namespace */ + nsObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj); + Jim_AppendStrings(interp, nsObj, "::", name, NULL); + } + return nsObj; +} + +/** + * An efficient version of JimQualifyNameObj() where the name is + * available (and needed) as a 'const char *'. + * Avoids creating an object if not necessary. + * The object stored in *objPtrPtr should be disposed of with JimFreeQualifiedName() after use. + */ +static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj **objPtrPtr) +{ + Jim_Obj *objPtr = interp->emptyObj; + + if (name[0] == ':' && name[1] == ':') { + /* This command is being defined in the global namespace */ + while (*++name == ':') { + } + } + else if (Jim_Length(interp->framePtr->nsObj)) { + /* This command is being defined in a non-global namespace */ + objPtr = Jim_DuplicateObj(interp, interp->framePtr->nsObj); + Jim_AppendStrings(interp, objPtr, "::", name, NULL); + name = Jim_String(objPtr); + } + Jim_IncrRefCount(objPtr); + *objPtrPtr = objPtr; + return name; +} + + #define JimFreeQualifiedName(INTERP, OBJ) Jim_DecrRefCount((INTERP), (OBJ)) + +#else + /* We can be more efficient in the no-namespace case */ + #define JimQualifyName(INTERP, NAME, DUMMY) (((NAME)[0] == ':' && (NAME)[1] == ':') ? (NAME) + 2 : (NAME)) + #define JimFreeQualifiedName(INTERP, DUMMY) (void)(DUMMY) +#endif + +static int JimCreateCommand(Jim_Interp *interp, const char *name, Jim_Cmd *cmd) +{ + /* It may already exist, so we try to delete the old one. + * Note that reference count means that it won't be deleted yet if + * it exists in the call stack. + * + * BUT, if 'local' is in force, instead of deleting the existing + * proc, we stash a reference to the old proc here. + */ + Jim_HashEntry *he = Jim_FindHashEntry(&interp->commands, name); + if (he) { + /* There was an old cmd with the same name, + * so this requires a 'proc epoch' update. */ + + /* If a procedure with the same name didn't exist there is no need + * to increment the 'proc epoch' because creation of a new procedure + * can never affect existing cached commands. We don't do + * negative caching. */ + Jim_InterpIncrProcEpoch(interp); + } + + if (he && interp->local) { + /* Push this command over the top of the previous one */ + cmd->prevCmd = he->u.val; + he->u.val = cmd; + } + else { + if (he) { + /* Replace the existing command */ + Jim_DeleteHashEntry(&interp->commands, name); + } + + Jim_AddHashEntry(&interp->commands, name, cmd); + } + return JIM_OK; +} + + +int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr, + Jim_CmdProc cmdProc, void *privData, Jim_DelCmdProc delProc) +{ + Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr)); + + /* Store the new details for this command */ + memset(cmdPtr, 0, sizeof(*cmdPtr)); + cmdPtr->inUse = 1; + cmdPtr->u.native.delProc = delProc; + cmdPtr->u.native.cmdProc = cmdProc; + cmdPtr->u.native.privData = privData; + + JimCreateCommand(interp, cmdNameStr, cmdPtr); + + return JIM_OK; +} + +static int JimCreateProcedureStatics(Jim_Interp *interp, Jim_Cmd *cmdPtr, Jim_Obj *staticsListObjPtr) +{ + int len, i; + + len = Jim_ListLength(interp, staticsListObjPtr); + if (len == 0) { + return JIM_OK; + } + + cmdPtr->u.proc.staticVars = Jim_Alloc(sizeof(Jim_HashTable)); + Jim_InitHashTable(cmdPtr->u.proc.staticVars, &JimVariablesHashTableType, interp); + for (i = 0; i < len; i++) { + Jim_Obj *objPtr = NULL, *initObjPtr = NULL, *nameObjPtr = NULL; + Jim_Var *varPtr; + int subLen; + + Jim_ListIndex(interp, staticsListObjPtr, i, &objPtr, JIM_NONE); + /* Check if it's composed of two elements. */ + subLen = Jim_ListLength(interp, objPtr); + if (subLen == 1 || subLen == 2) { + /* Try to get the variable value from the current + * environment. */ + Jim_ListIndex(interp, objPtr, 0, &nameObjPtr, JIM_NONE); + if (subLen == 1) { + initObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_NONE); + if (initObjPtr == NULL) { + Jim_SetResultFormatted(interp, + "variable for initialization of static \"%#s\" not found in the local context", + nameObjPtr); + return JIM_ERR; + } + } + else { + Jim_ListIndex(interp, objPtr, 1, &initObjPtr, JIM_NONE); + } + if (JimValidName(interp, "static variable", nameObjPtr) != JIM_OK) { + return JIM_ERR; + } + + varPtr = Jim_Alloc(sizeof(*varPtr)); + varPtr->objPtr = initObjPtr; + Jim_IncrRefCount(initObjPtr); + varPtr->linkFramePtr = NULL; + if (Jim_AddHashEntry(cmdPtr->u.proc.staticVars, + Jim_String(nameObjPtr), varPtr) != JIM_OK) { + Jim_SetResultFormatted(interp, + "static variable name \"%#s\" duplicated in statics list", nameObjPtr); + Jim_DecrRefCount(interp, initObjPtr); + Jim_Free(varPtr); + return JIM_ERR; + } + } + else { + Jim_SetResultFormatted(interp, "too many fields in static specifier \"%#s\"", + objPtr); + return JIM_ERR; + } + } + return JIM_OK; +} + +static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const char *cmdname) +{ +#ifdef jim_ext_namespace + if (cmdPtr->isproc) { + /* XXX: Really need JimNamespaceSplit() */ + const char *pt = strrchr(cmdname, ':'); + if (pt && pt != cmdname && pt[-1] == ':') { + Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj); + cmdPtr->u.proc.nsObj = Jim_NewStringObj(interp, cmdname, pt - cmdname - 1); + Jim_IncrRefCount(cmdPtr->u.proc.nsObj); + + if (Jim_FindHashEntry(&interp->commands, pt + 1)) { + /* This commands shadows a global command, so a proc epoch update is required */ + Jim_InterpIncrProcEpoch(interp); + } + } + } +#endif +} + +static Jim_Cmd *JimCreateProcedureCmd(Jim_Interp *interp, Jim_Obj *argListObjPtr, + Jim_Obj *staticsListObjPtr, Jim_Obj *bodyObjPtr, Jim_Obj *nsObj) +{ + Jim_Cmd *cmdPtr; + int argListLen; + int i; + + argListLen = Jim_ListLength(interp, argListObjPtr); + + /* Allocate space for both the command pointer and the arg list */ + cmdPtr = Jim_Alloc(sizeof(*cmdPtr) + sizeof(struct Jim_ProcArg) * argListLen); + memset(cmdPtr, 0, sizeof(*cmdPtr)); + cmdPtr->inUse = 1; + cmdPtr->isproc = 1; + cmdPtr->u.proc.argListObjPtr = argListObjPtr; + cmdPtr->u.proc.argListLen = argListLen; + cmdPtr->u.proc.bodyObjPtr = bodyObjPtr; + cmdPtr->u.proc.argsPos = -1; + cmdPtr->u.proc.arglist = (struct Jim_ProcArg *)(cmdPtr + 1); + cmdPtr->u.proc.nsObj = nsObj ? nsObj : interp->emptyObj; + Jim_IncrRefCount(argListObjPtr); + Jim_IncrRefCount(bodyObjPtr); + Jim_IncrRefCount(cmdPtr->u.proc.nsObj); + + /* Create the statics hash table. */ + if (staticsListObjPtr && JimCreateProcedureStatics(interp, cmdPtr, staticsListObjPtr) != JIM_OK) { + goto err; + } + + /* Parse the args out into arglist, validating as we go */ + /* Examine the argument list for default parameters and 'args' */ + for (i = 0; i < argListLen; i++) { + Jim_Obj *argPtr; + Jim_Obj *nameObjPtr; + Jim_Obj *defaultObjPtr; + int len; + + /* Examine a parameter */ + Jim_ListIndex(interp, argListObjPtr, i, &argPtr, JIM_NONE); + len = Jim_ListLength(interp, argPtr); + if (len == 0) { + Jim_SetResultString(interp, "argument with no name", -1); +err: + JimDecrCmdRefCount(interp, cmdPtr); + return NULL; + } + if (len > 2) { + Jim_SetResultFormatted(interp, "too many fields in argument specifier \"%#s\"", argPtr); + goto err; + } + + if (len == 2) { + /* Optional parameter */ + Jim_ListIndex(interp, argPtr, 0, &nameObjPtr, JIM_NONE); + Jim_ListIndex(interp, argPtr, 1, &defaultObjPtr, JIM_NONE); + } + else { + /* Required parameter */ + nameObjPtr = argPtr; + defaultObjPtr = NULL; + } + + + if (Jim_CompareStringImmediate(interp, nameObjPtr, "args")) { + if (cmdPtr->u.proc.argsPos >= 0) { + Jim_SetResultString(interp, "'args' specified more than once", -1); + goto err; + } + cmdPtr->u.proc.argsPos = i; + } + else { + if (len == 2) { + cmdPtr->u.proc.optArity++; + } + else { + cmdPtr->u.proc.reqArity++; + } + } + + cmdPtr->u.proc.arglist[i].nameObjPtr = nameObjPtr; + cmdPtr->u.proc.arglist[i].defaultObjPtr = defaultObjPtr; + } + + return cmdPtr; +} + +int Jim_DeleteCommand(Jim_Interp *interp, const char *name) +{ + int ret = JIM_OK; + Jim_Obj *qualifiedNameObj; + const char *qualname = JimQualifyName(interp, name, &qualifiedNameObj); + + if (Jim_DeleteHashEntry(&interp->commands, qualname) == JIM_ERR) { + Jim_SetResultFormatted(interp, "can't delete \"%s\": command doesn't exist", name); + ret = JIM_ERR; + } + else { + Jim_InterpIncrProcEpoch(interp); + } + + JimFreeQualifiedName(interp, qualifiedNameObj); + + return ret; +} + +int Jim_RenameCommand(Jim_Interp *interp, const char *oldName, const char *newName) +{ + int ret = JIM_ERR; + Jim_HashEntry *he; + Jim_Cmd *cmdPtr; + Jim_Obj *qualifiedOldNameObj; + Jim_Obj *qualifiedNewNameObj; + const char *fqold; + const char *fqnew; + + if (newName[0] == 0) { + return Jim_DeleteCommand(interp, oldName); + } + + fqold = JimQualifyName(interp, oldName, &qualifiedOldNameObj); + fqnew = JimQualifyName(interp, newName, &qualifiedNewNameObj); + + /* Does it exist? */ + he = Jim_FindHashEntry(&interp->commands, fqold); + if (he == NULL) { + Jim_SetResultFormatted(interp, "can't rename \"%s\": command doesn't exist", oldName); + } + else if (Jim_FindHashEntry(&interp->commands, fqnew)) { + Jim_SetResultFormatted(interp, "can't rename to \"%s\": command already exists", newName); + } + else { + /* Add the new name first */ + cmdPtr = he->u.val; + JimIncrCmdRefCount(cmdPtr); + JimUpdateProcNamespace(interp, cmdPtr, fqnew); + Jim_AddHashEntry(&interp->commands, fqnew, cmdPtr); + + /* Now remove the old name */ + Jim_DeleteHashEntry(&interp->commands, fqold); + + /* Increment the epoch */ + Jim_InterpIncrProcEpoch(interp); + + ret = JIM_OK; + } + + JimFreeQualifiedName(interp, qualifiedOldNameObj); + JimFreeQualifiedName(interp, qualifiedNewNameObj); + + return ret; +} + +/* ----------------------------------------------------------------------------- + * Command object + * ---------------------------------------------------------------------------*/ + +static void FreeCommandInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.cmdValue.nsObj); +} + +static void DupCommandInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + dupPtr->internalRep.cmdValue = srcPtr->internalRep.cmdValue; + dupPtr->typePtr = srcPtr->typePtr; + Jim_IncrRefCount(dupPtr->internalRep.cmdValue.nsObj); +} + +static const Jim_ObjType commandObjType = { + "command", + FreeCommandInternalRep, + DupCommandInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + +/* This function returns the command structure for the command name + * stored in objPtr. It tries to specialize the objPtr to contain + * a cached info instead to perform the lookup into the hash table + * every time. The information cached may not be uptodate, in such + * a case the lookup is performed and the cache updated. + * + * Respects the 'upcall' setting + */ +Jim_Cmd *Jim_GetCommand(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + Jim_Cmd *cmd; + + /* In order to be valid, the proc epoch must match and + * the lookup must have occurred in the same namespace + */ + if (objPtr->typePtr != &commandObjType || + objPtr->internalRep.cmdValue.procEpoch != interp->procEpoch +#ifdef jim_ext_namespace + || !Jim_StringEqObj(objPtr->internalRep.cmdValue.nsObj, interp->framePtr->nsObj) +#endif + ) { + /* Not cached or out of date, so lookup */ + + /* Do we need to try the local namespace? */ + const char *name = Jim_String(objPtr); + Jim_HashEntry *he; + + if (name[0] == ':' && name[1] == ':') { + while (*++name == ':') { + } + } +#ifdef jim_ext_namespace + else if (Jim_Length(interp->framePtr->nsObj)) { + /* This command is being defined in a non-global namespace */ + Jim_Obj *nameObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj); + Jim_AppendStrings(interp, nameObj, "::", name, NULL); + he = Jim_FindHashEntry(&interp->commands, Jim_String(nameObj)); + Jim_FreeNewObj(interp, nameObj); + if (he) { + goto found; + } + } +#endif + + /* Lookup in the global namespace */ + he = Jim_FindHashEntry(&interp->commands, name); + if (he == NULL) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr); + } + return NULL; + } +#ifdef jim_ext_namespace +found: +#endif + cmd = (Jim_Cmd *)he->u.val; + + /* Free the old internal repr and set the new one. */ + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &commandObjType; + objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch; + objPtr->internalRep.cmdValue.cmdPtr = cmd; + objPtr->internalRep.cmdValue.nsObj = interp->framePtr->nsObj; + Jim_IncrRefCount(interp->framePtr->nsObj); + } + else { + cmd = objPtr->internalRep.cmdValue.cmdPtr; + } + while (cmd->u.proc.upcall) { + cmd = cmd->prevCmd; + } + return cmd; +} + +/* ----------------------------------------------------------------------------- + * Variables + * ---------------------------------------------------------------------------*/ + +/* ----------------------------------------------------------------------------- + * Variable object + * ---------------------------------------------------------------------------*/ + +#define JIM_DICT_SUGAR 100 /* Only returned by SetVariableFromAny() */ + +static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType variableObjType = { + "variable", + NULL, + NULL, + NULL, + JIM_TYPE_REFERENCES, +}; + +/** + * Check that the name does not contain embedded nulls. + * + * Variable and procedure names are maniplated as null terminated strings, so + * don't allow names with embedded nulls. + */ +static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr) +{ + /* Variable names and proc names can't contain embedded nulls */ + if (nameObjPtr->typePtr != &variableObjType) { + int len; + const char *str = Jim_GetString(nameObjPtr, &len); + if (memchr(str, '\0', len)) { + Jim_SetResultFormatted(interp, "%s name contains embedded null", type); + return JIM_ERR; + } + } + return JIM_OK; +} + +/* This method should be called only by the variable API. + * It returns JIM_OK on success (variable already exists), + * JIM_ERR if it does not exists, JIM_DICT_SUGAR if it's not + * a variable name, but syntax glue for [dict] i.e. the last + * character is ')' */ +static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + const char *varName; + Jim_CallFrame *framePtr; + Jim_HashEntry *he; + int global; + int len; + + /* Check if the object is already an uptodate variable */ + if (objPtr->typePtr == &variableObjType) { + framePtr = objPtr->internalRep.varValue.global ? interp->topFramePtr : interp->framePtr; + if (objPtr->internalRep.varValue.callFrameId == framePtr->id) { + /* nothing to do */ + return JIM_OK; + } + /* Need to re-resolve the variable in the updated callframe */ + } + else if (objPtr->typePtr == &dictSubstObjType) { + return JIM_DICT_SUGAR; + } + else if (JimValidName(interp, "variable", objPtr) != JIM_OK) { + return JIM_ERR; + } + + + varName = Jim_GetString(objPtr, &len); + + /* Make sure it's not syntax glue to get/set dict. */ + if (len && varName[len - 1] == ')' && strchr(varName, '(') != NULL) { + return JIM_DICT_SUGAR; + } + + if (varName[0] == ':' && varName[1] == ':') { + while (*++varName == ':') { + } + global = 1; + framePtr = interp->topFramePtr; + } + else { + global = 0; + framePtr = interp->framePtr; + } + + /* Resolve this name in the variables hash table */ + he = Jim_FindHashEntry(&framePtr->vars, varName); + if (he == NULL) { + if (!global && framePtr->staticVars) { + /* Try with static vars. */ + he = Jim_FindHashEntry(framePtr->staticVars, varName); + } + if (he == NULL) { + return JIM_ERR; + } + } + + /* Free the old internal repr and set the new one. */ + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &variableObjType; + objPtr->internalRep.varValue.callFrameId = framePtr->id; + objPtr->internalRep.varValue.varPtr = he->u.val; + objPtr->internalRep.varValue.global = global; + return JIM_OK; +} + +/* -------------------- Variables related functions ------------------------- */ +static int JimDictSugarSet(Jim_Interp *interp, Jim_Obj *ObjPtr, Jim_Obj *valObjPtr); +static Jim_Obj *JimDictSugarGet(Jim_Interp *interp, Jim_Obj *ObjPtr, int flags); + +static Jim_Var *JimCreateVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr) +{ + const char *name; + Jim_CallFrame *framePtr; + int global; + + /* New variable to create */ + Jim_Var *var = Jim_Alloc(sizeof(*var)); + + var->objPtr = valObjPtr; + Jim_IncrRefCount(valObjPtr); + var->linkFramePtr = NULL; + + name = Jim_String(nameObjPtr); + if (name[0] == ':' && name[1] == ':') { + while (*++name == ':') { + } + framePtr = interp->topFramePtr; + global = 1; + } + else { + framePtr = interp->framePtr; + global = 0; + } + + /* Insert the new variable */ + Jim_AddHashEntry(&framePtr->vars, name, var); + + /* Make the object int rep a variable */ + Jim_FreeIntRep(interp, nameObjPtr); + nameObjPtr->typePtr = &variableObjType; + nameObjPtr->internalRep.varValue.callFrameId = framePtr->id; + nameObjPtr->internalRep.varValue.varPtr = var; + nameObjPtr->internalRep.varValue.global = global; + + return var; +} + +/* For now that's dummy. Variables lookup should be optimized + * in many ways, with caching of lookups, and possibly with + * a table of pre-allocated vars in every CallFrame for local vars. + * All the caching should also have an 'epoch' mechanism similar + * to the one used by Tcl for procedures lookup caching. */ + +int Jim_SetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr) +{ + int err; + Jim_Var *var; + + switch (SetVariableFromAny(interp, nameObjPtr)) { + case JIM_DICT_SUGAR: + return JimDictSugarSet(interp, nameObjPtr, valObjPtr); + + case JIM_ERR: + if (JimValidName(interp, "variable", nameObjPtr) != JIM_OK) { + return JIM_ERR; + } + JimCreateVariable(interp, nameObjPtr, valObjPtr); + break; + + case JIM_OK: + var = nameObjPtr->internalRep.varValue.varPtr; + if (var->linkFramePtr == NULL) { + Jim_IncrRefCount(valObjPtr); + Jim_DecrRefCount(interp, var->objPtr); + var->objPtr = valObjPtr; + } + else { /* Else handle the link */ + Jim_CallFrame *savedCallFrame; + + savedCallFrame = interp->framePtr; + interp->framePtr = var->linkFramePtr; + err = Jim_SetVariable(interp, var->objPtr, valObjPtr); + interp->framePtr = savedCallFrame; + if (err != JIM_OK) + return err; + } + } + return JIM_OK; +} + +int Jim_SetVariableStr(Jim_Interp *interp, const char *name, Jim_Obj *objPtr) +{ + Jim_Obj *nameObjPtr; + int result; + + nameObjPtr = Jim_NewStringObj(interp, name, -1); + Jim_IncrRefCount(nameObjPtr); + result = Jim_SetVariable(interp, nameObjPtr, objPtr); + Jim_DecrRefCount(interp, nameObjPtr); + return result; +} + +int Jim_SetGlobalVariableStr(Jim_Interp *interp, const char *name, Jim_Obj *objPtr) +{ + Jim_CallFrame *savedFramePtr; + int result; + + savedFramePtr = interp->framePtr; + interp->framePtr = interp->topFramePtr; + result = Jim_SetVariableStr(interp, name, objPtr); + interp->framePtr = savedFramePtr; + return result; +} + +int Jim_SetVariableStrWithStr(Jim_Interp *interp, const char *name, const char *val) +{ + Jim_Obj *nameObjPtr, *valObjPtr; + int result; + + nameObjPtr = Jim_NewStringObj(interp, name, -1); + valObjPtr = Jim_NewStringObj(interp, val, -1); + Jim_IncrRefCount(nameObjPtr); + Jim_IncrRefCount(valObjPtr); + result = Jim_SetVariable(interp, nameObjPtr, valObjPtr); + Jim_DecrRefCount(interp, nameObjPtr); + Jim_DecrRefCount(interp, valObjPtr); + return result; +} + +int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr, + Jim_Obj *targetNameObjPtr, Jim_CallFrame *targetCallFrame) +{ + const char *varName; + const char *targetName; + Jim_CallFrame *framePtr; + Jim_Var *varPtr; + + /* Check for an existing variable or link */ + switch (SetVariableFromAny(interp, nameObjPtr)) { + case JIM_DICT_SUGAR: + /* XXX: This message seem unnecessarily verbose, but it matches Tcl */ + Jim_SetResultFormatted(interp, "bad variable name \"%#s\": upvar won't create a scalar variable that looks like an array element", nameObjPtr); + return JIM_ERR; + + case JIM_OK: + varPtr = nameObjPtr->internalRep.varValue.varPtr; + + if (varPtr->linkFramePtr == NULL) { + Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr); + return JIM_ERR; + } + + /* It exists, but is a link, so first delete the link */ + varPtr->linkFramePtr = NULL; + break; + } + + /* Resolve the call frames for both variables */ + /* XXX: SetVariableFromAny() already did this! */ + varName = Jim_String(nameObjPtr); + + if (varName[0] == ':' && varName[1] == ':') { + while (*++varName == ':') { + } + /* Linking a global var does nothing */ + framePtr = interp->topFramePtr; + } + else { + framePtr = interp->framePtr; + } + + targetName = Jim_String(targetNameObjPtr); + if (targetName[0] == ':' && targetName[1] == ':') { + while (*++targetName == ':') { + } + targetNameObjPtr = Jim_NewStringObj(interp, targetName, -1); + targetCallFrame = interp->topFramePtr; + } + Jim_IncrRefCount(targetNameObjPtr); + + if (framePtr->level < targetCallFrame->level) { + Jim_SetResultFormatted(interp, + "bad variable name \"%#s\": upvar won't create namespace variable that refers to procedure variable", + nameObjPtr); + Jim_DecrRefCount(interp, targetNameObjPtr); + return JIM_ERR; + } + + /* Check for cycles. */ + if (framePtr == targetCallFrame) { + Jim_Obj *objPtr = targetNameObjPtr; + + /* Cycles are only possible with 'uplevel 0' */ + while (1) { + if (strcmp(Jim_String(objPtr), varName) == 0) { + Jim_SetResultString(interp, "can't upvar from variable to itself", -1); + Jim_DecrRefCount(interp, targetNameObjPtr); + return JIM_ERR; + } + if (SetVariableFromAny(interp, objPtr) != JIM_OK) + break; + varPtr = objPtr->internalRep.varValue.varPtr; + if (varPtr->linkFramePtr != targetCallFrame) + break; + objPtr = varPtr->objPtr; + } + } + + /* Perform the binding */ + Jim_SetVariable(interp, nameObjPtr, targetNameObjPtr); + /* We are now sure 'nameObjPtr' type is variableObjType */ + nameObjPtr->internalRep.varValue.varPtr->linkFramePtr = targetCallFrame; + Jim_DecrRefCount(interp, targetNameObjPtr); + return JIM_OK; +} + +/* Return the Jim_Obj pointer associated with a variable name, + * or NULL if the variable was not found in the current context. + * The same optimization discussed in the comment to the + * 'SetVariable' function should apply here. + * + * If JIM_UNSHARED is set and the variable is an array element (dict sugar) + * in a dictionary which is shared, the array variable value is duplicated first. + * This allows the array element to be updated (e.g. append, lappend) without + * affecting other references to the dictionary. + */ +Jim_Obj *Jim_GetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) +{ + switch (SetVariableFromAny(interp, nameObjPtr)) { + case JIM_OK:{ + Jim_Var *varPtr = nameObjPtr->internalRep.varValue.varPtr; + + if (varPtr->linkFramePtr == NULL) { + return varPtr->objPtr; + } + else { + Jim_Obj *objPtr; + + /* The variable is a link? Resolve it. */ + Jim_CallFrame *savedCallFrame = interp->framePtr; + + interp->framePtr = varPtr->linkFramePtr; + objPtr = Jim_GetVariable(interp, varPtr->objPtr, flags); + interp->framePtr = savedCallFrame; + if (objPtr) { + return objPtr; + } + /* Error, so fall through to the error message */ + } + } + break; + + case JIM_DICT_SUGAR: + /* [dict] syntax sugar. */ + return JimDictSugarGet(interp, nameObjPtr, flags); + } + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "can't read \"%#s\": no such variable", nameObjPtr); + } + return NULL; +} + +Jim_Obj *Jim_GetGlobalVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) +{ + Jim_CallFrame *savedFramePtr; + Jim_Obj *objPtr; + + savedFramePtr = interp->framePtr; + interp->framePtr = interp->topFramePtr; + objPtr = Jim_GetVariable(interp, nameObjPtr, flags); + interp->framePtr = savedFramePtr; + + return objPtr; +} + +Jim_Obj *Jim_GetVariableStr(Jim_Interp *interp, const char *name, int flags) +{ + Jim_Obj *nameObjPtr, *varObjPtr; + + nameObjPtr = Jim_NewStringObj(interp, name, -1); + Jim_IncrRefCount(nameObjPtr); + varObjPtr = Jim_GetVariable(interp, nameObjPtr, flags); + Jim_DecrRefCount(interp, nameObjPtr); + return varObjPtr; +} + +Jim_Obj *Jim_GetGlobalVariableStr(Jim_Interp *interp, const char *name, int flags) +{ + Jim_CallFrame *savedFramePtr; + Jim_Obj *objPtr; + + savedFramePtr = interp->framePtr; + interp->framePtr = interp->topFramePtr; + objPtr = Jim_GetVariableStr(interp, name, flags); + interp->framePtr = savedFramePtr; + + return objPtr; +} + +/* Unset a variable. + * Note: On success unset invalidates all the variable objects created + * in the current call frame incrementing. */ +int Jim_UnsetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) +{ + Jim_Var *varPtr; + int retval; + Jim_CallFrame *framePtr; + + retval = SetVariableFromAny(interp, nameObjPtr); + if (retval == JIM_DICT_SUGAR) { + /* [dict] syntax sugar. */ + return JimDictSugarSet(interp, nameObjPtr, NULL); + } + else if (retval == JIM_OK) { + varPtr = nameObjPtr->internalRep.varValue.varPtr; + + /* If it's a link call UnsetVariable recursively */ + if (varPtr->linkFramePtr) { + framePtr = interp->framePtr; + interp->framePtr = varPtr->linkFramePtr; + retval = Jim_UnsetVariable(interp, varPtr->objPtr, JIM_NONE); + interp->framePtr = framePtr; + } + else { + const char *name = Jim_String(nameObjPtr); + if (nameObjPtr->internalRep.varValue.global) { + name += 2; + framePtr = interp->topFramePtr; + } + else { + framePtr = interp->framePtr; + } + + retval = Jim_DeleteHashEntry(&framePtr->vars, name); + if (retval == JIM_OK) { + /* Change the callframe id, invalidating var lookup caching */ + JimChangeCallFrameId(interp, framePtr); + } + } + } + if (retval != JIM_OK && (flags & JIM_ERRMSG)) { + Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such variable", nameObjPtr); + } + return retval; +} + +/* ---------- Dict syntax sugar (similar to array Tcl syntax) -------------- */ + +/* Given a variable name for [dict] operation syntax sugar, + * this function returns two objects, the first with the name + * of the variable to set, and the second with the rispective key. + * For example "foo(bar)" will return objects with string repr. of + * "foo" and "bar". + * + * The returned objects have refcount = 1. The function can't fail. */ +static void JimDictSugarParseVarKey(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj **varPtrPtr, Jim_Obj **keyPtrPtr) +{ + const char *str, *p; + int len, keyLen; + Jim_Obj *varObjPtr, *keyObjPtr; + + str = Jim_GetString(objPtr, &len); + + p = strchr(str, '('); + JimPanic((p == NULL, "JimDictSugarParseVarKey() called for non-dict-sugar (%s)", str)); + + varObjPtr = Jim_NewStringObj(interp, str, p - str); + + p++; + keyLen = (str + len) - p; + if (str[len - 1] == ')') { + keyLen--; + } + + /* Create the objects with the variable name and key. */ + keyObjPtr = Jim_NewStringObj(interp, p, keyLen); + + Jim_IncrRefCount(varObjPtr); + Jim_IncrRefCount(keyObjPtr); + *varPtrPtr = varObjPtr; + *keyPtrPtr = keyObjPtr; +} + +/* Helper of Jim_SetVariable() to deal with dict-syntax variable names. + * Also used by Jim_UnsetVariable() with valObjPtr = NULL. */ +static int JimDictSugarSet(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *valObjPtr) +{ + int err; + + SetDictSubstFromAny(interp, objPtr); + + err = Jim_SetDictKeysVector(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, + &objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_MUSTEXIST); + + if (err == JIM_OK) { + /* Don't keep an extra ref to the result */ + Jim_SetEmptyResult(interp); + } + else { + if (!valObjPtr) { + /* Better error message for unset a(2) where a exists but a(2) doesn't */ + if (Jim_GetVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, JIM_NONE)) { + Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such element in array", + objPtr); + return err; + } + } + /* Make the error more informative and Tcl-compatible */ + Jim_SetResultFormatted(interp, "can't %s \"%#s\": variable isn't array", + (valObjPtr ? "set" : "unset"), objPtr); + } + return err; +} + +/** + * Expands the array variable (dict sugar) and returns the result, or NULL on error. + * + * If JIM_UNSHARED is set and the dictionary is shared, it will be duplicated + * and stored back to the variable before expansion. + */ +static Jim_Obj *JimDictExpandArrayVariable(Jim_Interp *interp, Jim_Obj *varObjPtr, + Jim_Obj *keyObjPtr, int flags) +{ + Jim_Obj *dictObjPtr; + Jim_Obj *resObjPtr = NULL; + int ret; + + dictObjPtr = Jim_GetVariable(interp, varObjPtr, JIM_ERRMSG); + if (!dictObjPtr) { + return NULL; + } + + ret = Jim_DictKey(interp, dictObjPtr, keyObjPtr, &resObjPtr, JIM_NONE); + if (ret != JIM_OK) { + resObjPtr = NULL; + if (ret < 0) { + Jim_SetResultFormatted(interp, + "can't read \"%#s(%#s)\": variable isn't array", varObjPtr, keyObjPtr); + } + else { + Jim_SetResultFormatted(interp, + "can't read \"%#s(%#s)\": no such element in array", varObjPtr, keyObjPtr); + } + } + else if ((flags & JIM_UNSHARED) && Jim_IsShared(dictObjPtr)) { + dictObjPtr = Jim_DuplicateObj(interp, dictObjPtr); + if (Jim_SetVariable(interp, varObjPtr, dictObjPtr) != JIM_OK) { + /* This can probably never happen */ + JimPanic((1, "SetVariable failed for JIM_UNSHARED")); + } + /* We know that the key exists. Get the result in the now-unshared dictionary */ + Jim_DictKey(interp, dictObjPtr, keyObjPtr, &resObjPtr, JIM_NONE); + } + + return resObjPtr; +} + +/* Helper of Jim_GetVariable() to deal with dict-syntax variable names */ +static Jim_Obj *JimDictSugarGet(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + SetDictSubstFromAny(interp, objPtr); + + return JimDictExpandArrayVariable(interp, + objPtr->internalRep.dictSubstValue.varNameObjPtr, + objPtr->internalRep.dictSubstValue.indexObjPtr, flags); +} + +/* --------- $var(INDEX) substitution, using a specialized object ----------- */ + +void FreeDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr); + Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr); +} + +void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + JIM_NOTUSED(interp); + + dupPtr->internalRep.dictSubstValue.varNameObjPtr = + srcPtr->internalRep.dictSubstValue.varNameObjPtr; + dupPtr->internalRep.dictSubstValue.indexObjPtr = srcPtr->internalRep.dictSubstValue.indexObjPtr; + dupPtr->typePtr = &dictSubstObjType; +} + +/* Note: The object *must* be in dict-sugar format */ +static void SetDictSubstFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr->typePtr != &dictSubstObjType) { + Jim_Obj *varObjPtr, *keyObjPtr; + + if (objPtr->typePtr == &interpolatedObjType) { + /* An interpolated object in dict-sugar form */ + + varObjPtr = objPtr->internalRep.dictSubstValue.varNameObjPtr; + keyObjPtr = objPtr->internalRep.dictSubstValue.indexObjPtr; + + Jim_IncrRefCount(varObjPtr); + Jim_IncrRefCount(keyObjPtr); + } + else { + JimDictSugarParseVarKey(interp, objPtr, &varObjPtr, &keyObjPtr); + } + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &dictSubstObjType; + objPtr->internalRep.dictSubstValue.varNameObjPtr = varObjPtr; + objPtr->internalRep.dictSubstValue.indexObjPtr = keyObjPtr; + } +} + +/* This function is used to expand [dict get] sugar in the form + * of $var(INDEX). The function is mainly used by Jim_EvalObj() + * to deal with tokens of type JIM_TT_DICTSUGAR. objPtr points to an + * object that is *guaranteed* to be in the form VARNAME(INDEX). + * The 'index' part is [subst]ituted, and is used to lookup a key inside + * the [dict]ionary contained in variable VARNAME. */ +static Jim_Obj *JimExpandDictSugar(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_Obj *resObjPtr = NULL; + Jim_Obj *substKeyObjPtr = NULL; + + SetDictSubstFromAny(interp, objPtr); + + if (Jim_SubstObj(interp, objPtr->internalRep.dictSubstValue.indexObjPtr, + &substKeyObjPtr, JIM_NONE) + != JIM_OK) { + return NULL; + } + Jim_IncrRefCount(substKeyObjPtr); + resObjPtr = + JimDictExpandArrayVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, + substKeyObjPtr, 0); + Jim_DecrRefCount(interp, substKeyObjPtr); + + return resObjPtr; +} + +static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_Obj *resultObjPtr; + + if (Jim_EvalExpression(interp, objPtr, &resultObjPtr) == JIM_OK) { + /* Note that the result has a ref count of 1, but we need a ref count of 0 */ + resultObjPtr->refCount--; + return resultObjPtr; + } + return NULL; +} + +/* ----------------------------------------------------------------------------- + * CallFrame + * ---------------------------------------------------------------------------*/ + +static Jim_CallFrame *JimCreateCallFrame(Jim_Interp *interp, Jim_CallFrame *parent, Jim_Obj *nsObj) +{ + Jim_CallFrame *cf; + + if (interp->freeFramesList) { + cf = interp->freeFramesList; + interp->freeFramesList = cf->next; + } + else { + cf = Jim_Alloc(sizeof(*cf)); + cf->vars.table = NULL; + } + + cf->id = interp->callFrameEpoch++; + cf->parent = parent; + cf->level = parent ? parent->level + 1 : 0; + cf->argv = NULL; + cf->argc = 0; + cf->procArgsObjPtr = NULL; + cf->procBodyObjPtr = NULL; + cf->next = NULL; + cf->staticVars = NULL; + cf->localCommands = NULL; + + cf->nsObj = nsObj; + Jim_IncrRefCount(nsObj); + if (cf->vars.table == NULL) + Jim_InitHashTable(&cf->vars, &JimVariablesHashTableType, interp); + return cf; +} + +/* Used to invalidate every caching related to callframe stability. */ +static void JimChangeCallFrameId(Jim_Interp *interp, Jim_CallFrame *cf) +{ + cf->id = interp->callFrameEpoch++; +} + +static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands) +{ + /* Delete any local procs */ + if (localCommands) { + Jim_Obj *cmdNameObj; + + while ((cmdNameObj = Jim_StackPop(localCommands)) != NULL) { + Jim_HashEntry *he; + Jim_Obj *fqObjName; + + const char *fqname = JimQualifyName(interp, Jim_String(cmdNameObj), &fqObjName); + + he = Jim_FindHashEntry(&interp->commands, fqname); + + if (he) { + Jim_Cmd *cmd = he->u.val; + if (cmd->prevCmd) { + Jim_Cmd *prevCmd = cmd->prevCmd; + cmd->prevCmd = NULL; + + /* Delete the old command */ + JimDecrCmdRefCount(interp, cmd); + + /* And restore the original */ + he->u.val = prevCmd; + } + else { + Jim_DeleteHashEntry(&interp->commands, fqname); + Jim_InterpIncrProcEpoch(interp); + } + } + Jim_DecrRefCount(interp, cmdNameObj); + JimFreeQualifiedName(interp, fqObjName); + } + Jim_FreeStack(localCommands); + Jim_Free(localCommands); + } + return JIM_OK; +} + + +#define JIM_FCF_NONE 0 /* no flags */ +#define JIM_FCF_NOHT 1 /* don't free the hash table */ +static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int flags) +{ + if (cf->procArgsObjPtr) + Jim_DecrRefCount(interp, cf->procArgsObjPtr); + if (cf->procBodyObjPtr) + Jim_DecrRefCount(interp, cf->procBodyObjPtr); + Jim_DecrRefCount(interp, cf->nsObj); + if (!(flags & JIM_FCF_NOHT)) + Jim_FreeHashTable(&cf->vars); + else { + int i; + Jim_HashEntry **table = cf->vars.table, *he; + + for (i = 0; i < JIM_HT_INITIAL_SIZE; i++) { + he = table[i]; + while (he != NULL) { + Jim_HashEntry *nextEntry = he->next; + Jim_Var *varPtr = (void *)he->u.val; + + Jim_DecrRefCount(interp, varPtr->objPtr); + Jim_Free(he->u.val); + Jim_Free((void *)he->key); /* ATTENTION: const cast */ + Jim_Free(he); + table[i] = NULL; + he = nextEntry; + } + } + cf->vars.used = 0; + } + + JimDeleteLocalProcs(interp, cf->localCommands); + + cf->next = interp->freeFramesList; + interp->freeFramesList = cf; + +} + + +/* ----------------------------------------------------------------------------- + * References + * ---------------------------------------------------------------------------*/ +#ifdef JIM_REFERENCES + +/* References HashTable Type. + * + * Keys are unsigned long integers, dynamically allocated for now but in the + * future it's worth to cache this 4 bytes objects. Values are pointers + * to Jim_References. */ +static void JimReferencesHTValDestructor(void *interp, void *val) +{ + Jim_Reference *refPtr = (void *)val; + + Jim_DecrRefCount(interp, refPtr->objPtr); + if (refPtr->finalizerCmdNamePtr != NULL) { + Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr); + } + Jim_Free(val); +} + +static unsigned int JimReferencesHTHashFunction(const void *key) +{ + /* Only the least significant bits are used. */ + const unsigned long *widePtr = key; + unsigned int intValue = (unsigned int)*widePtr; + + return Jim_IntHashFunction(intValue); +} + +static void *JimReferencesHTKeyDup(void *privdata, const void *key) +{ + void *copy = Jim_Alloc(sizeof(unsigned long)); + + JIM_NOTUSED(privdata); + + memcpy(copy, key, sizeof(unsigned long)); + return copy; +} + +static int JimReferencesHTKeyCompare(void *privdata, const void *key1, const void *key2) +{ + JIM_NOTUSED(privdata); + + return memcmp(key1, key2, sizeof(unsigned long)) == 0; +} + +static void JimReferencesHTKeyDestructor(void *privdata, void *key) +{ + JIM_NOTUSED(privdata); + + Jim_Free(key); +} + +static const Jim_HashTableType JimReferencesHashTableType = { + JimReferencesHTHashFunction, /* hash function */ + JimReferencesHTKeyDup, /* key dup */ + NULL, /* val dup */ + JimReferencesHTKeyCompare, /* key compare */ + JimReferencesHTKeyDestructor, /* key destructor */ + JimReferencesHTValDestructor /* val destructor */ +}; + +/* ----------------------------------------------------------------------------- + * Reference object type and References API + * ---------------------------------------------------------------------------*/ + +/* The string representation of references has two features in order + * to make the GC faster. The first is that every reference starts + * with a non common character '<', in order to make the string matching + * faster. The second is that the reference string rep is 42 characters + * in length, this allows to avoid to check every object with a string + * repr < 42, and usually there aren't many of these objects. */ + +#define JIM_REFERENCE_SPACE (35+JIM_REFERENCE_TAGLEN) + +static int JimFormatReference(char *buf, Jim_Reference *refPtr, unsigned long id) +{ + const char *fmt = ".%020lu>"; + + sprintf(buf, fmt, refPtr->tag, id); + return JIM_REFERENCE_SPACE; +} + +static void UpdateStringOfReference(struct Jim_Obj *objPtr); + +static const Jim_ObjType referenceObjType = { + "reference", + NULL, + NULL, + UpdateStringOfReference, + JIM_TYPE_REFERENCES, +}; + +void UpdateStringOfReference(struct Jim_Obj *objPtr) +{ + int len; + char buf[JIM_REFERENCE_SPACE + 1]; + Jim_Reference *refPtr; + + refPtr = objPtr->internalRep.refValue.refPtr; + len = JimFormatReference(buf, refPtr, objPtr->internalRep.refValue.id); + objPtr->bytes = Jim_Alloc(len + 1); + memcpy(objPtr->bytes, buf, len + 1); + objPtr->length = len; +} + +/* returns true if 'c' is a valid reference tag character. + * i.e. inside the range [_a-zA-Z0-9] */ +static int isrefchar(int c) +{ + return (c == '_' || isalnum(c)); +} + +static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + unsigned long value; + int i, len; + const char *str, *start, *end; + char refId[21]; + Jim_Reference *refPtr; + Jim_HashEntry *he; + char *endptr; + + /* Get the string representation */ + str = Jim_GetString(objPtr, &len); + /* Check if it looks like a reference */ + if (len < JIM_REFERENCE_SPACE) + goto badformat; + /* Trim spaces */ + start = str; + end = str + len - 1; + while (*start == ' ') + start++; + while (*end == ' ' && end > start) + end--; + if (end - start + 1 != JIM_REFERENCE_SPACE) + goto badformat; + /* .%020> */ + if (memcmp(start, "references, &value); + if (he == NULL) { + Jim_SetResultFormatted(interp, "invalid reference id \"%#s\"", objPtr); + return JIM_ERR; + } + refPtr = he->u.val; + /* Free the old internal repr and set the new one. */ + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &referenceObjType; + objPtr->internalRep.refValue.id = value; + objPtr->internalRep.refValue.refPtr = refPtr; + return JIM_OK; + + badformat: + Jim_SetResultFormatted(interp, "expected reference but got \"%#s\"", objPtr); + return JIM_ERR; +} + +/* Returns a new reference pointing to objPtr, having cmdNamePtr + * as finalizer command (or NULL if there is no finalizer). + * The returned reference object has refcount = 0. */ +Jim_Obj *Jim_NewReference(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr) +{ + struct Jim_Reference *refPtr; + unsigned long id; + Jim_Obj *refObjPtr; + const char *tag; + int tagLen, i; + + /* Perform the Garbage Collection if needed. */ + Jim_CollectIfNeeded(interp); + + refPtr = Jim_Alloc(sizeof(*refPtr)); + refPtr->objPtr = objPtr; + Jim_IncrRefCount(objPtr); + refPtr->finalizerCmdNamePtr = cmdNamePtr; + if (cmdNamePtr) + Jim_IncrRefCount(cmdNamePtr); + id = interp->referenceNextId++; + Jim_AddHashEntry(&interp->references, &id, refPtr); + refObjPtr = Jim_NewObj(interp); + refObjPtr->typePtr = &referenceObjType; + refObjPtr->bytes = NULL; + refObjPtr->internalRep.refValue.id = id; + refObjPtr->internalRep.refValue.refPtr = refPtr; + interp->referenceNextId++; + /* Set the tag. Trimmed at JIM_REFERENCE_TAGLEN. Everything + * that does not pass the 'isrefchar' test is replaced with '_' */ + tag = Jim_GetString(tagPtr, &tagLen); + if (tagLen > JIM_REFERENCE_TAGLEN) + tagLen = JIM_REFERENCE_TAGLEN; + for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) { + if (i < tagLen && isrefchar(tag[i])) + refPtr->tag[i] = tag[i]; + else + refPtr->tag[i] = '_'; + } + refPtr->tag[JIM_REFERENCE_TAGLEN] = '\0'; + return refObjPtr; +} + +Jim_Reference *Jim_GetReference(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr->typePtr != &referenceObjType && SetReferenceFromAny(interp, objPtr) == JIM_ERR) + return NULL; + return objPtr->internalRep.refValue.refPtr; +} + +int Jim_SetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *cmdNamePtr) +{ + Jim_Reference *refPtr; + + if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL) + return JIM_ERR; + Jim_IncrRefCount(cmdNamePtr); + if (refPtr->finalizerCmdNamePtr) + Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr); + refPtr->finalizerCmdNamePtr = cmdNamePtr; + return JIM_OK; +} + +int Jim_GetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj **cmdNamePtrPtr) +{ + Jim_Reference *refPtr; + + if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL) + return JIM_ERR; + *cmdNamePtrPtr = refPtr->finalizerCmdNamePtr; + return JIM_OK; +} + +/* ----------------------------------------------------------------------------- + * References Garbage Collection + * ---------------------------------------------------------------------------*/ + +/* This the hash table type for the "MARK" phase of the GC */ +static const Jim_HashTableType JimRefMarkHashTableType = { + JimReferencesHTHashFunction, /* hash function */ + JimReferencesHTKeyDup, /* key dup */ + NULL, /* val dup */ + JimReferencesHTKeyCompare, /* key compare */ + JimReferencesHTKeyDestructor, /* key destructor */ + NULL /* val destructor */ +}; + +/* Performs the garbage collection. */ +int Jim_Collect(Jim_Interp *interp) +{ + int collected = 0; +#ifndef JIM_BOOTSTRAP + Jim_HashTable marks; + Jim_HashTableIterator htiter; + Jim_HashEntry *he; + Jim_Obj *objPtr; + + /* Avoid recursive calls */ + if (interp->lastCollectId == -1) { + /* Jim_Collect() already running. Return just now. */ + return 0; + } + interp->lastCollectId = -1; + + /* Mark all the references found into the 'mark' hash table. + * The references are searched in every live object that + * is of a type that can contain references. */ + Jim_InitHashTable(&marks, &JimRefMarkHashTableType, NULL); + objPtr = interp->liveList; + while (objPtr) { + if (objPtr->typePtr == NULL || objPtr->typePtr->flags & JIM_TYPE_REFERENCES) { + const char *str, *p; + int len; + + /* If the object is of type reference, to get the + * Id is simple... */ + if (objPtr->typePtr == &referenceObjType) { + Jim_AddHashEntry(&marks, &objPtr->internalRep.refValue.id, NULL); +#ifdef JIM_DEBUG_GC + printf("MARK (reference): %d refcount: %d" JIM_NL, + (int)objPtr->internalRep.refValue.id, objPtr->refCount); +#endif + objPtr = objPtr->nextObjPtr; + continue; + } + /* Get the string repr of the object we want + * to scan for references. */ + p = str = Jim_GetString(objPtr, &len); + /* Skip objects too little to contain references. */ + if (len < JIM_REFERENCE_SPACE) { + objPtr = objPtr->nextObjPtr; + continue; + } + /* Extract references from the object string repr. */ + while (1) { + int i; + unsigned long id; + + if ((p = strstr(p, "nextObjPtr; + } + + /* Run the references hash table to destroy every reference that + * is not referenced outside (not present in the mark HT). */ + JimInitHashTableIterator(&interp->references, &htiter); + while ((he = Jim_NextHashEntry(&htiter)) != NULL) { + const unsigned long *refId; + Jim_Reference *refPtr; + + refId = he->key; + /* Check if in the mark phase we encountered + * this reference. */ + if (Jim_FindHashEntry(&marks, refId) == NULL) { +#ifdef JIM_DEBUG_GC + printf("COLLECTING %d" JIM_NL, (int)*refId); +#endif + collected++; + /* Drop the reference, but call the + * finalizer first if registered. */ + refPtr = he->u.val; + if (refPtr->finalizerCmdNamePtr) { + char *refstr = Jim_Alloc(JIM_REFERENCE_SPACE + 1); + Jim_Obj *objv[3], *oldResult; + + JimFormatReference(refstr, refPtr, *refId); + + objv[0] = refPtr->finalizerCmdNamePtr; + objv[1] = Jim_NewStringObjNoAlloc(interp, refstr, JIM_REFERENCE_SPACE); + objv[2] = refPtr->objPtr; + + /* Drop the reference itself */ + /* Avoid the finaliser being freed here */ + Jim_IncrRefCount(objv[0]); + /* Don't remove the reference from the hash table just yet + * since that will free refPtr, and hence refPtr->objPtr + */ + + /* Call the finalizer. Errors ignored. */ + oldResult = interp->result; + Jim_IncrRefCount(oldResult); + Jim_EvalObjVector(interp, 3, objv); + Jim_SetResult(interp, oldResult); + Jim_DecrRefCount(interp, oldResult); + Jim_DeleteHashEntry(&interp->references, refId); + + Jim_DecrRefCount(interp, objv[0]); + } + else { + Jim_DeleteHashEntry(&interp->references, refId); + } + } + } + Jim_FreeHashTable(&marks); + interp->lastCollectId = interp->referenceNextId; + interp->lastCollectTime = time(NULL); +#endif /* JIM_BOOTSTRAP */ + return collected; +} + +#define JIM_COLLECT_ID_PERIOD 5000 +#define JIM_COLLECT_TIME_PERIOD 300 + +void Jim_CollectIfNeeded(Jim_Interp *interp) +{ + unsigned long elapsedId; + int elapsedTime; + + elapsedId = interp->referenceNextId - interp->lastCollectId; + elapsedTime = time(NULL) - interp->lastCollectTime; + + + if (elapsedId > JIM_COLLECT_ID_PERIOD || elapsedTime > JIM_COLLECT_TIME_PERIOD) { + Jim_Collect(interp); + } +} +#endif + +static int JimIsBigEndian(void) +{ + union { + unsigned short s; + unsigned char c[2]; + } uval = {0x0102}; + + return uval.c[0] == 1; +} + +/* ----------------------------------------------------------------------------- + * Interpreter related functions + * ---------------------------------------------------------------------------*/ + +Jim_Interp *Jim_CreateInterp(void) +{ + Jim_Interp *i = Jim_Alloc(sizeof(*i)); + + memset(i, 0, sizeof(*i)); + + i->maxCallFrameDepth = JIM_MAX_CALLFRAME_DEPTH; + i->maxEvalDepth = JIM_MAX_EVAL_DEPTH; + i->lastCollectTime = time(NULL); + + /* Note that we can create objects only after the + * interpreter liveList and freeList pointers are + * initialized to NULL. */ + Jim_InitHashTable(&i->commands, &JimCommandsHashTableType, i); +#ifdef JIM_REFERENCES + Jim_InitHashTable(&i->references, &JimReferencesHashTableType, i); +#endif + Jim_InitHashTable(&i->assocData, &JimAssocDataHashTableType, i); + Jim_InitHashTable(&i->packages, &JimPackageHashTableType, NULL); + i->emptyObj = Jim_NewEmptyStringObj(i); + i->trueObj = Jim_NewIntObj(i, 1); + i->falseObj = Jim_NewIntObj(i, 0); + i->framePtr = i->topFramePtr = JimCreateCallFrame(i, NULL, i->emptyObj); + i->errorFileNameObj = i->emptyObj; + i->result = i->emptyObj; + i->stackTrace = Jim_NewListObj(i, NULL, 0); + i->unknown = Jim_NewStringObj(i, "unknown", -1); + i->errorProc = i->emptyObj; + i->currentScriptObj = Jim_NewEmptyStringObj(i); + i->nullScriptObj = Jim_NewEmptyStringObj(i); + Jim_IncrRefCount(i->emptyObj); + Jim_IncrRefCount(i->errorFileNameObj); + Jim_IncrRefCount(i->result); + Jim_IncrRefCount(i->stackTrace); + Jim_IncrRefCount(i->unknown); + Jim_IncrRefCount(i->currentScriptObj); + Jim_IncrRefCount(i->nullScriptObj); + Jim_IncrRefCount(i->errorProc); + Jim_IncrRefCount(i->trueObj); + Jim_IncrRefCount(i->falseObj); + + /* Initialize key variables every interpreter should contain */ + Jim_SetVariableStrWithStr(i, JIM_LIBPATH, TCL_LIBRARY); + Jim_SetVariableStrWithStr(i, JIM_INTERACTIVE, "0"); + + Jim_SetVariableStrWithStr(i, "tcl_platform(os)", TCL_PLATFORM_OS); + Jim_SetVariableStrWithStr(i, "tcl_platform(platform)", TCL_PLATFORM_PLATFORM); + Jim_SetVariableStrWithStr(i, "tcl_platform(pathSeparator)", TCL_PLATFORM_PATH_SEPARATOR); + Jim_SetVariableStrWithStr(i, "tcl_platform(byteOrder)", JimIsBigEndian() ? "bigEndian" : "littleEndian"); + Jim_SetVariableStrWithStr(i, "tcl_platform(threaded)", "0"); + Jim_SetVariableStr(i, "tcl_platform(pointerSize)", Jim_NewIntObj(i, sizeof(void *))); + Jim_SetVariableStr(i, "tcl_platform(wordSize)", Jim_NewIntObj(i, sizeof(jim_wide))); + + return i; +} + +void Jim_FreeInterp(Jim_Interp *i) +{ + Jim_CallFrame *cf = i->framePtr, *prevcf, *nextcf; + Jim_Obj *objPtr, *nextObjPtr; + + Jim_DecrRefCount(i, i->emptyObj); + Jim_DecrRefCount(i, i->trueObj); + Jim_DecrRefCount(i, i->falseObj); + Jim_DecrRefCount(i, i->result); + Jim_DecrRefCount(i, i->stackTrace); + Jim_DecrRefCount(i, i->errorProc); + Jim_DecrRefCount(i, i->unknown); + Jim_DecrRefCount(i, i->errorFileNameObj); + Jim_DecrRefCount(i, i->currentScriptObj); + Jim_DecrRefCount(i, i->nullScriptObj); + Jim_FreeHashTable(&i->commands); +#ifdef JIM_REFERENCES + Jim_FreeHashTable(&i->references); +#endif + Jim_FreeHashTable(&i->packages); + Jim_Free(i->prngState); + Jim_FreeHashTable(&i->assocData); + + /* Free the call frames list */ + while (cf) { + prevcf = cf->parent; + JimFreeCallFrame(i, cf, JIM_FCF_NONE); + cf = prevcf; + } + /* Check that the live object list is empty, otherwise + * there is a memory leak. */ + if (i->liveList != NULL) { + objPtr = i->liveList; + + printf(JIM_NL "-------------------------------------" JIM_NL); + printf("Objects still in the free list:" JIM_NL); + while (objPtr) { + const char *type = objPtr->typePtr ? objPtr->typePtr->name : "string"; + + if (objPtr->bytes && strlen(objPtr->bytes) > 20) { + printf("%p (%d) %-10s: '%.20s...'" JIM_NL, + (void *)objPtr, objPtr->refCount, type, objPtr->bytes); + } + else { + printf("%p (%d) %-10s: '%s'" JIM_NL, + (void *)objPtr, objPtr->refCount, type, objPtr->bytes ? objPtr->bytes : "(null)"); + } + if (objPtr->typePtr == &sourceObjType) { + printf("FILE %s LINE %d" JIM_NL, + Jim_String(objPtr->internalRep.sourceValue.fileNameObj), + objPtr->internalRep.sourceValue.lineNumber); + } + objPtr = objPtr->nextObjPtr; + } + printf("-------------------------------------" JIM_NL JIM_NL); + JimPanic((1, "Live list non empty freeing the interpreter! Leak?")); + } + /* Free all the freed objects. */ + objPtr = i->freeList; + while (objPtr) { + nextObjPtr = objPtr->nextObjPtr; + Jim_Free(objPtr); + objPtr = nextObjPtr; + } + /* Free cached CallFrame structures */ + cf = i->freeFramesList; + while (cf) { + nextcf = cf->next; + if (cf->vars.table != NULL) + Jim_Free(cf->vars.table); + Jim_Free(cf); + cf = nextcf; + } +#ifdef jim_ext_load + Jim_FreeLoadHandles(i); +#endif + + /* Free the interpreter structure. */ + Jim_Free(i); +} + +/* Returns the call frame relative to the level represented by + * levelObjPtr. If levelObjPtr == NULL, the * level is assumed to be '1'. + * + * This function accepts the 'level' argument in the form + * of the commands [uplevel] and [upvar]. + * + * For a function accepting a relative integer as level suitable + * for implementation of [info level ?level?] check the + * JimGetCallFrameByInteger() function. + * + * Returns NULL on error. + */ +Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr) +{ + long level; + const char *str; + Jim_CallFrame *framePtr; + + if (levelObjPtr) { + str = Jim_String(levelObjPtr); + if (str[0] == '#') { + char *endptr; + + level = jim_strtol(str + 1, &endptr); + if (str[1] == '\0' || endptr[0] != '\0') { + level = -1; + } + } + else { + if (Jim_GetLong(interp, levelObjPtr, &level) != JIM_OK || level < 0) { + level = -1; + } + else { + /* Convert from a relative to an absolute level */ + level = interp->framePtr->level - level; + } + } + } + else { + str = "1"; /* Needed to format the error message. */ + level = interp->framePtr->level - 1; + } + + if (level == 0) { + return interp->topFramePtr; + } + if (level > 0) { + /* Lookup */ + for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) { + if (framePtr->level == level) { + return framePtr; + } + } + } + + Jim_SetResultFormatted(interp, "bad level \"%s\"", str); + return NULL; +} + +/* Similar to Jim_GetCallFrameByLevel() but the level is specified + * as a relative integer like in the [info level ?level?] command. + **/ +static Jim_CallFrame *JimGetCallFrameByInteger(Jim_Interp *interp, Jim_Obj *levelObjPtr) +{ + long level; + Jim_CallFrame *framePtr; + + if (Jim_GetLong(interp, levelObjPtr, &level) == JIM_OK) { + if (level <= 0) { + /* Convert from a relative to an absolute level */ + level = interp->framePtr->level + level; + } + + if (level == 0) { + return interp->topFramePtr; + } + + /* Lookup */ + for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) { + if (framePtr->level == level) { + return framePtr; + } + } + } + + Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr); + return NULL; +} + +static void JimResetStackTrace(Jim_Interp *interp) +{ + Jim_DecrRefCount(interp, interp->stackTrace); + interp->stackTrace = Jim_NewListObj(interp, NULL, 0); + Jim_IncrRefCount(interp->stackTrace); +} + +static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj) +{ + int len; + + /* Increment reference first in case these are the same object */ + Jim_IncrRefCount(stackTraceObj); + Jim_DecrRefCount(interp, interp->stackTrace); + interp->stackTrace = stackTraceObj; + interp->errorFlag = 1; + + /* This is a bit ugly. + * If the filename of the last entry of the stack trace is empty, + * the next stack level should be added. + */ + len = Jim_ListLength(interp, interp->stackTrace); + if (len >= 3) { + Jim_Obj *filenameObj; + + Jim_ListIndex(interp, interp->stackTrace, len - 2, &filenameObj, JIM_NONE); + + Jim_GetString(filenameObj, &len); + + if (!Jim_Length(filenameObj)) { + interp->addStackTrace = 1; + } + } +} + +/* Returns 1 if the stack trace information was used or 0 if not */ +static void JimAppendStackTrace(Jim_Interp *interp, const char *procname, + Jim_Obj *fileNameObj, int linenr) +{ + if (strcmp(procname, "unknown") == 0) { + procname = ""; + } + if (!*procname && !Jim_Length(fileNameObj)) { + /* No useful info here */ + return; + } + + if (Jim_IsShared(interp->stackTrace)) { + Jim_DecrRefCount(interp, interp->stackTrace); + interp->stackTrace = Jim_DuplicateObj(interp, interp->stackTrace); + Jim_IncrRefCount(interp->stackTrace); + } + + /* If we have no procname but the previous element did, merge with that frame */ + if (!*procname && Jim_Length(fileNameObj)) { + /* Just a filename. Check the previous entry */ + int len = Jim_ListLength(interp, interp->stackTrace); + + if (len >= 3) { + Jim_Obj *objPtr; + if (Jim_ListIndex(interp, interp->stackTrace, len - 3, &objPtr, JIM_NONE) == JIM_OK && Jim_Length(objPtr)) { + /* Yes, the previous level had procname */ + if (Jim_ListIndex(interp, interp->stackTrace, len - 2, &objPtr, JIM_NONE) == JIM_OK && !Jim_Length(objPtr)) { + /* But no filename, so merge the new info with that frame */ + ListSetIndex(interp, interp->stackTrace, len - 2, fileNameObj, 0); + ListSetIndex(interp, interp->stackTrace, len - 1, Jim_NewIntObj(interp, linenr), 0); + return; + } + } + } + } + + Jim_ListAppendElement(interp, interp->stackTrace, Jim_NewStringObj(interp, procname, -1)); + Jim_ListAppendElement(interp, interp->stackTrace, fileNameObj); + Jim_ListAppendElement(interp, interp->stackTrace, Jim_NewIntObj(interp, linenr)); +} + +int Jim_SetAssocData(Jim_Interp *interp, const char *key, Jim_InterpDeleteProc * delProc, + void *data) +{ + AssocDataValue *assocEntryPtr = (AssocDataValue *) Jim_Alloc(sizeof(AssocDataValue)); + + assocEntryPtr->delProc = delProc; + assocEntryPtr->data = data; + return Jim_AddHashEntry(&interp->assocData, key, assocEntryPtr); +} + +void *Jim_GetAssocData(Jim_Interp *interp, const char *key) +{ + Jim_HashEntry *entryPtr = Jim_FindHashEntry(&interp->assocData, key); + + if (entryPtr != NULL) { + AssocDataValue *assocEntryPtr = (AssocDataValue *) entryPtr->u.val; + + return assocEntryPtr->data; + } + return NULL; +} + +int Jim_DeleteAssocData(Jim_Interp *interp, const char *key) +{ + return Jim_DeleteHashEntry(&interp->assocData, key); +} + +int Jim_GetExitCode(Jim_Interp *interp) +{ + return interp->exitCode; +} + +/* ----------------------------------------------------------------------------- + * Integer object + * ---------------------------------------------------------------------------*/ +static void UpdateStringOfInt(struct Jim_Obj *objPtr); +static int SetIntFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags); + +static const Jim_ObjType intObjType = { + "int", + NULL, + NULL, + UpdateStringOfInt, + JIM_TYPE_NONE, +}; + +/* A coerced double is closer to an int than a double. + * It is an int value temporarily masquerading as a double value. + * i.e. it has the same string value as an int and Jim_GetWide() + * succeeds, but also Jim_GetDouble() returns the value directly. + */ +static const Jim_ObjType coercedDoubleObjType = { + "coerced-double", + NULL, + NULL, + UpdateStringOfInt, + JIM_TYPE_NONE, +}; + + +static void UpdateStringOfInt(struct Jim_Obj *objPtr) +{ + int len; + char buf[JIM_INTEGER_SPACE + 1]; + + len = JimWideToString(buf, JimWideValue(objPtr)); + objPtr->bytes = Jim_Alloc(len + 1); + memcpy(objPtr->bytes, buf, len + 1); + objPtr->length = len; +} + +int SetIntFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + jim_wide wideValue; + const char *str; + + if (objPtr->typePtr == &coercedDoubleObjType) { + /* Simple switcheroo */ + objPtr->typePtr = &intObjType; + return JIM_OK; + } + + /* Get the string representation */ + str = Jim_String(objPtr); + /* Try to convert into a jim_wide */ + if (Jim_StringToWide(str, &wideValue, 0) != JIM_OK) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "expected integer but got \"%#s\"", objPtr); + } + return JIM_ERR; + } + if ((wideValue == JIM_WIDE_MIN || wideValue == JIM_WIDE_MAX) && errno == ERANGE) { + Jim_SetResultString(interp, "Integer value too big to be represented", -1); + return JIM_ERR; + } + /* Free the old internal repr and set the new one. */ + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &intObjType; + objPtr->internalRep.wideValue = wideValue; + return JIM_OK; +} + +#ifdef JIM_OPTIMIZATION +static int JimIsWide(Jim_Obj *objPtr) +{ + return objPtr->typePtr == &intObjType; +} +#endif + +int Jim_GetWide(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr) +{ + if (objPtr->typePtr != &intObjType && SetIntFromAny(interp, objPtr, JIM_ERRMSG) == JIM_ERR) + return JIM_ERR; + *widePtr = JimWideValue(objPtr); + return JIM_OK; +} + +/* Get a wide but does not set an error if the format is bad. */ +static int JimGetWideNoErr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr) +{ + if (objPtr->typePtr != &intObjType && SetIntFromAny(interp, objPtr, JIM_NONE) == JIM_ERR) + return JIM_ERR; + *widePtr = JimWideValue(objPtr); + return JIM_OK; +} + +int Jim_GetLong(Jim_Interp *interp, Jim_Obj *objPtr, long *longPtr) +{ + jim_wide wideValue; + int retval; + + retval = Jim_GetWide(interp, objPtr, &wideValue); + if (retval == JIM_OK) { + *longPtr = (long)wideValue; + return JIM_OK; + } + return JIM_ERR; +} + +Jim_Obj *Jim_NewIntObj(Jim_Interp *interp, jim_wide wideValue) +{ + Jim_Obj *objPtr; + + objPtr = Jim_NewObj(interp); + objPtr->typePtr = &intObjType; + objPtr->bytes = NULL; + objPtr->internalRep.wideValue = wideValue; + return objPtr; +} + +/* ----------------------------------------------------------------------------- + * Double object + * ---------------------------------------------------------------------------*/ +#define JIM_DOUBLE_SPACE 30 + +static void UpdateStringOfDouble(struct Jim_Obj *objPtr); +static int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr); + +static const Jim_ObjType doubleObjType = { + "double", + NULL, + NULL, + UpdateStringOfDouble, + JIM_TYPE_NONE, +}; + +void UpdateStringOfDouble(struct Jim_Obj *objPtr) +{ + int len; + char buf[JIM_DOUBLE_SPACE + 1]; + + len = Jim_DoubleToString(buf, objPtr->internalRep.doubleValue); + objPtr->bytes = Jim_Alloc(len + 1); + memcpy(objPtr->bytes, buf, len + 1); + objPtr->length = len; +} + +int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + double doubleValue; + jim_wide wideValue; + const char *str; + + /* Preserve the string representation. + * Needed so we can convert back to int without loss + */ + str = Jim_String(objPtr); + +#ifdef HAVE_LONG_LONG + /* Assume a 53 bit mantissa */ +#define MIN_INT_IN_DOUBLE -(1LL << 53) +#define MAX_INT_IN_DOUBLE -(MIN_INT_IN_DOUBLE + 1) + + if (objPtr->typePtr == &intObjType + && JimWideValue(objPtr) >= MIN_INT_IN_DOUBLE + && JimWideValue(objPtr) <= MAX_INT_IN_DOUBLE) { + + /* Direct conversion to coerced double */ + objPtr->typePtr = &coercedDoubleObjType; + return JIM_OK; + } + else +#endif + if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) { + /* Managed to convert to an int, so we can use this as a cooerced double */ + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &coercedDoubleObjType; + objPtr->internalRep.wideValue = wideValue; + return JIM_OK; + } + else { + /* Try to convert into a double */ + if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) { + Jim_SetResultFormatted(interp, "expected number but got \"%#s\"", objPtr); + return JIM_ERR; + } + /* Free the old internal repr and set the new one. */ + Jim_FreeIntRep(interp, objPtr); + } + objPtr->typePtr = &doubleObjType; + objPtr->internalRep.doubleValue = doubleValue; + return JIM_OK; +} + +int Jim_GetDouble(Jim_Interp *interp, Jim_Obj *objPtr, double *doublePtr) +{ + if (objPtr->typePtr == &coercedDoubleObjType) { + *doublePtr = JimWideValue(objPtr); + return JIM_OK; + } + if (objPtr->typePtr != &doubleObjType && SetDoubleFromAny(interp, objPtr) == JIM_ERR) + return JIM_ERR; + + if (objPtr->typePtr == &coercedDoubleObjType) { + *doublePtr = JimWideValue(objPtr); + } + else { + *doublePtr = objPtr->internalRep.doubleValue; + } + return JIM_OK; +} + +Jim_Obj *Jim_NewDoubleObj(Jim_Interp *interp, double doubleValue) +{ + Jim_Obj *objPtr; + + objPtr = Jim_NewObj(interp); + objPtr->typePtr = &doubleObjType; + objPtr->bytes = NULL; + objPtr->internalRep.doubleValue = doubleValue; + return objPtr; +} + +/* ----------------------------------------------------------------------------- + * List object + * ---------------------------------------------------------------------------*/ +static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec); +static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr); +static void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static void UpdateStringOfList(struct Jim_Obj *objPtr); +static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +/* Note that while the elements of the list may contain references, + * the list object itself can't. This basically means that the + * list object string representation as a whole can't contain references + * that are not presents in the single elements. */ +static const Jim_ObjType listObjType = { + "list", + FreeListInternalRep, + DupListInternalRep, + UpdateStringOfList, + JIM_TYPE_NONE, +}; + +void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + int i; + + for (i = 0; i < objPtr->internalRep.listValue.len; i++) { + Jim_DecrRefCount(interp, objPtr->internalRep.listValue.ele[i]); + } + Jim_Free(objPtr->internalRep.listValue.ele); +} + +void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + int i; + + JIM_NOTUSED(interp); + + dupPtr->internalRep.listValue.len = srcPtr->internalRep.listValue.len; + dupPtr->internalRep.listValue.maxLen = srcPtr->internalRep.listValue.maxLen; + dupPtr->internalRep.listValue.ele = + Jim_Alloc(sizeof(Jim_Obj *) * srcPtr->internalRep.listValue.maxLen); + memcpy(dupPtr->internalRep.listValue.ele, srcPtr->internalRep.listValue.ele, + sizeof(Jim_Obj *) * srcPtr->internalRep.listValue.len); + for (i = 0; i < dupPtr->internalRep.listValue.len; i++) { + Jim_IncrRefCount(dupPtr->internalRep.listValue.ele[i]); + } + dupPtr->typePtr = &listObjType; +} + +/* The following function checks if a given string can be encoded + * into a list element without any kind of quoting, surrounded by braces, + * or using escapes to quote. */ +#define JIM_ELESTR_SIMPLE 0 +#define JIM_ELESTR_BRACE 1 +#define JIM_ELESTR_QUOTE 2 +static unsigned char ListElementQuotingType(const char *s, int len) +{ + int i, level, blevel, trySimple = 1; + + /* Try with the SIMPLE case */ + if (len == 0) + return JIM_ELESTR_BRACE; + if (s[0] == '"' || s[0] == '{') { + trySimple = 0; + goto testbrace; + } + for (i = 0; i < len; i++) { + switch (s[i]) { + case ' ': + case '$': + case '"': + case '[': + case ']': + case ';': + case '\\': + case '\r': + case '\n': + case '\t': + case '\f': + case '\v': + trySimple = 0; + case '{': + case '}': + goto testbrace; + } + } + return JIM_ELESTR_SIMPLE; + + testbrace: + /* Test if it's possible to do with braces */ + if (s[len - 1] == '\\') + return JIM_ELESTR_QUOTE; + level = 0; + blevel = 0; + for (i = 0; i < len; i++) { + switch (s[i]) { + case '{': + level++; + break; + case '}': + level--; + if (level < 0) + return JIM_ELESTR_QUOTE; + break; + case '[': + blevel++; + break; + case ']': + blevel--; + break; + case '\\': + if (s[i + 1] == '\n') + return JIM_ELESTR_QUOTE; + else if (s[i + 1] != '\0') + i++; + break; + } + } + if (blevel < 0) { + return JIM_ELESTR_QUOTE; + } + + if (level == 0) { + if (!trySimple) + return JIM_ELESTR_BRACE; + for (i = 0; i < len; i++) { + switch (s[i]) { + case ' ': + case '$': + case '"': + case '[': + case ']': + case ';': + case '\\': + case '\r': + case '\n': + case '\t': + case '\f': + case '\v': + return JIM_ELESTR_BRACE; + break; + } + } + return JIM_ELESTR_SIMPLE; + } + return JIM_ELESTR_QUOTE; +} + +/* Backslashes-escapes the null-terminated string 's' into the buffer at 'q' + * The buffer must be at least strlen(s) * 2 + 1 bytes long for the worst-case + * scenario. + * Returns the length of the result. + */ +static int BackslashQuoteString(const char *s, char *q) +{ + char *p = q; + + while (*s) { + switch (*s) { + case ' ': + case '$': + case '"': + case '[': + case ']': + case '{': + case '}': + case ';': + case '\\': + *p++ = '\\'; + *p++ = *s++; + break; + case '\n': + *p++ = '\\'; + *p++ = 'n'; + s++; + break; + case '\r': + *p++ = '\\'; + *p++ = 'r'; + s++; + break; + case '\t': + *p++ = '\\'; + *p++ = 't'; + s++; + break; + case '\f': + *p++ = '\\'; + *p++ = 'f'; + s++; + break; + case '\v': + *p++ = '\\'; + *p++ = 'v'; + s++; + break; + default: + *p++ = *s++; + break; + } + } + *p = '\0'; + + return p - q; +} + +static void JimMakeListStringRep(Jim_Obj *objPtr, Jim_Obj **objv, int objc) +{ + #define STATIC_QUOTING_LEN 32 + int i, bufLen, realLength; + const char *strRep; + char *p; + unsigned char *quotingType, staticQuoting[STATIC_QUOTING_LEN]; + + /* Estimate the space needed. */ + if (objc > STATIC_QUOTING_LEN) { + quotingType = Jim_Alloc(objc); + } + else { + quotingType = staticQuoting; + } + bufLen = 0; + for (i = 0; i < objc; i++) { + int len; + + strRep = Jim_GetString(objv[i], &len); + quotingType[i] = ListElementQuotingType(strRep, len); + switch (quotingType[i]) { + case JIM_ELESTR_SIMPLE: + if (i != 0 || strRep[0] != '#') { + bufLen += len; + break; + } + /* Special case '#' on first element needs braces */ + quotingType[i] = JIM_ELESTR_BRACE; + /* fall through */ + case JIM_ELESTR_BRACE: + bufLen += len + 2; + break; + case JIM_ELESTR_QUOTE: + bufLen += len * 2; + break; + } + bufLen++; /* elements separator. */ + } + bufLen++; + + /* Generate the string rep. */ + p = objPtr->bytes = Jim_Alloc(bufLen + 1); + realLength = 0; + for (i = 0; i < objc; i++) { + int len, qlen; + + strRep = Jim_GetString(objv[i], &len); + + switch (quotingType[i]) { + case JIM_ELESTR_SIMPLE: + memcpy(p, strRep, len); + p += len; + realLength += len; + break; + case JIM_ELESTR_BRACE: + *p++ = '{'; + memcpy(p, strRep, len); + p += len; + *p++ = '}'; + realLength += len + 2; + break; + case JIM_ELESTR_QUOTE: + if (i == 0 && strRep[0] == '#') { + *p++ = '\\'; + realLength++; + } + qlen = BackslashQuoteString(strRep, p); + p += qlen; + realLength += qlen; + break; + } + /* Add a separating space */ + if (i + 1 != objc) { + *p++ = ' '; + realLength++; + } + } + *p = '\0'; /* nul term. */ + objPtr->length = realLength; + + if (quotingType != staticQuoting) { + Jim_Free(quotingType); + } +} + +static void UpdateStringOfList(struct Jim_Obj *objPtr) +{ + JimMakeListStringRep(objPtr, objPtr->internalRep.listValue.ele, objPtr->internalRep.listValue.len); +} + +static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + struct JimParserCtx parser; + const char *str; + int strLen; + Jim_Obj *fileNameObj; + int linenr; + + if (objPtr->typePtr == &listObjType) { + return JIM_OK; + } + + /* Optimise dict -> list for unshared object. Note that this may only save a little time, but + * it also preserves any source location of the dict elements + * which can be very useful + */ + if (Jim_IsDict(objPtr) && !Jim_IsShared(objPtr)) { + Jim_Obj **listObjPtrPtr; + int len; + int i; + + listObjPtrPtr = JimDictPairs(objPtr, &len); + for (i = 0; i < len; i++) { + Jim_IncrRefCount(listObjPtrPtr[i]); + } + + /* Now just switch the internal rep */ + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &listObjType; + objPtr->internalRep.listValue.len = len; + objPtr->internalRep.listValue.maxLen = len; + objPtr->internalRep.listValue.ele = listObjPtrPtr; + + return JIM_OK; + } + + /* Try to preserve information about filename / line number */ + if (objPtr->typePtr == &sourceObjType) { + fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; + linenr = objPtr->internalRep.sourceValue.lineNumber; + } + else { + fileNameObj = interp->emptyObj; + linenr = 1; + } + Jim_IncrRefCount(fileNameObj); + + /* Get the string representation */ + str = Jim_GetString(objPtr, &strLen); + + /* Free the old internal repr just now and initialize the + * new one just now. The string->list conversion can't fail. */ + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &listObjType; + objPtr->internalRep.listValue.len = 0; + objPtr->internalRep.listValue.maxLen = 0; + objPtr->internalRep.listValue.ele = NULL; + + /* Convert into a list */ + if (strLen) { + JimParserInit(&parser, str, strLen, linenr); + while (!parser.eof) { + Jim_Obj *elementPtr; + + JimParseList(&parser); + if (parser.tt != JIM_TT_STR && parser.tt != JIM_TT_ESC) + continue; + elementPtr = JimParserGetTokenObj(interp, &parser); + JimSetSourceInfo(interp, elementPtr, fileNameObj, parser.tline); + ListAppendElement(objPtr, elementPtr); + } + } + Jim_DecrRefCount(interp, fileNameObj); + return JIM_OK; +} + +Jim_Obj *Jim_NewListObj(Jim_Interp *interp, Jim_Obj *const *elements, int len) +{ + Jim_Obj *objPtr; + + objPtr = Jim_NewObj(interp); + objPtr->typePtr = &listObjType; + objPtr->bytes = NULL; + objPtr->internalRep.listValue.ele = NULL; + objPtr->internalRep.listValue.len = 0; + objPtr->internalRep.listValue.maxLen = 0; + + if (len) { + ListInsertElements(objPtr, 0, len, elements); + } + + return objPtr; +} + +/* Return a vector of Jim_Obj with the elements of a Jim list, and the + * length of the vector. Note that the user of this function should make + * sure that the list object can't shimmer while the vector returned + * is in use, this vector is the one stored inside the internal representation + * of the list object. This function is not exported, extensions should + * always access to the List object elements using Jim_ListIndex(). */ +static void JimListGetElements(Jim_Interp *interp, Jim_Obj *listObj, int *listLen, + Jim_Obj ***listVec) +{ + *listLen = Jim_ListLength(interp, listObj); + *listVec = listObj->internalRep.listValue.ele; +} + +/* Sorting uses ints, but commands may return wide */ +static int JimSign(jim_wide w) +{ + if (w == 0) { + return 0; + } + else if (w < 0) { + return -1; + } + return 1; +} + +/* ListSortElements type values */ +struct lsort_info { + jmp_buf jmpbuf; + Jim_Obj *command; + Jim_Interp *interp; + enum { + JIM_LSORT_ASCII, + JIM_LSORT_NOCASE, + JIM_LSORT_INTEGER, + JIM_LSORT_COMMAND + } type; + int order; + int index; + int indexed; + int (*subfn)(Jim_Obj **, Jim_Obj **); +}; + +static struct lsort_info *sort_info; + +static int ListSortIndexHelper(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + Jim_Obj *lObj, *rObj; + + if (Jim_ListIndex(sort_info->interp, *lhsObj, sort_info->index, &lObj, JIM_ERRMSG) != JIM_OK || + Jim_ListIndex(sort_info->interp, *rhsObj, sort_info->index, &rObj, JIM_ERRMSG) != JIM_OK) { + longjmp(sort_info->jmpbuf, JIM_ERR); + } + return sort_info->subfn(&lObj, &rObj); +} + +/* Sort the internal rep of a list. */ +static int ListSortString(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + return Jim_StringCompareObj(sort_info->interp, *lhsObj, *rhsObj, 0) * sort_info->order; +} + +static int ListSortStringNoCase(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + return Jim_StringCompareObj(sort_info->interp, *lhsObj, *rhsObj, 1) * sort_info->order; +} + +static int ListSortInteger(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + jim_wide lhs = 0, rhs = 0; + + if (Jim_GetWide(sort_info->interp, *lhsObj, &lhs) != JIM_OK || + Jim_GetWide(sort_info->interp, *rhsObj, &rhs) != JIM_OK) { + longjmp(sort_info->jmpbuf, JIM_ERR); + } + + return JimSign(lhs - rhs) * sort_info->order; +} + +static int ListSortCommand(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + Jim_Obj *compare_script; + int rc; + + jim_wide ret = 0; + + /* This must be a valid list */ + compare_script = Jim_DuplicateObj(sort_info->interp, sort_info->command); + Jim_ListAppendElement(sort_info->interp, compare_script, *lhsObj); + Jim_ListAppendElement(sort_info->interp, compare_script, *rhsObj); + + rc = Jim_EvalObj(sort_info->interp, compare_script); + + if (rc != JIM_OK || Jim_GetWide(sort_info->interp, Jim_GetResult(sort_info->interp), &ret) != JIM_OK) { + longjmp(sort_info->jmpbuf, rc); + } + + return JimSign(ret) * sort_info->order; +} + +/* Sort a list *in place*. MUST be called with non-shared objects. */ +static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsort_info *info) +{ + struct lsort_info *prev_info; + + typedef int (qsort_comparator) (const void *, const void *); + int (*fn) (Jim_Obj **, Jim_Obj **); + Jim_Obj **vector; + int len; + int rc; + + JimPanic((Jim_IsShared(listObjPtr), "Jim_ListSortElements called with shared object")); + SetListFromAny(interp, listObjPtr); + + /* Allow lsort to be called reentrantly */ + prev_info = sort_info; + sort_info = info; + + vector = listObjPtr->internalRep.listValue.ele; + len = listObjPtr->internalRep.listValue.len; + switch (info->type) { + case JIM_LSORT_ASCII: + fn = ListSortString; + break; + case JIM_LSORT_NOCASE: + fn = ListSortStringNoCase; + break; + case JIM_LSORT_INTEGER: + fn = ListSortInteger; + break; + case JIM_LSORT_COMMAND: + fn = ListSortCommand; + break; + default: + fn = NULL; /* avoid warning */ + JimPanic((1, "ListSort called with invalid sort type")); + } + + if (info->indexed) { + /* Need to interpose a "list index" function */ + info->subfn = fn; + fn = ListSortIndexHelper; + } + + if ((rc = setjmp(info->jmpbuf)) == 0) { + qsort(vector, len, sizeof(Jim_Obj *), (qsort_comparator *) fn); + } + Jim_InvalidateStringRep(listObjPtr); + sort_info = prev_info; + + return rc; +} + +/* This is the low-level function to insert elements into a list. + * The higher-level Jim_ListInsertElements() performs shared object + * check and invalidate the string repr. This version is used + * in the internals of the List Object and is not exported. + * + * NOTE: this function can be called only against objects + * with internal type of List. + * + * An insertion point (idx) of -1 means end-of-list. + */ +static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec) +{ + int currentLen = listPtr->internalRep.listValue.len; + int requiredLen = currentLen + elemc; + int i; + Jim_Obj **point; + + if (requiredLen > listPtr->internalRep.listValue.maxLen) { + if (requiredLen < 2) { + /* Don't do allocations of under 4 pointers. */ + requiredLen = 4; + } + else { + requiredLen *= 2; + } + + listPtr->internalRep.listValue.ele = Jim_Realloc(listPtr->internalRep.listValue.ele, + sizeof(Jim_Obj *) * requiredLen); + + listPtr->internalRep.listValue.maxLen = requiredLen; + } + if (idx < 0) { + idx = currentLen; + } + point = listPtr->internalRep.listValue.ele + idx; + memmove(point + elemc, point, (currentLen - idx) * sizeof(Jim_Obj *)); + for (i = 0; i < elemc; ++i) { + point[i] = elemVec[i]; + Jim_IncrRefCount(point[i]); + } + listPtr->internalRep.listValue.len += elemc; +} + +/* Convenience call to ListInsertElements() to append a single element. + */ +static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr) +{ + ListInsertElements(listPtr, -1, 1, &objPtr); +} + +/* Appends every element of appendListPtr into listPtr. + * Both have to be of the list type. + * Convenience call to ListInsertElements() + */ +static void ListAppendList(Jim_Obj *listPtr, Jim_Obj *appendListPtr) +{ + ListInsertElements(listPtr, -1, + appendListPtr->internalRep.listValue.len, appendListPtr->internalRep.listValue.ele); +} + +void Jim_ListAppendElement(Jim_Interp *interp, Jim_Obj *listPtr, Jim_Obj *objPtr) +{ + JimPanic((Jim_IsShared(listPtr), "Jim_ListAppendElement called with shared object")); + SetListFromAny(interp, listPtr); + Jim_InvalidateStringRep(listPtr); + ListAppendElement(listPtr, objPtr); +} + +void Jim_ListAppendList(Jim_Interp *interp, Jim_Obj *listPtr, Jim_Obj *appendListPtr) +{ + JimPanic((Jim_IsShared(listPtr), "Jim_ListAppendList called with shared object")); + SetListFromAny(interp, listPtr); + SetListFromAny(interp, appendListPtr); + Jim_InvalidateStringRep(listPtr); + ListAppendList(listPtr, appendListPtr); +} + +int Jim_ListLength(Jim_Interp *interp, Jim_Obj *objPtr) +{ + SetListFromAny(interp, objPtr); + return objPtr->internalRep.listValue.len; +} + +void Jim_ListInsertElements(Jim_Interp *interp, Jim_Obj *listPtr, int idx, + int objc, Jim_Obj *const *objVec) +{ + JimPanic((Jim_IsShared(listPtr), "Jim_ListInsertElement called with shared object")); + SetListFromAny(interp, listPtr); + if (idx >= 0 && idx > listPtr->internalRep.listValue.len) + idx = listPtr->internalRep.listValue.len; + else if (idx < 0) + idx = 0; + Jim_InvalidateStringRep(listPtr); + ListInsertElements(listPtr, idx, objc, objVec); +} + +Jim_Obj *Jim_ListGetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx) +{ + SetListFromAny(interp, listPtr); + if ((idx >= 0 && idx >= listPtr->internalRep.listValue.len) || + (idx < 0 && (-idx - 1) >= listPtr->internalRep.listValue.len)) { + return NULL; + } + if (idx < 0) + idx = listPtr->internalRep.listValue.len + idx; + return listPtr->internalRep.listValue.ele[idx]; +} + +int Jim_ListIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx, Jim_Obj **objPtrPtr, int flags) +{ + *objPtrPtr = Jim_ListGetIndex(interp, listPtr, idx); + if (*objPtrPtr == NULL) { + if (flags & JIM_ERRMSG) { + Jim_SetResultString(interp, "list index out of range", -1); + } + return JIM_ERR; + } + return JIM_OK; +} + +static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx, + Jim_Obj *newObjPtr, int flags) +{ + SetListFromAny(interp, listPtr); + if ((idx >= 0 && idx >= listPtr->internalRep.listValue.len) || + (idx < 0 && (-idx - 1) >= listPtr->internalRep.listValue.len)) { + if (flags & JIM_ERRMSG) { + Jim_SetResultString(interp, "list index out of range", -1); + } + return JIM_ERR; + } + if (idx < 0) + idx = listPtr->internalRep.listValue.len + idx; + Jim_DecrRefCount(interp, listPtr->internalRep.listValue.ele[idx]); + listPtr->internalRep.listValue.ele[idx] = newObjPtr; + Jim_IncrRefCount(newObjPtr); + return JIM_OK; +} + +/* Modify the list stored into the variable named 'varNamePtr' + * setting the element specified by the 'indexc' indexes objects in 'indexv', + * with the new element 'newObjptr'. */ +int Jim_SetListIndex(Jim_Interp *interp, Jim_Obj *varNamePtr, + Jim_Obj *const *indexv, int indexc, Jim_Obj *newObjPtr) +{ + Jim_Obj *varObjPtr, *objPtr, *listObjPtr; + int shared, i, idx; + + varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG | JIM_UNSHARED); + if (objPtr == NULL) + return JIM_ERR; + if ((shared = Jim_IsShared(objPtr))) + varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr); + for (i = 0; i < indexc - 1; i++) { + listObjPtr = objPtr; + if (Jim_GetIndex(interp, indexv[i], &idx) != JIM_OK) + goto err; + if (Jim_ListIndex(interp, listObjPtr, idx, &objPtr, JIM_ERRMSG) != JIM_OK) { + goto err; + } + if (Jim_IsShared(objPtr)) { + objPtr = Jim_DuplicateObj(interp, objPtr); + ListSetIndex(interp, listObjPtr, idx, objPtr, JIM_NONE); + } + Jim_InvalidateStringRep(listObjPtr); + } + if (Jim_GetIndex(interp, indexv[indexc - 1], &idx) != JIM_OK) + goto err; + if (ListSetIndex(interp, objPtr, idx, newObjPtr, JIM_ERRMSG) == JIM_ERR) + goto err; + Jim_InvalidateStringRep(objPtr); + Jim_InvalidateStringRep(varObjPtr); + if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) + goto err; + Jim_SetResult(interp, varObjPtr); + return JIM_OK; + err: + if (shared) { + Jim_FreeNewObj(interp, varObjPtr); + } + return JIM_ERR; +} + +Jim_Obj *Jim_ListJoin(Jim_Interp *interp, Jim_Obj *listObjPtr, const char *joinStr, int joinStrLen) +{ + int i; + int listLen = Jim_ListLength(interp, listObjPtr); + Jim_Obj *resObjPtr = Jim_NewEmptyStringObj(interp); + + for (i = 0; i < listLen; ) { + Jim_Obj *objPtr; + + Jim_ListIndex(interp, listObjPtr, i, &objPtr, JIM_NONE); + Jim_AppendObj(interp, resObjPtr, objPtr); + if (++i != listLen) { + Jim_AppendString(interp, resObjPtr, joinStr, joinStrLen); + } + } + return resObjPtr; +} + +Jim_Obj *Jim_ConcatObj(Jim_Interp *interp, int objc, Jim_Obj *const *objv) +{ + int i; + + /* If all the objects in objv are lists, + * it's possible to return a list as result, that's the + * concatenation of all the lists. */ + for (i = 0; i < objc; i++) { + if (!Jim_IsList(objv[i])) + break; + } + if (i == objc) { + Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); + + for (i = 0; i < objc; i++) + ListAppendList(objPtr, objv[i]); + return objPtr; + } + else { + /* Else... we have to glue strings together */ + int len = 0, objLen; + char *bytes, *p; + + /* Compute the length */ + for (i = 0; i < objc; i++) { + Jim_GetString(objv[i], &objLen); + len += objLen; + } + if (objc) + len += objc - 1; + /* Create the string rep, and a string object holding it. */ + p = bytes = Jim_Alloc(len + 1); + for (i = 0; i < objc; i++) { + const char *s = Jim_GetString(objv[i], &objLen); + + /* Remove leading space */ + while (objLen && (*s == ' ' || *s == '\t' || *s == '\n')) { + s++; + objLen--; + len--; + } + /* And trailing space */ + while (objLen && (s[objLen - 1] == ' ' || + s[objLen - 1] == '\n' || s[objLen - 1] == '\t')) { + /* Handle trailing backslash-space case */ + if (objLen > 1 && s[objLen - 2] == '\\') { + break; + } + objLen--; + len--; + } + memcpy(p, s, objLen); + p += objLen; + if (objLen && i + 1 != objc) { + *p++ = ' '; + } + else if (i + 1 != objc) { + /* Drop the space calcuated for this + * element that is instead null. */ + len--; + } + } + *p = '\0'; + return Jim_NewStringObjNoAlloc(interp, bytes, len); + } +} + +/* Returns a list composed of the elements in the specified range. + * first and start are directly accepted as Jim_Objects and + * processed for the end?-index? case. */ +Jim_Obj *Jim_ListRange(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *firstObjPtr, + Jim_Obj *lastObjPtr) +{ + int first, last; + int len, rangeLen; + + if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK || + Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK) + return NULL; + len = Jim_ListLength(interp, listObjPtr); /* will convert into list */ + first = JimRelToAbsIndex(len, first); + last = JimRelToAbsIndex(len, last); + JimRelToAbsRange(len, &first, &last, &rangeLen); + if (first == 0 && last == len) { + return listObjPtr; + } + return Jim_NewListObj(interp, listObjPtr->internalRep.listValue.ele + first, rangeLen); +} + +/* ----------------------------------------------------------------------------- + * Dict object + * ---------------------------------------------------------------------------*/ +static void FreeDictInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupDictInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static void UpdateStringOfDict(struct Jim_Obj *objPtr); +static int SetDictFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +/* Dict HashTable Type. + * + * Keys and Values are Jim objects. */ + +static unsigned int JimObjectHTHashFunction(const void *key) +{ + int len; + const char *str = Jim_GetString((Jim_Obj *)key, &len); + return Jim_GenHashFunction((const unsigned char *)str, len); +} + +static int JimObjectHTKeyCompare(void *privdata, const void *key1, const void *key2) +{ + return Jim_StringEqObj((Jim_Obj *)key1, (Jim_Obj *)key2); +} + +static void JimObjectHTKeyValDestructor(void *interp, void *val) +{ + Jim_DecrRefCount(interp, (Jim_Obj *)val); +} + +static const Jim_HashTableType JimDictHashTableType = { + JimObjectHTHashFunction, /* hash function */ + NULL, /* key dup */ + NULL, /* val dup */ + JimObjectHTKeyCompare, /* key compare */ + JimObjectHTKeyValDestructor, /* key destructor */ + JimObjectHTKeyValDestructor /* val destructor */ +}; + +/* Note that while the elements of the dict may contain references, + * the list object itself can't. This basically means that the + * dict object string representation as a whole can't contain references + * that are not presents in the single elements. */ +static const Jim_ObjType dictObjType = { + "dict", + FreeDictInternalRep, + DupDictInternalRep, + UpdateStringOfDict, + JIM_TYPE_NONE, +}; + +void FreeDictInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + JIM_NOTUSED(interp); + + Jim_FreeHashTable(objPtr->internalRep.ptr); + Jim_Free(objPtr->internalRep.ptr); +} + +void DupDictInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + Jim_HashTable *ht, *dupHt; + Jim_HashTableIterator htiter; + Jim_HashEntry *he; + + /* Create a new hash table */ + ht = srcPtr->internalRep.ptr; + dupHt = Jim_Alloc(sizeof(*dupHt)); + Jim_InitHashTable(dupHt, &JimDictHashTableType, interp); + if (ht->size != 0) + Jim_ExpandHashTable(dupHt, ht->size); + /* Copy every element from the source to the dup hash table */ + JimInitHashTableIterator(ht, &htiter); + while ((he = Jim_NextHashEntry(&htiter)) != NULL) { + const Jim_Obj *keyObjPtr = he->key; + Jim_Obj *valObjPtr = he->u.val; + + Jim_IncrRefCount((Jim_Obj *)keyObjPtr); /* ATTENTION: const cast */ + Jim_IncrRefCount(valObjPtr); + Jim_AddHashEntry(dupHt, keyObjPtr, valObjPtr); + } + + dupPtr->internalRep.ptr = dupHt; + dupPtr->typePtr = &dictObjType; +} + +static Jim_Obj **JimDictPairs(Jim_Obj *dictPtr, int *len) +{ + Jim_HashTable *ht; + Jim_HashTableIterator htiter; + Jim_HashEntry *he; + Jim_Obj **objv; + int i; + + ht = dictPtr->internalRep.ptr; + + /* Turn the hash table into a flat vector of Jim_Objects. */ + objv = Jim_Alloc((ht->used * 2) * sizeof(Jim_Obj *)); + JimInitHashTableIterator(ht, &htiter); + i = 0; + while ((he = Jim_NextHashEntry(&htiter)) != NULL) { + objv[i++] = (Jim_Obj *)he->key; + objv[i++] = he->u.val; + } + *len = i; + return objv; +} + +static void UpdateStringOfDict(struct Jim_Obj *objPtr) +{ + /* Turn the hash table into a flat vector of Jim_Objects. */ + int len; + Jim_Obj **objv = JimDictPairs(objPtr, &len); + + JimMakeListStringRep(objPtr, objv, len); + + Jim_Free(objv); +} + +static int SetDictFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + int listlen; + + if (objPtr->typePtr == &dictObjType) { + return JIM_OK; + } + + /* Get the string representation. Do this first so we don't + * change order in case of fast conversion to dict. + */ + Jim_String(objPtr); + + /* For simplicity, convert a non-list object to a list and then to a dict */ + listlen = Jim_ListLength(interp, objPtr); + if (listlen % 2) { + Jim_SetResultString(interp, "missing value to go with key", -1); + return JIM_ERR; + } + else { + /* Now it is easy to convert to a dict from a list, and it can't fail */ + Jim_HashTable *ht; + int i; + + ht = Jim_Alloc(sizeof(*ht)); + Jim_InitHashTable(ht, &JimDictHashTableType, interp); + + for (i = 0; i < listlen; i += 2) { + Jim_Obj *keyObjPtr; + Jim_Obj *valObjPtr; + + Jim_ListIndex(interp, objPtr, i, &keyObjPtr, JIM_NONE); + Jim_ListIndex(interp, objPtr, i + 1, &valObjPtr, JIM_NONE); + + Jim_IncrRefCount(keyObjPtr); + Jim_IncrRefCount(valObjPtr); + + if (Jim_AddHashEntry(ht, keyObjPtr, valObjPtr) != JIM_OK) { + Jim_HashEntry *he; + + he = Jim_FindHashEntry(ht, keyObjPtr); + Jim_DecrRefCount(interp, keyObjPtr); + /* ATTENTION: const cast */ + Jim_DecrRefCount(interp, (Jim_Obj *)he->u.val); + he->u.val = valObjPtr; + } + } + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &dictObjType; + objPtr->internalRep.ptr = ht; + + return JIM_OK; + } +} + +/* Dict object API */ + +/* Add an element to a dict. objPtr must be of the "dict" type. + * The higer-level exported function is Jim_DictAddElement(). + * If an element with the specified key already exists, the value + * associated is replaced with the new one. + * + * if valueObjPtr == NULL, the key is instead removed if it exists. */ +static int DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr) +{ + Jim_HashTable *ht = objPtr->internalRep.ptr; + + if (valueObjPtr == NULL) { /* unset */ + return Jim_DeleteHashEntry(ht, keyObjPtr); + } + Jim_IncrRefCount(keyObjPtr); + Jim_IncrRefCount(valueObjPtr); + if (Jim_ReplaceHashEntry(ht, keyObjPtr, valueObjPtr)) { + /* Value existed, so need to decrement key ref count */ + Jim_DecrRefCount(interp, keyObjPtr); + } + return JIM_OK; +} + +/* Add an element, higher-level interface for DictAddElement(). + * If valueObjPtr == NULL, the key is removed if it exists. */ +int Jim_DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr) +{ + int retcode; + + JimPanic((Jim_IsShared(objPtr), "Jim_DictAddElement called with shared object")); + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return JIM_ERR; + } + retcode = DictAddElement(interp, objPtr, keyObjPtr, valueObjPtr); + Jim_InvalidateStringRep(objPtr); + return retcode; +} + +Jim_Obj *Jim_NewDictObj(Jim_Interp *interp, Jim_Obj *const *elements, int len) +{ + Jim_Obj *objPtr; + int i; + + JimPanic((len % 2, "Jim_NewDictObj() 'len' argument must be even")); + + objPtr = Jim_NewObj(interp); + objPtr->typePtr = &dictObjType; + objPtr->bytes = NULL; + objPtr->internalRep.ptr = Jim_Alloc(sizeof(Jim_HashTable)); + Jim_InitHashTable(objPtr->internalRep.ptr, &JimDictHashTableType, interp); + for (i = 0; i < len; i += 2) + DictAddElement(interp, objPtr, elements[i], elements[i + 1]); + return objPtr; +} + +/* Return the value associated to the specified dict key + * Note: Returns JIM_OK if OK, JIM_ERR if entry not found or -1 if can't create dict value + */ +int Jim_DictKey(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj *keyPtr, + Jim_Obj **objPtrPtr, int flags) +{ + Jim_HashEntry *he; + Jim_HashTable *ht; + + if (SetDictFromAny(interp, dictPtr) != JIM_OK) { + return -1; + } + ht = dictPtr->internalRep.ptr; + if ((he = Jim_FindHashEntry(ht, keyPtr)) == NULL) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "key \"%#s\" not known in dictionary", keyPtr); + } + return JIM_ERR; + } + *objPtrPtr = he->u.val; + return JIM_OK; +} + +/* Return an allocated array of key/value pairs for the dictionary. Stores the length in *len */ +int Jim_DictPairs(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj ***objPtrPtr, int *len) +{ + if (SetDictFromAny(interp, dictPtr) != JIM_OK) { + return JIM_ERR; + } + *objPtrPtr = JimDictPairs(dictPtr, len); + + return JIM_OK; +} + + +/* Return the value associated to the specified dict keys */ +int Jim_DictKeysVector(Jim_Interp *interp, Jim_Obj *dictPtr, + Jim_Obj *const *keyv, int keyc, Jim_Obj **objPtrPtr, int flags) +{ + int i; + + if (keyc == 0) { + *objPtrPtr = dictPtr; + return JIM_OK; + } + + for (i = 0; i < keyc; i++) { + Jim_Obj *objPtr; + + int rc = Jim_DictKey(interp, dictPtr, keyv[i], &objPtr, flags); + if (rc != JIM_OK) { + return rc; + } + dictPtr = objPtr; + } + *objPtrPtr = dictPtr; + return JIM_OK; +} + +/* Modify the dict stored into the variable named 'varNamePtr' + * setting the element specified by the 'keyc' keys objects in 'keyv', + * with the new value of the element 'newObjPtr'. + * + * If newObjPtr == NULL the operation is to remove the given key + * from the dictionary. + * + * If flags & JIM_ERRMSG, then failure to remove the key is considered an error + * and JIM_ERR is returned. Otherwise it is ignored and JIM_OK is returned. + */ +int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr, + Jim_Obj *const *keyv, int keyc, Jim_Obj *newObjPtr, int flags) +{ + Jim_Obj *varObjPtr, *objPtr, *dictObjPtr; + int shared, i; + + varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags); + if (objPtr == NULL) { + if (newObjPtr == NULL && (flags & JIM_MUSTEXIST)) { + /* Cannot remove a key from non existing var */ + return JIM_ERR; + } + varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0); + if (Jim_SetVariable(interp, varNamePtr, objPtr) != JIM_OK) { + Jim_FreeNewObj(interp, varObjPtr); + return JIM_ERR; + } + } + if ((shared = Jim_IsShared(objPtr))) + varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr); + for (i = 0; i < keyc; i++) { + dictObjPtr = objPtr; + + /* Check if it's a valid dictionary */ + if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) { + goto err; + } + + if (i == keyc - 1) { + /* Last key: Note that error on unset with missing last key is OK */ + if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) { + if (newObjPtr || (flags & JIM_MUSTEXIST)) { + goto err; + } + } + break; + } + + /* Check if the given key exists. */ + Jim_InvalidateStringRep(dictObjPtr); + if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr, + newObjPtr ? JIM_NONE : JIM_ERRMSG) == JIM_OK) { + /* This key exists at the current level. + * Make sure it's not shared!. */ + if (Jim_IsShared(objPtr)) { + objPtr = Jim_DuplicateObj(interp, objPtr); + DictAddElement(interp, dictObjPtr, keyv[i], objPtr); + } + } + else { + /* Key not found. If it's an [unset] operation + * this is an error. Only the last key may not + * exist. */ + if (newObjPtr == NULL) { + goto err; + } + /* Otherwise set an empty dictionary + * as key's value. */ + objPtr = Jim_NewDictObj(interp, NULL, 0); + DictAddElement(interp, dictObjPtr, keyv[i], objPtr); + } + } + Jim_InvalidateStringRep(objPtr); + Jim_InvalidateStringRep(varObjPtr); + if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) { + goto err; + } + Jim_SetResult(interp, varObjPtr); + return JIM_OK; + err: + if (shared) { + Jim_FreeNewObj(interp, varObjPtr); + } + return JIM_ERR; +} + +/* ----------------------------------------------------------------------------- + * Index object + * ---------------------------------------------------------------------------*/ +static void UpdateStringOfIndex(struct Jim_Obj *objPtr); +static int SetIndexFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType indexObjType = { + "index", + NULL, + NULL, + UpdateStringOfIndex, + JIM_TYPE_NONE, +}; + +void UpdateStringOfIndex(struct Jim_Obj *objPtr) +{ + int len; + char buf[JIM_INTEGER_SPACE + 1]; + + if (objPtr->internalRep.intValue >= 0) + len = sprintf(buf, "%d", objPtr->internalRep.intValue); + else if (objPtr->internalRep.intValue == -1) + len = sprintf(buf, "end"); + else { + len = sprintf(buf, "end%d", objPtr->internalRep.intValue + 1); + } + objPtr->bytes = Jim_Alloc(len + 1); + memcpy(objPtr->bytes, buf, len + 1); + objPtr->length = len; +} + +int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + int idx, end = 0; + const char *str; + char *endptr; + + /* Get the string representation */ + str = Jim_String(objPtr); + + /* Try to convert into an index */ + if (strncmp(str, "end", 3) == 0) { + end = 1; + str += 3; + idx = 0; + } + else { + idx = jim_strtol(str, &endptr); + + if (endptr == str) { + goto badindex; + } + str = endptr; + } + + /* Now str may include or + or - */ + if (*str == '+' || *str == '-') { + int sign = (*str == '+' ? 1 : -1); + + idx += sign * jim_strtol(++str, &endptr); + if (str == endptr || *endptr) { + goto badindex; + } + str = endptr; + } + /* The only thing left should be spaces */ + while (isspace(UCHAR(*str))) { + str++; + } + if (*str) { + goto badindex; + } + if (end) { + if (idx > 0) { + idx = INT_MAX; + } + else { + /* end-1 is repesented as -2 */ + idx--; + } + } + else if (idx < 0) { + idx = -INT_MAX; + } + + /* Free the old internal repr and set the new one. */ + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &indexObjType; + objPtr->internalRep.intValue = idx; + return JIM_OK; + + badindex: + Jim_SetResultFormatted(interp, + "bad index \"%#s\": must be integer?[+-]integer? or end?[+-]integer?", objPtr); + return JIM_ERR; +} + +int Jim_GetIndex(Jim_Interp *interp, Jim_Obj *objPtr, int *indexPtr) +{ + /* Avoid shimmering if the object is an integer. */ + if (objPtr->typePtr == &intObjType) { + jim_wide val = JimWideValue(objPtr); + + if (!(val < LONG_MIN) && !(val > LONG_MAX)) { + *indexPtr = (val < 0) ? -INT_MAX : (long)val;; + return JIM_OK; + } + } + if (objPtr->typePtr != &indexObjType && SetIndexFromAny(interp, objPtr) == JIM_ERR) + return JIM_ERR; + *indexPtr = objPtr->internalRep.intValue; + return JIM_OK; +} + +/* ----------------------------------------------------------------------------- + * Return Code Object. + * ---------------------------------------------------------------------------*/ + +/* NOTE: These must be kept in the same order as JIM_OK, JIM_ERR, ... */ +static const char * const jimReturnCodes[] = { + "ok", + "error", + "return", + "break", + "continue", + "signal", + "exit", + "eval", + NULL +}; + +#define jimReturnCodesSize (sizeof(jimReturnCodes)/sizeof(*jimReturnCodes)) + +static int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr); + +static const Jim_ObjType returnCodeObjType = { + "return-code", + NULL, + NULL, + NULL, + JIM_TYPE_NONE, +}; + +/* Converts a (standard) return code to a string. Returns "?" for + * non-standard return codes. + */ +const char *Jim_ReturnCode(int code) +{ + if (code < 0 || code >= (int)jimReturnCodesSize) { + return "?"; + } + else { + return jimReturnCodes[code]; + } +} + +int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + int returnCode; + jim_wide wideValue; + + /* Try to convert into an integer */ + if (JimGetWideNoErr(interp, objPtr, &wideValue) != JIM_ERR) + returnCode = (int)wideValue; + else if (Jim_GetEnum(interp, objPtr, jimReturnCodes, &returnCode, NULL, JIM_NONE) != JIM_OK) { + Jim_SetResultFormatted(interp, "expected return code but got \"%#s\"", objPtr); + return JIM_ERR; + } + /* Free the old internal repr and set the new one. */ + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &returnCodeObjType; + objPtr->internalRep.intValue = returnCode; + return JIM_OK; +} + +int Jim_GetReturnCode(Jim_Interp *interp, Jim_Obj *objPtr, int *intPtr) +{ + if (objPtr->typePtr != &returnCodeObjType && SetReturnCodeFromAny(interp, objPtr) == JIM_ERR) + return JIM_ERR; + *intPtr = objPtr->internalRep.intValue; + return JIM_OK; +} + +/* ----------------------------------------------------------------------------- + * Expression Parsing + * ---------------------------------------------------------------------------*/ +static int JimParseExprOperator(struct JimParserCtx *pc); +static int JimParseExprNumber(struct JimParserCtx *pc); +static int JimParseExprIrrational(struct JimParserCtx *pc); + +/* Exrp's Stack machine operators opcodes. */ + +/* Binary operators (numbers) */ +enum +{ + /* Continues on from the JIM_TT_ space */ + /* Operations */ + JIM_EXPROP_MUL = JIM_TT_EXPR_OP, /* 20 */ + JIM_EXPROP_DIV, + JIM_EXPROP_MOD, + JIM_EXPROP_SUB, + JIM_EXPROP_ADD, + JIM_EXPROP_LSHIFT, + JIM_EXPROP_RSHIFT, + JIM_EXPROP_ROTL, + JIM_EXPROP_ROTR, + JIM_EXPROP_LT, + JIM_EXPROP_GT, + JIM_EXPROP_LTE, + JIM_EXPROP_GTE, + JIM_EXPROP_NUMEQ, + JIM_EXPROP_NUMNE, + JIM_EXPROP_BITAND, /* 35 */ + JIM_EXPROP_BITXOR, + JIM_EXPROP_BITOR, + + /* Note must keep these together */ + JIM_EXPROP_LOGICAND, /* 38 */ + JIM_EXPROP_LOGICAND_LEFT, + JIM_EXPROP_LOGICAND_RIGHT, + + /* and these */ + JIM_EXPROP_LOGICOR, /* 41 */ + JIM_EXPROP_LOGICOR_LEFT, + JIM_EXPROP_LOGICOR_RIGHT, + + /* and these */ + /* Ternary operators */ + JIM_EXPROP_TERNARY, /* 44 */ + JIM_EXPROP_TERNARY_LEFT, + JIM_EXPROP_TERNARY_RIGHT, + + /* and these */ + JIM_EXPROP_COLON, /* 47 */ + JIM_EXPROP_COLON_LEFT, + JIM_EXPROP_COLON_RIGHT, + + JIM_EXPROP_POW, /* 50 */ + +/* Binary operators (strings) */ + JIM_EXPROP_STREQ, /* 51 */ + JIM_EXPROP_STRNE, + JIM_EXPROP_STRIN, + JIM_EXPROP_STRNI, + +/* Unary operators (numbers) */ + JIM_EXPROP_NOT, /* 55 */ + JIM_EXPROP_BITNOT, + JIM_EXPROP_UNARYMINUS, + JIM_EXPROP_UNARYPLUS, + + /* Functions */ + JIM_EXPROP_FUNC_FIRST, /* 59 */ + JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST, + JIM_EXPROP_FUNC_ABS, + JIM_EXPROP_FUNC_DOUBLE, + JIM_EXPROP_FUNC_ROUND, + JIM_EXPROP_FUNC_RAND, + JIM_EXPROP_FUNC_SRAND, + + /* math functions from libm */ + JIM_EXPROP_FUNC_SIN, /* 64 */ + JIM_EXPROP_FUNC_COS, + JIM_EXPROP_FUNC_TAN, + JIM_EXPROP_FUNC_ASIN, + JIM_EXPROP_FUNC_ACOS, + JIM_EXPROP_FUNC_ATAN, + JIM_EXPROP_FUNC_SINH, + JIM_EXPROP_FUNC_COSH, + JIM_EXPROP_FUNC_TANH, + JIM_EXPROP_FUNC_CEIL, + JIM_EXPROP_FUNC_FLOOR, + JIM_EXPROP_FUNC_EXP, + JIM_EXPROP_FUNC_LOG, + JIM_EXPROP_FUNC_LOG10, + JIM_EXPROP_FUNC_SQRT, + JIM_EXPROP_FUNC_POW, +}; + +struct JimExprState +{ + Jim_Obj **stack; + int stacklen; + int opcode; + int skip; +}; + +/* Operators table */ +typedef struct Jim_ExprOperator +{ + const char *name; + int (*funcop) (Jim_Interp *interp, struct JimExprState * e); + unsigned char precedence; + unsigned char arity; + unsigned char lazy; + unsigned char namelen; +} Jim_ExprOperator; + +static void ExprPush(struct JimExprState *e, Jim_Obj *obj) +{ + Jim_IncrRefCount(obj); + e->stack[e->stacklen++] = obj; +} + +static Jim_Obj *ExprPop(struct JimExprState *e) +{ + return e->stack[--e->stacklen]; +} + +static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprState *e) +{ + int intresult = 0; + int rc = JIM_OK; + Jim_Obj *A = ExprPop(e); + double dA, dC = 0; + jim_wide wA, wC = 0; + + if ((A->typePtr != &doubleObjType || A->bytes) && JimGetWideNoErr(interp, A, &wA) == JIM_OK) { + intresult = 1; + + switch (e->opcode) { + case JIM_EXPROP_FUNC_INT: + wC = wA; + break; + case JIM_EXPROP_FUNC_ROUND: + wC = wA; + break; + case JIM_EXPROP_FUNC_DOUBLE: + dC = wA; + intresult = 0; + break; + case JIM_EXPROP_FUNC_ABS: + wC = wA >= 0 ? wA : -wA; + break; + case JIM_EXPROP_UNARYMINUS: + wC = -wA; + break; + case JIM_EXPROP_UNARYPLUS: + wC = wA; + break; + case JIM_EXPROP_NOT: + wC = !wA; + break; + default: + abort(); + } + } + else if ((rc = Jim_GetDouble(interp, A, &dA)) == JIM_OK) { + switch (e->opcode) { + case JIM_EXPROP_FUNC_INT: + wC = dA; + intresult = 1; + break; + case JIM_EXPROP_FUNC_ROUND: + wC = dA < 0 ? (dA - 0.5) : (dA + 0.5); + intresult = 1; + break; + case JIM_EXPROP_FUNC_DOUBLE: + dC = dA; + break; + case JIM_EXPROP_FUNC_ABS: + dC = dA >= 0 ? dA : -dA; + break; + case JIM_EXPROP_UNARYMINUS: + dC = -dA; + break; + case JIM_EXPROP_UNARYPLUS: + dC = dA; + break; + case JIM_EXPROP_NOT: + wC = !dA; + intresult = 1; + break; + default: + abort(); + } + } + + if (rc == JIM_OK) { + if (intresult) { + ExprPush(e, Jim_NewIntObj(interp, wC)); + } + else { + ExprPush(e, Jim_NewDoubleObj(interp, dC)); + } + } + + Jim_DecrRefCount(interp, A); + + return rc; +} + +static double JimRandDouble(Jim_Interp *interp) +{ + unsigned long x; + JimRandomBytes(interp, &x, sizeof(x)); + + return (double)x / (unsigned long)~0; +} + +static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *A = ExprPop(e); + jim_wide wA; + + int rc = Jim_GetWide(interp, A, &wA); + if (rc == JIM_OK) { + switch (e->opcode) { + case JIM_EXPROP_BITNOT: + ExprPush(e, Jim_NewIntObj(interp, ~wA)); + break; + case JIM_EXPROP_FUNC_SRAND: + JimPrngSeed(interp, (unsigned char *)&wA, sizeof(wA)); + ExprPush(e, Jim_NewDoubleObj(interp, JimRandDouble(interp))); + break; + default: + abort(); + } + } + + Jim_DecrRefCount(interp, A); + + return rc; +} + +static int JimExprOpNone(Jim_Interp *interp, struct JimExprState *e) +{ + JimPanic((e->opcode != JIM_EXPROP_FUNC_RAND, "JimExprOpNone only support rand()")); + + ExprPush(e, Jim_NewDoubleObj(interp, JimRandDouble(interp))); + + return JIM_OK; +} + +#ifdef JIM_MATH_FUNCTIONS +static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprState *e) +{ + int rc; + Jim_Obj *A = ExprPop(e); + double dA, dC; + + rc = Jim_GetDouble(interp, A, &dA); + if (rc == JIM_OK) { + switch (e->opcode) { + case JIM_EXPROP_FUNC_SIN: + dC = sin(dA); + break; + case JIM_EXPROP_FUNC_COS: + dC = cos(dA); + break; + case JIM_EXPROP_FUNC_TAN: + dC = tan(dA); + break; + case JIM_EXPROP_FUNC_ASIN: + dC = asin(dA); + break; + case JIM_EXPROP_FUNC_ACOS: + dC = acos(dA); + break; + case JIM_EXPROP_FUNC_ATAN: + dC = atan(dA); + break; + case JIM_EXPROP_FUNC_SINH: + dC = sinh(dA); + break; + case JIM_EXPROP_FUNC_COSH: + dC = cosh(dA); + break; + case JIM_EXPROP_FUNC_TANH: + dC = tanh(dA); + break; + case JIM_EXPROP_FUNC_CEIL: + dC = ceil(dA); + break; + case JIM_EXPROP_FUNC_FLOOR: + dC = floor(dA); + break; + case JIM_EXPROP_FUNC_EXP: + dC = exp(dA); + break; + case JIM_EXPROP_FUNC_LOG: + dC = log(dA); + break; + case JIM_EXPROP_FUNC_LOG10: + dC = log10(dA); + break; + case JIM_EXPROP_FUNC_SQRT: + dC = sqrt(dA); + break; + default: + abort(); + } + ExprPush(e, Jim_NewDoubleObj(interp, dC)); + } + + Jim_DecrRefCount(interp, A); + + return rc; +} +#endif + +/* A binary operation on two ints */ +static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *B = ExprPop(e); + Jim_Obj *A = ExprPop(e); + jim_wide wA, wB; + int rc = JIM_ERR; + + if (Jim_GetWide(interp, A, &wA) == JIM_OK && Jim_GetWide(interp, B, &wB) == JIM_OK) { + jim_wide wC; + + rc = JIM_OK; + + switch (e->opcode) { + case JIM_EXPROP_LSHIFT: + wC = wA << wB; + break; + case JIM_EXPROP_RSHIFT: + wC = wA >> wB; + break; + case JIM_EXPROP_BITAND: + wC = wA & wB; + break; + case JIM_EXPROP_BITXOR: + wC = wA ^ wB; + break; + case JIM_EXPROP_BITOR: + wC = wA | wB; + break; + case JIM_EXPROP_MOD: + if (wB == 0) { + wC = 0; + Jim_SetResultString(interp, "Division by zero", -1); + rc = JIM_ERR; + } + else { + /* + * From Tcl 8.x + * + * This code is tricky: C doesn't guarantee much + * about the quotient or remainder, but Tcl does. + * The remainder always has the same sign as the + * divisor and a smaller absolute value. + */ + int negative = 0; + + if (wB < 0) { + wB = -wB; + wA = -wA; + negative = 1; + } + wC = wA % wB; + if (wC < 0) { + wC += wB; + } + if (negative) { + wC = -wC; + } + } + break; + case JIM_EXPROP_ROTL: + case JIM_EXPROP_ROTR:{ + /* uint32_t would be better. But not everyone has inttypes.h? */ + unsigned long uA = (unsigned long)wA; + unsigned long uB = (unsigned long)wB; + const unsigned int S = sizeof(unsigned long) * 8; + + /* Shift left by the word size or more is undefined. */ + uB %= S; + + if (e->opcode == JIM_EXPROP_ROTR) { + uB = S - uB; + } + wC = (unsigned long)(uA << uB) | (uA >> (S - uB)); + break; + } + default: + abort(); + } + ExprPush(e, Jim_NewIntObj(interp, wC)); + + } + + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, B); + + return rc; +} + + +/* A binary operation on two ints or two doubles (or two strings for some ops) */ +static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) +{ + int intresult = 0; + int rc = JIM_OK; + double dA, dB, dC = 0; + jim_wide wA, wB, wC = 0; + + Jim_Obj *B = ExprPop(e); + Jim_Obj *A = ExprPop(e); + + if ((A->typePtr != &doubleObjType || A->bytes) && + (B->typePtr != &doubleObjType || B->bytes) && + JimGetWideNoErr(interp, A, &wA) == JIM_OK && JimGetWideNoErr(interp, B, &wB) == JIM_OK) { + + /* Both are ints */ + + intresult = 1; + + switch (e->opcode) { + case JIM_EXPROP_POW: + case JIM_EXPROP_FUNC_POW: + wC = JimPowWide(wA, wB); + break; + case JIM_EXPROP_ADD: + wC = wA + wB; + break; + case JIM_EXPROP_SUB: + wC = wA - wB; + break; + case JIM_EXPROP_MUL: + wC = wA * wB; + break; + case JIM_EXPROP_DIV: + if (wB == 0) { + Jim_SetResultString(interp, "Division by zero", -1); + rc = JIM_ERR; + } + else { + /* + * From Tcl 8.x + * + * This code is tricky: C doesn't guarantee much + * about the quotient or remainder, but Tcl does. + * The remainder always has the same sign as the + * divisor and a smaller absolute value. + */ + if (wB < 0) { + wB = -wB; + wA = -wA; + } + wC = wA / wB; + if (wA % wB < 0) { + wC--; + } + } + break; + case JIM_EXPROP_LT: + wC = wA < wB; + break; + case JIM_EXPROP_GT: + wC = wA > wB; + break; + case JIM_EXPROP_LTE: + wC = wA <= wB; + break; + case JIM_EXPROP_GTE: + wC = wA >= wB; + break; + case JIM_EXPROP_NUMEQ: + wC = wA == wB; + break; + case JIM_EXPROP_NUMNE: + wC = wA != wB; + break; + default: + abort(); + } + } + else if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) { + switch (e->opcode) { + case JIM_EXPROP_POW: + case JIM_EXPROP_FUNC_POW: +#ifdef JIM_MATH_FUNCTIONS + dC = pow(dA, dB); +#else + Jim_SetResultString(interp, "unsupported", -1); + rc = JIM_ERR; +#endif + break; + case JIM_EXPROP_ADD: + dC = dA + dB; + break; + case JIM_EXPROP_SUB: + dC = dA - dB; + break; + case JIM_EXPROP_MUL: + dC = dA * dB; + break; + case JIM_EXPROP_DIV: + if (dB == 0) { +#ifdef INFINITY + dC = dA < 0 ? -INFINITY : INFINITY; +#else + dC = (dA < 0 ? -1.0 : 1.0) * strtod("Inf", NULL); +#endif + } + else { + dC = dA / dB; + } + break; + case JIM_EXPROP_LT: + wC = dA < dB; + intresult = 1; + break; + case JIM_EXPROP_GT: + wC = dA > dB; + intresult = 1; + break; + case JIM_EXPROP_LTE: + wC = dA <= dB; + intresult = 1; + break; + case JIM_EXPROP_GTE: + wC = dA >= dB; + intresult = 1; + break; + case JIM_EXPROP_NUMEQ: + wC = dA == dB; + intresult = 1; + break; + case JIM_EXPROP_NUMNE: + wC = dA != dB; + intresult = 1; + break; + default: + abort(); + } + } + else { + /* Handle the string case */ + + /* REVISIT: Could optimise the eq/ne case by checking lengths */ + int i = Jim_StringCompareObj(interp, A, B, 0); + + intresult = 1; + + switch (e->opcode) { + case JIM_EXPROP_LT: + wC = i < 0; + break; + case JIM_EXPROP_GT: + wC = i > 0; + break; + case JIM_EXPROP_LTE: + wC = i <= 0; + break; + case JIM_EXPROP_GTE: + wC = i >= 0; + break; + case JIM_EXPROP_NUMEQ: + wC = i == 0; + break; + case JIM_EXPROP_NUMNE: + wC = i != 0; + break; + default: + rc = JIM_ERR; + break; + } + } + + if (rc == JIM_OK) { + if (intresult) { + ExprPush(e, Jim_NewIntObj(interp, wC)); + } + else { + ExprPush(e, Jim_NewDoubleObj(interp, dC)); + } + } + + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, B); + + return rc; +} + +static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj) +{ + int listlen; + int i; + + listlen = Jim_ListLength(interp, listObjPtr); + for (i = 0; i < listlen; i++) { + Jim_Obj *objPtr; + + Jim_ListIndex(interp, listObjPtr, i, &objPtr, JIM_NONE); + + if (Jim_StringEqObj(objPtr, valObj)) { + return 1; + } + } + return 0; +} + +static int JimExprOpStrBin(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *B = ExprPop(e); + Jim_Obj *A = ExprPop(e); + + jim_wide wC; + + switch (e->opcode) { + case JIM_EXPROP_STREQ: + case JIM_EXPROP_STRNE: { + int Alen, Blen; + const char *sA = Jim_GetString(A, &Alen); + const char *sB = Jim_GetString(B, &Blen); + + if (e->opcode == JIM_EXPROP_STREQ) { + wC = (Alen == Blen && memcmp(sA, sB, Alen) == 0); + } + else { + wC = (Alen != Blen || memcmp(sA, sB, Alen) != 0); + } + break; + } + case JIM_EXPROP_STRIN: + wC = JimSearchList(interp, B, A); + break; + case JIM_EXPROP_STRNI: + wC = !JimSearchList(interp, B, A); + break; + default: + abort(); + } + ExprPush(e, Jim_NewIntObj(interp, wC)); + + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, B); + + return JIM_OK; +} + +static int ExprBool(Jim_Interp *interp, Jim_Obj *obj) +{ + long l; + double d; + + if (Jim_GetLong(interp, obj, &l) == JIM_OK) { + return l != 0; + } + if (Jim_GetDouble(interp, obj, &d) == JIM_OK) { + return d != 0; + } + return -1; +} + +static int JimExprOpAndLeft(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *skip = ExprPop(e); + Jim_Obj *A = ExprPop(e); + int rc = JIM_OK; + + switch (ExprBool(interp, A)) { + case 0: + /* false, so skip RHS opcodes with a 0 result */ + e->skip = JimWideValue(skip); + ExprPush(e, Jim_NewIntObj(interp, 0)); + break; + + case 1: + /* true so continue */ + break; + + case -1: + /* Invalid */ + rc = JIM_ERR; + } + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, skip); + + return rc; +} + +static int JimExprOpOrLeft(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *skip = ExprPop(e); + Jim_Obj *A = ExprPop(e); + int rc = JIM_OK; + + switch (ExprBool(interp, A)) { + case 0: + /* false, so do nothing */ + break; + + case 1: + /* true so skip RHS opcodes with a 1 result */ + e->skip = JimWideValue(skip); + ExprPush(e, Jim_NewIntObj(interp, 1)); + break; + + case -1: + /* Invalid */ + rc = JIM_ERR; + break; + } + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, skip); + + return rc; +} + +static int JimExprOpAndOrRight(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *A = ExprPop(e); + int rc = JIM_OK; + + switch (ExprBool(interp, A)) { + case 0: + ExprPush(e, Jim_NewIntObj(interp, 0)); + break; + + case 1: + ExprPush(e, Jim_NewIntObj(interp, 1)); + break; + + case -1: + /* Invalid */ + rc = JIM_ERR; + break; + } + Jim_DecrRefCount(interp, A); + + return rc; +} + +static int JimExprOpTernaryLeft(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *skip = ExprPop(e); + Jim_Obj *A = ExprPop(e); + int rc = JIM_OK; + + /* Repush A */ + ExprPush(e, A); + + switch (ExprBool(interp, A)) { + case 0: + /* false, skip RHS opcodes */ + e->skip = JimWideValue(skip); + /* Push a dummy value */ + ExprPush(e, Jim_NewIntObj(interp, 0)); + break; + + case 1: + /* true so do nothing */ + break; + + case -1: + /* Invalid */ + rc = JIM_ERR; + break; + } + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, skip); + + return rc; +} + +static int JimExprOpColonLeft(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *skip = ExprPop(e); + Jim_Obj *B = ExprPop(e); + Jim_Obj *A = ExprPop(e); + + /* No need to check for A as non-boolean */ + if (ExprBool(interp, A)) { + /* true, so skip RHS opcodes */ + e->skip = JimWideValue(skip); + /* Repush B as the answer */ + ExprPush(e, B); + } + + Jim_DecrRefCount(interp, skip); + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, B); + return JIM_OK; +} + +static int JimExprOpNull(Jim_Interp *interp, struct JimExprState *e) +{ + return JIM_OK; +} + +enum +{ + LAZY_NONE, + LAZY_OP, + LAZY_LEFT, + LAZY_RIGHT +}; + +/* name - precedence - arity - opcode + * + * This array *must* be kept in sync with the JIM_EXPROP enum. + * + * The following macro pre-computes the string length at compile time. + */ +#define OPRINIT(N, P, A, F, L) {N, F, P, A, L, sizeof(N) - 1} + +static const struct Jim_ExprOperator Jim_ExprOperators[] = { + OPRINIT("*", 110, 2, JimExprOpBin, LAZY_NONE), + OPRINIT("/", 110, 2, JimExprOpBin, LAZY_NONE), + OPRINIT("%", 110, 2, JimExprOpIntBin, LAZY_NONE), + + OPRINIT("-", 100, 2, JimExprOpBin, LAZY_NONE), + OPRINIT("+", 100, 2, JimExprOpBin, LAZY_NONE), + + OPRINIT("<<", 90, 2, JimExprOpIntBin, LAZY_NONE), + OPRINIT(">>", 90, 2, JimExprOpIntBin, LAZY_NONE), + + OPRINIT("<<<", 90, 2, JimExprOpIntBin, LAZY_NONE), + OPRINIT(">>>", 90, 2, JimExprOpIntBin, LAZY_NONE), + + OPRINIT("<", 80, 2, JimExprOpBin, LAZY_NONE), + OPRINIT(">", 80, 2, JimExprOpBin, LAZY_NONE), + OPRINIT("<=", 80, 2, JimExprOpBin, LAZY_NONE), + OPRINIT(">=", 80, 2, JimExprOpBin, LAZY_NONE), + + OPRINIT("==", 70, 2, JimExprOpBin, LAZY_NONE), + OPRINIT("!=", 70, 2, JimExprOpBin, LAZY_NONE), + + OPRINIT("&", 50, 2, JimExprOpIntBin, LAZY_NONE), + OPRINIT("^", 49, 2, JimExprOpIntBin, LAZY_NONE), + OPRINIT("|", 48, 2, JimExprOpIntBin, LAZY_NONE), + + OPRINIT("&&", 10, 2, NULL, LAZY_OP), + OPRINIT(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT), + OPRINIT(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT), + + OPRINIT("||", 9, 2, NULL, LAZY_OP), + OPRINIT(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT), + OPRINIT(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT), + + OPRINIT("?", 5, 2, JimExprOpNull, LAZY_OP), + OPRINIT(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT), + OPRINIT(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT), + + OPRINIT(":", 5, 2, JimExprOpNull, LAZY_OP), + OPRINIT(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT), + OPRINIT(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT), + + OPRINIT("**", 250, 2, JimExprOpBin, LAZY_NONE), + + OPRINIT("eq", 60, 2, JimExprOpStrBin, LAZY_NONE), + OPRINIT("ne", 60, 2, JimExprOpStrBin, LAZY_NONE), + + OPRINIT("in", 55, 2, JimExprOpStrBin, LAZY_NONE), + OPRINIT("ni", 55, 2, JimExprOpStrBin, LAZY_NONE), + + OPRINIT("!", 150, 1, JimExprOpNumUnary, LAZY_NONE), + OPRINIT("~", 150, 1, JimExprOpIntUnary, LAZY_NONE), + OPRINIT(NULL, 150, 1, JimExprOpNumUnary, LAZY_NONE), + OPRINIT(NULL, 150, 1, JimExprOpNumUnary, LAZY_NONE), + + + + OPRINIT("int", 200, 1, JimExprOpNumUnary, LAZY_NONE), + OPRINIT("abs", 200, 1, JimExprOpNumUnary, LAZY_NONE), + OPRINIT("double", 200, 1, JimExprOpNumUnary, LAZY_NONE), + OPRINIT("round", 200, 1, JimExprOpNumUnary, LAZY_NONE), + OPRINIT("rand", 200, 0, JimExprOpNone, LAZY_NONE), + OPRINIT("srand", 200, 1, JimExprOpIntUnary, LAZY_NONE), + +#ifdef JIM_MATH_FUNCTIONS + OPRINIT("sin", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("cos", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("tan", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("asin", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("acos", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("atan", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("sinh", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("cosh", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("tanh", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("ceil", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("floor", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("exp", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("log", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("log10", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("sqrt", 200, 1, JimExprOpDoubleUnary, LAZY_NONE), + OPRINIT("pow", 200, 2, JimExprOpBin, LAZY_NONE), +#endif +}; +#undef OPRINIT + +#define JIM_EXPR_OPERATORS_NUM \ + (sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator)) + +static int JimParseExpression(struct JimParserCtx *pc) +{ + /* Discard spaces and quoted newline */ + while (isspace(UCHAR(*pc->p)) || (*(pc->p) == '\\' && *(pc->p + 1) == '\n')) { + if (*pc->p == '\n') { + pc->linenr++; + } + pc->p++; + pc->len--; + } + + if (pc->len == 0) { + pc->tstart = pc->tend = pc->p; + pc->tline = pc->linenr; + pc->tt = JIM_TT_EOL; + pc->eof = 1; + return JIM_OK; + } + switch (*(pc->p)) { + case '(': + pc->tt = JIM_TT_SUBEXPR_START; + goto singlechar; + case ')': + pc->tt = JIM_TT_SUBEXPR_END; + goto singlechar; + case ',': + pc->tt = JIM_TT_SUBEXPR_COMMA; +singlechar: + pc->tstart = pc->tend = pc->p; + pc->tline = pc->linenr; + pc->p++; + pc->len--; + break; + case '[': + return JimParseCmd(pc); + case '$': + if (JimParseVar(pc) == JIM_ERR) + return JimParseExprOperator(pc); + else { + /* Don't allow expr sugar in expressions */ + if (pc->tt == JIM_TT_EXPRSUGAR) { + return JIM_ERR; + } + return JIM_OK; + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '.': + return JimParseExprNumber(pc); + case '"': + return JimParseQuote(pc); + case '{': + return JimParseBrace(pc); + + case 'N': + case 'I': + case 'n': + case 'i': + if (JimParseExprIrrational(pc) == JIM_ERR) + return JimParseExprOperator(pc); + break; + default: + return JimParseExprOperator(pc); + break; + } + return JIM_OK; +} + +static int JimParseExprNumber(struct JimParserCtx *pc) +{ + int allowdot = 1; + int base = 10; + + /* Assume an integer for now */ + pc->tt = JIM_TT_EXPR_INT; + pc->tstart = pc->p; + pc->tline = pc->linenr; + + /* Parse initial 0 */ + if (pc->p[0] == '0') { + switch (pc->p[1]) { + case 'x': + case 'X': + base = 16; + allowdot = 0; + pc->p += 2; + pc->len -= 2; + break; + case 'o': + case 'O': + base = 8; + allowdot = 0; + pc->p += 2; + pc->len -= 2; + break; + case 'b': + case 'B': + base = 2; + allowdot = 0; + pc->p += 2; + pc->len -= 2; + break; + } + } + + while (isdigit(UCHAR(*pc->p)) + || (base == 16 && isxdigit(UCHAR(*pc->p))) + || (base == 8 && *pc->p >= '0' && *pc->p <= '7') + || (base == 2 && (*pc->p == '0' || *pc->p == '1')) + || (allowdot && *pc->p == '.') + ) { + if (*pc->p == '.') { + allowdot = 0; + pc->tt = JIM_TT_EXPR_DOUBLE; + } + pc->p++; + pc->len--; + if (base == 10 && (*pc->p == 'e' || *pc->p == 'E') && (pc->p[1] == '-' || pc->p[1] == '+' + || isdigit(UCHAR(pc->p[1])))) { + pc->p += 2; + pc->len -= 2; + pc->tt = JIM_TT_EXPR_DOUBLE; + } + } + pc->tend = pc->p - 1; + return JIM_OK; +} + +static int JimParseExprIrrational(struct JimParserCtx *pc) +{ + const char *Tokens[] = { "NaN", "nan", "NAN", "Inf", "inf", "INF", NULL }; + const char **token; + + for (token = Tokens; *token != NULL; token++) { + int len = strlen(*token); + + if (strncmp(*token, pc->p, len) == 0) { + pc->tstart = pc->p; + pc->tend = pc->p + len - 1; + pc->p += len; + pc->len -= len; + pc->tline = pc->linenr; + pc->tt = JIM_TT_EXPR_DOUBLE; + return JIM_OK; + } + } + return JIM_ERR; +} + +static int JimParseExprOperator(struct JimParserCtx *pc) +{ + int i; + int bestIdx = -1, bestLen = 0; + + /* Try to get the longest match. */ + for (i = 0; i < (signed)JIM_EXPR_OPERATORS_NUM; i++) { + const char * const opname = Jim_ExprOperators[i].name; + const int oplen = Jim_ExprOperators[i].namelen; + + if (opname == NULL || opname[0] != pc->p[0]) { + continue; + } + + if (oplen > bestLen && strncmp(opname, pc->p, oplen) == 0) { + bestIdx = i + JIM_TT_EXPR_OP; + bestLen = oplen; + } + } + if (bestIdx == -1) { + return JIM_ERR; + } + + /* Validate paretheses around function arguments */ + if (bestIdx >= JIM_EXPROP_FUNC_FIRST) { + const char *p = pc->p + bestLen; + int len = pc->len - bestLen; + + while (len && isspace(UCHAR(*p))) { + len--; + p++; + } + if (*p != '(') { + return JIM_ERR; + } + } + pc->tstart = pc->p; + pc->tend = pc->p + bestLen - 1; + pc->p += bestLen; + pc->len -= bestLen; + pc->tline = pc->linenr; + + pc->tt = bestIdx; + return JIM_OK; +} + +static const struct Jim_ExprOperator *JimExprOperatorInfoByOpcode(int opcode) +{ + static Jim_ExprOperator dummy_op; + if (opcode < JIM_TT_EXPR_OP) { + return &dummy_op; + } + return &Jim_ExprOperators[opcode - JIM_TT_EXPR_OP]; +} + +const char *jim_tt_name(int type) +{ + static const char * const tt_names[JIM_TT_EXPR_OP] = + { "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", ",,,", "INT", + "DBL", "$()" }; + if (type < JIM_TT_EXPR_OP) { + return tt_names[type]; + } + else { + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(type); + static char buf[20]; + + if (op->name) { + return op->name; + } + sprintf(buf, "(%d)", type); + return buf; + } +} + +/* ----------------------------------------------------------------------------- + * Expression Object + * ---------------------------------------------------------------------------*/ +static void FreeExprInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType exprObjType = { + "expression", + FreeExprInternalRep, + DupExprInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + +/* Expr bytecode structure */ +typedef struct ExprByteCode +{ + ScriptToken *token; /* Tokens array. */ + int len; /* Length as number of tokens. */ + int inUse; /* Used for sharing. */ +} ExprByteCode; + +static void ExprFreeByteCode(Jim_Interp *interp, ExprByteCode * expr) +{ + int i; + + for (i = 0; i < expr->len; i++) { + Jim_DecrRefCount(interp, expr->token[i].objPtr); + } + Jim_Free(expr->token); + Jim_Free(expr); +} + +static void FreeExprInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + ExprByteCode *expr = (void *)objPtr->internalRep.ptr; + + if (expr) { + if (--expr->inUse != 0) { + return; + } + + ExprFreeByteCode(interp, expr); + } +} + +static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + JIM_NOTUSED(interp); + JIM_NOTUSED(srcPtr); + + /* Just returns an simple string. */ + dupPtr->typePtr = NULL; +} + +/* Check if an expr program looks correct. */ +static int ExprCheckCorrectness(ExprByteCode * expr) +{ + int i; + int stacklen = 0; + int ternary = 0; + + /* Try to check if there are stack underflows, + * and make sure at the end of the program there is + * a single result on the stack. */ + for (i = 0; i < expr->len; i++) { + ScriptToken *t = &expr->token[i]; + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type); + + stacklen -= op->arity; + if (stacklen < 0) { + break; + } + if (t->type == JIM_EXPROP_TERNARY || t->type == JIM_EXPROP_TERNARY_LEFT) { + ternary++; + } + else if (t->type == JIM_EXPROP_COLON || t->type == JIM_EXPROP_COLON_LEFT) { + ternary--; + } + + /* All operations and operands add one to the stack */ + stacklen++; + } + if (stacklen != 1 || ternary != 0) { + return JIM_ERR; + } + return JIM_OK; +} + +/* This procedure converts every occurrence of || and && opereators + * in lazy unary versions. + * + * a b || is converted into: + * + * a |L b |R + * + * a b && is converted into: + * + * a &L b &R + * + * "|L" checks if 'a' is true: + * 1) if it is true pushes 1 and skips instructions to reach + * the opcode just after |R. + * 2) if it is false does nothing. + * "|R" checks if 'b' is true: + * 1) if it is true pushes 1, otherwise pushes 0. + * + * "&L" checks if 'a' is true: + * 1) if it is true does nothing. + * 2) If it is false pushes 0 and skips instructions to reach + * the opcode just after &R + * "&R" checks if 'a' is true: + * if it is true pushes 1, otherwise pushes 0. + */ +static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t) +{ + int i; + + int leftindex, arity, offset; + + /* Search for the end of the first operator */ + leftindex = expr->len - 1; + + arity = 1; + while (arity) { + ScriptToken *tt = &expr->token[leftindex]; + + if (tt->type >= JIM_TT_EXPR_OP) { + arity += JimExprOperatorInfoByOpcode(tt->type)->arity; + } + arity--; + if (--leftindex < 0) { + return JIM_ERR; + } + } + leftindex++; + + /* Move them up */ + memmove(&expr->token[leftindex + 2], &expr->token[leftindex], + sizeof(*expr->token) * (expr->len - leftindex)); + expr->len += 2; + offset = (expr->len - leftindex) - 1; + + /* Now we rely on the fact the the left and right version have opcodes + * 1 and 2 after the main opcode respectively + */ + expr->token[leftindex + 1].type = t->type + 1; + expr->token[leftindex + 1].objPtr = interp->emptyObj; + + expr->token[leftindex].type = JIM_TT_EXPR_INT; + expr->token[leftindex].objPtr = Jim_NewIntObj(interp, offset); + + /* Now add the 'R' operator */ + expr->token[expr->len].objPtr = interp->emptyObj; + expr->token[expr->len].type = t->type + 2; + expr->len++; + + /* Do we need to adjust the skip count for any &L, |L, ?L or :L in the left operand? */ + for (i = leftindex - 1; i > 0; i--) { + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(expr->token[i].type); + if (op->lazy == LAZY_LEFT) { + if (JimWideValue(expr->token[i - 1].objPtr) + i - 1 >= leftindex) { + JimWideValue(expr->token[i - 1].objPtr) += 2; + } + } + } + return JIM_OK; +} + +static int ExprAddOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t) +{ + struct ScriptToken *token = &expr->token[expr->len]; + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type); + + if (op->lazy == LAZY_OP) { + if (ExprAddLazyOperator(interp, expr, t) != JIM_OK) { + Jim_SetResultFormatted(interp, "Expression has bad operands to %s", op->name); + return JIM_ERR; + } + } + else { + token->objPtr = interp->emptyObj; + token->type = t->type; + expr->len++; + } + return JIM_OK; +} + +/** + * Returns the index of the COLON_LEFT to the left of 'right_index' + * taking into account nesting. + * + * The expression *must* be well formed, thus a COLON_LEFT will always be found. + */ +static int ExprTernaryGetColonLeftIndex(ExprByteCode *expr, int right_index) +{ + int ternary_count = 1; + + right_index--; + + while (right_index > 1) { + if (expr->token[right_index].type == JIM_EXPROP_TERNARY_LEFT) { + ternary_count--; + } + else if (expr->token[right_index].type == JIM_EXPROP_COLON_RIGHT) { + ternary_count++; + } + else if (expr->token[right_index].type == JIM_EXPROP_COLON_LEFT && ternary_count == 1) { + return right_index; + } + right_index--; + } + + /*notreached*/ + return -1; +} + +/** + * Find the left/right indices for the ternary expression to the left of 'right_index'. + * + * Returns 1 if found, and fills in *prev_right_index and *prev_left_index. + * Otherwise returns 0. + */ +static int ExprTernaryGetMoveIndices(ExprByteCode *expr, int right_index, int *prev_right_index, int *prev_left_index) +{ + int i = right_index - 1; + int ternary_count = 1; + + while (i > 1) { + if (expr->token[i].type == JIM_EXPROP_TERNARY_LEFT) { + if (--ternary_count == 0 && expr->token[i - 2].type == JIM_EXPROP_COLON_RIGHT) { + *prev_right_index = i - 2; + *prev_left_index = ExprTernaryGetColonLeftIndex(expr, *prev_right_index); + return 1; + } + } + else if (expr->token[i].type == JIM_EXPROP_COLON_RIGHT) { + if (ternary_count == 0) { + return 0; + } + ternary_count++; + } + i--; + } + return 0; +} + +/* +* ExprTernaryReorderExpression description +* ======================================== +* +* ?: is right-to-left associative which doesn't work with the stack-based +* expression engine. The fix is to reorder the bytecode. +* +* The expression: +* +* expr 1?2:0?3:4 +* +* Has initial bytecode: +* +* '1' '2' (40=TERNARY_LEFT) '2' (41=TERNARY_RIGHT) '2' (43=COLON_LEFT) '0' (44=COLON_RIGHT) +* '2' (40=TERNARY_LEFT) '3' (41=TERNARY_RIGHT) '2' (43=COLON_LEFT) '4' (44=COLON_RIGHT) +* +* The fix involves simulating this expression instead: +* +* expr 1?2:(0?3:4) +* +* With the following bytecode: +* +* '1' '2' (40=TERNARY_LEFT) '2' (41=TERNARY_RIGHT) '10' (43=COLON_LEFT) '0' '2' (40=TERNARY_LEFT) +* '3' (41=TERNARY_RIGHT) '2' (43=COLON_LEFT) '4' (44=COLON_RIGHT) (44=COLON_RIGHT) +* +* i.e. The token COLON_RIGHT at index 8 is moved towards the end of the stack, all tokens above 8 +* are shifted down and the skip count of the token JIM_EXPROP_COLON_LEFT at index 5 is +* incremented by the amount tokens shifted down. The token JIM_EXPROP_COLON_RIGHT that is moved +* is identified as immediately preceeding a token JIM_EXPROP_TERNARY_LEFT +* +* ExprTernaryReorderExpression works thus as follows : +* - start from the end of the stack +* - while walking towards the beginning of the stack +* if token=JIM_EXPROP_COLON_RIGHT then +* find the associated token JIM_EXPROP_TERNARY_LEFT, which allows to +* find the associated token previous(JIM_EXPROP_COLON_RIGHT) +* find the associated token previous(JIM_EXPROP_LEFT_RIGHT) +* if all found then +* perform the rotation +* update the skip count of the token previous(JIM_EXPROP_LEFT_RIGHT) +* end if +* end if +* +* Note: care has to be taken for nested ternary constructs!!! +*/ +static void ExprTernaryReorderExpression(Jim_Interp *interp, ExprByteCode *expr) +{ + int i; + + for (i = expr->len - 1; i > 1; i--) { + int prev_right_index; + int prev_left_index; + int j; + ScriptToken tmp; + + if (expr->token[i].type != JIM_EXPROP_COLON_RIGHT) { + continue; + } + + /* COLON_RIGHT found: get the indexes needed to move the tokens in the stack (if any) */ + if (ExprTernaryGetMoveIndices(expr, i, &prev_right_index, &prev_left_index) == 0) { + continue; + } + + /* + ** rotate tokens down + ** + ** +-> [i] : JIM_EXPROP_COLON_RIGHT + ** | | | + ** | V V + ** | [...] : ... + ** | | | + ** | V V + ** | [...] : ... + ** | | | + ** | V V + ** +- [prev_right_index] : JIM_EXPROP_COLON_RIGHT + */ + tmp = expr->token[prev_right_index]; + for (j = prev_right_index; j < i; j++) { + expr->token[j] = expr->token[j + 1]; + } + expr->token[i] = tmp; + + /* Increment the 'skip' count associated to the previous JIM_EXPROP_COLON_LEFT token + * + * This is 'colon left increment' = i - prev_right_index + * + * [prev_left_index] : JIM_EXPROP_LEFT_RIGHT + * [prev_left_index-1] : skip_count + * + */ + JimWideValue(expr->token[prev_left_index-1].objPtr) += (i - prev_right_index); + + /* Adjust for i-- in the loop */ + i++; + } +} + +static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *fileNameObj) +{ + Jim_Stack stack; + ExprByteCode *expr; + int ok = 1; + int i; + int prevtt = JIM_TT_NONE; + int have_ternary = 0; + + /* -1 for EOL */ + int count = tokenlist->count - 1; + + expr = Jim_Alloc(sizeof(*expr)); + expr->inUse = 1; + expr->len = 0; + + Jim_InitStack(&stack); + + /* Need extra bytecodes for lazy operators. + * Also check for the ternary operator + */ + for (i = 0; i < tokenlist->count; i++) { + ParseToken *t = &tokenlist->list[i]; + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type); + + if (op->lazy == LAZY_OP) { + count += 2; + /* Ternary is a lazy op but also needs reordering */ + if (t->type == JIM_EXPROP_TERNARY) { + have_ternary = 1; + } + } + } + + expr->token = Jim_Alloc(sizeof(ScriptToken) * count); + + for (i = 0; i < tokenlist->count && ok; i++) { + ParseToken *t = &tokenlist->list[i]; + + /* Next token will be stored here */ + struct ScriptToken *token = &expr->token[expr->len]; + + if (t->type == JIM_TT_EOL) { + break; + } + + switch (t->type) { + case JIM_TT_STR: + case JIM_TT_ESC: + case JIM_TT_VAR: + case JIM_TT_DICTSUGAR: + case JIM_TT_EXPRSUGAR: + case JIM_TT_CMD: + token->type = t->type; +strexpr: + token->objPtr = Jim_NewStringObj(interp, t->token, t->len); + if (t->type == JIM_TT_CMD) { + /* Only commands need source info */ + JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line); + } + expr->len++; + break; + + case JIM_TT_EXPR_INT: + case JIM_TT_EXPR_DOUBLE: + { + char *endptr; + if (t->type == JIM_TT_EXPR_INT) { + token->objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr)); + } + else { + token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr)); + } + if (endptr != t->token + t->len) { + /* Conversion failed, so just store it as a string */ + Jim_FreeNewObj(interp, token->objPtr); + token->type = JIM_TT_STR; + goto strexpr; + } + token->type = t->type; + expr->len++; + } + break; + + case JIM_TT_SUBEXPR_START: + Jim_StackPush(&stack, t); + prevtt = JIM_TT_NONE; + continue; + + case JIM_TT_SUBEXPR_COMMA: + /* Simple approach. Comma is simply ignored */ + continue; + + case JIM_TT_SUBEXPR_END: + ok = 0; + while (Jim_StackLen(&stack)) { + ParseToken *tt = Jim_StackPop(&stack); + + if (tt->type == JIM_TT_SUBEXPR_START) { + ok = 1; + break; + } + + if (ExprAddOperator(interp, expr, tt) != JIM_OK) { + goto err; + } + } + if (!ok) { + Jim_SetResultString(interp, "Unexpected close parenthesis", -1); + goto err; + } + break; + + + default:{ + /* Must be an operator */ + const struct Jim_ExprOperator *op; + ParseToken *tt; + + /* Convert -/+ to unary minus or unary plus if necessary */ + if (prevtt == JIM_TT_NONE || prevtt >= JIM_TT_EXPR_OP) { + if (t->type == JIM_EXPROP_SUB) { + t->type = JIM_EXPROP_UNARYMINUS; + } + else if (t->type == JIM_EXPROP_ADD) { + t->type = JIM_EXPROP_UNARYPLUS; + } + } + + op = JimExprOperatorInfoByOpcode(t->type); + + /* Now handle precedence */ + while ((tt = Jim_StackPeek(&stack)) != NULL) { + const struct Jim_ExprOperator *tt_op = + JimExprOperatorInfoByOpcode(tt->type); + + /* Note that right-to-left associativity of ?: operator is handled later */ + + if (op->arity != 1 && tt_op->precedence >= op->precedence) { + if (ExprAddOperator(interp, expr, tt) != JIM_OK) { + ok = 0; + goto err; + } + Jim_StackPop(&stack); + } + else { + break; + } + } + Jim_StackPush(&stack, t); + break; + } + } + prevtt = t->type; + } + + /* Reduce any remaining subexpr */ + while (Jim_StackLen(&stack)) { + ParseToken *tt = Jim_StackPop(&stack); + + if (tt->type == JIM_TT_SUBEXPR_START) { + ok = 0; + Jim_SetResultString(interp, "Missing close parenthesis", -1); + goto err; + } + if (ExprAddOperator(interp, expr, tt) != JIM_OK) { + ok = 0; + goto err; + } + } + + if (have_ternary) { + ExprTernaryReorderExpression(interp, expr); + } + + err: + /* Free the stack used for the compilation. */ + Jim_FreeStack(&stack); + + for (i = 0; i < expr->len; i++) { + Jim_IncrRefCount(expr->token[i].objPtr); + } + + if (!ok) { + ExprFreeByteCode(interp, expr); + return NULL; + } + + return expr; +} + + +/* This method takes the string representation of an expression + * and generates a program for the Expr's stack-based VM. */ +static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + int exprTextLen; + const char *exprText; + struct JimParserCtx parser; + struct ExprByteCode *expr; + ParseTokenList tokenlist; + int line; + Jim_Obj *fileNameObj; + int rc = JIM_ERR; + + /* Try to get information about filename / line number */ + if (objPtr->typePtr == &sourceObjType) { + fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; + line = objPtr->internalRep.sourceValue.lineNumber; + } + else { + fileNameObj = interp->emptyObj; + line = 1; + } + Jim_IncrRefCount(fileNameObj); + + exprText = Jim_GetString(objPtr, &exprTextLen); + + /* Initially tokenise the expression into tokenlist */ + ScriptTokenListInit(&tokenlist); + + JimParserInit(&parser, exprText, exprTextLen, line); + while (!parser.eof) { + if (JimParseExpression(&parser) != JIM_OK) { + ScriptTokenListFree(&tokenlist); + invalidexpr: + Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr); + expr = NULL; + goto err; + } + + ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, + parser.tline); + } + +#ifdef DEBUG_SHOW_EXPR_TOKENS + { + int i; + printf("==== Expr Tokens ====\n"); + for (i = 0; i < tokenlist.count; i++) { + printf("[%2d]@%d %s '%.*s'\n", i, tokenlist.list[i].line, jim_tt_name(tokenlist.list[i].type), + tokenlist.list[i].len, tokenlist.list[i].token); + } + } +#endif + + /* Now create the expression bytecode from the tokenlist */ + expr = ExprCreateByteCode(interp, &tokenlist, fileNameObj); + + /* No longer need the token list */ + ScriptTokenListFree(&tokenlist); + + if (!expr) { + goto err; + } + +#ifdef DEBUG_SHOW_EXPR + { + int i; + + printf("==== Expr ====\n"); + for (i = 0; i < expr->len; i++) { + ScriptToken *t = &expr->token[i]; + + printf("[%2d] %s '%s'\n", i, jim_tt_name(t->type), Jim_String(t->objPtr)); + } + } +#endif + + /* Check program correctness. */ + if (ExprCheckCorrectness(expr) != JIM_OK) { + ExprFreeByteCode(interp, expr); + goto invalidexpr; + } + + rc = JIM_OK; + + err: + /* Free the old internal rep and set the new one. */ + Jim_DecrRefCount(interp, fileNameObj); + Jim_FreeIntRep(interp, objPtr); + Jim_SetIntRepPtr(objPtr, expr); + objPtr->typePtr = &exprObjType; + return rc; +} + +static ExprByteCode *JimGetExpression(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr->typePtr != &exprObjType) { + if (SetExprFromAny(interp, objPtr) != JIM_OK) { + return NULL; + } + } + return (ExprByteCode *) Jim_GetIntRepPtr(objPtr); +} + +/* ----------------------------------------------------------------------------- + * Expressions evaluation. + * Jim uses a specialized stack-based virtual machine for expressions, + * that takes advantage of the fact that expr's operators + * can't be redefined. + * + * Jim_EvalExpression() uses the bytecode compiled by + * SetExprFromAny() method of the "expression" object. + * + * On success a Tcl Object containing the result of the evaluation + * is stored into expResultPtrPtr (having refcount of 1), and JIM_OK is + * returned. + * On error the function returns a retcode != to JIM_OK and set a suitable + * error on the interp. + * ---------------------------------------------------------------------------*/ +#define JIM_EE_STATICSTACK_LEN 10 + +int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr) +{ + ExprByteCode *expr; + Jim_Obj *staticStack[JIM_EE_STATICSTACK_LEN]; + int i; + int retcode = JIM_OK; + struct JimExprState e; + + expr = JimGetExpression(interp, exprObjPtr); + if (!expr) { + return JIM_ERR; /* error in expression. */ + } + +#ifdef JIM_OPTIMIZATION + /* Check for one of the following common expressions used by while/for + * + * CONST + * $a + * !$a + * $a < CONST, $a < $b + * $a <= CONST, $a <= $b + * $a > CONST, $a > $b + * $a >= CONST, $a >= $b + * $a != CONST, $a != $b + * $a == CONST, $a == $b + */ + { + Jim_Obj *objPtr; + + /* STEP 1 -- Check if there are the conditions to run the specialized + * version of while */ + + switch (expr->len) { + case 1: + if (expr->token[0].type == JIM_TT_EXPR_INT) { + *exprResultPtrPtr = expr->token[0].objPtr; + Jim_IncrRefCount(*exprResultPtrPtr); + return JIM_OK; + } + if (expr->token[0].type == JIM_TT_VAR) { + objPtr = Jim_GetVariable(interp, expr->token[0].objPtr, JIM_ERRMSG); + if (objPtr) { + *exprResultPtrPtr = objPtr; + Jim_IncrRefCount(*exprResultPtrPtr); + return JIM_OK; + } + } + break; + + case 2: + if (expr->token[1].type == JIM_EXPROP_NOT && expr->token[0].type == JIM_TT_VAR) { + jim_wide wideValue; + + objPtr = Jim_GetVariable(interp, expr->token[0].objPtr, JIM_NONE); + if (objPtr && JimIsWide(objPtr) + && Jim_GetWide(interp, objPtr, &wideValue) == JIM_OK) { + *exprResultPtrPtr = wideValue ? interp->falseObj : interp->trueObj; + Jim_IncrRefCount(*exprResultPtrPtr); + return JIM_OK; + } + } + break; + + case 3: + if (expr->token[0].type == JIM_TT_VAR && (expr->token[1].type == JIM_TT_EXPR_INT + || expr->token[1].type == JIM_TT_VAR)) { + switch (expr->token[2].type) { + case JIM_EXPROP_LT: + case JIM_EXPROP_LTE: + case JIM_EXPROP_GT: + case JIM_EXPROP_GTE: + case JIM_EXPROP_NUMEQ: + case JIM_EXPROP_NUMNE:{ + /* optimise ok */ + jim_wide wideValueA; + jim_wide wideValueB; + + objPtr = Jim_GetVariable(interp, expr->token[0].objPtr, JIM_NONE); + if (objPtr && JimIsWide(objPtr) + && Jim_GetWide(interp, objPtr, &wideValueA) == JIM_OK) { + if (expr->token[1].type == JIM_TT_VAR) { + objPtr = + Jim_GetVariable(interp, expr->token[1].objPtr, + JIM_NONE); + } + else { + objPtr = expr->token[1].objPtr; + } + if (objPtr && JimIsWide(objPtr) + && Jim_GetWide(interp, objPtr, &wideValueB) == JIM_OK) { + int cmpRes; + + switch (expr->token[2].type) { + case JIM_EXPROP_LT: + cmpRes = wideValueA < wideValueB; + break; + case JIM_EXPROP_LTE: + cmpRes = wideValueA <= wideValueB; + break; + case JIM_EXPROP_GT: + cmpRes = wideValueA > wideValueB; + break; + case JIM_EXPROP_GTE: + cmpRes = wideValueA >= wideValueB; + break; + case JIM_EXPROP_NUMEQ: + cmpRes = wideValueA == wideValueB; + break; + case JIM_EXPROP_NUMNE: + cmpRes = wideValueA != wideValueB; + break; + default: /*notreached */ + cmpRes = 0; + } + *exprResultPtrPtr = + cmpRes ? interp->trueObj : interp->falseObj; + Jim_IncrRefCount(*exprResultPtrPtr); + return JIM_OK; + } + } + } + } + } + break; + } + } +#endif + + /* In order to avoid that the internal repr gets freed due to + * shimmering of the exprObjPtr's object, we make the internal rep + * shared. */ + expr->inUse++; + + /* The stack-based expr VM itself */ + + /* Stack allocation. Expr programs have the feature that + * a program of length N can't require a stack longer than + * N. */ + if (expr->len > JIM_EE_STATICSTACK_LEN) + e.stack = Jim_Alloc(sizeof(Jim_Obj *) * expr->len); + else + e.stack = staticStack; + + e.stacklen = 0; + + /* Execute every instruction */ + for (i = 0; i < expr->len && retcode == JIM_OK; i++) { + Jim_Obj *objPtr; + + switch (expr->token[i].type) { + case JIM_TT_EXPR_INT: + case JIM_TT_EXPR_DOUBLE: + case JIM_TT_STR: + ExprPush(&e, expr->token[i].objPtr); + break; + + case JIM_TT_VAR: + objPtr = Jim_GetVariable(interp, expr->token[i].objPtr, JIM_ERRMSG); + if (objPtr) { + ExprPush(&e, objPtr); + } + else { + retcode = JIM_ERR; + } + break; + + case JIM_TT_DICTSUGAR: + objPtr = JimExpandDictSugar(interp, expr->token[i].objPtr); + if (objPtr) { + ExprPush(&e, objPtr); + } + else { + retcode = JIM_ERR; + } + break; + + case JIM_TT_ESC: + retcode = Jim_SubstObj(interp, expr->token[i].objPtr, &objPtr, JIM_NONE); + if (retcode == JIM_OK) { + ExprPush(&e, objPtr); + } + break; + + case JIM_TT_CMD: + retcode = Jim_EvalObj(interp, expr->token[i].objPtr); + if (retcode == JIM_OK) { + ExprPush(&e, Jim_GetResult(interp)); + } + break; + + default:{ + /* Find and execute the operation */ + e.skip = 0; + e.opcode = expr->token[i].type; + + retcode = JimExprOperatorInfoByOpcode(e.opcode)->funcop(interp, &e); + /* Skip some opcodes if necessary */ + i += e.skip; + continue; + } + } + } + + expr->inUse--; + + if (retcode == JIM_OK) { + *exprResultPtrPtr = ExprPop(&e); + } + else { + for (i = 0; i < e.stacklen; i++) { + Jim_DecrRefCount(interp, e.stack[i]); + } + } + if (e.stack != staticStack) { + Jim_Free(e.stack); + } + return retcode; +} + +int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr) +{ + int retcode; + jim_wide wideValue; + double doubleValue; + Jim_Obj *exprResultPtr; + + retcode = Jim_EvalExpression(interp, exprObjPtr, &exprResultPtr); + if (retcode != JIM_OK) + return retcode; + + if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) { + if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK) { + Jim_DecrRefCount(interp, exprResultPtr); + return JIM_ERR; + } + else { + Jim_DecrRefCount(interp, exprResultPtr); + *boolPtr = doubleValue != 0; + return JIM_OK; + } + } + *boolPtr = wideValue != 0; + + Jim_DecrRefCount(interp, exprResultPtr); + return JIM_OK; +} + +/* ----------------------------------------------------------------------------- + * ScanFormat String Object + * ---------------------------------------------------------------------------*/ + +/* This Jim_Obj will held a parsed representation of a format string passed to + * the Jim_ScanString command. For error diagnostics, the scanformat string has + * to be parsed in its entirely first and then, if correct, can be used for + * scanning. To avoid endless re-parsing, the parsed representation will be + * stored in an internal representation and re-used for performance reason. */ + +/* A ScanFmtPartDescr will held the information of /one/ part of the whole + * scanformat string. This part will later be used to extract information + * out from the string to be parsed by Jim_ScanString */ + +typedef struct ScanFmtPartDescr +{ + char *arg; /* Specification of a CHARSET conversion */ + char *prefix; /* Prefix to be scanned literally before conversion */ + size_t width; /* Maximal width of input to be converted */ + int pos; /* -1 - no assign, 0 - natural pos, >0 - XPG3 pos */ + char type; /* Type of conversion (e.g. c, d, f) */ + char modifier; /* Modify type (e.g. l - long, h - short */ +} ScanFmtPartDescr; + +/* The ScanFmtStringObj will hold the internal representation of a scanformat + * string parsed and separated in part descriptions. Furthermore it contains + * the original string representation of the scanformat string to allow for + * fast update of the Jim_Obj's string representation part. + * + * As an add-on the internal object representation adds some scratch pad area + * for usage by Jim_ScanString to avoid endless allocating and freeing of + * memory for purpose of string scanning. + * + * The error member points to a static allocated string in case of a mal- + * formed scanformat string or it contains '0' (NULL) in case of a valid + * parse representation. + * + * The whole memory of the internal representation is allocated as a single + * area of memory that will be internally separated. So freeing and duplicating + * of such an object is cheap */ + +typedef struct ScanFmtStringObj +{ + jim_wide size; /* Size of internal repr in bytes */ + char *stringRep; /* Original string representation */ + size_t count; /* Number of ScanFmtPartDescr contained */ + size_t convCount; /* Number of conversions that will assign */ + size_t maxPos; /* Max position index if XPG3 is used */ + const char *error; /* Ptr to error text (NULL if no error */ + char *scratch; /* Some scratch pad used by Jim_ScanString */ + ScanFmtPartDescr descr[1]; /* The vector of partial descriptions */ +} ScanFmtStringObj; + + +static void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static void UpdateStringOfScanFmt(Jim_Obj *objPtr); + +static const Jim_ObjType scanFmtStringObjType = { + "scanformatstring", + FreeScanFmtInternalRep, + DupScanFmtInternalRep, + UpdateStringOfScanFmt, + JIM_TYPE_NONE, +}; + +void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + JIM_NOTUSED(interp); + Jim_Free((char *)objPtr->internalRep.ptr); + objPtr->internalRep.ptr = 0; +} + +void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + size_t size = (size_t) ((ScanFmtStringObj *) srcPtr->internalRep.ptr)->size; + ScanFmtStringObj *newVec = (ScanFmtStringObj *) Jim_Alloc(size); + + JIM_NOTUSED(interp); + memcpy(newVec, srcPtr->internalRep.ptr, size); + dupPtr->internalRep.ptr = newVec; + dupPtr->typePtr = &scanFmtStringObjType; +} + +void UpdateStringOfScanFmt(Jim_Obj *objPtr) +{ + char *bytes = ((ScanFmtStringObj *) objPtr->internalRep.ptr)->stringRep; + + objPtr->bytes = Jim_StrDup(bytes); + objPtr->length = strlen(bytes); +} + +/* SetScanFmtFromAny will parse a given string and create the internal + * representation of the format specification. In case of an error + * the error data member of the internal representation will be set + * to an descriptive error text and the function will be left with + * JIM_ERR to indicate unsucessful parsing (aka. malformed scanformat + * specification */ + +static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + ScanFmtStringObj *fmtObj; + char *buffer; + int maxCount, i, approxSize, lastPos = -1; + const char *fmt = objPtr->bytes; + int maxFmtLen = objPtr->length; + const char *fmtEnd = fmt + maxFmtLen; + int curr; + + Jim_FreeIntRep(interp, objPtr); + /* Count how many conversions could take place maximally */ + for (i = 0, maxCount = 0; i < maxFmtLen; ++i) + if (fmt[i] == '%') + ++maxCount; + /* Calculate an approximation of the memory necessary */ + approxSize = sizeof(ScanFmtStringObj) /* Size of the container */ + +(maxCount + 1) * sizeof(ScanFmtPartDescr) /* Size of all partials */ + +maxFmtLen * sizeof(char) + 3 + 1 /* Scratch + "%n" + '\0' */ + + maxFmtLen * sizeof(char) + 1 /* Original stringrep */ + + maxFmtLen * sizeof(char) /* Arg for CHARSETs */ + +(maxCount + 1) * sizeof(char) /* '\0' for every partial */ + +1; /* safety byte */ + fmtObj = (ScanFmtStringObj *) Jim_Alloc(approxSize); + memset(fmtObj, 0, approxSize); + fmtObj->size = approxSize; + fmtObj->maxPos = 0; + fmtObj->scratch = (char *)&fmtObj->descr[maxCount + 1]; + fmtObj->stringRep = fmtObj->scratch + maxFmtLen + 3 + 1; + memcpy(fmtObj->stringRep, fmt, maxFmtLen); + buffer = fmtObj->stringRep + maxFmtLen + 1; + objPtr->internalRep.ptr = fmtObj; + objPtr->typePtr = &scanFmtStringObjType; + for (i = 0, curr = 0; fmt < fmtEnd; ++fmt) { + int width = 0, skip; + ScanFmtPartDescr *descr = &fmtObj->descr[curr]; + + fmtObj->count++; + descr->width = 0; /* Assume width unspecified */ + /* Overread and store any "literal" prefix */ + if (*fmt != '%' || fmt[1] == '%') { + descr->type = 0; + descr->prefix = &buffer[i]; + for (; fmt < fmtEnd; ++fmt) { + if (*fmt == '%') { + if (fmt[1] != '%') + break; + ++fmt; + } + buffer[i++] = *fmt; + } + buffer[i++] = 0; + } + /* Skip the conversion introducing '%' sign */ + ++fmt; + /* End reached due to non-conversion literal only? */ + if (fmt >= fmtEnd) + goto done; + descr->pos = 0; /* Assume "natural" positioning */ + if (*fmt == '*') { + descr->pos = -1; /* Okay, conversion will not be assigned */ + ++fmt; + } + else + fmtObj->convCount++; /* Otherwise count as assign-conversion */ + /* Check if next token is a number (could be width or pos */ + if (sscanf(fmt, "%d%n", &width, &skip) == 1) { + fmt += skip; + /* Was the number a XPG3 position specifier? */ + if (descr->pos != -1 && *fmt == '$') { + int prev; + + ++fmt; + descr->pos = width; + width = 0; + /* Look if "natural" postioning and XPG3 one was mixed */ + if ((lastPos == 0 && descr->pos > 0) + || (lastPos > 0 && descr->pos == 0)) { + fmtObj->error = "cannot mix \"%\" and \"%n$\" conversion specifiers"; + return JIM_ERR; + } + /* Look if this position was already used */ + for (prev = 0; prev < curr; ++prev) { + if (fmtObj->descr[prev].pos == -1) + continue; + if (fmtObj->descr[prev].pos == descr->pos) { + fmtObj->error = + "variable is assigned by multiple \"%n$\" conversion specifiers"; + return JIM_ERR; + } + } + /* Try to find a width after the XPG3 specifier */ + if (sscanf(fmt, "%d%n", &width, &skip) == 1) { + descr->width = width; + fmt += skip; + } + if (descr->pos > 0 && (size_t) descr->pos > fmtObj->maxPos) + fmtObj->maxPos = descr->pos; + } + else { + /* Number was not a XPG3, so it has to be a width */ + descr->width = width; + } + } + /* If positioning mode was undetermined yet, fix this */ + if (lastPos == -1) + lastPos = descr->pos; + /* Handle CHARSET conversion type ... */ + if (*fmt == '[') { + int swapped = 1, beg = i, end, j; + + descr->type = '['; + descr->arg = &buffer[i]; + ++fmt; + if (*fmt == '^') + buffer[i++] = *fmt++; + if (*fmt == ']') + buffer[i++] = *fmt++; + while (*fmt && *fmt != ']') + buffer[i++] = *fmt++; + if (*fmt != ']') { + fmtObj->error = "unmatched [ in format string"; + return JIM_ERR; + } + end = i; + buffer[i++] = 0; + /* In case a range fence was given "backwards", swap it */ + while (swapped) { + swapped = 0; + for (j = beg + 1; j < end - 1; ++j) { + if (buffer[j] == '-' && buffer[j - 1] > buffer[j + 1]) { + char tmp = buffer[j - 1]; + + buffer[j - 1] = buffer[j + 1]; + buffer[j + 1] = tmp; + swapped = 1; + } + } + } + } + else { + /* Remember any valid modifier if given */ + if (strchr("hlL", *fmt) != 0) + descr->modifier = tolower((int)*fmt++); + + descr->type = *fmt; + if (strchr("efgcsndoxui", *fmt) == 0) { + fmtObj->error = "bad scan conversion character"; + return JIM_ERR; + } + else if (*fmt == 'c' && descr->width != 0) { + fmtObj->error = "field width may not be specified in %c " "conversion"; + return JIM_ERR; + } + else if (*fmt == 'u' && descr->modifier == 'l') { + fmtObj->error = "unsigned wide not supported"; + return JIM_ERR; + } + } + curr++; + } + done: + return JIM_OK; +} + +/* Some accessor macros to allow lowlevel access to fields of internal repr */ + +#define FormatGetCnvCount(_fo_) \ + ((ScanFmtStringObj*)((_fo_)->internalRep.ptr))->convCount +#define FormatGetMaxPos(_fo_) \ + ((ScanFmtStringObj*)((_fo_)->internalRep.ptr))->maxPos +#define FormatGetError(_fo_) \ + ((ScanFmtStringObj*)((_fo_)->internalRep.ptr))->error + +/* JimScanAString is used to scan an unspecified string that ends with + * next WS, or a string that is specified via a charset. + * + */ +static Jim_Obj *JimScanAString(Jim_Interp *interp, const char *sdescr, const char *str) +{ + char *buffer = Jim_StrDup(str); + char *p = buffer; + + while (*str) { + int c; + int n; + + if (!sdescr && isspace(UCHAR(*str))) + break; /* EOS via WS if unspecified */ + + n = utf8_tounicode(str, &c); + if (sdescr && !JimCharsetMatch(sdescr, c, JIM_CHARSET_SCAN)) + break; + while (n--) + *p++ = *str++; + } + *p = 0; + return Jim_NewStringObjNoAlloc(interp, buffer, p - buffer); +} + +/* ScanOneEntry will scan one entry out of the string passed as argument. + * It use the sscanf() function for this task. After extracting and + * converting of the value, the count of scanned characters will be + * returned of -1 in case of no conversion tool place and string was + * already scanned thru */ + +static int ScanOneEntry(Jim_Interp *interp, const char *str, int pos, int strLen, + ScanFmtStringObj * fmtObj, long idx, Jim_Obj **valObjPtr) +{ + const char *tok; + const ScanFmtPartDescr *descr = &fmtObj->descr[idx]; + size_t scanned = 0; + size_t anchor = pos; + int i; + Jim_Obj *tmpObj = NULL; + + /* First pessimistically assume, we will not scan anything :-) */ + *valObjPtr = 0; + if (descr->prefix) { + /* There was a prefix given before the conversion, skip it and adjust + * the string-to-be-parsed accordingly */ + /* XXX: Should be checking strLen, not str[pos] */ + for (i = 0; pos < strLen && descr->prefix[i]; ++i) { + /* If prefix require, skip WS */ + if (isspace(UCHAR(descr->prefix[i]))) + while (pos < strLen && isspace(UCHAR(str[pos]))) + ++pos; + else if (descr->prefix[i] != str[pos]) + break; /* Prefix do not match here, leave the loop */ + else + ++pos; /* Prefix matched so far, next round */ + } + if (pos >= strLen) { + return -1; /* All of str consumed: EOF condition */ + } + else if (descr->prefix[i] != 0) + return 0; /* Not whole prefix consumed, no conversion possible */ + } + /* For all but following conversion, skip leading WS */ + if (descr->type != 'c' && descr->type != '[' && descr->type != 'n') + while (isspace(UCHAR(str[pos]))) + ++pos; + /* Determine how much skipped/scanned so far */ + scanned = pos - anchor; + + /* %c is a special, simple case. no width */ + if (descr->type == 'n') { + /* Return pseudo conversion means: how much scanned so far? */ + *valObjPtr = Jim_NewIntObj(interp, anchor + scanned); + } + else if (pos >= strLen) { + /* Cannot scan anything, as str is totally consumed */ + return -1; + } + else if (descr->type == 'c') { + int c; + scanned += utf8_tounicode(&str[pos], &c); + *valObjPtr = Jim_NewIntObj(interp, c); + return scanned; + } + else { + /* Processing of conversions follows ... */ + if (descr->width > 0) { + /* Do not try to scan as fas as possible but only the given width. + * To ensure this, we copy the part that should be scanned. */ + size_t sLen = utf8_strlen(&str[pos], strLen - pos); + size_t tLen = descr->width > sLen ? sLen : descr->width; + + tmpObj = Jim_NewStringObjUtf8(interp, str + pos, tLen); + tok = tmpObj->bytes; + } + else { + /* As no width was given, simply refer to the original string */ + tok = &str[pos]; + } + switch (descr->type) { + case 'd': + case 'o': + case 'x': + case 'u': + case 'i':{ + char *endp; /* Position where the number finished */ + jim_wide w; + + int base = descr->type == 'o' ? 8 + : descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10; + + /* Try to scan a number with the given base */ + if (base == 0) { + w = jim_strtoull(tok, &endp); + } + else { + w = strtoull(tok, &endp, base); + } + + if (endp != tok) { + /* There was some number sucessfully scanned! */ + *valObjPtr = Jim_NewIntObj(interp, w); + + /* Adjust the number-of-chars scanned so far */ + scanned += endp - tok; + } + else { + /* Nothing was scanned. We have to determine if this + * happened due to e.g. prefix mismatch or input str + * exhausted */ + scanned = *tok ? 0 : -1; + } + break; + } + case 's': + case '[':{ + *valObjPtr = JimScanAString(interp, descr->arg, tok); + scanned += Jim_Length(*valObjPtr); + break; + } + case 'e': + case 'f': + case 'g':{ + char *endp; + double value = strtod(tok, &endp); + + if (endp != tok) { + /* There was some number sucessfully scanned! */ + *valObjPtr = Jim_NewDoubleObj(interp, value); + /* Adjust the number-of-chars scanned so far */ + scanned += endp - tok; + } + else { + /* Nothing was scanned. We have to determine if this + * happened due to e.g. prefix mismatch or input str + * exhausted */ + scanned = *tok ? 0 : -1; + } + break; + } + } + /* If a substring was allocated (due to pre-defined width) do not + * forget to free it */ + if (tmpObj) { + Jim_FreeNewObj(interp, tmpObj); + } + } + return scanned; +} + +/* Jim_ScanString is the workhorse of string scanning. It will scan a given + * string and returns all converted (and not ignored) values in a list back + * to the caller. If an error occured, a NULL pointer will be returned */ + +Jim_Obj *Jim_ScanString(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *fmtObjPtr, int flags) +{ + size_t i, pos; + int scanned = 1; + const char *str = Jim_String(strObjPtr); + int strLen = Jim_Utf8Length(interp, strObjPtr); + Jim_Obj *resultList = 0; + Jim_Obj **resultVec = 0; + int resultc; + Jim_Obj *emptyStr = 0; + ScanFmtStringObj *fmtObj; + + /* This should never happen. The format object should already be of the correct type */ + JimPanic((fmtObjPtr->typePtr != &scanFmtStringObjType, "Jim_ScanString() for non-scan format")); + + fmtObj = (ScanFmtStringObj *) fmtObjPtr->internalRep.ptr; + /* Check if format specification was valid */ + if (fmtObj->error != 0) { + if (flags & JIM_ERRMSG) + Jim_SetResultString(interp, fmtObj->error, -1); + return 0; + } + /* Allocate a new "shared" empty string for all unassigned conversions */ + emptyStr = Jim_NewEmptyStringObj(interp); + Jim_IncrRefCount(emptyStr); + /* Create a list and fill it with empty strings up to max specified XPG3 */ + resultList = Jim_NewListObj(interp, NULL, 0); + if (fmtObj->maxPos > 0) { + for (i = 0; i < fmtObj->maxPos; ++i) + Jim_ListAppendElement(interp, resultList, emptyStr); + JimListGetElements(interp, resultList, &resultc, &resultVec); + } + /* Now handle every partial format description */ + for (i = 0, pos = 0; i < fmtObj->count; ++i) { + ScanFmtPartDescr *descr = &(fmtObj->descr[i]); + Jim_Obj *value = 0; + + /* Only last type may be "literal" w/o conversion - skip it! */ + if (descr->type == 0) + continue; + /* As long as any conversion could be done, we will proceed */ + if (scanned > 0) + scanned = ScanOneEntry(interp, str, pos, strLen, fmtObj, i, &value); + /* In case our first try results in EOF, we will leave */ + if (scanned == -1 && i == 0) + goto eof; + /* Advance next pos-to-be-scanned for the amount scanned already */ + pos += scanned; + + /* value == 0 means no conversion took place so take empty string */ + if (value == 0) + value = Jim_NewEmptyStringObj(interp); + /* If value is a non-assignable one, skip it */ + if (descr->pos == -1) { + Jim_FreeNewObj(interp, value); + } + else if (descr->pos == 0) + /* Otherwise append it to the result list if no XPG3 was given */ + Jim_ListAppendElement(interp, resultList, value); + else if (resultVec[descr->pos - 1] == emptyStr) { + /* But due to given XPG3, put the value into the corr. slot */ + Jim_DecrRefCount(interp, resultVec[descr->pos - 1]); + Jim_IncrRefCount(value); + resultVec[descr->pos - 1] = value; + } + else { + /* Otherwise, the slot was already used - free obj and ERROR */ + Jim_FreeNewObj(interp, value); + goto err; + } + } + Jim_DecrRefCount(interp, emptyStr); + return resultList; + eof: + Jim_DecrRefCount(interp, emptyStr); + Jim_FreeNewObj(interp, resultList); + return (Jim_Obj *)EOF; + err: + Jim_DecrRefCount(interp, emptyStr); + Jim_FreeNewObj(interp, resultList); + return 0; +} + +/* ----------------------------------------------------------------------------- + * Pseudo Random Number Generation + * ---------------------------------------------------------------------------*/ +/* Initialize the sbox with the numbers from 0 to 255 */ +static void JimPrngInit(Jim_Interp *interp) +{ +#define PRNG_SEED_SIZE 256 + int i; + unsigned int *seed; + time_t t = time(NULL); + + interp->prngState = Jim_Alloc(sizeof(Jim_PrngState)); + + seed = Jim_Alloc(PRNG_SEED_SIZE * sizeof(*seed)); + for (i = 0; i < PRNG_SEED_SIZE; i++) { + seed[i] = (rand() ^ t ^ clock()); + } + JimPrngSeed(interp, (unsigned char *)seed, PRNG_SEED_SIZE * sizeof(*seed)); + Jim_Free(seed); +} + +/* Generates N bytes of random data */ +static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len) +{ + Jim_PrngState *prng; + unsigned char *destByte = (unsigned char *)dest; + unsigned int si, sj, x; + + /* initialization, only needed the first time */ + if (interp->prngState == NULL) + JimPrngInit(interp); + prng = interp->prngState; + /* generates 'len' bytes of pseudo-random numbers */ + for (x = 0; x < len; x++) { + prng->i = (prng->i + 1) & 0xff; + si = prng->sbox[prng->i]; + prng->j = (prng->j + si) & 0xff; + sj = prng->sbox[prng->j]; + prng->sbox[prng->i] = sj; + prng->sbox[prng->j] = si; + *destByte++ = prng->sbox[(si + sj) & 0xff]; + } +} + +/* Re-seed the generator with user-provided bytes */ +static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen) +{ + int i; + Jim_PrngState *prng; + + /* initialization, only needed the first time */ + if (interp->prngState == NULL) + JimPrngInit(interp); + prng = interp->prngState; + + /* Set the sbox[i] with i */ + for (i = 0; i < 256; i++) + prng->sbox[i] = i; + /* Now use the seed to perform a random permutation of the sbox */ + for (i = 0; i < seedLen; i++) { + unsigned char t; + + t = prng->sbox[i & 0xFF]; + prng->sbox[i & 0xFF] = prng->sbox[seed[i]]; + prng->sbox[seed[i]] = t; + } + prng->i = prng->j = 0; + + /* discard at least the first 256 bytes of stream. + * borrow the seed buffer for this + */ + for (i = 0; i < 256; i += seedLen) { + JimRandomBytes(interp, seed, seedLen); + } +} + +/* [incr] */ +static int Jim_IncrCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_wide wideValue, increment = 1; + Jim_Obj *intObjPtr; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?increment?"); + return JIM_ERR; + } + if (argc == 3) { + if (Jim_GetWide(interp, argv[2], &increment) != JIM_OK) + return JIM_ERR; + } + intObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); + if (!intObjPtr) { + /* Set missing variable to 0 */ + wideValue = 0; + } + else if (Jim_GetWide(interp, intObjPtr, &wideValue) != JIM_OK) { + return JIM_ERR; + } + if (!intObjPtr || Jim_IsShared(intObjPtr)) { + intObjPtr = Jim_NewIntObj(interp, wideValue + increment); + if (Jim_SetVariable(interp, argv[1], intObjPtr) != JIM_OK) { + Jim_FreeNewObj(interp, intObjPtr); + return JIM_ERR; + } + } + else { + /* Can do it the quick way */ + Jim_InvalidateStringRep(intObjPtr); + JimWideValue(intObjPtr) = wideValue + increment; + + /* The following step is required in order to invalidate the + * string repr of "FOO" if the var name is on the form of "FOO(IDX)" */ + if (argv[1]->typePtr != &variableObjType) { + /* Note that this can't fail since GetVariable already succeeded */ + Jim_SetVariable(interp, argv[1], intObjPtr); + } + } + Jim_SetResult(interp, intObjPtr); + return JIM_OK; +} + + +/* ----------------------------------------------------------------------------- + * Eval + * ---------------------------------------------------------------------------*/ +#define JIM_EVAL_SARGV_LEN 8 /* static arguments vector length */ +#define JIM_EVAL_SINTV_LEN 8 /* static interpolation vector length */ + +/* Handle calls to the [unknown] command */ +static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retcode; + + /* If JimUnknown() is recursively called too many times... + * done here + */ + if (interp->unknown_called > 50) { + return JIM_ERR; + } + + /* The object interp->unknown just contains + * the "unknown" string, it is used in order to + * avoid to lookup the unknown command every time + * but instead to cache the result. */ + + /* If the [unknown] command does not exist ... */ + if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL) + return JIM_ERR; + + interp->unknown_called++; + /* XXX: Are we losing fileNameObj and linenr? */ + retcode = Jim_EvalObjPrefix(interp, interp->unknown, argc, argv); + interp->unknown_called--; + + return retcode; +} + +static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv) +{ + int retcode; + Jim_Cmd *cmdPtr = Jim_GetCommand(interp, objv[0], JIM_ERRMSG); + + if (cmdPtr == NULL) { + return JimUnknown(interp, objc, objv); + } + if (interp->evalDepth == interp->maxEvalDepth) { + Jim_SetResultString(interp, "Infinite eval recursion", -1); + return JIM_ERR; + } + interp->evalDepth++; + + /* Call it -- Make sure result is an empty object. */ + JimIncrCmdRefCount(cmdPtr); + Jim_SetEmptyResult(interp); + if (cmdPtr->isproc) { + retcode = JimCallProcedure(interp, cmdPtr, objc, objv); + } + else { + interp->cmdPrivData = cmdPtr->u.native.privData; + retcode = cmdPtr->u.native.cmdProc(interp, objc, objv); + } + JimDecrCmdRefCount(interp, cmdPtr); + interp->evalDepth--; + + return retcode; +} + +/* Eval the object vector 'objv' composed of 'objc' elements. + * Every element is used as single argument. + * Jim_EvalObj() will call this function every time its object + * argument is of "list" type, with no string representation. + * + * This is possible because the string representation of a + * list object generated by the UpdateStringOfList is made + * in a way that ensures that every list element is a different + * command argument. */ +int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv) +{ + int i, retcode; + + /* Incr refcount of arguments. */ + for (i = 0; i < objc; i++) + Jim_IncrRefCount(objv[i]); + + retcode = JimInvokeCommand(interp, objc, objv); + + /* Decr refcount of arguments and return the retcode */ + for (i = 0; i < objc; i++) + Jim_DecrRefCount(interp, objv[i]); + + return retcode; +} + +/** + * Invokes 'prefix' as a command with the objv array as arguments. + */ +int Jim_EvalObjPrefix(Jim_Interp *interp, Jim_Obj *prefix, int objc, Jim_Obj *const *objv) +{ + int ret; + Jim_Obj **nargv = Jim_Alloc((objc + 1) * sizeof(*nargv)); + + nargv[0] = prefix; + memcpy(&nargv[1], &objv[0], sizeof(nargv[0]) * objc); + ret = Jim_EvalObjVector(interp, objc + 1, nargv); + Jim_Free(nargv); + return ret; +} + +static void JimAddErrorToStack(Jim_Interp *interp, int retcode, ScriptObj *script) +{ + int rc = retcode; + + if (rc == JIM_ERR && !interp->errorFlag) { + /* This is the first error, so save the file/line information and reset the stack */ + interp->errorFlag = 1; + Jim_IncrRefCount(script->fileNameObj); + Jim_DecrRefCount(interp, interp->errorFileNameObj); + interp->errorFileNameObj = script->fileNameObj; + interp->errorLine = script->linenr; + + JimResetStackTrace(interp); + /* Always add a level where the error first occurs */ + interp->addStackTrace++; + } + + /* Now if this is an "interesting" level, add it to the stack trace */ + if (rc == JIM_ERR && interp->addStackTrace > 0) { + /* Add the stack info for the current level */ + + JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr); + + /* Note: if we didn't have a filename for this level, + * don't clear the addStackTrace flag + * so we can pick it up at the next level + */ + if (Jim_Length(script->fileNameObj)) { + interp->addStackTrace = 0; + } + + Jim_DecrRefCount(interp, interp->errorProc); + interp->errorProc = interp->emptyObj; + Jim_IncrRefCount(interp->errorProc); + } + else if (rc == JIM_RETURN && interp->returnCode == JIM_ERR) { + /* Propagate the addStackTrace value through 'return -code error' */ + } + else { + interp->addStackTrace = 0; + } +} + +static int JimSubstOneToken(Jim_Interp *interp, const ScriptToken *token, Jim_Obj **objPtrPtr) +{ + Jim_Obj *objPtr; + + switch (token->type) { + case JIM_TT_STR: + case JIM_TT_ESC: + objPtr = token->objPtr; + break; + case JIM_TT_VAR: + objPtr = Jim_GetVariable(interp, token->objPtr, JIM_ERRMSG); + break; + case JIM_TT_DICTSUGAR: + objPtr = JimExpandDictSugar(interp, token->objPtr); + break; + case JIM_TT_EXPRSUGAR: + objPtr = JimExpandExprSugar(interp, token->objPtr); + break; + case JIM_TT_CMD: + switch (Jim_EvalObj(interp, token->objPtr)) { + case JIM_OK: + case JIM_RETURN: + objPtr = interp->result; + break; + case JIM_BREAK: + /* Stop substituting */ + return JIM_BREAK; + case JIM_CONTINUE: + /* just skip this one */ + return JIM_CONTINUE; + default: + return JIM_ERR; + } + break; + default: + JimPanic((1, + "default token type (%d) reached " "in Jim_SubstObj().", token->type)); + objPtr = NULL; + break; + } + if (objPtr) { + *objPtrPtr = objPtr; + return JIM_OK; + } + return JIM_ERR; +} + +/* Interpolate the given tokens into a unique Jim_Obj returned by reference + * via *objPtrPtr. This function is only called by Jim_EvalObj() and Jim_SubstObj() + * The returned object has refcount = 0. + */ +static Jim_Obj *JimInterpolateTokens(Jim_Interp *interp, const ScriptToken * token, int tokens, int flags) +{ + int totlen = 0, i; + Jim_Obj **intv; + Jim_Obj *sintv[JIM_EVAL_SINTV_LEN]; + Jim_Obj *objPtr; + char *s; + + if (tokens <= JIM_EVAL_SINTV_LEN) + intv = sintv; + else + intv = Jim_Alloc(sizeof(Jim_Obj *) * tokens); + + /* Compute every token forming the argument + * in the intv objects vector. */ + for (i = 0; i < tokens; i++) { + switch (JimSubstOneToken(interp, &token[i], &intv[i])) { + case JIM_OK: + case JIM_RETURN: + break; + case JIM_BREAK: + if (flags & JIM_SUBST_FLAG) { + /* Stop here */ + tokens = i; + continue; + } + /* XXX: Should probably set an error about break outside loop */ + /* fall through to error */ + case JIM_CONTINUE: + if (flags & JIM_SUBST_FLAG) { + intv[i] = NULL; + continue; + } + /* XXX: Ditto continue outside loop */ + /* fall through to error */ + default: + while (i--) { + Jim_DecrRefCount(interp, intv[i]); + } + if (intv != sintv) { + Jim_Free(intv); + } + return NULL; + } + Jim_IncrRefCount(intv[i]); + Jim_String(intv[i]); + totlen += intv[i]->length; + } + + /* Fast path return for a single token */ + if (tokens == 1 && intv[0] && intv == sintv) { + Jim_DecrRefCount(interp, intv[0]); + return intv[0]; + } + + /* Concatenate every token in an unique + * object. */ + objPtr = Jim_NewStringObjNoAlloc(interp, NULL, 0); + + if (tokens == 4 && token[0].type == JIM_TT_ESC && token[1].type == JIM_TT_ESC + && token[2].type == JIM_TT_VAR) { + /* May be able to do fast interpolated object -> dictSubst */ + objPtr->typePtr = &interpolatedObjType; + objPtr->internalRep.dictSubstValue.varNameObjPtr = token[0].objPtr; + objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2]; + Jim_IncrRefCount(intv[2]); + } + + s = objPtr->bytes = Jim_Alloc(totlen + 1); + objPtr->length = totlen; + for (i = 0; i < tokens; i++) { + if (intv[i]) { + memcpy(s, intv[i]->bytes, intv[i]->length); + s += intv[i]->length; + Jim_DecrRefCount(interp, intv[i]); + } + } + objPtr->bytes[totlen] = '\0'; + /* Free the intv vector if not static. */ + if (intv != sintv) { + Jim_Free(intv); + } + + return objPtr; +} + + +/* listPtr *must* be a list. + * The contents of the list is evaluated with the first element as the command and + * the remaining elements as the arguments. + */ +static int JimEvalObjList(Jim_Interp *interp, Jim_Obj *listPtr) +{ + int retcode = JIM_OK; + + if (listPtr->internalRep.listValue.len) { + Jim_IncrRefCount(listPtr); + retcode = JimInvokeCommand(interp, + listPtr->internalRep.listValue.len, + listPtr->internalRep.listValue.ele); + Jim_DecrRefCount(interp, listPtr); + } + return retcode; +} + +int Jim_EvalObjList(Jim_Interp *interp, Jim_Obj *listPtr) +{ + SetListFromAny(interp, listPtr); + return JimEvalObjList(interp, listPtr); +} + +int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) +{ + int i; + ScriptObj *script; + ScriptToken *token; + int retcode = JIM_OK; + Jim_Obj *sargv[JIM_EVAL_SARGV_LEN], **argv = NULL; + Jim_Obj *prevScriptObj; + + /* If the object is of type "list", with no string rep we can call + * a specialized version of Jim_EvalObj() */ + if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) { + return JimEvalObjList(interp, scriptObjPtr); + } + + Jim_IncrRefCount(scriptObjPtr); /* Make sure it's shared. */ + script = Jim_GetScript(interp, scriptObjPtr); + + /* Reset the interpreter result. This is useful to + * return the empty result in the case of empty program. */ + Jim_SetEmptyResult(interp); + + token = script->token; + +#ifdef JIM_OPTIMIZATION + /* Check for one of the following common scripts used by for, while + * + * {} + * incr a + */ + if (script->len == 0) { + Jim_DecrRefCount(interp, scriptObjPtr); + return JIM_OK; + } + if (script->len == 3 + && token[1].objPtr->typePtr == &commandObjType + && token[1].objPtr->internalRep.cmdValue.cmdPtr->isproc == 0 + && token[1].objPtr->internalRep.cmdValue.cmdPtr->u.native.cmdProc == Jim_IncrCoreCommand + && token[2].objPtr->typePtr == &variableObjType) { + + Jim_Obj *objPtr = Jim_GetVariable(interp, token[2].objPtr, JIM_NONE); + + if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) { + JimWideValue(objPtr)++; + Jim_InvalidateStringRep(objPtr); + Jim_DecrRefCount(interp, scriptObjPtr); + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + } +#endif + + /* Now we have to make sure the internal repr will not be + * freed on shimmering. + * + * Think for example to this: + * + * set x {llength $x; ... some more code ...}; eval $x + * + * In order to preserve the internal rep, we increment the + * inUse field of the script internal rep structure. */ + script->inUse++; + + /* Stash the current script */ + prevScriptObj = interp->currentScriptObj; + interp->currentScriptObj = scriptObjPtr; + + interp->errorFlag = 0; + argv = sargv; + + /* Execute every command sequentially until the end of the script + * or an error occurs. + */ + for (i = 0; i < script->len && retcode == JIM_OK; ) { + int argc; + int j; + + /* First token of the line is always JIM_TT_LINE */ + argc = token[i].objPtr->internalRep.scriptLineValue.argc; + script->linenr = token[i].objPtr->internalRep.scriptLineValue.line; + + /* Allocate the arguments vector if required */ + if (argc > JIM_EVAL_SARGV_LEN) + argv = Jim_Alloc(sizeof(Jim_Obj *) * argc); + + /* Skip the JIM_TT_LINE token */ + i++; + + /* Populate the arguments objects. + * If an error occurs, retcode will be set and + * 'j' will be set to the number of args expanded + */ + for (j = 0; j < argc; j++) { + long wordtokens = 1; + int expand = 0; + Jim_Obj *wordObjPtr = NULL; + + if (token[i].type == JIM_TT_WORD) { + wordtokens = JimWideValue(token[i++].objPtr); + if (wordtokens < 0) { + expand = 1; + wordtokens = -wordtokens; + } + } + + if (wordtokens == 1) { + /* Fast path if the token does not + * need interpolation */ + + switch (token[i].type) { + case JIM_TT_ESC: + case JIM_TT_STR: + wordObjPtr = token[i].objPtr; + break; + case JIM_TT_VAR: + wordObjPtr = Jim_GetVariable(interp, token[i].objPtr, JIM_ERRMSG); + break; + case JIM_TT_EXPRSUGAR: + wordObjPtr = JimExpandExprSugar(interp, token[i].objPtr); + break; + case JIM_TT_DICTSUGAR: + wordObjPtr = JimExpandDictSugar(interp, token[i].objPtr); + break; + case JIM_TT_CMD: + retcode = Jim_EvalObj(interp, token[i].objPtr); + if (retcode == JIM_OK) { + wordObjPtr = Jim_GetResult(interp); + } + break; + default: + JimPanic((1, "default token type reached " "in Jim_EvalObj().")); + } + } + else { + /* For interpolation we call a helper + * function to do the work for us. */ + wordObjPtr = JimInterpolateTokens(interp, token + i, wordtokens, JIM_NONE); + } + + if (!wordObjPtr) { + if (retcode == JIM_OK) { + retcode = JIM_ERR; + } + break; + } + + Jim_IncrRefCount(wordObjPtr); + i += wordtokens; + + if (!expand) { + argv[j] = wordObjPtr; + } + else { + /* Need to expand wordObjPtr into multiple args from argv[j] ... */ + int len = Jim_ListLength(interp, wordObjPtr); + int newargc = argc + len - 1; + int k; + + if (len > 1) { + if (argv == sargv) { + if (newargc > JIM_EVAL_SARGV_LEN) { + argv = Jim_Alloc(sizeof(*argv) * newargc); + memcpy(argv, sargv, sizeof(*argv) * j); + } + } + else { + /* Need to realloc to make room for (len - 1) more entries */ + argv = Jim_Realloc(argv, sizeof(*argv) * newargc); + } + } + + /* Now copy in the expanded version */ + for (k = 0; k < len; k++) { + argv[j++] = wordObjPtr->internalRep.listValue.ele[k]; + Jim_IncrRefCount(wordObjPtr->internalRep.listValue.ele[k]); + } + + /* The original object reference is no longer needed, + * after the expansion it is no longer present on + * the argument vector, but the single elements are + * in its place. */ + Jim_DecrRefCount(interp, wordObjPtr); + + /* And update the indexes */ + j--; + argc += len - 1; + } + } + + if (retcode == JIM_OK && argc) { + /* Invoke the command */ + retcode = JimInvokeCommand(interp, argc, argv); + if (interp->signal_level && interp->sigmask) { + /* Check for a signal after each command */ + retcode = JIM_SIGNAL; + } + } + + /* Finished with the command, so decrement ref counts of each argument */ + while (j-- > 0) { + Jim_DecrRefCount(interp, argv[j]); + } + + if (argv != sargv) { + Jim_Free(argv); + argv = sargv; + } + } + + /* Possibly add to the error stack trace */ + JimAddErrorToStack(interp, retcode, script); + + /* Restore the current script */ + interp->currentScriptObj = prevScriptObj; + + /* Note that we don't have to decrement inUse, because the + * following code transfers our use of the reference again to + * the script object. */ + Jim_FreeIntRep(interp, scriptObjPtr); + scriptObjPtr->typePtr = &scriptObjType; + Jim_SetIntRepPtr(scriptObjPtr, script); + Jim_DecrRefCount(interp, scriptObjPtr); + + return retcode; +} + +static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argValObj) +{ + int retcode; + /* If argObjPtr begins with '&', do an automatic upvar */ + const char *varname = Jim_String(argNameObj); + if (*varname == '&') { + /* First check that the target variable exists */ + Jim_Obj *objPtr; + Jim_CallFrame *savedCallFrame = interp->framePtr; + + interp->framePtr = interp->framePtr->parent; + objPtr = Jim_GetVariable(interp, argValObj, JIM_ERRMSG); + interp->framePtr = savedCallFrame; + if (!objPtr) { + return JIM_ERR; + } + + /* It exists, so perform the binding. */ + objPtr = Jim_NewStringObj(interp, varname + 1, -1); + Jim_IncrRefCount(objPtr); + retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parent); + Jim_DecrRefCount(interp, objPtr); + } + else { + retcode = Jim_SetVariable(interp, argNameObj, argValObj); + } + return retcode; +} + +/** + * Sets the interp result to be an error message indicating the required proc args. + */ +static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd) +{ + /* Create a nice error message, consistent with Tcl 8.5 */ + Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0); + int i; + + for (i = 0; i < cmd->u.proc.argListLen; i++) { + Jim_AppendString(interp, argmsg, " ", 1); + + if (i == cmd->u.proc.argsPos) { + if (cmd->u.proc.arglist[i].defaultObjPtr) { + /* Renamed args */ + Jim_AppendString(interp, argmsg, "?", 1); + Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].defaultObjPtr); + Jim_AppendString(interp, argmsg, " ...?", -1); + } + else { + /* We have plain args */ + Jim_AppendString(interp, argmsg, "?arg...?", -1); + } + } + else { + if (cmd->u.proc.arglist[i].defaultObjPtr) { + Jim_AppendString(interp, argmsg, "?", 1); + Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].nameObjPtr); + Jim_AppendString(interp, argmsg, "?", 1); + } + else { + const char *arg = Jim_String(cmd->u.proc.arglist[i].nameObjPtr); + if (*arg == '&') { + arg++; + } + Jim_AppendString(interp, argmsg, arg, -1); + } + } + } + Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s%#s\"", procNameObj, argmsg); + Jim_FreeNewObj(interp, argmsg); +} + +#ifdef jim_ext_namespace +/* + * [namespace eval] + */ +int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj) +{ + Jim_CallFrame *callFramePtr; + int retcode; + + /* Create a new callframe */ + callFramePtr = JimCreateCallFrame(interp, interp->framePtr, nsObj); + callFramePtr->argv = &interp->emptyObj; + callFramePtr->argc = 0; + callFramePtr->procArgsObjPtr = NULL; + callFramePtr->procBodyObjPtr = scriptObj; + callFramePtr->staticVars = NULL; + callFramePtr->fileNameObj = interp->emptyObj; + callFramePtr->line = 0; + Jim_IncrRefCount(scriptObj); + interp->framePtr = callFramePtr; + + /* Check if there are too nested calls */ + if (interp->framePtr->level == interp->maxCallFrameDepth) { + Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1); + retcode = JIM_ERR; + } + else { + /* Eval the body */ + retcode = Jim_EvalObj(interp, scriptObj); + } + + /* Destroy the callframe */ + interp->framePtr = interp->framePtr->parent; + if (callFramePtr->vars.size != JIM_HT_INITIAL_SIZE) { + JimFreeCallFrame(interp, callFramePtr, JIM_FCF_NONE); + } + else { + JimFreeCallFrame(interp, callFramePtr, JIM_FCF_NOHT); + } + + return retcode; +} +#endif + +/* Call a procedure implemented in Tcl. + * It's possible to speed-up a lot this function, currently + * the callframes are not cached, but allocated and + * destroied every time. What is expecially costly is + * to create/destroy the local vars hash table every time. + * + * This can be fixed just implementing callframes caching + * in JimCreateCallFrame() and JimFreeCallFrame(). */ +static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj *const *argv) +{ + Jim_CallFrame *callFramePtr; + int i, d, retcode, optargs; + Jim_Stack *localCommands; + ScriptObj *script; + + /* Check arity */ + if (argc - 1 < cmd->u.proc.reqArity || + (cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) { + JimSetProcWrongArgs(interp, argv[0], cmd); + return JIM_ERR; + } + + if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) { + /* Optimise for procedure with no body - useful for optional debugging */ + return JIM_OK; + } + + /* Check if there are too nested calls */ + if (interp->framePtr->level == interp->maxCallFrameDepth) { + Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1); + return JIM_ERR; + } + + /* Create a new callframe */ + callFramePtr = JimCreateCallFrame(interp, interp->framePtr, cmd->u.proc.nsObj); + callFramePtr->argv = argv; + callFramePtr->argc = argc; + callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr; + callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr; + callFramePtr->staticVars = cmd->u.proc.staticVars; + + /* Remember where we were called from. */ + script = Jim_GetScript(interp, interp->currentScriptObj); + callFramePtr->fileNameObj = script->fileNameObj; + callFramePtr->line = script->linenr; + + Jim_IncrRefCount(cmd->u.proc.argListObjPtr); + Jim_IncrRefCount(cmd->u.proc.bodyObjPtr); + interp->framePtr = callFramePtr; + + /* How many optional args are available */ + optargs = (argc - 1 - cmd->u.proc.reqArity); + + /* Step 'i' along the actual args, and step 'd' along the formal args */ + i = 1; + for (d = 0; d < cmd->u.proc.argListLen; d++) { + Jim_Obj *nameObjPtr = cmd->u.proc.arglist[d].nameObjPtr; + if (d == cmd->u.proc.argsPos) { + /* assign $args */ + Jim_Obj *listObjPtr; + int argsLen = 0; + if (cmd->u.proc.reqArity + cmd->u.proc.optArity < argc - 1) { + argsLen = argc - 1 - (cmd->u.proc.reqArity + cmd->u.proc.optArity); + } + listObjPtr = Jim_NewListObj(interp, &argv[i], argsLen); + + /* It is possible to rename args. */ + if (cmd->u.proc.arglist[d].defaultObjPtr) { + nameObjPtr =cmd->u.proc.arglist[d].defaultObjPtr; + } + retcode = Jim_SetVariable(interp, nameObjPtr, listObjPtr); + if (retcode != JIM_OK) { + goto badargset; + } + + i += argsLen; + continue; + } + + /* Optional or required? */ + if (cmd->u.proc.arglist[d].defaultObjPtr == NULL || optargs-- > 0) { + retcode = JimSetProcArg(interp, nameObjPtr, argv[i++]); + } + else { + /* Ran out, so use the default */ + retcode = Jim_SetVariable(interp, nameObjPtr, cmd->u.proc.arglist[d].defaultObjPtr); + } + if (retcode != JIM_OK) { + goto badargset; + } + } + + /* Eval the body */ + retcode = Jim_EvalObj(interp, cmd->u.proc.bodyObjPtr); + +badargset: + /* Destroy the callframe */ + /* But first remove the local commands */ + localCommands = callFramePtr->localCommands; + callFramePtr->localCommands = NULL; + + interp->framePtr = interp->framePtr->parent; + if (callFramePtr->vars.size != JIM_HT_INITIAL_SIZE) { + JimFreeCallFrame(interp, callFramePtr, JIM_FCF_NONE); + } + else { + JimFreeCallFrame(interp, callFramePtr, JIM_FCF_NOHT); + } + + /* Handle the JIM_EVAL return code */ + while (retcode == JIM_EVAL) { + Jim_Obj *resultScriptObjPtr = Jim_GetResult(interp); + + Jim_IncrRefCount(resultScriptObjPtr); + /* Result must be a list */ + JimPanic((!Jim_IsList(resultScriptObjPtr), "tailcall (JIM_EVAL) returned non-list")); + + retcode = JimEvalObjList(interp, resultScriptObjPtr); + if (retcode == JIM_RETURN) { + /* If the result of the tailcall invokes 'return', push + * it up to the caller + */ + interp->returnLevel++; + } + Jim_DecrRefCount(interp, resultScriptObjPtr); + } + /* Handle the JIM_RETURN return code */ + if (retcode == JIM_RETURN) { + if (--interp->returnLevel <= 0) { + retcode = interp->returnCode; + interp->returnCode = JIM_OK; + interp->returnLevel = 0; + } + } + else if (retcode == JIM_ERR) { + interp->addStackTrace++; + Jim_DecrRefCount(interp, interp->errorProc); + interp->errorProc = argv[0]; + Jim_IncrRefCount(interp->errorProc); + } + + /* Finally delete local procs */ + JimDeleteLocalProcs(interp, localCommands); + + return retcode; +} + +int Jim_EvalSource(Jim_Interp *interp, const char *filename, int lineno, const char *script) +{ + int retval; + Jim_Obj *scriptObjPtr; + + scriptObjPtr = Jim_NewStringObj(interp, script, -1); + Jim_IncrRefCount(scriptObjPtr); + + if (filename) { + Jim_Obj *prevScriptObj; + + JimSetSourceInfo(interp, scriptObjPtr, Jim_NewStringObj(interp, filename, -1), lineno); + + prevScriptObj = interp->currentScriptObj; + interp->currentScriptObj = scriptObjPtr; + + retval = Jim_EvalObj(interp, scriptObjPtr); + + interp->currentScriptObj = prevScriptObj; + } + else { + retval = Jim_EvalObj(interp, scriptObjPtr); + } + Jim_DecrRefCount(interp, scriptObjPtr); + return retval; +} + +int Jim_Eval(Jim_Interp *interp, const char *script) +{ + return Jim_EvalObj(interp, Jim_NewStringObj(interp, script, -1)); +} + +/* Execute script in the scope of the global level */ +int Jim_EvalGlobal(Jim_Interp *interp, const char *script) +{ + int retval; + Jim_CallFrame *savedFramePtr = interp->framePtr; + + interp->framePtr = interp->topFramePtr; + retval = Jim_Eval(interp, script); + interp->framePtr = savedFramePtr; + + return retval; +} + +int Jim_EvalFileGlobal(Jim_Interp *interp, const char *filename) +{ + int retval; + Jim_CallFrame *savedFramePtr = interp->framePtr; + + interp->framePtr = interp->topFramePtr; + retval = Jim_EvalFile(interp, filename); + interp->framePtr = savedFramePtr; + + return retval; +} + +#include + +int Jim_EvalFile(Jim_Interp *interp, const char *filename) +{ + FILE *fp; + char *buf; + Jim_Obj *scriptObjPtr; + Jim_Obj *prevScriptObj; + struct stat sb; + int retcode; + int readlen; + struct JimParseResult result; + + if (stat(filename, &sb) != 0 || (fp = fopen(filename, "rt")) == NULL) { + Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", filename, strerror(errno)); + return JIM_ERR; + } + if (sb.st_size == 0) { + fclose(fp); + return JIM_OK; + } + + buf = Jim_Alloc(sb.st_size + 1); + readlen = fread(buf, 1, sb.st_size, fp); + if (ferror(fp)) { + fclose(fp); + Jim_Free(buf); + Jim_SetResultFormatted(interp, "failed to load file \"%s\": %s", filename, strerror(errno)); + return JIM_ERR; + } + fclose(fp); + buf[readlen] = 0; + + scriptObjPtr = Jim_NewStringObjNoAlloc(interp, buf, readlen); + JimSetSourceInfo(interp, scriptObjPtr, Jim_NewStringObj(interp, filename, -1), 1); + Jim_IncrRefCount(scriptObjPtr); + + /* Now check the script for unmatched braces, etc. */ + if (SetScriptFromAny(interp, scriptObjPtr, &result) == JIM_ERR) { + const char *msg; + char linebuf[20]; + + switch (result.missing) { + case '[': + msg = "unmatched \"[\""; + break; + case '{': + msg = "missing close-brace"; + break; + case '"': + default: + msg = "missing quote"; + break; + } + + snprintf(linebuf, sizeof(linebuf), "%d", result.line); + + Jim_SetResultFormatted(interp, "%s in \"%s\" at line %s", + msg, filename, linebuf); + Jim_DecrRefCount(interp, scriptObjPtr); + return JIM_ERR; + } + + prevScriptObj = interp->currentScriptObj; + interp->currentScriptObj = scriptObjPtr; + + retcode = Jim_EvalObj(interp, scriptObjPtr); + + /* Handle the JIM_RETURN return code */ + if (retcode == JIM_RETURN) { + if (--interp->returnLevel <= 0) { + retcode = interp->returnCode; + interp->returnCode = JIM_OK; + interp->returnLevel = 0; + } + } + if (retcode == JIM_ERR) { + /* EvalFile changes context, so add a stack frame here */ + interp->addStackTrace++; + } + + interp->currentScriptObj = prevScriptObj; + + Jim_DecrRefCount(interp, scriptObjPtr); + + return retcode; +} + +/* ----------------------------------------------------------------------------- + * Subst + * ---------------------------------------------------------------------------*/ +static void JimParseSubst(struct JimParserCtx *pc, int flags) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + + if (pc->len == 0) { + pc->tend = pc->p; + pc->tt = JIM_TT_EOL; + pc->eof = 1; + return; + } + if (*pc->p == '[' && !(flags & JIM_SUBST_NOCMD)) { + JimParseCmd(pc); + return; + } + if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) { + if (JimParseVar(pc) == JIM_OK) { + return; + } + /* Not a var, so treat as a string */ + pc->tstart = pc->p; + flags |= JIM_SUBST_NOVAR; + } + while (pc->len) { + if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) { + break; + } + if (*pc->p == '[' && !(flags & JIM_SUBST_NOCMD)) { + break; + } + if (*pc->p == '\\' && pc->len > 1) { + pc->p++; + pc->len--; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = (flags & JIM_SUBST_NOESC) ? JIM_TT_STR : JIM_TT_ESC; +} + +/* The subst object type reuses most of the data structures and functions + * of the script object. Script's data structures are a bit more complex + * for what is needed for [subst]itution tasks, but the reuse helps to + * deal with a single data structure at the cost of some more memory + * usage for substitutions. */ + +/* This method takes the string representation of an object + * as a Tcl string where to perform [subst]itution, and generates + * the pre-parsed internal representation. */ +static int SetSubstFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, int flags) +{ + int scriptTextLen; + const char *scriptText = Jim_GetString(objPtr, &scriptTextLen); + struct JimParserCtx parser; + struct ScriptObj *script = Jim_Alloc(sizeof(*script)); + ParseTokenList tokenlist; + + /* Initially parse the subst into tokens (in tokenlist) */ + ScriptTokenListInit(&tokenlist); + + JimParserInit(&parser, scriptText, scriptTextLen, 1); + while (1) { + JimParseSubst(&parser, flags); + if (parser.eof) { + /* Note that subst doesn't need the EOL token */ + break; + } + ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, + parser.tline); + } + + /* Create the "real" subst/script tokens from the initial token list */ + script->inUse = 1; + script->substFlags = flags; + script->fileNameObj = interp->emptyObj; + Jim_IncrRefCount(script->fileNameObj); + SubstObjAddTokens(interp, script, &tokenlist); + + /* No longer need the token list */ + ScriptTokenListFree(&tokenlist); + +#ifdef DEBUG_SHOW_SUBST + { + int i; + + printf("==== Subst ====\n"); + for (i = 0; i < script->len; i++) { + printf("[%2d] %s '%s'\n", i, jim_tt_name(script->token[i].type), + Jim_String(script->token[i].objPtr)); + } + } +#endif + + /* Free the old internal rep and set the new one. */ + Jim_FreeIntRep(interp, objPtr); + Jim_SetIntRepPtr(objPtr, script); + objPtr->typePtr = &scriptObjType; + return JIM_OK; +} + +static ScriptObj *Jim_GetSubst(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + if (objPtr->typePtr != &scriptObjType || ((ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags != flags) + SetSubstFromAny(interp, objPtr, flags); + return (ScriptObj *) Jim_GetIntRepPtr(objPtr); +} + +/* Performs commands,variables,blackslashes substitution, + * storing the result object (with refcount 0) into + * resObjPtrPtr. */ +int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPtr, int flags) +{ + ScriptObj *script = Jim_GetSubst(interp, substObjPtr, flags); + + Jim_IncrRefCount(substObjPtr); /* Make sure it's shared. */ + /* In order to preserve the internal rep, we increment the + * inUse field of the script internal rep structure. */ + script->inUse++; + + *resObjPtrPtr = JimInterpolateTokens(interp, script->token, script->len, flags); + + script->inUse--; + Jim_DecrRefCount(interp, substObjPtr); + if (*resObjPtrPtr == NULL) { + return JIM_ERR; + } + return JIM_OK; +} + +/* ----------------------------------------------------------------------------- + * Core commands utility functions + * ---------------------------------------------------------------------------*/ +void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg) +{ + Jim_Obj *objPtr; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, argv, argc); + + if (*msg) { + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1)); + } + Jim_IncrRefCount(listObjPtr); + objPtr = Jim_ListJoin(interp, listObjPtr, " ", 1); + Jim_DecrRefCount(interp, listObjPtr); + + Jim_IncrRefCount(objPtr); + Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s\"", objPtr); + Jim_DecrRefCount(interp, objPtr); +} + +/** + * May add the key and/or value to the list. + */ +typedef void JimHashtableIteratorCallbackType(Jim_Interp *interp, Jim_Obj *listObjPtr, + Jim_HashEntry *he, int type); + +#define JimTrivialMatch(pattern) (strpbrk((pattern), "*[?\\") == NULL) + +/** + * For each key of the hash table 'ht' (with string keys) which matches the glob pattern (all if NULL), + * invoke the callback to add entries to a list. + * Returns the list. + */ +static Jim_Obj *JimHashtablePatternMatch(Jim_Interp *interp, Jim_HashTable *ht, Jim_Obj *patternObjPtr, + JimHashtableIteratorCallbackType *callback, int type) +{ + Jim_HashEntry *he; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + /* Check for the non-pattern case. We can do this much more efficiently. */ + if (patternObjPtr && JimTrivialMatch(Jim_String(patternObjPtr))) { + he = Jim_FindHashEntry(ht, Jim_String(patternObjPtr)); + if (he) { + callback(interp, listObjPtr, he, type); + } + } + else { + Jim_HashTableIterator htiter; + JimInitHashTableIterator(ht, &htiter); + while ((he = Jim_NextHashEntry(&htiter)) != NULL) { + if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), he->key, 0)) { + callback(interp, listObjPtr, he, type); + } + } + } + return listObjPtr; +} + +/* Keep these in order */ +#define JIM_CMDLIST_COMMANDS 0 +#define JIM_CMDLIST_PROCS 1 +#define JIM_CMDLIST_CHANNELS 2 + +/** + * Adds matching command names (procs, channels) to the list. + */ +static void JimCommandMatch(Jim_Interp *interp, Jim_Obj *listObjPtr, + Jim_HashEntry *he, int type) +{ + Jim_Cmd *cmdPtr = (Jim_Cmd *)he->u.val; + Jim_Obj *objPtr; + + if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) { + /* not a proc */ + return; + } + + objPtr = Jim_NewStringObj(interp, he->key, -1); + Jim_IncrRefCount(objPtr); + + if (type != JIM_CMDLIST_CHANNELS || Jim_AioFilehandle(interp, objPtr)) { + Jim_ListAppendElement(interp, listObjPtr, objPtr); + } + Jim_DecrRefCount(interp, objPtr); +} + +/* type is JIM_CMDLIST_xxx */ +static Jim_Obj *JimCommandsList(Jim_Interp *interp, Jim_Obj *patternObjPtr, int type) +{ + return JimHashtablePatternMatch(interp, &interp->commands, patternObjPtr, JimCommandMatch, type); +} + +/* Keep these in order */ +#define JIM_VARLIST_GLOBALS 0 +#define JIM_VARLIST_LOCALS 1 +#define JIM_VARLIST_VARS 2 + +#define JIM_VARLIST_VALUES 0x1000 + +/** + * Adds matching variable names to the list. + */ +static void JimVariablesMatch(Jim_Interp *interp, Jim_Obj *listObjPtr, + Jim_HashEntry *he, int type) +{ + Jim_Var *varPtr = (Jim_Var *)he->u.val; + + if (type != JIM_VARLIST_LOCALS || varPtr->linkFramePtr == NULL) { + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, he->key, -1)); + if (type & JIM_VARLIST_VALUES) { + Jim_ListAppendElement(interp, listObjPtr, varPtr->objPtr); + } + } +} + +/* mode is JIM_VARLIST_xxx */ +static Jim_Obj *JimVariablesList(Jim_Interp *interp, Jim_Obj *patternObjPtr, int mode) +{ + if (mode == JIM_VARLIST_LOCALS && interp->framePtr == interp->topFramePtr) { + /* For [info locals], if we are at top level an emtpy list + * is returned. I don't agree, but we aim at compatibility (SS) */ + return interp->emptyObj; + } + else { + Jim_CallFrame *framePtr = (mode == JIM_VARLIST_GLOBALS) ? interp->topFramePtr : interp->framePtr; + return JimHashtablePatternMatch(interp, &framePtr->vars, patternObjPtr, JimVariablesMatch, mode); + } +} + +static int JimInfoLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr, + Jim_Obj **objPtrPtr, int info_level_cmd) +{ + Jim_CallFrame *targetCallFrame; + + targetCallFrame = JimGetCallFrameByInteger(interp, levelObjPtr); + if (targetCallFrame == NULL) { + return JIM_ERR; + } + /* No proc call at toplevel callframe */ + if (targetCallFrame == interp->topFramePtr) { + Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr); + return JIM_ERR; + } + if (info_level_cmd) { + *objPtrPtr = Jim_NewListObj(interp, targetCallFrame->argv, targetCallFrame->argc); + } + else { + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + + Jim_ListAppendElement(interp, listObj, targetCallFrame->argv[0]); + Jim_ListAppendElement(interp, listObj, targetCallFrame->fileNameObj); + Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, targetCallFrame->line)); + *objPtrPtr = listObj; + } + return JIM_OK; +} + +/* ----------------------------------------------------------------------------- + * Core commands + * ---------------------------------------------------------------------------*/ + +/* fake [puts] -- not the real puts, just for debugging. */ +static int Jim_PutsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "?-nonewline? string"); + return JIM_ERR; + } + if (argc == 3) { + if (!Jim_CompareStringImmediate(interp, argv[1], "-nonewline")) { + Jim_SetResultString(interp, "The second argument must " "be -nonewline", -1); + return JIM_ERR; + } + else { + fputs(Jim_String(argv[2]), stdout); + } + } + else { + puts(Jim_String(argv[1])); + } + return JIM_OK; +} + +/* Helper for [+] and [*] */ +static int JimAddMulHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int op) +{ + jim_wide wideValue, res; + double doubleValue, doubleRes; + int i; + + res = (op == JIM_EXPROP_ADD) ? 0 : 1; + + for (i = 1; i < argc; i++) { + if (Jim_GetWide(interp, argv[i], &wideValue) != JIM_OK) + goto trydouble; + if (op == JIM_EXPROP_ADD) + res += wideValue; + else + res *= wideValue; + } + Jim_SetResultInt(interp, res); + return JIM_OK; + trydouble: + doubleRes = (double)res; + for (; i < argc; i++) { + if (Jim_GetDouble(interp, argv[i], &doubleValue) != JIM_OK) + return JIM_ERR; + if (op == JIM_EXPROP_ADD) + doubleRes += doubleValue; + else + doubleRes *= doubleValue; + } + Jim_SetResult(interp, Jim_NewDoubleObj(interp, doubleRes)); + return JIM_OK; +} + +/* Helper for [-] and [/] */ +static int JimSubDivHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int op) +{ + jim_wide wideValue, res = 0; + double doubleValue, doubleRes = 0; + int i = 2; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "number ?number ... number?"); + return JIM_ERR; + } + else if (argc == 2) { + /* The arity = 2 case is different. For [- x] returns -x, + * while [/ x] returns 1/x. */ + if (Jim_GetWide(interp, argv[1], &wideValue) != JIM_OK) { + if (Jim_GetDouble(interp, argv[1], &doubleValue) != JIM_OK) { + return JIM_ERR; + } + else { + if (op == JIM_EXPROP_SUB) + doubleRes = -doubleValue; + else + doubleRes = 1.0 / doubleValue; + Jim_SetResult(interp, Jim_NewDoubleObj(interp, doubleRes)); + return JIM_OK; + } + } + if (op == JIM_EXPROP_SUB) { + res = -wideValue; + Jim_SetResultInt(interp, res); + } + else { + doubleRes = 1.0 / wideValue; + Jim_SetResult(interp, Jim_NewDoubleObj(interp, doubleRes)); + } + return JIM_OK; + } + else { + if (Jim_GetWide(interp, argv[1], &res) != JIM_OK) { + if (Jim_GetDouble(interp, argv[1], &doubleRes) + != JIM_OK) { + return JIM_ERR; + } + else { + goto trydouble; + } + } + } + for (i = 2; i < argc; i++) { + if (Jim_GetWide(interp, argv[i], &wideValue) != JIM_OK) { + doubleRes = (double)res; + goto trydouble; + } + if (op == JIM_EXPROP_SUB) + res -= wideValue; + else + res /= wideValue; + } + Jim_SetResultInt(interp, res); + return JIM_OK; + trydouble: + for (; i < argc; i++) { + if (Jim_GetDouble(interp, argv[i], &doubleValue) != JIM_OK) + return JIM_ERR; + if (op == JIM_EXPROP_SUB) + doubleRes -= doubleValue; + else + doubleRes /= doubleValue; + } + Jim_SetResult(interp, Jim_NewDoubleObj(interp, doubleRes)); + return JIM_OK; +} + + +/* [+] */ +static int Jim_AddCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimAddMulHelper(interp, argc, argv, JIM_EXPROP_ADD); +} + +/* [*] */ +static int Jim_MulCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimAddMulHelper(interp, argc, argv, JIM_EXPROP_MUL); +} + +/* [-] */ +static int Jim_SubCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimSubDivHelper(interp, argc, argv, JIM_EXPROP_SUB); +} + +/* [/] */ +static int Jim_DivCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimSubDivHelper(interp, argc, argv, JIM_EXPROP_DIV); +} + +/* [set] */ +static int Jim_SetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?newValue?"); + return JIM_ERR; + } + if (argc == 2) { + Jim_Obj *objPtr; + + objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); + if (!objPtr) + return JIM_ERR; + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + /* argc == 3 case. */ + if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK) + return JIM_ERR; + Jim_SetResult(interp, argv[2]); + return JIM_OK; +} + +/* [unset] + * + * unset ?-nocomplain? ?--? ?varName ...? + */ +static int Jim_UnsetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i = 1; + int complain = 1; + + while (i < argc) { + if (Jim_CompareStringImmediate(interp, argv[i], "--")) { + i++; + break; + } + if (Jim_CompareStringImmediate(interp, argv[i], "-nocomplain")) { + complain = 0; + i++; + continue; + } + break; + } + + while (i < argc) { + if (Jim_UnsetVariable(interp, argv[i], complain ? JIM_ERRMSG : JIM_NONE) != JIM_OK + && complain) { + return JIM_ERR; + } + i++; + } + return JIM_OK; +} + +/* [while] */ +static int Jim_WhileCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "condition body"); + return JIM_ERR; + } + + /* The general purpose implementation of while starts here */ + while (1) { + int boolean, retval; + + if ((retval = Jim_GetBoolFromExpr(interp, argv[1], &boolean)) != JIM_OK) + return retval; + if (!boolean) + break; + + if ((retval = Jim_EvalObj(interp, argv[2])) != JIM_OK) { + switch (retval) { + case JIM_BREAK: + goto out; + break; + case JIM_CONTINUE: + continue; + break; + default: + return retval; + } + } + } + out: + Jim_SetEmptyResult(interp); + return JIM_OK; +} + +/* [for] */ +static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retval; + int boolean = 1; + Jim_Obj *varNamePtr = NULL; + Jim_Obj *stopVarNamePtr = NULL; + + if (argc != 5) { + Jim_WrongNumArgs(interp, 1, argv, "start test next body"); + return JIM_ERR; + } + + /* Do the initialisation */ + if ((retval = Jim_EvalObj(interp, argv[1])) != JIM_OK) { + return retval; + } + + /* And do the first test now. Better for optimisation + * if we can do next/test at the bottom of the loop + */ + retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean); + + /* Ready to do the body as follows: + * while (1) { + * body // check retcode + * next // check retcode + * test // check retcode/test bool + * } + */ + +#ifdef JIM_OPTIMIZATION + /* Check if the for is on the form: + * for ... {$i < CONST} {incr i} + * for ... {$i < $j} {incr i} + */ + if (retval == JIM_OK && boolean) { + ScriptObj *incrScript; + ExprByteCode *expr; + jim_wide stop, currentVal; + Jim_Obj *objPtr; + int cmpOffset; + + /* Do it only if there aren't shared arguments */ + expr = JimGetExpression(interp, argv[2]); + incrScript = Jim_GetScript(interp, argv[3]); + + /* Ensure proper lengths to start */ + if (incrScript->len != 3 || !expr || expr->len != 3) { + goto evalstart; + } + /* Ensure proper token types. */ + if (incrScript->token[1].type != JIM_TT_ESC || + expr->token[0].type != JIM_TT_VAR || + (expr->token[1].type != JIM_TT_EXPR_INT && expr->token[1].type != JIM_TT_VAR)) { + goto evalstart; + } + + if (expr->token[2].type == JIM_EXPROP_LT) { + cmpOffset = 0; + } + else if (expr->token[2].type == JIM_EXPROP_LTE) { + cmpOffset = 1; + } + else { + goto evalstart; + } + + /* Update command must be incr */ + if (!Jim_CompareStringImmediate(interp, incrScript->token[1].objPtr, "incr")) { + goto evalstart; + } + + /* incr, expression must be about the same variable */ + if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->token[0].objPtr)) { + goto evalstart; + } + + /* Get the stop condition (must be a variable or integer) */ + if (expr->token[1].type == JIM_TT_EXPR_INT) { + if (Jim_GetWide(interp, expr->token[1].objPtr, &stop) == JIM_ERR) { + goto evalstart; + } + } + else { + stopVarNamePtr = expr->token[1].objPtr; + Jim_IncrRefCount(stopVarNamePtr); + /* Keep the compiler happy */ + stop = 0; + } + + /* Initialization */ + varNamePtr = expr->token[0].objPtr; + Jim_IncrRefCount(varNamePtr); + + objPtr = Jim_GetVariable(interp, varNamePtr, JIM_NONE); + if (objPtr == NULL || Jim_GetWide(interp, objPtr, ¤tVal) != JIM_OK) { + goto testcond; + } + + /* --- OPTIMIZED FOR --- */ + while (retval == JIM_OK) { + /* === Check condition === */ + /* Note that currentVal is already set here */ + + /* Immediate or Variable? get the 'stop' value if the latter. */ + if (stopVarNamePtr) { + objPtr = Jim_GetVariable(interp, stopVarNamePtr, JIM_NONE); + if (objPtr == NULL || Jim_GetWide(interp, objPtr, &stop) != JIM_OK) { + goto testcond; + } + } + + if (currentVal >= stop + cmpOffset) { + break; + } + + /* Eval body */ + retval = Jim_EvalObj(interp, argv[4]); + if (retval == JIM_OK || retval == JIM_CONTINUE) { + retval = JIM_OK; + + objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG); + + /* Increment */ + if (objPtr == NULL) { + retval = JIM_ERR; + goto out; + } + if (!Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) { + currentVal = ++JimWideValue(objPtr); + Jim_InvalidateStringRep(objPtr); + } + else { + if (Jim_GetWide(interp, objPtr, ¤tVal) != JIM_OK || + Jim_SetVariable(interp, varNamePtr, Jim_NewIntObj(interp, + ++currentVal)) != JIM_OK) { + goto evalnext; + } + } + } + } + goto out; + } + evalstart: +#endif + + while (boolean && (retval == JIM_OK || retval == JIM_CONTINUE)) { + /* Body */ + retval = Jim_EvalObj(interp, argv[4]); + + if (retval == JIM_OK || retval == JIM_CONTINUE) { + /* increment */ + evalnext: + retval = Jim_EvalObj(interp, argv[3]); + if (retval == JIM_OK || retval == JIM_CONTINUE) { + /* test */ + testcond: + retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean); + } + } + } + out: + if (stopVarNamePtr) { + Jim_DecrRefCount(interp, stopVarNamePtr); + } + if (varNamePtr) { + Jim_DecrRefCount(interp, varNamePtr); + } + + if (retval == JIM_CONTINUE || retval == JIM_BREAK || retval == JIM_OK) { + Jim_SetEmptyResult(interp); + return JIM_OK; + } + + return retval; +} + +/* [loop] */ +static int Jim_LoopCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retval; + jim_wide i; + jim_wide limit; + jim_wide incr = 1; + Jim_Obj *bodyObjPtr; + + if (argc != 5 && argc != 6) { + Jim_WrongNumArgs(interp, 1, argv, "var first limit ?incr? body"); + return JIM_ERR; + } + + if (Jim_GetWide(interp, argv[2], &i) != JIM_OK || + Jim_GetWide(interp, argv[3], &limit) != JIM_OK || + (argc == 6 && Jim_GetWide(interp, argv[4], &incr) != JIM_OK)) { + return JIM_ERR; + } + bodyObjPtr = (argc == 5) ? argv[4] : argv[5]; + + retval = Jim_SetVariable(interp, argv[1], argv[2]); + + while (((i < limit && incr > 0) || (i > limit && incr < 0)) && retval == JIM_OK) { + retval = Jim_EvalObj(interp, bodyObjPtr); + if (retval == JIM_OK || retval == JIM_CONTINUE) { + Jim_Obj *objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); + + retval = JIM_OK; + + /* Increment */ + i += incr; + + if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) { + if (argv[1]->typePtr != &variableObjType) { + if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) { + return JIM_ERR; + } + } + JimWideValue(objPtr) = i; + Jim_InvalidateStringRep(objPtr); + + /* The following step is required in order to invalidate the + * string repr of "FOO" if the var name is of the form of "FOO(IDX)" */ + if (argv[1]->typePtr != &variableObjType) { + if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) { + retval = JIM_ERR; + break; + } + } + } + else { + objPtr = Jim_NewIntObj(interp, i); + retval = Jim_SetVariable(interp, argv[1], objPtr); + if (retval != JIM_OK) { + Jim_FreeNewObj(interp, objPtr); + } + } + } + } + + if (retval == JIM_OK || retval == JIM_CONTINUE || retval == JIM_BREAK) { + Jim_SetEmptyResult(interp); + return JIM_OK; + } + return retval; +} + +/* List iterators make it easy to iterate over a list. + * At some point iterators will be expanded to support generators. + */ +typedef struct { + Jim_Obj *objPtr; + int idx; +} Jim_ListIter; + +/** + * Initialise the iterator at the start of the list. + */ +static void JimListIterInit(Jim_ListIter *iter, Jim_Obj *objPtr) +{ + iter->objPtr = objPtr; + iter->idx = 0; +} + +/** + * Returns the next object from the list, or NULL on end-of-list. + */ +static Jim_Obj *JimListIterNext(Jim_Interp *interp, Jim_ListIter *iter) +{ + if (iter->idx >= Jim_ListLength(interp, iter->objPtr)) { + return NULL; + } + return iter->objPtr->internalRep.listValue.ele[iter->idx++]; +} + +/** + * Returns 1 if end-of-list has been reached. + */ +static int JimListIterDone(Jim_Interp *interp, Jim_ListIter *iter) +{ + return iter->idx >= Jim_ListLength(interp, iter->objPtr); +} + +/* foreach + lmap implementation. */ +static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int doMap) +{ + int result = JIM_ERR; + int i, numargs; + Jim_ListIter twoiters[2]; /* Avoid allocation for a single list */ + Jim_ListIter *iters; + Jim_Obj *script; + Jim_Obj *resultObj; + + if (argc < 4 || argc % 2 != 0) { + Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script"); + return JIM_ERR; + } + script = argv[argc - 1]; /* Last argument is a script */ + numargs = (argc - 1 - 1); /* argc - 'foreach' - script */ + + if (numargs == 2) { + iters = twoiters; + } + else { + iters = Jim_Alloc(numargs * sizeof(*iters)); + } + for (i = 0; i < numargs; i++) { + JimListIterInit(&iters[i], argv[i + 1]); + if (i % 2 == 0 && JimListIterDone(interp, &iters[i])) { + Jim_SetResultString(interp, "foreach varlist is empty", -1); + return JIM_ERR; + } + } + + if (doMap) { + resultObj = Jim_NewListObj(interp, NULL, 0); + } + else { + resultObj = interp->emptyObj; + } + Jim_IncrRefCount(resultObj); + + while (1) { + /* Have we expired all lists? */ + for (i = 0; i < numargs; i += 2) { + if (!JimListIterDone(interp, &iters[i + 1])) { + break; + } + } + if (i == numargs) { + /* All done */ + break; + } + + /* For each list */ + for (i = 0; i < numargs; i += 2) { + Jim_Obj *varName; + + /* foreach var */ + JimListIterInit(&iters[i], argv[i + 1]); + while ((varName = JimListIterNext(interp, &iters[i])) != NULL) { + Jim_Obj *valObj = JimListIterNext(interp, &iters[i + 1]); + if (!valObj) { + /* Ran out, so store the empty string */ + valObj = interp->emptyObj; + } + /* Avoid shimmering */ + Jim_IncrRefCount(valObj); + result = Jim_SetVariable(interp, varName, valObj); + Jim_DecrRefCount(interp, valObj); + if (result != JIM_OK) { + goto err; + } + } + } + switch (result = Jim_EvalObj(interp, script)) { + case JIM_OK: + if (doMap) { + Jim_ListAppendElement(interp, resultObj, interp->result); + } + break; + case JIM_CONTINUE: + break; + case JIM_BREAK: + goto out; + default: + goto err; + } + } + out: + result = JIM_OK; + Jim_SetResult(interp, resultObj); + err: + Jim_DecrRefCount(interp, resultObj); + if (numargs > 2) { + Jim_Free(iters); + } + return result; +} + +/* [foreach] */ +static int Jim_ForeachCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimForeachMapHelper(interp, argc, argv, 0); +} + +/* [lmap] */ +static int Jim_LmapCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimForeachMapHelper(interp, argc, argv, 1); +} + +/* [lassign] */ +static int Jim_LassignCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int result = JIM_ERR; + int i; + Jim_ListIter iter; + Jim_Obj *resultObj; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varList list ?varName ...?"); + return JIM_ERR; + } + + JimListIterInit(&iter, argv[1]); + + for (i = 2; i < argc; i++) { + Jim_Obj *valObj = JimListIterNext(interp, &iter); + result = Jim_SetVariable(interp, argv[i], valObj ? valObj : interp->emptyObj); + if (result != JIM_OK) { + return result; + } + } + + resultObj = Jim_NewListObj(interp, NULL, 0); + while (!JimListIterDone(interp, &iter)) { + Jim_ListAppendElement(interp, resultObj, JimListIterNext(interp, &iter)); + } + + Jim_SetResult(interp, resultObj); + + return JIM_OK; +} + +/* [if] */ +static int Jim_IfCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int boolean, retval, current = 1, falsebody = 0; + + if (argc >= 3) { + while (1) { + /* Far not enough arguments given! */ + if (current >= argc) + goto err; + if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean)) + != JIM_OK) + return retval; + /* There lacks something, isn't it? */ + if (current >= argc) + goto err; + if (Jim_CompareStringImmediate(interp, argv[current], "then")) + current++; + /* Tsk tsk, no then-clause? */ + if (current >= argc) + goto err; + if (boolean) + return Jim_EvalObj(interp, argv[current]); + /* Ok: no else-clause follows */ + if (++current >= argc) { + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + return JIM_OK; + } + falsebody = current++; + if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) { + /* IIICKS - else-clause isn't last cmd? */ + if (current != argc - 1) + goto err; + return Jim_EvalObj(interp, argv[current]); + } + else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif")) + /* Ok: elseif follows meaning all the stuff + * again (how boring...) */ + continue; + /* OOPS - else-clause is not last cmd? */ + else if (falsebody != argc - 1) + goto err; + return Jim_EvalObj(interp, argv[falsebody]); + } + return JIM_OK; + } + err: + Jim_WrongNumArgs(interp, 1, argv, "condition ?then? trueBody ?elseif ...? ?else? falseBody"); + return JIM_ERR; +} + + +/* Returns 1 if match, 0 if no match or - on error (e.g. -JIM_ERR, -JIM_BREAK)*/ +int Jim_CommandMatchObj(Jim_Interp *interp, Jim_Obj *commandObj, Jim_Obj *patternObj, + Jim_Obj *stringObj, int nocase) +{ + Jim_Obj *parms[4]; + int argc = 0; + long eq; + int rc; + + parms[argc++] = commandObj; + if (nocase) { + parms[argc++] = Jim_NewStringObj(interp, "-nocase", -1); + } + parms[argc++] = patternObj; + parms[argc++] = stringObj; + + rc = Jim_EvalObjVector(interp, argc, parms); + + if (rc != JIM_OK || Jim_GetLong(interp, Jim_GetResult(interp), &eq) != JIM_OK) { + eq = -rc; + } + + return eq; +} + +enum +{ SWITCH_EXACT, SWITCH_GLOB, SWITCH_RE, SWITCH_CMD }; + +/* [switch] */ +static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int matchOpt = SWITCH_EXACT, opt = 1, patCount, i; + Jim_Obj *command = 0, *const *caseList = 0, *strObj; + Jim_Obj *script = 0; + + if (argc < 3) { + wrongnumargs: + Jim_WrongNumArgs(interp, 1, argv, "?options? string " + "pattern body ... ?default body? or " "{pattern body ?pattern body ...?}"); + return JIM_ERR; + } + for (opt = 1; opt < argc; ++opt) { + const char *option = Jim_String(argv[opt]); + + if (*option != '-') + break; + else if (strncmp(option, "--", 2) == 0) { + ++opt; + break; + } + else if (strncmp(option, "-exact", 2) == 0) + matchOpt = SWITCH_EXACT; + else if (strncmp(option, "-glob", 2) == 0) + matchOpt = SWITCH_GLOB; + else if (strncmp(option, "-regexp", 2) == 0) + matchOpt = SWITCH_RE; + else if (strncmp(option, "-command", 2) == 0) { + matchOpt = SWITCH_CMD; + if ((argc - opt) < 2) + goto wrongnumargs; + command = argv[++opt]; + } + else { + Jim_SetResultFormatted(interp, + "bad option \"%#s\": must be -exact, -glob, -regexp, -command procname or --", + argv[opt]); + return JIM_ERR; + } + if ((argc - opt) < 2) + goto wrongnumargs; + } + strObj = argv[opt++]; + patCount = argc - opt; + if (patCount == 1) { + Jim_Obj **vector; + + JimListGetElements(interp, argv[opt], &patCount, &vector); + caseList = vector; + } + else + caseList = &argv[opt]; + if (patCount == 0 || patCount % 2 != 0) + goto wrongnumargs; + for (i = 0; script == 0 && i < patCount; i += 2) { + Jim_Obj *patObj = caseList[i]; + + if (!Jim_CompareStringImmediate(interp, patObj, "default") + || i < (patCount - 2)) { + switch (matchOpt) { + case SWITCH_EXACT: + if (Jim_StringEqObj(strObj, patObj)) + script = caseList[i + 1]; + break; + case SWITCH_GLOB: + if (Jim_StringMatchObj(interp, patObj, strObj, 0)) + script = caseList[i + 1]; + break; + case SWITCH_RE: + command = Jim_NewStringObj(interp, "regexp", -1); + /* Fall thru intentionally */ + case SWITCH_CMD:{ + int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, 0); + + /* After the execution of a command we need to + * make sure to reconvert the object into a list + * again. Only for the single-list style [switch]. */ + if (argc - opt == 1) { + Jim_Obj **vector; + + JimListGetElements(interp, argv[opt], &patCount, &vector); + caseList = vector; + } + /* command is here already decref'd */ + if (rc < 0) { + return -rc; + } + if (rc) + script = caseList[i + 1]; + break; + } + } + } + else { + script = caseList[i + 1]; + } + } + for (; i < patCount && Jim_CompareStringImmediate(interp, script, "-"); i += 2) + script = caseList[i + 1]; + if (script && Jim_CompareStringImmediate(interp, script, "-")) { + Jim_SetResultFormatted(interp, "no body specified for pattern \"%#s\"", caseList[i - 2]); + return JIM_ERR; + } + Jim_SetEmptyResult(interp); + if (script) { + return Jim_EvalObj(interp, script); + } + return JIM_OK; +} + +/* [list] */ +static int Jim_ListCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listObjPtr; + + listObjPtr = Jim_NewListObj(interp, argv + 1, argc - 1); + Jim_SetResult(interp, listObjPtr); + return JIM_OK; +} + +/* [lindex] */ +static int Jim_LindexCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr, *listObjPtr; + int i; + int idx; + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "list index ?...?"); + return JIM_ERR; + } + objPtr = argv[1]; + Jim_IncrRefCount(objPtr); + for (i = 2; i < argc; i++) { + listObjPtr = objPtr; + if (Jim_GetIndex(interp, argv[i], &idx) != JIM_OK) { + Jim_DecrRefCount(interp, listObjPtr); + return JIM_ERR; + } + if (Jim_ListIndex(interp, listObjPtr, idx, &objPtr, JIM_NONE) != JIM_OK) { + /* Returns an empty object if the index + * is out of range. */ + Jim_DecrRefCount(interp, listObjPtr); + Jim_SetEmptyResult(interp); + return JIM_OK; + } + Jim_IncrRefCount(objPtr); + Jim_DecrRefCount(interp, listObjPtr); + } + Jim_SetResult(interp, objPtr); + Jim_DecrRefCount(interp, objPtr); + return JIM_OK; +} + +/* [llength] */ +static int Jim_LlengthCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "list"); + return JIM_ERR; + } + Jim_SetResultInt(interp, Jim_ListLength(interp, argv[1])); + return JIM_OK; +} + +/* [lsearch] */ +static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + static const char * const options[] = { + "-bool", "-not", "-nocase", "-exact", "-glob", "-regexp", "-all", "-inline", "-command", + NULL + }; + enum + { OPT_BOOL, OPT_NOT, OPT_NOCASE, OPT_EXACT, OPT_GLOB, OPT_REGEXP, OPT_ALL, OPT_INLINE, + OPT_COMMAND }; + int i; + int opt_bool = 0; + int opt_not = 0; + int opt_nocase = 0; + int opt_all = 0; + int opt_inline = 0; + int opt_match = OPT_EXACT; + int listlen; + int rc = JIM_OK; + Jim_Obj *listObjPtr = NULL; + Jim_Obj *commandObj = NULL; + + if (argc < 3) { + wrongargs: + Jim_WrongNumArgs(interp, 1, argv, + "?-exact|-glob|-regexp|-command 'command'? ?-bool|-inline? ?-not? ?-nocase? ?-all? list value"); + return JIM_ERR; + } + + for (i = 1; i < argc - 2; i++) { + int option; + + if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + switch (option) { + case OPT_BOOL: + opt_bool = 1; + opt_inline = 0; + break; + case OPT_NOT: + opt_not = 1; + break; + case OPT_NOCASE: + opt_nocase = 1; + break; + case OPT_INLINE: + opt_inline = 1; + opt_bool = 0; + break; + case OPT_ALL: + opt_all = 1; + break; + case OPT_COMMAND: + if (i >= argc - 2) { + goto wrongargs; + } + commandObj = argv[++i]; + /* fallthru */ + case OPT_EXACT: + case OPT_GLOB: + case OPT_REGEXP: + opt_match = option; + break; + } + } + + argv += i; + + if (opt_all) { + listObjPtr = Jim_NewListObj(interp, NULL, 0); + } + if (opt_match == OPT_REGEXP) { + commandObj = Jim_NewStringObj(interp, "regexp", -1); + } + if (commandObj) { + Jim_IncrRefCount(commandObj); + } + + listlen = Jim_ListLength(interp, argv[0]); + for (i = 0; i < listlen; i++) { + Jim_Obj *objPtr; + int eq = 0; + + Jim_ListIndex(interp, argv[0], i, &objPtr, JIM_NONE); + switch (opt_match) { + case OPT_EXACT: + eq = Jim_StringCompareObj(interp, argv[1], objPtr, opt_nocase) == 0; + break; + + case OPT_GLOB: + eq = Jim_StringMatchObj(interp, argv[1], objPtr, opt_nocase); + break; + + case OPT_REGEXP: + case OPT_COMMAND: + eq = Jim_CommandMatchObj(interp, commandObj, argv[1], objPtr, opt_nocase); + if (eq < 0) { + if (listObjPtr) { + Jim_FreeNewObj(interp, listObjPtr); + } + rc = JIM_ERR; + goto done; + } + break; + } + + /* If we have a non-match with opt_bool, opt_not, !opt_all, can't exit early */ + if (!eq && opt_bool && opt_not && !opt_all) { + continue; + } + + if ((!opt_bool && eq == !opt_not) || (opt_bool && (eq || opt_all))) { + /* Got a match (or non-match for opt_not), or (opt_bool && opt_all) */ + Jim_Obj *resultObj; + + if (opt_bool) { + resultObj = Jim_NewIntObj(interp, eq ^ opt_not); + } + else if (!opt_inline) { + resultObj = Jim_NewIntObj(interp, i); + } + else { + resultObj = objPtr; + } + + if (opt_all) { + Jim_ListAppendElement(interp, listObjPtr, resultObj); + } + else { + Jim_SetResult(interp, resultObj); + goto done; + } + } + } + + if (opt_all) { + Jim_SetResult(interp, listObjPtr); + } + else { + /* No match */ + if (opt_bool) { + Jim_SetResultBool(interp, opt_not); + } + else if (!opt_inline) { + Jim_SetResultInt(interp, -1); + } + } + + done: + if (commandObj) { + Jim_DecrRefCount(interp, commandObj); + } + return rc; +} + +/* [lappend] */ +static int Jim_LappendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listObjPtr; + int shared, i; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?"); + return JIM_ERR; + } + listObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); + if (!listObjPtr) { + /* Create the list if it does not exists */ + listObjPtr = Jim_NewListObj(interp, NULL, 0); + if (Jim_SetVariable(interp, argv[1], listObjPtr) != JIM_OK) { + Jim_FreeNewObj(interp, listObjPtr); + return JIM_ERR; + } + } + shared = Jim_IsShared(listObjPtr); + if (shared) + listObjPtr = Jim_DuplicateObj(interp, listObjPtr); + for (i = 2; i < argc; i++) + Jim_ListAppendElement(interp, listObjPtr, argv[i]); + if (Jim_SetVariable(interp, argv[1], listObjPtr) != JIM_OK) { + if (shared) + Jim_FreeNewObj(interp, listObjPtr); + return JIM_ERR; + } + Jim_SetResult(interp, listObjPtr); + return JIM_OK; +} + +/* [linsert] */ +static int Jim_LinsertCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int idx, len; + Jim_Obj *listPtr; + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "list index ?element ...?"); + return JIM_ERR; + } + listPtr = argv[1]; + if (Jim_IsShared(listPtr)) + listPtr = Jim_DuplicateObj(interp, listPtr); + if (Jim_GetIndex(interp, argv[2], &idx) != JIM_OK) + goto err; + len = Jim_ListLength(interp, listPtr); + if (idx >= len) + idx = len; + else if (idx < 0) + idx = len + idx + 1; + Jim_ListInsertElements(interp, listPtr, idx, argc - 3, &argv[3]); + Jim_SetResult(interp, listPtr); + return JIM_OK; + err: + if (listPtr != argv[1]) { + Jim_FreeNewObj(interp, listPtr); + } + return JIM_ERR; +} + +/* [lreplace] */ +static int Jim_LreplaceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int first, last, len, rangeLen; + Jim_Obj *listObj; + Jim_Obj *newListObj; + + if (argc < 4) { + Jim_WrongNumArgs(interp, 1, argv, "list first last ?element ...?"); + return JIM_ERR; + } + if (Jim_GetIndex(interp, argv[2], &first) != JIM_OK || + Jim_GetIndex(interp, argv[3], &last) != JIM_OK) { + return JIM_ERR; + } + + listObj = argv[1]; + len = Jim_ListLength(interp, listObj); + + first = JimRelToAbsIndex(len, first); + last = JimRelToAbsIndex(len, last); + JimRelToAbsRange(len, &first, &last, &rangeLen); + + /* Now construct a new list which consists of: + * + */ + + /* Check to see if trying to replace past the end of the list */ + if (first < len) { + /* OK. Not past the end */ + } + else if (len == 0) { + /* Special for empty list, adjust first to 0 */ + first = 0; + } + else { + Jim_SetResultString(interp, "list doesn't contain element ", -1); + Jim_AppendObj(interp, Jim_GetResult(interp), argv[2]); + return JIM_ERR; + } + + /* Add the first set of elements */ + newListObj = Jim_NewListObj(interp, listObj->internalRep.listValue.ele, first); + + /* Add supplied elements */ + ListInsertElements(newListObj, -1, argc - 4, argv + 4); + + /* Add the remaining elements */ + ListInsertElements(newListObj, -1, len - first - rangeLen, listObj->internalRep.listValue.ele + first + rangeLen); + + Jim_SetResult(interp, newListObj); + return JIM_OK; +} + +/* [lset] */ +static int Jim_LsetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "listVar ?index...? newVal"); + return JIM_ERR; + } + else if (argc == 3) { + if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK) + return JIM_ERR; + Jim_SetResult(interp, argv[2]); + return JIM_OK; + } + if (Jim_SetListIndex(interp, argv[1], argv + 2, argc - 3, argv[argc - 1]) + == JIM_ERR) + return JIM_ERR; + return JIM_OK; +} + +/* [lsort] */ +static int Jim_LsortCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const argv[]) +{ + static const char * const options[] = { + "-ascii", "-nocase", "-increasing", "-decreasing", "-command", "-integer", "-index", NULL + }; + enum + { OPT_ASCII, OPT_NOCASE, OPT_INCREASING, OPT_DECREASING, OPT_COMMAND, OPT_INTEGER, OPT_INDEX }; + Jim_Obj *resObj; + int i; + int retCode; + + struct lsort_info info; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "?options? list"); + return JIM_ERR; + } + + info.type = JIM_LSORT_ASCII; + info.order = 1; + info.indexed = 0; + info.command = NULL; + info.interp = interp; + + for (i = 1; i < (argc - 1); i++) { + int option; + + if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ERRMSG) + != JIM_OK) + return JIM_ERR; + switch (option) { + case OPT_ASCII: + info.type = JIM_LSORT_ASCII; + break; + case OPT_NOCASE: + info.type = JIM_LSORT_NOCASE; + break; + case OPT_INTEGER: + info.type = JIM_LSORT_INTEGER; + break; + case OPT_INCREASING: + info.order = 1; + break; + case OPT_DECREASING: + info.order = -1; + break; + case OPT_COMMAND: + if (i >= (argc - 2)) { + Jim_SetResultString(interp, "\"-command\" option must be followed by comparison command", -1); + return JIM_ERR; + } + info.type = JIM_LSORT_COMMAND; + info.command = argv[i + 1]; + i++; + break; + case OPT_INDEX: + if (i >= (argc - 2)) { + Jim_SetResultString(interp, "\"-index\" option must be followed by list index", -1); + return JIM_ERR; + } + if (Jim_GetIndex(interp, argv[i + 1], &info.index) != JIM_OK) { + return JIM_ERR; + } + info.indexed = 1; + i++; + break; + } + } + resObj = Jim_DuplicateObj(interp, argv[argc - 1]); + retCode = ListSortElements(interp, resObj, &info); + if (retCode == JIM_OK) { + Jim_SetResult(interp, resObj); + } + else { + Jim_FreeNewObj(interp, resObj); + } + return retCode; +} + +/* [append] */ +static int Jim_AppendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *stringObjPtr; + int i; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?"); + return JIM_ERR; + } + if (argc == 2) { + stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); + if (!stringObjPtr) + return JIM_ERR; + } + else { + int freeobj = 0; + stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); + if (!stringObjPtr) { + /* Create the string if it doesn't exist */ + stringObjPtr = Jim_NewEmptyStringObj(interp); + freeobj = 1; + } + else if (Jim_IsShared(stringObjPtr)) { + freeobj = 1; + stringObjPtr = Jim_DuplicateObj(interp, stringObjPtr); + } + for (i = 2; i < argc; i++) { + Jim_AppendObj(interp, stringObjPtr, argv[i]); + } + if (Jim_SetVariable(interp, argv[1], stringObjPtr) != JIM_OK) { + if (freeobj) { + Jim_FreeNewObj(interp, stringObjPtr); + } + return JIM_ERR; + } + } + Jim_SetResult(interp, stringObjPtr); + return JIM_OK; +} + +/* [debug] */ +static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ +#if defined(JIM_DEBUG_COMMAND) && !defined(JIM_BOOTSTRAP) + static const char * const options[] = { + "refcount", "objcount", "objects", "invstr", "scriptlen", "exprlen", + "exprbc", "show", + NULL + }; + enum + { + OPT_REFCOUNT, OPT_OBJCOUNT, OPT_OBJECTS, OPT_INVSTR, OPT_SCRIPTLEN, + OPT_EXPRLEN, OPT_EXPRBC, OPT_SHOW, + }; + int option; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "subcommand ?...?"); + return JIM_ERR; + } + if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG) != JIM_OK) + return JIM_ERR; + if (option == OPT_REFCOUNT) { + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "object"); + return JIM_ERR; + } + Jim_SetResultInt(interp, argv[2]->refCount); + return JIM_OK; + } + else if (option == OPT_OBJCOUNT) { + int freeobj = 0, liveobj = 0; + char buf[256]; + Jim_Obj *objPtr; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 2, argv, ""); + return JIM_ERR; + } + /* Count the number of free objects. */ + objPtr = interp->freeList; + while (objPtr) { + freeobj++; + objPtr = objPtr->nextObjPtr; + } + /* Count the number of live objects. */ + objPtr = interp->liveList; + while (objPtr) { + liveobj++; + objPtr = objPtr->nextObjPtr; + } + /* Set the result string and return. */ + sprintf(buf, "free %d used %d", freeobj, liveobj); + Jim_SetResultString(interp, buf, -1); + return JIM_OK; + } + else if (option == OPT_OBJECTS) { + Jim_Obj *objPtr, *listObjPtr, *subListObjPtr; + + /* Count the number of live objects. */ + objPtr = interp->liveList; + listObjPtr = Jim_NewListObj(interp, NULL, 0); + while (objPtr) { + char buf[128]; + const char *type = objPtr->typePtr ? objPtr->typePtr->name : ""; + + subListObjPtr = Jim_NewListObj(interp, NULL, 0); + sprintf(buf, "%p", objPtr); + Jim_ListAppendElement(interp, subListObjPtr, Jim_NewStringObj(interp, buf, -1)); + Jim_ListAppendElement(interp, subListObjPtr, Jim_NewStringObj(interp, type, -1)); + Jim_ListAppendElement(interp, subListObjPtr, Jim_NewIntObj(interp, objPtr->refCount)); + Jim_ListAppendElement(interp, subListObjPtr, objPtr); + Jim_ListAppendElement(interp, listObjPtr, subListObjPtr); + objPtr = objPtr->nextObjPtr; + } + Jim_SetResult(interp, listObjPtr); + return JIM_OK; + } + else if (option == OPT_INVSTR) { + Jim_Obj *objPtr; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "object"); + return JIM_ERR; + } + objPtr = argv[2]; + if (objPtr->typePtr != NULL) + Jim_InvalidateStringRep(objPtr); + Jim_SetEmptyResult(interp); + return JIM_OK; + } + else if (option == OPT_SHOW) { + const char *s; + int len, charlen; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "object"); + return JIM_ERR; + } + s = Jim_GetString(argv[2], &len); +#ifdef JIM_UTF8 + charlen = utf8_strlen(s, len); +#else + charlen = len; +#endif + printf("refcount: %d, type: %s\n", argv[2]->refCount, JimObjTypeName(argv[2])); + printf("chars (%d): <<%s>>\n", charlen, s); + printf("bytes (%d):", len); + while (len--) { + printf(" %02x", (unsigned char)*s++); + } + printf("\n"); + return JIM_OK; + } + else if (option == OPT_SCRIPTLEN) { + ScriptObj *script; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "script"); + return JIM_ERR; + } + script = Jim_GetScript(interp, argv[2]); + Jim_SetResultInt(interp, script->len); + return JIM_OK; + } + else if (option == OPT_EXPRLEN) { + ExprByteCode *expr; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "expression"); + return JIM_ERR; + } + expr = JimGetExpression(interp, argv[2]); + if (expr == NULL) + return JIM_ERR; + Jim_SetResultInt(interp, expr->len); + return JIM_OK; + } + else if (option == OPT_EXPRBC) { + Jim_Obj *objPtr; + ExprByteCode *expr; + int i; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "expression"); + return JIM_ERR; + } + expr = JimGetExpression(interp, argv[2]); + if (expr == NULL) + return JIM_ERR; + objPtr = Jim_NewListObj(interp, NULL, 0); + for (i = 0; i < expr->len; i++) { + const char *type; + const Jim_ExprOperator *op; + Jim_Obj *obj = expr->token[i].objPtr; + + switch (expr->token[i].type) { + case JIM_TT_EXPR_INT: + type = "int"; + break; + case JIM_TT_EXPR_DOUBLE: + type = "double"; + break; + case JIM_TT_CMD: + type = "command"; + break; + case JIM_TT_VAR: + type = "variable"; + break; + case JIM_TT_DICTSUGAR: + type = "dictsugar"; + break; + case JIM_TT_EXPRSUGAR: + type = "exprsugar"; + break; + case JIM_TT_ESC: + type = "subst"; + break; + case JIM_TT_STR: + type = "string"; + break; + default: + op = JimExprOperatorInfoByOpcode(expr->token[i].type); + if (op == NULL) { + type = "private"; + } + else { + type = "operator"; + } + obj = Jim_NewStringObj(interp, op ? op->name : "", -1); + break; + } + Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, type, -1)); + Jim_ListAppendElement(interp, objPtr, obj); + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + else { + Jim_SetResultString(interp, + "bad option. Valid options are refcount, " "objcount, objects, invstr", -1); + return JIM_ERR; + } + /* unreached */ +#endif /* JIM_BOOTSTRAP */ +#if !defined(JIM_DEBUG_COMMAND) + Jim_SetResultString(interp, "unsupported", -1); + return JIM_ERR; +#endif +} + +/* [eval] */ +static int Jim_EvalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int rc; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "script ?...?"); + return JIM_ERR; + } + + if (argc == 2) { + rc = Jim_EvalObj(interp, argv[1]); + } + else { + rc = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1)); + } + + if (rc == JIM_ERR) { + /* eval is "interesting", so add a stack frame here */ + interp->addStackTrace++; + } + return rc; +} + +/* [uplevel] */ +static int Jim_UplevelCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc >= 2) { + int retcode; + Jim_CallFrame *savedCallFrame, *targetCallFrame; + Jim_Obj *objPtr; + const char *str; + + /* Save the old callframe pointer */ + savedCallFrame = interp->framePtr; + + /* Lookup the target frame pointer */ + str = Jim_String(argv[1]); + if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') { + targetCallFrame =Jim_GetCallFrameByLevel(interp, argv[1]); + argc--; + argv++; + } + else { + targetCallFrame = Jim_GetCallFrameByLevel(interp, NULL); + } + if (targetCallFrame == NULL) { + return JIM_ERR; + } + if (argc < 2) { + argv--; + Jim_WrongNumArgs(interp, 1, argv, "?level? command ?arg ...?"); + return JIM_ERR; + } + /* Eval the code in the target callframe. */ + interp->framePtr = targetCallFrame; + if (argc == 2) { + retcode = Jim_EvalObj(interp, argv[1]); + } + else { + objPtr = Jim_ConcatObj(interp, argc - 1, argv + 1); + Jim_IncrRefCount(objPtr); + retcode = Jim_EvalObj(interp, objPtr); + Jim_DecrRefCount(interp, objPtr); + } + interp->framePtr = savedCallFrame; + return retcode; + } + else { + Jim_WrongNumArgs(interp, 1, argv, "?level? command ?arg ...?"); + return JIM_ERR; + } +} + +/* [expr] */ +static int Jim_ExprCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *exprResultPtr; + int retcode; + + if (argc == 2) { + retcode = Jim_EvalExpression(interp, argv[1], &exprResultPtr); + } + else if (argc > 2) { + Jim_Obj *objPtr; + + objPtr = Jim_ConcatObj(interp, argc - 1, argv + 1); + Jim_IncrRefCount(objPtr); + retcode = Jim_EvalExpression(interp, objPtr, &exprResultPtr); + Jim_DecrRefCount(interp, objPtr); + } + else { + Jim_WrongNumArgs(interp, 1, argv, "expression ?...?"); + return JIM_ERR; + } + if (retcode != JIM_OK) + return retcode; + Jim_SetResult(interp, exprResultPtr); + Jim_DecrRefCount(interp, exprResultPtr); + return JIM_OK; +} + +/* [break] */ +static int Jim_BreakCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + return JIM_BREAK; +} + +/* [continue] */ +static int Jim_ContinueCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + return JIM_CONTINUE; +} + +/* [return] */ +static int Jim_ReturnCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + Jim_Obj *stackTraceObj = NULL; + Jim_Obj *errorCodeObj = NULL; + int returnCode = JIM_OK; + long level = 1; + + for (i = 1; i < argc - 1; i += 2) { + if (Jim_CompareStringImmediate(interp, argv[i], "-code")) { + if (Jim_GetReturnCode(interp, argv[i + 1], &returnCode) == JIM_ERR) { + return JIM_ERR; + } + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-errorinfo")) { + stackTraceObj = argv[i + 1]; + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-errorcode")) { + errorCodeObj = argv[i + 1]; + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-level")) { + if (Jim_GetLong(interp, argv[i + 1], &level) != JIM_OK || level < 0) { + Jim_SetResultFormatted(interp, "bad level \"%#s\"", argv[i + 1]); + return JIM_ERR; + } + } + else { + break; + } + } + + if (i != argc - 1 && i != argc) { + Jim_WrongNumArgs(interp, 1, argv, + "?-code code? ?-errorinfo stacktrace? ?-level level? ?result?"); + } + + /* If a stack trace is supplied and code is error, set the stack trace */ + if (stackTraceObj && returnCode == JIM_ERR) { + JimSetStackTrace(interp, stackTraceObj); + } + /* If an error code list is supplied, set the global $errorCode */ + if (errorCodeObj && returnCode == JIM_ERR) { + Jim_SetGlobalVariableStr(interp, "errorCode", errorCodeObj); + } + interp->returnCode = returnCode; + interp->returnLevel = level; + + if (i == argc - 1) { + Jim_SetResult(interp, argv[i]); + } + return JIM_RETURN; +} + +/* [tailcall] */ +static int Jim_TailcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_SetResult(interp, Jim_NewListObj(interp, argv + 1, argc - 1)); + return JIM_EVAL; +} + +static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *cmdList; + Jim_Obj *prefixListObj = Jim_CmdPrivData(interp); + + /* prefixListObj is a list to which the args need to be appended */ + cmdList = Jim_DuplicateObj(interp, prefixListObj); + ListInsertElements(cmdList, -1, argc - 1, argv + 1); + + return JimEvalObjList(interp, cmdList); +} + +static void JimAliasCmdDelete(Jim_Interp *interp, void *privData) +{ + Jim_Obj *prefixListObj = privData; + Jim_DecrRefCount(interp, prefixListObj); +} + +static int Jim_AliasCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *prefixListObj; + const char *newname; + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "newname command ?args ...?"); + return JIM_ERR; + } + + prefixListObj = Jim_NewListObj(interp, argv + 2, argc - 2); + Jim_IncrRefCount(prefixListObj); + newname = Jim_String(argv[1]); + if (newname[0] == ':' && newname[1] == ':') { + while (*++newname == ':') { + } + } + + Jim_SetResult(interp, argv[1]); + + return Jim_CreateCommand(interp, newname, JimAliasCmd, prefixListObj, JimAliasCmdDelete); +} + +/* [proc] */ +static int Jim_ProcCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Cmd *cmd; + + if (argc != 4 && argc != 5) { + Jim_WrongNumArgs(interp, 1, argv, "name arglist ?statics? body"); + return JIM_ERR; + } + + if (JimValidName(interp, "procedure", argv[1]) != JIM_OK) { + return JIM_ERR; + } + + if (argc == 4) { + cmd = JimCreateProcedureCmd(interp, argv[2], NULL, argv[3], NULL); + } + else { + cmd = JimCreateProcedureCmd(interp, argv[2], argv[3], argv[4], NULL); + } + + if (cmd) { + /* Add the new command */ + Jim_Obj *qualifiedCmdNameObj; + const char *cmdname = JimQualifyName(interp, Jim_String(argv[1]), &qualifiedCmdNameObj); + + JimCreateCommand(interp, cmdname, cmd); + + /* Calculate and set the namespace for this proc */ + JimUpdateProcNamespace(interp, cmd, cmdname); + + JimFreeQualifiedName(interp, qualifiedCmdNameObj); + + /* Unlike Tcl, set the name of the proc as the result */ + Jim_SetResult(interp, argv[1]); + return JIM_OK; + } + return JIM_ERR; +} + +/* [local] */ +static int Jim_LocalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retcode; + + /* Evaluate the arguments with 'local' in force */ + interp->local++; + retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); + interp->local--; + + + /* If OK, and the result is a proc, add it to the list of local procs */ + if (retcode == 0) { + Jim_Obj *cmdNameObj = Jim_GetResult(interp); + + if (Jim_GetCommand(interp, cmdNameObj, JIM_ERRMSG) == NULL) { + return JIM_ERR; + } + if (interp->framePtr->localCommands == NULL) { + interp->framePtr->localCommands = Jim_Alloc(sizeof(*interp->framePtr->localCommands)); + Jim_InitStack(interp->framePtr->localCommands); + } + Jim_IncrRefCount(cmdNameObj); + Jim_StackPush(interp->framePtr->localCommands, cmdNameObj); + } + + return retcode; +} + +/* [upcall] */ +static int Jim_UpcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?"); + return JIM_ERR; + } + else { + int retcode; + + Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG); + if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->prevCmd) { + Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]); + return JIM_ERR; + } + /* OK. Mark this command as being in an upcall */ + cmdPtr->u.proc.upcall++; + JimIncrCmdRefCount(cmdPtr); + + /* Invoke the command as normal */ + retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); + + /* No longer in an upcall */ + cmdPtr->u.proc.upcall--; + JimDecrCmdRefCount(interp, cmdPtr); + + return retcode; + } +} + +/* [apply] */ +static int Jim_ApplyCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "lambdaExpr ?arg ...?"); + return JIM_ERR; + } + else { + int ret; + Jim_Cmd *cmd; + Jim_Obj *argListObjPtr; + Jim_Obj *bodyObjPtr; + Jim_Obj *nsObj = NULL; + Jim_Obj **nargv; + + int len = Jim_ListLength(interp, argv[1]); + if (len != 2 && len != 3) { + Jim_SetResultFormatted(interp, "can't interpret \"%#s\" as a lambda expression", argv[1]); + return JIM_ERR; + } + + if (len == 3) { +#ifdef jim_ext_namespace + /* Need to canonicalise the given namespace. */ + nsObj = JimQualifyNameObj(interp, Jim_ListGetIndex(interp, argv[1], 2)); +#else + Jim_SetResultString(interp, "namespaces not enabled", -1); + return JIM_ERR; +#endif + } + argListObjPtr = Jim_ListGetIndex(interp, argv[1], 0); + bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1); + + cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj); + + if (cmd) { + /* Create a new argv array with a dummy argv[0], for error messages */ + nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv)); + nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1); + Jim_IncrRefCount(nargv[0]); + memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv)); + ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv); + Jim_DecrRefCount(interp, nargv[0]); + Jim_Free(nargv); + + JimDecrCmdRefCount(interp, cmd); + return ret; + } + return JIM_ERR; + } +} + + +/* [concat] */ +static int Jim_ConcatCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_SetResult(interp, Jim_ConcatObj(interp, argc - 1, argv + 1)); + return JIM_OK; +} + +/* [upvar] */ +static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + Jim_CallFrame *targetCallFrame; + + /* Lookup the target frame pointer */ + if (argc > 3 && (argc % 2 == 0)) { + targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]); + argc--; + argv++; + } + else { + targetCallFrame = Jim_GetCallFrameByLevel(interp, NULL); + } + if (targetCallFrame == NULL) { + return JIM_ERR; + } + + /* Check for arity */ + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "?level? otherVar localVar ?otherVar localVar ...?"); + return JIM_ERR; + } + + /* Now... for every other/local couple: */ + for (i = 1; i < argc; i += 2) { + if (Jim_SetVariableLink(interp, argv[i + 1], argv[i], targetCallFrame) != JIM_OK) + return JIM_ERR; + } + return JIM_OK; +} + +/* [global] */ +static int Jim_GlobalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?varName ...?"); + return JIM_ERR; + } + /* Link every var to the toplevel having the same name */ + if (interp->framePtr->level == 0) + return JIM_OK; /* global at toplevel... */ + for (i = 1; i < argc; i++) { + /* global ::blah does nothing */ + const char *name = Jim_String(argv[i]); + if (name[0] != ':' || name[1] != ':') { + if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK) + return JIM_ERR; + } + } + return JIM_OK; +} + +/* does the [string map] operation. On error NULL is returned, + * otherwise a new string object with the result, having refcount = 0, + * is returned. */ +static Jim_Obj *JimStringMap(Jim_Interp *interp, Jim_Obj *mapListObjPtr, + Jim_Obj *objPtr, int nocase) +{ + int numMaps; + const char *str, *noMatchStart = NULL; + int strLen, i; + Jim_Obj *resultObjPtr; + + numMaps = Jim_ListLength(interp, mapListObjPtr); + if (numMaps % 2) { + Jim_SetResultString(interp, "list must contain an even number of elements", -1); + return NULL; + } + + str = Jim_String(objPtr); + strLen = Jim_Utf8Length(interp, objPtr); + + /* Map it */ + resultObjPtr = Jim_NewStringObj(interp, "", 0); + while (strLen) { + for (i = 0; i < numMaps; i += 2) { + Jim_Obj *objPtr; + const char *k; + int kl; + + Jim_ListIndex(interp, mapListObjPtr, i, &objPtr, JIM_NONE); + k = Jim_String(objPtr); + kl = Jim_Utf8Length(interp, objPtr); + + if (strLen >= kl && kl) { + int rc; + rc = JimStringCompareLen(str, k, kl, nocase); + if (rc == 0) { + if (noMatchStart) { + Jim_AppendString(interp, resultObjPtr, noMatchStart, str - noMatchStart); + noMatchStart = NULL; + } + Jim_ListIndex(interp, mapListObjPtr, i + 1, &objPtr, JIM_NONE); + Jim_AppendObj(interp, resultObjPtr, objPtr); + str += utf8_index(str, kl); + strLen -= kl; + break; + } + } + } + if (i == numMaps) { /* no match */ + int c; + if (noMatchStart == NULL) + noMatchStart = str; + str += utf8_tounicode(str, &c); + strLen--; + } + } + if (noMatchStart) { + Jim_AppendString(interp, resultObjPtr, noMatchStart, str - noMatchStart); + } + return resultObjPtr; +} + +/* [string] */ +static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int len; + int opt_case = 1; + int option; + static const char * const options[] = { + "bytelength", "length", "compare", "match", "equal", "is", "byterange", "range", "replace", + "map", "repeat", "reverse", "index", "first", "last", + "trim", "trimleft", "trimright", "tolower", "toupper", "totitle", NULL + }; + enum + { + OPT_BYTELENGTH, OPT_LENGTH, OPT_COMPARE, OPT_MATCH, OPT_EQUAL, OPT_IS, OPT_BYTERANGE, OPT_RANGE, OPT_REPLACE, + OPT_MAP, OPT_REPEAT, OPT_REVERSE, OPT_INDEX, OPT_FIRST, OPT_LAST, + OPT_TRIM, OPT_TRIMLEFT, OPT_TRIMRIGHT, OPT_TOLOWER, OPT_TOUPPER, OPT_TOTITLE + }; + static const char * const nocase_options[] = { + "-nocase", NULL + }; + static const char * const nocase_length_options[] = { + "-nocase", "-length", NULL + }; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "option ?arguments ...?"); + return JIM_ERR; + } + if (Jim_GetEnum(interp, argv[1], options, &option, NULL, + JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) + return JIM_ERR; + + switch (option) { + case OPT_LENGTH: + case OPT_BYTELENGTH: + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "string"); + return JIM_ERR; + } + if (option == OPT_LENGTH) { + len = Jim_Utf8Length(interp, argv[2]); + } + else { + len = Jim_Length(argv[2]); + } + Jim_SetResultInt(interp, len); + return JIM_OK; + + case OPT_COMPARE: + case OPT_EQUAL: + { + /* n is the number of remaining option args */ + long opt_length = -1; + int n = argc - 4; + int i = 2; + while (n > 0) { + int subopt; + if (Jim_GetEnum(interp, argv[i++], nocase_length_options, &subopt, NULL, + JIM_ENUM_ABBREV) != JIM_OK) { +badcompareargs: + Jim_WrongNumArgs(interp, 2, argv, "?-nocase? ?-length int? string1 string2"); + return JIM_ERR; + } + if (subopt == 0) { + /* -nocase */ + opt_case = 0; + n--; + } + else { + /* -length */ + if (n < 2) { + goto badcompareargs; + } + if (Jim_GetLong(interp, argv[i++], &opt_length) != JIM_OK) { + return JIM_ERR; + } + n -= 2; + } + } + if (n) { + goto badcompareargs; + } + argv += argc - 2; + if (opt_length < 0 && option != OPT_COMPARE && opt_case) { + /* Fast version - [string equal], case sensitive, no length */ + Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1])); + } + else { + if (opt_length >= 0) { + n = JimStringCompareLen(Jim_String(argv[0]), Jim_String(argv[1]), opt_length, !opt_case); + } + else { + n = Jim_StringCompareObj(interp, argv[0], argv[1], !opt_case); + } + Jim_SetResultInt(interp, option == OPT_COMPARE ? n : n == 0); + } + return JIM_OK; + } + + case OPT_MATCH: + if (argc != 4 && + (argc != 5 || + Jim_GetEnum(interp, argv[2], nocase_options, &opt_case, NULL, + JIM_ENUM_ABBREV) != JIM_OK)) { + Jim_WrongNumArgs(interp, 2, argv, "?-nocase? pattern string"); + return JIM_ERR; + } + if (opt_case == 0) { + argv++; + } + Jim_SetResultBool(interp, Jim_StringMatchObj(interp, argv[2], argv[3], !opt_case)); + return JIM_OK; + + case OPT_MAP:{ + Jim_Obj *objPtr; + + if (argc != 4 && + (argc != 5 || + Jim_GetEnum(interp, argv[2], nocase_options, &opt_case, NULL, + JIM_ENUM_ABBREV) != JIM_OK)) { + Jim_WrongNumArgs(interp, 2, argv, "?-nocase? mapList string"); + return JIM_ERR; + } + + if (opt_case == 0) { + argv++; + } + objPtr = JimStringMap(interp, argv[2], argv[3], !opt_case); + if (objPtr == NULL) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + case OPT_RANGE: + case OPT_BYTERANGE:{ + Jim_Obj *objPtr; + + if (argc != 5) { + Jim_WrongNumArgs(interp, 2, argv, "string first last"); + return JIM_ERR; + } + if (option == OPT_RANGE) { + objPtr = Jim_StringRangeObj(interp, argv[2], argv[3], argv[4]); + } + else + { + objPtr = Jim_StringByteRangeObj(interp, argv[2], argv[3], argv[4]); + } + + if (objPtr == NULL) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + case OPT_REPLACE:{ + Jim_Obj *objPtr; + + if (argc != 5 && argc != 6) { + Jim_WrongNumArgs(interp, 2, argv, "string first last ?string?"); + return JIM_ERR; + } + objPtr = JimStringReplaceObj(interp, argv[2], argv[3], argv[4], argc == 6 ? argv[5] : NULL); + if (objPtr == NULL) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + + case OPT_REPEAT:{ + Jim_Obj *objPtr; + jim_wide count; + + if (argc != 4) { + Jim_WrongNumArgs(interp, 2, argv, "string count"); + return JIM_ERR; + } + if (Jim_GetWide(interp, argv[3], &count) != JIM_OK) { + return JIM_ERR; + } + objPtr = Jim_NewStringObj(interp, "", 0); + if (count > 0) { + while (count--) { + Jim_AppendObj(interp, objPtr, argv[2]); + } + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + case OPT_REVERSE:{ + char *buf, *p; + const char *str; + int len; + int i; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "string"); + return JIM_ERR; + } + + str = Jim_GetString(argv[2], &len); + buf = Jim_Alloc(len + 1); + p = buf + len; + *p = 0; + for (i = 0; i < len; ) { + int c; + int l = utf8_tounicode(str, &c); + memcpy(p - l, str, l); + p -= l; + i += l; + str += l; + } + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, len)); + return JIM_OK; + } + + case OPT_INDEX:{ + int idx; + const char *str; + + if (argc != 4) { + Jim_WrongNumArgs(interp, 2, argv, "string index"); + return JIM_ERR; + } + if (Jim_GetIndex(interp, argv[3], &idx) != JIM_OK) { + return JIM_ERR; + } + str = Jim_String(argv[2]); + len = Jim_Utf8Length(interp, argv[2]); + if (idx != INT_MIN && idx != INT_MAX) { + idx = JimRelToAbsIndex(len, idx); + } + if (idx < 0 || idx >= len || str == NULL) { + Jim_SetResultString(interp, "", 0); + } + else if (len == Jim_Length(argv[2])) { + /* ASCII optimisation */ + Jim_SetResultString(interp, str + idx, 1); + } + else { + int c; + int i = utf8_index(str, idx); + Jim_SetResultString(interp, str + i, utf8_tounicode(str + i, &c)); + } + return JIM_OK; + } + + case OPT_FIRST: + case OPT_LAST:{ + int idx = 0, l1, l2; + const char *s1, *s2; + + if (argc != 4 && argc != 5) { + Jim_WrongNumArgs(interp, 2, argv, "subString string ?index?"); + return JIM_ERR; + } + s1 = Jim_String(argv[2]); + s2 = Jim_String(argv[3]); + l1 = Jim_Utf8Length(interp, argv[2]); + l2 = Jim_Utf8Length(interp, argv[3]); + if (argc == 5) { + if (Jim_GetIndex(interp, argv[4], &idx) != JIM_OK) { + return JIM_ERR; + } + idx = JimRelToAbsIndex(l2, idx); + } + else if (option == OPT_LAST) { + idx = l2; + } + if (option == OPT_FIRST) { + Jim_SetResultInt(interp, JimStringFirst(s1, l1, s2, l2, idx)); + } + else { +#ifdef JIM_UTF8 + Jim_SetResultInt(interp, JimStringLastUtf8(s1, l1, s2, idx)); +#else + Jim_SetResultInt(interp, JimStringLast(s1, l1, s2, idx)); +#endif + } + return JIM_OK; + } + + case OPT_TRIM: + case OPT_TRIMLEFT: + case OPT_TRIMRIGHT:{ + Jim_Obj *trimchars; + + if (argc != 3 && argc != 4) { + Jim_WrongNumArgs(interp, 2, argv, "string ?trimchars?"); + return JIM_ERR; + } + trimchars = (argc == 4 ? argv[3] : NULL); + if (option == OPT_TRIM) { + Jim_SetResult(interp, JimStringTrim(interp, argv[2], trimchars)); + } + else if (option == OPT_TRIMLEFT) { + Jim_SetResult(interp, JimStringTrimLeft(interp, argv[2], trimchars)); + } + else if (option == OPT_TRIMRIGHT) { + Jim_SetResult(interp, JimStringTrimRight(interp, argv[2], trimchars)); + } + return JIM_OK; + } + + case OPT_TOLOWER: + case OPT_TOUPPER: + case OPT_TOTITLE: + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "string"); + return JIM_ERR; + } + if (option == OPT_TOLOWER) { + Jim_SetResult(interp, JimStringToLower(interp, argv[2])); + } + else if (option == OPT_TOUPPER) { + Jim_SetResult(interp, JimStringToUpper(interp, argv[2])); + } + else { + Jim_SetResult(interp, JimStringToTitle(interp, argv[2])); + } + return JIM_OK; + + case OPT_IS: + if (argc == 4 || (argc == 5 && Jim_CompareStringImmediate(interp, argv[3], "-strict"))) { + return JimStringIs(interp, argv[argc - 1], argv[2], argc == 5); + } + Jim_WrongNumArgs(interp, 2, argv, "class ?-strict? str"); + return JIM_ERR; + } + return JIM_OK; +} + +/* [time] */ +static int Jim_TimeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + long i, count = 1; + jim_wide start, elapsed; + char buf[60]; + const char *fmt = "%" JIM_WIDE_MODIFIER " microseconds per iteration"; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "script ?count?"); + return JIM_ERR; + } + if (argc == 3) { + if (Jim_GetLong(interp, argv[2], &count) != JIM_OK) + return JIM_ERR; + } + if (count < 0) + return JIM_OK; + i = count; + start = JimClock(); + while (i-- > 0) { + int retval; + + retval = Jim_EvalObj(interp, argv[1]); + if (retval != JIM_OK) { + return retval; + } + } + elapsed = JimClock() - start; + sprintf(buf, fmt, count == 0 ? 0 : elapsed / count); + Jim_SetResultString(interp, buf, -1); + return JIM_OK; +} + +/* [exit] */ +static int Jim_ExitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + long exitCode = 0; + + if (argc > 2) { + Jim_WrongNumArgs(interp, 1, argv, "?exitCode?"); + return JIM_ERR; + } + if (argc == 2) { + if (Jim_GetLong(interp, argv[1], &exitCode) != JIM_OK) + return JIM_ERR; + } + interp->exitCode = exitCode; + return JIM_EXIT; +} + +/* [catch] */ +static int Jim_CatchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int exitCode = 0; + int i; + int sig = 0; + + /* Which return codes are ignored (passed through)? By default, only exit, eval and signal */ + jim_wide ignore_mask = (1 << JIM_EXIT) | (1 << JIM_EVAL) | (1 << JIM_SIGNAL); + static const int max_ignore_code = sizeof(ignore_mask) * 8; + + /* Reset the error code before catch. + * Note that this is not strictly correct. + */ + Jim_SetGlobalVariableStr(interp, "errorCode", Jim_NewStringObj(interp, "NONE", -1)); + + for (i = 1; i < argc - 1; i++) { + const char *arg = Jim_String(argv[i]); + jim_wide option; + int ignore; + + /* It's a pity we can't use Jim_GetEnum here :-( */ + if (strcmp(arg, "--") == 0) { + i++; + break; + } + if (*arg != '-') { + break; + } + + if (strncmp(arg, "-no", 3) == 0) { + arg += 3; + ignore = 1; + } + else { + arg++; + ignore = 0; + } + + if (Jim_StringToWide(arg, &option, 10) != JIM_OK) { + option = -1; + } + if (option < 0) { + option = Jim_FindByName(arg, jimReturnCodes, jimReturnCodesSize); + } + if (option < 0) { + goto wrongargs; + } + + if (ignore) { + ignore_mask |= (1 << option); + } + else { + ignore_mask &= ~(1 << option); + } + } + + argc -= i; + if (argc < 1 || argc > 3) { + wrongargs: + Jim_WrongNumArgs(interp, 1, argv, + "?-?no?code ... --? script ?resultVarName? ?optionVarName?"); + return JIM_ERR; + } + argv += i; + + if ((ignore_mask & (1 << JIM_SIGNAL)) == 0) { + sig++; + } + + interp->signal_level += sig; + if (interp->signal_level && interp->sigmask) { + /* If a signal is set, don't even try to execute the body */ + exitCode = JIM_SIGNAL; + } + else { + exitCode = Jim_EvalObj(interp, argv[0]); + } + interp->signal_level -= sig; + + /* Catch or pass through? Only the first 32/64 codes can be passed through */ + if (exitCode >= 0 && exitCode < max_ignore_code && ((1 << exitCode) & ignore_mask)) { + /* Not caught, pass it up */ + return exitCode; + } + + if (sig && exitCode == JIM_SIGNAL) { + /* Catch the signal at this level */ + if (interp->signal_set_result) { + interp->signal_set_result(interp, interp->sigmask); + } + else { + Jim_SetResultInt(interp, interp->sigmask); + } + interp->sigmask = 0; + } + + if (argc >= 2) { + if (Jim_SetVariable(interp, argv[1], Jim_GetResult(interp)) != JIM_OK) { + return JIM_ERR; + } + if (argc == 3) { + Jim_Obj *optListObj = Jim_NewListObj(interp, NULL, 0); + + Jim_ListAppendElement(interp, optListObj, Jim_NewStringObj(interp, "-code", -1)); + Jim_ListAppendElement(interp, optListObj, + Jim_NewIntObj(interp, exitCode == JIM_RETURN ? interp->returnCode : exitCode)); + Jim_ListAppendElement(interp, optListObj, Jim_NewStringObj(interp, "-level", -1)); + Jim_ListAppendElement(interp, optListObj, Jim_NewIntObj(interp, interp->returnLevel)); + if (exitCode == JIM_ERR) { + Jim_Obj *errorCode; + Jim_ListAppendElement(interp, optListObj, Jim_NewStringObj(interp, "-errorinfo", + -1)); + Jim_ListAppendElement(interp, optListObj, interp->stackTrace); + + errorCode = Jim_GetGlobalVariableStr(interp, "errorCode", JIM_NONE); + if (errorCode) { + Jim_ListAppendElement(interp, optListObj, Jim_NewStringObj(interp, "-errorcode", -1)); + Jim_ListAppendElement(interp, optListObj, errorCode); + } + } + if (Jim_SetVariable(interp, argv[2], optListObj) != JIM_OK) { + return JIM_ERR; + } + } + } + Jim_SetResultInt(interp, exitCode); + return JIM_OK; +} + +#ifdef JIM_REFERENCES + +/* [ref] */ +static int Jim_RefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 3 && argc != 4) { + Jim_WrongNumArgs(interp, 1, argv, "string tag ?finalizer?"); + return JIM_ERR; + } + if (argc == 3) { + Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], NULL)); + } + else { + Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], argv[3])); + } + return JIM_OK; +} + +/* [getref] */ +static int Jim_GetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Reference *refPtr; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "reference"); + return JIM_ERR; + } + if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL) + return JIM_ERR; + Jim_SetResult(interp, refPtr->objPtr); + return JIM_OK; +} + +/* [setref] */ +static int Jim_SetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Reference *refPtr; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "reference newValue"); + return JIM_ERR; + } + if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL) + return JIM_ERR; + Jim_IncrRefCount(argv[2]); + Jim_DecrRefCount(interp, refPtr->objPtr); + refPtr->objPtr = argv[2]; + Jim_SetResult(interp, argv[2]); + return JIM_OK; +} + +/* [collect] */ +static int Jim_CollectCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + Jim_SetResultInt(interp, Jim_Collect(interp)); + + /* Free all the freed objects. */ + while (interp->freeList) { + Jim_Obj *nextObjPtr = interp->freeList->nextObjPtr; + Jim_Free(interp->freeList); + interp->freeList = nextObjPtr; + } + + return JIM_OK; +} + +/* [finalize] reference ?newValue? */ +static int Jim_FinalizeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "reference ?finalizerProc?"); + return JIM_ERR; + } + if (argc == 2) { + Jim_Obj *cmdNamePtr; + + if (Jim_GetFinalizer(interp, argv[1], &cmdNamePtr) != JIM_OK) + return JIM_ERR; + if (cmdNamePtr != NULL) /* otherwise the null string is returned. */ + Jim_SetResult(interp, cmdNamePtr); + } + else { + if (Jim_SetFinalizer(interp, argv[1], argv[2]) != JIM_OK) + return JIM_ERR; + Jim_SetResult(interp, argv[2]); + } + return JIM_OK; +} + +/* [info references] */ +static int JimInfoReferences(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listObjPtr; + Jim_HashTableIterator htiter; + Jim_HashEntry *he; + + listObjPtr = Jim_NewListObj(interp, NULL, 0); + + JimInitHashTableIterator(&interp->references, &htiter); + while ((he = Jim_NextHashEntry(&htiter)) != NULL) { + char buf[JIM_REFERENCE_SPACE + 1]; + Jim_Reference *refPtr = he->u.val; + const unsigned long *refId = he->key; + + JimFormatReference(buf, refPtr, *refId); + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, buf, -1)); + } + Jim_SetResult(interp, listObjPtr); + return JIM_OK; +} +#endif + +/* [rename] */ +static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "oldName newName"); + return JIM_ERR; + } + + if (JimValidName(interp, "new procedure", argv[2])) { + return JIM_ERR; + } + + return Jim_RenameCommand(interp, Jim_String(argv[1]), Jim_String(argv[2])); +} + +#define JIM_DICTMATCH_VALUES 0x0001 + +typedef void JimDictMatchCallbackType(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type); + +static void JimDictMatchKeys(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type) +{ + Jim_ListAppendElement(interp, listObjPtr, (Jim_Obj *)he->key); + if (type & JIM_DICTMATCH_VALUES) { + Jim_ListAppendElement(interp, listObjPtr, (Jim_Obj *)he->u.val); + } +} + +/** + * Like JimHashtablePatternMatch, but for dictionaries. + */ +static Jim_Obj *JimDictPatternMatch(Jim_Interp *interp, Jim_HashTable *ht, Jim_Obj *patternObjPtr, + JimDictMatchCallbackType *callback, int type) +{ + Jim_HashEntry *he; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + /* Check for the non-pattern case. We can do this much more efficiently. */ + Jim_HashTableIterator htiter; + JimInitHashTableIterator(ht, &htiter); + while ((he = Jim_NextHashEntry(&htiter)) != NULL) { + if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), Jim_String((Jim_Obj *)he->key), 0)) { + callback(interp, listObjPtr, he, type); + } + } + + return listObjPtr; +} + + +int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObjPtr) +{ + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, JimDictPatternMatch(interp, objPtr->internalRep.ptr, patternObjPtr, JimDictMatchKeys, 0)); + return JIM_OK; +} + +int Jim_DictValues(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObjPtr) +{ + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, JimDictPatternMatch(interp, objPtr->internalRep.ptr, patternObjPtr, JimDictMatchKeys, JIM_DICTMATCH_VALUES)); + return JIM_OK; +} + +int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return -1; + } + return ((Jim_HashTable *)objPtr->internalRep.ptr)->used; +} + +/* [dict] */ +static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + int option; + static const char * const options[] = { + "create", "get", "set", "unset", "exists", "keys", "merge", "size", "with", NULL + }; + enum + { + OPT_CREATE, OPT_GET, OPT_SET, OPT_UNSET, OPT_EXIST, OPT_KEYS, OPT_MERGE, OPT_SIZE, OPT_WITH, + }; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "subcommand ?arguments ...?"); + return JIM_ERR; + } + + if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + + switch (option) { + case OPT_GET: + if (argc < 3) { + Jim_WrongNumArgs(interp, 2, argv, "varName ?key ...?"); + return JIM_ERR; + } + if (Jim_DictKeysVector(interp, argv[2], argv + 3, argc - 3, &objPtr, + JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + + case OPT_SET: + if (argc < 5) { + Jim_WrongNumArgs(interp, 2, argv, "varName key ?key ...? value"); + return JIM_ERR; + } + return Jim_SetDictKeysVector(interp, argv[2], argv + 3, argc - 4, argv[argc - 1], JIM_ERRMSG); + + case OPT_EXIST: + if (argc < 3) { + Jim_WrongNumArgs(interp, 2, argv, "varName ?key ...?"); + return JIM_ERR; + } + Jim_SetResultBool(interp, Jim_DictKeysVector(interp, argv[2], argv + 3, argc - 3, + &objPtr, JIM_ERRMSG) == JIM_OK); + return JIM_OK; + + case OPT_UNSET: + if (argc < 4) { + Jim_WrongNumArgs(interp, 2, argv, "varName key ?key ...?"); + return JIM_ERR; + } + return Jim_SetDictKeysVector(interp, argv[2], argv + 3, argc - 3, NULL, JIM_NONE); + + case OPT_KEYS: + if (argc != 3 && argc != 4) { + Jim_WrongNumArgs(interp, 2, argv, "dictVar ?pattern?"); + return JIM_ERR; + } + return Jim_DictKeys(interp, argv[2], argc == 4 ? argv[3] : NULL); + + case OPT_SIZE: { + int size; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "dictVar"); + return JIM_ERR; + } + + size = Jim_DictSize(interp, argv[2]); + if (size < 0) { + return JIM_ERR; + } + Jim_SetResultInt(interp, size); + return JIM_OK; + } + + case OPT_MERGE: + if (argc == 2) { + return JIM_OK; + } + else if (SetDictFromAny(interp, argv[2]) != JIM_OK) { + return JIM_ERR; + } + else { + return Jim_EvalPrefix(interp, "dict merge", argc - 2, argv + 2); + } + + case OPT_WITH: + if (argc < 4) { + Jim_WrongNumArgs(interp, 2, argv, "dictVar ?key ...? script"); + return JIM_ERR; + } + else if (Jim_GetVariable(interp, argv[2], JIM_ERRMSG) == NULL) { + return JIM_ERR; + } + else { + return Jim_EvalPrefix(interp, "dict with", argc - 2, argv + 2); + } + + case OPT_CREATE: + if (argc % 2) { + Jim_WrongNumArgs(interp, 2, argv, "?key value ...?"); + return JIM_ERR; + } + objPtr = Jim_NewDictObj(interp, argv + 2, argc - 2); + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + return JIM_ERR; +} + +/* [subst] */ +static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + static const char * const options[] = { + "-nobackslashes", "-nocommands", "-novariables", NULL + }; + enum + { OPT_NOBACKSLASHES, OPT_NOCOMMANDS, OPT_NOVARIABLES }; + int i; + int flags = JIM_SUBST_FLAG; + Jim_Obj *objPtr; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "?options? string"); + return JIM_ERR; + } + for (i = 1; i < (argc - 1); i++) { + int option; + + if (Jim_GetEnum(interp, argv[i], options, &option, NULL, + JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + switch (option) { + case OPT_NOBACKSLASHES: + flags |= JIM_SUBST_NOESC; + break; + case OPT_NOCOMMANDS: + flags |= JIM_SUBST_NOCMD; + break; + case OPT_NOVARIABLES: + flags |= JIM_SUBST_NOVAR; + break; + } + } + if (Jim_SubstObj(interp, argv[argc - 1], &objPtr, flags) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + +/* [info] */ +static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int cmd; + Jim_Obj *objPtr; + int mode = 0; + + static const char * const commands[] = { + "body", "statics", "commands", "procs", "channels", "exists", "globals", "level", "frame", "locals", + "vars", "version", "patchlevel", "complete", "args", "hostname", + "script", "source", "stacktrace", "nameofexecutable", "returncodes", + "references", "alias", NULL + }; + enum + { INFO_BODY, INFO_STATICS, INFO_COMMANDS, INFO_PROCS, INFO_CHANNELS, INFO_EXISTS, INFO_GLOBALS, INFO_LEVEL, + INFO_FRAME, INFO_LOCALS, INFO_VARS, INFO_VERSION, INFO_PATCHLEVEL, INFO_COMPLETE, INFO_ARGS, + INFO_HOSTNAME, INFO_SCRIPT, INFO_SOURCE, INFO_STACKTRACE, INFO_NAMEOFEXECUTABLE, + INFO_RETURNCODES, INFO_REFERENCES, INFO_ALIAS + }; + +#ifdef jim_ext_namespace + int nons = 0; + + if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) { + /* This is for internal use only */ + argc--; + argv++; + nons = 1; + } +#endif + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "subcommand ?args ...?"); + return JIM_ERR; + } + if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) + != JIM_OK) { + return JIM_ERR; + } + + /* Test for the the most common commands first, just in case it makes a difference */ + switch (cmd) { + case INFO_EXISTS: + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "varName"); + return JIM_ERR; + } + Jim_SetResultBool(interp, Jim_GetVariable(interp, argv[2], 0) != NULL); + break; + + case INFO_ALIAS:{ + Jim_Cmd *cmdPtr; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "command"); + return JIM_ERR; + } + if ((cmdPtr = Jim_GetCommand(interp, argv[2], JIM_ERRMSG)) == NULL) { + return JIM_ERR; + } + if (cmdPtr->isproc || cmdPtr->u.native.cmdProc != JimAliasCmd) { + Jim_SetResultFormatted(interp, "command \"%#s\" is not an alias", argv[2]); + return JIM_ERR; + } + Jim_SetResult(interp, (Jim_Obj *)cmdPtr->u.native.privData); + return JIM_OK; + } + + case INFO_CHANNELS: + mode++; /* JIM_CMDLIST_CHANNELS */ +#ifndef jim_ext_aio + Jim_SetResultString(interp, "aio not enabled", -1); + return JIM_ERR; +#endif + case INFO_PROCS: + mode++; /* JIM_CMDLIST_PROCS */ + case INFO_COMMANDS: + /* mode 0 => JIM_CMDLIST_COMMANDS */ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "?pattern?"); + return JIM_ERR; + } +#ifdef jim_ext_namespace + if (!nons) { + if (Jim_Length(interp->framePtr->nsObj) || (argc == 3 && JimGlobMatch("::*", Jim_String(argv[2]), 0))) { + return Jim_EvalPrefix(interp, "namespace info", argc - 1, argv + 1); + } + } +#endif + Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, mode)); + break; + + case INFO_VARS: + mode++; /* JIM_VARLIST_VARS */ + case INFO_LOCALS: + mode++; /* JIM_VARLIST_LOCALS */ + case INFO_GLOBALS: + /* mode 0 => JIM_VARLIST_GLOBALS */ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "?pattern?"); + return JIM_ERR; + } +#ifdef jim_ext_namespace + if (!nons) { + if (Jim_Length(interp->framePtr->nsObj) || (argc == 3 && JimGlobMatch("::*", Jim_String(argv[2]), 0))) { + return Jim_EvalPrefix(interp, "namespace info", argc - 1, argv + 1); + } + } +#endif + Jim_SetResult(interp, JimVariablesList(interp, argc == 3 ? argv[2] : NULL, mode)); + break; + + case INFO_SCRIPT: + if (argc != 2) { + Jim_WrongNumArgs(interp, 2, argv, ""); + return JIM_ERR; + } + Jim_SetResult(interp, Jim_GetScript(interp, interp->currentScriptObj)->fileNameObj); + break; + + case INFO_SOURCE:{ + int line; + Jim_Obj *resObjPtr; + Jim_Obj *fileNameObj; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "source"); + return JIM_ERR; + } + if (argv[2]->typePtr == &sourceObjType) { + fileNameObj = argv[2]->internalRep.sourceValue.fileNameObj; + line = argv[2]->internalRep.sourceValue.lineNumber; + } + else if (argv[2]->typePtr == &scriptObjType) { + ScriptObj *script = Jim_GetScript(interp, argv[2]); + fileNameObj = script->fileNameObj; + line = script->firstline; + } + else { + fileNameObj = interp->emptyObj; + line = 1; + } + resObjPtr = Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, resObjPtr, fileNameObj); + Jim_ListAppendElement(interp, resObjPtr, Jim_NewIntObj(interp, line)); + Jim_SetResult(interp, resObjPtr); + break; + } + + case INFO_STACKTRACE: + Jim_SetResult(interp, interp->stackTrace); + break; + + case INFO_LEVEL: + case INFO_FRAME: + switch (argc) { + case 2: + Jim_SetResultInt(interp, interp->framePtr->level); + break; + + case 3: + if (JimInfoLevel(interp, argv[2], &objPtr, cmd == INFO_LEVEL) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + break; + + default: + Jim_WrongNumArgs(interp, 2, argv, "?levelNum?"); + return JIM_ERR; + } + break; + + case INFO_BODY: + case INFO_STATICS: + case INFO_ARGS:{ + Jim_Cmd *cmdPtr; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 2, argv, "procname"); + return JIM_ERR; + } + if ((cmdPtr = Jim_GetCommand(interp, argv[2], JIM_ERRMSG)) == NULL) { + return JIM_ERR; + } + if (!cmdPtr->isproc) { + Jim_SetResultFormatted(interp, "command \"%#s\" is not a procedure", argv[2]); + return JIM_ERR; + } + switch (cmd) { + case INFO_BODY: + Jim_SetResult(interp, cmdPtr->u.proc.bodyObjPtr); + break; + case INFO_ARGS: + Jim_SetResult(interp, cmdPtr->u.proc.argListObjPtr); + break; + case INFO_STATICS: + if (cmdPtr->u.proc.staticVars) { + int mode = JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES; + Jim_SetResult(interp, JimHashtablePatternMatch(interp, cmdPtr->u.proc.staticVars, + NULL, JimVariablesMatch, mode)); + } + break; + } + break; + } + + case INFO_VERSION: + case INFO_PATCHLEVEL:{ + char buf[(JIM_INTEGER_SPACE * 2) + 1]; + + sprintf(buf, "%d.%d", JIM_VERSION / 100, JIM_VERSION % 100); + Jim_SetResultString(interp, buf, -1); + break; + } + + case INFO_COMPLETE: + if (argc != 3 && argc != 4) { + Jim_WrongNumArgs(interp, 2, argv, "script ?missing?"); + return JIM_ERR; + } + else { + int len; + const char *s = Jim_GetString(argv[2], &len); + char missing; + + Jim_SetResultBool(interp, Jim_ScriptIsComplete(s, len, &missing)); + if (missing != ' ' && argc == 4) { + Jim_SetVariable(interp, argv[3], Jim_NewStringObj(interp, &missing, 1)); + } + } + break; + + case INFO_HOSTNAME: + /* Redirect to os.gethostname if it exists */ + return Jim_Eval(interp, "os.gethostname"); + + case INFO_NAMEOFEXECUTABLE: + /* Redirect to Tcl proc */ + return Jim_Eval(interp, "{info nameofexecutable}"); + + case INFO_RETURNCODES: + if (argc == 2) { + int i; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + for (i = 0; jimReturnCodes[i]; i++) { + Jim_ListAppendElement(interp, listObjPtr, Jim_NewIntObj(interp, i)); + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, + jimReturnCodes[i], -1)); + } + + Jim_SetResult(interp, listObjPtr); + } + else if (argc == 3) { + long code; + const char *name; + + if (Jim_GetLong(interp, argv[2], &code) != JIM_OK) { + return JIM_ERR; + } + name = Jim_ReturnCode(code); + if (*name == '?') { + Jim_SetResultInt(interp, code); + } + else { + Jim_SetResultString(interp, name, -1); + } + } + else { + Jim_WrongNumArgs(interp, 2, argv, "?code?"); + return JIM_ERR; + } + break; + case INFO_REFERENCES: +#ifdef JIM_REFERENCES + return JimInfoReferences(interp, argc, argv); +#else + Jim_SetResultString(interp, "not supported", -1); + return JIM_ERR; +#endif + } + return JIM_OK; +} + +/* [exists] */ +static int Jim_ExistsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + int result = 0; + + static const char * const options[] = { + "-command", "-proc", "-alias", "-var", NULL + }; + enum + { + OPT_COMMAND, OPT_PROC, OPT_ALIAS, OPT_VAR + }; + int option; + + if (argc == 2) { + option = OPT_VAR; + objPtr = argv[1]; + } + else if (argc == 3) { + if (Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + objPtr = argv[2]; + } + else { + Jim_WrongNumArgs(interp, 1, argv, "?option? name"); + return JIM_ERR; + } + + if (option == OPT_VAR) { + result = Jim_GetVariable(interp, objPtr, 0) != NULL; + } + else { + /* Now different kinds of commands */ + Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE); + + if (cmd) { + switch (option) { + case OPT_COMMAND: + result = 1; + break; + + case OPT_ALIAS: + result = cmd->isproc == 0 && cmd->u.native.cmdProc == JimAliasCmd; + break; + + case OPT_PROC: + result = cmd->isproc; + break; + } + } + } + Jim_SetResultBool(interp, result); + return JIM_OK; +} + +/* [split] */ +static int Jim_SplitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *str, *splitChars, *noMatchStart; + int splitLen, strLen; + Jim_Obj *resObjPtr; + int c; + int len; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "string ?splitChars?"); + return JIM_ERR; + } + + str = Jim_GetString(argv[1], &len); + if (len == 0) { + return JIM_OK; + } + strLen = Jim_Utf8Length(interp, argv[1]); + + /* Init */ + if (argc == 2) { + splitChars = " \n\t\r"; + splitLen = 4; + } + else { + splitChars = Jim_String(argv[2]); + splitLen = Jim_Utf8Length(interp, argv[2]); + } + + noMatchStart = str; + resObjPtr = Jim_NewListObj(interp, NULL, 0); + + /* Split */ + if (splitLen) { + Jim_Obj *objPtr; + while (strLen--) { + const char *sc = splitChars; + int scLen = splitLen; + int sl = utf8_tounicode(str, &c); + while (scLen--) { + int pc; + sc += utf8_tounicode(sc, &pc); + if (c == pc) { + objPtr = Jim_NewStringObj(interp, noMatchStart, (str - noMatchStart)); + Jim_ListAppendElement(interp, resObjPtr, objPtr); + noMatchStart = str + sl; + break; + } + } + str += sl; + } + objPtr = Jim_NewStringObj(interp, noMatchStart, (str - noMatchStart)); + Jim_ListAppendElement(interp, resObjPtr, objPtr); + } + else { + /* This handles the special case of splitchars eq {} + * Optimise by sharing common (ASCII) characters + */ + Jim_Obj **commonObj = NULL; +#define NUM_COMMON (128 - 9) + while (strLen--) { + int n = utf8_tounicode(str, &c); +#ifdef JIM_OPTIMIZATION + if (c >= 9 && c < 128) { + /* Common ASCII char. Note that 9 is the tab character */ + c -= 9; + if (!commonObj) { + commonObj = Jim_Alloc(sizeof(*commonObj) * NUM_COMMON); + memset(commonObj, 0, sizeof(*commonObj) * NUM_COMMON); + } + if (!commonObj[c]) { + commonObj[c] = Jim_NewStringObj(interp, str, 1); + } + Jim_ListAppendElement(interp, resObjPtr, commonObj[c]); + str++; + continue; + } +#endif + Jim_ListAppendElement(interp, resObjPtr, Jim_NewStringObjUtf8(interp, str, 1)); + str += n; + } + Jim_Free(commonObj); + } + + Jim_SetResult(interp, resObjPtr); + return JIM_OK; +} + +/* [join] */ +static int Jim_JoinCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *joinStr; + int joinStrLen; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?"); + return JIM_ERR; + } + /* Init */ + if (argc == 2) { + joinStr = " "; + joinStrLen = 1; + } + else { + joinStr = Jim_GetString(argv[2], &joinStrLen); + } + Jim_SetResult(interp, Jim_ListJoin(interp, argv[1], joinStr, joinStrLen)); + return JIM_OK; +} + +/* [format] */ +static int Jim_FormatCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "formatString ?arg arg ...?"); + return JIM_ERR; + } + objPtr = Jim_FormatString(interp, argv[1], argc - 2, argv + 2); + if (objPtr == NULL) + return JIM_ERR; + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + +/* [scan] */ +static int Jim_ScanCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listPtr, **outVec; + int outc, i; + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "string format ?varName varName ...?"); + return JIM_ERR; + } + if (argv[2]->typePtr != &scanFmtStringObjType) + SetScanFmtFromAny(interp, argv[2]); + if (FormatGetError(argv[2]) != 0) { + Jim_SetResultString(interp, FormatGetError(argv[2]), -1); + return JIM_ERR; + } + if (argc > 3) { + int maxPos = FormatGetMaxPos(argv[2]); + int count = FormatGetCnvCount(argv[2]); + + if (maxPos > argc - 3) { + Jim_SetResultString(interp, "\"%n$\" argument index out of range", -1); + return JIM_ERR; + } + else if (count > argc - 3) { + Jim_SetResultString(interp, "different numbers of variable names and " + "field specifiers", -1); + return JIM_ERR; + } + else if (count < argc - 3) { + Jim_SetResultString(interp, "variable is not assigned by any " + "conversion specifiers", -1); + return JIM_ERR; + } + } + listPtr = Jim_ScanString(interp, argv[1], argv[2], JIM_ERRMSG); + if (listPtr == 0) + return JIM_ERR; + if (argc > 3) { + int rc = JIM_OK; + int count = 0; + + if (listPtr != 0 && listPtr != (Jim_Obj *)EOF) { + int len = Jim_ListLength(interp, listPtr); + + if (len != 0) { + JimListGetElements(interp, listPtr, &outc, &outVec); + for (i = 0; i < outc; ++i) { + if (Jim_Length(outVec[i]) > 0) { + ++count; + if (Jim_SetVariable(interp, argv[3 + i], outVec[i]) != JIM_OK) { + rc = JIM_ERR; + } + } + } + } + Jim_FreeNewObj(interp, listPtr); + } + else { + count = -1; + } + if (rc == JIM_OK) { + Jim_SetResultInt(interp, count); + } + return rc; + } + else { + if (listPtr == (Jim_Obj *)EOF) { + Jim_SetResult(interp, Jim_NewListObj(interp, 0, 0)); + return JIM_OK; + } + Jim_SetResult(interp, listPtr); + } + return JIM_OK; +} + +/* [error] */ +static int Jim_ErrorCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "message ?stacktrace?"); + return JIM_ERR; + } + Jim_SetResult(interp, argv[1]); + if (argc == 3) { + JimSetStackTrace(interp, argv[2]); + return JIM_ERR; + } + interp->addStackTrace++; + return JIM_ERR; +} + +/* [lrange] */ +static int Jim_LrangeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + + if (argc != 4) { + Jim_WrongNumArgs(interp, 1, argv, "list first last"); + return JIM_ERR; + } + if ((objPtr = Jim_ListRange(interp, argv[1], argv[2], argv[3])) == NULL) + return JIM_ERR; + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + +/* [lrepeat] */ +static int Jim_LrepeatCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + long count; + + if (argc < 2 || Jim_GetLong(interp, argv[1], &count) != JIM_OK || count < 0) { + Jim_WrongNumArgs(interp, 1, argv, "count ?value ...?"); + return JIM_ERR; + } + + if (count == 0 || argc == 2) { + return JIM_OK; + } + + argc -= 2; + argv += 2; + + objPtr = Jim_NewListObj(interp, argv, argc); + while (--count) { + ListInsertElements(objPtr, -1, argc, argv); + } + + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + +char **Jim_GetEnviron(void) +{ +#if defined(HAVE__NSGETENVIRON) + return *_NSGetEnviron(); +#else + #if !defined(NO_ENVIRON_EXTERN) + extern char **environ; + #endif + + return environ; +#endif +} + +void Jim_SetEnviron(char **env) +{ +#if defined(HAVE__NSGETENVIRON) + *_NSGetEnviron() = env; +#else + #if !defined(NO_ENVIRON_EXTERN) + extern char **environ; + #endif + + environ = env; +#endif +} + +/* [env] */ +static int Jim_EnvCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *key; + const char *val; + + if (argc == 1) { + char **e = Jim_GetEnviron(); + + int i; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + for (i = 0; e[i]; i++) { + const char *equals = strchr(e[i], '='); + + if (equals) { + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, e[i], + equals - e[i])); + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, equals + 1, -1)); + } + } + + Jim_SetResult(interp, listObjPtr); + return JIM_OK; + } + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?default?"); + return JIM_ERR; + } + key = Jim_String(argv[1]); + val = getenv(key); + if (val == NULL) { + if (argc < 3) { + Jim_SetResultFormatted(interp, "environment variable \"%#s\" does not exist", argv[1]); + return JIM_ERR; + } + val = Jim_String(argv[2]); + } + Jim_SetResult(interp, Jim_NewStringObj(interp, val, -1)); + return JIM_OK; +} + +/* [source] */ +static int Jim_SourceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retval; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "fileName"); + return JIM_ERR; + } + retval = Jim_EvalFile(interp, Jim_String(argv[1])); + if (retval == JIM_RETURN) + return JIM_OK; + return retval; +} + +/* [lreverse] */ +static int Jim_LreverseCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *revObjPtr, **ele; + int len; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "list"); + return JIM_ERR; + } + JimListGetElements(interp, argv[1], &len, &ele); + len--; + revObjPtr = Jim_NewListObj(interp, NULL, 0); + while (len >= 0) + ListAppendElement(revObjPtr, ele[len--]); + Jim_SetResult(interp, revObjPtr); + return JIM_OK; +} + +static int JimRangeLen(jim_wide start, jim_wide end, jim_wide step) +{ + jim_wide len; + + if (step == 0) + return -1; + if (start == end) + return 0; + else if (step > 0 && start > end) + return -1; + else if (step < 0 && end > start) + return -1; + len = end - start; + if (len < 0) + len = -len; /* abs(len) */ + if (step < 0) + step = -step; /* abs(step) */ + len = 1 + ((len - 1) / step); + /* We can truncate safely to INT_MAX, the range command + * will always return an error for a such long range + * because Tcl lists can't be so long. */ + if (len > INT_MAX) + len = INT_MAX; + return (int)((len < 0) ? -1 : len); +} + +/* [range] */ +static int Jim_RangeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_wide start = 0, end, step = 1; + int len, i; + Jim_Obj *objPtr; + + if (argc < 2 || argc > 4) { + Jim_WrongNumArgs(interp, 1, argv, "?start? end ?step?"); + return JIM_ERR; + } + if (argc == 2) { + if (Jim_GetWide(interp, argv[1], &end) != JIM_OK) + return JIM_ERR; + } + else { + if (Jim_GetWide(interp, argv[1], &start) != JIM_OK || + Jim_GetWide(interp, argv[2], &end) != JIM_OK) + return JIM_ERR; + if (argc == 4 && Jim_GetWide(interp, argv[3], &step) != JIM_OK) + return JIM_ERR; + } + if ((len = JimRangeLen(start, end, step)) == -1) { + Jim_SetResultString(interp, "Invalid (infinite?) range specified", -1); + return JIM_ERR; + } + objPtr = Jim_NewListObj(interp, NULL, 0); + for (i = 0; i < len; i++) + ListAppendElement(objPtr, Jim_NewIntObj(interp, start + i * step)); + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + +/* [rand] */ +static int Jim_RandCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_wide min = 0, max = 0, len, maxMul; + + if (argc < 1 || argc > 3) { + Jim_WrongNumArgs(interp, 1, argv, "?min? max"); + return JIM_ERR; + } + if (argc == 1) { + max = JIM_WIDE_MAX; + } else if (argc == 2) { + if (Jim_GetWide(interp, argv[1], &max) != JIM_OK) + return JIM_ERR; + } else if (argc == 3) { + if (Jim_GetWide(interp, argv[1], &min) != JIM_OK || + Jim_GetWide(interp, argv[2], &max) != JIM_OK) + return JIM_ERR; + } + len = max-min; + if (len < 0) { + Jim_SetResultString(interp, "Invalid arguments (max < min)", -1); + return JIM_ERR; + } + maxMul = JIM_WIDE_MAX - (len ? (JIM_WIDE_MAX%len) : 0); + while (1) { + jim_wide r; + + JimRandomBytes(interp, &r, sizeof(jim_wide)); + if (r < 0 || r >= maxMul) continue; + r = (len == 0) ? 0 : r%len; + Jim_SetResultInt(interp, min+r); + return JIM_OK; + } +} + +static const struct { + const char *name; + Jim_CmdProc cmdProc; +} Jim_CoreCommandsTable[] = { + {"alias", Jim_AliasCoreCommand}, + {"set", Jim_SetCoreCommand}, + {"unset", Jim_UnsetCoreCommand}, + {"puts", Jim_PutsCoreCommand}, + {"+", Jim_AddCoreCommand}, + {"*", Jim_MulCoreCommand}, + {"-", Jim_SubCoreCommand}, + {"/", Jim_DivCoreCommand}, + {"incr", Jim_IncrCoreCommand}, + {"while", Jim_WhileCoreCommand}, + {"loop", Jim_LoopCoreCommand}, + {"for", Jim_ForCoreCommand}, + {"foreach", Jim_ForeachCoreCommand}, + {"lmap", Jim_LmapCoreCommand}, + {"lassign", Jim_LassignCoreCommand}, + {"if", Jim_IfCoreCommand}, + {"switch", Jim_SwitchCoreCommand}, + {"list", Jim_ListCoreCommand}, + {"lindex", Jim_LindexCoreCommand}, + {"lset", Jim_LsetCoreCommand}, + {"lsearch", Jim_LsearchCoreCommand}, + {"llength", Jim_LlengthCoreCommand}, + {"lappend", Jim_LappendCoreCommand}, + {"linsert", Jim_LinsertCoreCommand}, + {"lreplace", Jim_LreplaceCoreCommand}, + {"lsort", Jim_LsortCoreCommand}, + {"append", Jim_AppendCoreCommand}, + {"debug", Jim_DebugCoreCommand}, + {"eval", Jim_EvalCoreCommand}, + {"uplevel", Jim_UplevelCoreCommand}, + {"expr", Jim_ExprCoreCommand}, + {"break", Jim_BreakCoreCommand}, + {"continue", Jim_ContinueCoreCommand}, + {"proc", Jim_ProcCoreCommand}, + {"concat", Jim_ConcatCoreCommand}, + {"return", Jim_ReturnCoreCommand}, + {"upvar", Jim_UpvarCoreCommand}, + {"global", Jim_GlobalCoreCommand}, + {"string", Jim_StringCoreCommand}, + {"time", Jim_TimeCoreCommand}, + {"exit", Jim_ExitCoreCommand}, + {"catch", Jim_CatchCoreCommand}, +#ifdef JIM_REFERENCES + {"ref", Jim_RefCoreCommand}, + {"getref", Jim_GetrefCoreCommand}, + {"setref", Jim_SetrefCoreCommand}, + {"finalize", Jim_FinalizeCoreCommand}, + {"collect", Jim_CollectCoreCommand}, +#endif + {"rename", Jim_RenameCoreCommand}, + {"dict", Jim_DictCoreCommand}, + {"subst", Jim_SubstCoreCommand}, + {"info", Jim_InfoCoreCommand}, + {"exists", Jim_ExistsCoreCommand}, + {"split", Jim_SplitCoreCommand}, + {"join", Jim_JoinCoreCommand}, + {"format", Jim_FormatCoreCommand}, + {"scan", Jim_ScanCoreCommand}, + {"error", Jim_ErrorCoreCommand}, + {"lrange", Jim_LrangeCoreCommand}, + {"lrepeat", Jim_LrepeatCoreCommand}, + {"env", Jim_EnvCoreCommand}, + {"source", Jim_SourceCoreCommand}, + {"lreverse", Jim_LreverseCoreCommand}, + {"range", Jim_RangeCoreCommand}, + {"rand", Jim_RandCoreCommand}, + {"tailcall", Jim_TailcallCoreCommand}, + {"local", Jim_LocalCoreCommand}, + {"upcall", Jim_UpcallCoreCommand}, + {"apply", Jim_ApplyCoreCommand}, + {NULL, NULL}, +}; + +void Jim_RegisterCoreCommands(Jim_Interp *interp) +{ + int i = 0; + + while (Jim_CoreCommandsTable[i].name != NULL) { + Jim_CreateCommand(interp, + Jim_CoreCommandsTable[i].name, Jim_CoreCommandsTable[i].cmdProc, NULL, NULL); + i++; + } +} + +/* ----------------------------------------------------------------------------- + * Interactive prompt + * ---------------------------------------------------------------------------*/ +void Jim_MakeErrorMessage(Jim_Interp *interp) +{ + Jim_Obj *argv[2]; + + argv[0] = Jim_NewStringObj(interp, "errorInfo", -1); + argv[1] = interp->result; + + Jim_EvalObjVector(interp, 2, argv); +} + +static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype, + const char *prefix, const char *const *tablePtr, const char *name) +{ + int count; + char **tablePtrSorted; + int i; + + for (count = 0; tablePtr[count]; count++) { + } + + if (name == NULL) { + name = "option"; + } + + Jim_SetResultFormatted(interp, "%s%s \"%s\": must be ", badtype, name, arg); + tablePtrSorted = Jim_Alloc(sizeof(char *) * count); + memcpy(tablePtrSorted, tablePtr, sizeof(char *) * count); + qsort(tablePtrSorted, count, sizeof(char *), qsortCompareStringPointers); + for (i = 0; i < count; i++) { + if (i + 1 == count && count > 1) { + Jim_AppendString(interp, Jim_GetResult(interp), "or ", -1); + } + Jim_AppendStrings(interp, Jim_GetResult(interp), prefix, tablePtrSorted[i], NULL); + if (i + 1 != count) { + Jim_AppendString(interp, Jim_GetResult(interp), ", ", -1); + } + } + Jim_Free(tablePtrSorted); +} + +int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr, + const char *const *tablePtr, int *indexPtr, const char *name, int flags) +{ + const char *bad = "bad "; + const char *const *entryPtr = NULL; + int i; + int match = -1; + int arglen; + const char *arg = Jim_GetString(objPtr, &arglen); + + *indexPtr = -1; + + for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) { + if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) { + /* Found an exact match */ + *indexPtr = i; + return JIM_OK; + } + if (flags & JIM_ENUM_ABBREV) { + /* Accept an unambiguous abbreviation. + * Note that '-' doesnt' consitute a valid abbreviation + */ + if (strncmp(arg, *entryPtr, arglen) == 0) { + if (*arg == '-' && arglen == 1) { + break; + } + if (match >= 0) { + bad = "ambiguous "; + goto ambiguous; + } + match = i; + } + } + } + + /* If we had an unambiguous partial match */ + if (match >= 0) { + *indexPtr = match; + return JIM_OK; + } + + ambiguous: + if (flags & JIM_ERRMSG) { + JimSetFailedEnumResult(interp, arg, bad, "", tablePtr, name); + } + return JIM_ERR; +} + +int Jim_FindByName(const char *name, const char * const array[], size_t len) +{ + int i; + + for (i = 0; i < (int)len; i++) { + if (array[i] && strcmp(array[i], name) == 0) { + return i; + } + } + return -1; +} + +int Jim_IsDict(Jim_Obj *objPtr) +{ + return objPtr->typePtr == &dictObjType; +} + +int Jim_IsList(Jim_Obj *objPtr) +{ + return objPtr->typePtr == &listObjType; +} + +/** + * Very simple printf-like formatting, designed for error messages. + * + * The format may contain up to 5 '%s' or '%#s', corresponding to variable arguments. + * The resulting string is created and set as the result. + * + * Each '%s' should correspond to a regular string parameter. + * Each '%#s' should correspond to a (Jim_Obj *) parameter. + * Any other printf specifier is not allowed (but %% is allowed for the % character). + * + * e.g. Jim_SetResultFormatted(interp, "Bad option \"%#s\" in proc \"%#s\"", optionObjPtr, procNamePtr); + * + * Note: We take advantage of the fact that printf has the same behaviour for both %s and %#s + */ +void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...) +{ + /* Initial space needed */ + int len = strlen(format); + int extra = 0; + int n = 0; + const char *params[5]; + char *buf; + va_list args; + int i; + + va_start(args, format); + + for (i = 0; i < len && n < 5; i++) { + int l; + + if (strncmp(format + i, "%s", 2) == 0) { + params[n] = va_arg(args, char *); + + l = strlen(params[n]); + } + else if (strncmp(format + i, "%#s", 3) == 0) { + Jim_Obj *objPtr = va_arg(args, Jim_Obj *); + + params[n] = Jim_GetString(objPtr, &l); + } + else { + if (format[i] == '%') { + i++; + } + continue; + } + n++; + extra += l; + } + + len += extra; + buf = Jim_Alloc(len + 1); + len = snprintf(buf, len + 1, format, params[0], params[1], params[2], params[3], params[4]); + + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, len)); +} + +/* stubs */ +#ifndef jim_ext_package +int Jim_PackageProvide(Jim_Interp *interp, const char *name, const char *ver, int flags) +{ + return JIM_OK; +} +#endif +#ifndef jim_ext_aio +FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *fhObj) +{ + Jim_SetResultString(interp, "aio not enabled", -1); + return NULL; +} +#endif + + +/* + * Local Variables: *** + * c-basic-offset: 4 *** + * tab-width: 4 *** + * End: *** + */ diff --git a/debuggers/openocd/jimtcl/jim.h b/debuggers/openocd/jimtcl/jim.h new file mode 100644 index 00000000..1c23c233 --- /dev/null +++ b/debuggers/openocd/jimtcl/jim.h @@ -0,0 +1,936 @@ +/* Jim - A small embeddable Tcl interpreter + * + * Copyright 2005 Salvatore Sanfilippo + * Copyright 2005 Clemens Hintze + * Copyright 2005 patthoyts - Pat Thoyts + * Copyright 2008 oharboe - yvind Harboe - oyvind.harboe@zylin.com + * Copyright 2008 Andrew Lunn + * Copyright 2008 Duane Ellis + * Copyright 2008 Uwe Klein + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + * + *--- Inline Header File Documentation --- + * [By Duane Ellis, openocd@duaneellis.com, 8/18/8] + * + * Belief is "Jim" would greatly benifit if Jim Internals where + * documented in some way - form whatever, and perhaps - the package: + * 'doxygen' is the correct approach to do that. + * + * Details, see: http://www.stack.nl/~dimitri/doxygen/ + * + * To that end please follow these guide lines: + * + * (A) Document the PUBLIC api in the .H file. + * + * (B) Document JIM Internals, in the .C file. + * + * (C) Remember JIM is embedded in other packages, to that end do + * not assume that your way of documenting is the right way, Jim's + * public documentation should be agnostic, such that it is some + * what agreeable with the "package" that is embedding JIM inside + * of it's own doxygen documentation. + * + * (D) Use minimal Doxygen tags. + * + * This will be an "ongoing work in progress" for some time. + **/ + +#ifndef __JIM__H +#define __JIM__H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include /* for the FILE typedef definition */ +#include /* In order to export the Jim_Free() macro */ +#include /* In order to get type va_list */ + +/* ----------------------------------------------------------------------------- + * System configuration + * autoconf (configure) will set these + * ---------------------------------------------------------------------------*/ +#include + +#ifndef HAVE_NO_AUTOCONF +#include +#endif + +/* ----------------------------------------------------------------------------- + * Compiler specific fixes. + * ---------------------------------------------------------------------------*/ + +/* Long Long type and related issues */ +#ifndef jim_wide +# ifdef HAVE_LONG_LONG +# define jim_wide long long +# ifndef LLONG_MAX +# define LLONG_MAX 9223372036854775807LL +# endif +# ifndef LLONG_MIN +# define LLONG_MIN (-LLONG_MAX - 1LL) +# endif +# define JIM_WIDE_MIN LLONG_MIN +# define JIM_WIDE_MAX LLONG_MAX +# else +# define jim_wide long +# define JIM_WIDE_MIN LONG_MIN +# define JIM_WIDE_MAX LONG_MAX +# endif + +/* ----------------------------------------------------------------------------- + * LIBC specific fixes + * ---------------------------------------------------------------------------*/ + +# ifdef HAVE_LONG_LONG +# define JIM_WIDE_MODIFIER "lld" +# else +# define JIM_WIDE_MODIFIER "ld" +# define strtoull strtoul +# endif +#endif + +#define UCHAR(c) ((unsigned char)(c)) + +/* ----------------------------------------------------------------------------- + * Exported defines + * ---------------------------------------------------------------------------*/ + +/* Jim version numbering: every version of jim is marked with a + * successive integer number. This is version 0. The first + * stable version will be 1, then 2, 3, and so on. */ +#define JIM_VERSION 73 + +#define JIM_OK 0 +#define JIM_ERR 1 +#define JIM_RETURN 2 +#define JIM_BREAK 3 +#define JIM_CONTINUE 4 +#define JIM_SIGNAL 5 +#define JIM_EXIT 6 +/* The following are internal codes and should never been seen/used */ +#define JIM_EVAL 7 + +#define JIM_MAX_CALLFRAME_DEPTH 1000 /* default max nesting depth for procs */ +#define JIM_MAX_EVAL_DEPTH 2000 /* default max nesting depth for eval */ + +/* Some function get an integer argument with flags to change + * the behaviour. */ +#define JIM_NONE 0 /* no flags set */ +#define JIM_ERRMSG 1 /* set an error message in the interpreter. */ + +#define JIM_UNSHARED 4 /* Flag to Jim_GetVariable() */ +#define JIM_MUSTEXIST 8 /* Flag to Jim_SetDictKeysVector() - fail if non-existent */ + +/* Internal flags */ +#define JIM_GLOBAL_ONLY 0x100 + +/* Flags for Jim_SubstObj() */ +#define JIM_SUBST_NOVAR 1 /* don't perform variables substitutions */ +#define JIM_SUBST_NOCMD 2 /* don't perform command substitutions */ +#define JIM_SUBST_NOESC 4 /* don't perform escapes substitutions */ +#define JIM_SUBST_FLAG 128 /* flag to indicate that this is a real substition object */ + +/* Unused arguments generate annoying warnings... */ +#define JIM_NOTUSED(V) ((void) V) + +/* Flags for Jim_GetEnum() */ +#define JIM_ENUM_ABBREV 2 /* Allow unambiguous abbreviation */ + +/* Flags used by API calls getting a 'nocase' argument. */ +#define JIM_CASESENS 0 /* case sensitive */ +#define JIM_NOCASE 1 /* no case */ + +/* Filesystem related */ +#define JIM_PATH_LEN 1024 + +/* Newline, some embedded system may need -DJIM_CRLF */ +#ifdef JIM_CRLF +#define JIM_NL "\r\n" +#else +#define JIM_NL "\n" +#endif + +#define JIM_LIBPATH "auto_path" +#define JIM_INTERACTIVE "tcl_interactive" + +/* ----------------------------------------------------------------------------- + * Stack + * ---------------------------------------------------------------------------*/ + +typedef struct Jim_Stack { + int len; + int maxlen; + void **vector; +} Jim_Stack; + +/* ----------------------------------------------------------------------------- + * Hash table + * ---------------------------------------------------------------------------*/ + +typedef struct Jim_HashEntry { + void *key; + union { + void *val; + int intval; + } u; + struct Jim_HashEntry *next; +} Jim_HashEntry; + +typedef struct Jim_HashTableType { + unsigned int (*hashFunction)(const void *key); + void *(*keyDup)(void *privdata, const void *key); + void *(*valDup)(void *privdata, const void *obj); + int (*keyCompare)(void *privdata, const void *key1, const void *key2); + void (*keyDestructor)(void *privdata, void *key); + void (*valDestructor)(void *privdata, void *obj); +} Jim_HashTableType; + +typedef struct Jim_HashTable { + Jim_HashEntry **table; + const Jim_HashTableType *type; + unsigned int size; + unsigned int sizemask; + unsigned int used; + unsigned int collisions; + void *privdata; +} Jim_HashTable; + +typedef struct Jim_HashTableIterator { + Jim_HashTable *ht; + int index; + Jim_HashEntry *entry, *nextEntry; +} Jim_HashTableIterator; + +/* This is the initial size of every hash table */ +#define JIM_HT_INITIAL_SIZE 16 + +/* ------------------------------- Macros ------------------------------------*/ +#define Jim_FreeEntryVal(ht, entry) \ + if ((ht)->type->valDestructor) \ + (ht)->type->valDestructor((ht)->privdata, (entry)->u.val) + +#define Jim_SetHashVal(ht, entry, _val_) do { \ + if ((ht)->type->valDup) \ + entry->u.val = (ht)->type->valDup((ht)->privdata, _val_); \ + else \ + entry->u.val = (_val_); \ +} while(0) + +#define Jim_FreeEntryKey(ht, entry) \ + if ((ht)->type->keyDestructor) \ + (ht)->type->keyDestructor((ht)->privdata, (entry)->key) + +#define Jim_SetHashKey(ht, entry, _key_) do { \ + if ((ht)->type->keyDup) \ + entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \ + else \ + entry->key = (void *)(_key_); \ +} while(0) + +#define Jim_CompareHashKeys(ht, key1, key2) \ + (((ht)->type->keyCompare) ? \ + (ht)->type->keyCompare((ht)->privdata, key1, key2) : \ + (key1) == (key2)) + +#define Jim_HashKey(ht, key) (ht)->type->hashFunction(key) + +#define Jim_GetHashEntryKey(he) ((he)->key) +#define Jim_GetHashEntryVal(he) ((he)->val) +#define Jim_GetHashTableCollisions(ht) ((ht)->collisions) +#define Jim_GetHashTableSize(ht) ((ht)->size) +#define Jim_GetHashTableUsed(ht) ((ht)->used) + +/* ----------------------------------------------------------------------------- + * Jim_Obj structure + * ---------------------------------------------------------------------------*/ + +/* ----------------------------------------------------------------------------- + * Jim object. This is mostly the same as Tcl_Obj itself, + * with the addition of the 'prev' and 'next' pointers. + * In Jim all the objects are stored into a linked list for GC purposes, + * so that it's possible to access every object living in a given interpreter + * sequentially. When an object is freed, it's moved into a different + * linked list, used as object pool. + * + * The refcount of a freed object is always -1. + * ---------------------------------------------------------------------------*/ +typedef struct Jim_Obj { + char *bytes; /* string representation buffer. NULL = no string repr. */ + const struct Jim_ObjType *typePtr; /* object type. */ + int refCount; /* reference count */ + int length; /* number of bytes in 'bytes', not including the null term. */ + /* Internal representation union */ + union { + /* integer number type */ + jim_wide wideValue; + /* generic integer value (e.g. index, return code) */ + int intValue; + /* double number type */ + double doubleValue; + /* Generic pointer */ + void *ptr; + /* Generic two pointers value */ + struct { + void *ptr1; + void *ptr2; + } twoPtrValue; + /* Variable object */ + struct { + unsigned long callFrameId; /* for caching */ + struct Jim_Var *varPtr; + int global; /* If the variable name is globally scoped with :: */ + } varValue; + /* Command object */ + struct { + unsigned long procEpoch; /* for caching */ + struct Jim_Obj *nsObj; + struct Jim_Cmd *cmdPtr; + } cmdValue; + /* List object */ + struct { + struct Jim_Obj **ele; /* Elements vector */ + int len; /* Length */ + int maxLen; /* Allocated 'ele' length */ + } listValue; + /* String type */ + struct { + int maxLength; + int charLength; /* utf-8 char length. -1 if unknown */ + } strValue; + /* Reference type */ + struct { + unsigned long id; + struct Jim_Reference *refPtr; + } refValue; + /* Source type */ + struct { + struct Jim_Obj *fileNameObj; + int lineNumber; + } sourceValue; + /* Dict substitution type */ + struct { + struct Jim_Obj *varNameObjPtr; + struct Jim_Obj *indexObjPtr; + } dictSubstValue; + /* Regular expression pattern */ + struct { + unsigned flags; + void *compre; /* really an allocated (regex_t *) */ + } regexpValue; + struct { + int line; + int argc; + } scriptLineValue; + } internalRep; + /* This are 8 or 16 bytes more for every object + * but this is required for efficient garbage collection + * of Jim references. */ + struct Jim_Obj *prevObjPtr; /* pointer to the prev object. */ + struct Jim_Obj *nextObjPtr; /* pointer to the next object. */ +} Jim_Obj; + +/* Jim_Obj related macros */ +#define Jim_IncrRefCount(objPtr) \ + ++(objPtr)->refCount +#define Jim_DecrRefCount(interp, objPtr) \ + if (--(objPtr)->refCount <= 0) Jim_FreeObj(interp, objPtr) +#define Jim_IsShared(objPtr) \ + ((objPtr)->refCount > 1) + +/* This macro is used when we allocate a new object using + * Jim_New...Obj(), but for some error we need to destroy it. + * Instead to use Jim_IncrRefCount() + Jim_DecrRefCount() we + * can just call Jim_FreeNewObj. To call Jim_Free directly + * seems too raw, the object handling may change and we want + * that Jim_FreeNewObj() can be called only against objects + * that are belived to have refcount == 0. */ +#define Jim_FreeNewObj Jim_FreeObj + +/* Free the internal representation of the object. */ +#define Jim_FreeIntRep(i,o) \ + if ((o)->typePtr && (o)->typePtr->freeIntRepProc) \ + (o)->typePtr->freeIntRepProc(i, o) + +/* Get the internal representation pointer */ +#define Jim_GetIntRepPtr(o) (o)->internalRep.ptr + +/* Set the internal representation pointer */ +#define Jim_SetIntRepPtr(o, p) \ + (o)->internalRep.ptr = (p) + +/* The object type structure. + * There are four methods. + * + * - FreeIntRep is used to free the internal representation of the object. + * Can be NULL if there is nothing to free. + * - DupIntRep is used to duplicate the internal representation of the object. + * If NULL, when an object is duplicated, the internalRep union is + * directly copied from an object to another. + * Note that it's up to the caller to free the old internal repr of the + * object before to call the Dup method. + * - UpdateString is used to create the string from the internal repr. + * - setFromAny is used to convert the current object into one of this type. + */ + +struct Jim_Interp; + +typedef void (Jim_FreeInternalRepProc)(struct Jim_Interp *interp, + struct Jim_Obj *objPtr); +typedef void (Jim_DupInternalRepProc)(struct Jim_Interp *interp, + struct Jim_Obj *srcPtr, Jim_Obj *dupPtr); +typedef void (Jim_UpdateStringProc)(struct Jim_Obj *objPtr); + +typedef struct Jim_ObjType { + const char *name; /* The name of the type. */ + Jim_FreeInternalRepProc *freeIntRepProc; + Jim_DupInternalRepProc *dupIntRepProc; + Jim_UpdateStringProc *updateStringProc; + int flags; +} Jim_ObjType; + +/* Jim_ObjType flags */ +#define JIM_TYPE_NONE 0 /* No flags */ +#define JIM_TYPE_REFERENCES 1 /* The object may contain referneces. */ + +/* Starting from 1 << 20 flags are reserved for private uses of + * different calls. This way the same 'flags' argument may be used + * to pass both global flags and private flags. */ +#define JIM_PRIV_FLAG_SHIFT 20 + +/* ----------------------------------------------------------------------------- + * Call frame, vars, commands structures + * ---------------------------------------------------------------------------*/ + +/* Call frame */ +typedef struct Jim_CallFrame { + unsigned long id; /* Call Frame ID. Used for caching. */ + int level; /* Level of this call frame. 0 = global */ + struct Jim_HashTable vars; /* Where local vars are stored */ + struct Jim_HashTable *staticVars; /* pointer to procedure static vars */ + struct Jim_CallFrame *parent; /* The parent callframe */ + Jim_Obj *const *argv; /* object vector of the current procedure call. */ + int argc; /* number of args of the current procedure call. */ + Jim_Obj *procArgsObjPtr; /* arglist object of the running procedure */ + Jim_Obj *procBodyObjPtr; /* body object of the running procedure */ + struct Jim_CallFrame *next; /* Callframes are in a linked list */ + Jim_Obj *nsObj; /* Namespace for this proc call frame */ + Jim_Obj *fileNameObj; /* file and line of caller of this proc (if available) */ + int line; + Jim_Stack *localCommands; /* commands to be destroyed when the call frame is destroyed */ +} Jim_CallFrame; + +/* The var structure. It just holds the pointer of the referenced + * object. If linkFramePtr is not NULL the variable is a link + * to a variable of name store on objPtr living on the given callframe + * (this happens when the [global] or [upvar] command is used). + * The interp in order to always know how to free the Jim_Obj associated + * with a given variable because In Jim objects memory managment is + * bound to interpreters. */ +typedef struct Jim_Var { + Jim_Obj *objPtr; + struct Jim_CallFrame *linkFramePtr; +} Jim_Var; + +/* The cmd structure. */ +typedef int (*Jim_CmdProc)(struct Jim_Interp *interp, int argc, + Jim_Obj *const *argv); +typedef void (*Jim_DelCmdProc)(struct Jim_Interp *interp, void *privData); + + + +/* A command is implemented in C if funcPtr is != NULL, otherwise + * it's a Tcl procedure with the arglist and body represented by the + * two objects referenced by arglistObjPtr and bodyoObjPtr. */ +typedef struct Jim_Cmd { + int inUse; /* Reference count */ + int isproc; /* Is this a procedure? */ + struct Jim_Cmd *prevCmd; /* Previous command defn if cmd created 'local' */ + union { + struct { + /* native (C) command */ + Jim_CmdProc cmdProc; /* The command implementation */ + Jim_DelCmdProc delProc; /* Called when the command is deleted if != NULL */ + void *privData; /* command-private data available via Jim_CmdPrivData() */ + } native; + struct { + /* Tcl procedure */ + Jim_Obj *argListObjPtr; + Jim_Obj *bodyObjPtr; + Jim_HashTable *staticVars; /* Static vars hash table. NULL if no statics. */ + int argListLen; /* Length of argListObjPtr */ + int reqArity; /* Number of required parameters */ + int optArity; /* Number of optional parameters */ + int argsPos; /* Position of 'args', if specified, or -1 */ + int upcall; /* True if proc is currently in upcall */ + struct Jim_ProcArg { + Jim_Obj *nameObjPtr; /* Name of this arg */ + Jim_Obj *defaultObjPtr; /* Default value, (or rename for $args) */ + } *arglist; + Jim_Obj *nsObj; /* Namespace for this proc */ + } proc; + } u; +} Jim_Cmd; + +/* Pseudo Random Number Generator State structure */ +typedef struct Jim_PrngState { + unsigned char sbox[256]; + unsigned int i, j; +} Jim_PrngState; + +/* ----------------------------------------------------------------------------- + * Jim interpreter structure. + * Fields similar to the real Tcl interpreter structure have the same names. + * ---------------------------------------------------------------------------*/ +typedef struct Jim_Interp { + Jim_Obj *result; /* object returned by the last command called. */ + int errorLine; /* Error line where an error occurred. */ + Jim_Obj *errorFileNameObj; /* Error file where an error occurred. */ + int addStackTrace; /* > 0 If a level should be added to the stack trace */ + int maxCallFrameDepth; /* Used for infinite loop detection. */ + int maxEvalDepth; /* Used for infinite loop detection. */ + int evalDepth; /* Current eval depth */ + int returnCode; /* Completion code to return on JIM_RETURN. */ + int returnLevel; /* Current level of 'return -level' */ + int exitCode; /* Code to return to the OS on JIM_EXIT. */ + long id; /* Hold unique id for various purposes */ + int signal_level; /* A nesting level of catch -signal */ + jim_wide sigmask; /* Bit mask of caught signals, or 0 if none */ + int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask); /* Set a result for the sigmask */ + Jim_CallFrame *framePtr; /* Pointer to the current call frame */ + Jim_CallFrame *topFramePtr; /* toplevel/global frame pointer. */ + struct Jim_HashTable commands; /* Commands hash table */ + unsigned long procEpoch; /* Incremented every time the result + of procedures names lookup caching + may no longer be valid. */ + unsigned long callFrameEpoch; /* Incremented every time a new + callframe is created. This id is used for the + 'ID' field contained in the Jim_CallFrame + structure. */ + int local; /* If 'local' is in effect, newly defined procs keep a reference to the old defn */ + Jim_Obj *liveList; /* Linked list of all the live objects. */ + Jim_Obj *freeList; /* Linked list of all the unused objects. */ + Jim_Obj *currentScriptObj; /* Script currently in execution. */ + Jim_Obj *nullScriptObj; /* script representation of an empty string */ + Jim_Obj *emptyObj; /* Shared empty string object. */ + Jim_Obj *trueObj; /* Shared true int object. */ + Jim_Obj *falseObj; /* Shared false int object. */ + unsigned long referenceNextId; /* Next id for reference. */ + struct Jim_HashTable references; /* References hash table. */ + unsigned long lastCollectId; /* reference max Id of the last GC + execution. It's set to -1 while the collection + is running as sentinel to avoid to recursive + calls via the [collect] command inside + finalizers. */ + time_t lastCollectTime; /* unix time of the last GC execution */ + Jim_Obj *stackTrace; /* Stack trace object. */ + Jim_Obj *errorProc; /* Name of last procedure which returned an error */ + Jim_Obj *unknown; /* Unknown command cache */ + int unknown_called; /* The unknown command has been invoked */ + int errorFlag; /* Set if an error occurred during execution. */ + void *cmdPrivData; /* Used to pass the private data pointer to + a command. It is set to what the user specified + via Jim_CreateCommand(). */ + + struct Jim_CallFrame *freeFramesList; /* list of CallFrame structures. */ + struct Jim_HashTable assocData; /* per-interp storage for use by packages */ + Jim_PrngState *prngState; /* per interpreter Random Number Gen. state. */ + struct Jim_HashTable packages; /* Provided packages hash table */ + Jim_Stack *loadHandles; /* handles of loaded modules [load] */ +} Jim_Interp; + +/* Currently provided as macro that performs the increment. + * At some point may be a real function doing more work. + * The proc epoch is used in order to know when a command lookup + * cached can no longer considered valid. */ +#define Jim_InterpIncrProcEpoch(i) (i)->procEpoch++ +#define Jim_SetResultString(i,s,l) Jim_SetResult(i, Jim_NewStringObj(i,s,l)) +#define Jim_SetResultInt(i,intval) Jim_SetResult(i, Jim_NewIntObj(i,intval)) +/* Note: Using trueObj and falseObj here makes some things slower...*/ +#define Jim_SetResultBool(i,b) Jim_SetResultInt(i, b) +#define Jim_SetEmptyResult(i) Jim_SetResult(i, (i)->emptyObj) +#define Jim_GetResult(i) ((i)->result) +#define Jim_CmdPrivData(i) ((i)->cmdPrivData) + +/* Note that 'o' is expanded only one time inside this macro, + * so it's safe to use side effects. */ +#define Jim_SetResult(i,o) do { \ + Jim_Obj *_resultObjPtr_ = (o); \ + Jim_IncrRefCount(_resultObjPtr_); \ + Jim_DecrRefCount(i,(i)->result); \ + (i)->result = _resultObjPtr_; \ +} while(0) + +/* Use this for filehandles, etc. which need a unique id */ +#define Jim_GetId(i) (++(i)->id) + +/* Reference structure. The interpreter pointer is held within privdata member in HashTable */ +#define JIM_REFERENCE_TAGLEN 7 /* The tag is fixed-length, because the reference + string representation must be fixed length. */ +typedef struct Jim_Reference { + Jim_Obj *objPtr; + Jim_Obj *finalizerCmdNamePtr; + char tag[JIM_REFERENCE_TAGLEN+1]; +} Jim_Reference; + +/* ----------------------------------------------------------------------------- + * Exported API prototypes. + * ---------------------------------------------------------------------------*/ + +/* Macros that are common for extensions and core. */ +#define Jim_NewEmptyStringObj(i) Jim_NewStringObj(i, "", 0) + +/* The core includes real prototypes, extensions instead + * include a global function pointer for every function exported. + * Once the extension calls Jim_InitExtension(), the global + * functon pointers are set to the value of the STUB table + * contained in the Jim_Interp structure. + * + * This makes Jim able to load extensions even if it is statically + * linked itself, and to load extensions compiled with different + * versions of Jim (as long as the API is still compatible.) */ + +/* Macros are common for core and extensions */ +#define Jim_FreeHashTableIterator(iter) Jim_Free(iter) + +#define JIM_EXPORT + +/* Memory allocation */ +JIM_EXPORT void *Jim_Alloc (int size); +JIM_EXPORT void *Jim_Realloc(void *ptr, int size); +JIM_EXPORT void Jim_Free (void *ptr); +JIM_EXPORT char * Jim_StrDup (const char *s); +JIM_EXPORT char *Jim_StrDupLen(const char *s, int l); + +/* environment */ +JIM_EXPORT char **Jim_GetEnviron(void); +JIM_EXPORT void Jim_SetEnviron(char **env); + +/* evaluation */ +JIM_EXPORT int Jim_Eval(Jim_Interp *interp, const char *script); +/* in C code, you can do this and get better error messages */ +/* Jim_EvalSource( interp, __FILE__, __LINE__ , "some tcl commands"); */ +JIM_EXPORT int Jim_EvalSource(Jim_Interp *interp, const char *filename, int lineno, const char *script); +/* Backwards compatibility */ +#define Jim_Eval_Named(I, S, F, L) Jim_EvalSource((I), (F), (L), (S)) + +JIM_EXPORT int Jim_EvalGlobal(Jim_Interp *interp, const char *script); +JIM_EXPORT int Jim_EvalFile(Jim_Interp *interp, const char *filename); +JIM_EXPORT int Jim_EvalFileGlobal(Jim_Interp *interp, const char *filename); +JIM_EXPORT int Jim_EvalObj (Jim_Interp *interp, Jim_Obj *scriptObjPtr); +JIM_EXPORT int Jim_EvalObjVector (Jim_Interp *interp, int objc, + Jim_Obj *const *objv); +JIM_EXPORT int Jim_EvalObjList(Jim_Interp *interp, Jim_Obj *listObj); +JIM_EXPORT int Jim_EvalObjPrefix(Jim_Interp *interp, Jim_Obj *prefix, + int objc, Jim_Obj *const *objv); +#define Jim_EvalPrefix(i, p, oc, ov) Jim_EvalObjPrefix((i), Jim_NewStringObj((i), (p), -1), (oc), (ov)) +JIM_EXPORT int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj); +JIM_EXPORT int Jim_SubstObj (Jim_Interp *interp, Jim_Obj *substObjPtr, + Jim_Obj **resObjPtrPtr, int flags); + +/* stack */ +JIM_EXPORT void Jim_InitStack(Jim_Stack *stack); +JIM_EXPORT void Jim_FreeStack(Jim_Stack *stack); +JIM_EXPORT int Jim_StackLen(Jim_Stack *stack); +JIM_EXPORT void Jim_StackPush(Jim_Stack *stack, void *element); +JIM_EXPORT void * Jim_StackPop(Jim_Stack *stack); +JIM_EXPORT void * Jim_StackPeek(Jim_Stack *stack); +JIM_EXPORT void Jim_FreeStackElements(Jim_Stack *stack, void (*freeFunc)(void *ptr)); + +/* hash table */ +JIM_EXPORT int Jim_InitHashTable (Jim_HashTable *ht, + const Jim_HashTableType *type, void *privdata); +JIM_EXPORT void Jim_ExpandHashTable (Jim_HashTable *ht, + unsigned int size); +JIM_EXPORT int Jim_AddHashEntry (Jim_HashTable *ht, const void *key, + void *val); +JIM_EXPORT int Jim_ReplaceHashEntry (Jim_HashTable *ht, + const void *key, void *val); +JIM_EXPORT int Jim_DeleteHashEntry (Jim_HashTable *ht, + const void *key); +JIM_EXPORT int Jim_FreeHashTable (Jim_HashTable *ht); +JIM_EXPORT Jim_HashEntry * Jim_FindHashEntry (Jim_HashTable *ht, + const void *key); +JIM_EXPORT void Jim_ResizeHashTable (Jim_HashTable *ht); +JIM_EXPORT Jim_HashTableIterator *Jim_GetHashTableIterator + (Jim_HashTable *ht); +JIM_EXPORT Jim_HashEntry * Jim_NextHashEntry + (Jim_HashTableIterator *iter); + +/* objects */ +JIM_EXPORT Jim_Obj * Jim_NewObj (Jim_Interp *interp); +JIM_EXPORT void Jim_FreeObj (Jim_Interp *interp, Jim_Obj *objPtr); +JIM_EXPORT void Jim_InvalidateStringRep (Jim_Obj *objPtr); +JIM_EXPORT void Jim_InitStringRep (Jim_Obj *objPtr, const char *bytes, + int length); +JIM_EXPORT Jim_Obj * Jim_DuplicateObj (Jim_Interp *interp, + Jim_Obj *objPtr); +JIM_EXPORT const char * Jim_GetString(Jim_Obj *objPtr, + int *lenPtr); +JIM_EXPORT const char *Jim_String(Jim_Obj *objPtr); +JIM_EXPORT int Jim_Length(Jim_Obj *objPtr); + +/* string object */ +JIM_EXPORT Jim_Obj * Jim_NewStringObj (Jim_Interp *interp, + const char *s, int len); +JIM_EXPORT Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, + const char *s, int charlen); +JIM_EXPORT Jim_Obj * Jim_NewStringObjNoAlloc (Jim_Interp *interp, + char *s, int len); +JIM_EXPORT void Jim_AppendString (Jim_Interp *interp, Jim_Obj *objPtr, + const char *str, int len); +JIM_EXPORT void Jim_AppendObj (Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *appendObjPtr); +JIM_EXPORT void Jim_AppendStrings (Jim_Interp *interp, + Jim_Obj *objPtr, ...); +JIM_EXPORT int Jim_StringEqObj(Jim_Obj *aObjPtr, Jim_Obj *bObjPtr); +JIM_EXPORT int Jim_StringMatchObj (Jim_Interp *interp, Jim_Obj *patternObjPtr, + Jim_Obj *objPtr, int nocase); +JIM_EXPORT Jim_Obj * Jim_StringRangeObj (Jim_Interp *interp, + Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, + Jim_Obj *lastObjPtr); +JIM_EXPORT Jim_Obj * Jim_FormatString (Jim_Interp *interp, + Jim_Obj *fmtObjPtr, int objc, Jim_Obj *const *objv); +JIM_EXPORT Jim_Obj * Jim_ScanString (Jim_Interp *interp, Jim_Obj *strObjPtr, + Jim_Obj *fmtObjPtr, int flags); +JIM_EXPORT int Jim_CompareStringImmediate (Jim_Interp *interp, + Jim_Obj *objPtr, const char *str); +JIM_EXPORT int Jim_StringCompareObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, + Jim_Obj *secondObjPtr, int nocase); +JIM_EXPORT int Jim_StringCompareLenObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, + Jim_Obj *secondObjPtr, int nocase); +JIM_EXPORT int Jim_Utf8Length(Jim_Interp *interp, Jim_Obj *objPtr); + +/* reference object */ +JIM_EXPORT Jim_Obj * Jim_NewReference (Jim_Interp *interp, + Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr); +JIM_EXPORT Jim_Reference * Jim_GetReference (Jim_Interp *interp, + Jim_Obj *objPtr); +JIM_EXPORT int Jim_SetFinalizer (Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *cmdNamePtr); +JIM_EXPORT int Jim_GetFinalizer (Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj **cmdNamePtrPtr); + +/* interpreter */ +JIM_EXPORT Jim_Interp * Jim_CreateInterp (void); +JIM_EXPORT void Jim_FreeInterp (Jim_Interp *i); +JIM_EXPORT int Jim_GetExitCode (Jim_Interp *interp); +JIM_EXPORT const char *Jim_ReturnCode(int code); +JIM_EXPORT void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...); + +/* commands */ +JIM_EXPORT void Jim_RegisterCoreCommands (Jim_Interp *interp); +JIM_EXPORT int Jim_CreateCommand (Jim_Interp *interp, + const char *cmdName, Jim_CmdProc cmdProc, void *privData, + Jim_DelCmdProc delProc); +JIM_EXPORT int Jim_DeleteCommand (Jim_Interp *interp, + const char *cmdName); +JIM_EXPORT int Jim_RenameCommand (Jim_Interp *interp, + const char *oldName, const char *newName); +JIM_EXPORT Jim_Cmd * Jim_GetCommand (Jim_Interp *interp, + Jim_Obj *objPtr, int flags); +JIM_EXPORT int Jim_SetVariable (Jim_Interp *interp, + Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr); +JIM_EXPORT int Jim_SetVariableStr (Jim_Interp *interp, + const char *name, Jim_Obj *objPtr); +JIM_EXPORT int Jim_SetGlobalVariableStr (Jim_Interp *interp, + const char *name, Jim_Obj *objPtr); +JIM_EXPORT int Jim_SetVariableStrWithStr (Jim_Interp *interp, + const char *name, const char *val); +JIM_EXPORT int Jim_SetVariableLink (Jim_Interp *interp, + Jim_Obj *nameObjPtr, Jim_Obj *targetNameObjPtr, + Jim_CallFrame *targetCallFrame); +JIM_EXPORT int Jim_CreateNamespaceVariable(Jim_Interp *interp, + Jim_Obj *varNameObj, Jim_Obj *targetNameObj); +JIM_EXPORT int Jim_DiscardNamespaceVars(Jim_Interp *interp); +JIM_EXPORT Jim_Obj * Jim_GetVariable (Jim_Interp *interp, + Jim_Obj *nameObjPtr, int flags); +JIM_EXPORT Jim_Obj * Jim_GetGlobalVariable (Jim_Interp *interp, + Jim_Obj *nameObjPtr, int flags); +JIM_EXPORT Jim_Obj * Jim_GetVariableStr (Jim_Interp *interp, + const char *name, int flags); +JIM_EXPORT Jim_Obj * Jim_GetGlobalVariableStr (Jim_Interp *interp, + const char *name, int flags); +JIM_EXPORT int Jim_UnsetVariable (Jim_Interp *interp, + Jim_Obj *nameObjPtr, int flags); + +/* call frame */ +JIM_EXPORT Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, + Jim_Obj *levelObjPtr); + +/* garbage collection */ +JIM_EXPORT int Jim_Collect (Jim_Interp *interp); +JIM_EXPORT void Jim_CollectIfNeeded (Jim_Interp *interp); + +/* index object */ +JIM_EXPORT int Jim_GetIndex (Jim_Interp *interp, Jim_Obj *objPtr, + int *indexPtr); + +/* list object */ +JIM_EXPORT Jim_Obj * Jim_NewListObj (Jim_Interp *interp, + Jim_Obj *const *elements, int len); +JIM_EXPORT void Jim_ListInsertElements (Jim_Interp *interp, + Jim_Obj *listPtr, int listindex, int objc, Jim_Obj *const *objVec); +JIM_EXPORT void Jim_ListAppendElement (Jim_Interp *interp, + Jim_Obj *listPtr, Jim_Obj *objPtr); +JIM_EXPORT void Jim_ListAppendList (Jim_Interp *interp, + Jim_Obj *listPtr, Jim_Obj *appendListPtr); +JIM_EXPORT int Jim_ListLength (Jim_Interp *interp, Jim_Obj *objPtr); +JIM_EXPORT int Jim_ListIndex (Jim_Interp *interp, Jim_Obj *listPrt, + int listindex, Jim_Obj **objPtrPtr, int seterr); +JIM_EXPORT Jim_Obj *Jim_ListGetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx); +JIM_EXPORT int Jim_SetListIndex (Jim_Interp *interp, + Jim_Obj *varNamePtr, Jim_Obj *const *indexv, int indexc, + Jim_Obj *newObjPtr); +JIM_EXPORT Jim_Obj * Jim_ConcatObj (Jim_Interp *interp, int objc, + Jim_Obj *const *objv); +JIM_EXPORT Jim_Obj *Jim_ListJoin(Jim_Interp *interp, + Jim_Obj *listObjPtr, const char *joinStr, int joinStrLen); + +/* dict object */ +JIM_EXPORT Jim_Obj * Jim_NewDictObj (Jim_Interp *interp, + Jim_Obj *const *elements, int len); +JIM_EXPORT int Jim_DictKey (Jim_Interp *interp, Jim_Obj *dictPtr, + Jim_Obj *keyPtr, Jim_Obj **objPtrPtr, int flags); +JIM_EXPORT int Jim_DictKeysVector (Jim_Interp *interp, + Jim_Obj *dictPtr, Jim_Obj *const *keyv, int keyc, + Jim_Obj **objPtrPtr, int flags); +JIM_EXPORT int Jim_SetDictKeysVector (Jim_Interp *interp, + Jim_Obj *varNamePtr, Jim_Obj *const *keyv, int keyc, + Jim_Obj *newObjPtr, int flags); +JIM_EXPORT int Jim_DictPairs(Jim_Interp *interp, + Jim_Obj *dictPtr, Jim_Obj ***objPtrPtr, int *len); +JIM_EXPORT int Jim_DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr); +JIM_EXPORT int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj); +JIM_EXPORT int Jim_DictValues(Jim_Interp *interp, Jim_Obj *dictObjPtr, Jim_Obj *patternObjPtr); +JIM_EXPORT int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr); + +/* return code object */ +JIM_EXPORT int Jim_GetReturnCode (Jim_Interp *interp, Jim_Obj *objPtr, + int *intPtr); + +/* expression object */ +JIM_EXPORT int Jim_EvalExpression (Jim_Interp *interp, + Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr); +JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp, + Jim_Obj *exprObjPtr, int *boolPtr); + +/* integer object */ +JIM_EXPORT int Jim_GetWide (Jim_Interp *interp, Jim_Obj *objPtr, + jim_wide *widePtr); +JIM_EXPORT int Jim_GetLong (Jim_Interp *interp, Jim_Obj *objPtr, + long *longPtr); +#define Jim_NewWideObj Jim_NewIntObj +JIM_EXPORT Jim_Obj * Jim_NewIntObj (Jim_Interp *interp, + jim_wide wideValue); + +/* double object */ +JIM_EXPORT int Jim_GetDouble(Jim_Interp *interp, Jim_Obj *objPtr, + double *doublePtr); +JIM_EXPORT void Jim_SetDouble(Jim_Interp *interp, Jim_Obj *objPtr, + double doubleValue); +JIM_EXPORT Jim_Obj * Jim_NewDoubleObj(Jim_Interp *interp, double doubleValue); + +/* shared strings */ +JIM_EXPORT const char * Jim_GetSharedString (Jim_Interp *interp, + const char *str); +JIM_EXPORT void Jim_ReleaseSharedString (Jim_Interp *interp, + const char *str); + +/* commands utilities */ +JIM_EXPORT void Jim_WrongNumArgs (Jim_Interp *interp, int argc, + Jim_Obj *const *argv, const char *msg); +JIM_EXPORT int Jim_GetEnum (Jim_Interp *interp, Jim_Obj *objPtr, + const char * const *tablePtr, int *indexPtr, const char *name, int flags); +JIM_EXPORT int Jim_ScriptIsComplete (const char *s, int len, + char *stateCharPtr); +/** + * Find a matching name in the array of the given length. + * + * NULL entries are ignored. + * + * Returns the matching index if found, or -1 if not. + */ +JIM_EXPORT int Jim_FindByName(const char *name, const char * const array[], size_t len); + +/* package utilities */ +typedef void (Jim_InterpDeleteProc)(Jim_Interp *interp, void *data); +JIM_EXPORT void * Jim_GetAssocData(Jim_Interp *interp, const char *key); +JIM_EXPORT int Jim_SetAssocData(Jim_Interp *interp, const char *key, + Jim_InterpDeleteProc *delProc, void *data); +JIM_EXPORT int Jim_DeleteAssocData(Jim_Interp *interp, const char *key); + +/* Packages C API */ +/* jim-package.c */ +JIM_EXPORT int Jim_PackageProvide (Jim_Interp *interp, + const char *name, const char *ver, int flags); +JIM_EXPORT int Jim_PackageRequire (Jim_Interp *interp, + const char *name, int flags); + +/* error messages */ +JIM_EXPORT void Jim_MakeErrorMessage (Jim_Interp *interp); + +/* interactive mode */ +JIM_EXPORT int Jim_InteractivePrompt (Jim_Interp *interp); +JIM_EXPORT void Jim_HistoryLoad(const char *filename); +JIM_EXPORT void Jim_HistorySave(const char *filename); +JIM_EXPORT char *Jim_HistoryGetline(const char *prompt); +JIM_EXPORT void Jim_HistoryAdd(const char *line); +JIM_EXPORT void Jim_HistoryShow(void); + +/* Misc */ +JIM_EXPORT int Jim_InitStaticExtensions(Jim_Interp *interp); +JIM_EXPORT int Jim_StringToWide(const char *str, jim_wide *widePtr, int base); + +/* jim-load.c */ +JIM_EXPORT int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName); +JIM_EXPORT void Jim_FreeLoadHandles(Jim_Interp *interp); + +/* jim-aio.c */ +JIM_EXPORT FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command); + + +/* type inspection - avoid where possible */ +JIM_EXPORT int Jim_IsDict(Jim_Obj *objPtr); +JIM_EXPORT int Jim_IsList(Jim_Obj *objPtr); + +#ifdef __cplusplus +} +#endif + +#endif /* __JIM__H */ + +/* + * Local Variables: *** + * c-basic-offset: 4 *** + * tab-width: 4 *** + * End: *** + */ diff --git a/debuggers/openocd/jimtcl/jim_tcl.txt b/debuggers/openocd/jimtcl/jim_tcl.txt new file mode 100644 index 00000000..16d7891a --- /dev/null +++ b/debuggers/openocd/jimtcl/jim_tcl.txt @@ -0,0 +1,5028 @@ +Jim Tcl(n) +========== + +NAME +---- +Jim Tcl v0.74 - reference manual for the Jim Tcl scripting language + +SYNOPSIS +-------- + + cc -ljim + +or + + jimsh [] + jimsh -e '' + jimsh --version + + +.Quick Index +* <> +* <> +* <> +* <> + +INTRODUCTION +------------ +Jim Tcl is a small footprint reimplementation of the Tcl scripting language. +The core language engine is compatible with Tcl 8.5+, while implementing +a significant subset of the Tcl 8.6 command set, plus additional features +available only in Jim Tcl. + +Some notable differences with Tcl 8.5/8.6 are: + +1. Object-based I/O (aio), but with a Tcl-compatibility layer +2. I/O: Support for sockets and pipes including udp, unix domain sockets and IPv6 +3. Integers are 64bit +4. Support for references (`ref`/`getref`/`setref`) and garbage collection +5. Builtin dictionary type (`dict`) with some limitations compared to Tcl 8.6 +6. `env` command to access environment variables +7. Operating system features: `os.fork`, `os.wait`, `os.uptime`, `signal`, `alarm`, `sleep` +8. Much better error reporting. `info stacktrace` as a replacement for '$errorInfo', '$errorCode' +9. Support for "static" variables in procedures +10. Threads and coroutines are not supported +11. Command and variable traces are not supported +12. Built-in command line editing +13. Expression shorthand syntax: +$(...)+ +14. Modular build allows many features to be omitted or built as dynamic, loadable modules +15. Highly suitable for use in an embedded environment +16. Support for UDP, IPv6, Unix-Domain sockets in addition to TCP sockets + +RECENT CHANGES +-------------- + +Changes between 0.73 and 0.74 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +1. Numbers with leading zeros are treated as decimal, not octal + +Changes between 0.72 and 0.73 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +1. Built-in regexp now support non-capturing parentheses: (?:...) +2. Add `string replace` +3. Add `string totitle` +4. Add `info statics` +5. Add +build-jim-ext+ for easy separate building of loadable modules (extensions) +6. `local` now works with any command, not just procs +7. Add `info alias` to access the target of an alias +8. UTF-8 encoding past the basic multilingual plane (BMP) is supported +9. Add `tcl::prefix` +10. Add `history` +11. Most extensions are now enabled by default +12. Add support for namespaces and the `namespace` command +13. Add `apply` + +Changes between 0.71 and 0.72 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +1. procs now allow 'args' and optional parameters in any position +2. Add Tcl-compatible expr functions, `rand()`, `srand()` and `pow()` +3. Add support for the '-force' option to `file delete` +4. Better diagnostics when `source` fails to load a script with a missing quote or bracket +5. New +tcl_platform(pathSeparator)+ +6. Add support settings the modification time with `file mtime` +7. `exec` is now fully supported on win32 (mingw32) +8. `file join`, `pwd`, `glob` etc. now work for mingw32 +9. Line editing is now supported for the win32 console (mingw32) +10. Add `aio listen` command + +Changes between 0.70 and 0.71 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +1. Allow 'args' to be renamed in procs +2. Add +$(...)+ shorthand syntax for expressions +3. Add automatic reference variables in procs with +&var+ syntax +4. Support +jimsh --version+ +5. Additional variables in +tcl_platform()+ +6. `local` procs now push existing commands and `upcall` can call them +7. Add `loop` command (TclX compatible) +8. Add `aio buffering` command +9. `info complete` can now return the missing character +10. `binary format` and `binary scan` are now (optionally) supported +11. Add `string byterange` +12. Built-in regexp now support non-greedy repetition (*?, +?, ??) + +TCL INTRODUCTION +----------------- +Tcl stands for 'tool command language' and is pronounced 'tickle.' +It is actually two things: a language and a library. + +First, Tcl is a simple textual language, intended primarily for +issuing commands to interactive programs such as text editors, +debuggers, illustrators, and shells. It has a simple syntax and is also +programmable, so Tcl users can write command procedures to provide more +powerful commands than those in the built-in set. + +Second, Tcl is a library package that can be embedded in application +programs. The Tcl library consists of a parser for the Tcl language, +routines to implement the Tcl built-in commands, and procedures that +allow each application to extend Tcl with additional commands specific +to that application. The application program generates Tcl commands and +passes them to the Tcl parser for execution. Commands may be generated +by reading characters from an input source, or by associating command +strings with elements of the application's user interface, such as menu +entries, buttons, or keystrokes. + +When the Tcl library receives commands it parses them into component +fields and executes built-in commands directly. For commands implemented +by the application, Tcl calls back to the application to execute the +commands. In many cases commands will invoke recursive invocations of the +Tcl interpreter by passing in additional strings to execute (procedures, +looping commands, and conditional commands all work in this way). + +An application program gains three advantages by using Tcl for its command +language. First, Tcl provides a standard syntax: once users know Tcl, +they will be able to issue commands easily to any Tcl-based application. +Second, Tcl provides programmability. All a Tcl application needs +to do is to implement a few application-specific low-level commands. +Tcl provides many utility commands plus a general programming interface +for building up complex command procedures. By using Tcl, applications +need not re-implement these features. + +Third, Tcl can be used as a common language for communicating between +applications. Inter-application communication is not built into the +Tcl core described here, but various add-on libraries, such as the Tk +toolkit, allow applications to issue commands to each other. This makes +it possible for applications to work together in much more powerful ways +than was previously possible. + +Fourth, Jim Tcl includes a command processor, +jimsh+, which can be +used to run standalone Tcl scripts, or to run Tcl commands interactively. + +This manual page focuses primarily on the Tcl language. It describes +the language syntax and the built-in commands that will be available +in any application based on Tcl. The individual library procedures are +described in more detail in separate manual pages, one per procedure. + +JIMSH COMMAND INTERPRETER +------------------------- +A simple, but powerful command processor, +jimsh+, is part of Jim Tcl. +It may be invoked in interactive mode as: + + jimsh + +or to process the Tcl script in a file with: + + jimsh filename + +It may also be invoked to execute an immediate script with: + + jimsh -e "script" + +Interactive Mode +~~~~~~~~~~~~~~~~ +Interactive mode reads Tcl commands from standard input, evaluates +those commands and prints the results. + + $ jimsh + Welcome to Jim version 0.73, Copyright (c) 2005-8 Salvatore Sanfilippo + . info version + 0.73 + . lsort [info commands p*] + package parray pid popen proc puts pwd + . foreach i {a b c} { + {> puts $i + {> } + a + b + c + . bad + invalid command name "bad" + [error] . exit + $ + +If +jimsh+ is configured with line editing (it is by default) and a VT-100-compatible +terminal is detected, Emacs-style line editing commands are available, including: +arrow keys, +\^W+ to erase a word, +\^U+ to erase the line, +^R+ for reverse incremental search +in history. Additionally, the +h+ command may be used to display the command history. + +Command line history is automatically saved and loaded from +~/.jim_history+ + +In interactive mode, +jimsh+ automatically runs the script +~/.jimrc+ at startup +if it exists. + +INTERPRETERS +------------ +The central data structure in Tcl is an interpreter (C type 'Jim_Interp'). +An interpreter consists of a set of command bindings, a set of variable +values, and a few other miscellaneous pieces of state. Each Tcl command +is interpreted in the context of a particular interpreter. + +Some Tcl-based applications will maintain multiple interpreters +simultaneously, each associated with a different widget or portion of +the application. Interpreters are relatively lightweight structures. +They can be created and deleted quickly, so application programmers should +feel free to use multiple interpreters if that simplifies the application. + +DATA TYPES +---------- +Tcl supports only one type of data: strings. All commands, all arguments +to commands, all command results, and all variable values are strings. + +Where commands require numeric arguments or return numeric results, +the arguments and results are passed as strings. Many commands expect +their string arguments to have certain formats, but this interpretation +is up to the individual commands. For example, arguments often contain +Tcl command strings, which may get executed as part of the commands. +The easiest way to understand the Tcl interpreter is to remember that +everything is just an operation on a string. In many cases Tcl constructs +will look similar to more structured constructs from other languages. +However, the Tcl constructs are not structured at all; they are just +strings of characters, and this gives them a different behaviour than +the structures they may look like. + +Although the exact interpretation of a Tcl string depends on who is doing +the interpretation, there are three common forms that strings take: +commands, expressions, and lists. The major sections below discuss +these three forms in more detail. + +BASIC COMMAND SYNTAX +-------------------- +The Tcl language has syntactic similarities to both the Unix shells +and Lisp. However, the interpretation of commands is different +in Tcl than in either of those other two systems. +A Tcl command string consists of one or more commands separated +by newline characters or semi-colons. +Each command consists of a collection of fields separated by +white space (spaces or tabs). +The first field must be the name of a command, and the +additional fields, if any, are arguments that will be passed to +that command. For example, the command: + + set a 22 + +has three fields: the first, `set`, is the name of a Tcl command, and +the last two, 'a' and '22', will be passed as arguments to +the `set` command. The command name may refer either to a built-in +Tcl command, an application-specific command bound in with the library +procedure 'Jim_CreateCommand', or a command procedure defined with the +`proc` built-in command. + +Arguments are passed literally as text strings. Individual commands may +interpret those strings in any fashion they wish. The `set` command, +for example, will treat its first argument as the name of a variable +and its second argument as a string value to assign to that variable. +For other commands arguments may be interpreted as integers, lists, +file names, or Tcl commands. + +Command names should normally be typed completely (e.g. no abbreviations). +However, if the Tcl interpreter cannot locate a command it invokes a +special command named `unknown` which attempts to find or create the +command. + +For example, at many sites `unknown` will search through library +directories for the desired command and create it as a Tcl procedure if +it is found. The `unknown` command often provides automatic completion +of abbreviated commands, but usually only for commands that were typed +interactively. + +It's probably a bad idea to use abbreviations in command scripts and +other forms that will be re-used over time: changes to the command set +may cause abbreviations to become ambiguous, resulting in scripts that +no longer work. + +COMMENTS +-------- +If the first non-blank character in a command is +\#+, then everything +from the +#+ up through the next newline character is treated as +a comment and ignored. When comments are embedded inside nested +commands (e.g. fields enclosed in braces) they must have properly-matched +braces (this is necessary because when Tcl parses the top-level command +it doesn't yet know that the nested field will be used as a command so +it cannot process the nested comment character as a comment). + +GROUPING ARGUMENTS WITH DOUBLE-QUOTES +------------------------------------- +Normally each argument field ends at the next white space, but +double-quotes may be used to create arguments with embedded space. + +If an argument field begins with a double-quote, then the argument isn't +terminated by white space (including newlines) or a semi-colon (see below +for information on semi-colons); instead it ends at the next double-quote +character. The double-quotes are not included in the resulting argument. +For example, the command + + set a "This is a single argument" + +will pass two arguments to `set`: 'a' and 'This is a single argument'. + +Within double-quotes, command substitutions, variable substitutions, +and backslash substitutions still occur, as described below. If the +first character of a command field is not a quote, then quotes receive +no special interpretation in the parsing of that field. + +GROUPING ARGUMENTS WITH BRACES +------------------------------ +Curly braces may also be used for grouping arguments. They are similar +to quotes except for two differences. First, they nest; this makes them +easier to use for complicated arguments like nested Tcl command strings. +Second, the substitutions described below for commands, variables, and +backslashes do *not* occur in arguments enclosed in braces, so braces +can be used to prevent substitutions where they are undesirable. + +If an argument field begins with a left brace, then the argument ends +at the matching right brace. Tcl will strip off the outermost layer +of braces and pass the information between the braces to the command +without any further modification. For example, in the command + + set a {xyz a {b c d}} + +the `set` command will receive two arguments: 'a' +and 'xyz a {b c d}'. + +When braces or quotes are in effect, the matching brace or quote need +not be on the same line as the starting quote or brace; in this case +the newline will be included in the argument field along with any other +characters up to the matching brace or quote. For example, the `eval` +command takes one argument, which is a command string; `eval` invokes +the Tcl interpreter to execute the command string. The command + + eval { + set a 22 + set b 33 + } + +will assign the value '22' to 'a' and '33' to 'b'. + +If the first character of a command field is not a left +brace, then neither left nor right +braces in the field will be treated specially (except as part of +variable substitution; see below). + +COMMAND SUBSTITUTION WITH BRACKETS +---------------------------------- +If an open bracket occurs in a field of a command, then command +substitution occurs (except for fields enclosed in braces). All of the +text up to the matching close bracket is treated as a Tcl command and +executed immediately. Then the result of that command is substituted +for the bracketed text. For example, consider the command + + set a [set b] + +When the `set` command has only a single argument, it is the name of a +variable and `set` returns the contents of that variable. In this case, +if variable 'b' has the value 'foo', then the command above is equivalent +to the command + + set a foo + +Brackets can be used in more complex ways. For example, if the variable +'b' has the value 'foo' and the variable 'c' has the value 'gorp', +then the command + + set a xyz[set b].[set c] + +is equivalent to the command + + set a xyzfoo.gorp + + +A bracketed command may contain multiple commands separated by newlines +or semi-colons in the usual fashion. In this case the value of the last +command is used for substitution. For example, the command + + set a x[set b 22 + expr $b+2]x + +is equivalent to the command + + set a x24x + + +If a field is enclosed in braces then the brackets and the characters +between them are not interpreted specially; they are passed through to +the argument verbatim. + +VARIABLE SUBSTITUTION WITH $ +---------------------------- +The dollar sign (+$+) may be used as a special shorthand form for +substituting variable values. If +$+ appears in an argument that isn't +enclosed in braces then variable substitution will occur. The characters +after the +$+, up to the first character that isn't a number, letter, +or underscore, are taken as a variable name and the string value of that +variable is substituted for the name. + +For example, if variable 'foo' has the value 'test', then the command + + set a $foo.c + +is equivalent to the command + + set a test.c + +There are two special forms for variable substitution. If the next +character after the name of the variable is an open parenthesis, then +the variable is assumed to be an array name, and all of the characters +between the open parenthesis and the next close parenthesis are taken as +an index into the array. Command substitutions and variable substitutions +are performed on the information between the parentheses before it is +used as an index. + +For example, if the variable 'x' is an array with one element named +'first' and value '87' and another element named '14' and value 'more', +then the command + + set a xyz$x(first)zyx + +is equivalent to the command + + set a xyz87zyx + +If the variable 'index' has the value '14', then the command + + set a xyz$x($index)zyx + +is equivalent to the command + + set a xyzmorezyx + +For more information on arrays, see VARIABLES AND ARRAYS below. + +The second special form for variables occurs when the dollar sign is +followed by an open curly brace. In this case the variable name consists +of all the characters up to the next curly brace. + +Array references are not possible in this form: the name between braces +is assumed to refer to a scalar variable. For example, if variable +'foo' has the value 'test', then the command + + set a abc${foo}bar + +is equivalent to the command + + set a abctestbar + + +Variable substitution does not occur in arguments that are enclosed in +braces: the dollar sign and variable name are passed through to the +argument verbatim. + +The dollar sign abbreviation is simply a shorthand form. +$a+ is +completely equivalent to +[set a]+; it is provided as a convenience +to reduce typing. + +SEPARATING COMMANDS WITH SEMI-COLONS +------------------------------------ +Normally, each command occupies one line (the command is terminated by a +newline character). However, semi-colon (+;+) is treated as a command +separator character; multiple commands may be placed on one line by +separating them with a semi-colon. Semi-colons are not treated as +command separators if they appear within curly braces or double-quotes. + +BACKSLASH SUBSTITUTION +---------------------- +Backslashes may be used to insert non-printing characters into command +fields and also to insert special characters like braces and brackets +into fields without them being interpreted specially as described above. + +The backslash sequences understood by the Tcl interpreter are +listed below. In each case, the backslash +sequence is replaced by the given character: +[[BackslashSequences]] ++{backslash}b+:: + Backspace (0x8) + ++{backslash}f+:: + Form feed (0xc) + ++{backslash}n+:: + Newline (0xa) + ++{backslash}r+:: + Carriage-return (0xd). + ++{backslash}t+:: + Tab (0x9). + ++{backslash}v+:: + Vertical tab (0xb). + ++{backslash}{+:: + Left brace ({). + ++{backslash}}+:: + Right brace (}). + ++{backslash}[+:: + Open bracket ([). + ++{backslash}]+:: + Close bracket (]). + ++{backslash}$+:: + Dollar sign ($). + ++{backslash}+:: + Space ( ): doesn't terminate argument. + ++{backslash};+:: + Semi-colon: doesn't terminate command. + ++{backslash}"+:: + Double-quote. + ++{backslash}+:: + Nothing: this joins two lines together + into a single line. This backslash feature is unique in that + it will be applied even when the sequence occurs within braces. + ++{backslash}{backslash}+:: + Backslash ('{backslash}'). + ++{backslash}ddd+:: + The digits +'ddd'+ (one, two, or three of them) give the octal value of + the character. Note that Jim supports null characters in strings. + ++{backslash}unnnn+:: ++{backslash}u\{nnn\}+:: ++{backslash}Unnnnnnnn+:: + The UTF-8 encoding of the unicode codepoint represented by the hex digits, +'nnnn'+, is inserted. + The 'u' form allows for one to four hex digits. + The 'U' form allows for one to eight hex digits. + The 'u\{nnn\}' form allows for one to eight hex digits, but makes it easier to insert + characters UTF-8 characters which are followed by a hex digit. + +For example, in the command + + set a \{x\[\ yz\141 + +the second argument to `set` will be +{x[ yza+. + +If a backslash is followed by something other than one of the options +described above, then the backslash is transmitted to the argument +field without any special processing, and the Tcl scanner continues +normal processing with the next character. For example, in the +command + + set \*a \\\{foo + +The first argument to `set` will be +{backslash}*a+ and the second +argument will be +{backslash}{foo+. + +If an argument is enclosed in braces, then backslash sequences inside +the argument are parsed but no substitution occurs (except for +backslash-newline): the backslash +sequence is passed through to the argument as is, without making +any special interpretation of the characters in the backslash sequence. +In particular, backslashed braces are not counted in locating the +matching right brace that terminates the argument. +For example, in the +command + + set a {\{abc} + +the second argument to `set` will be +{backslash}{abc+. + +This backslash mechanism is not sufficient to generate absolutely +any argument structure; it only covers the +most common cases. To produce particularly complicated arguments +it is probably easiest to use the `format` command along with +command substitution. + +STRING AND LIST INDEX SPECIFICATIONS +------------------------------------ + +Many string and list commands take one or more 'index' parameters which +specify a position in the string relative to the start or end of the string/list. + +The index may be one of the following forms: + ++integer+:: + A simple integer, where '0' refers to the first element of the string + or list. + ++integer+integer+ or:: ++integer-integer+:: + The sum or difference of the two integers. e.g. +2+3+ refers to the 5th element. + This is useful when used with (e.g.) +$i+1+ rather than the more verbose + +[expr {$i+1\}]+ + ++end+:: + The last element of the string or list. + ++end-integer+:: + The 'nth-from-last' element of the string or list. + +COMMAND SUMMARY +--------------- +1. A command is just a string. +2. Within a string commands are separated by newlines or semi-colons + (unless the newline or semi-colon is within braces or brackets + or is backslashed). +3. A command consists of fields. The first field is the name of the command. + The other fields are strings that are passed to that command as arguments. +4. Fields are normally separated by white space. +5. Double-quotes allow white space and semi-colons to appear within + a single argument. + Command substitution, variable substitution, and backslash substitution + still occur inside quotes. +6. Braces defer interpretation of special characters. + If a field begins with a left brace, then it consists of everything + between the left brace and the matching right brace. The + braces themselves are not included in the argument. + No further processing is done on the information between the braces + except that backslash-newline sequences are eliminated. +7. If a field doesn't begin with a brace then backslash, + variable, and command substitution are done on the field. Only a + single level of processing is done: the results of one substitution + are not scanned again for further substitutions or any other + special treatment. Substitution can + occur on any field of a command, including the command name + as well as the arguments. +8. If the first non-blank character of a command is a +\#+, everything + from the +#+ up through the next newline is treated as a comment + and ignored. + +EXPRESSIONS +----------- +The second major interpretation applied to strings in Tcl is +as expressions. Several commands, such as `expr`, `for`, +and `if`, treat one or more of their arguments as expressions +and call the Tcl expression processors ('Jim_ExprLong', +'Jim_ExprBoolean', etc.) to evaluate them. + +The operators permitted in Tcl expressions are a subset of +the operators permitted in C expressions, and they have the +same meaning and precedence as the corresponding C operators. +Expressions almost always yield numeric results +(integer or floating-point values). +For example, the expression + + 8.2 + 6 + +evaluates to 14.2. + +Tcl expressions differ from C expressions in the way that +operands are specified, and in that Tcl expressions support +non-numeric operands and string comparisons. + +A Tcl expression consists of a combination of operands, operators, +and parentheses. + +White space may be used between the operands and operators and +parentheses; it is ignored by the expression processor. +Where possible, operands are interpreted as integer values. + +Integer values may be specified in decimal (the normal case) or in +hexadecimal (if the first two characters of the operand are '0x'). +Note that Jim Tcl does *not* treat numbers with leading zeros as octal. + +If an operand does not have one of the integer formats given +above, then it is treated as a floating-point number if that is +possible. Floating-point numbers may be specified in any of the +ways accepted by an ANSI-compliant C compiler (except that the +'f', 'F', 'l', and 'L' suffixes will not be permitted in +most installations). For example, all of the +following are valid floating-point numbers: 2.1, 3., 6e4, 7.91e+16. + +If no numeric interpretation is possible, then an operand is left +as a string (and only a limited set of operators may be applied to +it). + +1. Operands may be specified in any of the following ways: + +2. As a numeric value, either integer or floating-point. + +3. As a Tcl variable, using standard '$' notation. +The variable's value will be used as the operand. + +4. As a string enclosed in double-quotes. +The expression parser will perform backslash, variable, and +command substitutions on the information between the quotes, +and use the resulting value as the operand + +5. As a string enclosed in braces. +The characters between the open brace and matching close brace +will be used as the operand without any substitutions. + +6. As a Tcl command enclosed in brackets. +The command will be executed and its result will be used as +the operand. + +Where substitutions occur above (e.g. inside quoted strings), they +are performed by the expression processor. +However, an additional layer of substitution may already have +been performed by the command parser before the expression +processor was called. + +As discussed below, it is usually best to enclose expressions +in braces to prevent the command parser from performing substitutions +on the contents. + +For some examples of simple expressions, suppose the variable 'a' has +the value 3 and the variable 'b' has the value 6. Then the expression +on the left side of each of the lines below will evaluate to the value +on the right side of the line: + + $a + 3.1 6.1 + 2 + "$a.$b" 5.6 + 4*[llength "6 2"] 8 + {word one} < "word $a" 0 + +The valid operators are listed below, grouped in decreasing order +of precedence: +[[OperatorPrecedence]] ++int() double() round() abs(), rand(), srand()+:: + Unary functions (except rand() which takes no arguments) + * +'int()'+ converts the numeric argument to an integer by truncating down. + * +'double()'+ converts the numeric argument to floating point. + * +'round()'+ converts the numeric argument to the closest integer value. + * +'abs()'+ takes the absolute value of the numeric argument. + * +'rand()'+ takes the absolute value of the numeric argument. + * +'rand()'+ returns a pseudo-random floating-point value in the range (0,1). + * +'srand()'+ takes an integer argument to (re)seed the random number generator. Returns the first random number from that seed. + ++sin() cos() tan() asin() acos() atan() sinh() cosh() tanh() ceil() floor() exp() log() log10() sqrt()+:: + Unary math functions. + If Jim is compiled with math support, these functions are available. + ++- + ~ !+:: + Unary minus, unary plus, bit-wise NOT, logical NOT. None of these operands + may be applied to string operands, and bit-wise NOT may be + applied only to integers. + ++** pow(x,y)+:: + Power. e.g. 'x^y^'. If Jim is compiled with math support, supports doubles and + integers. Otherwise supports integers only. (Note that the math-function form + has the same highest precedence) + ++* / %+:: + Multiply, divide, remainder. None of these operands may be + applied to string operands, and remainder may be applied only + to integers. + +++ -+:: + Add and subtract. Valid for any numeric operands. + ++<< >> <<< >>>+:: + Left and right shift, left and right rotate. Valid for integer operands only. + ++< > \<= >=+:: + Boolean less, greater, less than or equal, and greater than or equal. + Each operator produces 1 if the condition is true, 0 otherwise. + These operators may be applied to strings as well as numeric operands, + in which case string comparison is used. + ++== !=+:: + Boolean equal and not equal. Each operator produces a zero/one result. + Valid for all operand types. *Note* that values will be converted to integers + if possible, then floating point types, and finally strings will be compared. + It is recommended that 'eq' and 'ne' should be used for string comparison. + ++eq ne+:: + String equal and not equal. Uses the string value directly without + attempting to convert to a number first. + ++in ni+:: + String in list and not in list. For 'in', result is 1 if the left operand (as a string) + is contained in the right operand (as a list), or 0 otherwise. The result for + +{$a ni $list}+ is equivalent to +{!($a in $list)}+. + ++&+:: + Bit-wise AND. Valid for integer operands only. + ++|+:: + Bit-wise OR. Valid for integer operands only. + ++^+:: + Bit-wise exclusive OR. Valid for integer operands only. + ++&&+:: + Logical AND. Produces a 1 result if both operands are non-zero, 0 otherwise. + Valid for numeric operands only (integers or floating-point). + ++||+:: + Logical OR. Produces a 0 result if both operands are zero, 1 otherwise. + Valid for numeric operands only (integers or floating-point). + ++x ? y : z+:: + If-then-else, as in C. If +'x'+ + evaluates to non-zero, then the result is the value of +'y'+. + Otherwise the result is the value of +'z'+. + The +'x'+ operand must have a numeric value, while +'y'+ and +'z'+ can + be of any type. + +See the C manual for more details on the results +produced by each operator. +All of the binary operators group left-to-right within the same +precedence level. For example, the expression + + 4*2 < 7 + +evaluates to 0. + +The +&&+, +||+, and +?:+ operators have 'lazy evaluation', just as +in C, which means that operands are not evaluated if they are not +needed to determine the outcome. For example, in + + $v ? [a] : [b] + +only one of +[a]+ or +[b]+ will actually be evaluated, +depending on the value of +$v+. + +All internal computations involving integers are done with the C +type 'long long' if available, or 'long' otherwise, and all internal +computations involving floating-point are done with the C type +'double'. + +When converting a string to floating-point, exponent overflow is +detected and results in a Tcl error. +For conversion to integer from string, detection of overflow depends +on the behaviour of some routines in the local C library, so it should +be regarded as unreliable. +In any case, overflow and underflow are generally not detected +reliably for intermediate results. + +Conversion among internal representations for integer, floating-point, +and string operands is done automatically as needed. +For arithmetic computations, integers are used until some +floating-point number is introduced, after which floating-point is used. +For example, + + 5 / 4 + +yields the result 1, while + + 5 / 4.0 + 5 / ( [string length "abcd"] + 0.0 ) + +both yield the result 1.25. + +String values may be used as operands of the comparison operators, +although the expression evaluator tries to do comparisons as integer +or floating-point when it can. +If one of the operands of a comparison is a string and the other +has a numeric value, the numeric operand is converted back to +a string using the C 'sprintf' format specifier +'%d' for integers and '%g' for floating-point values. +For example, the expressions + + "0x03" > "2" + "0y" < "0x12" + +both evaluate to 1. The first comparison is done using integer +comparison, and the second is done using string comparison after +the second operand is converted to the string '18'. + +In general it is safest to enclose an expression in braces when +entering it in a command: otherwise, if the expression contains +any white space then the Tcl interpreter will split it +among several arguments. For example, the command + + expr $a + $b + +results in three arguments being passed to `expr`: +$a+, +\+, and +$b+. In addition, if the expression isn't in braces +then the Tcl interpreter will perform variable and command substitution +immediately (it will happen in the command parser rather than in +the expression parser). In many cases the expression is being +passed to a command that will evaluate the expression later (or +even many times if, for example, the expression is to be used to +decide when to exit a loop). Usually the desired goal is to re-do +the variable or command substitutions each time the expression is +evaluated, rather than once and for all at the beginning. For example, +the command + + for {set i 1} $i<=10 {incr i} {...} ** WRONG ** + +is probably intended to iterate over all values of +i+ from 1 to 10. +After each iteration of the body of the loop, `for` will pass +its second argument to the expression evaluator to see whether or not +to continue processing. Unfortunately, in this case the value of +i+ +in the second argument will be substituted once and for all when the +`for` command is parsed. If +i+ was 0 before the `for` +command was invoked then the second argument of `for` will be +0\<=10+ +which will always evaluate to 1, even though +i+ eventually +becomes greater than 10. In the above case the loop will never +terminate. Instead, the expression should be placed in braces: + + for {set i 1} {$i<=10} {incr i} {...} ** RIGHT ** + +This causes the substitution of 'i' +to be delayed; it will be re-done each time the expression is +evaluated, which is the desired result. + +LISTS +----- +The third major way that strings are interpreted in Tcl is as lists. +A list is just a string with a list-like structure +consisting of fields separated by white space. For example, the +string + + Al Sue Anne John + +is a list with four elements or fields. +Lists have the same basic structure as command strings, except +that a newline character in a list is treated as a field separator +just like space or tab. Conventions for braces and quotes +and backslashes are the same for lists as for commands. For example, +the string + + a b\ c {d e {f g h}} + +is a list with three elements: +a+, +b c+, and +d e {f g h}+. + +Whenever an element is extracted from a list, the same rules about +braces and quotes and backslashes are applied as for commands. Thus in +the example above when the third element is extracted from the list, +the result is + + d e {f g h} + +(when the field was extracted, all that happened was to strip off +the outermost layer of braces). Command substitution and +variable substitution are never +made on a list (at least, not by the list-processing commands; the +list can always be passed to the Tcl interpreter for evaluation). + +The Tcl commands `concat`, `foreach`, `lappend`, `lindex`, `linsert`, +`list`, `llength`, `lrange`, `lreplace`, `lsearch`, and `lsort` allow +you to build lists, extract elements from them, search them, and perform +other list-related functions. + +Advanced list commands include `lrepeat`, `lreverse`, `lmap`, `lassign`, `lset`. + +LIST EXPANSION +-------------- + +A new addition to Tcl 8.5 is the ability to expand a list into separate +arguments. Support for this feature is also available in Jim. + +Consider the following attempt to exec a list: + + set cmd {ls -l} + exec $cmd + +This will attempt to exec the a command named "ls -l", which will clearly not +work. Typically eval and concat are required to solve this problem, however +it can be solved much more easily with +\{*\}+. + + exec {*}$cmd + +This will expand the following argument into individual elements and then evaluate +the resulting command. + +Note that the official Tcl syntax is +\{*\}+, however +\{expand\}+ is retained +for backward compatibility with experimental versions of this feature. + +REGULAR EXPRESSIONS +------------------- +Tcl provides two commands that support string matching using regular +expressions, `regexp` and `regsub`, as well as `switch -regexp` and +`lsearch -regexp`. + +Regular expressions may be implemented one of two ways. Either using the system's C library +POSIX regular expression support, or using the built-in regular expression engine. +The differences between these are described below. + +*NOTE* Tcl 7.x and 8.x use perl-style Advanced Regular Expressions (+ARE+). + +POSIX Regular Expressions +~~~~~~~~~~~~~~~~~~~~~~~~~ +If the system supports POSIX regular expressions, and UTF-8 support is not enabled, +this support will be used by default. The type of regular expressions supported are +Extended Regular Expressions (+ERE+) rather than Basic Regular Expressions (+BRE+). +See REG_EXTENDED in the documentation. + +Using the system-supported POSIX regular expressions will typically +make for the smallest code size, but some features such as UTF-8 +and +{backslash}w+, +{backslash}d+, +{backslash}s+ are not supported. + +See regex(3) and regex(7) for full details. + +Jim built-in Regular Expressions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The Jim built-in regulare expression engine may be selected with +./configure --with-jim-regexp+ +or it will be selected automatically if UTF-8 support is enabled. + +This engine supports UTF-8 as well as some +ARE+ features. The differences with both Tcl 7.x/8.x +and POSIX are highlighted below. + +1. UTF-8 strings and patterns are both supported +2. Supported character classes: +[:alnum:]+, +[:digit:]+ and +[:space:]+ +3. Supported shorthand character classes: +{backslash}w+ = +[:alnum:]+, +{backslash}d+ = +[:digit:],+ +{backslash}s+ = +[:space:]+ +4. Character classes apply to ASCII characters only +5. Supported constraint escapes: +{backslash}m+ = +{backslash}<+ = start of word, +{backslash}M+ = +{backslash}>+ = end of word +6. Backslash escapes may be used within regular expressions, such as +{backslash}n+ = newline, +{backslash}uNNNN+ = unicode +7. Support for the +?+ non-greedy quantifier. e.g. +*?+ +8. Support for non-capuring parentheses +(?:...)+ + +COMMAND RESULTS +--------------- +Each command produces two results: a code and a string. The +code indicates whether the command completed successfully or not, +and the string gives additional information. The valid codes are +defined in jim.h, and are: + ++JIM_OK(0)+:: + This is the normal return code, and indicates that the command completed + successfully. The string gives the command's return value. + ++JIM_ERR(1)+:: + Indicates that an error occurred; the string gives a message describing + the error. + ++JIM_RETURN(2)+:: + Indicates that the `return` command has been invoked, and that the + current procedure (or top-level command or `source` command) + should return immediately. The + string gives the return value for the procedure or command. + ++JIM_BREAK(3)+:: + Indicates that the `break` command has been invoked, so the + innermost loop should abort immediately. The string should always + be empty. + ++JIM_CONTINUE(4)+:: + Indicates that the `continue` command has been invoked, so the + innermost loop should go on to the next iteration. The string + should always be empty. + ++JIM_SIGNAL(5)+:: + Indicates that a signal was caught while executing a commands. + The string contains the name of the signal caught. + See the `signal` and `catch` commands. + ++JIM_EXIT(6)+:: + Indicates that the command called the `exit` command. + The string contains the exit code. + +Tcl programmers do not normally need to think about return codes, +since +JIM_OK+ is almost always returned. If anything else is returned +by a command, then the Tcl interpreter immediately stops processing +commands and returns to its caller. If there are several nested +invocations of the Tcl interpreter in progress, then each nested +command will usually return the error to its caller, until eventually +the error is reported to the top-level application code. The +application will then display the error message for the user. + +In a few cases, some commands will handle certain `error` conditions +themselves and not return them upwards. For example, the `for` +command checks for the +JIM_BREAK+ code; if it occurs, then `for` +stops executing the body of the loop and returns +JIM_OK+ to its +caller. The `for` command also handles +JIM_CONTINUE+ codes and the +procedure interpreter handles +JIM_RETURN+ codes. The `catch` +command allows Tcl programs to catch errors and handle them without +aborting command interpretation any further. + +The `info returncodes` command may be used to programmatically map between +return codes and names. + +PROCEDURES +---------- +Tcl allows you to extend the command interface by defining +procedures. A Tcl procedure can be invoked just like any other Tcl +command (it has a name and it receives one or more arguments). +The only difference is that its body isn't a piece of C code linked +into the program; it is a string containing one or more other +Tcl commands. + +The `proc` command is used to create a new Tcl command procedure: + ++*proc* 'name arglist ?statics? body'+ + +The new command is named +'name'+, and it replaces any existing command +there may have been by that name. Whenever the new command is +invoked, the contents of +'body'+ will be executed by the Tcl +interpreter. + ++'arglist'+ specifies the formal arguments to the procedure. +It consists of a list, possibly empty, of the following +argument specifiers: + ++name+:: + Required Argument - A simple argument name. + ++name default+:: + Optional Argument - A two-element list consisting of the + argument name, followed by the default value, which will + be used if the corresponding argument is not supplied. + ++&name+:: + Reference Argument - The caller is expected to pass the name of + an existing variable. An implicit `upvar 1 'origname' 'name'` is done + to make the variable available in the proc scope. + ++*args*+:: + Variable Argument - The special name +'args'+, which is + assigned all remaining arguments (including none) as a list. The + variable argument may only be specified once. Note that + the syntax +args newname+ may be used to retain the special + behaviour of +'args'+ with a different local name. In this case, + the variable is named +'newname'+ rather than +'args'+. + +When the command is invoked, a local variable will be created for each of +the formal arguments to the procedure; its value will be the value +of corresponding argument in the invoking command or the argument's +default value. + +Arguments with default values need not be specified in a procedure +invocation. However, there must be enough actual arguments for all +required arguments, and there must not be any extra actual arguments +(unless the Variable Argument is specified). + +Actual arguments are assigned to formal arguments as in left-to-right +order with the following precedence. + +1. Required Arguments (including Reference Arguments) +2. Optional Arguments +3. Variable Argument + +The following example illustrates precedence. Assume a procedure declaration: + + proc p {{a A} args b {c C} d} {...} + +This procedure requires at least two arguments, but can accept an unlimited number. +The following table shows how various numbers of arguments are assigned. +Values marked as +-+ are assigned the default value. + +[width="40%",frame="topbot",options="header"] +|============== +|Number of arguments|a|args|b|c|d +|2|-|-|1|-|2 +|3|1|-|2|-|3 +|4|1|-|2|3|4 +|5|1|2|3|4|5 +|6|1|2,3|4|5|6 +|============== + +When +'body'+ is being executed, variable names normally refer to local +variables, which are created automatically when referenced and deleted +when the procedure returns. One local variable is automatically created +for each of the procedure's arguments. Global variables can be +accessed by invoking the `global` command or via the +::+ prefix. + +New in Jim +~~~~~~~~~~ +In addition to procedure arguments, Jim procedures may declare static variables. +These variables scoped to the procedure and initialised at procedure definition. +Either from the static variable definition, or from the enclosing scope. + +Consider the following example: + + jim> set a 1 + jim> proc a {} {a {b 2}} { + set c 1 + puts "$a $b $c" + incr a + incr b + incr c + } + jim> a + 1 2 1 + jim> a + 2 3 1 + +The static variable +'a'+ has no initialiser, so it is initialised from +the enclosing scope with the value 1. (Note that it is an error if there +is no variable with the same name in the enclosing scope). However +'b'+ +has an initialiser, so it is initialised to 2. + +Unlike a local variable, the value of a static variable is retained across +invocations of the procedure. + +See the `proc` command for information on how to define procedures +and what happens when they are invoked. See also NAMESPACES. + +VARIABLES - SCALARS AND ARRAYS +------------------------------ +Tcl allows the definition of variables and the use of their values +either through '$'-style variable substitution, the `set` +command, or a few other mechanisms. + +Variables need not be declared: a new variable will automatically +be created each time a new variable name is used. + +Tcl supports two types of variables: scalars and arrays. +A scalar variable has a single value, whereas an array variable +can have any number of elements, each with a name (called +its 'index') and a value. + +Array indexes may be arbitrary strings; they need not be numeric. +Parentheses are used refer to array elements in Tcl commands. +For example, the command + + set x(first) 44 + +will modify the element of 'x' whose index is 'first' +so that its new value is '44'. + +Two-dimensional arrays can be simulated in Tcl by using indexes +that contain multiple concatenated values. +For example, the commands + + set a(2,3) 1 + set a(3,6) 2 + +set the elements of 'a' whose indexes are '2,3' and '3,6'. + +In general, array elements may be used anywhere in Tcl that scalar +variables may be used. + +If an array is defined with a particular name, then there may +not be a scalar variable with the same name. + +Similarly, if there is a scalar variable with a particular +name then it is not possible to make array references to the +variable. + +To convert a scalar variable to an array or vice versa, remove +the existing variable with the `unset` command. + +The `array` command provides several features for dealing +with arrays, such as querying the names of all the elements of +the array and converting between an array and a list. + +Variables may be either global or local. If a variable +name is used when a procedure isn't being executed, then it +automatically refers to a global variable. Variable names used +within a procedure normally refer to local variables associated with that +invocation of the procedure. Local variables are deleted whenever +a procedure exits. Either `global` command may be used to request +that a name refer to a global variable for the duration of the current +procedure (this is somewhat analogous to 'extern' in C), or the variable +may be explicitly scoped with the +::+ prefix. For example + + set a 1 + set b 2 + proc p {} { + set c 3 + global a + + puts "$a $::b $c" + } + p + +will output: + + 1 2 3 + +ARRAYS AS LISTS IN JIM +---------------------- +Unlike Tcl, Jim can automatically convert between a list (with an even +number of elements) and an array value. This is similar to the way Tcl +can convert between a string and a list. + +For example: + + set a {1 one 2 two} + puts $a(2) + +will output: + + two + +Thus `array set` is equivalent to `set` when the variable does not +exist or is empty. + +The reverse is also true where an array will be converted into +a list. + + set a(1) one; set a(2) two + puts $a + +will output: + + 1 one 2 two + +DICTIONARY VALUES +----------------- +Tcl 8.5 introduced the dict command, and Jim Tcl has added a version +of this command. Dictionaries provide efficient access to key-value +pairs, just like arrays, but dictionaries are pure values. This +means that you can pass them to a procedure just as a list or a +string. Tcl dictionaries are therefore much more like Tcl lists, +except that they represent a mapping from keys to values, rather +than an ordered sequence. + +You can nest dictionaries, so that the value for a particular key +consists of another dictionary. That way you can elegantly build +complicated data structures, such as hierarchical databases. You +can also combine dictionaries with other Tcl data structures. For +instance, you can build a list of dictionaries that themselves +contain lists. + +Dictionaries are values that contain an efficient, order-preserving +mapping from arbitrary keys to arbitrary values. Each key in the +dictionary maps to a single value. They have a textual format that +is exactly that of any list with an even number of elements, with +each mapping in the dictionary being represented as two items in +the list. When a command takes a dictionary and produces a new +dictionary based on it (either returning it or writing it back into +the variable that the starting dictionary was read from) the new +dictionary will have the same order of keys, modulo any deleted +keys and with new keys added on to the end. When a string is +interpreted as a dictionary and it would otherwise have duplicate +keys, only the last value for a particular key is used; the others +are ignored, meaning that, "apple banana" and "apple carrot apple +banana" are equivalent dictionaries (with different string +representations). + +Note that in Jim, arrays are implemented as dictionaries. +Thus automatic conversion between lists and dictionaries applies +as it does for arrays. + + jim> dict set a 1 one + 1 one + jim> dict set a 2 two + 1 one 2 two + jim> puts $a + 1 one 2 two + jim> puts $a(2) + two + jim> dict set a 3 T three + 1 one 2 two 3 {T three} + +See the `dict` command for more details. + +NAMESPACES +---------- +Tcl added namespaces as a mechanism avoiding name clashes, especially in applications +including a number of 3rd party components. While there is less need for namespaces +in Jim Tcl (which does not strive to support large applications), it is convenient to +provide a subset of the support for namespaces to easy porting code from Tcl. + +Jim Tcl currently supports "light-weight" namespaces which should be adequate for most +purposes. This feature is currently experimental. See README.namespaces for more information +and the documentation of the `namespace` command. + +GARBAGE COLLECTION, REFERENCES, LAMBDA +-------------------------------------- +Unlike Tcl, Jim has some sophisticated support for functional programming. +These are described briefly below. + +More information may be found at http://wiki.tcl.tk/13847 + +References +~~~~~~~~~~ +A reference can be thought of as holding a value with one level of indirection, +where the value may be garbage collected when unreferenced. +Consider the following example: + + jim> set r [ref "One String" test] + .00000000000000000000> + jim> getref $r + One String + +The operation `ref` creates a references to the value specified by the +first argument. (The second argument is a "type" used for documentation purposes). + +The operation `getref` is the dereferencing operation which retrieves the value +stored in the reference. + + jim> setref $r "New String" + New String + jim> getref $r + New String + +The operation `setref` replaces the value stored by the reference. If the old value +is no longer accessible by any reference, it will eventually be automatically be garbage +collected. + +Garbage Collection +~~~~~~~~~~~~~~~~~~ +Normally, all values in Tcl are passed by value. As such values are copied and released +automatically as necessary. + +With the introduction of references, it is possible to create values whose lifetime +transcend their scope. To support this, case, the Jim system will periodically identify +and discard objects which are no longer accessible by any reference. + +The `collect` command may be used to force garbage collection. Consider a reference created +with a finalizer: + + jim> proc f {ref value} { puts "Finaliser called for $ref,$value" } + jim> set r [ref "One String" test f] + .00000000000 + jim> collect + 0 + jim> set r "" + jim> collect + Finaliser called for .00000000000,One String + 1 + +Note that once the reference, 'r', was modified so that it no longer +contained a reference to the value, the garbage collector discarded +the value (after calling the finalizer). + +The finalizer for a reference may be examined or changed with the `finalize` command + + jim> finalize $r + f + jim> finalize $r newf + newf + +Lambda +~~~~~~ +Jim provides a garbage collected lambda function. This is a procedure +which is able to create an anonymous procedure. Consider: + + jim> set f [lambda {a} {{x 0}} { incr x $a }] + jim> $f 1 + 1 + jim> $f 2 + 3 + jim> set f "" + +This create an anonymous procedure (with the name stored in 'f'), with a static variable +which is incremented by the supplied value and the result returned. + +Once the procedure name is no longer accessible, it will automatically be deleted +when the garbage collector runs. + +The procedure may also be delete immediately by renaming it "". e.g. + + jim> rename $f "" + +UTF-8 AND UNICODE +----------------- +If Jim is built with UTF-8 support enabled (configure --enable-utf), +then most string-related commands become UTF-8 aware. These include, +but are not limited to, `string match`, `split`, `glob`, `scan` and +`format`. + +UTF-8 encoding has many advantages, but one of the complications is that +characters can take a variable number of bytes. Thus the addition of +`string bytelength` which returns the number of bytes in a string, +while `string length` returns the number of characters. + +If UTF-8 support is not enabled, all commands treat bytes as characters +and `string bytelength` returns the same value as `string length`. + +Note that even if UTF-8 support is not enabled, the +{backslash}uNNNN+ and related syntax +is still available to embed UTF-8 sequences. + +Jim Tcl supports all currently defined unicode codepoints. That is 21 bits, up to +'U+1FFFFF'. + +String Matching +~~~~~~~~~~~~~~~ +Commands such as `string match`, `lsearch -glob`, `array names` and others use string +pattern matching rules. These commands support UTF-8. For example: + + string match a\[\ua0-\ubf\]b "a\u00a3b" + +format and scan +~~~~~~~~~~~~~~~ ++format %c+ allows a unicode codepoint to be be encoded. For example, the following will return +a string with two bytes and one character. The same as +{backslash}ub5+ + + format %c 0xb5 + +`format` respects widths as character widths, not byte widths. For example, the following will +return a string with three characters, not three bytes. + + format %.3s \ub5\ub6\ub7\ub8 + +Similarly, +scan ... %c+ allows a UTF-8 to be decoded to a unicode codepoint. The following will set ++'a'+ to 181 (0xb5) and +'b'+ to 65 (0x41). + + scan \u00b5A %c%c a b + +`scan %s` will also accept a character class, including unicode ranges. + +String Classes +~~~~~~~~~~~~~~ +`string is` has *not* been extended to classify UTF-8 characters. Therefore, the following +will return 0, even though the string may be considered to be alphabetic. + + string is alpha \ub5Test + +This does not affect the string classes 'ascii', 'control', 'digit', 'double', 'integer' or 'xdigit'. + +Case Mapping and Conversion +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Jim provides a simplified unicode case mapping. This means that case conversion +and comparison will not increase or decrease the number of characters in a string. +(Although it may change the number of bytes). + +`string toupper` will convert any lowercase letters to their uppercase equivalent. +Any character which is not a letter or has no uppercase equivalent is left unchanged. +Similarly for `string tolower` and `string totitle`. + +Commands which perform case insensitive matches, such as `string compare -nocase` +and `lsearch -nocase` fold both strings to uppercase before comparison. + +Invalid UTF-8 Sequences +~~~~~~~~~~~~~~~~~~~~~~~ +Some UTF-8 character sequences are invalid, such as those beginning with '0xff', +those which represent character sequences longer than 3 bytes (greater than U+FFFF), +and those which end prematurely, such as a lone '0xc2'. + +In these situations, the offending bytes are treated as single characters. For example, +the following returns 2. + + string bytelength \xff\xff + +Regular Expressions +~~~~~~~~~~~~~~~~~~~ +If UTF-8 support is enabled, the built-in regular expression engine will be +selected which supports UTF-8 strings and patterns. + +See REGULAR EXPRESSIONS + +BUILT-IN COMMANDS +----------------- +The Tcl library provides the following built-in commands, which will +be available in any application using Tcl. In addition to these +built-in commands, there may be additional commands defined by each +application, plus commands defined as Tcl procedures. + +In the command syntax descriptions below, words in +*boldface*+ are +literals that you type verbatim to Tcl. + +Words in +'italics'+ are meta-symbols; they serve as names for any of +a range of values that you can type. + +Optional arguments or groups of arguments are indicated by enclosing them +in +?question-marks?+. + +Ellipses (+\...+) indicate that any number of additional +arguments or groups of arguments may appear, in the same format +as the preceding argument(s). + +[[CommandIndex]] +Command Index +~~~~~~~~~~~~~ +@INSERTINDEX@ + +alarm +~~~~~ ++*alarm* 'seconds'+ + +Delivers the +SIGALRM+ signal to the process after the given +number of seconds. If the platform supports 'ualarm(3)' then +the argument may be a floating point value. Otherwise it must +be an integer. + +Note that unless a signal handler for +SIGALRM+ has been installed +(see `signal`), the process will exit on this signal. + +alias +~~~~~ ++*alias* 'name args\...'+ + +Creates a single word alias (command) for one or more words. For example, +the following creates an alias for the command `info exists`. + + alias e info exists + if {[e var]} { + ... + } + +`alias` returns +'name'+, allowing it to be used with `local`. + +See also `proc`, `curry`, `lambda`, `local`, `info alias`, `exists -alias` + +append +~~~~~~ ++*append* 'varName value ?value value ...?'+ + +Append all of the +'value'+ arguments to the current value +of variable +'varName'+. If +'varName'+ doesn't exist, +it is given a value equal to the concatenation of all the ++'value'+ arguments. + +This command provides an efficient way to build up long +variables incrementally. +For example, "`append a $b`" is much more efficient than +"`set a $a$b`" if +$a+ is long. + +apply +~~~~~~ ++*apply* 'lambdaExpr ?arg1 arg2 \...?'+ + +The command `apply` provides for anonymous procedure calls, +similar to `lambda`, but without command name being created, even temporarily. + +The function +'lambdaExpr'+ is a two element list +{args body}+ +or a three element list +{args body namespace}+. The first element +args specifies the formal arguments, in the same form as the `proc` and `lambda` commands. + +array +~~~~~ ++*array* 'option arrayName ?arg\...?'+ + +This command performs one of several operations on the +variable given by +'arrayName'+. + +Note that in general, if the named array does not exist, the +'array'+ command behaves +as though the array exists but is empty. + +The +'option'+ argument determines what action is carried out by the +command. The legal +'options'+ (which may be abbreviated) are: + ++*array exists* 'arrayName'+:: + Returns 1 if arrayName is an array variable, 0 if there is + no variable by that name. This command is essentially + identical to `info exists` + ++*array get* 'arrayName ?pattern?'+:: + Returns a list containing pairs of elements. The first + element in each pair is the name of an element in arrayName + and the second element of each pair is the value of the + array element. The order of the pairs is undefined. If + pattern is not specified, then all of the elements of the + array are included in the result. If pattern is specified, + then only those elements whose names match pattern (using + the matching rules of string match) are included. If arrayName + isn't the name of an array variable, or if the array contains + no elements, then an empty list is returned. + ++*array names* 'arrayName ?pattern?'+:: + Returns a list containing the names of all of the elements + in the array that match pattern. If pattern is omitted then + the command returns all of the element names in the array. + If pattern is specified, then only those elements whose + names match pattern (using the matching rules of string + match) are included. If there are no (matching) elements + in the array, or if arrayName isn't the name of an array + variable, then an empty string is returned. + ++*array set* 'arrayName list'+:: + Sets the values of one or more elements in arrayName. list + must have a form like that returned by array get, consisting + of an even number of elements. Each odd-numbered element + in list is treated as an element name within arrayName, and + the following element in list is used as a new value for + that array element. If the variable arrayName does not + already exist and list is empty, arrayName is created with + an empty array value. + ++*array size* 'arrayName'+:: + Returns the number of elements in the array. If arrayName + isn't the name of an array then 0 is returned. + ++*array unset* 'arrayName ?pattern?'+:: + Unsets all of the elements in the array that match pattern + (using the matching rules of string match). If arrayName + isn't the name of an array variable or there are no matching + elements in the array, no error will be raised. If pattern + is omitted and arrayName is an array variable, then the + command unsets the entire array. The command always returns + an empty string. + +break +~~~~~ ++*break*+ + +This command may be invoked only inside the body of a loop command +such as `for` or `foreach` or `while`. It returns a +JIM_BREAK+ code +to signal the innermost containing loop command to return immediately. + +case +~~~~ ++*case* 'string' ?in? 'patList body ?patList body ...?'+ + ++*case* 'string' ?in? {'patList body ?patList body ...?'}+ + +*Note* that the `switch` command should generally be preferred unless compatibility +with Tcl 6.x is desired. + +Match +'string'+ against each of the +'patList'+ arguments +in order. If one matches, then evaluate the following +'body'+ argument +by passing it recursively to the Tcl interpreter, and return the result +of that evaluation. Each +'patList'+ argument consists of a single +pattern or list of patterns. Each pattern may contain any of the wild-cards +described under `string match`. + +If a +'patList'+ argument is +default+, the corresponding body will be +evaluated if no +'patList'+ matches +'string'+. If no +'patList'+ argument +matches +'string'+ and no default is given, then the `case` command returns +an empty string. + +Two syntaxes are provided. + +The first uses a separate argument for each of the patterns and commands; +this form is convenient if substitutions are desired on some of the +patterns or commands. + +The second form places all of the patterns and commands together into +a single argument; the argument must have proper list structure, with +the elements of the list being the patterns and commands. + +The second form makes it easy to construct multi-line case commands, +since the braces around the whole list make it unnecessary to include a +backslash at the end of each line. + +Since the +'patList'+ arguments are in braces in the second form, +no command or variable substitutions are performed on them; this makes +the behaviour of the second form different than the first form in some +cases. + +Below are some examples of `case` commands: + + case abc in {a b} {format 1} default {format 2} a* {format 3} + +will return '3', + + case a in { + {a b} {format 1} + default {format 2} + a* {format 3} + } + +will return '1', and + + case xyz { + {a b} + {format 1} + default + {format 2} + a* + {format 3} + } + +will return '2'. + +catch +~~~~~ ++*catch* ?-?no?'code \...'? ?--? 'command ?resultVarName? ?optionsVarName?'+ + +The `catch` command may be used to prevent errors from aborting +command interpretation. `catch` evaluates +'command'+, and returns a ++JIM_OK+ code, regardless of any errors that might occur while +executing +'command'+ (with the possible exception of +JIM_SIGNAL+ - +see below). + +The return value from `catch` is a decimal string giving the code +returned by the Tcl interpreter after executing +'command'+. This +will be '0' (+JIM_OK+) if there were no errors in +'command'+; otherwise +it will have a non-zero value corresponding to one of the exceptional +return codes (see jim.h for the definitions of code values, or the +`info returncodes` command). + +If the +'resultVarName'+ argument is given, then it gives the name +of a variable; `catch` will set the value of the variable to the +string returned from +'command'+ (either a result or an error message). + +If the +'optionsVarName'+ argument is given, then it gives the name +of a variable; `catch` will set the value of the variable to a +dictionary. For any return code other than +JIM_RETURN+, the value +for the key +-code+ will be set to the return code. For +JIM_RETURN+ +it will be set to the code given in `return -code`. Additionally, +for the return code +JIM_ERR+, the value of the key +-errorinfo+ +will contain the current stack trace (the same result as `info stacktrace`), +the value of the key +-errorcode+ will contain the +same value as the global variable $::errorCode, and the value of +the key +-level+ will be the current return level (see `return -level`). +This can be useful to rethrow an error: + + if {[catch {...} msg opts]} { + ...maybe do something with the error... + incr opts(-level) + return {*}$opts $msg + } + +Normally `catch` will +'not'+ catch any of the codes +JIM_EXIT+, +JIM_EVAL+ or +JIM_SIGNAL+. +The set of codes which will be caught may be modified by specifying the one more codes before ++'command'+. + +e.g. To catch +JIM_EXIT+ but not +JIM_BREAK+ or +JIM_CONTINUE+ + + catch -exit -nobreak -nocontinue -- { ... } + +The use of +--+ is optional. It signifies that no more return code options follow. + +Note that if a signal marked as `signal handle` is caught with `catch -signal`, the return value +(stored in +'resultVarName'+) is name of the signal caught. + +cd +~~ ++*cd* 'dirName'+ + +Change the current working directory to +'dirName'+. + +Returns an empty string. + +This command can potentially be disruptive to an application, so it may +be removed in some applications. + +clock +~~~~~ ++*clock seconds*+:: + Returns the current time as seconds since the epoch. + ++*clock format* 'seconds' ?*-format* 'format?'+:: + Format the given time (seconds since the epoch) according to the given + format. See strftime(3) for supported formats. + If no format is supplied, "%c" is used. + ++*clock scan* 'str' *-format* 'format'+:: + Scan the given time string using the given format string. + See strptime(3) for supported formats. + +close +~~~~~ ++*close* 'fileId'+ + ++'fileId' *close*+ + +Closes the file given by +'fileId'+. ++'fileId'+ must be the return value from a previous invocation +of the `open` command; after this command, it should not be +used anymore. + +collect +~~~~~~~ ++*collect*+ + +Normally reference garbage collection is automatically performed periodically. +However it may be run immediately with the `collect` command. + +See GARBAGE COLLECTION, REFERENCES, LAMBDA for more detail. + +concat +~~~~~~ ++*concat* 'arg ?arg \...?'+ + +This command treats each argument as a list and concatenates them +into a single list. It permits any number of arguments. For example, +the command + + concat a b {c d e} {f {g h}} + +will return + + a b c d e f {g h} + +as its result. + +continue +~~~~~~~~ ++*continue*+ + +This command may be invoked only inside the body of a loop command such +as `for` or `foreach` or `while`. It returns a +JIM_CONTINUE+ code to +signal the innermost containing loop command to skip the remainder of +the loop's body but continue with the next iteration of the loop. + +curry +~~~~~ ++*alias* 'args\...'+ + +Similar to `alias` except it creates an anonymous procedure (lambda) instead of +a named procedure. + +the following creates a local, unnamed alias for the command `info exists`. + + set e [local curry info exists] + if {[$e var]} { + ... + } + +`curry` returns the name of the procedure. + +See also `proc`, `alias`, `lambda`, `local`. + +dict +~~~~ ++*dict* 'option ?arg\...?'+ + +Performs one of several operations on dictionary values. + +The +'option'+ argument determines what action is carried out by the +command. The legal +'options'+ are: + ++*dict create* '?key value \...?'+:: + Create and return a new dictionary value that contains each of + the key/value mappings listed as arguments (keys and values + alternating, with each key being followed by its associated + value.) + ++*dict exists* 'dictionary key ?key \...?'+:: + Returns a boolean value indicating whether the given key (or path + of keys through a set of nested dictionaries) exists in the given + dictionary value. This returns a true value exactly when `dict get` + on that path will succeed. + ++*dict get* 'dictionary ?key \...?'+:: + Given a dictionary value (first argument) and a key (second argument), + this will retrieve the value for that key. Where several keys are + supplied, the behaviour of the command shall be as if the result + of "`dict get $dictVal $key`" was passed as the first argument to + dict get with the remaining arguments as second (and possibly + subsequent) arguments. This facilitates lookups in nested dictionaries. + If no keys are provided, dict would return a list containing pairs + of elements in a man- ner similar to array get. That is, the first + element of each pair would be the key and the second element would + be the value for that key. It is an error to attempt to retrieve + a value for a key that is not present in the dictionary. + ++*dict keys* 'dictionary ?pattern?'+:: + Returns a list of the keys in the dictionary. + If pattern is specified, then only those keys whose + names match +'pattern'+ (using the matching rules of string + match) are included. + ++*dict merge* ?'dictionary \...'?+:: + Return a dictionary that contains the contents of each of the + +'dictionary'+ arguments. Where two (or more) dictionaries + contain a mapping for the same key, the resulting dictionary + maps that key to the value according to the last dictionary on + the command line containing a mapping for that key. + ++*dict set* 'dictionaryName key ?key \...? value'+:: + This operation takes the +'name'+ of a variable containing a dictionary + value and places an updated dictionary value in that variable + containing a mapping from the given key to the given value. When + multiple keys are present, this operation creates or updates a chain + of nested dictionaries. + ++*dict size* 'dictionary'+:: + Return the number of key/value mappings in the given dictionary value. + ++*dict unset* 'dictionaryName key ?key \...? value'+:: + This operation (the companion to `dict set`) takes the name of a + variable containing a dictionary value and places an updated + dictionary value in that variable that does not contain a mapping + for the given key. Where multiple keys are present, this describes + a path through nested dictionaries to the mapping to remove. At + least one key must be specified, but the last key on the key-path + need not exist. All other components on the path must exist. + ++*dict with* 'dictionaryName key ?key \...? script'+:: + Execute the Tcl script in +'script'+ with the value for each + key in +'dictionaryName'+ mapped to a variable with the same + name. Where one or more keys are given, these indicate a chain + of nested dictionaries, with the innermost dictionary being the + one opened out for the execution of body. Making +'dictionaryName'+ + unreadable will make the updates to the dictionary be discarded, + and this also happens if the contents of +'dictionaryName'+ are + adjusted so that the chain of dictionaries no longer exists. + The result of `dict with` is (unless some kind of error occurs) + the result of the evaluation of body. + :: + The variables are mapped in the scope enclosing the `dict with`; + it is recommended that this command only be used in a local + scope (procedure). Because of this, the variables set by + `dict with` will continue to exist after the command finishes (unless + explicitly unset). Note that changes to the contents of +'dictionaryName'+ + only happen when +'script'+ terminates. + +env +~~~ ++*env* '?name? ?default?'+ + +If +'name'+ is supplied, returns the value of +'name'+ from the initial +environment (see getenv(3)). An error is returned if +'name'+ does not +exist in the environment, unless +'default'+ is supplied - in which case +that value is returned instead. + +If no arguments are supplied, returns a list of all environment variables +and their values as +{name value \...}+ + +See also the global variable +::env+ + +eof +~~~ ++*eof* 'fileId'+ + ++'fileId' *eof*+ + +Returns 1 if an end-of-file condition has occurred on +'fileId'+, +0 otherwise. + ++'fileId'+ must have been the return value from a previous call to `open`, +or it may be +stdin+, +stdout+, or +stderr+ to refer to one of the +standard I/O channels. + +error +~~~~~ ++*error* 'message ?stacktrace?'+ + +Returns a +JIM_ERR+ code, which causes command interpretation to be +unwound. +'message'+ is a string that is returned to the application +to indicate what went wrong. + +If the +'stacktrace'+ argument is provided and is non-empty, +it is used to initialize the stacktrace. + +This feature is most useful in conjunction with the `catch` command: +if a caught error cannot be handled successfully, +'stacktrace'+ can be used +to return a stack trace reflecting the original point of occurrence +of the error: + + catch {...} errMsg + ... + error $errMsg [info stacktrace] + +See also `errorInfo`, `info stacktrace`, `catch` and `return` + +errorInfo +~~~~~~~~~ ++*errorInfo* 'error ?stacktrace?'+ + +Returns a human-readable representation of the given error message and stack trace. +Typical usage is: + + if {[catch {...} error]} { + puts stderr [errorInfo $error [info stacktrace]] + exit 1 + } + +See also `error`. + +eval +~~~~ ++*eval* 'arg ?arg\...?'+ + +`eval` takes one or more arguments, which together comprise a Tcl +command (or collection of Tcl commands separated by newlines in the +usual way). `eval` concatenates all its arguments in the same +fashion as the `concat` command, passes the concatenated string to the +Tcl interpreter recursively, and returns the result of that +evaluation (or any error generated by it). + +exec +~~~~ ++*exec* 'arg ?arg\...?'+ + +This command treats its arguments as the specification +of one or more UNIX commands to execute as subprocesses. +The commands take the form of a standard shell pipeline; ++|+ arguments separate commands in the +pipeline and cause standard output of the preceding command +to be piped into standard input of the next command (or +|&+ for +both standard output and standard error). + +Under normal conditions the result of the `exec` command +consists of the standard output produced by the last command +in the pipeline. + +If any of the commands in the pipeline exit abnormally or +are killed or suspended, then `exec` will return an error +and the error message will include the pipeline's output followed by +error messages describing the abnormal terminations. + +If any of the commands writes to its standard error file, +then `exec` will return an error, and the error message +will include the pipeline's output, followed by messages +about abnormal terminations (if any), followed by the standard error +output. + +If the last character of the result or error message +is a newline then that character is deleted from the result +or error message for consistency with normal +Tcl return values. + +An +'arg'+ may have one of the following special forms: + ++>filename+:: + The standard output of the last command in the pipeline + is redirected to the file. In this situation `exec` + will normally return an empty string. + ++>>filename+:: + As above, but append to the file. + ++>@fileId+:: + The standard output of the last command in the pipeline is + redirected to the given (writable) file descriptor (e.g. stdout, + stderr, or the result of `open`). In this situation `exec` + will normally return an empty string. + ++2>filename+:: + The standard error of the last command in the pipeline + is redirected to the file. + ++2>>filename+:: + As above, but append to the file. + ++2>@fileId+:: + The standard error of the last command in the pipeline is + redirected to the given (writable) file descriptor. + ++2>@1+:: + The standard error of the last command in the pipeline is + redirected to the same file descriptor as the standard output. + ++>&filename+:: + Both the standard output and standard error of the last command + in the pipeline is redirected to the file. + ++>>&filename+:: + As above, but append to the file. + +++, and +&+ arguments, and the +arguments that follow +<+, +<<+, and +>+. + +The first word in each command is taken as the command name; +the directories in the PATH environment variable are searched for +an executable by the given name. + +No `glob` expansion or other shell-like substitutions +are performed on the arguments to commands. + +If the command fails, the global $::errorCode (and the -errorcode +option in `catch`) will be set to a list, as follows: + ++*CHILDKILLED* 'pid sigName msg'+:: + This format is used when a child process has been killed + because of a signal. The pid element will be the process's + identifier (in decimal). The sigName element will be the + symbolic name of the signal that caused the process to + terminate; it will be one of the names from the include + file signal.h, such as SIGPIPE. The msg element will be a + short human-readable message describing the signal, such + as "write on pipe with no readers" for SIGPIPE. + ++*CHILDSUSP* 'pid sigName msg'+:: + This format is used when a child process has been suspended + because of a signal. The pid element will be the process's + identifier, in decimal. The sigName element will be the + symbolic name of the signal that caused the process to + suspend; this will be one of the names from the include + file signal.h, such as SIGTTIN. The msg element will be a + short human-readable message describing the signal, such + as "background tty read" for SIGTTIN. + ++*CHILDSTATUS* 'pid code'+:: + This format is used when a child process has exited with a + non-zero exit status. The pid element will be the process's + identifier (in decimal) and the code element will be the + exit code returned by the process (also in decimal). + +The environment for the executed command is set from $::env (unless +this variable is unset, in which case the original environment is used). + +exists +~~~~~~ ++*exists ?-var|-proc|-command|-alias?* 'name'+ + +Checks the existence of the given variable, procedure, command +or alias respectively and returns 1 if it exists or 0 if not. This command +provides a more simplified/convenient version of `info exists`, +`info procs` and `info commands`. + +If the type is omitted, a type of '-var' is used. The type may be abbreviated. + +exit +~~~~ ++*exit* '?returnCode?'+ + +Terminate the process, returning +'returnCode'+ to the +parent as the exit status. + +If +'returnCode'+ isn't specified then it defaults +to 0. + +Note that exit can be caught with `catch`. + +expr +~~~~ ++*expr* 'arg'+ + +Calls the expression processor to evaluate +'arg'+, and returns +the result as a string. See the section EXPRESSIONS above. + +Note that Jim supports a shorthand syntax for `expr` as +$(\...)+ +The following two are identical. + + set x [expr {3 * 2 + 1}] + set x $(3 * 2 + 1) + +file +~~~~ ++*file* 'option name ?arg\...?'+ + +Operate on a file or a file name. +'name'+ is the name of a file. + ++'option'+ indicates what to do with the file name. Any unique +abbreviation for +'option'+ is acceptable. The valid options are: + ++*file atime* 'name'+:: + Return a decimal string giving the time at which file +'name'+ + was last accessed. The time is measured in the standard UNIX + fashion as seconds from a fixed starting time (often January 1, 1970). + If the file doesn't exist or its access time cannot be queried then an + error is generated. + ++*file copy ?-force?* 'source target'+:: + Copies file +'source'+ to file +'target'+. The source file must exist. + The target file must not exist, unless +-force+ is specified. + ++*file delete ?-force?* 'name\...'+:: + Deletes file or directory +'name'+. If the file or directory doesn't exist, nothing happens. + If it can't be deleted, an error is generated. Non-empty directories will not be deleted + unless the +-force+ options is given. In this case no errors will be generated, even + if the file/directory can't be deleted. + ++*file dirname* 'name'+:: + Return all of the characters in +'name'+ up to but not including + the last slash character. If there are no slashes in +'name'+ + then return +.+ (a single dot). If the last slash in +'name'+ is its first + character, then return +/+. + ++*file executable* 'name'+:: + Return '1' if file +'name'+ is executable by + the current user, '0' otherwise. + ++*file exists* 'name'+:: + Return '1' if file +'name'+ exists and the current user has + search privileges for the directories leading to it, '0' otherwise. + ++*file extension* 'name'+:: + Return all of the characters in +'name'+ after and including the + last dot in +'name'+. If there is no dot in +'name'+ then return + the empty string. + ++*file isdirectory* 'name'+:: + Return '1' if file +'name'+ is a directory, + '0' otherwise. + ++*file isfile* 'name'+:: + Return '1' if file +'name'+ is a regular file, + '0' otherwise. + ++*file join* 'arg\...'+:: + Joins multiple path components. Note that if any components is + an absolute path, the preceding components are ignored. + Thus +"`file` join /tmp /root"+ returns +"/root"+. + ++*file lstat* 'name varName'+:: + Same as 'stat' option (see below) except uses the +'lstat'+ + kernel call instead of +'stat'+. This means that if +'name'+ + refers to a symbolic link the information returned in +'varName'+ + is for the link rather than the file it refers to. On systems that + don't support symbolic links this option behaves exactly the same + as the 'stat' option. + ++*file mkdir* 'dir1 ?dir2\...?'+:: + Creates each directory specified. For each pathname +'dir'+ specified, + this command will create all non-existing parent directories + as well as +'dir'+ itself. If an existing directory is specified, + then no action is taken and no error is returned. Trying to + overwrite an existing file with a directory will result in an + error. Arguments are processed in the order specified, halting + at the first error, if any. + ++*file mtime* 'name ?time?'+:: + Return a decimal string giving the time at which file +'name'+ + was last modified. The time is measured in the standard UNIX + fashion as seconds from a fixed starting time (often January 1, 1970). + If the file doesn't exist or its modified time cannot be queried then an + error is generated. If +'time'+ is given, sets the modification time + of the file to the given value. + ++*file normalize* 'name'+:: + Return the normalized path of +'name'+. See 'realpath(3)'. + ++*file owned* 'name'+:: + Return '1' if file +'name'+ is owned by the current user, + '0' otherwise. + ++*file readable* 'name'+:: + Return '1' if file +'name'+ is readable by + the current user, '0' otherwise. + ++*file readlink* 'name'+:: + Returns the value of the symbolic link given by +'name'+ (i.e. the + name of the file it points to). If + +'name'+ isn't a symbolic link or its value cannot be read, then + an error is returned. On systems that don't support symbolic links + this option is undefined. + ++*file rename* 'oldname' 'newname'+:: + Renames the file from the old name to the new name. + ++*file rootname* 'name'+:: + Return all of the characters in +'name'+ up to but not including + the last '.' character in the name. If +'name'+ doesn't contain + a dot, then return +'name'+. + ++*file size* 'name'+:: + Return a decimal string giving the size of file +'name'+ in bytes. + If the file doesn't exist or its size cannot be queried then an + error is generated. + ++*file stat* 'name varName'+:: + Invoke the 'stat' kernel call on +'name'+, and use the + variable given by +'varName'+ to hold information returned from + the kernel call. + +'varName'+ is treated as an array variable, + and the following elements of that variable are set: 'atime', + 'ctime', 'dev', 'gid', 'ino', 'mode', 'mtime', + 'nlink', 'size', 'type', 'uid'. + Each element except 'type' is a decimal string with the value of + the corresponding field from the 'stat' return structure; see the + manual entry for 'stat' for details on the meanings of the values. + The 'type' element gives the type of the file in the same form + returned by the command `file type`. + This command returns an empty string. + ++*file tail* 'name'+:: + Return all of the characters in +'name'+ after the last slash. + If +'name'+ contains no slashes then return +'name'+. + ++*file tempfile* '?template?'+:: + Creates and returns the name of a unique temporary file. If +'template'+ is omitted, a + default template will be used to place the file in /tmp. See 'mkstemp(3)' for + the format of the template and security concerns. + ++*file type* 'name'+:: + Returns a string giving the type of file +'name'+, which will be + one of +file+, +directory+, +characterSpecial+, + +blockSpecial+, +fifo+, +link+, or +socket+. + ++*file writable* 'name'+:: + Return '1' if file +'name'+ is writable by + the current user, '0' otherwise. + +The `file` commands that return 0/1 results are often used in +conditional or looping commands, for example: + + if {![file exists foo]} { + error {bad file name} + } else { + ... + } + +finalize +~~~~~~~~ ++*finalize* 'reference ?command?'+ + +If +'command'+ is omitted, returns the finalizer command for the given reference. + +Otherwise, sets a new finalizer command for the given reference. +'command'+ may be +the empty string to remove the current finalizer. + +The reference must be a valid reference create with the `ref` +command. + +See GARBAGE COLLECTION, REFERENCES, LAMBDA for more detail. + +flush +~~~~~ ++*flush* 'fileId'+ + ++'fileId' *flush*+ + +Flushes any output that has been buffered for +'fileId'+. +'fileId'+ must +have been the return value from a previous call to `open`, or it may be ++stdout+ or +stderr+ to access one of the standard I/O streams; it must +refer to a file that was opened for writing. This command returns an +empty string. + +for +~~~ ++*for* 'start test next body'+ + +`for` is a looping command, similar in structure to the C `for` statement. +The +'start'+, +'next'+, and +'body'+ arguments must be Tcl command strings, +and +'test'+ is an expression string. + +The `for` command first invokes the Tcl interpreter to execute +'start'+. +Then it repeatedly evaluates +'test'+ as an expression; if the result is +non-zero it invokes the Tcl interpreter on +'body'+, then invokes the Tcl +interpreter on +'next'+, then repeats the loop. The command terminates +when +'test'+ evaluates to 0. + +If a `continue` command is invoked within +'body'+ then any remaining +commands in the current execution of +'body'+ are skipped; processing +continues by invoking the Tcl interpreter on +'next'+, then evaluating ++'test'+, and so on. + +If a `break` command is invoked within +'body'+ or +'next'+, then the `for` +command will return immediately. + +The operation of `break` and `continue` are similar to the corresponding +statements in C. + +`for` returns an empty string. + +foreach +~~~~~~~ ++*foreach* 'varName list body'+ + ++*foreach* 'varList list ?varList2 list2 \...? body'+ + +In this command, +'varName'+ is the name of a variable, +'list'+ +is a list of values to assign to +'varName'+, and +'body'+ is a +collection of Tcl commands. + +For each field in +'list'+ (in order from left to right), `foreach` assigns +the contents of the field to +'varName'+ (as if the `lindex` command +had been used to extract the field), then calls the Tcl interpreter to +execute +'body'+. + +If instead of being a simple name, +'varList'+ is used, multiple assignments +are made each time through the loop, one for each element of +'varList'+. + +For example, if there are two elements in +'varList'+ and six elements in +the list, the loop will be executed three times. + +If the length of the list doesn't evenly divide by the number of elements +in +'varList'+, the value of the remaining variables in the last iteration +of the loop are undefined. + +The `break` and `continue` statements may be invoked inside +'body'+, +with the same effect as in the `for` command. + +`foreach` returns an empty string. + +format +~~~~~~ ++*format* 'formatString ?arg \...?'+ + +This command generates a formatted string in the same way as the +C 'sprintf' procedure (it uses 'sprintf' in its +implementation). +'formatString'+ indicates how to format +the result, using +%+ fields as in 'sprintf', and the additional +arguments, if any, provide values to be substituted into the result. + +All of the 'sprintf' options are valid; see the 'sprintf' +man page for details. Each +'arg'+ must match the expected type +from the +%+ field in +'formatString'+; the `format` command +converts each argument to the correct type (floating, integer, etc.) +before passing it to 'sprintf' for formatting. + +The only unusual conversion is for +%c+; in this case the argument +must be a decimal string, which will then be converted to the corresponding +ASCII character value. + +`format` does backslash substitution on its +'formatString'+ +argument, so backslash sequences in +'formatString'+ will be handled +correctly even if the argument is in braces. + +The return value from `format` is the formatted string. + +getref +~~~~~~ ++*getref* 'reference'+ + +Returns the string associated with +'reference'+. The reference must +be a valid reference create with the `ref` command. + +See GARBAGE COLLECTION, REFERENCES, LAMBDA for more detail. + +gets +~~~~ ++*gets* 'fileId ?varName?'+ + ++'fileId' *gets* '?varName?'+ + +Reads the next line from the file given by +'fileId'+ and discards +the terminating newline character. + +If +'varName'+ is specified, then the line is placed in the variable +by that name and the return value is a count of the number of characters +read (not including the newline). + +If the end of the file is reached before reading +any characters then -1 is returned and +'varName'+ is set to an +empty string. + +If +'varName'+ is not specified then the return value will be +the line (minus the newline character) or an empty string if +the end of the file is reached before reading any characters. + +An empty string will also be returned if a line contains no characters +except the newline, so `eof` may have to be used to determine +what really happened. + +If the last character in the file is not a newline character, then +`gets` behaves as if there were an additional newline character +at the end of the file. + ++'fileId'+ must be +stdin+ or the return value from a previous +call to `open`; it must refer to a file that was opened +for reading. + +glob +~~~~ ++*glob* ?*-nocomplain*? ?*-directory* 'dir'? ?*--*? 'pattern ?pattern \...?'+ + +This command performs filename globbing, using csh rules. The returned +value from `glob` is the list of expanded filenames. + +If +-nocomplain+ is specified as the first argument then an empty +list may be returned; otherwise an error is returned if the expanded +list is empty. The +-nocomplain+ argument must be provided +exactly: an abbreviation will not be accepted. + +If +-directory+ is given, the +'dir'+ is understood to contain a +directory name to search in. This allows globbing inside directories +whose names may contain glob-sensitive characters. The returned names +are specified relative to this directory. + +global +~~~~~~ + ++*global* 'varName ?varName \...?'+ + +This command is ignored unless a Tcl procedure is being interpreted. +If so, then it declares each given +'varName'+ to be a global variable +rather than a local one. For the duration of the current procedure +(and only while executing in the current procedure), any reference to ++'varName'+ will be bound to a global variable instead +of a local one. + +An alternative to using `global` is to use the +::+ prefix +to explicitly name a variable in the global scope. + +if +~~ ++*if* 'expr1' ?*then*? 'body1' *elseif* 'expr2' ?*then*? 'body2' *elseif* \... ?*else*? ?'bodyN'?+ + +The `if` command evaluates +'expr1'+ as an expression (in the same way +that `expr` evaluates its argument). The value of the expression must +be numeric; if it is non-zero then +'body1'+ is executed by passing it to +the Tcl interpreter. + +Otherwise +'expr2'+ is evaluated as an expression and if it is non-zero +then +'body2'+ is executed, and so on. + +If none of the expressions evaluates to non-zero then +'bodyN'+ is executed. + +The +then+ and +else+ arguments are optional "noise words" to make the +command easier to read. + +There may be any number of +elseif+ clauses, including zero. +'bodyN'+ +may also be omitted as long as +else+ is omitted too. + +The return value from the command is the result of the body script that +was executed, or an empty string if none of the expressions was non-zero +and there was no +'bodyN'+. + +incr +~~~~ ++*incr* 'varName ?increment?'+ + +Increment the value stored in the variable whose name is +'varName'+. +The value of the variable must be integral. + +If +'increment'+ is supplied then its value (which must be an +integer) is added to the value of variable +'varName'+; otherwise +1 is added to +'varName'+. + +The new value is stored as a decimal string in variable +'varName'+ +and also returned as result. + +If the variable does not exist, the variable is implicitly created +and set to +0+ first. + +info +~~~~ + ++*info* 'option ?arg\...?'+:: + +Provide information about various internals to the Tcl interpreter. +The legal +'option'+'s (which may be abbreviated) are: + ++*info args* 'procname'+:: + Returns a list containing the names of the arguments to procedure + +'procname'+, in order. +'procname'+ must be the name of a + Tcl command procedure. + ++*info alias* 'command'+:: + +'command'+ must be an alias created with `alias`. In which case the target + command and arguments, as passed to `alias` are returned. See `exists -alias` + ++*info body* 'procname'+:: + Returns the body of procedure +'procname'+. +'procname'+ must be + the name of a Tcl command procedure. + ++*info channels*+:: + Returns a list of all open file handles from `open` or `socket` + ++*info commands* ?'pattern'?+:: + If +'pattern'+ isn't specified, returns a list of names of all the + Tcl commands, including both the built-in commands written in C and + the command procedures defined using the `proc` command. + If +'pattern'+ is specified, only those names matching +'pattern'+ + are returned. Matching is determined using the same rules as for + `string match`. + ++*info complete* 'command' ?'missing'?+:: + Returns 1 if +'command'+ is a complete Tcl command in the sense of + having no unclosed quotes, braces, brackets or array element names, + If the command doesn't appear to be complete then 0 is returned. + This command is typically used in line-oriented input environments + to allow users to type in commands that span multiple lines; if the + command isn't complete, the script can delay evaluating it until additional + lines have been typed to complete the command. If +'varName'+ is specified, the + missing character is stored in the variable with that name. + ++*info exists* 'varName'+:: + Returns '1' if the variable named +'varName'+ exists in the + current context (either as a global or local variable), returns '0' + otherwise. + ++*info frame* ?'number'?+:: + If +'number'+ is not specified, this command returns a number + which is the same result as `info level` - the current stack frame level. + If +'number'+ is specified, then the result is a list consisting of the procedure, + filename and line number for the procedure call at level +'number'+ on the stack. + If +'number'+ is positive then it selects a particular stack level (1 refers + to the top-most active procedure, 2 to the procedure it called, and + so on); otherwise it gives a level relative to the current level + (0 refers to the current procedure, -1 to its caller, and so on). + The level has an identical meaning to `info level`. + ++*info globals* ?'pattern'?+:: + If +'pattern'+ isn't specified, returns a list of all the names + of currently-defined global variables. + If +'pattern'+ is specified, only those names matching +'pattern'+ + are returned. Matching is determined using the same rules as for + `string match`. + ++*info hostname*+:: + An alias for `os.gethostname` for compatibility with Tcl 6.x + ++*info level* ?'number'?+:: + If +'number'+ is not specified, this command returns a number + giving the stack level of the invoking procedure, or 0 if the + command is invoked at top-level. If +'number'+ is specified, + then the result is a list consisting of the name and arguments for the + procedure call at level +'number'+ on the stack. If +'number'+ + is positive then it selects a particular stack level (1 refers + to the top-most active procedure, 2 to the procedure it called, and + so on); otherwise it gives a level relative to the current level + (0 refers to the current procedure, -1 to its caller, and so on). + See the `uplevel` command for more information on what stack + levels mean. + ++*info locals* ?'pattern'?+:: + If +'pattern'+ isn't specified, returns a list of all the names + of currently-defined local variables, including arguments to the + current procedure, if any. Variables defined with the `global` + and `upvar` commands will not be returned. If +'pattern'+ is + specified, only those names matching +'pattern'+ are returned. + Matching is determined using the same rules as for `string match`. + ++*info nameofexecutable*+:: + Returns the name of the binary file from which the application + was invoked. A full path will be returned, unless the path + can't be determined, in which case the empty string will be returned. + ++*info procs* ?'pattern'?+:: + If +'pattern'+ isn't specified, returns a list of all the + names of Tcl command procedures. + If +'pattern'+ is specified, only those names matching +'pattern'+ + are returned. Matching is determined using the same rules as for + `string match`. + ++*info references*+:: + Returns a list of all references which have not yet been garbage + collected. + ++*info returncodes* ?'code'?+:: + Returns a list representing the mapping of standard return codes + to names. e.g. +{0 ok 1 error 2 return \...}+. If a code is given, + instead returns the name for the given code. + ++*info script*+:: + If a Tcl script file is currently being evaluated (i.e. there is a + call to 'Jim_EvalFile' active or there is an active invocation + of the `source` command), then this command returns the name + of the innermost file being processed. Otherwise the command returns an + empty string. + ++*info source* 'script'+:: + Returns the original source location of the given script as a list of + +{filename linenumber}+. If the source location can't be determined, the + list +{{} 0}+ is returned. + ++*info stacktrace*+:: + After an error is caught with `catch`, returns the stack trace as a list + of +{procedure filename line \...}+. + ++*info statics* 'procname'+:: + Returns a dictionary of the static variables of procedure + +'procname'+. +'procname'+ must be the name of a Tcl command + procedure. An empty dictionary is returned if the procedure has + no static variables. + ++*info version*+:: + Returns the version number for this version of Jim in the form +*x.yy*+. + ++*info vars* ?'pattern'?+:: + If +'pattern'+ isn't specified, + returns a list of all the names of currently-visible variables, including + both locals and currently-visible globals. + If +'pattern'+ is specified, only those names matching +'pattern'+ + are returned. Matching is determined using the same rules as for + `string match`. + +join +~~~~ ++*join* 'list ?joinString?'+ + +The +'list'+ argument must be a valid Tcl list. This command returns the +string formed by joining all of the elements of +'list'+ together with ++'joinString'+ separating each adjacent pair of elements. + +The +'joinString'+ argument defaults to a space character. + +kill +~~~~ ++*kill* ?'SIG'|*-0*? 'pid'+ + +Sends the given signal to the process identified by +'pid'+. + +The signal may be specified by name or number in one of the following forms: + +* +TERM+ +* +SIGTERM+ +* +-TERM+ +* +15+ +* +-15+ + +The signal name may be in either upper or lower case. + +The special signal name +-0+ simply checks that a signal +'could'+ be sent. + +If no signal is specified, SIGTERM is used. + +An error is raised if the signal could not be delivered. + +lambda +~~~~~~ ++*lambda* 'args ?statics? body'+ + +The `lambda` command is identical to `proc`, except rather than +creating a named procedure, it creates an anonymous procedure and returns +the name of the procedure. + +See `proc` and GARBAGE COLLECTION, REFERENCES, LAMBDA for more detail. + +lappend +~~~~~~~ ++*lappend* 'varName value ?value value \...?'+ + +Treat the variable given by +'varName'+ as a list and append each of +the +'value'+ arguments to that list as a separate element, with spaces +between elements. + +If +'varName'+ doesn't exist, it is created as a list with elements given +by the +'value'+ arguments. `lappend` is similar to `append` except that +each +'value'+ is appended as a list element rather than raw text. + +This command provides a relatively efficient way to build up large lists. +For example, + + lappend a $b + +is much more efficient than + + set a [concat $a [list $b]] + +when +$a+ is long. + +lassign +~~~~~~~ ++*lassign* 'list varName ?varName \...?'+ + +This command treats the value +'list'+ as a list and assigns successive elements from that list to +the variables given by the +'varName'+ arguments in order. If there are more variable names than +list elements, the remaining variables are set to the empty string. If there are more list ele- +ments than variables, a list of unassigned elements is returned. + + jim> lassign {1 2 3} a b; puts a=$a,b=$b + 3 + a=1,b=2 + +local +~~~~~ ++*local* 'cmd ?arg\...?'+ + +First, `local` evaluates +'cmd'+ with the given arguments. The return value must +be the name of an existing command, which is marked as having local scope. +This means that when the current procedure exits, the specified +command is deleted. This can be useful with `lambda`, local procedures or +to automatically close a filehandle. + +In addition, if a command already exists with the same name, +the existing command will be kept rather than deleted, and may be called +via `upcall`. The previous command will be restored when the current +procedure exits. See `upcall` for more details. + +In this example, a local procedure is created. Note that the procedure +continues to have global scope while it is active. + + proc outer {} { + # proc ... returns "inner" which is marked local + local proc inner {} { + # will be deleted when 'outer' exits + } + + inner + ... + } + +In this example, the lambda is deleted at the end of the procedure rather +than waiting until garbage collection. + + proc outer {} { + set x [lambda inner {args} { + # will be deleted when 'outer' exits + }] + # Use 'function' here which simply returns $x + local function $x + + $x ... + ... + } + +loop +~~~~ ++*loop* 'var first limit ?incr? body'+ + +Similar to `for` except simpler and possibly more efficient. +With a positive increment, equivalent to: + + for {set var $first} {$var < $limit} {incr var $incr} $body + +If +'incr'+ is not specified, 1 is used. +Note that setting the loop variable inside the loop does not +affect the loop count. + +lindex +~~~~~~ ++*lindex* 'list index'+ + +Treats +'list'+ as a Tcl list and returns element +'index'+ from it +(0 refers to the first element of the list). +See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'index'+. + +In extracting the element, +'lindex'+ observes the same rules concerning +braces and quotes and backslashes as the Tcl command interpreter; however, +variable substitution and command substitution do not occur. + +If +'index'+ is negative or greater than or equal to the number of elements +in +'value'+, then an empty string is returned. + +linsert +~~~~~~~ ++*linsert* 'list index element ?element element \...?'+ + +This command produces a new list from +'list'+ by inserting all +of the +'element'+ arguments just before the element +'index'+ +of +'list'+. Each +'element'+ argument will become +a separate element of the new list. If +'index'+ is less than +or equal to zero, then the new elements are inserted at the +beginning of the list. If +'index'+ is greater than or equal +to the number of elements in the list, then the new elements are +appended to the list. + +See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'index'+. + +list +~~~~ + ++*list* 'arg ?arg \...?'+ + +This command returns a list comprised of all the arguments, +'arg'+. Braces +and backslashes get added as necessary, so that the `lindex` command +may be used on the result to re-extract the original arguments, and also +so that `eval` may be used to execute the resulting list, with ++'arg1'+ comprising the command's name and the other args comprising +its arguments. `list` produces slightly different results than +`concat`: `concat` removes one level of grouping before forming +the list, while `list` works directly from the original arguments. +For example, the command + + list a b {c d e} {f {g h}} + +will return + + a b {c d e} {f {g h}} + +while `concat` with the same arguments will return + + a b c d e f {g h} + +llength +~~~~~~~ ++*llength* 'list'+ + +Treats +'list'+ as a list and returns a decimal string giving +the number of elements in it. + +lset +~~~~ ++*lset* 'varName ?index ..? newValue'+ + +Sets an element in a list. + +The `lset` command accepts a parameter, +'varName'+, which it interprets +as the name of a variable containing a Tcl list. It also accepts +zero or more indices into the list. Finally, it accepts a new value +for an element of varName. If no indices are presented, the command +takes the form: + + lset varName newValue + +In this case, newValue replaces the old value of the variable +varName. + +When presented with a single index, the `lset` command +treats the content of the varName variable as a Tcl list. It addresses +the index'th element in it (0 refers to the first element of the +list). When interpreting the list, `lset` observes the same rules +concerning braces and quotes and backslashes as the Tcl command +interpreter; however, variable substitution and command substitution +do not occur. The command constructs a new list in which the +designated element is replaced with newValue. This new list is +stored in the variable varName, and is also the return value from +the `lset` command. + +If index is negative or greater than or equal to the number of +elements in $varName, then an error occurs. + +See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'index'+. + +If additional index arguments are supplied, then each argument is +used in turn to address an element within a sublist designated by +the previous indexing operation, allowing the script to alter +elements in sublists. The command, + + lset a 1 2 newValue + +replaces element 2 of sublist 1 with +'newValue'+. + +The integer appearing in each index argument must be greater than +or equal to zero. The integer appearing in each index argument must +be strictly less than the length of the corresponding list. In other +words, the `lset` command cannot change the size of a list. If an +index is outside the permitted range, an error is reported. + +lmap +~~~~ + ++*lmap* 'varName list body'+ + ++*lmap* 'varList list ?varList2 list2 \...? body'+ + +`lmap` is a "collecting" `foreach` which returns a list of its results. + +For example: + + jim> lmap i {1 2 3 4 5} {expr $i*$i} + 1 4 9 16 25 + jim> lmap a {1 2 3} b {A B C} {list $a $b} + {1 A} {2 B} {3 C} + +If the body invokes `continue`, no value is added for this iteration. +If the body invokes `break`, the loop ends and no more values are added. + +load +~~~~ ++*load* 'filename'+ + +Loads the dynamic extension, +'filename'+. Generally the filename should have +the extension +.so+. The initialisation function for the module must be based +on the name of the file. For example loading +hwaccess.so+ will invoke +the initialisation function, +Jim_hwaccessInit+. Normally the `load` command +should not be used directly. Instead it is invoked automatically by `package require`. + +lrange +~~~~~~ ++*lrange* 'list first last'+ + ++'list'+ must be a valid Tcl list. This command will return a new +list consisting of elements +'first'+ through +'last'+, inclusive. + +See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'first'+ and +'last'+. + +If +'last'+ is greater than or equal to the number of elements +in the list, then it is treated as if it were +end+. + +If +'first'+ is greater than +'last'+ then an empty string +is returned. + +Note: +"`lrange` 'list first first'"+ does not always produce the +same result as +"`lindex` 'list first'"+ (although it often does +for simple fields that aren't enclosed in braces); it does, however, +produce exactly the same results as +"`list` [`lindex` 'list first']"+ + +lreplace +~~~~~~~~ + ++*lreplace* 'list first last ?element element \...?'+ + +Returns a new list formed by replacing one or more elements of ++'list'+ with the +'element'+ arguments. + ++'first'+ gives the index in +'list'+ of the first element +to be replaced. + +If +'first'+ is less than zero then it refers to the first +element of +'list'+; the element indicated by +'first'+ +must exist in the list. + ++'last'+ gives the index in +'list'+ of the last element +to be replaced; it must be greater than or equal to +'first'+. + +See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'first'+ and +'last'+. + +The +'element'+ arguments specify zero or more new arguments to +be added to the list in place of those that were deleted. + +Each +'element'+ argument will become a separate element of +the list. + +If no +'element'+ arguments are specified, then the elements +between +'first'+ and +'last'+ are simply deleted. + +lrepeat +~~~~~~~~ ++*lrepeat* 'number element1 ?element2 \...?'+ + +Build a list by repeating elements +'number'+ times (which must be +a positive integer). + + jim> lrepeat 3 a b + a b a b a b + +lreverse +~~~~~~~~ ++*lreverse* 'list'+ + +Returns the list in reverse order. + + jim> lreverse {1 2 3} + 3 2 1 + +lsearch +~~~~~~~ ++*lsearch* '?options? list pattern'+ + +This command searches the elements +'list'+ to see if one of them matches +'pattern'+. If so, the +command returns the index of the first matching element (unless the options +-all+, +-inline+ or +-bool+ are +specified.) If not, the command returns -1. The option arguments indicates how the elements of +the list are to be matched against pattern and must have one of the values below: + +*Note* that this command is different from Tcl in that default match type is +-exact+ rather than +-glob+. + ++*-exact*+:: + +'pattern'+ is a literal string that is compared for exact equality against each list element. + This is the default. + ++*-glob*+:: + +'pattern'+ is a glob-style pattern which is matched against each list element using the same + rules as the string match command. + ++*-regexp*+:: + +'pattern'+ is treated as a regular expression and matched against each list element using + the rules described by `regexp`. + ++*-command* 'cmdname'+:: + +'cmdname'+ is a command which is used to match the pattern against each element of the + list. It is invoked as +'cmdname' ?*-nocase*? 'pattern listvalue'+ and should return 1 + for a match, or 0 for no match. + ++*-all*+:: + Changes the result to be the list of all matching indices (or all matching values if + +-inline+ is specified as well). If indices are returned, the indices will be in numeric + order. If values are returned, the order of the values will be the order of those values + within the input list. + ++*-inline*+:: + The matching value is returned instead of its index (or an empty string if no value + matches). If +-all+ is also specified, then the result of the command is the list of all + values that matched. The +-inline+ and +-bool+ options are mutually exclusive. + ++*-bool*+:: + Changes the result to '1' if a match was found, or '0' otherwise. If +-all+ is also specified, + the result will be a list of '0' and '1' for each element of the list depending upon whether + the corresponding element matches. The +-inline+ and +-bool+ options are mutually exclusive. + ++*-not*+:: + This negates the sense of the match, returning the index (or value + if +-inline+ is specified) of the first non-matching value in the + list. If +-bool+ is also specified, the '0' will be returned if a + match is found, or '1' otherwise. If +-all+ is also specified, + non-matches will be returned rather than matches. + ++*-nocase*+:: + Causes comparisons to be handled in a case-insensitive manner. + +lsort +~~~~~ ++*lsort* ?*-index* 'listindex'? ?*-integer*|*-command* 'cmdname'? ?*-decreasing*|*-increasing*? 'list'+ + +Sort the elements of +'list'+, returning a new list in sorted order. +By default, ASCII sorting is used, with the result in increasing order. + +If +-integer+ is specified, numeric sorting is used. + +If +-command 'cmdname'+ is specified, +'cmdname'+ is treated as a command +name. For each comparison, +'cmdname $value1 $value2+' is called which +should compare the values and return an integer less than, equal +to, or greater than zero if the +'$value1'+ is to be considered less +than, equal to, or greater than +'$value2'+, respectively. + +If +-decreasing+ is specified, the resulting list is in the opposite +order to what it would be otherwise. +-increasing+ is the default. + +If +-index 'listindex'+ is specified, each element of the list is treated as a list and +the given index is extracted from the list for comparison. The list index may +be any valid list index, such as +1+, +end+ or +end-2+. + +If +-index 'listindex'+ is specified, each element of the list is treated as a list and +the given index is extracted from the list for comparison. The list index may +be any valid list index, such as +1+, +end+ or +end-2+. + +open +~~~~ ++*open* 'fileName ?access?'+ + ++*open* '|command-pipeline ?access?'+ + +Opens a file and returns an identifier +that may be used in future invocations +of commands like `read`, `puts`, and `close`. ++'fileName'+ gives the name of the file to open. + +The +'access'+ argument indicates the way in which the file is to be accessed. +It may have any of the following values: + ++r+:: + Open the file for reading only; the file must already exist. + ++r++:: + Open the file for both reading and writing; the file must + already exist. + ++w+:: + Open the file for writing only. Truncate it if it exists. If it doesn't + exist, create a new file. + ++w++:: + Open the file for reading and writing. Truncate it if it exists. + If it doesn't exist, create a new file. + ++a+:: + Open the file for writing only. The file must already exist, and the file + is positioned so that new data is appended to the file. + ++a++:: + Open the file for reading and writing. If the file doesn't + exist, create a new empty file. Set the initial access position + to the end of the file. + ++'access'+ defaults to 'r'. + +If a file is opened for both reading and writing, then `seek` +must be invoked between a read and a write, or vice versa. + +If the first character of +'fileName'+ is "|" then the remaining +characters of +'fileName'+ are treated as a list of arguments that +describe a command pipeline to invoke, in the same style as the +arguments for exec. In this case, the channel identifier returned +by open may be used to write to the command's input pipe or read +from its output pipe, depending on the value of +'access'+. If write-only +access is used (e.g. +'access'+ is 'w'), then standard output for the +pipeline is directed to the current standard output unless overridden +by the command. If read-only access is used (e.g. +'access'+ is r), +standard input for the pipeline is taken from the current standard +input unless overridden by the command. + +The `pid` command may be used to return the process ids of the commands +forming the command pipeline. + +See also `socket`, `pid`, `exec` + +package +~~~~~~~ ++*package provide* 'name ?version?'+ + +Indicates that the current script provides the package named +'name'+. +If no version is specified, '1.0' is used. + +Any script which provides a package may include this statement +as the first statement, although it is not required. + ++*package require* 'name ?version?'*+ + +Searches for the package with the given +'name'+ by examining each path +in '$::auto_path' and trying to load '$path/$name.so' as a dynamic extension, +or '$path/$name.tcl' as a script package. + +The first such file which is found is considered to provide the the package. +(The version number is ignored). + +If '$name.so' exists, it is loaded with the `load` command, +otherwise if '$name.tcl' exists it is loaded with the `source` command. + +If `load` or `source` fails, `package require` will fail immediately. +No further attempt will be made to locate the file. + +pid +~~~ ++*pid*+ + ++*pid* 'fileId'+ + +The first form returns the process identifier of the current process. + +The second form accepts a handle returned by `open` and returns a list +of the process ids forming the pipeline in the same form as `exec ... &`. +If 'fileId' represents a regular file handle rather than a command pipeline, +the empty string is returned instead. + +See also `open`, `exec` + +proc +~~~~ ++*proc* 'name args ?statics? body'+ + +The `proc` command creates a new Tcl command procedure, +'name'+. +When the new command is invoked, the contents of +'body'+ will be executed. +Tcl interpreter. +'args'+ specifies the formal arguments to the procedure. +If specified, +'static'+, declares static variables which are bound to the +procedure. + +See PROCEDURES for detailed information about Tcl procedures. + +The `proc` command returns +'name'+ (which is useful with `local`). + +When a procedure is invoked, the procedure's return value is the +value specified in a `return` command. If the procedure doesn't +execute an explicit `return`, then its return value is the value +of the last command executed in the procedure's body. + +If an error occurs while executing the procedure body, then the +procedure-as-a-whole will return that same error. + +puts +~~~~ ++*puts* ?*-nonewline*? '?fileId? string'+ + ++'fileId' *puts* ?*-nonewline*? 'string'+ + +Writes the characters given by +'string'+ to the file given +by +'fileId'+. +'fileId'+ must have been the return +value from a previous call to `open`, or it may be ++stdout+ or +stderr+ to refer to one of the standard I/O +channels; it must refer to a file that was opened for +writing. + +In the first form, if no +'fileId'+ is specified then it defaults to +stdout+. +`puts` normally outputs a newline character after +'string'+, +but this feature may be suppressed by specifying the +-nonewline+ +switch. + +Output to files is buffered internally by Tcl; the `flush` +command may be used to force buffered characters to be output. + +pwd +~~~ ++*pwd*+ + +Returns the path name of the current working directory. + +rand +~~~~ ++*rand* '?min? ?max?'+ + +Returns a random integer between +'min'+ (defaults to 0) and +'max'+ +(defaults to the maximum integer). + +If only one argument is given, it is interpreted as +'max'+. + +range +~~~~ ++*range* '?start? end ?step?'+ + +Returns a list of integers starting at +'start'+ (defaults to 0) +and ranging up to but not including +'end'+ in steps of +'step'+ defaults to 1). + + jim> range 5 + 0 1 2 3 4 + jim> range 2 5 + 2 3 4 + jim> range 2 10 4 + 2 6 + jim> range 7 4 -2 + 7 5 + +read +~~~~ ++*read* ?*-nonewline*? 'fileId'+ + ++'fileId' *read* ?*-nonewline*?+ + ++*read* 'fileId numBytes'+ + ++'fileId' *read* 'numBytes'+ + + +In the first form, all of the remaining bytes are read from the file +given by +'fileId'+; they are returned as the result of the command. +If the +-nonewline+ switch is specified then the last +character of the file is discarded if it is a newline. + +In the second form, the extra argument specifies how many bytes to read; +exactly this many bytes will be read and returned, unless there are fewer than ++'numBytes'+ bytes left in the file; in this case, all the remaining +bytes are returned. + ++'fileId'+ must be +stdin+ or the return value from a previous call +to `open`; it must refer to a file that was opened for reading. + +regexp +~~~~~~ ++*regexp ?-nocase? ?-line? ?-indices? ?-start* 'offset'? *?-all? ?-inline? ?--?* 'exp string ?matchVar? ?subMatchVar subMatchVar \...?'+ + +Determines whether the regular expression +'exp'+ matches part or +all of +'string'+ and returns 1 if it does, 0 if it doesn't. + +See REGULAR EXPRESSIONS above for complete information on the +syntax of +'exp'+ and how it is matched against +'string'+. + +If additional arguments are specified after +'string'+ then they +are treated as the names of variables to use to return +information about which part(s) of +'string'+ matched +'exp'+. ++'matchVar'+ will be set to the range of +'string'+ that +matched all of +'exp'+. The first +'subMatchVar'+ will contain +the characters in +'string'+ that matched the leftmost parenthesized +subexpression within +'exp'+, the next +'subMatchVar'+ will +contain the characters that matched the next parenthesized +subexpression to the right in +'exp'+, and so on. + +Normally, +'matchVar'+ and the each +'subMatchVar'+ are set to hold the +matching characters from `string`, however see +-indices+ and ++-inline+ below. + +If there are more values for +'subMatchVar'+ than parenthesized subexpressions +within +'exp'+, or if a particular subexpression in +'exp'+ doesn't +match the string (e.g. because it was in a portion of the expression +that wasn't matched), then the corresponding +'subMatchVar'+ will be +set to +"-1 -1"+ if +-indices+ has been specified or to an empty +string otherwise. + +The following switches modify the behaviour of +'regexp'+ + ++*-nocase*+:: + Causes upper-case and lower-case characters to be treated as + identical during the matching process. + ++*-line*+:: + Use newline-sensitive matching. By default, newline + is a completely ordinary character with no special meaning in + either REs or strings. With this flag, +[^+ bracket expressions + and +.+ never match newline, a +^+ anchor matches the null + string after any newline in the string in addition to its normal + function, and the +$+ anchor matches the null string before any + newline in the string in addition to its normal function. + ++*-indices*+:: + Changes what is stored in the subMatchVars. Instead of + storing the matching characters from string, each variable + will contain a list of two decimal strings giving the indices + in string of the first and last characters in the matching + range of characters. + ++*-start* 'offset'+:: + Specifies a character index offset into the string at which to start + matching the regular expression. If +-indices+ is + specified, the indices will be indexed starting from the + absolute beginning of the input string. +'offset'+ will be + constrained to the bounds of the input string. + ++*-all*+:: + Causes the regular expression to be matched as many times as possible + in the string, returning the total number of matches found. If this + is specified with match variables, they will contain information + for the last match only. + ++*-inline*+:: + Causes the command to return, as a list, the data that would otherwise + be placed in match variables. When using +-inline+, match variables + may not be specified. If used with +-all+, the list will be concatenated + at each iteration, such that a flat list is always returned. For + each match iteration, the command will append the overall match + data, plus one element for each subexpression in the regular + expression. + ++*--*+:: + Marks the end of switches. The argument following this one will be + treated as +'exp'+ even if it starts with a +-+. + +regsub +~~~~~~ ++*regsub ?-nocase? ?-all? ?-line? ?-start* 'offset'? ?*--*? 'exp string subSpec ?varName?'+ + +This command matches the regular expression +'exp'+ against ++'string'+ using the rules described in REGULAR EXPRESSIONS +above. + +If +'varName'+ is specified, the commands stores +'string'+ to +'varName'+ +with the substitutions detailed below, and returns the number of +substitutions made (normally 1 unless +-all+ is specified). +This is 0 if there were no matches. + +If +'varName'+ is not specified, the substituted string will be returned +instead. + +When copying +'string'+, the portion of +'string'+ that +matched +'exp'+ is replaced with +'subSpec'+. +If +'subSpec'+ contains a +&+ or +{backslash}0+, then it is replaced +in the substitution with the portion of +'string'+ that +matched +'exp'+. + +If +'subSpec'+ contains a +{backslash}n+, where +'n'+ is a digit +between 1 and 9, then it is replaced in the substitution with +the portion of +'string'+ that matched the +'n'+\'-th +parenthesized subexpression of +'exp'+. +Additional backslashes may be used in +'subSpec'+ to prevent special +interpretation of +&+ or +{backslash}0+ or +{backslash}n+ or +backslash. + +The use of backslashes in +'subSpec'+ tends to interact badly +with the Tcl parser's use of backslashes, so it's generally +safest to enclose +'subSpec'+ in braces if it includes +backslashes. + +The following switches modify the behaviour of +'regsub'+ + ++*-nocase*+:: + Upper-case characters in +'string'+ are converted to lower-case + before matching against +'exp'+; however, substitutions + specified by +'subSpec'+ use the original unconverted form + of +'string'+. + ++*-all*+:: + All ranges in +'string'+ that match +'exp'+ are found and substitution + is performed for each of these ranges, rather than only the + first. The +&+ and +{backslash}n+ sequences are handled for + each substitution using the information from the corresponding + match. + ++*-line*+:: + Use newline-sensitive matching. By default, newline + is a completely ordinary character with no special meaning in + either REs or strings. With this flag, +[^+ bracket expressions + and +.+ never match newline, a +^+ anchor matches the null + string after any newline in the string in addition to its normal + function, and the +$+ anchor matches the null string before any + newline in the string in addition to its normal function. + ++*-start* 'offset'+:: + Specifies a character index offset into the string at which to + start matching the regular expression. +'offset'+ will be + constrained to the bounds of the input string. + ++*--*+:: + Marks the end of switches. The argument following this one will be + treated as +'exp'+ even if it starts with a +-+. + +ref +~~~ ++*ref* 'string tag ?finalizer?'+ + +Create a new reference containing +'string'+ of type +'tag'+. +If +'finalizer'+ is specified, it is a command which will be invoked +when the a garbage collection cycle runs and this reference is +no longer accessible. + +The finalizer is invoked as: + + finalizer reference string + +See GARBAGE COLLECTION, REFERENCES, LAMBDA for more detail. + +rename +~~~~~~ ++*rename* 'oldName newName'+ + +Rename the command that used to be called +'oldName'+ so that it +is now called +'newName'+. If +'newName'+ is an empty string +(e.g. {}) then +'oldName'+ is deleted. The `rename` command +returns an empty string as result. + +return +~~~~~~ ++*return* ?*-code* 'code'? ?*-errorinfo* 'stacktrace'? ?*-errorcode* 'errorcode'? ?*-level* 'n'? ?'value'?+ + +Return immediately from the current procedure (or top-level command +or `source` command), with +'value'+ as the return value. If +'value'+ +is not specified, an empty string will be returned as result. + +If +-code+ is specified (as either a number or ok, error, break, +continue, signal, return or exit), this code will be used instead +of +JIM_OK+. This is generally useful when implementing flow of control +commands. + +If +-level+ is specified and greater than 1, it has the effect of delaying +the new return code from +-code+. This is useful when rethrowing an error +from `catch`. See the implementation of try/catch in tclcompat.tcl for +an example of how this is done. + +Note: The following options are only used when +-code+ is JIM_ERR. + +If +-errorinfo+ is specified (as returned from `info stacktrace`) +it is used to initialize the stacktrace. + +If +-errorcode+ is specified, it is used to set the global variable $::errorCode. + +scan +~~~~ ++*scan* 'string format varName1 ?varName2 \...?'+ + +This command parses fields from an input string in the same fashion +as the C 'sscanf' procedure. +'string'+ gives the input to be parsed +and +'format'+ indicates how to parse it, using '%' fields as in +'sscanf'. All of the 'sscanf' options are valid; see the 'sscanf' +man page for details. Each +'varName'+ gives the name of a variable; +when a field is scanned from +'string'+, the result is converted back +into a string and assigned to the corresponding +'varName'+. The +only unusual conversion is for '%c'. For '%c' conversions a single +character value is converted to a decimal string, which is then +assigned to the corresponding +'varName'+; no field width may be +specified for this conversion. + +seek +~~~~ ++*seek* 'fileId offset ?origin?'+ + ++'fileId' *seek* 'offset ?origin?'+ + +Change the current access position for +'fileId'+. +The +'offset'+ and +'origin'+ arguments specify the position at +which the next read or write will occur for +'fileId'+. ++'offset'+ must be a number (which may be negative) and +'origin'+ +must be one of the following: + ++*start*+:: + The new access position will be +'offset'+ bytes from the start + of the file. + ++*current*+:: + The new access position will be +'offset'+ bytes from the current + access position; a negative +'offset'+ moves the access position + backwards in the file. + ++*end*+:: + The new access position will be +'offset'+ bytes from the end of + the file. A negative +'offset'+ places the access position before + the end-of-file, and a positive +'offset'+ places the access position + after the end-of-file. + +The +'origin'+ argument defaults to +start+. + ++'fileId'+ must have been the return value from a previous call to +`open`, or it may be +stdin+, +stdout+, or +stderr+ to refer to one +of the standard I/O channels. + +This command returns an empty string. + +set +~~~ ++*set* 'varName ?value?'+ + +Returns the value of variable +'varName'+. + +If +'value'+ is specified, then set the value of +'varName'+ to +'value'+, +creating a new variable if one doesn't already exist, and return +its value. + +If +'varName'+ contains an open parenthesis and ends with a +close parenthesis, then it refers to an array element: the characters +before the open parenthesis are the name of the array, and the characters +between the parentheses are the index within the array. +Otherwise +'varName'+ refers to a scalar variable. + +If no procedure is active, then +'varName'+ refers to a global +variable. + +If a procedure is active, then +'varName'+ refers to a parameter +or local variable of the procedure, unless the +'global'+ command +has been invoked to declare +'varName'+ to be global. + +The +::+ prefix may also be used to explicitly reference a variable +in the global scope. + +setref +~~~~~~ ++*setref* 'reference string'+ + +Store a new string in +'reference'+, replacing the existing string. +The reference must be a valid reference create with the `ref` +command. + +See GARBAGE COLLECTION, REFERENCES, LAMBDA for more detail. + +signal +~~~~~~ +Command for signal handling. + +See `kill` for the different forms which may be used to specify signals. + +Commands which return a list of signal names do so using the canonical form: +"+SIGINT SIGTERM+". + ++*signal handle* ?'signals \...'?+:: + If no signals are given, returns a list of all signals which are currently + being handled. + If signals are specified, these are added to the list of signals currently + being handled. + ++*signal ignore* ?'signals \...'?+:: + If no signals are given, returns a lists all signals which are currently + being ignored. + If signals are specified, these are added to the list of signals + currently being ignored. These signals are still delivered, but + are not considered by `catch -signal` or `try -signal`. Use + `signal check` to determine which signals have occurred but + been ignored. + ++*signal default* ?'signals \...'?+:: + If no signals are given, returns a lists all signals which are currently have + the default behaviour. + If signals are specified, these are added to the list of signals which have + the default behaviour. + ++*signal check ?-clear?* ?'signals \...'?+:: + Returns a list of signals which have been delivered to the process + but are 'ignored'. If signals are specified, only that set of signals will + be checked, otherwise all signals will be checked. + If +-clear+ is specified, any signals returned are removed and will not be + returned by subsequent calls to `signal check` unless delivered again. + ++*signal throw* ?'signal'?+:: + Raises the given signal, which defaults to +SIGINT+ if not specified. + The behaviour is identical to: + + kill signal [pid] + +Note that `signal handle` and `signal ignore` represent two forms of signal +handling. `signal handle` is used in conjunction with `catch -signal` or `try -signal` +to immediately abort execution when the signal is delivered. Alternatively, `signal ignore` +is used in conjunction with `signal check` to handle signal synchronously. Consider the +two examples below. + +Prevent a processing from taking too long + + signal handle SIGALRM + alarm 20 + try -signal { + .. possibly long running process .. + alarm 0 + } on signal {sig} { + puts stderr "Process took too long" + } + +Handle SIGHUP to reconfigure: + + signal ignore SIGHUP + while {1} { + ... handle configuration/reconfiguration ... + while {[signal check -clear SIGHUP] eq ""} { + ... do processing .. + } + # Received SIGHUP, so reconfigure + } + +sleep +~~~~~ ++*sleep* 'seconds'+ + +Pauses for the given number of seconds, which may be a floating +point value less than one to sleep for less than a second, or an +integer to sleep for one or more seconds. + +source +~~~~~~ ++*source* 'fileName'+ + +Read file +'fileName'+ and pass the contents to the Tcl interpreter +as a sequence of commands to execute in the normal fashion. The return +value of `source` is the return value of the last command executed +from the file. If an error occurs in executing the contents of the +file, then the `source` command will return that error. + +If a `return` command is invoked from within the file, the remainder of +the file will be skipped and the `source` command will return +normally with the result from the `return` command. + +split +~~~~~ ++*split* 'string ?splitChars?'+ + +Returns a list created by splitting +'string'+ at each character +that is in the +'splitChars'+ argument. + +Each element of the result list will consist of the +characters from +'string'+ between instances of the +characters in +'splitChars'+. + +Empty list elements will be generated if +'string'+ contains +adjacent characters in +'splitChars'+, or if the first or last +character of +'string'+ is in +'splitChars'+. + +If +'splitChars'+ is an empty string then each character of ++'string'+ becomes a separate element of the result list. + ++'splitChars'+ defaults to the standard white-space characters. +For example, + + split "comp.unix.misc" . + +returns +'"comp unix misc"'+ and + + split "Hello world" {} + +returns +'"H e l l o { } w o r l d"'+. + +stackdump +~~~~~~~~~ + ++*stackdump* 'stacktrace'+ + +Creates a human readable representation of a stack trace. + +stacktrace +~~~~~~~~~~ + ++*stacktrace*+ + +Returns a live stack trace as a list of +proc file line proc file line \...+. +Iteratively uses `info frame` to create the stack trace. This stack trace is in the +same form as produced by `catch` and `info stacktrace` + +See also `stackdump`. + +string +~~~~~~ + ++*string* 'option arg ?arg \...?'+ + +Perform one of several string operations, depending on +'option'+. +The legal options (which may be abbreviated) are: + ++*string bytelength* 'string'+:: + Returns the length of the string in bytes. This will return + the same value as `string length` if UTF-8 support is not enabled, + or if the string is composed entirely of ASCII characters. + See UTF-8 AND UNICODE. + ++*string byterange* 'string first last'+:: + Like `string range` except works on bytes rather than characters. + These commands are identical if UTF-8 support is not enabled. + ++*string compare ?-nocase?* ?*-length* 'len? string1 string2'+:: + Perform a character-by-character comparison of strings +'string1'+ and + +'string2'+ in the same way as the C 'strcmp' procedure. Return + -1, 0, or 1, depending on whether +'string1'+ is lexicographically + less than, equal to, or greater than +'string2'+. If +-length+ + is specified, then only the first +'len'+ characters are used + in the comparison. If +'len'+ is negative, it is ignored. + Performs a case-insensitive comparison if +-nocase+ is specified. + ++*string equal ?-nocase?* '?*-length* len?' 'string1 string2'+:: + Returns 1 if the strings are equal, or 0 otherwise. If +-length+ + is specified, then only the first +'len'+ characters are used + in the comparison. If +'len'+ is negative, it is ignored. + Performs a case-insensitive comparison if +-nocase+ is specified. + ++*string first* 'string1 string2 ?firstIndex?'+:: + Search +'string2'+ for a sequence of characters that exactly match + the characters in +'string1'+. If found, return the index of the + first character in the first such match within +'string2'+. If not + found, return -1. If +'firstIndex'+ is specified, matching will start + from +'firstIndex'+ of +'string1'+. + :: + See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'firstIndex'+. + ++*string index* 'string charIndex'+:: + Returns the +'charIndex'+'th character of the +'string'+ + argument. A +'charIndex'+ of 0 corresponds to the first + character of the string. + If +'charIndex'+ is less than 0 or greater than + or equal to the length of the string then an empty string is + returned. + :: + See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'charIndex'+. + ++*string is* 'class' ?*-strict*? 'string'+:: + Returns 1 if +'string'+ is a valid member of the specified character + class, otherwise returns 0. If +-strict+ is specified, then an + empty string returns 0, otherwise an empty string will return 1 + on any class. The following character classes are recognized + (the class name can be abbreviated): + :: + +alnum+;; Any alphabet or digit character. + +alpha+;; Any alphabet character. + +ascii+;; Any character with a value less than 128 (those that are in the 7-bit ascii range). + +control+;; Any control character. + +digit+;; Any digit character. + +double+;; Any of the valid forms for a double in Tcl, with optional surrounding whitespace. + In case of under/overflow in the value, 0 is returned. + +graph+;; Any printing character, except space. + +integer+;; Any of the valid string formats for an integer value in Tcl, with optional surrounding whitespace. + +lower+;; Any lower case alphabet character. + +print+;; Any printing character, including space. + +punct+;; Any punctuation character. + +space+;; Any space character. + +upper+;; Any upper case alphabet character. + +xdigit+;; Any hexadecimal digit character ([0-9A-Fa-f]). + :: + Note that string classification does +'not'+ respect UTF-8. See UTF-8 AND UNICODE + ++*string last* 'string1 string2 ?lastIndex?'+:: + Search +'string2'+ for a sequence of characters that exactly match + the characters in +'string1'+. If found, return the index of the + first character in the last such match within +'string2'+. If there + is no match, then return -1. If +'lastIndex'+ is specified, only characters + up to +'lastIndex'+ of +'string2'+ will be considered in the match. + :: + See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'lastIndex'+. + ++*string length* 'string'+:: + Returns a decimal string giving the number of characters in +'string'+. + If UTF-8 support is enabled, this may be different than the number of bytes. + See UTF-8 AND UNICODE + ++*string map ?-nocase?* 'mapping string'+:: + Replaces substrings in +'string'+ based on the key-value pairs in + +'mapping'+, which is a list of +key value key value \...+ as in the form + returned by `array get`. Each instance of a key in the string will be + replaced with its corresponding value. If +-nocase+ is specified, then + matching is done without regard to case differences. Both key and value may + be multiple characters. Replacement is done in an ordered manner, so the + key appearing first in the list will be checked first, and so on. +'string'+ is + only iterated over once, so earlier key replacements will have no affect for + later key matches. For example, + + string map {abc 1 ab 2 a 3 1 0} 1abcaababcabababc + + :: + will return the string +01321221+. + :: + Note that if an earlier key is a prefix of a later one, it will completely mask the later + one. So if the previous example is reordered like this, + + string map {1 0 ab 2 a 3 abc 1} 1abcaababcabababc + + :: + it will return the string +02c322c222c+. + ++*string match ?-nocase?* 'pattern string'+:: + See if +'pattern'+ matches +'string'+; return 1 if it does, 0 + if it doesn't. Matching is done in a fashion similar to that + used by the C-shell. For the two strings to match, their contents + must be identical except that the following special sequences + may appear in +'pattern'+: + + +*+;; + Matches any sequence of characters in +'string'+, + including a null string. + + +?+;; + Matches any single character in +'string'+. + + +['chars']+;; + Matches any character in the set given by +'chars'+. + If a sequence of the form +'x-y'+ appears in +'chars'+, + then any character between +'x'+ and +'y'+, inclusive, + will match. + + +{backslash}x+;; + Matches the single character +'x'+. This provides a way of + avoiding the special interpretation of the characters +{backslash}*?[]+ + in +'pattern'+. + :: + Performs a case-insensitive comparison if +-nocase+ is specified. + ++*string range* 'string first last'+:: + Returns a range of consecutive characters from +'string'+, starting + with the character whose index is +'first'+ and ending with the + character whose index is +'last'+. An index of 0 refers to the + first character of the string. + :: + See STRING AND LIST INDEX SPECIFICATIONS for all allowed forms for +'first'+ and +'last'+. + :: + If +'first'+ is less than zero then it is treated as if it were zero, and + if +'last'+ is greater than or equal to the length of the string then + it is treated as if it were +end+. If +'first'+ is greater than + +'last'+ then an empty string is returned. + ++*string repeat* 'string count'+:: + Returns a new string consisting of +'string'+ repeated +'count'+ times. + ++*string replace* 'string first last ?newstring?'+:: + Removes a range of consecutive characters from +'string'+, starting + with the character whose index is +'first'+ and ending with the + character whose index is +'last'+. If +'newstring'+ is specified, + then it is placed in the removed character range. If +'first'+ is + less than zero then it is treated as if it were zero, and if +'last'+ + is greater than or equal to the length of the string then it is + treated as if it were +end+. If +'first'+ is greater than +'last'+ + or the length of the initial string, or +'last'+ is less than 0, + then the initial string is returned untouched. + ++*string reverse* 'string'+:: + Returns a string that is the same length as +'string'+ but + with its characters in the reverse order. + ++*string tolower* 'string'+:: + Returns a value equal to +'string'+ except that all upper case + letters have been converted to lower case. + ++*string totitle* 'string'+:: + Returns a value equal to +'string'+ except that the first character + is converted to title case (or upper case if there is no UTF-8 titlecase variant) + and all remaining characters have been converted to lower case. + ++*string toupper* 'string'+:: + Returns a value equal to +'string'+ except that all lower case + letters have been converted to upper case. + ++*string trim* 'string ?chars?'+:: + Returns a value equal to +'string'+ except that any leading + or trailing characters from the set given by +'chars'+ are + removed. + If +'chars'+ is not specified then white space is removed + (spaces, tabs, newlines, and carriage returns). + ++*string trimleft* 'string ?chars?'+:: + Returns a value equal to +'string'+ except that any + leading characters from the set given by +'chars'+ are + removed. + If +'chars'+ is not specified then white space is removed + (spaces, tabs, newlines, and carriage returns). + ++*string trimright* 'string ?chars?'+:: + Returns a value equal to +'string'+ except that any + trailing characters from the set given by +'chars'+ are + removed. + If +'chars'+ is not specified then white space is removed + (spaces, tabs, newlines, and carriage returns). + Null characters are always removed. + +subst +~~~~~ ++*subst ?-nobackslashes? ?-nocommands? ?-novariables?* 'string'+ + +This command performs variable substitutions, command substitutions, +and backslash substitutions on its string argument and returns the +fully-substituted result. The substitutions are performed in exactly +the same way as for Tcl commands. As a result, the string argument +is actually substituted twice, once by the Tcl parser in the usual +fashion for Tcl commands, and again by the subst command. + +If any of the +-nobackslashes+, +-nocommands+, or +-novariables+ are +specified, then the corresponding substitutions are not performed. +For example, if +-nocommands+ is specified, no command substitution +is performed: open and close brackets are treated as ordinary +characters with no special interpretation. + +*Note*: when it performs its substitutions, subst does not give any +special treatment to double quotes or curly braces. For example, +the following script returns +xyz \{44\}+, not +xyz \{$a\}+. + + set a 44 + subst {xyz {$a}} + + +switch +~~~~~~ ++*switch* '?options? string pattern body ?pattern body \...?'+ + ++*switch* '?options? string {pattern body ?pattern body \...?}'+ + +The `switch` command matches its string argument against each of +the pattern arguments in order. As soon as it finds a pattern that +matches string it evaluates the following body and returns the +result of that evaluation. If the last pattern argument is default +then it matches anything. If no pattern argument matches string and +no default is given, then the `switch` command returns an empty string. +If the initial arguments to switch start with - then they are treated +as options. The following options are currently supported: + + +-exact+:: + Use exact matching when comparing string to a + pattern. This is the default. + + +-glob+:: + When matching string to the patterns, use glob-style + matching (i.e. the same as implemented by the string + match command). + + +-regexp+:: + When matching string to the patterns, use regular + expression matching (i.e. the same as implemented + by the regexp command). + + +-command 'commandname'+:: + When matching string to the patterns, use the given command, which + must be a single word. The command is invoked as + 'commandname pattern string', or 'commandname -nocase pattern string' + and must return 1 if matched, or 0 if not. + + +--+:: + Marks the end of options. The argument following + this one will be treated as string even if it starts + with a +-+. + +Two syntaxes are provided for the pattern and body arguments. The +first uses a separate argument for each of the patterns and commands; +this form is convenient if substitutions are desired on some of the +patterns or commands. The second form places all of the patterns +and commands together into a single argument; the argument must +have proper list structure, with the elements of the list being the +patterns and commands. The second form makes it easy to construct +multi-line `switch` commands, since the braces around the whole list +make it unnecessary to include a backslash at the end of each line. +Since the pattern arguments are in braces in the second form, no +command or variable substitutions are performed on them; this makes +the behaviour of the second form different than the first form in +some cases. + +If a body is specified as +-+ it means that the body for the next +pattern should also be used as the body for this pattern (if the +next pattern also has a body of +-+ then the body after that is +used, and so on). This feature makes it possible to share a single +body among several patterns. + +Below are some examples of `switch` commands: + + switch abc a - b {format 1} abc {format 2} default {format 3} + +will return 2, + + switch -regexp aaab { + ^a.*b$ - + b {format 1} + a* {format 2} + default {format 3} + } + +will return 1, and + + switch xyz { + a - + b {format 1} + a* {format 2} + default {format 3} + } + +will return 3. + +tailcall +~~~~~~~~ ++*tailcall* 'cmd ?arg\...?'+ + +The `tailcall` command provides an optimised way of invoking a command whilst replacing +the current call frame. This is similar to 'exec' in Bourne Shell. + +The following are identical except the first immediately replaces the current call frame. + + tailcall a b c + + return [uplevel 1 [list a b c]] + +`tailcall` is useful as a dispatch mechanism: + + proc a {cmd args} { + tailcall sub_$cmd {*}$args + } + proc sub_cmd1 ... + proc sub_cmd2 ... + +tell +~~~~ ++*tell* 'fileId'+ + ++'fileId' *tell*+ + +Returns a decimal string giving the current access position in ++'fileId'+. + ++'fileId'+ must have been the return value from a previous call to +`open`, or it may be +stdin+, +stdout+, or +stderr+ to refer to one +of the standard I/O channels. + +throw +~~~~~ ++*throw* 'code ?msg?'+ + +This command throws an exception (return) code along with an optional message. +This command is mostly for convenient usage with `try`. + +The command +throw break+ is equivalent to +break+. +The command +throw 20 message+ can be caught with an +on 20 \...+ clause to `try`. + +time +~~~~ ++*time* 'command ?count?'+ + +This command will call the Tcl interpreter +'count'+ +times to execute +'command'+ (or once if +'count'+ isn't +specified). It will then return a string of the form + + 503 microseconds per iteration + +which indicates the average amount of time required per iteration, +in microseconds. + +Time is measured in elapsed time, not CPU time. + +try +~~~ ++*try* '?catchopts? tryscript' ?*on* 'returncodes {?resultvar? ?optsvar?} handlerscript \...'? ?*finally* 'finalscript'?+ + +The `try` command is provided as a convenience for exception handling. + +This interpeter first evaluates +'tryscript'+ under the effect of the catch +options +'catchopts'+ (e.g. +-signal -noexit --+, see `catch`). + +It then evaluates the script for the first matching 'on' handler +(there many be zero or more) based on the return code from the `try` +section. For example a normal +JIM_ERR+ error will be matched by +an 'on error' handler. + +Finally, any +'finalscript'+ is evaluated. + +The result of this command is the result of +'tryscript'+, except in the +case where an exception occurs in a matching 'on' handler script or the 'finally' script, +in which case the result is this new exception. + +The specified +'returncodes'+ is a list of return codes either as names ('ok', 'error', 'break', etc.) +or as integers. + +If +'resultvar'+ and +'optsvar'+ are specified, they are set as for `catch` before evaluating +the matching handler. + +For example: + + set f [open input] + try -signal { + process $f + } on {continue break} {} { + error "Unexpected break/continue" + } on error {msg opts} { + puts "Dealing with error" + return {*}$opts $msg + } on signal sig { + puts "Got signal: $sig" + } finally { + $f close + } + +If break, continue or error are raised, they are dealt with by the matching +handler. + +In any case, the file will be closed via the 'finally' clause. + +See also `throw`, `catch`, `return`, `error`. + +unknown +~~~~~~~ ++*unknown* 'cmdName ?arg arg ...?'+ + +This command doesn't actually exist as part of Tcl, but Tcl will +invoke it if it does exist. + +If the Tcl interpreter encounters a command name for which there +is not a defined command, then Tcl checks for the existence of +a command named `unknown`. + +If there is no such command, then the interpreter returns an +error. + +If the `unknown` command exists, then it is invoked with +arguments consisting of the fully-substituted name and arguments +for the original non-existent command. + +The `unknown` command typically does things like searching +through library directories for a command procedure with the name ++'cmdName'+, or expanding abbreviated command names to full-length, +or automatically executing unknown commands as UNIX sub-processes. + +In some cases (such as expanding abbreviations) `unknown` will +change the original command slightly and then (re-)execute it. +The result of the `unknown` command is used as the result for +the original non-existent command. + +unset +~~~~~ ++*unset ?-nocomplain? ?--?* '?name name ...?'+ + +Remove variables. +Each +'name'+ is a variable name, specified in any of the +ways acceptable to the `set` command. + +If a +'name'+ refers to an element of an array, then that +element is removed without affecting the rest of the array. + +If a +'name'+ consists of an array name with no parenthesized +index, then the entire array is deleted. + +The `unset` command returns an empty string as result. + +An error occurs if any of the variables doesn't exist, unless '-nocomplain' +is specified. The '--' argument may be specified to stop option processing +in case the variable name may be '-nocomplain'. + +upcall +~~~~~~~ ++*upcall* 'command ?args ...?'+ + +May be used from within a proc defined as `local` `proc` in order to call +the previous, hidden version of the same command. + +If there is no previous definition of the command, an error is returned. + +uplevel +~~~~~~~ ++*uplevel* '?level? command ?command ...?'+ + +All of the +'command'+ arguments are concatenated as if they had +been passed to `concat`; the result is then evaluated in the +variable context indicated by +'level'+. `uplevel` returns +the result of that evaluation. If +'level'+ is an integer, then +it gives a distance (up the procedure calling stack) to move before +executing the command. If +'level'+ consists of +\#+ followed by +a number then the number gives an absolute level number. If +'level'+ +is omitted then it defaults to +1+. +'level'+ cannot be +defaulted if the first +'command'+ argument starts with a digit or +#+. + +For example, suppose that procedure 'a' was invoked +from top-level, and that it called 'b', and that 'b' called 'c'. +Suppose that 'c' invokes the `uplevel` command. If +'level'+ +is +1+ or +#2+ or omitted, then the command will be executed +in the variable context of 'b'. If +'level'+ is +2+ or +#1+ +then the command will be executed in the variable context of 'a'. + +If +'level'+ is '3' or +#0+ then the command will be executed +at top-level (only global variables will be visible). +The `uplevel` command causes the invoking procedure to disappear +from the procedure calling stack while the command is being executed. +In the above example, suppose 'c' invokes the command + + uplevel 1 {set x 43; d} + +where 'd' is another Tcl procedure. The `set` command will +modify the variable 'x' in 'b's context, and 'd' will execute +at level 3, as if called from 'b'. If it in turn executes +the command + + uplevel {set x 42} + +then the `set` command will modify the same variable 'x' in 'b's +context: the procedure 'c' does not appear to be on the call stack +when 'd' is executing. The command `info level` may +be used to obtain the level of the current procedure. + +`uplevel` makes it possible to implement new control +constructs as Tcl procedures (for example, `uplevel` could +be used to implement the `while` construct as a Tcl procedure). + +upvar +~~~~~ ++*upvar* '?level? otherVar myVar ?otherVar myVar ...?'+ + +This command arranges for one or more local variables in the current +procedure to refer to variables in an enclosing procedure call or +to global variables. + ++'level'+ may have any of the forms permitted for the `uplevel` +command, and may be omitted if the first letter of the first +'otherVar'+ +isn't +#+ or a digit (it defaults to '1'). + +For each +'otherVar'+ argument, `upvar` makes the variable +by that name in the procedure frame given by +'level'+ (or at +global level, if +'level'+ is +#0+) accessible +in the current procedure by the name given in the corresponding ++'myVar'+ argument. + +The variable named by +'otherVar'+ need not exist at the time of the +call; it will be created the first time +'myVar'+ is referenced, just like +an ordinary variable. + +`upvar` may only be invoked from within procedures. + +`upvar` returns an empty string. + +The `upvar` command simplifies the implementation of call-by-name +procedure calling and also makes it easier to build new control constructs +as Tcl procedures. +For example, consider the following procedure: + + proc add2 name { + upvar $name x + set x [expr $x+2] + } + +'add2' is invoked with an argument giving the name of a variable, +and it adds two to the value of that variable. +Although 'add2' could have been implemented using `uplevel` +instead of `upvar`, `upvar` makes it simpler for 'add2' +to access the variable in the caller's procedure frame. + +while +~~~~~ ++*while* 'test body'+ + +The +'while'+ command evaluates +'test'+ as an expression +(in the same way that `expr` evaluates its argument). +The value of the expression must be numeric; if it is non-zero +then +'body'+ is executed by passing it to the Tcl interpreter. + +Once +'body'+ has been executed then +'test'+ is evaluated +again, and the process repeats until eventually +'test'+ +evaluates to a zero numeric value. `continue` +commands may be executed inside +'body'+ to terminate the current +iteration of the loop, and `break` +commands may be executed inside +'body'+ to cause immediate +termination of the `while` command. + +The `while` command always returns an empty string. + +OPTIONAL-EXTENSIONS +------------------- + +The following extensions may or may not be available depending upon +what options were selected when Jim Tcl was built. + +[[cmd_1]] +posix: os.fork, os.wait, os.gethostname, os.getids, os.uptime +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++*os.fork*+:: + Invokes 'fork(2)' and returns the result. + ++*os.wait -nohang* 'pid'+:: + Invokes waitpid(2), with WNOHANG if +-nohang+ is specified. + Returns a list of 3 elements. + + {0 none 0} if -nohang is specified, and the process is still alive. + + {-1 error } if the process does not exist or has already been waited for. + + { exit } if the process exited normally. + + { signal } if the process terminated on a signal. + + { other 0} otherwise (core dump, stopped, continued, etc.) + ++*os.gethostname*+:: + Invokes 'gethostname(3)' and returns the result. + ++*os.getids*+:: + Returns the various user/group ids for the current process. + + jim> os.getids + uid 1000 euid 1000 gid 100 egid 100 + ++*os.uptime*+:: + Returns the number of seconds since system boot. See description of 'uptime' in 'sysinfo(2)'. + +ANSI I/O (aio) and EVENTLOOP API +-------------------------------- +Jim provides an alternative object-based API for I/O. + +See `open` and `socket` for commands which return an I/O handle. + +aio +~~~ ++$handle *read ?-nonewline?* '?len?'+:: + Read and return bytes from the stream. To eof if no len. + ++$handle *gets* '?var?'+:: + Read one line and return it or store it in the var + ++$handle *puts ?-nonewline?* 'str'+:: + Write the string, with newline unless -nonewline + ++$handle *copyto* 'tofd ?size?'+:: + Copy bytes to the file descriptor +'tofd'+. If +'size'+ is specified, at most + that many bytes will be copied. Otherwise copying continues until the end + of the input file. Returns the number of bytes actually copied. + ++$handle *flush*+:: + Flush the stream + ++$handle *filename*+:: + Returns the original filename associated with the handle. + Handles returned by `socket` give the socket type instead of a filename. + ++$handle *eof*+:: + Returns 1 if stream is at eof + ++$handle *close*+:: + Closes the stream + ++$handle *seek* 'offset' *?start|current|end?*+:: + Seeks in the stream (default 'current') + ++$handle *tell*+:: + Returns the current seek position + ++$handle *filename*+:: + Returns the original filename used when opening the file. + If the handle was returned from `socket`, the type of the + handle is returned instead. + ++$handle *ndelay ?0|1?*+:: + Set O_NDELAY (if arg). Returns current/new setting. + Note that in general ANSI I/O interacts badly with non-blocking I/O. + Use with care. + ++$handle *buffering none|line|full*+:: + Sets the buffering mode of the stream. + ++$handle *accept*+:: + Server socket only: Accept a connection and return stream + ++$handle *sendto* 'str ?hostname:?port'+:: + Sends the string, +'str'+, to the given address via the socket using sendto(2). + This is intended for udp sockets and may give an error or behave in unintended + ways for other handle types. + Returns the number of bytes written. + ++$handle *recvfrom* 'maxlen ?addrvar?'+:: + Receives a message from the handle via recvfrom(2) and returns it. + At most +'maxlen'+ bytes are read. + If +'addrvar'+ is specified, the sending address of the message is stored in + the named variable in the form 'addr:port'. See `socket` for details. + +fconfigure +~~~~~~~~~~ ++*fconfigure* 'handle' *?-blocking 0|1? ?-buffering noneline|full? ?-translation* 'mode'?+:: + For compatibility with Tcl, a limited form of the `fconfigure` + command is supported. + * `fconfigure ... -blocking` maps to `aio ndelay` + * `fconfigure ... -buffering` maps to `aio buffering` + * `fconfigure ... -translation` is accepted but ignored + +[[cmd_2]] +eventloop: after, vwait, update +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following commands allow a script to be invoked when the given condition occurs. +If no script is given, returns the current script. If the given script is the empty, the +handler is removed. + ++$handle *readable* '?readable-script?'+:: + Sets or returns the script for when the socket is readable. + ++$handle *writable* '?writable-script?'+:: + Sets or returns the script for when the socket is writable. + ++$handle *onexception* '?exception-script?'+:: + Sets or returns the script for when when oob data received. + +For compatibility with 'Tcl', these may be prefixed with `fileevent`. e.g. + + :: + +fileevent $handle *readable* '\...'+ + +Time-based execution is also available via the eventloop API. + ++*after* 'ms'+:: + Sleeps for the given number of milliseconds. No events are + processed during this time. + ++*after* 'ms'|*idle* script ?script \...?'+:: + The scripts are concatenated and executed after the given + number of milliseconds have elapsed. If 'idle' is specified, + the script will run the next time the event loop is processed + with `vwait` or `update`. The script is only run once and + then removed. Returns an event id. + ++*after cancel* 'id|command'+:: + Cancels an `after` event with the given event id or matching + command (script). Returns the number of milliseconds + remaining until the event would have fired. Returns the + empty string if no matching event is found. + ++*after info* '?id?'+:: + If +'id'+ is not given, returns a list of current `after` + events. If +'id'+ is given, returns a list containing the + associated script and either 'timer' or 'idle' to indicated + the type of the event. An error occurs if +'id'+ does not + match an event. + ++*vwait* 'variable'+:: + A call to `vwait` is enters the eventloop. `vwait` processes + events until the named (global) variable changes or all + event handlers are removed. The variable need not exist + beforehand. If there are no event handlers defined, `vwait` + returns immediately. + ++*update ?idletasks?*+:: + A call to `update` enters the eventloop to process expired events, but + no new events. If 'idletasks' is specified, only expired time events are handled, + not file events. + Returns once handlers have been run for all expired events. + +Scripts are executed at the global scope. If an error occurs during a handler script, +an attempt is made to call (the user-defined command) `bgerror` with the details of the error. +If the `bgerror` commands does not exist, it is printed to stderr instead. + +If a file event handler script generates an error, the handler is automatically removed +to prevent infinite errors. (A time event handler is always removed after execution). + ++*bgerror* 'error'+:: + Called when an event handler script generates an error. + +socket +~~~~~~ +Various socket types may be created. + ++*socket unix* 'path'+:: + A unix domain socket client. + ++*socket unix.server* 'path'+:: + A unix domain socket server. + ++*socket ?-ipv6? stream* 'addr:port'+:: + A TCP socket client. + ++*socket ?-ipv6? stream.server* '?addr:?port'+:: + A TCP socket server (+'addr'+ defaults to +0.0.0.0+ for IPv4 or +[::]+ for IPv6). + ++*socket ?-ipv6? dgram* ?'addr:port'?+:: + A UDP socket client. If the address is not specified, + the client socket will be unbound and 'sendto' must be used + to indicated the destination. + ++*socket ?-ipv6? dgram.server* 'addr:port'+:: + A UDP socket server. + ++*socket pipe*+:: + A pipe. Note that unlike all other socket types, this command returns + a list of two channels: {read write} + +This command creates a socket connected (client) or bound (server) to the given +address. + +The returned value is channel and may generally be used with the various file I/O +commands (gets, puts, read, etc.), either as object-based syntax or Tcl-compatible syntax. + + set f [socket stream www.google.com:80] + aio.sockstream1 + $f puts -nonewline "GET / HTTP/1.0\r\n\r\n" + $f gets + HTTP/1.0 302 Found + $f close + +Server sockets, however support only 'accept', which is most useful in conjunction with +the EVENTLOOP API. + + set f [socket stream.server 80] + $f readable { + set client [$f accept] + $client gets $buf + ... + $client puts -nonewline "HTTP/1.1 404 Not found\r\n" + $client close + } + vwait done + +The address, +'addr'+, can be given in one of the following forms: + +1. For IPv4 socket types, an IPv4 address such as 192.168.1.1 +2. For IPv6 socket types, an IPv6 address such as [fe80::1234] or [::] +3. A hostname + +Note that on many systems, listening on an IPv6 address such as [::] will +also accept requests via IPv4. + +Where a hostname is specified, the +'first'+ returned address is used +which matches the socket type is used. + +The special type 'pipe' isn't really a socket. + + lassign [socket pipe] r w + + # Must close $w after exec + exec ps >@$w & + $w close + + $r readable ... + +syslog +~~~~~~ ++*syslog* '?options? ?priority? message'+ + +This command sends message to system syslog facility with given +priority. Valid priorities are: + + emerg, alert, crit, err, error, warning, notice, info, debug + +If a message is specified, but no priority is specified, then a +priority of info is used. + +By default, facility user is used and the value of global tcl variable +argv0 is used as ident string. However, any of the following options +may be specified before priority to control these parameters: + ++*-facility* 'value'+:: + Use specified facility instead of user. The following + values for facility are recognized: + + authpriv, cron, daemon, kernel, lpr, mail, news, syslog, user, + uucp, local0-local7 + ++*-ident* 'string'+:: + Use given string instead of argv0 variable for ident string. + ++*-options* 'integer'+:: + Set syslog options such as +LOG_CONS+, +LOG_NDELAY+. You should + use numeric values of those from your system syslog.h file, + because I haven't got time to implement yet another hash + table. + +pack: pack, unpack +~~~~~~~~~~~~~~~~~~ +The optional 'pack' extension provides commands to encode and decode binary strings. + ++*pack* 'varName value' *-intle|-intbe|-str* 'bitwidth ?bitoffset?'+:: + Packs the binary representation of +'value'+ into the variable + +'varName'+. The value is packed according to the given type + (integer/string, big-endian/little-endian), width and bit offset. + The variable is created if necessary (like `append`). + Ihe variable is expanded if necessary. + ++*unpack* 'binvalue' *-intbe|-intle|-uintbe|-uintle|-str* 'bitpos bitwidth'+:: + Unpacks bits from +'binvalue'+ at bit position +'bitpos'+ and with +'bitwidth'+. + Interprets the value according to the type (integer/string, big-endian/little-endian + and signed/unsigned) and returns it. For integer types, +'bitwidth'+ + may be up to the size of a Jim Tcl integer (typically 64 bits). For the string type, + both the width and the offset must be on a byte boundary (multiple of 8). Attempting to + access outside the length of the value will return 0 for integer types or the empty string + for the string type. + +binary +~~~~~~ +The optional, pure-Tcl 'binary' extension provides the Tcl-compatible `binary scan` and `binary format` +commands based on the low-level `pack` and `unpack` commands. + +See the Tcl documentation at: http://www.tcl.tk/man/tcl8.5/TclCmd/binary.htm + +Note that packing and unpacking of floating point values is not supported. + +oo: class, super +~~~~~~~~~~~~~~~~ +The optional, pure-Tcl 'oo' extension provides object-oriented (OO) support for Jim Tcl. + +See the online documentation (http://jim.berlios.de/documentation/oo/) for more details. + ++*class* 'classname ?baseclasses? classvars'+:: + Create a new class, +'classname'+, with the given dictionary + (+'classvars'+) as class variables. These are the initial variables + which all newly created objects of this class are initialised with. + If a list of baseclasses is given, methods and instance variables + are inherited. + ++*super* 'method ?args \...?'+:: + From within a method, invokes the given method on the base class. + Note that this will only call the last baseclass given. + +tree +~~~~ +The optional, pure-Tcl 'tree' extension implements an OO, general purpose tree structure +similar to that provided by tcllib ::struct::tree (http://tcllib.sourceforge.net/doc/struct_tree.html) + +A tree is a collection of nodes, where each node (except the root node) has a single parent +and zero or more child nodes (ordered), as well as zero or more attribute/value pairs. + ++*tree*+:: + Creates and returns a new tree object with a single node named "root". + All operations on the tree are invoked through this object. + ++$tree *destroy*+:: + Destroy the tree and all it's nodes. (Note that the the tree will also + be automatically garbage collected once it goes out of scope). + ++$tree *set* 'nodename key value'+:: + Set the value for the given attribute key. + ++$tree *lappend* 'nodename key value \...'+:: + Append to the (list) value(s) for the given attribute key, or set if not yet set. + ++$tree *keyexists* 'nodename key'+:: + Returns 1 if the given attribute key exists. + ++$tree *get* 'nodename key'+:: + Returns the value associated with the given attribute key. + ++$tree *getall* 'nodename'+:: + Returns the entire attribute dictionary associated with the given key. + ++$tree *depth* 'nodename'+:: + Returns the depth of the given node. The depth of "root" is 0. + ++$tree *parent* 'nodename'+:: + Returns the node name of the parent node, or "" for the root node. + ++$tree *numchildren* 'nodename'+:: + Returns the number of child nodes. + ++$tree *children* 'nodename'+:: + Returns a list of the child nodes. + ++$tree *next* 'nodename'+:: + Returns the next sibling node, or "" if none. + ++$tree *insert* 'nodename ?index?'+:: + Add a new child node to the given node. The index is a list index + such as +3+ or +end-2+. The default index is +end+. + Returns the name of the newly added node. + ++$tree *walk* 'nodename' *dfs|bfs* {'actionvar nodevar'} 'script'+:: + Walks the tree starting from the given node, either breadth first (+bfs+) + depth first (+dfs+). + The value +"enter"+ or +"exit"+ is stored in variable +'actionvar'+. + The name of each node is stored in +'nodevar'+. + The script is evaluated twice for each node, on entry and exit. + ++$tree *dump*+:: + Dumps the tree contents to stdout + +tcl::prefix +~~~~~~~~~~~ +The optional tclprefix extension provides the Tcl8.6-compatible 'tcl::prefix' command +(http://www.tcl.tk/man/tcl8.6/TclCmd/prefix.htm) for matching strings against a table +of possible values (typically commands or options). + ++*tcl::prefix all* 'table string'+:: + Returns a list of all elements in +'table'+ that begin with the prefix +'string'+. + ++*tcl::prefix longest* 'table string'+:: + Returns the longest common prefix of all elements in +'table'+ that begin with the prefix +'string'+. + ++*tcl::prefix match* '?options? table string'+:: + If +'string'+ equals one element in +'table'+ or is a prefix to + exactly one element, the matched element is returned. If not, the + result depends on the +-error+ option. + + * +*-exact*+ Accept only exact matches. + * +*-message* 'string'+ Use +'string'+ in the error message at a mismatch. Default is "option". + * +*-error* 'options'+ The options are used when no match is found. If +'options'+ is + empty, no error is generated and an empty string is returned. + Otherwise the options are used as return options when + generating the error message. The default corresponds to + setting +-level 0+. + +history +~~~~~~~ +The optional history extension provides script access to the command line editing +and history support available in 'jimsh'. See 'examples/jtclsh.tcl' for an example. +Note: if line editing support is not available, `history getline` acts like `gets` and +the remaining subcommands do nothing. + ++*history load* 'filename'+:: + Load history from a (text) file. If the file does not exist or is not readable, + it is ignored. + ++*history getline* 'prompt ?varname?'+:: + Displays the given prompt and allows a line to be entered. Similarly to `gets`, + if +'varname'+ is given, it receives the line and the length of the line is returned, + or -1 on EOF. If +'varname'+ is not given, the line is returned directly. + ++*history add* 'line'+:: + Adds the given line to the history buffer. + ++*history save* 'filename'+:: + Saves the current history buffer to the given file. + ++*history show*+:: + Displays the current history buffer to standard output. + +namespace +~~~~~~~~~ +Provides namespace-related functions. See also: http://www.tcl.tk/man/tcl8.6/TclCmd/namespace.htm + ++*namespace code* 'script'+:: + Captures the current namespace context for later execution of + the script +'script'+. It returns a new script in which script has + been wrapped in a +*namespace inscope*+ command. + ++*namespace current*+:: + Returns the fully-qualified name for the current namespace. + ++*namespace delete* '?namespace ...?'+:: + Deletes all commands and variables with the given namespace prefixes. + ++*namespace eval* 'namespace arg ?arg...?'+:: + Activates a namespace called +'namespace'+ and evaluates some code in that context. + ++*namespace origin* 'command'+:: + Returns the fully-qualified name of the original command to which the imported command +'command'+ refers. + ++*namespace parent* ?namespace?+:: + Returns the fully-qualified name of the parent namespace for namespace +'namespace'+, if given, otherwise + for the current namespace. + ++*namespace qualifiers* 'string'+:: + Returns any leading namespace qualifiers for +'string'+ + ++*namespace tail* 'string'+:: + Returns the simple name at the end of a qualified string. + ++*namespace upvar* 'namespace ?arg...?'+:: + This command arranges for zero or more local variables in the current procedure to refer to variables in +'namespace'+ + ++*namespace which* '?-command|-variable? name'+:: + Looks up +'name'+ as either a command (the default) or variable and returns its fully-qualified name. + +[[BuiltinVariables]] +BUILT-IN VARIABLES +------------------ + +The following global variables are created automatically +by the Tcl library. + ++*env*+:: + This variable is set by Jim as an array + whose elements are the environment variables for the process. + Reading an element will return the value of the corresponding + environment variable. + This array is initialised at startup from the `env` command. + It may be modified and will affect the environment passed to + commands invoked with `exec`. + ++*platform_tcl*+:: + This variable is set by Jim as an array containing information + about the platform on which Jim was built. Currently this includes + 'os' and 'platform'. + ++*auto_path*+:: + This variable contains a list of paths to search for packages. + It defaults to a location based on where jim is installed + (e.g. +/usr/local/lib/jim+), but may be changed by +jimsh+ + or the embedding application. Note that +jimsh+ will consider + the environment variable +$JIMLIB+ to be a list of colon-separated + list of paths to add to +*auto_path*+. + ++*errorCode*+:: + This variable holds the value of the -errorcode return + option set by the most recent error that occurred in this + interpreter. This list value represents additional information + about the error in a form that is easy to process with + programs. The first element of the list identifies a general + class of errors, and determines the format of the rest of + the list. The following formats for -errorcode return options + are used by the Tcl core; individual applications may define + additional formats. Currently only `exec` sets this variable. + Otherwise it will be +NONE+. + +The following global variables are set by jimsh. + ++*tcl_interactive*+:: + This variable is set to 1 if jimsh is started in interactive mode + or 0 otherwise. + ++*tcl_platform*+:: + This variable is set by Jim as an array containing information + about the platform upon which Jim was built. The following is an + example of the contents of this array. + + tcl_platform(byteOrder) = littleEndian + tcl_platform(os) = Darwin + tcl_platform(platform) = unix + tcl_platform(pointerSize) = 8 + tcl_platform(threaded) = 0 + tcl_platform(wordSize) = 8 + tcl_platform(pathSeparator) = : + ++*argv0*+:: + If jimsh is invoked to run a script, this variable contains the name + of the script. + ++*argv*+:: + If jimsh is invoked to run a script, this variable contains a list + of any arguments supplied to the script. + ++*argc*+:: + If jimsh is invoked to run a script, this variable contains the number + of arguments supplied to the script. + ++*jim_argv0*+:: + The value of argv[0] when jimsh was invoked. + +CHANGES IN PREVIOUS RELEASES +---------------------------- + +=== In v0.70 === + +1. +platform_tcl()+ settings are now automatically determined +2. Add aio `$handle filename` +3. Add `info channels` +4. The 'bio' extension is gone. Now `aio` supports 'copyto'. +5. Add `exists` command +6. Add the pure-Tcl 'oo' extension +7. The `exec` command now only uses vfork(), not fork() +8. Unit test framework is less verbose and more Tcl-compatible +9. Optional UTF-8 support +10. Optional built-in regexp engine for better Tcl compatibility and UTF-8 support +11. Command line editing in interactive mode, e.g. 'jimsh' + +=== In v0.63 === + +1. `source` now checks that a script is complete (.i.e. not missing a brace) +2. 'info complete' now uses the real parser and so is 100% accurate +3. Better access to live stack frames with 'info frame', `stacktrace` and `stackdump` +4. `tailcall` no longer loses stack trace information +5. Add `alias` and `curry` +6. `lambda`, `alias` and `curry` are implemented via `tailcall` for efficiency +7. `local` allows procedures to be deleted automatically at the end of the current procedure +8. udp sockets are now supported for both clients and servers. +9. vfork-based exec is now working correctly +10. Add 'file tempfile' +11. Add 'socket pipe' +12. Enhance 'try ... on ... finally' to be more Tcl 8.6 compatible +13. It is now possible to `return` from within `try` +14. IPv6 support is now included +15. Add 'string is' +16. Event handlers works better if an error occurs. eof handler has been removed. +17. `exec` now sets $::errorCode, and catch sets opts(-errorcode) for exit status +18. Command pipelines via open "|..." are now supported +19. `pid` can now return pids of a command pipeline +20. Add 'info references' +21. Add support for 'after +'ms'+', 'after idle', 'after info', `update` +22. `exec` now sets environment based on $::env +23. Add 'dict keys' +24. Add support for 'lsort -index' + +=== In v0.62 === + +1. Add support to `exec` for '>&', '>>&', '|&', '2>@1' +2. Fix `exec` error messages when special token (e.g. '>') is the last token +3. Fix `subst` handling of backslash escapes. +4. Allow abbreviated options for `subst` +5. Add support for `return`, `break`, `continue` in subst +6. Many `expr` bug fixes +7. Add support for functions in `expr` (e.g. int(), abs()), and also 'in', 'ni' list operations +8. The variable name argument to `regsub` is now optional +9. Add support for 'unset -nocomplain' +10. Add support for list commands: `lassign`, `lrepeat` +11. Fully-functional `lsearch` is now implemented +12. Add 'info nameofexecutable' and 'info returncodes' +13. Allow `catch` to determine what return codes are caught +14. Allow `incr` to increment an unset variable by first setting to 0 +15. Allow 'args' and optional arguments to the left or required arguments in `proc` +16. Add 'file copy' +17. Add 'try ... finally' command + + +LICENCE +------- + + Copyright 2005 Salvatore Sanfilippo + Copyright 2005 Clemens Hintze + Copyright 2005 patthoyts - Pat Thoyts + Copyright 2008 oharboe - Oyvind Harboe - oyvind.harboe@zylin.com + Copyright 2008 Andrew Lunn + Copyright 2008 Duane Ellis + Copyright 2008 Uwe Klein + Copyright 2009 Steve Bennett + +[literal] + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + The views and conclusions contained in the software and documentation + are those of the authors and should not be interpreted as representing + official policies, either expressed or implied, of the Jim Tcl Project. diff --git a/debuggers/openocd/jimtcl/jimautoconf.h.in b/debuggers/openocd/jimtcl/jimautoconf.h.in new file mode 100644 index 00000000..f4eb0e59 --- /dev/null +++ b/debuggers/openocd/jimtcl/jimautoconf.h.in @@ -0,0 +1,145 @@ +/* jimautoconf.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `backtrace' function. */ +#undef HAVE_BACKTRACE + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Have the dlopen function */ +#undef HAVE_DLOPEN + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if you have the `getaddrinfo' function. */ +#undef HAVE_GETADDRINFO + +/* Define to 1 if you have the `geteuid' function. */ +#undef HAVE_GETEUID + +/* Define to 1 if you have the `inet_ntop' function. */ +#undef HAVE_INET_NTOP + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if the system has the type `long long'. */ +#undef HAVE_LONG_LONG + +/* Define to 1 if you have the `lstat' function. */ +#undef HAVE_LSTAT + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mkstemp' function. */ +#undef HAVE_MKSTEMP + +/* Define to 1 if you have the `opendir' function. */ +#undef HAVE_OPENDIR + +/* Define to 1 if you have the `pipe' function. */ +#undef HAVE_PIPE + +/* Have libreadline */ +#undef HAVE_READLINE + +/* Define to 1 if you have the `readlink' function. */ +#undef HAVE_READLINK + +/* Define to 1 if you have the `realpath' function. */ +#undef HAVE_REALPATH + +/* Define to 1 if you have the `regcomp' function. */ +#undef HAVE_REGCOMP + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the `sleep' function. */ +#undef HAVE_SLEEP + +/* Have libsqlite */ +#undef HAVE_SQLITE + +/* Have libsqlite3 */ +#undef HAVE_SQLITE3 + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strptime' function. */ +#undef HAVE_STRPTIME + +/* Define to 1 if you have the `sysinfo' function. */ +#undef HAVE_SYSINFO + +/* Define to 1 if you have the `syslog' function. */ +#undef HAVE_SYSLOG + +/* Define to 1 if you have the `sys_siglist' function. */ +#undef HAVE_SYS_SIGLIST + +/* Define to 1 if you have the `sys_signame' function. */ +#undef HAVE_SYS_SIGNAME + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TERMIOS_H + +/* Define to 1 if you have the `ualarm' function. */ +#undef HAVE_UALARM + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `usleep' function. */ +#undef HAVE_USLEEP + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the `waitpid' function. */ +#undef HAVE_WAITPID + +/* No need to declare extern 'environ'. */ +#undef NO_ENVIRON_EXTERN + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS diff --git a/debuggers/openocd/jimtcl/jimregexp.c b/debuggers/openocd/jimtcl/jimregexp.c new file mode 100644 index 00000000..efc56a13 --- /dev/null +++ b/debuggers/openocd/jimtcl/jimregexp.c @@ -0,0 +1,1809 @@ +/* + * regcomp and regexec -- regsub and regerror are elsewhere + * + * Copyright (c) 1986 by University of Toronto. + * Written by Henry Spencer. Not derived from licensed software. + * + * Permission is granted to anyone to use this software for any + * purpose on any computer system, and to redistribute it freely, + * subject to the following restrictions: + * + * 1. The author is not responsible for the consequences of use of + * this software, no matter how awful, even if they arise + * from defects in it. + * + * 2. The origin of this software must not be misrepresented, either + * by explicit claim or by omission. + * + * 3. Altered versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, + *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to | + *** to assist in implementing egrep. + *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, + *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching + *** as in BSD grep and ex. + *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, + *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \. + *** THIS IS AN ALTERED VERSION. It was altered by James A. Woods, + *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy. + *** THIS IS AN ALTERED VERSION. It was altered by Christopher Seiwald + *** seiwald@vix.com, on 28 August 1993, for use in jam. Regmagic.h + *** was moved into regexp.h, and the include of regexp.h now uses "'s + *** to avoid conflicting with the system regexp.h. Const, bless its + *** soul, was removed so it can compile everywhere. The declaration + *** of strchr() was in conflict on AIX, so it was removed (as it is + *** happily defined in string.h). + *** THIS IS AN ALTERED VERSION. It was altered by Christopher Seiwald + *** seiwald@perforce.com, on 20 January 2000, to use function prototypes. + *** THIS IS AN ALTERED VERSION. It was altered by Christopher Seiwald + *** seiwald@perforce.com, on 05 November 2002, to const string literals. + * + * THIS IS AN ALTERED VERSION. It was altered by Steve Bennett + * on 16 October 2010, to remove static state and add better Tcl ARE compatibility. + * This includes counted repetitions, UTF-8 support, character classes, + * shorthand character classes, increased number of parentheses to 100, + * backslash escape sequences. It also removes \n as an alternative to |. + * + * Beware that some of this code is subtly aware of the way operator + * precedence is structured in regular expressions. Serious changes in + * regular-expression syntax might require a total rethink. + */ +#include +#include +#include +#include + +#include "jim.h" +#include "jimautoconf.h" +#include "jimregexp.h" +#include "utf8.h" + +#if !defined(HAVE_REGCOMP) || defined(JIM_REGEXP) + +/* + * Structure for regexp "program". This is essentially a linear encoding + * of a nondeterministic finite-state machine (aka syntax charts or + * "railroad normal form" in parsing technology). Each node is an opcode + * plus a "next" pointer, possibly plus an operand. "Next" pointers of + * all nodes except BRANCH implement concatenation; a "next" pointer with + * a BRANCH on both ends of it is connecting two alternatives. (Here we + * have one of the subtle syntax dependencies: an individual BRANCH (as + * opposed to a collection of them) is never concatenated with anything + * because of operator precedence.) The operand of some types of node is + * a literal string; for others, it is a node leading into a sub-FSM. In + * particular, the operand of a BRANCH node is the first node of the branch. + * (NB this is *not* a tree structure: the tail of the branch connects + * to the thing following the set of BRANCHes.) The opcodes are: + */ + +/* This *MUST* be less than (255-20-1)/2=117 */ +#define REG_MAX_PAREN 100 + +/* definition number opnd? meaning */ +#define END 0 /* no End of program. */ +#define BOL 1 /* no Match "" at beginning of line. */ +#define EOL 2 /* no Match "" at end of line. */ +#define ANY 3 /* no Match any one character. */ +#define ANYOF 4 /* str Match any character in this string. */ +#define ANYBUT 5 /* str Match any character not in this string. */ +#define BRANCH 6 /* node Match this alternative, or the next... */ +#define BACK 7 /* no Match "", "next" ptr points backward. */ +#define EXACTLY 8 /* str Match this string. */ +#define NOTHING 9 /* no Match empty string. */ +#define REP 10 /* max,min Match this (simple) thing [min,max] times. */ +#define REPMIN 11 /* max,min Match this (simple) thing [min,max] times, mininal match. */ +#define REPX 12 /* max,min Match this (complex) thing [min,max] times. */ +#define REPXMIN 13 /* max,min Match this (complex) thing [min,max] times, minimal match. */ + +#define WORDA 15 /* no Match "" at wordchar, where prev is nonword */ +#define WORDZ 16 /* no Match "" at nonwordchar, where prev is word */ +#define OPENNC 19 /* no Non-capturing parentheses - must be OPEN-1 */ +#define OPEN 20 /* no Mark this point in input as start of #n. */ + /* OPEN+1 is number 1, etc. */ +#define CLOSE (OPEN+REG_MAX_PAREN+1) /* no Analogous to OPEN. */ +#define CLOSE_END (CLOSE+REG_MAX_PAREN) +#define CLOSENC (CLOSE-1) /* no Non-capturing parentheses - must be CLOSE-1 */ + +/* + * The first byte of the regexp internal "program" is actually this magic + * number; the start node begins in the second byte. + */ +#define REG_MAGIC 0xFADED00D + +/* + * Opcode notes: + * + * BRANCH The set of branches constituting a single choice are hooked + * together with their "next" pointers, since precedence prevents + * anything being concatenated to any individual branch. The + * "next" pointer of the last BRANCH in a choice points to the + * thing following the whole choice. This is also where the + * final "next" pointer of each individual branch points; each + * branch starts with the operand node of a BRANCH node. + * + * BACK Normal "next" pointers all implicitly point forward; BACK + * exists to make loop structures possible. + * + * STAR,PLUS '?', and complex '*' and '+', are implemented as circular + * BRANCH structures using BACK. Simple cases (one character + * per match) are implemented with STAR and PLUS for speed + * and to minimize recursive plunges. + * + * OPEN,CLOSE ...are numbered at compile time. + */ + +/* + * A node is one char of opcode followed by two chars of "next" pointer. + * "Next" pointers are stored as two 8-bit pieces, high order first. The + * value is a positive offset from the opcode of the node containing it. + * An operand, if any, simply follows the node. (Note that much of the + * code generation knows about this implicit relationship.) + * + * Using two bytes for the "next" pointer is vast overkill for most things, + * but allows patterns to get big without disasters. + */ +#define OP(preg, p) (preg->program[p]) +#define NEXT(preg, p) (preg->program[p + 1]) +#define OPERAND(p) ((p) + 2) + +/* + * See regmagic.h for one further detail of program structure. + */ + + +/* + * Utility definitions. + */ + +#define FAIL(R,M) { (R)->err = (M); return (M); } +#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?' || (c) == '{') +#define META "^$.[()|?{+*" + +/* + * Flags to be passed up and down. + */ +#define HASWIDTH 01 /* Known never to match null string. */ +#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ +#define SPSTART 04 /* Starts with * or +. */ +#define WORST 0 /* Worst case. */ + +#define MAX_REP_COUNT 1000000 + +/* + * Forward declarations for regcomp()'s friends. + */ +static int reg(regex_t *preg, int paren /* Parenthesized? */, int *flagp ); +static int regpiece(regex_t *preg, int *flagp ); +static int regbranch(regex_t *preg, int *flagp ); +static int regatom(regex_t *preg, int *flagp ); +static int regnode(regex_t *preg, int op ); +static int regnext(regex_t *preg, int p ); +static void regc(regex_t *preg, int b ); +static int reginsert(regex_t *preg, int op, int size, int opnd ); +static void regtail_(regex_t *preg, int p, int val, int line ); +static void regoptail(regex_t *preg, int p, int val ); +#define regtail(PREG, P, VAL) regtail_(PREG, P, VAL, __LINE__) + +static int reg_range_find(const int *string, int c); +static const char *str_find(const char *string, int c, int nocase); +static int prefix_cmp(const int *prog, int proglen, const char *string, int nocase); + +/*#define DEBUG*/ +#ifdef DEBUG +static int regnarrate = 0; +static void regdump(regex_t *preg); +static const char *regprop( int op ); +#endif + + +/** + * Returns the length of the null-terminated integer sequence. + */ +static int str_int_len(const int *seq) +{ + int n = 0; + while (*seq++) { + n++; + } + return n; +} + +/* + - regcomp - compile a regular expression into internal code + * + * We can't allocate space until we know how big the compiled form will be, + * but we can't compile it (and thus know how big it is) until we've got a + * place to put the code. So we cheat: we compile it twice, once with code + * generation turned off and size counting turned on, and once "for real". + * This also means that we don't allocate space until we are sure that the + * thing really will compile successfully, and we never have to move the + * code and thus invalidate pointers into it. (Note that it has to be in + * one piece because free() must be able to free it all.) + * + * Beware that the optimization-preparation code in here knows about some + * of the structure of the compiled regexp. + */ +int regcomp(regex_t *preg, const char *exp, int cflags) +{ + int scan; + int longest; + unsigned len; + int flags; + +#ifdef DEBUG + fprintf(stderr, "Compiling: '%s'\n", exp); +#endif + memset(preg, 0, sizeof(*preg)); + + if (exp == NULL) + FAIL(preg, REG_ERR_NULL_ARGUMENT); + + /* First pass: determine size, legality. */ + preg->cflags = cflags; + preg->regparse = exp; + /* XXX: For now, start unallocated */ + preg->program = NULL; + preg->proglen = 0; + + /* Allocate space. */ + preg->proglen = (strlen(exp) + 1) * 5; + preg->program = malloc(preg->proglen * sizeof(int)); + if (preg->program == NULL) + FAIL(preg, REG_ERR_NOMEM); + + /* Note that since we store a magic value as the first item in the program, + * program offsets will never be 0 + */ + regc(preg, REG_MAGIC); + if (reg(preg, 0, &flags) == 0) { + return preg->err; + } + + /* Small enough for pointer-storage convention? */ + if (preg->re_nsub >= REG_MAX_PAREN) /* Probably could be 65535L. */ + FAIL(preg,REG_ERR_TOO_BIG); + + /* Dig out information for optimizations. */ + preg->regstart = 0; /* Worst-case defaults. */ + preg->reganch = 0; + preg->regmust = 0; + preg->regmlen = 0; + scan = 1; /* First BRANCH. */ + if (OP(preg, regnext(preg, scan)) == END) { /* Only one top-level choice. */ + scan = OPERAND(scan); + + /* Starting-point info. */ + if (OP(preg, scan) == EXACTLY) { + preg->regstart = preg->program[OPERAND(scan)]; + } + else if (OP(preg, scan) == BOL) + preg->reganch++; + + /* + * If there's something expensive in the r.e., find the + * longest literal string that must appear and make it the + * regmust. Resolve ties in favor of later strings, since + * the regstart check works with the beginning of the r.e. + * and avoiding duplication strengthens checking. Not a + * strong reason, but sufficient in the absence of others. + */ + if (flags&SPSTART) { + longest = 0; + len = 0; + for (; scan != 0; scan = regnext(preg, scan)) { + if (OP(preg, scan) == EXACTLY) { + int plen = str_int_len(preg->program + OPERAND(scan)); + if (plen >= len) { + longest = OPERAND(scan); + len = plen; + } + } + } + preg->regmust = longest; + preg->regmlen = len; + } + } + +#ifdef DEBUG + regdump(preg); +#endif + + return 0; +} + +/* + - reg - regular expression, i.e. main body or parenthesized thing + * + * Caller must absorb opening parenthesis. + * + * Combining parenthesis handling with the base level of regular expression + * is a trifle forced, but the need to tie the tails of the branches to what + * follows makes it hard to avoid. + */ +static int reg(regex_t *preg, int paren /* Parenthesized? */, int *flagp ) +{ + int ret; + int br; + int ender; + int parno = 0; + int flags; + + *flagp = HASWIDTH; /* Tentatively. */ + + /* Make an OPEN node, if parenthesized. */ + if (paren) { + if (preg->regparse[0] == '?' && preg->regparse[1] == ':') { + /* non-capturing paren */ + preg->regparse += 2; + parno = -1; + } + else { + parno = ++preg->re_nsub; + } + ret = regnode(preg, OPEN+parno); + } else + ret = 0; + + /* Pick up the branches, linking them together. */ + br = regbranch(preg, &flags); + if (br == 0) + return 0; + if (ret != 0) + regtail(preg, ret, br); /* OPEN -> first. */ + else + ret = br; + if (!(flags&HASWIDTH)) + *flagp &= ~HASWIDTH; + *flagp |= flags&SPSTART; + while (*preg->regparse == '|') { + preg->regparse++; + br = regbranch(preg, &flags); + if (br == 0) + return 0; + regtail(preg, ret, br); /* BRANCH -> BRANCH. */ + if (!(flags&HASWIDTH)) + *flagp &= ~HASWIDTH; + *flagp |= flags&SPSTART; + } + + /* Make a closing node, and hook it on the end. */ + ender = regnode(preg, (paren) ? CLOSE+parno : END); + regtail(preg, ret, ender); + + /* Hook the tails of the branches to the closing node. */ + for (br = ret; br != 0; br = regnext(preg, br)) + regoptail(preg, br, ender); + + /* Check for proper termination. */ + if (paren && *preg->regparse++ != ')') { + preg->err = REG_ERR_UNMATCHED_PAREN; + return 0; + } else if (!paren && *preg->regparse != '\0') { + if (*preg->regparse == ')') { + preg->err = REG_ERR_UNMATCHED_PAREN; + return 0; + } else { + preg->err = REG_ERR_JUNK_ON_END; + return 0; + } + } + + return(ret); +} + +/* + - regbranch - one alternative of an | operator + * + * Implements the concatenation operator. + */ +static int regbranch(regex_t *preg, int *flagp ) +{ + int ret; + int chain; + int latest; + int flags; + + *flagp = WORST; /* Tentatively. */ + + ret = regnode(preg, BRANCH); + chain = 0; + while (*preg->regparse != '\0' && *preg->regparse != ')' && + *preg->regparse != '|') { + latest = regpiece(preg, &flags); + if (latest == 0) + return 0; + *flagp |= flags&HASWIDTH; + if (chain == 0) {/* First piece. */ + *flagp |= flags&SPSTART; + } + else { + regtail(preg, chain, latest); + } + chain = latest; + } + if (chain == 0) /* Loop ran zero times. */ + (void) regnode(preg, NOTHING); + + return(ret); +} + +/* + - regpiece - something followed by possible [*+?] + * + * Note that the branching code sequences used for ? and the general cases + * of * and + are somewhat optimized: they use the same NOTHING node as + * both the endmarker for their branch list and the body of the last branch. + * It might seem that this node could be dispensed with entirely, but the + * endmarker role is not redundant. + */ +static int regpiece(regex_t *preg, int *flagp) +{ + int ret; + char op; + int next; + int flags; + int chain = 0; + int min; + int max; + + ret = regatom(preg, &flags); + if (ret == 0) + return 0; + + op = *preg->regparse; + if (!ISMULT(op)) { + *flagp = flags; + return(ret); + } + + if (!(flags&HASWIDTH) && op != '?') { + preg->err = REG_ERR_OPERAND_COULD_BE_EMPTY; + return 0; + } + + /* Handle braces (counted repetition) by expansion */ + if (op == '{') { + char *end; + + min = strtoul(preg->regparse + 1, &end, 10); + if (end == preg->regparse + 1) { + preg->err = REG_ERR_BAD_COUNT; + return 0; + } + if (*end == '}') { + max = min; + } + else { + preg->regparse = end; + max = strtoul(preg->regparse + 1, &end, 10); + if (*end != '}') { + preg->err = REG_ERR_UNMATCHED_BRACES; + return 0; + } + } + if (end == preg->regparse + 1) { + max = MAX_REP_COUNT; + } + else if (max < min || max >= 100) { + preg->err = REG_ERR_BAD_COUNT; + return 0; + } + if (min >= 100) { + preg->err = REG_ERR_BAD_COUNT; + return 0; + } + + preg->regparse = strchr(preg->regparse, '}'); + } + else { + min = (op == '+'); + max = (op == '?' ? 1 : MAX_REP_COUNT); + } + + if (preg->regparse[1] == '?') { + preg->regparse++; + next = reginsert(preg, flags & SIMPLE ? REPMIN : REPXMIN, 5, ret); + } + else { + next = reginsert(preg, flags & SIMPLE ? REP: REPX, 5, ret); + } + preg->program[ret + 2] = max; + preg->program[ret + 3] = min; + preg->program[ret + 4] = 0; + + *flagp = (min) ? (WORST|HASWIDTH) : (WORST|SPSTART); + + if (!(flags & SIMPLE)) { + int back = regnode(preg, BACK); + regtail(preg, back, ret); + regtail(preg, next, back); + } + + preg->regparse++; + if (ISMULT(*preg->regparse)) { + preg->err = REG_ERR_NESTED_COUNT; + return 0; + } + + return chain ? chain : ret; +} + +/** + * Add all characters in the inclusive range between lower and upper. + * + * Handles a swapped range (upper < lower). + */ +static void reg_addrange(regex_t *preg, int lower, int upper) +{ + if (lower > upper) { + reg_addrange(preg, upper, lower); + } + /* Add a range as length, start */ + regc(preg, upper - lower + 1); + regc(preg, lower); +} + +/** + * Add a null-terminated literal string as a set of ranges. + */ +static void reg_addrange_str(regex_t *preg, const char *str) +{ + while (*str) { + reg_addrange(preg, *str, *str); + str++; + } +} + +/** + * Extracts the next unicode char from utf8. + * + * If 'upper' is set, converts the char to uppercase. + */ +static int reg_utf8_tounicode_case(const char *s, int *uc, int upper) +{ + int l = utf8_tounicode(s, uc); + if (upper) { + *uc = utf8_upper(*uc); + } + return l; +} + +/** + * Converts a hex digit to decimal. + * + * Returns -1 for an invalid hex digit. + */ +static int hexdigitval(int c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +/** + * Parses up to 'n' hex digits at 's' and stores the result in *uc. + * + * Returns the number of hex digits parsed. + * If there are no hex digits, returns 0 and stores nothing. + */ +static int parse_hex(const char *s, int n, int *uc) +{ + int val = 0; + int k; + + for (k = 0; k < n; k++) { + int c = hexdigitval(*s++); + if (c == -1) { + break; + } + val = (val << 4) | c; + } + if (k) { + *uc = val; + } + return k; +} + +/** + * Call for chars after a backlash to decode the escape sequence. + * + * Stores the result in *ch. + * + * Returns the number of bytes consumed. + */ +static int reg_decode_escape(const char *s, int *ch) +{ + int n; + const char *s0 = s; + + *ch = *s++; + + switch (*ch) { + case 'b': *ch = '\b'; break; + case 'e': *ch = 27; break; + case 'f': *ch = '\f'; break; + case 'n': *ch = '\n'; break; + case 'r': *ch = '\r'; break; + case 't': *ch = '\t'; break; + case 'v': *ch = '\v'; break; + case 'u': + if (*s == '{') { + /* Expect \u{NNNN} */ + n = parse_hex(s + 1, 6, ch); + if (n > 0 && s[n + 1] == '}' && *ch >= 0 && *ch <= 0x1fffff) { + s += n + 2; + } + else { + /* Invalid, so just treat as an escaped 'u' */ + *ch = 'u'; + } + } + else if ((n = parse_hex(s, 4, ch)) > 0) { + s += n; + } + break; + case 'U': + if ((n = parse_hex(s, 8, ch)) > 0) { + s += n; + } + case 'x': + if ((n = parse_hex(s, 2, ch)) > 0) { + s += n; + } + break; + case '\0': + s--; + *ch = '\\'; + break; + } + return s - s0; +} + +/* + - regatom - the lowest level + * + * Optimization: gobbles an entire sequence of ordinary characters so that + * it can turn them into a single node, which is smaller to store and + * faster to run. Backslashed characters are exceptions, each becoming a + * separate node; the code is simpler that way and it's not worth fixing. + */ +static int regatom(regex_t *preg, int *flagp) +{ + int ret; + int flags; + int nocase = (preg->cflags & REG_ICASE); + + int ch; + int n = reg_utf8_tounicode_case(preg->regparse, &ch, nocase); + + *flagp = WORST; /* Tentatively. */ + + preg->regparse += n; + switch (ch) { + /* FIXME: these chars only have meaning at beg/end of pat? */ + case '^': + ret = regnode(preg, BOL); + break; + case '$': + ret = regnode(preg, EOL); + break; + case '.': + ret = regnode(preg, ANY); + *flagp |= HASWIDTH|SIMPLE; + break; + case '[': { + const char *pattern = preg->regparse; + + if (*pattern == '^') { /* Complement of range. */ + ret = regnode(preg, ANYBUT); + pattern++; + } else + ret = regnode(preg, ANYOF); + + /* Special case. If the first char is ']' or '-', it is part of the set */ + if (*pattern == ']' || *pattern == '-') { + reg_addrange(preg, *pattern, *pattern); + pattern++; + } + + while (*pattern && *pattern != ']') { + /* Is this a range? a-z */ + int start; + int end; + + pattern += reg_utf8_tounicode_case(pattern, &start, nocase); + if (start == '\\') { + pattern += reg_decode_escape(pattern, &start); + if (start == 0) { + preg->err = REG_ERR_NULL_CHAR; + return 0; + } + } + if (pattern[0] == '-' && pattern[1] && pattern[1] != ']') { + /* skip '-' */ + pattern += utf8_tounicode(pattern, &end); + pattern += reg_utf8_tounicode_case(pattern, &end, nocase); + if (end == '\\') { + pattern += reg_decode_escape(pattern, &end); + if (end == 0) { + preg->err = REG_ERR_NULL_CHAR; + return 0; + } + } + + reg_addrange(preg, start, end); + continue; + } + if (start == '[') { + if (strncmp(pattern, ":alpha:]", 8) == 0) { + if ((preg->cflags & REG_ICASE) == 0) { + reg_addrange(preg, 'a', 'z'); + } + reg_addrange(preg, 'A', 'Z'); + pattern += 8; + continue; + } + if (strncmp(pattern, ":alnum:]", 8) == 0) { + if ((preg->cflags & REG_ICASE) == 0) { + reg_addrange(preg, 'a', 'z'); + } + reg_addrange(preg, 'A', 'Z'); + reg_addrange(preg, '0', '9'); + pattern += 8; + continue; + } + if (strncmp(pattern, ":space:]", 8) == 0) { + reg_addrange_str(preg, " \t\r\n\f\v"); + pattern += 8; + continue; + } + } + /* Not a range, so just add the char */ + reg_addrange(preg, start, start); + } + regc(preg, '\0'); + + if (*pattern) { + pattern++; + } + preg->regparse = pattern; + + *flagp |= HASWIDTH|SIMPLE; + } + break; + case '(': + ret = reg(preg, 1, &flags); + if (ret == 0) + return 0; + *flagp |= flags&(HASWIDTH|SPSTART); + break; + case '\0': + case '|': + case ')': + preg->err = REG_ERR_INTERNAL; + return 0; /* Supposed to be caught earlier. */ + case '?': + case '+': + case '*': + case '{': + preg->err = REG_ERR_COUNT_FOLLOWS_NOTHING; + return 0; + case '\\': + switch (*preg->regparse++) { + case '\0': + preg->err = REG_ERR_TRAILING_BACKSLASH; + return 0; + case '<': + case 'm': + ret = regnode(preg, WORDA); + break; + case '>': + case 'M': + ret = regnode(preg, WORDZ); + break; + case 'd': + ret = regnode(preg, ANYOF); + reg_addrange(preg, '0', '9'); + regc(preg, '\0'); + *flagp |= HASWIDTH|SIMPLE; + break; + case 'w': + ret = regnode(preg, ANYOF); + if ((preg->cflags & REG_ICASE) == 0) { + reg_addrange(preg, 'a', 'z'); + } + reg_addrange(preg, 'A', 'Z'); + reg_addrange(preg, '0', '9'); + reg_addrange(preg, '_', '_'); + regc(preg, '\0'); + *flagp |= HASWIDTH|SIMPLE; + break; + case 's': + ret = regnode(preg, ANYOF); + reg_addrange_str(preg," \t\r\n\f\v"); + regc(preg, '\0'); + *flagp |= HASWIDTH|SIMPLE; + break; + /* FIXME: Someday handle \1, \2, ... */ + default: + /* Handle general quoted chars in exact-match routine */ + /* Back up to include the backslash */ + preg->regparse--; + goto de_fault; + } + break; + de_fault: + default: { + /* + * Encode a string of characters to be matched exactly. + */ + int added = 0; + + /* Back up to pick up the first char of interest */ + preg->regparse -= n; + + ret = regnode(preg, EXACTLY); + + /* Note that a META operator such as ? or * consumes the + * preceding char. + * Thus we must be careful to look ahead by 2 and add the + * last char as it's own EXACTLY if necessary + */ + + /* Until end of string or a META char is reached */ + while (*preg->regparse && strchr(META, *preg->regparse) == NULL) { + n = reg_utf8_tounicode_case(preg->regparse, &ch, (preg->cflags & REG_ICASE)); + if (ch == '\\' && preg->regparse[n]) { + /* Non-trailing backslash. + * Is this a special escape, or a regular escape? + */ + if (strchr("<>mMwds", preg->regparse[n])) { + /* A special escape. All done with EXACTLY */ + break; + } + /* Decode it. Note that we add the length for the escape + * sequence to the length for the backlash so we can skip + * the entire sequence, or not as required. + */ + n += reg_decode_escape(preg->regparse + n, &ch); + if (ch == 0) { + preg->err = REG_ERR_NULL_CHAR; + return 0; + } + } + + /* Now we have one char 'ch' of length 'n'. + * Check to see if the following char is a MULT + */ + + if (ISMULT(preg->regparse[n])) { + /* Yes. But do we already have some EXACTLY chars? */ + if (added) { + /* Yes, so return what we have and pick up the current char next time around */ + break; + } + /* No, so add this single char and finish */ + regc(preg, ch); + added++; + preg->regparse += n; + break; + } + + /* No, so just add this char normally */ + regc(preg, ch); + added++; + preg->regparse += n; + } + regc(preg, '\0'); + + *flagp |= HASWIDTH; + if (added == 1) + *flagp |= SIMPLE; + break; + } + break; + } + + return(ret); +} + +static void reg_grow(regex_t *preg, int n) +{ + if (preg->p + n >= preg->proglen) { + preg->proglen = (preg->p + n) * 2; + preg->program = realloc(preg->program, preg->proglen * sizeof(int)); + } +} + +/* + - regnode - emit a node + */ +/* Location. */ +static int regnode(regex_t *preg, int op) +{ + reg_grow(preg, 2); + + preg->program[preg->p++] = op; + preg->program[preg->p++] = 0; + + /* Return the start of the node */ + return preg->p - 2; +} + +/* + - regc - emit (if appropriate) a byte of code + */ +static void regc(regex_t *preg, int b ) +{ + reg_grow(preg, 1); + preg->program[preg->p++] = b; +} + +/* + - reginsert - insert an operator in front of already-emitted operand + * + * Means relocating the operand. + * Returns the new location of the original operand. + */ +static int reginsert(regex_t *preg, int op, int size, int opnd ) +{ + reg_grow(preg, size); + + /* Move everything from opnd up */ + memmove(preg->program + opnd + size, preg->program + opnd, sizeof(int) * (preg->p - opnd)); + /* Zero out the new space */ + memset(preg->program + opnd, 0, sizeof(int) * size); + + preg->program[opnd] = op; + + preg->p += size; + + return opnd + size; +} + +/* + - regtail - set the next-pointer at the end of a node chain + */ +static void regtail_(regex_t *preg, int p, int val, int line ) +{ + int scan; + int temp; + int offset; + + /* Find last node. */ + scan = p; + for (;;) { + temp = regnext(preg, scan); + if (temp == 0) + break; + scan = temp; + } + + if (OP(preg, scan) == BACK) + offset = scan - val; + else + offset = val - scan; + + preg->program[scan + 1] = offset; +} + +/* + - regoptail - regtail on operand of first argument; nop if operandless + */ + +static void regoptail(regex_t *preg, int p, int val ) +{ + /* "Operandless" and "op != BRANCH" are synonymous in practice. */ + if (p != 0 && OP(preg, p) == BRANCH) { + regtail(preg, OPERAND(p), val); + } +} + +/* + * regexec and friends + */ + +/* + * Forwards. + */ +static int regtry(regex_t *preg, const char *string ); +static int regmatch(regex_t *preg, int prog); +static int regrepeat(regex_t *preg, int p, int max); + +/* + - regexec - match a regexp against a string + */ +int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) +{ + const char *s; + int scan; + + /* Be paranoid... */ + if (preg == NULL || preg->program == NULL || string == NULL) { + return REG_ERR_NULL_ARGUMENT; + } + + /* Check validity of program. */ + if (*preg->program != REG_MAGIC) { + return REG_ERR_CORRUPTED; + } + +#ifdef DEBUG + fprintf(stderr, "regexec: %s\n", string); + regdump(preg); +#endif + + preg->eflags = eflags; + preg->pmatch = pmatch; + preg->nmatch = nmatch; + preg->start = string; /* All offsets are computed from here */ + + /* Must clear out the embedded repeat counts */ + for (scan = OPERAND(1); scan != 0; ) { + switch (OP(preg, scan)) { + case REP: + case REPMIN: + case REPX: + case REPXMIN: + preg->program[scan + 4] = 0; + scan += 5; + break; + + case ANYOF: + case ANYBUT: + case EXACTLY: + scan += 2; + while (preg->program[scan++]) { + } + break; + + case END: + scan = 0; + break; + + default: + scan += 2; + break; + } + } + + /* If there is a "must appear" string, look for it. */ + if (preg->regmust != 0) { + s = string; + while ((s = str_find(s, preg->program[preg->regmust], preg->cflags & REG_ICASE)) != NULL) { + if (prefix_cmp(preg->program + preg->regmust, preg->regmlen, s, preg->cflags & REG_ICASE) >= 0) { + break; + } + s++; + } + if (s == NULL) /* Not present. */ + return REG_NOMATCH; + } + + /* Mark beginning of line for ^ . */ + preg->regbol = string; + + /* Simplest case: anchored match need be tried only once (maybe per line). */ + if (preg->reganch) { + if (eflags & REG_NOTBOL) { + /* This is an anchored search, but not an BOL, so possibly skip to the next line */ + goto nextline; + } + while (1) { + if (regtry(preg, string)) { + return REG_NOERROR; + } + if (*string) { +nextline: + if (preg->cflags & REG_NEWLINE) { + /* Try the next anchor? */ + string = strchr(string, '\n'); + if (string) { + preg->regbol = ++string; + continue; + } + } + } + return REG_NOMATCH; + } + } + + /* Messy cases: unanchored match. */ + s = string; + if (preg->regstart != '\0') { + /* We know what char it must start with. */ + while ((s = str_find(s, preg->regstart, preg->cflags & REG_ICASE)) != NULL) { + if (regtry(preg, s)) + return REG_NOERROR; + s++; + } + } + else + /* We don't -- general case. */ + while (1) { + if (regtry(preg, s)) + return REG_NOERROR; + if (*s == '\0') { + break; + } + else { + int c; + s += utf8_tounicode(s, &c); + } + } + + /* Failure. */ + return REG_NOMATCH; +} + +/* + - regtry - try match at specific point + */ + /* 0 failure, 1 success */ +static int regtry( regex_t *preg, const char *string ) +{ + int i; + + preg->reginput = string; + + for (i = 0; i < preg->nmatch; i++) { + preg->pmatch[i].rm_so = -1; + preg->pmatch[i].rm_eo = -1; + } + if (regmatch(preg, 1)) { + preg->pmatch[0].rm_so = string - preg->start; + preg->pmatch[0].rm_eo = preg->reginput - preg->start; + return(1); + } else + return(0); +} + +/** + * Returns bytes matched if 'pattern' is a prefix of 'string'. + * + * If 'nocase' is non-zero, does a case-insensitive match. + * + * Returns -1 on not found. + */ +static int prefix_cmp(const int *prog, int proglen, const char *string, int nocase) +{ + const char *s = string; + while (proglen && *s) { + int ch; + int n = reg_utf8_tounicode_case(s, &ch, nocase); + if (ch != *prog) { + return -1; + } + prog++; + s += n; + proglen--; + } + if (proglen == 0) { + return s - string; + } + return -1; +} + +/** + * Searchs for 'c' in the range 'range'. + * + * Returns 1 if found, or 0 if not. + */ +static int reg_range_find(const int *range, int c) +{ + while (*range) { + /*printf("Checking %d in range [%d,%d]\n", c, range[1], (range[0] + range[1] - 1));*/ + if (c >= range[1] && c <= (range[0] + range[1] - 1)) { + return 1; + } + range += 2; + } + return 0; +} + +/** + * Search for the character 'c' in the utf-8 string 'string'. + * + * If 'nocase' is set, the 'string' is assumed to be uppercase + * and 'c' is converted to uppercase before matching. + * + * Returns the byte position in the string where the 'c' was found, or + * NULL if not found. + */ +static const char *str_find(const char *string, int c, int nocase) +{ + if (nocase) { + /* The "string" should already be converted to uppercase */ + c = utf8_upper(c); + } + while (*string) { + int ch; + int n = reg_utf8_tounicode_case(string, &ch, nocase); + if (c == ch) { + return string; + } + string += n; + } + return NULL; +} + +/** + * Returns true if 'ch' is an end-of-line char. + * + * In REG_NEWLINE mode, \n is considered EOL in + * addition to \0 + */ +static int reg_iseol(regex_t *preg, int ch) +{ + if (preg->cflags & REG_NEWLINE) { + return ch == '\0' || ch == '\n'; + } + else { + return ch == '\0'; + } +} + +static int regmatchsimplerepeat(regex_t *preg, int scan, int matchmin) +{ + int nextch = '\0'; + const char *save; + int no; + int c; + + int max = preg->program[scan + 2]; + int min = preg->program[scan + 3]; + int next = regnext(preg, scan); + + /* + * Lookahead to avoid useless match attempts + * when we know what character comes next. + */ + if (OP(preg, next) == EXACTLY) { + nextch = preg->program[OPERAND(next)]; + } + save = preg->reginput; + no = regrepeat(preg, scan + 5, max); + if (no < min) { + return 0; + } + if (matchmin) { + /* from min up to no */ + max = no; + no = min; + } + /* else from no down to min */ + while (1) { + if (matchmin) { + if (no > max) { + break; + } + } + else { + if (no < min) { + break; + } + } + preg->reginput = save + utf8_index(save, no); + reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE)); + /* If it could work, try it. */ + if (reg_iseol(preg, nextch) || c == nextch) { + if (regmatch(preg, next)) { + return(1); + } + } + if (matchmin) { + /* Couldn't or didn't, add one more */ + no++; + } + else { + /* Couldn't or didn't -- back up. */ + no--; + } + } + return(0); +} + +static int regmatchrepeat(regex_t *preg, int scan, int matchmin) +{ + int *scanpt = preg->program + scan; + + int max = scanpt[2]; + int min = scanpt[3]; + + /* Have we reached min? */ + if (scanpt[4] < min) { + /* No, so get another one */ + scanpt[4]++; + if (regmatch(preg, scan + 5)) { + return 1; + } + scanpt[4]--; + return 0; + } + if (scanpt[4] > max) { + return 0; + } + + if (matchmin) { + /* minimal, so try other branch first */ + if (regmatch(preg, regnext(preg, scan))) { + return 1; + } + /* No, so try one more */ + scanpt[4]++; + if (regmatch(preg, scan + 5)) { + return 1; + } + scanpt[4]--; + return 0; + } + /* maximal, so try this branch again */ + if (scanpt[4] < max) { + scanpt[4]++; + if (regmatch(preg, scan + 5)) { + return 1; + } + scanpt[4]--; + } + /* At this point we are at max with no match. Try the other branch */ + return regmatch(preg, regnext(preg, scan)); +} + +/* + - regmatch - main matching routine + * + * Conceptually the strategy is simple: check to see whether the current + * node matches, call self recursively to see whether the rest matches, + * and then act accordingly. In practice we make some effort to avoid + * recursion, in particular by going through "ordinary" nodes (that don't + * need to know whether the rest of the match failed) by a loop instead of + * by recursion. + */ +/* 0 failure, 1 success */ +static int regmatch(regex_t *preg, int prog) +{ + int scan; /* Current node. */ + int next; /* Next node. */ + + scan = prog; + +#ifdef DEBUG + if (scan != 0 && regnarrate) + fprintf(stderr, "%s(\n", regprop(scan)); +#endif + while (scan != 0) { + int n; + int c; +#ifdef DEBUG + if (regnarrate) { + fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan))); /* Where, what. */ + } +#endif + next = regnext(preg, scan); + n = reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE)); + + switch (OP(preg, scan)) { + case BOL: + if (preg->reginput != preg->regbol) + return(0); + break; + case EOL: + if (!reg_iseol(preg, c)) { + return(0); + } + break; + case WORDA: + /* Must be looking at a letter, digit, or _ */ + if ((!isalnum(UCHAR(c))) && c != '_') + return(0); + /* Prev must be BOL or nonword */ + if (preg->reginput > preg->regbol && + (isalnum(UCHAR(preg->reginput[-1])) || preg->reginput[-1] == '_')) + return(0); + break; + case WORDZ: + /* Can't match at BOL */ + if (preg->reginput > preg->regbol) { + /* Current must be EOL or nonword */ + if (reg_iseol(preg, c) || !isalnum(UCHAR(c)) || c != '_') { + c = preg->reginput[-1]; + /* Previous must be word */ + if (isalnum(UCHAR(c)) || c == '_') { + break; + } + } + } + /* No */ + return(0); + + case ANY: + if (reg_iseol(preg, c)) + return 0; + preg->reginput += n; + break; + case EXACTLY: { + int opnd; + int len; + int slen; + + opnd = OPERAND(scan); + len = str_int_len(preg->program + opnd); + + slen = prefix_cmp(preg->program + opnd, len, preg->reginput, preg->cflags & REG_ICASE); + if (slen < 0) { + return(0); + } + preg->reginput += slen; + } + break; + case ANYOF: + if (reg_iseol(preg, c) || reg_range_find(preg->program + OPERAND(scan), c) == 0) { + return(0); + } + preg->reginput += n; + break; + case ANYBUT: + if (reg_iseol(preg, c) || reg_range_find(preg->program + OPERAND(scan), c) != 0) { + return(0); + } + preg->reginput += n; + break; + case NOTHING: + break; + case BACK: + break; + case BRANCH: { + const char *save; + + if (OP(preg, next) != BRANCH) /* No choice. */ + next = OPERAND(scan); /* Avoid recursion. */ + else { + do { + save = preg->reginput; + if (regmatch(preg, OPERAND(scan))) { + return(1); + } + preg->reginput = save; + scan = regnext(preg, scan); + } while (scan != 0 && OP(preg, scan) == BRANCH); + return(0); + /* NOTREACHED */ + } + } + break; + case REP: + case REPMIN: + return regmatchsimplerepeat(preg, scan, OP(preg, scan) == REPMIN); + + case REPX: + case REPXMIN: + return regmatchrepeat(preg, scan, OP(preg, scan) == REPXMIN); + + case END: + return(1); /* Success! */ + break; + + case OPENNC: + case CLOSENC: + if (regmatch(preg, next)) { + return 1; + } + return 0; + + default: + if (OP(preg, scan) >= OPEN+1 && OP(preg, scan) < CLOSE_END) { + const char *save; + + save = preg->reginput; + + if (regmatch(preg, next)) { + int no; + /* + * Don't set startp if some later + * invocation of the same parentheses + * already has. + */ + if (OP(preg, scan) < CLOSE) { + no = OP(preg, scan) - OPEN; + if (no < preg->nmatch && preg->pmatch[no].rm_so == -1) { + preg->pmatch[no].rm_so = save - preg->start; + } + } + else { + no = OP(preg, scan) - CLOSE; + if (no < preg->nmatch && preg->pmatch[no].rm_eo == -1) { + preg->pmatch[no].rm_eo = save - preg->start; + } + } + return(1); + } else + return(0); + } + return REG_ERR_INTERNAL; + } + + scan = next; + } + + /* + * We get here only if there's trouble -- normally "case END" is + * the terminating point. + */ + return REG_ERR_INTERNAL; +} + +/* + - regrepeat - repeatedly match something simple, report how many + */ +static int regrepeat(regex_t *preg, int p, int max) +{ + int count = 0; + const char *scan; + int opnd; + int ch; + int n; + + scan = preg->reginput; + opnd = OPERAND(p); + switch (OP(preg, p)) { + case ANY: + /* No need to handle utf8 specially here */ + while (!reg_iseol(preg, *scan) && count < max) { + count++; + scan++; + } + break; + case EXACTLY: + while (count < max) { + n = reg_utf8_tounicode_case(scan, &ch, preg->cflags & REG_ICASE); + if (preg->program[opnd] != ch) { + break; + } + count++; + scan += n; + } + break; + case ANYOF: + while (count < max) { + n = reg_utf8_tounicode_case(scan, &ch, preg->cflags & REG_ICASE); + if (reg_iseol(preg, ch) || reg_range_find(preg->program + opnd, ch) == 0) { + break; + } + count++; + scan += n; + } + break; + case ANYBUT: + while (count < max) { + n = reg_utf8_tounicode_case(scan, &ch, preg->cflags & REG_ICASE); + if (reg_iseol(preg, ch) || reg_range_find(preg->program + opnd, ch) != 0) { + break; + } + count++; + scan += n; + } + break; + default: /* Oh dear. Called inappropriately. */ + preg->err = REG_ERR_INTERNAL; + count = 0; /* Best compromise. */ + break; + } + preg->reginput = scan; + + return(count); +} + +/* + - regnext - dig the "next" pointer out of a node + */ +static int regnext(regex_t *preg, int p ) +{ + int offset; + + offset = NEXT(preg, p); + + if (offset == 0) + return 0; + + if (OP(preg, p) == BACK) + return(p-offset); + else + return(p+offset); +} + +#if defined(DEBUG) && !defined(JIM_BOOTSTRAP) + +/* + - regdump - dump a regexp onto stdout in vaguely comprehensible form + */ +static void regdump(regex_t *preg) +{ + int s; + int op = EXACTLY; /* Arbitrary non-END op. */ + int next; + char buf[MAX_UTF8_LEN + 1]; + + int i; + for (i = 1; i < preg->p; i++) { + printf("%02x ", (unsigned char)preg->program[i]); + if (i % 16 == 0) { + printf("\n"); + } + } + printf("\n"); + + s = 1; + while (op != END && s < preg->p) { /* While that wasn't END last time... */ + op = OP(preg, s); + printf("%3d: %s", s, regprop(op)); /* Where, what. */ + next = regnext(preg, s); + if (next == 0) /* Next ptr. */ + printf("(0)"); + else + printf("(%d)", next); + s += 2; + if (op == REP || op == REPMIN || op == REPX || op == REPXMIN) { + int max = preg->program[s]; + int min = preg->program[s + 1]; + if (max == 65535) { + printf("{%d,*}", min); + } + else { + printf("{%d,%d}", min, max); + } + printf(" %d", preg->program[s + 2]); + s += 3; + } + else if (op == ANYOF || op == ANYBUT) { + /* set of ranges */ + + while (preg->program[s]) { + int len = preg->program[s++]; + int first = preg->program[s++]; + buf[utf8_fromunicode(buf, first)] = 0; + printf("%s", buf); + if (len > 1) { + buf[utf8_fromunicode(buf, first + len - 1)] = 0; + printf("-%s", buf); + } + } + s++; + } + else if (op == EXACTLY) { + /* Literal string, where present. */ + + while (preg->program[s]) { + buf[utf8_fromunicode(buf, preg->program[s])] = 0; + printf("%s", buf); + s++; + } + s++; + } + putchar('\n'); + } + + if (op == END) { + /* Header fields of interest. */ + if (preg->regstart) { + buf[utf8_fromunicode(buf, preg->regstart)] = 0; + printf("start '%s' ", buf); + } + if (preg->reganch) + printf("anchored "); + if (preg->regmust != 0) { + int i; + printf("must have:"); + for (i = 0; i < preg->regmlen; i++) { + putchar(preg->program[preg->regmust + i]); + } + putchar('\n'); + } + } + printf("\n"); +} + +/* + - regprop - printable representation of opcode + */ +static const char *regprop( int op ) +{ + static char buf[50]; + + switch (op) { + case BOL: + return "BOL"; + case EOL: + return "EOL"; + case ANY: + return "ANY"; + case ANYOF: + return "ANYOF"; + case ANYBUT: + return "ANYBUT"; + case BRANCH: + return "BRANCH"; + case EXACTLY: + return "EXACTLY"; + case NOTHING: + return "NOTHING"; + case BACK: + return "BACK"; + case END: + return "END"; + case REP: + return "REP"; + case REPMIN: + return "REPMIN"; + case REPX: + return "REPX"; + case REPXMIN: + return "REPXMIN"; + case WORDA: + return "WORDA"; + case WORDZ: + return "WORDZ"; + case OPENNC: + return "OPEN"; + case CLOSENC: + return "CLOSE"; + default: + if (op >= OPEN && op < CLOSE) { + snprintf(buf, sizeof(buf), "OPEN%d", op-OPEN); + } + else if (op >= CLOSE && op < CLOSE_END) { + snprintf(buf, sizeof(buf), "CLOSE%d", op-CLOSE); + } + else { + snprintf(buf, sizeof(buf), "?%d?\n", op); + } + return(buf); + } +} +#endif /* JIM_BOOTSTRAP */ + +size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) +{ + static const char *error_strings[] = { + "success", + "no match", + "bad pattern", + "null argument", + "unknown error", + "too big", + "out of memory", + "too many ()", + "parentheses () not balanced", + "braces {} not balanced", + "invalid repetition count(s)", + "extra characters", + "*+ of empty atom", + "nested count", + "internal error", + "count follows nothing", + "trailing backslash", + "corrupted program", + "contains null char", + }; + const char *err; + + if (errcode < 0 || errcode >= REG_ERR_NUM) { + err = "Bad error code"; + } + else { + err = error_strings[errcode]; + } + + return snprintf(errbuf, errbuf_size, "%s", err); +} + +void regfree(regex_t *preg) +{ + free(preg->program); +} + +#endif diff --git a/debuggers/openocd/jimtcl/jimregexp.h b/debuggers/openocd/jimtcl/jimregexp.h new file mode 100644 index 00000000..79a87e5f --- /dev/null +++ b/debuggers/openocd/jimtcl/jimregexp.h @@ -0,0 +1,117 @@ +#ifndef JIMREGEXP_H +#define JIMREGEXP_H + +#ifndef _JIMAUTOCONF_H +#error Need jimautoconf.h +#endif + +#if defined(HAVE_REGCOMP) && !defined(JIM_REGEXP) +/* Use POSIX regex */ +#include + +#else + +#include + +/* + * Definitions etc. for regexp(3) routines. + * + * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], + * not the System V one. + * + * 11/04/02 (seiwald) - const-ing for string literals + */ + +typedef struct { + int rm_so; + int rm_eo; +} regmatch_t; + +/* + * The "internal use only" fields in regexp.h are present to pass info from + * compile to execute that permits the execute phase to run lots faster on + * simple cases. They are: + * + * regstart char that must begin a match; '\0' if none obvious + * reganch is the match anchored (at beginning-of-line only)? + * regmust string (pointer into program) that match must include, or NULL + * regmlen length of regmust string + * + * Regstart and reganch permit very fast decisions on suitable starting points + * for a match, cutting down the work a lot. Regmust permits fast rejection + * of lines that cannot possibly match. The regmust tests are costly enough + * that regcomp() supplies a regmust only if the r.e. contains something + * potentially expensive (at present, the only such thing detected is * or + + * at the start of the r.e., which can involve a lot of backup). Regmlen is + * supplied because the test in regexec() needs it and regcomp() is computing + * it anyway. + */ + +typedef struct regexp { + /* -- public -- */ + int re_nsub; /* number of parenthesized subexpressions */ + + /* -- private -- */ + int cflags; /* Flags used when compiling */ + int err; /* Any error which occurred during compile */ + int regstart; /* Internal use only. */ + int reganch; /* Internal use only. */ + int regmust; /* Internal use only. */ + int regmlen; /* Internal use only. */ + int *program; /* Allocated */ + + /* working state - compile */ + const char *regparse; /* Input-scan pointer. */ + int p; /* Current output pos in program */ + int proglen; /* Allocated program size */ + + /* working state - exec */ + int eflags; /* Flags used when executing */ + const char *start; /* Initial string pointer. */ + const char *reginput; /* Current input pointer. */ + const char *regbol; /* Beginning of input, for ^ check. */ + + /* Input to regexec() */ + regmatch_t *pmatch; /* submatches will be stored here */ + int nmatch; /* size of pmatch[] */ +} regexp; + +typedef regexp regex_t; + +#define REG_EXTENDED 0 +#define REG_NEWLINE 1 +#define REG_ICASE 2 + +#define REG_NOTBOL 16 + +enum { + REG_NOERROR, /* Success. */ + REG_NOMATCH, /* Didn't find a match (for regexec). */ + REG_BADPAT, /* >= REG_BADPAT is an error */ + REG_ERR_NULL_ARGUMENT, + REG_ERR_UNKNOWN, + REG_ERR_TOO_BIG, + REG_ERR_NOMEM, + REG_ERR_TOO_MANY_PAREN, + REG_ERR_UNMATCHED_PAREN, + REG_ERR_UNMATCHED_BRACES, + REG_ERR_BAD_COUNT, + REG_ERR_JUNK_ON_END, + REG_ERR_OPERAND_COULD_BE_EMPTY, + REG_ERR_NESTED_COUNT, + REG_ERR_INTERNAL, + REG_ERR_COUNT_FOLLOWS_NOTHING, + REG_ERR_TRAILING_BACKSLASH, + REG_ERR_CORRUPTED, + REG_ERR_NULL_CHAR, + REG_ERR_NUM +}; + +int regcomp(regex_t *preg, const char *regex, int cflags); +int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); +size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size); +void regfree(regex_t *preg); + +#endif + +#endif diff --git a/debuggers/openocd/jimtcl/jimsh.c b/debuggers/openocd/jimtcl/jimsh.c new file mode 100644 index 00000000..36d1a2d8 --- /dev/null +++ b/debuggers/openocd/jimtcl/jimsh.c @@ -0,0 +1,125 @@ +/* + * jimsh - An interactive shell for Jim + * + * Copyright 2005 Salvatore Sanfilippo + * Copyright 2009 Steve Bennett + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the Jim Tcl Project. + */ + +#include +#include +#include + +#include "jim.h" +#include "jimautoconf.h" + +/* From initjimsh.tcl */ +extern int Jim_initjimshInit(Jim_Interp *interp); + +static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[]) +{ + int n; + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + + /* Populate argv global var */ + for (n = 0; n < argc; n++) { + Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1); + + Jim_ListAppendElement(interp, listObj, obj); + } + + Jim_SetVariableStr(interp, "argv", listObj); + Jim_SetVariableStr(interp, "argc", Jim_NewIntObj(interp, argc)); +} + +int main(int argc, char *const argv[]) +{ + int retcode; + Jim_Interp *interp; + + if (argc > 1 && strcmp(argv[1], "--version") == 0) { + printf("%d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100); + return 0; + } + + /* Create and initialize the interpreter */ + interp = Jim_CreateInterp(); + Jim_RegisterCoreCommands(interp); + + /* Register static extensions */ + if (Jim_InitStaticExtensions(interp) != JIM_OK) { + Jim_MakeErrorMessage(interp); + fprintf(stderr, "%s\n", Jim_String(Jim_GetResult(interp))); + } + + Jim_SetVariableStrWithStr(interp, "jim_argv0", argv[0]); + Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0"); + retcode = Jim_initjimshInit(interp); + + if (argc == 1) { + if (retcode == JIM_ERR) { + Jim_MakeErrorMessage(interp); + fprintf(stderr, "%s\n", Jim_String(Jim_GetResult(interp))); + } + if (retcode != JIM_EXIT) { + JimSetArgv(interp, 0, NULL); + retcode = Jim_InteractivePrompt(interp); + } + } + else { + if (argc > 2 && strcmp(argv[1], "-e") == 0) { + JimSetArgv(interp, argc - 3, argv + 3); + retcode = Jim_Eval(interp, argv[2]); + if (retcode != JIM_ERR) { + printf("%s\n", Jim_String(Jim_GetResult(interp))); + } + } + else { + Jim_SetVariableStr(interp, "argv0", Jim_NewStringObj(interp, argv[1], -1)); + JimSetArgv(interp, argc - 2, argv + 2); + retcode = Jim_EvalFile(interp, argv[1]); + } + if (retcode == JIM_ERR) { + Jim_MakeErrorMessage(interp); + fprintf(stderr, "%s\n", Jim_String(Jim_GetResult(interp))); + } + } + if (retcode == JIM_EXIT) { + retcode = Jim_GetExitCode(interp); + } + else if (retcode == JIM_ERR) { + retcode = 1; + } + else { + retcode = 0; + } + Jim_FreeInterp(interp); + return retcode; +} diff --git a/debuggers/openocd/jimtcl/linenoise.c b/debuggers/openocd/jimtcl/linenoise.c new file mode 100644 index 00000000..a35ea125 --- /dev/null +++ b/debuggers/openocd/jimtcl/linenoise.c @@ -0,0 +1,1396 @@ +/* linenoise.c -- guerrilla line editing library against the idea that a + * line editing lib needs to be 20,000 lines of C code. + * + * You can find the latest source code at: + * + * http://github.com/msteveb/linenoise + * (forked from http://github.com/antirez/linenoise) + * + * Does a number of crazy assumptions that happen to be true in 99.9999% of + * the 2010 UNIX computers around. + * + * ------------------------------------------------------------------------ + * + * Copyright (c) 2010, Salvatore Sanfilippo + * Copyright (c) 2010, Pieter Noordhuis + * Copyright (c) 2011, Steve Bennett + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ------------------------------------------------------------------------ + * + * References: + * - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html + * - http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html + * + * Bloat: + * - Completion? + * + * Unix/termios + * ------------ + * List of escape sequences used by this program, we do everything just + * a few sequences. In order to be so cheap we may have some + * flickering effect with some slow terminal, but the lesser sequences + * the more compatible. + * + * EL (Erase Line) + * Sequence: ESC [ n K + * Effect: if n is 0 or missing, clear from cursor to end of line + * Effect: if n is 1, clear from beginning of line to cursor + * Effect: if n is 2, clear entire line + * + * CUF (CUrsor Forward) + * Sequence: ESC [ n C + * Effect: moves cursor forward of n chars + * + * CR (Carriage Return) + * Sequence: \r + * Effect: moves cursor to column 1 + * + * The following are used to clear the screen: ESC [ H ESC [ 2 J + * This is actually composed of two sequences: + * + * cursorhome + * Sequence: ESC [ H + * Effect: moves the cursor to upper left corner + * + * ED2 (Clear entire screen) + * Sequence: ESC [ 2 J + * Effect: clear the whole screen + * + * == For highlighting control characters, we also use the following two == + * SO (enter StandOut) + * Sequence: ESC [ 7 m + * Effect: Uses some standout mode such as reverse video + * + * SE (Standout End) + * Sequence: ESC [ 0 m + * Effect: Exit standout mode + * + * == Only used if TIOCGWINSZ fails == + * DSR/CPR (Report cursor position) + * Sequence: ESC [ 6 n + * Effect: reports current cursor position as ESC [ NNN ; MMM R + * + * win32/console + * ------------- + * If __MINGW32__ is defined, the win32 console API is used. + * This could probably be made to work for the msvc compiler too. + * This support based in part on work by Jon Griffiths. + */ + +#ifdef _WIN32 /* Windows platform, either MinGW or Visual Studio (MSVC) */ +#include +#include +#define USE_WINCONSOLE +#ifdef __MINGW32__ +#define HAVE_UNISTD_H +#else +/* Microsoft headers don't like old POSIX names */ +#define strdup _strdup +#define snprintf _snprintf +#endif +#else +#include +#include +#include +#define USE_TERMIOS +#define HAVE_UNISTD_H +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#include "linenoise.h" + +#include "jim-config.h" +#ifdef JIM_UTF8 +#define USE_UTF8 +#endif +#include "utf8.h" + +#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100 +#define LINENOISE_MAX_LINE 4096 + +#define ctrl(C) ((C) - '@') + +/* Use -ve numbers here to co-exist with normal unicode chars */ +enum { + SPECIAL_NONE, + SPECIAL_UP = -20, + SPECIAL_DOWN = -21, + SPECIAL_LEFT = -22, + SPECIAL_RIGHT = -23, + SPECIAL_DELETE = -24, + SPECIAL_HOME = -25, + SPECIAL_END = -26, +}; + +static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN; +static int history_len = 0; +static char **history = NULL; + +/* Structure to contain the status of the current (being edited) line */ +struct current { + char *buf; /* Current buffer. Always null terminated */ + int bufmax; /* Size of the buffer, including space for the null termination */ + int len; /* Number of bytes in 'buf' */ + int chars; /* Number of chars in 'buf' (utf-8 chars) */ + int pos; /* Cursor position, measured in chars */ + int cols; /* Size of the window, in chars */ + const char *prompt; +#if defined(USE_TERMIOS) + int fd; /* Terminal fd */ +#elif defined(USE_WINCONSOLE) + HANDLE outh; /* Console output handle */ + HANDLE inh; /* Console input handle */ + int rows; /* Screen rows */ + int x; /* Current column during output */ + int y; /* Current row */ +#endif +}; + +static int fd_read(struct current *current); +static int getWindowSize(struct current *current); + +void linenoiseHistoryFree(void) { + if (history) { + int j; + + for (j = 0; j < history_len; j++) + free(history[j]); + free(history); + history = NULL; + } +} + +#if defined(USE_TERMIOS) +static void linenoiseAtExit(void); +static struct termios orig_termios; /* in order to restore at exit */ +static int rawmode = 0; /* for atexit() function to check if restore is needed*/ +static int atexit_registered = 0; /* register atexit just 1 time */ + +static const char *unsupported_term[] = {"dumb","cons25",NULL}; + +static int isUnsupportedTerm(void) { + char *term = getenv("TERM"); + + if (term) { + int j; + for (j = 0; unsupported_term[j]; j++) { + if (strcasecmp(term, unsupported_term[j]) == 0) { + return 1; + } + } + } + return 0; +} + +static int enableRawMode(struct current *current) { + struct termios raw; + + current->fd = STDIN_FILENO; + + if (!isatty(current->fd) || isUnsupportedTerm() || + tcgetattr(current->fd, &orig_termios) == -1) { +fatal: + errno = ENOTTY; + return -1; + } + + if (!atexit_registered) { + atexit(linenoiseAtExit); + atexit_registered = 1; + } + + raw = orig_termios; /* modify the original mode */ + /* input modes: no break, no CR to NL, no parity check, no strip char, + * no start/stop output control. */ + raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + /* output modes - disable post processing */ + raw.c_oflag &= ~(OPOST); + /* control modes - set 8 bit chars */ + raw.c_cflag |= (CS8); + /* local modes - choing off, canonical off, no extended functions, + * no signal chars (^Z,^C) */ + raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); + /* control chars - set return condition: min number of bytes and timer. + * We want read to return every single byte, without timeout. */ + raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */ + + /* put terminal in raw mode after flushing */ + if (tcsetattr(current->fd,TCSADRAIN,&raw) < 0) { + goto fatal; + } + rawmode = 1; + + current->cols = 0; + return 0; +} + +static void disableRawMode(struct current *current) { + /* Don't even check the return value as it's too late. */ + if (rawmode && tcsetattr(current->fd,TCSADRAIN,&orig_termios) != -1) + rawmode = 0; +} + +/* At exit we'll try to fix the terminal to the initial conditions. */ +static void linenoiseAtExit(void) { + if (rawmode) { + tcsetattr(STDIN_FILENO, TCSADRAIN, &orig_termios); + } + linenoiseHistoryFree(); +} + +/* gcc/glibc insists that we care about the return code of write! */ +#define IGNORE_RC(EXPR) if (EXPR) {} + +/* This is fdprintf() on some systems, but use a different + * name to avoid conflicts + */ +static void fd_printf(int fd, const char *format, ...) +{ + va_list args; + char buf[64]; + int n; + + va_start(args, format); + n = vsnprintf(buf, sizeof(buf), format, args); + va_end(args); + IGNORE_RC(write(fd, buf, n)); +} + +static void clearScreen(struct current *current) +{ + fd_printf(current->fd, "\x1b[H\x1b[2J"); +} + +static void cursorToLeft(struct current *current) +{ + fd_printf(current->fd, "\r"); +} + +static int outputChars(struct current *current, const char *buf, int len) +{ + return write(current->fd, buf, len); +} + +static void outputControlChar(struct current *current, char ch) +{ + fd_printf(current->fd, "\x1b[7m^%c\x1b[0m", ch); +} + +static void eraseEol(struct current *current) +{ + fd_printf(current->fd, "\x1b[0K"); +} + +static void setCursorPos(struct current *current, int x) +{ + fd_printf(current->fd, "\r\x1b[%dC", x); +} + +/** + * Reads a char from 'fd', waiting at most 'timeout' milliseconds. + * + * A timeout of -1 means to wait forever. + * + * Returns -1 if no char is received within the time or an error occurs. + */ +static int fd_read_char(int fd, int timeout) +{ + struct pollfd p; + unsigned char c; + + p.fd = fd; + p.events = POLLIN; + + if (poll(&p, 1, timeout) == 0) { + /* timeout */ + return -1; + } + if (read(fd, &c, 1) != 1) { + return -1; + } + return c; +} + +/** + * Reads a complete utf-8 character + * and returns the unicode value, or -1 on error. + */ +static int fd_read(struct current *current) +{ +#ifdef USE_UTF8 + char buf[4]; + int n; + int i; + int c; + + if (read(current->fd, &buf[0], 1) != 1) { + return -1; + } + n = utf8_charlen(buf[0]); + if (n < 1 || n > 3) { + return -1; + } + for (i = 1; i < n; i++) { + if (read(current->fd, &buf[i], 1) != 1) { + return -1; + } + } + buf[n] = 0; + /* decode and return the character */ + utf8_tounicode(buf, &c); + return c; +#else + return fd_read_char(current->fd, -1); +#endif +} + +static int getWindowSize(struct current *current) +{ + struct winsize ws; + + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col != 0) { + current->cols = ws.ws_col; + return 0; + } + + /* Failed to query the window size. Perhaps we are on a serial terminal. + * Try to query the width by sending the cursor as far to the right + * and reading back the cursor position. + * Note that this is only done once per call to linenoise rather than + * every time the line is refreshed for efficiency reasons. + */ + if (current->cols == 0) { + current->cols = 80; + + /* Move cursor far right and report cursor position, then back to the left */ + fd_printf(current->fd, "\x1b[999C" "\x1b[6n"); + + /* Parse the response: ESC [ rows ; cols R */ + if (fd_read_char(current->fd, 100) == 0x1b && fd_read_char(current->fd, 100) == '[') { + int n = 0; + while (1) { + int ch = fd_read_char(current->fd, 100); + if (ch == ';') { + /* Ignore rows */ + n = 0; + } + else if (ch == 'R') { + /* Got cols */ + if (n != 0 && n < 1000) { + current->cols = n; + } + break; + } + else if (ch >= 0 && ch <= '9') { + n = n * 10 + ch - '0'; + } + else { + break; + } + } + } + } + return 0; +} + +/** + * If escape (27) was received, reads subsequent + * chars to determine if this is a known special key. + * + * Returns SPECIAL_NONE if unrecognised, or -1 if EOF. + * + * If no additional char is received within a short time, + * 27 is returned. + */ +static int check_special(int fd) +{ + int c = fd_read_char(fd, 50); + int c2; + + if (c < 0) { + return 27; + } + + c2 = fd_read_char(fd, 50); + if (c2 < 0) { + return c2; + } + if (c == '[' || c == 'O') { + /* Potential arrow key */ + switch (c2) { + case 'A': + return SPECIAL_UP; + case 'B': + return SPECIAL_DOWN; + case 'C': + return SPECIAL_RIGHT; + case 'D': + return SPECIAL_LEFT; + case 'F': + return SPECIAL_END; + case 'H': + return SPECIAL_HOME; + } + } + if (c == '[' && c2 >= '1' && c2 <= '8') { + /* extended escape */ + c = fd_read_char(fd, 50); + if (c == '~') { + switch (c2) { + case '3': + return SPECIAL_DELETE; + case '7': + return SPECIAL_HOME; + case '8': + return SPECIAL_END; + } + } + while (c != -1 && c != '~') { + /* .e.g \e[12~ or '\e[11;2~ discard the complete sequence */ + c = fd_read_char(fd, 50); + } + } + + return SPECIAL_NONE; +} +#elif defined(USE_WINCONSOLE) + +static DWORD orig_consolemode = 0; + +static int enableRawMode(struct current *current) { + DWORD n; + INPUT_RECORD irec; + + current->outh = GetStdHandle(STD_OUTPUT_HANDLE); + current->inh = GetStdHandle(STD_INPUT_HANDLE); + + if (!PeekConsoleInput(current->inh, &irec, 1, &n)) { + return -1; + } + if (getWindowSize(current) != 0) { + return -1; + } + if (GetConsoleMode(current->inh, &orig_consolemode)) { + SetConsoleMode(current->inh, ENABLE_PROCESSED_INPUT); + } + return 0; +} + +static void disableRawMode(struct current *current) +{ + SetConsoleMode(current->inh, orig_consolemode); +} + +static void clearScreen(struct current *current) +{ + COORD topleft = { 0, 0 }; + DWORD n; + + FillConsoleOutputCharacter(current->outh, ' ', + current->cols * current->rows, topleft, &n); + FillConsoleOutputAttribute(current->outh, + FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, + current->cols * current->rows, topleft, &n); + SetConsoleCursorPosition(current->outh, topleft); +} + +static void cursorToLeft(struct current *current) +{ + COORD pos = { 0, (SHORT)current->y }; + DWORD n; + + FillConsoleOutputAttribute(current->outh, + FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, current->cols, pos, &n); + current->x = 0; +} + +static int outputChars(struct current *current, const char *buf, int len) +{ + COORD pos = { (SHORT)current->x, (SHORT)current->y }; + DWORD n; + + WriteConsoleOutputCharacter(current->outh, buf, len, pos, &n); + current->x += len; + return 0; +} + +static void outputControlChar(struct current *current, char ch) +{ + COORD pos = { (SHORT)current->x, (SHORT)current->y }; + DWORD n; + + FillConsoleOutputAttribute(current->outh, BACKGROUND_INTENSITY, 2, pos, &n); + outputChars(current, "^", 1); + outputChars(current, &ch, 1); +} + +static void eraseEol(struct current *current) +{ + COORD pos = { (SHORT)current->x, (SHORT)current->y }; + DWORD n; + + FillConsoleOutputCharacter(current->outh, ' ', current->cols - current->x, pos, &n); +} + +static void setCursorPos(struct current *current, int x) +{ + COORD pos = { (SHORT)x, (SHORT)current->y }; + + SetConsoleCursorPosition(current->outh, pos); + current->x = x; +} + +static int fd_read(struct current *current) +{ + while (1) { + INPUT_RECORD irec; + DWORD n; + if (WaitForSingleObject(current->inh, INFINITE) != WAIT_OBJECT_0) { + break; + } + if (!ReadConsoleInput (current->inh, &irec, 1, &n)) { + break; + } + if (irec.EventType == KEY_EVENT && irec.Event.KeyEvent.bKeyDown) { + KEY_EVENT_RECORD *k = &irec.Event.KeyEvent; + if (k->dwControlKeyState & ENHANCED_KEY) { + switch (k->wVirtualKeyCode) { + case VK_LEFT: + return SPECIAL_LEFT; + case VK_RIGHT: + return SPECIAL_RIGHT; + case VK_UP: + return SPECIAL_UP; + case VK_DOWN: + return SPECIAL_DOWN; + case VK_DELETE: + return SPECIAL_DELETE; + case VK_HOME: + return SPECIAL_HOME; + case VK_END: + return SPECIAL_END; + } + } + /* Note that control characters are already translated in AsciiChar */ + else { +#ifdef USE_UTF8 + return k->uChar.UnicodeChar; +#else + return k->uChar.AsciiChar; +#endif + } + } + } + return -1; +} + +static int getWindowSize(struct current *current) +{ + CONSOLE_SCREEN_BUFFER_INFO info; + if (!GetConsoleScreenBufferInfo(current->outh, &info)) { + return -1; + } + current->cols = info.dwSize.X; + current->rows = info.dwSize.Y; + if (current->cols <= 0 || current->rows <= 0) { + current->cols = 80; + return -1; + } + current->y = info.dwCursorPosition.Y; + current->x = info.dwCursorPosition.X; + return 0; +} +#endif + +static int utf8_getchars(char *buf, int c) +{ +#ifdef USE_UTF8 + return utf8_fromunicode(buf, c); +#else + *buf = c; + return 1; +#endif +} + +/** + * Returns the unicode character at the given offset, + * or -1 if none. + */ +static int get_char(struct current *current, int pos) +{ + if (pos >= 0 && pos < current->chars) { + int c; + int i = utf8_index(current->buf, pos); + (void)utf8_tounicode(current->buf + i, &c); + return c; + } + return -1; +} + +static void refreshLine(const char *prompt, struct current *current) +{ + int plen; + int pchars; + int backup = 0; + int i; + const char *buf = current->buf; + int chars = current->chars; + int pos = current->pos; + int b; + int ch; + int n; + + /* Should intercept SIGWINCH. For now, just get the size every time */ + getWindowSize(current); + + plen = strlen(prompt); + pchars = utf8_strlen(prompt, plen); + + /* Account for a line which is too long to fit in the window. + * Note that control chars require an extra column + */ + + /* How many cols are required to the left of 'pos'? + * The prompt, plus one extra for each control char + */ + n = pchars + utf8_strlen(buf, current->len); + b = 0; + for (i = 0; i < pos; i++) { + b += utf8_tounicode(buf + b, &ch); + if (ch < ' ') { + n++; + } + } + + /* If too many are need, strip chars off the front of 'buf' + * until it fits. Note that if the current char is a control character, + * we need one extra col. + */ + if (current->pos < current->chars && get_char(current, current->pos) < ' ') { + n++; + } + + while (n >= current->cols && pos > 0) { + b = utf8_tounicode(buf, &ch); + if (ch < ' ') { + n--; + } + n--; + buf += b; + pos--; + chars--; + } + + /* Cursor to left edge, then the prompt */ + cursorToLeft(current); + outputChars(current, prompt, plen); + + /* Now the current buffer content */ + + /* Need special handling for control characters. + * If we hit 'cols', stop. + */ + b = 0; /* unwritted bytes */ + n = 0; /* How many control chars were written */ + for (i = 0; i < chars; i++) { + int ch; + int w = utf8_tounicode(buf + b, &ch); + if (ch < ' ') { + n++; + } + if (pchars + i + n >= current->cols) { + break; + } + if (ch < ' ') { + /* A control character, so write the buffer so far */ + outputChars(current, buf, b); + buf += b + w; + b = 0; + outputControlChar(current, ch + '@'); + if (i < pos) { + backup++; + } + } + else { + b += w; + } + } + outputChars(current, buf, b); + + /* Erase to right, move cursor to original position */ + eraseEol(current); + setCursorPos(current, pos + pchars + backup); +} + +static void set_current(struct current *current, const char *str) +{ + strncpy(current->buf, str, current->bufmax); + current->buf[current->bufmax - 1] = 0; + current->len = strlen(current->buf); + current->pos = current->chars = utf8_strlen(current->buf, current->len); +} + +static int has_room(struct current *current, int bytes) +{ + return current->len + bytes < current->bufmax - 1; +} + +/** + * Removes the char at 'pos'. + * + * Returns 1 if the line needs to be refreshed, 2 if not + * and 0 if nothing was removed + */ +static int remove_char(struct current *current, int pos) +{ + if (pos >= 0 && pos < current->chars) { + int p1, p2; + int ret = 1; + p1 = utf8_index(current->buf, pos); + p2 = p1 + utf8_index(current->buf + p1, 1); + +#ifdef USE_TERMIOS + /* optimise remove char in the case of removing the last char */ + if (current->pos == pos + 1 && current->pos == current->chars) { + if (current->buf[pos] >= ' ' && utf8_strlen(current->prompt, -1) + utf8_strlen(current->buf, current->len) < current->cols - 1) { + ret = 2; + fd_printf(current->fd, "\b \b"); + } + } +#endif + + /* Move the null char too */ + memmove(current->buf + p1, current->buf + p2, current->len - p2 + 1); + current->len -= (p2 - p1); + current->chars--; + + if (current->pos > pos) { + current->pos--; + } + return ret; + } + return 0; +} + +/** + * Insert 'ch' at position 'pos' + * + * Returns 1 if the line needs to be refreshed, 2 if not + * and 0 if nothing was inserted (no room) + */ +static int insert_char(struct current *current, int pos, int ch) +{ + char buf[3]; + int n = utf8_getchars(buf, ch); + + if (has_room(current, n) && pos >= 0 && pos <= current->chars) { + int p1, p2; + int ret = 1; + p1 = utf8_index(current->buf, pos); + p2 = p1 + n; + +#ifdef USE_TERMIOS + /* optimise the case where adding a single char to the end and no scrolling is needed */ + if (current->pos == pos && current->chars == pos) { + if (ch >= ' ' && utf8_strlen(current->prompt, -1) + utf8_strlen(current->buf, current->len) < current->cols - 1) { + IGNORE_RC(write(current->fd, buf, n)); + ret = 2; + } + } +#endif + + memmove(current->buf + p2, current->buf + p1, current->len - p1); + memcpy(current->buf + p1, buf, n); + current->len += n; + + current->chars++; + if (current->pos >= pos) { + current->pos++; + } + return ret; + } + return 0; +} + +/** + * Returns 0 if no chars were removed or non-zero otherwise. + */ +static int remove_chars(struct current *current, int pos, int n) +{ + int removed = 0; + while (n-- && remove_char(current, pos)) { + removed++; + } + return removed; +} + +#ifndef NO_COMPLETION +static linenoiseCompletionCallback *completionCallback = NULL; + +static void beep() { +#ifdef USE_TERMIOS + fprintf(stderr, "\x7"); + fflush(stderr); +#endif +} + +static void freeCompletions(linenoiseCompletions *lc) { + size_t i; + for (i = 0; i < lc->len; i++) + free(lc->cvec[i]); + free(lc->cvec); +} + +static int completeLine(struct current *current) { + linenoiseCompletions lc = { 0, NULL }; + int c = 0; + + completionCallback(current->buf,&lc); + if (lc.len == 0) { + beep(); + } else { + size_t stop = 0, i = 0; + + while(!stop) { + /* Show completion or original buffer */ + if (i < lc.len) { + struct current tmp = *current; + tmp.buf = lc.cvec[i]; + tmp.pos = tmp.len = strlen(tmp.buf); + tmp.chars = utf8_strlen(tmp.buf, tmp.len); + refreshLine(current->prompt, &tmp); + } else { + refreshLine(current->prompt, current); + } + + c = fd_read(current); + if (c == -1) { + break; + } + + switch(c) { + case '\t': /* tab */ + i = (i+1) % (lc.len+1); + if (i == lc.len) beep(); + break; + case 27: /* escape */ + /* Re-show original buffer */ + if (i < lc.len) { + refreshLine(current->prompt, current); + } + stop = 1; + break; + default: + /* Update buffer and return */ + if (i < lc.len) { + set_current(current,lc.cvec[i]); + } + stop = 1; + break; + } + } + } + + freeCompletions(&lc); + return c; /* Return last read character */ +} + +/* Register a callback function to be called for tab-completion. */ +void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) { + completionCallback = fn; +} + +void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) { + lc->cvec = (char **)realloc(lc->cvec,sizeof(char*)*(lc->len+1)); + lc->cvec[lc->len++] = strdup(str); +} + +#endif + +static int linenoisePrompt(struct current *current) { + int history_index = 0; + + /* The latest history entry is always our current buffer, that + * initially is just an empty string. */ + linenoiseHistoryAdd(""); + + set_current(current, ""); + refreshLine(current->prompt, current); + + while(1) { + int dir = -1; + int c = fd_read(current); + +#ifndef NO_COMPLETION + /* Only autocomplete when the callback is set. It returns < 0 when + * there was an error reading from fd. Otherwise it will return the + * character that should be handled next. */ + if (c == '\t' && current->pos == current->chars && completionCallback != NULL) { + c = completeLine(current); + /* Return on errors */ + if (c < 0) return current->len; + /* Read next character when 0 */ + if (c == 0) continue; + } +#endif + +process_char: + if (c == -1) return current->len; +#ifdef USE_TERMIOS + if (c == 27) { /* escape sequence */ + c = check_special(current->fd); + } +#endif + switch(c) { + case '\r': /* enter */ + history_len--; + free(history[history_len]); + return current->len; + case ctrl('C'): /* ctrl-c */ + errno = EAGAIN; + return -1; + case 127: /* backspace */ + case ctrl('H'): + if (remove_char(current, current->pos - 1) == 1) { + refreshLine(current->prompt, current); + } + break; + case ctrl('D'): /* ctrl-d */ + if (current->len == 0) { + /* Empty line, so EOF */ + history_len--; + free(history[history_len]); + return -1; + } + /* Otherwise fall through to delete char to right of cursor */ + case SPECIAL_DELETE: + if (remove_char(current, current->pos) == 1) { + refreshLine(current->prompt, current); + } + break; + case ctrl('W'): /* ctrl-w */ + /* eat any spaces on the left */ + { + int pos = current->pos; + while (pos > 0 && get_char(current, pos - 1) == ' ') { + pos--; + } + + /* now eat any non-spaces on the left */ + while (pos > 0 && get_char(current, pos - 1) != ' ') { + pos--; + } + + if (remove_chars(current, pos, current->pos - pos)) { + refreshLine(current->prompt, current); + } + } + break; + case ctrl('R'): /* ctrl-r */ + { + /* Display the reverse-i-search prompt and process chars */ + char rbuf[50]; + char rprompt[80]; + int rchars = 0; + int rlen = 0; + int searchpos = history_len - 1; + + rbuf[0] = 0; + while (1) { + int n = 0; + const char *p = NULL; + int skipsame = 0; + int searchdir = -1; + + snprintf(rprompt, sizeof(rprompt), "(reverse-i-search)'%s': ", rbuf); + refreshLine(rprompt, current); + c = fd_read(current); + if (c == ctrl('H') || c == 127) { + if (rchars) { + int p = utf8_index(rbuf, --rchars); + rbuf[p] = 0; + rlen = strlen(rbuf); + } + continue; + } +#ifdef USE_TERMIOS + if (c == 27) { + c = check_special(current->fd); + } +#endif + if (c == ctrl('P') || c == SPECIAL_UP) { + /* Search for the previous (earlier) match */ + if (searchpos > 0) { + searchpos--; + } + skipsame = 1; + } + else if (c == ctrl('N') || c == SPECIAL_DOWN) { + /* Search for the next (later) match */ + if (searchpos < history_len) { + searchpos++; + } + searchdir = 1; + skipsame = 1; + } + else if (c >= ' ') { + if (rlen >= (int)sizeof(rbuf) + 3) { + continue; + } + + n = utf8_getchars(rbuf + rlen, c); + rlen += n; + rchars++; + rbuf[rlen] = 0; + + /* Adding a new char resets the search location */ + searchpos = history_len - 1; + } + else { + /* Exit from incremental search mode */ + break; + } + + /* Now search through the history for a match */ + for (; searchpos >= 0 && searchpos < history_len; searchpos += searchdir) { + p = strstr(history[searchpos], rbuf); + if (p) { + /* Found a match */ + if (skipsame && strcmp(history[searchpos], current->buf) == 0) { + /* But it is identical, so skip it */ + continue; + } + /* Copy the matching line and set the cursor position */ + set_current(current,history[searchpos]); + current->pos = utf8_strlen(history[searchpos], p - history[searchpos]); + break; + } + } + if (!p && n) { + /* No match, so don't add it */ + rchars--; + rlen -= n; + rbuf[rlen] = 0; + } + } + if (c == ctrl('G') || c == ctrl('C')) { + /* ctrl-g terminates the search with no effect */ + set_current(current, ""); + c = 0; + } + else if (c == ctrl('J')) { + /* ctrl-j terminates the search leaving the buffer in place */ + c = 0; + } + /* Go process the char normally */ + refreshLine(current->prompt, current); + goto process_char; + } + break; + case ctrl('T'): /* ctrl-t */ + if (current->pos > 0 && current->pos < current->chars) { + c = get_char(current, current->pos); + remove_char(current, current->pos); + insert_char(current, current->pos - 1, c); + refreshLine(current->prompt, current); + } + break; + case ctrl('V'): /* ctrl-v */ + if (has_room(current, 3)) { + /* Insert the ^V first */ + if (insert_char(current, current->pos, c)) { + refreshLine(current->prompt, current); + /* Now wait for the next char. Can insert anything except \0 */ + c = fd_read(current); + + /* Remove the ^V first */ + remove_char(current, current->pos - 1); + if (c != -1) { + /* Insert the actual char */ + insert_char(current, current->pos, c); + } + refreshLine(current->prompt, current); + } + } + break; + case ctrl('B'): + case SPECIAL_LEFT: + if (current->pos > 0) { + current->pos--; + refreshLine(current->prompt, current); + } + break; + case ctrl('F'): + case SPECIAL_RIGHT: + if (current->pos < current->chars) { + current->pos++; + refreshLine(current->prompt, current); + } + break; + case ctrl('P'): + case SPECIAL_UP: + dir = 1; + case ctrl('N'): + case SPECIAL_DOWN: + if (history_len > 1) { + /* Update the current history entry before to + * overwrite it with tne next one. */ + free(history[history_len-1-history_index]); + history[history_len-1-history_index] = strdup(current->buf); + /* Show the new entry */ + history_index += dir; + if (history_index < 0) { + history_index = 0; + break; + } else if (history_index >= history_len) { + history_index = history_len-1; + break; + } + set_current(current, history[history_len-1-history_index]); + refreshLine(current->prompt, current); + } + break; + case ctrl('A'): /* Ctrl+a, go to the start of the line */ + case SPECIAL_HOME: + current->pos = 0; + refreshLine(current->prompt, current); + break; + case ctrl('E'): /* ctrl+e, go to the end of the line */ + case SPECIAL_END: + current->pos = current->chars; + refreshLine(current->prompt, current); + break; + case ctrl('U'): /* Ctrl+u, delete to beginning of line. */ + if (remove_chars(current, 0, current->pos)) { + refreshLine(current->prompt, current); + } + break; + case ctrl('K'): /* Ctrl+k, delete from current to end of line. */ + if (remove_chars(current, current->pos, current->chars - current->pos)) { + refreshLine(current->prompt, current); + } + break; + case ctrl('L'): /* Ctrl+L, clear screen */ + clearScreen(current); + /* Force recalc of window size for serial terminals */ + current->cols = 0; + refreshLine(current->prompt, current); + break; + default: + /* Only tab is allowed without ^V */ + if (c == '\t' || c >= ' ') { + if (insert_char(current, current->pos, c) == 1) { + refreshLine(current->prompt, current); + } + } + break; + } + } + return current->len; +} + +char *linenoise(const char *prompt) +{ + int count; + struct current current; + char buf[LINENOISE_MAX_LINE]; + + if (enableRawMode(¤t) == -1) { + printf("%s", prompt); + fflush(stdout); + if (fgets(buf, sizeof(buf), stdin) == NULL) { + return NULL; + } + count = strlen(buf); + if (count && buf[count-1] == '\n') { + count--; + buf[count] = '\0'; + } + } + else + { + current.buf = buf; + current.bufmax = sizeof(buf); + current.len = 0; + current.chars = 0; + current.pos = 0; + current.prompt = prompt; + + count = linenoisePrompt(¤t); + disableRawMode(¤t); + printf("\n"); + if (count == -1) { + return NULL; + } + } + return strdup(buf); +} + +/* Using a circular buffer is smarter, but a bit more complex to handle. */ +int linenoiseHistoryAdd(const char *line) { + char *linecopy; + + if (history_max_len == 0) return 0; + if (history == NULL) { + history = (char **)malloc(sizeof(char*)*history_max_len); + if (history == NULL) return 0; + memset(history,0,(sizeof(char*)*history_max_len)); + } + + /* do not insert duplicate lines into history */ + if (history_len > 0 && strcmp(line, history[history_len - 1]) == 0) { + return 0; + } + + linecopy = strdup(line); + if (!linecopy) return 0; + if (history_len == history_max_len) { + free(history[0]); + memmove(history,history+1,sizeof(char*)*(history_max_len-1)); + history_len--; + } + history[history_len] = linecopy; + history_len++; + return 1; +} + +int linenoiseHistorySetMaxLen(int len) { + char **newHistory; + + if (len < 1) return 0; + if (history) { + int tocopy = history_len; + + newHistory = (char **)malloc(sizeof(char*)*len); + if (newHistory == NULL) return 0; + if (len < tocopy) tocopy = len; + memcpy(newHistory,history+(history_max_len-tocopy), sizeof(char*)*tocopy); + free(history); + history = newHistory; + } + history_max_len = len; + if (history_len > history_max_len) + history_len = history_max_len; + return 1; +} + +/* Save the history in the specified file. On success 0 is returned + * otherwise -1 is returned. */ +int linenoiseHistorySave(const char *filename) { + FILE *fp = fopen(filename,"w"); + int j; + + if (fp == NULL) return -1; + for (j = 0; j < history_len; j++) { + const char *str = history[j]; + /* Need to encode backslash, nl and cr */ + while (*str) { + if (*str == '\\') { + fputs("\\\\", fp); + } + else if (*str == '\n') { + fputs("\\n", fp); + } + else if (*str == '\r') { + fputs("\\r", fp); + } + else { + fputc(*str, fp); + } + str++; + } + fputc('\n', fp); + } + + fclose(fp); + return 0; +} + +/* Load the history from the specified file. If the file does not exist + * zero is returned and no operation is performed. + * + * If the file exists and the operation succeeded 0 is returned, otherwise + * on error -1 is returned. */ +int linenoiseHistoryLoad(const char *filename) { + FILE *fp = fopen(filename,"r"); + char buf[LINENOISE_MAX_LINE]; + + if (fp == NULL) return -1; + + while (fgets(buf,LINENOISE_MAX_LINE,fp) != NULL) { + char *src, *dest; + + /* Decode backslash escaped values */ + for (src = dest = buf; *src; src++) { + char ch = *src; + + if (ch == '\\') { + src++; + if (*src == 'n') { + ch = '\n'; + } + else if (*src == 'r') { + ch = '\r'; + } else { + ch = *src; + } + } + *dest++ = ch; + } + /* Remove trailing newline */ + if (dest != buf && (dest[-1] == '\n' || dest[-1] == '\r')) { + dest--; + } + *dest = 0; + + linenoiseHistoryAdd(buf); + } + fclose(fp); + return 0; +} + +/* Provide access to the history buffer. + * + * If 'len' is not NULL, the length is stored in *len. + */ +char **linenoiseHistory(int *len) { + if (len) { + *len = history_len; + } + return history; +} diff --git a/debuggers/openocd/jimtcl/linenoise.h b/debuggers/openocd/jimtcl/linenoise.h new file mode 100644 index 00000000..dcf22f7b --- /dev/null +++ b/debuggers/openocd/jimtcl/linenoise.h @@ -0,0 +1,62 @@ +/* linenoise.h -- guerrilla line editing library against the idea that a + * line editing lib needs to be 20,000 lines of C code. + * + * See linenoise.c for more information. + * + * ------------------------------------------------------------------------ + * + * Copyright (c) 2010, Salvatore Sanfilippo + * Copyright (c) 2010, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LINENOISE_H +#define __LINENOISE_H + +/* Currently never enable completion */ +#define NO_COMPLETION + +#ifndef NO_COMPLETION +typedef struct linenoiseCompletions { + size_t len; + char **cvec; +} linenoiseCompletions; + +typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *); +void linenoiseSetCompletionCallback(linenoiseCompletionCallback *); +void linenoiseAddCompletion(linenoiseCompletions *, const char *); +#endif + +char *linenoise(const char *prompt); +int linenoiseHistoryAdd(const char *line); +int linenoiseHistorySetMaxLen(int len); +int linenoiseHistorySave(const char *filename); +int linenoiseHistoryLoad(const char *filename); +void linenoiseHistoryFree(void); +char **linenoiseHistory(int *len); + +#endif /* __LINENOISE_H */ diff --git a/debuggers/openocd/jimtcl/make-bootstrap-jim b/debuggers/openocd/jimtcl/make-bootstrap-jim new file mode 100755 index 00000000..707d8880 --- /dev/null +++ b/debuggers/openocd/jimtcl/make-bootstrap-jim @@ -0,0 +1,118 @@ +#!/bin/sh + +# This script writes to stdout, a single source file (e.g. jimsh0.c) +# which can be compiled to provide a bootstrap version of jimsh. +# e.g. cc -o jimsh0 jimsh0.c + +makeext() +{ + source="$1" + basename=`basename "$source" .tcl` +cat <jim-source.c + +# Converts a Tcl source file into C source suitable +# for loading as a static extension. + +lassign $argv source + +if {![string match *.tcl $source]} { + error "Source $source is not a .tcl file" +} + +# Read the Tcl source and convert to C +# Note that no lines are removed in order to preserve line numbering +set sourcelines {} +set f [open $source] +while {[gets $f buf] >= 0} { + # Remove comment lines + regsub {^[ \t]*#.*$} $buf "" buf + # Escape quotes and backlashes + set buf [string map [list \\ \\\\ \" \\"] $buf] + lappend sourcelines \"$buf\\n\" +} +close $f + +lappend lines {/* autogenerated - do not edit */} +lappend lines {#include } +set basename [file tail $source] +set pkgname [file rootname $basename] + +lappend lines "int Jim_${pkgname}Init(Jim_Interp *interp)" +lappend lines "\{" +lappend lines "\tif (Jim_PackageProvide(interp, \"$pkgname\", \"1.0\", JIM_ERRMSG)) return JIM_ERR;" +lappend lines "\treturn Jim_EvalSource(interp, \"$basename\", 1, [join $sourcelines \n]);" +lappend lines "\}" + +puts [join $lines \n] diff --git a/debuggers/openocd/jimtcl/make-index b/debuggers/openocd/jimtcl/make-index new file mode 100755 index 00000000..1908d007 --- /dev/null +++ b/debuggers/openocd/jimtcl/make-index @@ -0,0 +1,76 @@ +#!/usr/bin/env tclsh +# vim:se syn=tcl: + +set filename [lindex $argv 0] +set f [open $filename] + +# Read the file looking for command definitions +set lines {} +set commands {} +array set cdict {} +set c 0 + +while {[gets $f buf] >= 0} { + if {[string match "~~*" $buf]} { + if {[string match "*: *" $prev]} { + incr c + set target cmd_$c + set lines [linsert $lines end-1 "\[\[$target\]\]"] + set prevlist [split $prev ":, "] + } else { + set target _[string map {:: _} $prev] + set prevlist [list $prev] + } + foreach cmd $prevlist { + set cmd [string trim $cmd] + if {[regexp {^[a-z.:]+$} $cmd]} { + lappend commands [list $cmd $target] + set cdict($cmd) $target + } + } + } + lappend lines $buf + set prev $buf +} +close $f + +# Build the command index in the list: $index +lappend index {[frame="none",grid="none"]} +lappend index {|=========================} +set i 0 +set row {} +foreach command [lsort $commands] { + lassign $command cmd target + + append row "|<<$target,*`$cmd`*>> " + incr i + if {$i % 8 == 0} { + lappend index $row + set row {} + } +} +while {$i % 8 != 0} { + incr i + append row "| " +} +lappend index $row +lappend index {|=========================} + +# Map all `cmd` to <<$target,`cmd`>> +set mapping {} +foreach c [array names cdict] { + lappend mapping `$c` <<$cdict($c),*`$c`*>> + lappend mapping "`$c " "<<$cdict($c),*`$c`*>> `" +} + +# And the command index +lappend mapping @INSERTINDEX@ [join $index \n] + +# Output the result +foreach line $lines { + if {[string first ` $line] >= 0 || [string first @ $line] >= 0} { + puts [string map $mapping $line] + } else { + puts $line + } +} diff --git a/debuggers/openocd/jimtcl/make-load-static-exts.tcl b/debuggers/openocd/jimtcl/make-load-static-exts.tcl new file mode 100644 index 00000000..9185e775 --- /dev/null +++ b/debuggers/openocd/jimtcl/make-load-static-exts.tcl @@ -0,0 +1,48 @@ +#!/usr/bin/env tclsh + +# Usage: make-load-static-exts extname ... >load-static-exts.c + +# Creates load-static-exts.c based on the configured static extensions + +# There are some dependencies on static extensions which require +# a certain load order. Do this by setting priorities and sorting. + +array set pri { + stdlib 0 + readdir 1 + glob 2 + oo 1 + tree 2 + pack 1 + binary 2 +} + +foreach i $argv { + set p 1 + if {[info exists pri($i)]} { + set p $pri($i) + } + lappend exts [list $p $i] +} +set exts [lsort $exts] + +puts { +/* autogenerated - do not edit */ +#include "jim.h" +#include "jimautoconf.h" +int Jim_InitStaticExtensions(Jim_Interp *interp) +} +puts \{ + +foreach e $exts { + set ext [lindex $e 1] + puts "\textern int Jim_${ext}Init(Jim_Interp *);" +} +foreach e $exts { + set ext [lindex $e 1] + puts "\tJim_${ext}Init(interp);" +} + +puts "\treturn JIM_OK;" + +puts \} diff --git a/debuggers/openocd/jimtcl/make-release.sh b/debuggers/openocd/jimtcl/make-release.sh new file mode 100755 index 00000000..07030c7c --- /dev/null +++ b/debuggers/openocd/jimtcl/make-release.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +version=`sed -n -e 's/.*JIM_VERSION *\([0-9]*\).*/0.\1/p' jim.h` + +if [ `git clean -nqx | wc -l` -ne 0 ]; then + git clean -nqx + echo "***: Tree not clean" + exit 1 +fi +if [ `git status | grep modified: | wc -l` -ne 0 ]; then + git status + echo "***: Modified files exist" + exit 1 +fi +mkdir jimtcl-$version +rsync --exclude=.git --exclude=jimtcl-$version -a ./ jimtcl-$version/ +tar -czf jimtcl-$version.tar.gz jimtcl-$version +rm -rf jimtcl-$version +ls -l jimtcl-$version.tar.gz diff --git a/debuggers/openocd/jimtcl/nshelper.tcl b/debuggers/openocd/jimtcl/nshelper.tcl new file mode 100644 index 00000000..c91973f8 --- /dev/null +++ b/debuggers/openocd/jimtcl/nshelper.tcl @@ -0,0 +1,124 @@ +proc {namespace delete} {args} { + foreach name $args { + if {$name ni {:: ""}} { + set name [uplevel 1 [list ::namespace canon $name]] + foreach i [info commands ${name}::*] { rename $i "" } + uplevel #0 [list unset {*}[info globals ${name}::*]] + } + } +} + +proc {namespace origin} {name} { + set nscanon [uplevel 1 [list ::namespace canon $name]] + if {[exists -alias $nscanon]} { + tailcall {namespace origin} [info alias $nscanon] + } + if {[exists -command $nscanon]} { + return ::$nscanon + } + if {[exists -command $name]} { + return ::$name + } + + return -code error "invalid command name \"$name\"" +} + +proc {namespace which} {{type -command} name} { + set nsname ::[uplevel 1 [list ::namespace canon $name]] + if {$type eq "-variable"} { + return $nsname + } + if {$type eq "-command"} { + if {[exists -command $nsname]} { + return $nsname + } elseif {[exists -command ::$name]} { + return ::$name + } + return "" + } + return -code error {wrong # args: should be "namespace which ?-command? ?-variable? name"} +} + + +proc {namespace code} {arg} { + if {[string first "::namespace inscope " $arg] == 0} { + # Already scoped + return $arg + } + list ::namespace inscope [uplevel 1 ::namespace current] $arg +} + +proc {namespace inscope} {name arg args} { + tailcall namespace eval $name $arg $args +} + +proc {namespace import} {args} { + set current [uplevel 1 ::namespace canon] + + foreach pattern $args { + foreach cmd [info commands [namespace canon $current $pattern]] { + alias ${current}::[namespace tail $cmd] $cmd + } + } +} + +# namespace-aware info commands: procs, channels, globals, locals, vars +proc {namespace info} {cmd {pattern *}} { + set current [uplevel 1 ::namespace canon] + # Now we may need to strip $pattern + if {[string first :: $pattern] == 0} { + set global 1 + set prefix :: + } else { + set global 0 + set clen [string length $current] + incr clen 2 + } + set fqp [namespace canon $current $pattern] + switch -glob -- $cmd { + co* - p* { + if {$global} { + set result [info $cmd $fqp] + } else { + # Add commands in the current namespace + set r {} + foreach c [info $cmd $fqp] { + dict set r [string range $c $clen end] 1 + } + if {[string match co* $cmd]} { + # Now in the global namespace + foreach c [info -nons commands $pattern] { + dict set r $c 1 + } + } + set result [dict keys $r] + } + } + ch* { + set result [info channels $pattern] + } + v* { + #puts "uplevel #0 info gvars $fqp" + set result [uplevel #0 info -nons vars $fqp] + } + g* { + set result [info globals $fqp] + } + l* { + set result [uplevel 1 info -nons locals $pattern] + } + } + if {$global} { + set result [lmap p $result { set p $prefix$p }] + } + return $result +} + +proc {namespace upvar} {ns args} { + set nscanon ::[uplevel 1 [list ::namespace canon $ns]] + set script [list upvar 0] + foreach {other local} $args { + lappend script ${nscanon}::$other $local + } + tailcall {*}$script +} diff --git a/debuggers/openocd/jimtcl/oo.tcl b/debuggers/openocd/jimtcl/oo.tcl new file mode 100644 index 00000000..b57daf5d --- /dev/null +++ b/debuggers/openocd/jimtcl/oo.tcl @@ -0,0 +1,92 @@ +# OO support for Jim Tcl, with multiple inheritance + +# Create a new class $classname, with the given +# dictionary as class variables. These are the initial +# variables which all newly created objects of this class are +# initialised with. +# +# If a list of baseclasses is given, +# methods and instance variables are inherited. +# The *last* baseclass can be accessed directly with [super] +# Later baseclasses take precedence if the same method exists in more than one +proc class {classname {baseclasses {}} classvars} { + set baseclassvars {} + foreach baseclass $baseclasses { + # Start by mapping all methods to the parent class + foreach method [$baseclass methods] { alias "$classname $method" "$baseclass $method" } + # Now import the base class classvars + set baseclassvars [dict merge $baseclassvars [$baseclass classvars]] + # The last baseclass will win here + proc "$classname baseclass" {} baseclass { return $baseclass } + } + + # Merge in the baseclass vars with lower precedence + set classvars [dict merge $baseclassvars $classvars] + set vars [lsort [dict keys $classvars]] + + # This is the class dispatcher for $classname + # It simply dispatches 'classname cmd' to a procedure named {classname cmd} + # with a nice message if the class procedure doesn't exist + proc $classname {{cmd new} args} classname { + if {![exists -command "$classname $cmd"]} { + return -code error "$classname, unknown command \"$cmd\": should be [join [$classname methods] ", "]" + } + tailcall "$classname $cmd" {*}$args + } + + # Constructor + proc "$classname new" {{instvars {}}} {classname classvars} { + set instvars [dict merge $classvars $instvars] + + # This is the object dispatcher for $classname. + # Store the classname in both the ref value and tag, for debugging + # ref tag (for debugging) + proc [ref $classname $classname "$classname finalize"] {method args} {classname instvars} { + if {![exists -command "$classname $method"]} { + return -code error "$classname, unknown method \"$method\": should be [join [$classname methods] ", "]" + } + "$classname $method" {*}$args + } + } + # Finalizer to invoke destructor during garbage collection + proc "$classname finalize" {ref classname} { $ref destroy } + # Method creator + proc "$classname method" {method arglist body} classname { + proc "$classname $method" $arglist {body} { + # Make sure this isn't incorrectly called without an object + if {![uplevel exists instvars]} { + return -code error -level 2 "\"[lindex [info level 0] 0]\" method called with no object" + } + set self [lindex [info level -1] 0] + # Note that we can't use 'dict with' here because + # the dict isn't updated until the body completes. + foreach _ [$self vars] {upvar 1 instvars($_) $_} + unset _ + eval $body + } + } + # Other simple class procs + proc "$classname vars" {} vars { return $vars } + proc "$classname classvars" {} classvars { return $classvars } + proc "$classname classname" {} classname { return $classname } + proc "$classname methods" {} classname { + lsort [lmap p [info procs "$classname *"] { + lindex [split $p " "] 1 + }] + } + # Pre-defined some instance methods + $classname method destroy {} { rename $self "" } + $classname method get {var} { set $var } + $classname method eval {{locals {}} code} { + foreach var $locals { upvar 2 $var $var } + eval $code + } + return $classname +} + +# From within a method, invokes the given method on the base class. +# Note that this will only call the last baseclass given +proc super {method args} { + upvar self self + uplevel 2 [$self baseclass] $method {*}$args +} diff --git a/debuggers/openocd/jimtcl/parse-unidata.tcl b/debuggers/openocd/jimtcl/parse-unidata.tcl new file mode 100644 index 00000000..348a114a --- /dev/null +++ b/debuggers/openocd/jimtcl/parse-unidata.tcl @@ -0,0 +1,53 @@ +#!/usr/bin/env tclsh + +# Generate UTF-8 case mapping tables +# +# (c) 2010 Steve Bennett +# +# See LICENCE for licence details. +#/ + +# Parse the unicode data from: http://unicode.org/Public/UNIDATA/UnicodeData.txt +# to generate case mapping tables +set map(lower) {} +set map(upper) {} +set map(title) {} + +set f [open [lindex $argv 0]] +while {[gets $f buf] >= 0} { + set title "" + set lower "" + set upper "" + foreach {code name class x x x x x x x x x upper lower title} [split $buf ";"] break + set codex [string tolower 0x$code] + if {$codex <= 0x7f} { + continue + } + if {$codex > 0xffff} { + break + } + if {![string match L* $class]} { + continue + } + if {$upper ne ""} { + lappend map(upper) $codex [string tolower 0x$upper] + } + if {$lower ne ""} { + lappend map(lower) $codex [string tolower 0x$lower] + } + if {$title ne "" && $title ne $upper} { + if {$title eq $code} { + set title 0 + } + lappend map(title) $codex [string tolower 0x$title] + } +} +close $f + +foreach type {upper lower title} { + puts "static const struct casemap unicode_case_mapping_$type\[\] = \{" + foreach {code alt} $map($type) { + puts "\t{ $code, $alt }," + } + puts "\};\n" +} diff --git a/debuggers/openocd/jimtcl/regtest.tcl b/debuggers/openocd/jimtcl/regtest.tcl new file mode 100644 index 00000000..2f09700d --- /dev/null +++ b/debuggers/openocd/jimtcl/regtest.tcl @@ -0,0 +1,215 @@ +# REGTEST 1 +# 27Jan2005 - SIGSEGV for bug on Jim_DuplicateObj(). + +for {set i 0} {$i < 100} {incr i} { + set a "x" + lappend a n +} +puts "TEST 1 PASSED" + +# REGTEST 2 +# 29Jan2005 - SEGFAULT parsing script composed of just one comment. +eval {#foobar} +puts "TEST 2 PASSED" + +# REGTEST 3 +# 29Jan2005 - "Error in Expression" with correct expression +set x 5 +expr {$x-5} +puts "TEST 3 PASSED" + +# REGTEST 4 +# 29Jan2005 - SIGSEGV when run this code, due to expr's bug. +proc fibonacci {x} { + if {$x <= 1} { + expr 1 + } else { + expr {[fibonacci [expr {$x-1}]] + [fibonacci [expr {$x-2}]]} + } +} +fibonacci 6 +puts "TEST 4 PASSED" + +# REGTEST 5 +# 06Mar2005 - This looped forever... +for {set i 0} {$i < 10} {incr i} {continue} +puts "TEST 5 PASSED" + +# REGTEST 6 +# 07Mar2005 - Unset create variable + dict is using dict syntax sugar at +# currently non-existing variable +catch {unset thisvardoesnotexists(thiskeytoo)} +if {[catch {set thisvardoesnotexists}] == 0} { + puts "TEST 6 FAILED - unset created dict for non-existing variable" + break +} +puts "TEST 6 PASSED" + +# REGTEST 7 +# 04Nov2008 - variable parsing does not eat last brace +set a 1 +list ${a} +puts "TEST 7 PASSED" + +# REGTEST 8 +# 04Nov2008 - string toupper/tolower do not convert to string rep +string tolower [list a] +string toupper [list a] +puts "TEST 8 PASSED" + +# REGTEST 9 +# 04Nov2008 - crash on exit when replacing Tcl proc with C command. +# Requires the clock extension to be built as a loadable module. +proc clock {args} {} +catch {package require clock} +# Note, crash on exit, so don't say we passed! + +# REGTEST 10 +# 05Nov2008 - incorrect lazy expression evaluation with unary not +expr {1 || !0} +puts "TEST 10 PASSED" + +# REGTEST 11 +# 14 Feb 2010 - access static variable in deleted proc +proc a {} {{x 1}} { rename a ""; incr x } +a +puts "TEST 11 PASSED" + +# REGTEST 12 +# 13 Sep 2010 - reference with invalid tag +set a b[ref value "tag name"] +getref [string range $a 1 end] +puts "TEST 12 PASSED" + +# REGTEST 13 +# 14 Sep 2010 - parse list with trailing backslash +set x "switch -0 \$on \\" +lindex $x 1 +puts "TEST 13 PASSED" + +# REGTEST 14 +# 14 Sep 2010 - command expands to nothing +eval "{*}{}" +puts "TEST 14 PASSED" + +# REGTEST 15 +# 24 Feb 2010 - bad reference counting of the stack trace in 'error' +proc a {msg stack} { + tailcall error $msg $stack +} +catch {fail} msg opts +catch {a $msg $opts(-errorinfo)} + +# REGTEST 16 +# 24 Feb 2010 - rename the current proc +# Leaves unfreed objects on the stack +proc a {} { rename a newa} +a + +# REGTEST 17 +# 26 Nov 2010 - crashes on invalid dict sugar +catch {eval {$x(}} +puts "TEST 17 PASSED" + +# REGTEST 18 +# 12 Apr 2011 - crashes on unset for loop var +catch { + for {set i 0} {$i < 5} {incr i} {unset i} +} +puts "TEST 18 PASSED" + +# REGTEST 19 +# 25 May 2011 - crashes with double colon +catch { + expr {5 ne ::} +} +puts "TEST 19 PASSED" + +# REGTEST 20 +# 26 May 2011 - infinite recursion +proc a {} { global ::blah; set ::blah test } +a +puts "TEST 20 PASSED" + +# REGTEST 21 +# 26 May 2011 - infinite loop with null byte in subst +subst "abc\0def" +puts "TEST 21 PASSED" + +# REGTEST 22 +# 21 June 2011 - crashes on lappend to to value with script rep +set x rand +eval $x +lappend x b +puts "TEST 22 PASSED" + +# REGTEST 23 +# 27 July 2011 - unfreed objects on exit +catch { + set x abc + subst $x + regexp $x $x +} +# Actually, the test passes if no objects leaked on exit +puts "TEST 23 PASSED" + +# REGTEST 24 +# 13 Nov 2011 - invalid cached global var +proc a {} { + foreach i {1 2} { + incr z [set ::t] + unset ::t + } +} +set t 6 +catch a +puts "TEST 24 PASSED" + +# REGTEST 25 +# 14 Nov 2011 - link global var to proc var +proc a {} { + set x 3 + upvar 0 x ::globx +} +set globx 0 +catch { + a +} +incr globx +puts "TEST 25 PASSED" + +# REGTEST 26 +# 2 Dec 2011 - infinite eval recursion +catch { + set x 0 + set y {incr x; eval $y} + eval $y +} msg +puts "TEST 26 PASSED" + +# REGTEST 27 +# 2 Dec 2011 - infinite alias recursion +catch { + proc p {} {} + alias p p + p +} msg +puts "TEST 27 PASSED" + +# REGTEST 28 +# 16 Dec 2011 - ref count problem with finalizers +catch { + ref x x [list dummy] + collect +} +puts "TEST 28 PASSED" + +# REGTEST 29 +# Reference counting problem at exit +set x [lindex {} 0] +info source $x +eval $x + +# TAKE THE FOLLOWING puts AS LAST LINE + +puts "--- ALL TESTS PASSED ---" diff --git a/debuggers/openocd/jimtcl/rlprompt.tcl b/debuggers/openocd/jimtcl/rlprompt.tcl new file mode 100644 index 00000000..cdd78d4c --- /dev/null +++ b/debuggers/openocd/jimtcl/rlprompt.tcl @@ -0,0 +1,45 @@ +# Readline-based interactive shell for Jim +# Copyright(C) 2005 Salvatore Sanfilippo +# +# In order to automatically have readline-editing features +# put this in your $HOME/.jimrc +# +# if {$jim_interactive} { +# if {[catch {package require rlprompt}] == 0} { +# rlprompt.shell +# } +# } +package require readline + +proc rlprompt.shell {} { + puts "Readline shell loaded" + puts "Welcome to Jim [info version]!" + set prompt ". " + set buf "" + while 1 { + set line [readline.readline $prompt] + + if {[string length $line] == 0} { + continue + } + if {$buf eq ""} { + set buf $line + } else { + append buf \n $line + } + if {![info complete $buf]} { + set prompt "> " + continue + } + readline.addhistory $buf + + catch { + uplevel #0 $buf + } error + if {$error ne ""} { + puts $error + } + set buf "" + set prompt ". " + } +} diff --git a/debuggers/openocd/jimtcl/sqlite3/README b/debuggers/openocd/jimtcl/sqlite3/README new file mode 100644 index 00000000..d1094ddd --- /dev/null +++ b/debuggers/openocd/jimtcl/sqlite3/README @@ -0,0 +1,60 @@ +Full sqlite3 Extension for Jim Tcl +================================== + +Author: Steve Bennett +Date: Thu 24 Nov 2011 + +This directory builds a Jim Tcl extension containing a complete sqlite3 implementation and binding. + +Building +-------- + +Ensure that you have configured and built jim in the source directory, then: + +$ make + +./build-ext -o sqlite3.so -I.. -L.. -DSQLITE_OMIT_LOAD_EXTENSION=1 ... jim-sqlite3.c sqlite3.c +Building sqlite3.so from jim-sqlite3.c sqlite3.c + +Warning: libjim is static. Dynamic module may not work on some platforms. + +Compile: jim-sqlite3.o +Compile: sqlite3.o +Link: sqlite3.so + +Success! + +Testing +------- + +$ make test + +Installing +---------- + +Copy sqlite3.so to your jim library directory, typically /usr/local/lib/jim or +where $JIMLIB points to. + +Using +----- +In your Jim Tcl code, ensure that sqlite3.so is in a directory on $auto_path. +Then: + + package require sqlite3 + + sqlite3 db test.db + ...etc.. + +Documentation +------------- + +The Jim Tcl binding is almost exactly identical to the Tcl binding. +See http://www.sqlite.org/tclsqlite.html for documentation. + +Differences: +- INCRBLOB is not supported as Jim Tcl does not support channels +- No attempt is made to change encoding between Jim Tcl and sqlite +- Jim Tcl doesn't differentiate between binary data (bytearray) and + string, so only the @field syntax causes a fieldsto be bound + as a blob rather than text. +- Jim Tcl doesn't have a boolean type diff --git a/debuggers/openocd/jimtcl/sqlite3/jim-sqlite3.c b/debuggers/openocd/jimtcl/sqlite3/jim-sqlite3.c new file mode 100644 index 00000000..7b09a9ae --- /dev/null +++ b/debuggers/openocd/jimtcl/sqlite3/jim-sqlite3.c @@ -0,0 +1,2830 @@ +/* Jim Tcl version of the sqlite3 Tcl binding. + * From sqlite3 3.6.22 + * + * This version is (c) Steve Bennett + * Copyright of the original version is below. + */ + +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** A TCL Interface to SQLite. Append this file to sqlite3.c and +** compile the whole thing to build a TCL-enabled version of SQLite. +** +** Compile-time options: +** +** -D SQLITE_TEST When used in conjuction with -DTCLSH=1, add +** hundreds of new commands used for testing +** SQLite. This option implies -DSQLITE_TCLMD5. +*/ +#include +#include +#include +#include + +/* +** Some additional include files are needed if this file is not +** appended to the amalgamation. +*/ +#ifndef SQLITE_AMALGAMATION +# include "sqlite3.h" +# include +# include +# include + typedef unsigned char u8; +#endif +#include + +#define NUM_PREPARED_STMTS 10 +#define MAX_PREPARED_STMTS 100 + +/* +** If Jim Tcl uses UTF-8 and SQLite is configured to use iso8859, then we +#ifdef JIM_UTF8 +#define SQLITE_UTF8 +#endif + +** have to do a translation when going between the two. Set the +** UTF_TRANSLATION_NEEDED macro to indicate that we need to do +** this translation. +*/ +#if defined(JIM_UTF8) && !defined(SQLITE_UTF8) +# define UTF_TRANSLATION_NEEDED 1 +# warning Jim Tcl can not translate encoding from iso8859 to utf-8 +#endif + +/* +** New SQL functions can be created as TCL scripts. Each such function +** is described by an instance of the following structure. +*/ +typedef struct SqlFunc SqlFunc; +struct SqlFunc { + Jim_Interp *interp; /* The TCL interpret to execute the function */ + Jim_Obj *pScript; /* The Jim_Obj representation of the script */ + int useEvalObjv; /* True if it is safe to use Jim_EvalObjv */ + char *zName; /* Name of this function */ + SqlFunc *pNext; /* Next function on the list of them all */ +}; + +/* +** New collation sequences function can be created as TCL scripts. Each such +** function is described by an instance of the following structure. +*/ +typedef struct SqlCollate SqlCollate; +struct SqlCollate { + Jim_Interp *interp; /* The TCL interpret to execute the function */ + char *zScript; /* The script to be run */ + SqlCollate *pNext; /* Next function on the list of them all */ +}; + +/* +** Prepared statements are cached for faster execution. Each prepared +** statement is described by an instance of the following structure. +*/ +typedef struct SqlPreparedStmt SqlPreparedStmt; +struct SqlPreparedStmt { + SqlPreparedStmt *pNext; /* Next in linked list */ + SqlPreparedStmt *pPrev; /* Previous on the list */ + sqlite3_stmt *pStmt; /* The prepared statement */ + int nSql; /* chars in zSql[] */ + const char *zSql; /* Text of the SQL statement */ + int nParm; /* Size of apParm array */ + Jim_Obj **apParm; /* Array of referenced object pointers */ +}; + +typedef struct IncrblobChannel IncrblobChannel; + +/* +** There is one instance of this structure for each SQLite database +** that has been opened by the SQLite TCL interface. +*/ +typedef struct SqliteDb SqliteDb; +struct SqliteDb { + sqlite3 *db; /* The "real" database structure. MUST BE FIRST */ + Jim_Interp *interp; /* The interpreter used for this database */ + char *zBusy; /* The busy callback routine */ + char *zCommit; /* The commit hook callback routine */ + char *zTrace; /* The trace callback routine */ + char *zProfile; /* The profile callback routine */ + char *zProgress; /* The progress callback routine */ + char *zAuth; /* The authorization callback routine */ + int disableAuth; /* Disable the authorizer if it exists */ + char *zNull; /* Text to substitute for an SQL NULL value */ + SqlFunc *pFunc; /* List of SQL functions */ + Jim_Obj *pUpdateHook; /* Update hook script (if any) */ + Jim_Obj *pRollbackHook; /* Rollback hook script (if any) */ + Jim_Obj *pUnlockNotify; /* Unlock notify script (if any) */ + SqlCollate *pCollate; /* List of SQL collation functions */ + int rc; /* Return code of most recent sqlite3_exec() */ + Jim_Obj *pCollateNeeded; /* Collation needed script */ + SqlPreparedStmt *stmtList; /* List of prepared statements*/ + SqlPreparedStmt *stmtLast; /* Last statement in the list */ + int maxStmt; /* The next maximum number of stmtList */ + int nStmt; /* Number of statements in stmtList */ + IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */ + int nStep, nSort; /* Statistics for most recent operation */ + int nTransaction; /* Number of nested [transaction] methods */ +}; + +struct IncrblobChannel { + sqlite3_blob *pBlob; /* sqlite3 blob handle */ + SqliteDb *pDb; /* Associated database connection */ + int iSeek; /* Current seek offset */ + Jim_Obj *channel; /* Channel identifier */ + IncrblobChannel *pNext; /* Linked list of all open incrblob channels */ + IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */ +}; + +/* +** Compute a string length that is limited to what can be stored in +** lower 30 bits of a 32-bit signed integer. +*/ +static int strlen30(const char *z){ + const char *z2 = z; + while( *z2 ){ z2++; } + return 0x3fffffff & (int)(z2 - z); +} + + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** Close all incrblob channels opened using database connection pDb. +** This is called when shutting down the database connection. +*/ +static void closeIncrblobChannels(SqliteDb *pDb){ + IncrblobChannel *p; + IncrblobChannel *pNext; + + for(p=pDb->pIncrblob; p; p=pNext){ + pNext = p->pNext; + + /* Note: Calling unregister here call Jim_Close on the incrblob channel, + ** which deletes the IncrblobChannel structure at *p. So do not + ** call Jim_Free() here. + */ + Jim_UnregisterChannel(pDb->interp, p->channel); + } +} + +/* +** Close an incremental blob channel. +*/ +static int incrblobClose(ClientData instanceData, Jim_Interp *interp){ + IncrblobChannel *p = (IncrblobChannel *)instanceData; + int rc = sqlite3_blob_close(p->pBlob); + sqlite3 *db = p->pDb->db; + + /* Remove the channel from the SqliteDb.pIncrblob list. */ + if( p->pNext ){ + p->pNext->pPrev = p->pPrev; + } + if( p->pPrev ){ + p->pPrev->pNext = p->pNext; + } + if( p->pDb->pIncrblob==p ){ + p->pDb->pIncrblob = p->pNext; + } + + /* Free the IncrblobChannel structure */ + Jim_Free((char *)p); + + if( rc!=SQLITE_OK ){ + Jim_SetResult(interp, (char *)sqlite3_errmsg(db), JIM_VOLATILE); + return JIM_ERR; + } + return JIM_OK; +} + +/* +** Read data from an incremental blob channel. +*/ +static int incrblobInput( + ClientData instanceData, + char *buf, + int bufSize, + int *errorCodePtr +){ + IncrblobChannel *p = (IncrblobChannel *)instanceData; + int nRead = bufSize; /* Number of bytes to read */ + int nBlob; /* Total size of the blob */ + int rc; /* sqlite error code */ + + nBlob = sqlite3_blob_bytes(p->pBlob); + if( (p->iSeek+nRead)>nBlob ){ + nRead = nBlob-p->iSeek; + } + if( nRead<=0 ){ + return 0; + } + + rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek); + if( rc!=SQLITE_OK ){ + *errorCodePtr = rc; + return -1; + } + + p->iSeek += nRead; + return nRead; +} + +/* +** Write data to an incremental blob channel. +*/ +static int incrblobOutput( + ClientData instanceData, + CONST char *buf, + int toWrite, + int *errorCodePtr +){ + IncrblobChannel *p = (IncrblobChannel *)instanceData; + int nWrite = toWrite; /* Number of bytes to write */ + int nBlob; /* Total size of the blob */ + int rc; /* sqlite error code */ + + nBlob = sqlite3_blob_bytes(p->pBlob); + if( (p->iSeek+nWrite)>nBlob ){ + *errorCodePtr = EINVAL; + return -1; + } + if( nWrite<=0 ){ + return 0; + } + + rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek); + if( rc!=SQLITE_OK ){ + *errorCodePtr = EIO; + return -1; + } + + p->iSeek += nWrite; + return nWrite; +} + +/* +** Seek an incremental blob channel. +*/ +static int incrblobSeek( + ClientData instanceData, + long offset, + int seekMode, + int *errorCodePtr +){ + IncrblobChannel *p = (IncrblobChannel *)instanceData; + + switch( seekMode ){ + case SEEK_SET: + p->iSeek = offset; + break; + case SEEK_CUR: + p->iSeek += offset; + break; + case SEEK_END: + p->iSeek = sqlite3_blob_bytes(p->pBlob) + offset; + break; + + default: assert(!"Bad seekMode"); + } + + return p->iSeek; +} + + +static void incrblobWatch(ClientData instanceData, int mode){ + /* NO-OP */ +} +static int incrblobHandle(ClientData instanceData, int dir, ClientData *hPtr){ + return JIM_ERR; +} + +static Jim_ChannelType IncrblobChannelType = { + "incrblob", /* typeName */ + JIM_CHANNEL_VERSION_2, /* version */ + incrblobClose, /* closeProc */ + incrblobInput, /* inputProc */ + incrblobOutput, /* outputProc */ + incrblobSeek, /* seekProc */ + 0, /* setOptionProc */ + 0, /* getOptionProc */ + incrblobWatch, /* watchProc (this is a no-op) */ + incrblobHandle, /* getHandleProc (always returns error) */ + 0, /* close2Proc */ + 0, /* blockModeProc */ + 0, /* flushProc */ + 0, /* handlerProc */ + 0, /* wideSeekProc */ +}; + +/* +** Create a new incrblob channel. +*/ +static int createIncrblobChannel( + Jim_Interp *interp, + SqliteDb *pDb, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite_int64 iRow, + int isReadonly +){ + IncrblobChannel *p; + sqlite3 *db = pDb->db; + sqlite3_blob *pBlob; + int rc; + int flags = JIM_READABLE|(isReadonly ? 0 : JIM_WRITABLE); + + /* This variable is used to name the channels: "incrblob_[incr count]" */ + static int count = 0; + char zChannel[64]; + + rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob); + if( rc!=SQLITE_OK ){ + Jim_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), JIM_VOLATILE); + return JIM_ERR; + } + + p = (IncrblobChannel *)Jim_Alloc(sizeof(IncrblobChannel)); + p->iSeek = 0; + p->pBlob = pBlob; + + sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count); + p->channel = Jim_CreateChannel(&IncrblobChannelType, zChannel, p, flags); + Jim_RegisterChannel(interp, p->channel); + + /* Link the new channel into the SqliteDb.pIncrblob list. */ + p->pNext = pDb->pIncrblob; + p->pPrev = 0; + if( p->pNext ){ + p->pNext->pPrev = p; + } + pDb->pIncrblob = p; + p->pDb = pDb; + + Jim_SetResult(interp, (char *)Jim_GetChannelName(p->channel), JIM_VOLATILE); + return JIM_OK; +} +#else /* else clause for "#ifndef SQLITE_OMIT_INCRBLOB" */ + #define closeIncrblobChannels(pDb) +#endif + +/* +** Look at the script prefix in pCmd. We will be executing this script +** after first appending one or more arguments. This routine analyzes +** the script to see if it is safe to use Jim_EvalObjv() on the script +** rather than the more general Jim_EvalEx(). Jim_EvalObjv() is much +** faster. +** +** Scripts that are safe to use with Jim_EvalObjv() consists of a +** command name followed by zero or more arguments with no [...] or $ +** or {...} or ; to be seen anywhere. Most callback scripts consist +** of just a single procedure name and they meet this requirement. +*/ +static int safeToUseEvalObjv(Jim_Interp *interp, Jim_Obj *pCmd){ + /* We could try to do something with Jim_Parse(). But we will instead + ** just do a search for forbidden characters. If any of the forbidden + ** characters appear in pCmd, we will report the string as unsafe. + */ + const char *z; + int n; + z = Jim_GetString(pCmd, &n); + while( n-- > 0 ){ + int c = *(z++); + if( c=='$' || c=='[' || c==';' ) return 0; + } + return 1; +} + +/* +** Find an SqlFunc structure with the given name. Or create a new +** one if an existing one cannot be found. Return a pointer to the +** structure. +*/ +static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){ + SqlFunc *p, *pNew; + int i; + pNew = (SqlFunc*)Jim_Alloc( sizeof(*pNew) + strlen30(zName) + 1 ); + pNew->zName = (char*)&pNew[1]; + for(i=0; zName[i]; i++){ pNew->zName[i] = tolower((unsigned)zName[i]); } + pNew->zName[i] = 0; + for(p=pDb->pFunc; p; p=p->pNext){ + if( strcmp(p->zName, pNew->zName)==0 ){ + Jim_Free((char*)pNew); + return p; + } + } + pNew->interp = pDb->interp; + pNew->pScript = 0; + pNew->pNext = pDb->pFunc; + pDb->pFunc = pNew; + return pNew; +} + +/* +** Finalize and free a list of prepared statements +*/ +static void flushStmtCache( SqliteDb *pDb ){ + SqlPreparedStmt *pPreStmt; + + while( pDb->stmtList ){ + sqlite3_finalize( pDb->stmtList->pStmt ); + pPreStmt = pDb->stmtList; + pDb->stmtList = pDb->stmtList->pNext; + Jim_Free( (char*)pPreStmt ); + } + pDb->nStmt = 0; + pDb->stmtLast = 0; +} + +/* +** TCL calls this procedure when an sqlite3 database command is +** deleted. +*/ +static void DbDeleteCmd(Jim_Interp *interp, void *db){ + SqliteDb *pDb = (SqliteDb*)db; + flushStmtCache(pDb); + closeIncrblobChannels(pDb); + sqlite3_close(pDb->db); + while( pDb->pFunc ){ + SqlFunc *pFunc = pDb->pFunc; + pDb->pFunc = pFunc->pNext; + Jim_DecrRefCount(interp, pFunc->pScript); + Jim_Free((char*)pFunc); + } + while( pDb->pCollate ){ + SqlCollate *pCollate = pDb->pCollate; + pDb->pCollate = pCollate->pNext; + Jim_Free((char*)pCollate); + } + if( pDb->zBusy ){ + Jim_Free(pDb->zBusy); + } + if( pDb->zTrace ){ + Jim_Free(pDb->zTrace); + } + if( pDb->zProfile ){ + Jim_Free(pDb->zProfile); + } + if( pDb->zAuth ){ + Jim_Free(pDb->zAuth); + } + if( pDb->zNull ){ + Jim_Free(pDb->zNull); + } + if( pDb->pUpdateHook ){ + Jim_DecrRefCount(interp, pDb->pUpdateHook); + } + if( pDb->pRollbackHook ){ + Jim_DecrRefCount(interp, pDb->pRollbackHook); + } + if( pDb->pCollateNeeded ){ + Jim_DecrRefCount(interp, pDb->pCollateNeeded); + } + Jim_Free((char*)pDb); +} + +/* +** This routine is called when a database file is locked while trying +** to execute SQL. +*/ +static int DbBusyHandler(void *cd, int nTries){ + SqliteDb *pDb = (SqliteDb*)cd; + int rc; + char zVal[30]; + Jim_Obj *objPtr; + + sqlite3_snprintf(sizeof(zVal), zVal, "%d", nTries); + + objPtr = Jim_NewStringObj(pDb->interp, pDb->zBusy, -1); + Jim_AppendStrings(pDb->interp, objPtr, " ", zVal, NULL); + rc = Jim_EvalObj(pDb->interp, objPtr); + if( rc!=JIM_OK || atoi(Jim_String(Jim_GetResult(pDb->interp))) ){ + return 0; + } + return 1; +} + +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK +/* +** This routine is invoked as the 'progress callback' for the database. +*/ +static int DbProgressHandler(void *cd){ + SqliteDb *pDb = (SqliteDb*)cd; + int rc; + + assert( pDb->zProgress ); + rc = Jim_Eval(pDb->interp, pDb->zProgress); + if( rc!=JIM_OK || atoi(Jim_String(Jim_GetResult(pDb->interp))) ){ + return 1; + } + return 0; +} +#endif + +#ifndef SQLITE_OMIT_TRACE +/* +** This routine is called by the SQLite trace handler whenever a new +** block of SQL is executed. The TCL script in pDb->zTrace is executed. +*/ +static void DbTraceHandler(void *cd, const char *zSql){ + SqliteDb *pDb = (SqliteDb*)cd; + + Jim_Obj *str = Jim_NewStringObj(pDb->interp, pDb->zTrace, -1); + Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zSql, -1)); + Jim_Eval(pDb->interp, zSql); + Jim_SetEmptyResult(pDb->interp); +} +#endif + +#ifndef SQLITE_OMIT_TRACE +/* +** This routine is called by the SQLite profile handler after a statement +** SQL has executed. The TCL script in pDb->zProfile is evaluated. +*/ +static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){ + SqliteDb *pDb = (SqliteDb*)cd; + Jim_Obj *str; + char zTm[100]; + + sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm); + str = Jim_NewStringObj(pDb->interp, pDb->zProfile, -1); + Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zSql, -1)); + Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zTm, -1)); + Jim_EvalObj(pDb->interp, str); + Jim_SetEmptyResult(pDb->interp); +} +#endif + +/* +** This routine is called when a transaction is committed. The +** TCL script in pDb->zCommit is executed. If it returns non-zero or +** if it throws an exception, the transaction is rolled back instead +** of being committed. +*/ +static int DbCommitHandler(void *cd){ + SqliteDb *pDb = (SqliteDb*)cd; + int rc; + + rc = Jim_Eval(pDb->interp, pDb->zCommit); + if( rc!=JIM_OK || atoi(Jim_String(Jim_GetResult(pDb->interp))) ){ + return 1; + } + return 0; +} + +static void DbRollbackHandler(void *clientData){ + SqliteDb *pDb = (SqliteDb*)clientData; + assert(pDb->pRollbackHook); + Jim_EvalObjBackground(pDb->interp, pDb->pRollbackHook); +} + +#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY) +static void setTestUnlockNotifyVars(Jim_Interp *interp, int iArg, int nArg){ + char zBuf[64]; + sprintf(zBuf, "%d", iArg); + Jim_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, JIM_GLOBAL_ONLY); + sprintf(zBuf, "%d", nArg); + Jim_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, JIM_GLOBAL_ONLY); +} +#else +# define setTestUnlockNotifyVars(x,y,z) +#endif + +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY +static void DbUnlockNotify(void **apArg, int nArg){ + int i; + for(i=0; iinterp, i, nArg); + assert( pDb->pUnlockNotify); + Jim_EvalObjEx(pDb->interp, pDb->pUnlockNotify, flags); + Jim_DecrRefCount(interp, pDb->pUnlockNotify); + pDb->pUnlockNotify = 0; + } +} +#endif + +static void DbUpdateHandler( + void *p, + int op, + const char *zDb, + const char *zTbl, + sqlite_int64 rowid +){ + SqliteDb *pDb = (SqliteDb *)p; + Jim_Obj *pCmd; + + assert( pDb->pUpdateHook ); + assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE ); + + pCmd = Jim_DuplicateObj(pDb->interp, pDb->pUpdateHook); + Jim_IncrRefCount(pCmd); + Jim_ListAppendElement(0, pCmd, Jim_NewStringObj(pDb->interp, + ( (op==SQLITE_INSERT)?"INSERT":(op==SQLITE_UPDATE)?"UPDATE":"DELETE"), -1)); + Jim_ListAppendElement(pDb->interp, pCmd, Jim_NewStringObj(pDb->interp, zDb, -1)); + Jim_ListAppendElement(pDb->interp, pCmd, Jim_NewStringObj(pDb->interp, zTbl, -1)); + Jim_ListAppendElement(pDb->interp, pCmd, Jim_NewIntObj(pDb->interp, rowid)); + Jim_EvalObj(pDb->interp, pCmd); +} + +static void tclCollateNeeded( + void *pCtx, + sqlite3 *db, + int enc, + const char *zName +){ + SqliteDb *pDb = (SqliteDb *)pCtx; + Jim_Obj *pScript = Jim_DuplicateObj(pDb->interp, pDb->pCollateNeeded); + //Jim_IncrRefCount(pScript); + Jim_ListAppendElement(pDb->interp, pScript, Jim_NewStringObj(pDb->interp, zName, -1)); + Jim_EvalObj(pDb->interp, pScript); + //Jim_DecrRefCount(pDb->interp, pScript); +} + +/* +** This routine is called to evaluate an SQL collation function implemented +** using TCL script. +*/ +static int tclSqlCollate( + void *pCtx, + int nA, + const void *zA, + int nB, + const void *zB +){ + SqlCollate *p = (SqlCollate *)pCtx; + Jim_Obj *pCmd; + + pCmd = Jim_NewStringObj(p->interp, p->zScript, -1); + //Jim_IncrRefCount(pCmd); + Jim_ListAppendElement(p->interp, pCmd, Jim_NewStringObj(p->interp, zA, nA)); + Jim_ListAppendElement(p->interp, pCmd, Jim_NewStringObj(p->interp, zB, nB)); + Jim_EvalObj(p->interp, pCmd); + //Jim_DecrRefCount(interp, pCmd); + return (atoi(Jim_String(Jim_GetResult(p->interp)))); +} + +/* +** This routine is called to evaluate an SQL function implemented +** using TCL script. +*/ +static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ + SqlFunc *p = sqlite3_user_data(context); + Jim_Obj *pCmd; + int i; + int rc; + + if( argc==0 ){ + /* If there are no arguments to the function, call Jim_EvalObjEx on the + ** script object directly. This allows the TCL compiler to generate + ** bytecode for the command on the first invocation and thus make + ** subsequent invocations much faster. */ + pCmd = p->pScript; + //Jim_IncrRefCount(pCmd); + rc = Jim_EvalObj(p->interp, pCmd); + //Jim_DecrRefCount(interp, pCmd); + }else{ + /* If there are arguments to the function, make a shallow copy of the + ** script object, lappend the arguments, then evaluate the copy. + ** + ** By "shallow" copy, we mean a only the outer list Jim_Obj is duplicated. + ** The new Jim_Obj contains pointers to the original list elements. + ** That way, when Jim_EvalObjv() is run and shimmers the first element + ** of the list to tclCmdNameType, that alternate representation will + ** be preserved and reused on the next invocation. + */ + pCmd = Jim_DuplicateObj(p->interp, p->pScript); + Jim_IncrRefCount(pCmd); + for(i=0; iinterp, sqlite3_value_blob(pIn), bytes); + break; + } + case SQLITE_INTEGER: { + sqlite_int64 v = sqlite3_value_int64(pIn); + pVal = Jim_NewIntObj(p->interp, v); + break; + } + case SQLITE_FLOAT: { + double r = sqlite3_value_double(pIn); + pVal = Jim_NewDoubleObj(p->interp, r); + break; + } + case SQLITE_NULL: { + pVal = Jim_NewStringObj(p->interp, "", 0); + break; + } + default: { + int bytes = sqlite3_value_bytes(pIn); + pVal = Jim_NewStringObj(p->interp, (char *)sqlite3_value_text(pIn), bytes); + break; + } + } + Jim_ListAppendElement(p->interp, pCmd, pVal); + } + if( !p->useEvalObjv ){ + /* Jim_EvalOb() will automatically call Jim_EvalObjVector() if pCmd + ** is a list without a string representation. To prevent this from + ** happening, make sure pCmd has a valid string representation */ + Jim_String(pCmd); + } + rc = Jim_EvalObj(p->interp, pCmd); + Jim_DecrRefCount(p->interp, pCmd); + } + + if( rc && rc!=JIM_RETURN ){ + sqlite3_result_error(context, Jim_String(Jim_GetResult(p->interp)), -1); + }else{ + Jim_Obj *pVar = Jim_GetResult(p->interp); + int n; + u8 *data; + /* XXX: Jim Tcl doesn't have bytearray or boolean */ + const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); + char c = zType[0]; +#if 0 + if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){ + /* Only return a BLOB type if the Tcl variable is a bytearray and + ** has no string representation. */ + data = Jim_GetByteArrayFromObj(pVar, &n); + sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT); + }else if( c=='b' && strcmp(zType,"boolean")==0 ){ + Jim_GetWide(0, pVar, &n); + sqlite3_result_int(context, n); + }else +#endif + if( c=='d' && strcmp(zType,"double")==0 ){ + double r; + Jim_GetDouble(0, pVar, &r); + sqlite3_result_double(context, r); + /* XXX: Is a cooerced double better as a double or an int? */ + }else if( (c=='c' && strcmp(zType,"coerced-double")==0) || + (c=='i' && strcmp(zType,"int")==0) ){ + jim_wide v; + Jim_GetWide(p->interp, pVar, &v); + sqlite3_result_int64(context, v); + }else{ + data = (unsigned char *)Jim_GetString(pVar, &n); + sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT); + } + } +} + +#ifndef SQLITE_OMIT_AUTHORIZATION +/* +** This is the authentication function. It appends the authentication +** type code and the two arguments to zCmd[] then invokes the result +** on the interpreter. The reply is examined to determine if the +** authentication fails or succeeds. +*/ +static int auth_callback( + void *pArg, + int code, + const char *zArg1, + const char *zArg2, + const char *zArg3, + const char *zArg4 +){ + char *zCode; + Jim_Obj *str; + int rc; + const char *zReply; + SqliteDb *pDb = (SqliteDb*)pArg; + if( pDb->disableAuth ) return SQLITE_OK; + + switch( code ){ + case SQLITE_COPY : zCode="SQLITE_COPY"; break; + case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break; + case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break; + case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break; + case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break; + case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break; + case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break; + case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break; + case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break; + case SQLITE_DELETE : zCode="SQLITE_DELETE"; break; + case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break; + case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break; + case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break; + case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break; + case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break; + case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break; + case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break; + case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break; + case SQLITE_INSERT : zCode="SQLITE_INSERT"; break; + case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break; + case SQLITE_READ : zCode="SQLITE_READ"; break; + case SQLITE_SELECT : zCode="SQLITE_SELECT"; break; + case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break; + case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break; + case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break; + case SQLITE_DETACH : zCode="SQLITE_DETACH"; break; + case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break; + case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break; + case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break; + case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break; + case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break; + case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break; + case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break; + default : zCode="????"; break; + } + str = Jim_NewStringObj(pDb->interp, pDb->zAuth, -1); + /* XXX: list or string here? */ + Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zCode, -1)); + if (zArg1) { + Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zArg1, -1)); + } + if (zArg2) { + Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zArg2, -1)); + } + if (zArg3) { + Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zArg3, -1)); + } + if (zArg4) { + Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zArg4, -1)); + } + Jim_IncrRefCount(str); + rc = Jim_EvalGlobal(pDb->interp, Jim_String(str)); + Jim_DecrRefCount(pDb->interp, str); + zReply = Jim_String(Jim_GetResult(pDb->interp)); + if( strcmp(zReply,"SQLITE_OK")==0 ){ + rc = SQLITE_OK; + }else if( strcmp(zReply,"SQLITE_DENY")==0 ){ + rc = SQLITE_DENY; + }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){ + rc = SQLITE_IGNORE; + }else{ + rc = 999; + } + return rc; +} +#endif /* SQLITE_OMIT_AUTHORIZATION */ + +/* +** Note that Jim Tcl can't do encoding conversion, +** so this simply returns the string as an object. +*/ +static Jim_Obj *dbTextToObj(Jim_Interp *interp, char const *zText){ + return Jim_NewStringObj(interp, zText ? zText : "", -1); +} + +/* +** This routine reads a line of text from FILE in, stores +** the text in memory obtained from malloc() and returns a pointer +** to the text. NULL is returned at end of file. +** +** The interface is like "readline" but no command-line editing +** is done. +** +** copied from shell.c from '.import' command +*/ +static char *local_getline(char *zPrompt, FILE *in){ + char *zLine; + int nLine; + int n; + int eol; + + nLine = 100; + zLine = Jim_Alloc( nLine ); + n = 0; + eol = 0; + while( !eol ){ + if( n+100>nLine ){ + nLine = nLine*2 + 100; + zLine = realloc(zLine, nLine); + if( zLine==0 ) return 0; + } + if( fgets(&zLine[n], nLine - n, in)==0 ){ + if( n==0 ){ + Jim_Free(zLine); + return 0; + } + zLine[n] = 0; + eol = 1; + break; + } + while( zLine[n] ){ n++; } + if( n>0 && zLine[n-1]=='\n' ){ + n--; + zLine[n] = 0; + eol = 1; + } + } + zLine = realloc( zLine, n+1 ); + return zLine; +} + + +/* +** This function is part of the implementation of the command: +** +** $db transaction [-deferred|-immediate|-exclusive] SCRIPT +** +** It is invoked after evaluating the script SCRIPT to commit or rollback +** the transaction or savepoint opened by the [transaction] command. +*/ +static int DbTransPostCmd( + Jim_Interp *interp, /* Tcl interpreter */ + SqliteDb *pDb, + int result /* Result of evaluating SCRIPT */ +){ + static const char *azEnd[] = { + "RELEASE _tcl_transaction", /* rc==JIM_ERR, nTransaction!=0 */ + "COMMIT", /* rc!=JIM_ERR, nTransaction==0 */ + "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction", + "ROLLBACK" /* rc==JIM_ERR, nTransaction==0 */ + }; + int rc = result; + const char *zEnd; + + pDb->nTransaction--; + zEnd = azEnd[(rc==JIM_ERR)*2 + (pDb->nTransaction==0)]; + + pDb->disableAuth++; + if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){ + /* This is a tricky scenario to handle. The most likely cause of an + ** error is that the exec() above was an attempt to commit the + ** top-level transaction that returned SQLITE_BUSY. Or, less likely, + ** that an IO-error has occured. In either case, throw a Tcl exception + ** and try to rollback the transaction. + ** + ** But it could also be that the user executed one or more BEGIN, + ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing + ** this method's logic. Not clear how this would be best handled. + */ + if( rc!=JIM_ERR ){ + Jim_AppendString(interp, Jim_GetResult(interp), sqlite3_errmsg(pDb->db), -1); + rc = JIM_ERR; + } + sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0); + } + pDb->disableAuth--; + + return rc; +} + +/* +** Search the cache for a prepared-statement object that implements the +** first SQL statement in the buffer pointed to by parameter zIn. If +** no such prepared-statement can be found, allocate and prepare a new +** one. In either case, bind the current values of the relevant Tcl +** variables to any $var, :var or @var variables in the statement. Before +** returning, set *ppPreStmt to point to the prepared-statement object. +** +** Output parameter *pzOut is set to point to the next SQL statement in +** buffer zIn, or to the '\0' byte at the end of zIn if there is no +** next statement. +** +** If successful, JIM_OK is returned. Otherwise, JIM_ERR is returned +** and an error message loaded into interpreter pDb->interp. +*/ +static int dbPrepareAndBind( + SqliteDb *pDb, /* Database object */ + char const *zIn, /* SQL to compile */ + char const **pzOut, /* OUT: Pointer to next SQL statement */ + SqlPreparedStmt **ppPreStmt /* OUT: Object used to cache statement */ +){ + const char *zSql = zIn; /* Pointer to first SQL statement in zIn */ + sqlite3_stmt *pStmt; /* Prepared statement object */ + SqlPreparedStmt *pPreStmt; /* Pointer to cached statement */ + int nSql; /* Length of zSql in bytes */ + int nVar; /* Number of variables in statement */ + int iParm = 0; /* Next free entry in apParm */ + int i; + Jim_Interp *interp = pDb->interp; + + *ppPreStmt = 0; + + /* Trim spaces from the start of zSql and calculate the remaining length. */ + while( isspace((unsigned)zSql[0]) ){ zSql++; } + nSql = strlen30(zSql); + + for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){ + int n = pPreStmt->nSql; + if( nSql>=n + && memcmp(pPreStmt->zSql, zSql, n)==0 + && (zSql[n]==0 || zSql[n-1]==';') + ){ + pStmt = pPreStmt->pStmt; + *pzOut = &zSql[pPreStmt->nSql]; + + /* When a prepared statement is found, unlink it from the + ** cache list. It will later be added back to the beginning + ** of the cache list in order to implement LRU replacement. + */ + if( pPreStmt->pPrev ){ + pPreStmt->pPrev->pNext = pPreStmt->pNext; + }else{ + pDb->stmtList = pPreStmt->pNext; + } + if( pPreStmt->pNext ){ + pPreStmt->pNext->pPrev = pPreStmt->pPrev; + }else{ + pDb->stmtLast = pPreStmt->pPrev; + } + pDb->nStmt--; + nVar = sqlite3_bind_parameter_count(pStmt); + break; + } + } + + /* If no prepared statement was found. Compile the SQL text. Also allocate + ** a new SqlPreparedStmt structure. */ + if( pPreStmt==0 ){ + int nByte; + + if( SQLITE_OK!=sqlite3_prepare_v2(pDb->db, zSql, -1, &pStmt, pzOut) ){ + Jim_SetResult(interp, dbTextToObj(pDb->interp, sqlite3_errmsg(pDb->db))); + return JIM_ERR; + } + if( pStmt==0 ){ + if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){ + /* A compile-time error in the statement. */ + Jim_SetResult(interp, dbTextToObj(pDb->interp, sqlite3_errmsg(pDb->db))); + return JIM_ERR; + }else{ + /* The statement was a no-op. Continue to the next statement + ** in the SQL string. + */ + return JIM_OK; + } + } + + assert( pPreStmt==0 ); + nVar = sqlite3_bind_parameter_count(pStmt); + nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Jim_Obj *); + pPreStmt = (SqlPreparedStmt*)Jim_Alloc(nByte); + memset(pPreStmt, 0, nByte); + + pPreStmt->pStmt = pStmt; + pPreStmt->nSql = (*pzOut - zSql); + pPreStmt->zSql = sqlite3_sql(pStmt); + pPreStmt->apParm = (Jim_Obj **)&pPreStmt[1]; + } + assert( pPreStmt ); + assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql ); + assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) ); + + /* Bind values to parameters that begin with $ or : */ + for(i=1; i<=nVar; i++){ + const char *zVar = sqlite3_bind_parameter_name(pStmt, i); + if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){ + Jim_Obj *pVar = Jim_GetVariableStr(interp, &zVar[1], 0); + if( pVar ){ + int n; + u8 *data; + const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); + char c = zType[0]; + /* XXX: Jim Tcl doesn't have bytearray or boolean */ + if( zVar[0]=='@') { +#if 0 + || + (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){ + /* Load a BLOB type if the Tcl variable is a bytearray and + ** it has no string representation or the host + ** parameter name begins with "@". */ + data = Jim_GetByteArrayFromObj(pVar, &n); +#else + data = (unsigned char *)Jim_GetString(pVar, &n); +#endif + sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC); + Jim_IncrRefCount(pVar); + pPreStmt->apParm[iParm++] = pVar; +#if 0 + }else if( c=='b' && strcmp(zType,"boolean")==0 ){ + Jim_GetWide(interp, pVar, &n); + sqlite3_bind_int(pStmt, i, n); +#endif + }else if( c=='d' && strcmp(zType,"double")==0 ){ + double r; + Jim_GetDouble(interp, pVar, &r); + sqlite3_bind_double(pStmt, i, r); + }else if( (c=='c' && strcmp(zType,"coerced-double")==0) || + (c=='i' && strcmp(zType,"int")==0) ){ + jim_wide v; + Jim_GetWide(interp, pVar, &v); + sqlite3_bind_int64(pStmt, i, v); + }else{ + data = (unsigned char *)Jim_GetString(pVar, &n); + sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC); + Jim_IncrRefCount(pVar); + pPreStmt->apParm[iParm++] = pVar; + } + }else{ + sqlite3_bind_null(pStmt, i); + } + } + } + pPreStmt->nParm = iParm; + *ppPreStmt = pPreStmt; + + return JIM_OK; +} + + +/* +** Release a statement reference obtained by calling dbPrepareAndBind(). +** There should be exactly one call to this function for each call to +** dbPrepareAndBind(). +** +** If the discard parameter is non-zero, then the statement is deleted +** immediately. Otherwise it is added to the LRU list and may be returned +** by a subsequent call to dbPrepareAndBind(). +*/ +static void dbReleaseStmt( + SqliteDb *pDb, /* Database handle */ + SqlPreparedStmt *pPreStmt, /* Prepared statement handle to release */ + int discard /* True to delete (not cache) the pPreStmt */ +){ + int i; + + /* Free the bound string and blob parameters */ + for(i=0; inParm; i++){ + Jim_DecrRefCount(pDb->interp, pPreStmt->apParm[i]); + } + pPreStmt->nParm = 0; + + if( pDb->maxStmt<=0 || discard ){ + /* If the cache is turned off, deallocated the statement */ + sqlite3_finalize(pPreStmt->pStmt); + Jim_Free((char *)pPreStmt); + }else{ + /* Add the prepared statement to the beginning of the cache list. */ + pPreStmt->pNext = pDb->stmtList; + pPreStmt->pPrev = 0; + if( pDb->stmtList ){ + pDb->stmtList->pPrev = pPreStmt; + } + pDb->stmtList = pPreStmt; + if( pDb->stmtLast==0 ){ + assert( pDb->nStmt==0 ); + pDb->stmtLast = pPreStmt; + }else{ + assert( pDb->nStmt>0 ); + } + pDb->nStmt++; + + /* If we have too many statement in cache, remove the surplus from + ** the end of the cache list. */ + while( pDb->nStmt>pDb->maxStmt ){ + sqlite3_finalize(pDb->stmtLast->pStmt); + pDb->stmtLast = pDb->stmtLast->pPrev; + Jim_Free((char*)pDb->stmtLast->pNext); + pDb->stmtLast->pNext = 0; + pDb->nStmt--; + } + } +} + +/* +** Structure used with dbEvalXXX() functions: +** +** dbEvalInit() +** dbEvalStep() +** dbEvalFinalize() +** dbEvalRowInfo() +** dbEvalColumnValue() +*/ +typedef struct DbEvalContext DbEvalContext; +struct DbEvalContext { + SqliteDb *pDb; /* Database handle */ + Jim_Obj *pSql; /* Object holding string zSql */ + const char *zSql; /* Remaining SQL to execute */ + SqlPreparedStmt *pPreStmt; /* Current statement */ + int nCol; /* Number of columns returned by pStmt */ + Jim_Obj *pArray; /* Name of array variable */ + Jim_Obj **apColName; /* Array of column names */ +}; + +/* +** Release any cache of column names currently held as part of +** the DbEvalContext structure passed as the first argument. +*/ +static void dbReleaseColumnNames(DbEvalContext *p){ + if( p->apColName ){ + int i; + for(i=0; inCol; i++){ + Jim_DecrRefCount(p->pDb->interp, p->apColName[i]); + } + Jim_Free((char *)p->apColName); + p->apColName = 0; + } + p->nCol = 0; +} + +/* +** Initialize a DbEvalContext structure. +** +** If pArray is not NULL, then it contains the name of a Tcl array +** variable. The "*" member of this array is set to a list containing +** the names of the columns returned by the statement as part of each +** call to dbEvalStep(), in order from left to right. e.g. if the names +** of the returned columns are a, b and c, it does the equivalent of the +** tcl command: +** +** set ${pArray}(*) {a b c} +*/ +static void dbEvalInit( + DbEvalContext *p, /* Pointer to structure to initialize */ + SqliteDb *pDb, /* Database handle */ + Jim_Obj *pSql, /* Object containing SQL script */ + Jim_Obj *pArray /* Name of Tcl array to set (*) element of */ +){ + memset(p, 0, sizeof(DbEvalContext)); + p->pDb = pDb; + p->zSql = Jim_String(pSql); + p->pSql = pSql; + Jim_IncrRefCount(pSql); + if( pArray ){ + p->pArray = pArray; + Jim_IncrRefCount(pArray); + } +} + +/* +** Obtain information about the row that the DbEvalContext passed as the +** first argument currently points to. +*/ +static void dbEvalRowInfo( + DbEvalContext *p, /* Evaluation context */ + int *pnCol, /* OUT: Number of column names */ + Jim_Obj ***papColName /* OUT: Array of column names */ +){ + /* Compute column names */ + if( 0==p->apColName ){ + sqlite3_stmt *pStmt = p->pPreStmt->pStmt; + int i; /* Iterator variable */ + int nCol; /* Number of columns returned by pStmt */ + Jim_Obj **apColName = 0; /* Array of column names */ + + p->nCol = nCol = sqlite3_column_count(pStmt); + if( nCol>0 && (papColName || p->pArray) ){ + apColName = (Jim_Obj**)Jim_Alloc( sizeof(Jim_Obj*)*nCol ); + for(i=0; ipDb->interp, sqlite3_column_name(pStmt,i)); + Jim_IncrRefCount(apColName[i]); + } + p->apColName = apColName; + } + + /* If results are being stored in an array variable, then create + ** the array(*) entry for that array + */ + if( p->pArray ){ + Jim_Interp *interp = p->pDb->interp; + Jim_Obj *pColList = Jim_NewListObj(interp, apColName, nCol); + Jim_Obj *pStar = Jim_NewStringObj(interp, "*", -1); + Jim_IncrRefCount(pStar); + Jim_SetDictKeysVector(interp, p->pArray, &pStar, 1, pColList, 0); + Jim_DecrRefCount(interp, pStar); + } + } + + if( papColName ){ + *papColName = p->apColName; + } + if( pnCol ){ + *pnCol = p->nCol; + } +} + +/* +** Return one of JIM_OK, JIM_BREAK or JIM_ERR. If JIM_ERR is +** returned, then an error message is stored in the interpreter before +** returning. +** +** A return value of JIM_OK means there is a row of data available. The +** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This +** is analogous to a return of SQLITE_ROW from sqlite3_step(). If JIM_BREAK +** is returned, then the SQL script has finished executing and there are +** no further rows available. This is similar to SQLITE_DONE. +*/ +static int dbEvalStep(DbEvalContext *p){ + while( p->zSql[0] || p->pPreStmt ){ + int rc; + if( p->pPreStmt==0 ){ + rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt); + if( rc!=JIM_OK ) return rc; + }else{ + int rcs; + SqliteDb *pDb = p->pDb; + SqlPreparedStmt *pPreStmt = p->pPreStmt; + sqlite3_stmt *pStmt = pPreStmt->pStmt; + + rcs = sqlite3_step(pStmt); + if( rcs==SQLITE_ROW ){ + return JIM_OK; + } + if( p->pArray ){ + dbEvalRowInfo(p, 0, 0); + } + rcs = sqlite3_reset(pStmt); + + pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1); + pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1); + dbReleaseColumnNames(p); + p->pPreStmt = 0; + + if( rcs!=SQLITE_OK ){ + /* If a run-time error occurs, report the error and stop reading + ** the SQL. */ + Jim_SetResult(pDb->interp, dbTextToObj(pDb->interp, sqlite3_errmsg(pDb->db))); + dbReleaseStmt(pDb, pPreStmt, 1); + return JIM_ERR; + }else{ + dbReleaseStmt(pDb, pPreStmt, 0); + } + } + } + + /* Finished */ + return JIM_BREAK; +} + +/* +** Free all resources currently held by the DbEvalContext structure passed +** as the first argument. There should be exactly one call to this function +** for each call to dbEvalInit(). +*/ +static void dbEvalFinalize(DbEvalContext *p){ + if( p->pPreStmt ){ + sqlite3_reset(p->pPreStmt->pStmt); + dbReleaseStmt(p->pDb, p->pPreStmt, 0); + p->pPreStmt = 0; + } + if( p->pArray ){ + Jim_DecrRefCount(p->pDb->interp, p->pArray); + p->pArray = 0; + } + Jim_DecrRefCount(p->pDb->interp, p->pSql); + dbReleaseColumnNames(p); +} + +/* +** Return a pointer to a Jim_Obj structure with ref-count 0 that contains +** the value for the iCol'th column of the row currently pointed to by +** the DbEvalContext structure passed as the first argument. +*/ +static Jim_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){ + sqlite3_stmt *pStmt = p->pPreStmt->pStmt; + switch( sqlite3_column_type(pStmt, iCol) ){ + case SQLITE_BLOB: { + int bytes = sqlite3_column_bytes(pStmt, iCol); + const char *zBlob = sqlite3_column_blob(pStmt, iCol); + if( !zBlob ) bytes = 0; + //return Jim_NewByteArrayObj((u8*)zBlob, bytes); + return Jim_NewStringObj(p->pDb->interp, zBlob, bytes); + } + case SQLITE_INTEGER: { + sqlite_int64 v = sqlite3_column_int64(pStmt, iCol); + return Jim_NewIntObj(p->pDb->interp, v); + } + case SQLITE_FLOAT: { + return Jim_NewDoubleObj(p->pDb->interp, sqlite3_column_double(pStmt, iCol)); + } + case SQLITE_NULL: { + return dbTextToObj(p->pDb->interp, p->pDb->zNull); + } + } + + return dbTextToObj(p->pDb->interp, (char *)sqlite3_column_text(pStmt, iCol)); +} + +static int Jim_ObjSetVar2(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *keyObjPtr, Jim_Obj *valObjPtr) +{ + return Jim_SetDictKeysVector(interp, nameObjPtr, &keyObjPtr, 1, valObjPtr, 0); +} + +/* +** This function is part of the implementation of the command: +** +** $db eval SQL ?ARRAYNAME? SCRIPT +*/ +static int DbEvalNextCmd( + Jim_Interp *interp, /* Tcl interpreter */ + DbEvalContext *p, + Jim_Obj *pScript, + int result /* Result so far */ +){ + int rc = result; /* Return code */ + + Jim_Obj *pArray = p->pArray; + + while( (rc==JIM_OK || rc==JIM_CONTINUE) && JIM_OK==(rc = dbEvalStep(p)) ){ + int i; + int nCol; + Jim_Obj **apColName; + dbEvalRowInfo(p, &nCol, &apColName); + for(i=0; i3 ){ + Jim_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); + return JIM_ERR; + }else if( objc==2 ){ + if( pDb->zAuth ){ + Jim_SetResultString(interp, pDb->zAuth, -1); + } + }else{ + const char *zAuth; + int len; + if( pDb->zAuth ){ + Jim_Free(pDb->zAuth); + } + zAuth = Jim_GetString(objv[2], &len); + if( zAuth && len>0 ){ + pDb->zAuth = Jim_Alloc( len + 1 ); + memcpy(pDb->zAuth, zAuth, len+1); + }else{ + pDb->zAuth = 0; + } + if( pDb->zAuth ){ + pDb->interp = interp; + sqlite3_set_authorizer(pDb->db, auth_callback, pDb); + }else{ + sqlite3_set_authorizer(pDb->db, 0, 0); + } + } +#endif + break; + } + + /* $db backup ?DATABASE? FILENAME + ** + ** Open or create a database file named FILENAME. Transfer the + ** content of local database DATABASE (default: "main") into the + ** FILENAME database. + */ + case DB_BACKUP: { + const char *zDestFile; + const char *zSrcDb; + sqlite3 *pDest; + sqlite3_backup *pBackup; + + if( objc==3 ){ + zSrcDb = "main"; + zDestFile = Jim_String(objv[2]); + }else if( objc==4 ){ + zSrcDb = Jim_String(objv[2]); + zDestFile = Jim_String(objv[3]); + }else{ + Jim_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME"); + return JIM_ERR; + } + rc = sqlite3_open(zDestFile, &pDest); + if( rc!=SQLITE_OK ){ + Jim_SetResultFormatted(interp, "cannot open target database: %s", sqlite3_errmsg(pDest)); + sqlite3_close(pDest); + return JIM_ERR; + } + pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb); + if( pBackup==0 ){ + Jim_SetResultFormatted(interp, "backup failed: %s", sqlite3_errmsg(pDest)); + sqlite3_close(pDest); + return JIM_ERR; + } + while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} + sqlite3_backup_finish(pBackup); + if( rc==SQLITE_DONE ){ + rc = JIM_OK; + }else{ + Jim_SetResultFormatted(interp, "backup failed: %s", sqlite3_errmsg(pDest)); + rc = JIM_ERR; + } + sqlite3_close(pDest); + break; + } + + /* $db busy ?CALLBACK? + ** + ** Invoke the given callback if an SQL statement attempts to open + ** a locked database file. + */ + case DB_BUSY: { + if( objc>3 ){ + Jim_WrongNumArgs(interp, 2, objv, "CALLBACK"); + return JIM_ERR; + }else if( objc==2 ){ + if( pDb->zBusy ){ + Jim_SetResultString(interp, pDb->zBusy, -1); + } + }else{ + const char *zBusy; + int len; + if( pDb->zBusy ){ + Jim_Free(pDb->zBusy); + } + zBusy = Jim_GetString(objv[2], &len); + if( zBusy && len>0 ){ + pDb->zBusy = Jim_Alloc( len + 1 ); + memcpy(pDb->zBusy, zBusy, len+1); + }else{ + pDb->zBusy = 0; + } + if( pDb->zBusy ){ + pDb->interp = interp; + sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb); + }else{ + sqlite3_busy_handler(pDb->db, 0, 0); + } + } + break; + } + + /* $db cache flush + ** $db cache size n + ** + ** Flush the prepared statement cache, or set the maximum number of + ** cached statements. + */ + case DB_CACHE: { + const char *subCmd; + + if( objc<=2 ){ + Jim_WrongNumArgs(interp, 1, objv, "cache option ?arg?"); + return JIM_ERR; + } + subCmd = Jim_String( objv[2]); + if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){ + if( objc!=3 ){ + Jim_WrongNumArgs(interp, 2, objv, "flush"); + return JIM_ERR; + }else{ + flushStmtCache( pDb ); + } + }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){ + if( objc!=4 ){ + Jim_WrongNumArgs(interp, 2, objv, "size n"); + return JIM_ERR; + }else{ + jim_wide w; + if( JIM_ERR==Jim_GetWide(interp, objv[3], &w) ){ + return JIM_ERR; + }else{ + if( w<0 ){ + flushStmtCache( pDb ); + w = 0; + }else if( w>MAX_PREPARED_STMTS ){ + w = MAX_PREPARED_STMTS; + } + pDb->maxStmt = w; + } + } + }else{ + Jim_SetResultFormatted(interp, "bad option \"%#s\": must be flush or size", objv[2]); + return JIM_ERR; + } + break; + } + + /* $db changes + ** + ** Return the number of rows that were modified, inserted, or deleted by + ** the most recent INSERT, UPDATE or DELETE statement, not including + ** any changes made by trigger programs. + */ + case DB_CHANGES: { + if( objc!=2 ){ + Jim_WrongNumArgs(interp, 2, objv, ""); + return JIM_ERR; + } + Jim_SetResultInt(interp, sqlite3_changes(pDb->db)); + break; + } + + /* $db close + ** + ** Shutdown the database + */ + case DB_CLOSE: { + Jim_DeleteCommand(interp, Jim_String(objv[0])); + break; + } + + /* + ** $db collate NAME SCRIPT + ** + ** Create a new SQL collation function called NAME. Whenever + ** that function is called, invoke SCRIPT to evaluate the function. + */ + case DB_COLLATE: { + SqlCollate *pCollate; + const char *zName; + const char *zScript; + int nScript; + if( objc!=4 ){ + Jim_WrongNumArgs(interp, 2, objv, "NAME SCRIPT"); + return JIM_ERR; + } + zName = Jim_String(objv[2]); + zScript = Jim_GetString(objv[3], &nScript); + pCollate = (SqlCollate*)Jim_Alloc( sizeof(*pCollate) + nScript + 1 ); + if( pCollate==0 ) return JIM_ERR; + pCollate->interp = interp; + pCollate->pNext = pDb->pCollate; + pCollate->zScript = (char*)&pCollate[1]; + pDb->pCollate = pCollate; + memcpy(pCollate->zScript, zScript, nScript+1); + if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, + pCollate, tclSqlCollate) ){ + Jim_SetResultString(interp, (char *)sqlite3_errmsg(pDb->db), -1); + return JIM_ERR; + } + break; + } + + /* + ** $db collation_needed SCRIPT + ** + ** Create a new SQL collation function called NAME. Whenever + ** that function is called, invoke SCRIPT to evaluate the function. + */ + case DB_COLLATION_NEEDED: { + if( objc!=3 ){ + Jim_WrongNumArgs(interp, 2, objv, "SCRIPT"); + return JIM_ERR; + } + if( pDb->pCollateNeeded ){ + Jim_DecrRefCount(interp, pDb->pCollateNeeded); + } + pDb->pCollateNeeded = Jim_DuplicateObj(pDb->interp, objv[2]); + Jim_IncrRefCount(pDb->pCollateNeeded); + sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded); + break; + } + + /* $db commit_hook ?CALLBACK? + ** + ** Invoke the given callback just before committing every SQL transaction. + ** If the callback throws an exception or returns non-zero, then the + ** transaction is aborted. If CALLBACK is an empty string, the callback + ** is disabled. + */ + case DB_COMMIT_HOOK: { + if( objc>3 ){ + Jim_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); + return JIM_ERR; + }else if( objc==2 ){ + if( pDb->zCommit ){ + Jim_SetResultString(interp, pDb->zCommit, -1); + } + }else{ + const char *zCommit; + int len; + if( pDb->zCommit ){ + Jim_Free(pDb->zCommit); + } + zCommit = Jim_GetString(objv[2], &len); + if( zCommit && len>0 ){ + pDb->zCommit = Jim_Alloc( len + 1 ); + memcpy(pDb->zCommit, zCommit, len+1); + }else{ + pDb->zCommit = 0; + } + if( pDb->zCommit ){ + pDb->interp = interp; + sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb); + }else{ + sqlite3_commit_hook(pDb->db, 0, 0); + } + } + break; + } + + /* $db complete SQL + ** + ** Return TRUE if SQL is a complete SQL statement. Return FALSE if + ** additional lines of input are needed. This is similar to the + ** built-in "info complete" command of Tcl. + */ + case DB_COMPLETE: { +#ifndef SQLITE_OMIT_COMPLETE + if( objc!=3 ){ + Jim_WrongNumArgs(interp, 2, objv, "SQL"); + return JIM_ERR; + } + Jim_SetResultInt(interp, sqlite3_complete( Jim_String(objv[2]) )); +#endif + break; + } + + /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR? + ** + ** Copy data into table from filename, optionally using SEPARATOR + ** as column separators. If a column contains a null string, or the + ** value of NULLINDICATOR, a NULL is inserted for the column. + ** conflict-algorithm is one of the sqlite conflict algorithms: + ** rollback, abort, fail, ignore, replace + ** On success, return the number of lines processed, not necessarily same + ** as 'db changes' due to conflict-algorithm selected. + ** + ** This code is basically an implementation/enhancement of + ** the sqlite3 shell.c ".import" command. + ** + ** This command usage is equivalent to the sqlite2.x COPY statement, + ** which imports file data into a table using the PostgreSQL COPY file format: + ** $db copy $conflit_algo $table_name $filename \t \\N + */ + case DB_COPY: { + const char *zTable; /* Insert data into this table */ + const char *zFile; /* The file from which to extract data */ + const char *zConflict; /* The conflict algorithm to use */ + sqlite3_stmt *pStmt; /* A statement */ + int nCol; /* Number of columns in the table */ + int nByte; /* Number of bytes in an SQL string */ + int i, j; /* Loop counters */ + int nSep; /* Number of bytes in zSep[] */ + int nNull; /* Number of bytes in zNull[] */ + char *zSql; /* An SQL statement */ + char *zLine; /* A single line of input from the file */ + char **azCol; /* zLine[] broken up into columns */ + char *zCommit; /* How to commit changes */ + FILE *in; /* The input file */ + int lineno = 0; /* Line number of input file */ + char zLineNum[80]; /* Line number print buffer */ + + const char *zSep; + const char *zNull; + if( objc<5 || objc>7 ){ + Jim_WrongNumArgs(interp, 2, objv, + "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"); + return JIM_ERR; + } + if( objc>=6 ){ + zSep = Jim_String(objv[5]); + }else{ + zSep = "\t"; + } + if( objc>=7 ){ + zNull = Jim_String(objv[6]); + }else{ + zNull = ""; + } + zConflict = Jim_String(objv[2]); + zTable = Jim_String(objv[3]); + zFile = Jim_String(objv[4]); + nSep = strlen30(zSep); + nNull = strlen30(zNull); + if( nSep==0 ){ + Jim_SetResultString(interp, "Error: non-null separator required for copy", -1); + return JIM_ERR; + } + if(strcmp(zConflict, "rollback") != 0 && + strcmp(zConflict, "abort" ) != 0 && + strcmp(zConflict, "fail" ) != 0 && + strcmp(zConflict, "ignore" ) != 0 && + strcmp(zConflict, "replace" ) != 0 ) { + Jim_SetResultFormatted(interp, "Error: \"%s\", conflict-algorithm must be one of: rollback, " + "abort, fail, ignore, or replace", zConflict); + return JIM_ERR; + } + zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); + if( zSql==0 ){ + Jim_SetResultFormatted(interp, "Error: no such table: %s", zTable); + return JIM_ERR; + } + nByte = strlen30(zSql); + rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( rc ){ + Jim_SetResultFormatted(interp, "Error: %s", sqlite3_errmsg(pDb->db)); + nCol = 0; + }else{ + nCol = sqlite3_column_count(pStmt); + } + sqlite3_finalize(pStmt); + if( nCol==0 ) { + return JIM_ERR; + } + zSql = Jim_Alloc( nByte + 50 + nCol*2 ); + sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?", + zConflict, zTable); + j = strlen30(zSql); + for(i=1; idb, zSql, -1, &pStmt, 0); + Jim_Free(zSql); + if( rc ){ + Jim_SetResultFormatted(interp, "Error: %s", sqlite3_errmsg(pDb->db)); + sqlite3_finalize(pStmt); + return JIM_ERR; + } + in = fopen(zFile, "rb"); + if( in==0 ){ + Jim_SetResultFormatted(interp, "Error: cannot open file: %s", zFile); + sqlite3_finalize(pStmt); + return JIM_ERR; + } + azCol = Jim_Alloc( sizeof(azCol[0])*(nCol+1) ); + (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0); + zCommit = "COMMIT"; + while( (zLine = local_getline(0, in))!=0 ){ + char *z; + i = 0; + lineno++; + azCol[0] = zLine; + for(i=0, z=zLine; *z; z++){ + if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){ + *z = 0; + i++; + if( i0 && strcmp(azCol[i], zNull)==0) + || strlen30(azCol[i])==0 + ){ + sqlite3_bind_null(pStmt, i+1); + }else{ + sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC); + } + } + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + Jim_Free(zLine); + if( rc!=SQLITE_OK ){ + Jim_SetResultFormatted(interp, "Error: %s", sqlite3_errmsg(pDb->db)); + zCommit = "ROLLBACK"; + break; + } + } + Jim_Free(azCol); + fclose(in); + sqlite3_finalize(pStmt); + (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0); + + if( zCommit[0] == 'C' ){ + /* success, set result as number of lines processed */ + Jim_SetResultInt(interp, lineno); + rc = JIM_OK; + }else{ + /* failure, append lineno where failed */ + sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno); + Jim_AppendStrings(interp, Jim_GetResult(interp), ", failed while processing line: ", zLineNum, NULL); + rc = JIM_ERR; + } + break; + } + + /* + ** $db enable_load_extension BOOLEAN + ** + ** Turn the extension loading feature on or off. It if off by + ** default. + */ + case DB_ENABLE_LOAD_EXTENSION: { +#ifndef SQLITE_OMIT_LOAD_EXTENSION + long onoff; + if( objc!=3 ){ + Jim_WrongNumArgs(interp, 2, objv, "BOOLEAN"); + return JIM_ERR; + } + if( Jim_GetLong(interp, objv[2], &onoff) ){ + return JIM_ERR; + } + sqlite3_enable_load_extension(pDb->db, onoff); + break; +#else + Jim_SetResultString(interp, "extension loading is turned off at compile-time", -1); + return JIM_ERR; +#endif + } + + /* + ** $db errorcode + ** + ** Return the numeric error code that was returned by the most recent + ** call to sqlite3_exec(). + */ + case DB_ERRORCODE: { + Jim_SetResultInt(interp, sqlite3_errcode(pDb->db)); + break; + } + + /* + ** $db exists $sql + ** $db onecolumn $sql + ** + ** The onecolumn method is the equivalent of: + ** lindex [$db eval $sql] 0 + */ + case DB_EXISTS: + case DB_ONECOLUMN: { + DbEvalContext sEval; + if( objc!=3 ){ + Jim_WrongNumArgs(interp, 2, objv, "SQL"); + return JIM_ERR; + } + + dbEvalInit(&sEval, pDb, objv[2], 0); + rc = dbEvalStep(&sEval); + if( choice==DB_ONECOLUMN ){ + if( rc==JIM_OK ){ + Jim_SetResult(interp, dbEvalColumnValue(&sEval, 0)); + } + }else if( rc==JIM_BREAK || rc==JIM_OK ){ + Jim_SetResultInt(interp, rc==JIM_OK); + } + dbEvalFinalize(&sEval); + + if( rc==JIM_BREAK ){ + rc = JIM_OK; + } + break; + } + + /* + ** $db eval $sql ?array? ?{ ...code... }? + ** + ** The SQL statement in $sql is evaluated. For each row, the values are + ** placed in elements of the array named "array" and ...code... is executed. + ** If "array" and "code" are omitted, then no callback is every invoked. + ** If "array" is an empty string, then the values are placed in variables + ** that have the same name as the fields extracted by the query. + */ + case DB_EVAL: { + if( objc<3 || objc>5 ){ + Jim_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?"); + return JIM_ERR; + } + + if( objc==3 ){ + DbEvalContext sEval; + Jim_Obj *pRet = Jim_NewListObj(interp, NULL, 0); + Jim_IncrRefCount(pRet); + dbEvalInit(&sEval, pDb, objv[2], 0); + while( JIM_OK==(rc = dbEvalStep(&sEval)) ){ + int i; + int nCol; + dbEvalRowInfo(&sEval, &nCol, 0); + for(i=0; i2 && strncmp(z, "-argcount",n)==0 ){ + if( Jim_GetLong(interp, objv[4], &nArg) ) return JIM_ERR; + if( nArg<0 ){ + Jim_SetResultString(interp, "number of arguments must be non-negative", -1); + return JIM_ERR; + } + } + pScript = objv[5]; + }else if( objc!=4 ){ + Jim_WrongNumArgs(interp, 2, objv, "NAME [-argcount N] SCRIPT"); + return JIM_ERR; + }else{ + pScript = objv[3]; + } + zName = Jim_String(objv[2]); + pFunc = findSqlFunc(pDb, zName); + if( pFunc==0 ) return JIM_ERR; + if( pFunc->pScript ){ + Jim_DecrRefCount(interp, pFunc->pScript); + } + pFunc->pScript = pScript; + Jim_IncrRefCount(pScript); + pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript); + rc = sqlite3_create_function(pDb->db, zName, nArg, SQLITE_UTF8, + pFunc, tclSqlFunc, 0, 0); + if( rc!=SQLITE_OK ){ + rc = JIM_ERR; + Jim_SetResultString(interp, (char *)sqlite3_errmsg(pDb->db), -1); + } + break; + } + + /* + ** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID + */ + case DB_INCRBLOB: { +#ifdef SQLITE_OMIT_INCRBLOB + Jim_SetResultString(interp, "incrblob not available in this build", -1); + return JIM_ERR; +#else + int isReadonly = 0; + const char *zDb = "main"; + const char *zTable; + const char *zColumn; + sqlite_int64 iRow; + + /* Check for the -readonly option */ + if( objc>3 && strcmp(Jim_GetString(objv[2]), "-readonly")==0 ){ + isReadonly = 1; + } + + if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){ + Jim_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID"); + return JIM_ERR; + } + + if( objc==(6+isReadonly) ){ + zDb = Jim_GetString(objv[2]); + } + zTable = Jim_GetString(objv[objc-3]); + zColumn = Jim_GetString(objv[objc-2]); + rc = Jim_GetWide(interp, objv[objc-1], &iRow); + + if( rc==JIM_OK ){ + rc = createIncrblobChannel( + interp, pDb, zDb, zTable, zColumn, iRow, isReadonly + ); + } +#endif + break; + } + + /* + ** $db interrupt + ** + ** Interrupt the execution of the inner-most SQL interpreter. This + ** causes the SQL statement to return an error of SQLITE_INTERRUPT. + */ + case DB_INTERRUPT: { + sqlite3_interrupt(pDb->db); + break; + } + + /* + ** $db nullvalue ?STRING? + ** + ** Change text used when a NULL comes back from the database. If ?STRING? + ** is not present, then the current string used for NULL is returned. + ** If STRING is present, then STRING is returned. + ** + */ + case DB_NULLVALUE: { + if( objc!=2 && objc!=3 ){ + Jim_WrongNumArgs(interp, 2, objv, "NULLVALUE"); + return JIM_ERR; + } + if( objc==3 ){ + int len; + const char *zNull = Jim_GetString(objv[2], &len); + if( pDb->zNull ){ + Jim_Free(pDb->zNull); + } + if( zNull && len>0 ){ + pDb->zNull = Jim_Alloc( len + 1 ); + strncpy(pDb->zNull, zNull, len); + pDb->zNull[len] = '\0'; + }else{ + pDb->zNull = 0; + } + } + Jim_SetResult(interp, dbTextToObj(interp, pDb->zNull)); + break; + } + + /* + ** $db last_insert_rowid + ** + ** Return an integer which is the ROWID for the most recent insert. + */ + case DB_LAST_INSERT_ROWID: { + if( objc!=2 ){ + Jim_WrongNumArgs(interp, 2, objv, ""); + return JIM_ERR; + } + Jim_SetResultInt(interp, sqlite3_last_insert_rowid(pDb->db)); + break; + } + + /* + ** The DB_ONECOLUMN method is implemented together with DB_EXISTS. + */ + + /* $db progress ?N CALLBACK? + ** + ** Invoke the given callback every N virtual machine opcodes while executing + ** queries. + */ + case DB_PROGRESS: { + if( objc==2 ){ + if( pDb->zProgress ){ + Jim_AppendString(interp, Jim_GetResult(interp), pDb->zProgress, -1); + } + }else if( objc==4 ){ + const char *zProgress; + int len; + long N; + if( JIM_OK!=Jim_GetLong(interp, objv[2], &N) ){ + return JIM_ERR; + }; + if( pDb->zProgress ){ + Jim_Free(pDb->zProgress); + } + zProgress = Jim_GetString(objv[3], &len); + if( zProgress && len>0 ){ + pDb->zProgress = Jim_Alloc( len + 1 ); + memcpy(pDb->zProgress, zProgress, len+1); + }else{ + pDb->zProgress = 0; + } +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + if( pDb->zProgress ){ + pDb->interp = interp; + sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb); + }else{ + sqlite3_progress_handler(pDb->db, 0, 0, 0); + } +#endif + }else{ + Jim_WrongNumArgs(interp, 2, objv, "N CALLBACK"); + return JIM_ERR; + } + break; + } + + /* $db profile ?CALLBACK? + ** + ** Make arrangements to invoke the CALLBACK routine after each SQL statement + ** that has run. The text of the SQL and the amount of elapse time are + ** appended to CALLBACK before the script is run. + */ + case DB_PROFILE: { + if( objc>3 ){ + Jim_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); + return JIM_ERR; + }else if( objc==2 ){ + if( pDb->zProfile ){ + Jim_SetResultString(interp, pDb->zProfile, -1); + } + }else{ + const char *zProfile; + int len; + if( pDb->zProfile ){ + Jim_Free(pDb->zProfile); + } + zProfile = Jim_GetString(objv[2], &len); + if( zProfile && len>0 ){ + pDb->zProfile = Jim_Alloc( len + 1 ); + memcpy(pDb->zProfile, zProfile, len+1); + }else{ + pDb->zProfile = 0; + } +#ifndef SQLITE_OMIT_TRACE + if( pDb->zProfile ){ + pDb->interp = interp; + sqlite3_profile(pDb->db, DbProfileHandler, pDb); + }else{ + sqlite3_profile(pDb->db, 0, 0); + } +#endif + } + break; + } + + /* + ** $db rekey KEY + ** + ** Change the encryption key on the currently open database. + */ + case DB_REKEY: { + int nKey; + const char *pKey; + if( objc!=3 ){ + Jim_WrongNumArgs(interp, 2, objv, "KEY"); + return JIM_ERR; + } + //pKey = Jim_GetByteArrayFromObj(objv[2], &nKey); + pKey = Jim_GetString(objv[2], &nKey); +#ifdef SQLITE_HAS_CODEC + rc = sqlite3_rekey(pDb->db, pKey, nKey); + if( rc ){ + Jim_SetResultString(interp, sqlite3ErrStr(rc), -1); + rc = JIM_ERR; + } +#endif + break; + } + + /* $db restore ?DATABASE? FILENAME + ** + ** Open a database file named FILENAME. Transfer the content + ** of FILENAME into the local database DATABASE (default: "main"). + */ + case DB_RESTORE: { + const char *zSrcFile; + const char *zDestDb; + sqlite3 *pSrc; + sqlite3_backup *pBackup; + int nTimeout = 0; + + if( objc==3 ){ + zDestDb = "main"; + zSrcFile = Jim_String(objv[2]); + }else if( objc==4 ){ + zDestDb = Jim_String(objv[2]); + zSrcFile = Jim_String(objv[3]); + }else{ + Jim_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME"); + return JIM_ERR; + } + rc = sqlite3_open_v2(zSrcFile, &pSrc, SQLITE_OPEN_READONLY, 0); + if( rc!=SQLITE_OK ){ + Jim_SetResultFormatted(interp, "cannot open source database: %s", sqlite3_errmsg(pSrc)); + sqlite3_close(pSrc); + return JIM_ERR; + } + pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main"); + if( pBackup==0 ){ + Jim_SetResultFormatted(interp, "restore failed: %s", sqlite3_errmsg(pDb->db)); + sqlite3_close(pSrc); + return JIM_ERR; + } + while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK + || rc==SQLITE_BUSY ){ + if( rc==SQLITE_BUSY ){ + if( nTimeout++ >= 3 ) break; + sqlite3_sleep(100); + } + } + sqlite3_backup_finish(pBackup); + if( rc==SQLITE_DONE ){ + rc = JIM_OK; + }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ + Jim_SetResultString(interp, "restore failed: source database busy", -1); + rc = JIM_ERR; + }else{ + Jim_SetResultFormatted(interp, "restore failed: %s", sqlite3_errmsg(pDb->db)); + rc = JIM_ERR; + } + sqlite3_close(pSrc); + break; + } + + /* + ** $db status (step|sort) + ** + ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or + ** SQLITE_STMTSTATUS_SORT for the most recent eval. + */ + case DB_STATUS: { + int v; + const char *zOp; + if( objc!=3 ){ + Jim_WrongNumArgs(interp, 2, objv, "(step|sort)"); + return JIM_ERR; + } + zOp = Jim_String(objv[2]); + if( strcmp(zOp, "step")==0 ){ + v = pDb->nStep; + }else if( strcmp(zOp, "sort")==0 ){ + v = pDb->nSort; + }else{ + Jim_SetResultString(interp, "bad argument: should be step or sort", -1); + return JIM_ERR; + } + Jim_SetResultInt(interp, v); + break; + } + + /* + ** $db timeout MILLESECONDS + ** + ** Delay for the number of milliseconds specified when a file is locked. + */ + case DB_TIMEOUT: { + long ms; + if( objc!=3 ){ + Jim_WrongNumArgs(interp, 2, objv, "MILLISECONDS"); + return JIM_ERR; + } + if( Jim_GetLong(interp, objv[2], &ms) ) return JIM_ERR; + sqlite3_busy_timeout(pDb->db, ms); + break; + } + + /* + ** $db total_changes + ** + ** Return the number of rows that were modified, inserted, or deleted + ** since the database handle was created. + */ + case DB_TOTAL_CHANGES: { + if( objc!=2 ){ + Jim_WrongNumArgs(interp, 2, objv, ""); + return JIM_ERR; + } + Jim_SetResultInt(interp, sqlite3_total_changes(pDb->db)); + break; + } + + /* $db trace ?CALLBACK? + ** + ** Make arrangements to invoke the CALLBACK routine for each SQL statement + ** that is executed. The text of the SQL is appended to CALLBACK before + ** it is executed. + */ + case DB_TRACE: { + if( objc>3 ){ + Jim_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); + return JIM_ERR; + }else if( objc==2 ){ + if( pDb->zTrace ){ + Jim_AppendString(interp, Jim_GetResult(interp), pDb->zTrace, -1); + } + }else{ + const char *zTrace; + int len; + if( pDb->zTrace ){ + Jim_Free(pDb->zTrace); + } + zTrace = Jim_GetString(objv[2], &len); + if( zTrace && len>0 ){ + pDb->zTrace = Jim_Alloc( len + 1 ); + memcpy(pDb->zTrace, zTrace, len+1); + }else{ + pDb->zTrace = 0; + } +#ifndef SQLITE_OMIT_TRACE + if( pDb->zTrace ){ + pDb->interp = interp; + sqlite3_trace(pDb->db, DbTraceHandler, pDb); + }else{ + sqlite3_trace(pDb->db, 0, 0); + } +#endif + } + break; + } + + /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT + ** + ** Start a new transaction (if we are not already in the midst of a + ** transaction) and execute the TCL script SCRIPT. After SCRIPT + ** completes, either commit the transaction or roll it back if SCRIPT + ** throws an exception. Or if no new transation was started, do nothing. + ** pass the exception on up the stack. + ** + ** This command was inspired by Dave Thomas's talk on Ruby at the + ** 2005 O'Reilly Open Source Convention (OSCON). + */ + case DB_TRANSACTION: { + Jim_Obj *pScript; + const char *zBegin = "SAVEPOINT _tcl_transaction"; + if( objc!=3 && objc!=4 ){ + Jim_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT"); + return JIM_ERR; + } + + if( pDb->nTransaction==0 && objc==4 ){ + static const char *TTYPE_strs[] = { + "deferred", "exclusive", "immediate", 0 + }; + enum TTYPE_enum { + TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE + }; + int ttype; + if( Jim_GetEnum(interp, objv[2], TTYPE_strs, &ttype, "transaction type", JIM_ERRMSG | JIM_ENUM_ABBREV) ){ + return JIM_ERR; + } + switch( (enum TTYPE_enum)ttype ){ + case TTYPE_DEFERRED: /* no-op */; break; + case TTYPE_EXCLUSIVE: zBegin = "BEGIN EXCLUSIVE"; break; + case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break; + } + } + pScript = objv[objc-1]; + + /* Run the SQLite BEGIN command to open a transaction or savepoint. */ + pDb->disableAuth++; + rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0); + pDb->disableAuth--; + if( rc!=SQLITE_OK ){ + Jim_SetResultString(interp, sqlite3_errmsg(pDb->db), -1); + return JIM_ERR; + } + pDb->nTransaction++; + + /* No NRE in Jim Tcl, so evaluate the script directly, then + ** call function DbTransPostCmd() to commit (or rollback) the transaction + ** or savepoint. */ + rc = DbTransPostCmd(interp, pDb, Jim_EvalObj(interp, pScript)); + break; + } + + /* + ** $db unlock_notify ?script? + */ + case DB_UNLOCK_NOTIFY: { +#ifndef SQLITE_ENABLE_UNLOCK_NOTIFY + Jim_SetResultString(interp, "unlock_notify not available in this build", -1); + rc = JIM_ERR; +#else + if( objc!=2 && objc!=3 ){ + Jim_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); + rc = JIM_ERR; + }else{ + void (*xNotify)(void **, int) = 0; + void *pNotifyArg = 0; + + if( pDb->pUnlockNotify ){ + Jim_DecrRefCount(interp, pDb->pUnlockNotify); + pDb->pUnlockNotify = 0; + } + + if( objc==3 ){ + xNotify = DbUnlockNotify; + pNotifyArg = (void *)pDb; + pDb->pUnlockNotify = objv[2]; + Jim_IncrRefCount(pDb->pUnlockNotify); + } + + if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){ + Jim_SetResultString(interp, sqlite3_errmsg(pDb->db), -1); + rc = JIM_ERR; + } + } +#endif + break; + } + + /* + ** $db update_hook ?script? + ** $db rollback_hook ?script? + */ + case DB_UPDATE_HOOK: + case DB_ROLLBACK_HOOK: { + + /* set ppHook to point at pUpdateHook or pRollbackHook, depending on + ** whether [$db update_hook] or [$db rollback_hook] was invoked. + */ + Jim_Obj **ppHook; + if( choice==DB_UPDATE_HOOK ){ + ppHook = &pDb->pUpdateHook; + }else{ + ppHook = &pDb->pRollbackHook; + } + + if( objc!=2 && objc!=3 ){ + Jim_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); + return JIM_ERR; + } + if( *ppHook ){ + Jim_SetResult(interp, *ppHook); + if( objc==3 ){ + Jim_DecrRefCount(interp, *ppHook); + *ppHook = 0; + } + } + if( objc==3 ){ + assert( !(*ppHook) ); + if( Jim_Length(objv[2])>0 ){ + *ppHook = objv[2]; + Jim_IncrRefCount(*ppHook); + } + } + + sqlite3_update_hook(pDb->db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb); + sqlite3_rollback_hook(pDb->db,(pDb->pRollbackHook?DbRollbackHandler:0),pDb); + + break; + } + + /* $db version + ** + ** Return the version string for this database. + */ + case DB_VERSION: { + Jim_SetResultString(interp, sqlite3_libversion(), -1); + break; + } + + + } /* End of the SWITCH statement */ + return rc; +} + +/* +** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN? +** ?-create BOOLEAN? ?-nomutex BOOLEAN? +** +** This is the main Tcl command. When the "sqlite" Tcl command is +** invoked, this routine runs to process that command. +** +** The first argument, DBNAME, is an arbitrary name for a new +** database connection. This command creates a new command named +** DBNAME that is used to control that connection. The database +** connection is deleted when the DBNAME command is deleted. +** +** The second argument is the name of the database file. +** +*/ +static int DbMain(Jim_Interp *interp, int objc, Jim_Obj *const*objv){ + SqliteDb *p; + const char *pKey = 0; + int nKey = 0; + const char *zArg; + char *zErrMsg; + int i; + const char *zFile; + const char *zVfs = 0; + int flags; + + /* Not threading in Jim, so no mutexing is needed */ + flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX; + + if( objc==2 ){ + zArg = Jim_String(objv[1]); + if( strcmp(zArg,"-version")==0 ){ + Jim_SetResultString(interp, sqlite3_version, -1); + return JIM_OK; + } + if( strcmp(zArg,"-has-codec")==0 ){ +#ifdef SQLITE_HAS_CODEC + Jim_SetResultInt(interp, 1); +#else + Jim_SetResultInt(interp, 0); +#endif + return JIM_OK; + } + } + for(i=3; i+1db, flags, zVfs); + if( SQLITE_OK!=sqlite3_errcode(p->db) ){ + zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); + sqlite3_close(p->db); + p->db = 0; + } +#ifdef SQLITE_HAS_CODEC + if( p->db ){ + sqlite3_key(p->db, pKey, nKey); + } +#endif + if( p->db==0 ){ + Jim_SetResultString(interp, zErrMsg, -1); + Jim_Free((char*)p); + sqlite3_free(zErrMsg); + return JIM_ERR; + } + p->maxStmt = NUM_PREPARED_STMTS; + p->interp = interp; + zArg = Jim_String(objv[1]); + Jim_CreateCommand(interp, zArg, DbObjCmd, p, DbDeleteCmd); + return JIM_OK; +} + +/* +** Make sure we have a PACKAGE_VERSION macro defined. This will be +** defined automatically by the TEA makefile. But other makefiles +** do not define it. +*/ +#ifndef PACKAGE_VERSION +# define PACKAGE_VERSION SQLITE_VERSION +#endif + +#define EXTERN +/* +** Initialize this module. +** +** This Tcl module contains only a single new Tcl command named "sqlite". +** (Hence there is no namespace. There is no point in using a namespace +** if the extension only supplies one new name!) The "sqlite" command is +** used to open a new SQLite database. See the DbMain() routine above +** for additional information. +*/ +EXTERN int Jim_sqlite3Init(Jim_Interp *interp){ + Jim_CreateCommand(interp, "sqlite3", DbMain, 0, 0); + Jim_PackageProvide(interp, "sqlite3", PACKAGE_VERSION, 0); + Jim_CreateCommand(interp, "sqlite", DbMain, 0, 0); + Jim_PackageProvide(interp, "sqlite", PACKAGE_VERSION, 0); + return JIM_OK; +} diff --git a/debuggers/openocd/jimtcl/sqlite3/sqlite3.c b/debuggers/openocd/jimtcl/sqlite3/sqlite3.c new file mode 100644 index 00000000..a7f2677e --- /dev/null +++ b/debuggers/openocd/jimtcl/sqlite3/sqlite3.c @@ -0,0 +1,131878 @@ +/****************************************************************************** +** This file is an amalgamation of many separate C source files from SQLite +** version 3.7.9. By combining all the individual C code files into this +** single large file, the entire code can be compiled as a single translation +** unit. This allows many compilers to do optimizations that would not be +** possible if the files were compiled separately. Performance improvements +** of 5% or more are commonly seen when SQLite is compiled as a single +** translation unit. +** +** This file is all you need to compile SQLite. To use SQLite in other +** programs, you need this file and the "sqlite3.h" header file that defines +** the programming interface to the SQLite library. (If you do not have +** the "sqlite3.h" header file at hand, you will find a copy embedded within +** the text of this file. Search for "Begin file sqlite3.h" to find the start +** of the embedded sqlite3.h header file.) Additional code files may be needed +** if you want a wrapper to interface SQLite with your choice of programming +** language. The code for the "sqlite3" command-line shell is also in a +** separate file. This file contains only code for the core SQLite library. +*/ +#define SQLITE_CORE 1 +#define SQLITE_AMALGAMATION 1 +#ifndef SQLITE_PRIVATE +# define SQLITE_PRIVATE static +#endif +#ifndef SQLITE_API +# define SQLITE_API +#endif +/************** Begin file sqliteInt.h ***************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Internal interface definitions for SQLite. +** +*/ +#ifndef _SQLITEINT_H_ +#define _SQLITEINT_H_ + +/* +** These #defines should enable >2GB file support on POSIX if the +** underlying operating system supports it. If the OS lacks +** large file support, or if the OS is windows, these should be no-ops. +** +** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any +** system #includes. Hence, this block of code must be the very first +** code in all source files. +** +** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch +** on the compiler command line. This is necessary if you are compiling +** on a recent machine (ex: Red Hat 7.2) but you want your code to work +** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2 +** without this option, LFS is enable. But LFS does not exist in the kernel +** in Red Hat 6.0, so the code won't work. Hence, for maximum binary +** portability you should omit LFS. +** +** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later. +*/ +#ifndef SQLITE_DISABLE_LFS +# define _LARGE_FILE 1 +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +# define _LARGEFILE_SOURCE 1 +#endif + +/* +** Include the configuration header output by 'configure' if we're using the +** autoconf-based build +*/ +#ifdef _HAVE_SQLITE_CONFIG_H +#include "config.h" +#endif + +/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/ +/************** Begin file sqliteLimit.h *************************************/ +/* +** 2007 May 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file defines various limits of what SQLite can process. +*/ + +/* +** The maximum length of a TEXT or BLOB in bytes. This also +** limits the size of a row in a table or index. +** +** The hard limit is the ability of a 32-bit signed integer +** to count the size: 2^31-1 or 2147483647. +*/ +#ifndef SQLITE_MAX_LENGTH +# define SQLITE_MAX_LENGTH 1000000000 +#endif + +/* +** This is the maximum number of +** +** * Columns in a table +** * Columns in an index +** * Columns in a view +** * Terms in the SET clause of an UPDATE statement +** * Terms in the result set of a SELECT statement +** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement. +** * Terms in the VALUES clause of an INSERT statement +** +** The hard upper limit here is 32676. Most database people will +** tell you that in a well-normalized database, you usually should +** not have more than a dozen or so columns in any table. And if +** that is the case, there is no point in having more than a few +** dozen values in any of the other situations described above. +*/ +#ifndef SQLITE_MAX_COLUMN +# define SQLITE_MAX_COLUMN 2000 +#endif + +/* +** The maximum length of a single SQL statement in bytes. +** +** It used to be the case that setting this value to zero would +** turn the limit off. That is no longer true. It is not possible +** to turn this limit off. +*/ +#ifndef SQLITE_MAX_SQL_LENGTH +# define SQLITE_MAX_SQL_LENGTH 1000000000 +#endif + +/* +** The maximum depth of an expression tree. This is limited to +** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might +** want to place more severe limits on the complexity of an +** expression. +** +** A value of 0 used to mean that the limit was not enforced. +** But that is no longer true. The limit is now strictly enforced +** at all times. +*/ +#ifndef SQLITE_MAX_EXPR_DEPTH +# define SQLITE_MAX_EXPR_DEPTH 1000 +#endif + +/* +** The maximum number of terms in a compound SELECT statement. +** The code generator for compound SELECT statements does one +** level of recursion for each term. A stack overflow can result +** if the number of terms is too large. In practice, most SQL +** never has more than 3 or 4 terms. Use a value of 0 to disable +** any limit on the number of terms in a compount SELECT. +*/ +#ifndef SQLITE_MAX_COMPOUND_SELECT +# define SQLITE_MAX_COMPOUND_SELECT 500 +#endif + +/* +** The maximum number of opcodes in a VDBE program. +** Not currently enforced. +*/ +#ifndef SQLITE_MAX_VDBE_OP +# define SQLITE_MAX_VDBE_OP 25000 +#endif + +/* +** The maximum number of arguments to an SQL function. +*/ +#ifndef SQLITE_MAX_FUNCTION_ARG +# define SQLITE_MAX_FUNCTION_ARG 127 +#endif + +/* +** The maximum number of in-memory pages to use for the main database +** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE +*/ +#ifndef SQLITE_DEFAULT_CACHE_SIZE +# define SQLITE_DEFAULT_CACHE_SIZE 2000 +#endif +#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE +# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500 +#endif + +/* +** The default number of frames to accumulate in the log file before +** checkpointing the database in WAL mode. +*/ +#ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT +# define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT 1000 +#endif + +/* +** The maximum number of attached databases. This must be between 0 +** and 62. The upper bound on 62 is because a 64-bit integer bitmap +** is used internally to track attached databases. +*/ +#ifndef SQLITE_MAX_ATTACHED +# define SQLITE_MAX_ATTACHED 10 +#endif + + +/* +** The maximum value of a ?nnn wildcard that the parser will accept. +*/ +#ifndef SQLITE_MAX_VARIABLE_NUMBER +# define SQLITE_MAX_VARIABLE_NUMBER 999 +#endif + +/* Maximum page size. The upper bound on this value is 65536. This a limit +** imposed by the use of 16-bit offsets within each page. +** +** Earlier versions of SQLite allowed the user to change this value at +** compile time. This is no longer permitted, on the grounds that it creates +** a library that is technically incompatible with an SQLite library +** compiled with a different limit. If a process operating on a database +** with a page-size of 65536 bytes crashes, then an instance of SQLite +** compiled with the default page-size limit will not be able to rollback +** the aborted transaction. This could lead to database corruption. +*/ +#ifdef SQLITE_MAX_PAGE_SIZE +# undef SQLITE_MAX_PAGE_SIZE +#endif +#define SQLITE_MAX_PAGE_SIZE 65536 + + +/* +** The default size of a database page. +*/ +#ifndef SQLITE_DEFAULT_PAGE_SIZE +# define SQLITE_DEFAULT_PAGE_SIZE 1024 +#endif +#if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE +# undef SQLITE_DEFAULT_PAGE_SIZE +# define SQLITE_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE +#endif + +/* +** Ordinarily, if no value is explicitly provided, SQLite creates databases +** with page size SQLITE_DEFAULT_PAGE_SIZE. However, based on certain +** device characteristics (sector-size and atomic write() support), +** SQLite may choose a larger value. This constant is the maximum value +** SQLite will choose on its own. +*/ +#ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE +# define SQLITE_MAX_DEFAULT_PAGE_SIZE 8192 +#endif +#if SQLITE_MAX_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE +# undef SQLITE_MAX_DEFAULT_PAGE_SIZE +# define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE +#endif + + +/* +** Maximum number of pages in one database file. +** +** This is really just the default value for the max_page_count pragma. +** This value can be lowered (or raised) at run-time using that the +** max_page_count macro. +*/ +#ifndef SQLITE_MAX_PAGE_COUNT +# define SQLITE_MAX_PAGE_COUNT 1073741823 +#endif + +/* +** Maximum length (in bytes) of the pattern in a LIKE or GLOB +** operator. +*/ +#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH +# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000 +#endif + +/* +** Maximum depth of recursion for triggers. +** +** A value of 1 means that a trigger program will not be able to itself +** fire any triggers. A value of 0 means that no trigger programs at all +** may be executed. +*/ +#ifndef SQLITE_MAX_TRIGGER_DEPTH +# define SQLITE_MAX_TRIGGER_DEPTH 1000 +#endif + +/************** End of sqliteLimit.h *****************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + +/* Disable nuisance warnings on Borland compilers */ +#if defined(__BORLANDC__) +#pragma warn -rch /* unreachable code */ +#pragma warn -ccc /* Condition is always true or false */ +#pragma warn -aus /* Assigned value is never used */ +#pragma warn -csu /* Comparing signed and unsigned */ +#pragma warn -spa /* Suspicious pointer arithmetic */ +#endif + +/* Needed for various definitions... */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +/* +** Include standard header files as necessary +*/ +#ifdef HAVE_STDINT_H +#include +#endif +#ifdef HAVE_INTTYPES_H +#include +#endif + +/* +** The following macros are used to cast pointers to integers and +** integers to pointers. The way you do this varies from one compiler +** to the next, so we have developed the following set of #if statements +** to generate appropriate macros for a wide range of compilers. +** +** The correct "ANSI" way to do this is to use the intptr_t type. +** Unfortunately, that typedef is not available on all compilers, or +** if it is available, it requires an #include of specific headers +** that vary from one machine to the next. +** +** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on +** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)). +** So we have to define the macros in different ways depending on the +** compiler. +*/ +#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */ +# define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X)) +# define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X)) +#elif !defined(__GNUC__) /* Works for compilers other than LLVM */ +# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X]) +# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0)) +#elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */ +# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X)) +# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X)) +#else /* Generates a warning - but it always works */ +# define SQLITE_INT_TO_PTR(X) ((void*)(X)) +# define SQLITE_PTR_TO_INT(X) ((int)(X)) +#endif + +/* +** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. +** 0 means mutexes are permanently disable and the library is never +** threadsafe. 1 means the library is serialized which is the highest +** level of threadsafety. 2 means the libary is multithreaded - multiple +** threads can use SQLite as long as no two threads try to use the same +** database connection at the same time. +** +** Older versions of SQLite used an optional THREADSAFE macro. +** We support that for legacy. +*/ +#if !defined(SQLITE_THREADSAFE) +#if defined(THREADSAFE) +# define SQLITE_THREADSAFE THREADSAFE +#else +# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */ +#endif +#endif + +/* +** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1. +** It determines whether or not the features related to +** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can +** be overridden at runtime using the sqlite3_config() API. +*/ +#if !defined(SQLITE_DEFAULT_MEMSTATUS) +# define SQLITE_DEFAULT_MEMSTATUS 1 +#endif + +/* +** Exactly one of the following macros must be defined in order to +** specify which memory allocation subsystem to use. +** +** SQLITE_SYSTEM_MALLOC // Use normal system malloc() +** SQLITE_WIN32_MALLOC // Use Win32 native heap API +** SQLITE_MEMDEBUG // Debugging version of system malloc() +** +** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the +** assert() macro is enabled, each call into the Win32 native heap subsystem +** will cause HeapValidate to be called. If heap validation should fail, an +** assertion will be triggered. +** +** (Historical note: There used to be several other options, but we've +** pared it down to just these three.) +** +** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as +** the default. +*/ +#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1 +# error "At most one of the following compile-time configuration options\ + is allows: SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG" +#endif +#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)==0 +# define SQLITE_SYSTEM_MALLOC 1 +#endif + +/* +** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the +** sizes of memory allocations below this value where possible. +*/ +#if !defined(SQLITE_MALLOC_SOFT_LIMIT) +# define SQLITE_MALLOC_SOFT_LIMIT 1024 +#endif + +/* +** We need to define _XOPEN_SOURCE as follows in order to enable +** recursive mutexes on most Unix systems. But Mac OS X is different. +** The _XOPEN_SOURCE define causes problems for Mac OS X we are told, +** so it is omitted there. See ticket #2673. +** +** Later we learn that _XOPEN_SOURCE is poorly or incorrectly +** implemented on some systems. So we avoid defining it at all +** if it is already defined or if it is unneeded because we are +** not doing a threadsafe build. Ticket #2681. +** +** See also ticket #2741. +*/ +#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE_THREADSAFE +# define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */ +#endif + +/* +** The TCL headers are only needed when compiling the TCL bindings. +*/ +#if defined(SQLITE_TCL) || defined(TCLSH) +# include +#endif + +/* +** Many people are failing to set -DNDEBUG=1 when compiling SQLite. +** Setting NDEBUG makes the code smaller and run faster. So the following +** lines are added to automatically set NDEBUG unless the -DSQLITE_DEBUG=1 +** option is set. Thus NDEBUG becomes an opt-in rather than an opt-out +** feature. +*/ +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif + +/* +** The testcase() macro is used to aid in coverage testing. When +** doing coverage testing, the condition inside the argument to +** testcase() must be evaluated both true and false in order to +** get full branch coverage. The testcase() macro is inserted +** to help ensure adequate test coverage in places where simple +** condition/decision coverage is inadequate. For example, testcase() +** can be used to make sure boundary values are tested. For +** bitmask tests, testcase() can be used to make sure each bit +** is significant and used at least once. On switch statements +** where multiple cases go to the same block of code, testcase() +** can insure that all cases are evaluated. +** +*/ +#ifdef SQLITE_COVERAGE_TEST +SQLITE_PRIVATE void sqlite3Coverage(int); +# define testcase(X) if( X ){ sqlite3Coverage(__LINE__); } +#else +# define testcase(X) +#endif + +/* +** The TESTONLY macro is used to enclose variable declarations or +** other bits of code that are needed to support the arguments +** within testcase() and assert() macros. +*/ +#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST) +# define TESTONLY(X) X +#else +# define TESTONLY(X) +#endif + +/* +** Sometimes we need a small amount of code such as a variable initialization +** to setup for a later assert() statement. We do not want this code to +** appear when assert() is disabled. The following macro is therefore +** used to contain that setup code. The "VVA" acronym stands for +** "Verification, Validation, and Accreditation". In other words, the +** code within VVA_ONLY() will only run during verification processes. +*/ +#ifndef NDEBUG +# define VVA_ONLY(X) X +#else +# define VVA_ONLY(X) +#endif + +/* +** The ALWAYS and NEVER macros surround boolean expressions which +** are intended to always be true or false, respectively. Such +** expressions could be omitted from the code completely. But they +** are included in a few cases in order to enhance the resilience +** of SQLite to unexpected behavior - to make the code "self-healing" +** or "ductile" rather than being "brittle" and crashing at the first +** hint of unplanned behavior. +** +** In other words, ALWAYS and NEVER are added for defensive code. +** +** When doing coverage testing ALWAYS and NEVER are hard-coded to +** be true and false so that the unreachable code then specify will +** not be counted as untested code. +*/ +#if defined(SQLITE_COVERAGE_TEST) +# define ALWAYS(X) (1) +# define NEVER(X) (0) +#elif !defined(NDEBUG) +# define ALWAYS(X) ((X)?1:(assert(0),0)) +# define NEVER(X) ((X)?(assert(0),1):0) +#else +# define ALWAYS(X) (X) +# define NEVER(X) (X) +#endif + +/* +** Return true (non-zero) if the input is a integer that is too large +** to fit in 32-bits. This macro is used inside of various testcase() +** macros to verify that we have tested SQLite for large-file support. +*/ +#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0) + +/* +** The macro unlikely() is a hint that surrounds a boolean +** expression that is usually false. Macro likely() surrounds +** a boolean expression that is usually true. GCC is able to +** use these hints to generate better code, sometimes. +*/ +#if defined(__GNUC__) && 0 +# define likely(X) __builtin_expect((X),1) +# define unlikely(X) __builtin_expect((X),0) +#else +# define likely(X) !!(X) +# define unlikely(X) !!(X) +#endif + +/************** Include sqlite3.h in the middle of sqliteInt.h ***************/ +/************** Begin file sqlite3.h *****************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve the right to make minor changes +** if experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ +#include /* Needed for the definition of va_list */ + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +extern "C" { +#endif + + +/* +** Add the ability to override 'extern' +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif + +#ifndef SQLITE_API +# define SQLITE_API +#endif + + +/* +** These no-op macros are used in front of interfaces to mark those +** interfaces as either deprecated or experimental. New applications +** should not use deprecated interfaces - they are support for backwards +** compatibility only. Application writers should be aware that +** experimental interfaces are subject to change in point releases. +** +** These macros used to resolve to various kinds of compiler magic that +** would generate warning messages when they were used. But that +** compiler magic ended up generating such a flurry of bug reports +** that we have taken it all out and gone back to using simple +** noop macros. +*/ +#define SQLITE_DEPRECATED +#define SQLITE_EXPERIMENTAL + +/* +** Ensure these symbols were not defined by some previous header file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header +** evaluates to a string literal that is the SQLite version in the +** format "X.Y.Z" where X is the major version number (always 3 for +** SQLite3) and Y is the minor version number and Z is the release number.)^ +** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer +** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same +** numbers used in [SQLITE_VERSION].)^ +** The SQLITE_VERSION_NUMBER for any given release of SQLite will also +** be larger than the release from which it is derived. Either Y will +** be held constant and Z will be incremented or else Y will be incremented +** and Z will be reset to zero. +** +** Since version 3.6.18, SQLite source code has been stored in the +** Fossil configuration management +** system. ^The SQLITE_SOURCE_ID macro evaluates to +** a string which identifies a particular check-in of SQLite +** within its configuration management system. ^The SQLITE_SOURCE_ID +** string contains the date and time of the check-in (UTC) and an SHA1 +** hash of the entire source tree. +** +** See also: [sqlite3_libversion()], +** [sqlite3_libversion_number()], [sqlite3_sourceid()], +** [sqlite_version()] and [sqlite_source_id()]. +*/ +#define SQLITE_VERSION "3.7.9" +#define SQLITE_VERSION_NUMBER 3007009 +#define SQLITE_SOURCE_ID "2011-10-29 19:25:08 5b82ec6fbbd2f4195ad06dd911de3817373ad5bf" + +/* +** CAPI3REF: Run-Time Library Version Numbers +** KEYWORDS: sqlite3_version, sqlite3_sourceid +** +** These interfaces provide the same information as the [SQLITE_VERSION], +** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros +** but are associated with the library instead of the header file. ^(Cautious +** programmers might include assert() statements in their application to +** verify that values returned by these interfaces match the macros in +** the header, and thus insure that the application is +** compiled with matching library and header files. +** +**
+** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
+** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
+** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
+** 
)^ +** +** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION] +** macro. ^The sqlite3_libversion() function returns a pointer to the +** to the sqlite3_version[] string constant. The sqlite3_libversion() +** function is provided for use in DLLs since DLL users usually do not have +** direct access to string constants within the DLL. ^The +** sqlite3_libversion_number() function returns an integer equal to +** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns +** a pointer to a string constant whose value is the same as the +** [SQLITE_SOURCE_ID] C preprocessor macro. +** +** See also: [sqlite_version()] and [sqlite_source_id()]. +*/ +SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; +SQLITE_API const char *sqlite3_libversion(void); +SQLITE_API const char *sqlite3_sourceid(void); +SQLITE_API int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Run-Time Library Compilation Options Diagnostics +** +** ^The sqlite3_compileoption_used() function returns 0 or 1 +** indicating whether the specified option was defined at +** compile time. ^The SQLITE_ prefix may be omitted from the +** option name passed to sqlite3_compileoption_used(). +** +** ^The sqlite3_compileoption_get() function allows iterating +** over the list of options that were defined at compile time by +** returning the N-th compile time option string. ^If N is out of range, +** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ +** prefix is omitted from any strings returned by +** sqlite3_compileoption_get(). +** +** ^Support for the diagnostic functions sqlite3_compileoption_used() +** and sqlite3_compileoption_get() may be omitted by specifying the +** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. +** +** See also: SQL functions [sqlite_compileoption_used()] and +** [sqlite_compileoption_get()] and the [compile_options pragma]. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +SQLITE_API int sqlite3_compileoption_used(const char *zOptName); +SQLITE_API const char *sqlite3_compileoption_get(int N); +#endif + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** ^The sqlite3_threadsafe() function returns zero if and only if +** SQLite was compiled mutexing code omitted due to the +** [SQLITE_THREADSAFE] compile-time option being set to 0. +** +** SQLite can be compiled with or without mutexes. When +** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes +** are enabled and SQLite is threadsafe. When the +** [SQLITE_THREADSAFE] macro is 0, +** the mutexes are omitted. Without the mutexes, it is not safe +** to use SQLite concurrently from more than one thread. +** +** Enabling mutexes incurs a measurable performance penalty. +** So if speed is of utmost importance, it makes sense to disable +** the mutexes. But for maximum safety, mutexes should be enabled. +** ^The default behavior is for mutexes to be enabled. +** +** This interface can be used by an application to make sure that the +** version of SQLite that it is linking against was compiled with +** the desired setting of the [SQLITE_THREADSAFE] macro. +** +** This interface only reports on the compile-time mutex setting +** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with +** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but +** can be fully or partially disabled using a call to [sqlite3_config()] +** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD], +** or [SQLITE_CONFIG_MUTEX]. ^(The return value of the +** sqlite3_threadsafe() function shows only the compile-time setting of +** thread safety, not any run-time changes to that setting made by +** sqlite3_config(). In other words, the return value from sqlite3_threadsafe() +** is unchanged by calls to sqlite3_config().)^ +** +** See the [threading mode] documentation for additional information. +*/ +SQLITE_API int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** KEYWORDS: {database connection} {database connections} +** +** Each open SQLite database is represented by a pointer to an instance of +** the opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()] +** is its destructor. There are many other interfaces (such as +** [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on an +** sqlite3 object. +*/ +typedef struct sqlite3 sqlite3; + +/* +** CAPI3REF: 64-Bit Integer Types +** KEYWORDS: sqlite_int64 sqlite_uint64 +** +** Because there is no cross-platform way to specify 64-bit integer types +** SQLite includes typedefs for 64-bit signed and unsigned integers. +** +** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions. +** The sqlite_int64 and sqlite_uint64 types are supported for backwards +** compatibility only. +** +** ^The sqlite3_int64 and sqlite_int64 types can store integer values +** between -9223372036854775808 and +9223372036854775807 inclusive. ^The +** sqlite3_uint64 and sqlite_uint64 types can store integer values +** between 0 and +18446744073709551615 inclusive. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** +** ^The sqlite3_close() routine is the destructor for the [sqlite3] object. +** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is +** successfully destroyed and all associated resources are deallocated. +** +** Applications must [sqlite3_finalize | finalize] all [prepared statements] +** and [sqlite3_blob_close | close] all [BLOB handles] associated with +** the [sqlite3] object prior to attempting to close the object. ^If +** sqlite3_close() is called on a [database connection] that still has +** outstanding [prepared statements] or [BLOB handles], then it returns +** SQLITE_BUSY. +** +** ^If [sqlite3_close()] is invoked while a transaction is open, +** the transaction is automatically rolled back. +** +** The C parameter to [sqlite3_close(C)] must be either a NULL +** pointer or an [sqlite3] object pointer obtained +** from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()], and not previously closed. +** ^Calling sqlite3_close() with a NULL pointer argument is a +** harmless no-op. +*/ +SQLITE_API int sqlite3_close(sqlite3 *); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** +** The sqlite3_exec() interface is a convenience wrapper around +** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], +** that allows an application to run multiple statements of SQL +** without having to use a lot of C code. +** +** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, +** semicolon-separate SQL statements passed into its 2nd argument, +** in the context of the [database connection] passed in as its 1st +** argument. ^If the callback function of the 3rd argument to +** sqlite3_exec() is not NULL, then it is invoked for each result row +** coming out of the evaluated SQL statements. ^The 4th argument to +** sqlite3_exec() is relayed through to the 1st argument of each +** callback invocation. ^If the callback pointer to sqlite3_exec() +** is NULL, then no callback is ever invoked and result rows are +** ignored. +** +** ^If an error occurs while evaluating the SQL statements passed into +** sqlite3_exec(), then execution of the current statement stops and +** subsequent statements are skipped. ^If the 5th parameter to sqlite3_exec() +** is not NULL then any error message is written into memory obtained +** from [sqlite3_malloc()] and passed back through the 5th parameter. +** To avoid memory leaks, the application should invoke [sqlite3_free()] +** on error message strings returned through the 5th parameter of +** of sqlite3_exec() after the error message string is no longer needed. +** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors +** occur, then sqlite3_exec() sets the pointer in its 5th parameter to +** NULL before returning. +** +** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec() +** routine returns SQLITE_ABORT without invoking the callback again and +** without running any subsequent SQL statements. +** +** ^The 2nd argument to the sqlite3_exec() callback function is the +** number of columns in the result. ^The 3rd argument to the sqlite3_exec() +** callback is an array of pointers to strings obtained as if from +** [sqlite3_column_text()], one for each column. ^If an element of a +** result row is NULL then the corresponding string pointer for the +** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the +** sqlite3_exec() callback is an array of pointers to strings where each +** entry represents the name of corresponding result column as obtained +** from [sqlite3_column_name()]. +** +** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer +** to an empty string, or a pointer that contains only whitespace and/or +** SQL comments, then no SQL statements are evaluated and the database +** is not changed. +** +** Restrictions: +** +**
    +**
  • The application must insure that the 1st parameter to sqlite3_exec() +** is a valid and open [database connection]. +**
  • The application must not close [database connection] specified by +** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. +**
  • The application must not modify the SQL statement text passed into +** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. +**
+*/ +SQLITE_API int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluated */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: SQLITE_OK {error code} {error codes} +** KEYWORDS: {result code} {result codes} +** +** Many SQLite functions return an integer result code from the set shown +** here in order to indicates success or failure. +** +** New error codes may be added in future versions of SQLite. +** +** See also: [SQLITE_IOERR_READ | extended result codes], +** [sqlite3_vtab_on_conflict()] [SQLITE_ROLLBACK | result codes]. +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** KEYWORDS: {extended error code} {extended error codes} +** KEYWORDS: {extended result code} {extended result codes} +** +** In its default configuration, SQLite API routines return one of 26 integer +** [SQLITE_OK | result codes]. However, experience has shown that many of +** these result codes are too coarse-grained. They do not provide as +** much information about problems as programmers might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. The extended result codes are enabled or disabled +** on a per database connection basis using the +** [sqlite3_extended_result_codes()] API. +** +** Some of the available extended result codes are listed here. +** One may expect the number of extended result codes will be expand +** over time. Software that uses extended result codes should expect +** to see new result codes in future releases of SQLite. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) +#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8)) +#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8)) +#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8)) +#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8)) +#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8)) +#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) +#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) +#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) +#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) +#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) +#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) +#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) +#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) +#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) +#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) +#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** These bit values are intended for use in the +** 3rd parameter to the [sqlite3_open_v2()] interface and +** in the 4th parameter to the [sqlite3_vfs.xOpen] method. +*/ +#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ +#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ +#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ +#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ +#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ + +/* Reserved: 0x00F00000 */ + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCharacteristics method of the [sqlite3_io_methods] +** object returns an integer which is a vector of the these +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 +#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of these integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an +** [sqlite3_io_methods] object it uses a combination of +** these integer values as the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. If the lower four bits of the flag +** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics. +** If the lower four bits equal SQLITE_SYNC_FULL, that means +** to use Mac OS X style fullsync instead of fsync(). +** +** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags +** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL +** settings. The [synchronous pragma] determines when calls to the +** xSync VFS method occur and applies uniformly across all platforms. +** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how +** energetic or rigorous or forceful the sync operations are and +** only make a difference on Mac OSX for the default SQLite code. +** (Third-party VFS implementations might also make the distinction +** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the +** operating systems natively supported by SQLite, only Mac OSX +** cares about the difference.) +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the +** [sqlite3_vfs | OS interface layer]. Individual OS interface +** implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs.xOpen] method populates an +** [sqlite3_file] object (or, more commonly, a subclass of the +** [sqlite3_file] object) with a pointer to an instance of this object. +** This object defines the methods used to perform various operations +** against the open file represented by the [sqlite3_file] object. +** +** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The +** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen] +** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element +** to NULL. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] +** flag may be ORed in to indicate that only the data of the file +** and not its inode needs to be synced. +** +** The integer values to xLock() and xUnlock() are one of +**
    +**
  • [SQLITE_LOCK_NONE], +**
  • [SQLITE_LOCK_SHARED], +**
  • [SQLITE_LOCK_RESERVED], +**
  • [SQLITE_LOCK_PENDING], or +**
  • [SQLITE_LOCK_EXCLUSIVE]. +**
+** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method checks whether any database connection, +** either in this process or in some other process, is holding a RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false otherwise. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument is an +** integer opcode. The third argument is a generic pointer intended to +** point to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves all opcodes less than 100 for its own use. +** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. VFS implementations should +** return [SQLITE_NOTFOUND] for file control opcodes that they do not +** recognize. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +**
    +**
  • [SQLITE_IOCAP_ATOMIC] +**
  • [SQLITE_IOCAP_ATOMIC512] +**
  • [SQLITE_IOCAP_ATOMIC1K] +**
  • [SQLITE_IOCAP_ATOMIC2K] +**
  • [SQLITE_IOCAP_ATOMIC4K] +**
  • [SQLITE_IOCAP_ATOMIC8K] +**
  • [SQLITE_IOCAP_ATOMIC16K] +**
  • [SQLITE_IOCAP_ATOMIC32K] +**
  • [SQLITE_IOCAP_ATOMIC64K] +**
  • [SQLITE_IOCAP_SAFE_APPEND] +**
  • [SQLITE_IOCAP_SEQUENTIAL] +**
+** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +** +** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill +** in the unread portions of the buffer with zeros. A VFS that +** fails to zero-fill short reads might seem to work. However, +** failure to zero-fill short reads will eventually lead to +** database corruption. +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Methods above are valid for version 1 */ + int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); + int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); + void (*xShmBarrier)(sqlite3_file*); + int (*xShmUnmap)(sqlite3_file*, int deleteFlag); + /* Methods above are valid for version 2 */ + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] +** interface. +** +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode causes the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and only needs to be supported when SQLITE_TEST +** is defined. +** +** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS +** layer a hint of how large the database file will grow to be during the +** current transaction. This hint is not guaranteed to be accurate but it +** is often close. The underlying VFS might choose to preallocate database +** file space based on this hint in order to help writes to the database +** file run faster. +** +** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS +** extends and truncates the database file in chunks of a size specified +** by the user. The fourth argument to [sqlite3_file_control()] should +** point to an integer (type int) containing the new chunk-size to use +** for the nominated database. Allocating database file space in large +** chunks (say 1MB at a time), may reduce file-system fragmentation and +** improve performance on some systems. +** +** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer +** to the [sqlite3_file] object associated with a particular database +** connection. See the [sqlite3_file_control()] documentation for +** additional information. +** +** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by +** SQLite and sent to all VFSes in place of a call to the xSync method +** when the database connection has [PRAGMA synchronous] set to OFF.)^ +** Some specialized VFSes need this signal in order to operate correctly +** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most +** VFSes do not need this signal and should silently ignore this opcode. +** Applications should not call [sqlite3_file_control()] with this +** opcode as doing so may disrupt the operation of the specialized VFSes +** that do require it. +** +** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic +** retry counts and intervals for certain disk I/O operations for the +** windows [VFS] in order to work to provide robustness against +** anti-virus programs. By default, the windows VFS will retry file read, +** file write, and file delete opertions up to 10 times, with a delay +** of 25 milliseconds before the first retry and with the delay increasing +** by an additional 25 milliseconds with each subsequent retry. This +** opcode allows those to values (10 retries and 25 milliseconds of delay) +** to be adjusted. The values are changed for all database connections +** within the same process. The argument is a pointer to an array of two +** integers where the first integer i the new retry count and the second +** integer is the delay. If either integer is negative, then the setting +** is not changed but instead the prior value of that setting is written +** into the array entry, allowing the current retry settings to be +** interrogated. The zDbName parameter is ignored. +** +** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the +** persistent [WAL | Write AHead Log] setting. By default, the auxiliary +** write ahead log and shared memory files used for transaction control +** are automatically deleted when the latest connection to the database +** closes. Setting persistent WAL mode causes those files to persist after +** close. Persisting the files is useful when other processes that do not +** have write permission on the directory containing the database file want +** to read the database file, as the WAL and shared memory files must exist +** in order for the database to be readable. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable persistent WAL mode or 1 to enable persistent +** WAL mode. If the integer is -1, then it is overwritten with the current +** WAL persistence setting. +** +** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening +** a write transaction to indicate that, unless it is rolled back for some +** reason, the entire database file will be overwritten by the current +** transaction. This is used by VACUUM operations. +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 +#define SQLITE_GET_LOCKPROXYFILE 2 +#define SQLITE_SET_LOCKPROXYFILE 3 +#define SQLITE_LAST_ERRNO 4 +#define SQLITE_FCNTL_SIZE_HINT 5 +#define SQLITE_FCNTL_CHUNK_SIZE 6 +#define SQLITE_FCNTL_FILE_POINTER 7 +#define SQLITE_FCNTL_SYNC_OMITTED 8 +#define SQLITE_FCNTL_WIN32_AV_RETRY 9 +#define SQLITE_FCNTL_PERSIST_WAL 10 +#define SQLITE_FCNTL_OVERWRITE 11 + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of the sqlite3_vfs object defines the interface between +** the SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". See +** the [VFS | VFS documentation] for further information. +** +** The value of the iVersion field is initially 1 but may be larger in +** future versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. Note that the structure +** of the sqlite3_vfs object changes in the transaction between +** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not +** modified. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered sqlite3_vfs objects are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. Neither the application code nor the VFS +** implementation should use the pNext pointer. +** +** The pNext field is the only field in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** [[sqlite3_vfs.xOpen]] +** ^SQLite guarantees that the zFilename parameter to xOpen +** is either a NULL pointer or string obtained +** from xFullPathname() with an optional suffix added. +** ^If a suffix is added to the zFilename parameter, it will +** consist of a single "-" character followed by no more than +** 10 alphanumeric and/or "-" characters. +** ^SQLite further guarantees that +** the string will be valid and unchanged until xClose() is +** called. Because of the previous sentence, +** the [sqlite3_file] can safely store a pointer to the +** filename if it needs to remember the filename for some reason. +** If the zFilename parameter to xOpen is a NULL pointer then xOpen +** must invent its own temporary name for the file. ^Whenever the +** xFilename parameter is NULL it will also be the case that the +** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. +** +** The flags argument to xOpen() includes all bits set in +** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] +** or [sqlite3_open16()] is used, then flags includes at least +** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set. +** +** ^(SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +**
    +**
  • [SQLITE_OPEN_MAIN_DB] +**
  • [SQLITE_OPEN_MAIN_JOURNAL] +**
  • [SQLITE_OPEN_TEMP_DB] +**
  • [SQLITE_OPEN_TEMP_JOURNAL] +**
  • [SQLITE_OPEN_TRANSIENT_DB] +**
  • [SQLITE_OPEN_SUBJOURNAL] +**
  • [SQLITE_OPEN_MASTER_JOURNAL] +**
  • [SQLITE_OPEN_WAL] +**
)^ +** +** The file I/O implementation can use the object type flags to +** change the way it deals with files. For example, an application +** that does not care about crash recovery or rollback might make +** the open of a journal file a no-op. Writes to this journal would +** also be no-ops, and any attempt to read the journal would return +** SQLITE_IOERR. Or the implementation might recognize that a database +** file will be doing page-aligned sector reads and writes in a random +** order and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen method: +** +**
    +**
  • [SQLITE_OPEN_DELETEONCLOSE] +**
  • [SQLITE_OPEN_EXCLUSIVE] +**
+** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. ^The [SQLITE_OPEN_DELETEONCLOSE] +** will be set for TEMP databases and their journals, transient +** databases, and subjournals. +** +** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction +** with the [SQLITE_OPEN_CREATE] flag, which are both directly +** analogous to the O_EXCL and O_CREAT flags of the POSIX open() +** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the +** SQLITE_OPEN_CREATE, is used to indicate that file should always +** be created, and that it is an error if it already exists. +** It is not used to indicate the file should be opened +** for exclusive access. +** +** ^At least szOsFile bytes of memory are allocated by SQLite +** to hold the [sqlite3_file] structure passed as the third +** argument to xOpen. The xOpen method does not have to +** allocate the structure; it should just fill it in. Note that +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods +** element will be valid after xOpen returns regardless of the success +** or failure of the xOpen call. +** +** [[sqlite3_vfs.xAccess]] +** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to +** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test whether a file is at least readable. The file can be a +** directory. +** +** ^SQLite will always allocate at least mxPathname+1 bytes for the +** output buffer xFullPathname. The exact size of the output buffer +** is also passed as a parameter to both methods. If the output buffer +** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is +** handled as a fatal error by SQLite, vfs implementations should endeavor +** to prevent this by setting mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() +** interfaces are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. +** The xSleep() method causes the calling thread to sleep for at +** least the number of microseconds given. ^The xCurrentTime() +** method returns a Julian Day Number for the current date and time as +** a floating point value. +** ^The xCurrentTimeInt64() method returns, as an integer, the Julian +** Day Number multiplied by 86400000 (the number of milliseconds in +** a 24-hour day). +** ^SQLite will use the xCurrentTimeInt64() method to get the current +** date and time if that method is available (if iVersion is 2 or +** greater and the function pointer is not NULL) and will fall back +** to xCurrentTime() if xCurrentTimeInt64() is unavailable. +** +** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces +** are not used by the SQLite core. These optional interfaces are provided +** by some VFSes to facilitate testing of the VFS code. By overriding +** system calls with functions under its control, a test program can +** simulate faults and error conditions that would otherwise be difficult +** or impossible to induce. The set of system calls that can be overridden +** varies from one VFS to another, and from one version of the same VFS to the +** next. Applications that use these interfaces must be prepared for any +** or all of these interfaces to be NULL or for their behavior to change +** from one release to the next. Applications must not attempt to access +** any of these methods if the iVersion of the VFS is less than 3. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +typedef void (*sqlite3_syscall_ptr)(void); +struct sqlite3_vfs { + int iVersion; /* Structure version number (currently 3) */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + int (*xGetLastError)(sqlite3_vfs*, int, char *); + /* + ** The methods above are in version 1 of the sqlite_vfs object + ** definition. Those that follow are added in version 2 or later + */ + int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); + /* + ** The methods above are in versions 1 and 2 of the sqlite_vfs object. + ** Those below are for version 3 and greater. + */ + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); + sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); + const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); + /* + ** The methods above are in versions 1 through 3 of the sqlite_vfs object. + ** New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. + */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** what kind of permissions the xAccess method is looking for. +** With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks whether the file exists. +** With SQLITE_ACCESS_READWRITE, the xAccess method +** checks whether the named directory is both readable and writable +** (in other words, if files can be added, removed, and renamed within +** the directory). +** The SQLITE_ACCESS_READWRITE constant is currently used only by the +** [temp_store_directory pragma], though this could change in a future +** release of SQLite. +** With SQLITE_ACCESS_READ, the xAccess method +** checks whether the file is readable. The SQLITE_ACCESS_READ constant is +** currently unused, though it might be used in a future release of +** SQLite. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */ +#define SQLITE_ACCESS_READ 2 /* Unused */ + +/* +** CAPI3REF: Flags for the xShmLock VFS method +** +** These integer constants define the various locking operations +** allowed by the xShmLock method of [sqlite3_io_methods]. The +** following are the only legal combinations of flags to the +** xShmLock method: +** +**
    +**
  • SQLITE_SHM_LOCK | SQLITE_SHM_SHARED +**
  • SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE +**
  • SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED +**
  • SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE +**
+** +** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as +** was given no the corresponding lock. +** +** The xShmLock method can transition between unlocked and SHARED or +** between unlocked and EXCLUSIVE. It cannot transition between SHARED +** and EXCLUSIVE. +*/ +#define SQLITE_SHM_UNLOCK 1 +#define SQLITE_SHM_LOCK 2 +#define SQLITE_SHM_SHARED 4 +#define SQLITE_SHM_EXCLUSIVE 8 + +/* +** CAPI3REF: Maximum xShmLock index +** +** The xShmLock method on [sqlite3_io_methods] may use values +** between 0 and this upper bound as its "offset" argument. +** The SQLite core will never attempt to acquire or release a +** lock outside of this range +*/ +#define SQLITE_SHM_NLOCK 8 + + +/* +** CAPI3REF: Initialize The SQLite Library +** +** ^The sqlite3_initialize() routine initializes the +** SQLite library. ^The sqlite3_shutdown() routine +** deallocates any resources that were allocated by sqlite3_initialize(). +** These routines are designed to aid in process initialization and +** shutdown on embedded systems. Workstation applications using +** SQLite normally do not need to invoke either of these routines. +** +** A call to sqlite3_initialize() is an "effective" call if it is +** the first time sqlite3_initialize() is invoked during the lifetime of +** the process, or if it is the first time sqlite3_initialize() is invoked +** following a call to sqlite3_shutdown(). ^(Only an effective call +** of sqlite3_initialize() does any initialization. All other calls +** are harmless no-ops.)^ +** +** A call to sqlite3_shutdown() is an "effective" call if it is the first +** call to sqlite3_shutdown() since the last sqlite3_initialize(). ^(Only +** an effective call to sqlite3_shutdown() does any deinitialization. +** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^ +** +** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown() +** is not. The sqlite3_shutdown() interface must only be called from a +** single thread. All open [database connections] must be closed and all +** other SQLite resources must be deallocated prior to invoking +** sqlite3_shutdown(). +** +** Among other things, ^sqlite3_initialize() will invoke +** sqlite3_os_init(). Similarly, ^sqlite3_shutdown() +** will invoke sqlite3_os_end(). +** +** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success. +** ^If for some reason, sqlite3_initialize() is unable to initialize +** the library (perhaps it is unable to allocate a needed resource such +** as a mutex) it returns an [error code] other than [SQLITE_OK]. +** +** ^The sqlite3_initialize() routine is called internally by many other +** SQLite interfaces so that an application usually does not need to +** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] +** calls sqlite3_initialize() so the SQLite library will be automatically +** initialized when [sqlite3_open()] is called if it has not be initialized +** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT] +** compile-time option, then the automatic calls to sqlite3_initialize() +** are omitted and the application must call sqlite3_initialize() directly +** prior to using any other SQLite interface. For maximum portability, +** it is recommended that applications always invoke sqlite3_initialize() +** directly prior to using any other SQLite interface. Future releases +** of SQLite may require this. In other words, the behavior exhibited +** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the +** default behavior in some future release of SQLite. +** +** The sqlite3_os_init() routine does operating-system specific +** initialization of the SQLite library. The sqlite3_os_end() +** routine undoes the effect of sqlite3_os_init(). Typical tasks +** performed by these routines include allocation or deallocation +** of static resources, initialization of global variables, +** setting up a default [sqlite3_vfs] module, or setting up +** a default configuration using [sqlite3_config()]. +** +** The application should never invoke either sqlite3_os_init() +** or sqlite3_os_end() directly. The application should only invoke +** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init() +** interface is called automatically by sqlite3_initialize() and +** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate +** implementations for sqlite3_os_init() and sqlite3_os_end() +** are built into SQLite when it is compiled for Unix, Windows, or OS/2. +** When [custom builds | built for other platforms] +** (using the [SQLITE_OS_OTHER=1] compile-time +** option) the application must supply a suitable implementation for +** sqlite3_os_init() and sqlite3_os_end(). An application-supplied +** implementation of sqlite3_os_init() or sqlite3_os_end() +** must return [SQLITE_OK] on success and some other [error code] upon +** failure. +*/ +SQLITE_API int sqlite3_initialize(void); +SQLITE_API int sqlite3_shutdown(void); +SQLITE_API int sqlite3_os_init(void); +SQLITE_API int sqlite3_os_end(void); + +/* +** CAPI3REF: Configuring The SQLite Library +** +** The sqlite3_config() interface is used to make global configuration +** changes to SQLite in order to tune SQLite to the specific needs of +** the application. The default configuration is recommended for most +** applications and so this routine is usually not necessary. It is +** provided to support rare applications with unusual needs. +** +** The sqlite3_config() interface is not threadsafe. The application +** must insure that no other SQLite interfaces are invoked by other +** threads while sqlite3_config() is running. Furthermore, sqlite3_config() +** may only be invoked prior to library initialization using +** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. +** ^If sqlite3_config() is called after [sqlite3_initialize()] and before +** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. +** Note, however, that ^sqlite3_config() can be called as part of the +** implementation of an application-defined [sqlite3_os_init()]. +** +** The first argument to sqlite3_config() is an integer +** [configuration option] that determines +** what property of SQLite is to be configured. Subsequent arguments +** vary depending on the [configuration option] +** in the first argument. +** +** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. +** ^If the option is unknown or SQLite is unable to set the option +** then this routine returns a non-zero [error code]. +*/ +SQLITE_API int sqlite3_config(int, ...); + +/* +** CAPI3REF: Configure database connections +** +** The sqlite3_db_config() interface is used to make configuration +** changes to a [database connection]. The interface is similar to +** [sqlite3_config()] except that the changes apply to a single +** [database connection] (specified in the first argument). +** +** The second argument to sqlite3_db_config(D,V,...) is the +** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code +** that indicates what aspect of the [database connection] is being configured. +** Subsequent arguments vary depending on the configuration verb. +** +** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if +** the call is considered successful. +*/ +SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Memory Allocation Routines +** +** An instance of this object defines the interface between SQLite +** and low-level memory allocation routines. +** +** This object is used in only one place in the SQLite interface. +** A pointer to an instance of this object is the argument to +** [sqlite3_config()] when the configuration option is +** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. +** By creating an instance of this object +** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) +** during configuration, an application can specify an alternative +** memory allocation subsystem for SQLite to use for all of its +** dynamic memory needs. +** +** Note that SQLite comes with several [built-in memory allocators] +** that are perfectly adequate for the overwhelming majority of applications +** and that this object is only useful to a tiny minority of applications +** with specialized memory allocation requirements. This object is +** also used during testing of SQLite in order to specify an alternative +** memory allocator that simulates memory out-of-memory conditions in +** order to verify that SQLite recovers gracefully from such +** conditions. +** +** The xMalloc, xRealloc, and xFree methods must work like the +** malloc(), realloc() and free() functions from the standard C library. +** ^SQLite guarantees that the second argument to +** xRealloc is always a value returned by a prior call to xRoundup. +** +** xSize should return the allocated size of a memory allocation +** previously obtained from xMalloc or xRealloc. The allocated size +** is always at least as big as the requested size but may be larger. +** +** The xRoundup method returns what would be the allocated size of +** a memory allocation given a particular requested size. Most memory +** allocators round up memory allocations at least to the next multiple +** of 8. Some allocators round up to a larger multiple or to a power of 2. +** Every memory allocation request coming in through [sqlite3_malloc()] +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** that causes the corresponding memory allocation to fail. +** +** The xInit method initializes the memory allocator. (For example, +** it might allocate any require mutexes or initialize internal data +** structures. The xShutdown method is invoked (indirectly) by +** [sqlite3_shutdown()] and should deallocate any resources acquired +** by xInit. The pAppData pointer is used as the only parameter to +** xInit and xShutdown. +** +** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. For all other methods, SQLite +** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the +** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which +** it is by default) and so the methods are automatically serialized. +** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other +** methods must be threadsafe or else make their own arrangements for +** serialization. +** +** SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +*/ +typedef struct sqlite3_mem_methods sqlite3_mem_methods; +struct sqlite3_mem_methods { + void *(*xMalloc)(int); /* Memory allocation function */ + void (*xFree)(void*); /* Free a prior allocation */ + void *(*xRealloc)(void*,int); /* Resize an allocation */ + int (*xSize)(void*); /* Return the size of an allocation */ + int (*xRoundup)(int); /* Round up request size to allocation size */ + int (*xInit)(void*); /* Initialize the memory allocator */ + void (*xShutdown)(void*); /* Deinitialize the memory allocator */ + void *pAppData; /* Argument to xInit() and xShutdown() */ +}; + +/* +** CAPI3REF: Configuration Options +** KEYWORDS: {configuration option} +** +** These constants are the available integer configuration options that +** can be passed as the first argument to the [sqlite3_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_config()] to make sure that +** the call worked. The [sqlite3_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
+** [[SQLITE_CONFIG_SINGLETHREAD]]
SQLITE_CONFIG_SINGLETHREAD
+**
There are no arguments to this option. ^This option sets the +** [threading mode] to Single-thread. In other words, it disables +** all mutexing and puts SQLite into a mode where it can only be used +** by a single thread. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to change the [threading mode] from its default +** value of Single-thread and so [sqlite3_config()] will return +** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD +** configuration option.
+** +** [[SQLITE_CONFIG_MULTITHREAD]]
SQLITE_CONFIG_MULTITHREAD
+**
There are no arguments to this option. ^This option sets the +** [threading mode] to Multi-thread. In other words, it disables +** mutexing on [database connection] and [prepared statement] objects. +** The application is responsible for serializing access to +** [database connections] and [prepared statements]. But other mutexes +** are enabled so that SQLite will be safe to use in a multi-threaded +** environment as long as no two threads attempt to use the same +** [database connection] at the same time. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Multi-thread [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_MULTITHREAD configuration option.
+** +** [[SQLITE_CONFIG_SERIALIZED]]
SQLITE_CONFIG_SERIALIZED
+**
There are no arguments to this option. ^This option sets the +** [threading mode] to Serialized. In other words, this option enables +** all mutexes including the recursive +** mutexes on [database connection] and [prepared statement] objects. +** In this mode (which is the default when SQLite is compiled with +** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access +** to [database connections] and [prepared statements] so that the +** application is free to use the same [database connection] or the +** same [prepared statement] in different threads at the same time. +** ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Serialized [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_SERIALIZED configuration option.
+** +** [[SQLITE_CONFIG_MALLOC]]
SQLITE_CONFIG_MALLOC
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mem_methods] structure. The argument specifies +** alternative low-level memory allocation routines to be used in place of +** the memory allocation routines built into SQLite.)^ ^SQLite makes +** its own private copy of the content of the [sqlite3_mem_methods] structure +** before the [sqlite3_config()] call returns.
+** +** [[SQLITE_CONFIG_GETMALLOC]]
SQLITE_CONFIG_GETMALLOC
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mem_methods] structure. The [sqlite3_mem_methods] +** structure is filled with the currently defined memory allocation routines.)^ +** This option can be used to overload the default memory allocation +** routines with a wrapper that simulations memory allocation failure or +** tracks memory usage, for example.
+** +** [[SQLITE_CONFIG_MEMSTATUS]]
SQLITE_CONFIG_MEMSTATUS
+**
^This option takes single argument of type int, interpreted as a +** boolean, which enables or disables the collection of memory allocation +** statistics. ^(When memory allocation statistics are disabled, the +** following SQLite interfaces become non-operational: +**
    +**
  • [sqlite3_memory_used()] +**
  • [sqlite3_memory_highwater()] +**
  • [sqlite3_soft_heap_limit64()] +**
  • [sqlite3_status()] +**
)^ +** ^Memory allocation statistics are enabled by default unless SQLite is +** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory +** allocation statistics are disabled by default. +**
+** +** [[SQLITE_CONFIG_SCRATCH]]
SQLITE_CONFIG_SCRATCH
+**
^This option specifies a static memory buffer that SQLite can use for +** scratch memory. There are three arguments: A pointer an 8-byte +** aligned memory buffer from which the scratch allocations will be +** drawn, the size of each scratch allocation (sz), +** and the maximum number of scratch allocations (N). The sz +** argument must be a multiple of 16. +** The first argument must be a pointer to an 8-byte aligned buffer +** of at least sz*N bytes of memory. +** ^SQLite will use no more than two scratch buffers per thread. So +** N should be set to twice the expected maximum number of threads. +** ^SQLite will never require a scratch buffer that is more than 6 +** times the database page size. ^If SQLite needs needs additional +** scratch memory beyond what is provided by this configuration option, then +** [sqlite3_malloc()] will be used to obtain the memory needed.
+** +** [[SQLITE_CONFIG_PAGECACHE]]
SQLITE_CONFIG_PAGECACHE
+**
^This option specifies a static memory buffer that SQLite can use for +** the database page cache with the default page cache implementation. +** This configuration should not be used if an application-define page +** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. +** There are three arguments to this option: A pointer to 8-byte aligned +** memory, the size of each page buffer (sz), and the number of pages (N). +** The sz argument should be the size of the largest database page +** (a power of two between 512 and 32768) plus a little extra for each +** page header. ^The page header size is 20 to 40 bytes depending on +** the host architecture. ^It is harmless, apart from the wasted memory, +** to make sz a little too large. The first +** argument should point to an allocation of at least sz*N bytes of memory. +** ^SQLite will use the memory provided by the first argument to satisfy its +** memory needs for the first N pages that it adds to cache. ^If additional +** page cache memory is needed beyond what is provided by this option, then +** SQLite goes to [sqlite3_malloc()] for the additional storage space. +** The pointer in the first argument must +** be aligned to an 8-byte boundary or subsequent behavior of SQLite +** will be undefined.
+** +** [[SQLITE_CONFIG_HEAP]]
SQLITE_CONFIG_HEAP
+**
^This option specifies a static memory buffer that SQLite will use +** for all of its dynamic memory allocation needs beyond those provided +** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE]. +** There are three arguments: An 8-byte aligned pointer to the memory, +** the number of bytes in the memory buffer, and the minimum allocation size. +** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts +** to using its default memory allocator (the system malloc() implementation), +** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the +** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or +** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory +** allocator is engaged to handle all of SQLites memory allocation needs. +** The first pointer (the memory pointer) must be aligned to an 8-byte +** boundary or subsequent behavior of SQLite will be undefined. +** The minimum allocation size is capped at 2**12. Reasonable values +** for the minimum allocation size are 2**5 through 2**8.
+** +** [[SQLITE_CONFIG_MUTEX]]
SQLITE_CONFIG_MUTEX
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mutex_methods] structure. The argument specifies +** alternative low-level mutex routines to be used in place +** the mutex routines built into SQLite.)^ ^SQLite makes a copy of the +** content of the [sqlite3_mutex_methods] structure before the call to +** [sqlite3_config()] returns. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will +** return [SQLITE_ERROR].
+** +** [[SQLITE_CONFIG_GETMUTEX]]
SQLITE_CONFIG_GETMUTEX
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mutex_methods] structure. The +** [sqlite3_mutex_methods] +** structure is filled with the currently defined mutex routines.)^ +** This option can be used to overload the default mutex allocation +** routines with a wrapper used to track mutex usage for performance +** profiling or testing, for example. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will +** return [SQLITE_ERROR].
+** +** [[SQLITE_CONFIG_LOOKASIDE]]
SQLITE_CONFIG_LOOKASIDE
+**
^(This option takes two arguments that determine the default +** memory allocation for the lookaside memory allocator on each +** [database connection]. The first argument is the +** size of each lookaside buffer slot and the second is the number of +** slots allocated to each database connection.)^ ^(This option sets the +** default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] +** verb to [sqlite3_db_config()] can be used to change the lookaside +** configuration on individual connections.)^
+** +** [[SQLITE_CONFIG_PCACHE]]
SQLITE_CONFIG_PCACHE
+**
^(This option takes a single argument which is a pointer to +** an [sqlite3_pcache_methods] object. This object specifies the interface +** to a custom page cache implementation.)^ ^SQLite makes a copy of the +** object and uses it for page cache memory allocations.
+** +** [[SQLITE_CONFIG_GETPCACHE]]
SQLITE_CONFIG_GETPCACHE
+**
^(This option takes a single argument which is a pointer to an +** [sqlite3_pcache_methods] object. SQLite copies of the current +** page cache implementation into that object.)^
+** +** [[SQLITE_CONFIG_LOG]]
SQLITE_CONFIG_LOG
+**
^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a +** function with a call signature of void(*)(void*,int,const char*), +** and a pointer to void. ^If the function pointer is not NULL, it is +** invoked by [sqlite3_log()] to process each logging event. ^If the +** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. +** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is +** passed through as the first parameter to the application-defined logger +** function whenever that function is invoked. ^The second parameter to +** the logger function is a copy of the first parameter to the corresponding +** [sqlite3_log()] call and is intended to be a [result code] or an +** [extended result code]. ^The third parameter passed to the logger is +** log message after formatting via [sqlite3_snprintf()]. +** The SQLite logging interface is not reentrant; the logger function +** supplied by the application must not invoke any SQLite interface. +** In a multi-threaded application, the application-defined logger +** function must be threadsafe.
+** +** [[SQLITE_CONFIG_URI]]
SQLITE_CONFIG_URI +**
This option takes a single argument of type int. If non-zero, then +** URI handling is globally enabled. If the parameter is zero, then URI handling +** is globally disabled. If URI handling is globally enabled, all filenames +** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or +** specified as part of [ATTACH] commands are interpreted as URIs, regardless +** of whether or not the [SQLITE_OPEN_URI] flag is set when the database +** connection is opened. If it is globally disabled, filenames are +** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the +** database connection is opened. By default, URI handling is globally +** disabled. The default value may be changed by compiling with the +** [SQLITE_USE_URI] symbol defined. +**
+*/ +#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ +#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ +#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ +#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ +#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ +#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ +#define SQLITE_CONFIG_PCACHE 14 /* sqlite3_pcache_methods* */ +#define SQLITE_CONFIG_GETPCACHE 15 /* sqlite3_pcache_methods* */ +#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ +#define SQLITE_CONFIG_URI 17 /* int */ + +/* +** CAPI3REF: Database Connection Configuration Options +** +** These constants are the available integer configuration options that +** can be passed as the second argument to the [sqlite3_db_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_db_config()] to make sure that +** the call worked. ^The [sqlite3_db_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
+**
SQLITE_DBCONFIG_LOOKASIDE
+**
^This option takes three additional arguments that determine the +** [lookaside memory allocator] configuration for the [database connection]. +** ^The first argument (the third parameter to [sqlite3_db_config()] is a +** pointer to a memory buffer to use for lookaside memory. +** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb +** may be NULL in which case SQLite will allocate the +** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the +** size of each lookaside buffer slot. ^The third argument is the number of +** slots. The size of the buffer in the first argument must be greater than +** or equal to the product of the second and third arguments. The buffer +** must be aligned to an 8-byte boundary. ^If the second argument to +** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally +** rounded down to the next smaller multiple of 8. ^(The lookaside memory +** configuration for a database connection can only be changed when that +** connection is not currently using lookaside memory, or in other words +** when the "current value" returned by +** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. +** Any attempt to change the lookaside memory configuration when lookaside +** memory is in use leaves the configuration unchanged and returns +** [SQLITE_BUSY].)^
+** +**
SQLITE_DBCONFIG_ENABLE_FKEY
+**
^This option is used to enable or disable the enforcement of +** [foreign key constraints]. There should be two additional arguments. +** The first argument is an integer which is 0 to disable FK enforcement, +** positive to enable FK enforcement or negative to leave FK enforcement +** unchanged. The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether FK enforcement is off or on +** following this call. The second parameter may be a NULL pointer, in +** which case the FK enforcement setting is not reported back.
+** +**
SQLITE_DBCONFIG_ENABLE_TRIGGER
+**
^This option is used to enable or disable [CREATE TRIGGER | triggers]. +** There should be two additional arguments. +** The first argument is an integer which is 0 to disable triggers, +** positive to enable triggers or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether triggers are disabled or enabled +** following this call. The second parameter may be a NULL pointer, in +** which case the trigger setting is not reported back.
+** +**
+*/ +#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ +#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ + + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** +** ^The sqlite3_extended_result_codes() routine enables or disables the +** [extended result codes] feature of SQLite. ^The extended result +** codes are disabled by default for historical compatibility. +*/ +SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** +** ^Each entry in an SQLite table has a unique 64-bit signed +** integer key called the [ROWID | "rowid"]. ^The rowid is always available +** as an undeclared column named ROWID, OID, or _ROWID_ as long as those +** names are not also used by explicitly declared columns. ^If +** the table has a column of type [INTEGER PRIMARY KEY] then that column +** is another alias for the rowid. +** +** ^This routine returns the [rowid] of the most recent +** successful [INSERT] into the database from the [database connection] +** in the first argument. ^As of SQLite version 3.7.7, this routines +** records the last insert rowid of both ordinary tables and [virtual tables]. +** ^If no successful [INSERT]s +** have ever occurred on that database connection, zero is returned. +** +** ^(If an [INSERT] occurs within a trigger or within a [virtual table] +** method, then this routine will return the [rowid] of the inserted +** row as long as the trigger or virtual table method is running. +** But once the trigger or virtual table method ends, the value returned +** by this routine reverts to what it was before the trigger or virtual +** table method began.)^ +** +** ^An [INSERT] that fails due to a constraint violation is not a +** successful [INSERT] and does not change the value returned by this +** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. ^(When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface.)^ +** +** ^For the purposes of this routine, an [INSERT] is considered to +** be successful even if it is subsequently rolled back. +** +** This function is accessible to SQL statements via the +** [last_insert_rowid() SQL function]. +** +** If a separate thread performs a new [INSERT] on the same +** database connection while the [sqlite3_last_insert_rowid()] +** function is running and thus changes the last insert [rowid], +** then the value returned by [sqlite3_last_insert_rowid()] is +** unpredictable and might not equal either the old or the new +** last insert [rowid]. +*/ +SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** +** ^This function returns the number of database rows that were changed +** or inserted or deleted by the most recently completed SQL statement +** on the [database connection] specified by the first parameter. +** ^(Only changes that are directly specified by the [INSERT], [UPDATE], +** or [DELETE] statement are counted. Auxiliary changes caused by +** triggers or [foreign key actions] are not counted.)^ Use the +** [sqlite3_total_changes()] function to find the total number of changes +** including changes caused by triggers and foreign key actions. +** +** ^Changes to a view that are simulated by an [INSTEAD OF trigger] +** are not counted. Only real table changes are counted. +** +** ^(A "row change" is a change to a single row of a single table +** caused by an INSERT, DELETE, or UPDATE statement. Rows that +** are changed as side effects of [REPLACE] constraint resolution, +** rollback, ABORT processing, [DROP TABLE], or by any other +** mechanisms do not count as direct row changes.)^ +** +** A "trigger context" is a scope of execution that begins and +** ends with the script of a [CREATE TRIGGER | trigger]. +** Most SQL statements are +** evaluated outside of any trigger. This is the "top level" +** trigger context. If a trigger fires from the top level, a +** new trigger context is entered for the duration of that one +** trigger. Subtriggers create subcontexts for their duration. +** +** ^Calling [sqlite3_exec()] or [sqlite3_step()] recursively does +** not create a new trigger context. +** +** ^This function returns the number of direct row changes in the +** most recent INSERT, UPDATE, or DELETE statement within the same +** trigger context. +** +** ^Thus, when called from the top level, this function returns the +** number of changes in the most recent INSERT, UPDATE, or DELETE +** that also occurred at the top level. ^(Within the body of a trigger, +** the sqlite3_changes() interface can be called to find the number of +** changes in the most recently completed INSERT, UPDATE, or DELETE +** statement within the body of the same trigger. +** However, the number returned does not include changes +** caused by subtriggers since those have their own context.)^ +** +** See also the [sqlite3_total_changes()] interface, the +** [count_changes pragma], and the [changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_changes()] is running then the value returned +** is unpredictable and not meaningful. +*/ +SQLITE_API int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +** +** ^This function returns the number of row changes caused by [INSERT], +** [UPDATE] or [DELETE] statements since the [database connection] was opened. +** ^(The count returned by sqlite3_total_changes() includes all changes +** from all [CREATE TRIGGER | trigger] contexts and changes made by +** [foreign key actions]. However, +** the count does not include changes used to implement [REPLACE] constraints, +** do rollbacks or ABORT processing, or [DROP TABLE] processing. The +** count does not include rows of views that fire an [INSTEAD OF trigger], +** though if the INSTEAD OF trigger makes changes of its own, those changes +** are counted.)^ +** ^The sqlite3_total_changes() function counts the changes as soon as +** the statement that makes them is completed (when the statement handle +** is passed to [sqlite3_reset()] or [sqlite3_finalize()]). +** +** See also the [sqlite3_changes()] interface, the +** [count_changes pragma], and the [total_changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_total_changes()] is running then the value +** returned is unpredictable and not meaningful. +*/ +SQLITE_API int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** +** ^This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** ^It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a [database connection] that +** is closed or might close before sqlite3_interrupt() returns. +** +** ^If an SQL operation is very nearly finished at the time when +** sqlite3_interrupt() is called, then it might not have an opportunity +** to be interrupted and might continue to completion. +** +** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE +** that is inside an explicit transaction, then the entire transaction +** will be rolled back automatically. +** +** ^The sqlite3_interrupt(D) call is in effect until all currently running +** SQL statements on [database connection] D complete. ^Any new SQL statements +** that are started after the sqlite3_interrupt() call and before the +** running statements reaches zero are interrupted as if they had been +** running prior to the sqlite3_interrupt() call. ^New SQL statements +** that are started after the running statement count reaches zero are +** not effected by the sqlite3_interrupt(). +** ^A call to sqlite3_interrupt(D) that occurs when there are no running +** SQL statements is a no-op and has no effect on SQL statements +** that are started after the sqlite3_interrupt() call returns. +** +** If the database connection closes while [sqlite3_interrupt()] +** is running then bad things will likely happen. +*/ +SQLITE_API void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These routines are useful during command-line input to determine if the +** currently entered text seems to form a complete SQL statement or +** if additional input is needed before sending the text into +** SQLite for parsing. ^These routines return 1 if the input string +** appears to be a complete SQL statement. ^A statement is judged to be +** complete if it ends with a semicolon token and is not a prefix of a +** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within +** string literals or quoted identifier names or comments are not +** independent tokens (they are part of the token in which they are +** embedded) and thus do not count as a statement terminator. ^Whitespace +** and comments that follow the final semicolon are ignored. +** +** ^These routines return 0 if the statement is incomplete. ^If a +** memory allocation fails, then SQLITE_NOMEM is returned. +** +** ^These routines do not parse the SQL statements thus +** will not detect syntactically incorrect SQL. +** +** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior +** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked +** automatically by sqlite3_complete16(). If that initialization fails, +** then the return value from sqlite3_complete16() will be non-zero +** regardless of whether or not the input SQL is complete.)^ +** +** The input to [sqlite3_complete()] must be a zero-terminated +** UTF-8 string. +** +** The input to [sqlite3_complete16()] must be a zero-terminated +** UTF-16 string in native byte order. +*/ +SQLITE_API int sqlite3_complete(const char *sql); +SQLITE_API int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** +** ^This routine sets a callback function that might be invoked whenever +** an attempt is made to open a database table that another thread +** or process has locked. +** +** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] +** is returned immediately upon encountering the lock. ^If the busy callback +** is not NULL, then the callback might be invoked with two arguments. +** +** ^The first argument to the busy handler is a copy of the void* pointer which +** is the third argument to sqlite3_busy_handler(). ^The second argument to +** the busy handler callback is the number of times that the busy handler has +** been invoked for this locking event. ^If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. +** ^If the callback returns non-zero, then another attempt +** is made to open the database for reading and the cycle repeats. +** +** The presence of a busy handler does not guarantee that it will be invoked +** when there is lock contention. ^If SQLite determines that invoking the busy +** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] +** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** ^The default busy callback is NULL. +** +** ^The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED] +** when SQLite is in the middle of a large transaction where all the +** changes will not fit into the in-memory cache. SQLite will +** already hold a RESERVED lock on the database file, but it needs +** to promote this lock to EXCLUSIVE so that it can spill cache +** pages into the database file without harm to concurrent +** readers. ^If it is unable to promote the lock, then the in-memory +** cache will be left in an inconsistent state and so the error +** code is promoted from the relatively benign [SQLITE_BUSY] to +** the more severe [SQLITE_IOERR_BLOCKED]. ^This error code promotion +** forces an automatic rollback of the changes. See the +** +** CorruptionFollowingBusyError wiki page for a discussion of why +** this is important. +** +** ^(There can only be a single busy handler defined for each +** [database connection]. Setting a new busy handler clears any +** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] +** will also set or clear the busy handler. +** +** The busy callback should not take any actions which modify the +** database connection that invoked the busy handler. Any such actions +** result in undefined behavior. +** +** A busy handler must not close the database connection +** or [prepared statement] that invoked the busy handler. +*/ +SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** +** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps +** for a specified amount of time when a table is locked. ^The handler +** will sleep multiple times until at least "ms" milliseconds of sleeping +** have accumulated. ^After at least "ms" milliseconds of sleeping, +** the handler returns 0 which causes [sqlite3_step()] to return +** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. +** +** ^Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** ^(There can only be a single busy handler for a particular +** [database connection] any any given moment. If another busy handler +** was defined (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared.)^ +*/ +SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** +** This is a legacy interface that is preserved for backwards compatibility. +** Use of this interface is not recommended. +** +** Definition: A result table is memory data structure created by the +** [sqlite3_get_table()] interface. A result table records the +** complete query results from one or more queries. +** +** The table conceptually has a number of rows and columns. But +** these numbers are not part of the result table itself. These +** numbers are obtained separately. Let N be the number of rows +** and M be the number of columns. +** +** A result table is an array of pointers to zero-terminated UTF-8 strings. +** There are (N+1)*M elements in the array. The first M pointers point +** to zero-terminated strings that contain the names of the columns. +** The remaining entries all point to query results. NULL values result +** in NULL pointers. All other values are in their UTF-8 zero-terminated +** string representation as returned by [sqlite3_column_text()]. +** +** A result table might consist of one or more memory allocations. +** It is not safe to pass a result table directly to [sqlite3_free()]. +** A result table should be deallocated using [sqlite3_free_table()]. +** +** ^(As an example of the result table format, suppose a query result +** is as follows: +** +**
+**        Name        | Age
+**        -----------------------
+**        Alice       | 43
+**        Bob         | 28
+**        Cindy       | 21
+** 
+** +** There are two column (M==2) and three rows (N==3). Thus the +** result table has 8 entries. Suppose the result table is stored +** in an array names azResult. Then azResult holds this content: +** +**
+**        azResult[0] = "Name";
+**        azResult[1] = "Age";
+**        azResult[2] = "Alice";
+**        azResult[3] = "43";
+**        azResult[4] = "Bob";
+**        azResult[5] = "28";
+**        azResult[6] = "Cindy";
+**        azResult[7] = "21";
+** 
)^ +** +** ^The sqlite3_get_table() function evaluates one or more +** semicolon-separated SQL statements in the zero-terminated UTF-8 +** string of its 2nd parameter and returns a result table to the +** pointer given in its 3rd parameter. +** +** After the application has finished with the result from sqlite3_get_table(), +** it must pass the result table pointer to sqlite3_free_table() in order to +** release the memory that was malloced. Because of the way the +** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling +** function must not try to call [sqlite3_free()] directly. Only +** [sqlite3_free_table()] is able to release the memory properly and safely. +** +** The sqlite3_get_table() interface is implemented as a wrapper around +** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access +** to any internal data structures of SQLite. It uses only the public +** interface defined here. As a consequence, errors that occur in the +** wrapper layer outside of the internal [sqlite3_exec()] call are not +** reflected in subsequent calls to [sqlite3_errcode()] or +** [sqlite3_errmsg()]. +*/ +SQLITE_API int sqlite3_get_table( + sqlite3 *db, /* An open database */ + const char *zSql, /* SQL to be evaluated */ + char ***pazResult, /* Results of the query */ + int *pnRow, /* Number of result rows written here */ + int *pnColumn, /* Number of result columns written here */ + char **pzErrmsg /* Error msg written here */ +); +SQLITE_API void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are work-alikes of the "printf()" family of functions +** from the standard C library. +** +** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. ^Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf().)^ This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. ^(Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer.)^ We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** ^As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. ^The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf() formatting options apply. In addition, there +** is are "%q", "%Q", and "%z" options. +** +** ^(The %q option works like %s in that it substitutes a null-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal.)^ By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, assume the string variable zText contains text as follows: +** +**
+**  char *zText = "It's a happy day!";
+** 
+** +** One can use this text in an SQL statement as follows: +** +**
+**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
+**  sqlite3_exec(db, zSQL, 0, 0, 0);
+**  sqlite3_free(zSQL);
+** 
+** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +**
+**  INSERT INTO table1 VALUES('It''s a happy day!')
+** 
+** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +**
+**  INSERT INTO table1 VALUES('It's a happy day!');
+** 
+** +** This second example is an SQL syntax error. As a general rule you should +** always use %q instead of %s when inserting text into a string literal. +** +** ^(The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Additionally, if the parameter in the +** argument list is a NULL pointer, %Q substitutes the text "NULL" (without +** single quotes).)^ So, for example, one could say: +** +**
+**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
+**  sqlite3_exec(db, zSQL, 0, 0, 0);
+**  sqlite3_free(zSQL);
+** 
+** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** ^(The "%z" formatting option works like "%s" but with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string.)^ +*/ +SQLITE_API char *sqlite3_mprintf(const char*,...); +SQLITE_API char *sqlite3_vmprintf(const char*, va_list); +SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); +SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. "Core" in the previous sentence +** does not include operating-system specific VFS implementation. The +** Windows VFS uses native malloc() and free() for some operations. +** +** ^The sqlite3_malloc() routine returns a pointer to a block +** of memory at least N bytes in length, where N is the parameter. +** ^If sqlite3_malloc() is unable to obtain sufficient free +** memory, it returns a NULL pointer. ^If the parameter N to +** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns +** a NULL pointer. +** +** ^Calling sqlite3_free() with a pointer previously returned +** by sqlite3_malloc() or sqlite3_realloc() releases that memory so +** that it might be reused. ^The sqlite3_free() routine is +** a no-op if is called with a NULL pointer. Passing a NULL pointer +** to sqlite3_free() is harmless. After being freed, memory +** should neither be read nor written. Even reading previously freed +** memory might result in a segmentation fault or other severe error. +** Memory corruption, a segmentation fault, or other severe error +** might result if sqlite3_free() is called with a non-NULL pointer that +** was not obtained from sqlite3_malloc() or sqlite3_realloc(). +** +** ^(The sqlite3_realloc() interface attempts to resize a +** prior memory allocation to be at least N bytes, where N is the +** second parameter. The memory allocation to be resized is the first +** parameter.)^ ^ If the first parameter to sqlite3_realloc() +** is a NULL pointer then its behavior is identical to calling +** sqlite3_malloc(N) where N is the second parameter to sqlite3_realloc(). +** ^If the second parameter to sqlite3_realloc() is zero or +** negative then the behavior is exactly the same as calling +** sqlite3_free(P) where P is the first parameter to sqlite3_realloc(). +** ^sqlite3_realloc() returns a pointer to a memory allocation +** of at least N bytes in size or NULL if sufficient memory is unavailable. +** ^If M is the size of the prior allocation, then min(N,M) bytes +** of the prior allocation are copied into the beginning of buffer returned +** by sqlite3_realloc() and the prior allocation is freed. +** ^If sqlite3_realloc() returns NULL, then the prior allocation +** is not freed. +** +** ^The memory returned by sqlite3_malloc() and sqlite3_realloc() +** is always aligned to at least an 8 byte boundary, or to a +** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time +** option is used. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be used. +** +** The Windows OS interface layer calls +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular Windows +** installation. Memory allocation errors are detected, but +** they are reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +** +** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] +** must be either NULL or else pointers obtained from a prior +** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have +** not yet been released. +** +** The application must not read or write any part of +** a block of memory after it has been released using +** [sqlite3_free()] or [sqlite3_realloc()]. +*/ +SQLITE_API void *sqlite3_malloc(int); +SQLITE_API void *sqlite3_realloc(void*, int); +SQLITE_API void sqlite3_free(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** SQLite provides these two interfaces for reporting on the status +** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()] +** routines, which form the built-in memory allocation subsystem. +** +** ^The [sqlite3_memory_used()] routine returns the number of bytes +** of memory currently outstanding (malloced but not freed). +** ^The [sqlite3_memory_highwater()] routine returns the maximum +** value of [sqlite3_memory_used()] since the high-water mark +** was last reset. ^The values returned by [sqlite3_memory_used()] and +** [sqlite3_memory_highwater()] include any overhead +** added by SQLite in its implementation of [sqlite3_malloc()], +** but not overhead added by the any underlying system library +** routines that [sqlite3_malloc()] may call. +** +** ^The memory high-water mark is reset to the current value of +** [sqlite3_memory_used()] if and only if the parameter to +** [sqlite3_memory_highwater()] is true. ^The value returned +** by [sqlite3_memory_highwater(1)] is the high-water mark +** prior to the reset. +*/ +SQLITE_API sqlite3_int64 sqlite3_memory_used(void); +SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Pseudo-Random Number Generator +** +** SQLite contains a high-quality pseudo-random number generator (PRNG) used to +** select random [ROWID | ROWIDs] when inserting new records into a table that +** already uses the largest possible [ROWID]. The PRNG is also used for +** the build-in random() and randomblob() SQL functions. This interface allows +** applications to access the same PRNG for other purposes. +** +** ^A call to this routine stores N bytes of randomness into buffer P. +** +** ^The first time this routine is invoked (either internally or by +** the application) the PRNG is seeded using randomness obtained +** from the xRandomness method of the default [sqlite3_vfs] object. +** ^On all subsequent invocations, the pseudo-randomness is generated +** internally and without recourse to the [sqlite3_vfs] xRandomness +** method. +*/ +SQLITE_API void sqlite3_randomness(int N, void *P); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +** +** ^This routine registers an authorizer callback with a particular +** [database connection], supplied in the first argument. +** ^The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. ^The authorizer callback should +** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. ^If the authorizer callback returns +** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] +** then the [sqlite3_prepare_v2()] or equivalent call that triggered +** the authorizer will fail with an error message. +** +** When the callback returns [SQLITE_OK], that means the operation +** requested is ok. ^When the callback returns [SQLITE_DENY], the +** [sqlite3_prepare_v2()] or equivalent call that triggered the +** authorizer will fail with an error message explaining that +** access is denied. +** +** ^The first parameter to the authorizer callback is a copy of the third +** parameter to the sqlite3_set_authorizer() interface. ^The second parameter +** to the callback is an integer [SQLITE_COPY | action code] that specifies +** the particular action to be authorized. ^The third through sixth parameters +** to the callback are zero-terminated strings that contain additional +** details about the action to be authorized. +** +** ^If the action code is [SQLITE_READ] +** and the callback returns [SQLITE_IGNORE] then the +** [prepared statement] statement is constructed to substitute +** a NULL value in place of the table column that would have +** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] +** return can be used to deny an untrusted user access to individual +** columns of a table. +** ^If the action code is [SQLITE_DELETE] and the callback returns +** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the +** [truncate optimization] is disabled and all rows are deleted individually. +** +** An authorizer is used when [sqlite3_prepare | preparing] +** SQL statements from an untrusted source, to ensure that the SQL statements +** do not try to access data they are not allowed to see, or that they do not +** try to execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being [sqlite3_prepare | prepared] that +** disallows everything except [SELECT] statements. +** +** Applications that need to process SQL from untrusted sources +** might also consider lowering resource limits using [sqlite3_limit()] +** and limiting database size using the [max_page_count] [PRAGMA] +** in addition to using an authorizer. +** +** ^(Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call.)^ ^Disable the authorizer by installing a NULL callback. +** The authorizer is disabled by default. +** +** The authorizer callback must not do anything that will modify +** the database connection that invoked the authorizer callback. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the +** statement might be re-prepared during [sqlite3_step()] due to a +** schema change. Hence, the application should ensure that the +** correct authorizer callback remains in place during the [sqlite3_step()]. +** +** ^Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()], unless +** as stated in the previous paragraph, sqlite3_step() invokes +** sqlite3_prepare_v2() to reprepare a statement after a schema change. +*/ +SQLITE_API int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +** +** Note that SQLITE_IGNORE is also used as a [SQLITE_ROLLBACK | return code] +** from the [sqlite3_vtab_on_conflict()] interface. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorize certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization +** callback function will be parameters or NULL depending on which of these +** codes is used as the second parameter. ^(The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* Operation NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* NULL Function Name */ +#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ +#define SQLITE_COPY 0 /* No longer used */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** +** ^The callback function registered by sqlite3_trace() is invoked at +** various times when an SQL statement is being run by [sqlite3_step()]. +** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the +** SQL statement text as the statement first begins executing. +** ^(Additional sqlite3_trace() callbacks might occur +** as each triggered subprogram is entered. The callbacks for triggers +** contain a UTF-8 SQL comment that identifies the trigger.)^ +** +** ^The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes. ^The profile callback contains +** the original statement text and an estimate of wall-clock time +** of how long that statement took to run. ^The profile callback +** time is in units of nanoseconds, however the current implementation +** is only capable of millisecond resolution so the six least significant +** digits in the time are meaningless. Future versions of SQLite +** might provide greater resolution on the profiler callback. The +** sqlite3_profile() function is considered experimental and is +** subject to change in future versions of SQLite. +*/ +SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** +** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback +** function X to be invoked periodically during long running calls to +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for +** database connection D. An example use for this +** interface is to keep a GUI updated during a large query. +** +** ^The parameter P is passed through as the only parameter to the +** callback function X. ^The parameter N is the number of +** [virtual machine instructions] that are evaluated between successive +** invocations of the callback X. +** +** ^Only a single progress handler may be defined at one time per +** [database connection]; setting a new progress handler cancels the +** old one. ^Setting parameter X to NULL disables the progress handler. +** ^The progress handler is also disabled by setting N to a value less +** than 1. +** +** ^If the progress callback returns non-zero, the operation is +** interrupted. This feature can be used to implement a +** "Cancel" button on a GUI progress dialog box. +** +** The progress handler callback must not do anything that will modify +** the database connection that invoked the progress handler. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +*/ +SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** +** ^These routines open an SQLite database file as specified by the +** filename argument. ^The filename argument is interpreted as UTF-8 for +** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte +** order for sqlite3_open16(). ^(A [database connection] handle is usually +** returned in *ppDb, even if an error occurs. The only exception is that +** if SQLite is unable to allocate memory to hold the [sqlite3] object, +** a NULL will be written into *ppDb instead of a pointer to the [sqlite3] +** object.)^ ^(If the database is opened (and/or created) successfully, then +** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error following a failure of any +** of the sqlite3_open() routines. +** +** ^The default encoding for the database will be UTF-8 if +** sqlite3_open() or sqlite3_open_v2() is called and +** UTF-16 in the native byte order if sqlite3_open16() is used. +** +** Whether or not an error occurs when it is opened, resources +** associated with the [database connection] handle should be released by +** passing it to [sqlite3_close()] when it is no longer required. +** +** The sqlite3_open_v2() interface works like sqlite3_open() +** except that it accepts two additional parameters for additional control +** over the new database connection. ^(The flags parameter to +** sqlite3_open_v2() can take one of +** the following three values, optionally combined with the +** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE], +** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^ +** +**
+** ^(
[SQLITE_OPEN_READONLY]
+**
The database is opened in read-only mode. If the database does not +** already exist, an error is returned.
)^ +** +** ^(
[SQLITE_OPEN_READWRITE]
+**
The database is opened for reading and writing if possible, or reading +** only if the file is write protected by the operating system. In either +** case the database must already exist, otherwise an error is returned.
)^ +** +** ^(
[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
+**
The database is opened for reading and writing, and is created if +** it does not already exist. This is the behavior that is always used for +** sqlite3_open() and sqlite3_open16().
)^ +**
+** +** If the 3rd parameter to sqlite3_open_v2() is not one of the +** combinations shown above optionally combined with other +** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] +** then the behavior is undefined. +** +** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection +** opens in the multi-thread [threading mode] as long as the single-thread +** mode has not been set at compile-time or start-time. ^If the +** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens +** in the serialized [threading mode] unless single-thread was +** previously selected at compile-time or start-time. +** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be +** eligible to use [shared cache mode], regardless of whether or not shared +** cache is enabled using [sqlite3_enable_shared_cache()]. ^The +** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not +** participate in [shared cache mode] even if it is enabled. +** +** ^The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system interface that +** the new database connection should use. ^If the fourth parameter is +** a NULL pointer then the default [sqlite3_vfs] object is used. +** +** ^If the filename is ":memory:", then a private, temporary in-memory database +** is created for the connection. ^This in-memory database will vanish when +** the database connection is closed. Future versions of SQLite might +** make use of additional special filenames that begin with the ":" character. +** It is recommended that when a database filename actually does begin with +** a ":" character you should prefix the filename with a pathname such as +** "./" to avoid ambiguity. +** +** ^If the filename is an empty string, then a private, temporary +** on-disk database will be created. ^This private database will be +** automatically deleted as soon as the database connection is closed. +** +** [[URI filenames in sqlite3_open()]]

URI Filenames

+** +** ^If [URI filename] interpretation is enabled, and the filename argument +** begins with "file:", then the filename is interpreted as a URI. ^URI +** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is +** set in the fourth argument to sqlite3_open_v2(), or if it has +** been enabled globally using the [SQLITE_CONFIG_URI] option with the +** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. +** As of SQLite version 3.7.7, URI filename interpretation is turned off +** by default, but future releases of SQLite might enable URI filename +** interpretation by default. See "[URI filenames]" for additional +** information. +** +** URI filenames are parsed according to RFC 3986. ^If the URI contains an +** authority, then it must be either an empty string or the string +** "localhost". ^If the authority is not an empty string or "localhost", an +** error is returned to the caller. ^The fragment component of a URI, if +** present, is ignored. +** +** ^SQLite uses the path component of the URI as the name of the disk file +** which contains the database. ^If the path begins with a '/' character, +** then it is interpreted as an absolute path. ^If the path does not begin +** with a '/' (meaning that the authority section is omitted from the URI) +** then the path is interpreted as a relative path. +** ^On windows, the first component of an absolute path +** is a drive specification (e.g. "C:"). +** +** [[core URI query parameters]] +** The query component of a URI may contain parameters that are interpreted +** either by SQLite itself, or by a [VFS | custom VFS implementation]. +** SQLite interprets the following three query parameters: +** +**
    +**
  • vfs: ^The "vfs" parameter may be used to specify the name of +** a VFS object that provides the operating system interface that should +** be used to access the database file on disk. ^If this option is set to +** an empty string the default VFS object is used. ^Specifying an unknown +** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is +** present, then the VFS specified by the option takes precedence over +** the value passed as the fourth parameter to sqlite3_open_v2(). +** +**
  • mode: ^(The mode parameter may be set to either "ro", "rw" or +** "rwc". Attempting to set it to any other value is an error)^. +** ^If "ro" is specified, then the database is opened for read-only +** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the +** third argument to sqlite3_prepare_v2(). ^If the mode option is set to +** "rw", then the database is opened for read-write (but not create) +** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had +** been set. ^Value "rwc" is equivalent to setting both +** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If sqlite3_open_v2() is +** used, it is an error to specify a value for the mode parameter that is +** less restrictive than that specified by the flags passed as the third +** parameter. +** +**
  • cache: ^The cache parameter may be set to either "shared" or +** "private". ^Setting it to "shared" is equivalent to setting the +** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to +** sqlite3_open_v2(). ^Setting the cache parameter to "private" is +** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. +** ^If sqlite3_open_v2() is used and the "cache" parameter is present in +** a URI filename, its value overrides any behaviour requested by setting +** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. +**
+** +** ^Specifying an unknown parameter in the query component of a URI is not an +** error. Future versions of SQLite might understand additional query +** parameters. See "[query parameters with special meaning to SQLite]" for +** additional information. +** +** [[URI filename examples]]

URI filename examples

+** +** +**
URI filenames Results +**
file:data.db +** Open the file "data.db" in the current directory. +**
file:/home/fred/data.db
+** file:///home/fred/data.db
+** file://localhost/home/fred/data.db
+** Open the database file "/home/fred/data.db". +**
file://darkstar/home/fred/data.db +** An error. "darkstar" is not a recognized authority. +**
+** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db +** Windows only: Open the file "data.db" on fred's desktop on drive +** C:. Note that the %20 escaping in this example is not strictly +** necessary - space characters can be used literally +** in URI filenames. +**
file:data.db?mode=ro&cache=private +** Open file "data.db" in the current directory for read-only access. +** Regardless of whether or not shared-cache mode is enabled by +** default, use a private cache. +**
file:/home/fred/data.db?vfs=unix-nolock +** Open file "/home/fred/data.db". Use the special VFS "unix-nolock". +**
file:data.db?mode=readonly +** An error. "readonly" is not a valid option for the "mode" parameter. +**
+** +** ^URI hexadecimal escape sequences (%HH) are supported within the path and +** query components of a URI. A hexadecimal escape sequence consists of a +** percent sign - "%" - followed by exactly two hexadecimal digits +** specifying an octet value. ^Before the path or query components of a +** URI filename are interpreted, they are encoded using UTF-8 and all +** hexadecimal escape sequences replaced by a single byte containing the +** corresponding octet. If this process generates an invalid UTF-8 encoding, +** the results are undefined. +** +** Note to Windows users: The encoding used for the filename argument +** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** sqlite3_open() or sqlite3_open_v2(). +*/ +SQLITE_API int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Obtain Values For URI Parameters +** +** This is a utility routine, useful to VFS implementations, that checks +** to see if a database file was a URI that contained a specific query +** parameter, and if so obtains the value of the query parameter. +** +** The zFilename argument is the filename pointer passed into the xOpen() +** method of a VFS implementation. The zParam argument is the name of the +** query parameter we seek. This routine returns the value of the zParam +** parameter if it exists. If the parameter does not exist, this routine +** returns a NULL pointer. +** +** If the zFilename argument to this function is not a pointer that SQLite +** passed into the xOpen VFS method, then the behavior of this routine +** is undefined and probably undesirable. +*/ +SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); + + +/* +** CAPI3REF: Error Codes And Messages +** +** ^The sqlite3_errcode() interface returns the numeric [result code] or +** [extended result code] for the most recent failed sqlite3_* API call +** associated with a [database connection]. If a prior API call failed +** but the most recent API call succeeded, the return value from +** sqlite3_errcode() is undefined. ^The sqlite3_extended_errcode() +** interface is the same except that it always returns the +** [extended result code] even when extended result codes are +** disabled. +** +** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF-8 or UTF-16 respectively. +** ^(Memory to hold the error message string is managed internally. +** The application does not need to worry about freeing the result. +** However, the error string might be overwritten or deallocated by +** subsequent calls to other SQLite interface functions.)^ +** +** When the serialized [threading mode] is in use, it might be the +** case that a second error occurs on a separate thread in between +** the time of the first error and the call to these interfaces. +** When that happens, the second error will be reported since these +** interfaces always report the most recent result. To avoid +** this, each thread can obtain exclusive use of the [database connection] D +** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning +** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after +** all calls to the interfaces listed here are completed. +** +** If an interface fails with SQLITE_MISUSE, that means the interface +** was invoked incorrectly by the application. In that case, the +** error code and message may or may not be set. +*/ +SQLITE_API int sqlite3_errcode(sqlite3 *db); +SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); +SQLITE_API const char *sqlite3_errmsg(sqlite3*); +SQLITE_API const void *sqlite3_errmsg16(sqlite3*); + +/* +** CAPI3REF: SQL Statement Object +** KEYWORDS: {prepared statement} {prepared statements} +** +** An instance of this object represents a single SQL statement. +** This object is variously known as a "prepared statement" or a +** "compiled SQL statement" or simply as a "statement". +** +** The life of a statement object goes something like this: +** +**
    +**
  1. Create the object using [sqlite3_prepare_v2()] or a related +** function. +**
  2. Bind values to [host parameters] using the sqlite3_bind_*() +** interfaces. +**
  3. Run the SQL by calling [sqlite3_step()] one or more times. +**
  4. Reset the statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +**
  5. Destroy the object using [sqlite3_finalize()]. +**
+** +** Refer to documentation on individual methods above for additional +** information. +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Run-time Limits +** +** ^(This interface allows the size of various constructs to be limited +** on a connection by connection basis. The first parameter is the +** [database connection] whose limit is to be set or queried. The +** second parameter is one of the [limit categories] that define a +** class of constructs to be size limited. The third parameter is the +** new limit for that construct.)^ +** +** ^If the new limit is a negative number, the limit is unchanged. +** ^(For each limit category SQLITE_LIMIT_NAME there is a +** [limits | hard upper bound] +** set at compile-time by a C preprocessor macro called +** [limits | SQLITE_MAX_NAME]. +** (The "_LIMIT_" in the name is changed to "_MAX_".))^ +** ^Attempts to increase a limit above its hard upper bound are +** silently truncated to the hard upper bound. +** +** ^Regardless of whether or not the limit was changed, the +** [sqlite3_limit()] interface returns the prior value of the limit. +** ^Hence, to find the current value of a limit without changing it, +** simply invoke this interface with the third parameter set to -1. +** +** Run-time limits are intended for use in applications that manage +** both their own internal database and also databases that are controlled +** by untrusted external sources. An example application might be a +** web browser that has its own databases for storing history and +** separate databases controlled by JavaScript applications downloaded +** off the Internet. The internal databases can be given the +** large, default limits. Databases managed by external sources can +** be given much smaller limits designed to prevent a denial of service +** attack. Developers might also want to use the [sqlite3_set_authorizer()] +** interface to further control untrusted SQL. The size of the database +** created by an untrusted script can be contained using the +** [max_page_count] [PRAGMA]. +** +** New run-time limit categories may be added in future releases. +*/ +SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + +/* +** CAPI3REF: Run-Time Limit Categories +** KEYWORDS: {limit category} {*limit categories} +** +** These constants define various performance limits +** that can be lowered at run-time using [sqlite3_limit()]. +** The synopsis of the meanings of the various limits is shown below. +** Additional information is available at [limits | Limits in SQLite]. +** +**
+** [[SQLITE_LIMIT_LENGTH]] ^(
SQLITE_LIMIT_LENGTH
+**
The maximum size of any string or BLOB or table row, in bytes.
)^ +** +** [[SQLITE_LIMIT_SQL_LENGTH]] ^(
SQLITE_LIMIT_SQL_LENGTH
+**
The maximum length of an SQL statement, in bytes.
)^ +** +** [[SQLITE_LIMIT_COLUMN]] ^(
SQLITE_LIMIT_COLUMN
+**
The maximum number of columns in a table definition or in the +** result set of a [SELECT] or the maximum number of columns in an index +** or in an ORDER BY or GROUP BY clause.
)^ +** +** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(
SQLITE_LIMIT_EXPR_DEPTH
+**
The maximum depth of the parse tree on any expression.
)^ +** +** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(
SQLITE_LIMIT_COMPOUND_SELECT
+**
The maximum number of terms in a compound SELECT statement.
)^ +** +** [[SQLITE_LIMIT_VDBE_OP]] ^(
SQLITE_LIMIT_VDBE_OP
+**
The maximum number of instructions in a virtual machine program +** used to implement an SQL statement. This limit is not currently +** enforced, though that might be added in some future release of +** SQLite.
)^ +** +** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(
SQLITE_LIMIT_FUNCTION_ARG
+**
The maximum number of arguments on a function.
)^ +** +** [[SQLITE_LIMIT_ATTACHED]] ^(
SQLITE_LIMIT_ATTACHED
+**
The maximum number of [ATTACH | attached databases].)^
+** +** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]] +** ^(
SQLITE_LIMIT_LIKE_PATTERN_LENGTH
+**
The maximum length of the pattern argument to the [LIKE] or +** [GLOB] operators.
)^ +** +** [[SQLITE_LIMIT_VARIABLE_NUMBER]] +** ^(
SQLITE_LIMIT_VARIABLE_NUMBER
+**
The maximum index number of any [parameter] in an SQL statement.)^ +** +** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(
SQLITE_LIMIT_TRIGGER_DEPTH
+**
The maximum depth of recursion for triggers.
)^ +**
+*/ +#define SQLITE_LIMIT_LENGTH 0 +#define SQLITE_LIMIT_SQL_LENGTH 1 +#define SQLITE_LIMIT_COLUMN 2 +#define SQLITE_LIMIT_EXPR_DEPTH 3 +#define SQLITE_LIMIT_COMPOUND_SELECT 4 +#define SQLITE_LIMIT_VDBE_OP 5 +#define SQLITE_LIMIT_FUNCTION_ARG 6 +#define SQLITE_LIMIT_ATTACHED 7 +#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 +#define SQLITE_LIMIT_VARIABLE_NUMBER 9 +#define SQLITE_LIMIT_TRIGGER_DEPTH 10 + +/* +** CAPI3REF: Compiling An SQL Statement +** KEYWORDS: {SQL statement compiler} +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument, "db", is a [database connection] obtained from a +** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or +** [sqlite3_open16()]. The database connection must not have been closed. +** +** The second argument, "zSql", is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** ^If the nByte argument is less than zero, then zSql is read up to the +** first zero terminator. ^If nByte is non-negative, then it is the maximum +** number of bytes read from zSql. ^When nByte is non-negative, the +** zSql string ends at either the first '\000' or '\u0000' character or +** the nByte-th byte, whichever comes first. If the caller knows +** that the supplied string is nul-terminated, then there is a small +** performance advantage to be gained by passing an nByte parameter that +** is equal to the number of bytes in the input string including +** the nul-terminator bytes as this saves SQLite from having to +** make a copy of the input string. +** +** ^If pzTail is not NULL then *pzTail is made to point to the first byte +** past the end of the first SQL statement in zSql. These routines only +** compile the first statement in zSql, so *pzTail is left pointing to +** what remains uncompiled. +** +** ^*ppStmt is left pointing to a compiled [prepared statement] that can be +** executed using [sqlite3_step()]. ^If there is an error, *ppStmt is set +** to NULL. ^If the input text contains no SQL (if the input is an empty +** string or a comment) then *ppStmt is set to NULL. +** The calling procedure is responsible for deleting the compiled +** SQL statement using [sqlite3_finalize()] after it has finished with it. +** ppStmt may not be NULL. +** +** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK]; +** otherwise an [error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** ^In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave differently in three ways: +** +**
    +**
  1. +** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. +**
  2. +** +**
  3. +** ^When an error occurs, [sqlite3_step()] will return one of the detailed +** [error codes] or [extended error codes]. ^The legacy behavior was that +** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code +** and the application would have to make a second call to [sqlite3_reset()] +** in order to find the underlying cause of the problem. With the "v2" prepare +** interfaces, the underlying reason for the error is returned immediately. +**
  4. +** +**
  5. +** ^If the specific value bound to [parameter | host parameter] in the +** WHERE clause might influence the choice of query plan for a statement, +** then the statement will be automatically recompiled, as if there had been +** a schema change, on the first [sqlite3_step()] call following any change +** to the [sqlite3_bind_text | bindings] of that [parameter]. +** ^The specific value of WHERE-clause [parameter] might influence the +** choice of query plan if the parameter is the left-hand side of a [LIKE] +** or [GLOB] operator or if the parameter is compared to an indexed column +** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. +** the +**
  6. +**
+*/ +SQLITE_API int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** CAPI3REF: Retrieving Statement SQL +** +** ^This interface can be used to retrieve a saved copy of the original +** SQL text used to create a [prepared statement] if that statement was +** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. +*/ +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Determine If An SQL Statement Writes The Database +** +** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if +** and only if the [prepared statement] X makes no direct changes to +** the content of the database file. +** +** Note that [application-defined SQL functions] or +** [virtual tables] might change the database indirectly as a side effect. +** ^(For example, if an application defines a function "eval()" that +** calls [sqlite3_exec()], then the following SQL statement would +** change the database file through side-effects: +** +**
+**    SELECT eval('DELETE FROM t1') FROM t2;
+** 
+** +** But because the [SELECT] statement does not change the database file +** directly, sqlite3_stmt_readonly() would still return true.)^ +** +** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], +** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true, +** since the statements themselves do not actually modify the database but +** rather they control the timing of when other statements modify the +** database. ^The [ATTACH] and [DETACH] statements also cause +** sqlite3_stmt_readonly() to return true since, while those statements +** change the configuration of a database connection, they do not make +** changes to the content of the database files on disk. +*/ +SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Dynamically Typed Value Object +** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} +** +** SQLite uses the sqlite3_value object to represent all values +** that can be stored in a database table. SQLite uses dynamic typing +** for the values it stores. ^Values stored in sqlite3_value objects +** can be integers, floating point values, strings, BLOBs, or NULL. +** +** An sqlite3_value object may be either "protected" or "unprotected". +** Some interfaces require a protected sqlite3_value. Other interfaces +** will accept either a protected or an unprotected sqlite3_value. +** Every interface that accepts sqlite3_value arguments specifies +** whether or not it requires a protected sqlite3_value. +** +** The terms "protected" and "unprotected" refer to whether or not +** a mutex is held. An internal mutex is held for a protected +** sqlite3_value object but no mutex is held for an unprotected +** sqlite3_value object. If SQLite is compiled to be single-threaded +** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) +** or if SQLite is run in one of reduced mutex modes +** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] +** then there is no distinction between protected and unprotected +** sqlite3_value objects and they can be used interchangeably. However, +** for maximum code portability it is recommended that applications +** still make the distinction between protected and unprotected +** sqlite3_value objects even when not strictly required. +** +** ^The sqlite3_value objects that are passed as parameters into the +** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value object returned by +** [sqlite3_column_value()] is unprotected. +** Unprotected sqlite3_value objects may only be used with +** [sqlite3_result_value()] and [sqlite3_bind_value()]. +** The [sqlite3_value_blob | sqlite3_value_type()] family of +** interfaces require protected sqlite3_value objects. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. ^A pointer to an sqlite3_context object +** is always first parameter to [application-defined SQL functions]. +** The application-defined SQL function implementation will pass this +** pointer through into calls to [sqlite3_result_int | sqlite3_result()], +** [sqlite3_aggregate_context()], [sqlite3_user_data()], +** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()], +** and/or [sqlite3_set_auxdata()]. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** KEYWORDS: {host parameter} {host parameters} {host parameter name} +** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} +** +** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, +** literals may be replaced by a [parameter] that matches one of following +** templates: +** +**
    +**
  • ? +**
  • ?NNN +**
  • :VVV +**
  • @VVV +**
  • $VVV +**
+** +** In the templates above, NNN represents an integer literal, +** and VVV represents an alphanumeric identifier.)^ ^The values of these +** parameters (also called "host parameter names" or "SQL parameters") +** can be set using the sqlite3_bind_*() routines defined here. +** +** ^The first argument to the sqlite3_bind_*() routines is always +** a pointer to the [sqlite3_stmt] object returned from +** [sqlite3_prepare_v2()] or its variants. +** +** ^The second argument is the index of the SQL parameter to be set. +** ^The leftmost SQL parameter has an index of 1. ^When the same named +** SQL parameter is used more than once, second and subsequent +** occurrences have the same index as the first occurrence. +** ^The index for named parameters can be looked up using the +** [sqlite3_bind_parameter_index()] API if desired. ^The index +** for "?NNN" parameters is the value of NNN. +** ^The NNN value must be between 1 and the [sqlite3_limit()] +** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999). +** +** ^The third argument is the value to bind to the parameter. +** +** ^(In those routines that have a fourth argument, its value is the +** number of bytes in the parameter. To be clear: the value is the +** number of bytes in the value, not the number of characters.)^ +** ^If the fourth parameter is negative, the length of the string is +** the number of bytes up to the first zero terminator. +** If a non-negative fourth parameter is provided to sqlite3_bind_text() +** or sqlite3_bind_text16() then that parameter must be the byte offset +** where the NUL terminator would occur assuming the string were NUL +** terminated. If any NUL characters occur at byte offsets less than +** the value of the fourth parameter then the resulting string value will +** contain embedded NULs. The result of expressions involving strings +** with embedded NULs is undefined. +** +** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and +** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or +** string after SQLite has finished with it. ^The destructor is called +** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(), +** sqlite3_bind_text(), or sqlite3_bind_text16() fails. +** ^If the fifth argument is +** the special value [SQLITE_STATIC], then SQLite assumes that the +** information is in static, unmanaged space and does not need to be freed. +** ^If the fifth argument has the value [SQLITE_TRANSIENT], then +** SQLite makes its own private copy of the data immediately, before +** the sqlite3_bind_*() routine returns. +** +** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that +** is filled with zeroes. ^A zeroblob uses a fixed amount of memory +** (just an integer to hold its size) while it is being processed. +** Zeroblobs are intended to serve as placeholders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | incremental BLOB I/O] routines. +** ^A negative value for the zeroblob results in a zero-length BLOB. +** +** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer +** for the [prepared statement] or with a prepared statement for which +** [sqlite3_step()] has been called more recently than [sqlite3_reset()], +** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() +** routine is passed a [prepared statement] that has been finalized, the +** result is undefined and probably harmful. +** +** ^Bindings are not cleared by the [sqlite3_reset()] routine. +** ^Unbound parameters are interpreted as NULL. +** +** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an +** [error code] if anything goes wrong. +** ^[SQLITE_RANGE] is returned if the parameter +** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. +** +** See also: [sqlite3_bind_parameter_count()], +** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); +SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); +SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); +SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of SQL Parameters +** +** ^This routine can be used to find the number of [SQL parameters] +** in a [prepared statement]. SQL parameters are tokens of the +** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as +** placeholders for values that are [sqlite3_bind_blob | bound] +** to the parameters at a later time. +** +** ^(This routine actually returns the index of the largest (rightmost) +** parameter. For all forms except ?NNN, this will correspond to the +** number of unique parameters. If parameters of the ?NNN form are used, +** there may be gaps in the list.)^ +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_name()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** +** ^The sqlite3_bind_parameter_name(P,N) interface returns +** the name of the N-th [SQL parameter] in the [prepared statement] P. +** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA" +** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA" +** respectively. +** In other words, the initial ":" or "$" or "@" or "?" +** is included as part of the name.)^ +** ^Parameters of the form "?" without a following integer have no name +** and are referred to as "nameless" or "anonymous parameters". +** +** ^The first host parameter has an index of 1, not 0. +** +** ^If the value N is out of range or if the N-th parameter is +** nameless, then NULL is returned. ^The returned string is +** always in UTF-8 encoding even if the named parameter was +** originally specified as UTF-16 in [sqlite3_prepare16()] or +** [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** +** ^Return the index of an SQL parameter given its name. ^The +** index value returned is suitable for use as the second +** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero +** is returned if no matching parameter is found. ^The parameter +** name must be given in UTF-8 even if the original statement +** was prepared from UTF-16 text using [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** +** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset +** the [sqlite3_bind_blob | bindings] on a [prepared statement]. +** ^Use this routine to reset all host parameters to NULL. +*/ +SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** +** ^Return the number of columns in the result set returned by the +** [prepared statement]. ^This routine returns 0 if pStmt is an SQL +** statement that does not return data (for example an [UPDATE]). +** +** See also: [sqlite3_data_count()] +*/ +SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** +** ^These routines return the name assigned to a particular column +** in the result set of a [SELECT] statement. ^The sqlite3_column_name() +** interface returns a pointer to a zero-terminated UTF-8 string +** and sqlite3_column_name16() returns a pointer to a zero-terminated +** UTF-16 string. ^The first parameter is the [prepared statement] +** that implements the [SELECT] statement. ^The second parameter is the +** column number. ^The leftmost column is number 0. +** +** ^The returned string pointer is valid until either the [prepared statement] +** is destroyed by [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the next call to +** sqlite3_column_name() or sqlite3_column_name16() on the same column. +** +** ^If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +** +** ^The name of a result column is the value of the "AS" clause for +** that column, if there is an AS clause. If there is no AS clause +** then the name of the column is unspecified and may change from +** one release of SQLite to the next. +*/ +SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); +SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** +** ^These routines provide a means to determine the database, table, and +** table column that is the origin of a particular result column in +** [SELECT] statement. +** ^The name of the database or table or column can be returned as +** either a UTF-8 or UTF-16 string. ^The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** ^The returned string is valid until the [prepared statement] is destroyed +** using [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the same information is requested +** again in a different encoding. +** +** ^The names returned are the original un-aliased names of the +** database, table, and column. +** +** ^The first argument to these interfaces is a [prepared statement]. +** ^These functions return information about the Nth result column returned by +** the statement, where N is the second function argument. +** ^The left-most column is column 0 for these routines. +** +** ^If the Nth column returned by the statement is an expression or +** subquery and is not a column value, then all of these functions return +** NULL. ^These routine might also return NULL if a memory allocation error +** occurs. ^Otherwise, they return the name of the attached database, table, +** or column that query result column was extracted from. +** +** ^As with all other SQLite APIs, those whose names end with "16" return +** UTF-16 encoded strings and the other functions return UTF-8. +** +** ^These APIs are only available if the library was compiled with the +** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +** +** If two or more threads call one or more +** [sqlite3_column_database_name | column metadata interfaces] +** for the same [prepared statement] and result column +** at the same time then the results are undefined. +*/ +SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** +** ^(The first parameter is a [prepared statement]. +** If this statement is a [SELECT] statement and the Nth column of the +** returned result set of that [SELECT] is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned.)^ ^If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** ^The returned string is always UTF-8 encoded. +** +** ^(For example, given the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** and the following statement to be compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** this routine would return the string "VARIANT" for the second result +** column (i==1), and a NULL pointer for the first result column (i==0).)^ +** +** ^SQLite uses dynamic run-time typing. ^So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. ^Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** +** After a [prepared statement] has been prepared using either +** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy +** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function +** must be called one or more times to evaluate the statement. +** +** The details of the behavior of the sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** ^In the legacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** ^With the "v2" interface, any of the other [result codes] or +** [extended result codes] might be returned as well. +** +** ^[SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. ^If the statement is a [COMMIT] +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a [COMMIT] and occurs within an +** explicit transaction then you should rollback the transaction before +** continuing. +** +** ^[SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** ^If the SQL statement being executed returns any data, then [SQLITE_ROW] +** is returned each time a new row of data is ready for processing by the +** caller. The values may be accessed using the [column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** ^[SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** ^With the legacy interface, a more specific error code (for example, +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [prepared statement]. ^In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** For all versions of SQLite up to and including 3.6.23.1, a call to +** [sqlite3_reset()] was required after sqlite3_step() returned anything +** other than [SQLITE_ROW] before any subsequent invocation of +** sqlite3_step(). Failure to reset the prepared statement using +** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from +** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began +** calling [sqlite3_reset()] automatically in this circumstance rather +** than returning [SQLITE_MISUSE]. This is not considered a compatibility +** break because any application that ever receives an SQLITE_MISUSE error +** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option +** can be used to restore the legacy behavior. +** +** Goofy Interface Alert: In the legacy interface, the sqlite3_step() +** API always returns a generic error code, [SQLITE_ERROR], following any +** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call +** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the +** specific [error codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, +** then the more specific [error codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +SQLITE_API int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: Number of columns in a result set +** +** ^The sqlite3_data_count(P) interface returns the number of columns in the +** current row of the result set of [prepared statement] P. +** ^If prepared statement P does not have results ready to return +** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of +** interfaces) then sqlite3_data_count(P) returns 0. +** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. +** ^The sqlite3_data_count(P) routine returns 0 if the previous call to +** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P) +** will return non-zero if previous call to [sqlite3_step](P) returned +** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum] +** where it always returns zero since each step of that multi-step +** pragma returns 0 columns of data. +** +** See also: [sqlite3_column_count()] +*/ +SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** KEYWORDS: SQLITE_TEXT +** +** ^(Every value in SQLite has one of five fundamental datatypes: +** +**
    +**
  • 64-bit signed integer +**
  • 64-bit IEEE floating point number +**
  • string +**
  • BLOB +**
  • NULL +**
)^ +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Result Values From A Query +** KEYWORDS: {column access functions} +** +** These routines form the "result set" interface. +** +** ^These routines return information about a single column of the current +** result row of a query. ^In every case the first argument is a pointer +** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] +** that was returned from [sqlite3_prepare_v2()] or one of its variants) +** and the second argument is the index of the column for which information +** should be returned. ^The leftmost column of the result set has the index 0. +** ^The number of columns in the result can be determined using +** [sqlite3_column_count()]. +** +** If the SQL statement does not currently point to a valid row, or if the +** column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** ^The sqlite3_column_type() routine returns the +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. ^The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes() returns zero. +** +** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts +** the string to UTF-16 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes16() uses +** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes16() returns zero. +** +** ^The values returned by [sqlite3_column_bytes()] and +** [sqlite3_column_bytes16()] do not include the zero terminators at the end +** of the string. ^For clarity: the values returned by +** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of +** bytes in the string, not the number of characters. +** +** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even empty strings, are always zero terminated. ^The return +** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. +** +** ^The object returned by [sqlite3_column_value()] is an +** [unprotected sqlite3_value] object. An unprotected sqlite3_value object +** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()]. +** If the [unprotected sqlite3_value] object returned by +** [sqlite3_column_value()] is used in any other way, including calls +** to routines like [sqlite3_value_int()], [sqlite3_value_text()], +** or [sqlite3_value_bytes()], then the behavior is undefined. +** +** These routines attempt to convert the value where appropriate. ^For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to perform the +** conversion automatically. ^(The following table details the conversions +** that are applied: +** +**
+** +**
Internal
Type
Requested
Type
Conversion +** +**
NULL INTEGER Result is 0 +**
NULL FLOAT Result is 0.0 +**
NULL TEXT Result is NULL pointer +**
NULL BLOB Result is NULL pointer +**
INTEGER FLOAT Convert from integer to float +**
INTEGER TEXT ASCII rendering of the integer +**
INTEGER BLOB Same as INTEGER->TEXT +**
FLOAT INTEGER Convert from float to integer +**
FLOAT TEXT ASCII rendering of the float +**
FLOAT BLOB Same as FLOAT->TEXT +**
TEXT INTEGER Use atoi() +**
TEXT FLOAT Use atof() +**
TEXT BLOB No change +**
BLOB INTEGER Convert to TEXT then use atoi() +**
BLOB FLOAT Convert to TEXT then use atof() +**
BLOB TEXT Add a zero terminator if needed +**
+**
)^ +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** own equivalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +**
    +**
  • The initial content is a BLOB and sqlite3_column_text() or +** sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.
  • +**
  • The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.
  • +**
  • The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.
  • +**
+** +** ^Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer references will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometimes they +** are not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +**
    +**
  • sqlite3_column_text() followed by sqlite3_column_bytes()
  • +**
  • sqlite3_column_blob() followed by sqlite3_column_bytes()
  • +**
  • sqlite3_column_text16() followed by sqlite3_column_bytes16()
  • +**
+** +** In other words, you should call sqlite3_column_text(), +** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result +** into the desired format, then invoke sqlite3_column_bytes() or +** sqlite3_column_bytes16() to find the size of the result. Do not mix calls +** to sqlite3_column_text() or sqlite3_column_blob() with calls to +** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16() +** with calls to sqlite3_column_bytes(). +** +** ^The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. ^The memory space used to hold strings +** and BLOBs is freed automatically. Do not pass the pointers returned +** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** ^(If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM].)^ +*/ +SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** +** ^The sqlite3_finalize() function is called to delete a [prepared statement]. +** ^If the most recent evaluation of the statement encountered no errors +** or if the statement is never been evaluated, then sqlite3_finalize() returns +** SQLITE_OK. ^If the most recent evaluation of statement S failed, then +** sqlite3_finalize(S) returns the appropriate [error code] or +** [extended error code]. +** +** ^The sqlite3_finalize(S) routine can be called at any point during +** the life cycle of [prepared statement] S: +** before statement S is ever evaluated, after +** one or more calls to [sqlite3_reset()], or after any call +** to [sqlite3_step()] regardless of whether or not the statement has +** completed execution. +** +** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op. +** +** The application must finalize every [prepared statement] in order to avoid +** resource leaks. It is a grievous error for the application to try to use +** a prepared statement after it has been finalized. Any use of a prepared +** statement after it has been finalized can result in undefined and +** undesirable behavior such as segfaults and heap corruption. +*/ +SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** +** The sqlite3_reset() function is called to reset a [prepared statement] +** object back to its initial state, ready to be re-executed. +** ^Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +** +** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S +** back to the beginning of its program. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], +** or if [sqlite3_step(S)] has never before been called on S, +** then [sqlite3_reset(S)] returns [SQLITE_OK]. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S indicated an error, then +** [sqlite3_reset(S)] returns an appropriate [error code]. +** +** ^The [sqlite3_reset(S)] interface does not change the values +** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. +*/ +SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** KEYWORDS: {function creation routines} +** KEYWORDS: {application-defined SQL function} +** KEYWORDS: {application-defined SQL functions} +** +** ^These functions (collectively known as "function creation routines") +** are used to add SQL functions or aggregates or to redefine the behavior +** of existing SQL functions or aggregates. The only differences between +** these routines are the text encoding expected for +** the second parameter (the name of the function being created) +** and the presence or absence of a destructor callback for +** the application data pointer. +** +** ^The first parameter is the [database connection] to which the SQL +** function is to be added. ^If an application uses more than one database +** connection then application-defined SQL functions must be added +** to each database connection separately. +** +** ^The second parameter is the name of the SQL function to be created or +** redefined. ^The length of the name is limited to 255 bytes in a UTF-8 +** representation, exclusive of the zero-terminator. ^Note that the name +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. +** ^Any attempt to create a function with a longer name +** will result in [SQLITE_MISUSE] being returned. +** +** ^The third parameter (nArg) +** is the number of arguments that the SQL function or +** aggregate takes. ^If this parameter is -1, then the SQL function or +** aggregate may take any number of arguments between 0 and the limit +** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third +** parameter is less than -1 or greater than 127 then the behavior is +** undefined. +** +** ^The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. Every SQL function implementation must be able to work +** with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** more efficient with one encoding than another. ^An application may +** invoke sqlite3_create_function() or sqlite3_create_function16() multiple +** times with the same function but with different values of eTextRep. +** ^When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** If there is only a single implementation which does not care what text +** encoding is used, then the fourth argument should be [SQLITE_ANY]. +** +** ^(The fifth parameter is an arbitrary pointer. The implementation of the +** function can gain access to this pointer using [sqlite3_user_data()].)^ +** +** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL function or +** aggregate. ^A scalar SQL function requires an implementation of the xFunc +** callback only; NULL pointers must be passed as the xStep and xFinal +** parameters. ^An aggregate SQL function requires an implementation of xStep +** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing +** SQL function or aggregate, pass NULL pointers for all three function +** callbacks. +** +** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, +** then it is destructor for the application data pointer. +** The destructor is invoked when the function is deleted, either by being +** overloaded or when the database connection closes.)^ +** ^The destructor is also invoked if the call to +** sqlite3_create_function_v2() fails. +** ^When the destructor callback of the tenth parameter is invoked, it +** is passed a single argument which is a copy of the application data +** pointer which was the fifth parameter to sqlite3_create_function_v2(). +** +** ^It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing preferred text encodings. ^SQLite will use +** the implementation that most closely matches the way in which the +** SQL function is used. ^A function implementation with a non-negative +** nArg parameter is a better match than a function implementation with +** a negative nArg. ^A function where the preferred text encoding +** matches the database encoding is a better +** match than a function where the encoding is different. +** ^A function where the encoding difference is between UTF16le and UTF16be +** is a closer match than a function where the encoding difference is +** between UTF8 and UTF16. +** +** ^Built-in functions may be overloaded by new application-defined functions. +** +** ^An application-defined function is permitted to call other +** SQLite interfaces. However, such calls must not +** close the database connection nor finalize or reset the prepared +** statement in which the function is running. +*/ +SQLITE_API int sqlite3_create_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 +#define SQLITE_UTF16LE 2 +#define SQLITE_UTF16BE 3 +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Deprecated Functions +** DEPRECATED +** +** These functions are [deprecated]. In order to maintain +** backwards compatibility with older code, these functions continue +** to be supported. However, new applications should avoid +** the use of these functions. To help encourage people to avoid +** using these functions, we are not going to tell you what they do. +*/ +#ifndef SQLITE_OMIT_DEPRECATED +SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void); +SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); +SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); +#endif + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 3rd parameter to these callbacks is an array of pointers to +** [protected sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work only with [protected sqlite3_value] objects. +** Any attempt to use these routines on an [unprotected sqlite3_value] +** object results in undefined behavior. +** +** ^These routines work just like the corresponding [column access functions] +** except that these routines take a single [protected sqlite3_value] object +** pointer instead of a [sqlite3_stmt*] pointer and an integer column number. +** +** ^The sqlite3_value_text16() interface extracts a UTF-16 string +** in the native byte-order of the host machine. ^The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF-16 strings as big-endian and little-endian respectively. +** +** ^(The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in other +** words, if the value is a string that looks like a number) +** then the conversion is performed. Otherwise no conversion occurs. +** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ +** +** Please pay particular attention to the fact that the pointer returned +** from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the [sqlite3_value*] parameters. +*/ +SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); +SQLITE_API double sqlite3_value_double(sqlite3_value*); +SQLITE_API int sqlite3_value_int(sqlite3_value*); +SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int sqlite3_value_type(sqlite3_value*); +SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** +** Implementations of aggregate SQL functions use this +** routine to allocate memory for storing their state. +** +** ^The first time the sqlite3_aggregate_context(C,N) routine is called +** for a particular aggregate function, SQLite +** allocates N of memory, zeroes out that memory, and returns a pointer +** to the new memory. ^On second and subsequent calls to +** sqlite3_aggregate_context() for the same aggregate function instance, +** the same buffer is returned. Sqlite3_aggregate_context() is normally +** called once for each invocation of the xStep callback and then one +** last time when the xFinal callback is invoked. ^(When no rows match +** an aggregate query, the xStep() callback of the aggregate function +** implementation is never called and xFinal() is called exactly once. +** In those cases, sqlite3_aggregate_context() might be called for the +** first time from within xFinal().)^ +** +** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer if N is +** less than or equal to zero or if a memory allocate error occurs. +** +** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is +** determined by the N parameter on first successful call. Changing the +** value of N in subsequent call to sqlite3_aggregate_context() within +** the same aggregate function instance will not resize the memory +** allocation.)^ +** +** ^SQLite automatically frees the memory allocated by +** sqlite3_aggregate_context() when the aggregate query concludes. +** +** The first parameter must be a copy of the +** [sqlite3_context | SQL function context] that is the first parameter +** to the xStep or xFinal callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** +** ^The sqlite3_user_data() interface returns a copy of +** the pointer that was the pUserData parameter (the 5th parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +** +** This routine must be called from the same thread in which +** the application-defined function is running. +*/ +SQLITE_API void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Database Connection For Functions +** +** ^The sqlite3_context_db_handle() interface returns a copy of +** the pointer to the [database connection] (the 1st parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +*/ +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** +** The following two functions may be used by scalar SQL functions to +** associate metadata with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated metadata may be preserved. This may +** be used, for example, to add a regular-expression matching scalar +** function. The compiled version of the regular expression is stored as +** metadata associated with the SQL value passed as the regular expression +** pattern. The compiled regular expression can be reused on multiple +** invocations of the same function so that the original pattern string +** does not need to be recompiled on each invocation. +** +** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata +** associated by the sqlite3_set_auxdata() function with the Nth argument +** value to the application-defined function. ^If no metadata has been ever +** been set for the Nth argument of the function, or if the corresponding +** function parameter has changed since the meta-data was set, +** then sqlite3_get_auxdata() returns a NULL pointer. +** +** ^The sqlite3_set_auxdata() interface saves the metadata +** pointed to by its 3rd parameter as the metadata for the N-th +** argument of the application-defined function. Subsequent +** calls to sqlite3_get_auxdata() might return this data, if it has +** not been destroyed. +** ^If it is not NULL, SQLite will invoke the destructor +** function given by the 4th parameter to sqlite3_set_auxdata() on +** the metadata when the corresponding function parameter changes +** or when the SQL statement completes, whichever comes first. +** +** SQLite is free to call the destructor and drop metadata on any +** parameter of any function at any time. ^The only guarantee is that +** the destructor will be called before the metadata is dropped. +** +** ^(In practice, metadata is preserved between function calls for +** expressions that are constant at compile time. This includes literal +** values and [parameters].)^ +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); +SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special values for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. ^If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. ^The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the [parameter binding] family of +** functions used to bind values to host parameters in prepared statements. +** Refer to the [SQL parameter] documentation for additional information. +** +** ^The sqlite3_result_blob() interface sets the result from +** an application-defined function to be the BLOB whose content is pointed +** to by the second parameter and which is N bytes long where N is the +** third parameter. +** +** ^The sqlite3_result_zeroblob() interfaces set the result of +** the application-defined function to be a BLOB containing all zero +** bytes and N bytes in size, where N is the value of the 2nd parameter. +** +** ^The sqlite3_result_double() interface sets the result from +** an application-defined function to be a floating point value specified +** by its 2nd argument. +** +** ^The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. +** ^SQLite uses the string pointed to by the +** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() +** as the text of an error message. ^SQLite interprets the error +** message string from sqlite3_result_error() as UTF-8. ^SQLite +** interprets the string from sqlite3_result_error16() as UTF-16 in native +** byte order. ^If the third parameter to sqlite3_result_error() +** or sqlite3_result_error16() is negative then SQLite takes as the error +** message all text up through the first zero character. +** ^If the third parameter to sqlite3_result_error() or +** sqlite3_result_error16() is non-negative then SQLite takes that many +** bytes (not characters) from the 2nd parameter as the error message. +** ^The sqlite3_result_error() and sqlite3_result_error16() +** routines make a private copy of the error message text before +** they return. Hence, the calling function can deallocate or +** modify the text after they return without harm. +** ^The sqlite3_result_error_code() function changes the error code +** returned by SQLite as a result of an error in a function. ^By default, +** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() +** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. +** +** ^The sqlite3_result_toobig() interface causes SQLite to throw an error +** indicating that a string or BLOB is too long to represent. +** +** ^The sqlite3_result_nomem() interface causes SQLite to throw an error +** indicating that a memory allocation failed. +** +** ^The sqlite3_result_int() interface sets the return value +** of the application-defined function to be the 32-bit signed integer +** value given in the 2nd argument. +** ^The sqlite3_result_int64() interface sets the return value +** of the application-defined function to be the 64-bit signed integer +** value given in the 2nd argument. +** +** ^The sqlite3_result_null() interface sets the return value +** of the application-defined function to be NULL. +** +** ^The sqlite3_result_text(), sqlite3_result_text16(), +** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces +** set the return value of the application-defined function to be +** a text string which is represented as UTF-8, UTF-16 native byte order, +** UTF-16 little endian, or UTF-16 big endian, respectively. +** ^SQLite takes the text result from the application from +** the 2nd parameter of the sqlite3_result_text* interfaces. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is negative, then SQLite takes result text from the 2nd parameter +** through the first zero character. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is non-negative, then as many bytes (not characters) of the text +** pointed to by the 2nd parameter are taken as the application-defined +** function result. If the 3rd parameter is non-negative, then it +** must be the byte offset into the string where the NUL terminator would +** appear if the string where NUL terminated. If any NUL characters occur +** in the string at a byte offset that is less than the value of the 3rd +** parameter, then the resulting string will contain embedded NULs and the +** result of expressions operating on strings with embedded NULs is undefined. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that +** function as the destructor on the text or BLOB result when it has +** finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces or to +** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite +** assumes that the text or BLOB result is in constant space and does not +** copy the content of the parameter nor call a destructor on the content +** when it has finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT +** then SQLite makes a copy of the result into space obtained from +** from [sqlite3_malloc()] before it returns. +** +** ^The sqlite3_result_value() interface sets the result of +** the application-defined function to be a copy the +** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The +** sqlite3_result_value() interface makes a copy of the [sqlite3_value] +** so that the [sqlite3_value] specified in the parameter may change or +** be deallocated after sqlite3_result_value() returns without harm. +** ^A [protected sqlite3_value] object may always be used where an +** [unprotected sqlite3_value] object is required, so either +** kind of [sqlite3_value] object can be used with this interface. +** +** If these routines are called from within the different thread +** than the one containing the application-defined function that received +** the [sqlite3_context] pointer, the results are undefined. +*/ +SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_double(sqlite3_context*, double); +SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); +SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); +SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); +SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +SQLITE_API void sqlite3_result_null(sqlite3_context*); +SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** +** ^These functions add, remove, or modify a [collation] associated +** with the [database connection] specified as the first argument. +** +** ^The name of the collation is a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string in native byte order for sqlite3_create_collation16(). +** ^Collation names that compare equal according to [sqlite3_strnicmp()] are +** considered to be the same name. +** +** ^(The third argument (eTextRep) must be one of the constants: +**
    +**
  • [SQLITE_UTF8], +**
  • [SQLITE_UTF16LE], +**
  • [SQLITE_UTF16BE], +**
  • [SQLITE_UTF16], or +**
  • [SQLITE_UTF16_ALIGNED]. +**
)^ +** ^The eTextRep argument determines the encoding of strings passed +** to the collating function callback, xCallback. +** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep +** force strings to be UTF16 with native byte order. +** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin +** on an even byte address. +** +** ^The fourth argument, pArg, is an application data pointer that is passed +** through as the first argument to the collating function callback. +** +** ^The fifth argument, xCallback, is a pointer to the collating function. +** ^Multiple collating functions can be registered using the same name but +** with different eTextRep parameters and SQLite will use whichever +** function requires the least amount of data transformation. +** ^If the xCallback argument is NULL then the collating function is +** deleted. ^When all collating functions having the same name are deleted, +** that collation is no longer usable. +** +** ^The collating function callback is invoked with a copy of the pArg +** application data pointer and with two strings in the encoding specified +** by the eTextRep argument. The collating function must return an +** integer that is negative, zero, or positive +** if the first string is less than, equal to, or greater than the second, +** respectively. A collating function must always return the same answer +** given the same inputs. If two or more collating functions are registered +** to the same collation name (using different eTextRep values) then all +** must give an equivalent answer when invoked with equivalent strings. +** The collating function must obey the following properties for all +** strings A, B, and C: +** +**
    +**
  1. If A==B then B==A. +**
  2. If A==B and B==C then A==C. +**
  3. If A<B THEN B>A. +**
  4. If A<B and B<C then A<C. +**
+** +** If a collating function fails any of the above constraints and that +** collating function is registered and used, then the behavior of SQLite +** is undefined. +** +** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** with the addition that the xDestroy callback is invoked on pArg when +** the collating function is deleted. +** ^Collating functions are deleted when they are overridden by later +** calls to the collation creation functions or when the +** [database connection] is closed using [sqlite3_close()]. +** +** ^The xDestroy callback is not called if the +** sqlite3_create_collation_v2() function fails. Applications that invoke +** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should +** check the return code and dispose of the application data pointer +** themselves rather than expecting SQLite to deal with it for them. +** This is different from every other SQLite interface. The inconsistency +** is unfortunate but cannot be changed without breaking backwards +** compatibility. +** +** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. +*/ +SQLITE_API int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); +SQLITE_API int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +SQLITE_API int sqlite3_create_collation16( + sqlite3*, + const void *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: Collation Needed Callbacks +** +** ^To avoid having to register all collation sequences before a database +** can be used, a single callback function may be registered with the +** [database connection] to be invoked whenever an undefined collation +** sequence is required. +** +** ^If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. ^If sqlite3_collation_needed16() is used, +** the names are passed as UTF-16 in machine native byte order. +** ^A call to either function replaces the existing collation-needed callback. +** +** ^(When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE], indicating the most desirable form of the collation +** sequence function required. The fourth parameter is the name of the +** required collation sequence.)^ +** +** The callback function should register the desired collation using +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +SQLITE_API int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +SQLITE_API int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +#ifdef SQLITE_HAS_CODEC +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +/* +** Specify the activation key for a SEE database. Unless +** activated, none of the SEE routines will work. +*/ +SQLITE_API void sqlite3_activate_see( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +#ifdef SQLITE_ENABLE_CEROD +/* +** Specify the activation key for a CEROD database. Unless +** activated, none of the CEROD routines will work. +*/ +SQLITE_API void sqlite3_activate_cerod( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** The sqlite3_sleep() function causes the current thread to suspend execution +** for at least a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** ^SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. If the xSleep() method +** of the default VFS is not implemented correctly, or not implemented at +** all, then the behavior of sqlite3_sleep() may deviate from the description +** in the previous paragraphs. +*/ +SQLITE_API int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** ^(If this global variable is made to point to a string which is +** the name of a folder (a.k.a. directory), then all temporary files +** created by SQLite when using a built-in [sqlite3_vfs | VFS] +** will be placed in that directory.)^ ^If this variable +** is a NULL pointer, then SQLite performs a search for an appropriate +** temporary file directory. +** +** It is not safe to read or modify this variable in more than one +** thread at a time. It is not safe to read or modify this variable +** if a [database connection] is being used at the same time in a separate +** thread. +** It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been called and that this variable remain unchanged +** thereafter. +** +** ^The [temp_store_directory pragma] may modify this variable and cause +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, +** the [temp_store_directory pragma] always assumes that any string +** that this variable points to is held in memory obtained from +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. +** Hence, if this variable is modified directly, either it should be +** made NULL or made to point to memory obtained from [sqlite3_malloc] +** or else the use of the [temp_store_directory pragma] should be avoided. +*/ +SQLITE_API char *sqlite3_temp_directory; + +/* +** CAPI3REF: Test For Auto-Commit Mode +** KEYWORDS: {autocommit mode} +** +** ^The sqlite3_get_autocommit() interface returns non-zero or +** zero if the given database connection is or is not in autocommit mode, +** respectively. ^Autocommit mode is on by default. +** ^Autocommit mode is disabled by a [BEGIN] statement. +** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK]. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out whether SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +SQLITE_API int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Of A Prepared Statement +** +** ^The sqlite3_db_handle interface returns the [database connection] handle +** to which a [prepared statement] belongs. ^The [database connection] +** returned by sqlite3_db_handle is the same [database connection] +** that was the first argument +** to the [sqlite3_prepare_v2()] call (or its variants) that was used to +** create the statement in the first place. +*/ +SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + +/* +** CAPI3REF: Find the next prepared statement +** +** ^This interface returns a pointer to the next [prepared statement] after +** pStmt associated with the [database connection] pDb. ^If pStmt is NULL +** then this interface returns a pointer to the first prepared statement +** associated with the database connection pDb. ^If no prepared statement +** satisfies the conditions of this routine, it returns NULL. +** +** The [database connection] pointer D in a call to +** [sqlite3_next_stmt(D,S)] must refer to an open database +** connection and in particular must not be a NULL pointer. +*/ +SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** +** ^The sqlite3_commit_hook() interface registers a callback +** function to be invoked whenever a transaction is [COMMIT | committed]. +** ^Any callback set by a previous call to sqlite3_commit_hook() +** for the same database connection is overridden. +** ^The sqlite3_rollback_hook() interface registers a callback +** function to be invoked whenever a transaction is [ROLLBACK | rolled back]. +** ^Any callback set by a previous call to sqlite3_rollback_hook() +** for the same database connection is overridden. +** ^The pArg argument is passed through to the callback. +** ^If the callback on a commit hook function returns non-zero, +** then the commit is converted into a rollback. +** +** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions +** return the P argument from the previous call of the same function +** on the same [database connection] D, or NULL for +** the first call for each function on D. +** +** The callback implementation must not do anything that will modify +** the database connection that invoked the callback. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the commit +** or rollback hook in the first place. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^Registering a NULL function disables the callback. +** +** ^When the commit hook callback routine returns zero, the [COMMIT] +** operation is allowed to continue normally. ^If the commit hook +** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK]. +** ^The rollback hook is invoked on a rollback that results from a commit +** hook returning non-zero, just as it would be with any other rollback. +** +** ^For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. +** ^The rollback callback is not invoked if a transaction is +** automatically rolled back because the database connection is closed. +** +** See also the [sqlite3_update_hook()] interface. +*/ +SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** +** ^The sqlite3_update_hook() interface registers a callback function +** with the [database connection] identified by the first argument +** to be invoked whenever a row is updated, inserted or deleted. +** ^Any callback set by a previous call to this function +** for the same database connection is overridden. +** +** ^The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted. +** ^The first argument to the callback is a copy of the third argument +** to sqlite3_update_hook(). +** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], +** or [SQLITE_UPDATE], depending on the operation that caused the callback +** to be invoked. +** ^The third and fourth arguments to the callback contain pointers to the +** database and table name containing the affected row. +** ^The final callback parameter is the [rowid] of the row. +** ^In the case of an update, this is the [rowid] after the update takes place. +** +** ^(The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence).)^ +** +** ^In the current implementation, the update hook +** is not invoked when duplication rows are deleted because of an +** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook +** invoked when rows are deleted using the [truncate optimization]. +** The exceptions defined in this paragraph might change in a future +** release of SQLite. +** +** The update hook implementation must not do anything that will modify +** the database connection that invoked the update hook. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the update hook. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^The sqlite3_update_hook(D,C,P) function +** returns the P argument from the previous call +** on the same [database connection] D, or NULL for +** the first call on D. +** +** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] +** interfaces. +*/ +SQLITE_API void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** KEYWORDS: {shared cache} +** +** ^(This routine enables or disables the sharing of the database cache +** and schema data structures between [database connection | connections] +** to the same database. Sharing is enabled if the argument is true +** and disabled if the argument is false.)^ +** +** ^Cache sharing is enabled and disabled for an entire process. +** This is a change as of SQLite version 3.5.0. In prior versions of SQLite, +** sharing was enabled or disabled for each thread separately. +** +** ^(The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode +** that was in effect at the time they were opened.)^ +** +** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled +** successfully. An [error code] is returned otherwise.)^ +** +** ^Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +** +** See Also: [SQLite Shared-Cache Mode] +*/ +SQLITE_API int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** ^The sqlite3_release_memory() interface attempts to free N bytes +** of heap memory by deallocating non-essential memory allocations +** held by the database library. Memory used to cache database +** pages to improve performance is an example of non-essential memory. +** ^sqlite3_release_memory() returns the number of bytes actually freed, +** which might be more or less than the amount requested. +** ^The sqlite3_release_memory() routine is a no-op returning zero +** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +*/ +SQLITE_API int sqlite3_release_memory(int); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the +** soft limit on the amount of heap memory that may be allocated by SQLite. +** ^SQLite strives to keep heap memory utilization below the soft heap +** limit by reducing the number of pages held in the page cache +** as heap memory usages approaches the limit. +** ^The soft heap limit is "soft" because even though SQLite strives to stay +** below the limit, it will exceed the limit rather than generate +** an [SQLITE_NOMEM] error. In other words, the soft heap limit +** is advisory only. +** +** ^The return value from sqlite3_soft_heap_limit64() is the size of +** the soft heap limit prior to the call. ^If the argument N is negative +** then no change is made to the soft heap limit. Hence, the current +** size of the soft heap limit can be determined by invoking +** sqlite3_soft_heap_limit64() with a negative argument. +** +** ^If the argument N is zero then the soft heap limit is disabled. +** +** ^(The soft heap limit is not enforced in the current implementation +** if one or more of following conditions are true: +** +**
    +**
  • The soft heap limit is set to zero. +**
  • Memory accounting is disabled using a combination of the +** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and +** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. +**
  • An alternative page cache implementation is specified using +** [sqlite3_config]([SQLITE_CONFIG_PCACHE],...). +**
  • The page cache allocates from its own memory pool supplied +** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than +** from the heap. +**
)^ +** +** Beginning with SQLite version 3.7.3, the soft heap limit is enforced +** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT] +** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT], +** the soft heap limit is enforced on every memory allocation. Without +** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced +** when memory is allocated by the page cache. Testing suggests that because +** the page cache is the predominate memory user in SQLite, most +** applications will achieve adequate soft heap limit enforcement without +** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** The circumstances under which SQLite will enforce the soft heap limit may +** changes in future releases of SQLite. +*/ +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); + +/* +** CAPI3REF: Deprecated Soft Heap Limit Interface +** DEPRECATED +** +** This is a deprecated version of the [sqlite3_soft_heap_limit64()] +** interface. This routine is provided for historical compatibility +** only. All new applications should use the +** [sqlite3_soft_heap_limit64()] interface rather than this one. +*/ +SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); + + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** +** ^This routine returns metadata about a specific column of a specific +** database table accessible using the [database connection] handle +** passed as the first function argument. +** +** ^The column is identified by the second, third and fourth parameters to +** this function. ^The second parameter is either the name of the database +** (i.e. "main", "temp", or an attached database) containing the specified +** table or NULL. ^If it is NULL, then all attached databases are searched +** for the table using the same algorithm used by the database engine to +** resolve unqualified table references. +** +** ^The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. Neither of these parameters +** may be NULL. +** +** ^Metadata is returned by writing to the memory locations passed as the 5th +** and subsequent parameters to this function. ^Any of these arguments may be +** NULL, in which case the corresponding element of metadata is omitted. +** +** ^(
+** +**
Parameter Output
Type
Description +** +**
5th const char* Data type +**
6th const char* Name of default collation sequence +**
7th int True if column has a NOT NULL constraint +**
8th int True if column is part of the PRIMARY KEY +**
9th int True if column is [AUTOINCREMENT] +**
+**
)^ +** +** ^The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid only until the next +** call to any SQLite API function. +** +** ^If the specified table is actually a view, an [error code] is returned. +** +** ^If the specified column is "rowid", "oid" or "_rowid_" and an +** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. ^(If there is no +** explicitly declared [INTEGER PRIMARY KEY] column, then the output +** parameters are set as follows: +** +**
+**     data type: "INTEGER"
+**     collation sequence: "BINARY"
+**     not null: 0
+**     primary key: 1
+**     auto increment: 0
+** 
)^ +** +** ^(This function may load one or more schemas from database files. If an +** error occurs during this process, or if the requested table or column +** cannot be found, an [error code] is returned and an error message left +** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^ +** +** ^This API is only available if the library was compiled with the +** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined. +*/ +SQLITE_API int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** +** ^This interface loads an SQLite extension library from the named file. +** +** ^The sqlite3_load_extension() interface attempts to load an +** SQLite extension library contained in the file zFile. +** +** ^The entry point is zProc. +** ^zProc may be 0, in which case the name of the entry point +** defaults to "sqlite3_extension_init". +** ^The sqlite3_load_extension() interface returns +** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** ^If an error occurs and pzErrMsg is not 0, then the +** [sqlite3_load_extension()] interface shall attempt to +** fill *pzErrMsg with error message text stored in memory +** obtained from [sqlite3_malloc()]. The calling function +** should free this memory by calling [sqlite3_free()]. +** +** ^Extension loading must be enabled using +** [sqlite3_enable_load_extension()] prior to calling this API, +** otherwise an error will be returned. +** +** See also the [load_extension() SQL function]. +*/ +SQLITE_API int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** +** ^So as not to open security holes in older applications that are +** unprepared to deal with extension loading, and as a means of disabling +** extension loading while evaluating user-entered SQL, the following API +** is provided to turn the [sqlite3_load_extension()] mechanism on and off. +** +** ^Extension loading is off by default. See ticket #1863. +** ^Call the sqlite3_enable_load_extension() routine with onoff==1 +** to turn extension loading on and call it with onoff==0 to turn +** it back off again. +*/ +SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Automatically Load Statically Linked Extensions +** +** ^This interface causes the xEntryPoint() function to be invoked for +** each new [database connection] that is created. The idea here is that +** xEntryPoint() is the entry point for a statically linked SQLite extension +** that is to be automatically loaded into all new database connections. +** +** ^(Even though the function prototype shows that xEntryPoint() takes +** no arguments and returns void, SQLite invokes xEntryPoint() with three +** arguments and expects and integer result as if the signature of the +** entry point where as follows: +** +**
+**    int xEntryPoint(
+**      sqlite3 *db,
+**      const char **pzErrMsg,
+**      const struct sqlite3_api_routines *pThunk
+**    );
+** 
)^ +** +** If the xEntryPoint routine encounters an error, it should make *pzErrMsg +** point to an appropriate error message (obtained from [sqlite3_mprintf()]) +** and return an appropriate [error code]. ^SQLite ensures that *pzErrMsg +** is NULL before calling the xEntryPoint(). ^SQLite will invoke +** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any +** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()], +** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail. +** +** ^Calling sqlite3_auto_extension(X) with an entry point X that is already +** on the list of automatic extensions is a harmless no-op. ^No entry point +** will be called more than once for each database connection that is opened. +** +** See also: [sqlite3_reset_auto_extension()]. +*/ +SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void)); + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** ^This interface disables all automatic extensions previously +** registered using [sqlite3_auto_extension()]. +*/ +SQLITE_API void sqlite3_reset_auto_extension(void); + +/* +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** CAPI3REF: Virtual Table Object +** KEYWORDS: sqlite3_module {virtual table module} +** +** This structure, sometimes called a "virtual table module", +** defines the implementation of a [virtual tables]. +** This structure consists mostly of methods for the module. +** +** ^A virtual table module is created by filling in a persistent +** instance of this structure and passing a pointer to that instance +** to [sqlite3_create_module()] or [sqlite3_create_module_v2()]. +** ^The registration remains valid until it is replaced by a different +** module or until the [database connection] closes. The content +** of this structure must not change while it is registered with +** any database connection. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); + /* The methods above are in version 1 of the sqlite_module object. Those + ** below are for version 2 and greater. */ + int (*xSavepoint)(sqlite3_vtab *pVTab, int); + int (*xRelease)(sqlite3_vtab *pVTab, int); + int (*xRollbackTo)(sqlite3_vtab *pVTab, int); +}; + +/* +** CAPI3REF: Virtual Table Indexing Information +** KEYWORDS: sqlite3_index_info +** +** The sqlite3_index_info structure and its substructures is used as part +** of the [virtual table] interface to +** pass information into and receive the reply from the [xBestIndex] +** method of a [virtual table module]. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** ^(The aConstraint[] array records WHERE clause constraints of the form: +** +**
column OP expr
+** +** where OP is =, <, <=, >, or >=.)^ ^(The particular operator is +** stored in aConstraint[].op using one of the +** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^ +** ^(The index of the column is stored in +** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot.)^ +** +** ^The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** ^The aConstraint[] array only reports WHERE clause terms that are +** relevant to the particular virtual table being queried. +** +** ^Information about the ORDER BY clause is stored in aOrderBy[]. +** ^Each term of aOrderBy records a column of the ORDER BY clause. +** +** The [xBestIndex] method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. ^If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite.)^ +** +** ^The idxNum and idxPtr values are recorded and passed into the +** [xFilter] method. +** ^[sqlite3_free()] is used to free idxPtr if and only if +** needToFreeIdxPtr is true. +** +** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** ^The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; + +/* +** CAPI3REF: Virtual Table Constraint Operator Codes +** +** These macros defined the allowed values for the +** [sqlite3_index_info].aConstraint[].op field. Each value represents +** an operator that is part of a constraint term in the wHERE clause of +** a query that uses a [virtual table]. +*/ +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** CAPI3REF: Register A Virtual Table Implementation +** +** ^These routines are used to register a new [virtual table module] name. +** ^Module names must be registered before +** creating a new [virtual table] using the module and before using a +** preexisting [virtual table] for the module. +** +** ^The module name is registered on the [database connection] specified +** by the first parameter. ^The name of the module is given by the +** second parameter. ^The third parameter is a pointer to +** the implementation of the [virtual table module]. ^The fourth +** parameter is an arbitrary client data pointer that is passed through +** into the [xCreate] and [xConnect] methods of the virtual table module +** when a new virtual table is be being created or reinitialized. +** +** ^The sqlite3_create_module_v2() interface has a fifth parameter which +** is a pointer to a destructor for the pClientData. ^SQLite will +** invoke the destructor function (if it is not NULL) when SQLite +** no longer needs the pClientData pointer. ^The destructor will also +** be invoked if the call to sqlite3_create_module_v2() fails. +** ^The sqlite3_create_module() +** interface is equivalent to sqlite3_create_module_v2() with a NULL +** destructor. +*/ +SQLITE_API int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData /* Client data for xCreate/xConnect */ +); +SQLITE_API int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** CAPI3REF: Virtual Table Instance Object +** KEYWORDS: sqlite3_vtab +** +** Every [virtual table module] implementation uses a subclass +** of this object to describe a particular instance +** of the [virtual table]. Each subclass will +** be tailored to the specific needs of the module implementation. +** The purpose of this superclass is to define certain fields that are +** common to all module implementations. +** +** ^Virtual tables methods can set an error message by assigning a +** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should +** take care that any prior string is freed by a call to [sqlite3_free()] +** prior to assigning a new string to zErrMsg. ^After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* NO LONGER USED */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Virtual Table Cursor Object +** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor} +** +** Every [virtual table module] implementation uses a subclass of the +** following structure to describe cursors that point into the +** [virtual table] and are used +** to loop through the virtual table. Cursors are created using the +** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed +** by the [sqlite3_module.xClose | xClose] method. Cursors are used +** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods +** of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Declare The Schema Of A Virtual Table +** +** ^The [xCreate] and [xConnect] methods of a +** [virtual table module] call this interface +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); + +/* +** CAPI3REF: Overload A Function For A Virtual Table +** +** ^(Virtual tables can provide alternative implementations of functions +** using the [xFindFunction] method of the [virtual table module]. +** But global versions of those functions +** must exist in order to be overloaded.)^ +** +** ^(This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created.)^ ^The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a placeholder function that can be overloaded +** by a [virtual table]. +*/ +SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** KEYWORDS: {BLOB handle} {BLOB handles} +** +** An instance of this object represents an open BLOB on which +** [sqlite3_blob_open | incremental BLOB I/O] can be performed. +** ^Objects of this type are created by [sqlite3_blob_open()] +** and destroyed by [sqlite3_blob_close()]. +** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the BLOB. +** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** +** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located +** in row iRow, column zColumn, table zTable in database zDb; +** in other words, the same BLOB that would be selected by: +** +**
+**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
+** 
)^ +** +** ^If the flags parameter is non-zero, then the BLOB is opened for read +** and write access. ^If it is zero, the BLOB is opened for read access. +** ^It is not possible to open a column that is part of an index or primary +** key for writing. ^If [foreign key constraints] are enabled, it is +** not possible to open a column that is part of a [child key] for writing. +** +** ^Note that the database name is not the filename that contains +** the database but rather the symbolic name of the database that +** appears after the AS keyword when the database is connected using [ATTACH]. +** ^For the main database file, the database name is "main". +** ^For TEMP tables, the database name is "temp". +** +** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is written +** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set +** to be a null pointer.)^ +** ^This function sets the [database connection] error code and message +** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related +** functions. ^Note that the *ppBlob variable is always initialized in a +** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob +** regardless of the success or failure of this routine. +** +** ^(If the row that a BLOB handle points to is modified by an +** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects +** then the BLOB handle is marked as "expired". +** This is true if any column of the row is changed, even a column +** other than the one the BLOB handle is open on.)^ +** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for +** an expired BLOB handle fail with a return code of [SQLITE_ABORT]. +** ^(Changes written into a BLOB prior to the BLOB expiring are not +** rolled back by the expiration of the BLOB. Such changes will eventually +** commit if the transaction continues to completion.)^ +** +** ^Use the [sqlite3_blob_bytes()] interface to determine the size of +** the opened blob. ^The size of a blob may not be changed by this +** interface. Use the [UPDATE] SQL command to change the size of a +** blob. +** +** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces +** and the built-in [zeroblob] SQL function can be used, if desired, +** to create an empty, zero-filled blob in which to read or write using +** this interface. +** +** To avoid a resource leak, every open [BLOB handle] should eventually +** be released by a call to [sqlite3_blob_close()]. +*/ +SQLITE_API int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Move a BLOB Handle to a New Row +** +** ^This function is used to move an existing blob handle so that it points +** to a different row of the same database table. ^The new row is identified +** by the rowid value passed as the second argument. Only the row can be +** changed. ^The database, table and column on which the blob handle is open +** remain the same. Moving an existing blob handle to a new row can be +** faster than closing the existing handle and opening a new one. +** +** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - +** it must exist and there must be either a blob or text value stored in +** the nominated column.)^ ^If the new row is not present in the table, or if +** it does not contain a blob or text value, or if another error occurs, an +** SQLite error code is returned and the blob handle is considered aborted. +** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or +** [sqlite3_blob_reopen()] on an aborted blob handle immediately return +** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle +** always returns zero. +** +** ^This function sets the database handle error code and message. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); + +/* +** CAPI3REF: Close A BLOB Handle +** +** ^Closes an open [BLOB handle]. +** +** ^Closing a BLOB shall cause the current transaction to commit +** if there are no other BLOBs, no pending prepared statements, and the +** database connection is in [autocommit mode]. +** ^If any writes were made to the BLOB, they might be held in cache +** until the close operation if they will fit. +** +** ^(Closing the BLOB often forces the changes +** out to disk and so if any I/O errors occur, they will likely occur +** at the time when the BLOB is closed. Any errors that occur during +** closing are reported as a non-zero return value.)^ +** +** ^(The BLOB is closed unconditionally. Even if this routine returns +** an error code, the BLOB is still closed.)^ +** +** ^Calling this routine with a null pointer (such as would be returned +** by a failed call to [sqlite3_blob_open()]) is a harmless no-op. +*/ +SQLITE_API int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** +** ^Returns the size in bytes of the BLOB accessible via the +** successfully opened [BLOB handle] in its only argument. ^The +** incremental blob I/O routines can only read or overwriting existing +** blob content; they cannot change the size of a blob. +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +*/ +SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** +** ^(This function is used to read data from an open [BLOB handle] into a +** caller-supplied buffer. N bytes of data are copied into buffer Z +** from the open BLOB, starting at offset iOffset.)^ +** +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is +** less than zero, [SQLITE_ERROR] is returned and no data is read. +** ^The size of the blob (and hence the maximum value of N+iOffset) +** can be determined using the [sqlite3_blob_bytes()] interface. +** +** ^An attempt to read from an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. +** +** ^(On success, sqlite3_blob_read() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_write()]. +*/ +SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** +** ^This function is used to write data into an open [BLOB handle] from a +** caller-supplied buffer. ^N bytes of data are copied from the buffer Z +** into the open BLOB, starting at offset iOffset. +** +** ^If the [BLOB handle] passed as the first argument was not opened for +** writing (the flags parameter to [sqlite3_blob_open()] was zero), +** this function returns [SQLITE_READONLY]. +** +** ^This function may only modify the contents of the BLOB; it is +** not possible to increase the size of a BLOB using this API. +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is written. ^If N is +** less than zero [SQLITE_ERROR] is returned and no data is written. +** The size of the BLOB (and hence the maximum value of N+iOffset) +** can be determined using the [sqlite3_blob_bytes()] interface. +** +** ^An attempt to write to an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred +** before the [BLOB handle] expired are not rolled back by the +** expiration of the handle, though of course those changes might +** have been overwritten by the statement that expired the BLOB handle +** or by other independent statements. +** +** ^(On success, sqlite3_blob_write() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_read()]. +*/ +SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most SQLite builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name. +** ^Names are case sensitive. +** ^Names are zero-terminated UTF-8 strings. +** ^If there is no match, a NULL pointer is returned. +** ^If zVfsName is NULL then the default VFS is returned. +** +** ^New VFSes are registered with sqlite3_vfs_register(). +** ^Each new VFS becomes the default VFS if the makeDflt flag is set. +** ^The same VFS can be registered multiple times without injury. +** ^To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. +** ^(If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary.)^ +*/ +SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. ^(The following +** implementations are available in the SQLite core: +** +**
    +**
  • SQLITE_MUTEX_OS2 +**
  • SQLITE_MUTEX_PTHREAD +**
  • SQLITE_MUTEX_W32 +**
  • SQLITE_MUTEX_NOOP +**
)^ +** +** ^The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. ^The SQLITE_MUTEX_OS2, +** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations +** are appropriate for use on OS/2, Unix, and Windows. +** +** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. In this case the +** application must supply a custom mutex implementation using the +** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function +** before calling sqlite3_initialize() or any other public sqlite3_ +** function that calls sqlite3_initialize().)^ +** +** ^The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. ^If it returns NULL +** that means that a mutex could not be allocated. ^SQLite +** will unwind its stack and return an error. ^(The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +**
    +**
  • SQLITE_MUTEX_FAST +**
  • SQLITE_MUTEX_RECURSIVE +**
  • SQLITE_MUTEX_STATIC_MASTER +**
  • SQLITE_MUTEX_STATIC_MEM +**
  • SQLITE_MUTEX_STATIC_MEM2 +**
  • SQLITE_MUTEX_STATIC_PRNG +**
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_LRU2 +**
)^ +** +** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) +** cause sqlite3_mutex_alloc() to create +** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. ^SQLite will only request a recursive mutex in +** cases where it really needs one. ^If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other +** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return +** a pointer to a static preexisting mutex. ^Six static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. ^But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** ^The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. ^SQLite is careful to deallocate every +** dynamic mutex that it allocates. The dynamic mutexes must not be in +** use when they are deallocated. Attempting to deallocate a static +** mutex results in undefined behavior. ^SQLite never deallocates +** a static mutex. +** +** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. ^If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK] +** upon successful entry. ^(Mutexes created using +** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. +** In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter.)^ ^(If the same thread tries to enter any other +** kind of mutex more than once, the behavior is undefined. +** SQLite will never exhibit +** such behavior in its own use of mutexes.)^ +** +** ^(Some systems (for example, Windows 95) do not support the operation +** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() +** will always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^ +** +** ^The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. ^(The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. SQLite will +** never do either.)^ +** +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or +** sqlite3_mutex_leave() is a NULL pointer, then all three routines +** behave as no-ops. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); +SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Methods Object +** +** An instance of this structure defines the low-level routines +** used to allocate and use mutexes. +** +** Usually, the default mutex implementations provided by SQLite are +** sufficient, however the user has the option of substituting a custom +** implementation for specialized deployments or systems for which SQLite +** does not provide a suitable implementation. In this case, the user +** creates and populates an instance of this structure to pass +** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option. +** Additionally, an instance of this structure can be used as an +** output variable when querying the system for the current mutex +** implementation, using the [SQLITE_CONFIG_GETMUTEX] option. +** +** ^The xMutexInit method defined by this structure is invoked as +** part of system initialization by the sqlite3_initialize() function. +** ^The xMutexInit routine is called by SQLite exactly once for each +** effective call to [sqlite3_initialize()]. +** +** ^The xMutexEnd method defined by this structure is invoked as +** part of system shutdown by the sqlite3_shutdown() function. The +** implementation of this method is expected to release all outstanding +** resources obtained by the mutex methods implementation, especially +** those obtained by the xMutexInit method. ^The xMutexEnd() +** interface is invoked exactly once for each call to [sqlite3_shutdown()]. +** +** ^(The remaining seven methods defined by this structure (xMutexAlloc, +** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and +** xMutexNotheld) implement the following interfaces (respectively): +** +**
    +**
  • [sqlite3_mutex_alloc()]
  • +**
  • [sqlite3_mutex_free()]
  • +**
  • [sqlite3_mutex_enter()]
  • +**
  • [sqlite3_mutex_try()]
  • +**
  • [sqlite3_mutex_leave()]
  • +**
  • [sqlite3_mutex_held()]
  • +**
  • [sqlite3_mutex_notheld()]
  • +**
)^ +** +** The only difference is that the public sqlite3_XXX functions enumerated +** above silently ignore any invocations that pass a NULL pointer instead +** of a valid mutex handle. The implementations of the methods defined +** by this structure are not required to handle this case, the results +** of passing a NULL pointer instead of a valid mutex handle are undefined +** (i.e. it is acceptable to provide an implementation that segfaults if +** it is passed a NULL pointer). +** +** The xMutexInit() method must be threadsafe. ^It must be harmless to +** invoke xMutexInit() multiple times within the same process and without +** intervening calls to xMutexEnd(). Second and subsequent calls to +** xMutexInit() must be no-ops. +** +** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] +** and its associates). ^Similarly, xMutexAlloc() must not use SQLite memory +** allocation for a static mutex. ^However xMutexAlloc() may use SQLite +** memory allocation for a fast or recursive mutex. +** +** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is +** called, but only if the prior call to xMutexInit returned SQLITE_OK. +** If xMutexInit fails in any way, it is expected to clean up after itself +** prior to returning. +*/ +typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; +struct sqlite3_mutex_methods { + int (*xMutexInit)(void); + int (*xMutexEnd)(void); + sqlite3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlite3_mutex *); + void (*xMutexEnter)(sqlite3_mutex *); + int (*xMutexTry)(sqlite3_mutex *); + void (*xMutexLeave)(sqlite3_mutex *); + int (*xMutexHeld)(sqlite3_mutex *); + int (*xMutexNotheld)(sqlite3_mutex *); +}; + +/* +** CAPI3REF: Mutex Verification Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. ^The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. ^The SQLite core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. ^External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** ^These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** ^The implementation is not required to provided versions of these +** routines that actually work. If the implementation does not provide working +** versions of these routines, it should at least provide stubs that always +** return true so that one does not get spurious assertion failures. +** +** ^If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. ^The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +#ifndef NDEBUG +SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); +#endif + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +** +** The set of static mutexes may change from one SQLite release to the +** next. Applications that override the built-in mutex logic must be +** prepared to accommodate additional static mutexes. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ +#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ + +/* +** CAPI3REF: Retrieve the mutex for a database connection +** +** ^This interface returns a pointer the [sqlite3_mutex] object that +** serializes access to the [database connection] given in the argument +** when the [threading mode] is Serialized. +** ^If the [threading mode] is Single-thread or Multi-thread then this +** routine returns a NULL pointer. +*/ +SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); + +/* +** CAPI3REF: Low-Level Control Of Database Files +** +** ^The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. ^The +** name of the database is "main" for the main database or "temp" for the +** TEMP database, or the name that appears after the AS keyword for +** databases that are added using the [ATTACH] SQL command. +** ^A NULL pointer can be used in place of "main" to refer to the +** main database file. +** ^The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. ^The return value of the xFileControl +** method becomes the return value of this routine. +** +** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes +** a pointer to the underlying [sqlite3_file] object to be written into +** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER +** case is a short-circuit path which does not actually invoke the +** underlying sqlite3_io_methods.xFileControl method. +** +** ^If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. ^This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** CAPI3REF: Testing Interface +** +** ^The sqlite3_test_control() interface is used to read out internal +** state of SQLite and to inject faults into SQLite for testing +** purposes. ^The first parameter is an operation code that determines +** the number, meaning, and operation of all subsequent parameters. +** +** This interface is not for use by applications. It exists solely +** for verifying the correct operation of the SQLite library. Depending +** on how the SQLite library is compiled, this interface might not exist. +** +** The details of the operation codes, their meanings, the parameters +** they take, and what they do are all subject to change without notice. +** Unlike most of the SQLite API, this function is not guaranteed to +** operate consistently from one release to the next. +*/ +SQLITE_API int sqlite3_test_control(int op, ...); + +/* +** CAPI3REF: Testing Interface Operation Codes +** +** These constants are the valid operation code parameters used +** as the first argument to [sqlite3_test_control()]. +** +** These parameters and their meanings are subject to change +** without notice. These values are for testing purposes only. +** Applications should not use any of these parameters or the +** [sqlite3_test_control()] interface. +*/ +#define SQLITE_TESTCTRL_FIRST 5 +#define SQLITE_TESTCTRL_PRNG_SAVE 5 +#define SQLITE_TESTCTRL_PRNG_RESTORE 6 +#define SQLITE_TESTCTRL_PRNG_RESET 7 +#define SQLITE_TESTCTRL_BITVEC_TEST 8 +#define SQLITE_TESTCTRL_FAULT_INSTALL 9 +#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 +#define SQLITE_TESTCTRL_PENDING_BYTE 11 +#define SQLITE_TESTCTRL_ASSERT 12 +#define SQLITE_TESTCTRL_ALWAYS 13 +#define SQLITE_TESTCTRL_RESERVE 14 +#define SQLITE_TESTCTRL_OPTIMIZATIONS 15 +#define SQLITE_TESTCTRL_ISKEYWORD 16 +#define SQLITE_TESTCTRL_PGHDRSZ 17 +#define SQLITE_TESTCTRL_SCRATCHMALLOC 18 +#define SQLITE_TESTCTRL_LOCALTIME_FAULT 19 +#define SQLITE_TESTCTRL_LAST 19 + +/* +** CAPI3REF: SQLite Runtime Status +** +** ^This interface is used to retrieve runtime status information +** about the performance of SQLite, and optionally to reset various +** highwater marks. ^The first argument is an integer code for +** the specific parameter to measure. ^(Recognized integer codes +** are of the form [status parameters | SQLITE_STATUS_...].)^ +** ^The current value of the parameter is returned into *pCurrent. +** ^The highest recorded value is returned in *pHighwater. ^If the +** resetFlag is true, then the highest record value is reset after +** *pHighwater is written. ^(Some parameters do not record the highest +** value. For those parameters +** nothing is written into *pHighwater and the resetFlag is ignored.)^ +** ^(Other parameters record only the highwater mark and not the current +** value. For these latter parameters nothing is written into *pCurrent.)^ +** +** ^The sqlite3_status() routine returns SQLITE_OK on success and a +** non-zero [error code] on failure. +** +** This routine is threadsafe but is not atomic. This routine can be +** called while other threads are running the same or different SQLite +** interfaces. However the values returned in *pCurrent and +** *pHighwater reflect the status of SQLite at different points in time +** and it is possible that another thread might change the parameter +** in between the times when *pCurrent and *pHighwater are written. +** +** See also: [sqlite3_db_status()] +*/ +SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); + + +/* +** CAPI3REF: Status Parameters +** KEYWORDS: {status parameters} +** +** These integer constants designate various run-time status parameters +** that can be returned by [sqlite3_status()]. +** +**
+** [[SQLITE_STATUS_MEMORY_USED]] ^(
SQLITE_STATUS_MEMORY_USED
+**
This parameter is the current amount of memory checked out +** using [sqlite3_malloc()], either directly or indirectly. The +** figure includes calls made to [sqlite3_malloc()] by the application +** and internal memory usage by the SQLite library. Scratch memory +** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache +** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in +** this parameter. The amount returned is the sum of the allocation +** sizes as reported by the xSize method in [sqlite3_mem_methods].
)^ +** +** [[SQLITE_STATUS_MALLOC_SIZE]] ^(
SQLITE_STATUS_MALLOC_SIZE
+**
This parameter records the largest memory allocation request +** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their +** internal equivalents). Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
)^ +** +** [[SQLITE_STATUS_MALLOC_COUNT]] ^(
SQLITE_STATUS_MALLOC_COUNT
+**
This parameter records the number of separate memory allocations +** currently checked out.
)^ +** +** [[SQLITE_STATUS_PAGECACHE_USED]] ^(
SQLITE_STATUS_PAGECACHE_USED
+**
This parameter returns the number of pages used out of the +** [pagecache memory allocator] that was configured using +** [SQLITE_CONFIG_PAGECACHE]. The +** value returned is in pages, not in bytes.
)^ +** +** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] +** ^(
SQLITE_STATUS_PAGECACHE_OVERFLOW
+**
This parameter returns the number of bytes of page cache +** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] +** buffer and where forced to overflow to [sqlite3_malloc()]. The +** returned value includes allocations that overflowed because they +** where too large (they were larger than the "sz" parameter to +** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because +** no space was left in the page cache.
)^ +** +** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(
SQLITE_STATUS_PAGECACHE_SIZE
+**
This parameter records the largest memory allocation request +** handed to [pagecache memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
)^ +** +** [[SQLITE_STATUS_SCRATCH_USED]] ^(
SQLITE_STATUS_SCRATCH_USED
+**
This parameter returns the number of allocations used out of the +** [scratch memory allocator] configured using +** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not +** in bytes. Since a single thread may only have one scratch allocation +** outstanding at time, this parameter also reports the number of threads +** using scratch memory at the same time.
)^ +** +** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(
SQLITE_STATUS_SCRATCH_OVERFLOW
+**
This parameter returns the number of bytes of scratch memory +** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] +** buffer and where forced to overflow to [sqlite3_malloc()]. The values +** returned include overflows because the requested allocation was too +** larger (that is, because the requested allocation was larger than the +** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer +** slots were available. +**
)^ +** +** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(
SQLITE_STATUS_SCRATCH_SIZE
+**
This parameter records the largest memory allocation request +** handed to [scratch memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
)^ +** +** [[SQLITE_STATUS_PARSER_STACK]] ^(
SQLITE_STATUS_PARSER_STACK
+**
This parameter records the deepest parser stack. It is only +** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].
)^ +**
+** +** New status parameters may be added from time to time. +*/ +#define SQLITE_STATUS_MEMORY_USED 0 +#define SQLITE_STATUS_PAGECACHE_USED 1 +#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 +#define SQLITE_STATUS_SCRATCH_USED 3 +#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 +#define SQLITE_STATUS_MALLOC_SIZE 5 +#define SQLITE_STATUS_PARSER_STACK 6 +#define SQLITE_STATUS_PAGECACHE_SIZE 7 +#define SQLITE_STATUS_SCRATCH_SIZE 8 +#define SQLITE_STATUS_MALLOC_COUNT 9 + +/* +** CAPI3REF: Database Connection Status +** +** ^This interface is used to retrieve runtime status information +** about a single [database connection]. ^The first argument is the +** database connection object to be interrogated. ^The second argument +** is an integer constant, taken from the set of +** [SQLITE_DBSTATUS options], that +** determines the parameter to interrogate. The set of +** [SQLITE_DBSTATUS options] is likely +** to grow in future releases of SQLite. +** +** ^The current value of the requested parameter is written into *pCur +** and the highest instantaneous value is written into *pHiwtr. ^If +** the resetFlg is true, then the highest instantaneous value is +** reset back down to the current value. +** +** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a +** non-zero [error code] on failure. +** +** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. +*/ +SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); + +/* +** CAPI3REF: Status Parameters for database connections +** KEYWORDS: {SQLITE_DBSTATUS options} +** +** These constants are the available integer "verbs" that can be passed as +** the second argument to the [sqlite3_db_status()] interface. +** +** New verbs may be added in future releases of SQLite. Existing verbs +** might be discontinued. Applications should check the return code from +** [sqlite3_db_status()] to make sure that the call worked. +** The [sqlite3_db_status()] interface will return a non-zero error code +** if a discontinued or unsupported verb is invoked. +** +**
+** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(
SQLITE_DBSTATUS_LOOKASIDE_USED
+**
This parameter returns the number of lookaside memory slots currently +** checked out.
)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
SQLITE_DBSTATUS_LOOKASIDE_HIT
+**
This parameter returns the number malloc attempts that were +** satisfied using lookaside memory. Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] +** ^(
SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
+**
This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to the amount of +** memory requested being larger than the lookaside slot size. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] +** ^(
SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
+**
This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to all lookaside +** memory already being in use. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_CACHE_USED]] ^(
SQLITE_DBSTATUS_CACHE_USED
+**
This parameter returns the approximate number of of bytes of heap +** memory used by all pager caches associated with the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. +** +** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
SQLITE_DBSTATUS_SCHEMA_USED
+**
This parameter returns the approximate number of of bytes of heap +** memory used to store the schema for all databases associated +** with the connection - main, temp, and any [ATTACH]-ed databases.)^ +** ^The full amount of memory used by the schemas is reported, even if the +** schema memory is shared with other database connections due to +** [shared cache mode] being enabled. +** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. +** +** [[SQLITE_DBSTATUS_STMT_USED]] ^(
SQLITE_DBSTATUS_STMT_USED
+**
This parameter returns the approximate number of of bytes of heap +** and lookaside memory used by all prepared statements associated with +** the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. +**
+** +** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(
SQLITE_DBSTATUS_CACHE_HIT
+**
This parameter returns the number of pager cache hits that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT +** is always 0. +**
+** +** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(
SQLITE_DBSTATUS_CACHE_MISS
+**
This parameter returns the number of pager cache misses that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS +** is always 0. +**
+**
+*/ +#define SQLITE_DBSTATUS_LOOKASIDE_USED 0 +#define SQLITE_DBSTATUS_CACHE_USED 1 +#define SQLITE_DBSTATUS_SCHEMA_USED 2 +#define SQLITE_DBSTATUS_STMT_USED 3 +#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 +#define SQLITE_DBSTATUS_CACHE_HIT 7 +#define SQLITE_DBSTATUS_CACHE_MISS 8 +#define SQLITE_DBSTATUS_MAX 8 /* Largest defined DBSTATUS */ + + +/* +** CAPI3REF: Prepared Statement Status +** +** ^(Each prepared statement maintains various +** [SQLITE_STMTSTATUS counters] that measure the number +** of times it has performed specific operations.)^ These counters can +** be used to monitor the performance characteristics of the prepared +** statements. For example, if the number of table steps greatly exceeds +** the number of table searches or result rows, that would tend to indicate +** that the prepared statement is using a full table scan rather than +** an index. +** +** ^(This interface is used to retrieve and reset counter values from +** a [prepared statement]. The first argument is the prepared statement +** object to be interrogated. The second argument +** is an integer code for a specific [SQLITE_STMTSTATUS counter] +** to be interrogated.)^ +** ^The current value of the requested counter is returned. +** ^If the resetFlg is true, then the counter is reset to zero after this +** interface call returns. +** +** See also: [sqlite3_status()] and [sqlite3_db_status()]. +*/ +SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); + +/* +** CAPI3REF: Status Parameters for prepared statements +** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters} +** +** These preprocessor macros define integer codes that name counter +** values associated with the [sqlite3_stmt_status()] interface. +** The meanings of the various counters are as follows: +** +**
+** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]]
SQLITE_STMTSTATUS_FULLSCAN_STEP
+**
^This is the number of times that SQLite has stepped forward in +** a table as part of a full table scan. Large numbers for this counter +** may indicate opportunities for performance improvement through +** careful use of indices.
+** +** [[SQLITE_STMTSTATUS_SORT]]
SQLITE_STMTSTATUS_SORT
+**
^This is the number of sort operations that have occurred. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance through careful use of indices.
+** +** [[SQLITE_STMTSTATUS_AUTOINDEX]]
SQLITE_STMTSTATUS_AUTOINDEX
+**
^This is the number of rows inserted into transient indices that +** were created automatically in order to help joins run faster. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance by adding permanent indices that do not +** need to be reinitialized each time the statement is run.
+**
+*/ +#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 +#define SQLITE_STMTSTATUS_SORT 2 +#define SQLITE_STMTSTATUS_AUTOINDEX 3 + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache type is opaque. It is implemented by +** the pluggable module. The SQLite core has no knowledge of +** its size or internal structure and never deals with the +** sqlite3_pcache object except by holding and passing pointers +** to the object. +** +** See [sqlite3_pcache_methods] for additional information. +*/ +typedef struct sqlite3_pcache sqlite3_pcache; + +/* +** CAPI3REF: Application Defined Page Cache. +** KEYWORDS: {page cache} +** +** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can +** register an alternative page cache implementation by passing in an +** instance of the sqlite3_pcache_methods structure.)^ +** In many applications, most of the heap memory allocated by +** SQLite is used for the page cache. +** By implementing a +** custom page cache using this API, an application can better control +** the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to +** determine exactly which parts of a database file are cached and for +** how long. +** +** The alternative page cache mechanism is an +** extreme measure that is only needed by the most demanding applications. +** The built-in page cache is recommended for most uses. +** +** ^(The contents of the sqlite3_pcache_methods structure are copied to an +** internal buffer by SQLite within the call to [sqlite3_config]. Hence +** the application may discard the parameter after the call to +** [sqlite3_config()] returns.)^ +** +** [[the xInit() page cache method]] +** ^(The xInit() method is called once for each effective +** call to [sqlite3_initialize()])^ +** (usually only once during the lifetime of the process). ^(The xInit() +** method is passed a copy of the sqlite3_pcache_methods.pArg value.)^ +** The intent of the xInit() method is to set up global data structures +** required by the custom page cache implementation. +** ^(If the xInit() method is NULL, then the +** built-in default page cache is used instead of the application defined +** page cache.)^ +** +** [[the xShutdown() page cache method]] +** ^The xShutdown() method is called by [sqlite3_shutdown()]. +** It can be used to clean up +** any outstanding resources before process shutdown, if required. +** ^The xShutdown() method may be NULL. +** +** ^SQLite automatically serializes calls to the xInit method, +** so the xInit method need not be threadsafe. ^The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. All other methods must be threadsafe +** in multithreaded applications. +** +** ^SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +** +** [[the xCreate() page cache methods]] +** ^SQLite invokes the xCreate() method to construct a new cache instance. +** SQLite will typically create one cache instance for each open database file, +** though this is not guaranteed. ^The +** first parameter, szPage, is the size in bytes of the pages that must +** be allocated by the cache. ^szPage will not be a power of two. ^szPage +** will the page size of the database file that is to be cached plus an +** increment (here called "R") of less than 250. SQLite will use the +** extra R bytes on each page to store metadata about the underlying +** database page on disk. The value of R depends +** on the SQLite version, the target platform, and how SQLite was compiled. +** ^(R is constant for a particular build of SQLite. Except, there are two +** distinct values of R when SQLite is compiled with the proprietary +** ZIPVFS extension.)^ ^The second argument to +** xCreate(), bPurgeable, is true if the cache being created will +** be used to cache database pages of a file stored on disk, or +** false if it is used for an in-memory database. The cache implementation +** does not have to do anything special based with the value of bPurgeable; +** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will +** never invoke xUnpin() except to deliberately delete a page. +** ^In other words, calls to xUnpin() on a cache with bPurgeable set to +** false will always have the "discard" flag set to true. +** ^Hence, a cache created with bPurgeable false will +** never contain any unpinned pages. +** +** [[the xCachesize() page cache method]] +** ^(The xCachesize() method may be called at any time by SQLite to set the +** suggested maximum cache-size (number of pages stored by) the cache +** instance passed as the first argument. This is the value configured using +** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable +** parameter, the implementation is not required to do anything with this +** value; it is advisory only. +** +** [[the xPagecount() page cache methods]] +** The xPagecount() method must return the number of pages currently +** stored in the cache, both pinned and unpinned. +** +** [[the xFetch() page cache methods]] +** The xFetch() method locates a page in the cache and returns a pointer to +** the page, or a NULL pointer. +** A "page", in this context, means a buffer of szPage bytes aligned at an +** 8-byte boundary. The page to be fetched is determined by the key. ^The +** minimum key value is 1. After it has been retrieved using xFetch, the page +** is considered to be "pinned". +** +** If the requested page is already in the page cache, then the page cache +** implementation must return a pointer to the page buffer with its content +** intact. If the requested page is not already in the cache, then the +** cache implementation should use the value of the createFlag +** parameter to help it determined what action to take: +** +** +**
createFlag Behaviour when page is not already in cache +**
0 Do not allocate a new page. Return NULL. +**
1 Allocate a new page if it easy and convenient to do so. +** Otherwise return NULL. +**
2 Make every effort to allocate a new page. Only return +** NULL if allocating a new page is effectively impossible. +**
+** +** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite +** will only use a createFlag of 2 after a prior call with a createFlag of 1 +** failed.)^ In between the to xFetch() calls, SQLite may +** attempt to unpin one or more cache pages by spilling the content of +** pinned pages to disk and synching the operating system disk cache. +** +** [[the xUnpin() page cache method]] +** ^xUnpin() is called by SQLite with a pointer to a currently pinned page +** as its second argument. If the third parameter, discard, is non-zero, +** then the page must be evicted from the cache. +** ^If the discard parameter is +** zero, then the page may be discarded or retained at the discretion of +** page cache implementation. ^The page cache implementation +** may choose to evict unpinned pages at any time. +** +** The cache must not perform any reference counting. A single +** call to xUnpin() unpins the page regardless of the number of prior calls +** to xFetch(). +** +** [[the xRekey() page cache methods]] +** The xRekey() method is used to change the key value associated with the +** page passed as the second argument. If the cache +** previously contains an entry associated with newKey, it must be +** discarded. ^Any prior cache entry associated with newKey is guaranteed not +** to be pinned. +** +** When SQLite calls the xTruncate() method, the cache must discard all +** existing cache entries with page numbers (keys) greater than or equal +** to the value of the iLimit parameter passed to xTruncate(). If any +** of these pages are pinned, they are implicitly unpinned, meaning that +** they can be safely discarded. +** +** [[the xDestroy() page cache method]] +** ^The xDestroy() method is used to delete a cache allocated by xCreate(). +** All resources associated with the specified cache should be freed. ^After +** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] +** handle invalid, and will not use it with any other sqlite3_pcache_methods +** functions. +*/ +typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; +struct sqlite3_pcache_methods { + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, void*, int discard); + void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); +}; + +/* +** CAPI3REF: Online Backup Object +** +** The sqlite3_backup object records state information about an ongoing +** online backup operation. ^The sqlite3_backup object is created by +** a call to [sqlite3_backup_init()] and is destroyed by a call to +** [sqlite3_backup_finish()]. +** +** See Also: [Using the SQLite Online Backup API] +*/ +typedef struct sqlite3_backup sqlite3_backup; + +/* +** CAPI3REF: Online Backup API. +** +** The backup API copies the content of one database into another. +** It is useful either for creating backups of databases or +** for copying in-memory databases to or from persistent files. +** +** See Also: [Using the SQLite Online Backup API] +** +** ^SQLite holds a write transaction open on the destination database file +** for the duration of the backup operation. +** ^The source database is read-locked only while it is being read; +** it is not locked continuously for the entire backup operation. +** ^Thus, the backup may be performed on a live source database without +** preventing other database connections from +** reading or writing to the source database while the backup is underway. +** +** ^(To perform a backup operation: +**
    +**
  1. sqlite3_backup_init() is called once to initialize the +** backup, +**
  2. sqlite3_backup_step() is called one or more times to transfer +** the data between the two databases, and finally +**
  3. sqlite3_backup_finish() is called to release all resources +** associated with the backup operation. +**
)^ +** There should be exactly one call to sqlite3_backup_finish() for each +** successful call to sqlite3_backup_init(). +** +** [[sqlite3_backup_init()]] sqlite3_backup_init() +** +** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the +** [database connection] associated with the destination database +** and the database name, respectively. +** ^The database name is "main" for the main database, "temp" for the +** temporary database, or the name specified after the AS keyword in +** an [ATTACH] statement for an attached database. +** ^The S and M arguments passed to +** sqlite3_backup_init(D,N,S,M) identify the [database connection] +** and database name of the source database, respectively. +** ^The source and destination [database connections] (parameters S and D) +** must be different or else sqlite3_backup_init(D,N,S,M) will fail with +** an error. +** +** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is +** returned and an error code and error message are stored in the +** destination [database connection] D. +** ^The error code and message for the failed call to sqlite3_backup_init() +** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or +** [sqlite3_errmsg16()] functions. +** ^A successful call to sqlite3_backup_init() returns a pointer to an +** [sqlite3_backup] object. +** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and +** sqlite3_backup_finish() functions to perform the specified backup +** operation. +** +** [[sqlite3_backup_step()]] sqlite3_backup_step() +** +** ^Function sqlite3_backup_step(B,N) will copy up to N pages between +** the source and destination databases specified by [sqlite3_backup] object B. +** ^If N is negative, all remaining source pages are copied. +** ^If sqlite3_backup_step(B,N) successfully copies N pages and there +** are still more pages to be copied, then the function returns [SQLITE_OK]. +** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages +** from source to destination, then it returns [SQLITE_DONE]. +** ^If an error occurs while running sqlite3_backup_step(B,N), +** then an [error code] is returned. ^As well as [SQLITE_OK] and +** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY], +** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code. +** +** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if +**
    +**
  1. the destination database was opened read-only, or +**
  2. the destination database is using write-ahead-log journaling +** and the destination and source page sizes differ, or +**
  3. the destination database is an in-memory database and the +** destination and source page sizes differ. +**
)^ +** +** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then +** the [sqlite3_busy_handler | busy-handler function] +** is invoked (if one is specified). ^If the +** busy-handler returns non-zero before the lock is available, then +** [SQLITE_BUSY] is returned to the caller. ^In this case the call to +** sqlite3_backup_step() can be retried later. ^If the source +** [database connection] +** is being used to write to the source database when sqlite3_backup_step() +** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this +** case the call to sqlite3_backup_step() can be retried later on. ^(If +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or +** [SQLITE_READONLY] is returned, then +** there is no point in retrying the call to sqlite3_backup_step(). These +** errors are considered fatal.)^ The application must accept +** that the backup operation has failed and pass the backup operation handle +** to the sqlite3_backup_finish() to release associated resources. +** +** ^The first call to sqlite3_backup_step() obtains an exclusive lock +** on the destination file. ^The exclusive lock is not released until either +** sqlite3_backup_finish() is called or the backup operation is complete +** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to +** sqlite3_backup_step() obtains a [shared lock] on the source database that +** lasts for the duration of the sqlite3_backup_step() call. +** ^Because the source database is not locked between calls to +** sqlite3_backup_step(), the source database may be modified mid-way +** through the backup process. ^If the source database is modified by an +** external process or via a database connection other than the one being +** used by the backup operation, then the backup will be automatically +** restarted by the next call to sqlite3_backup_step(). ^If the source +** database is modified by the using the same database connection as is used +** by the backup operation, then the backup database is automatically +** updated at the same time. +** +** [[sqlite3_backup_finish()]] sqlite3_backup_finish() +** +** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the +** application wishes to abandon the backup operation, the application +** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). +** ^The sqlite3_backup_finish() interfaces releases all +** resources associated with the [sqlite3_backup] object. +** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any +** active write-transaction on the destination database is rolled back. +** The [sqlite3_backup] object is invalid +** and may not be used following a call to sqlite3_backup_finish(). +** +** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no +** sqlite3_backup_step() errors occurred, regardless or whether or not +** sqlite3_backup_step() completed. +** ^If an out-of-memory condition or IO error occurred during any prior +** sqlite3_backup_step() call on the same [sqlite3_backup] object, then +** sqlite3_backup_finish() returns the corresponding [error code]. +** +** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() +** is not a permanent error and does not affect the return value of +** sqlite3_backup_finish(). +** +** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]] +** sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** +** ^Each call to sqlite3_backup_step() sets two values inside +** the [sqlite3_backup] object: the number of pages still to be backed +** up and the total number of pages in the source database file. +** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces +** retrieve these two values, respectively. +** +** ^The values returned by these functions are only updated by +** sqlite3_backup_step(). ^If the source database is modified during a backup +** operation, then the values are not updated to account for any extra +** pages that need to be updated or the size of the source database file +** changing. +** +** Concurrent Usage of Database Handles +** +** ^The source [database connection] may be used by the application for other +** purposes while a backup operation is underway or being initialized. +** ^If SQLite is compiled and configured to support threadsafe database +** connections, then the source database connection may be used concurrently +** from within other threads. +** +** However, the application must guarantee that the destination +** [database connection] is not passed to any other API (by any thread) after +** sqlite3_backup_init() is called and before the corresponding call to +** sqlite3_backup_finish(). SQLite does not currently check to see +** if the application incorrectly accesses the destination [database connection] +** and so no error code is reported, but the operations may malfunction +** nevertheless. Use of the destination database connection while a +** backup is in progress might also also cause a mutex deadlock. +** +** If running in [shared cache mode], the application must +** guarantee that the shared cache used by the destination database +** is not accessed while the backup is running. In practice this means +** that the application must guarantee that the disk file being +** backed up to is not accessed by any connection within the process, +** not just the specific connection that was passed to sqlite3_backup_init(). +** +** The [sqlite3_backup] object itself is partially threadsafe. Multiple +** threads may safely make multiple concurrent calls to sqlite3_backup_step(). +** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** APIs are not strictly speaking threadsafe. If they are invoked at the +** same time as another thread is invoking sqlite3_backup_step() it is +** possible that they return invalid values. +*/ +SQLITE_API sqlite3_backup *sqlite3_backup_init( + sqlite3 *pDest, /* Destination database handle */ + const char *zDestName, /* Destination database name */ + sqlite3 *pSource, /* Source database handle */ + const char *zSourceName /* Source database name */ +); +SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage); +SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); + +/* +** CAPI3REF: Unlock Notification +** +** ^When running in shared-cache mode, a database operation may fail with +** an [SQLITE_LOCKED] error if the required locks on the shared-cache or +** individual tables within the shared-cache cannot be obtained. See +** [SQLite Shared-Cache Mode] for a description of shared-cache locking. +** ^This API may be used to register a callback that SQLite will invoke +** when the connection currently holding the required lock relinquishes it. +** ^This API is only available if the library was compiled with the +** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. +** +** See Also: [Using the SQLite Unlock Notification Feature]. +** +** ^Shared-cache locks are released when a database connection concludes +** its current transaction, either by committing it or rolling it back. +** +** ^When a connection (known as the blocked connection) fails to obtain a +** shared-cache lock and SQLITE_LOCKED is returned to the caller, the +** identity of the database connection (the blocking connection) that +** has locked the required resource is stored internally. ^After an +** application receives an SQLITE_LOCKED error, it may call the +** sqlite3_unlock_notify() method with the blocked connection handle as +** the first argument to register for a callback that will be invoked +** when the blocking connections current transaction is concluded. ^The +** callback is invoked from within the [sqlite3_step] or [sqlite3_close] +** call that concludes the blocking connections transaction. +** +** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, +** there is a chance that the blocking connection will have already +** concluded its transaction by the time sqlite3_unlock_notify() is invoked. +** If this happens, then the specified callback is invoked immediately, +** from within the call to sqlite3_unlock_notify().)^ +** +** ^If the blocked connection is attempting to obtain a write-lock on a +** shared-cache table, and more than one other connection currently holds +** a read-lock on the same table, then SQLite arbitrarily selects one of +** the other connections to use as the blocking connection. +** +** ^(There may be at most one unlock-notify callback registered by a +** blocked connection. If sqlite3_unlock_notify() is called when the +** blocked connection already has a registered unlock-notify callback, +** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is +** called with a NULL pointer as its second argument, then any existing +** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback may also be canceled by closing the blocked +** connection using [sqlite3_close()]. +** +** The unlock-notify callback is not reentrant. If an application invokes +** any sqlite3_xxx API functions from within an unlock-notify callback, a +** crash or deadlock may be the result. +** +** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always +** returns SQLITE_OK. +** +** Callback Invocation Details +** +** When an unlock-notify callback is registered, the application provides a +** single void* pointer that is passed to the callback when it is invoked. +** However, the signature of the callback function allows SQLite to pass +** it an array of void* context pointers. The first argument passed to +** an unlock-notify callback is a pointer to an array of void* pointers, +** and the second is the number of entries in the array. +** +** When a blocking connections transaction is concluded, there may be +** more than one blocked connection that has registered for an unlock-notify +** callback. ^If two or more such blocked connections have specified the +** same callback function, then instead of invoking the callback function +** multiple times, it is invoked once with the set of void* context pointers +** specified by the blocked connections bundled together into an array. +** This gives the application an opportunity to prioritize any actions +** related to the set of unblocked database connections. +** +** Deadlock Detection +** +** Assuming that after registering for an unlock-notify callback a +** database waits for the callback to be issued before taking any further +** action (a reasonable assumption), then using this API may cause the +** application to deadlock. For example, if connection X is waiting for +** connection Y's transaction to be concluded, and similarly connection +** Y is waiting on connection X's transaction, then neither connection +** will proceed and the system may remain deadlocked indefinitely. +** +** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock +** detection. ^If a given call to sqlite3_unlock_notify() would put the +** system in a deadlocked state, then SQLITE_LOCKED is returned and no +** unlock-notify callback is registered. The system is said to be in +** a deadlocked state if connection A has registered for an unlock-notify +** callback on the conclusion of connection B's transaction, and connection +** B has itself registered for an unlock-notify callback when connection +** A's transaction is concluded. ^Indirect deadlock is also detected, so +** the system is also considered to be deadlocked if connection B has +** registered for an unlock-notify callback on the conclusion of connection +** C's transaction, where connection C is waiting on connection A. ^Any +** number of levels of indirection are allowed. +** +** The "DROP TABLE" Exception +** +** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost +** always appropriate to call sqlite3_unlock_notify(). There is however, +** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, +** SQLite checks if there are any currently executing SELECT statements +** that belong to the same connection. If there are, SQLITE_LOCKED is +** returned. In this case there is no "blocking connection", so invoking +** sqlite3_unlock_notify() results in the unlock-notify callback being +** invoked immediately. If the application then re-attempts the "DROP TABLE" +** or "DROP INDEX" query, an infinite loop might be the result. +** +** One way around this problem is to check the extended error code returned +** by an sqlite3_step() call. ^(If there is a blocking connection, then the +** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in +** the special "DROP TABLE/INDEX" case, the extended error code is just +** SQLITE_LOCKED.)^ +*/ +SQLITE_API int sqlite3_unlock_notify( + sqlite3 *pBlocked, /* Waiting connection */ + void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ + void *pNotifyArg /* Argument to pass to xNotify */ +); + + +/* +** CAPI3REF: String Comparison +** +** ^The [sqlite3_strnicmp()] API allows applications and extensions to +** compare the contents of two buffers containing UTF-8 strings in a +** case-independent fashion, using the same definition of case independence +** that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); + +/* +** CAPI3REF: Error Logging Interface +** +** ^The [sqlite3_log()] interface writes a message into the error log +** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. +** ^If logging is enabled, the zFormat string and subsequent arguments are +** used with [sqlite3_snprintf()] to generate the final output string. +** +** The sqlite3_log() interface is intended for use by extensions such as +** virtual tables, collating functions, and SQL functions. While there is +** nothing to prevent an application from calling sqlite3_log(), doing so +** is considered bad form. +** +** The zFormat string must not be NULL. +** +** To avoid deadlocks and other threading problems, the sqlite3_log() routine +** will not use dynamically allocated memory. The log message is stored in +** a fixed-length buffer on the stack. If the log message is longer than +** a few hundred characters, it will be truncated to the length of the +** buffer. +*/ +SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); + +/* +** CAPI3REF: Write-Ahead Log Commit Hook +** +** ^The [sqlite3_wal_hook()] function is used to register a callback that +** will be invoked each time a database connection commits data to a +** [write-ahead log] (i.e. whenever a transaction is committed in +** [journal_mode | journal_mode=WAL mode]). +** +** ^The callback is invoked by SQLite after the commit has taken place and +** the associated write-lock on the database released, so the implementation +** may read, write or [checkpoint] the database as required. +** +** ^The first parameter passed to the callback function when it is invoked +** is a copy of the third parameter passed to sqlite3_wal_hook() when +** registering the callback. ^The second is a copy of the database handle. +** ^The third parameter is the name of the database that was written to - +** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter +** is the number of pages currently in the write-ahead log file, +** including those that were just committed. +** +** The callback function should normally return [SQLITE_OK]. ^If an error +** code is returned, that error will propagate back up through the +** SQLite code base to cause the statement that provoked the callback +** to report an error, though the commit will have still occurred. If the +** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value +** that does not correspond to any valid SQLite error code, the results +** are undefined. +** +** A single database handle may have at most a single write-ahead log callback +** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any +** previously registered write-ahead log callback. ^Note that the +** [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will +** those overwrite any prior [sqlite3_wal_hook()] settings. +*/ +SQLITE_API void *sqlite3_wal_hook( + sqlite3*, + int(*)(void *,sqlite3*,const char*,int), + void* +); + +/* +** CAPI3REF: Configure an auto-checkpoint +** +** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around +** [sqlite3_wal_hook()] that causes any database on [database connection] D +** to automatically [checkpoint] +** after committing a transaction if there are N or +** more frames in the [write-ahead log] file. ^Passing zero or +** a negative value as the nFrame parameter disables automatic +** checkpoints entirely. +** +** ^The callback registered by this function replaces any existing callback +** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback +** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism +** configured by this function. +** +** ^The [wal_autocheckpoint pragma] can be used to invoke this interface +** from SQL. +** +** ^Every new [database connection] defaults to having the auto-checkpoint +** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] +** pages. The use of this interface +** is only necessary if the default setting is found to be suboptimal +** for a particular application. +*/ +SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); + +/* +** CAPI3REF: Checkpoint a database +** +** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X +** on [database connection] D to be [checkpointed]. ^If X is NULL or an +** empty string, then a checkpoint is run on all databases of +** connection D. ^If the database connection D is not in +** [WAL | write-ahead log mode] then this interface is a harmless no-op. +** +** ^The [wal_checkpoint pragma] can be used to invoke this interface +** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] can be used to cause this interface to be +** run whenever the WAL reaches a certain size threshold. +** +** See also: [sqlite3_wal_checkpoint_v2()] +*/ +SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); + +/* +** CAPI3REF: Checkpoint a database +** +** Run a checkpoint operation on WAL database zDb attached to database +** handle db. The specific operation is determined by the value of the +** eMode parameter: +** +**
+**
SQLITE_CHECKPOINT_PASSIVE
+** Checkpoint as many frames as possible without waiting for any database +** readers or writers to finish. Sync the db file if all frames in the log +** are checkpointed. This mode is the same as calling +** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked. +** +**
SQLITE_CHECKPOINT_FULL
+** This mode blocks (calls the busy-handler callback) until there is no +** database writer and all readers are reading from the most recent database +** snapshot. It then checkpoints all frames in the log file and syncs the +** database file. This call blocks database writers while it is running, +** but not database readers. +** +**
SQLITE_CHECKPOINT_RESTART
+** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after +** checkpointing the log file it blocks (calls the busy-handler callback) +** until all readers are reading from the database file only. This ensures +** that the next client to write to the database file restarts the log file +** from the beginning. This call blocks database writers while it is running, +** but not database readers. +**
+** +** If pnLog is not NULL, then *pnLog is set to the total number of frames in +** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to +** the total number of checkpointed frames (including any that were already +** checkpointed when this function is called). *pnLog and *pnCkpt may be +** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK. +** If no values are available because of an error, they are both set to -1 +** before returning to communicate this to the caller. +** +** All calls obtain an exclusive "checkpoint" lock on the database file. If +** any other process is running a checkpoint operation at the same time, the +** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a +** busy-handler configured, it will not be invoked in this case. +** +** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive +** "writer" lock on the database file. If the writer lock cannot be obtained +** immediately, and a busy-handler is configured, it is invoked and the writer +** lock retried until either the busy-handler returns 0 or the lock is +** successfully obtained. The busy-handler is also invoked while waiting for +** database readers as described above. If the busy-handler returns 0 before +** the writer lock is obtained or while waiting for database readers, the +** checkpoint operation proceeds from that point in the same way as +** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible +** without blocking any further. SQLITE_BUSY is returned in this case. +** +** If parameter zDb is NULL or points to a zero length string, then the +** specified operation is attempted on all WAL databases. In this case the +** values written to output parameters *pnLog and *pnCkpt are undefined. If +** an SQLITE_BUSY error is encountered when processing one or more of the +** attached WAL databases, the operation is still attempted on any remaining +** attached databases and SQLITE_BUSY is returned to the caller. If any other +** error occurs while processing an attached database, processing is abandoned +** and the error code returned to the caller immediately. If no error +** (SQLITE_BUSY or otherwise) is encountered while processing the attached +** databases, SQLITE_OK is returned. +** +** If database zDb is the name of an attached database that is not in WAL +** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If +** zDb is not NULL (or a zero length string) and is not the name of any +** attached database, SQLITE_ERROR is returned to the caller. +*/ +SQLITE_API int sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +); + +/* +** CAPI3REF: Checkpoint operation parameters +** +** These constants can be used as the 3rd parameter to +** [sqlite3_wal_checkpoint_v2()]. See the [sqlite3_wal_checkpoint_v2()] +** documentation for additional information about the meaning and use of +** each of these values. +*/ +#define SQLITE_CHECKPOINT_PASSIVE 0 +#define SQLITE_CHECKPOINT_FULL 1 +#define SQLITE_CHECKPOINT_RESTART 2 + +/* +** CAPI3REF: Virtual Table Interface Configuration +** +** This function may be called by either the [xConnect] or [xCreate] method +** of a [virtual table] implementation to configure +** various facets of the virtual table interface. +** +** If this interface is invoked outside the context of an xConnect or +** xCreate virtual table method then the behavior is undefined. +** +** At present, there is only one option that may be configured using +** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options +** may be added in the future. +*/ +SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Virtual Table Configuration Options +** +** These macros define the various options to the +** [sqlite3_vtab_config()] interface that [virtual table] implementations +** can use to customize and optimize their behavior. +** +**
+**
SQLITE_VTAB_CONSTRAINT_SUPPORT +**
Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, +** where X is an integer. If X is zero, then the [virtual table] whose +** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not +** support constraints. In this configuration (which is the default) if +** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire +** statement is rolled back as if [ON CONFLICT | OR ABORT] had been +** specified as part of the users SQL statement, regardless of the actual +** ON CONFLICT mode specified. +** +** If X is non-zero, then the virtual table implementation guarantees +** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before +** any modifications to internal or persistent data structures have been made. +** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite +** is able to roll back a statement or database transaction, and abandon +** or continue processing the current SQL statement as appropriate. +** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns +** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode +** had been ABORT. +** +** Virtual table implementations that are required to handle OR REPLACE +** must do so within the [xUpdate] method. If a call to the +** [sqlite3_vtab_on_conflict()] function indicates that the current ON +** CONFLICT policy is REPLACE, the virtual table implementation should +** silently replace the appropriate rows within the xUpdate callback and +** return SQLITE_OK. Or, if this is not possible, it may return +** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT +** constraint handling. +**
+*/ +#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 + +/* +** CAPI3REF: Determine The Virtual Table Conflict Policy +** +** This function may only be called from within a call to the [xUpdate] method +** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The +** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL], +** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode +** of the SQL statement that triggered the call to the [xUpdate] method of the +** [virtual table]. +*/ +SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); + +/* +** CAPI3REF: Conflict resolution modes +** +** These constants are returned by [sqlite3_vtab_on_conflict()] to +** inform a [virtual table] implementation what the [ON CONFLICT] mode +** is for the SQL statement being evaluated. +** +** Note that the [SQLITE_IGNORE] constant is also used as a potential +** return value from the [sqlite3_set_authorizer()] callback and that +** [SQLITE_ABORT] is also a [result code]. +*/ +#define SQLITE_ROLLBACK 1 +/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */ +#define SQLITE_FAIL 3 +/* #define SQLITE_ABORT 4 // Also an error code */ +#define SQLITE_REPLACE 5 + + + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#if 0 +} /* End of the 'extern "C"' block */ +#endif +#endif + +/* +** 2010 August 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ + +#ifndef _SQLITE3RTREE_H_ +#define _SQLITE3RTREE_H_ + + +#if 0 +extern "C" { +#endif + +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; + +/* +** Register a geometry callback named zGeom that can be used as part of an +** R-Tree geometry query as follows: +** +** SELECT ... FROM WHERE MATCH $zGeom(... params ...) +*/ +SQLITE_API int sqlite3_rtree_geometry_callback( + sqlite3 *db, + const char *zGeom, + int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes), + void *pContext +); + + +/* +** A pointer to a structure of the following type is passed as the first +** argument to callbacks registered using rtree_geometry_callback(). +*/ +struct sqlite3_rtree_geometry { + void *pContext; /* Copy of pContext passed to s_r_g_c() */ + int nParam; /* Size of array aParam[] */ + double *aParam; /* Parameters passed to SQL geom function */ + void *pUser; /* Callback implementation user data */ + void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ +}; + + +#if 0 +} /* end of the 'extern "C"' block */ +#endif + +#endif /* ifndef _SQLITE3RTREE_H_ */ + + +/************** End of sqlite3.h *********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include hash.h in the middle of sqliteInt.h ******************/ +/************** Begin file hash.h ********************************************/ +/* +** 2001 September 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This is the header file for the generic hash-table implemenation +** used in SQLite. +*/ +#ifndef _SQLITE_HASH_H_ +#define _SQLITE_HASH_H_ + +/* Forward declarations of structures. */ +typedef struct Hash Hash; +typedef struct HashElem HashElem; + +/* A complete hash table is an instance of the following structure. +** The internals of this structure are intended to be opaque -- client +** code should not attempt to access or modify the fields of this structure +** directly. Change this structure only by using the routines below. +** However, some of the "procedures" and "functions" for modifying and +** accessing this structure are really macros, so we can't really make +** this structure opaque. +** +** All elements of the hash table are on a single doubly-linked list. +** Hash.first points to the head of this list. +** +** There are Hash.htsize buckets. Each bucket points to a spot in +** the global doubly-linked list. The contents of the bucket are the +** element pointed to plus the next _ht.count-1 elements in the list. +** +** Hash.htsize and Hash.ht may be zero. In that case lookup is done +** by a linear search of the global list. For small tables, the +** Hash.ht table is never allocated because if there are few elements +** in the table, it is faster to do a linear search than to manage +** the hash table. +*/ +struct Hash { + unsigned int htsize; /* Number of buckets in the hash table */ + unsigned int count; /* Number of entries in this table */ + HashElem *first; /* The first element of the array */ + struct _ht { /* the hash table */ + int count; /* Number of entries with this hash */ + HashElem *chain; /* Pointer to first entry with this hash */ + } *ht; +}; + +/* Each element in the hash table is an instance of the following +** structure. All elements are stored on a single doubly-linked list. +** +** Again, this structure is intended to be opaque, but it can't really +** be opaque because it is used by macros. +*/ +struct HashElem { + HashElem *next, *prev; /* Next and previous elements in the table */ + void *data; /* Data associated with this element */ + const char *pKey; int nKey; /* Key associated with this element */ +}; + +/* +** Access routines. To delete, insert a NULL pointer. +*/ +SQLITE_PRIVATE void sqlite3HashInit(Hash*); +SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, int nKey, void *pData); +SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey, int nKey); +SQLITE_PRIVATE void sqlite3HashClear(Hash*); + +/* +** Macros for looping over all elements of a hash table. The idiom is +** like this: +** +** Hash h; +** HashElem *p; +** ... +** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){ +** SomeStructure *pData = sqliteHashData(p); +** // do something with pData +** } +*/ +#define sqliteHashFirst(H) ((H)->first) +#define sqliteHashNext(E) ((E)->next) +#define sqliteHashData(E) ((E)->data) +/* #define sqliteHashKey(E) ((E)->pKey) // NOT USED */ +/* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */ + +/* +** Number of entries in a hash table +*/ +/* #define sqliteHashCount(H) ((H)->count) // NOT USED */ + +#endif /* _SQLITE_HASH_H_ */ + +/************** End of hash.h ************************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include parse.h in the middle of sqliteInt.h *****************/ +/************** Begin file parse.h *******************************************/ +#define TK_SEMI 1 +#define TK_EXPLAIN 2 +#define TK_QUERY 3 +#define TK_PLAN 4 +#define TK_BEGIN 5 +#define TK_TRANSACTION 6 +#define TK_DEFERRED 7 +#define TK_IMMEDIATE 8 +#define TK_EXCLUSIVE 9 +#define TK_COMMIT 10 +#define TK_END 11 +#define TK_ROLLBACK 12 +#define TK_SAVEPOINT 13 +#define TK_RELEASE 14 +#define TK_TO 15 +#define TK_TABLE 16 +#define TK_CREATE 17 +#define TK_IF 18 +#define TK_NOT 19 +#define TK_EXISTS 20 +#define TK_TEMP 21 +#define TK_LP 22 +#define TK_RP 23 +#define TK_AS 24 +#define TK_COMMA 25 +#define TK_ID 26 +#define TK_INDEXED 27 +#define TK_ABORT 28 +#define TK_ACTION 29 +#define TK_AFTER 30 +#define TK_ANALYZE 31 +#define TK_ASC 32 +#define TK_ATTACH 33 +#define TK_BEFORE 34 +#define TK_BY 35 +#define TK_CASCADE 36 +#define TK_CAST 37 +#define TK_COLUMNKW 38 +#define TK_CONFLICT 39 +#define TK_DATABASE 40 +#define TK_DESC 41 +#define TK_DETACH 42 +#define TK_EACH 43 +#define TK_FAIL 44 +#define TK_FOR 45 +#define TK_IGNORE 46 +#define TK_INITIALLY 47 +#define TK_INSTEAD 48 +#define TK_LIKE_KW 49 +#define TK_MATCH 50 +#define TK_NO 51 +#define TK_KEY 52 +#define TK_OF 53 +#define TK_OFFSET 54 +#define TK_PRAGMA 55 +#define TK_RAISE 56 +#define TK_REPLACE 57 +#define TK_RESTRICT 58 +#define TK_ROW 59 +#define TK_TRIGGER 60 +#define TK_VACUUM 61 +#define TK_VIEW 62 +#define TK_VIRTUAL 63 +#define TK_REINDEX 64 +#define TK_RENAME 65 +#define TK_CTIME_KW 66 +#define TK_ANY 67 +#define TK_OR 68 +#define TK_AND 69 +#define TK_IS 70 +#define TK_BETWEEN 71 +#define TK_IN 72 +#define TK_ISNULL 73 +#define TK_NOTNULL 74 +#define TK_NE 75 +#define TK_EQ 76 +#define TK_GT 77 +#define TK_LE 78 +#define TK_LT 79 +#define TK_GE 80 +#define TK_ESCAPE 81 +#define TK_BITAND 82 +#define TK_BITOR 83 +#define TK_LSHIFT 84 +#define TK_RSHIFT 85 +#define TK_PLUS 86 +#define TK_MINUS 87 +#define TK_STAR 88 +#define TK_SLASH 89 +#define TK_REM 90 +#define TK_CONCAT 91 +#define TK_COLLATE 92 +#define TK_BITNOT 93 +#define TK_STRING 94 +#define TK_JOIN_KW 95 +#define TK_CONSTRAINT 96 +#define TK_DEFAULT 97 +#define TK_NULL 98 +#define TK_PRIMARY 99 +#define TK_UNIQUE 100 +#define TK_CHECK 101 +#define TK_REFERENCES 102 +#define TK_AUTOINCR 103 +#define TK_ON 104 +#define TK_INSERT 105 +#define TK_DELETE 106 +#define TK_UPDATE 107 +#define TK_SET 108 +#define TK_DEFERRABLE 109 +#define TK_FOREIGN 110 +#define TK_DROP 111 +#define TK_UNION 112 +#define TK_ALL 113 +#define TK_EXCEPT 114 +#define TK_INTERSECT 115 +#define TK_SELECT 116 +#define TK_DISTINCT 117 +#define TK_DOT 118 +#define TK_FROM 119 +#define TK_JOIN 120 +#define TK_USING 121 +#define TK_ORDER 122 +#define TK_GROUP 123 +#define TK_HAVING 124 +#define TK_LIMIT 125 +#define TK_WHERE 126 +#define TK_INTO 127 +#define TK_VALUES 128 +#define TK_INTEGER 129 +#define TK_FLOAT 130 +#define TK_BLOB 131 +#define TK_REGISTER 132 +#define TK_VARIABLE 133 +#define TK_CASE 134 +#define TK_WHEN 135 +#define TK_THEN 136 +#define TK_ELSE 137 +#define TK_INDEX 138 +#define TK_ALTER 139 +#define TK_ADD 140 +#define TK_TO_TEXT 141 +#define TK_TO_BLOB 142 +#define TK_TO_NUMERIC 143 +#define TK_TO_INT 144 +#define TK_TO_REAL 145 +#define TK_ISNOT 146 +#define TK_END_OF_FILE 147 +#define TK_ILLEGAL 148 +#define TK_SPACE 149 +#define TK_UNCLOSED_STRING 150 +#define TK_FUNCTION 151 +#define TK_COLUMN 152 +#define TK_AGG_FUNCTION 153 +#define TK_AGG_COLUMN 154 +#define TK_CONST_FUNC 155 +#define TK_UMINUS 156 +#define TK_UPLUS 157 + +/************** End of parse.h ***********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +#include +#include +#include +#include +#include + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite_int64 +# define float sqlite_int64 +# define LONGDOUBLE_TYPE sqlite_int64 +# ifndef SQLITE_BIG_DBL +# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) +# endif +# define SQLITE_OMIT_DATETIME_FUNCS 1 +# define SQLITE_OMIT_TRACE 1 +# undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT +# undef SQLITE_HAVE_ISNAN +#endif +#ifndef SQLITE_BIG_DBL +# define SQLITE_BIG_DBL (1e99) +#endif + +/* +** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0 +** afterward. Having this macro allows us to cause the C compiler +** to omit code used by TEMP tables without messy #ifndef statements. +*/ +#ifdef SQLITE_OMIT_TEMPDB +#define OMIT_TEMPDB 1 +#else +#define OMIT_TEMPDB 0 +#endif + +/* +** The "file format" number is an integer that is incremented whenever +** the VDBE-level file format changes. The following macros define the +** the default file format for new databases and the maximum file format +** that the library can read. +*/ +#define SQLITE_MAX_FILE_FORMAT 4 +#ifndef SQLITE_DEFAULT_FILE_FORMAT +# define SQLITE_DEFAULT_FILE_FORMAT 1 +#endif + +/* +** Determine whether triggers are recursive by default. This can be +** changed at run-time using a pragma. +*/ +#ifndef SQLITE_DEFAULT_RECURSIVE_TRIGGERS +# define SQLITE_DEFAULT_RECURSIVE_TRIGGERS 0 +#endif + +/* +** Provide a default value for SQLITE_TEMP_STORE in case it is not specified +** on the command-line +*/ +#ifndef SQLITE_TEMP_STORE +# define SQLITE_TEMP_STORE 1 +#endif + +/* +** GCC does not define the offsetof() macro so we'll have to do it +** ourselves. +*/ +#ifndef offsetof +#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) +#endif + +/* +** Check to see if this machine uses EBCDIC. (Yes, believe it or +** not, there are still machines out there that use EBCDIC.) +*/ +#if 'A' == '\301' +# define SQLITE_EBCDIC 1 +#else +# define SQLITE_ASCII 1 +#endif + +/* +** Integers of known sizes. These typedefs might change for architectures +** where the sizes very. Preprocessor macros are available so that the +** types can be conveniently redefined at compile-type. Like this: +** +** cc '-DUINTPTR_TYPE=long long int' ... +*/ +#ifndef UINT32_TYPE +# ifdef HAVE_UINT32_T +# define UINT32_TYPE uint32_t +# else +# define UINT32_TYPE unsigned int +# endif +#endif +#ifndef UINT16_TYPE +# ifdef HAVE_UINT16_T +# define UINT16_TYPE uint16_t +# else +# define UINT16_TYPE unsigned short int +# endif +#endif +#ifndef INT16_TYPE +# ifdef HAVE_INT16_T +# define INT16_TYPE int16_t +# else +# define INT16_TYPE short int +# endif +#endif +#ifndef UINT8_TYPE +# ifdef HAVE_UINT8_T +# define UINT8_TYPE uint8_t +# else +# define UINT8_TYPE unsigned char +# endif +#endif +#ifndef INT8_TYPE +# ifdef HAVE_INT8_T +# define INT8_TYPE int8_t +# else +# define INT8_TYPE signed char +# endif +#endif +#ifndef LONGDOUBLE_TYPE +# define LONGDOUBLE_TYPE long double +#endif +typedef sqlite_int64 i64; /* 8-byte signed integer */ +typedef sqlite_uint64 u64; /* 8-byte unsigned integer */ +typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ +typedef UINT16_TYPE u16; /* 2-byte unsigned integer */ +typedef INT16_TYPE i16; /* 2-byte signed integer */ +typedef UINT8_TYPE u8; /* 1-byte unsigned integer */ +typedef INT8_TYPE i8; /* 1-byte signed integer */ + +/* +** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value +** that can be stored in a u32 without loss of data. The value +** is 0x00000000ffffffff. But because of quirks of some compilers, we +** have to specify the value in the less intuitive manner shown: +*/ +#define SQLITE_MAX_U32 ((((u64)1)<<32)-1) + +/* +** The datatype used to store estimates of the number of rows in a +** table or index. This is an unsigned integer type. For 99.9% of +** the world, a 32-bit integer is sufficient. But a 64-bit integer +** can be used at compile-time if desired. +*/ +#ifdef SQLITE_64BIT_STATS + typedef u64 tRowcnt; /* 64-bit only if requested at compile-time */ +#else + typedef u32 tRowcnt; /* 32-bit is the default */ +#endif + +/* +** Macros to determine whether the machine is big or little endian, +** evaluated at runtime. +*/ +#ifdef SQLITE_AMALGAMATION +SQLITE_PRIVATE const int sqlite3one = 1; +#else +SQLITE_PRIVATE const int sqlite3one; +#endif +#if defined(i386) || defined(__i386__) || defined(_M_IX86)\ + || defined(__x86_64) || defined(__x86_64__) +# define SQLITE_BIGENDIAN 0 +# define SQLITE_LITTLEENDIAN 1 +# define SQLITE_UTF16NATIVE SQLITE_UTF16LE +#else +# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) +# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) +# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) +#endif + +/* +** Constants for the largest and smallest possible 64-bit signed integers. +** These macros are designed to work correctly on both 32-bit and 64-bit +** compilers. +*/ +#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) +#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) + +/* +** Round up a number to the next larger multiple of 8. This is used +** to force 8-byte alignment on 64-bit architectures. +*/ +#define ROUND8(x) (((x)+7)&~7) + +/* +** Round down to the nearest multiple of 8 +*/ +#define ROUNDDOWN8(x) ((x)&~7) + +/* +** Assert that the pointer X is aligned to an 8-byte boundary. This +** macro is used only within assert() to verify that the code gets +** all alignment restrictions correct. +** +** Except, if SQLITE_4_BYTE_ALIGNED_MALLOC is defined, then the +** underlying malloc() implemention might return us 4-byte aligned +** pointers. In that case, only verify 4-byte alignment. +*/ +#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC +# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0) +#else +# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0) +#endif + + +/* +** An instance of the following structure is used to store the busy-handler +** callback for a given sqlite handle. +** +** The sqlite.busyHandler member of the sqlite struct contains the busy +** callback for the database handle. Each pager opened via the sqlite +** handle is passed a pointer to sqlite.busyHandler. The busy-handler +** callback is currently invoked only from within pager.c. +*/ +typedef struct BusyHandler BusyHandler; +struct BusyHandler { + int (*xFunc)(void *,int); /* The busy callback */ + void *pArg; /* First arg to busy callback */ + int nBusy; /* Incremented with each busy call */ +}; + +/* +** Name of the master database table. The master database table +** is a special table that holds the names and attributes of all +** user tables and indices. +*/ +#define MASTER_NAME "sqlite_master" +#define TEMP_MASTER_NAME "sqlite_temp_master" + +/* +** The root-page of the master database table. +*/ +#define MASTER_ROOT 1 + +/* +** The name of the schema table. +*/ +#define SCHEMA_TABLE(x) ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME) + +/* +** A convenience macro that returns the number of elements in +** an array. +*/ +#define ArraySize(X) ((int)(sizeof(X)/sizeof(X[0]))) + +/* +** The following value as a destructor means to use sqlite3DbFree(). +** This is an internal extension to SQLITE_STATIC and SQLITE_TRANSIENT. +*/ +#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3DbFree) + +/* +** When SQLITE_OMIT_WSD is defined, it means that the target platform does +** not support Writable Static Data (WSD) such as global and static variables. +** All variables must either be on the stack or dynamically allocated from +** the heap. When WSD is unsupported, the variable declarations scattered +** throughout the SQLite code must become constants instead. The SQLITE_WSD +** macro is used for this purpose. And instead of referencing the variable +** directly, we use its constant as a key to lookup the run-time allocated +** buffer that holds real variable. The constant is also the initializer +** for the run-time allocated buffer. +** +** In the usual case where WSD is supported, the SQLITE_WSD and GLOBAL +** macros become no-ops and have zero performance impact. +*/ +#ifdef SQLITE_OMIT_WSD + #define SQLITE_WSD const + #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v))) + #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config) +SQLITE_API int sqlite3_wsd_init(int N, int J); +SQLITE_API void *sqlite3_wsd_find(void *K, int L); +#else + #define SQLITE_WSD + #define GLOBAL(t,v) v + #define sqlite3GlobalConfig sqlite3Config +#endif + +/* +** The following macros are used to suppress compiler warnings and to +** make it clear to human readers when a function parameter is deliberately +** left unused within the body of a function. This usually happens when +** a function is called via a function pointer. For example the +** implementation of an SQL aggregate step callback may not use the +** parameter indicating the number of arguments passed to the aggregate, +** if it knows that this is enforced elsewhere. +** +** When a function parameter is not used at all within the body of a function, +** it is generally named "NotUsed" or "NotUsed2" to make things even clearer. +** However, these macros may also be used to suppress warnings related to +** parameters that may or may not be used depending on compilation options. +** For example those parameters only used in assert() statements. In these +** cases the parameters are named as per the usual conventions. +*/ +#define UNUSED_PARAMETER(x) (void)(x) +#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y) + +/* +** Forward references to structures +*/ +typedef struct AggInfo AggInfo; +typedef struct AuthContext AuthContext; +typedef struct AutoincInfo AutoincInfo; +typedef struct Bitvec Bitvec; +typedef struct CollSeq CollSeq; +typedef struct Column Column; +typedef struct Db Db; +typedef struct Schema Schema; +typedef struct Expr Expr; +typedef struct ExprList ExprList; +typedef struct ExprSpan ExprSpan; +typedef struct FKey FKey; +typedef struct FuncDestructor FuncDestructor; +typedef struct FuncDef FuncDef; +typedef struct FuncDefHash FuncDefHash; +typedef struct IdList IdList; +typedef struct Index Index; +typedef struct IndexSample IndexSample; +typedef struct KeyClass KeyClass; +typedef struct KeyInfo KeyInfo; +typedef struct Lookaside Lookaside; +typedef struct LookasideSlot LookasideSlot; +typedef struct Module Module; +typedef struct NameContext NameContext; +typedef struct Parse Parse; +typedef struct RowSet RowSet; +typedef struct Savepoint Savepoint; +typedef struct Select Select; +typedef struct SrcList SrcList; +typedef struct StrAccum StrAccum; +typedef struct Table Table; +typedef struct TableLock TableLock; +typedef struct Token Token; +typedef struct Trigger Trigger; +typedef struct TriggerPrg TriggerPrg; +typedef struct TriggerStep TriggerStep; +typedef struct UnpackedRecord UnpackedRecord; +typedef struct VTable VTable; +typedef struct VtabCtx VtabCtx; +typedef struct Walker Walker; +typedef struct WherePlan WherePlan; +typedef struct WhereInfo WhereInfo; +typedef struct WhereLevel WhereLevel; + +/* +** Defer sourcing vdbe.h and btree.h until after the "u8" and +** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque +** pointer types (i.e. FuncDef) defined above. +*/ +/************** Include btree.h in the middle of sqliteInt.h *****************/ +/************** Begin file btree.h *******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the sqlite B-Tree file +** subsystem. See comments in the source code for a detailed description +** of what each interface routine does. +*/ +#ifndef _BTREE_H_ +#define _BTREE_H_ + +/* TODO: This definition is just included so other modules compile. It +** needs to be revisited. +*/ +#define SQLITE_N_BTREE_META 10 + +/* +** If defined as non-zero, auto-vacuum is enabled by default. Otherwise +** it must be turned on for each database using "PRAGMA auto_vacuum = 1". +*/ +#ifndef SQLITE_DEFAULT_AUTOVACUUM + #define SQLITE_DEFAULT_AUTOVACUUM 0 +#endif + +#define BTREE_AUTOVACUUM_NONE 0 /* Do not do auto-vacuum */ +#define BTREE_AUTOVACUUM_FULL 1 /* Do full auto-vacuum */ +#define BTREE_AUTOVACUUM_INCR 2 /* Incremental vacuum */ + +/* +** Forward declarations of structure +*/ +typedef struct Btree Btree; +typedef struct BtCursor BtCursor; +typedef struct BtShared BtShared; + + +SQLITE_PRIVATE int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, /* VFS to use with this b-tree */ + const char *zFilename, /* Name of database file to open */ + sqlite3 *db, /* Associated database connection */ + Btree **ppBtree, /* Return open Btree* here */ + int flags, /* Flags */ + int vfsFlags /* Flags passed through to VFS open */ +); + +/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the +** following values. +** +** NOTE: These values must match the corresponding PAGER_ values in +** pager.h. +*/ +#define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ +#define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ +#define BTREE_MEMORY 4 /* This is an in-memory DB */ +#define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ +#define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ + +SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); +SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int); +SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*); +SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); +SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*); +SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int); +SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*); +SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*); +SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int); +SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *); +SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int); +SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*); +SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*); +SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags); +SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*); +SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*); +SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*); +SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); +SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree); +SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock); +SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int); + +SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *); +SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *); +SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *); + +SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *); + +/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR +** of the flags shown below. +** +** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set. +** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data +** is stored in the leaves. (BTREE_INTKEY is used for SQL tables.) With +** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored +** anywhere - the key is the content. (BTREE_BLOBKEY is used for SQL +** indices.) +*/ +#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */ +#define BTREE_BLOBKEY 2 /* Table has keys only - no data */ + +SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*); +SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*); +SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int); + +SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue); +SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); + +/* +** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta +** should be one of the following values. The integer values are assigned +** to constants so that the offset of the corresponding field in an +** SQLite database header may be found using the following formula: +** +** offset = 36 + (idx * 4) +** +** For example, the free-page-count field is located at byte offset 36 of +** the database file header. The incr-vacuum-flag field is located at +** byte offset 64 (== 36+4*7). +*/ +#define BTREE_FREE_PAGE_COUNT 0 +#define BTREE_SCHEMA_VERSION 1 +#define BTREE_FILE_FORMAT 2 +#define BTREE_DEFAULT_CACHE_SIZE 3 +#define BTREE_LARGEST_ROOT_PAGE 4 +#define BTREE_TEXT_ENCODING 5 +#define BTREE_USER_VERSION 6 +#define BTREE_INCR_VACUUM 7 + +SQLITE_PRIVATE int sqlite3BtreeCursor( + Btree*, /* BTree containing table to open */ + int iTable, /* Index of root page */ + int wrFlag, /* 1 for writing. 0 for read-only */ + struct KeyInfo*, /* First argument to compare function */ + BtCursor *pCursor /* Space to write cursor structure */ +); +SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); +SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); + +SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( + BtCursor*, + UnpackedRecord *pUnKey, + i64 intKey, + int bias, + int *pRes +); +SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*, int*); +SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, + const void *pData, int nData, + int nZero, int bias, int seekResult); +SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor*, i64 *pSize); +SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*); +SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt); +SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt); +SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor*, u32 *pSize); +SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); +SQLITE_PRIVATE void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64); +SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor*); + +SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); +SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); + +SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); +SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *); +SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); + +SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); + +#ifndef NDEBUG +SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); +#endif + +#ifndef SQLITE_OMIT_BTREECOUNT +SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *); +#endif + +#ifdef SQLITE_TEST +SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int); +SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*); +#endif + +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); +#endif + +/* +** If we are not using shared cache, then there is no need to +** use mutexes to access the BtShared structures. So make the +** Enter and Leave procedures no-ops. +*/ +#ifndef SQLITE_OMIT_SHARED_CACHE +SQLITE_PRIVATE void sqlite3BtreeEnter(Btree*); +SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3*); +#else +# define sqlite3BtreeEnter(X) +# define sqlite3BtreeEnterAll(X) +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE +SQLITE_PRIVATE int sqlite3BtreeSharable(Btree*); +SQLITE_PRIVATE void sqlite3BtreeLeave(Btree*); +SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor*); +SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor*); +SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3*); +#ifndef NDEBUG + /* These routines are used inside assert() statements only. */ +SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree*); +SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3*); +SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*); +#endif +#else + +# define sqlite3BtreeSharable(X) 0 +# define sqlite3BtreeLeave(X) +# define sqlite3BtreeEnterCursor(X) +# define sqlite3BtreeLeaveCursor(X) +# define sqlite3BtreeLeaveAll(X) + +# define sqlite3BtreeHoldsMutex(X) 1 +# define sqlite3BtreeHoldsAllMutexes(X) 1 +# define sqlite3SchemaMutexHeld(X,Y,Z) 1 +#endif + + +#endif /* _BTREE_H_ */ + +/************** End of btree.h ***********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include vdbe.h in the middle of sqliteInt.h ******************/ +/************** Begin file vdbe.h ********************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Header file for the Virtual DataBase Engine (VDBE) +** +** This header defines the interface to the virtual database engine +** or VDBE. The VDBE implements an abstract machine that runs a +** simple program to access and modify the underlying database. +*/ +#ifndef _SQLITE_VDBE_H_ +#define _SQLITE_VDBE_H_ +/* #include */ + +/* +** A single VDBE is an opaque structure named "Vdbe". Only routines +** in the source file sqliteVdbe.c are allowed to see the insides +** of this structure. +*/ +typedef struct Vdbe Vdbe; + +/* +** The names of the following types declared in vdbeInt.h are required +** for the VdbeOp definition. +*/ +typedef struct VdbeFunc VdbeFunc; +typedef struct Mem Mem; +typedef struct SubProgram SubProgram; + +/* +** A single instruction of the virtual machine has an opcode +** and as many as three operands. The instruction is recorded +** as an instance of the following structure: +*/ +struct VdbeOp { + u8 opcode; /* What operation to perform */ + signed char p4type; /* One of the P4_xxx constants for p4 */ + u8 opflags; /* Mask of the OPFLG_* flags in opcodes.h */ + u8 p5; /* Fifth parameter is an unsigned character */ + int p1; /* First operand */ + int p2; /* Second parameter (often the jump destination) */ + int p3; /* The third parameter */ + union { /* fourth parameter */ + int i; /* Integer value if p4type==P4_INT32 */ + void *p; /* Generic pointer */ + char *z; /* Pointer to data for string (char array) types */ + i64 *pI64; /* Used when p4type is P4_INT64 */ + double *pReal; /* Used when p4type is P4_REAL */ + FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */ + VdbeFunc *pVdbeFunc; /* Used when p4type is P4_VDBEFUNC */ + CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */ + Mem *pMem; /* Used when p4type is P4_MEM */ + VTable *pVtab; /* Used when p4type is P4_VTAB */ + KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */ + int *ai; /* Used when p4type is P4_INTARRAY */ + SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ + int (*xAdvance)(BtCursor *, int *); + } p4; +#ifdef SQLITE_DEBUG + char *zComment; /* Comment to improve readability */ +#endif +#ifdef VDBE_PROFILE + int cnt; /* Number of times this instruction was executed */ + u64 cycles; /* Total time spent executing this instruction */ +#endif +}; +typedef struct VdbeOp VdbeOp; + + +/* +** A sub-routine used to implement a trigger program. +*/ +struct SubProgram { + VdbeOp *aOp; /* Array of opcodes for sub-program */ + int nOp; /* Elements in aOp[] */ + int nMem; /* Number of memory cells required */ + int nCsr; /* Number of cursors required */ + void *token; /* id that may be used to recursive triggers */ + SubProgram *pNext; /* Next sub-program already visited */ +}; + +/* +** A smaller version of VdbeOp used for the VdbeAddOpList() function because +** it takes up less space. +*/ +struct VdbeOpList { + u8 opcode; /* What operation to perform */ + signed char p1; /* First operand */ + signed char p2; /* Second parameter (often the jump destination) */ + signed char p3; /* Third parameter */ +}; +typedef struct VdbeOpList VdbeOpList; + +/* +** Allowed values of VdbeOp.p4type +*/ +#define P4_NOTUSED 0 /* The P4 parameter is not used */ +#define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ +#define P4_STATIC (-2) /* Pointer to a static string */ +#define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */ +#define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */ +#define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */ +#define P4_VDBEFUNC (-7) /* P4 is a pointer to a VdbeFunc structure */ +#define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */ +#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ +#define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */ +#define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */ +#define P4_REAL (-12) /* P4 is a 64-bit floating point value */ +#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ +#define P4_INT32 (-14) /* P4 is a 32-bit signed integer */ +#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ +#define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */ +#define P4_ADVANCE (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */ + +/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure +** is made. That copy is freed when the Vdbe is finalized. But if the +** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used. It still +** gets freed when the Vdbe is finalized so it still should be obtained +** from a single sqliteMalloc(). But no copy is made and the calling +** function should *not* try to free the KeyInfo. +*/ +#define P4_KEYINFO_HANDOFF (-16) +#define P4_KEYINFO_STATIC (-17) + +/* +** The Vdbe.aColName array contains 5n Mem structures, where n is the +** number of columns of data returned by the statement. +*/ +#define COLNAME_NAME 0 +#define COLNAME_DECLTYPE 1 +#define COLNAME_DATABASE 2 +#define COLNAME_TABLE 3 +#define COLNAME_COLUMN 4 +#ifdef SQLITE_ENABLE_COLUMN_METADATA +# define COLNAME_N 5 /* Number of COLNAME_xxx symbols */ +#else +# ifdef SQLITE_OMIT_DECLTYPE +# define COLNAME_N 1 /* Store only the name */ +# else +# define COLNAME_N 2 /* Store the name and decltype */ +# endif +#endif + +/* +** The following macro converts a relative address in the p2 field +** of a VdbeOp structure into a negative number so that +** sqlite3VdbeAddOpList() knows that the address is relative. Calling +** the macro again restores the address. +*/ +#define ADDR(X) (-1-(X)) + +/* +** The makefile scans the vdbe.c source file and creates the "opcodes.h" +** header file that defines a number for each opcode used by the VDBE. +*/ +/************** Include opcodes.h in the middle of vdbe.h ********************/ +/************** Begin file opcodes.h *****************************************/ +/* Automatically generated. Do not edit */ +/* See the mkopcodeh.awk script for details */ +#define OP_Goto 1 +#define OP_Gosub 2 +#define OP_Return 3 +#define OP_Yield 4 +#define OP_HaltIfNull 5 +#define OP_Halt 6 +#define OP_Integer 7 +#define OP_Int64 8 +#define OP_Real 130 /* same as TK_FLOAT */ +#define OP_String8 94 /* same as TK_STRING */ +#define OP_String 9 +#define OP_Null 10 +#define OP_Blob 11 +#define OP_Variable 12 +#define OP_Move 13 +#define OP_Copy 14 +#define OP_SCopy 15 +#define OP_ResultRow 16 +#define OP_Concat 91 /* same as TK_CONCAT */ +#define OP_Add 86 /* same as TK_PLUS */ +#define OP_Subtract 87 /* same as TK_MINUS */ +#define OP_Multiply 88 /* same as TK_STAR */ +#define OP_Divide 89 /* same as TK_SLASH */ +#define OP_Remainder 90 /* same as TK_REM */ +#define OP_CollSeq 17 +#define OP_Function 18 +#define OP_BitAnd 82 /* same as TK_BITAND */ +#define OP_BitOr 83 /* same as TK_BITOR */ +#define OP_ShiftLeft 84 /* same as TK_LSHIFT */ +#define OP_ShiftRight 85 /* same as TK_RSHIFT */ +#define OP_AddImm 20 +#define OP_MustBeInt 21 +#define OP_RealAffinity 22 +#define OP_ToText 141 /* same as TK_TO_TEXT */ +#define OP_ToBlob 142 /* same as TK_TO_BLOB */ +#define OP_ToNumeric 143 /* same as TK_TO_NUMERIC*/ +#define OP_ToInt 144 /* same as TK_TO_INT */ +#define OP_ToReal 145 /* same as TK_TO_REAL */ +#define OP_Eq 76 /* same as TK_EQ */ +#define OP_Ne 75 /* same as TK_NE */ +#define OP_Lt 79 /* same as TK_LT */ +#define OP_Le 78 /* same as TK_LE */ +#define OP_Gt 77 /* same as TK_GT */ +#define OP_Ge 80 /* same as TK_GE */ +#define OP_Permutation 23 +#define OP_Compare 24 +#define OP_Jump 25 +#define OP_And 69 /* same as TK_AND */ +#define OP_Or 68 /* same as TK_OR */ +#define OP_Not 19 /* same as TK_NOT */ +#define OP_BitNot 93 /* same as TK_BITNOT */ +#define OP_Once 26 +#define OP_If 27 +#define OP_IfNot 28 +#define OP_IsNull 73 /* same as TK_ISNULL */ +#define OP_NotNull 74 /* same as TK_NOTNULL */ +#define OP_Column 29 +#define OP_Affinity 30 +#define OP_MakeRecord 31 +#define OP_Count 32 +#define OP_Savepoint 33 +#define OP_AutoCommit 34 +#define OP_Transaction 35 +#define OP_ReadCookie 36 +#define OP_SetCookie 37 +#define OP_VerifyCookie 38 +#define OP_OpenRead 39 +#define OP_OpenWrite 40 +#define OP_OpenAutoindex 41 +#define OP_OpenEphemeral 42 +#define OP_SorterOpen 43 +#define OP_OpenPseudo 44 +#define OP_Close 45 +#define OP_SeekLt 46 +#define OP_SeekLe 47 +#define OP_SeekGe 48 +#define OP_SeekGt 49 +#define OP_Seek 50 +#define OP_NotFound 51 +#define OP_Found 52 +#define OP_IsUnique 53 +#define OP_NotExists 54 +#define OP_Sequence 55 +#define OP_NewRowid 56 +#define OP_Insert 57 +#define OP_InsertInt 58 +#define OP_Delete 59 +#define OP_ResetCount 60 +#define OP_SorterCompare 61 +#define OP_SorterData 62 +#define OP_RowKey 63 +#define OP_RowData 64 +#define OP_Rowid 65 +#define OP_NullRow 66 +#define OP_Last 67 +#define OP_SorterSort 70 +#define OP_Sort 71 +#define OP_Rewind 72 +#define OP_SorterNext 81 +#define OP_Prev 92 +#define OP_Next 95 +#define OP_SorterInsert 96 +#define OP_IdxInsert 97 +#define OP_IdxDelete 98 +#define OP_IdxRowid 99 +#define OP_IdxLT 100 +#define OP_IdxGE 101 +#define OP_Destroy 102 +#define OP_Clear 103 +#define OP_CreateIndex 104 +#define OP_CreateTable 105 +#define OP_ParseSchema 106 +#define OP_LoadAnalysis 107 +#define OP_DropTable 108 +#define OP_DropIndex 109 +#define OP_DropTrigger 110 +#define OP_IntegrityCk 111 +#define OP_RowSetAdd 112 +#define OP_RowSetRead 113 +#define OP_RowSetTest 114 +#define OP_Program 115 +#define OP_Param 116 +#define OP_FkCounter 117 +#define OP_FkIfZero 118 +#define OP_MemMax 119 +#define OP_IfPos 120 +#define OP_IfNeg 121 +#define OP_IfZero 122 +#define OP_AggStep 123 +#define OP_AggFinal 124 +#define OP_Checkpoint 125 +#define OP_JournalMode 126 +#define OP_Vacuum 127 +#define OP_IncrVacuum 128 +#define OP_Expire 129 +#define OP_TableLock 131 +#define OP_VBegin 132 +#define OP_VCreate 133 +#define OP_VDestroy 134 +#define OP_VOpen 135 +#define OP_VFilter 136 +#define OP_VColumn 137 +#define OP_VNext 138 +#define OP_VRename 139 +#define OP_VUpdate 140 +#define OP_Pagecount 146 +#define OP_MaxPgcnt 147 +#define OP_Trace 148 +#define OP_Noop 149 +#define OP_Explain 150 + + +/* Properties such as "out2" or "jump" that are specified in +** comments following the "case" for each opcode in the vdbe.c +** are encoded into bitvectors as follows: +*/ +#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */ +#define OPFLG_OUT2_PRERELEASE 0x0002 /* out2-prerelease: */ +#define OPFLG_IN1 0x0004 /* in1: P1 is an input */ +#define OPFLG_IN2 0x0008 /* in2: P2 is an input */ +#define OPFLG_IN3 0x0010 /* in3: P3 is an input */ +#define OPFLG_OUT2 0x0020 /* out2: P2 is an output */ +#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */ +#define OPFLG_INITIALIZER {\ +/* 0 */ 0x00, 0x01, 0x05, 0x04, 0x04, 0x10, 0x00, 0x02,\ +/* 8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x24, 0x24,\ +/* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\ +/* 24 */ 0x00, 0x01, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00,\ +/* 32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\ +/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\ +/* 48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\ +/* 56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\ +/* 72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\ +/* 80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\ +/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\ +/* 96 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\ +/* 104 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 112 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\ +/* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00,\ +/* 128 */ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 136 */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x04,\ +/* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,} + +/************** End of opcodes.h *********************************************/ +/************** Continuing where we left off in vdbe.h ***********************/ + +/* +** Prototypes for the VDBE interface. See comments on the implementation +** for a description of what each of these routines does. +*/ +SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3*); +SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp); +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); +SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); +SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2); +SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); +SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5); +SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); +SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr); +SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); +SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); +SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); +SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); +SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); +SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); +SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*); +#endif +SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); +SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); +SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); +SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int); +SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); +SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); +SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8); +SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); +#ifndef SQLITE_OMIT_TRACE +SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); +#endif + +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); +SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); + +#ifndef SQLITE_OMIT_TRIGGER +SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); +#endif + + +#ifndef NDEBUG +SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...); +# define VdbeComment(X) sqlite3VdbeComment X +SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); +# define VdbeNoopComment(X) sqlite3VdbeNoopComment X +#else +# define VdbeComment(X) +# define VdbeNoopComment(X) +#endif + +#endif + +/************** End of vdbe.h ************************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include pager.h in the middle of sqliteInt.h *****************/ +/************** Begin file pager.h *******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the sqlite page cache +** subsystem. The page cache subsystem reads and writes a file a page +** at a time and provides a journal for rollback. +*/ + +#ifndef _PAGER_H_ +#define _PAGER_H_ + +/* +** Default maximum size for persistent journal files. A negative +** value means no limit. This value may be overridden using the +** sqlite3PagerJournalSizeLimit() API. See also "PRAGMA journal_size_limit". +*/ +#ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT + #define SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT -1 +#endif + +/* +** The type used to represent a page number. The first page in a file +** is called page 1. 0 is used to represent "not a page". +*/ +typedef u32 Pgno; + +/* +** Each open file is managed by a separate instance of the "Pager" structure. +*/ +typedef struct Pager Pager; + +/* +** Handle type for pages. +*/ +typedef struct PgHdr DbPage; + +/* +** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is +** reserved for working around a windows/posix incompatibility). It is +** used in the journal to signify that the remainder of the journal file +** is devoted to storing a master journal name - there are no more pages to +** roll back. See comments for function writeMasterJournal() in pager.c +** for details. +*/ +#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1)) + +/* +** Allowed values for the flags parameter to sqlite3PagerOpen(). +** +** NOTE: These values must match the corresponding BTREE_ values in btree.h. +*/ +#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ +#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ +#define PAGER_MEMORY 0x0004 /* In-memory database */ + +/* +** Valid values for the second argument to sqlite3PagerLockingMode(). +*/ +#define PAGER_LOCKINGMODE_QUERY -1 +#define PAGER_LOCKINGMODE_NORMAL 0 +#define PAGER_LOCKINGMODE_EXCLUSIVE 1 + +/* +** Numeric constants that encode the journalmode. +*/ +#define PAGER_JOURNALMODE_QUERY (-1) /* Query the value of journalmode */ +#define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */ +#define PAGER_JOURNALMODE_PERSIST 1 /* Commit by zeroing journal header */ +#define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */ +#define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */ +#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */ +#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ + +/* +** The remainder of this file contains the declarations of the functions +** that make up the Pager sub-system API. See source code comments for +** a detailed description of each routine. +*/ + +/* Open and close a Pager connection. */ +SQLITE_PRIVATE int sqlite3PagerOpen( + sqlite3_vfs*, + Pager **ppPager, + const char*, + int, + int, + int, + void(*)(DbPage*) +); +SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); + +/* Functions used to configure a Pager object. */ +SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int); +SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int); +SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int); +SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int,int); +SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int); +SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int); +SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*); +SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*); +SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64); +SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*); + +/* Functions used to obtain and release page references. */ +SQLITE_PRIVATE int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); +#define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0) +SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); +SQLITE_PRIVATE void sqlite3PagerRef(DbPage*); +SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*); + +/* Operations on page references. */ +SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*); +SQLITE_PRIVATE void sqlite3PagerDontWrite(DbPage*); +SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int); +SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage*); +SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *); +SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *); + +/* Functions used to manage pager transactions and savepoints. */ +SQLITE_PRIVATE void sqlite3PagerPagecount(Pager*, int*); +SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag, int); +SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int); +SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager*); +SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*); +SQLITE_PRIVATE int sqlite3PagerRollback(Pager*); +SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n); +SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint); +SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager); + +SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*); +SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); +SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager); + +/* Functions used to query pager state and configuration. */ +SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); +SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); +SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); +SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*); +SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*); +SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); +SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); +SQLITE_PRIVATE int sqlite3PagerNosync(Pager*); +SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); +SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); +SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *); + +/* Functions used to truncate the database file. */ +SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); + +#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL) +SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *); +#endif + +/* Functions to support testing and debugging. */ +#if !defined(NDEBUG) || defined(SQLITE_TEST) +SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage*); +SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage*); +#endif +#ifdef SQLITE_TEST +SQLITE_PRIVATE int *sqlite3PagerStats(Pager*); +SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*); + void disable_simulated_io_errors(void); + void enable_simulated_io_errors(void); +#else +# define disable_simulated_io_errors() +# define enable_simulated_io_errors() +#endif + +#endif /* _PAGER_H_ */ + +/************** End of pager.h ***********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include pcache.h in the middle of sqliteInt.h ****************/ +/************** Begin file pcache.h ******************************************/ +/* +** 2008 August 05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the sqlite page cache +** subsystem. +*/ + +#ifndef _PCACHE_H_ + +typedef struct PgHdr PgHdr; +typedef struct PCache PCache; + +/* +** Every page in the cache is controlled by an instance of the following +** structure. +*/ +struct PgHdr { + void *pData; /* Content of this page */ + void *pExtra; /* Extra content */ + PgHdr *pDirty; /* Transient list of dirty pages */ + Pgno pgno; /* Page number for this page */ + Pager *pPager; /* The pager this page is part of */ +#ifdef SQLITE_CHECK_PAGES + u32 pageHash; /* Hash of page content */ +#endif + u16 flags; /* PGHDR flags defined below */ + + /********************************************************************** + ** Elements above are public. All that follows is private to pcache.c + ** and should not be accessed by other modules. + */ + i16 nRef; /* Number of users of this page */ + PCache *pCache; /* Cache that owns this page */ + + PgHdr *pDirtyNext; /* Next element in list of dirty pages */ + PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ +}; + +/* Bit values for PgHdr.flags */ +#define PGHDR_DIRTY 0x002 /* Page has changed */ +#define PGHDR_NEED_SYNC 0x004 /* Fsync the rollback journal before + ** writing this page to the database */ +#define PGHDR_NEED_READ 0x008 /* Content is unread */ +#define PGHDR_REUSE_UNLIKELY 0x010 /* A hint that reuse is unlikely */ +#define PGHDR_DONT_WRITE 0x020 /* Do not write content to disk */ + +/* Initialize and shutdown the page cache subsystem */ +SQLITE_PRIVATE int sqlite3PcacheInitialize(void); +SQLITE_PRIVATE void sqlite3PcacheShutdown(void); + +/* Page cache buffer management: +** These routines implement SQLITE_CONFIG_PAGECACHE. +*/ +SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *, int sz, int n); + +/* Create a new pager cache. +** Under memory stress, invoke xStress to try to make pages clean. +** Only clean and unpinned pages can be reclaimed. +*/ +SQLITE_PRIVATE void sqlite3PcacheOpen( + int szPage, /* Size of every page */ + int szExtra, /* Extra space associated with each page */ + int bPurgeable, /* True if pages are on backing store */ + int (*xStress)(void*, PgHdr*), /* Call to try to make pages clean */ + void *pStress, /* Argument to xStress */ + PCache *pToInit /* Preallocated space for the PCache */ +); + +/* Modify the page-size after the cache has been created. */ +SQLITE_PRIVATE void sqlite3PcacheSetPageSize(PCache *, int); + +/* Return the size in bytes of a PCache object. Used to preallocate +** storage space. +*/ +SQLITE_PRIVATE int sqlite3PcacheSize(void); + +/* One release per successful fetch. Page is pinned until released. +** Reference counted. +*/ +SQLITE_PRIVATE int sqlite3PcacheFetch(PCache*, Pgno, int createFlag, PgHdr**); +SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr*); + +SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */ +SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */ +SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */ +SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */ + +/* Change a page number. Used by incr-vacuum. */ +SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr*, Pgno); + +/* Remove all pages with pgno>x. Reset the cache if x==0 */ +SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache*, Pgno x); + +/* Get a list of all dirty pages in the cache, sorted by page number */ +SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache*); + +/* Reset and close the cache object */ +SQLITE_PRIVATE void sqlite3PcacheClose(PCache*); + +/* Clear flags from pages of the page cache */ +SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *); + +/* Discard the contents of the cache */ +SQLITE_PRIVATE void sqlite3PcacheClear(PCache*); + +/* Return the total number of outstanding page references */ +SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache*); + +/* Increment the reference count of an existing page */ +SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*); + +SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr*); + +/* Return the total number of pages stored in the cache */ +SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*); + +#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) +/* Iterate through all dirty pages currently stored in the cache. This +** interface is only available if SQLITE_CHECK_PAGES is defined when the +** library is built. +*/ +SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)); +#endif + +/* Set and get the suggested cache-size for the specified pager-cache. +** +** If no global maximum is configured, then the system attempts to limit +** the total number of pages cached by purgeable pager-caches to the sum +** of the suggested cache-sizes. +*/ +SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *, int); +#ifdef SQLITE_TEST +SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *); +#endif + +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT +/* Try to return memory used by the pcache module to the main memory heap */ +SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int); +#endif + +#ifdef SQLITE_TEST +SQLITE_PRIVATE void sqlite3PcacheStats(int*,int*,int*,int*); +#endif + +SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); + +#endif /* _PCACHE_H_ */ + +/************** End of pcache.h **********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + +/************** Include os.h in the middle of sqliteInt.h ********************/ +/************** Begin file os.h **********************************************/ +/* +** 2001 September 16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This header file (together with is companion C source-code file +** "os.c") attempt to abstract the underlying operating system so that +** the SQLite library will work on both POSIX and windows systems. +** +** This header file is #include-ed by sqliteInt.h and thus ends up +** being included by every source file. +*/ +#ifndef _SQLITE_OS_H_ +#define _SQLITE_OS_H_ + +/* +** Figure out if we are dealing with Unix, Windows, or some other +** operating system. After the following block of preprocess macros, +** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER +** will defined to either 1 or 0. One of the four will be 1. The other +** three will be 0. +*/ +#if defined(SQLITE_OS_OTHER) +# if SQLITE_OS_OTHER==1 +# undef SQLITE_OS_UNIX +# define SQLITE_OS_UNIX 0 +# undef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# undef SQLITE_OS_OS2 +# define SQLITE_OS_OS2 0 +# else +# undef SQLITE_OS_OTHER +# endif +#endif +#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) +# define SQLITE_OS_OTHER 0 +# ifndef SQLITE_OS_WIN +# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) +# define SQLITE_OS_WIN 1 +# define SQLITE_OS_UNIX 0 +# define SQLITE_OS_OS2 0 +# elif defined(__EMX__) || defined(_OS2) || defined(OS2) || defined(_OS2_) || defined(__OS2__) +# define SQLITE_OS_WIN 0 +# define SQLITE_OS_UNIX 0 +# define SQLITE_OS_OS2 1 +# else +# define SQLITE_OS_WIN 0 +# define SQLITE_OS_UNIX 1 +# define SQLITE_OS_OS2 0 +# endif +# else +# define SQLITE_OS_UNIX 0 +# define SQLITE_OS_OS2 0 +# endif +#else +# ifndef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# endif +#endif + +/* +** Determine if we are dealing with WindowsCE - which has a much +** reduced API. +*/ +#if defined(_WIN32_WCE) +# define SQLITE_OS_WINCE 1 +#else +# define SQLITE_OS_WINCE 0 +#endif + + +/* +** Define the maximum size of a temporary filename +*/ +#if SQLITE_OS_WIN +# include +# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50) +#elif SQLITE_OS_OS2 +# if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY) +# include /* has to be included before os2.h for linking to work */ +# endif +# define INCL_DOSDATETIME +# define INCL_DOSFILEMGR +# define INCL_DOSERRORS +# define INCL_DOSMISC +# define INCL_DOSPROCESS +# define INCL_DOSMODULEMGR +# define INCL_DOSSEMAPHORES +# include +# include +# define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP) +#else +# define SQLITE_TEMPNAME_SIZE 200 +#endif + +/* If the SET_FULLSYNC macro is not defined above, then make it +** a no-op +*/ +#ifndef SET_FULLSYNC +# define SET_FULLSYNC(x,y) +#endif + +/* +** The default size of a disk sector +*/ +#ifndef SQLITE_DEFAULT_SECTOR_SIZE +# define SQLITE_DEFAULT_SECTOR_SIZE 512 +#endif + +/* +** Temporary files are named starting with this prefix followed by 16 random +** alphanumeric characters, and no file extension. They are stored in the +** OS's standard temporary file directory, and are deleted prior to exit. +** If sqlite is being embedded in another program, you may wish to change the +** prefix to reflect your program's name, so that if your program exits +** prematurely, old temporary files can be easily identified. This can be done +** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. +** +** 2006-10-31: The default prefix used to be "sqlite_". But then +** Mcafee started using SQLite in their anti-virus product and it +** started putting files with the "sqlite" name in the c:/temp folder. +** This annoyed many windows users. Those users would then do a +** Google search for "sqlite", find the telephone numbers of the +** developers and call to wake them up at night and complain. +** For this reason, the default name prefix is changed to be "sqlite" +** spelled backwards. So the temp files are still identified, but +** anybody smart enough to figure out the code is also likely smart +** enough to know that calling the developer will not help get rid +** of the file. +*/ +#ifndef SQLITE_TEMP_FILE_PREFIX +# define SQLITE_TEMP_FILE_PREFIX "etilqs_" +#endif + +/* +** The following values may be passed as the second argument to +** sqlite3OsLock(). The various locks exhibit the following semantics: +** +** SHARED: Any number of processes may hold a SHARED lock simultaneously. +** RESERVED: A single process may hold a RESERVED lock on a file at +** any time. Other processes may hold and obtain new SHARED locks. +** PENDING: A single process may hold a PENDING lock on a file at +** any one time. Existing SHARED locks may persist, but no new +** SHARED locks may be obtained by other processes. +** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. +** +** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a +** process that requests an EXCLUSIVE lock may actually obtain a PENDING +** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to +** sqlite3OsLock(). +*/ +#define NO_LOCK 0 +#define SHARED_LOCK 1 +#define RESERVED_LOCK 2 +#define PENDING_LOCK 3 +#define EXCLUSIVE_LOCK 4 + +/* +** File Locking Notes: (Mostly about windows but also some info for Unix) +** +** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because +** those functions are not available. So we use only LockFile() and +** UnlockFile(). +** +** LockFile() prevents not just writing but also reading by other processes. +** A SHARED_LOCK is obtained by locking a single randomly-chosen +** byte out of a specific range of bytes. The lock byte is obtained at +** random so two separate readers can probably access the file at the +** same time, unless they are unlucky and choose the same lock byte. +** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. +** There can only be one writer. A RESERVED_LOCK is obtained by locking +** a single byte of the file that is designated as the reserved lock byte. +** A PENDING_LOCK is obtained by locking a designated byte different from +** the RESERVED_LOCK byte. +** +** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, +** which means we can use reader/writer locks. When reader/writer locks +** are used, the lock is placed on the same range of bytes that is used +** for probabilistic locking in Win95/98/ME. Hence, the locking scheme +** will support two or more Win95 readers or two or more WinNT readers. +** But a single Win95 reader will lock out all WinNT readers and a single +** WinNT reader will lock out all other Win95 readers. +** +** The following #defines specify the range of bytes used for locking. +** SHARED_SIZE is the number of bytes available in the pool from which +** a random byte is selected for a shared lock. The pool of bytes for +** shared locks begins at SHARED_FIRST. +** +** The same locking strategy and +** byte ranges are used for Unix. This leaves open the possiblity of having +** clients on win95, winNT, and unix all talking to the same shared file +** and all locking correctly. To do so would require that samba (or whatever +** tool is being used for file sharing) implements locks correctly between +** windows and unix. I'm guessing that isn't likely to happen, but by +** using the same locking range we are at least open to the possibility. +** +** Locking in windows is manditory. For this reason, we cannot store +** actual data in the bytes used for locking. The pager never allocates +** the pages involved in locking therefore. SHARED_SIZE is selected so +** that all locks will fit on a single page even at the minimum page size. +** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE +** is set high so that we don't have to allocate an unused page except +** for very large databases. But one should test the page skipping logic +** by setting PENDING_BYTE low and running the entire regression suite. +** +** Changing the value of PENDING_BYTE results in a subtly incompatible +** file format. Depending on how it is changed, you might not notice +** the incompatibility right away, even running a full regression test. +** The default location of PENDING_BYTE is the first byte past the +** 1GB boundary. +** +*/ +#ifdef SQLITE_OMIT_WSD +# define PENDING_BYTE (0x40000000) +#else +# define PENDING_BYTE sqlite3PendingByte +#endif +#define RESERVED_BYTE (PENDING_BYTE+1) +#define SHARED_FIRST (PENDING_BYTE+2) +#define SHARED_SIZE 510 + +/* +** Wrapper around OS specific sqlite3_os_init() function. +*/ +SQLITE_PRIVATE int sqlite3OsInit(void); + +/* +** Functions for accessing sqlite3_file methods +*/ +SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file*); +SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); +SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); +SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size); +SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); +SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); +SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); +#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 +SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); +SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); +SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); + +/* +** Functions for accessing sqlite3_vfs methods +*/ +SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); +SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int); +SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); +SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); +#ifndef SQLITE_OMIT_LOAD_EXTENSION +SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); +SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); +SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ +SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); +SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); + +/* +** Convenience functions for opening and closing files using +** sqlite3_malloc() to obtain space for the file-handle structure. +*/ +SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); +SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *); + +#endif /* _SQLITE_OS_H_ */ + +/************** End of os.h **************************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include mutex.h in the middle of sqliteInt.h *****************/ +/************** Begin file mutex.h *******************************************/ +/* +** 2007 August 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains the common header for all mutex implementations. +** The sqliteInt.h header #includes this file so that it is available +** to all source files. We break it out in an effort to keep the code +** better organized. +** +** NOTE: source files should *not* #include this header file directly. +** Source files should #include the sqliteInt.h file and let that file +** include this one indirectly. +*/ + + +/* +** Figure out what version of the code to use. The choices are +** +** SQLITE_MUTEX_OMIT No mutex logic. Not even stubs. The +** mutexes implemention cannot be overridden +** at start-time. +** +** SQLITE_MUTEX_NOOP For single-threaded applications. No +** mutual exclusion is provided. But this +** implementation can be overridden at +** start-time. +** +** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix. +** +** SQLITE_MUTEX_W32 For multi-threaded applications on Win32. +** +** SQLITE_MUTEX_OS2 For multi-threaded applications on OS/2. +*/ +#if !SQLITE_THREADSAFE +# define SQLITE_MUTEX_OMIT +#endif +#if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP) +# if SQLITE_OS_UNIX +# define SQLITE_MUTEX_PTHREADS +# elif SQLITE_OS_WIN +# define SQLITE_MUTEX_W32 +# elif SQLITE_OS_OS2 +# define SQLITE_MUTEX_OS2 +# else +# define SQLITE_MUTEX_NOOP +# endif +#endif + +#ifdef SQLITE_MUTEX_OMIT +/* +** If this is a no-op implementation, implement everything as macros. +*/ +#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) +#define sqlite3_mutex_free(X) +#define sqlite3_mutex_enter(X) +#define sqlite3_mutex_try(X) SQLITE_OK +#define sqlite3_mutex_leave(X) +#define sqlite3_mutex_held(X) ((void)(X),1) +#define sqlite3_mutex_notheld(X) ((void)(X),1) +#define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8) +#define sqlite3MutexInit() SQLITE_OK +#define sqlite3MutexEnd() +#define MUTEX_LOGIC(X) +#else +#define MUTEX_LOGIC(X) X +#endif /* defined(SQLITE_MUTEX_OMIT) */ + +/************** End of mutex.h ***********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + + +/* +** Each database file to be accessed by the system is an instance +** of the following structure. There are normally two of these structures +** in the sqlite.aDb[] array. aDb[0] is the main database file and +** aDb[1] is the database file used to hold temporary tables. Additional +** databases may be attached. +*/ +struct Db { + char *zName; /* Name of this database */ + Btree *pBt; /* The B*Tree structure for this database file */ + u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */ + u8 safety_level; /* How aggressive at syncing data to disk */ + Schema *pSchema; /* Pointer to database schema (possibly shared) */ +}; + +/* +** An instance of the following structure stores a database schema. +** +** Most Schema objects are associated with a Btree. The exception is +** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing. +** In shared cache mode, a single Schema object can be shared by multiple +** Btrees that refer to the same underlying BtShared object. +** +** Schema objects are automatically deallocated when the last Btree that +** references them is destroyed. The TEMP Schema is manually freed by +** sqlite3_close(). +* +** A thread must be holding a mutex on the corresponding Btree in order +** to access Schema content. This implies that the thread must also be +** holding a mutex on the sqlite3 connection pointer that owns the Btree. +** For a TEMP Schema, only the connection mutex is required. +*/ +struct Schema { + int schema_cookie; /* Database schema version number for this file */ + int iGeneration; /* Generation counter. Incremented with each change */ + Hash tblHash; /* All tables indexed by name */ + Hash idxHash; /* All (named) indices indexed by name */ + Hash trigHash; /* All triggers indexed by name */ + Hash fkeyHash; /* All foreign keys by referenced table name */ + Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ + u8 file_format; /* Schema format version for this file */ + u8 enc; /* Text encoding used by this database */ + u16 flags; /* Flags associated with this schema */ + int cache_size; /* Number of pages to use in the cache */ +}; + +/* +** These macros can be used to test, set, or clear bits in the +** Db.pSchema->flags field. +*/ +#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))==(P)) +#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))!=0) +#define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->flags|=(P) +#define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->flags&=~(P) + +/* +** Allowed values for the DB.pSchema->flags field. +** +** The DB_SchemaLoaded flag is set after the database schema has been +** read into internal hash tables. +** +** DB_UnresetViews means that one or more views have column names that +** have been filled out. If the schema changes, these column names might +** changes and so the view will need to be reset. +*/ +#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */ +#define DB_UnresetViews 0x0002 /* Some views have defined column names */ +#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ + +/* +** The number of different kinds of things that can be limited +** using the sqlite3_limit() interface. +*/ +#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_DEPTH+1) + +/* +** Lookaside malloc is a set of fixed-size buffers that can be used +** to satisfy small transient memory allocation requests for objects +** associated with a particular database connection. The use of +** lookaside malloc provides a significant performance enhancement +** (approx 10%) by avoiding numerous malloc/free requests while parsing +** SQL statements. +** +** The Lookaside structure holds configuration information about the +** lookaside malloc subsystem. Each available memory allocation in +** the lookaside subsystem is stored on a linked list of LookasideSlot +** objects. +** +** Lookaside allocations are only allowed for objects that are associated +** with a particular database connection. Hence, schema information cannot +** be stored in lookaside because in shared cache mode the schema information +** is shared by multiple database connections. Therefore, while parsing +** schema information, the Lookaside.bEnabled flag is cleared so that +** lookaside allocations are not used to construct the schema objects. +*/ +struct Lookaside { + u16 sz; /* Size of each buffer in bytes */ + u8 bEnabled; /* False to disable new lookaside allocations */ + u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ + int nOut; /* Number of buffers currently checked out */ + int mxOut; /* Highwater mark for nOut */ + int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ + LookasideSlot *pFree; /* List of available buffers */ + void *pStart; /* First byte of available memory space */ + void *pEnd; /* First byte past end of available space */ +}; +struct LookasideSlot { + LookasideSlot *pNext; /* Next buffer in the list of free buffers */ +}; + +/* +** A hash table for function definitions. +** +** Hash each FuncDef structure into one of the FuncDefHash.a[] slots. +** Collisions are on the FuncDef.pHash chain. +*/ +struct FuncDefHash { + FuncDef *a[23]; /* Hash table for functions */ +}; + +/* +** Each database connection is an instance of the following structure. +** +** The sqlite.lastRowid records the last insert rowid generated by an +** insert statement. Inserts on views do not affect its value. Each +** trigger has its own context, so that lastRowid can be updated inside +** triggers as usual. The previous value will be restored once the trigger +** exits. Upon entering a before or instead of trigger, lastRowid is no +** longer (since after version 2.8.12) reset to -1. +** +** The sqlite.nChange does not count changes within triggers and keeps no +** context. It is reset at start of sqlite3_exec. +** The sqlite.lsChange represents the number of changes made by the last +** insert, update, or delete statement. It remains constant throughout the +** length of a statement and is then updated by OP_SetCounts. It keeps a +** context stack just like lastRowid so that the count of changes +** within a trigger is not seen outside the trigger. Changes to views do not +** affect the value of lsChange. +** The sqlite.csChange keeps track of the number of current changes (since +** the last statement) and is used to update sqlite_lsChange. +** +** The member variables sqlite.errCode, sqlite.zErrMsg and sqlite.zErrMsg16 +** store the most recent error code and, if applicable, string. The +** internal function sqlite3Error() is used to set these variables +** consistently. +*/ +struct sqlite3 { + sqlite3_vfs *pVfs; /* OS Interface */ + int nDb; /* Number of backends currently in use */ + Db *aDb; /* All backends */ + int flags; /* Miscellaneous flags. See below */ + unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ + int errCode; /* Most recent error code (SQLITE_*) */ + int errMask; /* & result codes with this before returning */ + u8 autoCommit; /* The auto-commit flag. */ + u8 temp_store; /* 1: file 2: memory 0: default */ + u8 mallocFailed; /* True if we have seen a malloc failure */ + u8 dfltLockMode; /* Default locking-mode for attached dbs */ + signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ + u8 suppressErr; /* Do not issue error messages if true */ + u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ + int nextPagesize; /* Pagesize after VACUUM if >0 */ + int nTable; /* Number of tables in the database */ + CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ + i64 lastRowid; /* ROWID of most recent insert (see above) */ + u32 magic; /* Magic number for detect library misuse */ + int nChange; /* Value returned by sqlite3_changes() */ + int nTotalChange; /* Value returned by sqlite3_total_changes() */ + sqlite3_mutex *mutex; /* Connection mutex */ + int aLimit[SQLITE_N_LIMIT]; /* Limits */ + struct sqlite3InitInfo { /* Information used during initialization */ + int iDb; /* When back is being initialized */ + int newTnum; /* Rootpage of table being initialized */ + u8 busy; /* TRUE if currently initializing */ + u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */ + } init; + int nExtension; /* Number of loaded extensions */ + void **aExtension; /* Array of shared library handles */ + struct Vdbe *pVdbe; /* List of active virtual machines */ + int activeVdbeCnt; /* Number of VDBEs currently executing */ + int writeVdbeCnt; /* Number of active VDBEs that are writing */ + int vdbeExecCnt; /* Number of nested calls to VdbeExec() */ + void (*xTrace)(void*,const char*); /* Trace function */ + void *pTraceArg; /* Argument to the trace function */ + void (*xProfile)(void*,const char*,u64); /* Profiling function */ + void *pProfileArg; /* Argument to profile function */ + void *pCommitArg; /* Argument to xCommitCallback() */ + int (*xCommitCallback)(void*); /* Invoked at every commit. */ + void *pRollbackArg; /* Argument to xRollbackCallback() */ + void (*xRollbackCallback)(void*); /* Invoked at every commit. */ + void *pUpdateArg; + void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64); +#ifndef SQLITE_OMIT_WAL + int (*xWalCallback)(void *, sqlite3 *, const char *, int); + void *pWalArg; +#endif + void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); + void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); + void *pCollNeededArg; + sqlite3_value *pErr; /* Most recent error message */ + char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ + char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ + union { + volatile int isInterrupted; /* True if sqlite3_interrupt has been called */ + double notUsed1; /* Spacer */ + } u1; + Lookaside lookaside; /* Lookaside malloc configuration */ +#ifndef SQLITE_OMIT_AUTHORIZATION + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); + /* Access authorization function */ + void *pAuthArg; /* 1st argument to the access auth function */ +#endif +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + int (*xProgress)(void *); /* The progress callback */ + void *pProgressArg; /* Argument to the progress callback */ + int nProgressOps; /* Number of opcodes for progress callback */ +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + Hash aModule; /* populated by sqlite3_create_module() */ + VtabCtx *pVtabCtx; /* Context for active vtab connect/create */ + VTable **aVTrans; /* Virtual tables with open transactions */ + int nVTrans; /* Allocated size of aVTrans */ + VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ +#endif + FuncDefHash aFunc; /* Hash table of connection functions */ + Hash aCollSeq; /* All collating sequences */ + BusyHandler busyHandler; /* Busy callback */ + int busyTimeout; /* Busy handler timeout, in msec */ + Db aDbStatic[2]; /* Static space for the 2 default backends */ + Savepoint *pSavepoint; /* List of active savepoints */ + int nSavepoint; /* Number of non-transaction savepoints */ + int nStatement; /* Number of nested statement-transactions */ + u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ + i64 nDeferredCons; /* Net deferred constraints this transaction. */ + int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ + +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + /* The following variables are all protected by the STATIC_MASTER + ** mutex, not by sqlite3.mutex. They are used by code in notify.c. + ** + ** When X.pUnlockConnection==Y, that means that X is waiting for Y to + ** unlock so that it can proceed. + ** + ** When X.pBlockingConnection==Y, that means that something that X tried + ** tried to do recently failed with an SQLITE_LOCKED error due to locks + ** held by Y. + */ + sqlite3 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */ + sqlite3 *pUnlockConnection; /* Connection to watch for unlock */ + void *pUnlockArg; /* Argument to xUnlockNotify */ + void (*xUnlockNotify)(void **, int); /* Unlock notify callback */ + sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ +#endif +}; + +/* +** A macro to discover the encoding of a database. +*/ +#define ENC(db) ((db)->aDb[0].pSchema->enc) + +/* +** Possible values for the sqlite3.flags. +*/ +#define SQLITE_VdbeTrace 0x00000100 /* True to trace VDBE execution */ +#define SQLITE_InternChanges 0x00000200 /* Uncommitted Hash table changes */ +#define SQLITE_FullColNames 0x00000400 /* Show full column names on SELECT */ +#define SQLITE_ShortColNames 0x00000800 /* Show short columns names */ +#define SQLITE_CountRows 0x00001000 /* Count rows changed by INSERT, */ + /* DELETE, or UPDATE and return */ + /* the count using a callback. */ +#define SQLITE_NullCallback 0x00002000 /* Invoke the callback once if the */ + /* result set is empty */ +#define SQLITE_SqlTrace 0x00004000 /* Debug print SQL as it executes */ +#define SQLITE_VdbeListing 0x00008000 /* Debug listings of VDBE programs */ +#define SQLITE_WriteSchema 0x00010000 /* OK to update SQLITE_MASTER */ +#define SQLITE_NoReadlock 0x00020000 /* Readlocks are omitted when + ** accessing read-only databases */ +#define SQLITE_IgnoreChecks 0x00040000 /* Do not enforce check constraints */ +#define SQLITE_ReadUncommitted 0x0080000 /* For shared-cache mode */ +#define SQLITE_LegacyFileFmt 0x00100000 /* Create new databases in format 1 */ +#define SQLITE_FullFSync 0x00200000 /* Use full fsync on the backend */ +#define SQLITE_CkptFullFSync 0x00400000 /* Use full fsync for checkpoint */ +#define SQLITE_RecoveryMode 0x00800000 /* Ignore schema errors */ +#define SQLITE_ReverseOrder 0x01000000 /* Reverse unordered SELECTs */ +#define SQLITE_RecTriggers 0x02000000 /* Enable recursive triggers */ +#define SQLITE_ForeignKeys 0x04000000 /* Enforce foreign key constraints */ +#define SQLITE_AutoIndex 0x08000000 /* Enable automatic indexes */ +#define SQLITE_PreferBuiltin 0x10000000 /* Preference to built-in funcs */ +#define SQLITE_LoadExtension 0x20000000 /* Enable load_extension */ +#define SQLITE_EnableTrigger 0x40000000 /* True to enable triggers */ + +/* +** Bits of the sqlite3.flags field that are used by the +** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface. +** These must be the low-order bits of the flags field. +*/ +#define SQLITE_QueryFlattener 0x01 /* Disable query flattening */ +#define SQLITE_ColumnCache 0x02 /* Disable the column cache */ +#define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */ +#define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */ +#define SQLITE_IndexCover 0x10 /* Disable index covering table */ +#define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */ +#define SQLITE_FactorOutConst 0x40 /* Disable factoring out constants */ +#define SQLITE_IdxRealAsInt 0x80 /* Store REAL as INT in indices */ +#define SQLITE_DistinctOpt 0x80 /* DISTINCT using indexes */ +#define SQLITE_OptMask 0xff /* Mask of all disablable opts */ + +/* +** Possible values for the sqlite.magic field. +** The numbers are obtained at random and have no special meaning, other +** than being distinct from one another. +*/ +#define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */ +#define SQLITE_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */ +#define SQLITE_MAGIC_SICK 0x4b771290 /* Error and awaiting close */ +#define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */ +#define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */ + +/* +** Each SQL function is defined by an instance of the following +** structure. A pointer to this structure is stored in the sqlite.aFunc +** hash table. When multiple functions have the same name, the hash table +** points to a linked list of these structures. +*/ +struct FuncDef { + i16 nArg; /* Number of arguments. -1 means unlimited */ + u8 iPrefEnc; /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */ + u8 flags; /* Some combination of SQLITE_FUNC_* */ + void *pUserData; /* User data parameter */ + FuncDef *pNext; /* Next function with same name */ + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */ + void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */ + void (*xFinalize)(sqlite3_context*); /* Aggregate finalizer */ + char *zName; /* SQL name of the function. */ + FuncDef *pHash; /* Next with a different name but the same hash */ + FuncDestructor *pDestructor; /* Reference counted destructor function */ +}; + +/* +** This structure encapsulates a user-function destructor callback (as +** configured using create_function_v2()) and a reference counter. When +** create_function_v2() is called to create a function with a destructor, +** a single object of this type is allocated. FuncDestructor.nRef is set to +** the number of FuncDef objects created (either 1 or 3, depending on whether +** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor +** member of each of the new FuncDef objects is set to point to the allocated +** FuncDestructor. +** +** Thereafter, when one of the FuncDef objects is deleted, the reference +** count on this object is decremented. When it reaches 0, the destructor +** is invoked and the FuncDestructor structure freed. +*/ +struct FuncDestructor { + int nRef; + void (*xDestroy)(void *); + void *pUserData; +}; + +/* +** Possible values for FuncDef.flags +*/ +#define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */ +#define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */ +#define SQLITE_FUNC_EPHEM 0x04 /* Ephemeral. Delete with VDBE */ +#define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */ +#define SQLITE_FUNC_PRIVATE 0x10 /* Allowed for internal use only */ +#define SQLITE_FUNC_COUNT 0x20 /* Built-in count(*) aggregate */ +#define SQLITE_FUNC_COALESCE 0x40 /* Built-in coalesce() or ifnull() function */ + +/* +** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are +** used to create the initializers for the FuncDef structures. +** +** FUNCTION(zName, nArg, iArg, bNC, xFunc) +** Used to create a scalar function definition of a function zName +** implemented by C function xFunc that accepts nArg arguments. The +** value passed as iArg is cast to a (void*) and made available +** as the user-data (sqlite3_user_data()) for the function. If +** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set. +** +** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal) +** Used to create an aggregate function definition implemented by +** the C functions xStep and xFinal. The first four parameters +** are interpreted in the same way as the first 4 parameters to +** FUNCTION(). +** +** LIKEFUNC(zName, nArg, pArg, flags) +** Used to create a scalar function definition of a function zName +** that accepts nArg arguments and is implemented by a call to C +** function likeFunc. Argument pArg is cast to a (void *) and made +** available as the function user-data (sqlite3_user_data()). The +** FuncDef.flags variable is set to the value passed as the flags +** parameter. +*/ +#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ + {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} +#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ + {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \ + pArg, 0, xFunc, 0, 0, #zName, 0, 0} +#define LIKEFUNC(zName, nArg, arg, flags) \ + {nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} +#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ + {nArg, SQLITE_UTF8, nc*SQLITE_FUNC_NEEDCOLL, \ + SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} + +/* +** All current savepoints are stored in a linked list starting at +** sqlite3.pSavepoint. The first element in the list is the most recently +** opened savepoint. Savepoints are added to the list by the vdbe +** OP_Savepoint instruction. +*/ +struct Savepoint { + char *zName; /* Savepoint name (nul-terminated) */ + i64 nDeferredCons; /* Number of deferred fk violations */ + Savepoint *pNext; /* Parent savepoint (if any) */ +}; + +/* +** The following are used as the second parameter to sqlite3Savepoint(), +** and as the P1 argument to the OP_Savepoint instruction. +*/ +#define SAVEPOINT_BEGIN 0 +#define SAVEPOINT_RELEASE 1 +#define SAVEPOINT_ROLLBACK 2 + + +/* +** Each SQLite module (virtual table definition) is defined by an +** instance of the following structure, stored in the sqlite3.aModule +** hash table. +*/ +struct Module { + const sqlite3_module *pModule; /* Callback pointers */ + const char *zName; /* Name passed to create_module() */ + void *pAux; /* pAux passed to create_module() */ + void (*xDestroy)(void *); /* Module destructor function */ +}; + +/* +** information about each column of an SQL table is held in an instance +** of this structure. +*/ +struct Column { + char *zName; /* Name of this column */ + Expr *pDflt; /* Default value of this column */ + char *zDflt; /* Original text of the default value */ + char *zType; /* Data type for this column */ + char *zColl; /* Collating sequence. If NULL, use the default */ + u8 notNull; /* True if there is a NOT NULL constraint */ + u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */ + char affinity; /* One of the SQLITE_AFF_... values */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + u8 isHidden; /* True if this column is 'hidden' */ +#endif +}; + +/* +** A "Collating Sequence" is defined by an instance of the following +** structure. Conceptually, a collating sequence consists of a name and +** a comparison routine that defines the order of that sequence. +** +** There may two separate implementations of the collation function, one +** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that +** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine +** native byte order. When a collation sequence is invoked, SQLite selects +** the version that will require the least expensive encoding +** translations, if any. +** +** The CollSeq.pUser member variable is an extra parameter that passed in +** as the first argument to the UTF-8 comparison function, xCmp. +** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function, +** xCmp16. +** +** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the +** collating sequence is undefined. Indices built on an undefined +** collating sequence may not be read or written. +*/ +struct CollSeq { + char *zName; /* Name of the collating sequence, UTF-8 encoded */ + u8 enc; /* Text encoding handled by xCmp() */ + u8 type; /* One of the SQLITE_COLL_... values below */ + void *pUser; /* First argument to xCmp() */ + int (*xCmp)(void*,int, const void*, int, const void*); + void (*xDel)(void*); /* Destructor for pUser */ +}; + +/* +** Allowed values of CollSeq.type: +*/ +#define SQLITE_COLL_BINARY 1 /* The default memcmp() collating sequence */ +#define SQLITE_COLL_NOCASE 2 /* The built-in NOCASE collating sequence */ +#define SQLITE_COLL_REVERSE 3 /* The built-in REVERSE collating sequence */ +#define SQLITE_COLL_USER 0 /* Any other user-defined collating sequence */ + +/* +** A sort order can be either ASC or DESC. +*/ +#define SQLITE_SO_ASC 0 /* Sort in ascending order */ +#define SQLITE_SO_DESC 1 /* Sort in ascending order */ + +/* +** Column affinity types. +** +** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and +** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve +** the speed a little by numbering the values consecutively. +** +** But rather than start with 0 or 1, we begin with 'a'. That way, +** when multiple affinity types are concatenated into a string and +** used as the P4 operand, they will be more readable. +** +** Note also that the numeric types are grouped together so that testing +** for a numeric type is a single comparison. +*/ +#define SQLITE_AFF_TEXT 'a' +#define SQLITE_AFF_NONE 'b' +#define SQLITE_AFF_NUMERIC 'c' +#define SQLITE_AFF_INTEGER 'd' +#define SQLITE_AFF_REAL 'e' + +#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) + +/* +** The SQLITE_AFF_MASK values masks off the significant bits of an +** affinity value. +*/ +#define SQLITE_AFF_MASK 0x67 + +/* +** Additional bit values that can be ORed with an affinity without +** changing the affinity. +*/ +#define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */ +#define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */ +#define SQLITE_NULLEQ 0x80 /* NULL=NULL */ + +/* +** An object of this type is created for each virtual table present in +** the database schema. +** +** If the database schema is shared, then there is one instance of this +** structure for each database connection (sqlite3*) that uses the shared +** schema. This is because each database connection requires its own unique +** instance of the sqlite3_vtab* handle used to access the virtual table +** implementation. sqlite3_vtab* handles can not be shared between +** database connections, even when the rest of the in-memory database +** schema is shared, as the implementation often stores the database +** connection handle passed to it via the xConnect() or xCreate() method +** during initialization internally. This database connection handle may +** then be used by the virtual table implementation to access real tables +** within the database. So that they appear as part of the callers +** transaction, these accesses need to be made via the same database +** connection as that used to execute SQL operations on the virtual table. +** +** All VTable objects that correspond to a single table in a shared +** database schema are initially stored in a linked-list pointed to by +** the Table.pVTable member variable of the corresponding Table object. +** When an sqlite3_prepare() operation is required to access the virtual +** table, it searches the list for the VTable that corresponds to the +** database connection doing the preparing so as to use the correct +** sqlite3_vtab* handle in the compiled query. +** +** When an in-memory Table object is deleted (for example when the +** schema is being reloaded for some reason), the VTable objects are not +** deleted and the sqlite3_vtab* handles are not xDisconnect()ed +** immediately. Instead, they are moved from the Table.pVTable list to +** another linked list headed by the sqlite3.pDisconnect member of the +** corresponding sqlite3 structure. They are then deleted/xDisconnected +** next time a statement is prepared using said sqlite3*. This is done +** to avoid deadlock issues involving multiple sqlite3.mutex mutexes. +** Refer to comments above function sqlite3VtabUnlockList() for an +** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect +** list without holding the corresponding sqlite3.mutex mutex. +** +** The memory for objects of this type is always allocated by +** sqlite3DbMalloc(), using the connection handle stored in VTable.db as +** the first argument. +*/ +struct VTable { + sqlite3 *db; /* Database connection associated with this table */ + Module *pMod; /* Pointer to module implementation */ + sqlite3_vtab *pVtab; /* Pointer to vtab instance */ + int nRef; /* Number of pointers to this structure */ + u8 bConstraint; /* True if constraints are supported */ + int iSavepoint; /* Depth of the SAVEPOINT stack */ + VTable *pNext; /* Next in linked list (see above) */ +}; + +/* +** Each SQL table is represented in memory by an instance of the +** following structure. +** +** Table.zName is the name of the table. The case of the original +** CREATE TABLE statement is stored, but case is not significant for +** comparisons. +** +** Table.nCol is the number of columns in this table. Table.aCol is a +** pointer to an array of Column structures, one for each column. +** +** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of +** the column that is that key. Otherwise Table.iPKey is negative. Note +** that the datatype of the PRIMARY KEY must be INTEGER for this field to +** be set. An INTEGER PRIMARY KEY is used as the rowid for each row of +** the table. If a table has no INTEGER PRIMARY KEY, then a random rowid +** is generated for each row of the table. TF_HasPrimaryKey is set if +** the table has any PRIMARY KEY, INTEGER or otherwise. +** +** Table.tnum is the page number for the root BTree page of the table in the +** database file. If Table.iDb is the index of the database table backend +** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that +** holds temporary tables and indices. If TF_Ephemeral is set +** then the table is stored in a file that is automatically deleted +** when the VDBE cursor to the table is closed. In this case Table.tnum +** refers VDBE cursor number that holds the table open, not to the root +** page number. Transient tables are used to hold the results of a +** sub-query that appears instead of a real table name in the FROM clause +** of a SELECT statement. +*/ +struct Table { + char *zName; /* Name of the table or view */ + int iPKey; /* If not negative, use aCol[iPKey] as the primary key */ + int nCol; /* Number of columns in this table */ + Column *aCol; /* Information about each column */ + Index *pIndex; /* List of SQL indexes on this table. */ + int tnum; /* Root BTree node for this table (see note above) */ + tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */ + Select *pSelect; /* NULL for tables. Points to definition if a view. */ + u16 nRef; /* Number of pointers to this Table */ + u8 tabFlags; /* Mask of TF_* values */ + u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ + FKey *pFKey; /* Linked list of all foreign keys in this table */ + char *zColAff; /* String defining the affinity of each column */ +#ifndef SQLITE_OMIT_CHECK + Expr *pCheck; /* The AND of all CHECK constraints */ +#endif +#ifndef SQLITE_OMIT_ALTERTABLE + int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + VTable *pVTable; /* List of VTable objects. */ + int nModuleArg; /* Number of arguments to the module */ + char **azModuleArg; /* Text of all module args. [0] is module name */ +#endif + Trigger *pTrigger; /* List of triggers stored in pSchema */ + Schema *pSchema; /* Schema that contains this table */ + Table *pNextZombie; /* Next on the Parse.pZombieTab list */ +}; + +/* +** Allowed values for Tabe.tabFlags. +*/ +#define TF_Readonly 0x01 /* Read-only system table */ +#define TF_Ephemeral 0x02 /* An ephemeral table */ +#define TF_HasPrimaryKey 0x04 /* Table has a primary key */ +#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ +#define TF_Virtual 0x10 /* Is a virtual table */ +#define TF_NeedMetadata 0x20 /* aCol[].zType and aCol[].pColl missing */ + + + +/* +** Test to see whether or not a table is a virtual table. This is +** done as a macro so that it will be optimized out when virtual +** table support is omitted from the build. +*/ +#ifndef SQLITE_OMIT_VIRTUALTABLE +# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0) +# define IsHiddenColumn(X) ((X)->isHidden) +#else +# define IsVirtual(X) 0 +# define IsHiddenColumn(X) 0 +#endif + +/* +** Each foreign key constraint is an instance of the following structure. +** +** A foreign key is associated with two tables. The "from" table is +** the table that contains the REFERENCES clause that creates the foreign +** key. The "to" table is the table that is named in the REFERENCES clause. +** Consider this example: +** +** CREATE TABLE ex1( +** a INTEGER PRIMARY KEY, +** b INTEGER CONSTRAINT fk1 REFERENCES ex2(x) +** ); +** +** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2". +** +** Each REFERENCES clause generates an instance of the following structure +** which is attached to the from-table. The to-table need not exist when +** the from-table is created. The existence of the to-table is not checked. +*/ +struct FKey { + Table *pFrom; /* Table containing the REFERENCES clause (aka: Child) */ + FKey *pNextFrom; /* Next foreign key in pFrom */ + char *zTo; /* Name of table that the key points to (aka: Parent) */ + FKey *pNextTo; /* Next foreign key on table named zTo */ + FKey *pPrevTo; /* Previous foreign key on table named zTo */ + int nCol; /* Number of columns in this key */ + /* EV: R-30323-21917 */ + u8 isDeferred; /* True if constraint checking is deferred till COMMIT */ + u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */ + Trigger *apTrigger[2]; /* Triggers for aAction[] actions */ + struct sColMap { /* Mapping of columns in pFrom to columns in zTo */ + int iFrom; /* Index of column in pFrom */ + char *zCol; /* Name of column in zTo. If 0 use PRIMARY KEY */ + } aCol[1]; /* One entry for each of nCol column s */ +}; + +/* +** SQLite supports many different ways to resolve a constraint +** error. ROLLBACK processing means that a constraint violation +** causes the operation in process to fail and for the current transaction +** to be rolled back. ABORT processing means the operation in process +** fails and any prior changes from that one operation are backed out, +** but the transaction is not rolled back. FAIL processing means that +** the operation in progress stops and returns an error code. But prior +** changes due to the same operation are not backed out and no rollback +** occurs. IGNORE means that the particular row that caused the constraint +** error is not inserted or updated. Processing continues and no error +** is returned. REPLACE means that preexisting database rows that caused +** a UNIQUE constraint violation are removed so that the new insert or +** update can proceed. Processing continues and no error is reported. +** +** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys. +** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the +** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign +** key is set to NULL. CASCADE means that a DELETE or UPDATE of the +** referenced table row is propagated into the row that holds the +** foreign key. +** +** The following symbolic values are used to record which type +** of action to take. +*/ +#define OE_None 0 /* There is no constraint to check */ +#define OE_Rollback 1 /* Fail the operation and rollback the transaction */ +#define OE_Abort 2 /* Back out changes but do no rollback transaction */ +#define OE_Fail 3 /* Stop the operation but leave all prior changes */ +#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */ +#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */ + +#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */ +#define OE_SetNull 7 /* Set the foreign key value to NULL */ +#define OE_SetDflt 8 /* Set the foreign key value to its default */ +#define OE_Cascade 9 /* Cascade the changes */ + +#define OE_Default 99 /* Do whatever the default action is */ + + +/* +** An instance of the following structure is passed as the first +** argument to sqlite3VdbeKeyCompare and is used to control the +** comparison of the two index keys. +*/ +struct KeyInfo { + sqlite3 *db; /* The database connection */ + u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ + u16 nField; /* Number of entries in aColl[] */ + u8 *aSortOrder; /* Sort order for each column. May be NULL */ + CollSeq *aColl[1]; /* Collating sequence for each term of the key */ +}; + +/* +** An instance of the following structure holds information about a +** single index record that has already been parsed out into individual +** values. +** +** A record is an object that contains one or more fields of data. +** Records are used to store the content of a table row and to store +** the key of an index. A blob encoding of a record is created by +** the OP_MakeRecord opcode of the VDBE and is disassembled by the +** OP_Column opcode. +** +** This structure holds a record that has already been disassembled +** into its constituent fields. +*/ +struct UnpackedRecord { + KeyInfo *pKeyInfo; /* Collation and sort-order information */ + u16 nField; /* Number of entries in apMem[] */ + u16 flags; /* Boolean settings. UNPACKED_... below */ + i64 rowid; /* Used by UNPACKED_PREFIX_SEARCH */ + Mem *aMem; /* Values */ +}; + +/* +** Allowed values of UnpackedRecord.flags +*/ +#define UNPACKED_NEED_FREE 0x0001 /* Memory is from sqlite3Malloc() */ +#define UNPACKED_NEED_DESTROY 0x0002 /* apMem[]s should all be destroyed */ +#define UNPACKED_IGNORE_ROWID 0x0004 /* Ignore trailing rowid on key1 */ +#define UNPACKED_INCRKEY 0x0008 /* Make this key an epsilon larger */ +#define UNPACKED_PREFIX_MATCH 0x0010 /* A prefix match is considered OK */ +#define UNPACKED_PREFIX_SEARCH 0x0020 /* A prefix match is considered OK */ + +/* +** Each SQL index is represented in memory by an +** instance of the following structure. +** +** The columns of the table that are to be indexed are described +** by the aiColumn[] field of this structure. For example, suppose +** we have the following table and index: +** +** CREATE TABLE Ex1(c1 int, c2 int, c3 text); +** CREATE INDEX Ex2 ON Ex1(c3,c1); +** +** In the Table structure describing Ex1, nCol==3 because there are +** three columns in the table. In the Index structure describing +** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed. +** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the +** first column to be indexed (c3) has an index of 2 in Ex1.aCol[]. +** The second column to be indexed (c1) has an index of 0 in +** Ex1.aCol[], hence Ex2.aiColumn[1]==0. +** +** The Index.onError field determines whether or not the indexed columns +** must be unique and what to do if they are not. When Index.onError=OE_None, +** it means this is not a unique index. Otherwise it is a unique index +** and the value of Index.onError indicate the which conflict resolution +** algorithm to employ whenever an attempt is made to insert a non-unique +** element. +*/ +struct Index { + char *zName; /* Name of this index */ + int nColumn; /* Number of columns in the table used by this index */ + int *aiColumn; /* Which columns are used by this index. 1st is 0 */ + tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */ + Table *pTable; /* The SQL table being indexed */ + int tnum; /* Page containing root of this index in database file */ + u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ + u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ + u8 bUnordered; /* Use this index for == or IN queries only */ + char *zColAff; /* String defining the affinity of each column */ + Index *pNext; /* The next index associated with the same table */ + Schema *pSchema; /* Schema containing this index */ + u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */ + char **azColl; /* Array of collation sequence names for index */ +#ifdef SQLITE_ENABLE_STAT3 + int nSample; /* Number of elements in aSample[] */ + tRowcnt avgEq; /* Average nEq value for key values not in aSample */ + IndexSample *aSample; /* Samples of the left-most key */ +#endif +}; + +/* +** Each sample stored in the sqlite_stat3 table is represented in memory +** using a structure of this type. See documentation at the top of the +** analyze.c source file for additional information. +*/ +struct IndexSample { + union { + char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */ + double r; /* Value if eType is SQLITE_FLOAT */ + i64 i; /* Value if eType is SQLITE_INTEGER */ + } u; + u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */ + int nByte; /* Size in byte of text or blob. */ + tRowcnt nEq; /* Est. number of rows where the key equals this sample */ + tRowcnt nLt; /* Est. number of rows where key is less than this sample */ + tRowcnt nDLt; /* Est. number of distinct keys less than this sample */ +}; + +/* +** Each token coming out of the lexer is an instance of +** this structure. Tokens are also used as part of an expression. +** +** Note if Token.z==0 then Token.dyn and Token.n are undefined and +** may contain random values. Do not make any assumptions about Token.dyn +** and Token.n when Token.z==0. +*/ +struct Token { + const char *z; /* Text of the token. Not NULL-terminated! */ + unsigned int n; /* Number of characters in this token */ +}; + +/* +** An instance of this structure contains information needed to generate +** code for a SELECT that contains aggregate functions. +** +** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a +** pointer to this structure. The Expr.iColumn field is the index in +** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate +** code for that node. +** +** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the +** original Select structure that describes the SELECT statement. These +** fields do not need to be freed when deallocating the AggInfo structure. +*/ +struct AggInfo { + u8 directMode; /* Direct rendering mode means take data directly + ** from source tables rather than from accumulators */ + u8 useSortingIdx; /* In direct mode, reference the sorting index rather + ** than the source table */ + int sortingIdx; /* Cursor number of the sorting index */ + int sortingIdxPTab; /* Cursor number of pseudo-table */ + ExprList *pGroupBy; /* The group by clause */ + int nSortingColumn; /* Number of columns in the sorting index */ + struct AggInfo_col { /* For each column used in source tables */ + Table *pTab; /* Source table */ + int iTable; /* Cursor number of the source table */ + int iColumn; /* Column number within the source table */ + int iSorterColumn; /* Column number in the sorting index */ + int iMem; /* Memory location that acts as accumulator */ + Expr *pExpr; /* The original expression */ + } *aCol; + int nColumn; /* Number of used entries in aCol[] */ + int nColumnAlloc; /* Number of slots allocated for aCol[] */ + int nAccumulator; /* Number of columns that show through to the output. + ** Additional columns are used only as parameters to + ** aggregate functions */ + struct AggInfo_func { /* For each aggregate function */ + Expr *pExpr; /* Expression encoding the function */ + FuncDef *pFunc; /* The aggregate function implementation */ + int iMem; /* Memory location that acts as accumulator */ + int iDistinct; /* Ephemeral table used to enforce DISTINCT */ + } *aFunc; + int nFunc; /* Number of entries in aFunc[] */ + int nFuncAlloc; /* Number of slots allocated for aFunc[] */ +}; + +/* +** The datatype ynVar is a signed integer, either 16-bit or 32-bit. +** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater +** than 32767 we have to make it 32-bit. 16-bit is preferred because +** it uses less memory in the Expr object, which is a big memory user +** in systems with lots of prepared statements. And few applications +** need more than about 10 or 20 variables. But some extreme users want +** to have prepared statements with over 32767 variables, and for them +** the option is available (at compile-time). +*/ +#if SQLITE_MAX_VARIABLE_NUMBER<=32767 +typedef i16 ynVar; +#else +typedef int ynVar; +#endif + +/* +** Each node of an expression in the parse tree is an instance +** of this structure. +** +** Expr.op is the opcode. The integer parser token codes are reused +** as opcodes here. For example, the parser defines TK_GE to be an integer +** code representing the ">=" operator. This same integer code is reused +** to represent the greater-than-or-equal-to operator in the expression +** tree. +** +** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB, +** or TK_STRING), then Expr.token contains the text of the SQL literal. If +** the expression is a variable (TK_VARIABLE), then Expr.token contains the +** variable name. Finally, if the expression is an SQL function (TK_FUNCTION), +** then Expr.token contains the name of the function. +** +** Expr.pRight and Expr.pLeft are the left and right subexpressions of a +** binary operator. Either or both may be NULL. +** +** Expr.x.pList is a list of arguments if the expression is an SQL function, +** a CASE expression or an IN expression of the form " IN (, ...)". +** Expr.x.pSelect is used if the expression is a sub-select or an expression of +** the form " IN (SELECT ...)". If the EP_xIsSelect bit is set in the +** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is +** valid. +** +** An expression of the form ID or ID.ID refers to a column in a table. +** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is +** the integer cursor number of a VDBE cursor pointing to that table and +** Expr.iColumn is the column number for the specific column. If the +** expression is used as a result in an aggregate SELECT, then the +** value is also stored in the Expr.iAgg column in the aggregate so that +** it can be accessed after all aggregates are computed. +** +** If the expression is an unbound variable marker (a question mark +** character '?' in the original SQL) then the Expr.iTable holds the index +** number for that variable. +** +** If the expression is a subquery then Expr.iColumn holds an integer +** register number containing the result of the subquery. If the +** subquery gives a constant result, then iTable is -1. If the subquery +** gives a different answer at different times during statement processing +** then iTable is the address of a subroutine that computes the subquery. +** +** If the Expr is of type OP_Column, and the table it is selecting from +** is a disk table or the "old.*" pseudo-table, then pTab points to the +** corresponding table definition. +** +** ALLOCATION NOTES: +** +** Expr objects can use a lot of memory space in database schema. To +** help reduce memory requirements, sometimes an Expr object will be +** truncated. And to reduce the number of memory allocations, sometimes +** two or more Expr objects will be stored in a single memory allocation, +** together with Expr.zToken strings. +** +** If the EP_Reduced and EP_TokenOnly flags are set when +** an Expr object is truncated. When EP_Reduced is set, then all +** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees +** are contained within the same memory allocation. Note, however, that +** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately +** allocated, regardless of whether or not EP_Reduced is set. +*/ +struct Expr { + u8 op; /* Operation performed by this node */ + char affinity; /* The affinity of the column or 0 if not a column */ + u16 flags; /* Various flags. EP_* See below */ + union { + char *zToken; /* Token value. Zero terminated and dequoted */ + int iValue; /* Non-negative integer value if EP_IntValue */ + } u; + + /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no + ** space is allocated for the fields below this point. An attempt to + ** access them will result in a segfault or malfunction. + *********************************************************************/ + + Expr *pLeft; /* Left subnode */ + Expr *pRight; /* Right subnode */ + union { + ExprList *pList; /* Function arguments or in " IN ( IN (