From: Alex Smith Date: Sat, 31 Mar 2007 18:38:06 +0000 (-0400) Subject: Alex Smith's 0.26 release. Nominal release date April 1st 2007. X-Git-Tag: 0.26 X-Git-Url: http://thyrsus.com/gitweb/?a=commitdiff_plain;h=d484f0c4e06f3dcc195ac169d5b9ff6685038720;p=intercal.git Alex Smith's 0.26 release. Nominal release date April 1st 2007. (This is a retrospective comment.) --- diff --git a/BUGS b/BUGS deleted file mode 100644 index 2524d44..0000000 --- a/BUGS +++ /dev/null @@ -1,66 +0,0 @@ - BUGS - -There are still some known bugs in INTERCAL (and no doubt many we don't even -suspect as yet). The following list accumulates current bug reports and -TO DO agenda items through the current release. - -ESR = Eric S. Raymond -SS = Steve Swales -LHH = Louis Howell -BLR = Brian Raiter -AIS = Alex Smith - -1) (ESR) INTERCAL would be intrinsically a crock even if it worked right. - -2) (BLR) I have hacked up a fix to the problem with line numbers being off - due to statements sharing/spanning lines. The parser now stores the - starting line number for all tuples, not just the splatted - ones. Not only does this give synchronized lines in the comments in - the degenerated C code, but run-time error messages are just as - reliable as the parse/compile-time ones. The line number in the - error message is actually the line number of the next statement - (e.g., if the next statement is on the same line, the line number - of both statements will be used). - - Note that I said "just as reliable," as opposed to "fully - reliable". Since the lexer doesn't know where the line ends until - after it's already parsed the preamble (DO-PLEASE combo, line - label, oh-oh-seven number, etc) of the following line, it actually - stores as the starting line number the first non-whitespace of the - statement proper. So if a statement has its preamble on one line - and the rest of it on the next, the preamble will be beheaded. - - Still, it's a vast improvement, and as LHH pointed out, it's not - going to get much better without writing a preprocessing lexer that - can actually separate out the statements before any real parsing - begins. Until someone wants to do that, this will do nicely, I think. - - As a side bonus, splatting now shows the entire statement. (Er, - except when the statement both spans and shares a line. If a multi- - line statement ends on the same line as the beginning of the next - statement, the last part will get truncated. Again, not a case we - want to be encouraging people to explore anyway.) - -3) (BLR) Interleave does not check the type of its arguments. The manual - insinuates that interleaving 32-bit values should result in error 533; - instead, C-INTERCAL silently truncates them to 16 bits. Unfortunately, - the modified behavior of select's return type depends on this, so - there's not much we can do about it as things stand. - -4) (AIS) In multithread programs, a thread doing the equivalent of - (10) DO COME FROM (10) will cause the entire program to get stuck in - an infinite loop, because all COMING FROM a statement counts as part - of that statement, and all statements are atomic. - -5) (AIS) In a multithreaded backtracking program, you can't fork a thread - which has backtrack points in it. The problem is that backtracking past - the fork from one but not both of the new threads would lead to a - situation in which the fork hadn't happened in one possible route from - the fork, but had in the other. This is clearly absurd, even by the - standards of INTERCAL. - - TO DO - -1. (ESR) Add more optimization templates, esp. idioms for +, -, *, /. - -2. (ESR) Forget this @!%$#! crock and take a long vacation. diff --git a/BUGS.txt b/BUGS.txt new file mode 100644 index 0000000..4aabff4 --- /dev/null +++ b/BUGS.txt @@ -0,0 +1,65 @@ + BUGS + +There are still some known bugs in INTERCAL (and no doubt many we don't even +suspect as yet). The following list accumulates current bug reports and +TO DO agenda items through the current release. + +ESR = Eric S. Raymond +SS = Steve Swales +LHH = Louis Howell +BLR = Brian Raiter +AIS = Alex Smith + +1) (ESR) INTERCAL would be intrinsically a crock even if it worked right. + +2) (BLR) I have hacked up a fix to the problem with line numbers being off + due to statements sharing/spanning lines. The parser now stores the + starting line number for all tuples, not just the splatted + ones. Not only does this give synchronized lines in the comments in + the degenerated C code, but run-time error messages are just as + reliable as the parse/compile-time ones. The line number in the + error message is actually the line number of the next statement + (e.g., if the next statement is on the same line, the line number + of both statements will be used). + + Note that I said "just as reliable," as opposed to "fully + reliable". Since the lexer doesn't know where the line ends until + after it's already parsed the preamble (DO-PLEASE combo, line + label, oh-oh-seven number, etc) of the following line, it actually + stores as the starting line number the first non-whitespace of the + statement proper. So if a statement has its preamble on one line + and the rest of it on the next, the preamble will be beheaded. + + Still, it's a vast improvement, and as LHH pointed out, it's not + going to get much better without writing a preprocessing lexer that + can actually separate out the statements before any real parsing + begins. Until someone wants to do that, this will do nicely, I think. + + As a side bonus, splatting now shows the entire statement. (Er, + except when the statement both spans and shares a line. If a multi- + line statement ends on the same line as the beginning of the next + statement, the last part will get truncated. Again, not a case we + want to be encouraging people to explore anyway.) + +3) (BLR) Interleave does not check the type of its arguments. The manual + insinuates that interleaving 32-bit values should result in error 533; + instead, C-INTERCAL silently truncates them to 16 bits. Unfortunately, + the modified behavior of select's return type depends on this, so + there's not much we can do about it as things stand. + +4) (AIS) In multithread programs, a thread doing the equivalent of + (10) DO COME FROM (10) will cause the entire program to get stuck in + an infinite loop, because all COMING FROM a statement counts as part + of that statement, and all statements are atomic. + +5) (AIS) Reverse assignments (those with the expression on the left) + are very unlikely to work in bases other than 2. + +6) (AIS) Most of the features new in 0.26, and many in 0.25, haven't + been documented. (This is partly because I can't get groff to work.) + + TO DO + +1. (ESR) Add more optimization templates, esp. idioms for +, -, *, /. + +2. (ESR) Forget this @!%$#! crock and take a long vacation. diff --git a/COPYING b/COPYING deleted file mode 100644 index deb9da3..0000000 --- a/COPYING +++ /dev/null @@ -1,278 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, 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. diff --git a/COPYING.txt b/COPYING.txt new file mode 100644 index 0000000..deb9da3 --- /dev/null +++ b/COPYING.txt @@ -0,0 +1,278 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, 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. diff --git a/MANIFEST.txt b/MANIFEST.txt new file mode 100644 index 0000000..7847e36 --- /dev/null +++ b/MANIFEST.txt @@ -0,0 +1,186 @@ +.: +BUGS.txt +COPYING.txt +MANIFEST.txt +Makefile.in +NEWS.txt +README.txt +bin +cleanick.bat +cleanick.sh +config.log +config.status +configure.ac +configure.sh +districk.bat +districk.sh +djfix.bat +djfix.sh +doc +etc +ickspec +ickspec.in +include +install.sh +lib +makeick.bat +makeick.sh +pit +src +temp + +./bin: + +./doc: +Makefile +READ.ME +THEORY +chip.spec +intercal.mm + +./etc: +intercal.el + +./include: + +./lib: + +./pit: +CATALOG +Makefile +beer.doc +beer.i +blinkers +bubble.doc +bubble.i +change.doc +change.i +delta.fft +fft.doc +fft.i +flonck.doc +flonck.i +glider +gun +hail_mary.3i +hail_mary.doc +icat.i +iching.doc +iching1.i +iching2.i +ins.doc +ins.i +lib +life.doc +life.i +life2.doc +life2.i +pass.i +pi.doc +pi.i +pow.i +primes.doc +primes.i +quine.i +random.doc +random.i +random2.i +rot13.doc +rot13.i +rot13b.doc +rot13b.i +sample.i +sort.i +syslib.i +t_tet +tests +tophat.fft +tpk.doc +tpk.i +yapp.doc +yapp.i + +./pit/lib: +1910.doc +floatlib.doc +floatlib.i +lib2.doc +lib2.i +numio.doc +numio.i +plus.i +syslib-orig.i +syslib.3i +syslib.4i +syslib.5i +syslib.6i +syslib.7i +syslib.doc +syslib.i +syslib3-7.doc + +./pit/tests: +ais1.i +ais2.i +arrtest.doc +arrtest.i +compucome.i +count.3i +count.doc +hello.i +iogerunds.doc +iogerunds.i +knuth.i +limits.3i +limits.i +onceagain.i +permute.doc +permute.i +pictest.i +sink.doc +sink.i +test1.i +test16bit.i +test2.i +testarray.i +testcf.i +testi18n.i +testlib2.i +testonce.i +testops.3i +testops.5i +testsplat.i +version.4i +version.doc + +./src: +abcess.h +arrgghh.c +cesspool.c +coopt.sh +dekludge.c +feh.h +feh2.c +fiddle.c +fiddle.h +ick-wrap.c +ick.bat +ick.h +lexer.l +lose.c +lose.h +numerals.c +parser.y +perpet.c +pick1.h +pick2.h +pickwrap.c +sizes.h +unravel.c +yuk.c +yuk.h + +./temp: +lexer.c +parser.c +parser.h diff --git a/Makefile.in b/Makefile.in index 9a68945..6acd911 100644 --- a/Makefile.in +++ b/Makefile.in @@ -34,10 +34,10 @@ DESTDIR= # If you want to delete or move the distribution files, then you will have to move COPYING # to another directory; otherwise, you can aim this at COPYING. # It's also possible to aim this at a copy of COPYING from another GPL program. -copyloc = ${DESTDIR}${datadir}/COPYING +copyloc = ${DESTDIR}${datadir}/COPYING.txt CC = @CC@ -CFLAGS = @CFLAGS@ -DICKINCLUDEDIR=\"$(incdir)\" -DICKLIBDIR=\"$(datadir)\" -DICKBINDIR=\"$(bindir)\" -DYYDEBUG -DYUKCOPYLOC=\"$(copyloc)\" +CFLAGS = @CFLAGS@ -DICKINCLUDEDIR=\"$(incdir)\" -DICKLIBDIR=\"$(datadir)\" -DICKBINDIR=\"$(bindir)\" -DYYDEBUG -DYUKCOPYLOC=\"$(copyloc)\" -O2 -W -Wall -I./src -I./temp LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXFLAGS= @@ -46,74 +46,103 @@ YACCFLAGS = -d # -t LOADLIBS = @LIBS@ @INTLLIBS@ @LEXLIB@ -CSOURCES = ick.y lexer.l feh.c lose.c fiddle.c perpetrate.c unravel.c -ISOURCES = cesspool.c arrgghh.c ick-wrap.c numerals.c -YSOURCES = yuk.c -HEADERS = ick.h lose.h sizes.h abcess.h fiddle.h feh.h yuk.h +CSOURCES = src/parser.y src/lexer.l src/feh2.c src/dekludge.c src/lose.c src/fiddle.c src/perpet.c src/unravel.c +ISOURCES = src/cesspool.c src/arrgghh.c src/ick-wrap.c src/numerals.c +YSOURCES = src/yuk.c +HEADERS = src/ick.h src/lose.h src/sizes.h src/abcess.h src/fiddle.h src/feh.h src/yuk.h BUILD = Makefile.in Makefile configure.ac configure config.h.in intercal.spec.in intercal.spec install.sh -MISC = intercal.el coopt.sh -DOCS = BUGS COPYING NEWS README +MISC = etc/intercal.el src/coopt.sh +DOCS = BUGS.txt COPYING.txt NEWS.txt README.txt SOURCES = $(CSOURCES) $(ISOURCES) $(YSOURCES) $(HEADERS) $(BUILD) $(MISC) $(DOCS) pit doc -all: ick libick.a libickmt.a libyuk.a +all: bin/ick lib/libick.a lib/libickmt.a lib/libyuk.a ial -copycopy: COPYING +ial: src/fiddle.h src/abcess.h src/lose.h src/yuk.h src/ick-wrap.c src/pickwrap.c src/coopt.sh pit/lib/syslib.i + -cp src/fiddle.h include/fiddle.h + -cp src/abcess.h include/abcess.h + -cp src/lose.h include/lose.h + -cp src/yuk.h include/yuk.h + -cp pit/lib/syslib.i pit/lib/syslib.?i include + -cp src/ick-wrap.c lib/ick-wrap.c + -cp src/pickwrap.c lib/pickwrap.c + -cp src/coopt.sh lib/coopt.sh + +copycopy: COPYING.txt -mkdir $(DESTDIR)$(datadir) - -if cp $(copyloc) /dev/null ; then : ; else cp COPYING $(copyloc) ; fi + -if cp $(copyloc) /dev/null ; then : ; else cp COPYING.txt $(copyloc) ; fi checkcopy: @echo If the following line fails, change \"copyloc\" in your makefile. cp $(copyloc) /dev/null -ick: ick.o lexer.o feh.o lose.o fiddle.o perpetrate.o - $(CC) perpetrate.o ick.o lexer.o feh.o lose.o fiddle.o $(LDFLAGS) -o ick +bin/ick: temp/parser.o temp/lexer.o temp/feh2.o temp/dekludge.o temp/lose.o temp/fiddle.o temp/perpet.o + $(CC) temp/perpet.o temp/ick.o temp/lexer.o temp/feh2.o temp/dekludge.o temp/lose.o temp/fiddle.o $(LDFLAGS) -o bin/ick -y.tab.h ick.c: ick.y ick.h sizes.h feh.h lose.h - $(YACC) -d $(YACCFLAGS) ick.y - mv y.tab.c ick.c +temp/parser.h temp/parser.c: src/parser.y src/ick.h src/sizes.h src/feh.h src/lose.h + $(YACC) -d $(YACCFLAGS) src/parser.y + -rm temp/parser.c + mv y.tab.c temp/parser.c + -rm temp/parser.h + mv y.tab.h temp/parser.h -lexer.c: lexer.l ick.h lose.h - $(LEX) $(LEXFLAGS) lexer.l - mv lex.yy.c lexer.c +temp/lexer.c: src/lexer.l src/ick.h src/lose.h + $(LEX) $(LEXFLAGS) src/lexer.l + -rm temp/lexer.c + mv lex.yy.c temp/lexer.c # Uncomment the following if using a stock lex # LEXLIBS = -ll -lextest: y.tab.h lexer.c ick.h lose.o - $(CC) -DMAIN lexer.c lose.o $(LEXLIBS) -o lextest - -ick.o: ick.c ick.h feh.h lose.h sizes.h -lexer.o: lexer.c y.tab.h ick.h lose.h -feh.o: feh.c feh.h y.tab.h ick.h fiddle.h lose.h sizes.h -perpetrate.o: perpetrate.c y.tab.h ick.h lose.h sizes.h -cesspool.o: cesspool.c numerals.c abcess.h lose.h sizes.h -unravel.o: unravel.c abcess.h lose.h sizes.h -lose.o: lose.h -fiddle.o: fiddle.h sizes.h -yuk.o: checkcopy yuk.h lose.h sizes.h abcess.h - -libick.a: cesspool.o lose.o fiddle.o arrgghh.o - ar cr libick.a cesspool.o lose.o fiddle.o arrgghh.o - -ranlib libick.a - -libickmt.a: cesspool.o unravel.o lose.o fiddle.o arrgghh.o - ar cr libickmt.a cesspool.o unravel.o lose.o fiddle.o arrgghh.o +bin/lextest: temp/parser.h src/lexer.c src/ick.h temp/lose.o + $(CC) -DMAIN src/lexer.c src/lose.o $(LEXLIBS) -o bin/lextest + +temp/parser.o: temp/parser.c src/ick.h src/feh.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/ick.o temp/parser.c +temp/lexer.o: temp/lexer.c temp/parser.h src/ick.h src/lose.h + $(CC) $(CFLAGS) -c -o temp/lexer.o temp/lexer.c +temp/feh2.o: src/feh2.c src/feh.h temp/parser.h src/ick.h src/fiddle.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/feh2.o src/feh2.c +temp/dekludge.o: src/dekludge.c src/feh.h temp/parser.h src/ick.h src/fiddle.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/dekludge.o src/dekludge.c +temp/perpet.o: src/perpet.c temp/parser.h src/ick.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/perpet.o src/perpet.c +temp/cesspool.o: src/cesspool.c src/abcess.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/cesspool.o src/cesspool.c +temp/numerals.o: src/numerals.c src/abcess.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/numerals.o src/numerals.c +temp/unravel.o: src/unravel.c src/abcess.h src/lose.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/unravel.o src/unravel.c +temp/lose.o: src/lose.c src/lose.h + $(CC) $(CFLAGS) -c -o temp/lose.o src/lose.c +temp/fiddle.o: src/fiddle.c src/fiddle.h src/sizes.h + $(CC) $(CFLAGS) -c -o temp/fiddle.o src/fiddle.c +temp/arrgghh.o: src/arrgghh.c + $(CC) $(CFLAGS) -c -o temp/arrgghh.o src/arrgghh.c +temp/yuk.o: checkcopy src/yuk.h src/lose.h src/sizes.h src/abcess.h + $(CC) $(CFLAGS) -c -o temp/yuk.o src/yuk.c + +lib/libick.a: temp/cesspool.o temp/numerals.o temp/lose.o temp/fiddle.o temp/arrgghh.o + ar cr lib/libick.a temp/cesspool.o temp/numerals.o temp/lose.o temp/fiddle.o temp/arrgghh.o + -ranlib lib/libick.a + +lib/libickmt.a: temp/cesspool.o temp/numerals.o temp/unravel.o temp/lose.o temp/fiddle.o temp/arrgghh.o + ar cr lib/libickmt.a temp/cesspool.o temp/numerals.o temp/unravel.o temp/lose.o temp/fiddle.o temp/arrgghh.o -ranlib libickmt.a -libyuk.a: yuk.o - ar cr libyuk.a yuk.o - -ranlib libyuk.a +lib/libyuk.a: temp/yuk.o + ar cr lib/libyuk.a temp/yuk.o + -ranlib lib/libyuk.a install: copycopy all - cp ick $(DESTDIR)$(bindir) - cp libick.a $(DESTDIR)$(libdir) - cp libickmt.a $(DESTDIR)$(libdir) - cp libyuk.a $(DESTDIR)$(libdir) + cp bin/ick $(DESTDIR)$(bindir) + cp lib/libick.a $(DESTDIR)$(libdir) + cp lib/libickmt.a $(DESTDIR)$(libdir) + cp lib/libyuk.a $(DESTDIR)$(libdir) -mkdir -p $(DESTDIR)$(incdir) - cp lose.h abcess.h fiddle.h yuk.h $(DESTDIR)$(incdir) + cp src/lose.h src/abcess.h src/fiddle.h src/yuk.h $(DESTDIR)$(incdir) -mkdir $(DESTDIR)$(datadir) (cp -r pit $(DESTDIR)$(datadir)) - cp ick-wrap.c $(DESTDIR)$(datadir) - cp coopt.sh $(DESTDIR)$(bindir) + cp src/ick-wrap.c $(DESTDIR)$(datadir) + cp etc/coopt.sh $(DESTDIR)$(bindir) uninstall: rm -f $(DESTDIR)$(bindir)/ick $(DESTDIR)$(libdir)/libick.a @@ -124,15 +153,16 @@ uninstall: TAGS: $(SOURCES) etags $(SOURCES) -dist: intercal-@PACKAGE_VERSION@.tar.gz +dist: ick-@PACKAGE_VERSION@.tgz -intercal-@PACKAGE_VERSION@.tar.gz: $(SOURCES) - @find $(SOURCES) -type f -print | grep -v RCS | sed s:^:intercal-@PACKAGE_VERSION@/: >MANIFEST - @(cd ..; ln -s intercal intercal-@PACKAGE_VERSION@) - (cd ..; tar -czvf intercal/intercal-@PACKAGE_VERSION@.tar.gz `cat intercal/MANIFEST`) - @(cd ..; rm intercal-@PACKAGE_VERSION@) +ick-@PACKAGE_VERSION@.tgz: $(SOURCES) + @find $(SOURCES) -type f -print | grep -v RCS | sed s:^:ick-@PACKAGE_VERSION@/: >MANIFEST.txt + @(cd ..; ln -s intercal ick-@PACKAGE_VERSION@) + (cd ..; tar -czvf intercal/ick-@PACKAGE_VERSION@.tgz `cat intercal/MANIFEST.txt`) + @(cd ..; rm ick-@PACKAGE_VERSION@) clean: - rm -f yacc.* y.tab.* y.output *~ *.[oa] lexer.c ick.c lextest ick - rm -f intercal-@PACKAGE_VERSION@.tar.gz intercal.spec core + rm -f temp/* bin/* lib/* include/* +distr: + rm -f temp/*.o bin/* lib/* include/* diff --git a/NEWS b/NEWS deleted file mode 100644 index bcacb53..0000000 --- a/NEWS +++ /dev/null @@ -1,381 +0,0 @@ - NEW IN THIS RELEASE - - Release ? (by ?) ? - -(All these changes were by AIS) - -1. Added support for computed ABSTAIN and TRY AGAIN. - -2. Added support for computed COME FROM. - -3. Added support for multithread programs. This includes ONCE and AGAIN, -which also work in singlethread programs. - -4. Expanded intercal.el to support Font Lock and some utilities for generating -INTERCAL-style constants. It also works with the compilation routines of Emacs -to compile INTERCAL programs without the need for make. Degenerated C code now -has a mode line to help with Emacs compatibility. - -5. Added a rudimentary debugger and profiler for singlethread programs. The -debugger's features include useful things like 'write out INTERCAL expression -in simpler terms' (which is only possible if -O is on). The profiler works -much like gcov, counting the length of time spent in and number of executions -of each command in the code. - -6. Changed searching for includes, libraries, syslib, skeleton. This is so that -non-root users, or people who want to evaluate ick, can do so more simply. The -compiler will search for the above files in the directory they should have been -installed in, the current directory, and the directory in which ick's -executable resides (in that order). Skeleton problems, in particular, seem to -have been a major problem for unfamiliar users trying out ick. - -7. Added several new test programs to the Pit. - -8. Greatly expanded the original optimizer (which optimizes expressions). It -can now recognize most of the idioms in syslib, and many idioms in other Pit -programs. Also added a new optimizer, to try to optimize program flow, which is -important because otherwise INTERCAL wouldn't have any rudimentary optimizers. -There is also the -F optimizer, which I hope will become infamous. It creates -object code which is close to maximally fast in some specialized situations, at -the expense of compile time (compilation can take a very long time when -F is -active) and object file size. I suggest checking its effect on primes.i. - -9. Fixed the grammar (again) in a spark/ears situation involving array -subscripts, after proving that the previous fixes weren't adequate. - -10. Added support for backtracking (MAYBE, GO AHEAD, GO BACK). Note that it is -possible for multithreading, backtracking, computed ABSTAIN, and computed COME -FROM to all be used simultaneously in the same program, to help maximize -obfuscation. - -11. Added an option (-l) for generating warnings. To prevent this actually being -useful, it is designed to generate far too many warnings, which all have to be -trawled through to find the important ones, and has no way to turn the -unimportant ones off. - -12. Added the +printflow and +mystery options for executing INTERCAL programs. -Note that it is not entirely obvious what either of them do (+printflow is a -debugging aid, but the output is somewhat obfuscated, and I am not going to -explain what +mystery does in this document). - - Release 0.24 (by Eric S. Raymond) 31 Dec 2003 - -1. RPMs can now be built by non-root users. - - Release 0.23 (by Eric S. Raymond) 9 Mar 2003 - -1. More fixes by Don Knuth. He found a bug in the type-propagation logic. - - Release 0.22 (by Eric S. Raymond) 4 Mar 2003 - -1. Incorporated a minor fix patch from Donald Knuth. Yes, *the* -Donald Knuth. Seems he found a weakness in the code for handling -comments, and fixed it to do multiline comments properly. He also made -some improvements to intercal.el, and contributed a test program. - -2. Updated build machinery. This package now uses GNU autoconf. - - Release 0.21 (by Eric S. Raymond) 30 July 2002 - -1. Jonathan Nieder sent a grammar fix for BLR's old bug #5 (a bad spark-ears -interaction.) - -2. Latin-1 support and makefile fixes from Magnus Bodin. - - Release 0.20 (by Eric S. Raymond) 16 September 1999 - - (The following changes are due to John Cowan ) - -1. In addition to Latin-1, UTF-8 is now acceptable in source code as well. -All the numerous currency symbols of Unicode (ISO 10646) can be used as -big-money alternatives in their UTF-8 format. Indeed, a random mixture of -Latin-1 and UTF-8 also works fine; this seems very much in the spirit of -Intercal. - -2. Intercal has now been localized for the Ancient Roman as well as the -Posix/C locale. You may input numbers in Latin and write Intercal programs -using Latin keywords. See lexer.l for a list of equivalences. - -3. The Makefile in the pit directory now works like a real Makefile, and -won't compile anything that's already been compiled. - - Release 0.19 (by Eric S. Raymond) 16 August 1998 - -1. Fixed a code-generation error in assignments from tail and hybrid -variables. (Error pointed out by Malcom Ryan.) - - Release 0.18 (by Eric S. Raymond) 29 April 1998 - -(The following changes are due to John Cowan ) - -1. The source code is now POSIXly correct. By making the POSIX -variable in the Makefile undefined, you can restore the use of -, but otherwise is now used. - -2. Latin-1 (ISO 8859-1) is now the standard input charset of C-INTERCAL. -This means that the change operator (0xA2) has returned as an alternative to -big money ($). Furthermore, the quid (0xA3) and zlotnik (0xA4) are also -acceptable. For those using Latin-9 (ISO 8859-15), the euro (0xA4) will also -work. ("Euro", like "ampersand", cannot be sillified further.) -New names have been added to intercal.mm. - -3. A fortiori, input of Volap\"uk digits may now be in Latin-1 or TeX format. - -4. Yacc is now deprecated in favor of bison; some old yaccs don't do proper -error recovery, and lines like "DO ~ ERROR" failed at compile time. - -5. Some minor portability bugs on systems where ptr_diff is not the same -as int were removed by casting expressions of the form (ptr - ptr) to int. - - Release 0.17 (by Eric S. Raymond) 27 Feb 1998 - -Incorporates a minor bug fix by Jeff Uphoff . - - Release 0.16 (by Brian Raiter and Eric S. Raymond) 26 May 1997 - -This is the 25th-anniversary release of INTERCAL. This language, conceived -in irony a quarter century ago today, has outlasted many more serious and -high-minded essays in computer language design. This fact should give us -pause to reflect, or possibly frighten the crap out of us. Or both. - -1. Corrected manual bugs. - -2. Fixed over-enthusiastic install production in the Makefile. - -3. DO PLEASE is no longer accepted (Brian Raiter pointed out that the - manual does not sanction it). - -4. Fixed various bugs in the optimizer. - -5. Incorporated fixes made by William Walter Patterson for bugs that - appeared when multiple files are given on the command line. - -(The following changes are due to Brian Raiter) - -6. The system library is now available for TriINTERCAL (all bases, 3 to 7). - The compiler has been updated to use the right library automagically. - -7. The error 774 feature has been brought into conformance with the - Princeton compiler. The odds are now a flat 10% (but still 0% with -b). - -8. The compiler has been modified to allocate memory dynamically, and - the hard-coded limits on program size and number of variables has - been removed. Programs are now only limited by the amount of - available memory. - -9. Array output now fflushes after outputting newlines. - -10. Two minor bug fixes: one in wimpmode input, which was clamping - input to the signed integer range, and one in politesse checking. - The latter was causing programs to be recognized as impolite only - if their ratio was less that one-sixth, not one-fifth. (Fixing this - also necessitated adding a few PLEASEs to pit/rot13.i.) - -11. Several new programs have been tossed into the pit. - - Release 0.15 (by Eric S. Raymond) 20 Jun 1996 - -1. Switched the INTERCAL manual master to mgm in order to be able to handle - section crossreferences properly. The manual has now been carefully - proofread against the paper version by ESR and seems to match. It's - also been independently proofread for typos by Brian Raiter. - -2. The optimizer now does complete analysis and evaluation of constant - expressions at compile time. - -3. Added optimization templates for ~, |, &, ^ expressions. Also added - |, &, ^ idioms to the system library, and documented them. - -(The following changes are due to Brian Raiter) - -4. Every one of the INTERCAL-72 messages is now emitted when appropriate. - including the previously un-emitted E000, E197, and E200 (and see below). - -5. A close reading (while proofing) of the sections of the manual on - error messages seems to indicate that splatted lines were only - splatted in the default listing printed after a successful - compile. (This seems to be a standard feature of IBM compilers; I - remember that RPG did this as well.) My understanding of the manual is - when the syntactically offensive line is encountered at runtime, it is - printed as error E000. I have modified the code to do this. - -6. I have fixed INTERCAL in order to add another bug. Namely, I have - implemented the BUG/NOBUG option in the Princeton compiler. By - default, there is a chance that INTERCAL will randomly insert error - E774 into your executable. (The odds are 1/128 per statement, not - counting COME FROMs. Is there any way to find out what the - Princeton compiler's odds were?) The new option -b turns this - feature off. - -7. The new file pit/lib/numio.i contains routines for wimpmode I/O. - These routines are documented in the file pit/lib/numio.doc. - It is my earnest hope that C-INTERCAL programmers everywhere will - flock to these handy routines, and C-INTERCAL users will thus no - longer need to fear that they might succumb to the foul and awful - temptation to use the dastardly +wimpmode option. - - Release 0.14 (by Eric S. Raymond) 9 Jun 1996 - -1. The documentation has been reorganized and cleaned up (you can now - format either a C-INTERCAL or INTERCAL-72 manual from the same master). - The diagrams in the paper original have been transcribed as pic figures. - See doc/READ.ME for details. - -2. Yet more code. The pit now includes a second random-number generator, - a ROT13 filter, and even two programs in TriINTERCAL! - -3. Louis Howell's corrected system library is now included. - -4. The distribution is now formally GPLed. - - Release 0.13 (by Eric S. Raymond) 5 Jun 1996 - -1. I folded in patches by Brian Raiter that port - this code to Linux, ANSIfies it, and enables it to use flex. Note: This - version has been tested on Linux and SunOS but not yet elsewhere. - -2. Another piece of nontrivial INTERCAL code has been found! (Doubtless - hell is freezing over even as I write.) We've added to the pit the - `beer' program by Matt DiMeo , courtesy of the - infamous Beer List (URL:http://www.ionet.net/~timtroyr/funhouse/beer.html). - - Release 0.12 (by Eric S. Raymond) 22 Mar 1995 - -1. The code now compiles and runs under Linux, using bison and lex. It does - *not* yet work with flex; C.P. Osborne's patches for 0.11 turned out not - to be sufficient (at least for flex 2.4.6 under Linux using the -l option). - See the BUGS list. - -2. Note 3 under 0.11 was incorrect. We're in conformance after all. - -3. The politesse check is a little smarter about programs too small to - conform to the 1/5-to-1/3 criterion. All the pit programs have been - checked for conformance. Also, the politesse error message now tells - you the offending program's line count. - - Release 0.11 (by Eric S. Raymond) 24 Sep 1994 - -1. Incorporated changes by Jan-Pieter Cornet for - magical inclusion of the system library. These address an outstanding bug - - 2. (SS) The `system library' should be precompiled and `linked' to user - written code, at least optionally. Doing this with the current compiler - presents a few problems. - - which has accordingly been removed from the BUGS file. They also fix a - previously unknown bug; due to a minor oversight in the lexer, it was not - possible to ABSTAIN FROM WRITING IN or READING OUT. Jan also contributed - a test program that demonstrates gerund abstention. - -2. Despite the obvious appeal of the idea, and much discussion on - alt.lang.intercal, I decided *not* to add Klingon; maintaining two parallel - grammars just so the compiler could support SVO and OSV languages would be - too painful. There was also a minor mess near case-sensitivity in the - digits. The workaround kluges I was offered instead failed to satisfy. - -3. We fess up to a violation of the INTERCAL-72 standard. That implementation, - instead of accepting an entire multiple-digit number per line of input, - expected one digit per *card image* (input line). It is unclear how - INTERCAL-72 programs ever managed to input more than one number. - -4. Added patches by C.P.Osborne to make the lexer work - using flex, for Linux and BSD/386 support. I didn't use his error-reporting - patch, though; instead, I changed the parser to catch errors at logical-line - level. I also kept the N in `RESUBNIT'; this is a carefully preserved - feature of INTERCAL-72. - -5. Volapuk digits are now recognized on input. TO DO: Recognize Volapuk - keywords, including gerunds. - - Release 0.10 (by Eric S. Raymond) 9 Sep 1994 - -1. It is now possible to undo a line-number abstention with a gerund - reinstatement, or undo a gerund abstention with a line-number - reinstatement. In previous versions, gerund abstention/reinstatements and - line-number abstention/reinstatements were independent of each other. - -2. After release 0.5, I wrote in the TO DO list as follows: - - 2. (ESR) Input format internationalization -- allow WRITE IN input digits in - major languages such as Nahuatl, Tagalog, Sanskrit, and Basque. - - The twisted loons in the alt.folklore.computers crowd loved this idea, - and I actually got sent digit lists for Nahuatl, Tagalog, Sanskrit, and - Basque -- also, Kwakiutl, Georgian, Ojibwe, and Albanian. I've left - out Albanian (didn't want to keep track of the dipthong diacritical) - and Ojibwe (no zero digit). So: Nahuatl, Tagalog, Sanskrit, Basque, - Georgian, and Kwakiutl are now supported in addition to English. - -3. The THEORY document has been significantly revised. - - Release 0.9 (by Eric S. Raymond) 5 Mar 1993 - -1. An embarrassing port bug in the INTERCAL skeleton has been fixed - -2. Jamie Zawinski's suggestion for an improved E333 error message has - been accepted. - -3. Added and improved documentation for pit programs. - -4. The install production in the Makefile now puts lose.h in place - as well as cesspool.h. - -5. You can now set the C compiler to be used as a back end by INTERCAL - by setting the environment variable CC. The default is cc. - - Release 0.8 (many hacks on 0.7 by Eric Raymond) 21 Jan 1992 - -1. A previously undocumented `feature' of the Princeton compiler, - revealed by Don Woods, is now emulated. If fewer than 1/5 or more - than 1/3 of a program's statements contain the qualifier `PLEASE', the - program is rejected with an entertaining error message. Programs in pit - have been hacked to pass the politesse test. - -2. The `sample' program now works correctly, thanks to Louis Howell. Also, - he has contributed new programs to calculate pi and to search for prime - numbers. - -3. An intercal mode for GNU Emacs is included. It helps programmers deal with - the new politesse check by randomly expanding the abbrev "do" to DO PLEASE - or PLEASE DO about 1/4 of the time. - -4. Improvements in code generation for NEXT/RESUME. - -5. Fixes to the optimizer; it handles the results of optimized MINGLEs - correctly now. Also, added a rewrite rule that checks for the - equality-test idiom using XOR. - -6. The original error messages from the Princeton compiler have been restored. - -The documentation has been updated to reflect these changes. - - Release 0.7 (by Louis Howell) 21 Dec 1991 - -In addition to bug fixes, new features in this version include arrays, -character I/O, modified (hopefully improved!) semantics for the COME -FROM statement, extensions to bases other than 2, new INTERCAL programs, -and new documentation. - - Release 0.6 (by Steve Swales) 5 Jan 1991 - -1. Restored Princeton documentation (courtesy of Michael Ernst). - -2. Added -@ usage option to ick. - -3. Added [+/-]help, [+/-]traditional, and [+/-]wimpmode options for -generated programs; [+/-]traditional is a no-op at this point. - -4. Various bug fixes, esp. in lexical analysis. - - Release 0.5 (ESR's original pre-release) 5 Jun 1990 - -1. As a convenience to all you junior birdmen out there, `NINER' is accepted as - a synonym for `NINE' in INTERCAL input. - -2. The COME FROM statement is now compiled. - - ------------- - -The resurrection of INTERCAL from its grave took place on 12 May 1990 -when ESR released 0.3 on an unsuspecting USENET. - diff --git a/NEWS.txt b/NEWS.txt new file mode 100644 index 0000000..14c66b3 --- /dev/null +++ b/NEWS.txt @@ -0,0 +1,475 @@ + NEW IN THIS RELEASE + + Release 0.26 (by Alex Smith) +   +1. Fixed a few bugs in the previous release (some bugfixed by Joris Huizer). + +2. Ported to DJGPP. The compiler now works on both POSIX and DJGPP systems. + +3. Reorganized the directory structure. + +4. Added support for cross-compiling to the PIC microcontroller. + +5. Added a simple test program for PIC cross-compilation. + +6. Improved further searching for skeletons and executables. + +7. Delinted some of the code, and turned up the default gcc warning level. + +8. Reformatted some of the documentation. + +9. Renamed and split files; all files used in the build now have 8.3 + filenames, to prevent any problems using DJGPP on 8.3 systems. The + optimizer was split from the code degeneration into dekludge.c (optimizer) + and feh2.c (degeneration), because feh.c was getting too large. + +10. The text documentation (README, COPYING, NEWS, and BUGS) was renamed to + end .txt (again for DJGPP compatibility); formatting changes were made to + README in addition to the addition of extra readme information. + +11. Included precompiled-to-C versions of the parser and the lexer so that + DJGPP (or I suppose, POSIX if you hacked the makefile) implementations + without bison or flex could still compile the rest of C-INTERCAL and give + a running program. + +12. Fixed a bug involving optimization of Tri-INTERCAL programs. + +13. Added to the lexer, so that it supports CLC-INTERCAL syntax for operators + that were already present in C-INTERCAL, as long as they don't conflict + with C-INTERCAL syntax. (Using the -X switch will support CLC-INTERCAL + syntax for operators that were already present in C-INTERCAL even if they + conflict with C-INTERCAL syntax.) For the symbols present in the + CLC-INTERCAL character set but not in ASCII, ISO-8859-1 is supported as an + encoding as well as UTF-8 (to increase the chance that CLC-INTERCAL + programs will run without modification); it was meant to be supported to + some extent before, but seemed not to be working. + +14. Added the COMMENT gerund, with the same semantics as in CLC-INTERCAL. + +15. Added COME FROM gerund. This suffers from the same restrictions as + computed COME FROM, in that it can't be used in PIC programs and causes + the program to end up substantially less efficient. + +16. Added support for prefix as well as infix unary operators. The rule is + that any number of prefix unary operators, but only one infix unary + operator, is allowed on each group, variable, and/or mesh. (Previously, + only infix operators were supported, and then only one per mesh.) + +17. Added positional precedences to the parser. INTERCAL still doesn't have + operator precedences (that would be completely contrary to the spirit of + INTERCAL) but it now has rules for deciding on the meaning of previously + ambiguous expressions. Chains of select and mingle operations right- + associate, and when a unary operator could legitimately be in either a + prefix or infix position, the infix position is assumed (although remember + that only one infix operator is allowed for each group, variable, and/or + mesh). + +18. Added ¬ as a synonym for NOT. + +19. Added operand overloading, for onespot and twospot variables. This uses + the slat operator in almost, but not quite, the same way as + CLC-INTERCAL. Note that the width of unary operations will mostly depend + on the type a variable appears to have in an expression, rather than on + its actual bitwidth (if a onespot is overloaded to a twospot or vice + versa). Note that meshes won't change as the result of operand overloading + unless the -v option is used (an error will be generated instead). + +20. Added an option for generalised assignments. With the -v option, + expressions (rather than just variables) can appear on the left of an + assignment. Any meshes on the left of an assignment (even if in apparently + inoccuous positions) may change value as a result. (Note that such + assignments aren't always possible.) If the left-hand-side of an + expression is anything other than simply a variable or a constant, the + compiler will try to change the values of meshes and non-ignored variables + in the expression to make it fit. (In bases other than 2, it will nearly + always fail.) Unlike CLC-INTERCAL, assigning to a mesh only changes that + mesh, not line labels or other uses of the number. + +21. Restricted the compiler to just one input file at a time (it used to break + if this wasn't done anyway). + +22. Fixed a nonportability involving stdin and stdout in cesspool.c. + +23. Added support for the NEXT FROM command, with the same semantics as COME + FROM (including computed NEXT FROM and NEXT FROM gerund), except that it + saves the line that was NEXTed FROM on the choicepoint stack. + +24. Fixed a bug where the yuk debugger accessed unallocated memory. + + Release 0.25 (by Alex Smith) + +1. Added support for computed ABSTAIN and TRY AGAIN. + +2. Added support for computed COME FROM. + +3. Added support for multithread programs. This includes ONCE and AGAIN, +which also work in singlethread programs. + +4. Expanded intercal.el to support Font Lock and some utilities for generating +INTERCAL-style constants. It also works with the compilation routines of Emacs +to compile INTERCAL programs without the need for make. Degenerated C code now +has a mode line to help with Emacs compatibility. + +5. Added a rudimentary debugger and profiler for singlethread programs. The +debugger's features include useful things like 'write out INTERCAL expression +in simpler terms' (which is only possible if -O is on). The profiler works +much like gcov, counting the length of time spent in and number of executions +of each command in the code. + +6. Changed searching for includes, libraries, syslib, skeleton. This is so that +non-root users, or people who want to evaluate ick, can do so more simply. The +compiler will search for the above files in the directory they should have been +installed in, the current directory, and the directory in which ick's +executable resides (in that order). Skeleton problems, in particular, seem to +have been a major problem for unfamiliar users trying out ick. + +7. Added several new test programs to the Pit. + +8. Greatly expanded the original optimizer (which optimizes expressions). It +can now recognize most of the idioms in syslib, and many idioms in other Pit +programs. Also added a new optimizer, to try to optimize program flow, which is +important because otherwise INTERCAL wouldn't have any rudimentary optimizers. +There is also the -F optimizer, which I hope will become infamous. It creates +object code which is close to maximally fast in some specialized situations, at +the expense of compile time (compilation can take a very long time when -F is +active) and object file size. I suggest checking its effect on primes.i. + +9. Fixed the grammar (again) in a spark/ears situation involving array +subscripts, after proving that the previous fixes weren't adequate. + +10. Added support for backtracking (MAYBE, GO AHEAD, GO BACK). Note that it is +possible for multithreading, backtracking, computed ABSTAIN, and computed COME +FROM to all be used simultaneously in the same program, to help maximize +obfuscation. + +11. Added an option (-l) for generating warnings. To prevent this actually +being useful, it is designed to generate far too many warnings, which all have +to be trawled through to find the important ones, and has no way to turn the +unimportant ones off. + +12. Added the +printflow and +mystery options for executing INTERCAL programs. +Note that it is not entirely obvious what either of them do (+printflow is a +debugging aid, but the output is somewhat obfuscated, and I am not going to +explain what +mystery does in this document). + + Release 0.24 (by Eric S. Raymond) 31 Dec 2003 + +1. RPMs can now be built by non-root users. + + Release 0.23 (by Eric S. Raymond) 9 Mar 2003 + +1. More fixes by Don Knuth. He found a bug in the type-propagation logic. + + Release 0.22 (by Eric S. Raymond) 4 Mar 2003 + +1. Incorporated a minor fix patch from Donald Knuth. Yes, *the* +Donald Knuth. Seems he found a weakness in the code for handling +comments, and fixed it to do multiline comments properly. He also made +some improvements to intercal.el, and contributed a test program. + +2. Updated build machinery. This package now uses GNU autoconf. + + Release 0.21 (by Eric S. Raymond) 30 July 2002 + +1. Jonathan Nieder sent a grammar fix for BLR's old bug #5 (a bad spark-ears +interaction.) + +2. Latin-1 support and makefile fixes from Magnus Bodin. + + Release 0.20 (by Eric S. Raymond) 16 September 1999 + + (The following changes are due to John Cowan ) + +1. In addition to Latin-1, UTF-8 is now acceptable in source code as well. +All the numerous currency symbols of Unicode (ISO 10646) can be used as +big-money alternatives in their UTF-8 format. Indeed, a random mixture of +Latin-1 and UTF-8 also works fine; this seems very much in the spirit of +Intercal. + +2. Intercal has now been localized for the Ancient Roman as well as the +Posix/C locale. You may input numbers in Latin and write Intercal programs +using Latin keywords. See lexer.l for a list of equivalences. + +3. The Makefile in the pit directory now works like a real Makefile, and +won't compile anything that's already been compiled. + + Release 0.19 (by Eric S. Raymond) 16 August 1998 + +1. Fixed a code-generation error in assignments from tail and hybrid +variables. (Error pointed out by Malcom Ryan.) + + Release 0.18 (by Eric S. Raymond) 29 April 1998 + +(The following changes are due to John Cowan ) + +1. The source code is now POSIXly correct. By making the POSIX +variable in the Makefile undefined, you can restore the use of +, but otherwise is now used. + +2. Latin-1 (ISO 8859-1) is now the standard input charset of C-INTERCAL. +This means that the change operator (0xA2) has returned as an alternative to +big money ($). Furthermore, the quid (0xA3) and zlotnik (0xA4) are also +acceptable. For those using Latin-9 (ISO 8859-15), the euro (0xA4) will also +work. ("Euro", like "ampersand", cannot be sillified further.) +New names have been added to intercal.mm. + +3. A fortiori, input of Volap\"uk digits may now be in Latin-1 or TeX format. + +4. Yacc is now deprecated in favor of bison; some old yaccs don't do proper +error recovery, and lines like "DO ~ ERROR" failed at compile time. + +5. Some minor portability bugs on systems where ptr_diff is not the same +as int were removed by casting expressions of the form (ptr - ptr) to int. + + Release 0.17 (by Eric S. Raymond) 27 Feb 1998 + +Incorporates a minor bug fix by Jeff Uphoff . + + Release 0.16 (by Brian Raiter and Eric S. Raymond) 26 May 1997 + +This is the 25th-anniversary release of INTERCAL. This language, conceived +in irony a quarter century ago today, has outlasted many more serious and +high-minded essays in computer language design. This fact should give us +pause to reflect, or possibly frighten the crap out of us. Or both. + +1. Corrected manual bugs. + +2. Fixed over-enthusiastic install production in the Makefile. + +3. DO PLEASE is no longer accepted (Brian Raiter pointed out that the + manual does not sanction it). + +4. Fixed various bugs in the optimizer. + +5. Incorporated fixes made by William Walter Patterson for bugs that + appeared when multiple files are given on the command line. + +(The following changes are due to Brian Raiter) + +6. The system library is now available for TriINTERCAL (all bases, 3 to 7). + The compiler has been updated to use the right library automagically. + +7. The error 774 feature has been brought into conformance with the + Princeton compiler. The odds are now a flat 10% (but still 0% with -b). + +8. The compiler has been modified to allocate memory dynamically, and + the hard-coded limits on program size and number of variables has + been removed. Programs are now only limited by the amount of + available memory. + +9. Array output now fflushes after outputting newlines. + +10. Two minor bug fixes: one in wimpmode input, which was clamping + input to the signed integer range, and one in politesse checking. + The latter was causing programs to be recognized as impolite only + if their ratio was less that one-sixth, not one-fifth. (Fixing this + also necessitated adding a few PLEASEs to pit/rot13.i.) + +11. Several new programs have been tossed into the pit. + + Release 0.15 (by Eric S. Raymond) 20 Jun 1996 + +1. Switched the INTERCAL manual master to mgm in order to be able to handle + section crossreferences properly. The manual has now been carefully + proofread against the paper version by ESR and seems to match. It's + also been independently proofread for typos by Brian Raiter. + +2. The optimizer now does complete analysis and evaluation of constant + expressions at compile time. + +3. Added optimization templates for ~, |, &, ^ expressions. Also added + |, &, ^ idioms to the system library, and documented them. + +(The following changes are due to Brian Raiter) + +4. Every one of the INTERCAL-72 messages is now emitted when appropriate. + including the previously un-emitted E000, E197, and E200 (and see below). + +5. A close reading (while proofing) of the sections of the manual on + error messages seems to indicate that splatted lines were only + splatted in the default listing printed after a successful + compile. (This seems to be a standard feature of IBM compilers; I + remember that RPG did this as well.) My understanding of the manual is + when the syntactically offensive line is encountered at runtime, it is + printed as error E000. I have modified the code to do this. + +6. I have fixed INTERCAL in order to add another bug. Namely, I have + implemented the BUG/NOBUG option in the Princeton compiler. By + default, there is a chance that INTERCAL will randomly insert error + E774 into your executable. (The odds are 1/128 per statement, not + counting COME FROMs. Is there any way to find out what the + Princeton compiler's odds were?) The new option -b turns this + feature off. + +7. The new file pit/lib/numio.i contains routines for wimpmode I/O. + These routines are documented in the file pit/lib/numio.doc. + It is my earnest hope that C-INTERCAL programmers everywhere will + flock to these handy routines, and C-INTERCAL users will thus no + longer need to fear that they might succumb to the foul and awful + temptation to use the dastardly +wimpmode option. + + Release 0.14 (by Eric S. Raymond) 9 Jun 1996 + +1. The documentation has been reorganized and cleaned up (you can now + format either a C-INTERCAL or INTERCAL-72 manual from the same master). + The diagrams in the paper original have been transcribed as pic figures. + See doc/READ.ME for details. + +2. Yet more code. The pit now includes a second random-number generator, + a ROT13 filter, and even two programs in TriINTERCAL! + +3. Louis Howell's corrected system library is now included. + +4. The distribution is now formally GPLed. + + Release 0.13 (by Eric S. Raymond) 5 Jun 1996 + +1. I folded in patches by Brian Raiter that port + this code to Linux, ANSIfies it, and enables it to use flex. Note: This + version has been tested on Linux and SunOS but not yet elsewhere. + +2. Another piece of nontrivial INTERCAL code has been found! (Doubtless + hell is freezing over even as I write.) We've added to the pit the + `beer' program by Matt DiMeo , courtesy of the + infamous Beer List (URL:http://www.ionet.net/~timtroyr/funhouse/beer.html). + + Release 0.12 (by Eric S. Raymond) 22 Mar 1995 + +1. The code now compiles and runs under Linux, using bison and lex. It does + *not* yet work with flex; C.P. Osborne's patches for 0.11 turned out not + to be sufficient (at least for flex 2.4.6 under Linux using the -l option). + See the BUGS list. + +2. Note 3 under 0.11 was incorrect. We're in conformance after all. + +3. The politesse check is a little smarter about programs too small to + conform to the 1/5-to-1/3 criterion. All the pit programs have been + checked for conformance. Also, the politesse error message now tells + you the offending program's line count. + + Release 0.11 (by Eric S. Raymond) 24 Sep 1994 + +1. Incorporated changes by Jan-Pieter Cornet for + magical inclusion of the system library. These address an outstanding bug + + 2. (SS) The `system library' should be precompiled and `linked' to user + written code, at least optionally. Doing this with the current compiler + presents a few problems. + + which has accordingly been removed from the BUGS file. They also fix a + previously unknown bug; due to a minor oversight in the lexer, it was not + possible to ABSTAIN FROM WRITING IN or READING OUT. Jan also contributed + a test program that demonstrates gerund abstention. + +2. Despite the obvious appeal of the idea, and much discussion on + alt.lang.intercal, I decided *not* to add Klingon; maintaining two parallel + grammars just so the compiler could support SVO and OSV languages would be + too painful. There was also a minor mess near case-sensitivity in the + digits. The workaround kluges I was offered instead failed to satisfy. + +3. We fess up to a violation of the INTERCAL-72 standard. That implementation, + instead of accepting an entire multiple-digit number per line of input, + expected one digit per *card image* (input line). It is unclear how + INTERCAL-72 programs ever managed to input more than one number. + +4. Added patches by C.P.Osborne to make the lexer work + using flex, for Linux and BSD/386 support. I didn't use his error-reporting + patch, though; instead, I changed the parser to catch errors at logical-line + level. I also kept the N in `RESUBNIT'; this is a carefully preserved + feature of INTERCAL-72. + +5. Volapuk digits are now recognized on input. TO DO: Recognize Volapuk + keywords, including gerunds. + + Release 0.10 (by Eric S. Raymond) 9 Sep 1994 + +1. It is now possible to undo a line-number abstention with a gerund + reinstatement, or undo a gerund abstention with a line-number + reinstatement. In previous versions, gerund abstention/reinstatements and + line-number abstention/reinstatements were independent of each other. + +2. After release 0.5, I wrote in the TO DO list as follows: + + 2. (ESR) Input format internationalization -- allow WRITE IN input digits in + major languages such as Nahuatl, Tagalog, Sanskrit, and Basque. + + The twisted loons in the alt.folklore.computers crowd loved this idea, + and I actually got sent digit lists for Nahuatl, Tagalog, Sanskrit, and + Basque -- also, Kwakiutl, Georgian, Ojibwe, and Albanian. I've left + out Albanian (didn't want to keep track of the dipthong diacritical) + and Ojibwe (no zero digit). So: Nahuatl, Tagalog, Sanskrit, Basque, + Georgian, and Kwakiutl are now supported in addition to English. + +3. The THEORY document has been significantly revised. + + Release 0.9 (by Eric S. Raymond) 5 Mar 1993 + +1. An embarrassing port bug in the INTERCAL skeleton has been fixed + +2. Jamie Zawinski's suggestion for an improved E333 error message has + been accepted. + +3. Added and improved documentation for pit programs. + +4. The install production in the Makefile now puts lose.h in place + as well as cesspool.h. + +5. You can now set the C compiler to be used as a back end by INTERCAL + by setting the environment variable CC. The default is cc. + + Release 0.8 (many hacks on 0.7 by Eric Raymond) 21 Jan 1992 + +1. A previously undocumented `feature' of the Princeton compiler, + revealed by Don Woods, is now emulated. If fewer than 1/5 or more + than 1/3 of a program's statements contain the qualifier `PLEASE', the + program is rejected with an entertaining error message. Programs in pit + have been hacked to pass the politesse test. + +2. The `sample' program now works correctly, thanks to Louis Howell. Also, + he has contributed new programs to calculate pi and to search for prime + numbers. + +3. An intercal mode for GNU Emacs is included. It helps programmers deal with + the new politesse check by randomly expanding the abbrev "do" to DO PLEASE + or PLEASE DO about 1/4 of the time. + +4. Improvements in code generation for NEXT/RESUME. + +5. Fixes to the optimizer; it handles the results of optimized MINGLEs + correctly now. Also, added a rewrite rule that checks for the + equality-test idiom using XOR. + +6. The original error messages from the Princeton compiler have been restored. + +The documentation has been updated to reflect these changes. + + Release 0.7 (by Louis Howell) 21 Dec 1991 + +In addition to bug fixes, new features in this version include arrays, +character I/O, modified (hopefully improved!) semantics for the COME +FROM statement, extensions to bases other than 2, new INTERCAL programs, +and new documentation. + + Release 0.6 (by Steve Swales) 5 Jan 1991 + +1. Restored Princeton documentation (courtesy of Michael Ernst). + +2. Added -@ usage option to ick. + +3. Added [+/-]help, [+/-]traditional, and [+/-]wimpmode options for +generated programs; [+/-]traditional is a no-op at this point. + +4. Various bug fixes, esp. in lexical analysis. + + Release 0.5 (ESR's original pre-release) 5 Jun 1990 + +1. As a convenience to all you junior birdmen out there, `NINER' is accepted as + a synonym for `NINE' in INTERCAL input. + +2. The COME FROM statement is now compiled. + + ------------- + +The resurrection of INTERCAL from its grave took place on 12 May 1990 +when ESR released 0.3 on an unsuspecting USENET. + diff --git a/README b/README deleted file mode 100644 index bc44f1c..0000000 --- a/README +++ /dev/null @@ -1,150 +0,0 @@ - Release Notes for C-INTERCAL - - DISCREDITS - -This package is an implementation of the language INTERCAL designed by Don -Woods and James Lyon, who have since spent more than twenty years trying to -live it down. - -This implementation was created by Eric S. Raymond -during a fit of lunacy from which he has since mostly recovered. It has -been considerably hacked upon and improved by Steve Swales, Michael Ernst, -Louis Howell, Brian Raiter, and others. For detailed credits see NEWS. - - FILES - -The compiler itself is in the src directory. Setting a symbol in the -makefile will allow you to install it and its libraries and support files -in a directory of your choice. The doc directory contains (surprise!) -documentation, and pit contains various examples of INTERCAL source code, -writhing in agony. - -The files included are: - -README -- this file -BUGS -- current bug and to-do list -NEWS -- info on features and fixes new in this release -intercal.el -- elisp for editing INTERCAL code under GNU Emacs - -doc/READ.ME -- historical notes on the docs -doc/intercal.mm -- the manual in groffable form -doc/THEORY -- some notes on the internals of the INTERCAL compiler - -Makefile.in -- makefile for the INTERCAL compiler -lexer.l -- the lexical analyzer specification (in LEX) -ick.y -- the grammar specification (in YACC) -ick.h -- compilation types and defines -perpetrate.c -- main routine for compiler -feh.c -- INTERCAL-to-C code generator -feh.h -- interface to INTERCAL-to-C code generator -fiddle.c -- the INTERCAL operators -lose.[ch] -- INTERCAL compile- and run-time error handling -ick-wrap.c -- the driver for generated C-from-INTERCAL code -arrgghh.c -- option argument parsing for generated programs -abcess.h -- interface to functions linked with programs -cesspool.c -- the INTERCAL runtime support code -numerals.c -- numerals table for INTERCAL input -sizes.h -- variables defining the numeric base -unravel.c -- multithreading functions -yuk.[ch] -- INTERCAL debugger and profiler -coopt.sh -- shell-script to help out the -F optimizer - -pit/* -- sample INTERCAL code; see pit/CATALOG - - HOW TO GET STARTED - -You want a man page? Man pages are for wimps. To compile an INTERCAL -program `foo.i' to executable code, just do - - ick foo.i - -There's a -c option that leaves the generated `foo.c' in place for -inspection (suppressing compilation to machine code), a -d option that -enables verbose parse reporting from the yacc/bison parser, a -t -option that requires strict INTERCAL-72 compliance (rejecting COME -FROM and the extensions for bases other than two), a -b option that -disables the INTERCAL-72 random-bug feature, and an -O option that -enables the (hah!) optimizer (which can be invoked at higher levels -with -Of or -F). Invoking ick -? prints a usage message. The -m -option enables multithreading extensions. If you need to debug code, -you can use -y to invoke the debugger immediately after compilation, --p to invoke the profiler immediately after compilation, or -g to -generate the C code in such a way that it can be debugged with a C -debugger. -h, -H, and -hH generate debugging output from the -optimizer, which is useful if you need to understand an INTERCAL -program, and -l turns on warnings (far too many warnings!). If ick -itself needs debugging, the -U option will cause it to dump core on -E778. Other than that, yer on yer own. - -Another switch affects C-INTERCAL's runtime behavior. The `-C' -option forces output in "clockface" mode, for superstitious users who -believe writing "IV" upside-down offends IVPITER and would rather -see IIII. - -Every INTERCAL runtime also accepts certain options at runtime (code by -Steve Swales). These include [+/-]help, [+/-]traditional, and [+/-]wimpmode. -The help option (with either + or -) triggers a 'usage' message. The -+traditional option is presently a no-op. Also available are [+/-] printflow, -which gives information that may or may not be helpful for debugging a program, -and [+/-] mystery, which is undocumented. Note that these options are not -necessarily available if the program is compiled with -F. - -Steve writes: "The wimpmode option is the most interesting. I found myself -always running my test programs with filters on both ends to work around the -'nifty' INTERCAL number representations. This was so painful that I decided it -would be LESS painful (and a lot less code) if I added a 'wimp' option. With -the +wimpmode option, the user is subjected to a humiliating message about what -a wimp he or she is to use this mode, but after that is allowed to use -conventional numerical notation. While such a mode doubtless violates to some -extent the INTERCAL philosophy, the fact that a 'unbutcher' command has been -posted clearly indicates the need for it. Anyway... if you don't like it, don't -use it... the default is -wimpmode (i.e. NOT wimp mode)." - - SPREADING THE BLAME - -There is an INTERCAL Resource Page at http://www.catb.org/intercal - -The latest version of INTERCAL is also kept available at the -Retrocomputing Museun, http://www.catb.org/retro. - -There is, in addition, an occasionally active USENET newsgroup devoted to the -language: alt.lang.intercal. - - NOTES ON THE LINUX BUILD - -At the top of ick.h are two defines that you may need to remove if you -are using lex instead of flex. - -Many lexes export a yylineno variable, an undocumented feature that is -not in flex (by default). If your build fails because of redecleration -of yylineno, comment out the define of YYLINENO_BY_HAND. - -Some lexes also supply a yyrestart function to begin parsing a second -file, while others automatically restart after seeing an EOF. (This is -the case with flex.) If your build fails at link time because -yyrestart is not defined, comment out the define of USE_YYRESTART. - -If you are using gcc in an non-ANSI environment, such as SunOS, it is -strongly recommended that you add "-Wno-unused -Wimplicit" to the gcc -command in the makefile. If you are in an ANSI environment and are -using the current versions of gcc, flex, and bison, C-INTERCAL should -build with no warnings. - -As the debugger is interactive, it needs to be able to find the GNU GPL. -The Makefile attempts to copy the GPL to /dev/null to prove it exists. If -this fails, you will have to point the Makefile to a copy of the GPL -yourself. You can always copy the one included with this distribution -somewhere safe and use that (what the Makefile will try to do by default). - - LICENSING - -C-INTERCAL is now distributed under the General Public License, -except for the C skeleton file which is explicitly *not* GPLed -in order to avoid the (possibly mythical) "license virus" effect. -See the file COPYING for details on the General Public License. - - APOCALYPSE - -INTERCAL is fully Y2K-compliant. Indeed, it is Y2K-obsequious, and -loves nothing better than to be punished by relays of leather-clad and -spike-heeled calendricists. Bite me and go buy your own shotgun. diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..927ff81 --- /dev/null +++ b/README.txt @@ -0,0 +1,218 @@ + Release Notes for C-INTERCAL + + DISCREDITS + +This package is an implementation of the language INTERCAL designed by Don +Woods and James Lyon, who have since spent more than twenty years trying to +live it down. + +This implementation was created by Eric S. Raymond +during a fit of lunacy from which he has since mostly recovered. It has been +considerably hacked upon and improved by Steve Swales, Michael Ernst, Louis +Howell, Brian Raiter, and others. For detailed credits see NEWS. + + FILES + +The compiler itself is in the src directory. Setting a symbol in the makefile +will allow you to install it and its libraries and support files in a directory +of your choice. The doc directory contains (surprise!) documentation, and pit +contains various examples of INTERCAL source code, writhing in agony. + +The files included are: + +README.txt -- this file +BUGS.txt -- current bug and to-do list +NEWS.txt -- info on features and fixes new in this release +COPYING.txt -- copyright and licence information +MANIFEST.txt -- a list of all files in the distribution + +etc/intercal.el -- elisp for editing INTERCAL code under GNU Emacs + +doc/READ.ME -- historical notes on the docs +doc/intercal.mm -- the manual in groffable form +doc/THEORY -- some notes on the internals of the INTERCAL compiler + +src/lexer.l -- the lexical analyzer specification (in LEX) +src/parser.y -- the grammar specification (in YACC) +src/ick.h -- compilation types and defines +src/perpet.c -- main routine for compiler +src/feh2.c -- INTERCAL-to-C code generator +src/feh2.h -- interface to INTERCAL-to-C code generator +src/dekludge.c -- INTERCAL parse tree optimizer +src/fiddle.c -- the INTERCAL operators +src/lose.[ch] -- INTERCAL compile- and run-time error handling +src/ick-wrap.c -- the driver for generated C-from-INTERCAL code +src/pickwrap.c -- the driver for generated PIC C-from-INTERCAL code +src/arrgghh.c -- option argument parsing for generated programs +src/abcess.h -- interface to functions linked with programs +src/cesspool.c -- the INTERCAL runtime support code +src/numerals.c -- numerals table for INTERCAL input +src/sizes.h -- variables defining the numeric base +src/unravel.c -- multithreading functions +src/yuk.[ch] -- INTERCAL debugger and profiler (POSIX only) +src/pick1.h -- template for compiler-dependent PIC C headers +src/pick2.h -- runtime support for compiled PIC-INTERCAL +src/coopt.sh -- script to help out the -F optimizer (POSIX only) +src/ick.bat -- wrapper around the compiler (DJGPP only) + +temp/parser.[ch] -- Prebuilt parser (for DJGPP systems without bison) +temp/lexer.c -- Prebuilt lexer (for DJGPP systems without flex) + +Makefile.in -- makefile input for the INTERCAL compiler (POSIX) +makeick.bat -- script to compile under DJGPP +districk.bat -- script to remove files not distributed (DJGPP) +cleanick.bat -- script to remove all non-source files (DJGPP) +djfix.bat -- script to remove ^Ms that may have got in by mistake +makeick.sh --\ +districk.sh --|the same as above, but in sh format +cleanick.sh --| +djfix.sh --/ + +configure.sh -- GNU Autoconf script that generates a makefile + from Makefile.in +ickspec.in -- Input to configure.sh +configure.ac -- Source from which configure.sh was generated +install.sh -- Helper file for 'make install' + +bin/* -- Directory that holds binaries after the build +include/* -- Directory that holds header files after the build +lib/* -- Directory that holds library files after the build + +pit/* -- sample INTERCAL code; see pit/CATALOG + + HOW TO GET STARTED + +You want a man page? Man pages are for wimps. To compile an INTERCAL program +`foo.i' to executable code, just do + + ick foo.i + +There's a -c option that leaves the generated `foo.c' in place for inspection +(suppressing compilation to machine code), a -d option that enables verbose +parse reporting from the yacc/bison parser, a -t option that requires strict +INTERCAL-72 compliance (rejecting COME FROM and the extensions for bases other +than two), a -b option that disables the INTERCAL-72 random-bug feature, and an +-O option that enables the (hah!) optimizer (which can be invoked at higher +levels with -Of or -F). Invoking ick -? prints a usage message. The -m +option enables multithreading extensions. If you need to debug code, -g +generates the C code in such a way that it can be debugged with a C +debugger. -h, -H, and -hH generate debugging output from the optimizer, which +is useful if you need to understand an INTERCAL program, and -l turns on +warnings (far too many warnings!). If ick itself needs debugging, the -U option +will cause it to dump core on E778. Other than that, yer on yer own. + +-t has been mentioned above as a compatibility option; -X is also permitted, +and causes the program to treat the ambiguous characters ? and @ as having the +meanings that they have in CLC-INTERCAL rather than their traditional +C-INTERCAL meanings. + +Another switch affects C-INTERCAL's runtime behavior. The `-C' option forces +output in "clockface" mode, for superstitious users who believe writing "IV" +upside-down offends IVPITER and would rather see IIII. + +Every INTERCAL runtime also accepts certain options at runtime (code by Steve +Swales). These include [+/-]help, [+/-]traditional, and [+/-]wimpmode. The +help option (with either + or -) triggers a 'usage' message. The +traditional +option is presently a no-op. Also available are [+/-] printflow, which gives +information that may or may not be helpful for debugging a program, and [+/-] +mystery, which is deliberately undocumented. + +Steve writes: "The wimpmode option is the most interesting. I found myself +always running my test programs with filters on both ends to work around the +'nifty' INTERCAL number representations. This was so painful that I decided it +would be LESS painful (and a lot less code) if I added a 'wimp' option. With +the +wimpmode option, the user is subjected to a humiliating message about what +a wimp he or she is to use this mode, but after that is allowed to use +conventional numerical notation. While such a mode doubtless violates to some +extent the INTERCAL philosophy, the fact that a 'unbutcher' command has been +posted clearly indicates the need for it. Anyway... if you don't like it, don't +use it... the default is -wimpmode (i.e. NOT wimp mode)." + + SPREADING THE BLAME + +There is an INTERCAL Resource Page at http://www.catb.org/intercal + +The latest version of INTERCAL is also kept available at the Retrocomputing +Museun, http://www.catb.org/retro. + +There is, in addition, an occasionally active USENET newsgroup devoted to the +language: alt.lang.intercal. + + NOTES ON THE POSIX BUILD + +At the top of ick.h are two defines that you may need to remove if you are +using lex instead of flex. + +Many lexes export a yylineno variable, an undocumented feature that is not in +flex (by default). If your build fails because of redecleration of yylineno, +comment out the define of YYLINENO_BY_HAND. + +Some lexes also supply a yyrestart function to begin parsing a second file, +while others automatically restart after seeing an EOF. (This is the case with +flex.) If your build fails at link time because yyrestart is not defined, +comment out the define of USE_YYRESTART. + +If you are using gcc in an non-ANSI environment, such as SunOS, it is strongly +recommended that you add "-Wno-unused -Wimplicit" to the gcc command in the +makefile. If you are in an ANSI environment and are using the current versions +of gcc, flex, and bison, C-INTERCAL should build with no warnings. + +As the debugger is interactive, it needs to be able to find the GNU GPL. The +Makefile attempts to copy the GPL to /dev/null to prove it exists. If this +fails, you will have to point the Makefile to a copy of the GPL yourself. You +can always copy the one included with this distribution somewhere safe and use +that (what the Makefile will try to do by default). + + NOTES ON THE DJGPP BUILD + +This distribution needs prebuilding; you can use the makeick.bat or makeick.sh +file provided to compile the program if you can't compile using the usual +POSIX methods via configure and make. Once the implementation has been built, +you can install it by adding the \bin subdirectory to your PATH environment +variable (at either end). The temporary output from bison and flex is included +in the distribution (for those people who don't have bison and flex, makeick +will give error messages, but succeed anyway using the prebuilt versions). The +districk.bat file will remove all generated files that weren't in the +distribution, and the cleanick.bat file will remove all files that aren't +needed for a build (including the temporary bison/flex output). Note that +makeick.bat and makeick.sh produce DJGPP-specific output; and if you're +running DJGPP under bash under Windows XP, you'll need to either set your +default command interpreter for batch files to cmd rather than command.com, or +explicitly invoke the compiler as cmd /c ick rather than just ick. + +Some distributions of DJGPP have a bug where they complain that they can't find +'m4.exe'. You can solve this problem by copying m4.exe into the \temp +subdirectory before running makeick.bat. + +Some features (for instance, -F) are unavailable at the moment under DJGPP +(they are documented, but have no effect). + +Note that for copyright reasons, the compilation needs to know a location of +the GNU GPL on your system. There is one provided as COPYING.txt. You will +need to edit makeick.sh or makeick.bat to change the location given, if the +default (/DJGPP/COPYING) is incorrect. + +You can get a copy of DJGPP at . + + NOTES ON COMPILING PIC-INTERCAL + +PIC C compilers tend to differ substantially in the way they handle various +language constructs. As a result, this compiler will only compile to C (not to +hex or asm) when compiling a PIC-INTERCAL program. There are two header files, +pick1.h and pick2.h in the /src directory; these need to be placed somewhere +your compiler can find them, and pick1.h will need to be modified to contain +compiler-specific data (like the names of data types and the syntax for +specifying the device type, fuses, and various commands). + + LICENSING + +C-INTERCAL is now distributed under the General Public License, except for the +C skeleton file which is explicitly *not* GPLed in order to avoid the (possibly +mythical) "license virus" effect. See the file COPYING.txt for details on the +General Public License. + + APOCALYPSE + +INTERCAL is fully Y2K-compliant. Indeed, it is Y2K-obsequious, and loves +nothing better than to be punished by relays of leather-clad and spike-heeled +calendricists. Bite me and go buy your own shotgun. diff --git a/abcess.h b/abcess.h deleted file mode 100644 index 5604f62..0000000 --- a/abcess.h +++ /dev/null @@ -1,167 +0,0 @@ -/* abcess.h -- functions used by compiled INTERCAL programs */ - -/* AIS note: This header file now serves two purposes. For non-multithread - programs, it serves as headers to the degenerated code and many support - functions. For multithread programs, this header file adds extra functions - only when compiling the degenerated code and unravel.c, and holds its - previous contents during other files. */ - -typedef int bool; -#define TRUE 1 -#define FALSE 0 - -#define ONESPOT 0 -#define TWOSPOT 1 -#define TAIL 2 -#define HYBRID 3 - -#define MAXNEXT 80 /* AIS: Moved from cesspool.c */ - -/* the following two types must both promote to unsigned int in expressions */ - -typedef unsigned short type16; -typedef unsigned int type32; - -typedef struct array_t -{ - unsigned int rank; - unsigned int *dims; - union - { - type16 *tail; - type32 *hybrid; - } data; -} array; - -/* AIS: Moved from cesspool.c */ -typedef struct stashbox_t /* this is a save-stack element */ -{ - unsigned int type; /* variable type */ - unsigned int index; /* variable's index within the type */ - union /* the data itself */ - { - type16 onespot; - type32 twospot; - array *a; - } save; - struct stashbox_t *next; /* pointer to next-older stashbox */ -} stashbox; - -/* AIS: files to take input and output from */ -extern FILE* cesspoolin; -extern FILE* cesspoolout; - -/* defined in cesspool.c */ -extern void pushnext(int n); -extern unsigned int popnext(int n); -extern unsigned int resume(unsigned int n); -extern unsigned int pin(void); -extern void clockface(bool mode); -extern void pout(unsigned int val); -extern void binin(unsigned int type, array *a, bool forget); -extern void binout(unsigned int type, array *a); -extern unsigned int assign(char *dest, unsigned int type, bool forget, - unsigned int value); - -/* AIS: yuk and unravel need these */ -extern int* next; -extern int nextindex; -extern stashbox* first; - -/* AIS: Implement the +mystery command line option. */ -extern unsigned long mysteryc; -extern int mystery; -#define MYSTERYLINE if(mystery && mysteryc++ > 4000000000LU) exit(42); - -/* AIS: Handle multiple COME FROMs aiming at the same line */ -extern int multicome0(int errlineno, jmp_buf pc); - -#ifdef _POSIX_SOURCE -extern char *aref(unsigned int type, ...); -extern void resize(unsigned int type, ...); -#else -extern char *aref(); -extern void resize(); -#endif - -extern void stashinit(void); -extern void stash(unsigned int type, unsigned int index, void *from); -extern void retrieve(void *to, int type, unsigned int index, bool forget); -extern unsigned int roll(unsigned int n); - -/* defined in arrgghh.c */ -extern void parseargs(int argc, char **argv); - -/* AIS: Multithreading types and defines */ -#if MULTITHREAD != 0 -typedef struct tag_ickthread ickthread; -struct tag_ickthread -{ - void* varforget[8]; /* holds all four variable types, and forgetting data */ - int* nextstack; - int nextpointer; - jmp_buf pc; /* program counter */ - stashbox* sb; /* holds all stash data */ - ickthread* next; - ickthread* choicepoint; /* the top choicepoint available. Used as a next - pointer in the choicepoint stack. */ - int stale; /* if this is a choicepoint, whether it's a stale choicepoint. */ - int refcount; /* when Threaded INTERCAL and Backtracking INTERCAL are - combined, reference-counting on choicepoints is needed - so that backtracking past multithreading is possible. - This also allows for garbage-collection of choicepoints. - (Luckily, choicepoints cannot refer to themselves, so this - mechanism works.) This only applies to ickthreads that are - acting as choicepoints, not those acting as threads. */ - int ccfc; /* number of comefroms currently active */ - int skipto; /* compucome line number */ - jmp_buf cjb; /* keeps track of compucomes */ -}; -extern ickthread* ickmt_cur; /* current thread */ -extern ickthread* ickmt_prev; /* previous thread: an optimisation to make - thread switching O(1), not O(n), with - respect to the number of threads */ -#define NEXTTHREAD if(printflow) printf("[%d]",lineno); \ - if(setjmp(cjb) == 0) \ - nextthread(cjb, lineno, 3); - -extern void nextthread(jmp_buf pc, int errlineno, int flags); -extern void killthread(void); -extern void ickmtinit(void); -extern int multicome1(int errlineno, jmp_buf pc); -extern void choicepoint(void); -extern void choiceahead(void); -extern void choiceback(void); - -/* from ick-wrap.c, declare as extern so they can be accessed by cesspool.c, - unravel.c */ -extern int onespotcount; -extern int twospotcount; -extern int tailcount; -extern int hybridcount; - -extern int oldabstain; -extern int gonebackto; -extern int ccfc; -extern int skipto; -extern jmp_buf btjb; -extern jmp_buf cjb; - -#define MULTICOME multicome1 -#else -#define MULTICOME multicome0 -#endif /* MULTITHREAD */ - -/* AIS: Used by the debugger, multithread code */ -#if (MULTITHREAD != 0) || (YUKDEBUG != 0) -extern type16* onespots; -extern bool* oneforget; -extern type32* twospots; -extern bool* twoforget; -extern array* tails; -extern bool* tailforget; -extern array* hybrids; -extern bool* hyforget; -#endif - -/* abcess.h ends here */ diff --git a/arrgghh.c b/arrgghh.c deleted file mode 100644 index 05dd619..0000000 --- a/arrgghh.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * SYNOPSIS: parseargs(argc,argv) - * FILE : parseargs.c - * AUTHOR : Steve Swales - * DATE: October 7, 1990 - * PURPOSE: Parse arguments for INTERCAL programs. - * -LICENSE TERMS - Copyright (C) 1996 Eric S. Raymond - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include "abcess.h" -#include "lose.h" - -int traditional = 0; -int wimp_mode = 0; -int printflow = 0; /* AIS */ -int mystery = 0; /* AIS */ - -unsigned long mysteryc = 0; /* AIS */ - -void -parseargs(int argc, char **argv) -{ - register int i, j; - static int helpflag = -1; - static char *flags[] = { - "help", - "wimpmode", - "traditional", - "printflow", /* AIS */ - "mystery", /* AIS */ - }; - static int *bools[] = { - &helpflag, - &wimp_mode, - &traditional, - &printflow, /* AIS */ - &mystery, /* AIS */ - }; - static int nflags = (int)(sizeof(flags)/sizeof(flags[0])); - - for(i = 1;i < argc;i++) { - if(argv[i][0] != '+' && argv[i][0] != '-') { - break; - } - for(j = 0; j < nflags;j++) { - if(0 == strcmp(argv[i]+1,flags[j])) { - *(bools[j]) = (argv[i][0] == '+'); - break; - } - } - if(j == nflags) { - fprintf(stderr,"%s: can't grok %s\n",argv[0],argv[i]); - helpflag = 1; - } - } - if(helpflag != -1) { - if(!helpflag) { - fprintf(stderr, - "Once you start messing with INTERCAL... \n"); - fprintf(stderr,"\t\tthere is no help for you!\n\n"); - sleep(3); - } - fprintf(stderr,"Current flags (and current state) are:\n"); - for(i = 0;i < nflags;i++) { - fprintf(stderr,"\t[+/-]%-20.20s\t(%s)\n",flags[i], - (*(bools[i]) == 1)?"ON":((*(bools[i]) == 0)?"OFF":"???")); - } - fprintf(stderr,"All flags must be preceded by either + or -, which\n"); - fprintf(stderr," usually will mean turn on or turn off something,\n"); - fprintf(stderr," but not always, and not all of them currently\n"); - fprintf(stderr," do anything, but you can switch them on or off\n"); - fprintf(stderr," if you like anyway. Isn't this helpful?\n\n"); - fflush(stderr); - sleep(3); - lose(E778, 0, (char *)NULL); - } - if(wimp_mode) { - fprintf(stderr,"How sad... you have selected to run an INTERCAL\n"); - fprintf(stderr,"program in WIMP MODE.\n\n"); - fprintf(stderr,"This means that:\n"); - fprintf(stderr," A) Rather than the nifty input like:\n"); - fprintf(stderr,"\tONE NINER SEVEN TWO OH SIX THREE,\n"); - fprintf(stderr," and even niftier output like:\n"); - fprintf(stderr,"\t______\n"); - fprintf(stderr,"\tMCMLXXMMLXIII,\n"); - fprintf(stderr," you will have to settle for plain old number\n"); - fprintf(stderr," representations like 1972063; and,\n"); - fprintf(stderr," B) You are a WIMP!\n\n"); - fflush(stderr); - } -} diff --git a/cesspool.c b/cesspool.c deleted file mode 100644 index 64ea129..0000000 --- a/cesspool.c +++ /dev/null @@ -1,631 +0,0 @@ -/***************************************************************************** - -NAME - cesspool.c -- storage management and runtime support for INTERCAL - -LICENSE TERMS - Copyright (C) 1996 Eric S. Raymond - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - -***************************************************************************/ -/* LINTLIBRARY */ -#include -#include -#include -#include - -#ifdef _POSIX_SOURCE -#include -#else -#include -#endif - -#include "sizes.h" -#include "abcess.h" -#include "lose.h" - -#include "numerals.c" - -FILE* cesspoolin = stdin; -FILE* cesspoolout = stdout; -/* AIS: In a future version of ick or yuk, these might not be constants */ - -/********************************************************************** - * - * The following functions manipulate the nexting stack - * - *********************************************************************/ - -int* next; /* AIS: now allocated by ick-wrap.c */ -int nextindex = 0; - -void pushnext(int n) -{ - if (nextindex < MAXNEXT) - next[nextindex++] = n; - else - lose(E123, lineno, (char *)NULL); -} - -unsigned int popnext(int n) -{ - nextindex -= n; - if (nextindex < 0) { - nextindex = 0; - return (unsigned int)-1; - } - return(next[nextindex]); -} - -unsigned int resume(unsigned int n) -{ - if (n == 0) - { - lose(E621, lineno, (char *)NULL); - return 0; - } - else if ((n = popnext(n)) == (unsigned int)-1) - { - lose(E632, lineno, (char *)NULL); - return 0; - } - return(n); -} - -/********************************************************************** - * - * The following functions implement the INTERCAL I/O model - * - *********************************************************************/ - -unsigned int pin(void) -{ - char buf[BUFSIZ], *cp, *strtok(); - unsigned int result = 0; - int n; - extern int wimp_mode; - - if (fgets(buf, BUFSIZ, cesspoolin) == (char *)NULL) - lose(E562, lineno, (char *)NULL); - n = strlen(buf) - 1; - if (n > 0 && buf[n-1] == '\r') - --n; - buf[n] = '\0'; - - if(wimp_mode) { - result = (unsigned int)strtoul(buf, (char **)NULL, 10); - n = 1; - } - else - { - for(n=0,cp = strtok(buf, " ");cp;cp = strtok((char *)NULL, " "),n++) - { - int digit = -1; - numeral *np; - - for (np = numerals; np < numerals + sizeof(numerals)/sizeof(numeral); np++) - if (strcmp(np->name, cp) == 0) - { - digit = np->value; - break; - } - - if (digit == -1) - lose(E579, lineno, cp); - - if (result < 429496729 || (result == 429496729 && digit < 6)) - result = result * 10 + digit; - else - lose(E533, lineno, (char *)NULL); - } - } - if (!n) - lose(E562, lineno, (char *)NULL); - if (result > (unsigned int)Max_large) - lose(E533, lineno, (char *)NULL); - return(result); -} - -/********************************************************************** - * - * Butchered Roman numerals implemented by - * Michael Ernst, mernst@theory.lcs.mit.edu. May 7, 1990 - * - * The INTERCAL manual hints that 3999 should translate to MMMIM - * (compare MMMCMXCIX) without specifying what the translation is. - * That may be a typo; in any case, this implementation isn't that - * butchered. - * - *********************************************************************/ - -#define MAXDIGITS 10 /* max base 10 digits */ -#define MAXROMANS (MAXDIGITS*4+1) /* max chars in translation */ - -/* - * The first column tells how many of the succeeding columns are used. - * The other columns refer to the columns of br_equiv and br_overbar. - */ -static int br_trans[10][5] = -{ - {0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0}, - {2, 0, 0, 0, 0}, - {3, 0, 0, 0, 0}, - {2, 1, 2, 0, 0}, /* or use {4, 0, 0, 0, 0} */ - {1, 2, 0, 0, 0}, - {2, 2, 1, 0, 0}, - {3, 2, 1, 1, 0}, - {4, 2, 1, 1, 1}, - {2, 1, 3, 0, 0} -}; - -/* - * butcher places in the string result the "butchered" Roman numeral for val. - * This string should be printed at the beginning of a line; it spans two - * lines and already contains newlines. - * - * 11/24/91 LHH: Removed unnecessary final newline. - */ - -static void butcher(unsigned long val, char *result) -{ - int i, j; - int digitsig, digitval; - char res[MAXROMANS], ovb[MAXROMANS]; - - /* We need FOUR columns because of the odd way that M and I interact. */ - static char br_equiv[MAXDIGITS][4] = - { - {'I', 'I', 'V', 'X'}, {'X', 'X', 'L', 'C'}, - {'C', 'C', 'D', 'M'}, {'M', 'I', 'V', 'X'}, - {'X', 'X', 'L', 'C'}, {'C', 'C', 'D', 'M'}, - {'M', 'i', 'v', 'x'}, {'x', 'x', 'l', 'c'}, - {'c', 'c', 'd', 'm'}, {'m', 'i', 'v', 'x'}, - }; - - static char br_overbar[MAXDIGITS][4] = - { - {' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' '}, - {' ', '_', '_', '_'}, - {'_', '_', '_', '_'}, - {'_', '_', '_', '_'}, - {'_', ' ', ' ', ' '}, - {' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' '}, - {' ', '_', '_', '_'}, - }; - - if (val == 0) -/* Final newline will be added by puts. - (void) strcpy(result, "_\n \n"); -*/ - (void) strcpy(result, "_\n"); - else - { - res[MAXROMANS-1] = 0; - ovb[MAXROMANS-1] = 0; - i = MAXROMANS-1; - - /* the significance of the current digit is 10 ** digitsig */ - for (digitsig = 0; (digitsig < MAXDIGITS) && (val > 0); digitsig++) - { - digitval = val % 10; - for (j = br_trans[digitval][0]; j > 0; j--) - { - /* printf("In j loop: %d %d\n", j, i); */ - res[--i] = br_equiv[digitsig][br_trans[digitval][j]]; - ovb[i] = br_overbar[digitsig][br_trans[digitval][j]]; - } - val = val / 10; - } - - j = i; - while ((*result++ = ovb[j++])) - continue; - *--result = '\n'; - - j = i; - while ((*++result = res[j++])) - continue; -/* Final newline will be added by puts. - *result++ = '\n'; -*/ - *result = '\0'; - } -} - -void clockface(bool mode) -/* enable or disable clockface mode (output IIII instead of IV) */ -{ - if (mode) - { - /* clockface mode */ - br_trans[4][0] = 4; - br_trans[4][1] = 0; - br_trans[4][2] = 0; - } - else - { - /* normal mode */ - br_trans[4][0] = 2; - br_trans[4][1] = 1; - br_trans[4][2] = 2; - } -} - -void pout(unsigned int val) -/* output in `butchered' Roman numerals; see manual, part 4.4.13 */ -{ - char result[2*MAXROMANS+1]; - extern int wimp_mode; - - if(wimp_mode) { - (void) fprintf(cesspoolout,"%u\n",val); - } - else { - butcher(val, result); - (void) fprintf(cesspoolout,"%s\n",result); - } - fflush(cesspoolout); -} - -/********************************************************************** - * - * The following two routines implement bitwise I/O. They assume - * 8 bit characters, but there's no reason more general versions - * could not be written. - * - *********************************************************************/ - -void binin(unsigned int type, array *a, bool forget) -{ - static unsigned int lastin = 0; - int c, v; - unsigned int i; - - if (a->rank != 1) - lose(E241, lineno, (char *)NULL); - - for (i = 0 ; i < a->dims[0] ; i++) { - v = ((c=fgetc(cesspoolin)) == EOF) ? 256 : (c - lastin) % 256; - lastin = c; - if (!forget) { - if (type == TAIL) - a->data.tail[i] = v; - else - a->data.hybrid[i] = v; - } - } -} - -void binout(unsigned int type, array *a) -{ - static unsigned int lastout = 0; - unsigned int i, c; - - if (a->rank != 1) - lose(E241, lineno, (char *)NULL); - - for (i = 0 ; i < a->dims[0] ; i++) { - if (type == TAIL) - c = lastout - a->data.tail[i]; - else - c = lastout - a->data.hybrid[i]; - lastout = c; - c = (c & 0x0f) << 4 | (c & 0xf0) >> 4; - c = (c & 0x33) << 2 | (c & 0xcc) >> 2; - c = (c & 0x55) << 1 | (c & 0xaa) >> 1; - fputc(c,cesspoolout); - if (c == '\n') - fflush(cesspoolout); - } -} - -/********************************************************************** - * - * The following assignment function performs IGNORE and type checks - * - *********************************************************************/ - -unsigned int assign(char *dest, unsigned int type, bool forget, - unsigned int value) -{ - unsigned int retval; - if (type == ONESPOT || type == TAIL) { - if (value > (unsigned int)Max_small) - lose(E275, lineno, (char *)NULL); - if (forget) - retval = value; - else { - retval = *(type16*)dest; - *(type16*)dest = value; - } - } - else if (type == TWOSPOT || type == HYBRID) { - if (forget) - retval = value; - else { - retval = *(type32*)dest; - *(type32*)dest = value; - } - } - return retval; -} - -/********************************************************************** - * - * The following functions implement the INTERCAL array model - * If _POSIX_SOURCE is defined, stdarg is used, otherwise varargs. - * - *********************************************************************/ - - -#ifdef _POSIX_SOURCE -char *aref(unsigned int type, ...) -#else -char *aref(va_alist) va_dcl -#endif -/* return a pointer to the array location specified by args */ -{ -#ifndef _POSIX_SOURCE - unsigned int type; -#endif - array *a; - unsigned int v; - va_list ap; - int address = 0; - unsigned int i; - -#ifdef _POSIX_SOURCE - va_start(ap, type); -#else - va_start(ap); - type = va_arg(ap, unsigned int); -#endif - a = va_arg(ap, array*); - - if (va_arg(ap, unsigned int) != a->rank) - lose(E241, lineno, (char *)NULL); - - for (i = 0 ; i < a->rank ; i++) { - v = va_arg(ap, unsigned int); - if (v == 0 || v > a->dims[i]) - lose(E241, lineno, (char *)NULL); - address = address * a->dims[i] + v - 1; - } - - va_end(ap); - - if (type == TAIL) - return (char*)&a->data.tail[address]; - else - return (char*)&a->data.hybrid[address]; -} - -#ifdef _POSIX_SOURCE -void resize(unsigned int type, ...) -#else -void resize(va_alist) va_dcl -#endif -/* resize an array to the given shape */ -{ -#ifndef _POSIX_SOURCE - unsigned int type; -#endif - array *a; - bool forget; - unsigned int i, r, v; - va_list ap; - int prod = 1; - -#ifdef _POSIX_SOURCE - va_start(ap, type); -#else - va_start(ap); - type = va_arg(ap, unsigned int); -#endif - a = va_arg(ap, array*); - forget = va_arg(ap, bool); - - if (!a->rank) a->dims = 0; /* AIS: a->dims no longer initialised */ - - r = va_arg(ap, unsigned int); - if (!forget) { - a->rank = r; - if (a->dims) - free((char*)a->dims); - a->dims = (unsigned int*) malloc(a->rank * sizeof(unsigned int)); - if (a->dims == NULL) - lose(E241, lineno, (char *)NULL); - } - - for (i = 0 ; i < r ; i++) { - v = va_arg(ap, unsigned int); - if (v == 0) - lose(E240, lineno, (char *)NULL); - if (!forget) { - a->dims[i] = v; - prod *= v; - } - } - - if (!forget) { - if (type == TAIL) { - if (a->data.tail) - free((char *)a->data.tail); - a->data.tail = (type16*)malloc(prod * sizeof(type16)); - if (a->data.tail == NULL) - lose(E241, lineno, (char *)NULL); - } - else { - if (a->data.hybrid) - free((char *)a->data.hybrid); - a->data.hybrid = (type32*)malloc(prod * sizeof(type32)); - if (a->data.hybrid == NULL) - lose(E241, lineno, (char *)NULL); - } - } - - va_end(ap); -} - -/********************************************************************** - * - * The following functions implement save/retrieve - * - *********************************************************************/ - -stashbox *first; /* AIS: made non-static so it can be seen by unravel.c */ - -void stashinit(void) -{ - first = NULL; -} - -static stashbox *fetch(unsigned int type, unsigned int index) -/* find a stashed variable in the save stack and extract it */ -{ - stashbox **pp = &first, *sp = first; - - while (sp && (sp->type != type || sp->index != index)) { - pp = &sp->next; - sp = sp->next; - } - if (sp) - *pp = sp->next; - - return (sp); -} - -void stash(unsigned int type, unsigned int index, void *from) -/* stash away the variable's value */ -{ - /* create a new stashbox and push it onto the stack */ - stashbox *sp = (stashbox*)malloc(sizeof(stashbox)); - if (sp == NULL) lose(E222, lineno, (char *)NULL); - sp->next = first; - first = sp; - - /* store the variable in it */ - sp->type = type; - sp->index = index; - if (type == ONESPOT) - memcpy((char *)&sp->save.onespot, from, sizeof(type16)); - else if (type == TWOSPOT) - memcpy((char *)&sp->save.twospot, from, sizeof(type32)); - else if (type == TAIL || type == HYBRID) { - array *a = (array*)from; - int prod; - unsigned int i; - sp->save.a = (array*)malloc(sizeof(array)); - if (sp->save.a == NULL) lose(E222, lineno, (char *)NULL); - sp->save.a->rank = a->rank; - sp->save.a->dims = (unsigned int*)malloc(a->rank * sizeof(unsigned int)); - if (sp->save.a->dims == NULL) lose(E222, lineno, (char *)NULL); - memcpy((char*)sp->save.a->dims, (char*)a->dims, - a->rank * sizeof(unsigned int)); - prod = a->rank ? 1 : 0; - for (i = 0 ; i < a->rank ; i++) { - prod *= a->dims[i]; - } - if (type == TAIL) { - sp->save.a->data.tail = - (type16*)malloc(prod * sizeof(type16)); - if (sp->save.a->data.tail == NULL) lose(E222, lineno, (char *)NULL); - memcpy((char *)sp->save.a->data.tail, - (char*)a->data.tail, prod * sizeof(type16)); - } - else { - sp->save.a->data.hybrid = - (type32*)malloc(prod * sizeof(type32)); - if (sp->save.a->data.hybrid == NULL) lose(E222, lineno, (char *)NULL); - memcpy((char *)sp->save.a->data.hybrid, - (char*)a->data.hybrid, prod * sizeof(type32)); - } - } - return; -} - -void retrieve(void *to, int type, unsigned int index, bool forget) -/* restore the value of a variable from the save stack */ -{ - stashbox *sp; - - if ((sp = fetch(type, index)) == (stashbox *)NULL) - lose(E436, lineno, (char *)NULL); - else if (!forget) { - if (type == ONESPOT) - memcpy(to, (char *)&sp->save.onespot, sizeof(type16)); - else if (type == TWOSPOT) - memcpy(to, (char *)&sp->save.twospot, sizeof(type32)); - else if (type == TAIL || type == HYBRID) { - array *a = (array*)to; - if (a->rank) { - free(a->dims); - if (type == TAIL) - free(a->data.tail); - else - free(a->data.hybrid); - memcpy(to, (char*)sp->save.a, sizeof(array)); - } - free(sp->save.a); - } - } - else if (type == TAIL || type == HYBRID) { - free(sp->save.a->dims); - if (type == TAIL) - free(sp->save.a->data.tail); - else - free(sp->save.a->data.hybrid); - free(sp->save.a); - } - free(sp); -} - -/********************************************************************** - * - * The following function is used for random decision making - * - *********************************************************************/ - -unsigned int roll(unsigned int n) -/* return TRUE on n% chance, FALSE otherwise */ -{ -#ifdef USG - return((unsigned int)(lrand48() % 100) < n); -#else - return((unsigned int)(rand() % 100) < n); -#endif /* UNIX */ -} - -/********************************************************************** - * - * AIS: This function is called when two COME FROMs reference the same - * line at runtime. multicome0 is used in a non-multithread - * program; it produces an error. For multicome1, see unravel.c. - * - *********************************************************************/ - -int multicome0(int errlineno, jmp_buf pc) -{ - lose(E555, errlineno, (char *) NULL); - /* this line number is quite possibly going to be wildly inaccurate */ - return 0; -} - -/* cesspool.c ends here */ diff --git a/cleanick.bat b/cleanick.bat new file mode 100755 index 0000000..c5cc758 --- /dev/null +++ b/cleanick.bat @@ -0,0 +1,14 @@ +@echo off +rem This batch file removes all files that aren't needed to recompile. +del /q bin\*.* +del /q lib\*.* +del /q include\*.* +del /q temp\*.h +del /q temp\*.c +del /q temp\*.o +del /q temp\*.a +del /q temp\*.y +del /q temp\*.l +del /q temp\*.bat +del /q temp\*.sh +del /q temp\ickmain.exe diff --git a/cleanick.sh b/cleanick.sh new file mode 100755 index 0000000..2c459fd --- /dev/null +++ b/cleanick.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# make cleanick as a shell-script, for the benefit of DJGPP systems with broken +# versions of make. +# This batch file removes all files that weren't in the distribution. +rm -f bin/*.* +rm -f lib/*.* +rm -f include/*.* +rm -f temp/*.h +rm -f temp/*.c +rm -f temp/*.o +rm -f temp/*.a +rm -f temp/*.y +rm -f temp/*.l +rm -f temp/*.bat +rm -f temp/*.sh +rm -f temp/ickmain.exe +rm -f temp/*~ +rm -f src/*~ +rm -f *~ \ No newline at end of file diff --git a/config.h.in b/config.h.in deleted file mode 100644 index 5551add..0000000 --- a/config.h.in +++ /dev/null @@ -1,94 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#undef HAVE_MALLOC - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the `memset' function. */ -#undef HAVE_MEMSET - -/* Define to 1 if your system has a GNU libc compatible `realloc' function, - and to 0 otherwise. */ -#undef HAVE_REALLOC - -/* Define to 1 if stdbool.h conforms to C99. */ -#undef HAVE_STDBOOL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDDEF_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 `strrchr' function. */ -#undef HAVE_STRRCHR - -/* Define to 1 if you have the `strtol' function. */ -#undef HAVE_STRTOL - -/* Define to 1 if you have the `strtoul' function. */ -#undef HAVE_STRTOUL - -/* 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_UNISTD_H - -/* Define to 1 if the system has the type `_Bool'. */ -#undef HAVE__BOOL - -/* 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 version of this package. */ -#undef PACKAGE_VERSION - -/* Define as the return type of signal handlers (`int' or `void'). */ -#undef RETSIGTYPE - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a - `char[]'. */ -#undef YYTEXT_POINTER - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to rpl_malloc if the replacement function should be used. */ -#undef malloc - -/* Define to rpl_realloc if the replacement function should be used. */ -#undef realloc - -/* Define to `unsigned' if does not define. */ -#undef size_t diff --git a/config.log b/config.log new file mode 100644 index 0000000..75ff729 --- /dev/null +++ b/config.log @@ -0,0 +1,1144 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by intercal configure.sh 0.26, which was +generated by GNU Autoconf 2.57. Invocation command line was + + $ configure.sh + +## --------- ## +## Platform. ## +## --------- ## + +hostname = chillingi +uname -m = sun4u +uname -r = 5.9 +uname -s = SunOS +uname -v = Generic_118558-34 + +/usr/bin/uname -p = sparc +/bin/uname -X = System = SunOS +Node = chillingi +Release = 5.9 +KernelID = Generic_118558-34 +Machine = sun4u +BusType = +Serial = +Users = +OEM# = 0 +Origin# = 1 +NumCPU = 2 + +/bin/arch = sun4 +/usr/bin/arch -k = sun4u +/usr/convex/getsysinfo = unknown +hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: . +PATH: /home/ais523/bin +PATH: /home/ais523 +PATH: /opt/SUNWspro/bin +PATH: /usr/local/bin +PATH: /usr/sbin +PATH: /usr/ucb +PATH: /usr/bin +PATH: /usr/ccs/bin +PATH: /usr/etc +PATH: /usr/dt/bin +PATH: /usr/openwin/bin +PATH: /apps7/bin +PATH: /apps7/script + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure.sh:1275: checking for bison +configure.sh:1304: result: no +configure.sh:1275: checking for byacc +configure.sh:1304: result: no +configure.sh:1358: checking for gcc +configure.sh:1374: found /usr/local/bin/gcc +configure.sh:1384: result: gcc +configure.sh:1628: checking for C compiler version +configure.sh:1631: gcc --version &5 +2.95.2 +configure.sh:1634: $? = 0 +configure.sh:1636: gcc -v &5 +Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.7/2.95.2/specs +gcc version 2.95.2 19991024 (release) +configure.sh:1639: $? = 0 +configure.sh:1641: gcc -V &5 +gcc: argument to `-V' is missing +configure.sh:1644: $? = 1 +configure.sh:1668: checking for C compiler default output +configure.sh:1671: gcc conftest.c >&5 +configure.sh:1674: $? = 0 +configure.sh:1720: result: a.out +configure.sh:1725: checking whether the C compiler works +configure.sh:1731: ./a.out +configure.sh:1734: $? = 0 +configure.sh:1751: result: yes +configure.sh:1758: checking whether we are cross compiling +configure.sh:1760: result: no +configure.sh:1763: checking for suffix of executables +configure.sh:1765: gcc -o conftest conftest.c >&5 +configure.sh:1768: $? = 0 +configure.sh:1793: result: +configure.sh:1799: checking for suffix of object files +configure.sh:1821: gcc -c conftest.c >&5 +configure.sh:1824: $? = 0 +configure.sh:1846: result: o +configure.sh:1850: checking whether we are using the GNU C compiler +configure.sh:1875: gcc -c conftest.c >&5 +configure.sh:1878: $? = 0 +configure.sh:1881: test -s conftest.o +configure.sh:1884: $? = 0 +configure.sh:1897: result: yes +configure.sh:1903: checking whether gcc accepts -g +configure.sh:1925: gcc -c -g conftest.c >&5 +configure.sh:1928: $? = 0 +configure.sh:1931: test -s conftest.o +configure.sh:1934: $? = 0 +configure.sh:1945: result: yes +configure.sh:1962: checking for gcc option to accept ANSI C +configure.sh:2023: gcc -c -g -O2 conftest.c >&5 +configure.sh:2026: $? = 0 +configure.sh:2029: test -s conftest.o +configure.sh:2032: $? = 0 +configure.sh:2050: result: none needed +configure.sh:2068: gcc -c -g -O2 conftest.c >&5 +conftest.c:2: parse error before `me' +configure.sh:2071: $? = 1 +configure.sh: failed program was: +| #ifndef __cplusplus +| choke me +| #endif +configure.sh:2185: checking for flex +configure.sh:2214: result: no +configure.sh:2185: checking for lex +configure.sh:2201: found /usr/ccs/bin/lex +configure.sh:2211: result: lex +configure.sh:2224: checking for yywrap in -lfl +configure.sh:2255: gcc -o conftest -g -O2 conftest.c -lfl >&5 +ld: fatal: library -lfl: not found +ld: fatal: File processing errors. No output written to conftest +collect2: ld returned 1 exit status +configure.sh:2258: $? = 1 +configure.sh: failed program was: +| #line 2231 "configure" +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "intercal" +| #define PACKAGE_TARNAME "intercal" +| #define PACKAGE_VERSION "0.26" +| #define PACKAGE_STRING "intercal 0.26" +| #define PACKAGE_BUGREPORT "esr@thyrsus.com" +| /* end confdefs.h. */ +| +| /* Override any gcc2 internal prototype to avoid an error. */ +| #ifdef __cplusplus +| extern "C" +| #endif +| /* We use char because int might match the return type of a gcc2 +| builtin and then its argument prototype would still apply. */ +| char yywrap (); +| int +| main () +| { +| yywrap (); +| ; +| return 0; +| } +configure.sh:2276: result: no +configure.sh:2281: checking for yywrap in -ll +configure.sh:2312: gcc -o conftest -g -O2 conftest.c -ll >&5 +configure.sh:2315: $? = 0 +configure.sh:2318: test -s conftest +configure.sh:2321: $? = 0 +configure.sh:2333: result: yes +configure.sh:2344: checking lex output file root +configure.sh:2355: lex conftest.l +configure.sh:2358: $? = 0 +configure.sh:2370: result: lex.yy +configure.sh:2375: checking whether yytext is a pointer +configure.sh:2391: gcc -o conftest -g -O2 conftest.c -ll >&5 +conftest.c:418: conflicting types for `yytext' +conftest.c:71: previous declaration of `yytext' +configure.sh:2394: $? = 1 +configure.sh: failed program was: +| #include +| #include +| #include +| # define U(x) x +| # define NLSTATE yyprevious=YYNEWLINE +| # define BEGIN yybgin = yysvec + 1 + +| # define INITIAL 0 +| # define YYLERR yysvec +| # define YYSTATE (yyestate-yysvec-1) +| # define YYOPTIM 1 +| # ifndef YYLMAX +| # define YYLMAX BUFSIZ +| # endif +| #ifndef __cplusplus +| # define output(c) (void)putc(c,yyout) +| #else +| # define lex_output(c) (void)putc(c,yyout) +| #endif +| +| #if defined(__cplusplus) || defined(__STDC__) +| +| #if defined(__cplusplus) && defined(__EXTERN_C__) +| extern "C" { +| #endif +| int yyback(int *, int); +| int yyinput(void); +| int yylook(void); +| void yyoutput(int); +| int yyracc(int); +| int yyreject(void); +| void yyunput(int); +| int yylex(void); +| #ifdef YYLEX_E +| void yywoutput(wchar_t); +| wchar_t yywinput(void); +| #endif +| #ifndef yyless +| int yyless(int); +| #endif +| #ifndef yywrap +| int yywrap(void); +| #endif +| #ifdef LEXDEBUG +| void allprint(char); +| void sprint(char *); +| #endif +| #if defined(__cplusplus) && defined(__EXTERN_C__) +| } +| #endif +| +| #ifdef __cplusplus +| extern "C" { +| #endif +| void exit(int); +| #ifdef __cplusplus +| } +| #endif +| +| #endif +| # define unput(c) {yytchar= (c);if(yytchar=='\n')yylineno--;*yysptr++=yytchar;} +| # define yymore() (yymorfg=1) +| #ifndef __cplusplus +| # define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar) +| #else +| # define lex_input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar) +| #endif +| #define ECHO fprintf(yyout, "%s",yytext) +| # define REJECT { nstr = yyreject(); goto yyfussy;} +| int yyleng; +| #define YYISARRAY +| char yytext[YYLMAX]; +| int yymorfg; +| extern char *yysptr, yysbuf[]; +| int yytchar; +| FILE *yyin = {stdin}, *yyout = {stdout}; +| extern int yylineno; +| struct yysvf { +| struct yywork *yystoff; +| struct yysvf *yyother; +| int *yystops;}; +| struct yysvf *yyestate; +| extern struct yysvf yysvec[], *yybgin; +| # define YYNEWLINE 10 +| yylex(){ +| int nstr; extern int yyprevious; +| #ifdef __cplusplus +| /* to avoid CC and lint complaining yyfussy not being used ...*/ +| static int __lex_hack = 0; +| if (__lex_hack) goto yyfussy; +| #endif +| while((nstr = yylook()) >= 0) +| yyfussy: switch(nstr){ +| case 0: +| if(yywrap()) return(0); break; +| case -1: +| break; +| default: +| (void)fprintf(yyout,"bad switch yylook %d",nstr); +| } return(0); } +| /* end of yylex */ +| int yyvstop[] = { +| 0, +| 0}; +| # define YYTYPE unsigned char +| struct yywork { YYTYPE verify, advance; } yycrank[] = { +| 0,0, 0,0, 0,0, 0,0, +| 0,0}; +| struct yysvf yysvec[] = { +| 0, 0, 0, +| yycrank+0, 0, 0, +| yycrank+0, 0, 0, +| 0, 0, 0}; +| struct yywork *yytop = yycrank+0; +| struct yysvf *yybgin = yysvec+1; +| char yymatch[] = { +| 0, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 1, 1, 1, 1, 1, 1, 1, 1, +| 0}; +| char yyextra[] = { +| 0,0,0,0,0,0,0,0, +| 0}; +| /* Copyright (c) 1989 AT&T */ +| /* All Rights Reserved */ +| +| /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ +| /* The copyright notice above does not evidence any */ +| /* actual or intended publication of such source code. */ +| +| #pragma ident "@(#)ncform 6.12 97/12/08 SMI" +| +| int yylineno =1; +| # define YYU(x) x +| # define NLSTATE yyprevious=YYNEWLINE +| struct yysvf *yylstate [YYLMAX], **yylsp, **yyolsp; +| char yysbuf[YYLMAX]; +| char *yysptr = yysbuf; +| int *yyfnd; +| extern struct yysvf *yyestate; +| int yyprevious = YYNEWLINE; +| #if defined(__cplusplus) || defined(__STDC__) +| int yylook(void) +| #else +| yylook() +| #endif +| { +| register struct yysvf *yystate, **lsp; +| register struct yywork *yyt; +| struct yysvf *yyz; +| int yych, yyfirst; +| struct yywork *yyr; +| # ifdef LEXDEBUG +| int debug; +| # endif +| char *yylastch; +| /* start off machines */ +| # ifdef LEXDEBUG +| debug = 0; +| # endif +| yyfirst=1; +| if (!yymorfg) +| yylastch = yytext; +| else { +| yymorfg=0; +| yylastch = yytext+yyleng; +| } +| for(;;){ +| lsp = yylstate; +| yyestate = yystate = yybgin; +| if (yyprevious==YYNEWLINE) yystate++; +| for (;;){ +| # ifdef LEXDEBUG +| if(debug)fprintf(yyout,"state %d\n",yystate-yysvec-1); +| # endif +| yyt = yystate->yystoff; +| if(yyt == yycrank && !yyfirst){ /* may not be any transitions */ +| yyz = yystate->yyother; +| if(yyz == 0)break; +| if(yyz->yystoff == yycrank)break; +| } +| #ifndef __cplusplus +| *yylastch++ = yych = input(); +| #else +| *yylastch++ = yych = lex_input(); +| #endif +| #ifdef YYISARRAY +| if(yylastch > &yytext[YYLMAX]) { +| fprintf(yyout,"Input string too long, limit %d\n",YYLMAX); +| exit(1); +| } +| #else +| if (yylastch >= &yytext[ yytextsz ]) { +| int x = yylastch - yytext; +| +| yytextsz += YYTEXTSZINC; +| if (yytext == yy_tbuf) { +| yytext = (char *) malloc(yytextsz); +| memcpy(yytext, yy_tbuf, sizeof (yy_tbuf)); +| } +| else +| yytext = (char *) realloc(yytext, yytextsz); +| if (!yytext) { +| fprintf(yyout, +| "Cannot realloc yytext\n"); +| exit(1); +| } +| yylastch = yytext + x; +| } +| #endif +| yyfirst=0; +| tryagain: +| # ifdef LEXDEBUG +| if(debug){ +| fprintf(yyout,"char "); +| allprint(yych); +| putchar('\n'); +| } +| # endif +| yyr = yyt; +| if ( (uintptr_t)yyt > (uintptr_t)yycrank){ +| yyt = yyr + yych; +| if (yyt <= yytop && yyt->verify+yysvec == yystate){ +| if(yyt->advance+yysvec == YYLERR) /* error transitions */ +| {unput(*--yylastch);break;} +| *lsp++ = yystate = yyt->advance+yysvec; +| if(lsp > &yylstate[YYLMAX]) { +| fprintf(yyout,"Input string too long, limit %d\n",YYLMAX); +| exit(1); +| } +| goto contin; +| } +| } +| # ifdef YYOPTIM +| else if((uintptr_t)yyt < (uintptr_t)yycrank) { /* r < yycrank */ +| yyt = yyr = yycrank+(yycrank-yyt); +| # ifdef LEXDEBUG +| if(debug)fprintf(yyout,"compressed state\n"); +| # endif +| yyt = yyt + yych; +| if(yyt <= yytop && yyt->verify+yysvec == yystate){ +| if(yyt->advance+yysvec == YYLERR) /* error transitions */ +| {unput(*--yylastch);break;} +| *lsp++ = yystate = yyt->advance+yysvec; +| if(lsp > &yylstate[YYLMAX]) { +| fprintf(yyout,"Input string too long, limit %d\n",YYLMAX); +| exit(1); +| } +| goto contin; +| } +| yyt = yyr + YYU(yymatch[yych]); +| # ifdef LEXDEBUG +| if(debug){ +| fprintf(yyout,"try fall back character "); +| allprint(YYU(yymatch[yych])); +| putchar('\n'); +| } +| # endif +| if(yyt <= yytop && yyt->verify+yysvec == yystate){ +| if(yyt->advance+yysvec == YYLERR) /* error transition */ +| {unput(*--yylastch);break;} +| *lsp++ = yystate = yyt->advance+yysvec; +| if(lsp > &yylstate[YYLMAX]) { +| fprintf(yyout,"Input string too long, limit %d\n",YYLMAX); +| exit(1); +| } +| goto contin; +| } +| } +| if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){ +| # ifdef LEXDEBUG +| if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1); +| # endif +| goto tryagain; +| } +| # endif +| else +| {unput(*--yylastch);break;} +| contin: +| # ifdef LEXDEBUG +| if(debug){ +| fprintf(yyout,"state %d char ",yystate-yysvec-1); +| allprint(yych); +| putchar('\n'); +| } +| # endif +| ; +| } +| # ifdef LEXDEBUG +| if(debug){ +| fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1); +| allprint(yych); +| putchar('\n'); +| } +| # endif +| while (lsp-- > yylstate){ +| *yylastch-- = 0; +| if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){ +| yyolsp = lsp; +| if(yyextra[*yyfnd]){ /* must backup */ +| while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){ +| lsp--; +| unput(*yylastch--); +| } +| } +| yyprevious = YYU(*yylastch); +| yylsp = lsp; +| yyleng = yylastch-yytext+1; +| yytext[yyleng] = 0; +| # ifdef LEXDEBUG +| if(debug){ +| fprintf(yyout,"\nmatch "); +| sprint(yytext); +| fprintf(yyout," action %d\n",*yyfnd); +| } +| # endif +| return(*yyfnd++); +| } +| unput(*yylastch); +| } +| if (yytext[0] == 0 /* && feof(yyin) */) +| { +| yysptr=yysbuf; +| return(0); +| } +| #ifndef __cplusplus +| yyprevious = yytext[0] = input(); +| if (yyprevious>0) +| output(yyprevious); +| #else +| yyprevious = yytext[0] = lex_input(); +| if (yyprevious>0) +| lex_output(yyprevious); +| #endif +| yylastch=yytext; +| # ifdef LEXDEBUG +| if(debug)putchar('\n'); +| # endif +| } +| } +| #if defined(__cplusplus) || defined(__STDC__) +| int yyback(int *p, int m) +| #else +| yyback(p, m) +| int *p; +| #endif +| { +| if (p==0) return(0); +| while (*p) { +| if (*p++ == m) +| return(1); +| } +| return(0); +| } +| /* the following are only used in the lex library */ +| #if defined(__cplusplus) || defined(__STDC__) +| int yyinput(void) +| #else +| yyinput() +| #endif +| { +| #ifndef __cplusplus +| return(input()); +| #else +| return(lex_input()); +| #endif +| } +| #if defined(__cplusplus) || defined(__STDC__) +| void yyoutput(int c) +| #else +| yyoutput(c) +| int c; +| #endif +| { +| #ifndef __cplusplus +| output(c); +| #else +| lex_output(c); +| #endif +| } +| #if defined(__cplusplus) || defined(__STDC__) +| void yyunput(int c) +| #else +| yyunput(c) +| int c; +| #endif +| { +| unput(c); +| } +| extern char *yytext; +configure.sh:2413: result: no +configure.sh:2461: checking for a BSD-compatible install +configure.sh:2515: result: ./install.sh -c +configure.sh:2526: checking whether ln -s works +configure.sh:2530: result: yes +configure.sh:2537: checking whether make sets $(MAKE) +configure.sh:2557: result: yes +configure.sh:2575: checking how to run the C preprocessor +configure.sh:2611: gcc -E conftest.c +configure.sh:2617: $? = 0 +configure.sh:2649: gcc -E conftest.c +configure:2648: ac_nonexistent.h: No such file or directory +configure.sh:2655: $? = 1 +configure.sh: failed program was: +| #line 2640 "configure" +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "intercal" +| #define PACKAGE_TARNAME "intercal" +| #define PACKAGE_VERSION "0.26" +| #define PACKAGE_STRING "intercal 0.26" +| #define PACKAGE_BUGREPORT "esr@thyrsus.com" +| /* end confdefs.h. */ +| #include +configure.sh:2693: result: gcc -E +configure.sh:2718: gcc -E conftest.c +configure.sh:2724: $? = 0 +configure.sh:2756: gcc -E conftest.c +configure:2755: ac_nonexistent.h: No such file or directory +configure.sh:2762: $? = 1 +configure.sh: failed program was: +| #line 2747 "configure" +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "intercal" +| #define PACKAGE_TARNAME "intercal" +| #define PACKAGE_VERSION "0.26" +| #define PACKAGE_STRING "intercal 0.26" +| #define PACKAGE_BUGREPORT "esr@thyrsus.com" +| /* end confdefs.h. */ +| #include +configure.sh:2805: checking for egrep +configure.sh:2815: result: egrep +configure.sh:2820: checking for ANSI C header files +configure.sh:2846: gcc -c -g -O2 conftest.c >&5 +configure.sh:2849: $? = 0 +configure.sh:2852: test -s conftest.o +configure.sh:2855: $? = 0 +configure.sh:2944: gcc -o conftest -g -O2 conftest.c >&5 +configure.sh:2947: $? = 0 +configure.sh:2949: ./conftest +configure.sh:2952: $? = 0 +configure.sh:2967: result: yes +configure.sh:2991: checking for sys/types.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for sys/stat.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for stdlib.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for string.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for memory.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for strings.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for inttypes.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:2991: checking for stdint.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure:3047: stdint.h: No such file or directory +configure.sh:3011: $? = 1 +configure.sh: failed program was: +| #line 2996 "configure" +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "intercal" +| #define PACKAGE_TARNAME "intercal" +| #define PACKAGE_VERSION "0.26" +| #define PACKAGE_STRING "intercal 0.26" +| #define PACKAGE_BUGREPORT "esr@thyrsus.com" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| /* end confdefs.h. */ +| #include +| #if HAVE_SYS_TYPES_H +| # include +| #endif +| #if HAVE_SYS_STAT_H +| # include +| #endif +| #if STDC_HEADERS +| # include +| # include +| #else +| # if HAVE_STDLIB_H +| # include +| # endif +| #endif +| #if HAVE_STRING_H +| # if !STDC_HEADERS && HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #if HAVE_STRINGS_H +| # include +| #endif +| #if HAVE_INTTYPES_H +| # include +| #else +| # if HAVE_STDINT_H +| # include +| # endif +| #endif +| #if HAVE_UNISTD_H +| # include +| #endif +| +| #include +configure.sh:3028: result: no +configure.sh:2991: checking for unistd.h +configure.sh:3008: gcc -c -g -O2 conftest.c >&5 +configure.sh:3011: $? = 0 +configure.sh:3014: test -s conftest.o +configure.sh:3017: $? = 0 +configure.sh:3028: result: yes +configure.sh:3049: checking for memory.h +configure.sh:3054: result: yes +configure.sh:3058: checking stddef.h usability +configure.sh:3071: gcc -c -g -O2 conftest.c >&5 +configure.sh:3074: $? = 0 +configure.sh:3077: test -s conftest.o +configure.sh:3080: $? = 0 +configure.sh:3090: result: yes +configure.sh:3094: checking stddef.h presence +configure.sh:3105: gcc -E conftest.c +configure.sh:3111: $? = 0 +configure.sh:3130: result: yes +configure.sh:3166: checking for stddef.h +configure.sh:3173: result: yes +configure.sh:3049: checking for stdlib.h +configure.sh:3054: result: yes +configure.sh:3049: checking for string.h +configure.sh:3054: result: yes +configure.sh:3049: checking for unistd.h +configure.sh:3054: result: yes +configure.sh:3188: checking for stdbool.h that conforms to C99 +configure.sh:3242: gcc -c -g -O2 conftest.c >&5 +configure:3218: #error bool is not defined +configure:3230: #error true is not 1 +configure.sh:3245: $? = 1 +configure.sh: failed program was: +| #line 3193 "configure" +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "intercal" +| #define PACKAGE_TARNAME "intercal" +| #define PACKAGE_VERSION "0.26" +| #define PACKAGE_STRING "intercal 0.26" +| #define PACKAGE_BUGREPORT "esr@thyrsus.com" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_UNISTD_H 1 +| /* 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]; +| bool e = &s; +| char f[(_Bool) -0.0 == false ? 1 : -1]; +| char g[true]; +| char h[sizeof (_Bool)]; +| char i[sizeof s.t]; +| +| int +| main () +| { +| return !a + !b + !c + !d + !e + !f + !g + !h + !i; +| ; +| return 0; +| } +configure.sh:3262: result: no +configure.sh:3264: checking for _Bool +configure.sh:3289: gcc -c -g -O2 conftest.c >&5 +configure: In function `main': +configure:3328: `_Bool' undeclared (first use in this function) +configure:3328: (Each undeclared identifier is reported only once +configure:3328: for each function it appears in.) +configure:3328: parse error before `)' +configure.sh:3292: $? = 1 +configure.sh: failed program was: +| #line 3269 "configure" +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "intercal" +| #define PACKAGE_TARNAME "intercal" +| #define PACKAGE_VERSION "0.26" +| #define PACKAGE_STRING "intercal 0.26" +| #define PACKAGE_BUGREPORT "esr@thyrsus.com" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +| #if HAVE_SYS_TYPES_H +| # include +| #endif +| #if HAVE_SYS_STAT_H +| # include +| #endif +| #if STDC_HEADERS +| # include +| # include +| #else +| # if HAVE_STDLIB_H +| # include +| # endif +| #endif +| #if HAVE_STRING_H +| # if !STDC_HEADERS && HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #if HAVE_STRINGS_H +| # include +| #endif +| #if HAVE_INTTYPES_H +| # include +| #else +| # if HAVE_STDINT_H +| # include +| # endif +| #endif +| #if HAVE_UNISTD_H +| # include +| #endif +| int +| main () +| { +| if ((_Bool *) 0) +| return 0; +| if (sizeof (_Bool)) +| return 0; +| ; +| return 0; +| } +configure.sh:3309: result: no +configure.sh:3328: checking for an ANSI C-conforming const +configure.sh:3396: gcc -c -g -O2 conftest.c >&5 +configure.sh:3399: $? = 0 +configure.sh:3402: test -s conftest.o +configure.sh:3405: $? = 0 +configure.sh:3416: result: yes +configure.sh:3426: checking for size_t +configure.sh:3451: gcc -c -g -O2 conftest.c >&5 +configure.sh:3454: $? = 0 +configure.sh:3457: test -s conftest.o +configure.sh:3460: $? = 0 +configure.sh:3471: result: yes +configure.sh:3490: checking for stdlib.h +configure.sh:3495: result: yes +configure.sh:3627: checking for GNU libc compatible malloc +configure.sh:3657: gcc -o conftest -g -O2 conftest.c >&5 +configure.sh:3660: $? = 0 +configure.sh:3662: ./conftest +configure.sh:3665: $? = 0 +configure.sh:3679: result: yes +configure.sh:3707: checking for stdlib.h +configure.sh:3712: result: yes +configure.sh:3844: checking for GNU libc compatible realloc +configure.sh:3874: gcc -o conftest -g -O2 conftest.c >&5 +configure.sh:3877: $? = 0 +configure.sh:3879: ./conftest +configure.sh:3882: $? = 0 +configure.sh:3896: result: yes +configure.sh:3919: checking return type of signal handlers +configure.sh:3951: gcc -c -g -O2 conftest.c >&5 +configure.sh:3954: $? = 0 +configure.sh:3957: test -s conftest.o +configure.sh:3960: $? = 0 +configure.sh:3971: result: void +configure.sh:3986: checking for memset +configure.sh:4036: gcc -o conftest -g -O2 conftest.c >&5 +configure:4034: warning: conflicting types for built-in function `memset' +configure.sh:4039: $? = 0 +configure.sh:4042: test -s conftest +configure.sh:4045: $? = 0 +configure.sh:4056: result: yes +configure.sh:3986: checking for strrchr +configure.sh:4036: gcc -o conftest -g -O2 conftest.c >&5 +configure.sh:4039: $? = 0 +configure.sh:4042: test -s conftest +configure.sh:4045: $? = 0 +configure.sh:4056: result: yes +configure.sh:3986: checking for strtol +configure.sh:4036: gcc -o conftest -g -O2 conftest.c >&5 +configure.sh:4039: $? = 0 +configure.sh:4042: test -s conftest +configure.sh:4045: $? = 0 +configure.sh:4056: result: yes +configure.sh:3986: checking for strtoul +configure.sh:4036: gcc -o conftest -g -O2 conftest.c >&5 +configure.sh:4039: $? = 0 +configure.sh:4042: test -s conftest +configure.sh:4045: $? = 0 +configure.sh:4056: result: yes +configure.sh:4067: Version is 0.26 +configure.sh:4196: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by intercal config.status 0.26, which was +generated by GNU Autoconf 2.57. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on chillingi + +config.status:614: creating Makefile +config.status:614: creating ickspec + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_c_compiler_gnu=yes +ac_cv_c_const=yes +ac_cv_env_CC_set= +ac_cv_env_CC_value= +ac_cv_env_CFLAGS_set= +ac_cv_env_CFLAGS_value= +ac_cv_env_CPPFLAGS_set= +ac_cv_env_CPPFLAGS_value= +ac_cv_env_CPP_set= +ac_cv_env_CPP_value= +ac_cv_env_LDFLAGS_set= +ac_cv_env_LDFLAGS_value= +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_exeext= +ac_cv_func_malloc_0_nonnull=yes +ac_cv_func_memset=yes +ac_cv_func_realloc_0_nonnull=yes +ac_cv_func_strrchr=yes +ac_cv_func_strtol=yes +ac_cv_func_strtoul=yes +ac_cv_header_inttypes_h=yes +ac_cv_header_memory_h=yes +ac_cv_header_stdbool_h=no +ac_cv_header_stdc=yes +ac_cv_header_stddef_h=yes +ac_cv_header_stdint_h=no +ac_cv_header_stdlib_h=yes +ac_cv_header_string_h=yes +ac_cv_header_strings_h=yes +ac_cv_header_sys_stat_h=yes +ac_cv_header_sys_types_h=yes +ac_cv_header_unistd_h=yes +ac_cv_lib_fl_yywrap=no +ac_cv_lib_l_yywrap=yes +ac_cv_objext=o +ac_cv_prog_CPP=$'gcc -E' +ac_cv_prog_LEX=lex +ac_cv_prog_ac_ct_CC=gcc +ac_cv_prog_cc_g=yes +ac_cv_prog_cc_stdc= +ac_cv_prog_egrep=egrep +ac_cv_prog_lex_root=lex.yy +ac_cv_prog_lex_yytext_pointer=no +ac_cv_prog_make_make_set=yes +ac_cv_type__Bool=no +ac_cv_type_signal=void +ac_cv_type_size_t=yes + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +CC='gcc' +CFLAGS='-g -O2' +CPP='gcc -E' +CPPFLAGS='' +DEFS='-DPACKAGE_NAME=\"intercal\" -DPACKAGE_TARNAME=\"intercal\" -DPACKAGE_VERSION=\"0.26\" -DPACKAGE_STRING=\"intercal\ 0.26\" -DPACKAGE_BUGREPORT=\"esr@thyrsus.com\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_UNISTD_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STDDEF_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_STDLIB_H=1 -DHAVE_REALLOC=1 -DRETSIGTYPE=void -DHAVE_MEMSET=1 -DHAVE_STRRCHR=1 -DHAVE_STRTOL=1 -DHAVE_STRTOUL=1 ' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +EGREP='egrep' +EXEEXT='' +INSTALL_DATA='${INSTALL} -m 644' +INSTALL_PROGRAM='${INSTALL}' +INSTALL_SCRIPT='${INSTALL}' +LDFLAGS='' +LEX='lex' +LEXLIB='-ll' +LEX_OUTPUT_ROOT='lex.yy' +LIBOBJS='' +LIBS='' +LN_S='ln -s' +LTLIBOBJS='' +OBJEXT='o' +PACKAGE_BUGREPORT='esr@thyrsus.com' +PACKAGE_NAME='intercal' +PACKAGE_STRING='intercal 0.26' +PACKAGE_TARNAME='intercal' +PACKAGE_VERSION='0.26' +PATH_SEPARATOR=':' +SET_MAKE='' +SHELL='/bin/bash' +YACC='yacc' +ac_ct_CC='gcc' +bindir='${exec_prefix}/bin' +build_alias='' +datadir='${prefix}/share' +exec_prefix='${prefix}' +host_alias='' +includedir='${prefix}/include' +infodir='${prefix}/info' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localstatedir='${prefix}/var' +mandir='${prefix}/man' +oldincludedir='/usr/include' +prefix='/usr/local' +program_transform_name='s,x,x,' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +#define HAVE_INTTYPES_H 1 +#define HAVE_MALLOC 1 +#define HAVE_MEMORY_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_MEMSET 1 +#define HAVE_REALLOC 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_UNISTD_H 1 +#define PACKAGE_BUGREPORT "esr@thyrsus.com" +#define PACKAGE_NAME "intercal" +#define PACKAGE_STRING "intercal 0.26" +#define PACKAGE_TARNAME "intercal" +#define PACKAGE_VERSION "0.26" +#define RETSIGTYPE void +#define STDC_HEADERS 1 + +configure.sh: exit 0 diff --git a/config.status b/config.status new file mode 100755 index 0000000..9ee60a8 --- /dev/null +++ b/config.status @@ -0,0 +1,688 @@ +#! /bin/bash +# Generated by configure.sh. +# 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-/bin/bash} +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; 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 + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + 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 + + ;; + 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 + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # 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 sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="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="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by intercal $as_me 0.26, which was +generated by GNU Autoconf 2.57. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +config_files=" Makefile ickspec" + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -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 + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to ." +ac_cs_version="\ +intercal config.status 0.26 +configured by configure.sh, generated by GNU Autoconf 2.57, + with options \"\" + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=. +INSTALL="./install.sh -c" +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +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=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + 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 + +if $ac_cs_recheck; then + echo "running /bin/bash configure.sh " $ac_configure_extra_args " --no-create --no-recursion" >&6 + exec /bin/bash configure.sh $ac_configure_extra_args --no-create --no-recursion +fi + +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "ickspec" ) CONFIG_FILES="$CONFIG_FILES ickspec" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + 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 +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t$/@;t t/; /@;t t$/s/[\\&,]/\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t$/,;t t/' >$tmp/subs.sed <<\CEOF +s,@SHELL@,/bin/bash,;t t +s,@PATH_SEPARATOR@,:,;t t +s,@PACKAGE_NAME@,intercal,;t t +s,@PACKAGE_TARNAME@,intercal,;t t +s,@PACKAGE_VERSION@,0.26,;t t +s,@PACKAGE_STRING@,intercal 0.26,;t t +s,@PACKAGE_BUGREPORT@,esr@thyrsus.com,;t t +s,@exec_prefix@,${prefix},;t t +s,@prefix@,/usr/local,;t t +s,@program_transform_name@,s,x,x,,;t t +s,@bindir@,${exec_prefix}/bin,;t t +s,@sbindir@,${exec_prefix}/sbin,;t t +s,@libexecdir@,${exec_prefix}/libexec,;t t +s,@datadir@,${prefix}/share,;t t +s,@sysconfdir@,${prefix}/etc,;t t +s,@sharedstatedir@,${prefix}/com,;t t +s,@localstatedir@,${prefix}/var,;t t +s,@libdir@,${exec_prefix}/lib,;t t +s,@includedir@,${prefix}/include,;t t +s,@oldincludedir@,/usr/include,;t t +s,@infodir@,${prefix}/info,;t t +s,@mandir@,${prefix}/man,;t t +s,@build_alias@,,;t t +s,@host_alias@,,;t t +s,@target_alias@,,;t t +s,@DEFS@,-DPACKAGE_NAME=\"intercal\" -DPACKAGE_TARNAME=\"intercal\" -DPACKAGE_VERSION=\"0.26\" -DPACKAGE_STRING=\"intercal\ 0.26\" -DPACKAGE_BUGREPORT=\"esr@thyrsus.com\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_UNISTD_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STDDEF_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_STDLIB_H=1 -DHAVE_REALLOC=1 -DRETSIGTYPE=void -DHAVE_MEMSET=1 -DHAVE_STRRCHR=1 -DHAVE_STRTOL=1 -DHAVE_STRTOUL=1 ,;t t +s,@ECHO_C@,,;t t +s,@ECHO_N@,-n,;t t +s,@ECHO_T@,,;t t +s,@LIBS@,,;t t +s,@YACC@,yacc,;t t +s,@CC@,gcc,;t t +s,@CFLAGS@,-g -O2,;t t +s,@LDFLAGS@,,;t t +s,@CPPFLAGS@,,;t t +s,@ac_ct_CC@,gcc,;t t +s,@EXEEXT@,,;t t +s,@OBJEXT@,o,;t t +s,@LEX@,lex,;t t +s,@LEXLIB@,-ll,;t t +s,@LEX_OUTPUT_ROOT@,lex.yy,;t t +s,@INSTALL_PROGRAM@,${INSTALL},;t t +s,@INSTALL_SCRIPT@,${INSTALL},;t t +s,@INSTALL_DATA@,${INSTALL} -m 644,;t t +s,@LN_S@,ln -s,;t t +s,@SET_MAKE@,,;t t +s,@CPP@,gcc -E,;t t +s,@EGREP@,egrep,;t t +s,@LIBOBJS@,,;t t +s,@LTLIBOBJS@,,;t t +CEOF + + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # 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. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + sed "/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +} + +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;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,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done + +{ (exit 0); exit 0; } diff --git a/configure b/configure deleted file mode 100755 index c78c49a..0000000 --- a/configure +++ /dev/null @@ -1,4964 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.57 for intercal 0.25. -# -# Report bugs to . -# -# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -# 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 Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi - -# Support unset when possible. -if (FOO=FOO; unset FOO) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; 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 - - -# Name of the executable. -as_me=`$as_basename "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - - -# PATH needs CR, and LINENO needs CR and PATH. -# 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 - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - 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 - - ;; - 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 - { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # 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 sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - as_mkdir_p=false -fi - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="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="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -exec 6>&1 - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_config_libobj_dir=. -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Maximum number of lines to put in a shell here document. -# This variable seems obsolete. It should probably be removed, and -# only ac_max_sed_lines should be used. -: ${ac_max_here_lines=38} - -# Identity of this package. -PACKAGE_NAME='intercal' -PACKAGE_TARNAME='intercal' -PACKAGE_VERSION='0.25' -PACKAGE_STRING='intercal 0.25' -PACKAGE_BUGREPORT='esr@thyrsus.com' - -ac_unique_file="lose.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_STAT_H -# include -#endif -#if STDC_HEADERS -# include -# include -#else -# if HAVE_STDLIB_H -# include -# endif -#endif -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H -# include -# endif -# include -#endif -#if HAVE_STRINGS_H -# include -#endif -#if HAVE_INTTYPES_H -# include -#else -# if HAVE_STDINT_H -# include -# endif -#endif -#if HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS YACC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT LEX LEXLIB LEX_OUTPUT_ROOT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE CPP EGREP LIBOBJS LTLIBOBJS' -ac_subst_files='' - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -# 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. -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -ac_prev= -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 - - ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_option in - - -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 | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval "enable_$ac_feature=no" ;; - - -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "enable_$ac_feature='$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 ;; - - -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 ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - 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 ;; - - -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_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "with_$ac_package='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval "with_$ac_package=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 ;; - - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` - eval "$ac_envvar='$ac_optarg'" - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - 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'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -# Be sure to have absolute paths. -for ac_var in exec_prefix prefix -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* | NONE | '' ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# Be sure to have absolute paths. -for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir infodir mandir -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -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 - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - 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 - - -# 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 its parent. - ac_confdir=`(dirname "$0") 2>/dev/null || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$0" | - 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 - if test "$ac_srcdir_defaulted" = yes; then - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 - { (exit 1); exit 1; }; } - else - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } - fi -fi -(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || - { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 - { (exit 1); exit 1; }; } -srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` -ac_env_build_alias_set=${build_alias+set} -ac_env_build_alias_value=$build_alias -ac_cv_env_build_alias_set=${build_alias+set} -ac_cv_env_build_alias_value=$build_alias -ac_env_host_alias_set=${host_alias+set} -ac_env_host_alias_value=$host_alias -ac_cv_env_host_alias_set=${host_alias+set} -ac_cv_env_host_alias_value=$host_alias -ac_env_target_alias_set=${target_alias+set} -ac_env_target_alias_value=$target_alias -ac_cv_env_target_alias_set=${target_alias+set} -ac_cv_env_target_alias_value=$target_alias -ac_env_CC_set=${CC+set} -ac_env_CC_value=$CC -ac_cv_env_CC_set=${CC+set} -ac_cv_env_CC_value=$CC -ac_env_CFLAGS_set=${CFLAGS+set} -ac_env_CFLAGS_value=$CFLAGS -ac_cv_env_CFLAGS_set=${CFLAGS+set} -ac_cv_env_CFLAGS_value=$CFLAGS -ac_env_LDFLAGS_set=${LDFLAGS+set} -ac_env_LDFLAGS_value=$LDFLAGS -ac_cv_env_LDFLAGS_set=${LDFLAGS+set} -ac_cv_env_LDFLAGS_value=$LDFLAGS -ac_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_env_CPPFLAGS_value=$CPPFLAGS -ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_cv_env_CPPFLAGS_value=$CPPFLAGS -ac_env_CPP_set=${CPP+set} -ac_env_CPP_value=$CPP -ac_cv_env_CPP_set=${CPP+set} -ac_cv_env_CPP_value=$CPP - -# -# 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 intercal 0.25 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 \`..'] - -_ACEOF - - cat <<_ACEOF -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] - --datadir=DIR read-only architecture-independent data [PREFIX/share] - --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] - --infodir=DIR info documentation [PREFIX/info] - --mandir=DIR man documentation [PREFIX/man] -_ACEOF - - cat <<\_ACEOF -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of intercal 0.25:";; - esac - cat <<\_ACEOF - -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 - CPPFLAGS 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 -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - ac_popdir=`pwd` - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d $ac_dir || continue - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac -# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -# absolute. -ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` -ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` - - cd $ac_dir - # Check for guested configure; otherwise get Cygnus style 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 - elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then - echo - $ac_configure --help - else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi - cd $ac_popdir - done -fi - -test -n "$ac_init_help" && exit 0 -if $ac_init_version; then - cat <<\_ACEOF -intercal configure 0.25 -generated by GNU Autoconf 2.57 - -Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -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 0 -fi -exec 5>config.log -cat >&5 <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by intercal $as_me 0.25, which was -generated by GNU Autoconf 2.57. Invocation command line was - - $ $0 $@ - -_ACEOF -{ -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` -hostinfo = `(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=. - echo "PATH: $as_dir" -done - -} >&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_sep= -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=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; - 2) - ac_configure_args1="$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 - ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" - # Get rid of the leading space. - ac_sep=" " - ;; - esac - done -done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export 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: Be sure not to use single quotes in there, as some shells, -# such as our DU 5.0 friend, will then `close' the trap. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -{ - (set) 2>&1 | - case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in - *ac_space=\ *) - sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" - ;; - *) - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} - echo - - cat <<\_ASBOX -## ----------------- ## -## Output variables. ## -## ----------------- ## -_ASBOX - echo - for ac_var in $ac_subst_vars - do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" - done | sort - echo - - if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------- ## -## Output files. ## -## ------------- ## -_ASBOX - echo - for ac_var in $ac_subst_files - do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" - done | sort - echo - fi - - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - sed "/^$/d" confdefs.h | sort - echo - fi - test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" - } >&5 - rm -f core core.* *.core && - rm -rf conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status - ' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo >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 - - -# Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - 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. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . $cache_file;; - *) . ./$cache_file;; - esac - fi -else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -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 `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; 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,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -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 - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=$ac_var=`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. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#AC_CONFIG_HEADER([config.h]) - -# Checks for programs. -for ac_prog in 'bison -y' byacc -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_YACC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$YACC"; then - ac_cv_prog_YACC="$YACC" # 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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_YACC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -YACC=$ac_cv_prog_YACC -if test -n "$YACC"; then - echo "$as_me:$LINENO: result: $YACC" >&5 -echo "${ECHO_T}$YACC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$YACC" && break -done -test -n "$YACC" || YACC="yacc" - -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 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}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 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -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 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -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 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&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_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" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -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 - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl - 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 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_CC" && break -done - - CC=$ac_ct_CC -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out 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. -echo "$as_me:$LINENO: checking for C compiler default output" >&5 -echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 - (eval $ac_link_default) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Find the output, starting from the most likely. This scheme is -# not robust to junk in `.', hence go to wildcards (a.*) only as a last -# resort. - -# Be careful to initialize this variable, since it used to be cached. -# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. -ac_cv_exeext= -# b.out is created by i960 compilers. -for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) - ;; - conftest.$ac_ext ) - # This is the source file. - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - # FIXME: I believe we export ac_cv_exeext for Libtool, - # but it would be cool to find out if it's true. Does anybody - # maintain Libtool? --akim. - export ac_cv_exeext - break;; - * ) - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi - -ac_exeext=$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6 - -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - -rm -f a.out a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6 - -echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; 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 | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - export ac_cv_exeext - break;; - * ) break;; - esac -done -else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6 - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6 -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -CFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_prog_cc_g=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$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 -echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 -echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_stdc=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* 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; -} -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 -# Don't try gcc -ansi; that turns off useful extensions and -# breaks some systems' header files. -# AIX -qlanglvl=ansi -# Ultrix and OSF/1 -std1 -# HP-UX 10.20 and later -Ae -# HP-UX older versions -Aa -D_HPUX_SOURCE -# SVR4 -Xc -D__EXTENSIONS__ -for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_stdc=$ac_arg -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.$ac_objext -done -rm -f conftest.$ac_ext conftest.$ac_objext -CC=$ac_save_CC - -fi - -case "x$ac_cv_prog_cc_stdc" in - x|xno) - echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6 ;; - *) - echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 - CC="$CC $ac_cv_prog_cc_stdc" ;; -esac - -# Some people use a C++ compiler to compile C. Since we use `exit', -# in C++ we need to declare it. In case someone uses the same compiler -# for both compiling C and C++ we need to have the C++ compiler decide -# the declaration of exit, since it's the most demanding environment. -cat >conftest.$ac_ext <<_ACEOF -#ifndef __cplusplus - choke me -#endif -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - for ac_declaration in \ - ''\ - '#include ' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -continue -fi -rm -f conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.$ac_objext 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 - - -for ac_prog in flex lex -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_LEX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$LEX"; then - ac_cv_prog_LEX="$LEX" # 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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_LEX="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -LEX=$ac_cv_prog_LEX -if test -n "$LEX"; then - echo "$as_me:$LINENO: result: $LEX" >&5 -echo "${ECHO_T}$LEX" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$LEX" && break -done -test -n "$LEX" || LEX=":" - -if test -z "$LEXLIB" -then - echo "$as_me:$LINENO: checking for yywrap in -lfl" >&5 -echo $ECHO_N "checking for yywrap in -lfl... $ECHO_C" >&6 -if test "${ac_cv_lib_fl_yywrap+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lfl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char yywrap (); -int -main () -{ -yywrap (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_fl_yywrap=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_fl_yywrap=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_fl_yywrap" >&5 -echo "${ECHO_T}$ac_cv_lib_fl_yywrap" >&6 -if test $ac_cv_lib_fl_yywrap = yes; then - LEXLIB="-lfl" -else - echo "$as_me:$LINENO: checking for yywrap in -ll" >&5 -echo $ECHO_N "checking for yywrap in -ll... $ECHO_C" >&6 -if test "${ac_cv_lib_l_yywrap+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ll $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char yywrap (); -int -main () -{ -yywrap (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_l_yywrap=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_l_yywrap=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_l_yywrap" >&5 -echo "${ECHO_T}$ac_cv_lib_l_yywrap" >&6 -if test $ac_cv_lib_l_yywrap = yes; then - LEXLIB="-ll" -fi - -fi - -fi - -if test "x$LEX" != "x:"; then - echo "$as_me:$LINENO: checking lex output file root" >&5 -echo $ECHO_N "checking lex output file root... $ECHO_C" >&6 -if test "${ac_cv_prog_lex_root+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # The minimal lex program is just a single line: %%. But some broken lexes -# (Solaris, I think it was) want two %% lines, so accommodate them. -cat >conftest.l <<_ACEOF -%% -%% -_ACEOF -{ (eval echo "$as_me:$LINENO: \"$LEX conftest.l\"") >&5 - (eval $LEX conftest.l) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -if test -f lex.yy.c; then - ac_cv_prog_lex_root=lex.yy -elif test -f lexyy.c; then - ac_cv_prog_lex_root=lexyy -else - { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5 -echo "$as_me: error: cannot find output from $LEX; giving up" >&2;} - { (exit 1); exit 1; }; } -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5 -echo "${ECHO_T}$ac_cv_prog_lex_root" >&6 -rm -f conftest.l -LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root - -echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5 -echo $ECHO_N "checking whether yytext is a pointer... $ECHO_C" >&6 -if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # POSIX says lex can declare yytext either as a pointer or an array; the -# default is implementation-dependent. Figure out which it is, since -# not all implementations provide the %pointer and %array declarations. -ac_cv_prog_lex_yytext_pointer=no -echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c -ac_save_LIBS=$LIBS -LIBS="$LIBS $LEXLIB" -cat >conftest.$ac_ext <<_ACEOF -`cat $LEX_OUTPUT_ROOT.c` -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_lex_yytext_pointer=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_save_LIBS -rm -f "${LEX_OUTPUT_ROOT}.c" - -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5 -echo "${ECHO_T}$ac_cv_prog_lex_yytext_pointer" >&6 -if test $ac_cv_prog_lex_yytext_pointer = yes; then - -cat >>confdefs.h <<\_ACEOF -#define YYTEXT_POINTER 1 -_ACEOF - -fi - -fi -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 - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 -echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} - { (exit 1); exit 1; }; } -fi -ac_config_guess="$SHELL $ac_aux_dir/config.guess" -ac_config_sub="$SHELL $ac_aux_dir/config.sub" -ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. - -# 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" -# ./install, which can be erroneously created by make from ./install.sh. -echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&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/* | \ - /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_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 - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - done - done - ;; -esac -done - - -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. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL=$ac_install_sh - fi -fi -echo "$as_me:$LINENO: result: $INSTALL" >&5 -echo "${ECHO_T}$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' - -echo "$as_me:$LINENO: checking whether ln -s works" >&5 -echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else - echo "$as_me:$LINENO: result: no, using $LN_S" >&5 -echo "${ECHO_T}no, using $LN_S" >&6 -fi - -echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 -set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` -if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.make <<\_ACEOF -all: - @echo 'ac_maketemp="$(MAKE)"' -_ACEOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. -eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` -if test -n "$ac_maketemp"; then - eval ac_cv_prog_make_${ac_make}_set=yes -else - eval ac_cv_prog_make_${ac_make}_set=no -fi -rm -f conftest.make -fi -if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - SET_MAKE= -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - SET_MAKE="MAKE=${MAKE-make}" -fi - - -# Checks for libraries. - -# Checks for header files. -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 -echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f 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 -echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$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 >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -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 - - -echo "$as_me:$LINENO: checking for egrep" >&5 -echo $ECHO_N "checking for egrep... $ECHO_C" >&6 -if test "${ac_cv_prog_egrep+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if echo a | (grep -E '(a|b)') >/dev/null 2>&1 - then ac_cv_prog_egrep='grep -E' - else ac_cv_prog_egrep='egrep' - fi -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 -echo "${ECHO_T}$ac_cv_prog_egrep" >&6 - EGREP=$ac_cv_prog_egrep - - -echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 -if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_header_stdc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_header_stdc=no -fi -rm -f 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 >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* 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 >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* 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 >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#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)) - exit(2); - exit (0); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6 -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_Header=no" -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - - - - - -for ac_header in memory.h stddef.h stdlib.h string.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf@gnu.org. ## -## ------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; - no:yes ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf@gnu.org. ## -## ------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -# Checks for typedefs, structures, and compiler characteristics. -echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5 -echo $ECHO_N "checking for stdbool.h that conforms to C99... $ECHO_C" >&6 -if test "${ac_cv_header_stdbool_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* 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]; - bool e = &s; - char f[(_Bool) -0.0 == false ? 1 : -1]; - char g[true]; - char h[sizeof (_Bool)]; - char i[sizeof s.t]; - -int -main () -{ - return !a + !b + !c + !d + !e + !f + !g + !h + !i; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_header_stdbool_h=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_header_stdbool_h=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5 -echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6 -echo "$as_me:$LINENO: checking for _Bool" >&5 -echo $ECHO_N "checking for _Bool... $ECHO_C" >&6 -if test "${ac_cv_type__Bool+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((_Bool *) 0) - return 0; -if (sizeof (_Bool)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type__Bool=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type__Bool=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 -echo "${ECHO_T}$ac_cv_type__Bool" >&6 -if test $ac_cv_type__Bool = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE__BOOL 1 -_ACEOF - - -fi - -if test $ac_cv_header_stdbool_h = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_STDBOOL_H 1 -_ACEOF - -fi - -echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 -echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 -if test "${ac_cv_c_const+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -/* FIXME: Include the comments suggested by Paul. */ -#ifndef __cplusplus - /* Ultrix mips cc rejects this. */ - typedef int charset[2]; - const charset x; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *ccp; - char **p; - /* 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"; - ccp = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++ccp; - p = (char**) ccp; - ccp = (char const *const *) p; - { /* SCO 3.2v4 cc rejects this. */ - char *t; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 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 saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - } -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_const=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_c_const=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 -echo "${ECHO_T}$ac_cv_c_const" >&6 -if test $ac_cv_c_const = no; then - -cat >>confdefs.h <<\_ACEOF -#define const -_ACEOF - -fi - -echo "$as_me:$LINENO: checking for size_t" >&5 -echo $ECHO_N "checking for size_t... $ECHO_C" >&6 -if test "${ac_cv_type_size_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((size_t *) 0) - return 0; -if (sizeof (size_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_size_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_size_t=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 -echo "${ECHO_T}$ac_cv_type_size_t" >&6 -if test $ac_cv_type_size_t = yes; then - : -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned -_ACEOF - -fi - - -# Checks for library functions. - -for ac_header in stdlib.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf@gnu.org. ## -## ------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; - no:yes ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf@gnu.org. ## -## ------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5 -echo $ECHO_N "checking for GNU libc compatible malloc... $ECHO_C" >&6 -if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - ac_cv_func_malloc_0_nonnull=no -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#if STDC_HEADERS || HAVE_STDLIB_H -# include -#else -char *malloc (); -#endif - -int -main () -{ -exit (malloc (0) ? 0 : 1); - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_malloc_0_nonnull=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_func_malloc_0_nonnull=no -fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5 -echo "${ECHO_T}$ac_cv_func_malloc_0_nonnull" >&6 -if test $ac_cv_func_malloc_0_nonnull = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_MALLOC 1 -_ACEOF - -else - cat >>confdefs.h <<\_ACEOF -#define HAVE_MALLOC 0 -_ACEOF - - LIBOBJS="$LIBOBJS malloc.$ac_objext" - -cat >>confdefs.h <<\_ACEOF -#define malloc rpl_malloc -_ACEOF - -fi - - - - -for ac_header in stdlib.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf@gnu.org. ## -## ------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; - no:yes ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf@gnu.org. ## -## ------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -echo "$as_me:$LINENO: checking for GNU libc compatible realloc" >&5 -echo $ECHO_N "checking for GNU libc compatible realloc... $ECHO_C" >&6 -if test "${ac_cv_func_realloc_0_nonnull+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - ac_cv_func_realloc_0_nonnull=no -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#if STDC_HEADERS || HAVE_STDLIB_H -# include -#else -char *realloc (); -#endif - -int -main () -{ -exit (realloc (0, 0) ? 0 : 1); - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_realloc_0_nonnull=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_func_realloc_0_nonnull=no -fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_func_realloc_0_nonnull" >&5 -echo "${ECHO_T}$ac_cv_func_realloc_0_nonnull" >&6 -if test $ac_cv_func_realloc_0_nonnull = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_REALLOC 1 -_ACEOF - -else - cat >>confdefs.h <<\_ACEOF -#define HAVE_REALLOC 0 -_ACEOF - - LIBOBJS="$LIBOBJS realloc.$ac_objext" - -cat >>confdefs.h <<\_ACEOF -#define realloc rpl_realloc -_ACEOF - -fi - - - -echo "$as_me:$LINENO: checking return type of signal handlers" >&5 -echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6 -if test "${ac_cv_type_signal+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#ifdef signal -# undef signal -#endif -#ifdef __cplusplus -extern "C" void (*signal (int, void (*)(int)))(int); -#else -void (*signal ()) (); -#endif - -int -main () -{ -int i; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_signal=void -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_signal=int -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 -echo "${ECHO_T}$ac_cv_type_signal" >&6 - -cat >>confdefs.h <<_ACEOF -#define RETSIGTYPE $ac_cv_type_signal -_ACEOF - - - - - - -for ac_func in memset strrchr strtol strtoul -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ -#ifdef __STDC__ -# include -#else -# include -#endif -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* 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_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != $ac_func; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -{ echo "$as_me:$LINENO: Version is $PACKAGE_VERSION" >&5 -echo "$as_me: Version is $PACKAGE_VERSION" >&6;} - ac_config_files="$ac_config_files Makefile intercal.spec" -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, don't put newlines in cache variables' values. -# 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. -{ - (set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *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 \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} | - sed ' - t clear - : clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - : end' >>confcache -if diff $cache_file confcache >/dev/null 2>&1; then :; else - if test -w $cache_file; then - test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" - cat confcache >$cache_file - else - echo "not updating unwritable cache $cache_file" - 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}' - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ 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[ ]*=/{ -s/:*\$(srcdir):*/:/; -s/:*\${srcdir}:*/:/; -s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; -s/:*$//; -s/^[^=]*=[ ]*$//; -}' -fi - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then we branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -cat >confdef2opt.sed <<\_ACEOF -t clear -: clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g -t quote -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g -t quote -d -: quote -s,[ `~#$^&*(){}\\|;'"<>?],\\&,g -s,\[,\\&,g -s,\],\\&,g -s,\$,$$,g -p -_ACEOF -# We use echo to avoid assuming a particular line-breaking character. -# The extra dot is to prevent the shell from consuming trailing -# line-breaks from the sub-command output. A line-break within -# single-quotes doesn't work because, if this script is created in a -# platform that uses two characters for line-breaks (e.g., DOS), tr -# would break. -ac_LF_and_DOT=`echo; echo .` -DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` -rm -f confdef2opt.sed - - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_i=`echo "$ac_i" | - sed 's/\$U\././;s/\.o$//;s/\.obj$//'` - # 2. Add them. - ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - -: ${CONFIG_STATUS=./config.status} -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF -#! $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} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi - -# Support unset when possible. -if (FOO=FOO; unset FOO) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; 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 - - -# Name of the executable. -as_me=`$as_basename "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - - -# PATH needs CR, and LINENO needs CR and PATH. -# 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 - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - 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 - - ;; - 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 - { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} - { (exit 1); exit 1; }; } - - # 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 sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - as_mkdir_p=false -fi - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="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="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - -exec 6>&1 - -# Open the log real soon, to keep \$[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. Logging --version etc. is OK. -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 -cat >&5 <<_CSEOF - -This file was extended by intercal $as_me 0.25, which was -generated by GNU Autoconf 2.57. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -_CSEOF -echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -echo >&5 -_ACEOF - -# Files that config.status was made for. -if test -n "$ac_config_files"; then - echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_headers"; then - echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_links"; then - echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_commands"; then - echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS -fi - -cat >>$CONFIG_STATUS <<\_ACEOF - -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -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 - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - -Configuration files: -$config_files - -Report bugs to ." -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF -ac_cs_version="\\ -intercal config.status 0.25 -configured by $0, generated by GNU Autoconf 2.57, - with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" - -Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." -srcdir=$srcdir -INSTALL="$INSTALL" -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -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=$1 - ac_optarg=$2 - ac_shift=shift - ;; - *) # This is not an option, so the user has probably given explicit - # arguments. - ac_option=$1 - ac_need_defaults=false;; - esac - - case $ac_option in - # Handling of the options. -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --vers* | -V ) - echo "$ac_cs_version"; exit 0 ;; - --he | --h) - # Conflict between --help and --header - { { echo "$as_me:$LINENO: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" - ac_need_defaults=false;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" ;; - - 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 -if \$ac_cs_recheck; then - echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion -fi - -_ACEOF - - - - - -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_config_target in $ac_config_targets -do - case "$ac_config_target" in - # Handling of arguments. - "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "intercal.spec" ) CONFIG_FILES="$CONFIG_FILES intercal.spec" ;; - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - 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 -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason to put it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Create a temporary directory, and hook for its removal unless debugging. -$debug || -{ - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} - -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./confstat$$-$RANDOM - (umask 077 && mkdir $tmp) -} || -{ - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF - -# -# CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "\$CONFIG_FILES"; then - # Protect against being on the right side of a sed subst in config.status. - sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; - s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF -s,@SHELL@,$SHELL,;t t -s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t -s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t -s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t -s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t -s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t -s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t -s,@exec_prefix@,$exec_prefix,;t t -s,@prefix@,$prefix,;t t -s,@program_transform_name@,$program_transform_name,;t t -s,@bindir@,$bindir,;t t -s,@sbindir@,$sbindir,;t t -s,@libexecdir@,$libexecdir,;t t -s,@datadir@,$datadir,;t t -s,@sysconfdir@,$sysconfdir,;t t -s,@sharedstatedir@,$sharedstatedir,;t t -s,@localstatedir@,$localstatedir,;t t -s,@libdir@,$libdir,;t t -s,@includedir@,$includedir,;t t -s,@oldincludedir@,$oldincludedir,;t t -s,@infodir@,$infodir,;t t -s,@mandir@,$mandir,;t t -s,@build_alias@,$build_alias,;t t -s,@host_alias@,$host_alias,;t t -s,@target_alias@,$target_alias,;t t -s,@DEFS@,$DEFS,;t t -s,@ECHO_C@,$ECHO_C,;t t -s,@ECHO_N@,$ECHO_N,;t t -s,@ECHO_T@,$ECHO_T,;t t -s,@LIBS@,$LIBS,;t t -s,@YACC@,$YACC,;t t -s,@CC@,$CC,;t t -s,@CFLAGS@,$CFLAGS,;t t -s,@LDFLAGS@,$LDFLAGS,;t t -s,@CPPFLAGS@,$CPPFLAGS,;t t -s,@ac_ct_CC@,$ac_ct_CC,;t t -s,@EXEEXT@,$EXEEXT,;t t -s,@OBJEXT@,$OBJEXT,;t t -s,@LEX@,$LEX,;t t -s,@LEXLIB@,$LEXLIB,;t t -s,@LEX_OUTPUT_ROOT@,$LEX_OUTPUT_ROOT,;t t -s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t -s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t -s,@INSTALL_DATA@,$INSTALL_DATA,;t t -s,@LN_S@,$LN_S,;t t -s,@SET_MAKE@,$SET_MAKE,;t t -s,@CPP@,$CPP,;t t -s,@EGREP@,$EGREP,;t t -s,@LIBOBJS@,$LIBOBJS,;t t -s,@LTLIBOBJS@,$LTLIBOBJS,;t t -CEOF - -_ACEOF - - cat >>$CONFIG_STATUS <<\_ACEOF - # Split the substitutions into bite-sized pieces for seds with - # small command number limits, like on Digital OSF/1 and HP-UX. - ac_max_sed_lines=48 - ac_sed_frag=1 # Number of current file. - ac_beg=1 # First line for current file. - ac_end=$ac_max_sed_lines # Line after last line for current file. - ac_more_lines=: - ac_sed_cmds= - while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - else - sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - fi - if test ! -s $tmp/subs.frag; then - ac_more_lines=false - else - # The purpose of the label and of the branching condition is to - # speed up the sed processing (if there are no `@' at all, there - # is no need to browse any of the substitutions). - # These are the two extra sed commands mentioned above. - (echo ':t - /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" - else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" - fi - ac_sed_frag=`expr $ac_sed_frag + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_lines` - fi - done - if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat - fi -fi # test -n "$CONFIG_FILES" - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; - esac - - # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. - ac_dir=`(dirname "$ac_file") 2>/dev/null || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac -# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -# absolute. -ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` -ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` - - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_builddir$INSTALL ;; - esac - - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi - # 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. */ - if test x"$ac_file" = x-; then - configure_input= - else - configure_input="$ac_file. " - fi - configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo $f;; - *) # Relative - if test -f "$f"; then - # Build tree - echo $f - elif test -f "$srcdir/$f"; then - # Source tree - echo $srcdir/$f - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@configure_input@,$configure_input,;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,@top_builddir@,$ac_top_builddir,;t t -s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -s,@INSTALL@,$ac_INSTALL,;t t -" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out - rm -f $tmp/stdin - if test x"$ac_file" != x-; then - mv $tmp/out $ac_file - else - cat $tmp/out - rm -f $tmp/out - fi - -done -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - - -# 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 || { (exit 1); exit 1; } -fi - diff --git a/configure.ac b/configure.ac index 63b3af1..37da6fb 100644 --- a/configure.ac +++ b/configure.ac @@ -2,9 +2,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.57) -AC_INIT(intercal, 0.25, esr@thyrsus.com) -AC_CONFIG_SRCDIR([lose.h]) -#AC_CONFIG_HEADER([config.h]) +AC_INIT(intercal, 0.26, esr@thyrsus.com) +AC_CONFIG_SRCDIR([src/lose.h]) # Checks for programs. AC_PROG_YACC @@ -32,4 +31,4 @@ AC_TYPE_SIGNAL AC_CHECK_FUNCS([memset strrchr strtol strtoul]) AC_MSG_NOTICE(Version is $PACKAGE_VERSION) -AC_OUTPUT(Makefile intercal.spec) +AC_OUTPUT(Makefile ickspec) diff --git a/configure.sh b/configure.sh new file mode 100755 index 0000000..9609f29 --- /dev/null +++ b/configure.sh @@ -0,0 +1,4962 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.57 for intercal 0.26. +# +# Report bugs to . +# +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +# 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 Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; 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 + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + 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 + + ;; + 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 + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # 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 sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="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="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME='intercal' +PACKAGE_TARNAME='intercal' +PACKAGE_VERSION='0.26' +PACKAGE_STRING='intercal 0.26' +PACKAGE_BUGREPORT='esr@thyrsus.com' + +ac_unique_file="src/lose.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS YACC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT LEX LEXLIB LEX_OUTPUT_ROOT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE CPP EGREP LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# 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. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +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 + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -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 | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$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 ;; + + -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 ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + 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 ;; + + -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_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=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 ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + 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'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +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 + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + 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 + + +# 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 its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + 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 + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# 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 intercal 0.26 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 \`..'] + +_ACEOF + + cat <<_ACEOF +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] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --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] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of intercal 0.26:";; + esac + cat <<\_ACEOF + +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 + CPPFLAGS 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 +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style 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 + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF +intercal configure 0.26 +generated by GNU Autoconf 2.57 + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +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 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by intercal $as_me 0.26, which was +generated by GNU Autoconf 2.57. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +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` +hostinfo = `(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=. + echo "PATH: $as_dir" +done + +} >&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_sep= +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=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$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 + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export 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: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core core.* *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >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 + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + 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. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +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 `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; 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,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +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 + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`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. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# Checks for programs. +for ac_prog in 'bison -y' byacc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_YACC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$YACC"; then + ac_cv_prog_YACC="$YACC" # 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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_YACC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +YACC=$ac_cv_prog_YACC +if test -n "$YACC"; then + echo "$as_me:$LINENO: result: $YACC" >&5 +echo "${ECHO_T}$YACC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$YACC" && break +done +test -n "$YACC" || YACC="yacc" + +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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_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" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +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 + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + 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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out 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. +echo "$as_me:$LINENO: checking for C compiler default output" >&5 +echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$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 +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* 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; +} +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 +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext 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 + + +for ac_prog in flex lex +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_LEX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$LEX"; then + ac_cv_prog_LEX="$LEX" # 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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LEX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +LEX=$ac_cv_prog_LEX +if test -n "$LEX"; then + echo "$as_me:$LINENO: result: $LEX" >&5 +echo "${ECHO_T}$LEX" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$LEX" && break +done +test -n "$LEX" || LEX=":" + +if test -z "$LEXLIB" +then + echo "$as_me:$LINENO: checking for yywrap in -lfl" >&5 +echo $ECHO_N "checking for yywrap in -lfl... $ECHO_C" >&6 +if test "${ac_cv_lib_fl_yywrap+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lfl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char yywrap (); +int +main () +{ +yywrap (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_fl_yywrap=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_fl_yywrap=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_fl_yywrap" >&5 +echo "${ECHO_T}$ac_cv_lib_fl_yywrap" >&6 +if test $ac_cv_lib_fl_yywrap = yes; then + LEXLIB="-lfl" +else + echo "$as_me:$LINENO: checking for yywrap in -ll" >&5 +echo $ECHO_N "checking for yywrap in -ll... $ECHO_C" >&6 +if test "${ac_cv_lib_l_yywrap+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ll $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char yywrap (); +int +main () +{ +yywrap (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_l_yywrap=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_l_yywrap=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_l_yywrap" >&5 +echo "${ECHO_T}$ac_cv_lib_l_yywrap" >&6 +if test $ac_cv_lib_l_yywrap = yes; then + LEXLIB="-ll" +fi + +fi + +fi + +if test "x$LEX" != "x:"; then + echo "$as_me:$LINENO: checking lex output file root" >&5 +echo $ECHO_N "checking lex output file root... $ECHO_C" >&6 +if test "${ac_cv_prog_lex_root+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # The minimal lex program is just a single line: %%. But some broken lexes +# (Solaris, I think it was) want two %% lines, so accommodate them. +cat >conftest.l <<_ACEOF +%% +%% +_ACEOF +{ (eval echo "$as_me:$LINENO: \"$LEX conftest.l\"") >&5 + (eval $LEX conftest.l) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +if test -f lex.yy.c; then + ac_cv_prog_lex_root=lex.yy +elif test -f lexyy.c; then + ac_cv_prog_lex_root=lexyy +else + { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5 +echo "$as_me: error: cannot find output from $LEX; giving up" >&2;} + { (exit 1); exit 1; }; } +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5 +echo "${ECHO_T}$ac_cv_prog_lex_root" >&6 +rm -f conftest.l +LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root + +echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5 +echo $ECHO_N "checking whether yytext is a pointer... $ECHO_C" >&6 +if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # POSIX says lex can declare yytext either as a pointer or an array; the +# default is implementation-dependent. Figure out which it is, since +# not all implementations provide the %pointer and %array declarations. +ac_cv_prog_lex_yytext_pointer=no +echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c +ac_save_LIBS=$LIBS +LIBS="$LIBS $LEXLIB" +cat >conftest.$ac_ext <<_ACEOF +`cat $LEX_OUTPUT_ROOT.c` +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_lex_yytext_pointer=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_save_LIBS +rm -f "${LEX_OUTPUT_ROOT}.c" + +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5 +echo "${ECHO_T}$ac_cv_prog_lex_yytext_pointer" >&6 +if test $ac_cv_prog_lex_yytext_pointer = yes; then + +cat >>confdefs.h <<\_ACEOF +#define YYTEXT_POINTER 1 +_ACEOF + +fi + +fi +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 + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# 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" +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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/* | \ + /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_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 + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +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. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$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' + +echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6 +fi + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +# Checks for libraries. + +# Checks for header files. +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 +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f 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 +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$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 >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +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 + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f 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 >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#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)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + +for ac_header in memory.h stddef.h stdlib.h string.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. +echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5 +echo $ECHO_N "checking for stdbool.h that conforms to C99... $ECHO_C" >&6 +if test "${ac_cv_header_stdbool_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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]; + bool e = &s; + char f[(_Bool) -0.0 == false ? 1 : -1]; + char g[true]; + char h[sizeof (_Bool)]; + char i[sizeof s.t]; + +int +main () +{ + return !a + !b + !c + !d + !e + !f + !g + !h + !i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdbool_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdbool_h=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5 +echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6 +echo "$as_me:$LINENO: checking for _Bool" >&5 +echo $ECHO_N "checking for _Bool... $ECHO_C" >&6 +if test "${ac_cv_type__Bool+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((_Bool *) 0) + return 0; +if (sizeof (_Bool)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type__Bool=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type__Bool=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 +echo "${ECHO_T}$ac_cv_type__Bool" >&6 +if test $ac_cv_type__Bool = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE__BOOL 1 +_ACEOF + + +fi + +if test $ac_cv_header_stdbool_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_STDBOOL_H 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* 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"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 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 saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_const=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6 +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((size_t *) 0) + return 0; +if (sizeof (size_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_size_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6 +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned +_ACEOF + +fi + + +# Checks for library functions. + +for ac_header in stdlib.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5 +echo $ECHO_N "checking for GNU libc compatible malloc... $ECHO_C" >&6 +if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_malloc_0_nonnull=no +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if STDC_HEADERS || HAVE_STDLIB_H +# include +#else +char *malloc (); +#endif + +int +main () +{ +exit (malloc (0) ? 0 : 1); + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_malloc_0_nonnull=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_malloc_0_nonnull=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5 +echo "${ECHO_T}$ac_cv_func_malloc_0_nonnull" >&6 +if test $ac_cv_func_malloc_0_nonnull = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_MALLOC 1 +_ACEOF + +else + cat >>confdefs.h <<\_ACEOF +#define HAVE_MALLOC 0 +_ACEOF + + LIBOBJS="$LIBOBJS malloc.$ac_objext" + +cat >>confdefs.h <<\_ACEOF +#define malloc rpl_malloc +_ACEOF + +fi + + + + +for ac_header in stdlib.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +echo "$as_me:$LINENO: checking for GNU libc compatible realloc" >&5 +echo $ECHO_N "checking for GNU libc compatible realloc... $ECHO_C" >&6 +if test "${ac_cv_func_realloc_0_nonnull+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_realloc_0_nonnull=no +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if STDC_HEADERS || HAVE_STDLIB_H +# include +#else +char *realloc (); +#endif + +int +main () +{ +exit (realloc (0, 0) ? 0 : 1); + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_realloc_0_nonnull=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_realloc_0_nonnull=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_func_realloc_0_nonnull" >&5 +echo "${ECHO_T}$ac_cv_func_realloc_0_nonnull" >&6 +if test $ac_cv_func_realloc_0_nonnull = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_REALLOC 1 +_ACEOF + +else + cat >>confdefs.h <<\_ACEOF +#define HAVE_REALLOC 0 +_ACEOF + + LIBOBJS="$LIBOBJS realloc.$ac_objext" + +cat >>confdefs.h <<\_ACEOF +#define realloc rpl_realloc +_ACEOF + +fi + + + +echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6 +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#ifdef signal +# undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int +main () +{ +int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_signal=void +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_signal=int +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6 + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + + + + + +for ac_func in memset strrchr strtol strtoul +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +{ echo "$as_me:$LINENO: Version is $PACKAGE_VERSION" >&5 +echo "$as_me: Version is $PACKAGE_VERSION" >&6;} + ac_config_files="$ac_config_files Makefile ickspec" +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, don't put newlines in cache variables' values. +# 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. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *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 \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + 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}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ 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[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then we branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +cat >confdef2opt.sed <<\_ACEOF +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g +t quote +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g +t quote +d +: quote +s,[ `~#$^&*(){}\\|;'"<>?],\\&,g +s,\[,\\&,g +s,\],\\&,g +s,\$,$$,g +p +_ACEOF +# We use echo to avoid assuming a particular line-breaking character. +# The extra dot is to prevent the shell from consuming trailing +# line-breaks from the sub-command output. A line-break within +# single-quotes doesn't work because, if this script is created in a +# platform that uses two characters for line-breaks (e.g., DOS), tr +# would break. +ac_LF_and_DOT=`echo; echo .` +DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` +rm -f confdef2opt.sed + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $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} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; 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 + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + 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 + + ;; + 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 + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # 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 sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="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="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by intercal $as_me 0.26, which was +generated by GNU Autoconf 2.57. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -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 + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +intercal config.status 0.26 +configured by $0, generated by GNU Autoconf 2.57, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +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=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + 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 +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "ickspec" ) CONFIG_FILES="$CONFIG_FILES ickspec" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + 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 +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@YACC@,$YACC,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@LEX@,$LEX,;t t +s,@LEXLIB@,$LEXLIB,;t t +s,@LEX_OUTPUT_ROOT@,$LEX_OUTPUT_ROOT,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@LN_S@,$LN_S,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # 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. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;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,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# 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 || { (exit 1); exit 1; } +fi + diff --git a/coopt.sh b/coopt.sh deleted file mode 100644 index 1195018..0000000 --- a/coopt.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh -########################################################################### -# -# Name -# coopt.sh -- an inefficient optimizer that can produce very efficient -# code -# -# DESCRIPTION -# This optimizer is only run on noninteractive code that takes no -# output. (It's designed to run on executables produced by INTERCAL -# code, but will run on other executables that support the +mystery -# option). It optimizes the file by replacing it by one that simply -# produces the required output! Therefore, it creates fast but -# inefficient code. If the file to be optimized hits an error or -# is terminated by +mystery, then no changes are made. -# -# LICENSE TERMS -# Copyright (C) 2006 Alex Smith -# -# 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., 675 Mass Ave, Cambridge, MA 02139, USA. -# -########################################################################### - -rm icktemp.out >/dev/null 2>/dev/null -if $1 +mystery >icktemp.out 2>/dev/null ; then : ; else exit 0 ; fi -if grep 'ickoutTERM???!' icktemp.out ; then rm icktemp.out ; exit 0 ; fi -echo 'ickoutTERM???!' >> icktemp.out -rm $1 -echo "#!/bin/sh -cat <<'ickoutTERM???!'" | cat - icktemp.out > $1 -chmod +x $1 -rm icktemp.out -exit 0 diff --git a/districk.bat b/districk.bat new file mode 100755 index 0000000..9a593ef --- /dev/null +++ b/districk.bat @@ -0,0 +1,9 @@ +@echo off +rem This batch file removes all files that weren't in the distribution. +ren temp\parser.c parser.tmp +ren temp\parser.h parserh.tmp +ren temp\lexer.c lexer.tmp +call cleanick +ren temp\parser.tmp parser.c +ren temp\parserh.tmp parser.h +ren temp\lexer.tmp lexer.c diff --git a/districk.sh b/districk.sh new file mode 100755 index 0000000..7df8992 --- /dev/null +++ b/districk.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# make districk as a shell-script, for the benefit of DJGPP systems with broken +# versions of make. +# This batch file removes all files that weren't in the distribution. +mv temp/parser.c temp/parser.tmp +mv temp/parser.h temp/parserh.tmp +mv temp/lexer.c temp/lexer.tmp +sh cleanick.sh +mv temp/parser.tmp temp/parser.c +mv temp/parserh.tmp temp/parser.h +mv temp/lexer.tmp temp/lexer.c diff --git a/djfix.bat b/djfix.bat new file mode 100755 index 0000000..c05cd75 --- /dev/null +++ b/djfix.bat @@ -0,0 +1,17 @@ +@echo off +rem This is a script to remove trailing ^Ms that might otherwise get into files +rem when running under DJGPP, to prevent the files being unusable on Unix. + +dtou *.txt +dtou etc\intercal.el +dtou src\*.c +dtou src\*.h +dtou src\*.l +dtou src\*.y +dtou src\*.sh +dtou pit\*.doc +dtou pit\*.i +dtou pit\tests\*.doc +dtou pit\tests\*.i +dtou pit\lib\*.doc +dtou pit\lib\*.i diff --git a/djfix.sh b/djfix.sh new file mode 100755 index 0000000..cc8e946 --- /dev/null +++ b/djfix.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# This is a script to remove trailing ^Ms that might otherwise get into files +# when running under DJGPP, to prevent the files being unusable on Unix. + +dtou *.txt +dtou etc/intercal.el +dtou src/*.c +dtou src/*.h +dtou src/*.l +dtou src/*.y +dtou src/*.sh +dtou pit/*.doc +dtou pit/*.i +dtou pit/tests/*.doc +dtou pit/tests/*.i +dtou pit/lib/*.doc +dtou pit/lib/*.i diff --git a/etc/intercal.el b/etc/intercal.el new file mode 100644 index 0000000..7c3c93d --- /dev/null +++ b/etc/intercal.el @@ -0,0 +1,592 @@ +;;; intercal.el -- mode for editing INTERCAL code + +;; This mode was written by Eric S. Raymond +;; for the C-INTERCAL distribution, and is copyrighted by him 1992. Free +;; redistribution encouraged. Someday, maybe, this will be made part of GNU. +;; But probably not unless they take many mind-eroding drugs first. + +;; This mode provides abbrevs for C-INTERCAL's statements, including COME FROM. +;; These abbrevs are context-sensitive and will generate either verb or gerund +;; form as appropriate. The keys RET, ( and * are also bound in useful ways. + +;; The intercal-politesse-level adjustment purports to assist the hapless +;; INTERCAL programmer in meeting INTERCAL's Miss Manners requirement. In +;; INTERCAL-72 and C-INTERCAL releases after 0.7, no fewer than 1/5 and no +;; more than 1/3 of the program statements must contain a PLEASE to gratify +;; the iron whim of the INTERCAL compiler; this mode assists by randomly +;; expanding some fraction of the "do" abbrevs typed to PLEASE DO. +;; The intercal-politesse-level constant is the denominator of this fraction. + +;; AIS: I corrected the READ/WRITE, IN/OUT reversal independent of the correction +;; that happened from 0.22 to 0.24 (this code was originally based on the 0.22 +;; distribution and updated for 0.24 compatibility); this version is distributed +;; with C-INTERCAL 0.25. +;; +;; I also altered the code for ( so the user didn't have to go to the beginning +;; of the line, added C-c C-[a,c,r,s] for convenience when working with +;; constants, and added support for TRY AGAIN, ONCE, AGAIN, and Font Lock. +;; I added support for M-x compile so it could compile INTERCAL programs +;; correctly (assuming that ick has been installed). + +;; $Id: intercal.el,v 1.5 1996/11/14 04:02:00 esr Exp $ + +(defconst intercal-politesse-level 4 + "Fraction of DOs that are automagically expanded to PLEASE DO.") + +(defvar intercal-mode-map nil + "Keymap for INTERCAL mode.") +(if intercal-mode-map + nil + (setq intercal-mode-map (make-sparse-keymap)) + (define-key intercal-mode-map "\t" 'tab-to-tab-stop) + (define-key intercal-mode-map "\r" 'intercal-return) + (define-key intercal-mode-map "\C-J" 'intercal-return) + (define-key intercal-mode-map "\C-C\C-C" 'intercal-constant-convert) ;AIS + (define-key intercal-mode-map "\C-C\C-R" 'intercal-constant-radix-convert) ;AIS + (define-key intercal-mode-map "\C-C\C-S" 'intercal-char-constant-convert) ;AIS + (define-key intercal-mode-map "\C-C\C-A" 'intercal-string-array-convert) ;AIS + (define-key intercal-mode-map "\C-C\C-U" 'intercal-lnu) ;AIS + (define-key intercal-mode-map "(" 'intercal-paren) + (define-key intercal-mode-map "*" 'intercal-splat) + (define-key intercal-mode-map "\177" 'backward-delete-char-untabify) + ) + +(defvar intercal-mode-syntax-table nil + "Syntax table in use in Intercal-mode buffers.") + +(if intercal-mode-syntax-table + nil + (let ((table (make-syntax-table))) + (modify-syntax-entry ?\\ "\\" table) + (modify-syntax-entry ?+ "." table) + (modify-syntax-entry ?- "." table) + (modify-syntax-entry ?= "." table) + (modify-syntax-entry ?% "." table) + (modify-syntax-entry ?< "." table) + (modify-syntax-entry ?> "." table) + (modify-syntax-entry ?& "." table) + (modify-syntax-entry ?| "." table) + (modify-syntax-entry ?\' "\"" table) + (setq intercal-mode-syntax-table table))) + +(defvar intercal-mode-abbrev-table nil + "*Abbrev table in use in Intercal-mode buffers.") +(if intercal-mode-abbrev-table + nil + (define-abbrev-table 'intercal-mode-abbrev-table ()) + (define-abbrev intercal-mode-abbrev-table "pl" "PLEASE" nil) + (define-abbrev intercal-mode-abbrev-table "on" "ONCE" nil) ;AIS + (define-abbrev intercal-mode-abbrev-table "ag" "AGAIN" nil) ;AIS + (define-abbrev intercal-mode-abbrev-table "ne" "" 'intercal-ne-abbrev) + (define-abbrev intercal-mode-abbrev-table "fo" "" 'intercal-fo-abbrev) + (define-abbrev intercal-mode-abbrev-table "res" "" 'intercal-res-abbrev) + (define-abbrev intercal-mode-abbrev-table "st" "" 'intercal-st-abbrev) + (define-abbrev intercal-mode-abbrev-table "ret" "" 'intercal-ret-abbrev) + (define-abbrev intercal-mode-abbrev-table "ig" "" 'intercal-ig-abbrev) + (define-abbrev intercal-mode-abbrev-table "rem" "" 'intercal-rem-abbrev) + (define-abbrev intercal-mode-abbrev-table "ab" "" 'intercal-ab-abbrev) + (define-abbrev intercal-mode-abbrev-table "rei" "" 'intercal-rei-abbrev) + (define-abbrev intercal-mode-abbrev-table "gi" "" 'intercal-gi-abbrev) + (define-abbrev intercal-mode-abbrev-table "rea" "" 'intercal-rea-abbrev) + (define-abbrev intercal-mode-abbrev-table "wr" "" 'intercal-wr-abbrev) + (define-abbrev intercal-mode-abbrev-table "co" "" 'intercal-co-abbrev) + (define-abbrev intercal-mode-abbrev-table "do" "" 'intercal-do-abbrev) + (define-abbrev intercal-mode-abbrev-table "goa" "" 'intercal-goa-abbrev) ;AIS + (define-abbrev intercal-mode-abbrev-table "gob" "" 'intercal-gob-abbrev) ;AIS + (define-abbrev intercal-mode-abbrev-table "ma" "MAYBE" nil) ;AIS + (define-abbrev intercal-mode-abbrev-table "tr" "" 'intercal-tr-abbrev) ;AIS + (define-abbrev intercal-mode-abbrev-table "cal" "" 'intercal-cal-abbrev) ;AIS + ) + +(defun use-gerund () + (save-excursion + (beginning-of-line) + (or (looking-at ".*ABSTAIN") (looking-at ".*REINSTATE")))) + +(defmacro make-intercal-abbrev (sym gerund verb) + (list 'defun sym '() (list 'insert (list 'if '(use-gerund) gerund verb)))) + +(make-intercal-abbrev intercal-ne-abbrev "NEXTING" "NEXT") +(make-intercal-abbrev intercal-fo-abbrev "FORGETTING" "FORGET") +(make-intercal-abbrev intercal-res-abbrev "RESUMING" "RESUME") +(make-intercal-abbrev intercal-st-abbrev "STASHING" "STASH") +(make-intercal-abbrev intercal-ret-abbrev "RETRIEVING" "RETRIEVE") +(make-intercal-abbrev intercal-ig-abbrev "IGNORING" "IGNORE") +(make-intercal-abbrev intercal-rem-abbrev "REMEMBERING" "REMEMBER") +(make-intercal-abbrev intercal-ab-abbrev "ABSTAINING" "ABSTAIN FROM") +(make-intercal-abbrev intercal-rei-abbrev "REINSTATING" "REINSTATE") +(make-intercal-abbrev intercal-gi-abbrev "GIVING UP" "GIVE UP") +(make-intercal-abbrev intercal-rea-abbrev "READING OUT" "READ OUT") +(make-intercal-abbrev intercal-wr-abbrev "WRITING IN" "WRITE IN") +(make-intercal-abbrev intercal-co-abbrev "COMING FROM" "COME FROM") +(make-intercal-abbrev intercal-tr-abbrev "TRYING AGAIN" "TRY AGAIN") ;AIS +(make-intercal-abbrev intercal-cal-abbrev "CALCULATING" "cal") ;AIS +(make-intercal-abbrev intercal-goa-abbrev "GOING AHEAD" "GO AHEAD") ;AIS +(make-intercal-abbrev intercal-gob-abbrev "GOING BACK" "GO BACK") ;AIS + +(defun intercal-do-abbrev () + "Emit a DO (usually). Occasionally, emit PLEASE DO." + (insert + (if (zerop (% (random) intercal-politesse-level)) + "PLEASE DO" + "DO") + )) + +(defun intercal-return () + "Insert LFD + tab, to bring us back to code-indent level." + (interactive) + (if (eolp) (delete-horizontal-space)) + (insert "\n") + (delete-horizontal-space) ;AIS + (tab-to-tab-stop) + (if intercal-lnu-mode (intercal-lnu)) ;AIS + ) + +;; AIS: This is the old intercal-paren function, modified slightly. +(defun intercal-paren-2 () + "Generate an INTERCAL label if at start of line. Otherwise type '('." + (interactive) + (if (and (bolp) (looking-at "[ \t]\\|$")) + (insert (format "(%d)" + (save-restriction + (widen) + (save-excursion + (beginning-of-line) + (1+ (count-lines 1 (point)))))) + "\t") + (insert "("))) + +;; AIS: I wrote this as a better intercal-paren-2. +(defun intercal-paren () + "Generate an INTERCAL label or (." + (interactive) + (save-excursion + (beginning-of-line) + (if (looking-at "^[ \t]*$") + (delete-horizontal-space))) + (intercal-paren-2) +) + +(defun intercal-splat () + "Begin an INTERCAL comment." + (interactive) + (insert "*") + (forward-char -1) + (delete-horizontal-space) + (forward-char 1) + (insert " ") +) + +;; AIS: Added new abbreviations (marked ;AIS above), expanded the documentation. +(defun intercal-mode () + "A major editing mode for the language Intercal. +It activates the following abbrevs (each one appropriately modified to a +gerund if it occurs on a line with ABSTAIN or REINSTATE). + +ab ABSTAIN co COME FROM fo FORGET +gi GIVE UP ig IGNORE ne NEXT +rea READ OUT rei REINSTATE rem REMEMBER +res RESUME ret RETRIEVE st STASH +wr WRITE IN pl PLEASE tr TRY AGAIN +on ONCE ag AGAIN ma MAYBE +goa GO AHEAD gob GO BACK do DO, or sometimes PLEASE DO +cal CALCULATING (only as a gerund) + +Carriage return takes you to the first tab stop (code indent level). +Certain other single keys are bound to things which may or may not be useful. +You may consider discovering these one of the pleasures awaiting you in your +discovery of INTERCAL's unique ambience. + +Typing C-c C-c converts a constant in the form # to a legal +INTERCAL constant (such as #45 or #65280$#65280). If the answer is a mingled +one, it is only valid in binary. + +For programmers who prefer TRI-INTERCAL, another constant conversion function +is given. Typing a number in the format (say) #3r2210210011 and pressing +C-c C-r will result in a (possibly mingled) decimal constant that works in +base 3. This works likewise for other bases, say #6r520314 would generate a +base-6 constant. + +For binary I/O, C-c C-s is provided. This takes a constant of the form +#? and converts it into a constant of the form #. +With a prefix argument (as in C-u C-c C-s), the output has its bottom 8 bits +reversed, and so is suitable for use with semi-standard output routines. + +For longer strings, C-c C-a can produce sections of programs that store +strings in arrays. The command can give help on itself. + +For information about C-c C-u and LNU, see `intercal-lnu-mode'. + +Turning on Intercal mode calls the value of the variable intercal-mode-hook +with no args, if that value is non-nil." + (interactive) + (kill-all-local-variables) + (use-local-map intercal-mode-map) + (setq major-mode 'intercal-mode) + (setq mode-name "Intercal") + (setq local-abbrev-table intercal-mode-abbrev-table) + (set-syntax-table intercal-mode-syntax-table) + (make-local-variable 'comment-start) + (setq comment-start "* ") + (make-local-variable 'comment-end) + (setq comment-end "") + (make-local-variable 'comment-column) + (setq comment-column 32) + (make-local-variable 'require-final-newline) + (setq require-final-newline t) + (setq abbrev-mode t) + (setq abbrev-all-caps t) + (run-hooks 'intercal-mode-hook)) + +(provide 'intercal-mode) + +;; AIS: I wrote everything from here down. + +;; Line Number Update minor mode. +(defvar intercal-lnu-mode nil "Whether intercal-lnu-mode is on or not.") +(make-variable-buffer-local 'intercal-lnu-mode) + +(defvar intercal-lnu-mode-initialized nil "Whether intercal-lnu-mode is initialized.") + +(defun intercal-lnu-mode (arg) +"Minor mode used primarily when editing INTERCAL. + (LNU stands for Line Number Update). +The mode tries to ensure that all line labels below 1000 are equal to the line +numbers of the lines they refer to. Renumbering is done when RET is pressed, the +mode is turned on, or C-c C-u is pressed. This mode has no effect unless +intercal-mode is also active, or its functions are called. It is inadvisable to +turn LNU mode on in long files, because line number updates take a long time to +run in long files. Instead, leave LNU mode off and use `intercal-lnu' (C-c C-u). +Labels greater than or equal to 1000 are ignored because they probably indicate +library functions." + (interactive "P") + (setq intercal-lnu-mode + (if (null arg) (not intercal-lnu-mode) (> (prefix-numeric-value arg) 0))) + (force-mode-line-update) + (if intercal-lnu-mode (intercal-lnu)) + (if (not intercal-lnu-mode-initialized) (intercal-lnu-initialize)) +) + +(defun intercal-lnu-initialize () +"Initializes INTERCAL LNU mode. See `intercal-lnu-mode'." + (if (not intercal-lnu-mode-initialized) + (setq minor-mode-alist (cons '(intercal-lnu-mode " LNU") minor-mode-alist) + intercal-lnu-mode-initialized t)) +) + +(defsubst cadar (x) + "Return the car of the cdr of the car of X." + (car (cdr (car x)))) + +(defun intercal-lnu () +"Updates line numbers in an INTERCAL program. See `intercal-lnu-mode'. This +function will run even if intercal-lnu-mode is off, but intercal-mode must be +on. Running this function manually (with C-c C-u) rather than automatically is +a good idea in long files, which take a long time to update." + (interactive) + (if (equal major-mode 'intercal-mode) + (save-excursion + (let ((line-number-update-list nil)) + (goto-char (point-min)) + (while (re-search-forward "^(\\([0-9]+\\))" nil t) + (if (< (string-to-number (match-string-no-properties 1)) 1000) + (setq line-number-update-list (cons + (list + (string-to-number (match-string-no-properties 1)) + (count-lines 1 (point))) + line-number-update-list)))) + (while line-number-update-list + (intercal-lnu-individual (caar line-number-update-list) (cadar line-number-update-list)) + (setq line-number-update-list (cdr line-number-update-list)))) + (goto-char (point-min)) + (while (search-forward "LNUChange:" nil t) + (replace-match ""))) + (error "The buffer is not in intercal-mode")) +) + +(defun intercal-lnu-individual (oldlabel newlabel) +"Updates all occurrences of one label in an INTERCAL program for another." + (save-excursion + (goto-char (point-min)) + (while (search-forward (concat "(" (number-to-string oldlabel) ")") nil t) + (replace-match (concat "(LNUChange:" (number-to-string newlabel) ")")))) +) + +;; Font Lock settings. +;; We use keyword-face for commands, builtin-face for gerunds, constant-face +;; for meshes and mingle-mesh constants, and comment-face for initially +;; abstained lines (because these are usually comments, and anyway it's good +;; for them to stand out). Only the first line of multiline comments is marked. +;; MAYBE lines aren't marked because that's a big giveaway that the line won't +;; be abstained from all program. +(defvar intercal-font-lock-keywords + '(("^\\(([0-9]+)\\|\\)[ \t]*\\(PLEASE DO\\|DO\\|PLEASE\\)[ \t]*\\(NOT\\|N'T\\).*$" . font-lock-comment-face) + ("\\<\\(ABSTAIN\\|GIVE UP\\|READ OUT\\|RESUME\\|WRITE IN\\|PIN\\|COME\\|FROM\\|IGNORE\\|REINSTATE\\|RETRIEVE\\|PLEASE\\|DO\\|MAYBE\\|ONCE\\|AGAIN\\|FORGET\\|NEXT\\|REMEMBER\\|STASH\\|DON'T\\|NOT\\|TRY AGAIN\\|GO AHEAD\\|GO BACK\\)\\>" . font-lock-keyword-face) + ("\\<\\(ABSTAINING\\|GIVING UP\\|READING OUT\\|RESUMING\\|WRITING IN\\|PINNING\\|COMING\\|IGNORING\\|REINSTATING\\|RETRIEVING\\|FORGETTING\\|NEXTING\\|REMEMBERING\\|STASHING\\|TRYING AGAIN\\|CALCULATING\\|GOING AHEAD\\|GOING BACK\\)\\>" . font-lock-builtin-face) + ("[.,:;][0-9]+" . font-lock-variable-name-face) + ("#[0-9]+\\(\\$#[0-9]+\\|\\)" . font-lock-constant-face)) + "Default expressions to highlight in Intercal mode.") + +;; Find an error message produced by ick. If the famous RESUBNIT spelling error +;; is ever corrected, this will need to be corrected too. +(defvar intercal-error-regexp + '("ICL[0-9][0-9][0-9][IW].*\n[ \t]*ON THE WAY TO \\([0-9]+\\)\n[ \t]*\\(CORRECT\\|RECONSIDER\\) SOURCE AND RESUBNIT$" nil 1) + "Regexp that identifies an INTERCAL error message, and the file and line number positions in it.") + +;; Detect the line with which ick was invoked, so the filename used can be +;; used by Emacs' compile-mode to find the error. This will need to be changed +;; if command-line arguments to ick other than letters are allowed. +(defvar intercal-file-regexp '(".*ick \\(-[a-zA-Z]+ \\)*\\(.*i\\)$" 2) + "Regexp that identifies the line with which ick was invoked, and the filename it was used on.") + +;; Helper function for the binary I/O routines. +(defun intercal-reverse-bits-if-nonnull (flag num) + "Returns num if flag is null, or num with bits reversed if flag is nonnull." + (if (null flag) num + (let ((ans 0) (count 8) (num1 num)) + (while (> count 0) + (setq ans (* ans 2)) + (if (= (% num1 2) 1) (setq ans (1+ ans))) + (setq num1 (/ num1 2)) + (setq count (1- count))) + ans)) +) + +;; Internal memory for inter-function communication. Yes, I know it's +;; unLispish to do this sort of thing, and breaks if the user tries to +;; convert two strings simultaneously. +(defvar intercal-string-array-convert-options-buffer-used nil + "Variable that keeps track of a buffer used to display options +for intercal-string-array-convert.") + +;; Function that inputs options for intercal-string-array-convert. +;; If the user asks for help, it pops up a help buffer and returns nil. +;; Its documentation string is the information required to appear in +;; the help buffer. +(defun intercal-string-array-convert-options (opts) + "Options for use with intercal-string-array-convert: + ? Display the list of options + 1 Pack the string one char/element (default) + 2 Pack the string two chars/element (unimplemented) + 4 Pack the string four chars/element (unimplemented) + $ Pack the string in mingled format (default) + so \"abcd\" would become \"a$b\"$\"c$d\" + < Pack the string in shifted format + (concatentate the codes for each character) + R Bit-reverse each character code (default) + W Don't bit-reverse each character code + , Treat entered number as a tail array (default) + ; Treat entered number as a hybrid array + 0 Each character code is based at 0 (default) + + Each character code is based at the previous code (unimplemented)" + (interactive "sOptions: (type ?[RET] for help)") + (if (string= opts "?") + (progn + (setq intercal-string-array-convert-options-buffer-used t) + (with-output-to-temp-buffer "*Options*" + (princ (documentation 'intercal-string-array-convert-options))) + nil) + opts) +) + +;; The displaying of the help buffer is done by +;; intercal-string-array-convert-options, if required. This function holds +;; tests to put the display back as it was in two possible common situations +;; involving the user asking for help (one window active, two windows active). +(defun intercal-string-array-convert (in arr &optional opts) + "Generate INTERCAL code to initialize an array with information +that makes it suitable for use as a string. For more information, +run the command and enter a question mark for the options." + (interactive "*MEnter string to convert:\nnEnter number of array required:") + (let ((cb (current-buffer)) (w1p (one-window-p)) (ow nil)) + (if (null w1p) (setq ow other-window-scroll-buffer)) + (while (null opts) + (setq opts (call-interactively 'intercal-string-array-convert-options))) + (if intercal-string-array-convert-options-buffer-used + (progn + (select-window (get-buffer-window cb)) + (if w1p + (delete-other-windows) + (switch-to-buffer-other-window ow)))) + (setq intercal-string-array-convert-options-buffer-used nil)) + (let ((packing 1) (basis nil) (arrtype ",") (revbits t) (mingle t)) + (while (> (length opts) 0) + (if (string= (substring opts 0 1) "1") (setq packing 1) + (if (string= (substring opts 0 1) "2") (error "Unimplemented") ;(setq packing 2) ;unimplemented + (if (string= (substring opts 0 1) "4") (error "Unimplemented") ;(setq packing 4) ;unimplemented + (if (string= (substring opts 0 1) "$") (setq mingle t) ;unimplemented, but has no effect on option 1 + (if (string= (substring opts 0 1) "<") (setq mingle nil);unimplemented, but has no effect on option 1 + (if (string= (substring opts 0 1) "R") (setq revbits t) + (if (string= (substring opts 0 1) "W") (setq revbits nil) + (if (string= (substring opts 0 1) ",") (setq arrtype ",") + (if (string= (substring opts 0 1) ";") (setq arrtype ";") + (if (string= (substring opts 0 1) "0") (setq basis nil) + (if (string= (substring opts 0 1) "+") (error "Unimplemented") ;(setq basis t) ;unimplemented + (error "Invalid option")))))))))))) + (setq opts (substring opts 1))) + (intercal-return) + (intercal-do-abbrev) + (let ((al (/ (+ (length in) packing -1) packing))) + (insert " " arrtype (int-to-string arr) " <- #" (int-to-string al))) + (let ((lastchar 0) (arrind 1)) + (while (> (length in) 0) + (intercal-return) + (intercal-do-abbrev) + (insert " " arrtype (int-to-string arr) " SUB #" (int-to-string arrind)) + (insert " <- #?" (substring in 0 1)) + (setq in (substring in 1)) + (intercal-char-constant-convert revbits)))) +) + +;; Converts char to int by subtracting ! and adding 33. +(defun intercal-char-constant-convert (arg) + "Convert a constant of the form #? into a legal +INTERCAL constant representing the character's character code. +With a prefix argument, gives bit-reversed output. This routine +is intended for use with the binary I/O capabilities of INTERCAL." + (interactive "*P") ;Check prefix arg, not read-only + (save-excursion + (if (re-search-backward "#" (line-beginning-position) t) + (if (re-search-forward "#\\?\\(.\\)" (line-end-position) t) + (replace-match + (concat "#" (int-to-string (intercal-reverse-bits-if-nonnull arg + (+ 33 (- (string-to-char + (match-string-no-properties 1)) ?!))))))))) +) + + +;; This is simpler than the next function because we're +;; converting from the target base, so it's simply a case +;; of selecting every second character if we need to produce +;; a mingled result +(defun intercal-constant-radix-convert () + "Convert a constant of the form #r +to a legal TRI-INTERCAL constant in that base. If the number is +sufficiently small, it is converted to decimal; otherwise, it is +converted to two mingled decimal constants." + (interactive "*") + (save-excursion + (if (re-search-backward "#" (line-beginning-position) t) + (if (re-search-forward "#\\([2-7]\\)r\\([0-6]+\\)" + (line-end-position) t) + (replace-match + (let ((radix (string-to-number + (match-string-no-properties 1) 10)) + (str (match-string-no-properties 2)) (slen 0) + (mingle1 "") (mingle2 "") (num1 0) (num2 0)) + (setq slen (length str)) + (if (or (<= (* radix slen) 32) ; Calculate max onespot length + (or (and (= radix 6) (= slen 6)) ;on these + (and (= radix 7) (= slen 5)))) ;three lines + (progn + (setq num1 (string-to-number str radix)) + (concat "#" (number-to-string num1))) + (progn + (while (/= 0 (length str)) + (setq mingle2 (concat (substring str -1) mingle2)) + (setq str (substring str 0 -1)) + (if (/= 0 (length str)) + (progn + (setq mingle1 (concat (substring str -1) mingle1)) + (setq str (substring str 0 -1))))) + (setq num1 (string-to-number mingle1 radix)) + (setq num2 (string-to-number mingle2 radix)) + (concat "#" (number-to-string num1) + "$#" (number-to-string num2))))))))) +) + +;; The following code needs a bit of explanation. INTERCAL +;; can handle constants up to 4294967295 (0xffffffff), but +;; Emacs's constants max out somewhere between 100 million +;; and 1 billion. So, when a high number is entered, the +;; code processes the last 6 digits (in whatever base the +;; number is entered in) separately from the rest of the +;; number. This ensures that the arithmetic routines never +;; overflow if the input is a valid integer in the range +;; 0-4294967295. The calculations used do not work for +;; higher numbers, but that doesn't matter because +;; INTERCAL wouldn't accept them. Constants higher than +;; 65535 are given in mingled form (e.g. #65280$#65280). +(defun intercal-constant-convert () + "Convert a constant of the form # to a +legal INTERCAL constant (#<16-bit decimal integer> or +#<16-bit decimal integer>$#<16-bit decimal integer>). +Decimal (#4294967295), octal (#037777777777) and +hex (#0xffffffff) formats are all supported." + (interactive "*") + (save-excursion + (if (re-search-backward "#" (line-beginning-position) t) + (if (re-search-forward "#\\(0?[xX]?\\)\\([0-9a-fA-F]+\\)" + (line-end-position) t) + (replace-match + (let ((str (match-string-no-properties 2)) + (strhi "0") (strlow "0") + (base (if (string= (match-string-no-properties 1) "") + 10 + (if (string= (match-string-no-properties 1) "0") + 8 16)))) + (if (<= (length str) 6) (setq strlow str) + (setq strlow (substring str -6) strhi (substring str 0 -6))) + (let ((num (string-to-number strlow base)) + (numhi (string-to-number strhi base))) + (if (and (<= num 65535) (string= strhi "0")) + (concat "#" (number-to-string num)) + (let ((mingle1 0) (mingle2 0) (count 16) (temp 0)) + (while (> count 0) + (progn + (setq temp (% num 4)) + (setq num (/ num 4)) + (if (= (% temp 2) 1) (setq mingle2 (+ mingle2 65536))) + (if (> temp 1) (setq mingle1 (+ mingle1 65536))) + (setq mingle1 (/ mingle1 2)) + (setq mingle2 (/ mingle2 2)) + (setq count (- count 1)) + (if (= count 13) + (setq num (+ num (* (/ (expt base 6) 64) numhi)))))) + (concat "#" (number-to-string mingle1) + "$#" (number-to-string mingle2)) + )))) + t t)))) +) + +;; This wraps around compilation-parse-errors in compile, and makes sure that +;; the first line of the compilation buffer is blank. This is to make the +;; call of ick (which is needed to determine the source file) look like an +;; error message rather than a compiler call. +(defun intercal-error-wrap (limit-search find-at-least) + "Parse the current buffer as ick error messages. This just wraps around +'compilation-parse-errors'. See variable 'compilation-parse-errors-function' +for the interface it uses." + (save-excursion + (beginning-of-buffer) + (if (looking-at "^$") nil (newline))) + (compilation-parse-errors limit-search find-at-least) +) + +(require 'compile) ;Now a prerequisite for intercal.el, so its variables can be + ;changed to INTERCAL values upon loading an INTERCAL file + +;; This hook changes settings in fontlock and compile, so that they +;; recognize INTERCAL syntax and ick error messages. Default options to +;; ick are to optimize, but I chose not to give -b as a default (because +;; it spoils the fun). I'm slightly tempted to use -m as default, but +;; I'm not sure I'm that evil, and I left -f out for the time being because +;; it's something of a radical change to the output. +(add-hook 'intercal-mode-hook + (function (lambda () + (make-local-variable 'font-lock-defaults) + (setq font-lock-defaults '(intercal-font-lock-keywords t)) + (make-local-variable 'compilation-error-regexp-alist) + (setq compilation-error-regexp-alist (cons intercal-error-regexp + compilation-error-regexp-alist)) + (make-local-variable 'compilation-file-regexp-alist) + (setq compilation-file-regexp-alist (cons intercal-file-regexp + compilation-file-regexp-alist)) + (make-local-variable 'compile-command) + (setq compile-command (concat "ick -O " (buffer-name))) + (make-local-variable 'compilation-parse-errors-function) + (setq compilation-parse-errors-function 'intercal-error-wrap)))) + +;; AIS: End of section I wrote. + +;;; intercal.el ends here diff --git a/feh.c b/feh.c deleted file mode 100644 index be39609..0000000 --- a/feh.c +++ /dev/null @@ -1,3783 +0,0 @@ -/**************************************************************************** - -Name - feh.c -- code-generator back-end for ick parser - -DESCRIPTION - This module provides storage manglement, code degeneration, -and optimizations of dubious value for the INTERCAL compiler. - -LICENSE TERMS - Copyright (C) 1996 Eric S. Raymond - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - -****************************************************************************/ -/*LINTLIBRARY */ -#include -#include -#include -#include "sizes.h" -#include "ick.h" -#include "y.tab.h" -#include "fiddle.h" -#include "lose.h" -#include "feh.h" - -/* AIS: The following macro produces optimization debug data. I added all - occurences of it in this source file. It also keeps track of whether - optimizations have taken place. */ -#define OPTING(x) if(optdebug == 2) {\ - explexpr(optdebugnode,stderr);\ - putc('\n',stderr); } \ - if(optdebug == 3) {\ - prexpr(optdebugnode,stderr,0);\ - putc('\n',stderr); } \ - if(optdebug) fprintf(stderr,"[%s]",#x);\ - if(optdebug >= 2) putc('\n',stderr);\ - opted = 1; - -static int emitlineno; /* line number for errors encountered during emit */ - -static void checknodeactbits(node *np); /* AIS: This prototype needed early */ - -int mark112 = 0; /* AIS: Mark the next generated tuple for W112 */ - -/************************************************************************* - * - * Node allocation functions. - * - * Nodes are used to represent expression trees. The emit() function - * deallocates them. - * - **************************************************************************/ - -node *newnode(void) -/* allocate and zero out a new expression node */ -{ - return((node *)calloc(sizeof(node), 1)); -} - -node *cons(int type, node *car, node *cdr) -{ - node *np = newnode(); - - np->opcode = type; - np->lval = car; - np->rval = cdr; - - return(np); -} - -/* By AIS. This function looks remarkably like a C++ copy-constructor to me, - just with extra arrows in. */ -node *nodecopy(node* n) -{ - node* np; - if(!n) return 0; - np = cons(n->opcode, nodecopy(n->lval), nodecopy(n->rval)); - np->constant = n->constant; - np->optdata = n->optdata; - np->width = n->width; - return np; -} - -/* This function by AIS. Compares expressions. In C++, I'd call this - node::operator== . */ -static bool nodessame(node* n1, node* n2) -{ - if(!n1) return !n2; - if(!n2) return 0; - if(n1->opcode!=n2->opcode) return 0; - if(!nodessame(n1->lval,n2->lval)) return 0; - if(!nodessame(n1->rval,n2->rval)) return 0; - switch(n1->opcode) - { - case ONESPOT: - case TWOSPOT: - case HYBRID: - case TAIL: - case MESH: - case MESH32: - return n1->constant == n2->constant; - case AND: - case OR: - case XOR: - return n1->width == n2->width; - default: - return 1; - } -} - -/************************************************************************* - * - * Variable-name mapping - * - * This permits us to optimize use of variable storage at runtime - * - **************************************************************************/ - -unsigned int intern(int type, int index) -{ - atom *x; - - if (index < 1 || index > 65535) - lose(E200, yylineno, (char *)NULL); - - if (!oblist) - { - /* initialize oblist and obdex */ - oblist = malloc(ALLOC_CHUNK * sizeof(atom)); - if (!oblist) - lose(E778, yylineno, (char *)NULL); - obdex = oblist; - obcount = ALLOC_CHUNK; - } - - /* if it's already on the oblist, return its intindex */ - for (x = oblist; x < obdex; x++) - if (x->type == type && x->extindex == index) - return(x->intindex); - - /* else we must intern a new symbol */ - if (obdex >= oblist + obcount) - { - obcount += ALLOC_CHUNK; - x = realloc(oblist, obcount * sizeof(atom)); - if (!x) - lose(E333, yylineno, (char *)NULL); - obdex = x + (obdex - oblist); - oblist = x; - } - obdex->type = type; - obdex->extindex = index; - if (type == ONESPOT) - obdex->intindex = nonespots++; - if (type == TWOSPOT) - obdex->intindex = ntwospots++; - if (type == TAIL) - obdex->intindex = ntails++; - if (type == HYBRID) - obdex->intindex = nhybrids++; - ++obdex; - - return(obdex[-1].intindex); -} - -/************************************************************************* - * - * This function insures a label is valid. - * - **************************************************************************/ - -void checklabel(int label) -{ - if (label < 1 || label > 65535) - lose(E197, yylineno, (char *)NULL); -} - -/************************************************************************* - * - * AIS: Search for the indexth COME_FROM sucking in the given tuple. - * Return an int representing the COME_FROM's tn-tuples+1, or -1. - * index is based at 1, not 0 as is usual for C. - * - ***************************************************************************/ - -int comefromsearch(tuple* tn, unsigned int index) -{ - tuple* tp; - for (tp = tuples; tp < tuples + lineno; tp++) - { - if(tp->type == COME_FROM && tp->u.target == tn-tuples+1) index--; - if(!index) return tp-tuples+1; - } - return -1; -} - -/************************************************************************* - * - * Tuple allocation functions. - * - **************************************************************************/ - -void treset(void) -{ - tuplecount = 0; - if (tuples) - { - free(tuples); - tuples = NULL; - } - nonespots = ntwospots = ntails = nhybrids = 0; - obdex = oblist; - lineno = 0; -} - -tuple *newtuple(void) -/* allocate and zero out a new expression tuple */ -{ - if (lineno >= tuplecount) - { - tuplecount += ALLOC_CHUNK; - if (tuples) - tuples = realloc(tuples, tuplecount * sizeof(tuple)); - else - tuples = malloc(tuplecount * sizeof(tuple)); - if (!tuples) - { - lose(E666, yylineno, (char *)NULL); - return NULL; - } - memset(tuples + lineno, 0, (tuplecount - lineno) * sizeof(tuple)); - } - if(mark112) tuples[lineno].warn112 = 1; mark112 = 0; /* AIS */ - return(tuples + lineno++); -} - -/************************************************************************* - * - * The typecaster - * - * The theory here is that we associate a type with each node in order to - * know what widths of unary-logical operator to use. - * - **************************************************************************/ - -void typecast(node *np) -{ - /* recurse so we typecast each node after all its subnodes */ - if (np == (node *)NULL) - return; - else if (np->lval != (node *)NULL) - typecast(np->lval); - if (np->rval != (node *)NULL) - typecast(np->rval); - - /* - * This is an entire set of type-deducing machinery right here. - */ - if (np->opcode == MESH || np->opcode == ONESPOT || np->opcode == TAIL) - np->width = 16; - else if (np->opcode == TWOSPOT || np->opcode == HYBRID - || np->opcode == MINGLE || np->opcode == MESH32) - np->width = 32; - else if (np->opcode == AND || np->opcode == OR || np->opcode == XOR || - np->opcode == FIN || - (np->opcode >= WHIRL && np->opcode <= WHIRL5)) - np->width = np->rval->width; - else if (np->opcode == SELECT) - np->width = np->rval->width; /* n-bit select has an n-bit result */ - else if (np->opcode == SUB) - np->width = np->lval->width; /* type of the array */ -} - -/************************************************************************* - * - * The codechecker - * - * This checks for nasties like mismatched types in assignments that - * can be detected at compile time -- also for errors that could cause - * the compilation of the generated C to fail, like generated gotos to - * nonexistent labels or duplicate labels. - * - * AIS: codecheck has another important job, that of filling in information - * about COME FROM suckpoints and ABSTAIN/REINSTATE command numbers - * into the tuples. - * - **************************************************************************/ - -void codecheck(void) -{ - tuple *tp, *up; - int notpast1900; /* AIS */ - - /* check for assignment type mismatches */ - /* This check can't be done at compile time---RTFM. [LHH] */ -/* - for (tp = tuples; tp < tuples + lineno; tp++) - if (tp->type == GETS) - if (tp->u.node->lval->width == 16 && tp->u.node->rval->width == 32) - lose(E275, tp - tuples + 1, (char *)NULL); -*/ - - /* check for duplicate labels */ - for (tp = tuples; tp < tuples + lineno; tp++) - if (tp->label) - for (up = tuples; up < tuples + lineno; up++) - if (tp != up && tp->label == up->label) - lose(E182, tp - tuples + 1, (char *)NULL); - - /* - * Check that every NEXT, ABSTAIN, REINSTATE and COME_FROM actually has a - * legitimate target label. - */ - notpast1900 = TRUE; - for (tp = tuples; tp < tuples + lineno; tp++) - { - if (tp->label == 1900) notpast1900 = FALSE; /* AIS */ - if (tp->type == NEXT - || tp->type == ABSTAIN || tp->type == REINSTATE - || tp->type == COME_FROM || tp->type == FROM) /* AIS: added FROM. */ - { - bool foundit = FALSE; - - if (tp->u.target >= 1900 && tp->u.target <= 1998) - { - /* AIS: This program uses syslib.i's random number feature... or are - we in syslib already? */ - if(notpast1900) coopt = 0; - } - - for (up = tuples; up < tuples + lineno; up++) - if (tp->u.target == up->label) - { - foundit = TRUE; - break; - } - - if (!foundit) - { - if (tp->type == NEXT) - lose(E129, tp - tuples + 1, (char *)NULL); - else if (tp->type == COME_FROM) - lose(E444, tp - tuples + 1, (char *)NULL); - else - lose(E139, tp - tuples + 1, (char *)NULL); - } - /* tell the other tuple if it is a COME FROM target */ - else if (tp->type == COME_FROM) - { - if (up->ncomefrom && !multithread) /* AIS: multithread check */ - lose(E555, yylineno, (char *)NULL); - else - up->ncomefrom++; /* AIS: to handle multiple COME FROMs */ - } - /* this substitutes line numbers for label numbers - AIS: COME FROM now uses this too. This changes the logic - slightly so that an !foundit condition would fall through, - but as long as lose doesn't return, it's not a problem. - (I removed the else before the if.) */ - if (tp->type != NEXT) - { - tp->u.target = up - tuples + 1; - } - else /* AIS */ - { - tp->nexttarget = up - tuples + 1; - up->nextable = TRUE; - } - } - } -} - -/* AIS: Checks if an abstention could affect a tuple. */ -int abstainmatch(int npconstant, int tptype) -{ - if(npconstant == tptype) return 1; - if(npconstant == ABSTAIN) - if(tptype == FROM || tptype == MANYFROM || tptype == DISABLE) return 1; - if(npconstant == REINSTATE) - if(tptype == DISABLE) return 1; - return 0; -} - -/* AIS: Added the third argument to prexpr and prvar. It specifies - whether the node should be freed or not. I added the third - argument in all calls of prexpr/prvar. This protoype has been moved - up through the file so it can be used earlier. */ -static void prexpr(node *np, FILE *fp, int freenode); - -/************************************************************************* - * - * AIS: Flow optimizer. (I wrote the whole of optimizef.) - * - * This analyses the flow of the program, checking to see which lines can - * have their guards omitted, which lines can be omitted altogether, which - * variables can never be ignored, etc. The degenerator lower down can take - * this information into account, producing faster and shorter source code. - * In an ideal world, we'd end up with the produced INTERCAL looking like - * proper C code, but somehow I think that's unlikely to happen. - * At the moment, it just checks for unused !abstained[] guards on - * statements and removes them (possibly removing comments altogether). - * This is minor, but should clear up degenerated code substantially. - * It also allows the code for gets to replace assign() with the faster = - * in cases where this doesn't affect the behaviour of the program. - * See the function itself for what I did to NEXT. - * - *************************************************************************/ - -void optimizef(void) -{ - tuple* tp, *tpa, *tpb; - atom* op; - node* np; - if(!flowoptimize) lose(E778, yylineno, (char *) NULL); - for (tp = tuples; tp < tuples + lineno; tp++) tp->abstainable = 0; - /* abstainable holds whether a line's abstention status can change */ - for (op = oblist; op < obdex; op++) op->ignorable = 0; - /* ignorable holds whether a variable's ignorance status can change */ - for (tp = tuples; tp < tuples + lineno; tp++) - { - if(tp->maybe) tp->abstainable = 1; - if(tp->exechance < 0) tp->initabstain = 1; - if(tp->exechance != 100 && tp->exechance != -100) tp->abstainable = 1; - if(tp->onceagainflag != onceagain_NORMAL) tp->abstainable = 1; - if(tp->type == ABSTAIN || tp->type == FROM) - { - tpa = tp->u.target - 1 + tuples; - if(tpa->exechance >= 0) tpa->abstainable = 1; - } - if(tp->type == REINSTATE) - { - tpa = tp->u.target - 1 + tuples; - if(tpa->exechance < 0) tpa->abstainable = 1; - } - if(tp->type == DISABLE || tp->type == MANYFROM) - { - for (tpa = tuples; tpa < tuples + lineno; tpa++) - { - np = tp->u.node; - if(tp->type == MANYFROM) np = np->rval; - for(; np; np = np -> rval) - if(abstainmatch(np->constant, tpa->type)) - if(tpa->exechance >= 0) tpa->abstainable = 1; - } - } - if(tp->type == ENABLE) - { - for (tpa = tuples; tpa < tuples + lineno; tpa++) - { - np = tp->u.node; - for(; np; np = np -> rval) - if(abstainmatch(np->constant, tpa->type)) - if(tpa->exechance < 0) tpa->abstainable = 1; - } - } - if(tp->type == GETS) - checknodeactbits(tp->u.node->rval); - /* If optdata shows that the value must always fit in the variable, - and the variable cannot be ignored, assign can be replaced by the - cheaper =. */ - if(tp->type == IGNORE) - { - for (np = tp->u.node; np; np = np->rval) - { - for (op = oblist; op < obdex; op++) - { - if(op->type == np->opcode && op->intindex == np->constant) - op->ignorable = 1; - } - } - } - /* REMEMBERING variables has no effect on this code, because all - variables are initially remembered anyway, and so an IGNORE would - be needed (and caught above) to have an effect. */ - } - /* There are some flow idioms that maybe should be optimized. The most - common is the NEXTing idiom for if(), which looks like this: - - DO (1) NEXT - block 2 - escape via NEXTING or COMEFROM - (1) DO (2) NEXT - DO FORGET #1 - block 1 - - and elsewhere in the program: - (2) DO RESUME <1-or-2-condition> - - Recognizing this idiom is quite difficult because there are a number of - problems and common variations. - First, the FORGET might be placed elsewhere, or replaced with a higher - FORGET later or a higher RESUME later. If there is, in fact, a RESUME #1 - as the next NEXT-control statement, the idiom won't quite work properly. - So to handle this, we need to push the original return address on the - NEXT stack if block 1 is taken, unless the next statement is a FORGET #1. - Second, there may be abstentions or COME FROMs messing with control flow - in the area. The flow optimizer ought to be able to detect this and not - optimize the statement if true. (This means that a program which uses - gerund abstention on NEXTING or RESUMING, or that uses computed COME FROM, - will probably not benefit from this optimization). Third, how should a - <1-or-2-condition> be detected? Throughout syslib, the most common - condition to use is .5, which isn't inherently 1 or 2. The way round this - seems to be to detect a <1-or-2-assignment> as the previous statement, - again with checks for COME FROM and abstentions. (I treat MAYBE as a sort - of abstention, albeit a temporally undecided one.) So ignorance of the - relevant variable needs to be checked for also. The checks are done partly - in optimizef() and partly in emit(). - */ - if(compucomesused) return; /* That's one check out of the way! */ - - np = (node*) NULL; - for (tp = tuples; tp < tuples + lineno; tp++) - { - if(tp->type == GETS) - { - if(tp->u.node->rval->opcode == C_AND1ADD1 || - tp->u.node->rval->opcode == C_2SUBAND1 || - (tp->u.node->rval->opcode == C_1PLUS || - tp->u.node->rval->opcode == C_2MINUS) && - tp->u.node->rval->rval->optdata == 1) - { - /* This won't catch all <1-or-2-expressions>, but will get - most of them. */ - if(tp->u.node->lval->opcode != SUB) np = tp->u.node->lval; - } - else if(np&&nodessame(np, tp->u.node->lval)) np = (node*) NULL; - if(tp->nextable) np = (node*) NULL; - if(tp->maybe||tp->abstainable) np = (node*) NULL; - if(tp->ncomefrom&&multithread) np = (node*) NULL; - if(np) - { /* IGNORING np might prevent it getting its <1-or-2-value>. */ - atom* op; - int ignorable = 1; - for(op = oblist; op < obdex; op++) - { - if(op->type == np->opcode && - op->intindex == np->constant) - { - ignorable &= op->ignorable; - } - } - if(ignorable) np = (node*) NULL; - } - /* np will only have a nonnull value if it's a variable that must be - set to a <1-or-2-value> to reach line tp. Regardless of whether - maybes have been parsed or not, either maybe or abstainable or - both will be 1 on a MAYBE line. The last check is a precaution - against MAYBE COME FROM sneakily modifying a variable (although - I think it's unlikely that anyone would deliberately try to fool - -f like this, it is INTERCAL after all!) */ - } - if(tp->type == COME_FROM || tp->type == COMPUCOME) np = (node*) NULL; - if(tp->type == NEXT) - { - tpa = tuples + tp->nexttarget - 1; - if(tpa->type == NEXT && !tp->abstainable && !tpa->abstainable - && !tp->ncomefrom && !tpa->ncomefrom) - { - tpb = tuples + tpa->nexttarget - 1; - if(tpb->type == RESUME && ((tpb->u.node->opcode == C_AND1ADD1 || - tpb->u.node->opcode == C_2SUBAND1 || - (tpb->u.node->opcode == C_1PLUS || - tpb->u.node->opcode == C_2MINUS) && - tpb->u.node->rval->optdata == 1) || - np&&nodessame(tpb->u.node,np))&& - !tpb->abstainable) /* No COMING FROM a nonabstainable RESUME line! */ - { - tp->optversion = TRUE; - tp->u.node = nodecopy(tpb->u.node); - /* If tp->u.node is 2, then the statement should translate to a - no-op (NEXT...NEXT...RESUME #2). However, if tp->u.node is 1, - the statement should translate to a NEXT to the line after the - one it's aiming for. As it's aiming for a NEXT, the solution is - to NEXT to the return label of the NEXT it's aiming for. This - won't trigger any COME FROMs or ONCE/AGAIN flags, or even MAYBEs, - on the commands missed out, so the code has checked that they - aren't there. */ - } - } - np = (node*) NULL; - } - } -} - -/************************************************************************* - * - * Expression optimizer. - * - * It's not a very good optimizer, is it? - * - * AIS: All free'd pointers set to NULL, to help trace memory problems. - * The optimizer can now recognize the majority of syslib's idioms. - * The optimizer will make multiple passes. Although I am now happy - * with the quality of this optimizer, I'll keep the paragraph above - * this one for history's sake. The optimizing functions return 1 - * if any optimizations were made, apart from optimize itself, which - * is void. - * - **************************************************************************/ - -static int optimize_pass1(node *np); -static int optimize_pass2(node *np); -static void checkforintercaloperators(node *np); -static void checkW534(node *np); - -static node* optdebugnode; - -/* This function by AIS */ -void optimize(node *np) -{ - int optflag; - checknodeactbits(np); - checkW534(np); /* This must be done before optimization, and depends on - checknodeactbits. */ - if(optdebug == 1) explexpr(np,stderr); - if(optdebug == 1) fprintf(stderr," becomes "); - if(optdebug >= 2) optdebugnode = np; - optimize_pass1(np); /* Optimize idioms */ - if(Base!=2) - { - if(optdebug && optdebug != 3) explexpr(np,stderr); - if(optdebug == 3) prexpr(np,stderr,0); - if(optdebug) fprintf(stderr,"\n"); - if(optdebug >= 2) fprintf(stderr,"-----\n"); - return; - } - do - { - checknodeactbits(np); /* Determine bitranges */ - optflag = optimize_pass2(np); /* Optimize based on those bitranges */ - optflag |= optimize_pass1(np); - } while(optflag); /* Keep optimizing until no optimizations are found */ - if(optdebug && optdebug != 3) explexpr(np,stderr); - if(optdebug == 3) prexpr(np,stderr,0); - if(optdebug) fprintf(stderr,"\n"); - if(optdebug >= 2) fprintf(stderr,"-----\n"); - checkforintercaloperators(np); - if(optuple->type == RESUME && !np->optdata) optuple->warn622 = 1; -} - -/* By AIS. This relies on free'd pointers being NULLed. */ -static void nodefree(node *np) -{ - if(!np) return; - nodefree(np->lval); - nodefree(np->rval); - free(np); -} - -/* By AIS. This checks W534. */ -static void checkW534(node *np) -{ - if(!np) return; - if(np->opcode == AND || np->opcode == OR || np->opcode == XOR) - { - if(np->rval->opcode == SELECT && np->rval->rval->width == 32 && - !(np->rval->rval->optdata&0xffff0000lu)) - { - /* This looks suspicious, in that C-INTERCAL will do an op32, - but INTERCAL-72 would have done an op16. */ - optuple->warn534=1; - } - } - checkW534(np->lval); - checkW534(np->rval); -} - -/* By AIS. This checks W018. */ -static void checkforintercaloperators(node *np) -{ - if(!np) return; - switch(np->opcode) - { /* This only comes up in binary. */ - case AND: case OR: case XOR: case MINGLE: case SELECT: - optuple->warn018 = 1; - default: - checkforintercaloperators(np->lval); - checkforintercaloperators(np->rval); - return; - } -} - -/* By AIS (with a few code fragments copied from elsewhere in this file) */ -static void checknodeactbits(node *np) -{ - if (np == (node *)NULL) - return; - else if (np->lval != (node *)NULL) - checknodeactbits(np->lval); - if (np->rval != (node *)NULL) - checknodeactbits(np->rval); - - switch (np->opcode) - { - case MINGLE: - if(np->lval->optdata & 0xffff0000LU) optuple->warn276 = 1; - if(np->rval->optdata & 0xffff0000LU) optuple->warn276 = 1; - np->optdata = mingle(np->lval->optdata & 0xffff, - np->rval->optdata & 0xffff); - /* The bitmask is needed because the output of ~ might always be 16-bit - at runtime, but appear 32-bit at compile-time. But this is somewhat - suspicious, so we can at least give a warning (W276) if -l is used. */ - break; - - case SELECT: - np->optdata = np->lval->optdata & np->rval->optdata; - np->optdata = iselect(np->optdata, np->optdata); - break; - - case AND: - np->optdata = (np->width==16?and16:and32)(np->rval->optdata); - break; - - case OR: - case XOR: - np->optdata = (np->width==16?or16:or32)(np->rval->optdata); - /* This is or in both cases. */ - break; - - case FIN: - case WHIRL: - case WHIRL2: - case WHIRL3: - case WHIRL4: - case WHIRL5: /* We must be in binary to reach this point, so: */ - lose(E997, emitlineno, (char*) NULL); - break; - - case MESH: - case MESH32: - np->optdata = np->constant; /* It's trivial to tell which bits - can be nonzero! */ - break; - - case ONESPOT: - case TWOSPOT: - case TAIL: - case HYBRID: - case SUB: - np->optdata = np->width == 16 ? 0xffff : 0xffffffffLU; - break; - - /* cases from here down are generated by optimize_pass1 */ - case C_AND: - np->optdata = np->lval->optdata & np->rval->optdata; - break; - - case C_OR: - case C_XOR: - np->optdata = np->lval->optdata | np->rval->optdata; - /* bitwise-or is correct in both cases */ - break; - - case C_NOT: - np->optdata = np->width == 16 ? 0xffff : 0xffffffffLU; - break; - - case C_NOTEQUAL: - case C_NNAND: - case C_ISNONZERO: - case C_XORGREATER: - np->optdata = 1; /* that's what !! does! */ - break; - - case C_AND1ADD1: - case C_2SUBAND1: - np->optdata = 3; /* the value could be 1 or 2 */ - break; - - case C_1PLUS: - np->optdata = np->rval->optdata | (np->rval->optdata << 1); - /* this relies on unsigned overflow handling to work correctly */ - break; - - case C_2MINUS: - if(np->rval->optdata == 1) np->optdata = 3; - else np->optdata = (np->width == 16 ? 0xffff : 0xfffffffflu); - /* alright, so this might not be ruthless enough, but C_2MINUS is - only meant to be generated when the condition is true anyway */ - break; - - case C_LSHIFT: - np->optdata = (np->lval->optdata & np->rval->optdata) << 1; - break; - - case C_LSHIFTIN1: - np->optdata = ((np->lval->optdata & np->rval->optdata) << 1) | 1; - break; - - case C_LSHIFT2: - np->optdata = (np->lval->optdata & np->rval->optdata) << 2; - break; - - case C_LSHIFT8: - np->optdata = (np->lval->optdata & np->rval->optdata) << 8; - break; - - case C_RSHIFTBY: - if(np->rval->opcode == MESH || np->rval->opcode == MESH32) - np->optdata = np->lval->optdata >> np->rval->constant; - else np->optdata = (np->width == 16 ? 0xffff : 0xffffffffLU); - /* Just like C_2MINUS, play safe if the RHS isn't a constant */ - break; - - case C_RSHIFT: - np->optdata = (np->lval->optdata & np->rval->optdata) >> 1; - break; - - case GETS: - /* Of course, this doesn't return a value. So this uses the default - code just below it, which is why it doesn't end in break;. This - has its own case so that W276 can be given on an assignment. */ - if(np->lval->optdata == 0xffff && - np->rval->optdata & 0xffff0000lu) optuple->warn276 = 1; - /* no break;! */ - - default: - if(np->opcode == BY && !np->lval->optdata) optuple->warn239 = 1; - np->optdata = (np->width == 16 ? 0xffff : 0xffffffffLU); - /* Some values of opcode are used as placeholders, to save more than 1 - piece of information in a node. The optdata for these is probably - irrelevant, but just in case, we mark all possible bits as active. */ - break; - } -} - -/* This function by AIS. Pass 2 removes redundant logical operations, - mostly explicit and implied C_AND. It destroys information needed by - Pass 1, which is why it's in a separate function. */ -static int optimize_pass2(node *np) -{ - node *op; - int opted = 0; - /* AIS: Paraphrased from code in the old 'optimize' function */ - /* recurse so we simplify each node after all its subnodes */ - if (np == (node *)NULL) - return 0; - else if (np->lval != (node *)NULL) - opted |= optimize_pass2(np->lval); - if (np->rval != (node *)NULL) - opted |= optimize_pass2(np->rval); - /* End of paraphrase */ - - /* Put constants of AND-like opcodes on the right */ - if((np->opcode == C_AND || np->opcode == C_NNAND || - np->opcode == C_LSHIFT || np->opcode == C_LSHIFTIN1 || - np->opcode == C_LSHIFT2 || np->opcode == C_LSHIFT8 || - np->opcode == C_RSHIFT) && - (np->lval->opcode == MESH || np->lval->opcode == MESH32)) - { - OPTING(andlikeconstmove) - op = np->lval; - np->lval = np->rval; - np->rval = op; - } - - /* The implicit &1 in C_AND1ADD1 and C_2SUBAND1 may be removable. */ - if(np->opcode == C_AND1ADD1 && np->rval->optdata == 1) - { - OPTING(impand1a1) - np->opcode = C_1PLUS; - } - if(np->opcode == C_2SUBAND1 && np->rval->optdata == 1) - { - OPTING(impand12m) - np->opcode = C_2MINUS; - } - - if(np->opcode == C_AND && (np->rval->opcode == MESH || - np->rval->opcode == MESH32) && - !(np->lval->optdata & ~np->rval->constant)) - { - OPTING(unneededand) - /* This AND is unnecessary. optdata stays the same. */ - op = np->lval; - free(np->rval); - *np = *op; - free(op); - } - - if((np->opcode == C_NNAND || np->opcode == C_RSHIFT) && - (np->rval->opcode == MESH || np->rval->opcode == MESH32) && - !(np->lval->optdata & ~np->rval->constant)) - { - /* The implicit AND here is unneccesary. Eliminate it. */ - OPTING(unneededimpand) - if(np->opcode == C_RSHIFT) - { - np->rval->constant = 1; - np->rval->optdata = 1; - np->opcode = C_RSHIFTBY; - } - else - { - np->opcode = C_ISNONZERO; - free(np->rval); - np->rval = np->lval; - np->lval = (node*) NULL; - } - } - - if((np->opcode == C_AND || np->opcode == C_NNAND || - np->opcode == C_LSHIFT || np->opcode == C_LSHIFTIN1 || - np->opcode == C_LSHIFT2 || np->opcode == C_LSHIFT8 || - np->opcode == C_RSHIFT) && np->lval->opcode == C_AND && - (np->rval->opcode == MESH || np->rval->opcode == MESH32) && - (np->lval->rval->opcode == MESH || np->lval->rval->opcode == MESH32)) - { - OPTING(combineand) - /* Combine the two ANDs into one. (The AND at np may be implicit.) - Leave opdata the same. */ - np->rval->constant &= np->lval->rval->constant; - op = np->lval; - free(op->rval); - np->lval = op->lval; - free(op); - } - - if((np->opcode == C_AND || np->opcode == C_NNAND || - np->opcode == C_LSHIFT || np->opcode == C_LSHIFTIN1 || - np->opcode == C_LSHIFT2 || np->opcode == C_LSHIFT8 || - np->opcode == C_RSHIFT) && - (np->rval->opcode == MESH || np->rval->opcode == MESH32) && - (~np->lval->optdata & np->rval->constant)) - { - OPTING(weakenand) - /* Reduce the constant in this C_AND-like expression - to aid further optimization */ - np->rval->constant &= np->lval->optdata; - } - return opted; -} - -/* Pass 1. Optimizes idioms. */ -static int optimize_pass1(node *np) /* AIS: was 'optimize'. Recursive calls in - here have been updated. */ -{ - node *mingleop, *op, *op2; - unsigned long temp; - int temp2; - int opted = 0; - - /* recurse so we simplify each node after all its subnodes - AIS: Keep track of whether we've optimized anything. I added - all uses of the variable 'opted', and a return value. */ - if (np == (node *)NULL) - return 0; - else if (np->lval != (node *)NULL) - opted |= optimize_pass1(np->lval); - if (np->rval != (node *)NULL) - opted |= optimize_pass1(np->rval); - - /* - * OK, now do complete folding of constant expressions. - */ - - /* fold MINGLE operations on constants */ - if (np->opcode==MINGLE && (np->lval->opcode==MESH&&np->rval->opcode==MESH)) - { - OPTING(minglefold) - np->opcode = MESH32; - np->constant = mingle(np->lval->constant, np->rval->constant); - free(np->lval); - free(np->rval); - np->lval=(node*)NULL; - np->rval=(node*)NULL; - } - - /* fold SELECT operations on constants */ - if (np->opcode == SELECT - && ((np->lval->opcode==MESH || np->lval->opcode==MESH32) - && (np->rval->opcode==MESH || np->rval->opcode==MESH32))) - { - OPTING(selectfold) - np->opcode = np->rval->opcode; - np->constant = iselect(np->lval->constant, np->rval->constant); - free(np->lval); - free(np->rval); - np->lval=(node*)NULL; - np->rval=(node*)NULL; - } - - /* fold AND operations on 16-bit constants */ - if (np->opcode == AND && np->rval->opcode == MESH) - { - OPTING(and16fold) - np->opcode = MESH; - np->constant = and16(np->rval->constant); - free(np->rval); - np->rval=(node*)NULL; - } - - /* fold AND operations on 32-bit constants */ - if (np->opcode == AND && np->rval->opcode == MESH32) - { - OPTING(and32fold) - np->opcode = MESH32; - np->constant = and32(np->rval->constant); - free(np->rval); - np->rval=(node*)NULL; - } - - /* fold OR operations on 16-bit constants */ - if (np->opcode == OR && np->rval->opcode == MESH) - { - OPTING(or16fold) - np->opcode = MESH; - np->constant = or16(np->rval->constant); - free(np->rval); - np->rval=(node*)NULL; - } - - /* fold OR operations on 32-bit constants */ - if (np->opcode == OR && np->rval->opcode == MESH32) - { - OPTING(or32fold) - np->opcode = MESH32; - np->constant = or32(np->rval->constant); - free(np->rval); - np->rval=(node*)NULL; - } - - /* fold XOR operations on 16-bit constants */ - if (np->opcode == XOR && np->rval->opcode == MESH) - { - OPTING(xor16fold) - np->opcode = MESH; - np->constant = xor16(np->rval->constant); - free(np->rval); - np->rval=(node*)NULL; - } - - /* fold XOR operations on 32-bit constants */ - if (np->opcode == XOR && np->rval->opcode == MESH32) - { - OPTING(xor32fold) - np->opcode = MESH32; - np->constant = xor32(np->rval->constant); - free(np->rval); - np->rval=(node*)NULL; - } - - /* - * Less trivial stuff begins here - */ - - /* following optimizations only work in binary */ - if (Base != 2) - return opted; - - /* recognize the idioms for various C binary logical operations */ - if (np->opcode == SELECT - && np->rval->opcode == MESH32 && np->rval->constant == 0x55555555 - && (op = np->lval) - && (op->opcode == AND || op->opcode == OR || op->opcode == XOR) - && (mingleop = op->rval) && mingleop->opcode == MINGLE - && mingleop->rval->width == 16 - && mingleop->lval->width == 16) - { - OPTING(cbinlogop) - free(np->rval); /* AIS */ - - np->lval = mingleop->lval; - np->rval = mingleop->rval; - - switch(op->opcode) - { - case AND: np->opcode = C_AND; break; - case OR: np->opcode = C_OR; break; - case XOR: np->opcode = C_XOR; break; - default: lose(E778, yylineno, (char *)NULL); - } - - free(mingleop); free(op); - } - - /* AIS: Sometimes C binary logical operations have a smaller rval->constant. */ - if (np->opcode == SELECT - && (np->rval->opcode == MESH32||np->rval->opcode == MESH) - && (op = np->lval) && !(np->rval->constant&0xAAAAAAAALU) - && (op->opcode == AND || op->opcode == OR || op->opcode == XOR) - && (mingleop = op->rval) && mingleop->opcode == MINGLE - && mingleop->rval->width == 16 - && mingleop->lval->width == 16) - { - unsigned long i=iselect(np->rval->constant,0x55555555LU); - if(i==iselect(i,i)) - { - OPTING(smallcbinlogop) - np->lval = mingleop; - - switch(op->opcode) - { - case AND: np->lval->opcode = C_AND; break; - case OR: np->lval->opcode = C_OR; break; - case XOR: np->lval->opcode = C_XOR; break; - default: lose(E778, yylineno, (char *)NULL); - } - np->opcode = C_AND; - np->rval->constant=i; /* np->rval->opcode already correct */ - - free(op); - } - } - - /* recognize idioms for ~ */ - if (np->opcode == C_XOR) - { - /* AIS: Warning! We have to check again for C_XOR, else we will - be making use of the freed np->lval. This is not strictly necessary in - the first case. I added extra conditions to prevent np->lval being - used after deallocation, which is how I discovered the error in the - first place. (Some code elsewhere was messing up, and I suspected - memory allocation problems.) */ - if (np->opcode == C_XOR && np->rval->width == 16 - && np->lval->opcode == MESH &&np->lval->constant == 0xffff) - { - OPTING(cnot1) - np->opcode = C_NOT; - free(np->lval); - np->lval=(node*)NULL; - } - - if (np->opcode == C_XOR && np->lval->width == 16 - && np->rval->opcode == MESH && np->rval->constant == 0xffff) - { - OPTING(cnot2) - np->opcode = C_NOT; - free(np->rval); - np->rval = np->lval; - np->lval=(node*)NULL; - } - - if (np->opcode == C_XOR && np->rval->width == 32 - && np->lval->opcode == MESH32 && np->lval->constant == 0xffffffffLU) - { - OPTING(cnot3) - np->opcode = C_NOT; - free(np->lval); - np->lval=(node*)NULL; - } - - if (np->opcode == C_XOR && np->lval->width == 32 - && np->rval->opcode == MESH32 && np->rval->constant == 0xffffffffLU) - { - OPTING(cnot4) - np->opcode = C_NOT; - free(np->rval); - np->rval = np->lval; - np->lval=(node*)NULL; - } - } - - /* AIS: I wrote everything from here to the end of this function. */ - - /* recognize the idiom x~'pow(2,n)-1' */ - if (np->opcode==SELECT&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& - iselect(np->rval->constant,np->rval->constant)==np->rval->constant) - { - OPTING(pow2m1select) - np->opcode = C_AND; /* This is cheaper than both SELECT and C_NNAND. - lval, rval already correct. */ - } - - /* recognize the idiom x~pow(2,n). */ - if (np->opcode==SELECT&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& - iselect(np->rval->constant,np->rval->constant)==1) /* see, INTERCAL - operators can be - useful in C! */ - { - OPTING(pow2select) - np->opcode = C_NNAND; /* lval, rval already correct. C_NNAND is cheaper - than iselect. */ - if(np->rval->constant==1) np->opcode = C_AND; - } - - /* recognize select-mingle combinations which can be replaced by &, | and - single bitshifts (there are five of these in total) - Most of these idioms are used when doing 32-bit logical operations - separately on odd and even bits. Although these optimizations can speed - up code containing them a bit, their main purpose is to replace the - expressions with a consistent, short form that later optimizations can - recognize. (In fact, some later optimizations are effectively - optimizations on the degenerated C code, not on the INTERCAL original.) */ - if (np->opcode==MINGLE&&np->lval->opcode==SELECT&& - np->lval->rval->opcode==MESH32&&np->lval->rval->constant==0xaaaaaaaa) - { - OPTING(selectmingle1) - np->opcode=C_OR; - np->lval->opcode=C_AND; - op=np->rval; - np->rval=newnode(); - np->rval->opcode=MINGLE; - np->rval->lval=newnode(); - np->rval->lval->opcode=MESH; - np->rval->lval->width=16; - np->rval->lval->constant=0; - np->rval->rval=op; - np->rval->width=32; - optimize_pass1(np->rval); - optimize_pass1(np->lval); - /* replace (a~0xaaaaaaaa)$b with (a&0xaaaaaaaa)|(0$b) - if b is a constant, the recursive call to optimize does - constant folding */ - if(np->opcode==C_OR&&np->lval->opcode==C_AND&& - np->rval->opcode==MESH32&&np->rval->constant==0) - { /* check the conditions again in case it's been optimized */ - /* get rid of the C_OR */ - np->opcode=C_AND; - op=np->lval; - np->lval=op->lval; - np->rval->constant=op->rval->constant; - free(op->rval); - free(op); - optimize_pass1(np->lval); - } - else if(np->opcode==C_OR&&np->lval->opcode==C_AND&& - np->rval->opcode==MESH32&&np->rval->constant==0x55555555) - { /* check the conditions again in case it's been optimized */ - /* get rid of the C_AND */ - op=np->lval; - np->lval=op->lval; - free(op->rval); - free(op); - optimize_pass1(np->lval); - } - } - - if (np->opcode==MINGLE&&np->rval->opcode==SELECT&& - np->rval->rval->opcode==MESH32&&np->rval->rval->constant==0x55555555) - { - OPTING(selectmingle2) - np->opcode=C_OR; - np->rval->opcode=C_AND; - op=np->lval; - np->lval=newnode(); - np->lval->opcode=MINGLE; - np->lval->rval=newnode(); - np->lval->rval->opcode=MESH; - np->lval->rval->width=16; - np->lval->rval->constant=0; - np->lval->lval=op; - np->lval->width=32; - optimize_pass1(np->lval); - optimize_pass1(np->rval); - /* replace b$(a~0x55555555) with (a&0x55555555)|(b$0) - if b is a constant, the recursive call to optimize does - constant folding */ - if(np->opcode==C_OR&&np->rval->opcode==C_AND&& - np->lval->opcode==MESH32&&np->lval->constant==0) - { /* check the conditions again in case it's been optimized */ - /* get rid of the C_OR */ - np->opcode=C_AND; - op=np->rval; - np->rval=op->lval; - np->lval->constant=op->rval->constant; - free(op->rval); - free(op); - optimize_pass1(np->rval); - } - else if(np->opcode==C_OR&&np->rval->opcode==C_AND&& - np->lval->opcode==MESH32&&np->lval->constant==0xaaaaaaaa) - { /* check the conditions again in case it's been optimized */ - /* get rid of the C_AND */ - op=np->rval; - np->rval=op->lval; - free(op->rval); - free(op); - optimize_pass1(np->rval); - } - } - - if (np->opcode==MINGLE&&np->lval->opcode==SELECT&& - np->lval->rval->opcode==MESH32&&np->lval->rval->constant==0x55555555) - { - OPTING(selectmingle3) - np->opcode=C_OR; - np->lval->opcode=C_LSHIFT; /* (a&b)<<1 */ - op=np->rval; - np->rval=newnode(); - np->rval->opcode=MINGLE; - np->rval->lval=newnode(); - np->rval->lval->opcode=MESH; - np->rval->lval->width=16; - np->rval->lval->constant=0; - np->rval->rval=op; - np->rval->width=32; - optimize_pass1(np->rval); - optimize_pass1(np->lval); - /* replace (a~0x55555555)$b with ((a&0x55555555)<<1)|(0$b) - if b is a constant, the recursive call to optimize does - constant folding */ - if(np->opcode==C_OR&&np->lval->opcode==C_LSHIFT&& - np->rval->opcode==MESH32&&np->rval->constant==0) - { /* check the conditions again in case it's been optimized */ - /* get rid of the C_OR */ - np->opcode=C_LSHIFT; - op=np->lval; - np->lval=op->lval; - np->rval->constant=op->rval->constant; - free(op->rval); - free(op); - optimize_pass1(np->lval); /* 32-bit logic recognition */ - } - } - - if (np->opcode==MINGLE&&np->rval->opcode==SELECT&& - np->rval->rval->opcode==MESH32&&np->rval->rval->constant==0xaaaaaaaa) - { - OPTING(selectmingle4) - np->opcode=C_OR; - np->rval->opcode=C_RSHIFT; /* (a&b)>>1 */ - op=np->lval; - np->lval=newnode(); - np->lval->opcode=MINGLE; - np->lval->rval=newnode(); - np->lval->rval->opcode=MESH; - np->lval->rval->width=16; - np->lval->rval->constant=0; - np->lval->lval=op; - np->lval->width=32; - optimize_pass1(np->lval); - optimize_pass1(np->rval); - /* replace b$(a~0xaaaaaaaa) with ((a&0xaaaaaaaa)>>1)|(b$0) - if b is a constant, the recursive call to optimize does - constant folding */ - if(np->opcode==C_OR&&np->rval->opcode==C_RSHIFT&& - np->lval->opcode==MESH32&&np->lval->constant==0) - { /* check for these conditions again in case it's been optimized */ - /* get rid of the C_OR */ - np->opcode=C_RSHIFT; - op=np->rval; - np->rval=op->lval; - np->lval->constant=op->rval->constant; - free(op->rval); - free(op); - optimize_pass1(np->rval); - } - } - - if(np->opcode==MINGLE&&(np->lval->opcode==MESH|| - np->lval->opcode==MESH32)&& - np->lval->constant==0&&np->rval->opcode==C_LSHIFT&& - (np->rval->rval->opcode==MESH||np->rval->rval->opcode==MESH32)&& - np->rval->rval->constant==0x7fff&&np->rval->lval->opcode==SELECT&& - np->rval->lval->rval->opcode==MESH32&&np->rval->lval->rval->constant== - 0x2aaaaaaa) - { - OPTING(selectmingle5) - /* this is equivalent to (np->rval->lval->lval&0x2aaaaaaa)<<1 */ - np->opcode=C_LSHIFT; - np->lval->opcode=MESH32; - np->lval->constant=0x2aaaaaaa; - op=np->rval; - np->rval=op->lval->lval; - free(op->lval->rval); - free(op->lval); - free(op->rval); - free(op); - } - - /* recognize the idiom (x~x)~1 (already optimized to (x~x)&1). */ - - if (np->opcode==C_AND&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& - np->rval->constant==1&&np->lval->opcode==SELECT&& - nodessame(np->lval->lval,np->lval->rval)) -/* (np->lval->lval->opcode==ONESPOT||np->lval->lval->opcode==TWOSPOT)&& - np->lval->lval->opcode==np->lval->rval->opcode&& - np->lval->lval->constant==np->lval->rval->constant)*/ - { - OPTING(xselxsel1) - free(np->rval); - np->rval=np->lval->rval; - nodefree(np->lval->lval); - free(np->lval); - np->lval=(node*) NULL; - np->opcode = C_ISNONZERO; - } - - /* recognize the idiom (x~y)~1 (already optimized to (x~y)&1) in other cases. - if (np->opcode==C_AND&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& - np->rval->constant==1&&np->lval->opcode==SELECT) - { - OPTING(xselysel1) - np->opcode = C_NNAND; - free(np->rval); - np->rval = np->lval->rval; - op = np->lval; - np->lval = np->lval->lval; - free(op); - } - This idiom is commented out because I thought it simplified to !!(x & y), - and of course it doesn't. The next two idioms are (hopefully correct) - idioms that were inspired by this idea. - */ - - /* recognize the idiom (x ~ k) ~ 1 (ie (x ~ k) & 1) for constant k */ - if(np->opcode==C_AND&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& - np->rval->constant==1&&np->lval->opcode==SELECT&& - (np->lval->rval->opcode==MESH||np->lval->rval->opcode==MESH32)) - { - OPTING(xselksel1) - np->opcode = C_NNAND; - free(np->rval); - np->rval = np->lval->rval; - op = np->lval; - np->lval = np->lval->lval; - free(op); - temp = 1; - if(np->rval->constant == 0) temp = 0; else - while(!(np->rval->constant % 2)) - { - np->rval->constant /= 2; - temp *= 2; - } - np->rval->constant = temp; - /* So (x ~ k) ~ 1 optimizes to !!(x & n) where n is the lowest set - bit in k. */ - } - - /* recognize the idiom (k ~ x) ~ 1 (ie (k ~ x) & 1) where k is a power - of 2 minus 1 */ - if (np->opcode==C_AND&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& - np->rval->constant==1&&np->lval->opcode==SELECT&& - (np->lval->lval->opcode==MESH||np->lval->lval->opcode==MESH32)&& - iselect(np->lval->lval->constant,np->lval->lval->constant)== - np->lval->lval->constant) - { - OPTING(p2m1selxsel1) - np->opcode = C_NNAND; - free(np->rval); - np->rval = np->lval->rval; - op = np->lval; - np->lval = np->lval->lval; - free(op); - } - - /* recognize idioms for left-shift and right-shift */ - /* 16- or 32-bit right-shift by 1, not necessarily all the bits */ - if(np->opcode==SELECT&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& - iselect(np->rval->constant,np->rval->constant)<<1==np->rval->constant) - { - OPTING(rshift1) - np->opcode = C_RSHIFT; /* Keep rval as it tells us what to & with */ - } - - /* 16- or 32-bit right-shift by a higher number */ - if(np->opcode==SELECT&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& - iselect(xor32(np->rval->constant),xor32(np->rval->constant))==3&& - !(np->rval->constant&1)) - { - OPTING(rshiftby) - np->opcode = C_RSHIFTBY; - temp2 = 0; - temp = np->rval->constant; - while(!(np->rval->constant&1)) - { - np->rval->constant>>=1; - temp2++; - } - np->rval->constant = temp2; - op = np->lval; - np->lval = newnode(); - np->lval->width = np->width; - np->lval->rval = newnode(); - np->lval->opcode = C_AND; - np->lval->rval->opcode = np->rval->opcode; - np->rval->opcode = MESH; - np->lval->rval->width = np->rval->width; - np->rval->width = 16; - np->lval->rval->constant = temp; - np->lval->lval = op; - optimize_pass1(np->lval); /* not sure what good this will do, but it's good practice - to optimize newly created nodes, in case someone invents - a new optimization (this caught me out elsewhere) */ - /* The joke with this optimization is that it comes out with more nodes than - when it started. However, under most implementations of C, & and >> are - significantly cheaper than iselect. */ - } - - /* 16-bit left-shift by 1 */ - if(np->opcode==SELECT&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& - np->lval->opcode==MINGLE&&(np->rval->constant & 0x55555555LU)==1&& - (np->lval->rval->opcode==MESH||np->lval->rval->opcode==MESH32)&& - (np->lval->rval->constant==0||np->lval->rval->constant==1)) - { - unsigned long i=iselect(np->rval->constant, 0xaaaaaaaaLU); - if(i==iselect(i,i)) - { - OPTING(lshift16by1) - np->opcode = np->lval->rval->constant?C_LSHIFTIN1:C_LSHIFT; - /* We can shift either a 1 or a 0 into the right end of the number. */ - np->rval->constant=i; /* New effect of this node: (lval->lval & i)<<1 */ - /* We know that np->rval has the right opcode. */ - op=np->lval->lval; - free(np->lval); - np->lval=op; - } - } - - /* 32-bit left-shift of a variable by 1 */ - if(np->opcode==C_OR&&np->lval->opcode==C_LSHIFT&& - np->rval->opcode==C_LSHIFT) - do - { /* this is so we can break; out of the if */ - temp=0; - if(np->lval->lval->opcode==MESH32&& - np->lval->lval->constant==0x55555555) temp++; - if(np->lval->rval->opcode==MESH32&& - np->lval->rval->constant==0x55555555) temp++; - if(np->rval->lval->opcode==MESH32&& - np->rval->lval->constant==0x55555555) temp++; - if(np->rval->rval->opcode==MESH32&& - np->rval->rval->constant==0x55555555) temp++; - if(temp!=1) break; - temp=0; - if(np->lval->lval->opcode==MESH32&& - np->lval->lval->constant==0x2aaaaaaa) temp++; - if(np->lval->rval->opcode==MESH32&& - np->lval->rval->constant==0x2aaaaaaa) temp++; - if(np->rval->lval->opcode==MESH32&& - np->rval->lval->constant==0x2aaaaaaa) temp++; - if(np->rval->rval->opcode==MESH32&& - np->rval->rval->constant==0x2aaaaaaa) temp++; - if(temp!=1) break; - /* found the two required constants. Now we need two - identical TWOSPOTs on opposite sides of the C_OR. */ - temp=0xffffffff; /* who'd use that many variables? */ - if(np->lval->lval->opcode==TWOSPOT&& - np->rval->lval->opcode==TWOSPOT&& - np->lval->lval->constant== - np->rval->lval->constant) temp=np->lval->lval->constant; - if(np->lval->lval->opcode==TWOSPOT&& - np->rval->rval->opcode==TWOSPOT&& - np->lval->lval->constant== - np->rval->rval->constant) temp=np->lval->lval->constant; - if(np->lval->rval->opcode==TWOSPOT&& - np->rval->lval->opcode==TWOSPOT&& - np->lval->rval->constant== - np->rval->lval->constant) temp=np->lval->rval->constant; - if(np->lval->rval->opcode==TWOSPOT&& - np->rval->rval->opcode==TWOSPOT&& - np->lval->rval->constant== - np->rval->rval->constant) temp=np->lval->rval->constant; - if(temp==0xfffffffff) break; - /* recognized a 32-bit leftshift */ - OPTING(lshift32by1) - free(np->lval->lval); - free(np->lval->rval); - free(np->rval->lval); - free(np->rval->rval); - np->lval->opcode=TWOSPOT; - np->lval->constant=temp; - np->rval->opcode=MESH32; - np->rval->constant=0x7fffffff; - np->lval->lval=(node*)NULL; - np->lval->rval=(node*)NULL; - np->rval->lval=(node*)NULL; - np->rval->rval=(node*)NULL; - np->opcode=C_LSHIFT; - } while(0); - - /* 16-bit left-shift by 2 */ - if(np->opcode==C_LSHIFT&&np->lval->opcode==C_LSHIFT&& - np->rval->constant==np->lval->rval->constant) - { - OPTING(lshift16by2) - op=np->lval->lval; - np->opcode=C_LSHIFT2; - free(np->lval); - np->lval=op; - np->rval->constant>>=1; - } - - /* An idiom for 16-bit left-shift by 8 is caught later. */ - - /* recognize the idiom '?x$#y'~#3, where y is 1 or 2 - The ~ is already optimized to &. */ - if(np->opcode==C_AND&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& - np->rval->constant==3&&np->lval->opcode==XOR&& - np->lval->rval->opcode==MINGLE&&(mingleop=np->lval->rval)&& - (mingleop->rval->opcode==MESH||mingleop->rval->opcode==MESH32)&& - (mingleop->rval->constant==1||mingleop->rval->constant==2)) - { - OPTING(xorto1or2) - /* This depends only on the rightmost bit of x, and y. - For y=1: - If 0, answer = 0x1 - If 1, answer = 0x2 - For y=2: - If 0, answer = 0x2 - Id 1, answer = 0x1 - */ - np->opcode = mingleop->rval->constant==1?C_AND1ADD1:C_2SUBAND1; - free(np->rval); - np->rval=mingleop->lval; - free(mingleop->rval); - free(mingleop); - free(np->lval); - free(mingleop->rval); - np->lval=(node*)NULL; - - /* np->rval could be an iselect of a variable with itself, - and not have been caught yet (because the &1 was implied, - not explicit). Catch this now. */ - if(np->rval->opcode==SELECT&& - (np->rval->lval->opcode==ONESPOT||np->rval->lval->opcode==TWOSPOT)&& - np->rval->lval->opcode==np->rval->rval->opcode&& - np->rval->lval->constant==np->rval->rval->constant) - { - np->rval->opcode=C_ISNONZERO; - free(np->rval->lval); - np->rval->lval=(node*)NULL; - } - - /* Even if that didn't work, iselect can still be replaced by nnand - (because we have an implicit (x~y)&1) */ - if(np->rval->opcode==SELECT) np->rval->opcode=C_NNAND; - - /* If we know np->rval must be 0 or 1 at runtime, we can optimize further - (to avoid (1&x)&1, (x&1)&1 or (!!x)&1) */ - if(np->rval->opcode==C_NNAND||np->rval->opcode==C_ISNONZERO|| - (np->rval->opcode==C_AND&& - (np->rval->lval->opcode==MESH||np->rval->lval->opcode==MESH32) - &&np->rval->lval->constant==1) - ||(np->rval->opcode==C_AND&& - (np->rval->rval->opcode==MESH||np->rval->rval->opcode==MESH32) - &&np->rval->rval->constant==1) - ) - { - np->opcode=np->opcode==C_AND1ADD1?C_1PLUS:C_2MINUS; - } - } - - /* optimize a select with 0xffffffff (already optimized to &) */ - if(np->opcode==C_AND&&np->rval->opcode==MESH32&& - np->rval->constant==0xffffffff) - { - OPTING(noopand1r) - free(np->rval); - op=np->lval; - *np=*op; /* copy the whole node */ - np->width=32; - free(op); - } - if(np->opcode==C_AND&&np->lval->opcode==MESH32&& - np->lval->constant==0xffffffff) - { - OPTING(noopand1l) - free(np->lval); - op=np->rval; - *np=*op; /* copy the whole node */ - np->width=32; - free(op); - } - - /* optimize complementing the odd or even bits of a 32-bit number */ - /* complement odd bits, zero even bits */ - if(np->opcode==C_LSHIFT&&np->rval->opcode==MESH32&& - np->rval->constant==0x55555555&&np->lval->opcode==XOR&& - np->lval->width==32&&np->lval->rval->opcode==C_OR&& - ((np->lval->rval->rval->opcode==MESH32&&np->lval->rval->rval-> - constant==0x55555555&&((temp2 = 0),1))|| - (np->lval->rval->lval->opcode==MESH32&&np->lval->rval->lval-> - constant==0x55555555&&(temp2 = 1)))) - { - OPTING(com1z0l) - /* optimizations so far have given us code which sets all even - bits of a 32-bit expression, xor32s it, selects the even bits - and left-shifts. This is equivalent to complementing all odd - bits of the number and zeroing the even bits. */ - np->rval->constant = 0xaaaaaaaa; - np->lval->rval->opcode = C_AND; - op = temp2 ? np->lval->rval->lval : np->lval->rval->rval; - op->constant = 0xaaaaaaaa; - op = np->lval->rval; - free(np->lval); - np->lval = op; - np->opcode = C_XOR; - } - - /* same optimization with np's operands exchanged */ - if(np->opcode==C_LSHIFT&&np->lval->opcode==MESH32&& - np->lval->constant==0x55555555&&np->rval->opcode==XOR&& - np->rval->width==32&&np->rval->rval->opcode==C_OR&& - ((np->rval->rval->rval->opcode==MESH32&&np->rval->rval->rval-> - constant==0x55555555&&((temp2 = 0),1))|| - (np->rval->rval->lval->opcode==MESH32&&np->rval->rval->lval-> - constant==0x55555555&&(temp2 = 1)))) - { - OPTING(com1z0r) - /* optimizations so far have given us code which sets all even - bits of a 32-bit expression, xor32s it, selects the even bits - and left-shifts. This is equivalent to complementing all odd - bits of the number and zeroing the even bits. */ - np->lval->constant = 0xaaaaaaaa; - np->rval->rval->opcode = C_AND; - op = temp2 ? np->rval->rval->lval : np->rval->rval->rval; - op->constant = 0xaaaaaaaa; - op = np->rval->rval; - free(np->rval); - np->rval = op; - np->opcode = C_XOR; - } - - /* complement even bits, zero odd bits */ - if(np->opcode==C_AND&&np->rval->opcode==MESH32&& - np->rval->constant==0x55555555&&np->lval->opcode==XOR&& - np->lval->width==32&&np->lval->rval->opcode==C_OR&& - np->lval->rval->rval->opcode==MESH32&& - np->lval->rval->rval->constant==0x55555555&& - np->lval->rval->lval->opcode==C_LSHIFT&& - np->lval->rval->lval->rval->opcode==MESH32&& - np->lval->rval->lval->rval->constant==0x55555555) - { - OPTING(com0z1) - /* There are another 7 ways this expression could be written. - However, this is the only way likely to be generated by - the rest of the optimizer. */ - op=np->lval->rval->lval->lval; - free(np->lval->rval->lval->rval); - free(np->lval->rval->lval); - free(np->lval->rval->rval); - np->lval->opcode = C_AND; - np->opcode = C_XOR; - np->lval->lval = op; - np->lval->rval->opcode = MESH32; - np->lval->rval->lval = (node*) NULL; - np->lval->rval->rval = (node*) NULL; - np->lval->rval->constant = 0x55555555; - /* and np->rval is already correct! */ - } - - /* optimize no-op C_OR, C_AND, C_XOR - (some of these are produced as a result of earlier optimizations). - This sort of thing was also used in the days of INTERCAL-72 to - convert information to 16- or 32-bit representations. As C-INTERCAL - is almost untyped and the typechecker has already run, this can be - done safely. One of these cases has already been considered earlier - (the one generated by the code (something)~'#65535$#65535'), but it - is included it again to complete the list. */ - /* (something op constant) */ - if(np->opcode==C_OR&&(np->lval->opcode==MESH||np->lval->opcode==MESH32) - &&np->lval->constant==0) - { - OPTING(nooporl) - free(np->lval); - op=np->rval; - *np=*op; - free(op); - } - if(np->opcode==C_XOR&&(np->lval->opcode==MESH||np->lval->opcode==MESH32) - &&np->lval->constant==0) - { - OPTING(noopxorl) - free(np->lval); - op=np->rval; - *np=*op; - free(op); - } - if(np->opcode==C_AND&&(np->lval->opcode==MESH||np->lval->opcode==MESH32) - &&np->lval->constant==0xffffffff) - { - OPTING(noopandl) - free(np->lval); - op=np->rval; - *np=*op; - free(op); - } - if(np->opcode==C_OR&&(np->rval->opcode==MESH||np->rval->opcode==MESH32) - &&np->rval->constant==0) - { - OPTING(nooporr) - free(np->rval); - op=np->lval; - *np=*op; - free(op); - } - if(np->opcode==C_XOR&&(np->rval->opcode==MESH||np->rval->opcode==MESH32) - &&np->rval->constant==0) - { - OPTING(noopxorr) - free(np->rval); - op=np->lval; - *np=*op; - free(op); - } - if(np->opcode==C_AND&&(np->rval->opcode==MESH||np->rval->opcode==MESH32) - &&np->rval->constant==0xffffffff) - { - OPTING(noopandr) - free(np->rval); - op=np->lval; - *np=*op; - free(op); - } - /* something op itself */ - if((np->opcode==C_AND||np->opcode==C_OR)&&nodessame(np->lval,np->rval)) - { - OPTING(andoritself) - nodefree(np->rval); - op=np->lval; - *np=*op; - free(op); - } - if(np->opcode==C_XOR&&nodessame(np->lval,np->rval)) - { - OPTING(xoritself) - nodefree(np->lval); - nodefree(np->rval); - np->opcode = (np->width==16?MESH:MESH32); - np->lval = (node*) NULL; - np->rval = (node*) NULL; - np->constant = 0; - } - /* repetitive implicit C_AND */ - if(np->opcode==C_NNAND&&nodessame(np->lval,np->rval)) - { - OPTING(reptimpand) - nodefree(np->lval); - np->lval = (node*) NULL; - np->opcode = C_ISNONZERO; - } - - /* optimize 32-bit complement */ - if(np->opcode==C_OR&&np->lval->opcode==C_XOR&&np->lval->lval->opcode==C_AND&& - np->rval->opcode==C_XOR&&np->rval->lval->opcode==C_AND&& - np->lval->rval->opcode==MESH32&&np->lval->lval->rval->opcode==MESH32&& - np->rval->rval->opcode==MESH32&&np->rval->lval->rval->opcode==MESH32&& - np->lval->rval->constant==np->lval->lval->rval->constant&& - np->rval->rval->constant==np->rval->lval->rval->constant&& - (np->lval->rval->constant^np->rval->rval->constant)==0xffffffff&& - nodessame(np->lval->lval->lval,np->rval->lval->lval)) - { - OPTING(com32) - np->opcode = C_NOT; - np->width = 32; - free(np->rval->lval->lval); - free(np->rval->lval->rval); - free(np->rval->lval); - free(np->rval->rval); - free(np->rval); - op = np->lval->lval->lval; - free(np->lval->lval->rval); - free(np->lval->lval); - free(np->lval->rval); - free(np->lval); - np->rval = op; - np->lval = (node*)NULL; - } - - /* If constant is on the left, move it to the right. This will - simplify checking for the remaining optimizations, while not - altering the effect of code that cannot be optimized further. - (There are furious debates within the C community as to - whether a constant should be written on the left or right of - an operation. The argument in favour of 'constant on the left' - is mainly that it's better at detecting a mistype of = for ==. - This code assumes that ick won't make that mistake.) */ - if(np->opcode==C_LSHIFT||np->opcode==C_AND||np->opcode==C_OR|| - np->opcode==C_XOR||np->opcode==C_NNAND||np->opcode==C_RSHIFT) - { /* all the above opcodes are symmetrical wrt their operands */ - if(np->lval->opcode==MESH||np->lval->opcode==MESH32) - { - OPTING(constswitch) - op = np->lval; - np->lval = np->rval; - np->rval = op; - } - } - - /* 32-bit logical operations on alternate bits. - At this point, they have been optimized - to an expression of the form op32(oddbits | evenbits)&0x55555555, - which is good but still uses the INTERCAL operator op32. We should - be able to optimize this using & | ^ and bitshifts. */ - if((np->opcode==C_AND||np->opcode==C_LSHIFT)&&np->rval->opcode==MESH32&& - np->rval->constant==0x55555555&&np->lval->width==32&& - (np->lval->opcode==XOR||np->lval->opcode==OR|| - np->lval->opcode==AND)&&np->lval->rval->opcode==C_OR) - do /* so we can break; out */ - { - /* Check to see if the op32 is a C_OR of an oddbits and an - evenbits */ - op=np->lval->rval; - temp2=0; /* |=1 for oddbits found, |=2 for evenbits found */ - if(op->lval->opcode==C_AND&&op->lval->rval->opcode==MESH32&& - op->lval->rval->constant==0x55555555) temp2|=2; - if(op->lval->opcode==C_AND&&op->lval->rval->opcode==MESH32&& - op->lval->rval->constant==0xaaaaaaaa) temp2|=1; - if(op->rval->opcode==C_AND&&op->rval->rval->opcode==MESH32&& - op->rval->rval->constant==0x55555555) temp2|=2; - if(op->rval->opcode==C_AND&&op->rval->rval->opcode==MESH32&& - op->rval->rval->constant==0xaaaaaaaa) temp2|=1; - if(op->lval->opcode==C_LSHIFT&&op->lval->rval->opcode==MESH32&& - op->lval->rval->constant==0x55555555) temp2|=1; - if(op->lval->opcode==C_RSHIFT&&op->lval->rval->opcode==MESH32&& - op->lval->rval->constant==0xaaaaaaaa) temp2|=2; - if(op->rval->opcode==C_LSHIFT&&op->rval->rval->opcode==MESH32&& - op->rval->rval->constant==0x55555555) temp2|=1; - if(op->rval->opcode==C_RSHIFT&&op->rval->rval->opcode==MESH32&& - op->rval->rval->constant==0xaaaaaaaa) temp2|=2; - if(temp2!=3) break; - /* this expression can be optimized */ - OPTING(shiftand) - if(np->lval->opcode==XOR) op->opcode=C_XOR; - if(np->lval->opcode==OR) op->opcode=C_OR; - if(np->lval->opcode==AND) op->opcode=C_AND; - if(np->opcode==C_LSHIFT) - { - /* odd-bit-ize the evenbits we found */ - if(op->lval->rval->constant==0x55555555) op->lval->opcode=C_LSHIFT; - if(op->rval->rval->constant==0x55555555) op->rval->opcode=C_LSHIFT; - if(op->lval->rval->constant==0xaaaaaaaa) op->lval->opcode=C_AND; - if(op->rval->rval->constant==0xaaaaaaaa) op->rval->opcode=C_AND; - } else { - /* even-bit-ize the oddbits we found */ - if(op->lval->rval->constant==0x55555555) op->lval->opcode=C_AND; - if(op->rval->rval->constant==0x55555555) op->rval->opcode=C_AND; - if(op->lval->rval->constant==0xaaaaaaaa) op->lval->opcode=C_RSHIFT; - if(op->rval->rval->constant==0xaaaaaaaa) op->rval->opcode=C_RSHIFT; - } - /* What np should be is now in op */ - free(np->lval); - free(np->rval); - *np=*op; - } while(0); - - /* Optimize 32-bit logical expressions on the whole number. - At this point, the most common idiom for a 32-bit logical operation - (we write it here as %) looks like this: - ((a&0xaaaaaaaa)%(b&0xaaaaaaaa))|((a&0x55555555)%(b&0x55555555)) - So first, we use distributive laws to simplify such constructions - further. - - The distribution is done at a lower level of the expression tree, - but this is where it is done in the sequence of optimizations needed - to optimize a 32-bit expression. These optimizations are unlikely to - help in 16-bit code, because it's unlikely a programmer would take the - effort to code an expression like the ones below unless he/she had to. - - Expressions that distribute: - (a&k)&(b&k) == (a&b)&k - (a|k)&(b|k) == (a&b)|k - (a&k)|(b&k) == (a|b)&k - (a|k)|(b|k) == (a|b)|k - (a&k)^(b&k) == (a^b)&k */ - if((np->opcode==C_AND||np->opcode==C_OR||np->opcode==C_XOR)&& - (np->lval->opcode==C_AND||np->lval->opcode==C_OR)&& - !(np->lval->opcode==C_OR&&np->opcode==C_XOR)&& - np->lval->opcode==np->rval->opcode) - { - if(nodessame(np->lval->lval,np->rval->lval)) - { - OPTING(distribll) - nodefree(np->lval->lval); - np->lval->lval = np->rval->rval; - np->lval->opcode = np->opcode; - np->opcode = np->rval->opcode; - op = np->rval; - np->rval = np->rval->lval; - free(op); - } - else if(nodessame(np->lval->rval,np->rval->lval)) - { - OPTING(distribrl) - nodefree(np->lval->rval); - np->lval->rval = np->rval->rval; - np->lval->opcode = np->opcode; - np->opcode = np->rval->opcode; - op = np->rval; - np->rval = np->rval->lval; - free(op); - } - else if(nodessame(np->lval->lval,np->rval->rval)) - { - OPTING(distriblr) - nodefree(np->lval->lval); - np->lval->lval = np->rval->lval; - np->lval->opcode = np->opcode; - np->opcode = np->rval->opcode; - op = np->rval; - np->rval = np->rval->rval; - free(op); - } - else if(nodessame(np->lval->rval,np->rval->rval)) - { - OPTING(distribrr) - nodefree(np->lval->rval); - np->lval->rval = np->rval->lval; - np->lval->opcode = np->opcode; - np->opcode = np->rval->opcode; - op = np->rval; - np->rval = np->rval->rval; - free(op); - } - } - - /* At this point, the 32-bit logical expression looks like this: - (with % substituting for &,|, or ^) - (0xaaaaaaaa|0x55555555)&(a%b) - Clearly, what is needed is a bit of constant folding on C_OR. We - might as well do C_AND and C_XOR while we're at it. This will get - done during the second run of optimize_pass1. */ - if((np->opcode==C_AND||np->opcode==C_OR||np->opcode==C_XOR)&& - (np->lval->opcode==MESH||np->lval->opcode==MESH32)&& - (np->rval->opcode==MESH||np->rval->opcode==MESH32)) - { - OPTING(clogopfold) - switch(np->opcode) - { - case C_AND: np->constant = np->lval->constant & np->rval->constant; break; - case C_OR: np->constant = np->lval->constant | np->rval->constant; break; - case C_XOR: np->constant = np->lval->constant ^ np->rval->constant; break; - default: lose(E778, yylineno, (char*) NULL); - } - free(np->lval); - np->lval = (node*) NULL; - free(np->rval); - np->rval = (node*) NULL; - np->opcode = np->width == 16 ? MESH : MESH32; - } - - /* Somewhat incomprehensibly, there is a 32-bit right-shift in the - standard library that has been done using separation into even - and odd bits! This code recognizes that idiom, even though - surely it would have been simpler to select against - 0xfffffffe? (This would have been optimized much earlier in this - function, and would also be shorter and clearer. Perhaps the - obfuscation is the reason that it was written in separate bits.) */ - - /* Selecting something with 0x55555554, then mingling with 0, - right-shifts the even bits onto the odd bits. */ - if(np->opcode==MINGLE&&np->lval->opcode==SELECT&& - (np->rval->opcode==MESH||np->rval->opcode==MESH32)&& - np->rval->constant==0&&np->lval->rval->opcode==MESH32&& - np->lval->rval->constant==0x55555554) - { - OPTING(selminglershift) - np->opcode = C_RSHIFT; - np->rval->opcode = MESH32; - np->rval->width = 32; - np->rval->constant = 0x55555554; - free(np->lval->rval); - op = np->lval->lval; - free(np->lval); - np->lval = op; - } - - /* Since it's such a stupid idiom anyway, we'll just optimize it the - way round that the standard library has it. It looks like this: - (((a&0x55555554)>>1)|((a&0xaaaaaaaa)>>1)) */ - if(np->opcode==C_OR&&np->lval->opcode==C_RSHIFT&& - np->rval->opcode==C_RSHIFT&&np->lval->rval->opcode==MESH32&& - np->lval->rval->constant==0x55555554&& - np->rval->rval->opcode==MESH32&&np->rval->rval->constant== - 0xaaaaaaaa&&np->lval->lval->opcode==TWOSPOT&& - np->rval->lval->opcode==TWOSPOT&&np->lval->lval->constant== - np->rval->lval->constant) - { - OPTING(sillysyslibidiom) - op = np->lval; - free(np->rval->lval); - free(np->rval->rval); - free(np->rval); - op->rval->constant = 0xfffffffe; - *np = *op; - free(op); - optuple->warn128 = 1; - } - - /* A more useful idiom in the standard library is on the - internal subroutine labelled (1525). It's an 8-bit - left-shift. In INTERCAL, this is done with repeated - mingling and selection. So far, the optimiser can only - recognize two leftshifts in the inside, because the rest - of the expression is written assuming that the low-bits - of the result are unset (which is correct after a two-bit - left-shift). This code recognizes the entire idiom straight - off, rather than optimizing in stages, after the optimization - of the inside to a double-leftshift. */ - if(np->opcode==SELECT&&np->rval->opcode==MESH32&& - np->rval->constant==0xaaaaff&&np->lval->opcode==MINGLE&& - (np->lval->rval->opcode==MESH||np->lval->rval->opcode==MESH32)&& - np->lval->rval->constant==0&&np->lval->lval->opcode==SELECT&& - np->lval->lval->rval->opcode==MESH32&& - np->lval->lval->rval->constant==0xaaaaaaf&& - np->lval->lval->lval->opcode==MINGLE&&( - np->lval->lval->lval->rval->opcode==MESH|| - np->lval->lval->lval->rval->opcode==MESH32)&& - np->lval->lval->lval->rval->constant==0&& - np->lval->lval->lval->lval->opcode==C_LSHIFT2&&( - np->lval->lval->lval->lval->rval->opcode==MESH|| - np->lval->lval->lval->lval->rval->opcode==MESH32)&& - np->lval->lval->lval->lval->rval->constant==0x3fff) - { - OPTING(lshift8) - /* left-shift np->lval->lval->lval->lval->lval by 8 */ - op = np->lval->lval->lval->lval->lval; - free(np->lval->lval->lval->lval->rval); - free(np->lval->lval->lval->lval); - free(np->lval->lval->lval->rval); - free(np->lval->lval->lval); - free(np->lval->lval->rval); - free(np->lval->lval); - free(np->lval->rval); - free(np->lval); - np->lval = op; - np->opcode = C_LSHIFT8; - np->rval->constant = 0x00ffffff; - } - - /* recognize an idiom for ==, != */ - if(np->opcode == C_ISNONZERO && np->rval->opcode == C_XOR) - { - OPTING(xortoequal) - np->opcode = C_NOTEQUAL; - op = np->rval; - np->lval = op->lval; - np->rval = op->rval; - free(op); - /* So !!(a ^ b), as in 1 + !!(a^b), has become (a!=b). */ - } - - /* Some of the remaining idioms depend on active-bit analysis */ - checknodeactbits(np); - /* C binary logical operations can be done in 'expanded' form, that is, on - just oddbits or evenbits of a 32-bit number. */ - if((np->opcode==C_AND || np->opcode==C_LSHIFT || np->opcode == C_LSHIFT2 || - np->opcode==C_LSHIFT8 || np->opcode==C_LSHIFTIN1 || np->opcode==C_NNAND) - && (np->rval->opcode==MESH32 || np->rval->opcode==MESH) - && !(np->rval->constant & 0xaaaaaaaaLU)) - { - unsigned long i=iselect(np->rval->constant, 0x55555555LU); - if(i==iselect(i,i) && (np->lval->opcode == OR || - np->lval->opcode == AND || - np->lval->opcode == XOR) && - np->lval->rval->opcode==C_OR) - { - if(!(np->lval->rval->lval->optdata & 0x55555555LU) && - !(np->lval->rval->rval->optdata & 0xaaaaaaaaLU) && - (np->lval->rval->lval->opcode == C_AND || - np->lval->rval->lval->opcode == C_LSHIFT || - np->lval->rval->lval->opcode == MESH || - np->lval->rval->lval->opcode == MESH32)) - { /* recognized the idiom. Swap the C_OR round so we don't have to write - the code for this out twice. */ - OPTING(clogopexpswitch) - op=np->lval->rval->rval; - np->lval->rval->rval=np->lval->rval->lval; - np->lval->rval->lval=op; - } - if(!(np->lval->rval->lval->optdata & 0xaaaaaaaaLU) && - !(np->lval->rval->rval->optdata & 0x55555555LU) && - (np->lval->rval->rval->opcode == C_AND || - np->lval->rval->rval->opcode == C_LSHIFT || - np->lval->rval->lval->opcode == MESH || - np->lval->rval->lval->opcode == MESH32)) - { - OPTING(clogopexpand) - op = np->lval->rval; - switch(np->lval->opcode) - { - case AND: op->opcode = C_AND; break; - case OR: op->opcode = C_OR; break; - case XOR: op->opcode = C_XOR; break; - default: lose(E778, yylineno, (char*) NULL); - } - free(np->lval); - np->lval = op; - if(np->lval->rval->opcode == MESH || np->lval->rval->opcode == MESH32) - np->lval->rval->constant >>= 1; - else np->lval->rval->opcode = np->lval->rval->opcode == C_AND ? - C_RSHIFT : C_AND; - if(np->opcode == C_LSHIFT&&(np->lval->lval->opcode == C_AND || - np->lval->lval->opcode == C_RSHIFT || - np->lval->lval->opcode == MESH || - np->lval->lval->opcode == MESH32)) - { - /* Instead of doing the calculation on the evenbits, do it on the - oddbits; that'll save a bitshift (possibly even save two - bitshifts). */ - np->opcode = C_AND; - if(np->lval->lval->opcode == MESH || - np->lval->lval->opcode == MESH32) np->lval->lval->constant <<= 1; - else np->lval->lval->opcode = np->lval->lval->opcode == C_AND ? - C_LSHIFT : C_AND; - if(np->lval->rval->opcode == MESH || - np->lval->rval->opcode == MESH32) np->lval->rval->constant <<= 1; - else np->lval->rval->opcode = np->lval->rval->opcode == C_AND ? - C_LSHIFT : C_AND; - np->rval->constant <<= 1; - } - checknodeactbits(np); /* To calculate an improved active-bits value */ - } - } - } - - /* One common situation in which the previous idiom is used is a 32-bit - logic operation with a constant. The distributive law will not catch - such cases because even bits of the constant are used on one side and - odd bits of the constant are used on the other side, making the - expressions different. In syslib, the idiom is only used with the - constant equal to 0x80000000, leading to another problem; the logic - operation may not have been written at all on one side of the - expression, due to one parity set of bits having no effect. The - following code catches three cases involving 32-bit logical operations - with constants. Of course, some loony could theoretically write the - 16-bit version like this... */ - if(np->opcode==C_OR&&(np->lval->opcode==C_AND||np->lval->opcode==C_XOR|| - np->lval->opcode==C_OR||np->lval->opcode==C_LSHIFT|| - np->lval->opcode==C_RSHIFT)&& - (np->rval->opcode==C_AND||np->rval->opcode==C_XOR|| - np->rval->opcode==C_OR||np->rval->opcode==C_LSHIFT|| - np->rval->opcode==C_RSHIFT)&& - !(np->lval->optdata&np->rval->optdata)) - { - op = np->lval; - op2 = np->rval; - /* rely on the 'constant on the right' optimization */ - if(op->opcode!=C_LSHIFT&&op->opcode!=C_RSHIFT) - if(op->lval->opcode==C_AND || op->lval->opcode==C_LSHIFT) - if(op->rval->opcode==MESH || op->rval->opcode==MESH32) op=op->lval; - if(op2->opcode!=C_LSHIFT&&op2->opcode!=C_RSHIFT) - if(op2->lval->opcode==C_AND || op2->lval->opcode==C_LSHIFT) - if(op2->rval->opcode==MESH || op2->rval->opcode==MESH32) op2=op2->lval; - if(nodessame(op->lval,op2->lval) && - (op->rval->opcode==MESH||op->rval->opcode==MESH32) && - (op2->rval->opcode==MESH||op2->rval->opcode==MESH32) && - !(op->rval->constant&op2->rval->constant) && - (op->opcode==op2->opcode) && - (op->opcode==C_AND||op->opcode==C_LSHIFT||op->opcode==C_RSHIFT)&& - (op2->opcode==C_AND||op2->opcode==C_LSHIFT||op2->opcode==C_RSHIFT)) - { - /* Now op and op2 are & or implied & (only <<, >>, & are at all likely - to be here), and have the same lval. The only check left is that - this does actually correspond to (something32 op constant), in - other words that there is exactly one possibility for op. */ - if((np->lval==op||np->rval==op2||np->lval->opcode==np->rval->opcode) - &&(np->lval!=op||np->rval!=op2)) - { - OPTING(clogopwithconst) - if(np->lval!=op) temp2=np->lval->opcode; - if(np->rval!=op2) temp2=np->rval->opcode; - if(np->lval==op) temp=np->rval->rval->constant; - else if(np->rval==op2) temp=np->lval->rval->constant; - else switch(temp2) - { - case C_AND: - temp = np->rval->rval->constant & np->lval->rval->constant; break; - case C_OR: - temp = np->rval->rval->constant | np->lval->rval->constant; break; - case C_XOR: - temp = np->rval->rval->constant ^ np->lval->rval->constant; break; - default: lose(E778, yylineno, (char*)NULL); - } - np->opcode = temp2; - np->rval->opcode = np->width==16 ? MESH : MESH32; - np->rval->constant = temp; - temp = op->rval->constant | op2->rval->constant; - nodefree(np->rval->lval); - nodefree(np->rval->rval); - np->rval->lval = (node*) NULL; - np->rval->rval = (node*) NULL; - if(np->lval!=op) - { - op2 = np->lval; - np->lval = op; - free(op2); - } - np->lval->rval->constant = temp; - if(np->lval->rval->constant>0xffff) np->lval->rval->opcode = MESH32; - optimize_pass1(np->lval); - /* it's pretty likely that there's an & with 0xffffffff here, although - not guaranteed, so reoptimize it */ - } - } - } - - /* Greater than/less than. The longest idiom in syslib, it stretches over 2 - statements. The first statement will already be optimized to - :a <- (:b ^ :c) or similar. At this point in the code, the second - statement looks like ((:c ~ :a) ~ ((? (:a ~ :a)) ^ 0x80000000)) or - similar. (That's a 32-bit ?.) The idiom, obviously, also could work - with a 16-bit ? and 0x8000. The point is, it returns the bit of :c - that corresponds to the most significant set bit in :a, which is the - most significant bit that differs between :b and :c. So if this bit is - a 1, it means that :c is greater; if it's a 0, it means that :b is - greater, or the numbers are equal. optimize_pass1 only optimizes within - an expression, so we're going to render it as :c > (:a ^ :c). */ - if(np->opcode==SELECT&&np->lval->opcode==SELECT&&np->rval->opcode==C_XOR&& - (np->rval->rval->opcode==MESH||np->rval->rval->opcode==MESH32)&& - np->rval->lval->opcode==XOR&&np->rval->lval->rval->opcode==SELECT&& - ((np->rval->lval->width==32&&np->rval->rval->constant==0x80000000LU)|| - (np->rval->lval->width==16&&np->rval->rval->constant==0x8000))&& - nodessame(np->lval->rval,np->rval->lval->rval->lval)&& - nodessame(np->lval->rval,np->rval->lval->rval->rval)) - { - temp=np->rval->lval->width; - if(temp==32||(np->lval->lval->width==16&&np->lval->rval->width==16&& - np->rval->lval->rval->lval->width==16&& - np->rval->lval->rval->rval->width==16)) - { - OPTING(greaterthan) - nodefree(np->rval); - op = np->lval; - *np=*op; - free(op); - np->opcode = C_XORGREATER; - np->optdata = 1; - } - } - - /* Many previous optimizations generate Boolean values. In INTERCAL, - Boolean algebra on these will be done with the familiar mingle, - unary, select routine. However, in many cases the 'select' will be - an implied &1, which could have been computed by many of the earlier - optimizations. These Boolean algebra operations are caught here. */ - if((np->opcode==C_AND1ADD1||np->opcode==C_2SUBAND1|| - ((np->opcode==C_AND||np->opcode==C_NNAND||np->opcode==C_LSHIFT|| - np->opcode==C_RSHIFT||np->opcode==C_LSHIFT2||np->opcode==C_LSHIFT8|| - np->opcode==C_LSHIFTIN1)&& - (np->rval->opcode==MESH||np->rval->opcode==MESH32)&& - np->rval->constant==1))) - { - if(np->opcode==C_AND1ADD1||np->opcode==C_2SUBAND1) op = np->rval; - else op = np->lval; - if((op->opcode==AND||op->opcode==OR||op->opcode==XOR)&& - op->rval->opcode==MINGLE) - { - OPTING(clogopand1) - mingleop = op->rval; - switch(op->opcode) - { - case AND: mingleop->opcode = C_AND; break; - case OR: mingleop->opcode = C_OR; break; - case XOR: mingleop->opcode = C_XOR; break; - default: lose(E778, yylineno, (char *) NULL); - } - free(op); - if(np->opcode==C_AND1ADD1||np->opcode==C_2SUBAND1) - np->rval = mingleop; - else np->lval = mingleop; - } - } - - /* The next optimization is aided by splitting C_NNANDs when they are - the argument to C_OR. Two cases. */ - - if(np->opcode == C_OR && np->lval->opcode == C_NNAND) - { - OPTING(splitnnandinorl) - op = np->lval; - np->lval = cons(C_ISNONZERO, (node *) NULL, op); - np->lval->width = np->lval->rval->width; - np->lval->rval->opcode = C_AND; - np->lval->optdata = 1; - } - - if(np->opcode == C_OR && np->rval->opcode == C_NNAND) - { - OPTING(splitnnandinorr) - op = np->rval; - np->rval = cons(C_ISNONZERO, (node *) NULL, op); - np->rval->width = np->rval->rval->width; - np->rval->rval->opcode = C_AND; - np->rval->optdata = 1; - } - - /* We can save a small amount of time, and aid further optimization, - by undistributing C_ISNONZERO across C_OR. This is used in some tests - which produce Booolean output, when testing the oddbits and - evenbits separately. Unfortunately, this doesn't work for C_AND. */ - if(np->opcode == C_OR && np->lval->opcode == C_ISNONZERO && - np->rval->opcode == C_ISNONZERO) - { - OPTING(distribnon0overor) - np->opcode = C_ISNONZERO; - np->rval->opcode = C_OR; - np->rval->lval = np->lval->rval; - free(np->lval); - np->lval = 0; - optimize_pass1(np->rval); /* reoptimize this */ - } - - /* Recognize a C logical operation on just the oddbits or evenbits of a - number. Two cases (evenbits and oddbits). */ - - if (np->opcode==SELECT && np->rval->opcode==MESH32 && - np->rval->constant==0x55555555LU && - (np->lval->opcode==AND||np->lval->opcode==OR||np->lval->opcode==XOR) && - np->lval->rval->opcode == C_OR && - ((np->lval->rval->lval->opcode == C_LSHIFT && - np->lval->rval->rval->opcode == C_AND) || - (np->lval->rval->lval->opcode == C_AND && - np->lval->rval->rval->opcode == C_LSHIFT)) && - np->lval->rval->lval->rval->opcode == MESH32 && - np->lval->rval->rval->rval->opcode == MESH32 && - np->lval->rval->lval->rval->constant == 0x55555555LU && - np->lval->rval->rval->rval->constant == 0x55555555LU) - { - OPTING(clogopevenbits) - switch(np->lval->opcode) - { - case AND: np->lval->rval->opcode = C_AND; break; - case OR: np->lval->rval->opcode = C_OR; break; - case XOR: np->lval->rval->opcode = C_XOR; break; - default: lose(E778, yylineno, (char *) NULL); - } - op = np->lval->rval; - free(np->lval); - np->lval = op; - op = np->lval->lval->lval; - free(np->lval->lval->rval); - free(np->lval->lval); - np->lval->lval = op; - op = np->lval->rval->lval; - free(np->lval->rval->rval); - free(np->lval->rval); - np->lval->rval = op; - } - - if (np->opcode==SELECT && np->rval->opcode==MESH32 && - np->rval->constant==0x55555555LU && - (np->lval->opcode==AND||np->lval->opcode==OR||np->lval->opcode==XOR) && - np->lval->rval->opcode == C_OR && - ((np->lval->rval->lval->opcode == C_RSHIFT && - np->lval->rval->rval->opcode == C_AND) || - (np->lval->rval->lval->opcode == C_AND && - np->lval->rval->rval->opcode == C_RSHIFT)) && - np->lval->rval->lval->rval->opcode == MESH32 && - np->lval->rval->rval->rval->opcode == MESH32 && - np->lval->rval->lval->rval->constant == 0xAAAAAAAALU && - np->lval->rval->rval->rval->constant == 0xAAAAAAAALU) - { - OPTING(clogopoddbits) - switch(np->lval->opcode) - { - case AND: np->lval->rval->opcode = C_AND; break; - case OR: np->lval->rval->opcode = C_OR; break; - case XOR: np->lval->rval->opcode = C_XOR; break; - default: lose(E778, yylineno, (char *) NULL); - } - op = np->lval->rval; - free(np->lval); - np->lval = op; - op = np->lval->lval->lval; - free(np->lval->lval->rval); - free(np->lval->lval); - np->lval->lval = op; - op = np->lval->rval->lval; - free(np->lval->rval->rval); - free(np->lval->rval); - np->lval->rval = op; - np->rval->constant = 0xAAAAAAAALU; - } - - /* !!(a ~ b) can be weakened to !!(a & b) */ - if(np->opcode == C_ISNONZERO && np->rval->opcode == SELECT) - { - OPTING(non0seltonnand) - np->lval = np->rval->lval; - op = np->rval->rval; - free(np->rval); - np->rval = op; - np->opcode = C_NNAND; - } - return opted; -} - -/************************************************************************* - * - * Code degeneration - * - * The theory behind this crock is that we've been handed a pointer to - * a tuple representing a single INTERCAL statement, possibly with an - * expression tree hanging off it and twisting slowly, slowly in the wind. - * - * Our mission, should we choose to accept it, is to emit C code which, - * when linked to the INTERCAL run-time support, will do something - * resembling the right thing. - * - **************************************************************************/ - -/* - * If the order of statement-token defines in ick.y ever changes, - * this will need to be reordered. - */ -char *enablers[MAXTYPES] = -{ - "GETS", - "RESIZE", - "NEXT", - "GO_AHEAD", /* AIS: Added for backtracking */ - "GO_BACK", /* AIS: Added for backtracking */ - "FORGET", - "RESUME", - "STASH", - "RETRIEVE", - "IGNORE", - "REMEMBER", - "ABSTAIN", - "REINSTATE", - "DISABLE", - "ENABLE", - "MANYFROM", /* AIS: Added ABSTAIN expr FROM gerunds */ - "GIVE_UP", - "READ_OUT", - "WRITE_IN", - "COME_FROM", - "COMPUCOME", /* AIS: Added COMPUCOME */ - "TRY_AGAIN", /* AIS: Added TRY AGAIN */ - "FROM", /* AIS: ABSTAIN expr FROM LABEL */ -}; - -assoc vartypes[] = -{ - { ONESPOT, "ONESPOT" }, - { TWOSPOT, "TWOSPOT" }, - { TAIL, "TAIL" }, - { HYBRID, "HYBRID" }, - { 0, (char *)NULL } -}; - -static assoc forgetbits[] = -{ - { ONESPOT, "oneforget" }, - { TWOSPOT, "twoforget" }, - { TAIL, "tailforget" }, - { HYBRID, "hyforget" }, - { 0, (char *)NULL } -}; - -static assoc varstores[] = -{ - { ONESPOT, "onespots" }, - { TWOSPOT, "twospots" }, - { TAIL, "tails" }, - { HYBRID, "hybrids" }, - { 0, (char *)NULL } -}; - -static assoc typedefs[] = -{ - { ONESPOT, "type16" }, - { TWOSPOT, "type32" }, - { TAIL, "type16" }, - { HYBRID, "type32" }, - { 0, (char *)NULL } -}; - -char *nameof(int value, assoc table[]) -/* return string corresponding to value in table */ -{ - assoc *ap; - - for (ap = table; ap->name; ap++) - if (ap->value == value) - return(ap->name); - return((char *)NULL); -} - -/* AIS: Code for printing explanations (mixed C/INTERCAL code that lets - the user know what the meaning of an expression is). This is paraphrased - from the prexpr/prvar code lower down. It's passed to yuk so that the - explain ('e') command works. It's also included in the degenerated C - code when the option -c is used, so the person looking at the code can - debug both the INTERCAL and ick itself more effectively, and used by - -h to produce its optimizer-debug output. */ - -unsigned long varextern(unsigned long intern, int vartype) -{ - atom *x; - if(!oblist) lose(E778, emitlineno, (char*) NULL); - for (x = oblist; x < obdex; x++) - if (x->type == vartype && x->intindex == intern) - return(x->extindex); - lose(E778, emitlineno, (char*) NULL); -} - -static void explvar(node* np, FILE* fp) -{ - node *sp; - switch(np->opcode) - { - case ONESPOT: - (void) fprintf(fp, ".%lu", varextern(np->constant,ONESPOT)); - break; - case TWOSPOT: - (void) fprintf(fp, ":%lu", varextern(np->constant,TWOSPOT)); - break; - case TAIL: - (void) fprintf(fp, ",%lu", varextern(np->constant,TAIL)); - break; - case HYBRID: - (void) fprintf(fp, ";%lu", varextern(np->constant,HYBRID)); - break; - case SUB: - (void) fprintf(fp, "("); - explvar(np->lval, fp); - (void) fprintf(fp, " SUB "); - for (sp = np->rval ; sp ; sp = sp->rval) - explexpr(sp->lval, fp); - (void) fprintf(fp, ")"); - break; - default: - lose(E778, emitlineno, (char*) NULL); - } -} - -/* unlike prexpr, this doesn't free its operands */ -void explexpr(node* np, FILE* fp) -{ - if(!np) return; - switch (np->opcode) - { - case MINGLE: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " $ "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case SELECT: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " ~ "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case AND: - (void) fprintf(fp, "(& "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case OR: - (void) fprintf(fp, "(V "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case XOR: - (void) fprintf(fp, "(? "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case FIN: - if (Base < 3) - lose(E997, emitlineno, (char *)NULL); - (void) fprintf(fp, "(^ "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case WHIRL: - case WHIRL2: - case WHIRL3: - case WHIRL4: - case WHIRL5: - if (np->opcode - WHIRL + 3 > Base) - lose(E997, emitlineno, (char *)NULL); - if(np->opcode == WHIRL) - (void) fprintf(fp, "(@ "); - else - (void) fprintf(fp, "(%d@ ", np->opcode - WHIRL + 1); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case MESH: - (void) fprintf(fp, "0x%lx", np->constant); - break; - - case MESH32: - (void) fprintf(fp, "0x%lx", np->constant); - break; - - case ONESPOT: - case TWOSPOT: - case TAIL: - case HYBRID: - case SUB: - explvar(np, fp); - break; - - /* cases from here down are generated by the optimizer */ - case C_AND: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case C_OR: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " | "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case C_XOR: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " ^ "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case C_NOT: - (void) fprintf(fp, "(~ "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case C_NOTEQUAL: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " != "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case C_NNAND: - (void) fprintf(fp, "(!!("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, "))"); - break; - - case C_AND1ADD1: - (void) fprintf(fp, "(("); - explexpr(np->rval,fp); - (void) fprintf(fp, " & 0x1) + 0x1)"); - break; - - case C_1PLUS: - (void) fprintf(fp, "("); - explexpr(np->rval,fp); - (void) fprintf(fp, " + 0x1)"); - break; - - case C_2MINUS: - (void) fprintf(fp, "(0x2 - "); - explexpr(np->rval,fp); - (void) fprintf(fp, ")"); - break; - - case C_2SUBAND1: - (void) fprintf(fp, "(0x2 - ("); - explexpr(np->rval,fp); - (void) fprintf(fp, " & 0x1))"); - break; - - case C_LSHIFT: - (void) fprintf(fp, "(("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, ") << 0x1)"); - break; - - case C_LSHIFTIN1: - (void) fprintf(fp, "((("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, ") << 0x1) | 0x1)"); - break; - - case C_LSHIFT2: - (void) fprintf(fp, "(("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, ") << 0x2)"); - break; - - case C_LSHIFT8: - (void) fprintf(fp, "(("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, ") << 0x8)"); - break; - - case C_RSHIFTBY: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " >> "); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case C_RSHIFT: - (void) fprintf(fp, "(("); - explexpr(np->lval, fp); - (void) fprintf(fp, " & "); - explexpr(np->rval, fp); - (void) fprintf(fp, ") >> 0x1)"); - break; - - case C_XORGREATER: - (void) fprintf(fp, "("); - explexpr(np->lval, fp); - (void) fprintf(fp, " > ("); - explexpr(np->rval, fp); - (void) fprintf(fp, " ^ "); - explexpr(np->lval, fp); - (void) fprintf(fp, "))"); - break; - - case C_ISNONZERO: - (void) fprintf(fp, "(!!"); - explexpr(np->rval, fp); - (void) fprintf(fp, ")"); - break; - - case INTERSECTION: - explexpr(np->lval, fp); - (void) fprintf(fp, " + "); - explexpr(np->rval, fp); - break; - - case GETS: - case RESIZE: - explexpr(np->lval, fp); - (void) fprintf(fp, " <- "); - explexpr(np->rval, fp); - break; - - case BY: - explexpr(np->lval, fp); - (void) fprintf(fp, " BY "); - explexpr(np->rval, fp); - break; - - default: - lose(E778, emitlineno, (char*) NULL); - break; - } -} - -/* AIS: Added the third argument to prexpr and prvar. It specifies - whether the node should be freed or not. I added the third - argument in all calls of prexpr/prvar. */ - -/* AIS: I moved prexpr's prototype higher in the file. */ - -static void prvar(node *np, FILE *fp, int freenode) -/* print out args to pass to storage manager for reference */ -{ - node *sp; - int dim; - - switch (np->opcode) - { - case ONESPOT: - (void) fprintf(fp, "onespots[%lu]", np->constant); - break; - - case TWOSPOT: - (void) fprintf(fp, "twospots[%lu]", np->constant); - break; - - case TAIL: - (void) fprintf(fp, "TAIL, &tails[%lu]", np->constant); - break; - - case HYBRID: - (void) fprintf(fp, "HYBRID, &hybrids[%lu]", np->constant); - break; - - case SUB: - { - (void) fprintf(fp, "aref("); - prvar(np->lval, fp, freenode); - - dim = 0; - for (sp = np->rval ; sp ; sp = sp->rval) - dim++; - (void) fprintf(fp, ", %d", dim); - - for (sp = np->rval ; sp ; sp = sp->rval) { - (void) fprintf(fp, ", "); - prexpr(sp->lval, fp, freenode); - } - (void) fprintf(fp, ")"); - } - break; - default: /* Added by AIS */ - lose(E778, emitlineno, (char*) NULL); - break; - } -} - -static void prexpr(node *np, FILE *fp, int freenode) -/* print out C-function equivalent of an expression */ -{ - switch (np->opcode) - { - case MINGLE: - (void) fprintf(fp, "mingle("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, ", "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case SELECT: - (void) fprintf(fp, "iselect("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, ", "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case AND: - (void) fprintf(fp, "and%d(", np->width); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case OR: - (void) fprintf(fp, "or%d(", np->width); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case XOR: - (void) fprintf(fp, "xor%d(", np->width); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case FIN: - if (Base < 3) - lose(E997, emitlineno, (char *)NULL); - (void) fprintf(fp, "fin%d(", np->width); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case WHIRL: - case WHIRL2: - case WHIRL3: - case WHIRL4: - case WHIRL5: - if (np->opcode - WHIRL + 3 > Base) - lose(E997, emitlineno, (char *)NULL); - (void) fprintf(fp, "whirl%d(%d, ", np->width, np->opcode - WHIRL + 1); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case MESH: - (void) fprintf(fp, "0x%lx", np->constant); - break; - - case MESH32: - (void) fprintf(fp, "0x%lx", np->constant); - break; - - case ONESPOT: - case TWOSPOT: - case TAIL: - case HYBRID: - prvar(np, fp, freenode); - break; - - case SUB: - (void) fprintf(fp, "*(%s*)", nameof(np->lval->opcode, typedefs)); - prvar(np, fp, freenode); - break; - - /* cases from here down are generated by the optimizer */ - case C_AND: - (void) fprintf(fp, "("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case C_OR: - (void) fprintf(fp, "("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " | "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case C_XOR: - (void) fprintf(fp, "("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " ^ "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case C_NOT: - (void) fprintf(fp, "(~"); - prexpr(np->rval, fp, freenode); - if (np->rval->width == Small_digits) - (void) fprintf(fp, " & Max_small)"); - else - (void) fprintf(fp, " & Max_large)"); - break; - - /* AIS: I added the rest of the cases */ - case C_NOTEQUAL: - (void) fprintf(fp, "("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " != "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case C_NNAND: - (void) fprintf(fp, "(!!("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, "))"); - break; - - case C_AND1ADD1: - (void) fprintf(fp, "(("); - prexpr(np->rval,fp, freenode); - (void) fprintf(fp, " & 0x1) + 0x1)"); - break; - - case C_1PLUS: - (void) fprintf(fp, "("); - prexpr(np->rval,fp, freenode); - (void) fprintf(fp, " + 0x1)"); - break; - - case C_2MINUS: - (void) fprintf(fp, "(0x2 - "); - prexpr(np->rval,fp, freenode); - (void) fprintf(fp, ")"); - break; - - case C_2SUBAND1: - (void) fprintf(fp, "(0x2 - ("); - prexpr(np->rval,fp, freenode); - (void) fprintf(fp, " & 0x1))"); - break; - - case C_LSHIFT: - (void) fprintf(fp, "(("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ") << 0x1)"); - break; - - case C_LSHIFTIN1: - (void) fprintf(fp, "((("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ") << 0x1) | 0x1)"); - break; - - case C_LSHIFT2: - (void) fprintf(fp, "(("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ") << 0x2)"); - break; - - case C_LSHIFT8: - (void) fprintf(fp, "(("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ") << 0x8)"); - break; - - case C_RSHIFTBY: - (void) fprintf(fp, "(("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, ") >> "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ")"); - break; - - case C_RSHIFT: - (void) fprintf(fp, "(("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " & "); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, ") >> 0x1)"); - break; - - case C_XORGREATER: - (void) fprintf(fp, "("); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " > ("); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, " ^ "); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, "))"); - break; - - case C_ISNONZERO: - (void) fprintf(fp, "(!!("); - prexpr(np->rval, fp, freenode); - (void) fprintf(fp, "))"); - break; - - case GETS: /* AIS: this is used only if freenode == 0 */ - if(freenode) lose(E778, emitlineno, (char*) NULL); - prexpr(np->lval, fp, freenode); - (void) fprintf(fp, " = "); - prexpr(np->rval, fp, freenode); - break; - - default: /* Added by AIS */ - if(!freenode) break; /* Be less careful when not freeing, because - this is used by -hH to print out its - intermediate optimization stages */ - lose(E778, emitlineno, (char*) NULL); - break; - } - - if(freenode) (void) free(np); -} - -static char *nice_text(char *texts[], int lines) -{ -#define MAXNICEBUF 512 - static char buf[MAXNICEBUF]; - char *cp, *text; - int i; - - if (lines < 1) - lines = 1; - for (cp = buf, i = 0 ; i < lines ; ++i) { - if (cp>buf+MAXNICEBUF-10) goto abort; - if (i) { - (*cp++) = '\\'; - (*cp++) = 'n'; - (*cp++) = '\\'; - (*cp++) = '\n'; - (*cp++) = '\t'; - } - for (text = texts[i] ; text&&*text ; cp++, text++) { - if (cp>buf+MAXNICEBUF-10) goto abort; - if(*text == '"' || *text == '\\') { - (*cp++) = '\\'; - } - *cp = *text; - } - } - *cp = '\0'; - return buf; -abort: (*cp++) = '.'; - (*cp++) = '.'; - (*cp++) = '.'; - *cp = '\0'; - return buf; -} - -static void emit_guard(tuple *tn, FILE *fp) -/* emit execution guard for giiven tuple (note the unbalanced trailing {!) */ -{ - if(tn->maybe) /* AIS */ - { - if(!multithread) lose(E405, emitlineno, (char *)NULL); - (void) fprintf(fp, " gonebackto = setjmp(btjb); choicepoint();\n"); - } - if(!flowoptimize || tn->abstainable) /* This condition by AIS */ - { - (void) fprintf(fp, " if ("); - if (tn->maybe) /* AIS */ - (void) fprintf(fp, "gonebackto == !("); - if (tn->exechance < 100) - (void) fprintf(fp, "roll(%d) && ", tn->exechance); - if ((tn->type != NEXT && tn->type != GO_BACK && tn->type != COME_FROM) - || tn->onceagainflag == onceagain_NORMAL) - (void) fprintf(fp, "!abstained[%d])%s {\n", (int)(tn - tuples), - /* AIS */ tn->maybe?")":""); - else /* AIS: [NEXT, GO_BACK, COME_FROM] ONCE needs specially - handled abstentions */ - (void) fprintf(fp, "!oldabstain)%s {\n", - /* AIS */ tn->maybe?")":""); - } - else - { /* AIS */ - if(tn->maybe) lose(E778, emitlineno, (char*) NULL); - if(!tn->initabstain) - { - if(tn->type != COMPUCOME) (void) fprintf(fp, " {\n"); - else (void) fprintf(fp, " if(1) {\n"); /* COMPUCOME specifically needs - an if() so it can have - an else. */ - } - else (void) fprintf(fp, " if(0) {\n"); /* for exceptional cases like - DON'T COME FROM #1 where we - need a label or an else. */ - } -} - -void emittextlines(FILE *fp) -{ - int i=-1; - while(i++lineno); - if (tn->label) - (void) fprintf(fp, "L%d:", tn->label); - if (yydebug || compile_only) - { - (void) fprintf(fp, "\t/* %s */", textlines[tn->lineno]); - /* AIS: grind out an expression explanation */ - if (tn->type == GETS || tn->type == FORGET || tn->type == RESUME - || tn->type == FROM || tn->type == COMPUCOME - || tn->type == MANYFROM) - { - (void) fprintf(fp, "\n\t/* Expression is "); - explexpr(tn->type == MANYFROM ? tn->u.node->lval : - tn->type == GETS ? tn->u.node->rval : tn->u.node, fp); - (void) fprintf(fp, " */"); - } - } - (void) fputc('\n', fp); - - /* set up the "next" lexical line number for error messages */ - if (tn->type == NEXT) { - tuple *up; - for (up = tuples; up < tuples + lineno; up++) - if (tn->u.target == up->label) { - emitlineno = up->lineno; - break; - } - } else if (tn->ncomefrom) - emitlineno = comefromsearch(tn,1); /* AIS: For multithreading. - Return the 1st if we're forking. */ - else if (tn < tuples + lineno - 1) - emitlineno = tn[1].lineno; - else - emitlineno = yylineno; - (void) fprintf(fp, " lineno = %d;\n", emitlineno); - - /* print warnings on -l */ - if(checkforbugs) - { - if(tn->warn112) lwarn(W112, emitlineno, (char*) NULL); - if(tn->warn128) lwarn(W128, emitlineno, (char*) NULL); - if(tn->warn534) lwarn(W534, emitlineno, (char*) NULL); - if(tn->warn018) lwarn(W018, emitlineno, (char*) NULL); - if(tn->warn016) lwarn(W016, emitlineno, (char*) NULL); - if(tn->warn276) lwarn(W276, emitlineno, (char*) NULL); - if(tn->warn239) lwarn(W239, emitlineno, (char*) NULL); - if(tn->warn622) lwarn(W622, emitlineno, (char*) NULL); - } - - /* emit debugging information */ - if (yukdebug||yukprofile) - { - (void) fprintf(fp, " YUK(%d,%d);\n", - (int)(tn-tuples),emitlineno); - } - - /* AIS: The +mystery option on degenerated code causes the code to - unexpectedly terminate after 4 billion commands are run, thus - preventing an infinite loop. Of course, it will enhance the fun - if we don't tell the user that. (This is necessary for the - constant-output optimizer to work properly.) */ - (void) fprintf(fp, " MYSTERYLINE;\n"); - - /* AIS: If the tuple is ONCE/AGAIN flagged, we need a delayed-action - set of its abstention status to the AGAIN-flagged status. The - problem is that some statements, like COME FROM, need to set after - the command has finished, and some, like NEXT, need it before the - command has started. At the moment, only NEXT and GO_BACK have a - ONCE/AGAIN before it, rather than after (because neither of them - continue in the normal fashion). */ - if ((tn->type == NEXT || tn->type == GO_BACK) && - tn->onceagainflag != onceagain_NORMAL) - { - /* ONCE/AGAIN has already been swapped by perpetrate.c in the case - of a preabstained statement ('DO NOT'...). So if currently have - a ONCE, it means that being abstained is the attractive state, - and if we currently have an AGAIN, it means that being - reinstated is the attractive state. Semantics with computed - ABSTAIN: Don't change the abstention count unless necessary, in - which case change it to 0 or 1. */ - fprintf(fp," oldabstain = abstained[%d];\n", (int)(tn - tuples)); - fprintf(fp," abstained[%d] = %s;\n", - (int)(tn - tuples), - tn->onceagainflag==onceagain_ONCE ? "oldabstain ? oldabstain : 1" - : "0"); - /* This test-and-set must be atomic. As all statements are atomic anyway - in the current version of ick, that isn't a problem, but if anyone - wants to try using POSIX's multithreading features, the above two - lines need to be a critical section. */ - } - - /* in the case of COMPUCOME, we need an extra guard */ - if (tn->type == COMPUCOME) - { - fprintf(fp," if(0)\n {\n"); - fprintf(fp,"CCF%d:\n",compucomecount++); - fprintf(fp," if(skipto=="); - prexpr(tn->u.node, fp, 1); - fprintf(fp,") {\n"); - } - - /* AIS: With this block placed here, you can't even have a comment - after a TRY AGAIN line. Move it below the next check if this seems - to be undesirable behaviour. */ - if(pasttryagain) /* AIS */ - { - lose(E993, emitlineno, (char*)NULL); - } - - if(flowoptimize && tn->initabstain && !tn->abstainable - && tn->type != COMPUCOME && tn->type != COME_FROM && - tn->type != NEXT) /* AIS */ - goto skipcomment; /* Look, a comment! We can completely skip all - degeneration of this statement (although with - -c, comments will appear in the degenerated - code in its place). The COMPUCOME condition is - because it is so weird. COME_FROM and NEXT are - exempted so labels are generated. */ - - /* emit conditional-execution prefixes */ - if (tn->type != COME_FROM) - emit_guard(tn, fp); - - /* now emit the code for the statement body */ - switch(tn->type) - { - case GETS: - /* Start of AIS optimization */ - np = tn->u.node; - if(np->lval->opcode == SUB) np = np->lval; - if(flowoptimize && - (np->lval->opcode == TWOSPOT - || np->lval->opcode == HYBRID - || !(tn->u.node->lval->optdata & ~0xffffLU))) - { - atom* op; - int ignorable = 1; - for(op = oblist; op < obdex; op++) - { - if(op->type == np->lval->opcode && - op->intindex == np->lval->constant) - { - ignorable &= op->ignorable; - } - } - if(!ignorable) - { /* Variable can't be ignored, and expression must be in range */ - (void) fprintf(fp,"\t"); - prexpr(tn->u.node->lval, fp, 1); - (void) fprintf(fp, " = "); - prexpr(tn->u.node->rval, fp, 1); - (void) fprintf(fp, ";\n"); - break; - } - } - /* End of AIS optimization */ - - np = tn->u.node; - - if (np->lval->opcode != SUB) { - sp = np->lval; - (void) fprintf(fp,"\t(void) assign((char*)&"); - } - else { - sp = np->lval->lval; - (void) fprintf(fp,"\t(void) assign("); - } - prvar(np->lval, fp, 1); - (void) fprintf(fp,", %s", nameof(sp->opcode, vartypes)); - (void) fprintf(fp,", %s[%lu], ", nameof(sp->opcode, forgetbits), - sp->constant); - prexpr(np->rval, fp, 1); - (void) fprintf(fp,");\n"); - break; - - case RESIZE: - np = tn->u.node; - dim = 0; - for (sp = np->rval; sp; sp = sp->rval) - dim++; - (void) fprintf(fp, "\tresize("); - prvar(np->lval, fp, 1); - (void) fprintf(fp, ", %s[%lu]", nameof(np->lval->opcode, forgetbits), - np->lval->constant); - (void) fprintf(fp, ", %d", dim); - for (sp = np->rval; sp; sp = sp->rval) { - (void) fprintf(fp, ", "); - prexpr(sp->lval, fp, 1); - } - (void) fprintf(fp, ");\n"); - break; - - case NEXT: - /* Start of AIS optimization */ - if(tn->optversion) - { /* optimizef has checked that this is a valid optimization */ - (void) fprintf(fp, "\tif(1 == "); - prexpr(tn->u.node, fp, 1); /* frees optimizef's nodecopy */ - (void) fprintf(fp, ") {pushnext(%d); goto N%d;} N%d:;\n", - (int)(tn - tuples + 1), tn->nexttarget, (int)(tn - tuples + 1)); - break; - } - /* End of AIS optimization */ - (void) fprintf(fp, - "\tpushnext(%d); goto L%d; N%d:;\n", - (int)(tn - tuples + 1), tn->u.target, (int)(tn - tuples + 1)); - break; - - case GO_BACK: /* By AIS */ - if(!multithread) lose(E405, emitlineno, (char*) NULL); - (void) fprintf(fp, "\tchoiceback();\n"); - break; - - case GO_AHEAD: /* By AIS */ - if(!multithread) lose(E405, emitlineno, (char*) NULL); - (void) fprintf(fp, "\tchoiceahead();\n"); - break; - - case RESUME: - (void) fprintf(fp, "\tskipto = resume("); - prexpr(tn->u.node, fp, 1); - (void) fprintf(fp, "); goto top;\n"); - break; - - case FORGET: - (void) fprintf(fp, "\tpopnext("); - prexpr(tn->u.node, fp, 1); - (void) fprintf(fp, ");\n"); - break; - - case STASH: - for (np = tn->u.node; np; np = np->rval) - (void) fprintf(fp, "\tstash(%s, %lu, %s+%lu);\n", - nameof(np->opcode, vartypes), - np->constant, - nameof(np->opcode, varstores), np->constant); - break; - - case RETRIEVE: - for (np = tn->u.node; np; np = np->rval) - (void) fprintf(fp, "\tretrieve(%s+%lu, %s, %lu, %s[%lu]);\n", - nameof(np->opcode, varstores), np->constant, - nameof(np->opcode, vartypes), - np->constant, - nameof(np->opcode, forgetbits), - np->constant); - break; - - case IGNORE: - for (np = tn->u.node; np; np = np->rval) - (void) fprintf(fp,"\t%s[%lu] = TRUE;\n", - nameof(np->opcode, forgetbits), - np->constant); - break; - - case REMEMBER: - for (np = tn->u.node; np; np = np->rval) - (void) fprintf(fp,"\t%s[%lu] = FALSE;\n", - nameof(np->opcode, forgetbits), - np->constant); - break; - - /* All abstention code has been edited by AIS to allow for the new abstention rules */ - case ABSTAIN: - (void) fprintf(fp, "\tif(!abstained[%d]) abstained[%d] = 1;\n", tn->u.target - 1, tn->u.target-1); - break; - - case FROM: - (void) fprintf(fp, "\tabstained[%d]+=", tn->u.target-1); - tn->u.node->width = 32; - prexpr(tn->u.node,fp, 1); - (void) fprintf(fp, ";\n"); - break; - - case REINSTATE: - (void) fprintf(fp, "\tif(abstained[%d]) abstained[%d]--;\n", tn->u.target - 1, tn->u.target-1); - break; - - case ENABLE: - (void) fprintf(fp, - "\tint i;\n"); - for (np = tn->u.node; np; np = np->rval) - { - (void) fprintf(fp, - "\n\tfor (i = 0; i < (int)(sizeof(linetype)/sizeof(int)); i++)\n"); - if (np->constant == ABSTAIN) { - (void) fprintf(fp, - "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2], enablers[FROM-GETS], enablers[MANYFROM-GETS]); - } else if (np->constant == REINSTATE) { - (void) fprintf(fp, - "\t if (linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2]); - } else { - (void) fprintf(fp, - "\t if (linetype[i] == %s)\n", enablers[np->constant-GETS]); - } - (void) fprintf(fp, - "\t\tif(abstained[i]) abstained[i]--;\n"); - } - break; - - case DISABLE: - (void) fprintf(fp, - "\tint i;\n"); - for (np = tn->u.node; np; np = np->rval) - { - (void) fprintf(fp, - "\n\tfor (i = 0; i < (int)(sizeof(linetype)/sizeof(int)); i++)\n"); - if (np->constant == ABSTAIN) { - (void) fprintf(fp, - "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2], enablers[FROM-GETS], enablers[MANYFROM-GETS]); - } else if (np->constant == REINSTATE) { - (void) fprintf(fp, - "\t if (linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2]); - } else { - (void) fprintf(fp, - "\t if (linetype[i] == %s)\n", enablers[np->constant-GETS]); - } - (void) fprintf(fp, - "\t\tif(!abstained[i]) abstained[i] = 1;\n"); - } - break; - - case MANYFROM: - (void) fprintf(fp, - "\tint i;\n\tint j;\n\tj="); - tn->u.node->lval->width=32; - prexpr(tn->u.node->lval,fp, 1); - (void) fprintf(fp, - ";\n"); - for (np = tn->u.node->rval; np; np = np->rval) - { - (void) fprintf(fp, - "\n\tfor (i = 0; i < (int)(sizeof(linetype)/sizeof(int)); i++)\n"); - if (np->constant == ABSTAIN) { - (void) fprintf(fp, - "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2], enablers[FROM-GETS], enablers[MANYFROM-GETS]); - } else if (np->constant == REINSTATE) { - (void) fprintf(fp, - "\t if (linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2]); - } else { - (void) fprintf(fp, - "\t if (linetype[i] == %s)\n", enablers[np->constant-GETS]); - } - (void) fprintf(fp, - "\t\tabstained[i] += j;\n"); - } - break; - - case COMPUCOME: /* By AIS. Note that this doesn't even have balanced - braces; it's designed to work with COMPUCOME's - crazy guarding arrangements */ - fprintf(fp,"\t;} else goto CCF%d;\n",compucomecount); - break; - - case GIVE_UP: /* AIS: Edited to allow for yuk */ - if(yukprofile||yukdebug) fprintf(fp, "\tYUKTERM;\n"); - if(multithread) fprintf(fp, "\tkillthread();\n"); - (void) fprintf(fp, "\treturn(0);\n"); - break; - - case TRY_AGAIN: /* By AIS */ - (void) fprintf(fp, "\tgoto ick_restart;\n }\n"); - if(yukprofile||yukdebug) fprintf(fp, " if(yukloop) goto ick_restart;\n"); - if(yukprofile||yukdebug) fprintf(fp, " YUKTERM;\n"); - if(multithread) fprintf(fp, "\tkillthread();\n"); - (void) fprintf(fp, " {\n\treturn(0);\n"); - /* because if TRY AGAIN is the last line, falling off the end isn't an error */ - pasttryagain=1; /* flag an error if we try any more commands */ - break; - - case WRITE_IN: - for (np = tn->u.node; np; np = np->rval) { - if (np->lval->opcode == TAIL || np->lval->opcode == HYBRID) { - (void) fprintf(fp,"\tbinin("); - prvar(np->lval, fp, 1); - (void) fprintf(fp, ", %s[%lu]", - nameof(np->lval->opcode, forgetbits), - np->lval->constant); - (void) fprintf(fp,");\n"); - } - else { - if (np->lval->opcode != SUB) { - sp = np->lval; - (void) fprintf(fp,"\t(void) assign((char*)&"); - } - else { - sp = np->lval->lval; - (void) fprintf(fp,"\t(void) assign("); - } - prvar(np->lval, fp, 1); - (void) fprintf(fp,", %s", nameof(sp->opcode, vartypes)); - (void) fprintf(fp,", %s[%lu]", nameof(sp->opcode, forgetbits), - sp->constant); - (void) fprintf(fp,", pin());\n"); - } - } - break; - - case READ_OUT: - for (np = tn->u.node; np; np = np->rval) - { - if (np->lval->opcode == TAIL || np->lval->opcode == HYBRID) { - (void) fprintf(fp,"\tbinout("); - prvar(np->lval, fp, 1); - (void) fprintf(fp,");\n"); - } - else { - (void) fprintf(fp, "\tpout("); - prexpr(np->lval, fp, 1); - (void) fprintf(fp, ");\n"); - } - } - break; - - case SPLATTERED: - dim = emitlineno - tn->lineno; - if (tn->sharedline) - ++dim; - (void) fprintf(fp, "\tlose(E000, %d, \"%s\");\n", - emitlineno, nice_text(textlines + tn->lineno, dim)); - break; - - case COME_FROM: - (void) fprintf(fp, "C%ld:\n", (long)(tn-tuples+1)); - /* AIS: Changed so all COME_FROMs have unique labels even if two - of them aim at the same line. */ - break; - - default: - lose(E778, emitlineno, (char *)NULL); - break; - } - - if (tn->type != COME_FROM) - (void) fprintf(fp, " }\n"); - - skipcomment: - - if (tn->type == COMPUCOME) - { /* By AIS */ - (void) fprintf(fp," else goto CCF%d;\n",compucomecount); - (void) fprintf(fp," ccfc++;\n"); - /* Note that due to the semantics of setjmp, this has to be written as 2 - separate ifs. The MULTICOME macro expands to a non-multithreaded or - multithreaded function for handling a COME FROM clash. */ - (void) fprintf(fp," if(ccfc==1||MULTICOME(%d,cjb))\n" - "\tif(setjmp(cjb) == 0) goto CCF%d;\n", - emitlineno, compucomecount); - /* Of course, emitlineno is unlikely to be helpful! */ - (void) fprintf(fp," }\n"); - } - - /* AIS: Before any COMING FROM this line is done, we need to sort out - ONCE and AGAIN situations, unless this line was a NEXT or GO_BACK. - COME FROM is also excluded because it acts at the suckpoint, not - at the place it's written in the program. */ - if (tn->onceagainflag != onceagain_NORMAL && - (tn->type != NEXT && tn->type != GO_BACK && tn->type != COME_FROM)) - { - /* See my comments against the NEXT code for more information. - This code is placed here so COME FROM ... ONCE constructs work - properly (the line is abstained if the COME FROM is reached in - execution, or its suckpoint is reached in execution). */ - fprintf(fp," oldabstain = abstained[%d];\n", (int)(tn - tuples)); - fprintf(fp," abstained[%d] = %s;\n", - (int)(tn - tuples), - tn->onceagainflag==onceagain_ONCE ? "oldabstain ? oldabstain : 1" - : "0"); - } - - /* AIS: This is where we start the COME FROM suckpoint code. */ - - /* AIS: We need to keep track of how many COME FROMs are aiming here - at runtime, if we don't have the very simple situation of no - COMPUCOMEs and a single-thread program (in which case the check - is done at compile-time by codecheck). Even without COMPUCOME, - this can change in a multithread program due to abstentions. */ - if((tn->ncomefrom && multithread) || (tn->label && compucomesused)) - (void) fprintf(fp, " ccfc = 0;\n"); - - /* - * If the statement that was just degenerated was a COME FROM target, - * emit the code for the jump to the COME FROM. - * AIS: Changed most of this to allow for multithreading. - */ - while(tn->ncomefrom) /* acts as an if if singlethreading */ - { - tuple* cf; /* local to this block */ - if(multithread || compucomesused) generatecfjump = 1; - cf = tuples+comefromsearch(tn,tn->ncomefrom)-1; - if (yydebug || compile_only) - (void) fprintf(fp, - " /* line %03d is a suck point for the COME FROM " - "at line %03d */\n", tn->lineno, cf->lineno); - if (cf->onceagainflag != onceagain_NORMAL) - { /* Calculate ONCE/AGAIN when the suckpoint is passed */ - fprintf(fp," oldabstain = abstained[%d];\n", (int)(cf - tuples)); - fprintf(fp," abstained[%d] = %s;\n", - (int)(cf - tuples), - cf->onceagainflag==onceagain_ONCE ? "oldabstain ? oldabstain : 1" - : "0"); - } - emit_guard(cf, fp); - if(multithread || compucomesused) - (void) fprintf(fp, - "\tccfc++;\tif(ccfc==1||MULTICOME(%d,cjb)) " - "if(setjmp(cjb) == 1) goto C%ld;\n }\n", - emitlineno, (long)(cf-tuples+1)); - else /* optimize for the simple case */ - (void) fprintf(fp, "\tgoto C%ld;\n }\n", (long)(cf-tuples+1)); - tn->ncomefrom--; - } - - /* AIS: If the statement has a label, it might be a - computed COME FROM target. Also check the flag that says this - code is needed in a multithread non-COMPUCOME program. - If (at runtime) ccfc is nonzero, we know cjb has already been set; - otherwise, set it now. In the case of a multithread non-COMPUCOME - program, the goto will just jump to a longjmp, switching to the - one and only one COME FROM that hasn't been given its own thread. */ - if ((tn->label && compucomesused) || generatecfjump) - { - if(compucomesused) (void) fprintf(fp, " skipto = %d;\n", tn->label); - if(generatecfjump) (void) fprintf(fp, " if(ccfc) goto CCF0;\n"); - if(compucomesused) - { /* check all the COMPUCOMES */ - (void) fprintf(fp, " %sif(setjmp(cjb) == 0) goto CCF0;\n", - generatecfjump?"else ":""); - } - generatecfjump = 0; - } - - /* AIS: Now we've finished the statement, let's switch to the next - thread in a multithread program. */ - if(multithread) (void) fputs(" NEXTTHREAD;\n", fp); -} - -/* feh.c ends here */ diff --git a/feh.h b/feh.h deleted file mode 100644 index ae55dc5..0000000 --- a/feh.h +++ /dev/null @@ -1,22 +0,0 @@ -/* feh.h -- compilation functions used by perpetrate.c and ick.y */ - -extern node *newnode(void); -extern node *cons(int type, node *car, node *cdr); -extern unsigned int intern(int type, int index); -extern void checklabel(int label); -extern void treset(void); -extern tuple *newtuple(void); -extern void typecast(node *np); -extern void codecheck(void); -extern void optimize(node *np); -extern char *nameof(int value, assoc table[]); -extern void emit(tuple *tn, FILE *fp); -extern void emittextlines(FILE *fp); -extern int comefromsearch(tuple *tn, unsigned int index); /* AIS */ -extern void explexpr(node* np, FILE* fp); /* AIS */ -extern void optimizef(); /* AIS */ - -extern char *enablers[MAXTYPES]; -extern assoc vartypes[]; - -/* feh.h ends here */ diff --git a/fiddle.c b/fiddle.c deleted file mode 100644 index 2f6a9e5..0000000 --- a/fiddle.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * fiddle.c -- functions that implement the five INTERCAL operators - * - * We link these to the compiler, too, in order to do constant folding - * -LICENSE TERMS - Copyright (C) 1996 Eric S. Raymond - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "fiddle.h" -#include "sizes.h" -#include "lose.h" -#include - -unsigned int mingle(register unsigned int r, register unsigned int s) -{ - if (Base == 2) { - if (r>0xffff || s>0xffff) - lose(E533, lineno, (char *)NULL); - r = ((r & 0x0000ff00) << 8) | (r & 0x000000ff); - r = ((r & 0x00f000f0) << 4) | (r & 0x000f000f); - r = ((r & 0x0c0c0c0c) << 2) | (r & 0x03030303); - r = ((r & 0x22222222) << 1) | (r & 0x11111111); - s = ((s & 0x0000ff00) << 8) | (s & 0x000000ff); - s = ((s & 0x00f000f0) << 4) | (s & 0x000f000f); - s = ((s & 0x0c0c0c0c) << 2) | (s & 0x03030303); - s = ((s & 0x22222222) << 1) | (s & 0x11111111); - return (r << 1) | s; - } - else { - unsigned int result = 0, fac = 1; - int i; - for (i = 0 ; i < Small_digits ; i++) { - result += fac * (s % Base); - s /= Base; - fac *= Base; - result += fac * (r % Base); - r /= Base; - fac *= Base; - } - return result; - } -} - -unsigned int iselect(register unsigned int r, register unsigned int s) -{ - if (Base == 2) { - register unsigned int i = 1, t = 0; - while (s) { - if (s & i) { - t |= r & i; - s ^= i; - i <<= 1; - } - else { - s >>= 1; - r >>= 1; - } - } - return(t); - } - else { - unsigned int j, result = 0, fac, digit, ofac = 1; - for (j = Base - 1 ; j > 0 ; j--) { - int i; - fac = 1; - for (i = 0; i < Large_digits ; i++) { - if ((s / fac) % Base == j) { - digit = (r / fac) % Base; - if (digit) - result += ofac * (digit > j ? digit : j); - ofac *= Base; - } - fac *= Base; - } - } - return result; - } -} - -static unsigned int whirl(unsigned int len, unsigned int p, unsigned int n) -{ - unsigned int i, fac = 1, result = 0, d1, d2, dsave; - d1 = n % Base; - dsave = d1; - for (i = 1 ; i <= len ; i++) { - d2 = d1; - d1 = (i < len) ? (n /= Base, n % Base) : dsave; - if (d1 <= p) - result += fac * ((d2 < d1 || d2 > p) ? d1 : d2); - else - result += fac * ((d2 < d1 && d2 > p) ? d1 : d2); - fac *= Base; - } - return result; -} - -unsigned int and16(unsigned int n) -{ - if (Base == 2) { - unsigned int m = (n >> 1); - if (n & 1) - m |= 0x8000; - return(m & n); - } - else { - return whirl(Small_digits,0,n); - } -} - -unsigned int or16(unsigned int n) -{ - if (Base == 2) { - unsigned int m = (n >> 1); - if (n & 1) - m |= 0x8000; - return(m | n); - } - else { - return whirl(Small_digits,Base-1,n); - } -} - -unsigned int whirl16(unsigned int p, unsigned int n) -{ - return whirl(Small_digits,p,n); -} - -unsigned int and32(unsigned int n) -{ - if (Base == 2) { - unsigned int m = (n >> 1); - if (n & 1) - m |= 0x80000000; - return(m & n); - } - else { - return whirl(Large_digits,0,n); - } -} - -unsigned int or32(unsigned int n) -{ - if (Base == 2) { - unsigned int m = (n >> 1); - if (n & 1) - m |= 0x80000000; - return(m | n); - } - else { - return whirl(Large_digits,Base-1,n); - } -} - -unsigned int whirl32(unsigned int p, unsigned int n) -{ - return whirl(Large_digits,p,n); -} - -unsigned int xor(unsigned int len, unsigned int n) -{ - unsigned int i, fac = 1, result = 0, d1, d2, dsave; - d1 = n % Base; - dsave = d1; - for (i = 1 ; i <= len ; i++) { - d2 = d1; - d1 = (i < len) ? (n /= Base, n % Base) : dsave; - result += fac * ((Base + d1 - d2) % Base); - fac *= Base; - } - return result; -} - -unsigned int xor16(unsigned int n) -{ - if (Base == 2) { - unsigned int m = (n >> 1); - if (n & 1) - m |= 0x8000; - return(m ^ n); - } - else { - return xor(Small_digits,n); - } -} - -unsigned int xor32(unsigned int n) -{ - if (Base == 2) { - unsigned int m = (n >> 1); - if (n & 1) - m |= 0x80000000; - return(m ^ n); - } - else { - return xor(Large_digits,n); - } -} - -static unsigned int fin(unsigned int len, unsigned int n) -{ - unsigned int i, fac = 1, result = 0, d1, d2, dsave; - d1 = n % Base; - dsave = d1; - for (i = 1 ; i <= len ; i++) { - d2 = d1; - d1 = (i < len) ? (n /= Base, n % Base) : dsave; - result += fac * ((d1 + d2) % Base); - fac *= Base; - } - return result; -} - -unsigned int fin16(unsigned int n) -{ - if (Base == 2) { - unsigned int m = (n >> 1); - if (n & 1) - m |= 0x8000; - return(m ^ n); - } - else { - return fin(Small_digits,n); - } -} - -unsigned int fin32(unsigned int n) -{ - if (Base == 2) { - unsigned int m = (n >> 1); - if (n & 1) - m |= 0x80000000; - return(m ^ n); - } - else { - return fin(Large_digits,n); - } -} - -/* fiddle.c */ diff --git a/fiddle.h b/fiddle.h deleted file mode 100644 index b01346f..0000000 --- a/fiddle.h +++ /dev/null @@ -1,12 +0,0 @@ -/* fiddle.h -- functions implementing intercal's operators */ - -extern unsigned int mingle(register unsigned int r, register unsigned int s); -extern unsigned int iselect(register unsigned int r, register unsigned int s); -extern unsigned int and16(unsigned int n), or16(unsigned int n), - xor16(unsigned int n), fin16(unsigned int n); -extern unsigned int whirl16(unsigned int p, unsigned int n); -extern unsigned int and32(unsigned int n), or32(unsigned int n), - xor32(unsigned int n), fin32(unsigned int n); -extern unsigned int whirl32(unsigned int p, unsigned int n); - -/* fiddle.h ends here */ diff --git a/ick-wrap.c b/ick-wrap.c deleted file mode 100644 index a3dc7ae..0000000 --- a/ick-wrap.c +++ /dev/null @@ -1,76 +0,0 @@ -$L -/* $A.c -- generated C-code file for INTERCAL program $A.i */ - -/* This code is explicitly *not* GPLed. Use, abuse, and redistribute freely */ - -#include -#include -#include -#include - -$M -#include "fiddle.h" -#include "abcess.h" -#include "lose.h" -$K - -#define OK(d) !abstained[d] - -extern int printflow; - -int lineno; - -jmp_buf cjb; -int ccfc; -int skipto; - -int oldabstain; -int abstained[$B]$C; -$D -$E - -int main(int argc, char *argv[]) -{ - parseargs(argc,argv); - - skipto = 0; - - next = calloc(80, sizeof *next); -$N - -#ifdef YUK - yuklines = $J; - yukcommands = $B; -#endif - /* set seed for random error generation */ -#ifdef USG - srand48(time((long *)0) + getpid()); -#else - srand(time((long *)0)); -#endif /* UNIX */ - -#if MULTITHREAD == 1 - ickmtinit(); -#endif - - /* set up stash storage */ - stashinit(); - - $F - - /* degenerated code */ - ick_restart: - ; - -$G - -#ifdef YUK - if(yukloop) goto ick_restart; -#endif - lose(E633, $J, (char *)0); - -$H - return 0; -} - -/* Generated code for $A.i ends here */ diff --git a/ick.h b/ick.h deleted file mode 100644 index 1f0cafe..0000000 --- a/ick.h +++ /dev/null @@ -1,138 +0,0 @@ -/* ick.h -- compilation types for intercal parser */ - -/* Comment this out if your version of lex automatically supplies yylineno. */ -/*#define YYLINENO_BY_HAND*/ - -/* Comment this out if your version of lex doesn't use yyrestart(). */ -/*#define USE_YYRESTART*/ - -#define YY_NO_UNPUT - -typedef int bool; -#define TRUE 1 -#define FALSE 0 - -#define ALLOC_CHUNK 256 - -/* - * We choose this value for maximum number of possible variables on - * the theory that no human mind could grok a more complex INTERCAL - * program than this and still retain any vestige of sanity. -#define MAXVARS 100 - */ - -/* - * Maximum supported statement types; should be equal to (FROM - GETS + 1) - * AIS: Changed this when I added new statements. - */ -#define MAXTYPES 23 - -/* AIS: Maximum supported spark/ears nesting, divided by 32. The value given - allows for 256 nested spark/ears groupings, which should be enough. */ -#define SENESTMAX 8 - -enum onceagain {onceagain_NORMAL, onceagain_ONCE, onceagain_AGAIN}; /* AIS */ - -typedef struct node_t -{ - int opcode; /* operator or type code */ - unsigned long constant; /* constant data attached */ - unsigned long optdata; /* AIS: Temp used by the optimizer */ - int width; /* is this 32-bit data? */ - struct node_t *lval, *rval; /* attached expression nodes */ -} node; - -typedef struct tuple_t -{ - unsigned int label; /* label # of this statement */ - unsigned int ncomefrom; /* AIS: How many noncomputed COME FROMS - have this line as a suck-point */ - int exechance; /* chance of execution, initial abstain, - (AIS) MAYBE details */ - bool maybe; /* AIS: Where MAYBE details go when - exechance has been parsed */ - bool abstainable; /* AIS: Is it possible for this line to - be abstained from? */ - bool initabstain; /* AIS: Is this line initially - abstained from? */ - bool nextable; /* AIS: Can this line be a NEXT - target? */ - bool optversion; /* AIS: Use an optimized version? (Only - set if the optimizer thinks that - it's safe.) */ - bool warn112:1; /* AIS: Should this line produce warning - 112 during degeneration? */ - bool warn128:1, warn534:1, warn018:1, warn016:1, warn276:1, warn239:1, - warn622:1; /* AIS: As warn112. The warnings are a bitfield to save space. */ - unsigned int type; /* statement type */ - struct - { /* AIS: Struct, not union needed because ABSTAIN expr FROM (line) has both */ - unsigned int target; /* for NEXT statements */ - node *node; /* attached expression node(s) */ - } u; - unsigned int nexttarget; /* AIS: The target tuple of a NEXT must - also be recorded for optimizef */ - int lineno; /* source line for error messages */ - bool sharedline; /* if NZ, two statements on a line */ - enum onceagain onceagainflag; /* AIS: ONCE / AGAIN */ -} tuple; - -/* this maps the `external' name of a variable to an internal array index */ -typedef struct -{ - int type; - int extindex; - int intindex; - int ignorable; /* AIS: Can this variable be IGNOREd? */ -} -atom; - -typedef struct -{ - int value; - char *name; -} -assoc; - -extern atom *oblist, *obdex; -extern int obcount, nonespots, ntwospots, ntails, nhybrids; - -extern tuple *tuples; -extern int tuplecount; - -extern tuple *optuple; /* AIS: The tuple currently being optimized */ - -extern char *enablers[MAXTYPES]; -extern assoc vartypes[]; - -/* the lexical analyzer keeps copies of the source logical lines */ -extern char **textlines; -extern int textlinecount; -extern int yylineno; - -/* AIS: These are needed to sort out a grammar near-ambiguity */ -extern unsigned long sparkearsstack[SENESTMAX]; -extern int sparkearslev; - -/* compilation options */ -extern bool compile_only; /* just compile into C, don't run the linker */ -extern bool nocompilerbug; /* set possibility of E774 to zero */ -extern int traditional; /* compile as INTERCAL-72 */ -extern int yydebug; /* print debugging information while parsing */ - -extern int politesse; - - -/* AIS: I added these */ -extern int yukdebug; /* debug the code with yuk */ -extern int yukprofile; /* profile the code with yuk */ -extern int compucomecount; /* number of computed COME FROMs */ -extern int compucomesused; /* are computed COME FROMs used? */ -extern int multithread; /* is the program multithreaded? */ -extern int coreonerr; /* dump core on E778? */ -extern int optdebug; /* debug the optimizer */ -extern int flowoptimize; /* optimize program flow */ -extern int checkforbugs; /* check for bugs */ -extern int coopt; /* constant-output optimizer */ - -/* ick.h ends here */ diff --git a/ick.y b/ick.y deleted file mode 100644 index 391674c..0000000 --- a/ick.y +++ /dev/null @@ -1,437 +0,0 @@ -/***************************************************************************** - -NAME - ick.y -- grammar for the INTERCAL language - -DESCRIPTION - This YACC grammar parses the INTERCAL language by designed by Don R. Woods -and James M. Lyon. There are five syntax extensions over the original -INTERCAL-72 language; the COME FROM statement, the prefixed forms of the -WHIRL operator, and (AIS) the ABSTAIN FROM, COME FROM , -and ONCE/AGAIN forms. - -LICENSE TERMS - Copyright (C) 1996 Eric S. Raymond - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - -*****************************************************************************/ - -%{ -#include -#include -#include "sizes.h" -#include "ick.h" -#include "feh.h" -#include "lose.h" - -extern int yyerror(char*); - -/* Intervene our first-stage lexer. */ -extern int lexer(void); -#define yylex() lexer() - -static node *rlist; /* pointer to current right-hand node list */ -/*static node *llist;*/ /* pointer to current left-hand node list */ -static node *np; /* variable for building node lists */ - -extern int stbeginline; /* line number of last seen preamble */ -static int thisline; /* line number of beginning of current statement */ - -extern int mark112; /* AIS: Mark the tuple for W112 when it's created. */ - -static tuple *splat(void); - -#define GETLINENO \ - {if (stbeginline < 0) thisline = -stbeginline; \ - else {thisline = stbeginline; stbeginline = 0;}} - -#define ACTION(x, nt, nn) \ - {x = newtuple(); x->type = nt; x->lineno = thisline; x->u.node = nn;} -#define TARGET(x, nt, nn) \ - {x = newtuple(); x->type = nt; x->lineno = thisline; x->u.target = nn;} -#define ACTARGET(x, nt, nn, nn2)\ - {x = newtuple(); x->type = nt; x->lineno = thisline;\ - x->u.node = nn; x->u.target = nn2;} -/* AIS : The macro above was added for ABSTAIN expr FROM. */ -#define NEWFANGLED mark112 = 1; /* AIS: Added the mention of mark112 */ \ - if (traditional) lose(E111,yylineno,(char*)NULL); else - -#define DESTACKSE1 sparkearsstack[sparkearslev--/32] >>= 1 -#define DESTACKSPARKEARS DESTACKSE1; DESTACKSE1 - -%} - -%start program - -%union -{ - int numval; /* a numeric value */ - tuple *tuple; /* a code tuple */ - node *node; /* an expression-tree node */ -} - -/* - * Don't change this statement token list gratuitously! - * Some code in feh.c depends on GETS being the least - * statement type and on the order of the ones following. - * AIS: Added FROM, MANYFROM, TRY_AGAIN, COMPUCOME. - * AIS: COME_FROM now merged with the label following it, - * to distinguish it from COMPUCOME, in the lexer. This changes - * the parser somewhat. - */ -%token GETS RESIZE NEXT GO_AHEAD GO_BACK FORGET RESUME STASH RETRIEVE IGNORE -%token REMEMBER ABSTAIN REINSTATE -%token DISABLE ENABLE MANYFROM GIVE_UP READ_OUT WRITE_IN -%token COME_FROM -%token COMPUCOME TRY_AGAIN FROM - -/* AIS: ONCE and AGAIN added, for multithread support */ -%token MAYBE DO PLEASE NOT ONCE AGAIN MESH ONESPOT TWOSPOT TAIL HYBRID -%token MINGLE SELECT /* AIS: SPARK EARS */ SUB BY BADCHAR - -%token NUMBER UNARY OHOHSEVEN GERUND LABEL -%token INTERSECTION - -/* - * These are not tokens returned by the lexer, but they are used as - * tokens elsewhere. We define them here to insure that the values - * will not conflict with the other tokens. It is important that - * WHIRL through WHIRL5 be a continuous sequence. - */ -/* AIS: Added new tokens for optimizer output */ -%token SPLATTERED -%token C_AND C_OR C_XOR C_NOT C_NNAND C_ISNONZERO C_LSHIFT C_LSHIFT2 -%token C_LSHIFT8 C_LSHIFTIN1 C_RSHIFT C_AND1ADD1 C_2SUBAND1 C_1PLUS C_2MINUS -%token C_XORGREATER C_RSHIFTBY C_NOTEQUAL -%token AND OR XOR FIN MESH32 WHIRL WHIRL2 WHIRL3 WHIRL4 WHIRL5 - -%type expr varlist variable constant lvalue inlist outlist -%type subscr byexpr scalar array initem outitem sublist -%type unambig subscr1 sublist1 oparray osubscr osubscr1 -%type perform mtperform -%type please preftype - -%nonassoc OPENEARS OPENSPARK CLOSEEARS CLOSESPARK -%nonassoc HIGHPREC -/* AIS: I reversed this precedence, to sort out the near-ambiguity */ - -%% /* beginning of rules section */ - -/* A program description consists of a sequence of statements */ -program : /* EMPTY */ - | program command - ; - -/* - * Each command consists of an optional label, followed by a preamble, - * followed by an optional probability, followed by the statement body. - * Negative exechance values indicate initial abstentions, and will be - * made positive before code is emitted. - * AIS: An exechance above 100 indicates a MAYBE situation (e.g. 4545 - * means MAYBE DO %45 ...). This means %0 should be illegal. I modified - * all these to allow for MAYBE. - */ -command : please mtperform - {$2->label = 0; $2->exechance = $1 * 100;} - | please OHOHSEVEN mtperform - {$3->label = 0; $3->exechance = $1 * $2;} - | LABEL please mtperform - {checklabel($1); $3->label = $1; $3->exechance = $2 * 100;} - | LABEL please OHOHSEVEN mtperform - {checklabel($1); $4->label = $1; $4->exechance = $2 * $3;} - | error - {lose(E017, yylineno, (char *)NULL);} - ; -/* - * AIS: added for the ONCE/AGAIN qualifiers. It copies a pointer to the tuple, - * so command will set the values in the original tuple via the copy. - */ - -mtperform : perform - {$1->onceagainflag = onceagain_NORMAL; $$ = $1;} - | perform ONCE - {NEWFANGLED {$1->onceagainflag = onceagain_ONCE; $$ = $1;}} - | perform AGAIN - {NEWFANGLED {$1->onceagainflag = onceagain_AGAIN; $$ = $1;}} - -/* There are two (AIS: now four) forms of preamble returned by the lexer */ -please : DO {GETLINENO; $$ = 1;} - | DO NOT {GETLINENO; $$ = -1;} - | MAYBE {NEWFANGLED {GETLINENO; $$ = 101;}} - | MAYBE NOT {NEWFANGLED {GETLINENO; $$ = -101;}} - ; - -/* Here's how to parse statement bodies */ -perform : lvalue GETS expr {ACTION($$, GETS, cons(GETS,$1,$3));} - | array GETS byexpr {ACTION($$, RESIZE, cons(RESIZE,$1,$3));} - | LABEL NEXT {TARGET($$, NEXT, $1);} - | FORGET expr {ACTION($$, FORGET, $2);} - | RESUME expr {ACTION($$, RESUME, $2);} - | STASH varlist {ACTION($$, STASH, rlist);} - | RETRIEVE varlist {ACTION($$, RETRIEVE, rlist);} - | IGNORE varlist {ACTION($$, IGNORE, rlist);} - | REMEMBER varlist {ACTION($$, REMEMBER, rlist);} - | ABSTAIN FROM LABEL {stbeginline=0; TARGET($$, ABSTAIN, $3);} - | ABSTAIN FROM gerunds {ACTION($$, DISABLE, rlist);} - | ABSTAIN expr FROM LABEL {/* AIS */ NEWFANGLED {stbeginline=0; ACTARGET($$, FROM, $2, $4);}} - | ABSTAIN expr FROM gerunds {/* AIS */ NEWFANGLED {$$ = newtuple(); $$->type = MANYFROM; $$->lineno = thisline; \ - {node* tempnode=newnode(); $$->u.node = tempnode; tempnode->lval=$2; tempnode->rval=rlist; tempnode->opcode=MANYFROM;}}} - | REINSTATE LABEL {stbeginline=0; TARGET($$, REINSTATE, $2);} - | REINSTATE gerunds {ACTION($$, ENABLE, rlist);} - | WRITE_IN inlist {ACTION($$, WRITE_IN, $2);} - | READ_OUT outlist {ACTION($$, READ_OUT, $2);} - | GIVE_UP {ACTION($$, GIVE_UP, 0);} - | GO_AHEAD {/* AIS */ NEWFANGLED {ACTION($$, GO_AHEAD, 0);}} - | GO_BACK {/* AIS */ NEWFANGLED {ACTION($$, GO_BACK, 0);}} - | TRY_AGAIN {/* AIS */ NEWFANGLED {ACTION($$,TRY_AGAIN,0);}} - | COME_FROM {/* AIS: Modified this */ NEWFANGLED {TARGET($$,COME_FROM,$1);}} - | COMPUCOME expr {/* AIS */NEWFANGLED {ACTION($$,COMPUCOME,$2); compucomesused=1;}} - | BADCHAR {yyclearin; $$ = splat();} - | error {yyclearin; $$ = splat();} - ; - -/* gerund lists are used by ABSTAIN and REINSTATE */ -gerunds : GERUND - {rlist = np = newnode(); np->constant = $1;} - | gerunds INTERSECTION GERUND - { - np->rval = newnode(); - np = np->rval; - np->constant = $3; - } - ; - -/* OK, here's what a variable reference looks like */ -variable: scalar | array; - -lvalue : scalar | subscr; - -scalar : ONESPOT NUMBER - { - $$ = newnode(); - $$->opcode = ONESPOT; - $$->constant = intern(ONESPOT, $2); - } - | TWOSPOT NUMBER - { - $$ = newnode(); - $$->opcode = TWOSPOT; - $$->constant = intern(TWOSPOT, $2); - } - ; - -array : TAIL NUMBER - { - $$ = newnode(); - $$->opcode = TAIL; - $$->constant = intern(TAIL, $2); - } - | HYBRID NUMBER - { - $$ = newnode(); - $$->opcode = HYBRID; - $$->constant = intern(HYBRID, $2); - } - ; - -/* Array with unary operator is a special intermediate case; these - nodes will be rearranged when the subscript list is added */ -oparray : TAIL UNARY NUMBER - { - $$ = newnode(); - $$->opcode = $2; - $$->rval = newnode(); - $$->rval->opcode = TAIL; - $$->rval->constant = intern(TAIL, $3); - } - | HYBRID UNARY NUMBER - { - $$ = newnode(); - $$->opcode = $2; - $$->rval = newnode(); - $$->rval->opcode = HYBRID; - $$->rval->constant = intern(HYBRID, $3); - } - ; - -/* And a constant looks like this */ -constant: MESH NUMBER - { - /* enforce the 16-bit constant constraint */ - if ((unsigned int)$2 > Max_small) - lose(E017, yylineno, (char *)NULL); - $$ = newnode(); - $$->opcode = MESH; - $$->constant = $2; - } - ; - -/* variable lists are used in STASH, RETRIEVE, IGNORE, REMEMBER */ -varlist : variable {rlist = np = $1;} - | varlist INTERSECTION variable {np = np->rval = $3; - /* newnode(); */ } - ; - -/* scalars and subscript exprs are permitted in WRITE IN lists */ -/* new: arrays are also permitted to allow for bitwise I/0 */ -initem : scalar | subscr | array; -inlist : initem INTERSECTION inlist {$$=cons(INTERSECTION,$1,$3);} - | initem {$$=cons(INTERSECTION,$1,0);} - ; - -/* scalars, subscript exprs & constants are permitted in READ OUT lists */ -/* new: arrays are also permitted to allow for bitwise I/0 */ -outitem : scalar | subscr | constant | array; -outlist : outitem INTERSECTION outlist {$$=cons(INTERSECTION,$1,$3);} - | outitem {$$=cons(INTERSECTION,$1,0);} - ; - -/* Now the gnarly part -- expression syntax */ - -/* Support array dimension assignment */ -byexpr : expr BY byexpr {$$ = cons(BY, $1, $3);} - | expr {$$ = cons(BY, $1, 0);} - ; - -/* Support array subscripts (as lvalues) */ -subscr : subscr1 {$$ = $1;} - | array SUB sublist {$$ = cons(SUB, $1, $3);} - ; -subscr1 : array SUB sublist1 {$$ = cons(SUB, $1, $3);} - ; -sublist : unambig sublist {$$ = cons(INTERSECTION, $1, $2);} - | unambig sublist1 {$$ = cons(INTERSECTION, $1, $2);} - ; -sublist1: subscr1 {$$ = cons(INTERSECTION, $1, 0);} - | osubscr1 {$$ = cons(INTERSECTION, $1, 0);} - | unambig %prec HIGHPREC {$$ = cons(INTERSECTION, $1, 0);} - ; - -/* Unary operators with arrays act like arrays only in expressions */ -osubscr : osubscr1 {$$ = $1;} - | oparray SUB sublist - {$$ = $1; $$->rval = cons(SUB, $$->rval, $3);} - ; -osubscr1: oparray SUB sublist1 - {$$ = $1; $$->rval = cons(SUB, $$->rval, $3);} - ; - -/* here goes the general expression syntax */ -expr : unambig {$$ = $1;} - | unambig SELECT unambig {$$ = cons(SELECT, $1, $3);} - | unambig SELECT subscr {$$ = cons(SELECT, $1, $3);} - | unambig SELECT osubscr {$$ = cons(SELECT, $1, $3);} - | unambig MINGLE unambig {$$ = cons(MINGLE, $1, $3);} - | unambig MINGLE subscr {$$ = cons(MINGLE, $1, $3);} - | unambig MINGLE osubscr {$$ = cons(MINGLE, $1, $3);} - | subscr {$$ = $1;} - | osubscr {$$ = $1;} - ; - -preftype: MESH {$$=MESH; } | ONESPOT {$$=ONESPOT;} | TWOSPOT {$$=TWOSPOT;}; - -unambig : variable {$$ = $1;} - | constant {$$ = $1;} - - /* deal with the bizarre unary-op syntax */ - | preftype UNARY NUMBER - { - $$ = newnode(); - $$->opcode = $2; - $$->rval = newnode(); - $$->rval->opcode = $1; - if($1 == MESH) { - /* enforce the 16-bit constant constraint */ - if ((unsigned int)$3 > Max_small) - lose(E017, yylineno, (char *)NULL); - $$->rval->constant = $3; - } - else { - $$->rval->constant = intern($1, $3); - } - } - - /* Now deal with the screwy unary-op interaction with grouping */ - /* AIS: Modified to allow for maintenance of the SPARK/EARS stack */ - | eitherspark UNARY expr CLOSESPARK - { - $$ = newnode(); - $$->opcode = $2; - $$->rval = $3; - DESTACKSPARKEARS; - } - | eitherears UNARY expr CLOSEEARS - { - $$ = newnode(); - $$->opcode = $2; - $$->rval = $3; - DESTACKSPARKEARS; - } - - | eitherspark expr CLOSESPARK {$$ = $2; DESTACKSPARKEARS;} - | eitherears expr CLOSEEARS {$$ = $2; DESTACKSPARKEARS;} - ; - -eitherspark : OPENSPARK ; - | CLOSESPARK ; - ; - -eitherears : OPENEARS ; - | CLOSEEARS ; - ; - -%% - -static tuple *splat(void) -/* try to recover from an invalid statement. */ -{ - tuple *sp; - int tok, i; - extern bool re_send_token; - - /* - * The idea - * here is to skip to the next DO, PLEASE or label, then unget that token. - * which we can do with a tricky flag on the lexer (re_send_token). - */ - - /* fprintf(stderr,"attempting to splat at line %d....\n",yylineno); */ - for(i = 0,re_send_token = FALSE;;i++) { - tok = lexer(); - if (!tok) - { - re_send_token = TRUE; - tok = ' '; /* scanner must not see a NUL */ - break; - } - else if (tok == DO || tok == PLEASE || tok == LABEL - /* AIS */ || tok == MAYBE) { - re_send_token = TRUE; - break; - } - } - /* - fprintf(stderr,"found %d on line %d after %d other tokens.\n", - tok,yylineno,i); - */ - - /* generate a placeholder tuple for the text line */ - TARGET(sp, SPLATTERED, 0); - - return(sp); -} - -/* ick.y ends here */ diff --git a/ickspec b/ickspec new file mode 100644 index 0000000..704c76f --- /dev/null +++ b/ickspec @@ -0,0 +1,60 @@ +Name: intercal +Version: 0.26 +Release: 1 +URL: http://www.catb.org/~esr/intercal/ +Source: intercal-0.26.tar.gz +License: GPL +Group: Development/Languages +Summary: the language that kills the weak and drives mad the strong +BuildRoot: %{_tmppath}/%{name}-root + +%description +An implementation of the language INTERCAL, legendary for +its perversity and horribleness (this version adds COME FROM +for extra flavor). Comes with language manual and examples +including possibly the entire extant body of INTERCAL code. +Now supports i18n and l14n (to Ancient Roman locale only) +Now with fix patch by Donald Knuth. + +%prep +%setup -q + +%build +configure --prefix=/usr +make + +%clean +[ "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT" + +%install +[ "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT" +mkdir -p "$RPM_BUILD_ROOT"%{_bindir} +cp ick coopt.sh "$RPM_BUILD_ROOT"%{_bindir} +mkdir -p "$RPM_BUILD_ROOT"%{_libdir} +cp libick.a "$RPM_BUILD_ROOT"%{_libdir} +cp libickmt.a "$RPM_BUILD_ROOT"%{_libdir} +cp libyuk.a "$RPM_BUILD_ROOT"%{_libdir} +mkdir -p "$RPM_BUILD_ROOT"%{_includedir}/intercal-0.26 +cp lose.h abcess.h fiddle.h yuk.h "$RPM_BUILD_ROOT"%{_includedir}/intercal-0.26 + +%files +%doc README BUGS NEWS +%{_bindir}/ick +%{_libdir}/libick.a +%{_libdir}/libickmt.a +%{_libdir}/libyuk.a +%{_includedir}/intercal-0.26/lose.h +%{_includedir}/intercal-0.26/abcess.h +%{_includedir}/intercal-0.26/fiddle.h +%{_includedir}/intercal-0.26/yuk.h + +%changelog +* Wed Dec 31 2003 Eric S. Raymond 0.24-1 +- Non-root users can now build RPMs. + +# The following sets edit modes for GNU EMACS +# Local Variables: +# mode:rpm-spec +# End: + + diff --git a/ickspec.in b/ickspec.in new file mode 100644 index 0000000..74ee151 --- /dev/null +++ b/ickspec.in @@ -0,0 +1,60 @@ +Name: intercal +Version: @PACKAGE_VERSION@ +Release: 1 +URL: http://www.catb.org/~esr/intercal/ +Source: intercal-@PACKAGE_VERSION@.tar.gz +License: GPL +Group: Development/Languages +Summary: the language that kills the weak and drives mad the strong +BuildRoot: %{_tmppath}/%{name}-root + +%description +An implementation of the language INTERCAL, legendary for +its perversity and horribleness (this version adds COME FROM +for extra flavor). Comes with language manual and examples +including possibly the entire extant body of INTERCAL code. +Now supports i18n and l14n (to Ancient Roman locale only) +Now with fix patch by Donald Knuth. + +%prep +%setup -q + +%build +configure --prefix=/usr +make + +%clean +[ "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT" + +%install +[ "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT" +mkdir -p "$RPM_BUILD_ROOT"%{_bindir} +cp ick coopt.sh "$RPM_BUILD_ROOT"%{_bindir} +mkdir -p "$RPM_BUILD_ROOT"%{_libdir} +cp libick.a "$RPM_BUILD_ROOT"%{_libdir} +cp libickmt.a "$RPM_BUILD_ROOT"%{_libdir} +cp libyuk.a "$RPM_BUILD_ROOT"%{_libdir} +mkdir -p "$RPM_BUILD_ROOT"%{_includedir}/intercal-@PACKAGE_VERSION@ +cp lose.h abcess.h fiddle.h yuk.h "$RPM_BUILD_ROOT"%{_includedir}/intercal-@PACKAGE_VERSION@ + +%files +%doc README BUGS NEWS +%{_bindir}/ick +%{_libdir}/libick.a +%{_libdir}/libickmt.a +%{_libdir}/libyuk.a +%{_includedir}/intercal-@PACKAGE_VERSION@/lose.h +%{_includedir}/intercal-@PACKAGE_VERSION@/abcess.h +%{_includedir}/intercal-@PACKAGE_VERSION@/fiddle.h +%{_includedir}/intercal-@PACKAGE_VERSION@/yuk.h + +%changelog +* Wed Dec 31 2003 Eric S. Raymond 0.24-1 +- Non-root users can now build RPMs. + +# The following sets edit modes for GNU EMACS +# Local Variables: +# mode:rpm-spec +# End: + + diff --git a/intercal.el b/intercal.el deleted file mode 100644 index b5ab3a6..0000000 --- a/intercal.el +++ /dev/null @@ -1,592 +0,0 @@ -;;; intercal.el -- mode for editing INTERCAL code - -;; This mode was written by Eric S. Raymond -;; for the C-INTERCAL distribution, and is copyrighted by him 1992. Free -;; redistribution encouraged. Someday, maybe, this will be made part of GNU. -;; But probably not unless they take many mind-eroding drugs first. - -;; This mode provides abbrevs for C-INTERCAL's statements, including COME FROM. -;; These abbrevs are context-sensitive and will generate either verb or gerund -;; form as appropriate. The keys RET, ( and * are also bound in useful ways. - -;; The intercal-politesse-level adjustment purports to assist the hapless -;; INTERCAL programmer in meeting INTERCAL's Miss Manners requirement. In -;; INTERCAL-72 and C-INTERCAL releases after 0.7, no fewer than 1/5 and no -;; more than 1/3 of the program statements must contain a PLEASE to gratify -;; the iron whim of the INTERCAL compiler; this mode assists by randomly -;; expanding some fraction of the "do" abbrevs typed to PLEASE DO. -;; The intercal-politesse-level constant is the denominator of this fraction. - -;; AIS: I corrected the READ/WRITE, IN/OUT reversal independent of the correction -;; that happened from 0.22 to 0.24 (this code was originally based on the 0.22 -;; distribution and updated for 0.24 compatibility); this version is distributed -;; with C-INTERCAL 0.25. -;; -;; I also altered the code for ( so the user didn't have to go to the beginning -;; of the line, added C-c C-[a,c,r,s] for convenience when working with -;; constants, and added support for TRY AGAIN, ONCE, AGAIN, and Font Lock. -;; I added support for M-x compile so it could compile INTERCAL programs -;; correctly (assuming that ick has been installed). - -;; $Id: intercal.el,v 1.5 1996/11/14 04:02:00 esr Exp $ - -(defconst intercal-politesse-level 4 - "Fraction of DOs that are automagically expanded to PLEASE DO.") - -(defvar intercal-mode-map nil - "Keymap for INTERCAL mode.") -(if intercal-mode-map - nil - (setq intercal-mode-map (make-sparse-keymap)) - (define-key intercal-mode-map "\t" 'tab-to-tab-stop) - (define-key intercal-mode-map "\r" 'intercal-return) - (define-key intercal-mode-map "\C-J" 'intercal-return) - (define-key intercal-mode-map "\C-C\C-C" 'intercal-constant-convert) ;AIS - (define-key intercal-mode-map "\C-C\C-R" 'intercal-constant-radix-convert) ;AIS - (define-key intercal-mode-map "\C-C\C-S" 'intercal-char-constant-convert) ;AIS - (define-key intercal-mode-map "\C-C\C-A" 'intercal-string-array-convert) ;AIS - (define-key intercal-mode-map "\C-C\C-U" 'intercal-lnu) ;AIS - (define-key intercal-mode-map "(" 'intercal-paren) - (define-key intercal-mode-map "*" 'intercal-splat) - (define-key intercal-mode-map "\177" 'backward-delete-char-untabify) - ) - -(defvar intercal-mode-syntax-table nil - "Syntax table in use in Intercal-mode buffers.") - -(if intercal-mode-syntax-table - nil - (let ((table (make-syntax-table))) - (modify-syntax-entry ?\\ "\\" table) - (modify-syntax-entry ?+ "." table) - (modify-syntax-entry ?- "." table) - (modify-syntax-entry ?= "." table) - (modify-syntax-entry ?% "." table) - (modify-syntax-entry ?< "." table) - (modify-syntax-entry ?> "." table) - (modify-syntax-entry ?& "." table) - (modify-syntax-entry ?| "." table) - (modify-syntax-entry ?\' "\"" table) - (setq intercal-mode-syntax-table table))) - -(defvar intercal-mode-abbrev-table nil - "*Abbrev table in use in Intercal-mode buffers.") -(if intercal-mode-abbrev-table - nil - (define-abbrev-table 'intercal-mode-abbrev-table ()) - (define-abbrev intercal-mode-abbrev-table "pl" "PLEASE" nil) - (define-abbrev intercal-mode-abbrev-table "on" "ONCE" nil) ;AIS - (define-abbrev intercal-mode-abbrev-table "ag" "AGAIN" nil) ;AIS - (define-abbrev intercal-mode-abbrev-table "ne" "" 'intercal-ne-abbrev) - (define-abbrev intercal-mode-abbrev-table "fo" "" 'intercal-fo-abbrev) - (define-abbrev intercal-mode-abbrev-table "res" "" 'intercal-res-abbrev) - (define-abbrev intercal-mode-abbrev-table "st" "" 'intercal-st-abbrev) - (define-abbrev intercal-mode-abbrev-table "ret" "" 'intercal-ret-abbrev) - (define-abbrev intercal-mode-abbrev-table "ig" "" 'intercal-ig-abbrev) - (define-abbrev intercal-mode-abbrev-table "rem" "" 'intercal-rem-abbrev) - (define-abbrev intercal-mode-abbrev-table "ab" "" 'intercal-ab-abbrev) - (define-abbrev intercal-mode-abbrev-table "rei" "" 'intercal-rei-abbrev) - (define-abbrev intercal-mode-abbrev-table "gi" "" 'intercal-gi-abbrev) - (define-abbrev intercal-mode-abbrev-table "rea" "" 'intercal-rea-abbrev) - (define-abbrev intercal-mode-abbrev-table "wr" "" 'intercal-wr-abbrev) - (define-abbrev intercal-mode-abbrev-table "co" "" 'intercal-co-abbrev) - (define-abbrev intercal-mode-abbrev-table "do" "" 'intercal-do-abbrev) - (define-abbrev intercal-mode-abbrev-table "goa" "" 'intercal-goa-abbrev) ;AIS - (define-abbrev intercal-mode-abbrev-table "gob" "" 'intercal-gob-abbrev) ;AIS - (define-abbrev intercal-mode-abbrev-table "ma" "MAYBE" nil) ;AIS - (define-abbrev intercal-mode-abbrev-table "tr" "" 'intercal-tr-abbrev) ;AIS - (define-abbrev intercal-mode-abbrev-table "cal" "" 'intercal-cal-abbrev) ;AIS - ) - -(defun use-gerund () - (save-excursion - (beginning-of-line) - (or (looking-at ".*ABSTAIN") (looking-at ".*REINSTATE")))) - -(defmacro make-intercal-abbrev (sym gerund verb) - (list 'defun sym '() (list 'insert (list 'if '(use-gerund) gerund verb)))) - -(make-intercal-abbrev intercal-ne-abbrev "NEXTING" "NEXT") -(make-intercal-abbrev intercal-fo-abbrev "FORGETTING" "FORGET") -(make-intercal-abbrev intercal-res-abbrev "RESUMING" "RESUME") -(make-intercal-abbrev intercal-st-abbrev "STASHING" "STASH") -(make-intercal-abbrev intercal-ret-abbrev "RETRIEVING" "RETRIEVE") -(make-intercal-abbrev intercal-ig-abbrev "IGNORING" "IGNORE") -(make-intercal-abbrev intercal-rem-abbrev "REMEMBERING" "REMEMBER") -(make-intercal-abbrev intercal-ab-abbrev "ABSTAINING" "ABSTAIN FROM") -(make-intercal-abbrev intercal-rei-abbrev "REINSTATING" "REINSTATE") -(make-intercal-abbrev intercal-gi-abbrev "GIVING UP" "GIVE UP") -(make-intercal-abbrev intercal-rea-abbrev "READING OUT" "READ OUT") -(make-intercal-abbrev intercal-wr-abbrev "WRITING IN" "WRITE IN") -(make-intercal-abbrev intercal-co-abbrev "COMING FROM" "COME FROM") -(make-intercal-abbrev intercal-tr-abbrev "TRYING AGAIN" "TRY AGAIN") ;AIS -(make-intercal-abbrev intercal-cal-abbrev "CALCULATING" "cal") ;AIS -(make-intercal-abbrev intercal-goa-abbrev "GOING AHEAD" "GO AHEAD") ;AIS -(make-intercal-abbrev intercal-gob-abbrev "GOING BACK" "GO BACK") ;AIS - -(defun intercal-do-abbrev () - "Emit a DO (usually). Occasionally, emit PLEASE DO." - (insert - (if (zerop (% (random) intercal-politesse-level)) - "PLEASE DO" - "DO") - )) - -(defun intercal-return () - "Insert LFD + tab, to bring us back to code-indent level." - (interactive) - (if (eolp) (delete-horizontal-space)) - (insert "\n") - (delete-horizontal-space) ;AIS - (tab-to-tab-stop) - (if intercal-lnu-mode (intercal-lnu)) ;AIS - ) - -;; AIS: This is the old intercal-paren function, modified slightly. -(defun intercal-paren-2 () - "Generate an INTERCAL label if at start of line. Otherwise type '('." - (interactive) - (if (and (bolp) (looking-at "[ \t]\\|$")) - (insert (format "(%d)" - (save-restriction - (widen) - (save-excursion - (beginning-of-line) - (1+ (count-lines 1 (point)))))) - "\t") - (insert "("))) - -;; AIS: I wrote this as a better intercal-paren-2. -(defun intercal-paren () - "Generate an INTERCAL label or (." - (interactive) - (save-excursion - (beginning-of-line) - (if (looking-at "^[ \t]*$") - (delete-horizontal-space))) - (intercal-paren-2) -) - -(defun intercal-splat () - "Begin an INTERCAL comment." - (interactive) - (insert "*") - (forward-char -1) - (delete-horizontal-space) - (forward-char 1) - (insert " ") -) - -;; AIS: Added new abbreviations (marked ;AIS above), expanded the documentation. -(defun intercal-mode () - "A major editing mode for the language Intercal. -It activates the following abbrevs (each one appropriately modified to a -gerund if it occurs on a line with ABSTAIN or REINSTATE). - -ab ABSTAIN co COME FROM fo FORGET -gi GIVE UP ig IGNORE ne NEXT -rea READ OUT rei REINSTATE rem REMEMBER -res RESUME ret RETRIEVE st STASH -wr WRITE IN pl PLEASE tr TRY AGAIN -on ONCE ag AGAIN ma MAYBE -goa GO AHEAD gob GO BACK do DO, or sometimes PLEASE DO -cal CALCULATING (only as a gerund) - -Carriage return takes you to the first tab stop (code indent level). -Certain other single keys are bound to things which may or may not be useful. -You may consider discovering these one of the pleasures awaiting you in your -discovery of INTERCAL's unique ambience. - -Typing C-c C-c converts a constant in the form # to a legal -INTERCAL constant (such as #45 or #65280$#65280). If the answer is a mingled -one, it is only valid in binary. - -For programmers who prefer TRI-INTERCAL, another constant conversion function -is given. Typing a number in the format (say) #3r2210210011 and pressing -C-c C-r will result in a (possibly mingled) decimal constant that works in -base 3. This works likewise for other bases, say #6r520314 would generate a -base-6 constant. - -For binary I/O, C-c C-s is provided. This takes a constant of the form -#? and converts it into a constant of the form #. -With a prefix argument (as in C-u C-c C-s), the output has its bottom 8 bits -reversed, and so is suitable for use with semi-standard output routines. - -For longer strings, C-c C-a can produce sections of programs that store -strings in arrays. The command can give help on itself. - -For information about C-c C-u and LNU, see `intercal-lnu-mode'. - -Turning on Intercal mode calls the value of the variable intercal-mode-hook -with no args, if that value is non-nil." - (interactive) - (kill-all-local-variables) - (use-local-map intercal-mode-map) - (setq major-mode 'intercal-mode) - (setq mode-name "Intercal") - (setq local-abbrev-table intercal-mode-abbrev-table) - (set-syntax-table intercal-mode-syntax-table) - (make-local-variable 'comment-start) - (setq comment-start "* ") - (make-local-variable 'comment-end) - (setq comment-end "") - (make-local-variable 'comment-column) - (setq comment-column 32) - (make-local-variable 'require-final-newline) - (setq require-final-newline t) - (setq abbrev-mode t) - (setq abbrev-all-caps t) - (run-hooks 'intercal-mode-hook)) - -(provide 'intercal-mode) - -;; AIS: I wrote everything from here down. - -;; Line Number Update minor mode. -(defvar intercal-lnu-mode nil "Whether intercal-lnu-mode is on or not.") -(make-variable-buffer-local 'intercal-lnu-mode) - -(defvar intercal-lnu-mode-initialized nil "Whether intercal-lnu-mode is initialized.") - -(defun intercal-lnu-mode (arg) -"Minor mode used primarily when editing INTERCAL. - (LNU stands for Line Number Update). -The mode tries to ensure that all line labels below 1000 are equal to the line -numbers of the lines they refer to. Renumbering is done when RET is pressed, the -mode is turned on, or C-c C-u is pressed. This mode has no effect unless -intercal-mode is also active, or its functions are called. It is inadvisable to -turn LNU mode on in long files, because line number updates take a long time to -run in long files. Instead, leave LNU mode off and use `intercal-lnu' (C-c C-u). -Labels greater than or equal to 1000 are ignored because they probably indicate -library functions." - (interactive "P") - (setq intercal-lnu-mode - (if (null arg) (not intercal-lnu-mode) (> (prefix-numeric-value arg) 0))) - (force-mode-line-update) - (if intercal-lnu-mode (intercal-lnu)) - (if (not intercal-lnu-mode-initialized) (intercal-lnu-initialize)) -) - -(defun intercal-lnu-initialize () -"Initializes INTERCAL LNU mode. See `intercal-lnu-mode'." - (if (not intercal-lnu-mode-initialized) - (setq minor-mode-alist (cons '(intercal-lnu-mode " LNU") minor-mode-alist) - intercal-lnu-mode-initialized t)) -) - -(defsubst cadar (x) - "Return the car of the cdr of the car of X." - (car (cdr (car x)))) - -(defun intercal-lnu () -"Updates line numbers in an INTERCAL program. See `intercal-lnu-mode'. This -function will run even if intercal-lnu-mode is off, but intercal-mode must be -on. Running this function manually (with C-c C-u) rather than automatically is -a good idea in long files, which take a long time to update." - (interactive) - (if (equal major-mode 'intercal-mode) - (save-excursion - (let ((line-number-update-list nil)) - (goto-char (point-min)) - (while (re-search-forward "^(\\([0-9]+\\))" nil t) - (if (< (string-to-number (match-string-no-properties 1)) 1000) - (setq line-number-update-list (cons - (list - (string-to-number (match-string-no-properties 1)) - (count-lines 1 (point))) - line-number-update-list)))) - (while line-number-update-list - (intercal-lnu-individual (caar line-number-update-list) (cadar line-number-update-list)) - (setq line-number-update-list (cdr line-number-update-list)))) - (goto-char (point-min)) - (while (search-forward "LNUChange:" nil t) - (replace-match ""))) - (error "The buffer is not in intercal-mode")) -) - -(defun intercal-lnu-individual (oldlabel newlabel) -"Updates all occurrences of one label in an INTERCAL program for another." - (save-excursion - (goto-char (point-min)) - (while (search-forward (concat "(" (number-to-string oldlabel) ")") nil t) - (replace-match (concat "(LNUChange:" (number-to-string newlabel) ")")))) -) - -;; Font Lock settings. -;; We use keyword-face for commands, builtin-face for gerunds, constant-face -;; for meshes and mingle-mesh constants, and comment-face for initially -;; abstained lines (because these are usually comments, and anyway it's good -;; for them to stand out). Only the first line of multiline comments is marked. -;; MAYBE lines aren't marked because that's a big giveaway that the line won't -;; be abstained from all program. -(defvar intercal-font-lock-keywords - '(("^\\(([0-9]+)\\|\\)[ \t]*\\(PLEASE DO\\|DO\\|PLEASE\\)[ \t]*\\(NOT\\|N'T\\).*$" . font-lock-comment-face) - ("\\<\\(ABSTAIN\\|GIVE UP\\|READ OUT\\|RESUME\\|WRITE IN\\|COME\\|FROM\\|IGNORE\\|REINSTATE\\|RETRIEVE\\|PLEASE\\|DO\\|MAYBE\\|ONCE\\|AGAIN\\|FORGET\\|NEXT\\|REMEMBER\\|STASH\\|DON'T\\|NOT\\|TRY AGAIN\\|GO AHEAD\\|GO BACK\\)\\>" . font-lock-keyword-face) - ("\\<\\(ABSTAINING\\|GIVING UP\\|READING OUT\\|RESUMING\\|WRITING IN\\|COMING\\|IGNORING\\|REINSTATING\\|RETRIEVING\\|FORGETTING\\|NEXTING\\|REMEMBERING\\|STASHING\\|TRYING AGAIN\\|CALCULATING\\|GOING AHEAD\\|GOING BACK\\)\\>" . font-lock-builtin-face) - ("[.,:;][0-9]+" . font-lock-variable-name-face) - ("#[0-9]+\\(\\$#[0-9]+\\|\\)" . font-lock-constant-face)) - "Default expressions to highlight in Intercal mode.") - -;; Find an error message produced by ick. If the famous RESUBNIT spelling error -;; is ever corrected, this will need to be corrected too. -(defvar intercal-error-regexp - '("ICL[0-9][0-9][0-9][IW].*\n[ \t]*ON THE WAY TO \\([0-9]+\\)\n[ \t]*\\(CORRECT\\|RECONSIDER\\) SOURCE AND RESUBNIT$" nil 1) - "Regexp that identifies an INTERCAL error message, and the file and line number positions in it.") - -;; Detect the line with which ick was invoked, so the filename used can be -;; used by Emacs' compile-mode to find the error. This will need to be changed -;; if command-line arguments to ick other than letters are allowed. -(defvar intercal-file-regexp '(".*ick \\(-[a-zA-Z]+ \\)*\\(.*i\\)$" 2) - "Regexp that identifies the line with which ick was invoked, and the filename it was used on.") - -;; Helper function for the binary I/O routines. -(defun intercal-reverse-bits-if-nonnull (flag num) - "Returns num if flag is null, or num with bits reversed if flag is nonnull." - (if (null flag) num - (let ((ans 0) (count 8) (num1 num)) - (while (> count 0) - (setq ans (* ans 2)) - (if (= (% num1 2) 1) (setq ans (1+ ans))) - (setq num1 (/ num1 2)) - (setq count (1- count))) - ans)) -) - -;; Internal memory for inter-function communication. Yes, I know it's -;; unLispish to do this sort of thing, and breaks if the user tries to -;; convert two strings simultaneously. -(defvar intercal-string-array-convert-options-buffer-used nil - "Variable that keeps track of a buffer used to display options -for intercal-string-array-convert.") - -;; Function that inputs options for intercal-string-array-convert. -;; If the user asks for help, it pops up a help buffer and returns nil. -;; Its documentation string is the information required to appear in -;; the help buffer. -(defun intercal-string-array-convert-options (opts) - "Options for use with intercal-string-array-convert: - ? Display the list of options - 1 Pack the string one char/element (default) - 2 Pack the string two chars/element (unimplemented) - 4 Pack the string four chars/element (unimplemented) - $ Pack the string in mingled format (default) - so \"abcd\" would become \"a$b\"$\"c$d\" - < Pack the string in shifted format - (concatentate the codes for each character) - R Bit-reverse each character code (default) - W Don't bit-reverse each character code - , Treat entered number as a tail array (default) - ; Treat entered number as a hybrid array - 0 Each character code is based at 0 (default) - + Each character code is based at the previous code (unimplemented)" - (interactive "sOptions: (type ?[RET] for help)") - (if (string= opts "?") - (progn - (setq intercal-string-array-convert-options-buffer-used t) - (with-output-to-temp-buffer "*Options*" - (princ (documentation 'intercal-string-array-convert-options))) - nil) - opts) -) - -;; The displaying of the help buffer is done by -;; intercal-string-array-convert-options, if required. This function holds -;; tests to put the display back as it was in two possible common situations -;; involving the user asking for help (one window active, two windows active). -(defun intercal-string-array-convert (in arr &optional opts) - "Generate INTERCAL code to initialize an array with information -that makes it suitable for use as a string. For more information, -run the command and enter a question mark for the options." - (interactive "*MEnter string to convert:\nnEnter number of array required:") - (let ((cb (current-buffer)) (w1p (one-window-p)) (ow nil)) - (if (null w1p) (setq ow other-window-scroll-buffer)) - (while (null opts) - (setq opts (call-interactively 'intercal-string-array-convert-options))) - (if intercal-string-array-convert-options-buffer-used - (progn - (select-window (get-buffer-window cb)) - (if w1p - (delete-other-windows) - (switch-to-buffer-other-window ow)))) - (setq intercal-string-array-convert-options-buffer-used nil)) - (let ((packing 1) (basis nil) (arrtype ",") (revbits t) (mingle t)) - (while (> (length opts) 0) - (if (string= (substring opts 0 1) "1") (setq packing 1) - (if (string= (substring opts 0 1) "2") (error "Unimplemented") ;(setq packing 2) ;unimplemented - (if (string= (substring opts 0 1) "4") (error "Unimplemented") ;(setq packing 4) ;unimplemented - (if (string= (substring opts 0 1) "$") (setq mingle t) ;unimplemented, but has no effect on option 1 - (if (string= (substring opts 0 1) "<") (setq mingle nil);unimplemented, but has no effect on option 1 - (if (string= (substring opts 0 1) "R") (setq revbits t) - (if (string= (substring opts 0 1) "W") (setq revbits nil) - (if (string= (substring opts 0 1) ",") (setq arrtype ",") - (if (string= (substring opts 0 1) ";") (setq arrtype ";") - (if (string= (substring opts 0 1) "0") (setq basis nil) - (if (string= (substring opts 0 1) "+") (error "Unimplemented") ;(setq basis t) ;unimplemented - (error "Invalid option")))))))))))) - (setq opts (substring opts 1))) - (intercal-return) - (intercal-do-abbrev) - (let ((al (/ (+ (length in) packing -1) packing))) - (insert " " arrtype (int-to-string arr) " <- #" (int-to-string al))) - (let ((lastchar 0) (arrind 1)) - (while (> (length in) 0) - (intercal-return) - (intercal-do-abbrev) - (insert " " arrtype (int-to-string arr) " SUB #" (int-to-string arrind)) - (insert " <- #?" (substring in 0 1)) - (setq in (substring in 1)) - (intercal-char-constant-convert revbits)))) -) - -;; Converts char to int by subtracting ! and adding 33. -(defun intercal-char-constant-convert (arg) - "Convert a constant of the form #? into a legal -INTERCAL constant representing the character's character code. -With a prefix argument, gives bit-reversed output. This routine -is intended for use with the binary I/O capabilities of INTERCAL." - (interactive "*P") ;Check prefix arg, not read-only - (save-excursion - (if (re-search-backward "#" (line-beginning-position) t) - (if (re-search-forward "#\\?\\(.\\)" (line-end-position) t) - (replace-match - (concat "#" (int-to-string (intercal-reverse-bits-if-nonnull arg - (+ 33 (- (string-to-char - (match-string-no-properties 1)) ?!))))))))) -) - - -;; This is simpler than the next function because we're -;; converting from the target base, so it's simply a case -;; of selecting every second character if we need to produce -;; a mingled result -(defun intercal-constant-radix-convert () - "Convert a constant of the form #r -to a legal TRI-INTERCAL constant in that base. If the number is -sufficiently small, it is converted to decimal; otherwise, it is -converted to two mingled decimal constants." - (interactive "*") - (save-excursion - (if (re-search-backward "#" (line-beginning-position) t) - (if (re-search-forward "#\\([2-7]\\)r\\([0-6]+\\)" - (line-end-position) t) - (replace-match - (let ((radix (string-to-number - (match-string-no-properties 1) 10)) - (str (match-string-no-properties 2)) (slen 0) - (mingle1 "") (mingle2 "") (num1 0) (num2 0)) - (setq slen (length str)) - (if (or (<= (* radix slen) 32) ; Calculate max onespot length - (or (and (= radix 6) (= slen 6)) ;on these - (and (= radix 7) (= slen 5)))) ;three lines - (progn - (setq num1 (string-to-number str radix)) - (concat "#" (number-to-string num1))) - (progn - (while (/= 0 (length str)) - (setq mingle2 (concat (substring str -1) mingle2)) - (setq str (substring str 0 -1)) - (if (/= 0 (length str)) - (progn - (setq mingle1 (concat (substring str -1) mingle1)) - (setq str (substring str 0 -1))))) - (setq num1 (string-to-number mingle1 radix)) - (setq num2 (string-to-number mingle2 radix)) - (concat "#" (number-to-string num1) - "$#" (number-to-string num2))))))))) -) - -;; The following code needs a bit of explanation. INTERCAL -;; can handle constants up to 4294967295 (0xffffffff), but -;; Emacs's constants max out somewhere between 100 million -;; and 1 billion. So, when a high number is entered, the -;; code processes the last 6 digits (in whatever base the -;; number is entered in) separately from the rest of the -;; number. This ensures that the arithmetic routines never -;; overflow if the input is a valid integer in the range -;; 0-4294967295. The calculations used do not work for -;; higher numbers, but that doesn't matter because -;; INTERCAL wouldn't accept them. Constants higher than -;; 65535 are given in mingled form (e.g. #65280$#65280). -(defun intercal-constant-convert () - "Convert a constant of the form # to a -legal INTERCAL constant (#<16-bit decimal integer> or -#<16-bit decimal integer>$#<16-bit decimal integer>). -Decimal (#4294967295), octal (#037777777777) and -hex (#0xffffffff) formats are all supported." - (interactive "*") - (save-excursion - (if (re-search-backward "#" (line-beginning-position) t) - (if (re-search-forward "#\\(0?[xX]?\\)\\([0-9a-fA-F]+\\)" - (line-end-position) t) - (replace-match - (let ((str (match-string-no-properties 2)) - (strhi "0") (strlow "0") - (base (if (string= (match-string-no-properties 1) "") - 10 - (if (string= (match-string-no-properties 1) "0") - 8 16)))) - (if (<= (length str) 6) (setq strlow str) - (setq strlow (substring str -6) strhi (substring str 0 -6))) - (let ((num (string-to-number strlow base)) - (numhi (string-to-number strhi base))) - (if (and (<= num 65535) (string= strhi "0")) - (concat "#" (number-to-string num)) - (let ((mingle1 0) (mingle2 0) (count 16) (temp 0)) - (while (> count 0) - (progn - (setq temp (% num 4)) - (setq num (/ num 4)) - (if (= (% temp 2) 1) (setq mingle2 (+ mingle2 65536))) - (if (> temp 1) (setq mingle1 (+ mingle1 65536))) - (setq mingle1 (/ mingle1 2)) - (setq mingle2 (/ mingle2 2)) - (setq count (- count 1)) - (if (= count 13) - (setq num (+ num (* (/ (expt base 6) 64) numhi)))))) - (concat "#" (number-to-string mingle1) - "$#" (number-to-string mingle2)) - )))) - t t)))) -) - -;; This wraps around compilation-parse-errors in compile, and makes sure that -;; the first line of the compilation buffer is blank. This is to make the -;; call of ick (which is needed to determine the source file) look like an -;; error message rather than a compiler call. -(defun intercal-error-wrap (limit-search find-at-least) - "Parse the current buffer as ick error messages. This just wraps around -'compilation-parse-errors'. See variable 'compilation-parse-errors-function' -for the interface it uses." - (save-excursion - (beginning-of-buffer) - (if (looking-at "^$") nil (newline))) - (compilation-parse-errors limit-search find-at-least) -) - -(require 'compile) ;Now a prerequisite for intercal.el, so its variables can be - ;changed to INTERCAL values upon loading an INTERCAL file - -;; This hook changes settings in fontlock and compile, so that they -;; recognize INTERCAL syntax and ick error messages. Default options to -;; ick are to optimize, but I chose not to give -b as a default (because -;; it spoils the fun). I'm slightly tempted to use -m as default, but -;; I'm not sure I'm that evil, and I left -f out for the time being because -;; it's something of a radical change to the output. -(add-hook 'intercal-mode-hook - (function (lambda () - (make-local-variable 'font-lock-defaults) - (setq font-lock-defaults '(intercal-font-lock-keywords t)) - (make-local-variable 'compilation-error-regexp-alist) - (setq compilation-error-regexp-alist (cons intercal-error-regexp - compilation-error-regexp-alist)) - (make-local-variable 'compilation-file-regexp-alist) - (setq compilation-file-regexp-alist (cons intercal-file-regexp - compilation-file-regexp-alist)) - (make-local-variable 'compile-command) - (setq compile-command (concat "ick -O " (buffer-name))) - (make-local-variable 'compilation-parse-errors-function) - (setq compilation-parse-errors-function 'intercal-error-wrap)))) - -;; AIS: End of section I wrote. - -;;; intercal.el ends here diff --git a/intercal.spec.in b/intercal.spec.in deleted file mode 100644 index 74ee151..0000000 --- a/intercal.spec.in +++ /dev/null @@ -1,60 +0,0 @@ -Name: intercal -Version: @PACKAGE_VERSION@ -Release: 1 -URL: http://www.catb.org/~esr/intercal/ -Source: intercal-@PACKAGE_VERSION@.tar.gz -License: GPL -Group: Development/Languages -Summary: the language that kills the weak and drives mad the strong -BuildRoot: %{_tmppath}/%{name}-root - -%description -An implementation of the language INTERCAL, legendary for -its perversity and horribleness (this version adds COME FROM -for extra flavor). Comes with language manual and examples -including possibly the entire extant body of INTERCAL code. -Now supports i18n and l14n (to Ancient Roman locale only) -Now with fix patch by Donald Knuth. - -%prep -%setup -q - -%build -configure --prefix=/usr -make - -%clean -[ "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT" - -%install -[ "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT" -mkdir -p "$RPM_BUILD_ROOT"%{_bindir} -cp ick coopt.sh "$RPM_BUILD_ROOT"%{_bindir} -mkdir -p "$RPM_BUILD_ROOT"%{_libdir} -cp libick.a "$RPM_BUILD_ROOT"%{_libdir} -cp libickmt.a "$RPM_BUILD_ROOT"%{_libdir} -cp libyuk.a "$RPM_BUILD_ROOT"%{_libdir} -mkdir -p "$RPM_BUILD_ROOT"%{_includedir}/intercal-@PACKAGE_VERSION@ -cp lose.h abcess.h fiddle.h yuk.h "$RPM_BUILD_ROOT"%{_includedir}/intercal-@PACKAGE_VERSION@ - -%files -%doc README BUGS NEWS -%{_bindir}/ick -%{_libdir}/libick.a -%{_libdir}/libickmt.a -%{_libdir}/libyuk.a -%{_includedir}/intercal-@PACKAGE_VERSION@/lose.h -%{_includedir}/intercal-@PACKAGE_VERSION@/abcess.h -%{_includedir}/intercal-@PACKAGE_VERSION@/fiddle.h -%{_includedir}/intercal-@PACKAGE_VERSION@/yuk.h - -%changelog -* Wed Dec 31 2003 Eric S. Raymond 0.24-1 -- Non-root users can now build RPMs. - -# The following sets edit modes for GNU EMACS -# Local Variables: -# mode:rpm-spec -# End: - - diff --git a/lexer.l b/lexer.l deleted file mode 100644 index 4fabe88..0000000 --- a/lexer.l +++ /dev/null @@ -1,445 +0,0 @@ -%{ -/* - * NAME - * lexer.l -- source for the C-INTERCAL lexical analyzer. - * -LICENSE TERMS - Copyright (C) 1996 Eric S. Raymond - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ -#include -#include -#include -#include -#include "ick.h" -#include "y.tab.h" -#include "lose.h" - -/*#undef wchar_t*/ -/*#define wchar_t unsigned char*/ - -#ifndef yywrap -static int yywrap(void) -{ - return 1; -} -#endif /* yywrap */ - -#ifdef YYLINENO_BY_HAND -int yylineno = 1; -#endif /* YYLINENO_BY_HAND */ - -#ifdef MAIN -YYSTYPE yylval; -#endif /* MAIN */ - -char **textlines = NULL; -int textlinecount = 0; -int politesse = 0; -int stbeginline = 0; - -/* AIS: Sort out a grammar near-ambiguity */ -unsigned long sparkearsstack[SENESTMAX] = {0}; -int sparkearslev = 0; - -#ifdef FLEX_SCANNER -static char linebuf[YY_BUF_SIZE]; -#else /* FLEX_SCANNER */ -static char linebuf[YYLMAX]; -#endif /* FLEX_SCANNER */ - -static char *lineptr = linebuf; - -bool re_send_token = FALSE; - -int lexer(void); -static int myatoi(char *text); - -#define SETLINENO \ - {if (stbeginline == 0) stbeginline = yylineno; \ - else if (stbeginline < 0) stbeginline = 0;} - -/* AIS: Keep track of the spark/ears situation */ -#define STACKSPARKEARS(a) \ - if (sparkearslev+1>=SENESTMAX*32) lose(E281, yylineno, (char*) NULL); \ - sparkearslev++; sparkearsstack[sparkearslev/32]<<=1; \ - sparkearsstack[sparkearslev/32]+=a -#define CLEARSPARKEARSTACK {int i=SENESTMAX; \ - while(i--) sparkearsstack[i] = 0;} \ - sparkearslev = 0 - -/* - * The spectacular ugliness of INTERCAL syntax requires that the lexical - * analyzer have two levels. One, embedded in the getc() function, handles - * logical-line continuation and the ! abbrev, and stashes each logical - * line away in a buffer accessible to the code generator (this is necessary - * for the * construct to be interpreted correctly). The upper level is - * generated by lex(1) and does normal tokenizing. - */ - -#undef getc -int getc(FILE *fp) -{ - extern FILE* yyin; - - static bool bangflag = FALSE; - static bool backflag = FALSE; - - if (bangflag) - { - bangflag = FALSE; - /* *lineptr++ = '!'; */ - return('.'); - } - else if (backflag) /* converting ctrl-H (backspace) to two chars "^H" */ - { - backflag = FALSE; - /* *lineptr++ = '\b'; */ - return('H'); - } - else - { - int c; - char c_char; - /*fprintf(stderr,"about to fgetc(\045p)",(void*)fp);*/ - - (void)fread(&c_char,1,1,fp); - c = c_char; - /*fputc(c,stderr);*/ - if(feof(fp)) c=EOF; - - /*fprintf(stderr,"getc input a character: %c\n",c);*/ - - if (feof(yyin)) - { - *lineptr = '\0'; - return(EOF); - } -#ifdef BACKSLASH_CONTINUATION - else if (c == '\\') - { - do { - c = fgetc(fp); -#ifdef YYLINENO_BY_HAND - if( c == '\n' ) yylineno++; -#endif /* YYLINENO_BY_HAND */ - } while - (c != '\\' && isspace(c)); - } -#endif /* BACKSLASH_CONTINUATION */ - if (c == '!') - { - *lineptr++ = '!'; - bangflag = TRUE; - return(c = '\''); - } - else if (c == '\b') /* convert ctrl-H (backspace) to - two chars "^" and "H" so lex can take it */ - { - *lineptr++ = '\b'; - backflag = TRUE; - return(c = '^'); - } - else if (c == '\n') - { - *lineptr = '\0'; - lineptr = linebuf; - if (yylineno >= textlinecount) - { - textlinecount += ALLOC_CHUNK; - if (textlines) - textlines = realloc(textlines, - textlinecount * sizeof(char*)); - else - textlines = malloc(textlinecount * sizeof(char*)); - if (!textlines) - lose(E666, yylineno, (char *)NULL); - } - textlines[yylineno] = malloc(1 + strlen(linebuf)); - if (!textlines[yylineno]) - lose(E666, yylineno, (char *)NULL); - strcpy(textlines[yylineno], linebuf); -#ifdef YYLINENO_BY_HAND - yylineno++; -#endif /* YYLINENO_BY_HAND */ - return('\n'); - } - else - { -#ifdef ACCEPT_LOWERCASE - if (islower(c)) - c = toupper(c); -#endif /* ACCEPT_LOWERCASE */ - return(*lineptr++ = c); - } - } -} - -/* replace YY_INPUT so that it uses our getc function. */ -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - { \ - int c = getc(yyin); \ - if (c == EOF) { \ - if (ferror(yyin)) \ - YY_FATAL_ERROR("input in flex scanner failed"); \ - result = YY_NULL; \ - } else { \ - buf[0] = c; \ - result = 1; \ - } \ - } - -%} - -W [\ \t\n]* -D [0-9][\ \t\n0-9]* - -%% - -{D} {yylval.numval = myatoi(yytext); return(NUMBER);} -\. {return(ONESPOT);} -\: {return(TWOSPOT);} -\, {return(TAIL);} -\; {return(HYBRID);} -\# {return(MESH);} - -\$ | -\xA2 | -\xA3 | -\xA4 | -\xC2\xA2 | -\xC2\xA3 | -\xC2\xA4 | -\xE2\x82\xA0 | -\xE2\x82\xA1 | -\xE2\x82\xA2 | -\xE2\x82\xA3 | -\xE2\x82\xA4 | -\xE2\x82\xA5 | -\xE2\x82\xA6 | -\xE2\x82\xA7 | -\xE2\x82\xA8 | -\xE2\x82\xA9 | -\xE2\x82\xAA | -\xE2\x82\xAB | -\xE2\x82\xAC | -\xE0\xA7\xB2 | -\xE0\xA7\xB3 | -\xE0\xB8\xBF {return(MINGLE);} - -\~ {return(SELECT);} - -\& {yylval.numval = AND; return(UNARY);} -V {yylval.numval = OR; return(UNARY);} -"V^H-" | -\xE2\x88\x80 | -\? {yylval.numval = XOR; return(UNARY);} -\^ {yylval.numval = FIN; return(UNARY);} -@ {yylval.numval = WHIRL; return(UNARY);} -[2-5]{W}@ {yylval.numval = WHIRL + myatoi(yytext) - 1; return(UNARY);} - -\' {char temp = sparkearsstack[sparkearslev/32]&1; - STACKSPARKEARS(0); /* AIS: I added all mentions of - STACKSPARKEARS, OPEN\(SPARK\|EARS\), - CLOSE\(SPARK\|EARS\), - and CLEARSPARKEARSTACK */ - return(temp?OPENSPARK:CLOSESPARK);} -\" {char temp = sparkearsstack[sparkearslev/32]&1; - STACKSPARKEARS(1); - return(temp?CLOSEEARS:OPENEARS);} - -\({W}{D}\) {SETLINENO; yylval.numval = myatoi(yytext); return(LABEL);} - -DO {SETLINENO; CLEARSPARKEARSTACK; return(DO);} -FAC {SETLINENO; CLEARSPARKEARSTACK; return(DO);} -PLEASE {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(DO);} -PLACET {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(DO);} -PLEASE{W}DO {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(DO);} -PLACET{W}FACERE {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(DO);} -MAYBE {SETLINENO; CLEARSPARKEARSTACK; return(MAYBE);} -MAYBE{W}DO {SETLINENO; CLEARSPARKEARSTACK; return(MAYBE);} -MAYBE{W}PLEASE {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(MAYBE);} -MAYBE{W}PLEASE{W}DO {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(MAYBE); - /* AIS: I added all the MAYBE cases. It seems that MAYBE - has no simple Latin synonym. */} - -NOT {return(NOT);} -N\'T {return(NOT);} -NON {return(NOT);} -ONCE {return(ONCE);} -QUONDAM {return(ONCE);} -AGAIN {return(AGAIN);} -ITERUM {return(AGAIN);} - -\%{W}{D} {yylval.numval = myatoi(yytext); - if (yylval.numval && yylval.numval < 100) - return(OHOHSEVEN); - else - lose(E017, yylineno, (char *)NULL);} -SUB {return(SUB);} -MULTIPLICATUS{W}A | -BY {return(BY);} - -\<- {return(GETS);} -CALCULANDUM | -CALCULATING {yylval.numval = GETS; return(GERUND);} - -DEINDE | -NEXT {stbeginline = 0; return(NEXT);} -PROXIMANDUM | -NEXTING {yylval.numval = NEXT; return(GERUND);} -ALIENERE | -FORGET {return(FORGET);} -ALIENENDUM | -FORGETTING {yylval.numval = FORGET; return(GERUND);} -RECOLERE | -RESUME {return(RESUME);} -RECOLERENDUM | -RESUMING {yylval.numval = RESUME; return(GERUND);} -EXUERE | -STASH {return(STASH);} -EXUENDUM | -STASHING {yylval.numval = STASH; return(GERUND);} -INUERE | -RETRIEVE {return(RETRIEVE);} -INUENDUM | -RETRIEVING {yylval.numval = RETRIEVE; return(GERUND);} -DISSIMULARE | -IGNORE {return(IGNORE);} -DISSIMULANDUM | -IGNORING {yylval.numval = IGNORE; return(GERUND);} -MEMINISSE | -REMEMBER {return(REMEMBER);} -MEMINISSENDUM | -REMEMBERING {yylval.numval = REMEMBER; return(GERUND);} -ABSTINERE | -ABSTAIN {return(ABSTAIN);} -FROM | -A {return(FROM);} -ABSTINENDUM | -ABSTAINING {yylval.numval = ABSTAIN; return(GERUND);} -REINSTARE | -REINSTATE {return(REINSTATE);} -REINSTATANDUM | -REINSTATING {yylval.numval = REINSTATE; return(GERUND);} -LEGERE{W}EX | -READ{W}OUT {return(READ_OUT);} -LEGENDUM | -READING{W}OUT {yylval.numval = READ_OUT; return(GERUND);} -SCRIBERE{W}IN | -WRITE{W}IN {return(WRITE_IN);} -SCRIBENDUM | -WRITING{W}IN {yylval.numval = WRITE_IN; return(GERUND);} -ADVENIRE{W}DE{W}\({W}{D}\) | -COME{W}FROM{W}\({W}{D}\) {/* By AIS */ yylval.numval = myatoi(yytext); - return(COME_FROM);} -ADVENIRE{W}DE | -COME{W}FROM {/* By AIS */ return(COMPUCOME);} -ADVENENDUM | -COMING{W}FROM {yylval.numval = COME_FROM; return(GERUND);} -CONCEDERE | -DESPERARE | -GIVE{W}UP {return(GIVE_UP);} -CONOR{W}ITERUM | -TRY{W}AGAIN {return(TRY_AGAIN);} -TRYING{W}AGAIN {yylval.numval = TRY_AGAIN; return(GERUND);} -GO{W}BACK | -REDIRE {return(GO_BACK);} -GOING{W}BACK | -REDENDUM {yylval.numval = GO_BACK; return(GERUND);} -GO{W}AHEAD | -GRASSOR {return(GO_AHEAD);} -GOING{W}AHEAD {yylval.numval = GO_AHEAD; return(GERUND); - /* AIS: I'm having a few deponent troubles with the Latin, so - there are no Latin gerunds around here. Besides, the Latin - 'gerunds' look somewhat like gerundives to me, but that's - purely based on memory so I may be wrong. */} - -\+ {return(INTERSECTION);} - -{W} ; -. {yylval.numval = yytext[0]; return(BADCHAR);} - - -%% - -int lexer(void) -{ - static int tok = BADCHAR; - - if (re_send_token) - re_send_token = FALSE; - else - { - tok = yylex(); -#ifdef YYDEBUG - if (yydebug) - (void) fprintf(stdout, "yylex: returning token %d\n", tok); -#endif /* YYDEBUG */ - } - -#ifdef YYDEBUG - if (yydebug) - (void) fprintf(stdout, "lexer: returning token %d\n", tok); -#endif /* YYDEBUG */ - return(tok); -} - -static int myatoi(char *text) /* Alex edit! */ -{ -#define MAXTEXT 100 - static char buf[MAXTEXT]; - static char thinbuf[MAXTEXT]; - char* bp; - char* tp; - register int i; - - for(buf[i = 0] = '\0';*text && i < MAXTEXT;text++) { - if(isdigit(*text)) { - buf[i++] = *text; - } - } - buf[i] = '\0'; - bp=buf; tp=thinbuf; - while(*tp++=*bp++); /* thinbuf code added by an Alex edit, - in case we want to work with wchar_t */ - return atoi(thinbuf); -} - -void yyerror(char *errtype) -{ -#ifdef MAIN - (void) printf("lextest: lexer error: %s.\n", errtype); -#else /* MAIN */ - /* lose(E017, yylineno, (char *)NULL); */ - (void) errtype; -#endif /* MAIN */ -} - -#ifdef MAIN -int main(void) -{ - int t; - - while ((t = yylex()) > 0) - { - (void) printf("%03d %09d\n", t, yylval.numval); - yylval.numval = 0; - } - return 0; -} -#endif /* MAIN */ diff --git a/lose.c b/lose.c deleted file mode 100644 index 23cbee3..0000000 --- a/lose.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * - * NAME - * lose.c -- report INTERCAL compile- or run-time error - * -LICENSE TERMS - Copyright (C) 1996 Eric S. Raymond - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/*LINTLIBRARY*/ -#include -#include -#include -#include "lose.h" - -int coreonerr = 0; /* AIS */ - -int checkforbugs; /* AIS */ - -void lose(char *m, int n, char *s) -{ - (void) fflush(stdout); /* AIS: To stop stdout getting muddled with stderr*/ - (void) fprintf(stderr, - "ICL%c%c%cI\t", - m[0], m[1], m[2]); - if (s) - (void) fprintf(stderr, m + 4, s, n); - else - (void) fprintf(stderr, m + 4, n); - (void) fprintf(stderr, " CORRECT SOURCE AND RESUBNIT\n"); - if(atoi(m)==778&&coreonerr) /* AIS */ - { - /* AIS: Dump core. */ - raise(SIGABRT); - } - exit(atoi(m)); -} - -/* AIS: This function reports potential bugs. It's paraphrased from lose. */ -void lwarn(char *m, int n, char *s) -{ - if(!checkforbugs) return; /* Don't report a potential bug without -l */ - (void) fflush(stdout); - (void) fprintf(stderr, - "ICL%c%c%cW\t", - m[0],m[1],m[2]); - if (s) - (void) fprintf(stderr, m + 4, s, n); - else - (void) fprintf(stderr, m + 4, n); - (void) fprintf(stderr, " RECONSIDER SOURCE AND RESUBNIT\n\n"); - /* Don't exit. This is not any error except one not causing immediate - termination of program execution. */ -} - -/* lose.c ends here */ diff --git a/lose.h b/lose.h deleted file mode 100644 index a249fd4..0000000 --- a/lose.h +++ /dev/null @@ -1,217 +0,0 @@ -/* lose.h --- error message strings */ - -/* - * Note: these error message texts, with one exception, are direct from - * the Princeton compiler (INTERCAL-72) sources (transmitted by Don Woods). - * The one exception is E632, which in INTERCAL-72 had the error message - * PROGRAM ATTEMPTED TO EXIT WITHOUT ERROR MESSAGE - * ESR's "THE NEXT STACK HAS RUPTURED!..." has been retained on the grounds - * that it is more obscure and much funnier. For context, find a copy of - * Joe Haldeman's SF short story "A !Tangled Web", first published in - * Analog magazine in September 1981 and later anthologized in the author's - * "Infinite Dreams" (Ace 1985). - */ -/* An undecodable statement has been encountered in the course of execution. */ -#define E000 "000 %s\n\ - ON THE WAY TO %d\n" -/* An expression contains a syntax error. */ -#define E017 "017 DO YOU EXPECT ME TO FIGURE THIS OUT?\n\ - ON THE WAY TO %d\n" -/* Improper use has been made of statement identifiers. */ -#define E079 "079 PROGRAMMER IS INSUFFICIENTLY POLITE\n\ - ON THE WAY TO %d\n" -/* Improper use has been made of statement identifiers. */ -#define E099 "099 PROGRAMMER IS OVERLY POLITE\n\ - ON THE WAY TO %d\n" -/* Program has attempted 80 levels of NEXTing */ -#define E123 "123 PROGRAM HAS DISAPPEARED INTO THE BLACK LAGOON\n\ - ON THE WAY TO %d\n" -/* Program has attempted to transfer to a non-existent line label */ -#define E129 "129 PROGRAM HAS GOTTEN LOST\n\ - ON THE WAY TO WHO KNOWS WHERE\n" -/* An ABSTAIN or REINSTATE statement references a non-existent line label */ -#define E139 "139 I WASN'T PLANNING TO GO THERE ANYWAY\n\ - ON THE WAY TO %d\n" -/* A line label has been multiply defined. */ -#define E182 "182 YOU MUST LIKE THIS LABEL A LOT!\n\ - ON THE WAY TO %d\n" -/* An invalid line label has been encountered. */ -#define E197 "197 SO! 65535 LABELS AREN'T ENOUGH FOR YOU?\n\ - ON THE WAY TO %d\n" -/* An expression involves an unidentified variable. */ -#define E200 "200 NOTHING VENTURED, NOTHING GAINED\n\ - ON THE WAY TO %d\n" -/* An attempt has been made to give an array a dimension of zero. */ -#define E240 "240 ERROR HANDLER PRINTED SNIDE REMARK\n\ - ON THE WAY TO %d\n" -/* Invalid dimensioning information was supplied - * in defining or using an array. */ -#define E241 "241 VARIABLES MAY NOT BE STORED IN WEST HYPERSPACE\n\ - ON THE WAY TO %d\n" -/* A 32-bit value has been assigned to a 16-bit variable. */ -#define E275 "275 DON'T BYTE OFF MORE THAN YOU CAN CHEW\n\ - ON THE WAY TO %d\n" -/* A retrieval has been attempted for an unSTASHed value. */ -#define E436 "436 THROW STICK BEFORE RETRIEVING!\n\ - ON THE WAY TO %d\n" -/* A WRITE IN statement or interleave ($) operation - * has produced value requiring over 32 bits to represent. */ -#define E533 "533 YOU WANT MAYBE WE SHOULD IMPLEMENT 64-BIT VARIABLES?\n\ - ON THE WAY TO %d\n" -/* Insufficient data. (raised by reading past EOF) */ -#define E562 "562 I DO NOT COMPUTE\n\ - ON THE WAY TO %d\n" -/* Input data is invalid. */ -#define E579 "579 WHAT BASE AND/OR LANGUAGE INCLUDES %s?\n\ - ON THE WAY TO %d\n" -/* The expression of a RESUME statement evaluated to #0. */ -#define E621 "621 ERROR TYPE 621 ENCOUNTERED\n\ - ON THE WAY TO %d\n" -/* Program execution terminated via a RESUME statement instead of GIVE UP. */ -#define E632 "632 THE NEXT STACK RUPTURES. ALL DIE. OH, THE EMBARRASSMENT!\n\ - ON THE WAY TO %d\n" -/* Execution has passed beyond the last statement of the program. */ -#define E633 "633 PROGRAM FELL OFF THE EDGE\n\ - ON THE WAY TO THE NEW WORLD\n" -/* A compiler error has occurred (see section 8.1). */ -#define E774 "774 RANDOM COMPILER BUG\n\ - ON THE WAY TO %d\n" -/* An unexplainable compiler error has occurred (see J. Lyon or D. Woods). */ -#define E778 "778 UNEXPLAINED COMPILER BUG\n\ - ON THE WAY TO %d\n" - -/* - * These errors are unique to C-INTERCAL. - */ -/* You tried to use a C-INTERCAL extension with the `traditional' flag on */ -#define E111 "111 COMMUNIST PLOT DETECTED, COMPILER IS SUICIDING\n\ - ON THE WAY TO %d\n" -/* Cannot find the magically included system library */ -#define E127 "127 SAYING 'ABRACADABRA' WITHOUT A MAGIC WAND WON'T DO YOU ANY GOOD\n\ - ON THE WAY TO THE CLOSET\n" -/* Out of stash space */ -#define E222 "222 BUMMER, DUDE!\n\ - ON THE WAY TO %d\n" -/* (AIS) The spark/ears nesting is too deep. */ -#define E281 "281 THAT MUCH QUOTATION AMOUNTS TO PLAGIARISM\n\ - ON THE WAY TO %d\n" -/* Too many variables. */ -#define E333 "333 YOU CAN'T HAVE EVERYTHING, WHERE WOULD YOU PUT IT?\n\ - ON THE WAY TO %d\n" -/* (AIS, from the suggestion by Malcom Ryan) - GO BACK or GO AHEAD was executed without a choicepoint. */ -#define E404 "404 I'M ALL OUT OF CHOICES!\n\ - ON THE WAY TO %d\n" -/* (AIS) MAYBE, GO BACK, or GO AHEAD used without the -m option. */ -#define E405 "405 PROGRAM REJECTED FOR MENTAL HEALTH REASONS\n\ - ON THE WAY TO %d\n" -/* A COME FROM statement references a non-existent line label. */ -#define E444 "444 IT CAME FROM BEYOND SPACE\n\ - ON THE WAY TO %d\n" -/* More than one COME FROM references the same label. */ -#define E555 "555 FLOW DIAGRAM IS EXCESSIVELY CONNECTED\n\ - ON THE WAY TO %d\n" -/* Too many source lines. */ -#define E666 "666 COMPILER HAS INDIGESTION\n\ - ON THE WAY TO %d\n" -/* No such source file. */ -#define E777 "777 A SOURCE IS A SOURCE, OF COURSE, OF COURSE\n\ - ON THE WAY TO %d\n" -/* Can't open C output file */ -#define E888 "888 I HAVE NO FILE AND I MUST SCREAM\n\ - ON THE WAY TO %d\n" -/* Can't open C skeleton file. */ -#define E999 "999 NO SKELETON IN MY CLOSET, WOE IS ME!\n\ - ON THE WAY TO %d\n" -/* Source file name with invalid extension (use .i or .[3-7]i). */ -#define E998 "998 EXCUSE ME,\n\ - YOU MUST HAVE ME CONFUSED WITH SOME OTHER COMPILER\n" -/* Illegal possession of a controlled unary operator. */ -#define E997 "997 ILLEGAL POSSESSION OF A CONTROLLED UNARY OPERATOR.\n\ - ON THE WAY TO %d\n" -/* (AIS) Command found after TRY AGAIN. */ -#define E993 "993 I GAVE UP LONG AGO\n\ - ON THE WAY TO %d\n" -/* (AIS) Memory allocation failure during multithreading */ -#define E991 "991 YOU HAVE TOO MUCH ROPE TO HANG YOURSELF\n\ - ON THE WAY TO %d\n" - -/* - * AIS: These errors are generated by the yuk debugger - */ -/* (AIS) fgets' buffer overflowed on debugger comand input. */ -#define E810 "810 ARE ONE-CHARACTER COMMANDS TOO SHORT FOR YOU?\n\ - ON THE WAY TO %d\n" - -/* (AIS) Too many breakpoints. */ -#define E811 "811 PROGRAM IS TOO BADLY BROKEN TO RUN\n\ - ON THE WAY TO %d\n" - -/* - * (AIS) Warnings produced by -l. - */ - -/* (AIS) Non-INTERCAL-72 identifier used. */ -#define W112 "112 THAT RELIES ON THE NEW WORLD ORDER\n\ - ON THE WAY TO %d\n" - -/* (AIS) That stupid idiom in syslib was used. */ -#define W128 "128 SYSLIB IS OPTIMIZED FOR OBFUSCATION\n\ - ON THE WAY TO %d\n" - -/* (AIS) Possibly nonportable unary operator. */ -#define W534 "534 KEEP LOOKING AT THE TOP BIT\n\ - ON THE WAY TO %d\n" - -/* (AIS) Expression still contains INTERCAL operators after - optimization. Only in binary, because this nearly always - happens in the higher bases. Syslib causes quite a lot of - these. This warning is fine on INTERCAL-like lines, but - flags a mistake on lines that are meant to be translations - of C. */ -#define W018 "018 THAT WAS MEANT TO BE A JOKE\n\ - ON THE WAY TO %d\n" - -/* (AIS) Possible misplaced unary operator. At the moment, ick -l cannot - detect this condition (so it never comes up). It's meant to detect - expressions like '?"?.1~#256"$#2'~#3 (from numio.i); in this expression, - the second what has no effect (it changes only the msb of the immediately - surrounding expression, which is eventually filtered out by the select - against #3). But detecting this would probably require code that could - check which bits of a result were going to be used elsewhere in an - expression, which is something I haven't written yet (but would make - a decent optimize_pass3). */ -#define W016 "016 DON'T TYPE THAT SO HASTILY\n\ - ON THE WAY TO %d\n" - -/* (AIS) Possibly overflowing assignment or mingle. Syslib causes some of - these too, in complicated situations where the bugcatcher can't figure - out what's happening, and also in a few blatant statements in the mould - of DO .3 <- :3, which are quite clearly possible overflows. Strangely - enough, there's a commented-out section of code in feh.c that suggests - that someone tried to make this an error (using a more general check - which would have caught more correct code involving GETS, but none - involving $). As a middle ground, I've made it an -l warning. */ -#define W276 "276 YOU CAN'T EXPECT ME TO CHECK BACK THAT FAR\n\ - ON THE WAY TO %d\n" - -/* (AIS) The two following warnings are both compile-time traps for - near-certain runtime errors. As such, they have similar numbers - and similar messages. In fact, they're a shameless ripoff of the - originals, but should serve as a reminder for anyone aware of the - original messages. */ -/* (AIS) Dimension given for an array will come out as #0. */ -#define W239 "239 WARNING HANDLER PRINTED SNIDE REMARK\n\ - ON THE WAY TO %d\n" - -/* (AIS) RESUME argument will come out as #0. */ -#define W622 "622 WARNING TYPE 622 ENCOUNTERED\n\ - ON THE WAY TO %d\n" - -extern int lineno; - -extern void lose(char *m, int n, char *s); - -extern void lwarn(char *m, int n, char *s); - -/* lose.h ends here */ diff --git a/makeick.bat b/makeick.bat new file mode 100755 index 0000000..08d6b7b --- /dev/null +++ b/makeick.bat @@ -0,0 +1,66 @@ +@echo off + +rem C-INTERCAL 0.25 compilation batch file for DJGPP. + +rem This code will attempt to recompile the parser and lexer using +rem bison and flex. If you don't have them, you will get an error +rem message and the parser and lexer included with the distribution +rem will be used. My DJGPP distribution seems to require that you +rem copy DJDIR\bin\m4.exe to the temp subdir of the INTERCAL +rem distribution or bison won't work; YMMV. + +copy /y src\*.* temp +cd temp +bison -d -oparser.c parser.y +flex -olexer.c lexer.l + +rem If you don't care about being able to debug ick, use +rem set CFLAGS=-s -O2 -DICKNOSEARCH -W -Wall +set CFLAGS=-gstabs+ -O2 -DICKNOSEARCH -W -Wall + +rem Set this to a location of the GNU GPL on your system... +set COPYLOC=C:\DJGPP\COPYING +rem ...and this to the same thing, but within "s and with backslashes doubled. +set COPYLOCC="C:\\DJGPP\\COPYING" + +if not exist %COPYLOC% goto :error +echo Compiling... + +gcc -c %CFLAGS% parser.c +gcc -c %CFLAGS% lexer.c +gcc -c %CFLAGS% feh2.c +gcc -c %CFLAGS% dekludge.c +gcc -c %CFLAGS% perpet.c +gcc -c %CFLAGS% cesspool.c +gcc -c %CFLAGS% numerals.c +gcc -c %CFLAGS% unravel.c +gcc -c %CFLAGS% fiddle.c +gcc -c %CFLAGS% arrgghh.c +gcc -c %CFLAGS% lose.c +gcc -c %CFLAGS% -DYUKCOPYLOC=\"%COPYLOCC%\" yuk.c +ar cr libick.a cesspool.o numerals.o fiddle.o arrgghh.o lose.o +ranlib libick.a +ar cr libickmt.a cesspool.o numerals.o fiddle.o arrgghh.o lose.o unravel.o +ranlib libickmt.a +ar cr libyuk.a yuk.o +ranlib libyuk.a +gcc %CFLAGS% -oickmain.exe parser.o lexer.o perpet.o feh2.o dekludge.o lose.o fiddle.o +copy /y ickmain.exe ..\bin +copy /y *.a ..\lib +cd .. +copy /y src\ick-wrap.c lib +copy /y src\pickwrap.c lib +copy /y pit\lib\syslib.i lib +copy /y pit\lib\syslib.?i lib +copy /y src\fiddle.h include +copy /y src\abcess.h include +copy /y src\lose.h include +copy /y src\yuk.h include +copy /y src\ick.bat bin +echo Compilation complete unless there were errors. +goto :end +:error +echo You need to tell this batch file where the GNU GPL is on your system. +echo Please edit this batch file and set COPYLOC to a correct location. +echo (You can point it to the copy of COPYING.txt provided.) +:end \ No newline at end of file diff --git a/makeick.sh b/makeick.sh new file mode 100755 index 0000000..f9ba3a6 --- /dev/null +++ b/makeick.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +# C-INTERCAL 0.25 compilation batch file for sh and bash. + +# This code will attempt to recompile the parser and lexer using +# bison and flex. If you don't have them, you will get an error +# message and the parser and lexer included with the distribution +# will be used. My DJGPP distribution seems to require that you +# copy DJDIR/bin/m4.exe to the temp subdir of the INTERCAL +# distribution or bison won't work; YMMV. + +# Using configure.sh and make is recommended; this script is a fallback for +# when you can't get configure.sh and/or make to work on your system; make +# is broken on my DJGPP distribution, so I use this file instead. + +# This file is meant to contain the same content as makeick.bat; it's simply +# written for sh rather than COMMAND.COM (and doesn't make use of all its +# features, as it's meant to be exactly analogous). + +# Run this file from the directory in which this script is installed. + +cp src/* temp +cd temp +bison -d -oparser.c parser.y +flex -olexer.c lexer.l + +# If you don't care about being able to debug ick, use +# CFLAGS=-s -O2 -DICKNOSEARCH -W -Wall +CFLAGS='-gstabs+ -O2 -DICKNOSEARCH -W -Wall' + +# Set this to a location of the GNU GPL on your system. +# Please use forward-slash notation! +COPYLOC=c:/djgpp/copying + +echo If the following line fails, edit makeick.sh to point COPYLOC at a +echo location of the GNU GPL on your system. You can point it to the copy of +echo COPYING.txt provided. +cp ${COPYLOC} /dev/null || exit +echo Compiling... +gcc -c ${CFLAGS} parser.c +gcc -c ${CFLAGS} lexer.c +gcc -c ${CFLAGS} feh2.c +gcc -c ${CFLAGS} dekludge.c +gcc -c ${CFLAGS} perpet.c +gcc -c ${CFLAGS} cesspool.c +gcc -c ${CFLAGS} numerals.c +gcc -c ${CFLAGS} unravel.c +gcc -c ${CFLAGS} fiddle.c +gcc -c ${CFLAGS} arrgghh.c +gcc -c ${CFLAGS} lose.c +gcc -c ${CFLAGS} "-DYUKCOPYLOC=\"${COPYLOC}\"" yuk.c +ar cr libick.a cesspool.o numerals.o fiddle.o arrgghh.o lose.o +ranlib libick.a +ar cr libickmt.a cesspool.o numerals.o fiddle.o arrgghh.o lose.o unravel.o +ranlib libickmt.a +ar cr libyuk.a yuk.o +ranlib libyuk.a +gcc ${CFLAGS} -oickmain.exe parser.o lexer.o perpet.o feh2.o dekludge.o lose.o fiddle.o +cp ickmain.exe ../bin +cp *.a ../lib +cd .. +cp src/ick-wrap.c lib +cp src/pickwrap.c lib +cp pit/lib/syslib.i lib +cp pit/lib/syslib.?i lib +cp src/fiddle.h include +cp src/abcess.h include +cp src/lose.h include +cp src/yuk.h include +cp src/ick.bat bin +echo Compilation complete unless there were errors. \ No newline at end of file diff --git a/numerals.c b/numerals.c deleted file mode 100644 index c4a200e..0000000 --- a/numerals.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * numeral.c -- internationalization support for INTERCAL input. - * - * After release 0.5, I wrote: - * - * 2. (ESR) Input format internationalization -- allow WRITE IN input digits in - * major languages such as Nahuatl, Tagalog, Sanskrit, and Basque. - * - * The twisted loons in the alt.folklore.computers crowd loved this - * idea, and I actually got sent digit lists for Nahuatl, Tagalog, - * Sanskrit, and Basque -- also, Kwakiutl, Georgian, Ojibwe. Albanian, - * and Volap\"uk. I've left out Albanian (didn't want to keep track - * of the dipthong diacritical) and Ojibwe (no zero digit). So: - * Nahuatl, Tagalog, Sanskrit, Basque, Georgian, Kwakiutl, and - * Volap\"uk are now supported in addition to English. - * - * As of release 0.18, Volap\"uk digits can be entered in either traditional - * Tex format, Latin-1, or UTF-8. Latin is also now a supported language, - * to fulfill the requirement for Ancient Roman localization. - * -LICENSE TERMS - Copyright (C) 1996 Eric S. Raymond - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -typedef struct -{ - char *name; - int value; -} -numeral; - -static numeral numerals[] = -{ -/* English */ - { "OH", 0 }, - { "ZERO", 0 }, - { "ONE", 1 }, - { "TWO", 2 }, - { "THREE", 3 }, - { "FOUR", 4 }, - { "FIVE", 5 }, - { "SIX", 6 }, - { "SEVEN", 7 }, - { "EIGHT", 8 }, - { "NINE", 9 }, - { "NINER", 9 }, /* For all you junior birdmen */ -/* Sanskrit */ - { "SUTYA", 0 }, /* Retroflex s, pronounced halfway to sh */ - { "SHUTYA", 0 }, - { "EKA", 1 }, - { "DVI", 2 }, - { "TRI", 3 }, - { "CHATUR", 4 }, - { "PANCHAN", 5 }, - { "SHASH", 6 }, - { "SAPTAM", 7 }, - { "ASHTAN", 8 }, - { "NAVAN", 9 }, -/* Basque */ - { "ZEROA", 0 }, - { "BAT", 1 }, - { "BI", 2 }, - { "HIRO", 3 }, - { "LAU", 4 }, - { "BORTZ", 5 }, - { "SEI", 6 }, - { "ZAZPI", 7 }, - { "ZORTZI", 8 }, - { "BEDERATZI", 9 }, -/* Tagalog */ - { "WALA", 0 }, - { "ISA", 1 }, - { "DALAWA", 2 }, - { "TATLO", 3 }, - { "APAT", 4 }, - { "LIMA", 5 }, - { "ANIM", 6 }, - { "PITO", 7 }, - { "WALO", 8 }, - { "SIYAM", 9 }, -/* Classical Nahuatl */ - { "AHTLE", 0 }, /* Actually `nothing'; no separate zero word is known */ - { "CE", 1 }, - { "OME", 2 }, - { "IEI", 3 }, - { "NAUI", 4 }, - { "NACUILI", 5 }, - { "CHIQUACE", 6 }, - { "CHICOME", 7 }, - { "CHICUE", 8 }, - { "CHICUNAUI", 9 }, -/* Georgian */ - { "NULI", 0 }, - { "ERTI", 1 }, - { "ORI", 2 }, - { "SAMI", 3 }, - { "OTXI", 4 }, - { "XUTI", 5 }, - { "EKSVI", 6 }, - { "SHVIDI", 7 }, - { "RVA", 8 }, - { "CXRA", 9 }, -/* Kwakiutl (technically, Kwak'wala) */ - { "KE'YOS", 0 }, /* Actually `nothing'; no separate zero word is known */ - { "'NEM", 1 }, - { "MAL'H", 2 }, - { "YUDEXW", 3 }, - { "MU", 4 }, - { "SEK'A", 5 }, - { "Q'ETL'A", 6 }, - { "ETLEBU", 7 }, - { "MALHGWENALH", 8 }, - { "'NA'NE'MA", 9 }, -/* Volap\"uk */ - { "NOS", 0 }, - { "BAL", 1 }, - { "TEL", 2 }, - { "KIL", 3 }, - { "FOL", 4 }, - { "LUL", 5 }, - { "M\\\"AL", 6 }, - { "M\xC4L", 6 }, /* Latin-1 support */ - { "M\xA3\xA4L", 6 }, /* UTF-8 support */ - { "VEL", 7 }, - { "J\\\"OL", 8 }, - { "J\xD6L", 8 }, /* Latin-1 support */ - { "J\xA3\x96L", 8 }, /* UTF-8 support */ - { "Z\\\"UL", 9 }, - { "Z\xDCL", 9 }, /* Latin-1 support */ - { "Z\xA3\x9CL", 9 }, /* UTF-8 support */ -/* Latin localization */ - { "NIL", 0 }, - { "NIHIL", 0 }, - { "UNUS", 1 }, - { "UNA", 1 }, - { "UNUM", 1 }, - { "DUO", 2 }, - { "DUAE", 2 }, - { "TRES", 3 }, - { "QUATTUOR", 4 }, - { "QUATUOR", 4 }, - { "QUINQUE", 5 }, - { "SEX", 6 }, - { "SEPTEM", 7 }, - { "OCTO", 8 }, - { "NOVEM", 9 }, -}; - -/* numeral.c ends here */ diff --git a/perpetrate.c b/perpetrate.c deleted file mode 100644 index 5acec59..0000000 --- a/perpetrate.c +++ /dev/null @@ -1,980 +0,0 @@ -/**************************************************************************** - -NAME - perpetrate.c -- main routine for C-INTERCAL compiler. - -DESCRIPTION - This is where all the dirty work begins and ends. - -LICENSE TERMS - Copyright (C) 1996 Eric S. Raymond - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - -****************************************************************************/ -/*LINTLIBRARY */ -#include -#include -#include -#include -#include -#include -#include "ick.h" -#include "feh.h" -#include "y.tab.h" -#include "sizes.h" -#include "lose.h" - -#ifndef ICKINCLUDEDIR -#define ICKINCLUDEDIR "/usr/local/include" -#endif -#ifndef ICKLIBDIR -#define ICKLIBDIR "/usr/local/share" -#endif -#ifndef ICKBINDIR -#define ICKBINDIR "/usr/local/bin" -#endif -#ifndef CC -#define CC "gcc" -#endif - -#ifdef USE_YYRESTART -/* function supplied by lex */ -extern void yyrestart(FILE*); - -#endif /* USE_YYRESTART */ - -/* function created by yacc */ -extern int yyparse(void); - -int yydebug; - -/* compilation options */ -bool compile_only; /* just compile into C, don't run the linker */ -bool traditional; /* insist on strict INTERCAL-72 conformance */ -bool nocompilerbug; /* disable error E774 */ -int yukdebug; /* AIS: Use the yuk debugger. */ -int yukprofile; /* AIS: Use the yuk profiler. */ -extern int coreonerr; /* AIS: Dump core on E778. (defined in lose.c) */ -int multithread; /* AIS: Allow multithreading and backtracking. */ -int cdebug; /* AIS: Pass -g to our C compiler, and leave C code. */ -int optdebug; /* AIS: Debug the optimizer. Value is 0, 1, 2, or 3. */ -int flowoptimize; /* AIS: Do flow optimizations (in INTERCAL!). */ -int coopt; /* AIS: The constant-output optimization. This should - mean that INTERCAL will beat any other language at - many benchmark programs (!) */ -extern int checkforbugs;/* AIS: Try to find possible bugs in the source code */ - -int compucomecount=0; /* AIS: Computed COME FROM count */ -int compucomesused=0; /* AIS: Are computed COME FROMs used? */ - -static bool dooptimize; /* do optimizations? (controlled by -O) */ -static bool clockface; /* set up output to do IIII for IV */ - -#define SKELETON "ick-wrap.c" -#define SYSLIB "pit/lib/syslib" - -/* numeric base defaults, exported to other files */ - -#define DEFAULT_BASE 2 -#define DEFAULT_SMALL_DIGITS 16 -#define DEFAULT_LARGE_DIGITS 32 -#define DEFAULT_MAX_SMALL 0xffffL -#define DEFAULT_MAX_LARGE 0xffffffffL - -int Base; -int Small_digits; -int Large_digits; -unsigned int Max_small; -unsigned int Max_large; - -int lineno; /* after yyparse, this is the total number of statements */ - -/* currently supported numeric bases, not exported */ -static int maxbase = 7; -static int smallsizes[8] = {0, 0, 16, 10, 8, 6, 6, 5}; -static unsigned int maxsmalls[8] = - {0, 0, 65535, 59048, 65535, 15624, 46655, 16806}; - -static char *compiler; - -atom *oblist = NULL, *obdex; -int obcount = 0; -int nonespots, ntwospots, ntails, nhybrids; - -tuple *tuples = NULL; -int tuplecount = 0; - -tuple *optuple = NULL; /* AIS: Tuple being optimized */ - -static int myfgetc(FILE* in) -{ - char c; - fread(&c,1,1,in); - if(feof(in)) return EOF; - return (int)c; -} - - -static void abend(int signim) -{ - lose(E778, yylineno, (char *)NULL); - (void) signim; -} - -static void print_usage(char *prog, char *options) -{ - fprintf(stderr,"Usage: %s [-%s] [ ... ]\n",prog,options); - fprintf(stderr,"\t-b\t:reduce the probability of E774 to zero\n"); - fprintf(stderr,"\t-c\t:compile INTERCAL to C, but don't compile C\n"); - fprintf(stderr,"\t-d\t:print yacc debugging information (implies -c)\n"); - fprintf(stderr,"\t-t\t:traditional mode, accept only INTERCAL-72\n"); - fprintf(stderr,"\t-C\t:clockface output (e.g. use IIII instead of IV)\n"); - fprintf(stderr,"\t-O\t:optimize expresssions in generated code\n"); - /* AIS: Changed the help message for the previous line (because the - function of -O has changed). I wrote the next group of options. */ - fprintf(stderr,"\t-f\t:optimize control flow in generated code " - "(prevents -yp)\n"); - fprintf(stderr,"\t-F\t:optimize everything in generated code for\n" - "\t\tspeed, regardless of how slow the compiler becomes or how\n" - "\t\tlarge the object file becomes. Implies -fO,\n" - "\t\tprevents -cdghpyH\n"); - fprintf(stderr,"\t-h\t:print optimizer debugging information " - "(implies -cO)\n"); - fprintf(stderr,"\t-H\t:print verbose optimizer debugging information " - "(implies -cO)\n"); - fprintf(stderr,"\t-hH\t:print optimizer debugging information in a\n" - "\t\tdifferent form (implies -cO)\n"); - fprintf(stderr,"\t-y\t:run the yuk debugger on the code (prevents -fm)\n"); - fprintf(stderr,"\t-p\t:run the yuk profiler on the code (prevents -fm)\n"); - fprintf(stderr,"\t-m\t:allow multithreading and backtracking " - "(prevents -yp)\n"); - fprintf(stderr,"\t-U\t:dump core on E778 rather than printing an error\n"); - fprintf(stderr,"\t-g\t:compile to both debuggable executable and C\n"); - fprintf(stderr,"\t-l\t:attempt to report likely bugs " - "and nonportabilities (implies -O)\n"); - /* AIS: End of options I added. */ - fprintf(stderr,"\t\tINTERCAL source file(s) (use extension .i)\n"); - fprintf(stderr,"\t\teach file produces a separate output program.\n"); -} - -/* AIS: This function looks for the skeleton and syslib, searching first the - path they should be in, then the current directory, then argv[0]'s - directory (if one was given). This function avoids possible buffer - overflows, instead truncating filenames (and if that manages to find them, - I'll be incredibly surprised). */ -static FILE* findandfopen(char* file, char* guessdir, char* mode, char* argv0) -{ - char buf2[BUFSIZ], *fileiter; - int i = 0, j; - FILE* ret; - while(*guessdir&&i maxbase) - lose(E998, 1, (char *)NULL); - else if (traditional && Base != 2) - lose(E111, 1, (char *)NULL); - Small_digits = smallsizes[Base]; - Large_digits = 2 * Small_digits; - Max_small = maxsmalls[Base]; - if (Max_small == 0xffff) - Max_large = 0xffffffffLU; - else - Max_large = (Max_small + 1) * (Max_small + 1) - 1; - } - - /* zero out tuple and oblist storage */ - treset(); - politesse = 0; - - /* reset the lex/yacc environment */ - if (!firstfile) - { -#ifdef NEED_YYRESTART - yyrestart(stdin); -#endif /* NEED_YYRESTART */ -#ifdef YYLINENO_BY_HAND - yylineno = 1; -#endif /* YYLINENO_BY_HAND */ - } - - /* compile tuples from current input source */ - yyparse(); - - /* - * Miss Manners lives. - */ - if (lineno > 2) - { - if (politesse == 0 || (lineno - 1) / politesse >= 5) - lose(E079, yylineno, (char *)NULL); - else if (lineno / politesse < 3) - lose(E099, yylineno, (char *)NULL); - } - - /* - * check if we need to magically include the system library - */ - needsyslib = FALSE; - for (tp = tuples; tp->type; tp++) { - /* - * If some label in the (1000)-(2000) range is defined, - * then clearly the syslib is already there, so we - * can stop searching and won't need the syslib. - */ - if (tp->label >= 1000 && tp->label <= 1999) { - needsyslib = FALSE; - break; - } - /* - * If some label in the (1000)-(2000) range is being - * called, we might need the system library. - */ - if (tp->type == NEXT && tp->u.target >= 1000 && - tp->u.target <= 1999) - needsyslib = TRUE; - } - if ( needsyslib ) { /* AIS: modified to use findandfreopen */ - if (Base == 2) /* see code for opening the skeleton */ - (void) sprintf(buf2, "%s.i", SYSLIB); - else - (void) sprintf(buf2, "%s.%di", SYSLIB, Base); - if (findandfreopen(buf2, libdir, "r", argv[0], stdin) == 0) - lose(E127, 1, (char*) NULL); - -#ifdef USE_YYRESTART - yyrestart(stdin); -#endif /* USE_YYRESTART */ - yyparse(); - } - - /* - * Now propagate type information up the expression tree. - * We need to do this because the unary-logical operations - * are sensitive to the type widths of their operands, so - * we have to generate different code depending on the - * deducible type of the operand. - */ - for (tp = tuples; tp->type; tp++) - { - if (tp->type == GETS || tp->type == RESIZE - || tp->type == WRITE_IN || tp->type == READ_OUT - || tp->type == FROM || tp->type == MANYFROM - || tp->type == FORGET || tp->type == RESUME - || tp->type == COMPUCOME) - typecast(tp->type == MANYFROM ? tp->u.node->lval : tp->u.node); - if (tp->type == WRITE_IN) coopt = 0; /* AIS: may as well do - this here */ - } - - codecheck(); /* check for compile-time errors */ - /* AIS: And importantly, sort out line number references */ - - /* perform optimizations */ - if (dooptimize) - for (tp = tuples; tp->type; tp++) - { - optuple = tp; - if (tp->type == GETS || tp->type == RESIZE - || tp->type == FORGET || tp->type == RESUME - || tp->type == FROM || tp->type == COMPUCOME) - optimize(tp->u.node); - if (tp->type == MANYFROM) optimize(tp->u.node->lval); - } /* AIS: Added FROM and MANYFROM support. */ - - /* AIS: perform flow optimizations */ - if (flowoptimize) optimizef(); - - /* decide if and where to place the compiler bug */ -#ifdef USG - if (!nocompilerbug && lrand48() % 10 == 0) - bugline = (int)(lrand48() % lineno); -#else - if (!nocompilerbug && rand() % 10 == 0) - bugline = rand() % lineno; -#endif - else - bugline = -1; - - /* set up the generated C output file name */ - (void) strcpy(buf, argv[optind]); - (void) strcat(buf, ".c"); - if ((ofp = fopen(buf, "w")) == (FILE *)NULL) - lose(E888, 1, (char *)NULL); - - fseek(ifp,0L,0); /* rewind skeleton file */ - - /* AIS: Before changing argv[0], locate coopt.sh. */ - cooptsh = findandtestopen("coopt.sh", bindir, "rb", argv[0]); - - /* AIS: Remove the filename from argv[0], leaving only a directory. - If this would leave it blank, change argv[0] to '.'. - This is so gcc can find the includes/libraries the same way that - findandfreopen does. */ - if(strchr(argv[0],'/')) *(strrchr(argv[0],'/')) = 0; - else strcpy(argv[0],"."); - - (void) sprintf(buf2, - "%s %s%s-I%s -I%s -L%s -L%s -o %s -lick%s%s", - compiler, buf, yukdebug||yukprofile?" -lyuk ":" ", - includedir, argv[0], libdir, argv[0], - argv[optind], multithread?"mt":"", cdebug?" -g":""); - /* AIS: Possibly link in the debugger yuk and/or libickmt.a here. */ - /* AIS: Added -g support. */ - /* AIS: Added argv[0] to the -I, -L settings. */ - - while ((c = myfgetc(ifp)) != EOF) - if (c != '$') - (void) fputc(c, ofp); - else switch(myfgetc(ifp)) - { - case 'A': /* source name stem */ - (void) fputs(argv[optind], ofp); - break; - - case 'B': /* # of statements */ - (void) fprintf(ofp, "%d", lineno); - break; - - case 'C': /* initial abstentions */ - /* AIS: Modified to check for coopt */ - maxabstain = 0; - for (tp = tuples; tp->type; tp++) - if (((tp->exechance <= 0 || tp->exechance >= 101) - && tp - tuples + 1 > maxabstain) || coopt) - maxabstain = tp - tuples + 1; - if (maxabstain) - { - (void) fprintf(ofp, " = {"); - for (tp = tuples; tp < tuples + maxabstain; tp++) - { - if(tp->exechance != 100 && tp->exechance != -100) - { /* AIS: The double-oh-seven operator prevents - coopt working. However, syslib contains a - double-oh-seven. feh.c has checked that that - isn't referenced; if it isn't, we can allow - one double-oh-seven if syslib was - automagically inclulded. */ - if(needsyslib) needsyslib = 0; else coopt = 0; - } - if (tp->exechance > 0) - (void) fprintf(ofp, "0, "); - else { - (void) fprintf(ofp, "1, "); - tp->exechance = -tp->exechance; - /* AIS: If the line was abstained, we need to - swap ONCEs and AGAINs on it round, to suit - the code degenerator. */ - if(tp->onceagainflag == onceagain_ONCE) - tp->onceagainflag = onceagain_AGAIN; - else if(tp->onceagainflag == onceagain_AGAIN) - tp->onceagainflag = onceagain_ONCE; - } - if(tp->exechance >= 101) - { - /* AIS: This line has a MAYBE */ - tp->maybe = 1; - tp->exechance /= 100; - } - else tp->maybe = 0; - } - (void) fprintf(ofp, "}"); - } - break; - - case 'D': /* linetypes array for abstention handling */ - maxabstain = 0; - for (tp = tuples; tp->type; tp++) - if (tp->type == ENABLE || tp->type == DISABLE || tp->type == MANYFROM) - maxabstain++; - if (maxabstain) - { - (void) fprintf(ofp, "#define UNKNOWN\t\t0\n"); - i = 0; - for (; i < (int)(sizeof(enablers)/sizeof(char *)); i++) - (void) fprintf(ofp, - "#define %s\t%d\n", - enablers[i], i+1); - - (void) fprintf(ofp, "int linetype[] = {\n"); - for (tp = tuples; tp->type; tp++) - if (tp->type >= GETS && tp->type <= FROM) /* AIS: FROM added */ - (void) fprintf(ofp, - " %s,\n", - enablers[tp->type - GETS]); - else - (void) fprintf(ofp, " UNKNOWN,\n"); - (void) fprintf(ofp, "};\n"); - } - break; - - case 'E': /* extern to intern map */ - (void) fprintf(ofp,"int Base = %d;\n",Base); - (void) fprintf(ofp,"int Small_digits = %d;\n", - Small_digits); - (void) fprintf(ofp,"int Large_digits = %d;\n", - Large_digits); - (void) fprintf(ofp,"unsigned int Max_small = 0x%x;\n", - Max_small); - (void) fprintf(ofp,"unsigned int Max_large = 0x%x;\n", - Max_large); - if (yukprofile || yukdebug || multithread) - { /* AIS: yuk.c, multithreading require all these to exist */ - if(!nonespots) nonespots = 1; - if(!ntwospots) ntwospots = 1; - if(!ntails) ntails = 1; - if(!nhybrids) nhybrids = 1; - } - /* AIS: I de-staticed all these so they could be accessed by - yuk and cesspool, and added all the mentions of yuk and - multithread. Then I changed it so the variables would be - allocated dynamically, to speed up multithreading. (It's - an O(1) change to the speed of ordinary programs, so I - thought I could get away with it. The order is wrt the - number of lines in the program. The change is O(n) wrt - the number of variables, but again I hope that doesn't - matter, and I won't get the entire INTERCAL community - angry with me for daring to implement an extension that - slows down existing programs.) */ - if (nonespots) - { - (void) fprintf(ofp, - "type16* onespots;\n"); - (void) fprintf(ofp, - "bool* oneforget;\n"); - if(yukprofile || yukdebug) - { - (void) fprintf(ofp, - "type16 oneold[%d];\n", - nonespots); - (void) fprintf(ofp, - "signed char onewatch[%d];\n", - nonespots); - } - if(multithread) - { - (void) fprintf(ofp, - "int onespotcount = %d;\n", - nonespots); - } - } - if (ntwospots) - { - (void) fprintf(ofp, - "type32* twospots;\n"); - (void) fprintf(ofp, - "bool* twoforget;\n"); - if(yukprofile || yukdebug) - { - (void) fprintf(ofp, - "type32 twoold[%d];\n", - ntwospots); - (void) fprintf(ofp, - "signed char twowatch[%d];\n", - ntwospots); - } - if(multithread) - { - (void) fprintf(ofp, - "int twospotcount = %d;\n", - ntwospots); - } - } - if (ntails) - { - (void) fprintf(ofp, - "array* tails;\n"); - (void) fprintf(ofp, - "bool* tailforget;\n"); - if(multithread) - { - (void) fprintf(ofp, - "int tailcount = %d;\n", - ntails); - } - } - if (nhybrids) - { - (void) fprintf(ofp, - "array* hybrids;\n"); - (void) fprintf(ofp, - "bool* hyforget;\n"); - if(multithread) - { - (void) fprintf(ofp, - "int hybridcount = %d;\n", - nhybrids); - } - } - if (yydebug || compile_only) - for (op = oblist; op < obdex; op++) - (void) fprintf(ofp, " /* %s %d -> %d */\n", - nameof(op->type, vartypes), - op->extindex, - op->intindex); - if (yukdebug || yukprofile) - { /* AIS: drop intern to extern map into the program */ - (void) fprintf(ofp, "\nyukvar yukvars[]={\n"); - for (op = oblist; op < obdex; op++) - (void) fprintf(ofp," {%s,%d,%d},\n", - nameof(op->type, vartypes), - op->extindex, - op->intindex); - (void) fprintf(ofp," {YUKEND,0,0}};\n"); - } - break; - - case 'F': /* set clockface option? */ - if (clockface) - (void) fprintf(ofp, "clockface(TRUE);"); - break; - - case 'G': /* degenerated code */ - for (tp = tuples, i = 0; tp->type; tp++, i++) - { - emit(tp, ofp); - if (i == bugline) - (void) fprintf(ofp, " lose(E774, lineno, " - "(char *)NULL);\n"); - } - break; - - case 'H': /* COMPUCOME, and dispatching for resumes */ - /* AIS: Added COMPUCOME here. This line must be fully guarded - to prevent a longjmp to an uninitialised buffer (it's - guarded by a lose() in ick-wrap.c.) Also checks for - multithread; programs that mix normal and computed COME - FROM need to use the same conventions for both, so even - if no computed COME FROMs are used, the normal ones need - this line so that COME FROMs can be handled consistently.*/ - if(compucomesused || multithread) - { - (void) fprintf(ofp, "CCF%d: longjmp(cjb,1);\n", - compucomecount); - } - nextcount = 0; - for (tp = tuples; tp->type; tp++) - if (tp->type == NEXT) - nextcount++; - if (nextcount) - { - (void) fputs("/* generated switch for resumes */",ofp); - (void) fputs("top:\n switch(skipto)\n {\n", ofp); - for (tp = tuples; tp->type; tp++) - if (tp->type == NEXT) - (void) fprintf(ofp, - "\tcase %d: goto N%d; break;\n", - (int)(tp-tuples+1), (int)(tp-tuples+1)); - (void) fprintf(ofp, " }"); - } - break; - - case 'J': /* # of source file lines */ - (void) fprintf(ofp, "%d", yylineno); - break; - - case 'K': /* AIS: yuk information (or not) */ - if(yukdebug||yukprofile) - { - (void) fprintf(ofp, "#include \"yuk.h\"\n\n"); - (void) fprintf(ofp, "char* textlines[] = {\n"); - emittextlines(ofp); /* from feh.c */ - (void) fprintf(ofp, "\"\"};\n\n"); - (void) fprintf(ofp, "char* yukexplain[] = {\n"); - for (tp = tuples; tp->type; tp++) - { - if (tp->type == GETS || tp->type == FORGET || tp->type == RESUME - || tp->type == FROM || tp->type == COMPUCOME - || tp->type == MANYFROM) - { - (void) fprintf(ofp, "\""); - explexpr(tp->type == MANYFROM ? tp->u.node->lval : - tp->type == GETS ? tp->u.node->rval : tp->u.node, ofp); - (void) fprintf(ofp, "\",\n"); - } - else (void) fprintf(ofp, "0,"); - } - (void) fprintf(ofp, "0};\n\n"); - (void) fprintf(ofp, "int lineofaboff[] = {\n"); - for (tp = tuples; tp->type; tp++) - { - fprintf(ofp,"%d,",tp->lineno); - } - (void) fprintf(ofp, "-1};\n\n"); - (void) fprintf(ofp, "int yukopts = %d;\n", yukprofile+yukdebug*2); - (void) fprintf(ofp, "yptimer ypexectime[%d];\n", lineno); - (void) fprintf(ofp, "ypcounter ypexecount[%d];\n",lineno); - (void) fprintf(ofp, "ypcounter ypabscount[%d];\n",lineno); - } - break; - - case 'L': /* AIS: increase Emacs compatibility */ - (void) fprintf(ofp, - "/* -*- mode:c; compile-command:\"%s\" -*- */" - ,buf2); - break; - - case 'M': /* AIS: place a multithreading define in program */ - /* This is needed even in a non-multithread program, to let - the header files know it's non-multithread */ - (void) fprintf(ofp, "#define MULTITHREAD %d", multithread); - break; - - case 'N': /* allocate variables */ - /* AIS: I de-staticed all these so they could be accessed by - yuk and cesspool, and added all the mentions of yuk and - multithread. Then I changed it so the variables would be - allocated dynamically, to speed up multithreading (it's - an O(1) change to the speed of ordinary programs, so I - thought I could get away with it). At this point, the - 'E' case must already have been done. calloc sets all - the integer values to 0, as before. In the case of - arrays, it will not zero pointers, but the number-of- - dimensions value will become 0, which can serve as a - 'deallocated' flag. */ - if (nonespots) - { - (void) fprintf(ofp, - " onespots = calloc(" - "%d, sizeof *onespots);\n", - nonespots); - (void) fprintf(ofp, - " oneforget = calloc(" - "%d, sizeof *oneforget);\n", - nonespots); - } - if (ntwospots) - { - (void) fprintf(ofp, - " twospots = calloc(" - "%d, sizeof *twospots);\n", - ntwospots); - (void) fprintf(ofp, - " twoforget = calloc(" - "%d, sizeof *twoforget);\n", - ntwospots); - } - if (ntails) - { - (void) fprintf(ofp, - " tails = calloc(" - "%d, sizeof *tails);\n", - ntails); - (void) fprintf(ofp, - " tailforget = calloc(" - "%d, sizeof *tailforget);\n", - ntails); - } - if (nhybrids) - { - (void) fprintf(ofp, - " hybrids = calloc(" - "%d, sizeof *hybrids);\n", - nhybrids); - (void) fprintf(ofp, - " hyforget = calloc(" - "%d, sizeof *hyforget);\n", - nhybrids); - } - break; - } - - (void) fclose(ofp); - - /* OK, now sic the C compiler on the results */ - if (!compile_only&&!yukdebug&&!yukprofile) - { - /* AIS: buf2 now assigned elsewhere so $L works */ - (void) system(buf2); - /* AIS: no unlink if cdebug */ if(!cdebug) (void) unlink(buf); - } - else if(!compile_only) - { /* AIS: run, then delete all output but yuk.out */ - /* Note that the output must be deleted for copyright - reasons (so as not to GPL a non-GPL file automatically) */ - (void) system(buf2); - (void) freopen("/dev/tty", "r", stdin); - /* stdin has got seriously muddled, what with - it being redirected so much. Let's set it - to the keyboard (the only reasonable place - for input to a debugger anyway). If the user - wants to use the profiler with data from a file, - this won't work, so this code probably needs - changing. But the original value of stdin seems - to have been lost, and we need to redirect from - somewhere. */ - (void) system(argv[optind]); - (void) unlink(buf); - (void) unlink(argv[optind]); - } - if(coopt) /* AIS */ - { - /* The constant-output optimizer is a form of post-processor. - IMPORTANT NOTE: This MUST NOT be run if the input program - takes any input or is affected in any way by the state of - the system, as the degenerated program may be wrong. At the - moment, the only INTERCAL command that takes input is - WRITE IN. */ - if(cooptsh) - { - sprintf(buf2,"sh %s %s", cooptsh, argv[optind]); - (void) system(buf2); /* replaces the output executable if - neccesary */ - } - } - } - } - (void) fclose(ifp); - return 0; -} - -/* perpetrate.c ends here */ - diff --git a/pit/tests/pictest.i b/pit/tests/pictest.i new file mode 100644 index 0000000..95918b8 --- /dev/null +++ b/pit/tests/pictest.i @@ -0,0 +1,11 @@ +PLEASE NOTE This continuously copies PORTA to PORTB + (PORTA is always input, PORTB is always output) + DO .2 <- #0 + DO .1 <- #65280 + PLEASE COME FROM (11) + DO (1520) NEXT + DO PIN :1 + DO .1 <- :1~#255 + PLEASE DO .2 <- #257 + DO (1030) NEXT +(11) DO .1 <- .3 diff --git a/pit/tests/version.4i b/pit/tests/version.4i new file mode 100644 index 0000000..f18b9bc --- /dev/null +++ b/pit/tests/version.4i @@ -0,0 +1,7 @@ +(1) DO .1 <- #?6 + DOING DETECTION... YOU ARE USING INTERCAL-72 +(5) PLEASE COME FROM (1) + DOING DETECTION... YOU ARE USING C-INTERCAL + PLEASE COME FROM .1 + DOING DETECTION... YOU ARE USING CLC-INTERCAL + diff --git a/pit/tests/version.doc b/pit/tests/version.doc new file mode 100644 index 0000000..60ce346 --- /dev/null +++ b/pit/tests/version.doc @@ -0,0 +1,14 @@ +version.4i is a simple program that tests what version of INTERCAL you are +running. + +Under INTERCAL-72, the .4i suffix is ignored, and the COME FROM lines are +splatted. So execution flows to the first splat line, where an error is +reported that prints out the required message. + +Under C-INTERCAL (or CLC-INTERCAL faking it), the ? is interpreted as XOR, +leaving a hugely large value in .1. So the second COME FROM doesn't match, +and the second splat line generates the error. + +Under CLC-INTERCAL (or C-INTERCAL using the -X option), the ? is interpreted +as BUT, leaving #5 in .1. So the second COME FROM finds the required line +label, and the third splat line generates the error. diff --git a/sizes.h b/sizes.h deleted file mode 100644 index a344bc7..0000000 --- a/sizes.h +++ /dev/null @@ -1,9 +0,0 @@ -/* sizes.h -- constants defining the numeric base for INTERCAL variations */ - -extern int Base; -extern int Small_digits; -extern int Large_digits; -extern unsigned int Max_small; -extern unsigned int Max_large; - -/* sizes.h ends here */ diff --git a/specgen.sh b/specgen.sh deleted file mode 100755 index bc73394..0000000 --- a/specgen.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -version=$1 - -cat < 4000000000LU) exit(42); + +/* AIS: Handle multiple COME FROMs aiming at the same line */ +extern int multicome0(int errlineno, jmp_buf pc); + +#ifdef _POSIX_SOURCE +extern char *aref(unsigned int type, ...); +extern void resize(unsigned int type, ...); +#else +extern char *aref(); +extern void resize(); +#endif + +extern void stashinit(void); +/* AIS: Added mentions of oo. This is set to 0 in a non-overloaded program. */ +extern void stash(unsigned int type, unsigned int index, void *from, overop* oo); +extern void retrieve(void *to, int type, unsigned int index, bool forget, + overop* oo); +extern unsigned int roll(unsigned int n); + +/* defined in arrgghh.c */ +extern void parseargs(int argc, char **argv); + +/* AIS: Multithreading types and defines */ +#if MULTITHREAD != 0 +typedef struct tag_ickthread ickthread; +struct tag_ickthread +{ + void* varforget[8]; /* holds all four variable types, and forgetting data */ + int* nextstack; + int nextpointer; + jmp_buf pc; /* program counter */ + stashbox* sb; /* holds all stash data */ + ickthread* next; + ickthread* choicepoint; /* the top choicepoint available. Used as a next + pointer in the choicepoint stack. */ + int stale; /* if this is a choicepoint, whether it's a stale choicepoint. */ + int refcount; /* when Threaded INTERCAL and Backtracking INTERCAL are + combined, reference-counting on choicepoints is needed + so that backtracking past multithreading is possible. + This also allows for garbage-collection of choicepoints. + (Luckily, choicepoints cannot refer to themselves, so this + mechanism works.) This only applies to ickthreads that are + acting as choicepoints, not those acting as threads. */ + int ccfc; /* number of comefroms currently active */ + int skipto; /* compucome line number */ + jmp_buf cjb; /* keeps track of compucomes */ +}; +extern ickthread* ickmt_cur; /* current thread */ +extern ickthread* ickmt_prev; /* previous thread: an optimisation to make + thread switching O(1), not O(n), with + respect to the number of threads */ +#define NEXTTHREAD if(printflow) printf("[%d]",lineno); \ + if(setjmp(cjb) == 0) \ + nextthread(cjb, lineno, 3); + +extern void nextthread(jmp_buf pc, int errlineno, int flags); +extern void killthread(void); +extern void ickmtinit(void); +extern int multicome1(int errlineno, jmp_buf pc); +extern void choicepoint(void); +extern void choiceahead(void); +extern void choiceback(void); + +/* from ick-wrap.c, declare as extern so they can be accessed by cesspool.c, + unravel.c */ +extern int onespotcount; +extern int twospotcount; +extern int tailcount; +extern int hybridcount; + +extern int oldabstain; +extern int gonebackto; +extern int ccfc; +extern unsigned skipto; +extern jmp_buf btjb; +extern jmp_buf cjb; + +#define MULTICOME multicome1 +#else +#define MULTICOME multicome0 +#endif /* MULTITHREAD */ + +/* AIS: Used by the debugger, multithread code */ +#if (MULTITHREAD != 0) || (YUKDEBUG != 0) +extern type16* onespots; +extern bool* oneforget; +extern type32* twospots; +extern bool* twoforget; +extern array* tails; +extern bool* tailforget; +extern array* hybrids; +extern bool* hyforget; +#endif + +/* abcess.h ends here */ diff --git a/src/arrgghh.c b/src/arrgghh.c new file mode 100644 index 0000000..05dd619 --- /dev/null +++ b/src/arrgghh.c @@ -0,0 +1,111 @@ +/* + * SYNOPSIS: parseargs(argc,argv) + * FILE : parseargs.c + * AUTHOR : Steve Swales + * DATE: October 7, 1990 + * PURPOSE: Parse arguments for INTERCAL programs. + * +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include "abcess.h" +#include "lose.h" + +int traditional = 0; +int wimp_mode = 0; +int printflow = 0; /* AIS */ +int mystery = 0; /* AIS */ + +unsigned long mysteryc = 0; /* AIS */ + +void +parseargs(int argc, char **argv) +{ + register int i, j; + static int helpflag = -1; + static char *flags[] = { + "help", + "wimpmode", + "traditional", + "printflow", /* AIS */ + "mystery", /* AIS */ + }; + static int *bools[] = { + &helpflag, + &wimp_mode, + &traditional, + &printflow, /* AIS */ + &mystery, /* AIS */ + }; + static int nflags = (int)(sizeof(flags)/sizeof(flags[0])); + + for(i = 1;i < argc;i++) { + if(argv[i][0] != '+' && argv[i][0] != '-') { + break; + } + for(j = 0; j < nflags;j++) { + if(0 == strcmp(argv[i]+1,flags[j])) { + *(bools[j]) = (argv[i][0] == '+'); + break; + } + } + if(j == nflags) { + fprintf(stderr,"%s: can't grok %s\n",argv[0],argv[i]); + helpflag = 1; + } + } + if(helpflag != -1) { + if(!helpflag) { + fprintf(stderr, + "Once you start messing with INTERCAL... \n"); + fprintf(stderr,"\t\tthere is no help for you!\n\n"); + sleep(3); + } + fprintf(stderr,"Current flags (and current state) are:\n"); + for(i = 0;i < nflags;i++) { + fprintf(stderr,"\t[+/-]%-20.20s\t(%s)\n",flags[i], + (*(bools[i]) == 1)?"ON":((*(bools[i]) == 0)?"OFF":"???")); + } + fprintf(stderr,"All flags must be preceded by either + or -, which\n"); + fprintf(stderr," usually will mean turn on or turn off something,\n"); + fprintf(stderr," but not always, and not all of them currently\n"); + fprintf(stderr," do anything, but you can switch them on or off\n"); + fprintf(stderr," if you like anyway. Isn't this helpful?\n\n"); + fflush(stderr); + sleep(3); + lose(E778, 0, (char *)NULL); + } + if(wimp_mode) { + fprintf(stderr,"How sad... you have selected to run an INTERCAL\n"); + fprintf(stderr,"program in WIMP MODE.\n\n"); + fprintf(stderr,"This means that:\n"); + fprintf(stderr," A) Rather than the nifty input like:\n"); + fprintf(stderr,"\tONE NINER SEVEN TWO OH SIX THREE,\n"); + fprintf(stderr," and even niftier output like:\n"); + fprintf(stderr,"\t______\n"); + fprintf(stderr,"\tMCMLXXMMLXIII,\n"); + fprintf(stderr," you will have to settle for plain old number\n"); + fprintf(stderr," representations like 1972063; and,\n"); + fprintf(stderr," B) You are a WIMP!\n\n"); + fflush(stderr); + } +} diff --git a/src/cesspool.c b/src/cesspool.c new file mode 100644 index 0000000..f11283f --- /dev/null +++ b/src/cesspool.c @@ -0,0 +1,654 @@ +/***************************************************************************** + +NAME + cesspool.c -- storage management and runtime support for INTERCAL + +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +***************************************************************************/ +/* LINTLIBRARY */ +#include +#include +#include +#include + +/* AIS: Make this work with DJGPP's stdarg.h */ +#ifdef __DJGPP__ +#define _POSIX_SOURCE +#endif + +#ifdef _POSIX_SOURCE +#include +#else +#include +#endif + +#include "sizes.h" +/* AIS: To avoid a separate overloaded/nonoverloaded library, we import + the overloading defines here and ignore them if we don't need them. */ +#define MULTITHREAD 0 +#define OVEROPUSED 1 +#include "abcess.h" +#include "lose.h" + +#include "numerals.c" + +/* AIS: These will be set to stdin/stdout at the first opportunity, + which is not necessarily here. */ +FILE* cesspoolin=0; +FILE* cesspoolout=0; + +/********************************************************************** + * + * The following functions manipulate the nexting stack + * + *********************************************************************/ + +int* next; /* AIS: now allocated by ick-wrap.c */ +int nextindex = 0; + +void pushnext(int n) +{ + if (nextindex < MAXNEXT) + next[nextindex++] = n; + else + lose(E123, lineno, (char *)NULL); +} + +unsigned int popnext(int n) +{ + nextindex -= n; + if (nextindex < 0) { + nextindex = 0; + return (unsigned int)-1; + } + return(next[nextindex]); +} + +unsigned int resume(unsigned int n) +{ + if (n == 0) + { + lose(E621, lineno, (char *)NULL); + return 0; + } + else if ((n = popnext(n)) == (unsigned int)-1) + { + lose(E632, lineno, (char *)NULL); + return 0; + } + return(n); +} + +/********************************************************************** + * + * The following functions implement the INTERCAL I/O model + * + *********************************************************************/ + +unsigned int pin(void) +{ + char buf[BUFSIZ], *cp, *strtok(); + unsigned int result = 0; + int n; + extern int wimp_mode; + + if(!cesspoolin) cesspoolin=stdin; /* AIS */ + + if (fgets(buf, BUFSIZ, cesspoolin) == (char *)NULL) + lose(E562, lineno, (char *)NULL); + n = strlen(buf) - 1; + if (n > 0 && buf[n-1] == '\r') + --n; + buf[n] = '\0'; + + if(wimp_mode) { + result = (unsigned int)strtoul(buf, (char **)NULL, 10); + n = 1; + } + else + { + for(n=0,cp = strtok(buf, " ");cp;cp = strtok((char *)NULL, " "),n++) + { + int digit = -1; + numeral *np; + + for (np = numerals; np < numerals + sizeof(numerals)/sizeof(numeral); np++) + if (strcmp(np->name, cp) == 0) + { + digit = np->value; + break; + } + + if (digit == -1) + lose(E579, lineno, cp); + + if (result < 429496729 || (result == 429496729 && digit < 6)) + result = result * 10 + digit; + else + lose(E533, lineno, (char *)NULL); + } + } + if (!n) + lose(E562, lineno, (char *)NULL); + if (result > (unsigned int)Max_large) + lose(E533, lineno, (char *)NULL); + return(result); +} + +/********************************************************************** + * + * Butchered Roman numerals implemented by + * Michael Ernst, mernst@theory.lcs.mit.edu. May 7, 1990 + * + * The INTERCAL manual hints that 3999 should translate to MMMIM + * (compare MMMCMXCIX) without specifying what the translation is. + * That may be a typo; in any case, this implementation isn't that + * butchered. + * + *********************************************************************/ + +#define MAXDIGITS 10 /* max base 10 digits */ +#define MAXROMANS (MAXDIGITS*4+1) /* max chars in translation */ + +/* + * The first column tells how many of the succeeding columns are used. + * The other columns refer to the columns of br_equiv and br_overbar. + */ +static int br_trans[10][5] = +{ + {0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0}, + {2, 0, 0, 0, 0}, + {3, 0, 0, 0, 0}, + {2, 1, 2, 0, 0}, /* or use {4, 0, 0, 0, 0} */ + {1, 2, 0, 0, 0}, + {2, 2, 1, 0, 0}, + {3, 2, 1, 1, 0}, + {4, 2, 1, 1, 1}, + {2, 1, 3, 0, 0} +}; + +/* + * butcher places in the string result the "butchered" Roman numeral for val. + * This string should be printed at the beginning of a line; it spans two + * lines and already contains newlines. + * + * 11/24/91 LHH: Removed unnecessary final newline. + */ + +static void butcher(unsigned long val, char *result) +{ + int i, j; + int digitsig, digitval; + char res[MAXROMANS], ovb[MAXROMANS]; + + /* We need FOUR columns because of the odd way that M and I interact. */ + static char br_equiv[MAXDIGITS][4] = + { + {'I', 'I', 'V', 'X'}, {'X', 'X', 'L', 'C'}, + {'C', 'C', 'D', 'M'}, {'M', 'I', 'V', 'X'}, + {'X', 'X', 'L', 'C'}, {'C', 'C', 'D', 'M'}, + {'M', 'i', 'v', 'x'}, {'x', 'x', 'l', 'c'}, + {'c', 'c', 'd', 'm'}, {'m', 'i', 'v', 'x'}, + }; + + static char br_overbar[MAXDIGITS][4] = + { + {' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' '}, + {' ', '_', '_', '_'}, + {'_', '_', '_', '_'}, + {'_', '_', '_', '_'}, + {'_', ' ', ' ', ' '}, + {' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' '}, + {' ', '_', '_', '_'}, + }; + + if (val == 0) +/* Final newline will be added by puts. + (void) strcpy(result, "_\n \n"); +*/ + (void) strcpy(result, "_\n"); + else + { + res[MAXROMANS-1] = 0; + ovb[MAXROMANS-1] = 0; + i = MAXROMANS-1; + + /* the significance of the current digit is 10 ** digitsig */ + for (digitsig = 0; (digitsig < MAXDIGITS) && (val > 0); digitsig++) + { + digitval = val % 10; + for (j = br_trans[digitval][0]; j > 0; j--) + { + /* printf("In j loop: %d %d\n", j, i); */ + res[--i] = br_equiv[digitsig][br_trans[digitval][j]]; + ovb[i] = br_overbar[digitsig][br_trans[digitval][j]]; + } + val = val / 10; + } + + j = i; + while ((*result++ = ovb[j++])) + continue; + *--result = '\n'; + + j = i; + while ((*++result = res[j++])) + continue; +/* Final newline will be added by puts. + *result++ = '\n'; +*/ + *result = '\0'; + } +} + +void clockface(bool mode) +/* enable or disable clockface mode (output IIII instead of IV) */ +{ + if (mode) + { + /* clockface mode */ + br_trans[4][0] = 4; + br_trans[4][1] = 0; + br_trans[4][2] = 0; + } + else + { + /* normal mode */ + br_trans[4][0] = 2; + br_trans[4][1] = 1; + br_trans[4][2] = 2; + } +} + +void pout(unsigned int val) +/* output in `butchered' Roman numerals; see manual, part 4.4.13 */ +{ + char result[2*MAXROMANS+1]; + extern int wimp_mode; + + if(!cesspoolout) cesspoolout=stdout; /* AIS */ + + if(wimp_mode) { + (void) fprintf(cesspoolout,"%u\n",val); + } + else { + butcher(val, result); + (void) fprintf(cesspoolout,"%s\n",result); + } + fflush(cesspoolout); +} + +/********************************************************************** + * + * The following two routines implement bitwise I/O. They assume + * 8 bit characters, but there's no reason more general versions + * could not be written. + * + *********************************************************************/ + +void binin(unsigned int type, array *a, bool forget) +{ + static unsigned int lastin = 0; + int c, v; + unsigned int i; + + if (a->rank != 1) + lose(E241, lineno, (char *)NULL); + + if(!cesspoolin) cesspoolin=stdin; /* AIS */ + + for (i = 0 ; i < a->dims[0] ; i++) { + v = ((c=fgetc(cesspoolin)) == EOF) ? 256 : (c - lastin) % 256; + lastin = c; + if (!forget) { + if (type == TAIL) + a->data.tail[i] = v; + else + a->data.hybrid[i] = v; + } + } +} + +void binout(unsigned int type, array *a) +{ + static unsigned int lastout = 0; + unsigned int i, c; + + if (a->rank != 1) + lose(E241, lineno, (char *)NULL); + + if(!cesspoolout) cesspoolout=stdout; /* AIS */ + + for (i = 0 ; i < a->dims[0] ; i++) { + if (type == TAIL) + c = lastout - a->data.tail[i]; + else + c = lastout - a->data.hybrid[i]; + lastout = c; + c = (c & 0x0f) << 4 | (c & 0xf0) >> 4; + c = (c & 0x33) << 2 | (c & 0xcc) >> 2; + c = (c & 0x55) << 1 | (c & 0xaa) >> 1; + fputc(c,cesspoolout); + if (c == '\n') + fflush(cesspoolout); + } +} + +/********************************************************************** + * + * The following assignment function performs IGNORE and type checks + * + *********************************************************************/ + +unsigned int assign(char *dest, unsigned int type, bool forget, + unsigned int value) +{ + unsigned int retval = 0; + if (type == ONESPOT || type == TAIL) { + if (value > (unsigned int)Max_small) + lose(E275, lineno, (char *)NULL); + if (forget) + retval = value; + else { + retval = *(type16*)dest; + *(type16*)dest = value; + } + } + else if (type == TWOSPOT || type == HYBRID) { + if (forget) + retval = value; + else { + retval = *(type32*)dest; + *(type32*)dest = value; + } + } + return retval; +} + +/********************************************************************** + * + * The following functions implement the INTERCAL array model + * If _POSIX_SOURCE is defined, stdarg is used, otherwise varargs. + * + *********************************************************************/ + + +#ifdef _POSIX_SOURCE +char *aref(unsigned int type, ...) +#else +char *aref(va_alist) va_dcl +#endif +/* return a pointer to the array location specified by args */ +{ +#ifndef _POSIX_SOURCE + unsigned int type; +#endif + array *a; + unsigned int v; + va_list ap; + int address = 0; + unsigned int i; + +#ifdef _POSIX_SOURCE + va_start(ap, type); +#else + va_start(ap); + type = va_arg(ap, unsigned int); +#endif + a = va_arg(ap, array*); + + if (va_arg(ap, unsigned int) != a->rank) + lose(E241, lineno, (char *)NULL); + + for (i = 0 ; i < a->rank ; i++) { + v = va_arg(ap, unsigned int); + if (v == 0 || v > a->dims[i]) + lose(E241, lineno, (char *)NULL); + address = address * a->dims[i] + v - 1; + } + + va_end(ap); + + if (type == TAIL) + return (char*)&a->data.tail[address]; + else + return (char*)&a->data.hybrid[address]; +} + +#ifdef _POSIX_SOURCE +void resize(unsigned int type, ...) +#else +void resize(va_alist) va_dcl +#endif +/* resize an array to the given shape */ +{ +#ifndef _POSIX_SOURCE + unsigned int type; +#endif + array *a; + bool forget; + unsigned int i, r, v; + va_list ap; + int prod = 1; + +#ifdef _POSIX_SOURCE + va_start(ap, type); +#else + va_start(ap); + type = va_arg(ap, unsigned int); +#endif + a = va_arg(ap, array*); + forget = va_arg(ap, bool); + + if (!a->rank) a->dims = 0; /* AIS: a->dims no longer initialised */ + + r = va_arg(ap, unsigned int); + if (!forget) { + a->rank = r; + if (a->dims) + free((char*)a->dims); + a->dims = (unsigned int*) malloc(a->rank * sizeof(unsigned int)); + if (a->dims == NULL) + lose(E241, lineno, (char *)NULL); + } + + for (i = 0 ; i < r ; i++) { + v = va_arg(ap, unsigned int); + if (v == 0) + lose(E240, lineno, (char *)NULL); + if (!forget) { + a->dims[i] = v; + prod *= v; + } + } + + if (!forget) { + if (type == TAIL) { + if (a->data.tail) + free((char *)a->data.tail); + a->data.tail = (type16*)malloc(prod * sizeof(type16)); + if (a->data.tail == NULL) + lose(E241, lineno, (char *)NULL); + } + else { + if (a->data.hybrid) + free((char *)a->data.hybrid); + a->data.hybrid = (type32*)malloc(prod * sizeof(type32)); + if (a->data.hybrid == NULL) + lose(E241, lineno, (char *)NULL); + } + } + + va_end(ap); +} + +/********************************************************************** + * + * The following functions implement save/retrieve + * + *********************************************************************/ + +stashbox *first; /* AIS: made non-static so it can be seen by unravel.c */ + +void stashinit(void) +{ + first = NULL; +} + +static stashbox *fetch(unsigned int type, unsigned int index) +/* find a stashed variable in the save stack and extract it */ +{ + stashbox **pp = &first, *sp = first; + + while (sp && (sp->type != type || sp->index != index)) { + pp = &sp->next; + sp = sp->next; + } + if (sp) + *pp = sp->next; + + return (sp); +} + +void stash(unsigned int type, unsigned int index, void *from, overop* oo) +/* stash away the variable's value */ +{ + /* create a new stashbox and push it onto the stack */ + stashbox *sp = (stashbox*)malloc(sizeof(stashbox)); + if (sp == NULL) lose(E222, lineno, (char *)NULL); + sp->next = first; + first = sp; + + /* store the variable in it */ + sp->type = type; + sp->index = index; + if(oo) sp->overloadinfo=oo[index]; /* AIS */ + if (type == ONESPOT) + { + memcpy((char *)&sp->save.onespot, from, sizeof(type16)); + } + else if (type == TWOSPOT) + memcpy((char *)&sp->save.twospot, from, sizeof(type32)); + else if (type == TAIL || type == HYBRID) { + array *a = (array*)from; + int prod; + unsigned int i; + sp->save.a = (array*)malloc(sizeof(array)); + if (sp->save.a == NULL) lose(E222, lineno, (char *)NULL); + sp->save.a->rank = a->rank; + sp->save.a->dims = (unsigned int*)malloc(a->rank * sizeof(unsigned int)); + if (sp->save.a->dims == NULL) lose(E222, lineno, (char *)NULL); + memcpy((char*)sp->save.a->dims, (char*)a->dims, + a->rank * sizeof(unsigned int)); + prod = a->rank ? 1 : 0; + for (i = 0 ; i < a->rank ; i++) { + prod *= a->dims[i]; + } + if (type == TAIL) { + sp->save.a->data.tail = + (type16*)malloc(prod * sizeof(type16)); + if (sp->save.a->data.tail == NULL) lose(E222, lineno, (char *)NULL); + memcpy((char *)sp->save.a->data.tail, + (char*)a->data.tail, prod * sizeof(type16)); + } + else { + sp->save.a->data.hybrid = + (type32*)malloc(prod * sizeof(type32)); + if (sp->save.a->data.hybrid == NULL) lose(E222, lineno, (char *)NULL); + memcpy((char *)sp->save.a->data.hybrid, + (char*)a->data.hybrid, prod * sizeof(type32)); + } + } + return; +} + +void retrieve(void *to, int type, unsigned int index, bool forget, overop* oo) +/* restore the value of a variable from the save stack */ +{ + stashbox *sp; + + if ((sp = fetch(type, index)) == (stashbox *)NULL) + lose(E436, lineno, (char *)NULL); + else if (!forget) { + if(oo) oo[index]=sp->overloadinfo; /* AIS */ + if (type == ONESPOT) + memcpy(to, (char *)&sp->save.onespot, sizeof(type16)); + else if (type == TWOSPOT) + memcpy(to, (char *)&sp->save.twospot, sizeof(type32)); + else if (type == TAIL || type == HYBRID) { + array *a = (array*)to; + if (a->rank) { + free(a->dims); + if (type == TAIL) + free(a->data.tail); + else + free(a->data.hybrid); + memcpy(to, (char*)sp->save.a, sizeof(array)); + } + free(sp->save.a); + } + } + else if (type == TAIL || type == HYBRID) { + free(sp->save.a->dims); + if (type == TAIL) + free(sp->save.a->data.tail); + else + free(sp->save.a->data.hybrid); + free(sp->save.a); + } + free(sp); +} + +/********************************************************************** + * + * The following function is used for random decision making + * + *********************************************************************/ + +unsigned int roll(unsigned int n) +/* return TRUE on n% chance, FALSE otherwise */ +{ +#ifdef USG + return((unsigned int)(lrand48() % 100) < n); +#else + return((unsigned int)(rand() % 100) < n); +#endif /* UNIX */ +} + +/********************************************************************** + * + * AIS: This function is called when two COME FROMs reference the same + * line at runtime. multicome0 is used in a non-multithread + * program; it produces an error. For multicome1, see unravel.c. + * + *********************************************************************/ + +int multicome0(int errlineno, jmp_buf pc) +{ + (void) pc; /* it's ignored by this function */ + lose(E555, errlineno, (char *) NULL); + /* this line number is quite possibly going to be wildly inaccurate */ + return 0; +} + +/* cesspool.c ends here */ diff --git a/src/coopt.sh b/src/coopt.sh new file mode 100755 index 0000000..1195018 --- /dev/null +++ b/src/coopt.sh @@ -0,0 +1,45 @@ +#!/bin/sh +########################################################################### +# +# Name +# coopt.sh -- an inefficient optimizer that can produce very efficient +# code +# +# DESCRIPTION +# This optimizer is only run on noninteractive code that takes no +# output. (It's designed to run on executables produced by INTERCAL +# code, but will run on other executables that support the +mystery +# option). It optimizes the file by replacing it by one that simply +# produces the required output! Therefore, it creates fast but +# inefficient code. If the file to be optimized hits an error or +# is terminated by +mystery, then no changes are made. +# +# LICENSE TERMS +# Copyright (C) 2006 Alex Smith +# +# 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., 675 Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### + +rm icktemp.out >/dev/null 2>/dev/null +if $1 +mystery >icktemp.out 2>/dev/null ; then : ; else exit 0 ; fi +if grep 'ickoutTERM???!' icktemp.out ; then rm icktemp.out ; exit 0 ; fi +echo 'ickoutTERM???!' >> icktemp.out +rm $1 +echo "#!/bin/sh +cat <<'ickoutTERM???!'" | cat - icktemp.out > $1 +chmod +x $1 +rm icktemp.out +exit 0 diff --git a/src/dekludge.c b/src/dekludge.c new file mode 100644 index 0000000..f42004c --- /dev/null +++ b/src/dekludge.c @@ -0,0 +1,2198 @@ +/**************************************************************************** + +Name + dekludge.c -- C-INTERCAL expression and flow optimizers + +DESCRIPTION + This file contains optimizations used by the C-INTERCAL compiler. + +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +****************************************************************************/ +/*LINTLIBRARY */ +#include +#include +#include +#include "sizes.h" +#include "ick.h" +#include "parser.h" +#include "fiddle.h" +#include "lose.h" +#include "feh.h" + +extern int emitlineno; /* AIS: From feh2.c */ + +/* AIS: The following macro produces optimization debug data. I added all + occurences of it in this source file. It also keeps track of whether + optimizations have taken place. */ +#define OPTING(x) if(optdebug == 2) {\ + explexpr(optdebugnode,stderr);\ + putc('\n',stderr); } \ + if(optdebug == 3) {\ + prexpr(optdebugnode,stderr,0);\ + putc('\n',stderr); } \ + if(optdebug) fprintf(stderr,"[%s]",#x);\ + if(optdebug >= 2) putc('\n',stderr);\ + opted = 1; + +static void checknodeactbits(node *np); /* AIS: This prototype needed early */ +extern void prexpr(node *np, FILE* fp, int freenode); /* AIS */ + +/* By AIS. This function looks remarkably like a C++ copy-constructor to me, + just with extra arrows in. */ +node *nodecopy(node* n) +{ + node* np; + if(!n) return 0; + np = cons(n->opcode, nodecopy(n->lval), nodecopy(n->rval)); + np->constant = n->constant; + np->optdata = n->optdata; + np->width = n->width; + return np; +} + +/* This function by AIS. Compares expressions. In C++, I'd call this + node::operator== . */ +static bool nodessame(node* n1, node* n2) +{ + if(!n1) return !n2; + if(!n2) return 0; + if(n1->opcode!=n2->opcode) return 0; + if(!nodessame(n1->lval,n2->lval)) return 0; + if(!nodessame(n1->rval,n2->rval)) return 0; + switch(n1->opcode) + { + case ONESPOT: + case TWOSPOT: + case HYBRID: + case TAIL: + case MESH: + case MESH32: + return n1->constant == n2->constant; + case AND: + case OR: + case XOR: + return n1->width == n2->width; + default: + return 1; + } +} + +/* AIS: Checks if an abstention could affect a tuple. */ +int abstainmatch(int npconstant, int tptype) +{ + if(npconstant == tptype) return 1; + if(npconstant == ABSTAIN) + if(tptype == FROM || tptype == MANYFROM || tptype == DISABLE) return 1; + if(npconstant == REINSTATE) + if(tptype == DISABLE) return 1; + return 0; +} + + +/************************************************************************* + * + * AIS: Flow optimizer. (I wrote the whole of optimizef.) + * + * This analyses the flow of the program, checking to see which lines can + * have their guards omitted, which lines can be omitted altogether, which + * variables can never be ignored, etc. The degenerator lower down can take + * this information into account, producing faster and shorter source code. + * In an ideal world, we'd end up with the produced INTERCAL looking like + * proper C code, but somehow I think that's unlikely to happen. + * At the moment, it just checks for unused !abstained[] guards on + * statements and removes them (possibly removing comments altogether). + * This is minor, but should clear up degenerated code substantially. + * It also allows the code for gets to replace assign() with the faster = + * in cases where this doesn't affect the behaviour of the program. + * See the function itself for what I did to NEXT. + * + *************************************************************************/ + +void optimizef(void) +{ + tuple* tp, *tpa, *tpb; + atom* op; + node* np; + if(!flowoptimize) lose(E778, yylineno, (char *) NULL); + for (tp = tuples; tp < tuples + lineno; tp++) tp->abstainable = 0; + /* abstainable holds whether a line's abstention status can change */ + for (op = oblist; op < obdex; op++) op->ignorable = 0; + /* ignorable holds whether a variable's ignorance status can change */ + for (tp = tuples; tp < tuples + lineno; tp++) + { + if(tp->maybe) tp->abstainable = 1; + if(tp->exechance < 0) tp->initabstain = 1; + if(tp->exechance != 100 && tp->exechance != -100) tp->abstainable = 1; + if(tp->onceagainflag != onceagain_NORMAL) tp->abstainable = 1; + if(tp->type == ABSTAIN || tp->type == FROM) + { + tpa = tp->u.target - 1 + tuples; + if(tpa->exechance >= 0) tpa->abstainable = 1; + } + if(tp->type == REINSTATE) + { + tpa = tp->u.target - 1 + tuples; + if(tpa->exechance < 0) tpa->abstainable = 1; + } + if(tp->type == DISABLE || tp->type == MANYFROM) + { + for (tpa = tuples; tpa < tuples + lineno; tpa++) + { + np = tp->u.node; + if(tp->type == MANYFROM) np = np->rval; + for(; np; np = np -> rval) + if(abstainmatch(np->constant, tpa->type)) + if(tpa->exechance >= 0) tpa->abstainable = 1; + } + } + if(tp->type == ENABLE) + { + for (tpa = tuples; tpa < tuples + lineno; tpa++) + { + np = tp->u.node; + for(; np; np = np -> rval) + if(abstainmatch(np->constant, tpa->type)) + if(tpa->exechance < 0) tpa->abstainable = 1; + } + } + if(tp->type == GETS && Base == 2 && !opoverused) + checknodeactbits(tp->u.node->rval); + /* If optdata shows that the value must always fit in the variable, + and the variable cannot be ignored, assign can be replaced by the + cheaper =. */ + if(tp->type == IGNORE) + { + for (np = tp->u.node; np; np = np->rval) + { + for (op = oblist; op < obdex; op++) + { + if(op->type == np->opcode && (unsigned)op->intindex == np->constant) + op->ignorable = 1; + } + } + } + /* REMEMBERING variables has no effect on this code, because all + variables are initially remembered anyway, and so an IGNORE would + be needed (and caught above) to have an effect. */ + } + /* There are some flow idioms that maybe should be optimized. The most + common is the NEXTing idiom for if(), which looks like this: + + DO (1) NEXT + block 2 + escape via NEXTING or COMEFROM + (1) DO (2) NEXT + DO FORGET #1 + block 1 + + and elsewhere in the program: + (2) DO RESUME <1-or-2-condition> + + Recognizing this idiom is quite difficult because there are a number of + problems and common variations. + First, the FORGET might be placed elsewhere, or replaced with a higher + FORGET later or a higher RESUME later. If there is, in fact, a RESUME #1 + as the next NEXT-control statement, the idiom won't quite work properly. + So to handle this, we need to push the original return address on the + NEXT stack if block 1 is taken, unless the next statement is a FORGET #1. + Second, there may be abstentions or COME FROMs messing with control flow + in the area. The flow optimizer ought to be able to detect this and not + optimize the statement if true. (This means that a program which uses + gerund abstention on NEXTING or RESUMING, or that uses computed COME FROM, + will probably not benefit from this optimization). Third, how should a + <1-or-2-condition> be detected? Throughout syslib, the most common + condition to use is .5, which isn't inherently 1 or 2. The way round this + seems to be to detect a <1-or-2-assignment> as the previous statement, + again with checks for COME FROM and abstentions. (I treat MAYBE as a sort + of abstention, albeit a temporally undecided one.) So ignorance of the + relevant variable needs to be checked for also. The checks are done partly + in optimizef() and partly in emit(). + */ + if(compucomesused||Base!=2||opoverused) return; + + np = (node*) NULL; + for (tp = tuples; tp < tuples + lineno; tp++) + { + if(tp->type == GETS) + { + if(tp->u.node->rval->opcode == C_AND1ADD1 || + tp->u.node->rval->opcode == C_2SUBAND1 || + ((tp->u.node->rval->opcode == C_1PLUS || + tp->u.node->rval->opcode == C_2MINUS) && + tp->u.node->rval->rval->optdata == 1)) + { + /* This won't catch all <1-or-2-expressions>, but will get + most of them. */ + if(tp->u.node->lval->opcode != SUB) np = tp->u.node->lval; + } + else if(np&&nodessame(np, tp->u.node->lval)) np = (node*) NULL; + if(tp->nextable) np = (node*) NULL; + if(tp->maybe||tp->abstainable) np = (node*) NULL; + if(tp->ncomefrom&&multithread) np = (node*) NULL; + if(np) + { /* IGNORING np might prevent it getting its <1-or-2-value>. */ + atom* op; + int ignorable = 1; + for(op = oblist; op < obdex; op++) + { + if(op->type == np->opcode && + (unsigned)op->intindex == np->constant) + { + ignorable &= op->ignorable; + } + } + if(ignorable) np = (node*) NULL; + } + /* np will only have a nonnull value if it's a variable that must be + set to a <1-or-2-value> to reach line tp. Regardless of whether + maybes have been parsed or not, either maybe or abstainable or + both will be 1 on a MAYBE line. The last check is a precaution + against MAYBE COME FROM sneakily modifying a variable (although + I think it's unlikely that anyone would deliberately try to fool + -f like this, it is INTERCAL after all!) */ + } + if(tp->type == COME_FROM || tp->type == COMPUCOME) np = (node*) NULL; + if(tp->type == NEXT) + { + tpa = tuples + tp->nexttarget - 1; + if(tpa->type == NEXT && !tp->abstainable && !tpa->abstainable + && !tp->ncomefrom && !tpa->ncomefrom) + { + tpb = tuples + tpa->nexttarget - 1; + if(tpb->type == RESUME && ((tpb->u.node->opcode == C_AND1ADD1 || + tpb->u.node->opcode == C_2SUBAND1 || + ((tpb->u.node->opcode == C_1PLUS || + tpb->u.node->opcode == C_2MINUS) && + tpb->u.node->rval->optdata == 1)) || + (np&&nodessame(tpb->u.node,np))) && + !tpb->abstainable) + /* No COMING FROM a nonabstainable RESUME line! */ + { + tp->optversion = TRUE; + tp->u.node = nodecopy(tpb->u.node); + /* If tp->u.node is 2, then the statement should translate to a + no-op (NEXT...NEXT...RESUME #2). However, if tp->u.node is 1, + the statement should translate to a NEXT to the line after the + one it's aiming for. As it's aiming for a NEXT, the solution is + to NEXT to the return label of the NEXT it's aiming for. This + won't trigger any COME FROMs or ONCE/AGAIN flags, or even MAYBEs, + on the commands missed out, so the code has checked that they + aren't there. */ + } + } + np = (node*) NULL; + } + } +} + +/************************************************************************* + * + * Expression optimizer. + * + * It's not a very good optimizer, is it? + * + * AIS: All free'd pointers set to NULL, to help trace memory problems. + * The optimizer can now recognize the majority of syslib's idioms. + * The optimizer will make multiple passes. Although I am now happy + * with the quality of this optimizer, I'll keep the paragraph above + * this one for history's sake. The optimizing functions return 1 + * if any optimizations were made, apart from optimize itself, which + * is void. + * + **************************************************************************/ + +static int optimize_pass1(node *np); +static int optimize_pass2(node *np); +static void checkforintercaloperators(node *np); +static void checkW534(node *np); + +static node* optdebugnode; + +/* This function by AIS */ +void optimize(node *np) +{ + int optflag; + if(opoverused) return; /* what chance do we have of optimizing this? */ + if(Base==2) + { + checknodeactbits(np); + checkW534(np); /* This must be done before optimization, and depends on + checknodeactbits. */ + } + if(optdebug == 1) explexpr(np,stderr); + if(optdebug == 1) fprintf(stderr," becomes "); + if(optdebug >= 2) optdebugnode = np; + optimize_pass1(np); /* Optimize idioms */ + if(Base!=2) + { + if(optdebug && optdebug != 3) explexpr(np,stderr); + if(optdebug == 3) prexpr(np,stderr,0); + if(optdebug) fprintf(stderr,"\n"); + if(optdebug >= 2) fprintf(stderr,"-----\n"); + return; + } + do + { + checknodeactbits(np); /* Determine bitranges */ + optflag = optimize_pass2(np); /* Optimize based on those bitranges */ + optflag |= optimize_pass1(np); + } while(optflag); /* Keep optimizing until no optimizations are found */ + if(optdebug && optdebug != 3) explexpr(np,stderr); + if(optdebug == 3) prexpr(np,stderr,0); + if(optdebug) fprintf(stderr,"\n"); + if(optdebug >= 2) fprintf(stderr,"-----\n"); + checkforintercaloperators(np); + if(optuple->type == RESUME && !np->optdata) optuple->warn622 = 1; +} + +/* By AIS. This relies on free'd pointers being NULLed. */ +void nodefree(node *np) +{ + if(!np) return; + if(np->opcode==SLAT) return; /* mustn't be freed yet */ + nodefree(np->lval); + nodefree(np->rval); + free(np); +} + +/* By AIS. This checks W534. */ +static void checkW534(node *np) +{ + if(!np) return; + if(np->opcode == AND || np->opcode == OR || np->opcode == XOR) + { + if(np->rval->opcode == SELECT && np->rval->rval->width == 32 && + !(np->rval->rval->optdata&0xffff0000lu)) + { + /* This looks suspicious, in that C-INTERCAL will do an op32, + but INTERCAL-72 would have done an op16. */ + optuple->warn534=1; + } + } + checkW534(np->lval); + checkW534(np->rval); +} + +/* By AIS. This checks W018. */ +static void checkforintercaloperators(node *np) +{ + if(!np) return; + switch(np->opcode) + { /* This only comes up in binary. */ + case AND: case OR: case XOR: case MINGLE: case SELECT: + optuple->warn018 = 1; + default: + checkforintercaloperators(np->lval); + checkforintercaloperators(np->rval); + return; + } +} + +/* By AIS (with a few code fragments copied from elsewhere in this file) */ +static void checknodeactbits(node *np) +{ + if (np == (node *)NULL) + return; + else if (np->lval != (node *)NULL) + checknodeactbits(np->lval); + if (np->rval != (node *)NULL) + checknodeactbits(np->rval); + + switch (np->opcode) + { + case MINGLE: + if(np->lval->optdata & 0xffff0000LU) optuple->warn276 = 1; + if(np->rval->optdata & 0xffff0000LU) optuple->warn276 = 1; + np->optdata = mingle(np->lval->optdata & 0xffff, + np->rval->optdata & 0xffff); + /* The bitmask is needed because the output of ~ might always be 16-bit + at runtime, but appear 32-bit at compile-time. But this is somewhat + suspicious, so we can at least give a warning (W276) if -l is used. */ + break; + + case SELECT: + np->optdata = np->lval->optdata & np->rval->optdata; + np->optdata = iselect(np->optdata, np->optdata); + break; + + case AND: + np->optdata = (np->width==16?and16:and32)(np->rval->optdata); + break; + + case OR: + case XOR: + np->optdata = (np->width==16?or16:or32)(np->rval->optdata); + /* This is or in both cases. */ + break; + + case FIN: + case WHIRL: + case WHIRL2: + case WHIRL3: + case WHIRL4: + case WHIRL5: /* We must be in binary to reach this point, so: */ + lose(E997, emitlineno, (char*) NULL); + break; + + case MESH: + case MESH32: + np->optdata = np->constant; /* It's trivial to tell which bits + can be nonzero! */ + break; + + case ONESPOT: + case TWOSPOT: + case TAIL: + case HYBRID: + case SUB: + np->optdata = np->width == 16 ? 0xffff : 0xffffffffLU; + break; + + /* cases from here down are generated by optimize_pass1 */ + case C_AND: + np->optdata = np->lval->optdata & np->rval->optdata; + break; + + case C_OR: + case C_XOR: + np->optdata = np->lval->optdata | np->rval->optdata; + /* bitwise-or is correct in both cases */ + break; + + case C_NOT: + np->optdata = np->width == 16 ? 0xffff : 0xffffffffLU; + break; + + case C_A: + np->optdata = 0xffffffffLU; + break; + + case C_NOTEQUAL: + case C_NNAND: + case C_ISNONZERO: + case C_XORGREATER: + np->optdata = 1; /* that's what !! does! */ + break; + + case C_AND1ADD1: + case C_2SUBAND1: + np->optdata = 3; /* the value could be 1 or 2 */ + break; + + case C_1PLUS: + np->optdata = np->rval->optdata | (np->rval->optdata << 1); + /* this relies on unsigned overflow handling to work correctly */ + break; + + case C_2MINUS: + if(np->rval->optdata == 1) np->optdata = 3; + else np->optdata = (np->width == 16 ? 0xffff : 0xfffffffflu); + /* alright, so this might not be ruthless enough, but C_2MINUS is + only meant to be generated when the condition is true anyway */ + break; + + case C_LSHIFT: + np->optdata = (np->lval->optdata & np->rval->optdata) << 1; + break; + + case C_LSHIFTIN1: + np->optdata = ((np->lval->optdata & np->rval->optdata) << 1) | 1; + break; + + case C_LSHIFT2: + np->optdata = (np->lval->optdata & np->rval->optdata) << 2; + break; + + case C_LSHIFT8: + np->optdata = (np->lval->optdata & np->rval->optdata) << 8; + break; + + case C_RSHIFTBY: + if(np->rval->opcode == MESH || np->rval->opcode == MESH32) + np->optdata = np->lval->optdata >> np->rval->constant; + else np->optdata = (np->width == 16 ? 0xffff : 0xffffffffLU); + /* Just like C_2MINUS, play safe if the RHS isn't a constant */ + break; + + case C_RSHIFT: + np->optdata = (np->lval->optdata & np->rval->optdata) >> 1; + break; + + case GETS: + /* Of course, this doesn't return a value. So this uses the default + code just below it, which is why it doesn't end in break;. This + has its own case so that W276 can be given on an assignment. */ + if(np->lval->optdata == 0xffff && + np->rval->optdata & 0xffff0000lu) optuple->warn276 = 1; + /* no break;! */ + + default: + if(np->opcode == BY && !np->lval->optdata) optuple->warn239 = 1; + np->optdata = (np->width == 16 ? 0xffff : 0xffffffffLU); + /* Some values of opcode are used as placeholders, to save more than 1 + piece of information in a node. The optdata for these is probably + irrelevant, but just in case, we mark all possible bits as active. */ + break; + } +} + +/* This function by AIS. Pass 2 removes redundant logical operations, + mostly explicit and implied C_AND. It destroys information needed by + Pass 1, which is why it's in a separate function. */ +static int optimize_pass2(node *np) +{ + node *op; + int opted = 0; + /* AIS: Paraphrased from code in the old 'optimize' function */ + /* recurse so we simplify each node after all its subnodes */ + if (np == (node *)NULL) + return 0; + else if (np->lval != (node *)NULL) + opted |= optimize_pass2(np->lval); + if (np->rval != (node *)NULL) + opted |= optimize_pass2(np->rval); + /* End of paraphrase */ + + /* Put constants of AND-like opcodes on the right */ + if((np->opcode == C_AND || np->opcode == C_NNAND || + np->opcode == C_LSHIFT || np->opcode == C_LSHIFTIN1 || + np->opcode == C_LSHIFT2 || np->opcode == C_LSHIFT8 || + np->opcode == C_RSHIFT) && + (np->lval->opcode == MESH || np->lval->opcode == MESH32)) + { + OPTING(andlikeconstmove) + op = np->lval; + np->lval = np->rval; + np->rval = op; + } + + /* The implicit &1 in C_AND1ADD1 and C_2SUBAND1 may be removable. */ + if(np->opcode == C_AND1ADD1 && np->rval->optdata == 1) + { + OPTING(impand1a1) + np->opcode = C_1PLUS; + } + if(np->opcode == C_2SUBAND1 && np->rval->optdata == 1) + { + OPTING(impand12m) + np->opcode = C_2MINUS; + } + + if(np->opcode == C_AND && (np->rval->opcode == MESH || + np->rval->opcode == MESH32) && + !(np->lval->optdata & ~np->rval->constant)) + { + OPTING(unneededand) + /* This AND is unnecessary. optdata stays the same. */ + op = np->lval; + free(np->rval); + *np = *op; + free(op); + } + + if((np->opcode == C_NNAND || np->opcode == C_RSHIFT) && + (np->rval->opcode == MESH || np->rval->opcode == MESH32) && + !(np->lval->optdata & ~np->rval->constant)) + { + /* The implicit AND here is unneccesary. Eliminate it. */ + OPTING(unneededimpand) + if(np->opcode == C_RSHIFT) + { + np->rval->constant = 1; + np->rval->optdata = 1; + np->opcode = C_RSHIFTBY; + } + else + { + np->opcode = C_ISNONZERO; + free(np->rval); + np->rval = np->lval; + np->lval = (node*) NULL; + } + } + + if((np->opcode == C_AND || np->opcode == C_NNAND || + np->opcode == C_LSHIFT || np->opcode == C_LSHIFTIN1 || + np->opcode == C_LSHIFT2 || np->opcode == C_LSHIFT8 || + np->opcode == C_RSHIFT) && np->lval->opcode == C_AND && + (np->rval->opcode == MESH || np->rval->opcode == MESH32) && + (np->lval->rval->opcode == MESH || np->lval->rval->opcode == MESH32)) + { + OPTING(combineand) + /* Combine the two ANDs into one. (The AND at np may be implicit.) + Leave opdata the same. */ + np->rval->constant &= np->lval->rval->constant; + op = np->lval; + free(op->rval); + np->lval = op->lval; + free(op); + } + + if((np->opcode == C_AND || np->opcode == C_NNAND || + np->opcode == C_LSHIFT || np->opcode == C_LSHIFTIN1 || + np->opcode == C_LSHIFT2 || np->opcode == C_LSHIFT8 || + np->opcode == C_RSHIFT) && + (np->rval->opcode == MESH || np->rval->opcode == MESH32) && + (~np->lval->optdata & np->rval->constant)) + { + OPTING(weakenand) + /* Reduce the constant in this C_AND-like expression + to aid further optimization */ + np->rval->constant &= np->lval->optdata; + } + return opted; +} + +/* Pass 1. Optimizes idioms. */ +static int optimize_pass1(node *np) /* AIS: was 'optimize'. Recursive calls in + here have been updated. */ +{ + node *mingleop, *op, *op2; + unsigned long temp = 0; + int temp2 = 0; + int opted = 0; + + /* recurse so we simplify each node after all its subnodes + AIS: Keep track of whether we've optimized anything. I added + all uses of the variable 'opted', and a return value. */ + if (np == (node *)NULL) + return 0; + else if (np->lval != (node *)NULL) + opted |= optimize_pass1(np->lval); + if (np->rval != (node *)NULL) + opted |= optimize_pass1(np->rval); + + /* + * OK, now do complete folding of constant expressions. + */ + + /* fold MINGLE operations on constants */ + if (np->opcode==MINGLE && (np->lval->opcode==MESH&&np->rval->opcode==MESH)) + { + OPTING(minglefold) + np->opcode = MESH32; + np->constant = mingle(np->lval->constant, np->rval->constant); + free(np->lval); + free(np->rval); + np->lval=(node*)NULL; + np->rval=(node*)NULL; + } + + /* fold SELECT operations on constants */ + if (np->opcode == SELECT + && ((np->lval->opcode==MESH || np->lval->opcode==MESH32) + && (np->rval->opcode==MESH || np->rval->opcode==MESH32))) + { + OPTING(selectfold) + np->opcode = np->rval->opcode; + np->constant = iselect(np->lval->constant, np->rval->constant); + free(np->lval); + free(np->rval); + np->lval=(node*)NULL; + np->rval=(node*)NULL; + } + + /* fold AND operations on 16-bit constants */ + if (np->opcode == AND && np->rval->opcode == MESH) + { + OPTING(and16fold) + np->opcode = MESH; + np->constant = and16(np->rval->constant); + free(np->rval); + np->rval=(node*)NULL; + } + + /* fold AND operations on 32-bit constants */ + if (np->opcode == AND && np->rval->opcode == MESH32) + { + OPTING(and32fold) + np->opcode = MESH32; + np->constant = and32(np->rval->constant); + free(np->rval); + np->rval=(node*)NULL; + } + + /* fold OR operations on 16-bit constants */ + if (np->opcode == OR && np->rval->opcode == MESH) + { + OPTING(or16fold) + np->opcode = MESH; + np->constant = or16(np->rval->constant); + free(np->rval); + np->rval=(node*)NULL; + } + + /* fold OR operations on 32-bit constants */ + if (np->opcode == OR && np->rval->opcode == MESH32) + { + OPTING(or32fold) + np->opcode = MESH32; + np->constant = or32(np->rval->constant); + free(np->rval); + np->rval=(node*)NULL; + } + + /* fold XOR operations on 16-bit constants */ + if (np->opcode == XOR && np->rval->opcode == MESH) + { + OPTING(xor16fold) + np->opcode = MESH; + np->constant = xor16(np->rval->constant); + free(np->rval); + np->rval=(node*)NULL; + } + + /* fold XOR operations on 32-bit constants */ + if (np->opcode == XOR && np->rval->opcode == MESH32) + { + OPTING(xor32fold) + np->opcode = MESH32; + np->constant = xor32(np->rval->constant); + free(np->rval); + np->rval=(node*)NULL; + } + + /* + * Less trivial stuff begins here + */ + + /* following optimizations only work in binary */ + if (Base != 2) + return opted; + + /* recognize the idioms for various C binary logical operations */ + if (np->opcode == SELECT + && np->rval->opcode == MESH32 && np->rval->constant == 0x55555555 + && (op = np->lval) + && (op->opcode == AND || op->opcode == OR || op->opcode == XOR) + && (mingleop = op->rval) && mingleop->opcode == MINGLE + && mingleop->rval->width == 16 + && mingleop->lval->width == 16) + { + OPTING(cbinlogop) + free(np->rval); /* AIS */ + + np->lval = mingleop->lval; + np->rval = mingleop->rval; + + switch(op->opcode) + { + case AND: np->opcode = C_AND; break; + case OR: np->opcode = C_OR; break; + case XOR: np->opcode = C_XOR; break; + default: lose(E778, yylineno, (char *)NULL); + } + + free(mingleop); free(op); + } + + /* AIS: Sometimes C binary logical operations have a smaller rval->constant. */ + if (np->opcode == SELECT + && (np->rval->opcode == MESH32||np->rval->opcode == MESH) + && (op = np->lval) && !(np->rval->constant&0xAAAAAAAALU) + && (op->opcode == AND || op->opcode == OR || op->opcode == XOR) + && (mingleop = op->rval) && mingleop->opcode == MINGLE + && mingleop->rval->width == 16 + && mingleop->lval->width == 16) + { + unsigned long i=iselect(np->rval->constant,0x55555555LU); + if(i==iselect(i,i)) + { + OPTING(smallcbinlogop) + np->lval = mingleop; + + switch(op->opcode) + { + case AND: np->lval->opcode = C_AND; break; + case OR: np->lval->opcode = C_OR; break; + case XOR: np->lval->opcode = C_XOR; break; + default: lose(E778, yylineno, (char *)NULL); + } + np->opcode = C_AND; + np->rval->constant=i; /* np->rval->opcode already correct */ + + free(op); + } + } + + /* recognize idioms for ~ */ + if (np->opcode == C_XOR) + { + /* AIS: Warning! We have to check again for C_XOR, else we will + be making use of the freed np->lval. This is not strictly necessary in + the first case. I added extra conditions to prevent np->lval being + used after deallocation, which is how I discovered the error in the + first place. (Some code elsewhere was messing up, and I suspected + memory allocation problems.) */ + if (np->opcode == C_XOR && np->rval->width == 16 + && np->lval->opcode == MESH &&np->lval->constant == 0xffff) + { + OPTING(cnot1) + np->opcode = C_NOT; + free(np->lval); + np->lval=(node*)NULL; + } + + if (np->opcode == C_XOR && np->lval->width == 16 + && np->rval->opcode == MESH && np->rval->constant == 0xffff) + { + OPTING(cnot2) + np->opcode = C_NOT; + free(np->rval); + np->rval = np->lval; + np->lval=(node*)NULL; + } + + if (np->opcode == C_XOR && np->rval->width == 32 + && np->lval->opcode == MESH32 && np->lval->constant == 0xffffffffLU) + { + OPTING(cnot3) + np->opcode = C_NOT; + free(np->lval); + np->lval=(node*)NULL; + } + + if (np->opcode == C_XOR && np->lval->width == 32 + && np->rval->opcode == MESH32 && np->rval->constant == 0xffffffffLU) + { + OPTING(cnot4) + np->opcode = C_NOT; + free(np->rval); + np->rval = np->lval; + np->lval=(node*)NULL; + } + } + + /* AIS: I wrote everything from here to the end of this function. */ + + /* recognize the idiom x~'pow(2,n)-1' */ + if (np->opcode==SELECT&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& + iselect(np->rval->constant,np->rval->constant)==np->rval->constant) + { + OPTING(pow2m1select) + np->opcode = C_AND; /* This is cheaper than both SELECT and C_NNAND. + lval, rval already correct. */ + } + + /* recognize the idiom x~pow(2,n). */ + if (np->opcode==SELECT&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& + iselect(np->rval->constant,np->rval->constant)==1) /* see, INTERCAL + operators can be + useful in C! */ + { + OPTING(pow2select) + np->opcode = C_NNAND; /* lval, rval already correct. C_NNAND is cheaper + than iselect. */ + if(np->rval->constant==1) np->opcode = C_AND; + } + + /* recognize select-mingle combinations which can be replaced by &, | and + single bitshifts (there are five of these in total) + Most of these idioms are used when doing 32-bit logical operations + separately on odd and even bits. Although these optimizations can speed + up code containing them a bit, their main purpose is to replace the + expressions with a consistent, short form that later optimizations can + recognize. (In fact, some later optimizations are effectively + optimizations on the degenerated C code, not on the INTERCAL original.) */ + if (np->opcode==MINGLE&&np->lval->opcode==SELECT&& + np->lval->rval->opcode==MESH32&&np->lval->rval->constant==0xaaaaaaaa) + { + OPTING(selectmingle1) + np->opcode=C_OR; + np->lval->opcode=C_AND; + op=np->rval; + np->rval=newnode(); + np->rval->opcode=MINGLE; + np->rval->lval=newnode(); + np->rval->lval->opcode=MESH; + np->rval->lval->width=16; + np->rval->lval->constant=0; + np->rval->rval=op; + np->rval->width=32; + optimize_pass1(np->rval); + optimize_pass1(np->lval); + /* replace (a~0xaaaaaaaa)$b with (a&0xaaaaaaaa)|(0$b) + if b is a constant, the recursive call to optimize does + constant folding */ + if(np->opcode==C_OR&&np->lval->opcode==C_AND&& + np->rval->opcode==MESH32&&np->rval->constant==0) + { /* check the conditions again in case it's been optimized */ + /* get rid of the C_OR */ + np->opcode=C_AND; + op=np->lval; + np->lval=op->lval; + np->rval->constant=op->rval->constant; + free(op->rval); + free(op); + optimize_pass1(np->lval); + } + else if(np->opcode==C_OR&&np->lval->opcode==C_AND&& + np->rval->opcode==MESH32&&np->rval->constant==0x55555555) + { /* check the conditions again in case it's been optimized */ + /* get rid of the C_AND */ + op=np->lval; + np->lval=op->lval; + free(op->rval); + free(op); + optimize_pass1(np->lval); + } + } + + if (np->opcode==MINGLE&&np->rval->opcode==SELECT&& + np->rval->rval->opcode==MESH32&&np->rval->rval->constant==0x55555555) + { + OPTING(selectmingle2) + np->opcode=C_OR; + np->rval->opcode=C_AND; + op=np->lval; + np->lval=newnode(); + np->lval->opcode=MINGLE; + np->lval->rval=newnode(); + np->lval->rval->opcode=MESH; + np->lval->rval->width=16; + np->lval->rval->constant=0; + np->lval->lval=op; + np->lval->width=32; + optimize_pass1(np->lval); + optimize_pass1(np->rval); + /* replace b$(a~0x55555555) with (a&0x55555555)|(b$0) + if b is a constant, the recursive call to optimize does + constant folding */ + if(np->opcode==C_OR&&np->rval->opcode==C_AND&& + np->lval->opcode==MESH32&&np->lval->constant==0) + { /* check the conditions again in case it's been optimized */ + /* get rid of the C_OR */ + np->opcode=C_AND; + op=np->rval; + np->rval=op->lval; + np->lval->constant=op->rval->constant; + free(op->rval); + free(op); + optimize_pass1(np->rval); + } + else if(np->opcode==C_OR&&np->rval->opcode==C_AND&& + np->lval->opcode==MESH32&&np->lval->constant==0xaaaaaaaa) + { /* check the conditions again in case it's been optimized */ + /* get rid of the C_AND */ + op=np->rval; + np->rval=op->lval; + free(op->rval); + free(op); + optimize_pass1(np->rval); + } + } + + if (np->opcode==MINGLE&&np->lval->opcode==SELECT&& + np->lval->rval->opcode==MESH32&&np->lval->rval->constant==0x55555555) + { + OPTING(selectmingle3) + np->opcode=C_OR; + np->lval->opcode=C_LSHIFT; /* (a&b)<<1 */ + op=np->rval; + np->rval=newnode(); + np->rval->opcode=MINGLE; + np->rval->lval=newnode(); + np->rval->lval->opcode=MESH; + np->rval->lval->width=16; + np->rval->lval->constant=0; + np->rval->rval=op; + np->rval->width=32; + optimize_pass1(np->rval); + optimize_pass1(np->lval); + /* replace (a~0x55555555)$b with ((a&0x55555555)<<1)|(0$b) + if b is a constant, the recursive call to optimize does + constant folding */ + if(np->opcode==C_OR&&np->lval->opcode==C_LSHIFT&& + np->rval->opcode==MESH32&&np->rval->constant==0) + { /* check the conditions again in case it's been optimized */ + /* get rid of the C_OR */ + np->opcode=C_LSHIFT; + op=np->lval; + np->lval=op->lval; + np->rval->constant=op->rval->constant; + free(op->rval); + free(op); + optimize_pass1(np->lval); /* 32-bit logic recognition */ + } + } + + if (np->opcode==MINGLE&&np->rval->opcode==SELECT&& + np->rval->rval->opcode==MESH32&&np->rval->rval->constant==0xaaaaaaaa) + { + OPTING(selectmingle4) + np->opcode=C_OR; + np->rval->opcode=C_RSHIFT; /* (a&b)>>1 */ + op=np->lval; + np->lval=newnode(); + np->lval->opcode=MINGLE; + np->lval->rval=newnode(); + np->lval->rval->opcode=MESH; + np->lval->rval->width=16; + np->lval->rval->constant=0; + np->lval->lval=op; + np->lval->width=32; + optimize_pass1(np->lval); + optimize_pass1(np->rval); + /* replace b$(a~0xaaaaaaaa) with ((a&0xaaaaaaaa)>>1)|(b$0) + if b is a constant, the recursive call to optimize does + constant folding */ + if(np->opcode==C_OR&&np->rval->opcode==C_RSHIFT&& + np->lval->opcode==MESH32&&np->lval->constant==0) + { /* check for these conditions again in case it's been optimized */ + /* get rid of the C_OR */ + np->opcode=C_RSHIFT; + op=np->rval; + np->rval=op->lval; + np->lval->constant=op->rval->constant; + free(op->rval); + free(op); + optimize_pass1(np->rval); + } + } + + if(np->opcode==MINGLE&&(np->lval->opcode==MESH|| + np->lval->opcode==MESH32)&& + np->lval->constant==0&&np->rval->opcode==C_LSHIFT&& + (np->rval->rval->opcode==MESH||np->rval->rval->opcode==MESH32)&& + np->rval->rval->constant==0x7fff&&np->rval->lval->opcode==SELECT&& + np->rval->lval->rval->opcode==MESH32&&np->rval->lval->rval->constant== + 0x2aaaaaaa) + { + OPTING(selectmingle5) + /* this is equivalent to (np->rval->lval->lval&0x2aaaaaaa)<<1 */ + np->opcode=C_LSHIFT; + np->lval->opcode=MESH32; + np->lval->constant=0x2aaaaaaa; + op=np->rval; + np->rval=op->lval->lval; + free(op->lval->rval); + free(op->lval); + free(op->rval); + free(op); + } + + /* recognize the idiom (x~x)~1 (already optimized to (x~x)&1). */ + + if (np->opcode==C_AND&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& + np->rval->constant==1&&np->lval->opcode==SELECT&& + nodessame(np->lval->lval,np->lval->rval)) +/* (np->lval->lval->opcode==ONESPOT||np->lval->lval->opcode==TWOSPOT)&& + np->lval->lval->opcode==np->lval->rval->opcode&& + np->lval->lval->constant==np->lval->rval->constant)*/ + { + OPTING(xselxsel1) + free(np->rval); + np->rval=np->lval->rval; + nodefree(np->lval->lval); + free(np->lval); + np->lval=(node*) NULL; + np->opcode = C_ISNONZERO; + } + + /* recognize the idiom (x~y)~1 (already optimized to (x~y)&1) in other cases. + if (np->opcode==C_AND&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& + np->rval->constant==1&&np->lval->opcode==SELECT) + { + OPTING(xselysel1) + np->opcode = C_NNAND; + free(np->rval); + np->rval = np->lval->rval; + op = np->lval; + np->lval = np->lval->lval; + free(op); + } + This idiom is commented out because I thought it simplified to !!(x & y), + and of course it doesn't. The next two idioms are (hopefully correct) + idioms that were inspired by this idea. + */ + + /* recognize the idiom (x ~ k) ~ 1 (ie (x ~ k) & 1) for constant k */ + if(np->opcode==C_AND&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& + np->rval->constant==1&&np->lval->opcode==SELECT&& + (np->lval->rval->opcode==MESH||np->lval->rval->opcode==MESH32)) + { + OPTING(xselksel1) + np->opcode = C_NNAND; + free(np->rval); + np->rval = np->lval->rval; + op = np->lval; + np->lval = np->lval->lval; + free(op); + temp = 1; + if(np->rval->constant == 0) temp = 0; else + while(!(np->rval->constant % 2)) + { + np->rval->constant /= 2; + temp *= 2; + } + np->rval->constant = temp; + /* So (x ~ k) ~ 1 optimizes to !!(x & n) where n is the lowest set + bit in k. */ + } + + /* recognize the idiom (k ~ x) ~ 1 (ie (k ~ x) & 1) where k is a power + of 2 minus 1 */ + if (np->opcode==C_AND&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& + np->rval->constant==1&&np->lval->opcode==SELECT&& + (np->lval->lval->opcode==MESH||np->lval->lval->opcode==MESH32)&& + iselect(np->lval->lval->constant,np->lval->lval->constant)== + np->lval->lval->constant) + { + OPTING(p2m1selxsel1) + np->opcode = C_NNAND; + free(np->rval); + np->rval = np->lval->rval; + op = np->lval; + np->lval = np->lval->lval; + free(op); + } + + /* recognize idioms for left-shift and right-shift */ + /* 16- or 32-bit right-shift by 1, not necessarily all the bits */ + if(np->opcode==SELECT&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& + iselect(np->rval->constant,np->rval->constant)<<1==np->rval->constant) + { + OPTING(rshift1) + np->opcode = C_RSHIFT; /* Keep rval as it tells us what to & with */ + } + + /* 16- or 32-bit right-shift by a higher number */ + if(np->opcode==SELECT&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& + iselect(xor32(np->rval->constant),xor32(np->rval->constant))==3&& + !(np->rval->constant&1)) + { + OPTING(rshiftby) + np->opcode = C_RSHIFTBY; + temp2 = 0; + temp = np->rval->constant; + while(!(np->rval->constant&1)) + { + np->rval->constant>>=1; + temp2++; + } + np->rval->constant = temp2; + op = np->lval; + np->lval = newnode(); + np->lval->width = np->width; + np->lval->rval = newnode(); + np->lval->opcode = C_AND; + np->lval->rval->opcode = np->rval->opcode; + np->rval->opcode = MESH; + np->lval->rval->width = np->rval->width; + np->rval->width = 16; + np->lval->rval->constant = temp; + np->lval->lval = op; + optimize_pass1(np->lval); /* not sure what good this will do, but it's good practice + to optimize newly created nodes, in case someone invents + a new optimization (this caught me out elsewhere) */ + /* The joke with this optimization is that it comes out with more nodes than + when it started. However, under most implementations of C, & and >> are + significantly cheaper than iselect. */ + } + + /* 16-bit left-shift by 1 */ + if(np->opcode==SELECT&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& + np->lval->opcode==MINGLE&&(np->rval->constant & 0x55555555LU)==1&& + (np->lval->rval->opcode==MESH||np->lval->rval->opcode==MESH32)&& + (np->lval->rval->constant==0||np->lval->rval->constant==1)) + { + unsigned long i=iselect(np->rval->constant, 0xaaaaaaaaLU); + if(i==iselect(i,i)) + { + OPTING(lshift16by1) + np->opcode = np->lval->rval->constant?C_LSHIFTIN1:C_LSHIFT; + /* We can shift either a 1 or a 0 into the right end of the number. */ + np->rval->constant=i; /* New effect of this node: (lval->lval & i)<<1 */ + /* We know that np->rval has the right opcode. */ + op=np->lval->lval; + free(np->lval); + np->lval=op; + } + } + + /* 32-bit left-shift of a variable by 1 */ + if(np->opcode==C_OR&&np->lval->opcode==C_LSHIFT&& + np->rval->opcode==C_LSHIFT) + do + { /* this is so we can break; out of the if */ + temp=0; + if(np->lval->lval->opcode==MESH32&& + np->lval->lval->constant==0x55555555) temp++; + if(np->lval->rval->opcode==MESH32&& + np->lval->rval->constant==0x55555555) temp++; + if(np->rval->lval->opcode==MESH32&& + np->rval->lval->constant==0x55555555) temp++; + if(np->rval->rval->opcode==MESH32&& + np->rval->rval->constant==0x55555555) temp++; + if(temp!=1) break; + temp=0; + if(np->lval->lval->opcode==MESH32&& + np->lval->lval->constant==0x2aaaaaaa) temp++; + if(np->lval->rval->opcode==MESH32&& + np->lval->rval->constant==0x2aaaaaaa) temp++; + if(np->rval->lval->opcode==MESH32&& + np->rval->lval->constant==0x2aaaaaaa) temp++; + if(np->rval->rval->opcode==MESH32&& + np->rval->rval->constant==0x2aaaaaaa) temp++; + if(temp!=1) break; + /* found the two required constants. Now we need two + identical TWOSPOTs on opposite sides of the C_OR. */ + temp=0xffffffff; /* who'd use that many variables? */ + if(np->lval->lval->opcode==TWOSPOT&& + np->rval->lval->opcode==TWOSPOT&& + np->lval->lval->constant== + np->rval->lval->constant) temp=np->lval->lval->constant; + if(np->lval->lval->opcode==TWOSPOT&& + np->rval->rval->opcode==TWOSPOT&& + np->lval->lval->constant== + np->rval->rval->constant) temp=np->lval->lval->constant; + if(np->lval->rval->opcode==TWOSPOT&& + np->rval->lval->opcode==TWOSPOT&& + np->lval->rval->constant== + np->rval->lval->constant) temp=np->lval->rval->constant; + if(np->lval->rval->opcode==TWOSPOT&& + np->rval->rval->opcode==TWOSPOT&& + np->lval->rval->constant== + np->rval->rval->constant) temp=np->lval->rval->constant; + if(temp==0xffffffff) break; /* Patched by Joris Huizer */ + /* recognized a 32-bit leftshift */ + OPTING(lshift32by1) + free(np->lval->lval); + free(np->lval->rval); + free(np->rval->lval); + free(np->rval->rval); + np->lval->opcode=TWOSPOT; + np->lval->constant=temp; + np->rval->opcode=MESH32; + np->rval->constant=0x7fffffff; + np->lval->lval=(node*)NULL; + np->lval->rval=(node*)NULL; + np->rval->lval=(node*)NULL; + np->rval->rval=(node*)NULL; + np->opcode=C_LSHIFT; + } while(0); + + /* 16-bit left-shift by 2 */ + if(np->opcode==C_LSHIFT&&np->lval->opcode==C_LSHIFT&& + np->rval->constant==np->lval->rval->constant) + { + OPTING(lshift16by2) + op=np->lval->lval; + np->opcode=C_LSHIFT2; + free(np->lval); + np->lval=op; + np->rval->constant>>=1; + } + + /* An idiom for 16-bit left-shift by 8 is caught later. */ + + /* recognize the idiom '?x$#y'~#3, where y is 1 or 2 + The ~ is already optimized to &. */ + if(np->opcode==C_AND&&(np->rval->opcode==MESH||np->rval->opcode==MESH32)&& + np->rval->constant==3&&np->lval->opcode==XOR&& + np->lval->rval->opcode==MINGLE&&(mingleop=np->lval->rval)&& + (mingleop->rval->opcode==MESH||mingleop->rval->opcode==MESH32)&& + (mingleop->rval->constant==1||mingleop->rval->constant==2)) + { + OPTING(xorto1or2) + /* This depends only on the rightmost bit of x, and y. + For y=1: + If 0, answer = 0x1 + If 1, answer = 0x2 + For y=2: + If 0, answer = 0x2 + Id 1, answer = 0x1 + */ + np->opcode = mingleop->rval->constant==1?C_AND1ADD1:C_2SUBAND1; + free(np->rval); + np->rval=mingleop->lval; + free(mingleop->rval); + free(mingleop); + free(np->lval); + /*free(mingleop->rval);*/ + np->lval=(node*)NULL; + + /* np->rval could be an iselect of a variable with itself, + and not have been caught yet (because the &1 was implied, + not explicit). Catch this now. */ + if(np->rval->opcode==SELECT&& + (np->rval->lval->opcode==ONESPOT||np->rval->lval->opcode==TWOSPOT)&& + np->rval->lval->opcode==np->rval->rval->opcode&& + np->rval->lval->constant==np->rval->rval->constant) + { + np->rval->opcode=C_ISNONZERO; + free(np->rval->lval); + np->rval->lval=(node*)NULL; + } + + /* Even if that didn't work, iselect can still be replaced by nnand + (because we have an implicit (x~y)&1) */ + if(np->rval->opcode==SELECT) np->rval->opcode=C_NNAND; + + /* If we know np->rval must be 0 or 1 at runtime, we can optimize further + (to avoid (1&x)&1, (x&1)&1 or (!!x)&1) */ + if(np->rval->opcode==C_NNAND||np->rval->opcode==C_ISNONZERO|| + (np->rval->opcode==C_AND&& + (np->rval->lval->opcode==MESH||np->rval->lval->opcode==MESH32) + &&np->rval->lval->constant==1) + ||(np->rval->opcode==C_AND&& + (np->rval->rval->opcode==MESH||np->rval->rval->opcode==MESH32) + &&np->rval->rval->constant==1) + ) + { + np->opcode=np->opcode==C_AND1ADD1?C_1PLUS:C_2MINUS; + } + } + + /* optimize a select with 0xffffffff (already optimized to &) */ + if(np->opcode==C_AND&&np->rval->opcode==MESH32&& + np->rval->constant==0xffffffff) + { + OPTING(noopand1r) + free(np->rval); + op=np->lval; + *np=*op; /* copy the whole node */ + np->width=32; + free(op); + } + if(np->opcode==C_AND&&np->lval->opcode==MESH32&& + np->lval->constant==0xffffffff) + { + OPTING(noopand1l) + free(np->lval); + op=np->rval; + *np=*op; /* copy the whole node */ + np->width=32; + free(op); + } + + /* optimize complementing the odd or even bits of a 32-bit number */ + /* complement odd bits, zero even bits */ + if(np->opcode==C_LSHIFT&&np->rval->opcode==MESH32&& + np->rval->constant==0x55555555&&np->lval->opcode==XOR&& + np->lval->width==32&&np->lval->rval->opcode==C_OR&& + ((np->lval->rval->rval->opcode==MESH32&&np->lval->rval->rval-> + constant==0x55555555&&((temp2 = 0),1))|| + (np->lval->rval->lval->opcode==MESH32&&np->lval->rval->lval-> + constant==0x55555555&&(temp2 = 1)))) + { + OPTING(com1z0l) + /* optimizations so far have given us code which sets all even + bits of a 32-bit expression, xor32s it, selects the even bits + and left-shifts. This is equivalent to complementing all odd + bits of the number and zeroing the even bits. */ + np->rval->constant = 0xaaaaaaaa; + np->lval->rval->opcode = C_AND; + op = temp2 ? np->lval->rval->lval : np->lval->rval->rval; + op->constant = 0xaaaaaaaa; + op = np->lval->rval; + free(np->lval); + np->lval = op; + np->opcode = C_XOR; + } + + /* same optimization with np's operands exchanged */ + if(np->opcode==C_LSHIFT&&np->lval->opcode==MESH32&& + np->lval->constant==0x55555555&&np->rval->opcode==XOR&& + np->rval->width==32&&np->rval->rval->opcode==C_OR&& + ((np->rval->rval->rval->opcode==MESH32&&np->rval->rval->rval-> + constant==0x55555555&&((temp2 = 0),1))|| + (np->rval->rval->lval->opcode==MESH32&&np->rval->rval->lval-> + constant==0x55555555&&(temp2 = 1)))) + { + OPTING(com1z0r) + /* optimizations so far have given us code which sets all even + bits of a 32-bit expression, xor32s it, selects the even bits + and left-shifts. This is equivalent to complementing all odd + bits of the number and zeroing the even bits. */ + np->lval->constant = 0xaaaaaaaa; + np->rval->rval->opcode = C_AND; + op = temp2 ? np->rval->rval->lval : np->rval->rval->rval; + op->constant = 0xaaaaaaaa; + op = np->rval->rval; + free(np->rval); + np->rval = op; + np->opcode = C_XOR; + } + + /* complement even bits, zero odd bits */ + if(np->opcode==C_AND&&np->rval->opcode==MESH32&& + np->rval->constant==0x55555555&&np->lval->opcode==XOR&& + np->lval->width==32&&np->lval->rval->opcode==C_OR&& + np->lval->rval->rval->opcode==MESH32&& + np->lval->rval->rval->constant==0x55555555&& + np->lval->rval->lval->opcode==C_LSHIFT&& + np->lval->rval->lval->rval->opcode==MESH32&& + np->lval->rval->lval->rval->constant==0x55555555) + { + OPTING(com0z1) + /* There are another 7 ways this expression could be written. + However, this is the only way likely to be generated by + the rest of the optimizer. */ + op=np->lval->rval->lval->lval; + free(np->lval->rval->lval->rval); + free(np->lval->rval->lval); + free(np->lval->rval->rval); + np->lval->opcode = C_AND; + np->opcode = C_XOR; + np->lval->lval = op; + np->lval->rval->opcode = MESH32; + np->lval->rval->lval = (node*) NULL; + np->lval->rval->rval = (node*) NULL; + np->lval->rval->constant = 0x55555555; + /* and np->rval is already correct! */ + } + + /* optimize no-op C_OR, C_AND, C_XOR + (some of these are produced as a result of earlier optimizations). + This sort of thing was also used in the days of INTERCAL-72 to + convert information to 16- or 32-bit representations. As C-INTERCAL + is almost untyped and the typechecker has already run, this can be + done safely. One of these cases has already been considered earlier + (the one generated by the code (something)~'#65535$#65535'), but it + is included it again to complete the list. */ + /* (something op constant) */ + if(np->opcode==C_OR&&(np->lval->opcode==MESH||np->lval->opcode==MESH32) + &&np->lval->constant==0) + { + OPTING(nooporl) + free(np->lval); + op=np->rval; + *np=*op; + free(op); + } + if(np->opcode==C_XOR&&(np->lval->opcode==MESH||np->lval->opcode==MESH32) + &&np->lval->constant==0) + { + OPTING(noopxorl) + free(np->lval); + op=np->rval; + *np=*op; + free(op); + } + if(np->opcode==C_AND&&(np->lval->opcode==MESH||np->lval->opcode==MESH32) + &&np->lval->constant==0xffffffff) + { + OPTING(noopandl) + free(np->lval); + op=np->rval; + *np=*op; + free(op); + } + if(np->opcode==C_OR&&(np->rval->opcode==MESH||np->rval->opcode==MESH32) + &&np->rval->constant==0) + { + OPTING(nooporr) + free(np->rval); + op=np->lval; + *np=*op; + free(op); + } + if(np->opcode==C_XOR&&(np->rval->opcode==MESH||np->rval->opcode==MESH32) + &&np->rval->constant==0) + { + OPTING(noopxorr) + free(np->rval); + op=np->lval; + *np=*op; + free(op); + } + if(np->opcode==C_AND&&(np->rval->opcode==MESH||np->rval->opcode==MESH32) + &&np->rval->constant==0xffffffff) + { + OPTING(noopandr) + free(np->rval); + op=np->lval; + *np=*op; + free(op); + } + /* something op itself */ + if((np->opcode==C_AND||np->opcode==C_OR)&&nodessame(np->lval,np->rval)) + { + OPTING(andoritself) + nodefree(np->rval); + op=np->lval; + *np=*op; + free(op); + } + if(np->opcode==C_XOR&&nodessame(np->lval,np->rval)) + { + OPTING(xoritself) + nodefree(np->lval); + nodefree(np->rval); + np->opcode = (np->width==16?MESH:MESH32); + np->lval = (node*) NULL; + np->rval = (node*) NULL; + np->constant = 0; + } + /* repetitive implicit C_AND */ + if(np->opcode==C_NNAND&&nodessame(np->lval,np->rval)) + { + OPTING(reptimpand) + nodefree(np->lval); + np->lval = (node*) NULL; + np->opcode = C_ISNONZERO; + } + + /* optimize 32-bit complement */ + if(np->opcode==C_OR&&np->lval->opcode==C_XOR&&np->lval->lval->opcode==C_AND&& + np->rval->opcode==C_XOR&&np->rval->lval->opcode==C_AND&& + np->lval->rval->opcode==MESH32&&np->lval->lval->rval->opcode==MESH32&& + np->rval->rval->opcode==MESH32&&np->rval->lval->rval->opcode==MESH32&& + np->lval->rval->constant==np->lval->lval->rval->constant&& + np->rval->rval->constant==np->rval->lval->rval->constant&& + (np->lval->rval->constant^np->rval->rval->constant)==0xffffffff&& + nodessame(np->lval->lval->lval,np->rval->lval->lval)) + { + OPTING(com32) + np->opcode = C_NOT; + np->width = 32; + free(np->rval->lval->lval); + free(np->rval->lval->rval); + free(np->rval->lval); + free(np->rval->rval); + free(np->rval); + op = np->lval->lval->lval; + free(np->lval->lval->rval); + free(np->lval->lval); + free(np->lval->rval); + free(np->lval); + np->rval = op; + np->lval = (node*)NULL; + } + + /* If constant is on the left, move it to the right. This will + simplify checking for the remaining optimizations, while not + altering the effect of code that cannot be optimized further. + (There are furious debates within the C community as to + whether a constant should be written on the left or right of + an operation. The argument in favour of 'constant on the left' + is mainly that it's better at detecting a mistype of = for ==. + This code assumes that ick won't make that mistake.) */ + if(np->opcode==C_LSHIFT||np->opcode==C_AND||np->opcode==C_OR|| + np->opcode==C_XOR||np->opcode==C_NNAND||np->opcode==C_RSHIFT) + { /* all the above opcodes are symmetrical wrt their operands */ + if(np->lval->opcode==MESH||np->lval->opcode==MESH32) + { + OPTING(constswitch) + op = np->lval; + np->lval = np->rval; + np->rval = op; + } + } + + /* 32-bit logical operations on alternate bits. + At this point, they have been optimized + to an expression of the form op32(oddbits | evenbits)&0x55555555, + which is good but still uses the INTERCAL operator op32. We should + be able to optimize this using & | ^ and bitshifts. */ + if((np->opcode==C_AND||np->opcode==C_LSHIFT)&&np->rval->opcode==MESH32&& + np->rval->constant==0x55555555&&np->lval->width==32&& + (np->lval->opcode==XOR||np->lval->opcode==OR|| + np->lval->opcode==AND)&&np->lval->rval->opcode==C_OR) + do /* so we can break; out */ + { + /* Check to see if the op32 is a C_OR of an oddbits and an + evenbits */ + op=np->lval->rval; + temp2=0; /* |=1 for oddbits found, |=2 for evenbits found */ + if(op->lval->opcode==C_AND&&op->lval->rval->opcode==MESH32&& + op->lval->rval->constant==0x55555555) temp2|=2; + if(op->lval->opcode==C_AND&&op->lval->rval->opcode==MESH32&& + op->lval->rval->constant==0xaaaaaaaa) temp2|=1; + if(op->rval->opcode==C_AND&&op->rval->rval->opcode==MESH32&& + op->rval->rval->constant==0x55555555) temp2|=2; + if(op->rval->opcode==C_AND&&op->rval->rval->opcode==MESH32&& + op->rval->rval->constant==0xaaaaaaaa) temp2|=1; + if(op->lval->opcode==C_LSHIFT&&op->lval->rval->opcode==MESH32&& + op->lval->rval->constant==0x55555555) temp2|=1; + if(op->lval->opcode==C_RSHIFT&&op->lval->rval->opcode==MESH32&& + op->lval->rval->constant==0xaaaaaaaa) temp2|=2; + if(op->rval->opcode==C_LSHIFT&&op->rval->rval->opcode==MESH32&& + op->rval->rval->constant==0x55555555) temp2|=1; + if(op->rval->opcode==C_RSHIFT&&op->rval->rval->opcode==MESH32&& + op->rval->rval->constant==0xaaaaaaaa) temp2|=2; + if(temp2!=3) break; + /* this expression can be optimized */ + OPTING(shiftand) + if(np->lval->opcode==XOR) op->opcode=C_XOR; + if(np->lval->opcode==OR) op->opcode=C_OR; + if(np->lval->opcode==AND) op->opcode=C_AND; + if(np->opcode==C_LSHIFT) + { + /* odd-bit-ize the evenbits we found */ + if(op->lval->rval->constant==0x55555555) op->lval->opcode=C_LSHIFT; + if(op->rval->rval->constant==0x55555555) op->rval->opcode=C_LSHIFT; + if(op->lval->rval->constant==0xaaaaaaaa) op->lval->opcode=C_AND; + if(op->rval->rval->constant==0xaaaaaaaa) op->rval->opcode=C_AND; + } else { + /* even-bit-ize the oddbits we found */ + if(op->lval->rval->constant==0x55555555) op->lval->opcode=C_AND; + if(op->rval->rval->constant==0x55555555) op->rval->opcode=C_AND; + if(op->lval->rval->constant==0xaaaaaaaa) op->lval->opcode=C_RSHIFT; + if(op->rval->rval->constant==0xaaaaaaaa) op->rval->opcode=C_RSHIFT; + } + /* What np should be is now in op */ + free(np->lval); + free(np->rval); + *np=*op; + } while(0); + + /* Optimize 32-bit logical expressions on the whole number. + At this point, the most common idiom for a 32-bit logical operation + (we write it here as %) looks like this: + ((a&0xaaaaaaaa)%(b&0xaaaaaaaa))|((a&0x55555555)%(b&0x55555555)) + So first, we use distributive laws to simplify such constructions + further. + + The distribution is done at a lower level of the expression tree, + but this is where it is done in the sequence of optimizations needed + to optimize a 32-bit expression. These optimizations are unlikely to + help in 16-bit code, because it's unlikely a programmer would take the + effort to code an expression like the ones below unless he/she had to. + + Expressions that distribute: + (a&k)&(b&k) == (a&b)&k + (a|k)&(b|k) == (a&b)|k + (a&k)|(b&k) == (a|b)&k + (a|k)|(b|k) == (a|b)|k + (a&k)^(b&k) == (a^b)&k */ + if((np->opcode==C_AND||np->opcode==C_OR||np->opcode==C_XOR)&& + (np->lval->opcode==C_AND||np->lval->opcode==C_OR)&& + !(np->lval->opcode==C_OR&&np->opcode==C_XOR)&& + np->lval->opcode==np->rval->opcode) + { + if(nodessame(np->lval->lval,np->rval->lval)) + { + OPTING(distribll) + nodefree(np->lval->lval); + np->lval->lval = np->rval->rval; + np->lval->opcode = np->opcode; + np->opcode = np->rval->opcode; + op = np->rval; + np->rval = np->rval->lval; + free(op); + } + else if(nodessame(np->lval->rval,np->rval->lval)) + { + OPTING(distribrl) + nodefree(np->lval->rval); + np->lval->rval = np->rval->rval; + np->lval->opcode = np->opcode; + np->opcode = np->rval->opcode; + op = np->rval; + np->rval = np->rval->lval; + free(op); + } + else if(nodessame(np->lval->lval,np->rval->rval)) + { + OPTING(distriblr) + nodefree(np->lval->lval); + np->lval->lval = np->rval->lval; + np->lval->opcode = np->opcode; + np->opcode = np->rval->opcode; + op = np->rval; + np->rval = np->rval->rval; + free(op); + } + else if(nodessame(np->lval->rval,np->rval->rval)) + { + OPTING(distribrr) + nodefree(np->lval->rval); + np->lval->rval = np->rval->lval; + np->lval->opcode = np->opcode; + np->opcode = np->rval->opcode; + op = np->rval; + np->rval = np->rval->rval; + free(op); + } + } + + /* At this point, the 32-bit logical expression looks like this: + (with % substituting for &,|, or ^) + (0xaaaaaaaa|0x55555555)&(a%b) + Clearly, what is needed is a bit of constant folding on C_OR. We + might as well do C_AND and C_XOR while we're at it. This will get + done during the second run of optimize_pass1. */ + if((np->opcode==C_AND||np->opcode==C_OR||np->opcode==C_XOR)&& + (np->lval->opcode==MESH||np->lval->opcode==MESH32)&& + (np->rval->opcode==MESH||np->rval->opcode==MESH32)) + { + OPTING(clogopfold) + switch(np->opcode) + { + case C_AND: np->constant = np->lval->constant & np->rval->constant; break; + case C_OR: np->constant = np->lval->constant | np->rval->constant; break; + case C_XOR: np->constant = np->lval->constant ^ np->rval->constant; break; + default: lose(E778, yylineno, (char*) NULL); + } + free(np->lval); + np->lval = (node*) NULL; + free(np->rval); + np->rval = (node*) NULL; + np->opcode = np->width == 16 ? MESH : MESH32; + } + + /* Somewhat incomprehensibly, there is a 32-bit right-shift in the + standard library that has been done using separation into even + and odd bits! This code recognizes that idiom, even though + surely it would have been simpler to select against + 0xfffffffe? (This would have been optimized much earlier in this + function, and would also be shorter and clearer. Perhaps the + obfuscation is the reason that it was written in separate bits.) */ + + /* Selecting something with 0x55555554, then mingling with 0, + right-shifts the even bits onto the odd bits. */ + if(np->opcode==MINGLE&&np->lval->opcode==SELECT&& + (np->rval->opcode==MESH||np->rval->opcode==MESH32)&& + np->rval->constant==0&&np->lval->rval->opcode==MESH32&& + np->lval->rval->constant==0x55555554) + { + OPTING(selminglershift) + np->opcode = C_RSHIFT; + np->rval->opcode = MESH32; + np->rval->width = 32; + np->rval->constant = 0x55555554; + free(np->lval->rval); + op = np->lval->lval; + free(np->lval); + np->lval = op; + } + + /* Since it's such a stupid idiom anyway, we'll just optimize it the + way round that the standard library has it. It looks like this: + (((a&0x55555554)>>1)|((a&0xaaaaaaaa)>>1)) */ + if(np->opcode==C_OR&&np->lval->opcode==C_RSHIFT&& + np->rval->opcode==C_RSHIFT&&np->lval->rval->opcode==MESH32&& + np->lval->rval->constant==0x55555554&& + np->rval->rval->opcode==MESH32&&np->rval->rval->constant== + 0xaaaaaaaa&&np->lval->lval->opcode==TWOSPOT&& + np->rval->lval->opcode==TWOSPOT&&np->lval->lval->constant== + np->rval->lval->constant) + { + OPTING(sillysyslibidiom) + op = np->lval; + free(np->rval->lval); + free(np->rval->rval); + free(np->rval); + op->rval->constant = 0xfffffffe; + *np = *op; + free(op); + optuple->warn128 = 1; + } + + /* A more useful idiom in the standard library is on the + internal subroutine labelled (1525). It's an 8-bit + left-shift. In INTERCAL, this is done with repeated + mingling and selection. So far, the optimiser can only + recognize two leftshifts in the inside, because the rest + of the expression is written assuming that the low-bits + of the result are unset (which is correct after a two-bit + left-shift). This code recognizes the entire idiom straight + off, rather than optimizing in stages, after the optimization + of the inside to a double-leftshift. */ + if(np->opcode==SELECT&&np->rval->opcode==MESH32&& + np->rval->constant==0xaaaaff&&np->lval->opcode==MINGLE&& + (np->lval->rval->opcode==MESH||np->lval->rval->opcode==MESH32)&& + np->lval->rval->constant==0&&np->lval->lval->opcode==SELECT&& + np->lval->lval->rval->opcode==MESH32&& + np->lval->lval->rval->constant==0xaaaaaaf&& + np->lval->lval->lval->opcode==MINGLE&&( + np->lval->lval->lval->rval->opcode==MESH|| + np->lval->lval->lval->rval->opcode==MESH32)&& + np->lval->lval->lval->rval->constant==0&& + np->lval->lval->lval->lval->opcode==C_LSHIFT2&&( + np->lval->lval->lval->lval->rval->opcode==MESH|| + np->lval->lval->lval->lval->rval->opcode==MESH32)&& + np->lval->lval->lval->lval->rval->constant==0x3fff) + { + OPTING(lshift8) + /* left-shift np->lval->lval->lval->lval->lval by 8 */ + op = np->lval->lval->lval->lval->lval; + free(np->lval->lval->lval->lval->rval); + free(np->lval->lval->lval->lval); + free(np->lval->lval->lval->rval); + free(np->lval->lval->lval); + free(np->lval->lval->rval); + free(np->lval->lval); + free(np->lval->rval); + free(np->lval); + np->lval = op; + np->opcode = C_LSHIFT8; + np->rval->constant = 0x00ffffff; + } + + /* recognize an idiom for ==, != */ + if(np->opcode == C_ISNONZERO && np->rval->opcode == C_XOR) + { + OPTING(xortoequal) + np->opcode = C_NOTEQUAL; + op = np->rval; + np->lval = op->lval; + np->rval = op->rval; + free(op); + /* So !!(a ^ b), as in 1 + !!(a^b), has become (a!=b). */ + } + + /* Some of the remaining idioms depend on active-bit analysis */ + checknodeactbits(np); + /* C binary logical operations can be done in 'expanded' form, that is, on + just oddbits or evenbits of a 32-bit number. */ + if((np->opcode==C_AND || np->opcode==C_LSHIFT || np->opcode == C_LSHIFT2 || + np->opcode==C_LSHIFT8 || np->opcode==C_LSHIFTIN1 || np->opcode==C_NNAND) + && (np->rval->opcode==MESH32 || np->rval->opcode==MESH) + && !(np->rval->constant & 0xaaaaaaaaLU)) + { + unsigned long i=iselect(np->rval->constant, 0x55555555LU); + if(i==iselect(i,i) && (np->lval->opcode == OR || + np->lval->opcode == AND || + np->lval->opcode == XOR) && + np->lval->rval->opcode==C_OR) + { + if(!(np->lval->rval->lval->optdata & 0x55555555LU) && + !(np->lval->rval->rval->optdata & 0xaaaaaaaaLU) && + (np->lval->rval->lval->opcode == C_AND || + np->lval->rval->lval->opcode == C_LSHIFT || + np->lval->rval->lval->opcode == MESH || + np->lval->rval->lval->opcode == MESH32)) + { /* recognized the idiom. Swap the C_OR round so we don't have to write + the code for this out twice. */ + OPTING(clogopexpswitch) + op=np->lval->rval->rval; + np->lval->rval->rval=np->lval->rval->lval; + np->lval->rval->lval=op; + } + if(!(np->lval->rval->lval->optdata & 0xaaaaaaaaLU) && + !(np->lval->rval->rval->optdata & 0x55555555LU) && + (np->lval->rval->rval->opcode == C_AND || + np->lval->rval->rval->opcode == C_LSHIFT || + np->lval->rval->lval->opcode == MESH || + np->lval->rval->lval->opcode == MESH32)) + { + OPTING(clogopexpand) + op = np->lval->rval; + switch(np->lval->opcode) + { + case AND: op->opcode = C_AND; break; + case OR: op->opcode = C_OR; break; + case XOR: op->opcode = C_XOR; break; + default: lose(E778, yylineno, (char*) NULL); + } + free(np->lval); + np->lval = op; + if(np->lval->rval->opcode == MESH || np->lval->rval->opcode == MESH32) + np->lval->rval->constant >>= 1; + else np->lval->rval->opcode = np->lval->rval->opcode == C_AND ? + C_RSHIFT : C_AND; + if(np->opcode == C_LSHIFT&&(np->lval->lval->opcode == C_AND || + np->lval->lval->opcode == C_RSHIFT || + np->lval->lval->opcode == MESH || + np->lval->lval->opcode == MESH32)) + { + /* Instead of doing the calculation on the evenbits, do it on the + oddbits; that'll save a bitshift (possibly even save two + bitshifts). */ + np->opcode = C_AND; + if(np->lval->lval->opcode == MESH || + np->lval->lval->opcode == MESH32) np->lval->lval->constant <<= 1; + else np->lval->lval->opcode = np->lval->lval->opcode == C_AND ? + C_LSHIFT : C_AND; + if(np->lval->rval->opcode == MESH || + np->lval->rval->opcode == MESH32) np->lval->rval->constant <<= 1; + else np->lval->rval->opcode = np->lval->rval->opcode == C_AND ? + C_LSHIFT : C_AND; + np->rval->constant <<= 1; + } + checknodeactbits(np); /* To calculate an improved active-bits value */ + } + } + } + + /* One common situation in which the previous idiom is used is a 32-bit + logic operation with a constant. The distributive law will not catch + such cases because even bits of the constant are used on one side and + odd bits of the constant are used on the other side, making the + expressions different. In syslib, the idiom is only used with the + constant equal to 0x80000000, leading to another problem; the logic + operation may not have been written at all on one side of the + expression, due to one parity set of bits having no effect. The + following code catches three cases involving 32-bit logical operations + with constants. Of course, some loony could theoretically write the + 16-bit version like this... */ + if(np->opcode==C_OR&&(np->lval->opcode==C_AND||np->lval->opcode==C_XOR|| + np->lval->opcode==C_OR||np->lval->opcode==C_LSHIFT|| + np->lval->opcode==C_RSHIFT)&& + (np->rval->opcode==C_AND||np->rval->opcode==C_XOR|| + np->rval->opcode==C_OR||np->rval->opcode==C_LSHIFT|| + np->rval->opcode==C_RSHIFT)&& + !(np->lval->optdata&np->rval->optdata)) + { + op = np->lval; + op2 = np->rval; + /* rely on the 'constant on the right' optimization */ + if(op->opcode!=C_LSHIFT&&op->opcode!=C_RSHIFT) + if(op->lval->opcode==C_AND || op->lval->opcode==C_LSHIFT) + if(op->rval->opcode==MESH || op->rval->opcode==MESH32) op=op->lval; + if(op2->opcode!=C_LSHIFT&&op2->opcode!=C_RSHIFT) + if(op2->lval->opcode==C_AND || op2->lval->opcode==C_LSHIFT) + if(op2->rval->opcode==MESH || op2->rval->opcode==MESH32) op2=op2->lval; + if(nodessame(op->lval,op2->lval) && + (op->rval->opcode==MESH||op->rval->opcode==MESH32) && + (op2->rval->opcode==MESH||op2->rval->opcode==MESH32) && + !(op->rval->constant&op2->rval->constant) && + (op->opcode==op2->opcode) && + (op->opcode==C_AND||op->opcode==C_LSHIFT||op->opcode==C_RSHIFT)&& + (op2->opcode==C_AND||op2->opcode==C_LSHIFT||op2->opcode==C_RSHIFT)) + { + /* Now op and op2 are & or implied & (only <<, >>, & are at all likely + to be here), and have the same lval. The only check left is that + this does actually correspond to (something32 op constant), in + other words that there is exactly one possibility for op. */ + if((np->lval==op||np->rval==op2||np->lval->opcode==np->rval->opcode) + &&(np->lval!=op||np->rval!=op2)) + { + OPTING(clogopwithconst) + if(np->lval!=op) temp2=np->lval->opcode; + if(np->rval!=op2) temp2=np->rval->opcode; + if(np->lval==op) temp=np->rval->rval->constant; + else if(np->rval==op2) temp=np->lval->rval->constant; + else switch(temp2) + { + case C_AND: + temp = np->rval->rval->constant & np->lval->rval->constant; break; + case C_OR: + temp = np->rval->rval->constant | np->lval->rval->constant; break; + case C_XOR: + temp = np->rval->rval->constant ^ np->lval->rval->constant; break; + default: lose(E778, yylineno, (char*)NULL); + } + np->opcode = temp2; + np->rval->opcode = np->width==16 ? MESH : MESH32; + np->rval->constant = temp; + temp = op->rval->constant | op2->rval->constant; + nodefree(np->rval->lval); + nodefree(np->rval->rval); + np->rval->lval = (node*) NULL; + np->rval->rval = (node*) NULL; + if(np->lval!=op) + { + op2 = np->lval; + np->lval = op; + free(op2); + } + np->lval->rval->constant = temp; + if(np->lval->rval->constant>0xffff) np->lval->rval->opcode = MESH32; + optimize_pass1(np->lval); + /* it's pretty likely that there's an & with 0xffffffff here, although + not guaranteed, so reoptimize it */ + } + } + } + + /* Greater than/less than. The longest idiom in syslib, it stretches over 2 + statements. The first statement will already be optimized to + :a <- (:b ^ :c) or similar. At this point in the code, the second + statement looks like ((:c ~ :a) ~ ((? (:a ~ :a)) ^ 0x80000000)) or + similar. (That's a 32-bit ?.) The idiom, obviously, also could work + with a 16-bit ? and 0x8000. The point is, it returns the bit of :c + that corresponds to the most significant set bit in :a, which is the + most significant bit that differs between :b and :c. So if this bit is + a 1, it means that :c is greater; if it's a 0, it means that :b is + greater, or the numbers are equal. optimize_pass1 only optimizes within + an expression, so we're going to render it as :c > (:a ^ :c). */ + if(np->opcode==SELECT&&np->lval->opcode==SELECT&&np->rval->opcode==C_XOR&& + (np->rval->rval->opcode==MESH||np->rval->rval->opcode==MESH32)&& + np->rval->lval->opcode==XOR&&np->rval->lval->rval->opcode==SELECT&& + ((np->rval->lval->width==32&&np->rval->rval->constant==0x80000000LU)|| + (np->rval->lval->width==16&&np->rval->rval->constant==0x8000))&& + nodessame(np->lval->rval,np->rval->lval->rval->lval)&& + nodessame(np->lval->rval,np->rval->lval->rval->rval)) + { + temp=np->rval->lval->width; + if(temp==32||(np->lval->lval->width==16&&np->lval->rval->width==16&& + np->rval->lval->rval->lval->width==16&& + np->rval->lval->rval->rval->width==16)) + { + OPTING(greaterthan) + nodefree(np->rval); + op = np->lval; + *np=*op; + free(op); + np->opcode = C_XORGREATER; + np->optdata = 1; + } + } + + /* Many previous optimizations generate Boolean values. In INTERCAL, + Boolean algebra on these will be done with the familiar mingle, + unary, select routine. However, in many cases the 'select' will be + an implied &1, which could have been computed by many of the earlier + optimizations. These Boolean algebra operations are caught here. */ + if((np->opcode==C_AND1ADD1||np->opcode==C_2SUBAND1|| + ((np->opcode==C_AND||np->opcode==C_NNAND||np->opcode==C_LSHIFT|| + np->opcode==C_RSHIFT||np->opcode==C_LSHIFT2||np->opcode==C_LSHIFT8|| + np->opcode==C_LSHIFTIN1)&& + (np->rval->opcode==MESH||np->rval->opcode==MESH32)&& + np->rval->constant==1))) + { + if(np->opcode==C_AND1ADD1||np->opcode==C_2SUBAND1) op = np->rval; + else op = np->lval; + if((op->opcode==AND||op->opcode==OR||op->opcode==XOR)&& + op->rval->opcode==MINGLE) + { + OPTING(clogopand1) + mingleop = op->rval; + switch(op->opcode) + { + case AND: mingleop->opcode = C_AND; break; + case OR: mingleop->opcode = C_OR; break; + case XOR: mingleop->opcode = C_XOR; break; + default: lose(E778, yylineno, (char *) NULL); + } + free(op); + if(np->opcode==C_AND1ADD1||np->opcode==C_2SUBAND1) + np->rval = mingleop; + else np->lval = mingleop; + } + } + + /* The next optimization is aided by splitting C_NNANDs when they are + the argument to C_OR. Two cases. */ + + if(np->opcode == C_OR && np->lval->opcode == C_NNAND) + { + OPTING(splitnnandinorl) + op = np->lval; + np->lval = cons(C_ISNONZERO, (node *) NULL, op); + np->lval->width = np->lval->rval->width; + np->lval->rval->opcode = C_AND; + np->lval->optdata = 1; + } + + if(np->opcode == C_OR && np->rval->opcode == C_NNAND) + { + OPTING(splitnnandinorr) + op = np->rval; + np->rval = cons(C_ISNONZERO, (node *) NULL, op); + np->rval->width = np->rval->rval->width; + np->rval->rval->opcode = C_AND; + np->rval->optdata = 1; + } + + /* We can save a small amount of time, and aid further optimization, + by undistributing C_ISNONZERO across C_OR. This is used in some tests + which produce Booolean output, when testing the oddbits and + evenbits separately. Unfortunately, this doesn't work for C_AND. */ + if(np->opcode == C_OR && np->lval->opcode == C_ISNONZERO && + np->rval->opcode == C_ISNONZERO) + { + OPTING(distribnon0overor) + np->opcode = C_ISNONZERO; + np->rval->opcode = C_OR; + np->rval->lval = np->lval->rval; + free(np->lval); + np->lval = 0; + optimize_pass1(np->rval); /* reoptimize this */ + } + + /* Recognize a C logical operation on just the oddbits or evenbits of a + number. Two cases (evenbits and oddbits). */ + + if (np->opcode==SELECT && np->rval->opcode==MESH32 && + np->rval->constant==0x55555555LU && + (np->lval->opcode==AND||np->lval->opcode==OR||np->lval->opcode==XOR) && + np->lval->rval->opcode == C_OR && + ((np->lval->rval->lval->opcode == C_LSHIFT && + np->lval->rval->rval->opcode == C_AND) || + (np->lval->rval->lval->opcode == C_AND && + np->lval->rval->rval->opcode == C_LSHIFT)) && + np->lval->rval->lval->rval->opcode == MESH32 && + np->lval->rval->rval->rval->opcode == MESH32 && + np->lval->rval->lval->rval->constant == 0x55555555LU && + np->lval->rval->rval->rval->constant == 0x55555555LU) + { + OPTING(clogopevenbits) + switch(np->lval->opcode) + { + case AND: np->lval->rval->opcode = C_AND; break; + case OR: np->lval->rval->opcode = C_OR; break; + case XOR: np->lval->rval->opcode = C_XOR; break; + default: lose(E778, yylineno, (char *) NULL); + } + op = np->lval->rval; + free(np->lval); + np->lval = op; + op = np->lval->lval->lval; + free(np->lval->lval->rval); + free(np->lval->lval); + np->lval->lval = op; + op = np->lval->rval->lval; + free(np->lval->rval->rval); + free(np->lval->rval); + np->lval->rval = op; + } + + if (np->opcode==SELECT && np->rval->opcode==MESH32 && + np->rval->constant==0x55555555LU && + (np->lval->opcode==AND||np->lval->opcode==OR||np->lval->opcode==XOR) && + np->lval->rval->opcode == C_OR && + ((np->lval->rval->lval->opcode == C_RSHIFT && + np->lval->rval->rval->opcode == C_AND) || + (np->lval->rval->lval->opcode == C_AND && + np->lval->rval->rval->opcode == C_RSHIFT)) && + np->lval->rval->lval->rval->opcode == MESH32 && + np->lval->rval->rval->rval->opcode == MESH32 && + np->lval->rval->lval->rval->constant == 0xAAAAAAAALU && + np->lval->rval->rval->rval->constant == 0xAAAAAAAALU) + { + OPTING(clogopoddbits) + switch(np->lval->opcode) + { + case AND: np->lval->rval->opcode = C_AND; break; + case OR: np->lval->rval->opcode = C_OR; break; + case XOR: np->lval->rval->opcode = C_XOR; break; + default: lose(E778, yylineno, (char *) NULL); + } + op = np->lval->rval; + free(np->lval); + np->lval = op; + op = np->lval->lval->lval; + free(np->lval->lval->rval); + free(np->lval->lval); + np->lval->lval = op; + op = np->lval->rval->lval; + free(np->lval->rval->rval); + free(np->lval->rval); + np->lval->rval = op; + np->rval->constant = 0xAAAAAAAALU; + } + + /* !!(a ~ b) can be weakened to !!(a & b) */ + if(np->opcode == C_ISNONZERO && np->rval->opcode == SELECT) + { + OPTING(non0seltonnand) + np->lval = np->rval->lval; + op = np->rval->rval; + free(np->rval); + np->rval = op; + np->opcode = C_NNAND; + } + return opted; +} + diff --git a/src/feh.h b/src/feh.h new file mode 100644 index 0000000..582364a --- /dev/null +++ b/src/feh.h @@ -0,0 +1,28 @@ +/* feh.h -- compilation functions used by perpetrate.c and ick.y */ + +extern node *newnode(void); +extern node *cons(int type, node *car, node *cdr); +extern unsigned int intern(int type, unsigned int index); +extern void checklabel(int label); +extern void treset(void); +extern tuple *newtuple(void); +extern void typecast(node *np); +extern void codecheck(void); +extern void optimize(node *np); +extern char *nameof(int value, assoc table[]); +extern void emit(tuple *tn, FILE *fp); +extern void emittextlines(FILE *fp); +extern void emitslatproto(FILE *fp); /* AIS: emit prototypes for /-functions */ +extern void emitslat(FILE* fp); /* AIS: emit bodies of /-functions */ +extern int comefromsearch(tuple *tn, unsigned int index); /* AIS */ +extern void explexpr(node* np, FILE* fp); /* AIS */ +extern void optimizef(); /* AIS */ +extern void nodefree(node* np); /* AIS */ +extern unsigned long varextern(unsigned long intern, int vartype); /* AIS */ + +extern char **enablers; /* AIS: so that there can be an element before the + first element of the array (UNKNOWN is element + -1, just to cause a bit more confusion) */ +extern assoc vartypes[]; + +/* feh.h ends here */ diff --git a/src/feh2.c b/src/feh2.c new file mode 100644 index 0000000..576ae2d --- /dev/null +++ b/src/feh2.c @@ -0,0 +1,2297 @@ +/**************************************************************************** + +Name + feh2.c -- code-generator back-end for ick parser + +DESCRIPTION + This module provides storage manglement and code degeneration + for the INTERCAL compiler. Optimizations (formerly in this file) + were split into dekludge.c. + +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +****************************************************************************/ +/*LINTLIBRARY */ +#include +#include +#include +#include "sizes.h" +#include "ick.h" +#include "parser.h" +#include "fiddle.h" +#include "lose.h" +#include "feh.h" + +/* AIS: Destaticed for dekludge.c */ +int emitlineno; /* line number for errors encountered during emit */ + +int mark112 = 0; /* AIS: Mark the next generated tuple for W112 */ + +/* AIS: From perpet.c */ +extern int pickcompile; + +/************************************************************************* + * + * Node allocation functions. + * + * Nodes are used to represent expression trees. The emit() function + * deallocates them. + * + **************************************************************************/ + +node *newnode(void) +/* allocate and zero out a new expression node */ +{ + return((node *)calloc(sizeof(node), 1)); +} + +node *cons(int type, node *car, node *cdr) +{ + node *np = newnode(); + + np->opcode = type; + np->lval = car; + np->rval = cdr; + + return(np); +} + +/************************************************************************* + * + * Variable-name mapping + * + * This permits us to optimize use of variable storage at runtime + * + **************************************************************************/ + +unsigned int intern(int type, unsigned int index) +{ + atom *x; + + /* AIS: Allow use of a modifiable constant 0. */ + if ((index < 1 || index > 65535) && type!=MESH) + lose(E200, yylineno, (char *)NULL); + + if (!oblist) + { + /* initialize oblist and obdex */ + oblist = malloc(ALLOC_CHUNK * sizeof(atom)); + if (!oblist) + lose(E778, yylineno, (char *)NULL); + obdex = oblist; + obcount = ALLOC_CHUNK; + } + + /* if it's already on the oblist, return its intindex */ + for (x = oblist; x < obdex; x++) + if (x->type == type && x->extindex == index) + return(x->intindex); + + /* else we must intern a new symbol */ + if (obdex >= oblist + obcount) + { + obcount += ALLOC_CHUNK; + x = realloc(oblist, obcount * sizeof(atom)); + if (!x) + lose(E333, yylineno, (char *)NULL); + obdex = x + (obdex - oblist); + oblist = x; + } + obdex->type = type; + obdex->extindex = index; + obdex->memloc = 0; /* AIS: not placed in memory yet */ + if (type == ONESPOT) + obdex->intindex = nonespots++; + if (type == TWOSPOT) + obdex->intindex = ntwospots++; + if (type == TAIL) + obdex->intindex = ntails++; + if (type == HYBRID) + obdex->intindex = nhybrids++; + if (type == MESH) /* AIS: count meshes too */ + obdex->intindex = nmeshes++; + ++obdex; + + return(obdex[-1].intindex); +} + +/************************************************************************* + * + * This function insures a label is valid. + * + **************************************************************************/ + +void checklabel(int label) +{ + if (label < 1 || label > 65535) + lose(E197, yylineno, (char *)NULL); +} + +/************************************************************************* + * + * AIS: Search for the indexth COME_FROM sucking in the given tuple. + * Return an int representing the COME_FROM's tn-tuples+1, or -1. + * index is based at 1, not 0 as is usual for C. + * + ***************************************************************************/ + +int comefromsearch(tuple* tn, unsigned int index) +{ + tuple* tp; + for (tp = tuples; tp < tuples + lineno; tp++) + { + if((tp->type == COME_FROM || tp->type == NEXTFROMLABEL) + && tp->u.target == (unsigned)(tn-tuples+1)) + index--; + if(!index) return tp-tuples+1; + } + return -1; +} + +/************************************************************************* + * + * Tuple allocation functions. + * + **************************************************************************/ + +void treset(void) +{ + tuplecount = 0; + if (tuples) + { + free(tuples); + tuples = NULL; + } + nonespots = ntwospots = ntails = nhybrids = 0; + obdex = oblist; + lineno = 0; +} + +tuple *newtuple(void) +/* allocate and zero out a new expression tuple */ +{ + if (lineno >= tuplecount) + { + tuplecount += ALLOC_CHUNK; + if (tuples) + tuples = realloc(tuples, tuplecount * sizeof(tuple)); + else + tuples = malloc(tuplecount * sizeof(tuple)); + if (!tuples) + { + lose(E666, yylineno, (char *)NULL); + return NULL; + } + memset(tuples + lineno, 0, (tuplecount - lineno) * sizeof(tuple)); + } + if(mark112) tuples[lineno].warn112 = 1; mark112 = 0; /* AIS */ + return(tuples + lineno++); +} + +/************************************************************************* + * + * The typecaster + * + * The theory here is that we associate a type with each node in order to + * know what widths of unary-logical operator to use. + * + **************************************************************************/ + +void typecast(node *np) +{ + /* recurse so we typecast each node after all its subnodes */ + if (np == (node *)NULL) + return; + else if (np->lval != (node *)NULL) + typecast(np->lval); + if (np->rval != (node *)NULL) + typecast(np->rval); + + /* + * This is an entire set of type-deducing machinery right here. + */ + if (np->opcode == MESH || np->opcode == ONESPOT || np->opcode == TAIL) + np->width = 16; + else if (np->opcode == TWOSPOT || np->opcode == HYBRID + || np->opcode == MINGLE || np->opcode == MESH32) + np->width = 32; + else if (np->opcode == AND || np->opcode == OR || np->opcode == XOR || + np->opcode == FIN || + (np->opcode >= WHIRL && np->opcode <= WHIRL5)) + np->width = np->rval->width; + else if (np->opcode == SELECT) + np->width = np->rval->width; /* n-bit select has an n-bit result */ + else if (np->opcode == SUB) + np->width = np->lval->width; /* type of the array */ + else if (np->opcode == SLAT || np->opcode == BACKSLAT) + np->width = np->lval->width; /* AIS: \ and / return their left arg */ +} + +/************************************************************************* + * + * The codechecker + * + * This checks for nasties like mismatched types in assignments that + * can be detected at compile time -- also for errors that could cause + * the compilation of the generated C to fail, like generated gotos to + * nonexistent labels or duplicate labels. + * + * AIS: codecheck has another important job, that of filling in information + * about COME FROM suckpoints and ABSTAIN/REINSTATE command numbers + * into the tuples. + * + **************************************************************************/ + +void codecheck(void) +{ + tuple *tp, *up; + int notpast1900; /* AIS */ + + /* check for assignment type mismatches */ + /* This check can't be done at compile time---RTFM. [LHH] */ +/* + for (tp = tuples; tp < tuples + lineno; tp++) + if (tp->type == GETS) + if (tp->u.node->lval->width == 16 && tp->u.node->rval->width == 32) + lose(E275, tp - tuples + 1, (char *)NULL); +*/ + + /* check for duplicate labels */ + for (tp = tuples; tp < tuples + lineno; tp++) + if (tp->label) + for (up = tuples; up < tuples + lineno; up++) + if (tp != up && tp->label == up->label) + lose(E182, tp - tuples + 1, (char *)NULL); + + /* + * Check that every NEXT, ABSTAIN, REINSTATE and COME_FROM actually has a + * legitimate target label. + */ + notpast1900 = TRUE; + for (tp = tuples; tp < tuples + lineno; tp++) + { + if (tp->label == 1900) notpast1900 = FALSE; /* AIS */ + if (tp->type == NEXT + || tp->type == ABSTAIN || tp->type == REINSTATE + || tp->type == COME_FROM || tp->type == FROM + || tp->type == NEXTFROMLABEL) /* AIS: added FROM, NEXTFROMLABEL. */ + { + bool foundit = FALSE; + + if (tp->u.target >= 1900 && tp->u.target <= 1998) + { + /* AIS: This program uses syslib.i's random number feature... or are + we in syslib already? */ + if(notpast1900) coopt = 0; + } + + for (up = tuples; up < tuples + lineno; up++) + if (tp->u.target == up->label) + { + foundit = TRUE; + break; + } + + if (!foundit) + { + /* AIS: Added the pickcompile check. Syslib has to be optimized + for PICs, so syslib.i isn't imported and so none of the lables + in it will appear in the program. */ + if (tp->type == NEXT && + (!pickcompile||tp->u.target<1000||tp->u.target>1999)) + lose(E129, tp - tuples + 1, (char *)NULL); + else if (tp->type == NEXT) /* AIS */ + {tp->nexttarget=0; continue;} + /* AIS: NEXTFROMLABEL's basically identical to COME_FROM */ + else if (tp->type == COME_FROM || tp->type == NEXTFROMLABEL) + lose(E444, tp - tuples + 1, (char *)NULL); + else + lose(E139, tp - tuples + 1, (char *)NULL); + } + /* tell the other tuple if it is a COME FROM target */ + /* AIS: NEXTFROMLABEL again */ + else if (tp->type == COME_FROM || tp->type == NEXTFROMLABEL) + { + if (up->ncomefrom && !multithread) /* AIS: multithread check */ + lose(E555, yylineno, (char *)NULL); + else + up->ncomefrom++; /* AIS: to handle multiple COME FROMs */ + } + /* this substitutes line numbers for label numbers + AIS: COME FROM now uses this too. This changes the logic + slightly so that an !foundit condition would fall through, + but as long as lose doesn't return, it's not a problem. + (I removed the else before the if.) */ + if (tp->type != NEXT) + { + tp->u.target = up - tuples + 1; + } + else /* AIS */ + { + tp->nexttarget = up - tuples + 1; + up->nextable = TRUE; + } + } + } +} + +/* AIS: Added the third argument to prexpr and prvar. It specifies + whether the node should be freed or not. I added the third + argument in all calls of prexpr/prvar. This protoype has been moved + up through the file so it can be used earlier. Destaticed so it can + be referenced by dekludge.c. */ +void prexpr(node *np, FILE *fp, int freenode); +/************************************************************************* + * + * Code degeneration + * + * The theory behind this crock is that we've been handed a pointer to + * a tuple representing a single INTERCAL statement, possibly with an + * expression tree hanging off it and twisting slowly, slowly in the wind. + * + * Our mission, should we choose to accept it, is to emit C code which, + * when linked to the INTERCAL run-time support, will do something + * resembling the right thing. + * + **************************************************************************/ + +/* + * If the order of statement-token defines in parser.y ever changes, + * this will need to be reordered. + */ +char *enablersm1[MAXTYPES+1] = +{ + "UNKNOWN", /* AIS: so comments can be ABSTAINED/REINSTATED */ + "GETS", + "RESIZE", + "NEXT", + "GO_AHEAD", /* AIS: Added for backtracking */ + "GO_BACK", /* AIS: Added for backtracking */ + "FORGET", + "RESUME", + "STASH", + "RETRIEVE", + "IGNORE", + "REMEMBER", + "ABSTAIN", + "REINSTATE", + "DISABLE", + "ENABLE", + "MANYFROM", /* AIS: Added ABSTAIN expr FROM gerunds */ + "GIVE_UP", + "READ_OUT", + "WRITE_IN", + "PIN", + "COME_FROM", + "NEXTFROMLABEL", /* AIS */ + "NEXTFROMEXPR", /* AIS */ + "NEXTFROMGERUND", /* AIS */ + "COMPUCOME", /* AIS: Added COMPUCOME */ + "GERUCOME", /* AIS: This is COME FROM gerunds */ + "TRY_AGAIN", /* AIS: Added TRY AGAIN */ + "FROM", /* AIS: ABSTAIN expr FROM LABEL */ +}; +char** enablers = enablersm1+1; + +assoc vartypes[] = +{ + { ONESPOT, "ONESPOT" }, + { TWOSPOT, "TWOSPOT" }, + { TAIL, "TAIL" }, + { HYBRID, "HYBRID" }, + { 0, (char *)NULL } +}; + +static assoc forgetbits[] = +{ + { ONESPOT, "oneforget" }, + { TWOSPOT, "twoforget" }, + { TAIL, "tailforget" }, + { HYBRID, "hyforget" }, + { 0, (char *)NULL } +}; + +/* AIS: Destatic. This is now needed in perpet.c. */ +assoc varstores[] = +{ + { ONESPOT, "onespots" }, + { TWOSPOT, "twospots" }, + { TAIL, "tails" }, + { HYBRID, "hybrids" }, + { 0, (char *)NULL } +}; + +static assoc typedefs[] = +{ + { ONESPOT, "type16" }, + { TWOSPOT, "type32" }, + { TAIL, "type16" }, + { HYBRID, "type32" }, + { 0, (char *)NULL } +}; + +char *nameof(int value, assoc table[]) +/* return string corresponding to value in table */ +{ + assoc *ap; + + for (ap = table; ap->name; ap++) + if (ap->value == value) + return(ap->name); + return((char *)NULL); +} + +/* AIS: Code for printing explanations (mixed C/INTERCAL code that lets + the user know what the meaning of an expression is). This is paraphrased + from the prexpr/prvar code lower down. It's passed to yuk so that the + explain ('e') command works. It's also included in the degenerated C + code when the option -c is used, so the person looking at the code can + debug both the INTERCAL and ick itself more effectively, and used by + -h to produce its optimizer-debug output. */ + +unsigned long varextern(unsigned long intern, int vartype) +{ + atom *x; + if(!oblist) lose(E778, emitlineno, (char*) NULL); + for (x = oblist; x < obdex; x++) + if (x->type == vartype && (unsigned)x->intindex == intern) + return(x->extindex); + if(vartype==MESH) return 0; /* the mesh wasn't used after all */ + lose(E778, emitlineno, (char*) NULL); + return 0; /* never reached */ +} + +void explvar(node* np, FILE* fp) +{ + node *sp; + switch(np->opcode) + { + case ONESPOT: + (void) fprintf(fp, ".%lu", varextern(np->constant,ONESPOT)); + break; + case TWOSPOT: + (void) fprintf(fp, ":%lu", varextern(np->constant,TWOSPOT)); + break; + case TAIL: + (void) fprintf(fp, ",%lu", varextern(np->constant,TAIL)); + break; + case HYBRID: + (void) fprintf(fp, ";%lu", varextern(np->constant,HYBRID)); + break; + case SUB: + (void) fprintf(fp, "("); + explvar(np->lval, fp); + (void) fprintf(fp, " SUB "); + for (sp = np->rval ; sp ; sp = sp->rval) + explexpr(sp->lval, fp); + (void) fprintf(fp, ")"); + break; + default: + lose(E778, emitlineno, (char*) NULL); + } +} + +/* unlike prexpr, this doesn't free its operands */ +void explexpr(node* np, FILE* fp) +{ + if(!np) return; + switch (np->opcode) + { + case MINGLE: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " $ "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case SELECT: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " ~ "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case SLAT: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " / "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case BACKSLAT: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " \\ "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case AND: + (void) fprintf(fp, "(& "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case OR: + (void) fprintf(fp, "(V "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case XOR: + (void) fprintf(fp, "(? "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case FIN: + if (Base < 3) + lose(E997, emitlineno, (char *)NULL); + (void) fprintf(fp, "(^ "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case WHIRL: + case WHIRL2: + case WHIRL3: + case WHIRL4: + case WHIRL5: + if (np->opcode - WHIRL + 3 > Base) + lose(E997, emitlineno, (char *)NULL); + if(np->opcode == WHIRL) + (void) fprintf(fp, "(@ "); + else + (void) fprintf(fp, "(%d@ ", np->opcode - WHIRL + 1); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case MESH: + if(variableconstants) /* AIS */ + (void) fprintf(fp, "meshes[%lu]", np->constant); + else + (void) fprintf(fp, "0x%lx", np->constant); + break; + + case MESH32: + (void) fprintf(fp, "0x%lx", np->constant); + break; + + case ONESPOT: + case TWOSPOT: + case TAIL: + case HYBRID: + case SUB: + explvar(np, fp); + break; + + /* cases from here down are generated by the optimizer */ + case C_AND: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case C_OR: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " | "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case C_XOR: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " ^ "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case C_NOT: + (void) fprintf(fp, "(~ "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case C_NOTEQUAL: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " != "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case C_A: + (void) fprintf(fp, "a"); + break; + + case C_NNAND: + (void) fprintf(fp, "(!!("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, "))"); + break; + + case C_AND1ADD1: + (void) fprintf(fp, "(("); + explexpr(np->rval,fp); + (void) fprintf(fp, " & 0x1) + 0x1)"); + break; + + case C_1PLUS: + (void) fprintf(fp, "("); + explexpr(np->rval,fp); + (void) fprintf(fp, " + 0x1)"); + break; + + case C_2MINUS: + (void) fprintf(fp, "(0x2 - "); + explexpr(np->rval,fp); + (void) fprintf(fp, ")"); + break; + + case C_2SUBAND1: + (void) fprintf(fp, "(0x2 - ("); + explexpr(np->rval,fp); + (void) fprintf(fp, " & 0x1))"); + break; + + case C_LSHIFT: + (void) fprintf(fp, "(("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, ") << 0x1)"); + break; + + case C_LSHIFTIN1: + (void) fprintf(fp, "((("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, ") << 0x1) | 0x1)"); + break; + + case C_LSHIFT2: + (void) fprintf(fp, "(("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, ") << 0x2)"); + break; + + case C_LSHIFT8: + (void) fprintf(fp, "(("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, ") << 0x8)"); + break; + + case C_RSHIFTBY: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " >> "); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case C_RSHIFT: + (void) fprintf(fp, "(("); + explexpr(np->lval, fp); + (void) fprintf(fp, " & "); + explexpr(np->rval, fp); + (void) fprintf(fp, ") >> 0x1)"); + break; + + case C_XORGREATER: + (void) fprintf(fp, "("); + explexpr(np->lval, fp); + (void) fprintf(fp, " > ("); + explexpr(np->rval, fp); + (void) fprintf(fp, " ^ "); + explexpr(np->lval, fp); + (void) fprintf(fp, "))"); + break; + + case C_ISNONZERO: + (void) fprintf(fp, "(!!"); + explexpr(np->rval, fp); + (void) fprintf(fp, ")"); + break; + + case INTERSECTION: + explexpr(np->lval, fp); + (void) fprintf(fp, " + "); + explexpr(np->rval, fp); + break; + + case GETS: + case RESIZE: + explexpr(np->lval, fp); + (void) fprintf(fp, " <- "); + explexpr(np->rval, fp); + break; + + case BY: + explexpr(np->lval, fp); + (void) fprintf(fp, " BY "); + explexpr(np->rval, fp); + break; + + default: + lose(E778, emitlineno, (char*) NULL); + break; + } +} + +/* AIS: Added the third argument to prexpr and prvar. It specifies + whether the node should be freed or not. I added the third + argument in all calls of prexpr/prvar. */ + +/* AIS: I moved prexpr's prototype higher in the file. + Destaticed so the optimizer can access it. */ + +void prvar(node *np, FILE *fp, int freenode) +/* print out args to pass to storage manager for reference */ +{ + node *sp; + int dim; + + switch (np->opcode) + { + case ONESPOT: + (void) fprintf(fp, "onespots[%lu]", np->constant); + break; + + case TWOSPOT: + (void) fprintf(fp, "twospots[%lu]", np->constant); + break; + + case TAIL: + (void) fprintf(fp, "TAIL, &tails[%lu]", np->constant); + break; + + case HYBRID: + (void) fprintf(fp, "HYBRID, &hybrids[%lu]", np->constant); + break; + + case SUB: + { + (void) fprintf(fp, "aref("); + prvar(np->lval, fp, freenode); + + dim = 0; + for (sp = np->rval ; sp ; sp = sp->rval) + dim++; + (void) fprintf(fp, ", %d", dim); + + for (sp = np->rval ; sp ; sp = sp->rval) { + (void) fprintf(fp, ", "); + prexpr(sp->lval, fp, freenode); + } + (void) fprintf(fp, ")"); + } + break; + default: /* Added by AIS */ + lose(E778, emitlineno, (char*) NULL); + break; + } +} + +void ooprvar(node *np, FILE *fp, int freenode) +/* AIS: Print out the overloaded version */ +{ + node *sp; + int dim; + + switch (np->opcode) + { + case ONESPOT: + (void) fprintf(fp, "oo_onespots[%lu]", np->constant); + break; + + case TWOSPOT: + (void) fprintf(fp, "oo_twospots[%lu]", np->constant); + break; + + case TAIL: + case HYBRID: + /* This should never be reached */ + lose(E778, emitlineno, (char*) NULL); + break; + + case SUB: + { + (void) fprintf(fp, "aref("); + prvar(np->lval, fp, freenode); + + dim = 0; + for (sp = np->rval ; sp ; sp = sp->rval) + dim++; + (void) fprintf(fp, ", %d", dim); + + for (sp = np->rval ; sp ; sp = sp->rval) { + (void) fprintf(fp, ", "); + prexpr(sp->lval, fp, freenode); + } + (void) fprintf(fp, ")"); + } + break; + default: + lose(E778, emitlineno, (char*) NULL); + break; + } +} + +/* AIS: Give us a mesh with value x */ +static unsigned long meshval(unsigned long x) +{ + if(variableconstants) + return intern(MESH, x); + else + return x; +} + +/* AIS: This is the reverse of prexpr, in a way. + It degenerates an expression that causes *np to become equal to *target. + If this is impossible at any point, it degenerates code that causes + error 277 (and itself causes error 278 if the situation is inevitable). */ +void revprexpr(node *np, FILE *fp, node *target) +{ + node* temp; + switch (np->opcode) + { + case MINGLE: + /* We can use select to determine what np->lval and np->rval have + to become equal to, as long as we're in base 2. */ + if(Base!=2) + { + fprintf(fp, " lose(E277, lineno, (char*) NULL);\n"); + lwarn(W278, emitlineno, (char*) NULL); + break; + } + temp=cons(MESH,0,0); + temp->constant=meshval(0xAAAAAAAALU); + temp->width=32; + temp=cons(SELECT,target,temp); + temp->width=target->width; + revprexpr(np->lval, fp, temp); + free(temp->rval); + free(temp); + temp=cons(MESH,0,0); + temp->constant=meshval(0x55555555LU); + temp->width=32; + temp=cons(SELECT,target,temp); + temp->width=target->width; + revprexpr(np->rval, fp, temp); + free(temp->rval); + free(temp); + break; + + case SELECT: + /* Set the left of the select to the target, and the right + to 0xffffffff or 0xffff. This only works in base 2. */ + if(Base!=2) + { + fprintf(fp, " lose(E277, lineno, (char*) NULL);\n"); + lwarn(W278, emitlineno, (char*) NULL); + break; + } + temp=cons(MESH,0,0); + temp->constant=meshval(target->width==32?0xFFFFFFFFLU:0xFFFFLU); + temp->width=target->width; + revprexpr(np->lval, fp, target); + revprexpr(np->rval, fp, temp); + free(temp); + break; + + case BACKSLAT: + /* Unimplemented. This isn't even in the parser yet, so it's a + mystery how we got here. */ + lose(E778, emitlineno, (char*) NULL); + break; + + case SLAT: + /* We need to set the true value of the LHS... */ + + /* Copied and modified from the GETS code */ + if(!pickcompile) + { + (void) fprintf(fp," (void) assign((char*)&"); + prvar(np->lval, fp, 0); + (void) fprintf(fp,", %s", nameof(np->lval->opcode, vartypes)); + (void) fprintf(fp,", %s[%lu], ", nameof(np->lval->opcode, forgetbits), + np->lval->constant); + prexpr(target, fp, 0); + (void) fprintf(fp,"); \n"); + } + else /* AIS: Added this case for the simpler PIC assignment rules */ + { + (void) fprintf(fp,"\tif(ignore%s%lu) ", + nameof(np->lval->opcode,varstores), + np->lval->constant); + prexpr(np->lval, fp, 0); + (void) fprintf(fp, " = "); + prexpr(target, fp, 0); + (void) fprintf(fp, "; \n"); + } + + /* ... and we need to cause overloading to happen. This is a copy + of part of the code for SLAT, modified to work in this context. */ + ooprvar(np->lval, fp, 0); + /* Do something highly non-portable with pointers that should work + anyway. Each pointer needs to be given a unique code; so we use + the hex representation of np casted to an unsigned long. + Technically speaking, np->rval could be casted to anything; but + all implementations I've ever seen cast unique pointers to unique + numbers, which is good enough for our purposes. */ + (void) fprintf(fp, ".get=og%lx;\n ", (unsigned long)np); + ooprvar(np->lval, fp, 0); + (void) fprintf(fp, ".set=os%lx;\n", (unsigned long)np); + break; + + case AND: + case OR: + case XOR: + case FIN: + case WHIRL: + case WHIRL2: + case WHIRL3: + case WHIRL4: + case WHIRL5: + temp=cons(np->opcode-AND+REV_AND,0,target); + temp->width=temp->rval->width=np->width; + revprexpr(np->rval, fp, temp); + free(temp); + break; + + case MESH: + if(!variableconstants) + { + /* Can't set a mesh in this case */ + fprintf(fp, " lose(E277, lineno, (char*) NULL);\n"); + lwarn(W278, emitlineno, (char*) NULL); + break; + } + (void) fprintf(fp," meshes[%lu] = ",np->constant); + prexpr(target, fp, 0); + (void) fprintf(fp,";\n"); + break; + + case ONESPOT: + case TWOSPOT: + case TAIL: + case HYBRID: + case SUB: + /* Copy the code for the GETS statement; this is almost the same + thing. Modified because we're assigning target to np, not + np->lval to np->rval, and to not free(). */ + if(opoverused&& + (np->opcode==ONESPOT||np->opcode==TWOSPOT)) /* AIS */ + { + (void) fprintf(fp," "); + ooprvar(np, fp, 0); + (void) fprintf(fp,".set("); + prexpr(target, fp, 0); + (void) fprintf(fp,",(void(*)())os%dspot%lu);\n", + (np->opcode==TWOSPOT)+1, np->constant); + } + else if(!pickcompile) + { + node* sp; + + if (np->opcode != SUB) { + sp = np; + (void) fprintf(fp," (void) assign((char*)&"); + } + else { + sp = np->lval; + (void) fprintf(fp," (void) assign("); + } + prvar(np, fp, 0); + (void) fprintf(fp,", %s", nameof(sp->opcode, vartypes)); + (void) fprintf(fp,", %s[%lu], ", nameof(sp->opcode, forgetbits), + sp->constant); + prexpr(target, fp, 0); + (void) fprintf(fp,");\n"); + } + else /* AIS: Added this case for the simpler PIC assignment rules */ + { + (void) fprintf(fp," if(ignore%s%lu) ", + nameof(np->opcode,varstores), + np->constant); + prexpr(np, fp, 0); + (void) fprintf(fp, " = "); + prexpr(target, fp, 0); + (void) fprintf(fp, ";\n"); + } + break; + + /* cases from here down are generated by the optimizer, and so + should never come up here and are errors. The exception is + C_A, which should only ever appear in a target expression, + so is also an error. */ + case MESH32: + case C_AND: + case C_OR: + case C_XOR: + case C_NOT: + case C_NOTEQUAL: + case C_A: + case C_NNAND: + case C_AND1ADD1: + case C_1PLUS: + case C_2MINUS: + case C_2SUBAND1: + case C_LSHIFT: + case C_LSHIFTIN1: + case C_LSHIFT2: + case C_LSHIFT8: + case C_RSHIFTBY: + case C_RSHIFT: + case C_XORGREATER: + case C_ISNONZERO: + case GETS: /* should never come up */ + default: + lose(E778, emitlineno, (char*) NULL); + break; + } +} + +/* AIS: Destaticed */ +void prexpr(node *np, FILE *fp, int freenode) +/* print out C-function equivalent of an expression */ +{ + int tempint; + switch (np->opcode) + { + case MINGLE: + (void) fprintf(fp, "mingle("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, ", "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case SELECT: + (void) fprintf(fp, "iselect("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, ", "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case BACKSLAT: /* AIS */ + /* Unimplemented. This isn't even in the parser yet, so it's a + mystery how we got here. */ + lose(E778, emitlineno, (char*) NULL); + break; + + case SLAT: /* AIS */ + (void) fprintf(fp,"(("); + ooprvar(np->lval, fp, 0); + /* Do something highly non-portable with pointers that should work + anyway. Each pointer needs to be given a unique code; so we use + the hex representation of np casted to an unsigned long. + Technically speaking, np->rval could be casted to anything; but + all implementations I've ever seen cast unique pointers to unique + numbers, which is good enough for our purposes. */ + (void) fprintf(fp, ".get=og%lx),(", (unsigned long)np); + ooprvar(np->lval, fp, 0); + (void) fprintf(fp, ".set=os%lx),(", (unsigned long)np); + prvar(np->lval, fp, freenode); + /* np->rval will be freed later, when its expression is printed */ + (void) fprintf(fp, "))"); + return; /* mustn't be freed */ + + case AND: + (void) fprintf(fp, "and%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case OR: + (void) fprintf(fp, "or%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case XOR: + (void) fprintf(fp, "xor%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case FIN: + if (Base < 3) + lose(E997, emitlineno, (char *)NULL); + (void) fprintf(fp, "fin%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case WHIRL: + case WHIRL2: + case WHIRL3: + case WHIRL4: + case WHIRL5: + if (np->opcode - WHIRL + 3 > Base) + lose(E997, emitlineno, (char *)NULL); + (void) fprintf(fp, "whirl%d(%d, ", np->width, np->opcode - WHIRL + 1); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + /* AIS: Reversed operations */ + case REV_AND: + (void) fprintf(fp, "rev_and%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case REV_OR: + (void) fprintf(fp, "rev_or%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case REV_XOR: + (void) fprintf(fp, "rev_xor%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case REV_FIN: + if (Base < 3) + lose(E997, emitlineno, (char *)NULL); + (void) fprintf(fp, "rev_fin%d(", np->width); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case REV_WHIRL: + case REV_WHIRL2: + case REV_WHIRL3: + case REV_WHIRL4: + case REV_WHIRL5: + if (np->opcode - WHIRL + 3 > Base) + lose(E997, emitlineno, (char *)NULL); + (void) fprintf(fp, + "rev_whirl%d(%d, ", np->width, np->opcode - WHIRL + 1); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case MESH: + if(variableconstants) /* AIS */ + (void) fprintf(fp, "meshes[%lu]", np->constant); + else + (void) fprintf(fp, "0x%lx", np->constant); + break; + + case MESH32: + (void) fprintf(fp, "0x%lx", np->constant); + break; + + case ONESPOT: + case TWOSPOT: + case TAIL: + case HYBRID: + if(!opoverused||np->opcode==TAIL||np->opcode==HYBRID) + prvar(np, fp, freenode); + else /* AIS */ + { + ooprvar(np, fp, freenode); + fprintf(fp, ".get("); + prvar(np, fp, freenode); + fprintf(fp,")"); + } + break; + + case SUB: + (void) fprintf(fp, "*(%s*)", nameof(np->lval->opcode, typedefs)); + prvar(np, fp, freenode); + break; + + /* cases from here down are generated by the optimizer */ + case C_AND: + (void) fprintf(fp, "("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case C_OR: + (void) fprintf(fp, "("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " | "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case C_XOR: + (void) fprintf(fp, "("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " ^ "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case C_NOT: + (void) fprintf(fp, "(~"); + tempint=np->rval->width; /* AIS */ + prexpr(np->rval, fp, freenode); + if (tempint == Small_digits) + (void) fprintf(fp, " & Max_small)"); + else + (void) fprintf(fp, " & Max_large)"); + break; + + /* AIS: I added the rest of the cases */ + case C_NOTEQUAL: + (void) fprintf(fp, "("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " != "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case C_A: + (void) fprintf(fp, "a"); + break; + + case C_NNAND: + (void) fprintf(fp, "(!!("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, "))"); + break; + + case C_AND1ADD1: + (void) fprintf(fp, "(("); + prexpr(np->rval,fp, freenode); + (void) fprintf(fp, " & 0x1) + 0x1)"); + break; + + case C_1PLUS: + (void) fprintf(fp, "("); + prexpr(np->rval,fp, freenode); + (void) fprintf(fp, " + 0x1)"); + break; + + case C_2MINUS: + (void) fprintf(fp, "(0x2 - "); + prexpr(np->rval,fp, freenode); + (void) fprintf(fp, ")"); + break; + + case C_2SUBAND1: + (void) fprintf(fp, "(0x2 - ("); + prexpr(np->rval,fp, freenode); + (void) fprintf(fp, " & 0x1))"); + break; + + case C_LSHIFT: + (void) fprintf(fp, "(("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ") << 0x1)"); + break; + + case C_LSHIFTIN1: + (void) fprintf(fp, "((("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ") << 0x1) | 0x1)"); + break; + + case C_LSHIFT2: + (void) fprintf(fp, "(("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ") << 0x2)"); + break; + + case C_LSHIFT8: + (void) fprintf(fp, "(("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ") << 0x8)"); + break; + + case C_RSHIFTBY: + (void) fprintf(fp, "(("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, ") >> "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ")"); + break; + + case C_RSHIFT: + (void) fprintf(fp, "(("); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " & "); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, ") >> 0x1)"); + break; + + case C_XORGREATER: + (void) fprintf(fp, "("); + prexpr(np->lval, fp, 0); /* Patched by Joris Huizer */ + (void) fprintf(fp, " > ("); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, " ^ "); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, "))"); + break; + + case C_ISNONZERO: + (void) fprintf(fp, "(!!("); + prexpr(np->rval, fp, freenode); + (void) fprintf(fp, "))"); + break; + + case GETS: /* AIS: this is used only if freenode == 0 */ + if(freenode) lose(E778, emitlineno, (char*) NULL); + prexpr(np->lval, fp, freenode); + (void) fprintf(fp, " = "); + prexpr(np->rval, fp, freenode); + break; + + default: /* Added by AIS */ + if(!freenode) break; /* Be less careful when not freeing, because + this is used by -hH to print out its + intermediate optimization stages */ + lose(E778, emitlineno, (char*) NULL); + break; + } + + if(freenode) (void) free(np); +} + +static char *nice_text(char *texts[], int lines) +{ +#define MAXNICEBUF 512 + static char buf[MAXNICEBUF]; + char *cp, *text; + int i; + + if (lines < 1) + lines = 1; + for (cp = buf, i = 0 ; i < lines ; ++i) { + if (cp>buf+MAXNICEBUF-10) goto abort; + if (i) { + (*cp++) = '\\'; + (*cp++) = 'n'; + (*cp++) = '\\'; + (*cp++) = '\n'; + (*cp++) = '\t'; + } + for (text = texts[i] ; text&&*text ; cp++, text++) { + if (cp>buf+MAXNICEBUF-10) goto abort; + if(*text == '"' || *text == '\\') { + (*cp++) = '\\'; + } + *cp = *text; + } + } + *cp = '\0'; + return buf; +abort: (*cp++) = '.'; + (*cp++) = '.'; + (*cp++) = '.'; + *cp = '\0'; + return buf; +} + +static void emit_guard(tuple *tn, FILE *fp) +/* emit execution guard for giiven tuple (note the unbalanced trailing {!) */ +{ + if(tn->maybe) /* AIS */ + { + if(!multithread) lose(E405, emitlineno, (char *)NULL); + (void) fprintf(fp, " gonebackto = setjmp(btjb); choicepoint();\n"); + } + if(!flowoptimize || tn->abstainable) /* This condition by AIS */ + { + (void) fprintf(fp, " if ("); + if (tn->maybe) /* AIS */ + (void) fprintf(fp, "gonebackto == !("); + if (tn->exechance < 100) + (void) fprintf(fp, "roll(%d) && ", tn->exechance); + if ((tn->type != NEXT && tn->type != GO_BACK && tn->type != COME_FROM + && /* AIS */ tn->type != NEXTFROMLABEL) + || tn->onceagainflag == onceagain_NORMAL) + (void) fprintf(fp, "!ICKABSTAINED(%d))%s {\n", (int)(tn - tuples), + /* AIS */ tn->maybe?")":""); + else /* AIS: [NEXT, GO_BACK, COME_FROM] ONCE needs specially + handled abstentions */ + (void) fprintf(fp, "!oldabstain)%s {\n", + /* AIS */ tn->maybe?")":""); + } + else + { /* AIS */ + if(tn->maybe) lose(E778, emitlineno, (char*) NULL); + if(!tn->initabstain) + { + if(tn->type != COMPUCOME && tn->type != GERUCOME + && tn->type != NEXTFROMEXPR && tn->type != NEXTFROMGERUND) + (void) fprintf(fp, " {\n"); + else (void) fprintf(fp, " if(1) {\n"); /* COMPUCOME specifically needs + an if() so it can have + an else. */ + } + else (void) fprintf(fp, " if(0) {\n"); /* for exceptional cases like + DON'T COME FROM #1 where we + need a label or an else. */ + } +} + +void emittextlines(FILE *fp) +{ + int i=0; /* The first textline is line 1 */ + (void) fprintf(fp, "\"\",\n"); + while(++ilineno); + if (tn->label) + (void) fprintf(fp, "L%d:", tn->label); + if (yydebug || compile_only) + { + (void) fprintf(fp, "\t/* %s */", textlines[tn->lineno]); + /* AIS: grind out an expression explanation */ + if (tn->type == GETS || tn->type == FORGET || tn->type == RESUME + || tn->type == FROM || tn->type == COMPUCOME + || tn->type == MANYFROM || tn->type == NEXTFROMEXPR) + { + (void) fprintf(fp, "\n\t/* Expression is "); + explexpr(tn->type == MANYFROM ? tn->u.node->lval : + tn->type == GETS ? tn->u.node->rval : tn->u.node, fp); + (void) fprintf(fp, " */"); + } + } + (void) fputc('\n', fp); + + /* set up the "next" lexical line number for error messages */ + if (tn->type == NEXT) { + tuple *up; + for (up = tuples; up < tuples + lineno; up++) + if (tn->u.target == up->label) { + emitlineno = up->lineno; + break; + } + } else if (tn->ncomefrom) + emitlineno = comefromsearch(tn,1); /* AIS: For multithreading. + Return the 1st if we're forking. */ + else if (tn < tuples + lineno - 1) + emitlineno = tn[1].lineno; + else + emitlineno = yylineno; + if(!pickcompile) /* AIS: PICs can't report errors, so don't bother with lineno */ + (void) fprintf(fp, " lineno = %d;\n", emitlineno); + + /* print warnings on -l */ + if(checkforbugs) + { + if(tn->warn112) lwarn(W112, emitlineno, (char*) NULL); + if(tn->warn128) lwarn(W128, emitlineno, (char*) NULL); + if(tn->warn534) lwarn(W534, emitlineno, (char*) NULL); + if(tn->warn018) lwarn(W018, emitlineno, (char*) NULL); + if(tn->warn016) lwarn(W016, emitlineno, (char*) NULL); + if(tn->warn276) lwarn(W276, emitlineno, (char*) NULL); + if(tn->warn239) lwarn(W239, emitlineno, (char*) NULL); + if(tn->warn622) lwarn(W622, emitlineno, (char*) NULL); + } + + /* emit debugging information */ + if (yukdebug||yukprofile) + { + (void) fprintf(fp, " YUK(%d,%d);\n", + (int)(tn-tuples),emitlineno); + } + + /* AIS: The +mystery option on degenerated code causes the code to + unexpectedly terminate after 4 billion commands are run, thus + preventing an infinite loop. Of course, it will enhance the fun + if we don't tell the user that. (This is necessary for the + constant-output optimizer to work properly.) */ + if(coopt) (void) fprintf(fp, " MYSTERYLINE;\n"); + + /* AIS: If the tuple is ONCE/AGAIN flagged, we need a delayed-action + set of its abstention status to the AGAIN-flagged status. The + problem is that some statements, like COME FROM, need to set after + the command has finished, and some, like NEXT, need it before the + command has started. At the moment, only NEXT and GO_BACK have a + ONCE/AGAIN before it, rather than after (because neither of them + continue in the normal fashion). */ + if ((tn->type == NEXT || tn->type == GO_BACK) && + tn->onceagainflag != onceagain_NORMAL) + { + /* ONCE/AGAIN has already been swapped by perpetrate.c in the case + of a preabstained statement ('DO NOT'...). So if currently have + a ONCE, it means that being abstained is the attractive state, + and if we currently have an AGAIN, it means that being + reinstated is the attractive state. Semantics with computed + ABSTAIN: Don't change the abstention count unless necessary, in + which case change it to 0 or 1. */ + fprintf(fp," oldabstain = ICKABSTAINED(%d);\n", (int)(tn - tuples)); + fprintf(fp," ICKABSTAINED(%d) = %s;\n", + (int)(tn - tuples), + tn->onceagainflag==onceagain_ONCE ? "oldabstain ? oldabstain : 1" + : "0"); + /* This test-and-set must be atomic. As all statements are atomic anyway + in the current version of ick, that isn't a problem, but if anyone + wants to try using POSIX's multithreading features, the above two + lines need to be a critical section. */ + } + + /* in the case of COMPUCOME, we need an extra guard */ + if (tn->type == COMPUCOME || tn->type == GERUCOME + || tn->type == NEXTFROMEXPR || tn->type == NEXTFROMGERUND) + { + fprintf(fp," if(0)\n {\n"); + fprintf(fp,"CCF%d:\n",compucomecount++); + if(tn->type == COMPUCOME || tn->type == NEXTFROMEXPR) + { + fprintf(fp," if(skipto&&skipto=="); + prexpr(tn->u.node, fp, 1); + } + else if(tn->type == GERUCOME || tn->type == NEXTFROMGERUND) + { + fprintf(fp," if("); + for (np = tn->u.node; np; np = np->rval) + { + if (np->constant == ABSTAIN) { + (void) fprintf(fp, +"linetype[truelineno] == %s || linetype[truelineno] == %s || " +"linetype[truelineno] == %s || linetype[truelineno] == %s || ", + enablers[np->constant-GETS], + enablers[np->constant-GETS+2], + enablers[FROM-GETS], enablers[MANYFROM-GETS]); + } else if (np->constant == REINSTATE) { + (void) fprintf(fp, +"linetype[truelineno] == %s || linetype[truelineno] == %s || ", + enablers[np->constant-GETS], + enablers[np->constant-GETS+2]); + } else if (np->constant == COME_FROM) { + (void) fprintf(fp, +"linetype[truelineno] == %s || linetype[truelineno] == %s || " +"linetype[truelineno] == %s || ", + enablers[COME_FROM-GETS], + enablers[COMPUCOME-GETS], + enablers[GERUCOME-GETS]); + } else if (np->constant == NEXTFROMLABEL) { + (void) fprintf(fp, +"linetype[truelineno] == %s || linetype[truelineno] == %s || " +"linetype[truelineno] == %s || ", + enablers[NEXTFROMLABEL-GETS], + enablers[NEXTFROMEXPR-GETS], + enablers[NEXTFROMGERUND-GETS]); + } else { + (void) fprintf(fp, "linetype[truelineno] == %s || ", + enablers[np->constant-GETS]); + } + } + fprintf(fp, "0"); + } + fprintf(fp,") {\n"); + } + + /* AIS: With this block placed here, you can't even have a comment + after a TRY AGAIN line. Move it below the next check if this seems + to be undesirable behaviour. */ + if(pasttryagain) /* AIS */ + { + lose(E993, emitlineno, (char*)NULL); + } + + if(flowoptimize && tn->initabstain && !tn->abstainable + && tn->type != COMPUCOME && tn->type != COME_FROM && + tn->type != NEXT && tn->type != GERUCOME && + tn->type != NEXTFROMLABEL && tn->type != NEXTFROMEXPR && + tn->type != NEXTFROMGERUND) /* AIS */ + goto skipcomment; /* Look, a comment! We can completely skip all + degeneration of this statement (although with + -c, comments will appear in the degenerated + code in its place). The COMPUCOME condition is + because it is so weird. COME_FROM and NEXT are + exempted so labels are generated. */ + + /* emit conditional-execution prefixes */ + if (tn->type != COME_FROM && tn->type != NEXTFROMLABEL) + emit_guard(tn, fp); + + /* now emit the code for the statement body */ + switch(tn->type) + { + case GETS: + /* AIS: variableconstants means GETS has been generalised */ + if(variableconstants) + { + revprexpr(tn->u.node->lval, fp, tn->u.node->rval); + nodefree(tn->u.node); + break; + } + + /* Start of AIS optimization */ + np = tn->u.node; + if(np->lval->opcode == SUB) np = np->lval; + if(flowoptimize && Base == 2 && !opoverused && !variableconstants && + (np->lval->opcode == TWOSPOT + || np->lval->opcode == HYBRID + || !(tn->u.node->lval->optdata & ~0xffffLU))) + { + atom* op; + int ignorable = 1; + for(op = oblist; op < obdex; op++) + { + if(op->type == np->lval->opcode && + (unsigned)op->intindex == np->lval->constant) + { + ignorable &= op->ignorable; + } + } + if(!ignorable) + { /* Variable can't be ignored, and expression must be in range */ + (void) fprintf(fp,"\t"); + prexpr(tn->u.node->lval, fp, 1); + (void) fprintf(fp, " = "); + prexpr(tn->u.node->rval, fp, 1); + (void) fprintf(fp, ";\n"); + break; + } + } + /* End of AIS optimization */ + if(opoverused&& + (tn->u.node->lval->opcode==ONESPOT|| + tn->u.node->lval->opcode==TWOSPOT)) /* AIS */ + { + (void) fprintf(fp,"\t"); + ooprvar(tn->u.node->lval, fp, 1); + (void) fprintf(fp,".set("); + prexpr(tn->u.node->rval, fp, 1); + (void) fprintf(fp,",(void(*)())os%dspot%lu);\n", + (tn->u.node->rval->opcode==TWOSPOT)+1, + tn->u.node->rval->constant); + } + else if(!pickcompile) + { + np = tn->u.node; + + if (np->lval->opcode != SUB) { + sp = np->lval; + (void) fprintf(fp,"\t(void) assign((char*)&"); + } + else { + sp = np->lval->lval; + (void) fprintf(fp,"\t(void) assign("); + } + prvar(np->lval, fp, 1); + (void) fprintf(fp,", %s", nameof(sp->opcode, vartypes)); + (void) fprintf(fp,", %s[%lu], ", nameof(sp->opcode, forgetbits), + sp->constant); + prexpr(np->rval, fp, 1); + (void) fprintf(fp,");\n"); + } + else /* AIS: Added this case for the simpler PIC assignment rules */ + { + (void) fprintf(fp,"\tif(ignore%s%lu) ", + nameof(tn->u.node->lval->opcode,varstores), + tn->u.node->lval->constant); + prexpr(tn->u.node->lval, fp, 1); + (void) fprintf(fp, " = "); + prexpr(tn->u.node->rval, fp, 1); + (void) fprintf(fp, ";\n"); + } + break; + + case RESIZE: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + np = tn->u.node; + dim = 0; + for (sp = np->rval; sp; sp = sp->rval) + dim++; + (void) fprintf(fp, "\tresize("); + prvar(np->lval, fp, 1); + (void) fprintf(fp, ", %s[%lu]", nameof(np->lval->opcode, forgetbits), + np->lval->constant); + (void) fprintf(fp, ", %d", dim); + for (sp = np->rval; sp; sp = sp->rval) { + (void) fprintf(fp, ", "); + prexpr(sp->lval, fp, 1); + } + (void) fprintf(fp, ");\n"); + break; + + case NEXT: + /* Start of AIS optimization */ + if(tn->u.target>=1000 && tn->u.target<=1999 && pickcompile) + { + /* optimize syslib call on a PIC */ + (void) fprintf(fp, "\tsyslibopt%d();\n", tn->u.target); + break; + } + if(tn->optversion) + { /* optimizef has checked that this is a valid optimization */ + (void) fprintf(fp, "\tif(1 == "); + prexpr(tn->u.node, fp, 1); /* frees optimizef's nodecopy */ + /* AIS: Everything now in one giant switch(), with some very strange + constructs (including ;{;} as a null statement; this makes + degenerating the code slightly easier) */ + (void) fprintf(fp, ") {pushnext(%d); skipto=%d; goto top;}} case %d:;{;\n", + (int)(tn - tuples + 1), tn->nexttarget, (int)(tn - tuples + 1)); + break; + } + /* End of AIS optimization */ + (void) fprintf(fp, /* same change as above (case rather than a label) */ + "\tpushnext(%d); goto L%d;} case %d:;{;\n", + (int)(tn - tuples + 1), tn->u.target, (int)(tn - tuples + 1)); + break; + + case GO_BACK: /* By AIS */ + if(!multithread) lose(E405, emitlineno, (char*) NULL); + (void) fprintf(fp, "\tchoiceback();\n"); + break; + + case GO_AHEAD: /* By AIS */ + if(!multithread) lose(E405, emitlineno, (char*) NULL); + (void) fprintf(fp, "\tchoiceahead();\n"); + break; + + case RESUME: + (void) fprintf(fp, "\tskipto = resume("); + prexpr(tn->u.node, fp, 1); + (void) fprintf(fp, "); goto top;\n"); + break; + + case FORGET: + (void) fprintf(fp, "\tpopnext("); + prexpr(tn->u.node, fp, 1); + (void) fprintf(fp, ");\n"); + break; + + case STASH: + for (np = tn->u.node; np; np = np->rval) + (void) fprintf(fp, "\tICKSTASH(%s, %lu, %s, %s%s);\n", + nameof(np->opcode, vartypes), + np->constant, + nameof(np->opcode, varstores), + /* AIS */(opoverused&&(np->opcode==ONESPOT|| + np->opcode==TWOSPOT)? + "oo_":"0"), + /* AIS */(opoverused&&(np->opcode==ONESPOT|| + np->opcode==TWOSPOT)? + nameof(np->opcode, varstores):"0")); + break; + + case RETRIEVE: + for (np = tn->u.node; np; np = np->rval) + (void) fprintf(fp, "\tICKRETRIEVE(%s, %lu, %s, %s, %s%s);\n", + nameof(np->opcode, varstores), np->constant, + nameof(np->opcode, vartypes), + nameof(np->opcode, forgetbits), + /* AIS */(opoverused&&(np->opcode==ONESPOT|| + np->opcode==TWOSPOT)? + "oo_":"0"), + /* AIS */(opoverused&&(np->opcode==ONESPOT|| + np->opcode==TWOSPOT)? + nameof(np->opcode, varstores):"0")); + + break; + + case IGNORE: + for (np = tn->u.node; np; np = np->rval) + (void) fprintf(fp,"\tICKIGNORE(%s,%lu,%s) = TRUE;\n", + nameof(np->opcode, forgetbits), + np->constant, + nameof(np->opcode, varstores)); + break; + + case REMEMBER: + for (np = tn->u.node; np; np = np->rval) + (void) fprintf(fp,"\tICKIGNORE(%s,%lu,%s) = FALSE;\n", + nameof(np->opcode, forgetbits), + np->constant, + nameof(np->opcode, varstores)); + break; + + /* All abstention code has been edited by AIS to allow for the new + abstention rules */ + case ABSTAIN: + if(!pickcompile) + (void) fprintf(fp, "\tif(!ICKABSTAINED(%d)) ICKABSTAINED(%d) = 1;\n", tn->u.target - 1, tn->u.target-1); + else + (void) fprintf(fp, "ICKABSTAINED(%d) = 1;\n", tn->u.target-1); + break; + + case FROM: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); + (void) fprintf(fp, "\tICKABSTAINED(%d)+=", tn->u.target-1); + tn->u.node->width = 32; + prexpr(tn->u.node,fp, 1); + (void) fprintf(fp, ";\n"); + break; + + case REINSTATE: + if(!pickcompile) + (void) fprintf(fp, "\tif(ICKABSTAINED(%d)) ICKABSTAINED(%d)--;\n", tn->u.target - 1, tn->u.target-1); + else + (void) fprintf(fp, "\tICKABSTAINED(%d)=0;\n", tn->u.target - 1); + break; + + case ENABLE: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + (void) fprintf(fp, + "\tint i;\n"); + for (np = tn->u.node; np; np = np->rval) + { + (void) fprintf(fp, + "\n\tfor (i = 0; i < (int)(sizeof(linetype)/sizeof(int)); i++)\n"); + if (np->constant == ABSTAIN) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2], enablers[FROM-GETS], enablers[MANYFROM-GETS]); + } else if (np->constant == REINSTATE) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2]); + } else if (np->constant == COME_FROM) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[COME_FROM-GETS], enablers[COMPUCOME-GETS], enablers[GERUCOME-GETS]); + } else if (np->constant == NEXTFROMLABEL) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[NEXTFROMLABEL-GETS], enablers[NEXTFROMGERUND-GETS], enablers[NEXTFROMEXPR-GETS]); + } else { + (void) fprintf(fp, + "\t if (linetype[i] == %s)\n", enablers[np->constant-GETS]); + } + (void) fprintf(fp, + "\t\tif(abstained[i]) abstained[i]--;\n"); + } + break; + + case DISABLE: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + (void) fprintf(fp, + "\tint i;\n"); + for (np = tn->u.node; np; np = np->rval) + { + (void) fprintf(fp, + "\n\tfor (i = 0; i < (int)(sizeof(linetype)/sizeof(int)); i++)\n"); + if (np->constant == ABSTAIN) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2], enablers[FROM-GETS], enablers[MANYFROM-GETS]); + } else if (np->constant == REINSTATE) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2]); + } else if (np->constant == COME_FROM) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[COME_FROM-GETS], enablers[COMPUCOME-GETS], enablers[GERUCOME-GETS]); + } else if (np->constant == NEXTFROMLABEL) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[NEXTFROMLABEL-GETS], enablers[NEXTFROMGERUND-GETS], enablers[NEXTFROMEXPR-GETS]); + } else { + (void) fprintf(fp, + "\t if (linetype[i] == %s)\n", enablers[np->constant-GETS]); + } + (void) fprintf(fp, + "\t\tif(!abstained[i]) abstained[i] = 1;\n"); + } + break; + + case MANYFROM: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + (void) fprintf(fp, + "\tint i;\n\tint j;\n\tj="); + tn->u.node->lval->width=32; + prexpr(tn->u.node->lval,fp, 1); + (void) fprintf(fp, + ";\n"); + for (np = tn->u.node->rval; np; np = np->rval) + { + (void) fprintf(fp, + "\n\tfor (i = 0; i < (int)(sizeof(linetype)/sizeof(int)); i++)\n"); + if (np->constant == ABSTAIN) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s || linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2], enablers[FROM-GETS], enablers[MANYFROM-GETS]); + } else if (np->constant == REINSTATE) { + (void) fprintf(fp, + "\t if (linetype[i] == %s || linetype[i] == %s)\n", enablers[np->constant-GETS], enablers[np->constant-GETS+2]); + } else { + (void) fprintf(fp, + "\t if (linetype[i] == %s)\n", enablers[np->constant-GETS]); + } + (void) fprintf(fp, + "\t\tabstained[i] += j;\n"); + } + break; + + case NEXTFROMEXPR: + case NEXTFROMGERUND: + case GERUCOME: + case COMPUCOME: /* By AIS. Note that this doesn't even have balanced + braces; it's designed to work with COMPUCOME's + crazy guarding arrangements */ + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + fprintf(fp,"\t;} else goto CCF%d;\n",compucomecount); + break; + + case GIVE_UP: /* AIS: Edited to allow for yuk */ + if(yukprofile||yukdebug) fprintf(fp, "\tYUKTERM;\n"); + if(multithread) fprintf(fp, "\tkillthread();\n"); + (void) fprintf(fp, "\treturn(0);\n"); + break; + + case TRY_AGAIN: /* By AIS */ + (void) fprintf(fp, "\tgoto ick_restart;\n }\n"); + if(yukprofile||yukdebug) fprintf(fp, " if(yukloop) goto ick_restart;\n"); + if(yukprofile||yukdebug) fprintf(fp, " YUKTERM;\n"); + if(multithread) fprintf(fp, "\tkillthread();\n"); + (void) fprintf(fp, " {\n\treturn(0);\n"); + /* because if TRY AGAIN is the last line, falling off the end isn't an error */ + pasttryagain=1; /* flag an error if we try any more commands */ + break; + + case WRITE_IN: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + for (np = tn->u.node; np; np = np->rval) { + if (np->lval->opcode == TAIL || np->lval->opcode == HYBRID) { + (void) fprintf(fp,"\tbinin("); + prvar(np->lval, fp, 1); + (void) fprintf(fp, ", %s[%lu]", + nameof(np->lval->opcode, forgetbits), + np->lval->constant); + (void) fprintf(fp,");\n"); + } + else { + if (np->lval->opcode != SUB) { + sp = np->lval; + (void) fprintf(fp,"\t(void) assign((char*)&"); + } + else { + sp = np->lval->lval; + (void) fprintf(fp,"\t(void) assign("); + } + prvar(np->lval, fp, 1); + (void) fprintf(fp,", %s", nameof(sp->opcode, vartypes)); + (void) fprintf(fp,", %s[%lu]", nameof(sp->opcode, forgetbits), + sp->constant); + (void) fprintf(fp,", pin());\n"); + } + } + break; + + case READ_OUT: + if(pickcompile) lose(E256, emitlineno, (char*) NULL); /* AIS */ + for (np = tn->u.node; np; np = np->rval) + { + if (np->lval->opcode == TAIL || np->lval->opcode == HYBRID) { + (void) fprintf(fp,"\tbinout("); + prvar(np->lval, fp, 1); + (void) fprintf(fp,");\n"); + } + else { + (void) fprintf(fp, "\tpout("); + prexpr(np->lval, fp, 1); + (void) fprintf(fp, ");\n"); + } + } + break; + + case PIN: /* AIS, with some code borrowed from the GETS code */ + np = tn->u.node; + (void) fprintf(fp, "\tTRISA = seq(~(("); + prexpr(np, fp, 0); + (void) fprintf(fp, " >> 16) & 255));\n"); + (void) fprintf(fp, "\tTRISB = seq(~("); + prexpr(np, fp, 0); + (void) fprintf(fp, " >> 24));\n"); + (void) fprintf(fp, "\tPORTA = seq(~("); + prexpr(np, fp, 0); + (void) fprintf(fp, " & 255));\n"); + (void) fprintf(fp, "\tPORTB = seq(~(("); + prexpr(np, fp, 0); + (void) fprintf(fp, " >> 8) & 255));\n"); + { + atom* op; + int ignorable = 1; + for(op = oblist; op < obdex; op++) + { + if(op->type == np->opcode && + (unsigned)op->intindex == np->constant) + { + ignorable &= op->ignorable; + } + } + if(!ignorable) + { /* Variable can't be ignored, and expression must be in range */ + (void) fprintf(fp,"\t"); + prexpr(np, fp, 1); + (void) fprintf(fp, " = "); + } + else + { + np = tn->u.node; + (void) fprintf(fp,"\tif(ignore%s%lu) ", + nameof(np->opcode,varstores), + np->constant); + prexpr(np, fp, 1); + (void) fprintf(fp, " = "); + } + } + (void) fprintf(fp,"(TRISB<<24) | (TRISA<<16) | (PORTB<<8) | PORTA;\n"); + break; + + case SPLATTERED: + dim = emitlineno - tn->lineno; + if (tn->sharedline) + ++dim; + (void) fprintf(fp, "\tlose(E000, %d, \"%s\");\n", + emitlineno, nice_text(textlines + tn->lineno, dim)); + break; + + case COME_FROM: + case NEXTFROMLABEL: /* AIS */ + (void) fprintf(fp, "if(0) {C%ld: %s;}\n", (long)(tn-tuples+1), + tn->type==NEXTFROMLABEL ? "pushnext(truelineno+1)":""); + /* AIS: Changed so all COME_FROMs have unique labels even if two + of them aim at the same line, and added the NEXT FROM case (which + invloves hiding COME FROM labels in an unreachable if()). */ + break; + + default: + lose(E778, emitlineno, (char *)NULL); + break; + } + + if (tn->type != COME_FROM && tn->type != NEXTFROMLABEL) + (void) fprintf(fp, " }\n"); + + skipcomment: + + if (tn->type == COMPUCOME || tn->type == GERUCOME || + tn->type == NEXTFROMEXPR || tn->type == NEXTFROMGERUND) + { /* By AIS */ + (void) fprintf(fp," else goto CCF%d;\n",compucomecount); + (void) fprintf(fp," ccfc++;\n"); + /* Note that due to the semantics of setjmp, this has to be written as 2 + separate ifs. The MULTICOME macro expands to a non-multithreaded or + multithreaded function for handling a COME FROM clash. */ + (void) fprintf(fp," if(ccfc==1||MULTICOME(%d,cjb))\n" + "\tif(setjmp(cjb) == 0) goto CCF%d;\n", + emitlineno, compucomecount); + /* Of course, emitlineno is unlikely to be helpful! */ + if(tn->type == NEXTFROMEXPR || tn->type == NEXTFROMGERUND) + { + /* Stack up the statement we've NEXTed from */ + (void) fprintf(fp," pushnext(truelineno+1);\n"); + } + (void) fprintf(fp," }\n"); + } + + /* AIS: Before any COMING FROM this line is done, we need to sort out + ONCE and AGAIN situations, unless this line was a NEXT or GO_BACK. + COME FROM is also excluded because it acts at the suckpoint, not + at the place it's written in the program. */ + if (tn->onceagainflag != onceagain_NORMAL && + (tn->type != NEXT && tn->type != GO_BACK && tn->type != COME_FROM && + tn->type != NEXTFROMLABEL)) + { + /* See my comments against the NEXT code for more information. + This code is placed here so COME FROM ... ONCE constructs work + properly (the line is abstained if the COME FROM is reached in + execution, or its suckpoint is reached in execution). */ + fprintf(fp," oldabstain = ICKABSTAINED(%d);\n", (int)(tn - tuples)); + fprintf(fp," ICKABSTAINED(%d) = %s;\n", + (int)(tn - tuples), + tn->onceagainflag==onceagain_ONCE ? "oldabstain ? oldabstain : 1" + : "0"); + } + + /* AIS: This is where we start the COME FROM suckpoint code. */ + + /* AIS: We need to keep track of how many COME FROMs are aiming here + at runtime, if we don't have the very simple situation of no + COMPUCOMEs and a single-thread program (in which case the check + is done at compile-time by codecheck). Even without COMPUCOME, + this can change in a multithread program due to abstentions. */ + if((tn->ncomefrom && multithread) || (tn->label && compucomesused) + || gerucomesused) + (void) fprintf(fp, " ccfc = 0;\n"); + /* AIS: For NEXTING FROM this line */ + if(nextfromsused && tn->ncomefrom) + { + (void) fprintf(fp, " truelineno = %d;\n", (int)(tn-tuples)); + } + /* + * If the statement that was just degenerated was a COME FROM target, + * emit the code for the jump to the COME FROM. + * AIS: Changed most of this to allow for multithreading. + */ + while(tn->ncomefrom) /* acts as an if if singlethreading */ + { + tuple* cf; /* local to this block */ + if(multithread || compucomesused) generatecfjump = 1; + cf = tuples+comefromsearch(tn,tn->ncomefrom)-1; + if (yydebug || compile_only) + (void) fprintf(fp, + " /* line %03d is a suck point for the COME FROM " + "at line %03d */\n", tn->lineno, cf->lineno); + if (cf->onceagainflag != onceagain_NORMAL) + { /* Calculate ONCE/AGAIN when the suckpoint is passed */ + fprintf(fp," oldabstain = ICKABSTAINED(%d);\n", (int)(cf - tuples)); + fprintf(fp," ICKABSTAINED(%d) = %s;\n", + (int)(cf - tuples), + cf->onceagainflag==onceagain_ONCE ? "oldabstain ? oldabstain : 1" + : "0"); + } + emit_guard(cf, fp); + if(multithread || compucomesused) + (void) fprintf(fp, + "\tccfc++;\tif(ccfc==1||MULTICOME(%d,cjb)) " + "if(setjmp(cjb) == 1) goto C%ld;\n }\n", + emitlineno, (long)(cf-tuples+1)); + else /* optimize for the simple case */ + (void) fprintf(fp, "\tgoto C%ld;\n }\n", (long)(cf-tuples+1)); + tn->ncomefrom--; + } + + /* AIS: If the statement has a label, it might be a + computed COME FROM target. Also check the flag that says this + code is needed in a multithread non-COMPUCOME program. + If (at runtime) ccfc is nonzero, we know cjb has already been set; + otherwise, set it now. In the case of a multithread non-COMPUCOME + program, the goto will just jump to a longjmp, switching to the + one and only one COME FROM that hasn't been given its own thread. */ + if ((tn->label && compucomesused) || generatecfjump || gerucomesused) + { + if(compucomesused) + { + (void) fprintf(fp, " skipto = %d;\n", tn->label); + } + if(gerucomesused || nextfromsused) + { + (void) fprintf(fp, " truelineno = %d;\n", (int)(tn-tuples)); + } + if(generatecfjump) (void) fprintf(fp, " if(ccfc) goto CCF0;\n"); + if(compucomesused || gerucomesused) + { /* check all the COMPUCOMES */ + (void) fprintf(fp, " %sif(setjmp(cjb) == 0) goto CCF0;\n", + generatecfjump?"else ":""); + } + generatecfjump = 0; + /* AIS: If NEXT FROM's used, this might be a NEXT return target. + Don't generate case labels for NEXT, as it has them already. */ + if(nextfromsused && tn->type != NEXT) + { + (void) fprintf(fp, " case %u:;\n", (unsigned)(tn-tuples+1)); + } + } + + /* AIS: Now we've finished the statement, let's switch to the next + thread in a multithread program. */ + if(multithread) (void) fputs(" NEXTTHREAD;\n", fp); +} + +/* AIS: Generate prototypes for slat expressions */ +void emitslatproto(FILE* fp) +{ + node* np=firstslat; + char* t="type32"; + while(np) + { + fprintf(fp,"%s og%lx(%s);\nvoid os%lx(%s, void(*)());\n", + t,(unsigned long)np,t,(unsigned long)np,t); + np=np->nextslat; + } +} + +/* AIS: Generate bodies for slat expressions */ +void emitslat(FILE* fp) +{ + node* np=firstslat; + node* temp, *temp2; + char* t="type32"; + while(np) + { + fprintf(fp, + "void os%lx(%s a, void(*f)())\n{\n static int l=0;\n" + " if(l)\n {\n if(!f)lose(E778, lineno, (char *)NULL);\n" + " ((void(*)(%s,void(*)()))f)(a,0);\n return;\n }\n l=1;\n", + (unsigned long)np,t,t); + temp=cons(C_A, 0, 0); + revprexpr(np->rval, fp, temp); /* revprexpr can't free */ + fprintf(fp," l=0;\n}\n"); + fprintf(fp,"%s og%lx(%s t)\n{\n %s a;\n static int l=0;\n" + " if(l) return t;\n l=1;\n a=", + t,(unsigned long)np,t,t); + prexpr(np->rval, fp, 0); + fprintf(fp,";\n l=0;\n return a;\n}\n"); + np=np->nextslat; + } + np=firstslat; + /* Note that the order in which the parser assembles nodes means + that we have to free the nodes in reverse order so we don't + free child nodes twice. */ + temp2=0; + while(np) + { + temp=np->nextslat; + np->nextslat=temp2; /* reverse the chain */ + temp2=np; + np=temp; + } + np=temp2; + while(np) + { + temp=np->nextslat; + nodefree(np->rval); + free(np); + np=temp; + } +} + +/* feh.c ends here */ diff --git a/src/fiddle.c b/src/fiddle.c new file mode 100644 index 0000000..239e02f --- /dev/null +++ b/src/fiddle.c @@ -0,0 +1,378 @@ +/* + * fiddle.c -- functions that implement the five INTERCAL operators + * + * We link these to the compiler, too, in order to do constant folding + * +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "fiddle.h" +#include "sizes.h" +#include "lose.h" +#include + +unsigned int mingle(register unsigned int r, register unsigned int s) +{ + if (Base == 2) { + if (r>0xffff || s>0xffff) + lose(E533, lineno, (char *)NULL); + r = ((r & 0x0000ff00) << 8) | (r & 0x000000ff); + r = ((r & 0x00f000f0) << 4) | (r & 0x000f000f); + r = ((r & 0x0c0c0c0c) << 2) | (r & 0x03030303); + r = ((r & 0x22222222) << 1) | (r & 0x11111111); + s = ((s & 0x0000ff00) << 8) | (s & 0x000000ff); + s = ((s & 0x00f000f0) << 4) | (s & 0x000f000f); + s = ((s & 0x0c0c0c0c) << 2) | (s & 0x03030303); + s = ((s & 0x22222222) << 1) | (s & 0x11111111); + return (r << 1) | s; + } + else { + unsigned int result = 0, fac = 1; + int i; + for (i = 0 ; i < Small_digits ; i++) { + result += fac * (s % Base); + s /= Base; + fac *= Base; + result += fac * (r % Base); + r /= Base; + fac *= Base; + } + return result; + } +} + +unsigned int iselect(register unsigned int r, register unsigned int s) +{ + if (Base == 2) { + register unsigned int i = 1, t = 0; + while (s) { + if (s & i) { + t |= r & i; + s ^= i; + i <<= 1; + } + else { + s >>= 1; + r >>= 1; + } + } + return(t); + } + else { + unsigned int j, result = 0, fac, digit, ofac = 1; + for (j = Base - 1 ; j > 0 ; j--) { + int i; + fac = 1; + for (i = 0; i < Large_digits ; i++) { + if ((s / fac) % Base == j) { + digit = (r / fac) % Base; + if (digit) + result += ofac * (digit > j ? digit : j); + ofac *= Base; + } + fac *= Base; + } + } + return result; + } +} + +static unsigned int whirl(unsigned int len, unsigned int p, unsigned int n) +{ + unsigned int i, fac = 1, result = 0, d1, d2, dsave; + d1 = n % Base; + dsave = d1; + for (i = 1 ; i <= len ; i++) { + d2 = d1; + d1 = (i < len) ? (n /= Base, n % Base) : dsave; + if (d1 <= p) + result += fac * ((d2 < d1 || d2 > p) ? d1 : d2); + else + result += fac * ((d2 < d1 && d2 > p) ? d1 : d2); + fac *= Base; + } + return result; +} + +unsigned int and16(unsigned int n) +{ + if (Base == 2) { + unsigned int m = (n >> 1); + if (n & 1) + m |= 0x8000; + return(m & n); + } + else { + return whirl(Small_digits,0,n); + } +} + +unsigned int or16(unsigned int n) +{ + if (Base == 2) { + unsigned int m = (n >> 1); + if (n & 1) + m |= 0x8000; + return(m | n); + } + else { + return whirl(Small_digits,Base-1,n); + } +} + +unsigned int whirl16(unsigned int p, unsigned int n) +{ + return whirl(Small_digits,p,n); +} + +unsigned int and32(unsigned int n) +{ + if (Base == 2) { + unsigned int m = (n >> 1); + if (n & 1) + m |= 0x80000000; + return(m & n); + } + else { + return whirl(Large_digits,0,n); + } +} + +unsigned int or32(unsigned int n) +{ + if (Base == 2) { + unsigned int m = (n >> 1); + if (n & 1) + m |= 0x80000000; + return(m | n); + } + else { + return whirl(Large_digits,Base-1,n); + } +} + +unsigned int whirl32(unsigned int p, unsigned int n) +{ + return whirl(Large_digits,p,n); +} + +unsigned int xor(unsigned int len, unsigned int n) +{ + unsigned int i, fac = 1, result = 0, d1, d2, dsave; + d1 = n % Base; + dsave = d1; + for (i = 1 ; i <= len ; i++) { + d2 = d1; + d1 = (i < len) ? (n /= Base, n % Base) : dsave; + result += fac * ((Base + d1 - d2) % Base); + fac *= Base; + } + return result; +} + +unsigned int xor16(unsigned int n) +{ + if (Base == 2) { + unsigned int m = (n >> 1); + if (n & 1) + m |= 0x8000; + return(m ^ n); + } + else { + return xor(Small_digits,n); + } +} + +unsigned int xor32(unsigned int n) +{ + if (Base == 2) { + unsigned int m = (n >> 1); + if (n & 1) + m |= 0x80000000; + return(m ^ n); + } + else { + return xor(Large_digits,n); + } +} + +static unsigned int fin(unsigned int len, unsigned int n) +{ + unsigned int i, fac = 1, result = 0, d1, d2, dsave; + d1 = n % Base; + dsave = d1; + for (i = 1 ; i <= len ; i++) { + d2 = d1; + d1 = (i < len) ? (n /= Base, n % Base) : dsave; + result += fac * ((d1 + d2) % Base); + fac *= Base; + } + return result; +} + +unsigned int fin16(unsigned int n) +{ + if (Base == 2) { + unsigned int m = (n >> 1); + if (n & 1) + m |= 0x8000; + return(m ^ n); + } + else { + return fin(Small_digits,n); + } +} + +unsigned int fin32(unsigned int n) +{ + if (Base == 2) { + unsigned int m = (n >> 1); + if (n & 1) + m |= 0x80000000; + return(m ^ n); + } + else { + return fin(Large_digits,n); + } +} + +/* AIS: Reversed operations, for operand overloading */ + +static unsigned int rotleft16(unsigned int n) +{ + return !!(n&0x8000)|((n&0x7FFF)<<1); +} +static unsigned int rotleft32(unsigned int n) +{ + return !!(n&0x80000000)|((n&0x7FFFFFFF)<<1); +} + +/* For the time being, just work out the answer in binary, and test using + the base-whatever operation. This means that there'll nearly always be + a failure in reversing in bases other than 2. */ +unsigned int rev_or16(unsigned int n) +{ + if(or16(rotleft16(and16(n)))==n) return rotleft16(and16(n)); + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_or32(unsigned int n) +{ + if(or32(rotleft32(and32(n)))==n) return rotleft32(and32(n)); + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_and16(unsigned int n) +{ + if(and16(rotleft16(or16(n)))==n) return rotleft16(or16(n)); + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_and32(unsigned int n) +{ + if(and32(rotleft32(or32(n)))==n) return rotleft32(or32(n)); + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_xor16(unsigned int n) +{ + unsigned int a=0, l=1, t=0; + while(l<=0x4000) + { + if(n&l) + t^=1; + if(t) + a+=l*2; + l*=2; + } + if(xor16(a)==n) return a; + lose(E277, lineno, (char*) NULL); + return 0; +} + + +unsigned int rev_xor32(unsigned int n) +{ + unsigned int a=0, l=1, t=0; + while(l<=0x4000000) + { + if(n&l) + t^=1; + if(t) + a+=l*2; + l*=2; + } + if(xor32(a)==n) return a; + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_fin16(unsigned int n) +{ + unsigned int a=0, l=1, t=0; + while(l<=0x4000) + { + if(n&l) + t^=1; + if(t) + a+=l*2; + l*=2; + } + if(fin16(a)==n) return a; + lose(E277, lineno, (char*) NULL); + return 0; +} + + +unsigned int rev_fin32(unsigned int n) +{ + unsigned int a=0, l=1, t=0; + while(l<=0x4000000) + { + if(n&l) + t^=1; + if(t) + a+=l*2; + l*=2; + } + if(fin32(a)==n) return a; + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_whirl16(unsigned int p, unsigned int n) +{ + /* Only reverse if all digits are the same. */ + if(whirl16(p,n)==n) return n; + lose(E277, lineno, (char*) NULL); + return 0; +} + +unsigned int rev_whirl32(unsigned int p, unsigned int n) +{ + /* Only reverse if all digits are the same. */ + if(whirl32(p,n)==n) return n; + lose(E277, lineno, (char*) NULL); + return 0; +} + +/* fiddle.c */ diff --git a/src/fiddle.h b/src/fiddle.h new file mode 100644 index 0000000..a68d3d2 --- /dev/null +++ b/src/fiddle.h @@ -0,0 +1,18 @@ +/* fiddle.h -- functions implementing intercal's operators */ + +extern unsigned int mingle(register unsigned int r, register unsigned int s); +extern unsigned int iselect(register unsigned int r, register unsigned int s); +extern unsigned int and16(unsigned int n), or16(unsigned int n), + xor16(unsigned int n), fin16(unsigned int n); +extern unsigned int whirl16(unsigned int p, unsigned int n); +extern unsigned int and32(unsigned int n), or32(unsigned int n), + xor32(unsigned int n), fin32(unsigned int n); +extern unsigned int whirl32(unsigned int p, unsigned int n); +/* AIS: Reversed operators */ +extern unsigned int rev_and16(unsigned int n), rev_or16(unsigned int n), + rev_xor16(unsigned int n), rev_fin16(unsigned int n); +extern unsigned int rev_whirl16(unsigned int p, unsigned int n); +extern unsigned int rev_and32(unsigned int n), rev_or32(unsigned int n), + rev_xor32(unsigned int n), rev_fin32(unsigned int n); +extern unsigned int rev_whirl32(unsigned int p, unsigned int n); +/* fiddle.h ends here */ diff --git a/src/ick-wrap.c b/src/ick-wrap.c new file mode 100644 index 0000000..50ce9c6 --- /dev/null +++ b/src/ick-wrap.c @@ -0,0 +1,84 @@ +$L +/* $A.c -- generated C-code file for INTERCAL program $A.i */ + +/* This code is explicitly *not* GPLed. Use, abuse, and redistribute freely */ + +#include +#include +#include +#include + +$M +#include "fiddle.h" +#include "abcess.h" +#include "lose.h" +$K + +#define ICKABSTAINED(d) abstained[d] +#define ICKSTASH(a,b,c,d) stash(a, b, c+b, d) +#define ICKRETRIEVE(a,b,c,d,e) retrieve(a+b, c, b, d[b], e) +#define ICKIGNORE(a,b,c) a[b] + +extern int printflow; + +int lineno; + +jmp_buf cjb; +int ccfc; +unsigned skipto=0; +$O + +int oldabstain; +int abstained[$B]$C; +$D +$E +$P +int main(int argc, char *argv[]) +{ + parseargs(argc,argv); + + skipto = 0; + + next = calloc(80, sizeof *next); +$N + +#ifdef YUK + yuklines = $J; + yukcommands = $B; +#endif + /* set seed for random error generation */ +#ifdef USG + srand48(time(0) + getpid()); +#else + srand(time(0)); +#endif /* UNIX */ + +#if MULTITHREAD == 1 + ickmtinit(); +#endif + + /* set up stash storage */ + stashinit(); + + $F + + /* degenerated code */ + ick_restart: + top: + switch(skipto) + { + case 0: + $G + } + +#ifdef YUK + if(yukloop) goto ick_restart; +#endif + lose(E633, $J, (char *)0); + + $H + + return 0; +} +$Q +/* Generated code for $A.i ends here */ diff --git a/src/ick.bat b/src/ick.bat new file mode 100755 index 0000000..0e246b8 --- /dev/null +++ b/src/ick.bat @@ -0,0 +1,8 @@ +@rem Wrapper for ickmain.exe that gets around the 126-byte system() limit + +@echo off +ickmain %* +if exist ickgcc.rsp gcc @ickgcc.rsp +if exist ickgcc.rsp del ickgcc.rsp +if exist ickyuk.bat call ickyuk.bat +if exist ickyuk.bat del ickyuk.bat diff --git a/src/ick.h b/src/ick.h new file mode 100644 index 0000000..85e0581 --- /dev/null +++ b/src/ick.h @@ -0,0 +1,160 @@ +/* ick.h -- compilation types for intercal parser */ + +/* AIS: Changes for DJGPP */ +#ifdef __DJGPP__ +#define _POSIX_SOURCE +#endif + +#ifdef ICKNOSEARCH +#define ICKINCLUDEDIR "." +#define ICKLIBDIR "." +#define ICKBINDIR "." +#define YYDEBUG 1 +#endif + +/* Comment this out if your version of lex automatically supplies yylineno. */ +#define YYLINENO_BY_HAND + +/* Comment this out if your version of lex doesn't use yyrestart(). */ +#define USE_YYRESTART + +#define YY_NO_UNPUT + +typedef int bool; +#define TRUE 1 +#define FALSE 0 + +#define ALLOC_CHUNK 256 + +/* + * We choose this value for maximum number of possible variables on + * the theory that no human mind could grok a more complex INTERCAL + * program than this and still retain any vestige of sanity. +#define MAXVARS 100 + */ + +/* + * Maximum supported statement types; should be equal to (FROM - GETS + 1) + * AIS: Changed this when I added new statements. + */ +#define MAXTYPES 28 + +/* AIS: Maximum supported spark/ears nesting, divided by 32. The value given + allows for 256 nested spark/ears groupings, which should be enough. */ +#define SENESTMAX 8 + +enum onceagain {onceagain_NORMAL, onceagain_ONCE, onceagain_AGAIN}; /* AIS */ + +typedef struct node_t +{ + int opcode; /* operator or type code */ + unsigned long constant; /* constant data attached */ + unsigned long optdata; /* AIS: Temp used by the optimizer */ + int width; /* is this 32-bit data? */ + struct node_t *lval, *rval; /* attached expression nodes */ + struct node_t *nextslat; /* AIS: The next node with a slat */ +} node; + +typedef struct tuple_t +{ + unsigned int label; /* label # of this statement */ + unsigned int ncomefrom; /* AIS: How many noncomputed COME FROMS + have this line as a suck-point */ + int exechance; /* chance of execution, initial abstain, + (AIS) MAYBE details */ + bool maybe; /* AIS: Where MAYBE details go when + exechance has been parsed */ + bool abstainable; /* AIS: Is it possible for this line to + be abstained from? */ + bool initabstain; /* AIS: Is this line initially + abstained from? */ + bool nextable; /* AIS: Can this line be a NEXT + target? */ + bool optversion; /* AIS: Use an optimized version? (Only + set if the optimizer thinks that + it's safe.) */ + bool warn112:1; /* AIS: Should this line produce warning + 112 during degeneration? */ + bool warn128:1, warn534:1, warn018:1, warn016:1, warn276:1, warn239:1, + warn622:1; /* AIS: As warn112. The warnings are a bitfield to save space. */ + unsigned int type; /* statement type */ + struct + { /* AIS: Struct, not union needed because ABSTAIN expr FROM (line) has both */ + unsigned int target; /* for NEXT statements */ + node *node; /* attached expression node(s) */ + } u; + unsigned int nexttarget; /* AIS: The target tuple of a NEXT must + also be recorded for optimizef */ + int lineno; /* source line for error messages */ + bool sharedline; /* if NZ, two statements on a line */ + enum onceagain onceagainflag; /* AIS: ONCE / AGAIN */ +} tuple; + +/* this maps the `external' name of a variable to an internal array index */ +typedef struct +{ + int type; + unsigned int extindex; + unsigned int intindex; + int ignorable; /* AIS: Can this variable be IGNOREd? */ + int memloc; /* AIS: Where does a PIC store this in memory? */ +} +atom; + +typedef struct +{ + int value; + char *name; +} +assoc; + +extern atom *oblist, *obdex; +extern int obcount, nonespots, ntwospots, ntails, nhybrids; +extern int nmeshes; /* AIS */ + +extern tuple *tuples; +extern int tuplecount; + +extern tuple *optuple; /* AIS: The tuple currently being optimized */ + +extern char **enablers; +extern char *enablersm1[MAXTYPES+1]; +extern assoc vartypes[]; + +/* the lexical analyzer keeps copies of the source logical lines */ +extern char **textlines; +extern int textlinecount; +extern int yylineno; + +/* AIS: These are needed to sort out a grammar near-ambiguity */ +extern unsigned long sparkearsstack[SENESTMAX]; +extern int sparkearslev; + +/* compilation options */ +extern bool compile_only; /* just compile into C, don't run the linker */ +extern bool nocompilerbug; /* set possibility of E774 to zero */ +extern int traditional; /* compile as INTERCAL-72 */ +extern int yydebug; /* print debugging information while parsing */ + +extern int politesse; + + +/* AIS: I added these */ +extern int yukdebug; /* debug the code with yuk */ +extern int yukprofile; /* profile the code with yuk */ +extern int compucomecount; /* number of computed COME FROMs */ +extern int compucomesused; /* are computed COME FROMs used? */ +extern int nextfromsused; /* is NEXT FROM used? */ +extern int gerucomesused; /* is COME FROM gerund used? */ +extern int opoverused; /* is operand overloading used? */ +extern node* firstslat; /* the first node with a slat */ +extern node* prevslat; /* the last node so far with a slat */ +extern int multithread; /* is the program multithreaded? */ +extern int variableconstants; /* is any assignment allowed? */ +extern int coreonerr; /* dump core on E778? */ +extern int optdebug; /* debug the optimizer */ +extern int flowoptimize; /* optimize program flow */ +extern int checkforbugs; /* check for bugs */ +extern int coopt; /* constant-output optimizer */ + +/* ick.h ends here */ diff --git a/src/lexer.l b/src/lexer.l new file mode 100644 index 0000000..aee2b40 --- /dev/null +++ b/src/lexer.l @@ -0,0 +1,500 @@ +%e 2000 +%p 4000 +%n 1000 +%{ +/* + * NAME + * lexer.l -- source for the C-INTERCAL lexical analyzer. + * +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include +#include +#include +#include +#include "ick.h" +#include "parser.h" +#include "lose.h" + +/*#undef wchar_t*/ +/*#define wchar_t unsigned char*/ + +#ifndef yywrap +static int yywrap(void) +{ + return 1; +} +#endif /* yywrap */ + +#ifdef YYLINENO_BY_HAND +int yylineno = 1; +#endif /* YYLINENO_BY_HAND */ + +#ifdef MAIN +YYSTYPE yylval; +#endif /* MAIN */ + +char **textlines = NULL; +int textlinecount = 0; +int politesse = 0; +int stbeginline = 0; + +/* AIS: Sort out a grammar near-ambiguity */ +unsigned long sparkearsstack[SENESTMAX] = {0}; +int sparkearslev = 0; + +/* AIS: Some symbols are ambiguous between C-INTERCAL and CLC-INTERCAL: + Symbol C-INTERCAL CLC-INTERCAL + NOSPOT _ @ + WHIRL @ ? + XOR ? yen, or bookworm (bookworm's also C-INTERCAL legal) + By default, the C-INTERCAL meanings are used; the extern variable clclex + causes CLC-INTERCAL interpretations to be put on the ambiguous symbols. + Otherwise, mixing syntaxes freely is allowed. */ +extern int clclex; + +#ifdef FLEX_SCANNER +static char linebuf[YY_BUF_SIZE]; +#else /* FLEX_SCANNER */ +static char linebuf[YYLMAX]; +#endif /* FLEX_SCANNER */ + +static char *lineptr = linebuf; + +bool re_send_token = FALSE; + +int lexer(void); +static int myatoi(char *text); + +#define SETLINENO \ + {if (stbeginline == 0) stbeginline = yylineno; \ + else if (stbeginline < 0) stbeginline = 0;} + +/* AIS: Keep track of the spark/ears situation */ +#define STACKSPARKEARS(a) \ + if (sparkearslev+1>=SENESTMAX*32) lose(E281, yylineno, (char*) NULL); \ + sparkearslev++; sparkearsstack[sparkearslev/32]<<=1; \ + sparkearsstack[sparkearslev/32]+=a +#define CLEARSPARKEARSTACK {int i=SENESTMAX; \ + while(i--) sparkearsstack[i] = 0;} \ + sparkearslev = 0 + +/* + * The spectacular ugliness of INTERCAL syntax requires that the lexical + * analyzer have two levels. One, embedded in the getc() function, handles + * logical-line continuation and the ! abbrev, and stashes each logical + * line away in a buffer accessible to the code generator (this is necessary + * for the * construct to be interpreted correctly). The upper level is + * generated by lex(1) and does normal tokenizing. + */ + +#undef getc +int getc(FILE *fp) +{ + extern FILE* yyin; + + static bool bangflag = FALSE; + static bool backflag = FALSE; + + if (bangflag) + { + bangflag = FALSE; + /* *lineptr++ = '!'; */ + return('.'); + } + else if (backflag) /* converting ctrl-H (backspace) to two chars "^H" */ + { + backflag = FALSE; + /* *lineptr++ = '\b'; */ + return('H'); + } + else + { + int c; + char c_char; + /*fprintf(stderr,"about to fgetc(\045p)",(void*)fp);*/ + + c_char=0; /* AIS */ + (void)fread(&c_char,1,1,fp); + c = c_char; + /*if(!c) c=' '; AIS */ + if(feof(fp)) c=EOF; + + /*fprintf(stderr,"getc input a character: %c\n",c);*/ + + if (feof(yyin)) + { + *lineptr = '\0'; + return(EOF); + } +#ifdef BACKSLASH_CONTINUATION + else if (c == '\\') + { + do { + c = fgetc(fp); +#ifdef YYLINENO_BY_HAND + if( c == '\n' ) yylineno++; +#endif /* YYLINENO_BY_HAND */ + } while + (c != '\\' && isspace(c)); + } +#endif /* BACKSLASH_CONTINUATION */ + if (c == '!') + { + *lineptr++ = '!'; + bangflag = TRUE; + return(c = '\''); + } + else if (c == '\b') /* convert ctrl-H (backspace) to + two chars "^" and "H" so lex can take it */ + { + *lineptr++ = '\b'; + backflag = TRUE; + return(c = '^'); + } + else if (c == '\n') + { + *lineptr = '\0'; + lineptr = linebuf; + if (yylineno >= textlinecount) + { + textlinecount += ALLOC_CHUNK; + if (textlines) + textlines = realloc(textlines, + textlinecount * sizeof(char*)); + else + textlines = malloc(textlinecount * sizeof(char*)); + if (!textlines) + lose(E666, yylineno, (char *)NULL); + } + textlines[yylineno] = malloc(1 + strlen(linebuf)); + if (!textlines[yylineno]) + lose(E666, yylineno, (char *)NULL); + strcpy(textlines[yylineno], linebuf); +#ifdef YYLINENO_BY_HAND + yylineno++; +#endif /* YYLINENO_BY_HAND */ + return('\n'); + } + else + { +#ifdef ACCEPT_LOWERCASE + if (islower(c)) + c = toupper(c); +#endif /* ACCEPT_LOWERCASE */ + return(*lineptr++ = c); + } + } +} + +/* replace YY_INPUT so that it uses our getc function. */ +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + { \ + int c = getc(yyin); \ + if (c == EOF) { \ + if (ferror(yyin)) \ + YY_FATAL_ERROR("input in flex scanner failed"); \ + result = YY_NULL; \ + } else { \ + buf[0] = c; \ + result = 1; \ + } \ + } + +%} + +W [\ \t\n]* +D [0-9][\ \t\n0-9]* + +%% + +{D} {yylval.numval = myatoi(yytext); return(NUMBER);} +\_ {return(NOSPOT);} +\. {return(ONESPOT);} +\: {return(TWOSPOT);} +\, {return(TAIL);} +\; {return(HYBRID);} +\# {return(MESH);} + +\xBD | +"c^H/" | +"c^H|" {return(MINGLE); /* AIS: CLC-INTERCAL mingle symbols. + The \xBD is ISO-8859-1 for cent. */} +\$ | +\xA2 | +\xA3 | +\xA4 | +\xC2\xA2 | +\xC2\xA3 | +\xC2\xA4 | +\xE2\x82\xA0 | +\xE2\x82\xA1 | +\xE2\x82\xA2 | +\xE2\x82\xA3 | +\xE2\x82\xA4 | +\xE2\x82\xA5 | +\xE2\x82\xA6 | +\xE2\x82\xA7 | +\xE2\x82\xA8 | +\xE2\x82\xA9 | +\xE2\x82\xAA | +\xE2\x82\xAB | +\xE2\x82\xAC | +\xE0\xA7\xB2 | +\xE0\xA7\xB3 | +\xE0\xB8\xBF {return(MINGLE);} + +\~ {return(SELECT);} + +\/ {return(SLAT); /* AIS: Operand overloading */} +\\ {return(BACKSLAT); /* ditto */} + +\& {yylval.numval = AND; return(UNARY);} +V {yylval.numval = OR; return(UNARY);} +\xA5 | +\xBE | +"V^H-" | +\xE2\x88\x80 {yylval.numval = XOR; return(UNARY); + /* AIS: CLC-INTERCAL uses \xBE, ISO-8859-1 for yen; + for some reason, \xA5 is what was detected by the compiler + during my tests, so that's here too */} +\? {if(clclex) yylval.numval = WHIRL; + else yylval.numval = XOR; return(UNARY); + /* AIS: ? is a unary operator in both C-INTERCAL and + CLC-INTERCAL, but with different meanings. */} +\| | +\^ {yylval.numval = FIN; return(UNARY); /* AIS: | is CLC */} +@ {if(clclex) return(NOSPOT); /* AIS: a C/CLC ambiguity */ + else {yylval.numval = WHIRL; return(UNARY);}} +[2-5]{W}@ {yylval.numval = WHIRL + myatoi(yytext) - 1; return(UNARY);} + +\' {char temp = sparkearsstack[sparkearslev/32]&1; + STACKSPARKEARS(0); /* AIS: I added all mentions of + STACKSPARKEARS, OPEN\(SPARK\|EARS\), + CLOSE\(SPARK\|EARS\), + and CLEARSPARKEARSTACK */ + return(temp?OPENSPARK:CLOSESPARK);} +\" {char temp = sparkearsstack[sparkearslev/32]&1; + STACKSPARKEARS(1); + return(temp?CLOSEEARS:OPENEARS);} + +\({W}{D}\) {SETLINENO; yylval.numval = myatoi(yytext); return(LABEL);} + +DO {SETLINENO; CLEARSPARKEARSTACK; return(DO);} +FAC {SETLINENO; CLEARSPARKEARSTACK; return(DO);} +PLEASE {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(DO);} +PLACET {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(DO);} +PLEASE{W}DO {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(DO);} +PLACET{W}FACERE {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(DO);} +MAYBE {SETLINENO; CLEARSPARKEARSTACK; return(MAYBE);} +MAYBE{W}DO {SETLINENO; CLEARSPARKEARSTACK; return(MAYBE);} +MAYBE{W}PLEASE {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(MAYBE);} +MAYBE{W}PLEASE{W}DO {SETLINENO; CLEARSPARKEARSTACK; politesse++; return(MAYBE); + /* AIS: I added all the MAYBE cases. It seems that MAYBE + has no simple Latin synonym. */} + +NOT {return(NOT);} +N\'T {return(NOT);} +NON {return(NOT);} +\xAA {return(NOT); /* AIS: CLC-INTERCAL again, this time it's + ISO-8859-1 for the logical NOT symbol... */} +\xAC {return(NOT); /* ... but my computer translates it to \xAC */} + +ONCE {return(ONCE);} +QUONDAM {return(ONCE);} +AGAIN {return(AGAIN);} +ITERUM {return(AGAIN);} + +\%{W}{D} {yylval.numval = myatoi(yytext); + if (yylval.numval && yylval.numval < 100) + return(OHOHSEVEN); + else + lose(E017, yylineno, (char *)NULL);} +SUB {return(SUB);} +MULTIPLICATUS{W}A | +BY {return(BY);} + +\<- {return(GETS);} +CALCULANDUM | +CALCULATING {yylval.numval = GETS; return(GERUND);} + +ALIENERE | +FORGET {return(FORGET);} +ALIENENDUM | +FORGETTING {yylval.numval = FORGET; return(GERUND);} +RECOLERE | +RESUME {return(RESUME);} +RECOLERENDUM | +RESUMING {yylval.numval = RESUME; return(GERUND);} +EXUERE | +STASH {return(STASH);} +EXUENDUM | +STASHING {yylval.numval = STASH; return(GERUND);} +INUERE | +RETRIEVE {return(RETRIEVE);} +INUENDUM | +RETRIEVING {yylval.numval = RETRIEVE; return(GERUND);} +DISSIMULARE | +IGNORE {return(IGNORE);} +DISSIMULANDUM | +IGNORING {yylval.numval = IGNORE; return(GERUND);} +MEMINISSE | +REMEMBER {return(REMEMBER);} +MEMINISSENDUM | +REMEMBERING {yylval.numval = REMEMBER; return(GERUND);} +ABSTINERE | +ABSTAIN {return(ABSTAIN);} +ABSTINENDUM | +ABSTAINING {yylval.numval = ABSTAIN; return(GERUND);} +REINSTARE | +REINSTATE {return(REINSTATE);} +REINSTATANDUM | +REINSTATING {yylval.numval = REINSTATE; return(GERUND);} +LEGERE{W}EX | +READ{W}OUT {return(READ_OUT);} +LEGENDUM | +READING{W}OUT {yylval.numval = READ_OUT; return(GERUND);} +SCRIBERE{W}IN | +WRITE{W}IN {return(WRITE_IN);} +SCRIBENDUM | +WRITING{W}IN {yylval.numval = WRITE_IN; return(GERUND);} +COMMEMERO | +COMMENT {yylval.numval = UNKNOWN; return(GERUND); + /* AIS: An idea stolen from CLC-INTERCAL. + The Latin means literally 'remind' or 'mention'. */} +PIN {/* By AIS. I can't find a Latin translation for this. */ + return(PIN);} +PINNING {/* By AIS */ yylval.numval = PIN; return(GERUND);} +DEINDERE{W}A{W}\({W}{D}\) | +NEXT{W}FROM{W}\({W}{D}\) {/* AIS */ yylval.numval = myatoi(yytext); + return(NEXTFROMLABEL);} +DEINDERE{W}A | +NEXT{W}FROM {/* AIS: 'next' is not a verb, so the Latin is invented */ + return(NEXTFROMEXPR);} +DEINDENDUM | +NEXTING{W}FROM {/* AIS */ yylval.numval = NEXTFROMLABEL; return(GERUND);} +ADVENIRE{W}DE{W}\({W}{D}\) | +COME{W}FROM{W}\({W}{D}\) {/* AIS */ yylval.numval = myatoi(yytext); + return(COME_FROM);} +ADVENIRE{W}DE | +COME{W}FROM {/* AIS */ return(COMPUCOME);} +ADVENENDUM | +COMING{W}FROM {yylval.numval = COME_FROM; return(GERUND);} +DEINDE | +NEXT {stbeginline = 0; return(NEXT);} +PROXIMANDUM | +NEXTING {yylval.numval = NEXT; return(GERUND);} +FROM | +A {return(FROM);} +CONCEDERE | +DESPERARE | +GIVE{W}UP {return(GIVE_UP);} +CONOR{W}ITERUM | +TRY{W}AGAIN {return(TRY_AGAIN);} +TRYING{W}AGAIN {yylval.numval = TRY_AGAIN; return(GERUND);} +GO{W}BACK | +REDIRE {return(GO_BACK);} +GOING{W}BACK | +REDENDUM {yylval.numval = GO_BACK; return(GERUND);} +GO{W}AHEAD | +GRASSOR {return(GO_AHEAD);} +GOING{W}AHEAD {yylval.numval = GO_AHEAD; return(GERUND); + /* AIS: I'm having a few deponent troubles with the Latin, so + there are no Latin gerunds around here. Besides, the Latin + 'gerunds' look somewhat like gerundives to me, but that's + purely based on memory so I may be wrong. */} + +\+ {return(INTERSECTION);} + +{W} ; +. {yylval.numval = yytext[0]; /* AIS: The line below for debug */ + if(yydebug) fprintf(stdout, "yylex: bad char %#x\n",(unsigned char)yytext[0]); + return(BADCHAR);} + + +%% + +int lexer(void) +{ + static int tok = BADCHAR; + + if (re_send_token) + re_send_token = FALSE; + else + { + tok = yylex(); +#ifdef YYDEBUG + if (yydebug) + (void) fprintf(stdout, "yylex: returning token %d\n", tok); +#endif /* YYDEBUG */ + } + +#ifdef YYDEBUG + if (yydebug) + (void) fprintf(stdout, "lexer: returning token %d\n", tok); +#endif /* YYDEBUG */ + return(tok); +} + +static int myatoi(char *text) /* AIS */ +{ +#define MAXTEXT 100 + static char buf[MAXTEXT]; + static char thinbuf[MAXTEXT]; + char* bp; + char* tp; + register int i; + + for(buf[i = 0] = '\0';*text && i < MAXTEXT;text++) { + if(isdigit(*text)) { + buf[i++] = *text; + } + } + buf[i] = '\0'; + bp=buf; tp=thinbuf; + while(((*tp++=*bp++))); /* thinbuf code added by an AIS + in case we want to work with wchar_t; + the extra brackets tell GCC that this is + intended and not a mistaken assignment */ + return atoi(thinbuf); +} + +void yyerror(char *errtype) +{ +#ifdef MAIN + (void) printf("lextest: lexer error: %s.\n", errtype); +#else /* MAIN */ + /* lose(E017, yylineno, (char *)NULL); */ + (void) errtype; +#endif /* MAIN */ +} + +#ifdef MAIN +int main(void) +{ + int t; + + while ((t = yylex()) > 0) + { + (void) printf("%03d %09d\n", t, yylval.numval); + yylval.numval = 0; + } + return 0; +} +#endif /* MAIN */ diff --git a/src/lose.c b/src/lose.c new file mode 100644 index 0000000..adf751d --- /dev/null +++ b/src/lose.c @@ -0,0 +1,71 @@ +/* + * + * NAME + * lose.c -- report INTERCAL compile- or run-time error + * +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/*LINTLIBRARY*/ +#include +#include +#include +#include "lose.h" + +int coreonerr = 0; /* AIS */ + +int checkforbugs; /* AIS */ + +void lose(char *m, int n, char *s) +{ + (void) fflush(stdout); /* AIS: To stop stdout getting muddled with stderr*/ + (void) fprintf(stderr, + "ICL%c%c%cI\t", + m[0], m[1], m[2]); + if (s) + (void) fprintf(stderr, m + 4, s, n); + else + (void) fprintf(stderr, m + 4, n); + (void) fprintf(stderr, " CORRECT SOURCE AND RESUBNIT\n"); + if(atoi(m)==778&&coreonerr) /* AIS */ + { + /* AIS: Dump core. */ + raise(SIGABRT); + } + exit(atoi(m)); +} + +/* AIS: This function reports potential bugs. It's paraphrased from lose. */ +void lwarn(char *m, int n, char *s) +{ + if(!checkforbugs) return; /* Don't report a potential bug without -l */ + (void) fflush(stdout); + (void) fprintf(stderr, + "ICL%c%c%cW\t", + m[0],m[1],m[2]); + if (s) + (void) fprintf(stderr, m + 4, s, n); + else if(m[0]!='2'||m[1]!='7'||m[2]!='8') + (void) fprintf(stderr, m + 4, n); + else + (void) fprintf(stderr, m + 4); + (void) fprintf(stderr, " RECONSIDER SOURCE AND RESUBNIT\n\n"); + /* Don't exit. This is not any error except one not causing immediate + termination of program execution. */ +} + +/* lose.c ends here */ diff --git a/src/lose.h b/src/lose.h new file mode 100644 index 0000000..c613054 --- /dev/null +++ b/src/lose.h @@ -0,0 +1,238 @@ +/* lose.h --- error message strings */ + +/* + * Note: these error message texts, with one exception, are direct from + * the Princeton compiler (INTERCAL-72) sources (transmitted by Don Woods). + * The one exception is E632, which in INTERCAL-72 had the error message + * PROGRAM ATTEMPTED TO EXIT WITHOUT ERROR MESSAGE + * ESR's "THE NEXT STACK HAS RUPTURED!..." has been retained on the grounds + * that it is more obscure and much funnier. For context, find a copy of + * Joe Haldeman's SF short story "A !Tangled Web", first published in + * Analog magazine in September 1981 and later anthologized in the author's + * "Infinite Dreams" (Ace 1985). + */ +/* An undecodable statement has been encountered in the course of execution. */ +#define E000 "000 %s\n\ + ON THE WAY TO %d\n" +/* An expression contains a syntax error. */ +#define E017 "017 DO YOU EXPECT ME TO FIGURE THIS OUT?\n\ + ON THE WAY TO %d\n" +/* Improper use has been made of statement identifiers. */ +#define E079 "079 PROGRAMMER IS INSUFFICIENTLY POLITE\n\ + ON THE WAY TO %d\n" +/* Improper use has been made of statement identifiers. */ +#define E099 "099 PROGRAMMER IS OVERLY POLITE\n\ + ON THE WAY TO %d\n" +/* Program has attempted 80 levels of NEXTing */ +#define E123 "123 PROGRAM HAS DISAPPEARED INTO THE BLACK LAGOON\n\ + ON THE WAY TO %d\n" +/* Program has attempted to transfer to a non-existent line label */ +#define E129 "129 PROGRAM HAS GOTTEN LOST\n\ + ON THE WAY TO WHO KNOWS WHERE\n" +/* An ABSTAIN or REINSTATE statement references a non-existent line label */ +#define E139 "139 I WASN'T PLANNING TO GO THERE ANYWAY\n\ + ON THE WAY TO %d\n" +/* A line label has been multiply defined. */ +#define E182 "182 YOU MUST LIKE THIS LABEL A LOT!\n\ + ON THE WAY TO %d\n" +/* An invalid line label has been encountered. */ +#define E197 "197 SO! 65535 LABELS AREN'T ENOUGH FOR YOU?\n\ + ON THE WAY TO %d\n" +/* An expression involves an unidentified variable. */ +#define E200 "200 NOTHING VENTURED, NOTHING GAINED\n\ + ON THE WAY TO %d\n" +/* An attempt has been made to give an array a dimension of zero. */ +#define E240 "240 ERROR HANDLER PRINTED SNIDE REMARK\n\ + ON THE WAY TO %d\n" +/* Invalid dimensioning information was supplied + * in defining or using an array. */ +#define E241 "241 VARIABLES MAY NOT BE STORED IN WEST HYPERSPACE\n\ + ON THE WAY TO %d\n" +/* A 32-bit value has been assigned to a 16-bit variable. */ +#define E275 "275 DON'T BYTE OFF MORE THAN YOU CAN CHEW\n\ + ON THE WAY TO %d\n" +/* A retrieval has been attempted for an unSTASHed value. */ +#define E436 "436 THROW STICK BEFORE RETRIEVING!\n\ + ON THE WAY TO %d\n" +/* A WRITE IN statement or interleave ($) operation + * has produced value requiring over 32 bits to represent. */ +#define E533 "533 YOU WANT MAYBE WE SHOULD IMPLEMENT 64-BIT VARIABLES?\n\ + ON THE WAY TO %d\n" +/* Insufficient data. (raised by reading past EOF) */ +#define E562 "562 I DO NOT COMPUTE\n\ + ON THE WAY TO %d\n" +/* Input data is invalid. */ +#define E579 "579 WHAT BASE AND/OR LANGUAGE INCLUDES %s?\n\ + ON THE WAY TO %d\n" +/* The expression of a RESUME statement evaluated to #0. */ +#define E621 "621 ERROR TYPE 621 ENCOUNTERED\n\ + ON THE WAY TO %d\n" +/* Program execution terminated via a RESUME statement instead of GIVE UP. */ +#define E632 "632 THE NEXT STACK RUPTURES. ALL DIE. OH, THE EMBARRASSMENT!\n\ + ON THE WAY TO %d\n" +/* Execution has passed beyond the last statement of the program. */ +#define E633 "633 PROGRAM FELL OFF THE EDGE\n\ + ON THE WAY TO THE NEW WORLD\n" +/* A compiler error has occurred (see section 8.1). */ +#define E774 "774 RANDOM COMPILER BUG\n\ + ON THE WAY TO %d\n" +/* An unexplainable compiler error has occurred (see J. Lyon or D. Woods). */ +#define E778 "778 UNEXPLAINED COMPILER BUG\n\ + ON THE WAY TO %d\n" + +/* + * These errors are unique to C-INTERCAL. + */ +/* You tried to use a C-INTERCAL extension with the `traditional' flag on */ +#define E111 "111 COMMUNIST PLOT DETECTED, COMPILER IS SUICIDING\n\ + ON THE WAY TO %d\n" +/* Cannot find the magically included system library */ +#define E127 "127 SAYING 'ABRACADABRA' WITHOUT A MAGIC WAND WON'T DO YOU ANY GOOD\n\ + ON THE WAY TO THE CLOSET\n" +/* Out of stash space */ +#define E222 "222 BUMMER, DUDE!\n\ + ON THE WAY TO %d\n" +/* (AIS) Can't reverse an expression in an assignment. This is the + same error number as in CLC-INTERCAL, but the message is different. */ +#define E277 "277 YOU CAN ONLY DISTORT THE LAWS OF MATHEMATICS SO FAR\n\ + ON THE WAY TO %d\n" +/* (AIS) The spark/ears nesting is too deep. */ +#define E281 "281 THAT MUCH QUOTATION AMOUNTS TO PLAGIARISM\n\ + ON THE WAY TO %d\n" +/* Too many variables. */ +#define E333 "333 YOU CAN'T HAVE EVERYTHING, WHERE WOULD YOU PUT IT?\n\ + ON THE WAY TO %d\n" +/* (AIS, from the suggestion by Malcom Ryan) + GO BACK or GO AHEAD was executed without a choicepoint. */ +#define E404 "404 I'M ALL OUT OF CHOICES!\n\ + ON THE WAY TO %d\n" +/* (AIS) MAYBE, GO BACK, or GO AHEAD used without the -m option. */ +#define E405 "405 PROGRAM REJECTED FOR MENTAL HEALTH REASONS\n\ + ON THE WAY TO %d\n" +/* A COME FROM statement references a non-existent line label. */ +#define E444 "444 IT CAME FROM BEYOND SPACE\n\ + ON THE WAY TO %d\n" +/* More than one COME FROM references the same label. */ +#define E555 "555 FLOW DIAGRAM IS EXCESSIVELY CONNECTED\n\ + ON THE WAY TO %d\n" +/* Too many source lines. */ +#define E666 "666 COMPILER HAS INDIGESTION\n\ + ON THE WAY TO %d\n" +/* No such source file. */ +#define E777 "777 A SOURCE IS A SOURCE, OF COURSE, OF COURSE\n\ + ON THE WAY TO %d\n" +/* Can't open C output file */ +#define E888 "888 I HAVE NO FILE AND I MUST SCREAM\n\ + ON THE WAY TO %d\n" +/* Can't open C skeleton file. */ +#define E999 "999 NO SKELETON IN MY CLOSET, WOE IS ME!\n\ + ON THE WAY TO %d\n" +/* Source file name with invalid extension (use .i or .[3-7]i). */ +#define E998 "998 EXCUSE ME,\n\ + YOU MUST HAVE ME CONFUSED WITH SOME OTHER COMPILER\n" +/* Illegal possession of a controlled unary operator. */ +#define E997 "997 ILLEGAL POSSESSION OF A CONTROLLED UNARY OPERATOR.\n\ + ON THE WAY TO %d\n" +/* (AIS) Command found after TRY AGAIN. */ +#define E993 "993 I GAVE UP LONG AGO\n\ + ON THE WAY TO %d\n" +/* (AIS) Memory allocation failure during multithreading */ +#define E991 "991 YOU HAVE TOO MUCH ROPE TO HANG YOURSELF\n\ + ON THE WAY TO %d\n" +/* (AIS) Unimplemented feature used. This should never come up, hopefully. */ +#define E995 "995 DO YOU REALLY EXPECT ME TO HAVE IMPLEMENTED THAT?\n\ + ON THE WAY TO %d\n" +/* + * AIS: These errors are specific to PIC-INTERCAL + */ +/* (AIS) Attempted to use an unsupported language feature. */ +#define E256 "256 THAT'S TOO HARD FOR MY TINY BRAIN\n\ + ON THE WAY TO %d\n" + +/* (AIS) Attempted to use a PIC feature in a non-PIC program. */ +#define E652 "652 HOW DARE YOU INSULT ME!\n\ + ON THE WAY TO %d\n" + +/* + * AIS: These errors are generated by the yuk debugger + */ +/* (AIS) fgets' buffer overflowed on debugger comand input. */ +#define E810 "810 ARE ONE-CHARACTER COMMANDS TOO SHORT FOR YOU?\n\ + ON THE WAY TO %d\n" + +/* (AIS) Too many breakpoints. */ +#define E811 "811 PROGRAM IS TOO BADLY BROKEN TO RUN\n\ + ON THE WAY TO %d\n" + +/* + * (AIS) Warnings produced by -l. + */ + +/* (AIS) Non-INTERCAL-72 identifier used. */ +#define W112 "112 THAT RELIES ON THE NEW WORLD ORDER\n\ + ON THE WAY TO %d\n" + +/* (AIS) That stupid idiom in syslib was used. */ +#define W128 "128 SYSLIB IS OPTIMIZED FOR OBFUSCATION\n\ + ON THE WAY TO %d\n" + +/* (AIS) Possibly nonportable unary operator. */ +#define W534 "534 KEEP LOOKING AT THE TOP BIT\n\ + ON THE WAY TO %d\n" + +/* (AIS) Expression still contains INTERCAL operators after + optimization. Only in binary, because this nearly always + happens in the higher bases. Syslib causes quite a lot of + these. This warning is fine on INTERCAL-like lines, but + flags a mistake on lines that are meant to be translations + of C. */ +#define W018 "018 THAT WAS MEANT TO BE A JOKE\n\ + ON THE WAY TO %d\n" + +/* (AIS) Possible misplaced unary operator. At the moment, ick -l cannot + detect this condition (so it never comes up). It's meant to detect + expressions like '?"?.1~#256"$#2'~#3 (from numio.i); in this expression, + the second what has no effect (it changes only the msb of the immediately + surrounding expression, which is eventually filtered out by the select + against #3). But detecting this would probably require code that could + check which bits of a result were going to be used elsewhere in an + expression, which is something I haven't written yet (but would make + a decent optimize_pass3). */ +#define W016 "016 DON'T TYPE THAT SO HASTILY\n\ + ON THE WAY TO %d\n" + +/* (AIS) Possibly overflowing assignment or mingle. Syslib causes some of + these too, in complicated situations where the bugcatcher can't figure + out what's happening, and also in a few blatant statements in the mould + of DO .3 <- :3, which are quite clearly possible overflows. Strangely + enough, there's a commented-out section of code in feh.c that suggests + that someone tried to make this an error (using a more general check + which would have caught more correct code involving GETS, but none + involving $). As a middle ground, I've made it an -l warning. */ +#define W276 "276 YOU CAN'T EXPECT ME TO CHECK BACK THAT FAR\n\ + ON THE WAY TO %d\n" + +/* (AIS) A line will inevitably cause an expression-reversal failure. */ +#define W278 "278 FROM A CONTRADICTION, ANYTHING FOLLOWS\n\ + ON THE WAY TO A HUGE DISASTER\n" + +/* (AIS) The two following warnings are both compile-time traps for + near-certain runtime errors. As such, they have similar numbers + and similar messages. In fact, they're a shameless ripoff of the + originals, but should serve as a reminder for anyone aware of the + original messages. */ +/* (AIS) Dimension given for an array will come out as #0. */ +#define W239 "239 WARNING HANDLER PRINTED SNIDE REMARK\n\ + ON THE WAY TO %d\n" + +/* (AIS) RESUME argument will come out as #0. */ +#define W622 "622 WARNING TYPE 622 ENCOUNTERED\n\ + ON THE WAY TO %d\n" + +extern int lineno; + +extern void lose(char *m, int n, char *s); + +extern void lwarn(char *m, int n, char *s); + +/* lose.h ends here */ diff --git a/src/numerals.c b/src/numerals.c new file mode 100644 index 0000000..d6c9584 --- /dev/null +++ b/src/numerals.c @@ -0,0 +1,163 @@ +/* + * numeral.c -- internationalization support for INTERCAL input. + * + * After release 0.5, I wrote: + * + * 2. (ESR) Input format internationalization -- allow WRITE IN input digits in + * major languages such as Nahuatl, Tagalog, Sanskrit, and Basque. + * + * The twisted loons in the alt.folklore.computers crowd loved this + * idea, and I actually got sent digit lists for Nahuatl, Tagalog, + * Sanskrit, and Basque -- also, Kwakiutl, Georgian, Ojibwe. Albanian, + * and Volap\"uk. I've left out Albanian (didn't want to keep track + * of the dipthong diacritical) and Ojibwe (no zero digit). So: + * Nahuatl, Tagalog, Sanskrit, Basque, Georgian, Kwakiutl, and + * Volap\"uk are now supported in addition to English. + * + * As of release 0.18, Volap\"uk digits can be entered in either traditional + * Tex format, Latin-1, or UTF-8. Latin is also now a supported language, + * to fulfill the requirement for Ancient Roman localization. + * +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +typedef struct +{ + char *name; + int value; +} +numeral; + +numeral numerals[] = +{ +/* English */ + { "OH", 0 }, + { "ZERO", 0 }, + { "ONE", 1 }, + { "TWO", 2 }, + { "THREE", 3 }, + { "FOUR", 4 }, + { "FIVE", 5 }, + { "SIX", 6 }, + { "SEVEN", 7 }, + { "EIGHT", 8 }, + { "NINE", 9 }, + { "NINER", 9 }, /* For all you junior birdmen */ +/* Sanskrit */ + { "SUTYA", 0 }, /* Retroflex s, pronounced halfway to sh */ + { "SHUTYA", 0 }, + { "EKA", 1 }, + { "DVI", 2 }, + { "TRI", 3 }, + { "CHATUR", 4 }, + { "PANCHAN", 5 }, + { "SHASH", 6 }, + { "SAPTAM", 7 }, + { "ASHTAN", 8 }, + { "NAVAN", 9 }, +/* Basque */ + { "ZEROA", 0 }, + { "BAT", 1 }, + { "BI", 2 }, + { "HIRO", 3 }, + { "LAU", 4 }, + { "BORTZ", 5 }, + { "SEI", 6 }, + { "ZAZPI", 7 }, + { "ZORTZI", 8 }, + { "BEDERATZI", 9 }, +/* Tagalog */ + { "WALA", 0 }, + { "ISA", 1 }, + { "DALAWA", 2 }, + { "TATLO", 3 }, + { "APAT", 4 }, + { "LIMA", 5 }, + { "ANIM", 6 }, + { "PITO", 7 }, + { "WALO", 8 }, + { "SIYAM", 9 }, +/* Classical Nahuatl */ + { "AHTLE", 0 }, /* Actually `nothing'; no separate zero word is known */ + { "CE", 1 }, + { "OME", 2 }, + { "IEI", 3 }, + { "NAUI", 4 }, + { "NACUILI", 5 }, + { "CHIQUACE", 6 }, + { "CHICOME", 7 }, + { "CHICUE", 8 }, + { "CHICUNAUI", 9 }, +/* Georgian */ + { "NULI", 0 }, + { "ERTI", 1 }, + { "ORI", 2 }, + { "SAMI", 3 }, + { "OTXI", 4 }, + { "XUTI", 5 }, + { "EKSVI", 6 }, + { "SHVIDI", 7 }, + { "RVA", 8 }, + { "CXRA", 9 }, +/* Kwakiutl (technically, Kwak'wala) */ + { "KE'YOS", 0 }, /* Actually `nothing'; no separate zero word is known */ + { "'NEM", 1 }, + { "MAL'H", 2 }, + { "YUDEXW", 3 }, + { "MU", 4 }, + { "SEK'A", 5 }, + { "Q'ETL'A", 6 }, + { "ETLEBU", 7 }, + { "MALHGWENALH", 8 }, + { "'NA'NE'MA", 9 }, +/* Volap\"uk */ + { "NOS", 0 }, + { "BAL", 1 }, + { "TEL", 2 }, + { "KIL", 3 }, + { "FOL", 4 }, + { "LUL", 5 }, + { "M\\\"AL", 6 }, + { "M\xC4L", 6 }, /* Latin-1 support */ + { "M\xA3\xA4L", 6 }, /* UTF-8 support */ + { "VEL", 7 }, + { "J\\\"OL", 8 }, + { "J\xD6L", 8 }, /* Latin-1 support */ + { "J\xA3\x96L", 8 }, /* UTF-8 support */ + { "Z\\\"UL", 9 }, + { "Z\xDCL", 9 }, /* Latin-1 support */ + { "Z\xA3\x9CL", 9 }, /* UTF-8 support */ +/* Latin localization */ + { "NIL", 0 }, + { "NIHIL", 0 }, + { "UNUS", 1 }, + { "UNA", 1 }, + { "UNUM", 1 }, + { "DUO", 2 }, + { "DUAE", 2 }, + { "TRES", 3 }, + { "QUATTUOR", 4 }, + { "QUATUOR", 4 }, + { "QUINQUE", 5 }, + { "SEX", 6 }, + { "SEPTEM", 7 }, + { "OCTO", 8 }, + { "NOVEM", 9 }, +}; + +/* numeral.c ends here */ diff --git a/src/parser.y b/src/parser.y new file mode 100644 index 0000000..97807d7 --- /dev/null +++ b/src/parser.y @@ -0,0 +1,531 @@ +/***************************************************************************** + +NAME + ick.y -- grammar for the INTERCAL language + +DESCRIPTION + This YACC grammar parses the INTERCAL language by designed by Don R. Woods +and James M. Lyon. There are several syntax extensions over the original +INTERCAL-72 language. + +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +*****************************************************************************/ + +%{ +#include +#include +#include "sizes.h" +#include "ick.h" +#include "feh.h" +#include "lose.h" + +extern int yyerror(char*); + +/* Intervene our first-stage lexer. */ +extern int lexer(void); +#define yylex() lexer() + +static node *rlist; /* pointer to current right-hand node list */ +/*static node *llist;*/ /* pointer to current left-hand node list */ +static node *np; /* variable for building node lists */ + +extern int stbeginline; /* line number of last seen preamble */ +static int thisline; /* line number of beginning of current statement */ + +extern int mark112; /* AIS: Mark the tuple for W112 when it's created. */ + +static tuple *splat(void); + +#define GETLINENO \ + {if (stbeginline < 0) thisline = -stbeginline; \ + else {thisline = stbeginline; stbeginline = 0;}} + +#define ACTION(x, nt, nn) \ + {x = newtuple(); x->type = nt; x->lineno = thisline; x->u.node = nn;} +#define TARGET(x, nt, nn) \ + {x = newtuple(); x->type = nt; x->lineno = thisline; x->u.target = nn;} +#define ACTARGET(x, nt, nn, nn2)\ + {x = newtuple(); x->type = nt; x->lineno = thisline;\ + x->u.node = nn; x->u.target = nn2;} +/* AIS : The macro above was added for ABSTAIN expr FROM. */ +#define NEWFANGLED mark112 = 1; /* AIS: Added the mention of mark112 */ \ + if (traditional) lose(E111,yylineno,(char*)NULL); else + +#define DESTACKSE1 sparkearsstack[sparkearslev--/32] >>= 1 +#define DESTACKSPARKEARS DESTACKSE1; DESTACKSE1 + +%} + +%start program + +%union +{ + int numval; /* a numeric value */ + tuple *tuple; /* a code tuple */ + node *node; /* an expression-tree node */ +} + +/* + * Don't change this statement token list gratuitously! + * Some code in feh2.c depends on GETS being the least + * statement type and on the order of the ones following. + * AIS: Note that although GETS is the lowest statement type (with index 0 + * in feh2.c), UNKNOWN (i.e. a line that causes error 000) is an even + * lower statement type, with index -1. perpet.c uses indexes 1 higher. + * AIS: Added FROM, MANYFROM, TRY_AGAIN, COMPUCOME, GERUCOME, and + * three NEXT FROM cases. + * AIS: COME_FROM now merged with the label following it, + * to distinguish it from COMPUCOME, in the lexer. This changes + * the parser somewhat. + */ +%token UNKNOWN /* AIS: This is so comments can be REINSTATED */ +%token GETS RESIZE NEXT GO_AHEAD GO_BACK FORGET RESUME STASH RETRIEVE IGNORE +%token REMEMBER ABSTAIN REINSTATE +%token DISABLE ENABLE MANYFROM GIVE_UP READ_OUT WRITE_IN /* AIS: */PIN +%token COME_FROM NEXTFROMLABEL +%token NEXTFROMEXPR NEXTFROMGERUND COMPUCOME GERUCOME TRY_AGAIN FROM + +/* AIS: ONCE and AGAIN added, for multithread support; also, NOSPOT added, + so that I can reserve _ for future use (it's nowhere in the grammar yet) */ +%token MAYBE DO PLEASE NOT ONCE AGAIN MESH NOSPOT ONESPOT TWOSPOT TAIL HYBRID +%token MINGLE SELECT /* AIS: SPARK EARS */ SUB BY BADCHAR +/* AIS: For operand overloading */ +%token SLAT BACKSLAT + +%token NUMBER UNARY OHOHSEVEN GERUND LABEL +%token INTERSECTION + +/* + * These are not tokens returned by the lexer, but they are used as + * tokens elsewhere. We define them here to insure that the values + * will not conflict with the other tokens. It is important that + * WHIRL through WHIRL5 be a continuous sequence. + */ +/* AIS: Added new tokens for optimizer output */ +%token SPLATTERED MESH32 +%token C_AND C_OR C_XOR C_NOT C_NNAND C_ISNONZERO C_LSHIFT C_LSHIFT2 +%token C_LSHIFT8 C_LSHIFTIN1 C_RSHIFT C_AND1ADD1 C_2SUBAND1 C_1PLUS C_2MINUS +%token C_XORGREATER C_RSHIFTBY C_NOTEQUAL C_A +/* The reverse unary operators have to be in the same order as the forward + unary operators. */ +%token AND OR XOR FIN WHIRL WHIRL2 WHIRL3 WHIRL4 WHIRL5 +%token REV_AND REV_OR REV_XOR REV_FIN +%token REV_WHIRL REV_WHIRL2 REV_WHIRL3 REV_WHIRL4 REV_WHIRL5 + +%type expr limexpr varlist variable constant lvalue inlist outlist +%type subscr byexpr scalar scalar2s array initem outitem sublist +%type unambig limunambig subscr1 sublist1 oparray osubscr osubscr1 +%type notanlvalue nlunambig lunambig +%type perform mtperform +%type please preftype + +%nonassoc OPENEARS OPENSPARK CLOSEEARS CLOSESPARK +%nonassoc HIGHPREC +%nonassoc UNARYPREC +%nonassoc LOWPREC +/* AIS: I reversed this precedence, to sort out the near-ambiguity. + UNARYPREC and LOWPREC are to give the C-INTERCAL meaning of a statement + precedence above its CLC-INTERCAL meaning. */ + +%% /* beginning of rules section */ + +/* A program description consists of a sequence of statements */ +program : /* EMPTY */ + | program command + ; + +/* + * Each command consists of an optional label, followed by a preamble, + * followed by an optional probability, followed by the statement body. + * Negative exechance values indicate initial abstentions, and will be + * made positive before code is emitted. + * AIS: An exechance above 100 indicates a MAYBE situation (e.g. 4545 + * means MAYBE DO %45 ...). This means %0 should be illegal. I modified + * all these to allow for MAYBE. + */ +command : please mtperform + {$2->label = 0; $2->exechance = $1 * 100;} + | please OHOHSEVEN mtperform + {$3->label = 0; $3->exechance = $1 * $2;} + | LABEL please mtperform + {checklabel($1); $3->label = $1; $3->exechance = $2 * 100;} + | LABEL please OHOHSEVEN mtperform + {checklabel($1); $4->label = $1; $4->exechance = $2 * $3;} + | error + {lose(E017, yylineno, (char *)NULL);} + ; +/* + * AIS: added for the ONCE/AGAIN qualifiers. It copies a pointer to the tuple, + * so command will set the values in the original tuple via the copy. + */ + +mtperform : perform + {$1->onceagainflag = onceagain_NORMAL; $$ = $1;} + | perform ONCE + {NEWFANGLED {$1->onceagainflag = onceagain_ONCE; $$ = $1;}} + | perform AGAIN + {NEWFANGLED {$1->onceagainflag = onceagain_AGAIN; $$ = $1;}} + +/* There are two (AIS: now four) forms of preamble returned by the lexer */ +please : DO {GETLINENO; $$ = 1;} + | DO NOT {GETLINENO; $$ = -1;} + | MAYBE {NEWFANGLED {GETLINENO; $$ = 101;}} + | MAYBE NOT {NEWFANGLED {GETLINENO; $$ = -101;}} + ; + +/* Here's how to parse statement bodies */ +perform : lvalue GETS expr {ACTION($$, GETS, cons(GETS,$1,$3));} + | array GETS byexpr {ACTION($$, RESIZE, cons(RESIZE,$1,$3));} + | notanlvalue GETS expr %prec LOWPREC + {/* AIS: This is for variableconstants, and an error otherwise.*/ + if(variableconstants) ACTION($$, GETS, cons(GETS,$1,$3)) + else {yyclearin; $$=splat();}} + | LABEL NEXT {TARGET($$, NEXT, $1);} + | FORGET expr {ACTION($$, FORGET, $2);} + | RESUME expr {ACTION($$, RESUME, $2);} + | STASH varlist {ACTION($$, STASH, rlist);} + | RETRIEVE varlist {ACTION($$, RETRIEVE, rlist);} + | IGNORE varlist {ACTION($$, IGNORE, rlist);} + | REMEMBER varlist {ACTION($$, REMEMBER, rlist);} + | ABSTAIN FROM LABEL {stbeginline=0; TARGET($$, ABSTAIN, $3);} + | ABSTAIN FROM gerunds {ACTION($$, DISABLE, rlist);} + | ABSTAIN expr FROM LABEL {/* AIS */ NEWFANGLED {stbeginline=0; ACTARGET($$, FROM, $2, $4);}} + | ABSTAIN expr FROM gerunds {/* AIS */ NEWFANGLED {$$ = newtuple(); $$->type = MANYFROM; $$->lineno = thisline; \ + {node* tempnode=newnode(); $$->u.node = tempnode; tempnode->lval=$2; tempnode->rval=rlist; tempnode->opcode=MANYFROM;}}} + | REINSTATE LABEL {stbeginline=0; TARGET($$, REINSTATE, $2);} + | REINSTATE gerunds {ACTION($$, ENABLE, rlist);} + | WRITE_IN inlist {ACTION($$, WRITE_IN, $2);} + | READ_OUT outlist {ACTION($$, READ_OUT, $2);} + | PIN scalar2s {ACTION($$, PIN, $2);} + | GIVE_UP {ACTION($$, GIVE_UP, 0);} + | GO_AHEAD {/* AIS */ NEWFANGLED {ACTION($$, GO_AHEAD, 0);}} + | GO_BACK {/* AIS */ NEWFANGLED {ACTION($$, GO_BACK, 0);}} + | TRY_AGAIN {/* AIS */ NEWFANGLED {ACTION($$,TRY_AGAIN,0);}} + | COME_FROM {/* AIS: Modified */ NEWFANGLED {TARGET($$,COME_FROM,$1);}} + | COMPUCOME gerunds {/* AIS: COME FROM gerund */ + NEWFANGLED{ACTION($$,GERUCOME,rlist); + compucomesused=1; gerucomesused=1;}} + | COMPUCOME expr {/* AIS */NEWFANGLED {ACTION($$,COMPUCOME,$2); + compucomesused=1;}} +/* AIS: NEXT FROM works along the same lines as COME FROM */ + | NEXTFROMLABEL {NEWFANGLED {TARGET($$,NEXTFROMLABEL,$1);} + nextfromsused=1;} + | NEXTFROMEXPR gerunds{NEWFANGLED{ACTION($$,NEXTFROMGERUND,rlist); + compucomesused=1; gerucomesused=1;} + nextfromsused=1;} + | NEXTFROMEXPR expr {NEWFANGLED {ACTION($$,NEXTFROMEXPR,$2); + compucomesused=1; nextfromsused=1;}} + + | BADCHAR {yyclearin; $$ = splat();} + | error {yyclearin; $$ = splat();} + ; + +/* gerund lists are used by ABSTAIN and REINSTATE */ +gerunds : GERUND + {rlist = np = newnode(); np->constant = $1;} + | gerunds INTERSECTION GERUND + { + np->rval = newnode(); + np = np->rval; + np->constant = $3; + } + ; + +/* OK, here's what a variable reference looks like */ +variable: scalar | array; + +lvalue : scalar | subscr; + +scalar2s: TWOSPOT NUMBER /* AIS: for TWOSPOTs only */ + { + $$ = newnode(); + $$->opcode = TWOSPOT; + $$->constant = intern(TWOSPOT, $2); + } +scalar : ONESPOT NUMBER + { + $$ = newnode(); + $$->opcode = ONESPOT; + $$->constant = intern(ONESPOT, $2); + } + | TWOSPOT NUMBER + { + $$ = newnode(); + $$->opcode = TWOSPOT; + $$->constant = intern(TWOSPOT, $2); + } + ; + +array : TAIL NUMBER + { + $$ = newnode(); + $$->opcode = TAIL; + $$->constant = intern(TAIL, $2); + } + | HYBRID NUMBER + { + $$ = newnode(); + $$->opcode = HYBRID; + $$->constant = intern(HYBRID, $2); + } + ; + +/* Array with unary operator is a special intermediate case; these + nodes will be rearranged when the subscript list is added */ +oparray : TAIL UNARY NUMBER %prec UNARYPREC + { + $$ = newnode(); + $$->opcode = $2; + $$->rval = newnode(); + $$->rval->opcode = TAIL; + $$->rval->constant = intern(TAIL, $3); + } + | HYBRID UNARY NUMBER %prec UNARYPREC + { + $$ = newnode(); + $$->opcode = $2; + $$->rval = newnode(); + $$->rval->opcode = HYBRID; + $$->rval->constant = intern(HYBRID, $3); + } + ; + +/* And a constant looks like this */ +constant: MESH NUMBER + { + /* enforce the 16-bit constant constraint */ + if ((unsigned int)$2 > Max_small) + lose(E017, yylineno, (char *)NULL); + $$ = newnode(); + $$->opcode = MESH; + if(variableconstants) /* AIS */ + $$->constant = intern(MESH, $2); + else + $$->constant = $2; + } + ; + +/* variable lists are used in STASH, RETRIEVE, IGNORE, REMEMBER */ +varlist : variable {rlist = np = $1;} + | varlist INTERSECTION variable {np = np->rval = $3; + /* newnode(); */ } + ; + +/* scalars and subscript exprs are permitted in WRITE IN lists */ +/* new: arrays are also permitted to allow for bitwise I/0 */ +initem : scalar | subscr | array; +inlist : initem INTERSECTION inlist {$$=cons(INTERSECTION,$1,$3);} + | initem {$$=cons(INTERSECTION,$1,0);} + ; + +/* scalars, subscript exprs & constants are permitted in READ OUT lists */ +/* new: arrays are also permitted to allow for bitwise I/0 */ +outitem : scalar | subscr | constant | array; +outlist : outitem INTERSECTION outlist {$$=cons(INTERSECTION,$1,$3);} + | outitem {$$=cons(INTERSECTION,$1,0);} + ; + +/* Now the gnarly part -- expression syntax */ + +/* Support array dimension assignment */ +byexpr : expr BY byexpr {$$ = cons(BY, $1, $3);} + | expr {$$ = cons(BY, $1, 0);} + ; + +/* Support array subscripts (as lvalues) */ +subscr : subscr1 {$$ = $1;} + | array SUB sublist {$$ = cons(SUB, $1, $3);} + ; +subscr1 : array SUB sublist1 {$$ = cons(SUB, $1, $3);} + ; +sublist : unambig sublist {$$ = cons(INTERSECTION, $1, $2);} + | unambig sublist1 {$$ = cons(INTERSECTION, $1, $2);} + ; +sublist1: subscr1 {$$ = cons(INTERSECTION, $1, 0);} + | osubscr1 {$$ = cons(INTERSECTION, $1, 0);} + | unambig %prec HIGHPREC {$$ = cons(INTERSECTION, $1, 0);} + ; + +/* Unary operators with arrays act like arrays only in expressions */ +osubscr : osubscr1 {$$ = $1;} + | oparray SUB sublist + {$$ = $1; $$->rval = cons(SUB, $$->rval, $3);} + ; +osubscr1: oparray SUB sublist1 + {$$ = $1; $$->rval = cons(SUB, $$->rval, $3);} + ; + +/* here goes the general expression syntax */ +expr : unambig {$$ = $1;} +/* AIS: CLC-INTERCAL allows right-association of SELECT and MINGLE. + (Strangely, that simplifies this section somewhat.) */ + | unambig SELECT expr {$$ = cons(SELECT, $1, $3);} + | unambig MINGLE expr {$$ = cons(MINGLE, $1, $3);} +/* AIS: Operand overloading */ + | scalar SLAT expr {NEWFANGLED{$$ = cons(SLAT, $1, $3); + opoverused=1; if(!firstslat) + firstslat=$$; else + prevslat->nextslat=$$; prevslat=$$; + $$->nextslat=0;}} + | subscr {$$ = $1;} + | osubscr {$$ = $1;} + ; + +/* AIS: Any expression that isn't an lvalue */ +notanlvalue:nlunambig {$$ = $1;} + | osubscr {$$ = $1;} + | unambig SELECT expr {$$ = cons(SELECT, $1, $3);} + | unambig MINGLE expr {$$ = cons(MINGLE, $1, $3);} + | scalar SLAT expr {NEWFANGLED{$$ = cons(SLAT, $1, $3); + opoverused=1; if(!firstslat) + firstslat=$$; else + prevslat->nextslat=$$; prevslat=$$; + $$->nextslat=0;}} + ; + +/* AIS: an expr that doesn't start with a unary operator */ +limexpr : limunambig {$$ = $1;} + | limunambig SELECT expr {$$ = cons(SELECT, $1, $3);} + | limunambig MINGLE expr {$$ = cons(MINGLE, $1, $3);} + | scalar SLAT expr {NEWFANGLED{$$ = cons(SLAT, $1, $3); + opoverused=1; if(!firstslat) + firstslat=$$; else + prevslat->nextslat=$$; prevslat=$$; + $$->nextslat=0;}} + | subscr {$$ = $1;} + | osubscr {$$ = $1;} + ; + + +preftype: MESH {$$=MESH; } | ONESPOT {$$=ONESPOT;} | TWOSPOT {$$=TWOSPOT;}; + +/* AIS: unambig split into limunambig (unambigs that don't start with a + unary operator), nlunambig (unambigs that aren't lvalues), + lunambig (both), and unambig (the general case) */ +lunambig: constant {$$ = $1;} + /* deal with the bizarre unary-op syntax */ + | preftype UNARY NUMBER %prec UNARYPREC + { + $$ = newnode(); + $$->opcode = $2; + $$->rval = newnode(); + $$->rval->opcode = $1; + if($1 == MESH) { + /* enforce the 16-bit constant constraint */ + if ((unsigned int)$3 > Max_small) + lose(E017, yylineno, (char *)NULL); + $$->rval->constant = intern(MESH, $3); + } + else { + $$->rval->constant = intern($1, $3); + } + } + + /* Now deal with the screwy unary-op interaction with grouping */ + /* AIS: Modified to allow for maintenance of the SPARK/EARS stack */ + | eitherspark UNARY expr CLOSESPARK %prec UNARYPREC + { + $$ = newnode(); + $$->opcode = $2; + $$->rval = $3; + DESTACKSPARKEARS; + } + | eitherears UNARY expr CLOSEEARS %prec UNARYPREC + { + $$ = newnode(); + $$->opcode = $2; + $$->rval = $3; + DESTACKSPARKEARS; + } +/* AIS: limexpr, a limited expression that isn't allowed to start with a + unary operator, is used here to avoid a reduce/reduce conflict. */ + | eitherspark limexpr CLOSESPARK {$$ = $2; DESTACKSPARKEARS;} + | eitherears limexpr CLOSEEARS {$$ = $2; DESTACKSPARKEARS;} + ; + +limunambig: lunambig {$$ = $1;} + | scalar {$$ = $1;} + ; + +nlunambig: lunambig {$$ = $1;} + | UNARY unambig %prec LOWPREC + {$$=newnode(); $$->opcode = $1; $$->rval = $2;} + ; + +/* AIS: A bit of CLC-INTERCAL compatibility here. + The syntax now allows any number of unary operators before, and one inside, + an expression. In ambiguous cases like '&VV#1~#5', the & applies to the + whole expression (one operator inside is allowed, and inside takes + precedence), but the Vs apply just to the #1, because only one operator + inside is allowed. */ +unambig : limunambig {$$ = $1;} + | UNARY unambig %prec LOWPREC + {$$=newnode(); $$->opcode = $1; $$->rval = $2;} + ; + +eitherspark : OPENSPARK ; + | CLOSESPARK ; + ; + +eitherears : OPENEARS ; + | CLOSEEARS ; + ; + +%% + +static tuple *splat(void) +/* try to recover from an invalid statement. */ +{ + tuple *sp; + int tok, i; + extern bool re_send_token; + + /* + * The idea + * here is to skip to the next DO, PLEASE or label, then unget that token. + * which we can do with a tricky flag on the lexer (re_send_token). + */ + + /* fprintf(stderr,"attempting to splat at line %d....\n",yylineno); */ + for(i = 0,re_send_token = FALSE;;i++) { + tok = lexer(); + if (!tok) + { + re_send_token = TRUE; + tok = ' '; /* scanner must not see a NUL */ + break; + } + else if (tok == DO || tok == PLEASE || tok == LABEL + /* AIS */ || tok == MAYBE) { + re_send_token = TRUE; + break; + } + } + /* + fprintf(stderr,"found %d on line %d after %d other tokens.\n", + tok,yylineno,i); + */ + + /* generate a placeholder tuple for the text line */ + TARGET(sp, SPLATTERED, 0); + + return(sp); +} + +/* ick.y ends here */ diff --git a/src/perpet.c b/src/perpet.c new file mode 100644 index 0000000..6adeebc --- /dev/null +++ b/src/perpet.c @@ -0,0 +1,1322 @@ +/**************************************************************************** + +NAME + perpet.c -- main routine for C-INTERCAL compiler. + +DESCRIPTION + This is where all the dirty work begins and ends. + +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +****************************************************************************/ +/*LINTLIBRARY */ +#include +#include +#include +#include +#include +#include +#include "ick.h" +#include "feh.h" +#include "parser.h" +#include "sizes.h" +#include "lose.h" + +#ifndef ICKINCLUDEDIR +#define ICKINCLUDEDIR "/usr/local/include" +#endif +#ifndef ICKLIBDIR +#define ICKLIBDIR "/usr/local/share" +#endif +#ifndef ICKBINDIR +#define ICKBINDIR "/usr/local/bin" +#endif +#ifndef CC +#define CC "gcc" +#endif + +#define ARGSTRING "bcdfghlmptuvyCFHOPUX@" + +#ifdef USE_YYRESTART +/* function supplied by lex */ +extern void yyrestart(FILE*); + +#endif /* USE_YYRESTART */ + +/* function created by yacc */ +extern int yyparse(void); + +int yydebug; + +/* compilation options */ +bool compile_only; /* just compile into C, don't run the linker */ +bool traditional; /* insist on strict INTERCAL-72 conformance */ +bool nocompilerbug; /* disable error E774 */ +int yukdebug; /* AIS: Use the yuk debugger. */ +int yukprofile; /* AIS: Use the yuk profiler. */ +extern int coreonerr; /* AIS: Dump core on E778. (defined in lose.c) */ +int multithread; /* AIS: Allow multithreading and backtracking. */ +int variableconstants; /* AIS: Allow anything on the left of an assignment. */ +int cdebug; /* AIS: Pass -g to our C compiler, and leave C code. */ +int optdebug; /* AIS: Debug the optimizer. Value is 0, 1, 2, or 3. */ +int flowoptimize; /* AIS: Do flow optimizations (in INTERCAL!). */ +int coopt; /* AIS: The constant-output optimization. This should + mean that INTERCAL will beat any other language at + many benchmark programs (!) */ +int printfopens; /* AIS: Print messages whenever attempting to open a + file */ +extern int checkforbugs;/* AIS: Try to find possible bugs in the source code */ +int pickcompile; /* AIS: Compile for PIC? */ +int clclex; /* AIS: 1 means use CLC-INTERCAL meanings for @, ? */ +int outtostdout; /* AIS: Output on stdout rather than the output file */ + +/* AIS: Autodetected compilation options */ +int compucomecount=0; /* Computed COME FROM count */ +int compucomesused=0; /* Are computed COME FROMs used? */ +int gerucomesused=0; /* Is COME FROM gerund used? */ +int nextfromsused=0; /* Is NEXT FROM used? */ +int opoverused=0; /* Is operand overloading used? */ +node* firstslat=0; /* The first slat expression in the program */ +node* prevslat=0; /* The last slat expression used so far */ + +static bool dooptimize; /* do optimizations? (controlled by -O) */ +static bool clockface; /* set up output to do IIII for IV */ + +#define SKELETON "ick-wrap.c" +#define PSKELETON "pickwrap.c" +#define SYSLIB "syslib" + +/* numeric base defaults, exported to other files */ + +#define DEFAULT_BASE 2 +#define DEFAULT_SMALL_DIGITS 16 +#define DEFAULT_LARGE_DIGITS 32 +#define DEFAULT_MAX_SMALL 0xffffL +#define DEFAULT_MAX_LARGE 0xffffffffL + +int Base; +int Small_digits; +int Large_digits; +unsigned int Max_small; +unsigned int Max_large; + +int lineno; /* after yyparse, this is the total number of statements */ + +/* currently supported numeric bases, not exported */ +static int maxbase = 7; +static int smallsizes[8] = {0, 0, 16, 10, 8, 6, 6, 5}; +static unsigned int maxsmalls[8] = + {0, 0, 65535, 59048, 65535, 15624, 46655, 16806}; + +static char *compiler; + +atom *oblist = NULL, *obdex; +int obcount = 0; +int nonespots, ntwospots, ntails, nhybrids; +int nmeshes; /* AIS */ + +tuple *tuples = NULL; +int tuplecount = 0; + +tuple *optuple = NULL; /* AIS: Tuple being optimized */ + +extern assoc varstores[]; /* AIS: Need to know this for PIC compilation */ + +static int myfgetc(FILE* in) +{ + char c; + fread(&c,1,1,in); + if(feof(in)) return EOF; + return (int)c; +} + +static FILE* debfopen(char* fname, char* mode) +{ + FILE* t; + if(printfopens) fprintf(stderr,"Trying to open '%s'...\n",fname); + t=fopen(fname,mode); + if(printfopens&&t) fprintf(stderr,"Success!\n"); + if(printfopens&&!t) fprintf(stderr,"Failed!\n"); + return t; +} + +static void abend(int signim) +{ + lose(E778, yylineno, (char *)NULL); + (void) signim; +} +static void print_usage(char *prog, char *options) +{ + fprintf(stderr,"Usage: %s [-%s] [ ... ]\n",prog,options); + fprintf(stderr,"\t-b\t:reduce the probability of E774 to zero\n"); + fprintf(stderr,"\t-c\t:compile INTERCAL to C, but don't compile C\n"); + fprintf(stderr,"\t-d\t:print yacc debugging information (implies -c)\n"); + fprintf(stderr,"\t-t\t:traditional mode, accept only INTERCAL-72\n"); + fprintf(stderr,"\t-C\t:clockface output (e.g. use IIII instead of IV)\n"); + fprintf(stderr,"\t-O\t:optimize expresssions in generated code\n"); + /* AIS: Changed the help message for the previous line (because the + function of -O has changed). I wrote the next group of options. */ + fprintf(stderr,"\t-f\t:optimize control flow in generated code " + "(prevents -yp)\n"); + fprintf(stderr,"\t-F\t:optimize everything in generated code for\n" + "\t\tspeed, regardless of how slow the compiler becomes or how\n" + "\t\tlarge the object file becomes. Implies -fO,\n" + "\t\tprevents -cdghpyH\n"); + fprintf(stderr,"\t-h\t:print optimizer debugging information " + "(implies -cO)\n"); + fprintf(stderr,"\t-H\t:print verbose optimizer debugging information " + "(implies -cO)\n"); + fprintf(stderr,"\t-hH\t:print optimizer debugging information in a\n" + "\t\tdifferent form (implies -cO)\n"); + fprintf(stderr,"\t-y\t:run the yuk debugger on the code (prevents -fm)\n"); + fprintf(stderr,"\t-p\t:run the yuk profiler on the code (prevents -fm)\n"); + fprintf(stderr,"\t-m\t:allow multithreading and backtracking " + "(prevents -yp)\n"); + fprintf(stderr,"\t-v\t:allow anything on the left of an assignment. This " + "is required\n\t\tif you want operand overloading. " + "(prevents -fFOP)\n"); + fprintf(stderr,"\t-P\t:compile PIC-INTERCAL rather than INTERCAL\n"); + fprintf(stderr,"\t-o\t:output to stdout rather than .c (implies -c)"); + fprintf(stderr,"\t-X\t:interpret ? and @ with CLC-INTERCAL meanings\n"); + fprintf(stderr,"\t-u\t:print a message whenever the compiler tries to " + "open a file\n"); + fprintf(stderr,"\t-U\t:dump core on E778 rather than printing an error\n"); + fprintf(stderr,"\t-g\t:compile to both debuggable executable and C\n"); + fprintf(stderr,"\t-l\t:attempt to report likely bugs " + "and nonportabilities (implies -O)\n"); + /* AIS: End of options I added. */ + fprintf(stderr,"\t\tINTERCAL source file(s) (use extension .i)\n"); + fprintf(stderr,"\t\teach file produces a separate output program.\n"); +} + +/* AIS: This function looks for the skeleton and syslib, searching first the + path they should be in, then the current directory, then argv[0]'s + directory (if one was given). This function avoids possible buffer + overflows, instead truncating filenames (and if that manages to find them, + I'll be incredibly surprised). It also tries argv[0]/../lib and + argv[0]/../include (where they are when running without installing). */ +static FILE* findandfopen(char* file, char* guessdir, char* mode, char* argv0) +{ + char buf2[BUFSIZ], *fileiter; + int i = 0, j; + FILE* ret; + while(*guessdir&&i maxbase) + lose(E998, 1, (char *)NULL); + else if (traditional && Base != 2) + lose(E111, 1, (char *)NULL); + else if (pickcompile && Base != 2) + lose(E256, 1, (char *)NULL); /* AIS */ + Small_digits = smallsizes[Base]; + Large_digits = 2 * Small_digits; + Max_small = maxsmalls[Base]; + if (Max_small == 0xffff) + Max_large = 0xffffffffLU; + else + Max_large = (Max_small + 1) * (Max_small + 1) - 1; + } + + /* zero out tuple and oblist storage */ + treset(); + politesse = 0; + + /* reset the lex/yacc environment */ + if (!firstfile) + { +#ifdef NEED_YYRESTART + yyrestart(stdin); +#endif /* NEED_YYRESTART */ +#ifdef YYLINENO_BY_HAND + yylineno = 1; +#endif /* YYLINENO_BY_HAND */ + } + + /* compile tuples from current input source */ + yyparse(); + + if(variableconstants) + { + /* AIS: Up to 4 extra meshes may be needed by feh.c. */ + intern(MESH, 0xFFFFFFFFLU); + intern(MESH, 0xFFFFLU); + intern(MESH, 0xAAAAAAAALU); + intern(MESH, 0x55555555LU); + } + + + /* + * Miss Manners lives. + */ + if (lineno > 2) + { + if (politesse == 0 || (lineno - 1) / politesse >= 5) + lose(E079, yylineno, (char *)NULL); + else if (lineno / politesse < 3) + lose(E099, yylineno, (char *)NULL); + } + + /* + * check if we need to magically include the system library + */ + needsyslib = FALSE; + if(!pickcompile) /* AIS: We never need syslib when compiling + for PIC, because it's preoptimized. */ + { + for (tp = tuples; tp->type; tp++) + { + /* + * If some label in the (1000)-(2000) range is defined, + * then clearly the syslib is already there, so we + * can stop searching and won't need the syslib. + */ + if (tp->label >= 1000 && tp->label <= 1999) { + needsyslib = FALSE; + break; + } + /* + * If some label in the (1000)-(2000) range is being + * called, we might need the system library. + */ + if (tp->type == NEXT && tp->u.target >= 1000 && + tp->u.target <= 1999) + needsyslib = TRUE; + } + } + if ( needsyslib ) { /* AIS: modified to use findandfreopen */ + if (Base == 2) /* see code for opening the skeleton */ + (void) sprintf(buf2, "%s.i", SYSLIB); + else + (void) sprintf(buf2, "%s.%di", SYSLIB, Base); + if (findandfreopen(buf2, libdir, "r", argv[0], stdin) == 0) + lose(E127, 1, (char*) NULL); +#ifdef USE_YYRESTART + yyrestart(stdin); +#endif /* USE_YYRESTART */ + yyparse(); + } + + /* + * Now propagate type information up the expression tree. + * We need to do this because the unary-logical operations + * are sensitive to the type widths of their operands, so + * we have to generate different code depending on the + * deducible type of the operand. + */ + for (tp = tuples; tp->type; tp++) + { + if (tp->type == GETS || tp->type == RESIZE + || tp->type == WRITE_IN || tp->type == READ_OUT + || tp->type == FROM || tp->type == MANYFROM + || tp->type == FORGET || tp->type == RESUME + || tp->type == COMPUCOME) + typecast(tp->type == MANYFROM ? tp->u.node->lval : tp->u.node); + if (tp->type == WRITE_IN) coopt = 0; /* AIS: may as well do + this here */ + } + + codecheck(); /* check for compile-time errors */ + /* AIS: And importantly, sort out line number references */ + + /* perform optimizations */ + if (dooptimize) + for (tp = tuples; tp->type; tp++) + { + optuple = tp; + if (tp->type == GETS || tp->type == RESIZE + || tp->type == FORGET || tp->type == RESUME + || tp->type == FROM || tp->type == COMPUCOME) + optimize(tp->u.node); + if (tp->type == MANYFROM) optimize(tp->u.node->lval); + } /* AIS: Added FROM and MANYFROM support. */ + + /* AIS: perform flow optimizations */ + if (flowoptimize) optimizef(); + + /* decide if and where to place the compiler bug */ +#ifdef USG + if (!nocompilerbug && lrand48() % 10 == 0) + bugline = (int)(lrand48() % lineno); +#else + if (!nocompilerbug && rand() % 10 == 0) + bugline = rand() % lineno; +#endif + else + bugline = -1; + + /* set up the generated C output file name */ + (void) strcpy(buf, argv[optind]); + (void) strcat(buf, ".c"); + if(outtostdout) ofp=stdout; /* AIS */ + else if((ofp = debfopen(buf, "w")) == (FILE *)NULL) + lose(E888, 1, (char *)NULL); + + fseek(ifp,0L,0); /* rewind skeleton file */ + + /* AIS: Before changing argv[0], locate coopt.sh. */ + cooptsh = findandtestopen("coopt.sh", bindir, "rb", argv[0]); + + /* AIS: Remove the filename from argv[0], leaving only a directory. + If this would leave it blank, change argv[0] to '.'. + This is so gcc can find the includes/libraries the same way that + findandfreopen does. */ + if(strchr(argv[0],'/')) *(strrchr(argv[0],'/')) = 0; + else strcpy(argv[0],"."); + + (void) sprintf(buf2, + "%s %s%s-I%s -I%s -I%s/../include -L%s -L%s -L%s/../lib -O%c -o %s" +#ifdef __DJGPP__ + ".exe -lick%s%s","", +#else + " -lick%s%s",compiler, +#endif + buf, yukdebug||yukprofile?" -lyuk ":" ", + includedir, argv[0], argv[0], libdir, argv[0], argv[0], + coopt?'3':'2', /* AIS: If coopting, optimize as much as possible */ + argv[optind], multithread?"mt":"", cdebug?" -g":""); + /* AIS: Possibly link in the debugger yuk and/or libickmt.a here. */ + /* AIS: Added -g support. */ + /* AIS: Added argv[0] to the -I, -L settings. */ + + while ((c = myfgetc(ifp)) != EOF) + if (c != '$') + (void) fputc(c, ofp); + else switch(myfgetc(ifp)) + { + case 'A': /* source name stem */ + (void) fputs(argv[optind], ofp); + break; + + case 'B': /* # of statements */ + (void) fprintf(ofp, "%d", lineno); + break; + + case 'C': /* initial abstentions */ + /* AIS: Modified to check for coopt, pickcompile */ + maxabstain = 0; + for (tp = tuples; tp->type; tp++) + if (((tp->exechance <= 0 || tp->exechance >= 101) + && tp - tuples + 1 > maxabstain) + || coopt || pickcompile) + maxabstain = tp - tuples + 1; + if (maxabstain) + { + if(!pickcompile) (void) fprintf(ofp, " = {"); + for (tp = tuples; tp < tuples + maxabstain; tp++) + { + if(tp->exechance != 100 && tp->exechance != -100) + { /* AIS: The double-oh-seven operator prevents + coopt working. However, syslib contains a + double-oh-seven. feh.c has checked that that + isn't referenced; if it isn't, we can allow + one double-oh-seven if syslib was + automagically inclulded. */ + if(needsyslib) needsyslib = 0; else coopt = 0; + } + if(!pickcompile) + { + if (tp->exechance > 0) + (void) fprintf(ofp, "0, "); + else { + (void) fprintf(ofp, "1, "); + tp->exechance = -tp->exechance; + /* AIS: If the line was abstained, we need to + swap ONCEs and AGAINs on it round, to suit + the code degenerator. */ + if(tp->onceagainflag == onceagain_ONCE) + tp->onceagainflag = onceagain_AGAIN; + else if(tp->onceagainflag == onceagain_AGAIN) + tp->onceagainflag = onceagain_ONCE; + } + if(tp->exechance >= 101) + { + /* AIS: This line has a MAYBE */ + tp->maybe = 1; + tp->exechance /= 100; + } + else tp->maybe = 0; + } + else /* AIS: hardcoded abstain bits for PICs */ + { + if(!tp->abstainable) continue; + if(tp->exechance > 0) + (void) fprintf(ofp, "ICK_INT1 ICKABSTAINED(%d)=0;\n",tp-tuples); + else + (void) fprintf(ofp, "ICK_INT1 ICKABSTAINED(%d)=1;\n",tp-tuples); + } + } + if(!pickcompile) (void) fprintf(ofp, "}"); + } + break; + + case 'D': /* linetypes array for abstention handling */ + maxabstain = 0; + for (tp = tuples; tp->type; tp++) + if (tp->type == ENABLE || tp->type == DISABLE || tp->type == MANYFROM) + maxabstain++; + if (maxabstain || /* AIS */ gerucomesused) + { + /* AIS: Changed to use enablersm1 */ + /*(void) fprintf(ofp, "#define UNKNOWN\t\t0\n");*/ + i = 0; + for (;i < (int)(sizeof(enablersm1)/sizeof(char *));i++) + (void) fprintf(ofp, + "#define %s\t%d\n", + enablersm1[i], i); + + (void) fprintf(ofp, "int linetype[] = {\n"); + for (tp = tuples; tp->type; tp++) + if (tp->type >= GETS && tp->type <= FROM) /* AIS: FROM added */ + (void) fprintf(ofp, + " %s,\n", + enablers[tp->type - GETS]); + else + (void) fprintf(ofp, " UNKNOWN,\n"); + (void) fprintf(ofp, "};\n"); + } + break; + + case 'E': /* extern to intern map */ + if(!pickcompile) + { + (void) fprintf(ofp,"int Base = %d;\n",Base); + (void) fprintf(ofp,"int Small_digits = %d;\n", + Small_digits); + (void) fprintf(ofp,"int Large_digits = %d;\n", + Large_digits); + (void) fprintf(ofp,"unsigned int Max_small = 0x%x;\n", + Max_small); + (void) fprintf(ofp,"unsigned int Max_large = 0x%x;\n", + Max_large); + if (yukprofile || yukdebug || multithread) + { /* AIS: yuk.c, multithreading require all these to exist */ + if(!nonespots) nonespots = 1; + if(!ntwospots) ntwospots = 1; + if(!ntails) ntails = 1; + if(!nhybrids) nhybrids = 1; + } + else if(opoverused) + { + /* AIS: The operand-overloading code requires onespot and + twospot variables to exist. */ + if(!nonespots) nonespots = 1; + if(!ntwospots) ntwospots = 1; + } + /* AIS:I de-staticed all these so they could be accessed by + yuk and cesspool, and added all the mentions of yuk and + multithread. Then I changed it so the variables would be + allocated dynamically, to speed up multithreading. (It's + an O(1) change to the speed of ordinary programs, so I + thought I could get away with it. The order is wrt the + number of lines in the program. The change is O(n) wrt + the number of variables, but again I hope that doesn't + matter, and I won't get the entire INTERCAL community + angry with me for daring to implement an extension that + slows down existing programs.) */ + if (variableconstants) /* AIS */ + { + int temp=0; + (void) fprintf(ofp, "type32 meshes[%d] = {",nmeshes); + while(temptype!=MESH) /* AIS: Added this check */ + (void) fprintf(ofp, " /* %s %d -> %d */\n", + nameof(op->type, vartypes), + op->extindex, + op->intindex); + if (yukdebug || yukprofile) + { /* AIS: drop intern to extern map into the program */ + (void) fprintf(ofp, "\nyukvar yukvars[]={\n"); + for (op = oblist; op < obdex; op++) + if(op->type!=MESH) /* AIS: Added this check */ + (void) fprintf(ofp," {%s,%d,%d},\n", + nameof(op->type, vartypes), + op->extindex, + op->intindex); + (void) fprintf(ofp," {YUKEND,0,0}};\n"); + } + } + else + { + /* Compiling for PIC */ + /* Arrays not supported on PICs */ + if(ntails || nhybrids) + lose(E256, yylineno, (char*) NULL); + /* and neither are variable constants */ + if(variableconstants) + lose(E256, yylineno, (char*) NULL); + for (op = oblist; op < obdex; op++) + { + (void) fprintf(ofp, " /* %s %d -> %d */\n", + nameof(op->type, vartypes), + op->extindex, + op->intindex); + (void) fprintf(ofp, "#define %s%d %s[%d]\n", + nameof(op->type, vartypes), + op->extindex, + nameof(op->type, varstores), + op->intindex); + if(op->ignorable) + (void) fprintf(ofp, "ICK_INT1 ignore%s%d = 0;\n", + nameof(op->type, varstores), + op->intindex); + } + (void) fprintf(ofp, "#include \"pick1.h\"\n"); + if(nonespots) + { + (void) fprintf(ofp, + "ICK_INT16 onespots[%d];\n" + "ICK_INT16 onespotsstash[%d];\n", + nonespots, + nonespots); + if(opoverused) /* AIS */ + { + int temp=nonespots; + (void) fprintf(ofp, + "overop oo_onespots[%d];\n", + nonespots); + while(temp--) + (void) fprintf(ofp, +"type32 og1spot%d(type32 t)\n{\n (void)t;\n return onespots[%d];\n}\n" +"void os1spot%d(type32 val,void(*f)())\n{\n (void)f;\n if(!ignoreonespots%d)" +" onespots[%d]=val;\n}\n",temp,temp,temp,temp,temp); + } + } + if(ntwospots) + { + (void) fprintf(ofp, + "ICK_INT32 twospots[%d];\n" + "ICK_INT32 twospotsstash[%d];\n", + ntwospots, + ntwospots); + if(opoverused) /* AIS */ + { + int temp=ntwospots; + (void) fprintf(ofp, + "overop oo_twospots[%d];\n", + ntwospots); + while(temp--) + (void) fprintf(ofp, +"type32 og2spot%d(type32 t)\n{\n (void)t;\n return twospots[%d];\n}\n" +"void os2spot%d(type32 val,void(*f)())\n{\n (void)f;\n if(!ignoretwospots%d)" +" twospots[%d]=val;\n}\n",temp,temp,temp,temp,temp); + } + } + (void) fprintf(ofp, "#include \"pick2.h\"\n"); + } + break; + + case 'F': /* set clockface option? */ + if (clockface) + (void) fprintf(ofp, "clockface(TRUE);"); + break; + + case 'G': /* degenerated code */ + for (tp = tuples, i = 0; tp->type; tp++, i++) + { + emit(tp, ofp); + if (i == bugline) + (void) fprintf(ofp, " lose(E774, lineno, " + "(char *)NULL);\n"); + } + break; + + case 'H': /* COMPUCOME, and dispatching for resumes */ + /* AIS: Added COMPUCOME here. This line must be fully guarded + to prevent a longjmp to an uninitialised buffer (it's + guarded by a lose() in ick-wrap.c.) Also checks for + multithread; programs that mix normal and computed COME + FROM need to use the same conventions for both, so even + if no computed COME FROMs are used, the normal ones need + this line so that COME FROMs can be handled consistently.*/ + if(compucomesused || multithread) + { + (void) fprintf(ofp, "CCF%d: longjmp(cjb,1);\n", + compucomecount); + } +#if 0 + /* AIS: This section is no longer used, because a switch + is used inline instead of using gotos into the code. */ + nextcount = 0; + for (tp = tuples; tp->type; tp++) + if (tp->type == NEXT) + nextcount++; + if (nextcount) + { + (void) fputs("/* generated switch for resumes */",ofp); + (void) fputs("top:\n switch(skipto)\n {\n", ofp); + for (tp = tuples; tp->type; tp++) + if (tp->type == NEXT) + (void) fprintf(ofp, + "\tcase %d: goto N%d; break;\n", + (int)(tp-tuples+1), (int)(tp-tuples+1)); + (void) fprintf(ofp, " }"); + } +#endif + break; + + case 'J': /* # of source file lines */ + (void) fprintf(ofp, "%d", yylineno); + break; + + case 'K': /* AIS: yuk information (or not) */ + if(yukdebug||yukprofile) + { + (void) fprintf(ofp, "#include \"yuk.h\"\n\n"); + (void) fprintf(ofp, "char* textlines[] = {\n"); + emittextlines(ofp); /* from feh.c */ + (void) fprintf(ofp, "\"\"};\n\n"); + (void) fprintf(ofp, "char* yukexplain[] = {\n"); + for (tp = tuples; tp->type; tp++) + { + if (tp->type == GETS || tp->type == FORGET || tp->type == RESUME + || tp->type == FROM || tp->type == COMPUCOME + || tp->type == MANYFROM) + { + (void) fprintf(ofp, "\""); + explexpr(tp->type == MANYFROM ? tp->u.node->lval : + tp->type == GETS ? tp->u.node->rval : tp->u.node, ofp); + (void) fprintf(ofp, "\",\n"); + } + else (void) fprintf(ofp, "0,"); + } + (void) fprintf(ofp, "0};\n\n"); + (void) fprintf(ofp, "int lineofaboff[] = {\n"); + for (tp = tuples; tp->type; tp++) + { + fprintf(ofp,"%d,",tp->lineno); + } + (void) fprintf(ofp, "-1};\n\n"); + (void) fprintf(ofp, "int yukopts = %d;\n", yukprofile+yukdebug*2); + (void) fprintf(ofp, "yptimer ypexectime[%d];\n", lineno); + (void) fprintf(ofp, "ypcounter ypexecount[%d];\n",lineno); + (void) fprintf(ofp, "ypcounter ypabscount[%d];\n",lineno); + } + break; + + case 'L': /* AIS: increase Emacs compatibility */ + (void) fprintf(ofp, + "/* -*- mode:c; compile-command:\"%s%s%s\" -*- */", +#ifdef __DJGPP__ + compiler," ", +#else + "","", +#endif + buf2); + break; + + case 'M': /* AIS: place new features defines in program */ + /* This is needed even in a non-multithread program, to let + the header files know it's non-multithread */ + (void) fprintf(ofp, "#define MULTITHREAD %d\n", multithread); + /* Likewise, to let the header files know whether it + overloads operands (I don't think this is used at + the moment, though) */ + (void) fprintf(ofp, "#define OPOVERUSED %d\n",opoverused); + break; + + case 'N': /* allocate variables */ + /* AIS:I de-staticed all these so they could be accessed by + yuk and cesspool, and added all the mentions of yuk and + multithread. Then I changed it so the variables would be + allocated dynamically, to speed up multithreading (it's + an O(1) change to the speed of ordinary programs, so I + thought I could get away with it). At this point, the + 'E' case must already have been done. calloc sets all + the integer values to 0, as before. In the case of + arrays, it will not zero pointers, but the number-of- + dimensions value will become 0, which can serve as a + 'deallocated' flag. */ + if (nonespots) + { + if(!pickcompile) /* AIS */ + { + (void) fprintf(ofp, + " onespots = calloc(" + "%d, sizeof *onespots);\n", + nonespots); + (void) fprintf(ofp, + " oneforget = calloc(" + "%d, sizeof *oneforget);\n", + nonespots); + } + if(opoverused) + { + int temp=nonespots; + while(temp--) + (void) fprintf(ofp, +" oo_onespots[%d].get=og1spot%d;\n oo_onespots[%d].set=os1spot%d;\n", + temp,temp,temp,temp); + } + } + if (ntwospots) + { + if(!pickcompile) + { + (void) fprintf(ofp, + " twospots = calloc(" + "%d, sizeof *twospots);\n", + ntwospots); + (void) fprintf(ofp, + " twoforget = calloc(" + "%d, sizeof *twoforget);\n", + ntwospots); + } + if(opoverused) + { + int temp=ntwospots; + while(temp--) + (void) fprintf(ofp, +" oo_twospots[%d].get=og2spot%d;\n oo_twospots[%d].set=os2spot%d;\n", + temp,temp,temp,temp); + } + } + if (ntails&&!pickcompile) + { + (void) fprintf(ofp, + " tails = calloc(" + "%d, sizeof *tails);\n", + ntails); + (void) fprintf(ofp, + " tailforget = calloc(" + "%d, sizeof *tailforget);\n", + ntails); + } + if (nhybrids&&!pickcompile) + { + (void) fprintf(ofp, + " hybrids = calloc(" + "%d, sizeof *hybrids);\n", + nhybrids); + (void) fprintf(ofp, + " hyforget = calloc(" + "%d, sizeof *hyforget);\n", + nhybrids); + } + break; + case 'O': /* AIS; for GERUCOME and operand overloading */ + if(gerucomesused || nextfromsused) + fprintf(ofp,"unsigned truelineno = 0;\n"); + if(opoverused) + fprintf(ofp,"%s trueval;\n", + pickcompile?"ICK_INT32":"type32"); + break; + case 'P': /* AIS: for operand overloading */ + if(opoverused) + emitslatproto(ofp); + break; + case 'Q': /* AIS: for operand overloading */ + if(opoverused) + emitslat(ofp); + break; + } + + if(!outtostdout) (void) fclose(ofp); + +#ifndef __DJGPP__ + /* OK, now sic the C compiler on the results */ + if (!compile_only&&!yukdebug&&!yukprofile) + { + /* AIS: buf2 now assigned elsewhere so $L works */ + (void) system(buf2); + /* AIS: no unlink if cdebug */ if(!cdebug) (void) unlink(buf); + } + else if(!compile_only) + { /* AIS: run, then delete all output but yuk.out */ + /* Note that the output must be deleted for copyright + reasons (so as not to GPL a non-GPL file automatically) */ + (void) system(buf2); + (void) freopen("/dev/tty", "r", stdin); + /* stdin has got seriously muddled, what with + it being redirected so much. Let's set it + to the keyboard (the only reasonable place + for input to a debugger anyway). If the user + wants to use the profiler with data from a file, + this won't work, so this code probably needs + changing. But the original value of stdin seems + to have been lost, and we need to redirect from + somewhere. */ + (void) system(argv[optind]); + (void) unlink(buf); + (void) unlink(argv[optind]); + } + if(coopt) /* AIS */ + { + /* The constant-output optimizer is a form of post-processor. + IMPORTANT NOTE: This MUST NOT be run if the input program + takes any input or is affected in any way by the state of + the system, as the degenerated program may be wrong. At the + moment, the only INTERCAL command that takes input is + WRITE IN. Double-oh-sevens screw this up, too. */ + if(cooptsh) + { + sprintf(buf2,"sh %s %s", cooptsh, argv[optind]); + (void) system(buf2); /* replaces the output executable if + neccesary */ + } + } +#else /* we are using DJGPP */ + /* OK, now sic the C compiler on the results */ + if (!compile_only) + { + /* AIS: buf2 now assigned elsewhere so $L works */ + /* AIS: This changes somewhat for DJGPP, due to the + command-line cap. It creates a temporary file + with the arguments needed to give gcc. */ + FILE* rsp; + rsp=debfopen("ickgcc.rsp","w"); + fprintf(rsp,"%s\n",buf2); + fclose(rsp); + if(yukdebug || yukprofile) + { + /* Running the program from the batch file ickyuk.bat will + handle the input redirection and deletion of the files + afterwards. */ + rsp=debfopen("ickyuk.bat","w"); + fprintf(rsp,"%s.exe\ndel %s\ndel %s.exe\n", + argv[optind],buf,argv[optind]); + fclose(rsp); + } + else if(!cdebug) + { + /* delete from the batch file after compilation */ + rsp=debfopen("ickyuk.bat","w"); + fprintf(rsp,"del %s\n",buf); + fclose(rsp); + } + } +#endif + } + } + (void) fclose(ifp); + return 0; +} + +/* perpet.c ends here */ + diff --git a/src/pick1.h b/src/pick1.h new file mode 100644 index 0000000..31ded99 --- /dev/null +++ b/src/pick1.h @@ -0,0 +1,84 @@ +/* + * pick1.h - Compiler-dependent defines for PIC compilers + * + * This file allows porting of PIC-INTERCAL output files to different + * compilers. Most compilers will require this file to be modified; + * as written at the moment, it's ANSI C that invokes undefined + * behaviour (in a way that might plausibly produce correct + * results). + * +LICENSE TERMS + Copyright (C) 2006 Alex Smith + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Place any headers, config fuse selection statements, and device + statements your compiler needs here. */ +#include + +/* Define these constants to unsigned data types of the correct + bit width. (If your compiler doesn't use 1 bit variables, you + could substitute an 8 bit variable, but that would take up + extra RAM, which may or may not drive the program over the PIC's + RAM limit.) */ +#define ICK_INT32 uint32_t +#define ICK_INT16 uint16_t +#define ICK_INT8 uint8_t +#define ICK_INT1 uint1_t + +/* Define this to an error-handling procedure. You should ignore the + arguments, as they won't make too much sense in this context. + This should block the program; the SLEEP command is one possibility, + somehow getting the PIC to disconnect its own power supply and signal + an error is another. */ +#define lose(a,b,c) for(;;) + +/* PORTA, PORTB, TRISA, and TRISB must be variables which, when read or + modified, read or modify the corresponding location in the PIC's RAM; + these are often at locations 0x05, 0x06, 0x85, and 0x86 respectively. + Place the code to do this here, if it isn't added by the header files + above. See the section below if your compiler doesn't recognize the + volatile keyword, but this code is otherwise correct. */ +#define PORTA *(volatile ICK_INT8*)0x05 +#define PORTB *(volatile ICK_INT8*)0x06 +#define TRISA *(volatile ICK_INT8*)0x85 +#define TRISB *(volatile ICK_INT8*)0x86 + +/* Volatility is important; some compilers don't notice this. */ +#define seq(a) a +/* You may need to use the commented-out code instead if your compiler + is confused about volatile. + ICK_INT8 seq(ICK_INT8 n) + { + return n; + } +*/ + +void pickinit() +{ + /* Place any initialization code that is needed here. */ +} + +/* If your implementation doesn't use function pointers, delete this and + don't write any code that uses operator-overloading. */ +typedef struct overop_t +{ + ICK_INT32 (*get)(ICK_INT32); + void (*set)(ICK_INT32); +} overop; + +#define type16 ICK_INT16 +#define type32 ICK_INT32 diff --git a/src/pick2.h b/src/pick2.h new file mode 100644 index 0000000..a8c0066 --- /dev/null +++ b/src/pick2.h @@ -0,0 +1,235 @@ +/* + * pick2.h - Runtime library for INTERCAL, for use by PIC C compilers + * + * Some of the code here was originally in fiddle.c, some was originally + * in cesspool.c. The rest is a translation into C of syslib.i. + * +LICENSE TERMS + Copyright (C) 1996 Eric S. Raymond + Copyright (C) 2006 Alex Smith + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define resume popnext + +ICK_INT32 mingle(ICK_INT16 r, ICK_INT16 s) +{ + r = ((r & 0x0000ff00) << 8) | (r & 0x000000ff); + r = ((r & 0x00f000f0) << 4) | (r & 0x000f000f); + r = ((r & 0x0c0c0c0c) << 2) | (r & 0x03030303); + r = ((r & 0x22222222) << 1) | (r & 0x11111111); + s = ((s & 0x0000ff00) << 8) | (s & 0x000000ff); + s = ((s & 0x00f000f0) << 4) | (s & 0x000f000f); + s = ((s & 0x0c0c0c0c) << 2) | (s & 0x03030303); + s = ((s & 0x22222222) << 1) | (s & 0x11111111); + return (r << 1) | s; +} + +ICK_INT32 iselect(ICK_INT32 r, ICK_INT32 s) +{ + ICK_INT32 i = 1, t = 0; + while (s) { + if (s & i) { + t |= r & i; + s ^= i; + i <<= 1; + } + else { + s >>= 1; + r >>= 1; + } + } + return t; +} + +ICK_INT16 and16(ICK_INT16 n) +{ + ICK_INT16 m; + m = (n >> 1); + if (n & 1) + m |= 0x8000; + return(m & n); +} + +ICK_INT16 or16(ICK_INT16 n) +{ + ICK_INT16 m; + m = (n >> 1); + if (n & 1) + m |= 0x8000; + return(m | n); +} + +ICK_INT32 and32(ICK_INT32 n) +{ + ICK_INT32 m; + m = (n >> 1); + if (n & 1) + m |= 0x80000000; + return(m & n); +} + +ICK_INT32 or32(ICK_INT32 n) +{ + ICK_INT32 m; + m = (n >> 1); + if (n & 1) + m |= 0x80000000; + return(m | n); +} + +ICK_INT16 xor16(ICK_INT16 n) +{ + ICK_INT16 m; + m = (n >> 1); + if (n & 1) + m |= 0x8000; + return(m ^ n); +} + +ICK_INT32 xor32(ICK_INT32 n) +{ + ICK_INT32 m; + m = (n >> 1); + if (n & 1) + m |= 0x80000000; + return(m ^ n); +} + +ICK_INT8 nextindex = 0; +ICK_INT16 next[16]; + +void pushnext(ICK_INT16 n) +{ + next[nextindex++] = n; +} + +ICK_INT16 popnext(ICK_INT8 n) +{ + if (nextindex < n) { + nextindex = 0; + return (ICK_INT16)-1; + } + else + nextindex -= n; + return(next[nextindex]); +} + +/* It's hard to do randomization on a PIC. */ +ICK_INT1 roll(ICK_INT8 n) +{ + return n>50; +} + +/* Volatility is important; some compilers don't notice this. */ +#define seq(a) a +/* You may need to use the commented-out code instead if your compiler + is confused about volatile. + ICK_INT8 seq(ICK_INT8 n) + { + return n; + } +*/ + +/* Syslib, implemented in C to save ROM space. */ +#if defined(ONESPOT1)&&defined(ONESPOT2)&&defined(TWOSPOT1) +void syslibopt1050() +{ + ONESPOT2=0; + if(ONESPOT1) ONESPOT2=TWOSPOT1/ONESPOT1; +} +void syslibopt1520() +{ + TWOSPOT1=((ICK_INT32)ONESPOT1<<16)|ONESPOT2; +} +#endif /* .1 .2 :1 */ +#if defined(TWOSPOT1)&&defined(TWOSPOT2)&&defined(TWOSPOT3) +void syslibopt1550() +{ + TWOSPOT3=0; + if(TWOSPOT2) TWOSPOT3=TWOSPOT1/TWOSPOT2; +} +void syslipopt1500() +{ + TWOSPOT3=TWOSPOT2+TWOSPOT1; +} +void syslibopt1510() +{ + TWOSPOT3=TWOSPOT1-TWOSPOT2; +} +void syslibopt1530() +{ + TWOSPOT3=TWOSPOT1*TWOSPOT2; +} +void syslibopt1540() +{ + TWOSPOT3=0; + if(TWOSPOT2) TWOSPOT3=TWOSPOT1/TWOSPOT2; +} +#ifdef TWOSPOT4 +void syslibopt1509() +{ + TWOSPOT3=TWOSPOT2+TWOSPOT1; + TWOSPOT4=1; + if(TWOSPOT30xffffffff/TWOSPOT2) TWOSPOT4=2; + TWOSPOT3=TWOSPOT1*TWOSPOT2; +} +#endif /* :4 */ +#endif /* :1 :2 :3 */ +#if defined(ONESPOT1)&&defined(ONESPOT2)&&defined(ONESPOT3) +void syslipopt1000() +{ + ONESPOT3=ONESPOT2+ONESPOT1; +} +void syslibopt1010() +{ + ONESPOT3=ONESPOT1-ONESPOT2; +} +void syslibopt1030() +{ + ONESPOT3=ONESPOT1*ONESPOT2; +} +void syslibopt1040() +{ + ONESPOT3=0; + if(ONESPOT2) ONESPOT3=ONESPOT1/ONESPOT2; +} +#ifdef ONESPOT4 +void syslibopt1009() +{ + ONESPOT3=ONESPOT2+ONESPOT1; + ONESPOT4=1; + if(ONESPOT30xffff/ONESPOT2) ONESPOT4=2; + ONESPOT3=ONESPOT1*ONESPOT2; +} +#endif /* .4 */ +#endif /* .1 .2 .3 */ +#ifdef ONESPOT1 +void syslibopt1020() +{ + ONESPOT1++; +} +#endif diff --git a/src/pickwrap.c b/src/pickwrap.c new file mode 100644 index 0000000..9351a45 --- /dev/null +++ b/src/pickwrap.c @@ -0,0 +1,46 @@ +$L +/* $A.c -- generated PIC C-code file for INTERCAL program $A.i */ + +/* This code is explicitly *not* GPLed. Use, abuse, and redistribute freely */ + +$M +$E + +$K + +#define ICKABSTAINED(d) abstain##d +#define ICKSTASH(a,b,c,d) c##stash[b]=c[b] +#define ICKRETRIEVE(a,b,c,d,e) a[b]=a##stash[b] +#define ICKIGNORE(a,b,c) ignore##c##b + +ICK_INT16 skipto=0; +$O + +$C + +$D +$P +int main(void) +{ + pickinit(); + /* degenerated code */ + ick_restart: + top: + switch(skipto) + { + case 0: + $G + } + +#ifdef YUK + if(yukloop) goto ick_restart; +#endif + lose(E633, $J, (char *)0); + + $H + + return 0; +} +$Q + +/* Generated code for $A.i ends here */ diff --git a/src/sizes.h b/src/sizes.h new file mode 100644 index 0000000..a344bc7 --- /dev/null +++ b/src/sizes.h @@ -0,0 +1,9 @@ +/* sizes.h -- constants defining the numeric base for INTERCAL variations */ + +extern int Base; +extern int Small_digits; +extern int Large_digits; +extern unsigned int Max_small; +extern unsigned int Max_large; + +/* sizes.h ends here */ diff --git a/src/unravel.c b/src/unravel.c new file mode 100644 index 0000000..aab5988 --- /dev/null +++ b/src/unravel.c @@ -0,0 +1,645 @@ +/***************************************************************************** + +NAME + unravel.c -- multithreading and backtracking support for C-INTERCAL + +LICENSE TERMS + Copyright (C) 2006 Alex Smith + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +***************************************************************************/ + +/* Notes about authorship. This entire file was written by Alex Smith (AIS), + but with reference to an earlier implementation of Threaded INTERCAL written + by Malcom Ryan. I have not reused any of his C code (two of his INTERCAL + programs are in the pit), but it was a useful source of inspiration, even + though I did it a completely different and less efficient way (I think we + handled mutiple COME FROM recognition in much the same way). This file only + contains functions necessary for multithreading; some of the code is stored + in feh.c (stored in strings), or in perpetrate.c (again stored in strings). + The information about the required syntax is in ick.y and lexer.l. + A small amount of the multithread code is in ick-wrap.c, although as that + file is copied almost verbatim (although it's quite a big 'almost') into + all ick output, it's guarded there by #if...#endif. The whole multithread + idea started on alt.lang.intercal when it was noticed that multiple COME + FROMs aiming at the same line were hard to interpret, but I would like + to thank Malcom Ryan for drafting the Threaded Intercal standard and a + reference compiler, and for turning the idea into a concrete set of rules. + (The standard itself carries a note saying that a revision (use of AGAIN) + was inspired by Kyle Dean, so I'd like to mention that here too, and I also + revised it (so that ABSTAIN/REINSTATE were preserved through backtracking).) + In terms of the quality of the code, Malcom Ryan's code was clearly better + for multithread programs, but required rewriting most of the compiler. As + clearly it would be unfair to subject the INTERCAL community at large to + the risk of silent multithreading by default, I decided multithreading + should be off by default (but ONCE/AGAIN should be legal). So this code is + designed to interfere as little as possible with non-multithreaded output. + There are two versions of libick compiled by the Makefile in this + distribution: libick.a, the non-multithread version, and libickmt.a, the + multithread version. The only difference between them is this file, + unravel.c, which is multithread only, so it seemed a good place for this + comment. To see what the multithreading looks like in the object code, + see degenerated code or feh.c. */ + +/* This file also implements Backtracking INTERCAL, which is turned on with + the same command-line option (-m). This implementation differs from + Malcom Ryan's standard in that abstention stati are not restored upon + GOING BACK. As far as I know, this is the only Backtracking INTERCAL + implementation currently available, although the code depends on the + multithreading code (which is why -m is neccesary). */ + +/* Note about control structures: Crazy INTERCAL control structures call for + crazy C control structures. setjmp/longjmp is probably C's weirdest + control structure (it's sort of like a time-reversed computed COME FROM). + I've used them to implement both multithreading and computed COME FROMming. + + Worried that this code might actually be copied by a casual C programmer, I + have the following warning: + + setjmp/longjmp is worse than goto in terms of spaghettification of code. + It is strictly to be used only when neccesary, or when writing INTERCAL + compilers. They also lead to weird portability problems when you don't obey + all the restrictions put on them by the C standard. For instance, + if(setjmp(cjb)!=0) puts("Jumped"); is portable, but + if(setjmp(cjb)) puts("Jumped"); is not, despite seeming to mean exactly the + same thing. Also, the address of setjmp can't be taken. Semantically, + setjmp/longjmp lets you do the same crazy things like goto, like jump into + the middle of a loop, except in this case the loop can be in a different + function, or even in a different file. unravel.c has no qualms about + jumping straight into the middle of an if statement in a degenerated C + program, even if said degenerated C program didn't exist when libickmt.a was + compiled. */ + +/* LINTLIBRARY */ +#include +#include +#include +#include + +#define MULTITHREAD 1 + +#include "sizes.h" +#include "abcess.h" +#include "lose.h" + +int gonebackto; /* Is the choicepoint reached by GOING BACK? */ +static int choicing = 0; /* Is a multithread function being used to do + backtracking processing? */ +jmp_buf btjb; /* The backtracking jmp_buf */ +static ickthread* topchoice; /* Top of the choicepoint stack */ +extern int lineno; /* Keep track of error-message lines */ + +extern int printflow; /* from arrgghh.c; a debug option */ + +/********************************************************************** + * + * This functions deal with choicepoints, which are implemented as + * ickthread objects. choicepoint creates a choicepoint or marks a + * choicepoint as stale; choiceahead eliminates a choicepoint; + * choiceback eliminates a stale choicepoint or returns to a fresh + * choicepoint. + * + *********************************************************************/ + +void choicepoint(void) +{ + ickthread* oldprev, *oldtc; + if(gonebackto) + { /* Create a stale choicepoint */ + if(printflow) printf("(back)"); + oldtc = topchoice; + topchoice = (ickthread*) malloc(sizeof(ickthread)); + if(!topchoice) lose(E991, lineno, (char*) NULL); + topchoice->next = oldtc; + topchoice->stale = 1; + topchoice->refcount = 1; /* At the moment, this is the only + thread looking at this choicepoint */ + return; + } + else + { /* Create a new choicepoint */ + if(printflow) printf("(maybe)"); + oldprev = ickmt_prev; + choicing = 1; + multicome1(lineno,btjb); /* Duplicate data */ + choicing = 0; + oldprev->next = ickmt_cur; + ickmt_prev->choicepoint = topchoice; + topchoice = ickmt_prev; + ickmt_prev = oldprev; + topchoice->stale = 0; + topchoice->refcount = 1; + /* So in other words, we've duplicated the current execution + environment, except for the choicepoint stack, changed the + duplicate from a thread into a choicepoint, and pushed it + on top of the choicepoint stack. Its pc is the point in the + degenerated program where choicepoint was called. */ + } +} + +void choiceahead(void) +{ + ickthread* tempthread; + jmp_buf fakepc; + + if(printflow) printf("(ahead)"); + + if(!topchoice) lose(E404, lineno, (char*) NULL); /* That's what E404's for */ + /* GO AHEAD with multithreading requires care. The choicepoint should only + be removed from this thread. topchoice = topchoice->next almost works, but + is a memory leak. So most of this is garbage-collection. */ + + /* If other threads are using the choicepoint, don't free it. */ + if(topchoice->refcount > 1) + { + topchoice->refcount--; + topchoice = topchoice->choicepoint; + return; + } + + /* The top choicepoint is not being used by other threads; free it. */ + + /* Freeing a stale choicepoint (which contains no data) is easy. */ + if(topchoice->stale) + { + tempthread = topchoice; + topchoice = topchoice->choicepoint; + free(tempthread); + return; + } + + /* This code works by converting topchoice back to a thread and placing it + just before the current thread, and then killing it. First, the data from + this thread, apart from the choicepoint stack, must be saved. */ + choicing = 1; + if(setjmp(fakepc) == 0) + { + memcpy(ickmt_cur->pc,fakepc,sizeof(jmp_buf)); + nextthread(fakepc, -1, 5); + } + choicing = 0; + /* That's saved the current thread's data. Now to convert topchoice to a + thread. */ + tempthread = topchoice->choicepoint; + ickmt_prev->next = topchoice; + topchoice->next = ickmt_cur; + ickmt_cur = topchoice; + topchoice = tempthread; + /* Let's load the backtracking data... */ + choicing = 1; + if(setjmp(fakepc) == 0) + { + memcpy(ickmt_cur->pc,fakepc,sizeof(jmp_buf)); + nextthread(fakepc, -1, 6); + } + /* only to destroy it! Mwahahahahah! */ + if(setjmp(fakepc) == 0) + { + memcpy(ickmt_cur->next->pc,fakepc,sizeof(jmp_buf)); + killthread(); + } + choicing = 0; + /* So we've reloaded the original current thread, the original previous + thread is still correct, topchoice has become topchoice->choicepoint, + and the original topchoice has disappeared. Mission accomplished. */ +} + +void choiceback(void) +{ + if(!topchoice) lose(E404, lineno, (char *) NULL); + if(topchoice->stale) {if(printflow) printf("(back=)"); choiceahead(); return;} + /* That's two simple cases out of the way (at least once choiceahead's + been implemented). What we need to do to backtrack is to change + topchoice to a thread after the current thread (rather than before + as in the previous two functions), and then kill the current thread. + (It amuses me that destroying a choicepoint, as in choiceahead(), + is more complicated than either visiting a choicepoint or creating a + choicepoint. That's how much work it can take to avoid a memory leak.) + In this case, choiceback won't return in the normal fashion. */ + if(topchoice->refcount > 1) + { + /* The Threaded INTERCAL standard states that if other threads are using + the choicepoint, a GO BACK should cause the thread it's in to be + killed. (Of course, if it's stale, it should just have been removed.)*/ + killthread(); + return; + } + topchoice->next = ickmt_cur->next; + ickmt_cur->next = topchoice; + topchoice = topchoice->choicepoint; + if(ickmt_cur==ickmt_prev) ickmt_prev = ickmt_cur->next; + choicing = 2; /* Tells killthread to set it back to 0 */ + killthread(); +} + +/********************************************************************** + * + * This function is called when two COME FROMs reference the same + * line at runtime. multicome1 is used in a multithread + * program; it forks the program. For multicome0, see cesspool.c. + * + *********************************************************************/ + +int multicome1(int errlineno, jmp_buf pc) +{ + /* Make a new thread just before the current one. Fake a PC in the + current thread within this function, change to the new thread, then + call nextthread. The upshot of all this is that all this thread's + data is stored in the new thread's state. Then, we have to copy + all this thread's current data to new locations. */ + static ickthread* newthread; + jmp_buf fakepc; + stashbox *isb, *isb2, *isbprev; + void* tvp; + array* a; + int prod, i, j; + newthread = malloc(sizeof(ickthread)); + if(!newthread) lose(E991, errlineno, (char *) NULL); + ickmt_prev->next = newthread; + newthread->next = ickmt_cur; + ickmt_cur = newthread; + + if(printflow && !choicing) printf("(fork)"); + + if(setjmp(fakepc) == 0) + { + memcpy(newthread->next->pc,fakepc,sizeof(jmp_buf)); + nextthread(pc, -1, 1); + } + /* So on the previous line: Save the value of pc as the program + counter of the new thread, and give a fake value for the + program value of the current thread (so it returns here, + not anywhere in the degenerated program). All that remains + is to duplicate all the data stored through pointers in the 'old' + thread (nextthread has changed ickmt_cur to point at the 'old' + thread). The original memory pointed to by these pointers is in + use storing the values in the 'new' thread, so the 'old' thread + needs new copies that it can modify independently. */ + + /* duplicate variables, forget indicators */ + i = onespotcount; + tvp = onespots; + onespots = malloc(i * sizeof *onespots); + if(!onespots) lose(E991, errlineno, (char *) NULL); + memcpy(onespots, tvp, i * sizeof *onespots); + i = twospotcount; + tvp = twospots; + twospots = malloc(i * sizeof *twospots); + if(!twospots) lose(E991, errlineno, (char *) NULL); + memcpy(twospots, tvp, i * sizeof *twospots); + i = tailcount; + tvp = tails; + tails = malloc(i * sizeof *tails); + if(!tails) lose(E991, errlineno, (char *) NULL); + memcpy(tails, tvp, i * sizeof *tails); + i = hybridcount; + tvp = hybrids; + hybrids = malloc(i * sizeof *hybrids); + if(!hybrids) lose(E991, errlineno, (char *) NULL); + memcpy(hybrids, tvp, i * sizeof *hybrids); + i = onespotcount; + tvp = oneforget; + oneforget = malloc(i * sizeof *oneforget); + if(!oneforget) lose(E991, errlineno, (char *) NULL); + memcpy(oneforget, tvp, i * sizeof *oneforget); + i = twospotcount; + tvp = twoforget; + twoforget = malloc(i * sizeof *twoforget); + if(!twoforget) lose(E991, errlineno, (char *) NULL); + memcpy(twoforget, tvp, i * sizeof *twoforget); + i = tailcount; + tvp = tailforget; + tailforget = malloc(i * sizeof *tailforget); + if(!tailforget) lose(E991, errlineno, (char *) NULL); + memcpy(tailforget, tvp, i * sizeof *tailforget); + i = hybridcount; + tvp = hyforget; + hyforget = malloc(i * sizeof *hyforget); + if(!hyforget) lose(E991, errlineno, (char *) NULL); + memcpy(hyforget, tvp, i * sizeof *hyforget); + + /* duplicate NEXT stack */ + tvp = next; + next = malloc(MAXNEXT * sizeof *next); + if(!next) lose(E991, errlineno, (char *) NULL); + memcpy(next, tvp, MAXNEXT * sizeof *next); + + /* duplicate data stored in arrays */ + j = tailcount; + while(j--) + { + a = tails+j; /* &(tails[j]) */ + if(!a->rank||!a->dims) continue; /* don't duplicate a deallocated array */ + tvp = a->dims; + /* Much of this code is paraphrased from the stashbox-copying code below, + which was in turn paraphrased from a section in cesspool.c I didn't + write. So any errors in this code are probably mine, but the algorithm + isn't. */ + a->dims = malloc(a->rank * sizeof(unsigned int)); + memcpy(a->dims, tvp, a->rank * sizeof(unsigned int)); + prod = !!a->rank; + i = a->rank; + while(i--) prod *= a->dims[i]; + tvp = a->data.tail; + a->data.tail = malloc(prod * sizeof(type16)); + if(!a->data.tail) lose(E991, errlineno, (char *) NULL); + memcpy(a->data.tail, tvp, prod * sizeof(type16)); + } + j = hybridcount; + while(j--) + { + a = hybrids+j; /* &(hybrids[j]) */ + if(!a->rank||!a->dims) continue; /* don't duplicate a deallocated array */ + tvp = a->dims; + /* Much of this code is paraphrased from the stashbox-copying code below, + which was in turn paraphrased from a section in cesspool.c I didn't + write. So any errors in this code are probably mine, but the algorithm + isn't. */ + a->dims = malloc(a->rank * sizeof(unsigned int)); + memcpy(a->dims, tvp, a->rank * sizeof(unsigned int)); + prod = !!a->rank; + i = a->rank; + while(i--) prod *= a->dims[i]; + tvp = a->data.hybrid; + a->data.hybrid = malloc(prod * sizeof(type32)); + if(!a->data.hybrid) lose(E991, errlineno, (char *) NULL); + memcpy(a->data.hybrid, tvp, prod * sizeof(type32)); + } + + /* allow for multithreading with choicepoints on the stack */ + if(!choicing && topchoice) + { + ickthread* icktp = topchoice; + while(icktp) + { + icktp->refcount++; + icktp = icktp->choicepoint; /* next choicepoint on the stack */ + } + /* The old thread's and new thread's choicepoint stack share + memory. This is pretty much necessary to handle backtracking + past a fork correctly. */ + } + + /* duplicate stashbox */ + isb2 = first; + isbprev = (stashbox*)NULL; + while(isb2) + { + isb = (stashbox*)malloc(sizeof(stashbox)); + if(!isb) lose(E991, errlineno, (char *) NULL); + memcpy(isb,isb2,sizeof(stashbox)); + if(isbprev) isbprev->next = isb; + isbprev = isb; + if(isb2==first) first = isb; /* change first only the first time round */ + if(isb->type == ONESPOT || isb->type == TWOSPOT) + { /* all copying already done */ + isb2 = isb->next; + continue; + } + /* Copy the stashed array. Much of this code is paraphrased from some + code in cesspool.c. In fact, it's the same, with a few idioms added + and variable names changed. So, although it's in this file, I can't + take the credit for it. */ + isb->save.a = (array*)malloc(sizeof(array)); + if(!isb->save.a) lose(E991, errlineno, (char *) NULL); + isb->save.a->rank = isb2->save.a->rank; + isb->save.a->dims = (unsigned int*)malloc(isb2->save.a->rank * + sizeof(unsigned int)); + if(!isb->save.a->dims) lose(E991, errlineno, (char *) NULL); + memcpy(isb->save.a->dims, isb2->save.a->dims, + isb2->save.a->rank * sizeof(unsigned int)); + prod = !!isb2->save.a->rank; /* I use this idiom often enough in the + code produced by my optimizer that I + may as well use it here. */ + i = isb2->save.a->rank; + while(i--) prod *= isb2->save.a->dims[i]; + if(isb2->type == TAIL) + { + isb->save.a->data.tail = (type16*)malloc(prod * sizeof(type16)); + if(!isb->save.a->data.tail) lose(E991, errlineno, (char *) NULL); + memcpy(isb->save.a->data.tail, isb2->save.a->data.tail, + prod * sizeof(type16)); + } + else + { + isb->save.a->data.hybrid = (type32*)malloc(prod * sizeof(type32)); + if(!isb->save.a->data.hybrid) lose(E991, errlineno, (char *) NULL); + memcpy(isb->save.a->data.hybrid, isb2->save.a->data.hybrid, + prod * sizeof(type32)); + } + isb2 = isb->next; + } + return 1; /* Tell the degenerated program to look for yet + another COME FROM */ +} + +/********************************************************************** + * + * These functions do the multithreading, using setjmp and longjmp + * to save the program counter. ickmtinit sets up the first + * thread, and nextthread changes to the next thread in the + * sequence. (Note that nextthread rarely actually returns). The + * code makes each command atomic, so that ONCE and AGAIN appear + * to the user to be atomic operations. + * + *********************************************************************/ + +ickthread* ickmt_cur; /* define ickmt_cur */ +ickthread* ickmt_prev; /* define ickmt_prev */ + +void ickmtinit(void) +{ + ickmt_cur = malloc(sizeof(ickthread)); + if(!ickmt_cur) lose(E991, 1, (char *) NULL); + ickmt_prev = ickmt_cur; + ickmt_cur->next = ickmt_cur; + topchoice = (ickthread*) NULL; /* No choicepoints */ +} + +/* Destroys the current thread, and switches to the next thread. + If there are no threads left, terminates the program using exit(0). */ +void killthread(void) +{ + static jmp_buf dummy; + stashbox* isb, *isbi; + int i; + + if(printflow&&!choicing) printf("(kill)"); + + /* Deallocate the current thread's data */ + i=tailcount; + while(i--) + { /* free tail data */ + if(!tails[i].rank||!tails[i].dims) continue; /* already free */ + free(tails[i].dims); + free(tails[i].data.tail); + } + i=hybridcount; + while(i--) + { /* free hybrid data */ + if(!hybrids[i].rank||!hybrids[i].dims) continue; /* already free */ + free(hybrids[i].dims); + free(hybrids[i].data.hybrid); + } + free(onespots); free(twospots); free(tails); free(hybrids); + free(oneforget); free(twoforget); free(tailforget); free(hyforget); + free(next); /* Free NEXT stack */ + if(!choicing) while(topchoice) choiceahead(); + /* The above line will mark each of the choicepoints as no longer being + used by this thread, and free them if neccesary. */ + isbi = first; + while(isbi) /* Free stash */ + { + isb=isbi->next; + if(isbi->type == TAIL || isbi->type == HYBRID) + { + free(isbi->save.a->dims); + if(isbi->type == TAIL) + free(isbi->save.a->data.tail); + else + free(isbi->save.a->data.hybrid); + } + free(isbi); + isbi=isb; + } + + ickmt_prev->next = ickmt_cur->next; + if(ickmt_cur->next == ickmt_cur) + { + free(ickmt_cur); + exit(0); + } + else + { + /* We need to run about half of nextthread. So we pass in a 2 for + flags and tell it to skip the first half. */ + free(ickmt_cur); + ickmt_cur = ickmt_prev; + nextthread(dummy, -1, 2); /* dummy is not used by nextthread */ + lose(E778, -1, (char *) NULL); /* nextthread does not return */ + } +} + +/* This function does not return in the normal fashion, but by a nonlocal + goto to a mysterious location, possibly in multicome1 but possibly in + the degenerated code. From the point of view of libickmt.a, we're going + to a piece of code that doesn't even exist yet! The general ugliness of + INTERCAL multithreading pulls out all the stops when it comes to using + unusual and confusing C control structures. It is important to remember + that longjmp clobbers all auto variables that have changed since the + corresponding setjmp. */ + +/* In this Threaded INTERCAL implementation, data is saved in a linked ring + of threads. A thread runs for a command, then all the data pointers are + changed, saving the old ones. This is an improvement on an earlier attempt + of mine in which the values themselves were copied, but is still less + efficient than Malcom Ryan's method (which didn't involve copying things + about except when forking). However, I justify this by saying that it leaves + as much existing code as possible untouched, which is helpful for single- + thread compatibility, modifying the code in feh.c without an understanding + of multithread issues, and because I'm lazy. It also makes the rest of the + program shorter. */ +void nextthread(jmp_buf pc, int errlineno, int flags) +{ /* flags | 1 means save this thread. + flags | 2 means load the next thread. + flags | 4 means don't change thread. */ + if(errlineno > -1 && ickmt_cur->next == ickmt_cur && !choicing) longjmp(pc,1); + /* If we only have 1 thread, just continue with it. Otherwise: */ + + if(!(flags&1)) goto advancethread; + /* OK, so I've spaghettified this procedure slightly by using goto + instead of if. But I was so deep into figuring out setjmp/longjmp, + a goto seemed crystal-clear by comparison. */ + + /* save variables */ + ickmt_cur->varforget[0] = onespots; + ickmt_cur->varforget[1] = twospots; + ickmt_cur->varforget[2] = tails; + ickmt_cur->varforget[3] = hybrids; + ickmt_cur->varforget[4] = oneforget; + ickmt_cur->varforget[5] = twoforget; + ickmt_cur->varforget[6] = tailforget; + ickmt_cur->varforget[7] = hyforget; + + /* save NEXT stack */ + ickmt_cur->nextstack = next; + ickmt_cur->nextpointer = nextindex; + + /* save stashbox */ + ickmt_cur->sb = first; + + /* save choicepoints */ + if(!choicing) ickmt_cur->choicepoint = topchoice; + + /* save comefrom information */ + memcpy(ickmt_cur->cjb, cjb, sizeof(jmp_buf)); + ickmt_cur->ccfc = ccfc; + ickmt_cur->skipto = skipto; + + /* save program counter */ + memcpy(ickmt_cur->pc, pc, sizeof(jmp_buf)); + /* And another thing about setjmp/longjmp. A jmp_buf + acts like a structure that passes itself around by + reference. However, it cannot be assigned, although + just about everything else in C can be, although it + can be copied with memcpy (what I'm doing in the line + above - remember it passes itself around by reference). + Generally speaking, it's some sort of array, + even though some implementors use a 1-element array. + The exact representation of jmp_buf is one of the most + implementation-dependent things in C (I've seen both + a 1-element array of structure and an int[12].) */ + + advancethread: + /* change thread */ + if(!(flags&4)) + { + ickmt_prev = ickmt_cur; + ickmt_cur = ickmt_cur->next; + } + + if(!(flags&2)) goto returnjmp; + + /* load variables */ + onespots = ickmt_cur->varforget[0]; + twospots = ickmt_cur->varforget[1]; + tails = ickmt_cur->varforget[2]; + hybrids = ickmt_cur->varforget[3]; + oneforget = ickmt_cur->varforget[4]; + twoforget = ickmt_cur->varforget[5]; + tailforget = ickmt_cur->varforget[6]; + hyforget = ickmt_cur->varforget[7]; + + /* load NEXT stack */ + next = ickmt_cur->nextstack; + nextindex = ickmt_cur->nextpointer; + + /* load choicepoints */ + if(!choicing) topchoice = ickmt_cur->choicepoint; + + /* load stashbox */ + first = ickmt_cur->sb; + + /* load comefrom information */ + memcpy(cjb, ickmt_cur->cjb, sizeof(jmp_buf)); + ccfc = ickmt_cur->ccfc; + skipto = ickmt_cur->skipto; + + returnjmp: + /* return to the new current thread's program counter */ + if(choicing==2) choicing = 0; + longjmp(ickmt_cur->pc, 1); +} diff --git a/src/yuk.c b/src/yuk.c new file mode 100644 index 0000000..1fdc303 --- /dev/null +++ b/src/yuk.c @@ -0,0 +1,769 @@ +/**************************************************************************** + +NAME + yuk.c -- C-INTERCAL debugger and profiler code, linked into programs. + +DESCRIPTION + File linked into programs as a debugger or profiler. + +LICENSE TERMS + Copyright (C) 2006 Alex Smith + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#define YUKDEBUG 1 + +#include "yuk.h" +#include "lose.h" +#include "sizes.h" +#include "abcess.h" + +#if YPTIMERTYPE == 4 +#include +#endif + +/* To help out shells that only understand backslashes in filenames. */ +#ifdef YUKCOPYLOCUS +#define STRINGIZE2(s) s +#define STRINGIZE(s) STRINGIZE2(s) +#define YUKCOPYLOC STRINGIZE(YUKCOPYLOCUS) +#endif + +extern signed char onewatch[]; +extern signed char twowatch[]; +extern type16 oneold[]; +extern type32 twoold[]; + +int yuklines = 0; +int yukloop = 0; +int yukcommands = 0; /* these 3 lines because externs must be defined + somewhere */ +/* Global variable storage types: + static: limited to the file + unadorned: defining an extern + extern: defined elsewhere (unless initialised) */ + +static char buf[20]; + +static sig_atomic_t singlestep = 1; /* if 0, run until a breakpoint */ +static sig_atomic_t writelines = 1; /* whether to display executed lines onscreen */ +static int breakpoints[80]; /* initialised to all 0s. Breakpoint locations */ +static int nbreakpoints = 1; /* how many breakpoints we have */ +static int monitors[80]; /* monitors give a message when program flow passes them */ +static int nmonitors = 0; +static int untilnext = -1; /* NEXTING level to break the program at */ +static int firstrun = 1; /* first time an interactive command point is reached */ +static int yukerrcmdg = -1; /* the aboff that indicates an error in the 'g' command */ + +static yptimer tickcount; /* yptimer of last run */ +static int lastaboff = 0; /* last value of aboff */ + +void handlesigint(int i) +{ /* this is a signal handler, so can't do much */ + singlestep = 1; + writelines = 1; + (void) i; /* we're ignoring our argument */ +} + +#if YPTIMERTYPE==1 || YPTIMERTYPE==2 +yptimer yukgettimeofday() +{ + static struct timeval tp; + yptimer temp; + gettimeofday(&tp,0); + temp=(yptimer)tp.tv_usec + + (yptimer)tp.tv_sec * (yptimer)1000000LU; + /* here we make use of unsigned wraparound. In the case + YPTIMERTYPE == 1, it seems quite likely that we're going + to wraparound, but because everything is cast to the + unsigned integral type yptimer, we get a value that will + wraparound in such a way that - will give us the correct + time interval. */ + return temp; +} +#elif YPTIMERTYPE == 4 +yptimer yuktimes() +{ + static struct tms tp; + times(&tp); + return tp.tms_utime + tp.tms_stime; +} +#endif /* YPTIMERTYPE 4 */ + +void yukterm(void) +{ + int i,lastline,thisline,inrow=0; + yptimer avgtime,avgtime2; + if(yukopts==2) puts("Program ended without error."); + if(!(yukopts&1)) return; + /* Print profiling information */ + puts("Profiling information saved to \"yuk.out\"."); + freopen("yuk.out","w",stdout); + i=-1; + lastline=-1; + while(++i.\n"); + puts("For help on yuk, type ?.\n"); + } + i=nbreakpoints; + broken=0; + while(i--) broken|=breakpoints[i]==lineofaboff[aboff]; + if(yukloop&&broken&&*breakpoints!=lineofaboff[aboff]) broken=0; + if(broken) + { + if(*breakpoints!=lineofaboff[aboff]) + printf("Breakpoint hit at line %d:\n",lineofaboff[aboff]); + singlestep=1; + } + else + { + i=nmonitors; + while(i--) broken|=monitors[i]==lineofaboff[aboff]; + if(yukloop) broken=0; + if(broken) printf("Command flowed past line %d:\n",lineofaboff[aboff]); + } + if(nextindex <= untilnext) + { + broken = 1; + singlestep = 1; + } + if(!broken&&yukerrcmdg==aboff) + { + singlestep = 1; + puts("There are no commands on that line."); + /* To the user, nothing will have happened but the error message! */ + } + i=-1; + while(++i,1) + { + if(yukvars[i].vartype==YUKEND) break; + if(yukvars[i].vartype==ONESPOT) + { + if(onewatch[yukvars[i].intername]) + { + if(onespots[yukvars[i].intername]!=oneold[yukvars[i].intername]&& + onewatch[yukvars[i].intername]>1) + { + oneold[yukvars[i].intername]=onespots[yukvars[i].intername]; + if(onewatch[yukvars[i].intername]==2||!onespots[yukvars[i].intername]) + { + printf(onewatch[yukvars[i].intername]==2? + "Variable .%d changed.\n":"Variable .%d became 0.\n", + yukvars[i].extername); + broken=1; singlestep=1; + } + } + if(writelines||broken) + { + printf(".%d is:\n",yukvars[i].extername); + pout(onespots[yukvars[i].intername]); + } + } + } + if(yukvars[i].vartype==TWOSPOT) + { + if(twowatch[yukvars[i].intername]) + { + if(twospots[yukvars[i].intername]!=twoold[yukvars[i].intername]&& + twowatch[yukvars[i].intername]>1) + { + twoold[yukvars[i].intername]=twospots[yukvars[i].intername]; + if(twowatch[yukvars[i].intername]==2||!twospots[yukvars[i].intername]) + { + printf(twowatch[yukvars[i].intername]==2? + "Variable :%d changed.\n":"Variable :%d became 0.\n", + yukvars[i].extername); + broken=1; singlestep=1; + } + } + if(writelines||broken) + { + printf(":%d is:\n",yukvars[i].extername); + pout(twospots[yukvars[i].intername]); + } + } + } + } + if(writelines||broken) + { + /* write line that we're on */ + printf("%5d:\t%s\n",lineofaboff[aboff],text); + /* write command within line that we're on */ + tempcmd=aboff; + while(tempcmd&&lineofaboff[--tempcmd]==lineofaboff[aboff]); + printf("On C%d: Abstained %d time%s\n",aboff?aboff-tempcmd:1, + abstained[aboff]-yukloop,abstained[aboff]-yukloop==1?".":"s."); + } + if(singlestep) + { + signal(SIGINT,handlesigint); /* placing this line here means that a rapid + ^C^C will terminate the program, if it's + stuck in a loop somewhere */ + keeplooping = 1; + breakpoints[0] = 0; /* breakpoints[0] goes whenever a breakpoint is hit */ + untilnext = -1; + if(yukloop) + { /* reverse the abstentions that g caused */ + i = -1; + while(++i\tabstain once from all non-abstained commands on "); + puts("b\tset breakpoint at "); + puts("c\tcontinue execution until a breakpoint is reached"); + puts("d\tdelete breakpoint at "); + puts("e\texplain the main expression on "); + puts("f\tstop producing messages when commands on are run"); + puts("g\tchange currently executing command to the first command"); + puts("\ton or the next command if already on "); + puts("h\tlist 10 lines either side of the current line"); + puts("i\tignore a variable"); + puts("j\tremember a variable"); + puts("k\tcontinue until we RESUME back to the current nexting level"); + puts("\t(that is, step unless we are on a NEXT, in which case execute"); + puts("\tuntil a RESUME or FORGET back to the same or smaller NEXT stack)"); + puts("l\tlist 10 lines either side of "); + puts("m\tproduce a message every time a command on is run"); + puts("n\tshow the NEXT stack"); + puts("o\tcontinue until we RESUME/FORGET below the current nexting level"); + puts("\tie until the NEXT stack becomes smaller than it is at present"); + puts("p\tdisplay the values of all onespot and twospot variables"); + puts("q\tabort execution"); + puts("r\treinstate once all abstained commands on "); + puts("s\tstep to the next line of code"); + puts("t\tcontinue until a breakpoint, displaying all lines executed"); + puts("u\texecute until just before is reached"); + puts("v\tshow value of variable every time a command is printed"); + puts("w\tshow the current line and current command"); + puts("x\tremove a variable view, breakchange, or breakzero"); + puts("y\tview variable every displayed line, and break on change"); + puts("z\tview variable every displayed line, and break on zero"); + puts("\tview the value of a onespot or twospot variable"); + puts("<\tset the value of a onespot or twospot variable"); + puts("*\tview the GNU General Public Licence"); + puts("?\tview this help screen"); + puts("@\tview this help screen"); + puts("Line numbers refer to lines of source code, not line labels."); + puts("Listings have (Axxxxxx) at the start of each line: this shows"); + puts("the abstention status of each command on that line."); + puts("The values of variables must be input in proper INTERCAL"); + puts("notation (i.e. ONE TWO THREE), and are output as butchered"); + puts("Roman numerals."); + puts("You can press ^C to break an executing program."); + break; + case 'q': + exit(0); + break; + case 'n': + i=nextindex; + if(!i) + { + puts("The NEXT stack is empty."); + } + else + { + puts("Commands NEXTED from:"); + while(i--) + { + /* write NEXT line */ + printf("%5d:\t%s\n",lineofaboff[next[i]-1], + textlines[lineofaboff[next[i]-1]]); + /* write NEXT command within line */ + tempcmd=next[i]; + while(tempcmd&&lineofaboff[--tempcmd]==lineofaboff[next[i]-1]); + printf("NEXTED from command C%d: Abstained %d time%s\n",next[i]-1? + next[i]-1-tempcmd:1,abstained[next[i]-1], + abstained[next[i]-1]==1?".":"s."); + } + } + break; + case 'w': + /* write line that we're on */ + printf("%5d:\t%s\n",lineofaboff[aboff],text); + /* write command within line that we're on */ + tempcmd=aboff; + while(tempcmd&&lineofaboff[--tempcmd]==lineofaboff[aboff]); + printf("On C%d: Abstained %d time%s\n",aboff?aboff-tempcmd:1,abstained[aboff], + abstained[aboff]==1?".":"s."); + break; + case 'p': + i=-1; + while(++i,1) + { + if(yukvars[i].vartype==YUKEND) break; + if(yukvars[i].vartype==ONESPOT) + { + printf("Variable .%d is:\n",yukvars[i].extername); + pout(onespots[yukvars[i].intername]); + } + if(yukvars[i].vartype==TWOSPOT) + { + printf("Variable :%d is:\n",yukvars[i].extername); + pout(twospots[yukvars[i].intername]); + } + } + break; + case '.': + case ':': + sscanf(buf+1,"%d",&templine); + if(templine<1) + { + puts("Don't know which variable you mean."); + break; + } + i=-1; + temp=0; + while(++i,!temp) + { + if(yukvars[i].vartype==YUKEND) break; + if((*buf=='.'&&yukvars[i].vartype==ONESPOT)|| + (*buf==':'&&yukvars[i].vartype==TWOSPOT)) + { + if(yukvars[i].extername==templine) + { + temp=1; + if(yukvars[i].vartype==ONESPOT) + { + pout(onespots[yukvars[i].intername]); + puts(oneforget[yukvars[i].intername]? + "This variable is currently ignored.": + "This variable is currently remembered."); + } + if(yukvars[i].vartype==TWOSPOT) + { + pout(twospots[yukvars[i].intername]); + puts(twoforget[yukvars[i].intername]? + "This variable is currently ignored.": + "This variable is currently remembered."); + } + } + } + } + if(temp) break; + puts("That variable is not in the program."); + break; + case 'v': + case 'x': + case 'y': + case 'z': + if(buf[1]!='.'&&buf[1]!=':') + { + puts("This command only works on onespot and twospot variables."); + break; + } + sscanf(buf+2,"%d",&templine); + if(templine<1) + { + puts("Don't know which variable you mean."); + break; + } + i=-1; + temp=0; + while(++i,!temp) + { + if(yukvars[i].vartype==YUKEND) break; + if(yukvars[i].extername==templine) + { + if(buf[1]=='.'&&yukvars[i].vartype==ONESPOT) + { + if(*buf=='v') onewatch[yukvars[i].intername]=1; + if(*buf=='x') onewatch[yukvars[i].intername]=0; + if(*buf=='y') onewatch[yukvars[i].intername]=2; + if(*buf=='z') onewatch[yukvars[i].intername]=3; + oneold[yukvars[i].intername]=onespots[yukvars[i].intername]; + temp=1; + } + if(buf[1]==':'&&yukvars[i].vartype==TWOSPOT) + { + if(*buf=='v') twowatch[yukvars[i].intername]=1; + if(*buf=='x') twowatch[yukvars[i].intername]=0; + if(*buf=='y') twowatch[yukvars[i].intername]=2; + if(*buf=='z') twowatch[yukvars[i].intername]=3; + twoold[yukvars[i].intername]=twospots[yukvars[i].intername]; + temp=1; + } + } + } + if(!temp) + { + puts("That variable is not in the program."); + break; + } + if(*buf=='v') puts("Set a normal variable view."); + if(*buf=='x') puts("Removed all views from that variable."); + if(*buf=='y') puts("Set a breakchange variable view."); + if(*buf=='z') puts("Set a breakzero variable view."); + break; + case 'i': + case 'j': + if(buf[1]!='.'&&buf[1]!=':'&&buf[1]!=','&&buf[1]!=';') + { + puts("That isn't a real sort of variable."); + break; + } + sscanf(buf+2,"%d",&templine); + if(templine<1) + { + puts("Don't know which variable you mean."); + break; + } + i=-1; + temp=0; + while(++i,!temp) + { + if(yukvars[i].vartype==YUKEND) break; + if((buf[1]=='.'&&yukvars[i].vartype==ONESPOT)|| + (buf[1]==':'&&yukvars[i].vartype==TWOSPOT)|| + (buf[1]==','&&yukvars[i].vartype==TAIL)|| + (buf[1]==';'&&yukvars[i].vartype==HYBRID)) + { + if(yukvars[i].extername==templine) + { + temp=1; + if(yukvars[i].vartype==ONESPOT) + oneforget[yukvars[i].intername]=*buf=='i'; + if(yukvars[i].vartype==TWOSPOT) + twoforget[yukvars[i].intername]=*buf=='i'; + if(yukvars[i].vartype==TAIL) + tailforget[yukvars[i].intername]=*buf=='i'; + if(yukvars[i].vartype==HYBRID) + hyforget[yukvars[i].intername]=*buf=='i'; + } + } + } + if(temp) + { + if(*buf=='i') + puts("Variable ignored."); + else + puts("Variable remembered."); + break; + } + puts("That variable is not in the program."); + break; + case '<': + if(buf[1]!='.'&&buf[1]!=':') + { + puts("You cannot set that sort of variable (if it exists at all)."); + break; + } + sscanf(buf+2,"%d",&templine); + if(templine<1) + { + puts("Don't know which variable you mean."); + break; + } + i=-1; + temp=0; + while(++i,!temp) + { + if(yukvars[i].vartype==YUKEND) break; + if((buf[1]=='.'&&yukvars[i].vartype==ONESPOT)|| + (buf[1]==':'&&yukvars[i].vartype==TWOSPOT)) + { + if(yukvars[i].extername==templine) + { + temp=1; + if(yukvars[i].vartype==ONESPOT) + onespots[yukvars[i].intername]=pin(); + if(yukvars[i].vartype==TWOSPOT) + twospots[yukvars[i].intername]=pin(); + /* note that when debugging, you can set an + ignored variable */ + } + } + } + if(temp) break; + puts("That variable is not in the program."); + break; + case 'g': + sscanf(buf+1,"%d",&templine); + if(!templine) + { + puts("Don't know which line you mean."); + break; + } + breakpoints[0] = templine; + yukloop = 1; + /* This is implemented by incrementing all ABSTAIN counts, + even the normally immutable ones on GIVE UP lines, setting + a temporary breakpoint ([0]) on the line given, and running the + program. When the breakpoint is hit singlestep will see that + yukloop is set (its purpose is to cause the program to go back + to the start when it reaches the end) and decrement all ABSTAIN + counts, putting the commands back the way they were. We set an error + breakpoint on this line in case the user is trying to jump to a + line with no commands (although this debugger command is called + 'g', would I dare to describe this as a GOTO?) */ + i = -1; + while(++i=80) lose(E811,emitlineno,(char*)NULL); + } + else + puts("Don't know which line you mean."); + break; + case 'd': + sscanf(buf+1,"%d",&templine); + if(templine) + { + printf("All breakpoints removed from line %d.\n",templine); + i=nbreakpoints; + while(i--) if(templine==breakpoints[i]) + { + memmove(breakpoints+i,breakpoints+i+1,sizeof(int)*(nbreakpoints-i)); + nbreakpoints--; + } + } + else + puts("Don't know which line you mean."); + break; + case 'm': + sscanf(buf+1,"%d",&templine); + if(templine) + { + printf("Monitor set at line %d.\n",templine); + monitors[nmonitors++]=templine; + if(nmonitors>=80) lose(E811,emitlineno,(char*)NULL); + } + else + puts("Don't know which line you mean."); + break; + case 'f': + sscanf(buf+1,"%d",&templine); + if(templine) + { + printf("All monitors removed from line %d.\n",templine); + i=nmonitors; + while(i--) if(templine==monitors[i]) + { + memmove(monitors+i,monitors+i+1,sizeof(int)*(nmonitors-i)); + nmonitors--; + } + } + else + puts("Don't know which line you mean."); + break; + case 's': + singlestep=1; + writelines=1; + keeplooping=0; + break; + case 't': + singlestep=0; + writelines=1; + keeplooping=0; + break; + case 'u': + sscanf(buf+1,"%d",&templine); + if(templine) + { + breakpoints[0]=templine; + singlestep=0; + writelines=0; + keeplooping=0; + } + else + puts("Don't know which line you mean."); + break; + case 'e': + sscanf(buf+1,"%d",&templine); + if(!templine) + { + puts("Don't know which line you mean."); + break; + } + tempcmd=-1; + temp=0; + i=0; + while(++tempcmd=yuklines) templine=yuklines-22; + if(templine<1) templine=1; + i=templine; + while(i9) buf[temp-1]='!'; + if(temp==6) break; + } + } + printf("(A%s)%5d:\t%s\n",buf,i,textlines[i]); + i++; + } + break; + case '*': + system("more < " YUKCOPYLOC); /* display the GNU GPL copyright */ + break; + default: + puts("Not sure what you mean. Try typing ?."); + break; + } + } while(keeplooping); + } + } + firstrun=0; +} diff --git a/src/yuk.h b/src/yuk.h new file mode 100644 index 0000000..2b2f0c2 --- /dev/null +++ b/src/yuk.h @@ -0,0 +1,99 @@ +/* yuk.h - header file for yuk.c and debugging versions of ick-wrap.c */ +/* Copyright (C) Alex Smith 2006. See yuk.c for copyright conditions. + This file is GPL'd, and so can be freely redistributed but has + absolutely no warranty. */ + +#include +#define YUK(t,u) yukline(t,u) +#define YUKTERM yukterm() + +#define YUKEND 5 + +extern void yukline(int,int); +extern void yukterm(void); + +extern int abstained[]; +extern int yukopts; +extern int lineno; +extern int yuklines; +extern int yukcommands; +extern char *textlines[]; +extern int lineofaboff[]; +extern char *yukexplain[]; + +extern int yukloop; + +/* Defines that change the functions used for profiling */ +#define YPTIMERTYPE 2 +/* 0 to use clock(), 1 to use gettimeofday() and long, + 2 to use gettimeofday() and long long, 3 to use gethrtime() + 4 to use times() */ +/* Note: On many systems, 0's resolution is too low to produce any output + 1 and 2 produce the same output; use 2 if your system can handle + long long because the overflow is dealt with more simply + 3 is a system-specific function. If there are more system-specific + functions around that return more accurate times than the others + used here, it would improve the profiler on those systems. */ + +#if YPTIMERTYPE == 0 +#define YPTIMERTFORMAT "lu" +#define YPCOUNTERTFORMAT "lu" +#define YPTIMERTFORMATD "6" YPTIMERTFORMAT +#define YPTIMERSCALE CLOCKS_PER_SEC +#define YPGETTIME clock() +typedef unsigned long yptimer; +typedef unsigned long ypcounter; + +#elif YPTIMERTYPE == 1 +#define YPTIMERTFORMAT "lu" +#define YPCOUNTERTFORMAT "lu" +#define YPTIMERTFORMATD "6" YPTIMERTFORMAT +#define YPTIMERSCALE 1000000LU +#define YPGETTIME yukgettimeofday() +typedef unsigned long yptimer; +typedef unsigned long ypcounter; + +#elif YPTIMERTYPE == 2 +#define YPTIMERTFORMAT "llu" +#define YPCOUNTERTFORMAT "lu" +#define YPTIMERTFORMATD "6" YPTIMERTFORMAT +#define YPTIMERSCALE 1000000LU +#define YPGETTIME yukgettimeofday() +typedef unsigned long long yptimer; +typedef unsigned long ypcounter; + +#elif YPTIMERTYPE == 3 +#define YPTIMERTFORMAT "llu" +#define YPCOUNTERTFORMAT "lu" +#define YPTIMERTFORMATD "9" YPTIMERTFORMAT +#define YPTIMERSCALE 1000000000LLU +#define YPGETTIME gethrtime() +typedef unsigned long long yptimer; +typedef unsigned long ypcounter; + +#elif YPTIMERTYPE == 4 +#define YPTIMERTFORMAT "lu" +#define YPCOUNTERTFORMAT "lu" +#define YPTIMERTFORMATD "6" YPTIMERTFORMAT +#define YPTIMERSCALE CLK_TCK +#define YPGETTIME yuktimes() +typedef unsigned long yptimer; +typedef unsigned long ypcounter; + +#else +#error Invalid YPTIMERTYPE in yuk.h + +#endif /* YPTIMERTYPE cases */ + +extern yptimer ypexectime[]; +extern ypcounter ypexecount[]; +extern ypcounter ypabscount[]; + +typedef struct yukvar_tag +{ + int vartype; + int extername; + int intername; +} yukvar; + +extern yukvar yukvars[]; diff --git a/unravel.c b/unravel.c deleted file mode 100644 index aab5988..0000000 --- a/unravel.c +++ /dev/null @@ -1,645 +0,0 @@ -/***************************************************************************** - -NAME - unravel.c -- multithreading and backtracking support for C-INTERCAL - -LICENSE TERMS - Copyright (C) 2006 Alex Smith - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - -***************************************************************************/ - -/* Notes about authorship. This entire file was written by Alex Smith (AIS), - but with reference to an earlier implementation of Threaded INTERCAL written - by Malcom Ryan. I have not reused any of his C code (two of his INTERCAL - programs are in the pit), but it was a useful source of inspiration, even - though I did it a completely different and less efficient way (I think we - handled mutiple COME FROM recognition in much the same way). This file only - contains functions necessary for multithreading; some of the code is stored - in feh.c (stored in strings), or in perpetrate.c (again stored in strings). - The information about the required syntax is in ick.y and lexer.l. - A small amount of the multithread code is in ick-wrap.c, although as that - file is copied almost verbatim (although it's quite a big 'almost') into - all ick output, it's guarded there by #if...#endif. The whole multithread - idea started on alt.lang.intercal when it was noticed that multiple COME - FROMs aiming at the same line were hard to interpret, but I would like - to thank Malcom Ryan for drafting the Threaded Intercal standard and a - reference compiler, and for turning the idea into a concrete set of rules. - (The standard itself carries a note saying that a revision (use of AGAIN) - was inspired by Kyle Dean, so I'd like to mention that here too, and I also - revised it (so that ABSTAIN/REINSTATE were preserved through backtracking).) - In terms of the quality of the code, Malcom Ryan's code was clearly better - for multithread programs, but required rewriting most of the compiler. As - clearly it would be unfair to subject the INTERCAL community at large to - the risk of silent multithreading by default, I decided multithreading - should be off by default (but ONCE/AGAIN should be legal). So this code is - designed to interfere as little as possible with non-multithreaded output. - There are two versions of libick compiled by the Makefile in this - distribution: libick.a, the non-multithread version, and libickmt.a, the - multithread version. The only difference between them is this file, - unravel.c, which is multithread only, so it seemed a good place for this - comment. To see what the multithreading looks like in the object code, - see degenerated code or feh.c. */ - -/* This file also implements Backtracking INTERCAL, which is turned on with - the same command-line option (-m). This implementation differs from - Malcom Ryan's standard in that abstention stati are not restored upon - GOING BACK. As far as I know, this is the only Backtracking INTERCAL - implementation currently available, although the code depends on the - multithreading code (which is why -m is neccesary). */ - -/* Note about control structures: Crazy INTERCAL control structures call for - crazy C control structures. setjmp/longjmp is probably C's weirdest - control structure (it's sort of like a time-reversed computed COME FROM). - I've used them to implement both multithreading and computed COME FROMming. - - Worried that this code might actually be copied by a casual C programmer, I - have the following warning: - - setjmp/longjmp is worse than goto in terms of spaghettification of code. - It is strictly to be used only when neccesary, or when writing INTERCAL - compilers. They also lead to weird portability problems when you don't obey - all the restrictions put on them by the C standard. For instance, - if(setjmp(cjb)!=0) puts("Jumped"); is portable, but - if(setjmp(cjb)) puts("Jumped"); is not, despite seeming to mean exactly the - same thing. Also, the address of setjmp can't be taken. Semantically, - setjmp/longjmp lets you do the same crazy things like goto, like jump into - the middle of a loop, except in this case the loop can be in a different - function, or even in a different file. unravel.c has no qualms about - jumping straight into the middle of an if statement in a degenerated C - program, even if said degenerated C program didn't exist when libickmt.a was - compiled. */ - -/* LINTLIBRARY */ -#include -#include -#include -#include - -#define MULTITHREAD 1 - -#include "sizes.h" -#include "abcess.h" -#include "lose.h" - -int gonebackto; /* Is the choicepoint reached by GOING BACK? */ -static int choicing = 0; /* Is a multithread function being used to do - backtracking processing? */ -jmp_buf btjb; /* The backtracking jmp_buf */ -static ickthread* topchoice; /* Top of the choicepoint stack */ -extern int lineno; /* Keep track of error-message lines */ - -extern int printflow; /* from arrgghh.c; a debug option */ - -/********************************************************************** - * - * This functions deal with choicepoints, which are implemented as - * ickthread objects. choicepoint creates a choicepoint or marks a - * choicepoint as stale; choiceahead eliminates a choicepoint; - * choiceback eliminates a stale choicepoint or returns to a fresh - * choicepoint. - * - *********************************************************************/ - -void choicepoint(void) -{ - ickthread* oldprev, *oldtc; - if(gonebackto) - { /* Create a stale choicepoint */ - if(printflow) printf("(back)"); - oldtc = topchoice; - topchoice = (ickthread*) malloc(sizeof(ickthread)); - if(!topchoice) lose(E991, lineno, (char*) NULL); - topchoice->next = oldtc; - topchoice->stale = 1; - topchoice->refcount = 1; /* At the moment, this is the only - thread looking at this choicepoint */ - return; - } - else - { /* Create a new choicepoint */ - if(printflow) printf("(maybe)"); - oldprev = ickmt_prev; - choicing = 1; - multicome1(lineno,btjb); /* Duplicate data */ - choicing = 0; - oldprev->next = ickmt_cur; - ickmt_prev->choicepoint = topchoice; - topchoice = ickmt_prev; - ickmt_prev = oldprev; - topchoice->stale = 0; - topchoice->refcount = 1; - /* So in other words, we've duplicated the current execution - environment, except for the choicepoint stack, changed the - duplicate from a thread into a choicepoint, and pushed it - on top of the choicepoint stack. Its pc is the point in the - degenerated program where choicepoint was called. */ - } -} - -void choiceahead(void) -{ - ickthread* tempthread; - jmp_buf fakepc; - - if(printflow) printf("(ahead)"); - - if(!topchoice) lose(E404, lineno, (char*) NULL); /* That's what E404's for */ - /* GO AHEAD with multithreading requires care. The choicepoint should only - be removed from this thread. topchoice = topchoice->next almost works, but - is a memory leak. So most of this is garbage-collection. */ - - /* If other threads are using the choicepoint, don't free it. */ - if(topchoice->refcount > 1) - { - topchoice->refcount--; - topchoice = topchoice->choicepoint; - return; - } - - /* The top choicepoint is not being used by other threads; free it. */ - - /* Freeing a stale choicepoint (which contains no data) is easy. */ - if(topchoice->stale) - { - tempthread = topchoice; - topchoice = topchoice->choicepoint; - free(tempthread); - return; - } - - /* This code works by converting topchoice back to a thread and placing it - just before the current thread, and then killing it. First, the data from - this thread, apart from the choicepoint stack, must be saved. */ - choicing = 1; - if(setjmp(fakepc) == 0) - { - memcpy(ickmt_cur->pc,fakepc,sizeof(jmp_buf)); - nextthread(fakepc, -1, 5); - } - choicing = 0; - /* That's saved the current thread's data. Now to convert topchoice to a - thread. */ - tempthread = topchoice->choicepoint; - ickmt_prev->next = topchoice; - topchoice->next = ickmt_cur; - ickmt_cur = topchoice; - topchoice = tempthread; - /* Let's load the backtracking data... */ - choicing = 1; - if(setjmp(fakepc) == 0) - { - memcpy(ickmt_cur->pc,fakepc,sizeof(jmp_buf)); - nextthread(fakepc, -1, 6); - } - /* only to destroy it! Mwahahahahah! */ - if(setjmp(fakepc) == 0) - { - memcpy(ickmt_cur->next->pc,fakepc,sizeof(jmp_buf)); - killthread(); - } - choicing = 0; - /* So we've reloaded the original current thread, the original previous - thread is still correct, topchoice has become topchoice->choicepoint, - and the original topchoice has disappeared. Mission accomplished. */ -} - -void choiceback(void) -{ - if(!topchoice) lose(E404, lineno, (char *) NULL); - if(topchoice->stale) {if(printflow) printf("(back=)"); choiceahead(); return;} - /* That's two simple cases out of the way (at least once choiceahead's - been implemented). What we need to do to backtrack is to change - topchoice to a thread after the current thread (rather than before - as in the previous two functions), and then kill the current thread. - (It amuses me that destroying a choicepoint, as in choiceahead(), - is more complicated than either visiting a choicepoint or creating a - choicepoint. That's how much work it can take to avoid a memory leak.) - In this case, choiceback won't return in the normal fashion. */ - if(topchoice->refcount > 1) - { - /* The Threaded INTERCAL standard states that if other threads are using - the choicepoint, a GO BACK should cause the thread it's in to be - killed. (Of course, if it's stale, it should just have been removed.)*/ - killthread(); - return; - } - topchoice->next = ickmt_cur->next; - ickmt_cur->next = topchoice; - topchoice = topchoice->choicepoint; - if(ickmt_cur==ickmt_prev) ickmt_prev = ickmt_cur->next; - choicing = 2; /* Tells killthread to set it back to 0 */ - killthread(); -} - -/********************************************************************** - * - * This function is called when two COME FROMs reference the same - * line at runtime. multicome1 is used in a multithread - * program; it forks the program. For multicome0, see cesspool.c. - * - *********************************************************************/ - -int multicome1(int errlineno, jmp_buf pc) -{ - /* Make a new thread just before the current one. Fake a PC in the - current thread within this function, change to the new thread, then - call nextthread. The upshot of all this is that all this thread's - data is stored in the new thread's state. Then, we have to copy - all this thread's current data to new locations. */ - static ickthread* newthread; - jmp_buf fakepc; - stashbox *isb, *isb2, *isbprev; - void* tvp; - array* a; - int prod, i, j; - newthread = malloc(sizeof(ickthread)); - if(!newthread) lose(E991, errlineno, (char *) NULL); - ickmt_prev->next = newthread; - newthread->next = ickmt_cur; - ickmt_cur = newthread; - - if(printflow && !choicing) printf("(fork)"); - - if(setjmp(fakepc) == 0) - { - memcpy(newthread->next->pc,fakepc,sizeof(jmp_buf)); - nextthread(pc, -1, 1); - } - /* So on the previous line: Save the value of pc as the program - counter of the new thread, and give a fake value for the - program value of the current thread (so it returns here, - not anywhere in the degenerated program). All that remains - is to duplicate all the data stored through pointers in the 'old' - thread (nextthread has changed ickmt_cur to point at the 'old' - thread). The original memory pointed to by these pointers is in - use storing the values in the 'new' thread, so the 'old' thread - needs new copies that it can modify independently. */ - - /* duplicate variables, forget indicators */ - i = onespotcount; - tvp = onespots; - onespots = malloc(i * sizeof *onespots); - if(!onespots) lose(E991, errlineno, (char *) NULL); - memcpy(onespots, tvp, i * sizeof *onespots); - i = twospotcount; - tvp = twospots; - twospots = malloc(i * sizeof *twospots); - if(!twospots) lose(E991, errlineno, (char *) NULL); - memcpy(twospots, tvp, i * sizeof *twospots); - i = tailcount; - tvp = tails; - tails = malloc(i * sizeof *tails); - if(!tails) lose(E991, errlineno, (char *) NULL); - memcpy(tails, tvp, i * sizeof *tails); - i = hybridcount; - tvp = hybrids; - hybrids = malloc(i * sizeof *hybrids); - if(!hybrids) lose(E991, errlineno, (char *) NULL); - memcpy(hybrids, tvp, i * sizeof *hybrids); - i = onespotcount; - tvp = oneforget; - oneforget = malloc(i * sizeof *oneforget); - if(!oneforget) lose(E991, errlineno, (char *) NULL); - memcpy(oneforget, tvp, i * sizeof *oneforget); - i = twospotcount; - tvp = twoforget; - twoforget = malloc(i * sizeof *twoforget); - if(!twoforget) lose(E991, errlineno, (char *) NULL); - memcpy(twoforget, tvp, i * sizeof *twoforget); - i = tailcount; - tvp = tailforget; - tailforget = malloc(i * sizeof *tailforget); - if(!tailforget) lose(E991, errlineno, (char *) NULL); - memcpy(tailforget, tvp, i * sizeof *tailforget); - i = hybridcount; - tvp = hyforget; - hyforget = malloc(i * sizeof *hyforget); - if(!hyforget) lose(E991, errlineno, (char *) NULL); - memcpy(hyforget, tvp, i * sizeof *hyforget); - - /* duplicate NEXT stack */ - tvp = next; - next = malloc(MAXNEXT * sizeof *next); - if(!next) lose(E991, errlineno, (char *) NULL); - memcpy(next, tvp, MAXNEXT * sizeof *next); - - /* duplicate data stored in arrays */ - j = tailcount; - while(j--) - { - a = tails+j; /* &(tails[j]) */ - if(!a->rank||!a->dims) continue; /* don't duplicate a deallocated array */ - tvp = a->dims; - /* Much of this code is paraphrased from the stashbox-copying code below, - which was in turn paraphrased from a section in cesspool.c I didn't - write. So any errors in this code are probably mine, but the algorithm - isn't. */ - a->dims = malloc(a->rank * sizeof(unsigned int)); - memcpy(a->dims, tvp, a->rank * sizeof(unsigned int)); - prod = !!a->rank; - i = a->rank; - while(i--) prod *= a->dims[i]; - tvp = a->data.tail; - a->data.tail = malloc(prod * sizeof(type16)); - if(!a->data.tail) lose(E991, errlineno, (char *) NULL); - memcpy(a->data.tail, tvp, prod * sizeof(type16)); - } - j = hybridcount; - while(j--) - { - a = hybrids+j; /* &(hybrids[j]) */ - if(!a->rank||!a->dims) continue; /* don't duplicate a deallocated array */ - tvp = a->dims; - /* Much of this code is paraphrased from the stashbox-copying code below, - which was in turn paraphrased from a section in cesspool.c I didn't - write. So any errors in this code are probably mine, but the algorithm - isn't. */ - a->dims = malloc(a->rank * sizeof(unsigned int)); - memcpy(a->dims, tvp, a->rank * sizeof(unsigned int)); - prod = !!a->rank; - i = a->rank; - while(i--) prod *= a->dims[i]; - tvp = a->data.hybrid; - a->data.hybrid = malloc(prod * sizeof(type32)); - if(!a->data.hybrid) lose(E991, errlineno, (char *) NULL); - memcpy(a->data.hybrid, tvp, prod * sizeof(type32)); - } - - /* allow for multithreading with choicepoints on the stack */ - if(!choicing && topchoice) - { - ickthread* icktp = topchoice; - while(icktp) - { - icktp->refcount++; - icktp = icktp->choicepoint; /* next choicepoint on the stack */ - } - /* The old thread's and new thread's choicepoint stack share - memory. This is pretty much necessary to handle backtracking - past a fork correctly. */ - } - - /* duplicate stashbox */ - isb2 = first; - isbprev = (stashbox*)NULL; - while(isb2) - { - isb = (stashbox*)malloc(sizeof(stashbox)); - if(!isb) lose(E991, errlineno, (char *) NULL); - memcpy(isb,isb2,sizeof(stashbox)); - if(isbprev) isbprev->next = isb; - isbprev = isb; - if(isb2==first) first = isb; /* change first only the first time round */ - if(isb->type == ONESPOT || isb->type == TWOSPOT) - { /* all copying already done */ - isb2 = isb->next; - continue; - } - /* Copy the stashed array. Much of this code is paraphrased from some - code in cesspool.c. In fact, it's the same, with a few idioms added - and variable names changed. So, although it's in this file, I can't - take the credit for it. */ - isb->save.a = (array*)malloc(sizeof(array)); - if(!isb->save.a) lose(E991, errlineno, (char *) NULL); - isb->save.a->rank = isb2->save.a->rank; - isb->save.a->dims = (unsigned int*)malloc(isb2->save.a->rank * - sizeof(unsigned int)); - if(!isb->save.a->dims) lose(E991, errlineno, (char *) NULL); - memcpy(isb->save.a->dims, isb2->save.a->dims, - isb2->save.a->rank * sizeof(unsigned int)); - prod = !!isb2->save.a->rank; /* I use this idiom often enough in the - code produced by my optimizer that I - may as well use it here. */ - i = isb2->save.a->rank; - while(i--) prod *= isb2->save.a->dims[i]; - if(isb2->type == TAIL) - { - isb->save.a->data.tail = (type16*)malloc(prod * sizeof(type16)); - if(!isb->save.a->data.tail) lose(E991, errlineno, (char *) NULL); - memcpy(isb->save.a->data.tail, isb2->save.a->data.tail, - prod * sizeof(type16)); - } - else - { - isb->save.a->data.hybrid = (type32*)malloc(prod * sizeof(type32)); - if(!isb->save.a->data.hybrid) lose(E991, errlineno, (char *) NULL); - memcpy(isb->save.a->data.hybrid, isb2->save.a->data.hybrid, - prod * sizeof(type32)); - } - isb2 = isb->next; - } - return 1; /* Tell the degenerated program to look for yet - another COME FROM */ -} - -/********************************************************************** - * - * These functions do the multithreading, using setjmp and longjmp - * to save the program counter. ickmtinit sets up the first - * thread, and nextthread changes to the next thread in the - * sequence. (Note that nextthread rarely actually returns). The - * code makes each command atomic, so that ONCE and AGAIN appear - * to the user to be atomic operations. - * - *********************************************************************/ - -ickthread* ickmt_cur; /* define ickmt_cur */ -ickthread* ickmt_prev; /* define ickmt_prev */ - -void ickmtinit(void) -{ - ickmt_cur = malloc(sizeof(ickthread)); - if(!ickmt_cur) lose(E991, 1, (char *) NULL); - ickmt_prev = ickmt_cur; - ickmt_cur->next = ickmt_cur; - topchoice = (ickthread*) NULL; /* No choicepoints */ -} - -/* Destroys the current thread, and switches to the next thread. - If there are no threads left, terminates the program using exit(0). */ -void killthread(void) -{ - static jmp_buf dummy; - stashbox* isb, *isbi; - int i; - - if(printflow&&!choicing) printf("(kill)"); - - /* Deallocate the current thread's data */ - i=tailcount; - while(i--) - { /* free tail data */ - if(!tails[i].rank||!tails[i].dims) continue; /* already free */ - free(tails[i].dims); - free(tails[i].data.tail); - } - i=hybridcount; - while(i--) - { /* free hybrid data */ - if(!hybrids[i].rank||!hybrids[i].dims) continue; /* already free */ - free(hybrids[i].dims); - free(hybrids[i].data.hybrid); - } - free(onespots); free(twospots); free(tails); free(hybrids); - free(oneforget); free(twoforget); free(tailforget); free(hyforget); - free(next); /* Free NEXT stack */ - if(!choicing) while(topchoice) choiceahead(); - /* The above line will mark each of the choicepoints as no longer being - used by this thread, and free them if neccesary. */ - isbi = first; - while(isbi) /* Free stash */ - { - isb=isbi->next; - if(isbi->type == TAIL || isbi->type == HYBRID) - { - free(isbi->save.a->dims); - if(isbi->type == TAIL) - free(isbi->save.a->data.tail); - else - free(isbi->save.a->data.hybrid); - } - free(isbi); - isbi=isb; - } - - ickmt_prev->next = ickmt_cur->next; - if(ickmt_cur->next == ickmt_cur) - { - free(ickmt_cur); - exit(0); - } - else - { - /* We need to run about half of nextthread. So we pass in a 2 for - flags and tell it to skip the first half. */ - free(ickmt_cur); - ickmt_cur = ickmt_prev; - nextthread(dummy, -1, 2); /* dummy is not used by nextthread */ - lose(E778, -1, (char *) NULL); /* nextthread does not return */ - } -} - -/* This function does not return in the normal fashion, but by a nonlocal - goto to a mysterious location, possibly in multicome1 but possibly in - the degenerated code. From the point of view of libickmt.a, we're going - to a piece of code that doesn't even exist yet! The general ugliness of - INTERCAL multithreading pulls out all the stops when it comes to using - unusual and confusing C control structures. It is important to remember - that longjmp clobbers all auto variables that have changed since the - corresponding setjmp. */ - -/* In this Threaded INTERCAL implementation, data is saved in a linked ring - of threads. A thread runs for a command, then all the data pointers are - changed, saving the old ones. This is an improvement on an earlier attempt - of mine in which the values themselves were copied, but is still less - efficient than Malcom Ryan's method (which didn't involve copying things - about except when forking). However, I justify this by saying that it leaves - as much existing code as possible untouched, which is helpful for single- - thread compatibility, modifying the code in feh.c without an understanding - of multithread issues, and because I'm lazy. It also makes the rest of the - program shorter. */ -void nextthread(jmp_buf pc, int errlineno, int flags) -{ /* flags | 1 means save this thread. - flags | 2 means load the next thread. - flags | 4 means don't change thread. */ - if(errlineno > -1 && ickmt_cur->next == ickmt_cur && !choicing) longjmp(pc,1); - /* If we only have 1 thread, just continue with it. Otherwise: */ - - if(!(flags&1)) goto advancethread; - /* OK, so I've spaghettified this procedure slightly by using goto - instead of if. But I was so deep into figuring out setjmp/longjmp, - a goto seemed crystal-clear by comparison. */ - - /* save variables */ - ickmt_cur->varforget[0] = onespots; - ickmt_cur->varforget[1] = twospots; - ickmt_cur->varforget[2] = tails; - ickmt_cur->varforget[3] = hybrids; - ickmt_cur->varforget[4] = oneforget; - ickmt_cur->varforget[5] = twoforget; - ickmt_cur->varforget[6] = tailforget; - ickmt_cur->varforget[7] = hyforget; - - /* save NEXT stack */ - ickmt_cur->nextstack = next; - ickmt_cur->nextpointer = nextindex; - - /* save stashbox */ - ickmt_cur->sb = first; - - /* save choicepoints */ - if(!choicing) ickmt_cur->choicepoint = topchoice; - - /* save comefrom information */ - memcpy(ickmt_cur->cjb, cjb, sizeof(jmp_buf)); - ickmt_cur->ccfc = ccfc; - ickmt_cur->skipto = skipto; - - /* save program counter */ - memcpy(ickmt_cur->pc, pc, sizeof(jmp_buf)); - /* And another thing about setjmp/longjmp. A jmp_buf - acts like a structure that passes itself around by - reference. However, it cannot be assigned, although - just about everything else in C can be, although it - can be copied with memcpy (what I'm doing in the line - above - remember it passes itself around by reference). - Generally speaking, it's some sort of array, - even though some implementors use a 1-element array. - The exact representation of jmp_buf is one of the most - implementation-dependent things in C (I've seen both - a 1-element array of structure and an int[12].) */ - - advancethread: - /* change thread */ - if(!(flags&4)) - { - ickmt_prev = ickmt_cur; - ickmt_cur = ickmt_cur->next; - } - - if(!(flags&2)) goto returnjmp; - - /* load variables */ - onespots = ickmt_cur->varforget[0]; - twospots = ickmt_cur->varforget[1]; - tails = ickmt_cur->varforget[2]; - hybrids = ickmt_cur->varforget[3]; - oneforget = ickmt_cur->varforget[4]; - twoforget = ickmt_cur->varforget[5]; - tailforget = ickmt_cur->varforget[6]; - hyforget = ickmt_cur->varforget[7]; - - /* load NEXT stack */ - next = ickmt_cur->nextstack; - nextindex = ickmt_cur->nextpointer; - - /* load choicepoints */ - if(!choicing) topchoice = ickmt_cur->choicepoint; - - /* load stashbox */ - first = ickmt_cur->sb; - - /* load comefrom information */ - memcpy(cjb, ickmt_cur->cjb, sizeof(jmp_buf)); - ccfc = ickmt_cur->ccfc; - skipto = ickmt_cur->skipto; - - returnjmp: - /* return to the new current thread's program counter */ - if(choicing==2) choicing = 0; - longjmp(ickmt_cur->pc, 1); -} diff --git a/yuk.c b/yuk.c deleted file mode 100644 index da79931..0000000 --- a/yuk.c +++ /dev/null @@ -1,761 +0,0 @@ -/**************************************************************************** - -NAME - yuk.c -- C-INTERCAL debugger and profiler code, linked into programs. - -DESCRIPTION - File linked into programs as a debugger or profiler. - -LICENSE TERMS - Copyright (C) 2006 Alex Smith - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - -****************************************************************************/ -#include -#include -#include -#include -#include -#include - -#define YUKDEBUG 1 - -#include "yuk.h" -#include "lose.h" -#include "sizes.h" -#include "abcess.h" - -#if YPTIMERTYPE == 4 -#include -#endif - -extern signed char onewatch[]; -extern signed char twowatch[]; -extern type16 oneold[]; -extern type32 twoold[]; - -int yuklines = 0; -int yukloop = 0; -int yukcommands = 0; /* these 3 lines because externs must be defined - somewhere */ -/* Global variable storage types: - static: limited to the file - unadorned: defining an extern - extern: defined elsewhere (unless initialised) */ - -static char buf[20]; - -static sig_atomic_t singlestep = 1; /* if 0, run until a breakpoint */ -static sig_atomic_t writelines = 1; /* whether to display executed lines onscreen */ -static int breakpoints[80]; /* initialised to all 0s. Breakpoint locations */ -static int nbreakpoints = 1; /* how many breakpoints we have */ -static int monitors[80]; /* monitors give a message when program flow passes them */ -static int nmonitors = 0; -static int untilnext = -1; /* NEXTING level to break the program at */ -static int firstrun = 1; /* first time an interactive command point is reached */ -static int yukerrcmdg = -1; /* the aboff that indicates an error in the 'g' command */ - -static yptimer tickcount; /* yptimer of last run */ -static int lastaboff = 0; /* last value of aboff */ - -void handlesigint(int i) -{ /* this is a signal handler, so can't do much */ - singlestep = 1; - writelines = 1; - (void) i; /* we're ignoring our argument */ -} - -#if YPTIMERTYPE==1 || YPTIMERTYPE==2 -yptimer yukgettimeofday() -{ - static struct timeval tp; - yptimer temp; - gettimeofday(&tp,0); - temp=(yptimer)tp.tv_usec + - (yptimer)tp.tv_sec * (yptimer)1000000LU; - /* here we make use of unsigned wraparound. In the case - YPTIMERTYPE == 1, it seems quite likely that we're going - to wraparound, but because everything is cast to the - unsigned integral type yptimer, we get a value that will - wraparound in such a way that - will give us the correct - time interval. */ - return temp; -} -#elif YPTIMERTYPE == 4 -yptimer yuktimes() -{ - static struct tms tp; - times(&tp); - return tp.tms_utime + tp.tms_stime; -} -#endif /* YPTIMERTYPE 4 */ - -void yukterm(void) -{ - int i,lastline,thisline,inrow; - yptimer avgtime,avgtime2; - if(yukopts==2) puts("Program ended without error."); - if(!(yukopts&1)) return; - /* Print profiling information */ - puts("Profiling information saved to \"yuk.out\"."); - freopen("yuk.out","w",stdout); - i=-1; - lastline=-1; - while(++i.\n"); - puts("For help on yuk, type ?.\n"); - } - i=nbreakpoints; - broken=0; - while(i--) broken|=breakpoints[i]==lineofaboff[aboff]; - if(yukloop&&broken&&*breakpoints!=lineofaboff[aboff]) broken=0; - if(broken) - { - if(*breakpoints!=lineofaboff[aboff]) - printf("Breakpoint hit at line %d:\n",lineofaboff[aboff]); - singlestep=1; - } - else - { - i=nmonitors; - while(i--) broken|=monitors[i]==lineofaboff[aboff]; - if(yukloop) broken=0; - if(broken) printf("Command flowed past line %d:\n",lineofaboff[aboff]); - } - if(nextindex <= untilnext) - { - broken = 1; - singlestep = 1; - } - if(!broken&&yukerrcmdg==aboff) - { - singlestep = 1; - puts("There are no commands on that line."); - /* To the user, nothing will have happened but the error message! */ - } - i=-1; - while(++i,1) - { - if(yukvars[i].vartype==YUKEND) break; - if(yukvars[i].vartype==ONESPOT) - { - if(onewatch[yukvars[i].intername]) - { - if(onespots[yukvars[i].intername]!=oneold[yukvars[i].intername]&& - onewatch[yukvars[i].intername]>1) - { - oneold[yukvars[i].intername]=onespots[yukvars[i].intername]; - if(onewatch[yukvars[i].intername]==2||!onespots[yukvars[i].intername]) - { - printf(onewatch[yukvars[i].intername]==2? - "Variable .%d changed.\n":"Variable .%d became 0.\n", - yukvars[i].extername); - broken=1; singlestep=1; - } - } - if(writelines||broken) - { - printf(".%d is:\n",yukvars[i].extername); - pout(onespots[yukvars[i].intername]); - } - } - } - if(yukvars[i].vartype==TWOSPOT) - { - if(twowatch[yukvars[i].intername]) - { - if(twospots[yukvars[i].intername]!=twoold[yukvars[i].intername]&& - twowatch[yukvars[i].intername]>1) - { - twoold[yukvars[i].intername]=twospots[yukvars[i].intername]; - if(twowatch[yukvars[i].intername]==2||!twospots[yukvars[i].intername]) - { - printf(twowatch[yukvars[i].intername]==2? - "Variable :%d changed.\n":"Variable :%d became 0.\n", - yukvars[i].extername); - broken=1; singlestep=1; - } - } - if(writelines||broken) - { - printf(":%d is:\n",yukvars[i].extername); - pout(twospots[yukvars[i].intername]); - } - } - } - } - if(writelines||broken) - { - /* write line that we're on */ - printf("%5d:\t%s\n",lineofaboff[aboff],text); - /* write command within line that we're on */ - tempcmd=aboff; - while(tempcmd&&lineofaboff[--tempcmd]==lineofaboff[aboff]); - printf("On C%d: Abstained %d time%s\n",aboff?aboff-tempcmd:1, - abstained[aboff]-yukloop,abstained[aboff]-yukloop==1?".":"s."); - } - if(singlestep) - { - signal(SIGINT,handlesigint); /* placing this line here means that a rapid - ^C^C will terminate the program, if it's - stuck in a loop somewhere */ - keeplooping = 1; - breakpoints[0] = 0; /* breakpoints[0] goes whenever a breakpoint is hit */ - untilnext = -1; - if(yukloop) - { /* reverse the abstentions that g caused */ - i = -1; - while(++i\tabstain once from all non-abstained commands on "); - puts("b\tset breakpoint at "); - puts("c\tcontinue execution until a breakpoint is reached"); - puts("d\tdelete breakpoint at "); - puts("e\texplain the main expression on "); - puts("f\tstop producing messages when commands on are run"); - puts("g\tchange currently executing command to the first command"); - puts("\ton or the next command if already on "); - puts("h\tlist 10 lines either side of the current line"); - puts("i\tignore a variable"); - puts("j\tremember a variable"); - puts("k\tcontinue until we RESUME back to the current nexting level"); - puts("\t(that is, step unless we are on a NEXT, in which case execute"); - puts("\tuntil a RESUME or FORGET back to the same or smaller NEXT stack)"); - puts("l\tlist 10 lines either side of "); - puts("m\tproduce a message every time a command on is run"); - puts("n\tshow the NEXT stack"); - puts("o\tcontinue until we RESUME/FORGET below the current nexting level"); - puts("\tie until the NEXT stack becomes smaller than it is at present"); - puts("p\tdisplay the values of all onespot and twospot variables"); - puts("q\tabort execution"); - puts("r\treinstate once all abstained commands on "); - puts("s\tstep to the next line of code"); - puts("t\tcontinue until a breakpoint, displaying all lines executed"); - puts("u\texecute until just before is reached"); - puts("v\tshow value of variable every time a command is printed"); - puts("w\tshow the current line and current command"); - puts("x\tremove a variable view, breakchange, or breakzero"); - puts("y\tview variable every displayed line, and break on change"); - puts("z\tview variable every displayed line, and break on zero"); - puts("\tview the value of a onespot or twospot variable"); - puts("<\tset the value of a onespot or twospot variable"); - puts("*\tview the GNU General Public Licence"); - puts("?\tview this help screen"); - puts("@\tview this help screen"); - puts("Line numbers refer to lines of source code, not line labels."); - puts("Listings have (Axxxxxx) at the start of each line: this shows"); - puts("the abstention status of each command on that line."); - puts("The values of variables must be input in proper INTERCAL"); - puts("notation (i.e. ONE TWO THREE), and are output as butchered"); - puts("Roman numerals."); - puts("You can press ^C to break an executing program."); - break; - case 'q': - exit(0); - break; - case 'n': - i=nextindex; - if(!i) - { - puts("The NEXT stack is empty."); - } - else - { - puts("Commands NEXTED from:"); - while(i--) - { - /* write NEXT line */ - printf("%5d:\t%s\n",lineofaboff[next[i]-1], - textlines[lineofaboff[next[i]-1]]); - /* write NEXT command within line */ - tempcmd=next[i]; - while(tempcmd&&lineofaboff[--tempcmd]==lineofaboff[next[i]-1]); - printf("NEXTED from command C%d: Abstained %d time%s\n",next[i]-1? - next[i]-1-tempcmd:1,abstained[next[i]-1], - abstained[next[i]-1]==1?".":"s."); - } - } - break; - case 'w': - /* write line that we're on */ - printf("%5d:\t%s\n",lineofaboff[aboff],text); - /* write command within line that we're on */ - tempcmd=aboff; - while(tempcmd&&lineofaboff[--tempcmd]==lineofaboff[aboff]); - printf("On C%d: Abstained %d time%s\n",aboff?aboff-tempcmd:1,abstained[aboff], - abstained[aboff]==1?".":"s."); - break; - case 'p': - i=-1; - while(++i,1) - { - if(yukvars[i].vartype==YUKEND) break; - if(yukvars[i].vartype==ONESPOT) - { - printf("Variable .%d is:\n",yukvars[i].extername); - pout(onespots[yukvars[i].intername]); - } - if(yukvars[i].vartype==TWOSPOT) - { - printf("Variable :%d is:\n",yukvars[i].extername); - pout(twospots[yukvars[i].intername]); - } - } - break; - case '.': - case ':': - sscanf(buf+1,"%d",&templine); - if(templine<1) - { - puts("Don't know which variable you mean."); - break; - } - i=-1; - temp=0; - while(++i,!temp) - { - if(yukvars[i].vartype==YUKEND) break; - if((*buf=='.'&&yukvars[i].vartype==ONESPOT)|| - (*buf==':'&&yukvars[i].vartype==TWOSPOT)) - { - if(yukvars[i].extername==templine) - { - temp=1; - if(yukvars[i].vartype==ONESPOT) - { - pout(onespots[yukvars[i].intername]); - puts(oneforget[yukvars[i].intername]? - "This variable is currently ignored.": - "This variable is currently remembered."); - } - if(yukvars[i].vartype==TWOSPOT) - { - pout(twospots[yukvars[i].intername]); - puts(twoforget[yukvars[i].intername]? - "This variable is currently ignored.": - "This variable is currently remembered."); - } - } - } - } - if(temp) break; - puts("That variable is not in the program."); - break; - case 'v': - case 'x': - case 'y': - case 'z': - if(buf[1]!='.'&&buf[1]!=':') - { - puts("This command only works on onespot and twospot variables."); - break; - } - sscanf(buf+2,"%d",&templine); - if(templine<1) - { - puts("Don't know which variable you mean."); - break; - } - i=-1; - temp=0; - while(++i,!temp) - { - if(yukvars[i].vartype==YUKEND) break; - if(yukvars[i].extername==templine) - { - if(buf[1]=='.'&&yukvars[i].vartype==ONESPOT) - { - if(*buf=='v') onewatch[yukvars[i].intername]=1; - if(*buf=='x') onewatch[yukvars[i].intername]=0; - if(*buf=='y') onewatch[yukvars[i].intername]=2; - if(*buf=='z') onewatch[yukvars[i].intername]=3; - oneold[yukvars[i].intername]=onespots[yukvars[i].intername]; - temp=1; - } - if(buf[1]==':'&&yukvars[i].vartype==TWOSPOT) - { - if(*buf=='v') twowatch[yukvars[i].intername]=1; - if(*buf=='x') twowatch[yukvars[i].intername]=0; - if(*buf=='y') twowatch[yukvars[i].intername]=2; - if(*buf=='z') twowatch[yukvars[i].intername]=3; - twoold[yukvars[i].intername]=twospots[yukvars[i].intername]; - temp=1; - } - } - } - if(!temp) - { - puts("That variable is not in the program."); - break; - } - if(*buf=='v') puts("Set a normal variable view."); - if(*buf=='x') puts("Removed all views from that variable."); - if(*buf=='y') puts("Set a breakchange variable view."); - if(*buf=='z') puts("Set a breakzero variable view."); - break; - case 'i': - case 'j': - if(buf[1]!='.'&&buf[1]!=':'&&buf[1]!=','&&buf[1]!=';') - { - puts("That isn't a real sort of variable."); - break; - } - sscanf(buf+2,"%d",&templine); - if(templine<1) - { - puts("Don't know which variable you mean."); - break; - } - i=-1; - temp=0; - while(++i,!temp) - { - if(yukvars[i].vartype==YUKEND) break; - if((buf[1]=='.'&&yukvars[i].vartype==ONESPOT)|| - (buf[1]==':'&&yukvars[i].vartype==TWOSPOT)|| - (buf[1]==','&&yukvars[i].vartype==TAIL)|| - (buf[1]==';'&&yukvars[i].vartype==HYBRID)) - { - if(yukvars[i].extername==templine) - { - temp=1; - if(yukvars[i].vartype==ONESPOT) - oneforget[yukvars[i].intername]=*buf=='i'; - if(yukvars[i].vartype==TWOSPOT) - twoforget[yukvars[i].intername]=*buf=='i'; - if(yukvars[i].vartype==TAIL) - tailforget[yukvars[i].intername]=*buf=='i'; - if(yukvars[i].vartype==HYBRID) - hyforget[yukvars[i].intername]=*buf=='i'; - } - } - } - if(temp) - { - if(*buf=='i') - puts("Variable ignored."); - else - puts("Variable remembered."); - break; - } - puts("That variable is not in the program."); - break; - case '<': - if(buf[1]!='.'&&buf[1]!=':') - { - puts("You cannot set that sort of variable (if it exists at all)."); - break; - } - sscanf(buf+2,"%d",&templine); - if(templine<1) - { - puts("Don't know which variable you mean."); - break; - } - i=-1; - temp=0; - while(++i,!temp) - { - if(yukvars[i].vartype==YUKEND) break; - if((buf[1]=='.'&&yukvars[i].vartype==ONESPOT)|| - (buf[1]==':'&&yukvars[i].vartype==TWOSPOT)) - { - if(yukvars[i].extername==templine) - { - temp=1; - if(yukvars[i].vartype==ONESPOT) - onespots[yukvars[i].intername]=pin(); - if(yukvars[i].vartype==TWOSPOT) - twospots[yukvars[i].intername]=pin(); - /* note that when debugging, you can set an - ignored variable */ - } - } - } - if(temp) break; - puts("That variable is not in the program."); - break; - case 'g': - sscanf(buf+1,"%d",&templine); - if(!templine) - { - puts("Don't know which line you mean."); - break; - } - breakpoints[0] = templine; - yukloop = 1; - /* This is implemented by incrementing all ABSTAIN counts, - even the normally immutable ones on GIVE UP lines, setting - a temporary breakpoint ([0]) on the line given, and running the - program. When the breakpoint is hit singlestep will see that - yukloop is set (its purpose is to cause the program to go back - to the start when it reaches the end) and decrement all ABSTAIN - counts, putting the commands back the way they were. We set an error - breakpoint on this line in case the user is trying to jump to a - line with no commands (although this debugger command is called - 'g', would I dare to describe this as a GOTO?) */ - i = -1; - while(++i=80) lose(E811,emitlineno,(char*)NULL); - } - else - puts("Don't know which line you mean."); - break; - case 'd': - sscanf(buf+1,"%d",&templine); - if(templine) - { - printf("All breakpoints removed from line %d.\n",templine); - i=nbreakpoints; - while(i--) if(templine==breakpoints[i]) - { - memmove(breakpoints+i,breakpoints+i+1,sizeof(int)*(nbreakpoints-i)); - nbreakpoints--; - } - } - else - puts("Don't know which line you mean."); - break; - case 'm': - sscanf(buf+1,"%d",&templine); - if(templine) - { - printf("Monitor set at line %d.\n",templine); - monitors[nmonitors++]=templine; - if(nmonitors>=80) lose(E811,emitlineno,(char*)NULL); - } - else - puts("Don't know which line you mean."); - break; - case 'f': - sscanf(buf+1,"%d",&templine); - if(templine) - { - printf("All monitors removed from line %d.\n",templine); - i=nmonitors; - while(i--) if(templine==monitors[i]) - { - memmove(monitors+i,monitors+i+1,sizeof(int)*(nmonitors-i)); - nmonitors--; - } - } - else - puts("Don't know which line you mean."); - break; - case 's': - singlestep=1; - writelines=1; - keeplooping=0; - break; - case 't': - singlestep=0; - writelines=1; - keeplooping=0; - break; - case 'u': - sscanf(buf+1,"%d",&templine); - if(templine) - { - breakpoints[0]=templine; - singlestep=0; - writelines=0; - keeplooping=0; - } - else - puts("Don't know which line you mean."); - break; - case 'e': - sscanf(buf+1,"%d",&templine); - if(!templine) - { - puts("Don't know which line you mean."); - break; - } - tempcmd=-1; - temp=0; - i=0; - while(++tempcmd=yuklines) templine=yuklines-22; - if(templine<1) templine=1; - i=templine; - while(i9) buf[temp-1]='!'; - if(temp==6) break; - } - } - printf("(A%s)%5d:\t%s\n",buf,i,textlines[i]); - i++; - } - break; - case '*': - system("more < " YUKCOPYLOC); /* display the GNU GPL copying conditions */ - break; - default: - puts("Not sure what you mean. Try typing ?."); - break; - } - } while(keeplooping); - } - } - firstrun=0; -} diff --git a/yuk.h b/yuk.h deleted file mode 100644 index 2b2f0c2..0000000 --- a/yuk.h +++ /dev/null @@ -1,99 +0,0 @@ -/* yuk.h - header file for yuk.c and debugging versions of ick-wrap.c */ -/* Copyright (C) Alex Smith 2006. See yuk.c for copyright conditions. - This file is GPL'd, and so can be freely redistributed but has - absolutely no warranty. */ - -#include -#define YUK(t,u) yukline(t,u) -#define YUKTERM yukterm() - -#define YUKEND 5 - -extern void yukline(int,int); -extern void yukterm(void); - -extern int abstained[]; -extern int yukopts; -extern int lineno; -extern int yuklines; -extern int yukcommands; -extern char *textlines[]; -extern int lineofaboff[]; -extern char *yukexplain[]; - -extern int yukloop; - -/* Defines that change the functions used for profiling */ -#define YPTIMERTYPE 2 -/* 0 to use clock(), 1 to use gettimeofday() and long, - 2 to use gettimeofday() and long long, 3 to use gethrtime() - 4 to use times() */ -/* Note: On many systems, 0's resolution is too low to produce any output - 1 and 2 produce the same output; use 2 if your system can handle - long long because the overflow is dealt with more simply - 3 is a system-specific function. If there are more system-specific - functions around that return more accurate times than the others - used here, it would improve the profiler on those systems. */ - -#if YPTIMERTYPE == 0 -#define YPTIMERTFORMAT "lu" -#define YPCOUNTERTFORMAT "lu" -#define YPTIMERTFORMATD "6" YPTIMERTFORMAT -#define YPTIMERSCALE CLOCKS_PER_SEC -#define YPGETTIME clock() -typedef unsigned long yptimer; -typedef unsigned long ypcounter; - -#elif YPTIMERTYPE == 1 -#define YPTIMERTFORMAT "lu" -#define YPCOUNTERTFORMAT "lu" -#define YPTIMERTFORMATD "6" YPTIMERTFORMAT -#define YPTIMERSCALE 1000000LU -#define YPGETTIME yukgettimeofday() -typedef unsigned long yptimer; -typedef unsigned long ypcounter; - -#elif YPTIMERTYPE == 2 -#define YPTIMERTFORMAT "llu" -#define YPCOUNTERTFORMAT "lu" -#define YPTIMERTFORMATD "6" YPTIMERTFORMAT -#define YPTIMERSCALE 1000000LU -#define YPGETTIME yukgettimeofday() -typedef unsigned long long yptimer; -typedef unsigned long ypcounter; - -#elif YPTIMERTYPE == 3 -#define YPTIMERTFORMAT "llu" -#define YPCOUNTERTFORMAT "lu" -#define YPTIMERTFORMATD "9" YPTIMERTFORMAT -#define YPTIMERSCALE 1000000000LLU -#define YPGETTIME gethrtime() -typedef unsigned long long yptimer; -typedef unsigned long ypcounter; - -#elif YPTIMERTYPE == 4 -#define YPTIMERTFORMAT "lu" -#define YPCOUNTERTFORMAT "lu" -#define YPTIMERTFORMATD "6" YPTIMERTFORMAT -#define YPTIMERSCALE CLK_TCK -#define YPGETTIME yuktimes() -typedef unsigned long yptimer; -typedef unsigned long ypcounter; - -#else -#error Invalid YPTIMERTYPE in yuk.h - -#endif /* YPTIMERTYPE cases */ - -extern yptimer ypexectime[]; -extern ypcounter ypexecount[]; -extern ypcounter ypabscount[]; - -typedef struct yukvar_tag -{ - int vartype; - int extername; - int intername; -} yukvar; - -extern yukvar yukvars[];