From: Maximiliano Curia Date: Fri, 18 Nov 2016 15:02:09 +0000 (+0000) Subject: Import ksyntax-highlighting_5.28.0.orig.tar.xz X-Git-Tag: archive/raspbian/5.70.0-1+rpi1~1^2^2^2~1 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success/%22http:/www.example.com/cgi/success?a=commitdiff_plain;h=9a6b3a1c9c8a277b0bc3c918c0ab178eef9d9fe9;p=ksyntax-highlighting.git Import ksyntax-highlighting_5.28.0.orig.tar.xz [dgit import orig ksyntax-highlighting_5.28.0.orig.tar.xz] --- 9a6b3a1c9c8a277b0bc3c918c0ab178eef9d9fe9 diff --git a/.arcconfig b/.arcconfig new file mode 100644 index 0000000..b9b60c8 --- /dev/null +++ b/.arcconfig @@ -0,0 +1,3 @@ +{ + "phabricator.uri" : "https://phabricator.kde.org/project/profile/152/" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..02b6adb --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.kdev4 +*~ +*.rej +*.orig +*.out +CMakeLists.txt.user +callgrind.* +heaptrack.* +po diff --git a/.kateconfig b/.kateconfig new file mode 100644 index 0000000..4442086 --- /dev/null +++ b/.kateconfig @@ -0,0 +1 @@ +// kate: space-indent on; indent-width 4; remove-trailing-spaces modified; diff --git a/.krazy b/.krazy new file mode 100644 index 0000000..02e434c --- /dev/null +++ b/.krazy @@ -0,0 +1,2 @@ +CHECKSETS kde5 +SKIP /autotests/input/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..0e8f2b0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,87 @@ +project(SyntaxHighlighting) + +cmake_minimum_required(VERSION 2.8.12) + +find_package(ECM 5.26.0 REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) +if(POLICY CMP0063) + cmake_policy(SET CMP0063 NEW) +endif() + +include(FeatureSummary) +include(GenerateExportHeader) +include(ECMSetupVersion) +include(ECMGenerateHeaders) +include(ECMGeneratePriFile) +include(ECMPackageConfigHelpers) +include(ECMPoQmTools) +include(ECMQtDeclareLoggingCategory) +include(KDEInstallDirs) +include(KDEFrameworkCompilerSettings) +include(KDECMakeSettings) + +set(KF5_VERSION "5.28.0") + +ecm_setup_version(${KF5_VERSION} + VARIABLE_PREFIX SyntaxHighlighting + VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/ksyntaxhighlighting_version.h" + PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfigVersion.cmake" +) + +# +# Dependencies +# +set(REQUIRED_QT_VERSION "5.6.0") +find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED COMPONENTS Core Gui Network Test) +find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE QUIET OPTIONAL_COMPONENTS Widgets XmlPatterns) +set_package_properties(Qt5 PROPERTIES URL "http://qt-project.org/") +set_package_properties(Qt5Widgets PROPERTIES PURPOSE "Example application.") +set_package_properties(Qt5XmlPatterns PROPERTIES PURPOSE "Compile-time validation of syntax definition files.") + +find_package(Perl REQUIRED) +set_package_properties(Perl PROPERTIES PURPOSE "Auto-generate PHP syntax definition files.") + +# +# Translations +# +if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") + ecm_install_po_files_as_qm(po) +endif() + +# +# Actually build the stuff +# +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +add_subdirectory(data) +add_subdirectory(src) +add_subdirectory(examples) +add_subdirectory(autotests) + +# +# CMake package config file generation +# +set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KF5SyntaxHighlighting") + +ecm_configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/KF5SyntaxHighlightingConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfig.cmake" + INSTALL_DESTINATION "${CMAKECONFIG_INSTALL_DIR}" +) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfigVersion.cmake" + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + COMPONENT Devel) + +install(EXPORT KF5SyntaxHighlightingTargets + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + FILE KF5SyntaxHighlightingTargets.cmake + NAMESPACE KF5::) + +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ksyntaxhighlighting_version.h" + DESTINATION "${KDE_INSTALL_INCLUDEDIR_KF5}" + COMPONENT Devel) +install(FILES org_kde_ksyntaxhighlighting.categories DESTINATION ${KDE_INSTALL_CONFDIR}) + +feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000..2d2d780 --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/KF5SyntaxHighlightingConfig.cmake.in b/KF5SyntaxHighlightingConfig.cmake.in new file mode 100644 index 0000000..d4cfc8a --- /dev/null +++ b/KF5SyntaxHighlightingConfig.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +find_package(Qt5 @Qt5Core_VERSION_MAJOR@.@Qt5Core_VERSION_MINOR@ NO_MODULE REQUIRED COMPONENTS Core Gui) + +include("${CMAKE_CURRENT_LIST_DIR}/KF5SyntaxHighlightingTargets.cmake") diff --git a/README.md b/README.md new file mode 100644 index 0000000..1eedc0a --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Syntax Highlighting + +Syntax highlighting engine for Kate syntax definitions + +## Introduction + +This is a stand-alone implementation of the Kate syntax highlighting engine. +It's meant as a building block for text editors as well as for simple highlighted +text rendering (e.g. as HTML), supporting both integration with a custom editor +as well as a ready-to-use QSyntaxHighlighter sub-class. + +## Syntax Definition Files + +This library uses Kate syntax definition files for the actual highlighting, +the file format is documented [here](https://docs.kde.org/stable5/en/applications/katepart/highlight.html). + +More than 250 syntax definition files are included, additional ones are +picked up from the file system if present, so you can easily extend this +by application-specific syntax definitions for example. + +## Out of scope + +To not turn this into yet another text editor, the following things are considered +out of scope: + +* code folding, beyond providing folding range information +* auto completion +* spell checking +* user interface for configuration +* management of text buffers or documents + +If you need any of this, check out [KTextEditor](https://api.kde.org/frameworks/ktexteditor/html/). diff --git a/add_license.sh b/add_license.sh new file mode 100755 index 0000000..00af0e5 --- /dev/null +++ b/add_license.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +find "$@" -name '*.h' -o -name '*.cpp' -o -name '*.qml' -o -name '*.c' | grep -v /3rdparty/ | grep -v /input | while read FILE; do + if grep -qiE "Copyright \(C\) [0-9, -]{4,} " "$FILE" ; then continue; fi + thisfile=`basename $FILE` + authorName=`git config user.name` + authorEmail=`git config user.email` + thisYear=`date +%Y` + cat < "$FILE".tmp +/* + Copyright (C) $thisYear $authorName <$authorEmail> + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +EOF + cat "$FILE" >> "$FILE".tmp + mv "$FILE".tmp "$FILE" +done + diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt new file mode 100644 index 0000000..5db5d42 --- /dev/null +++ b/autotests/CMakeLists.txt @@ -0,0 +1,34 @@ +configure_file(test-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/test-config.h) +configure_file(update-reference-data.sh.in ${CMAKE_CURRENT_BINARY_DIR}/update-reference-data.sh) + +add_executable(wildcardmatcher_test wildcardmatcher_test.cpp ${CMAKE_SOURCE_DIR}/src/lib/wildcardmatcher.cpp) +add_test(NAME wildcardmatcher_test COMMAND wildcardmatcher_test) +target_link_libraries(wildcardmatcher_test KF5SyntaxHighlighting Qt5::Test) + +add_executable(syntaxrepository_test syntaxrepository_test.cpp) +add_test(NAME syntaxrepository_test COMMAND syntaxrepository_test) +target_link_libraries(syntaxrepository_test KF5SyntaxHighlighting Qt5::Test) + +add_executable(theme_test theme_test.cpp) +add_test(NAME theme_test COMMAND theme_test) +target_link_libraries(theme_test KF5SyntaxHighlighting Qt5::Test) + +add_executable(testhighlighter_test testhighlighter.cpp) +add_test(NAME testhighlighter_test COMMAND testhighlighter_test) +target_link_libraries(testhighlighter_test KF5SyntaxHighlighting Qt5::Test) + +add_executable(htmlhighlighter_test htmlhighlighter_test.cpp) +add_test(NAME htmlhighlighter_test COMMAND htmlhighlighter_test) +target_link_libraries(htmlhighlighter_test KF5SyntaxHighlighting Qt5::Test) + +add_executable(folding_test foldingtest.cpp) +add_test(NAME folding_test COMMAND folding_test) +target_link_libraries(folding_test KF5SyntaxHighlighting Qt5::Test) + +add_executable(highlighter_benchmark highlighter_benchmark.cpp) +add_test(NAME highlighter_benchmark COMMAND highlighter_benchmark) +target_link_libraries(highlighter_benchmark KF5SyntaxHighlighting Qt5::Test) + +add_executable(repository_benchmark repository_benchmark.cpp) +add_test(NAME repository_benchmark COMMAND repository_benchmark) +target_link_libraries(repository_benchmark KF5SyntaxHighlighting Qt5::Test) diff --git a/autotests/folding/Dockerfile.fold b/autotests/folding/Dockerfile.fold new file mode 100644 index 0000000..95a81d3 --- /dev/null +++ b/autotests/folding/Dockerfile.fold @@ -0,0 +1,19 @@ +# LGPLv2+ example file + +# This is a comment +FROM ubuntu:14.04 +MAINTAINER James Turnbull # comment +ENV REFRESHED_AT 2014-06-01 + +RUN apt-get -yqq update +RUN apt-get install -yqq software-properties-common python-software-properties +RUN add-apt-repository ppa:chris-lea/redis-server +RUN apt-get -yqq update +RUN apt-get -yqq install redis-server redis-tools +RUN apt-get -yqq update # comment + +VOLUME [ "/var/lib/redis", "/var/log/redis/" ] + +EXPOSE 6379 + +CMD [] diff --git a/autotests/folding/Kconfig.fold b/autotests/folding/Kconfig.fold new file mode 100644 index 0000000..26df6be --- /dev/null +++ b/autotests/folding/Kconfig.fold @@ -0,0 +1,15 @@ +This is wrong but should not crash ] ) } ! + +# comment + +config BR2_PACKAGE_GAMMARAY + bool "gammaray" + depends on BR2_PACKAGE_QT5 + help + GammaRay Qt introspection probe. + second line of help, with correct indentation + third line underindented and thus wrong + default 'true' + +menu myMenumenu myMenu +endmenu diff --git a/autotests/folding/Makefile.fold b/autotests/folding/Makefile.fold new file mode 100644 index 0000000..1aae297 --- /dev/null +++ b/autotests/folding/Makefile.fold @@ -0,0 +1,25 @@ +# comment + +include Makefile.in + +.PHONY: all + +all: target + +foo = bar $(var) \ + $(baz) quux + +ifeq ($(CC),gcc) + bla=$(call func,param1,param2) +else + libs=$(normal_libs) +endif + +target1: + error + +target2: bla.cpp $@ + $(CC) bla.c -o bla.o + $(CC) bla.o $< \ + -o bla.exe + @echo "hello" diff --git a/autotests/folding/basic.markdown.fold b/autotests/folding/basic.markdown.fold new file mode 100644 index 0000000..f9a5bb3 --- /dev/null +++ b/autotests/folding/basic.markdown.fold @@ -0,0 +1,6 @@ +normal + +* item1 +still part of item + +normal text again diff --git a/autotests/folding/basic.xml.fold b/autotests/folding/basic.xml.fold new file mode 100644 index 0000000..1d6ab4b --- /dev/null +++ b/autotests/folding/basic.xml.fold @@ -0,0 +1,4 @@ + version="1.0" encoding="UTF-8"?> + attr1="a1"> + /> +> diff --git a/autotests/folding/complex.xml.fold b/autotests/folding/complex.xml.fold new file mode 100644 index 0000000..0c79e82 --- /dev/null +++ b/autotests/folding/complex.xml.fold @@ -0,0 +1,13 @@ + version="1.0" encoding="UTF-8"?> +language SYSTEM "language.dtd" +[ + + + +]> + attr1="a1" attr2="2.03" attr3="&entity;"> + /> +> + +> diff --git a/autotests/folding/cube.obj.fold b/autotests/folding/cube.obj.fold new file mode 100644 index 0000000..ef06c98 --- /dev/null +++ b/autotests/folding/cube.obj.fold @@ -0,0 +1,33 @@ +# cube.obj +# + +g cube + +v 0.0 0.0 0.0 +v 0.0 0.0 1.0 +v 0.0 1.0 0.0 +v 0.0 1.0 1.0 +v 1.0 0.0 0.0 +v 1.0 0.0 1.0 +v 1.0 1.0 0.0 +v 1.0 1.0 1.0 + +vn 0.0 0.0 1.0 +vn 0.0 0.0 -1.0 +vn 0.0 1.0 0.0 +vn 0.0 -1.0 0.0 +vn 1.0 0.0 0.0 +vn -1.0 0.0 0.0 + +f 1//2 7//2 5//2 +f 1//2 3//2 7//2 +f 1//6 4//6 3//6 +f 1//6 2//6 4//6 +f 3//3 8//3 7//3 +f 3//3 4//3 8//3 +f 5//5 7//5 8//5 +f 5//5 8//5 6//5 +f 1//4 5//4 6//4 +f 1//4 6//4 2//4 +f 2//1 6//1 8//1 +f 2//1 8//1 4//1 diff --git a/autotests/folding/cube.ply.fold b/autotests/folding/cube.ply.fold new file mode 100644 index 0000000..08d5f89 --- /dev/null +++ b/autotests/folding/cube.ply.fold @@ -0,0 +1,26 @@ +error before header + +ply +format ascii 1.0 +comment TODO this is a comment +element vertex 8 +property float x +property float y +property float z +element face 6 +property list uint int vertex_indices +end_header +-1 -1 -1 +1 -1 -1 +1 1 -1 +-1 1 -1 +-1 -1 1 +1 -1 1 +1 1 1 +-1 1 1 +4 0 1 2 3 +4 5 4 7 6 +4 6 2 1 5 +4 3 7 4 0 +4 7 3 2 6 +4 5 1 0 4 diff --git a/autotests/folding/cube.stl.fold b/autotests/folding/cube.stl.fold new file mode 100644 index 0000000..ae74fd9 --- /dev/null +++ b/autotests/folding/cube.stl.fold @@ -0,0 +1,30 @@ +solid cube_corner + facet normal 0.0 -1.0 0.0 + outer loop + vertex 0.0 0.0 0.0 + vertex 1.0 0.0 0.0 + vertex 0.0 0.0 1.0 + endloop + endfacet + facet normal 0.0 0.0 -1.0 + outer loop + vertex 0.0 0.0 0.0 + vertex 0.0 1.0 0.0 + vertex 1.0 0.0 0.0 + endloop + endfacet + facet normal -1.0 0.0 0.0 + outer loop + vertex 0.0 0.0 0.0 + vertex 0.0 0.0 1.0 + vertex 0.0 1.0 0.0 + endloop + endfacet + facet normal 0.577 0.577 0.577 + outer loop + vertex 1.0 0.0 0.0 + vertex 0.0 1.0 0.0 + vertex 0.0 0.0 1.0 + endloop + endfacet +endsolid diff --git a/autotests/folding/example.rmd.fold b/autotests/folding/example.rmd.fold new file mode 100644 index 0000000..154c31c --- /dev/null +++ b/autotests/folding/example.rmd.fold @@ -0,0 +1,39 @@ +--- +title: "test" +author: "me" +date: "07.10.2014" +output: html_document +--- + +This is a simple test document. It shows syntax highlighting switches between YAML (above), R blocks +```{r, echo=FALSE} +for (i in 1:10) { + if(i>=10) print(i) +} +# two blank lines below + +sessionInfo() +``` + +LaTeX equations, +$$ +h_{i}(t \mid q,C) = h_{0}(t) e^{\beta_{1}quality_{i} + \beta_{2}C_{iq}} +$$ + +and Markdown. A [link](http://example.com) in Markdown. + +Inline `r y <- 5 + x - sin(3)` R code. +Inline `y <- 5 + x - sin(3)` code. + + + Heading + ======= + + Sub-heading + ----------- + A list of editors: + * kate + * vim + * emacs + +*italic*, **bold**, `monospace` diff --git a/autotests/folding/firstNonSpace.c.fold b/autotests/folding/firstNonSpace.c.fold new file mode 100644 index 0000000..570ba90 --- /dev/null +++ b/autotests/folding/firstNonSpace.c.fold @@ -0,0 +1,7 @@ +#define 1 + #define 2 + #define 3 + #define 4 + #define 5 + #define tab + diff --git a/autotests/folding/folding.cpp.fold b/autotests/folding/folding.cpp.fold new file mode 100644 index 0000000..68e89c3 --- /dev/null +++ b/autotests/folding/folding.cpp.fold @@ -0,0 +1,15 @@ +/** + * multi-line comment + */ + +/* comment */ +{ { } { +//BEGIN +} +//END +} + +#if 0 +#elif 1 +#else +#endif diff --git a/autotests/folding/git-rebase.fold b/autotests/folding/git-rebase.fold new file mode 100644 index 0000000..43041bb --- /dev/null +++ b/autotests/folding/git-rebase.fold @@ -0,0 +1,32 @@ +pick 318aceb Add test for Makefile highlighting +p 4c7182a Add first batch of test files resurrected from Kate 4.6 +r 6f7d8a7 Sync xml files with KTextEditor +reword 8f0dbdc Add another batch of resurrected tests from Kate 4.6 +e 828de45 Add some more resurrected tests from Kate 4.6 +edit 6aa6264 Add simple coverage information for syntax definition tests +s 63df253 Add more syntax highlighting tests from Kate 4.6 +squash 3e7771f Add three more tests recovered from Kate 4.6 +f 5c7fd91 Add Kate 4.6 ASP syntax test +fixup 7a777ff Implement case-sensitive overrides for keyword rules +exec 2b16665 Implement dynamic DetectChar rules +drop dd808dc Quote captured strings we replace in regular expressions +x 0b703a3 Add a few more tests from the Kate 4.6 test suite + +# Rebase a27a854..0b703a3 onto a27a854 (13 command(s)) +# +# Commands: +# p, pick = use commit +# r, reword = use commit, but edit the commit message +# e, edit = use commit, but stop for amending +# s, squash = use commit, but meld into previous commit +# f, fixup = like "squash", but discard this commit's log message +# x, exec = run command (the rest of the line) using shell +# d, drop = remove commit +# +# These lines can be re-ordered; they are executed from top to bottom. +# +# If you remove a line here THAT COMMIT WILL BE LOST. +# +# However, if you remove everything, the rebase will be aborted. +# +# Note that empty commits are commented out diff --git a/autotests/folding/hello.exs.fold b/autotests/folding/hello.exs.fold new file mode 100644 index 0000000..cca72a1 --- /dev/null +++ b/autotests/folding/hello.exs.fold @@ -0,0 +1,11 @@ +parent = self() + +# Spawns an Elixir process (not an operating system one!) +spawn_link(fn -> + send parent, {:msg, "hello world"} +end) + +# Block until the message is received +receive do + {:msg, contents} -> IO.puts contents +end diff --git a/autotests/folding/highlight.ahdl.fold b/autotests/folding/highlight.ahdl.fold new file mode 100644 index 0000000..26924b4 --- /dev/null +++ b/autotests/folding/highlight.ahdl.fold @@ -0,0 +1,43 @@ +-- Test file for kate's syntax highlighting +Title "Test file"; + +-- BEGIN region (a region marker region) :) + +% multiline comment +goes on here % + +-- END + +FUNCTION FCT (Clk, Key) RETURNS (pulse); + +SUBDESIGN CDCLOCK2 +( +in : INPUT; -- go in +out[3..0] : OUTPUT; -- come out +) + +VARIABLE +start : soft; +usec[3..0] : node; + +BEGIN + +in = FCT(clock, some_key); -- senseless code + +-- comment +blubb = (blobb[] == H"3ff"); + +IF in THEN asdf +-- folde me +END IF; + +TABLE +-- missing code +END TABLE + + +END; + +-- hex, octal, binary +H"0" => B"1000000"; +O"01234567"; diff --git a/autotests/folding/highlight.asm-avr.fold b/autotests/folding/highlight.asm-avr.fold new file mode 100644 index 0000000..62e3ee9 --- /dev/null +++ b/autotests/folding/highlight.asm-avr.fold @@ -0,0 +1,75 @@ +;******************************************************************** +;* LED flasher: LED will flash with a X on/off ratio at PD6 +;* +;* NOTE: delay depends in the value of X, 1 is fast, 255 is slow +;* +;* No copyright ©1998 RES® * FREEWARE * +;* +;* NOTE: Connect a low current LED with a 1k resistor in serie from +;* Vdd to pin 11 of the MCU. (Or a normal LED with a 330ohm) +;* +;* RES® can be reached by email: digitalaudio@mail.com +;* or visit the website: http://home.wanadoo.nl/electro1/avr +;* +;* Version :1.0 +;* Date :12/26/98 +;* Author :Rob's ElectroSoft® +;* Target MCU :AT90S1200-12PI@4MHz +;******************************************************************** + +.include "1200def.inc" + + rjmp RESET ;reset handle + + +;* Long delay + +;* Register variables + + .def T1 = r1 + .def T2 = r2 + .def temp = r19 + +;* Code + +longDelay: + clr T1 ;T1 used as delay 2nd count + clr T2 ;T2 used as delay 3d count +delay_1: + dec T2 + brne delay_1 + dec T1 + brne delay_1 + dec temp ;temp must be preset as + brne delay_1 ; delay master count + ret + + +;* Resets the data direction register D + +;* Defines + + .equ led = 6 ;LED at PD6 + +;* Code + +RESET: + sbi DDRD, led ;connect LED to PORTD pin 6 + + +;* Main program + +;* This part will let the LED go on and off by X + +;* Register variables + + .equ X = 10 ;enter delaytime X + +flash: + sbi PORTD, led ;LED on + ldi temp, X ;X sec delay + rcall longDelay + cbi PORTD, led ;LED off + ldi temp, X ;X sec delay + rcall longDelay + rjmp flash ;another run diff --git a/autotests/folding/highlight.asm-nasm.fold b/autotests/folding/highlight.asm-nasm.fold new file mode 100644 index 0000000..a5da4d1 --- /dev/null +++ b/autotests/folding/highlight.asm-nasm.fold @@ -0,0 +1,27 @@ +; Example file for nasm.xml kate syntax file +; compile with `nasm example.asm -f elf -o example.o` +; and link with 'gcc example.o -o example` +; Public domain +; kate: hl Intel x86 (NASM); + +section .data + +hello dd 'Hello World', 0x0A, 0h +printf_param dd '%s', 0q + +section .text + +extern printf + +global main +main: + push ebp + mov ebp, esp + + push hello + push printf_param + call printf + + mov eax, 0b + leave + ret diff --git a/autotests/folding/highlight.asp.fold b/autotests/folding/highlight.asp.fold new file mode 100644 index 0000000..b938201 --- /dev/null +++ b/autotests/folding/highlight.asp.fold @@ -0,0 +1,58 @@ +<% 'kate: hl ASP; +if ( instr(request.servervariables("PATH_INFO"),"login.asp") <= 0 and instr(request.servervariables("PATH_INFO"),"inset") <= 0 and instr(request.servervariables("PATH_INFO"),"Data") <= 0 and instr(request.servervariables("PATH_INFO"),"dropDown") <= 0 ) then + Session("originalRequestedPage") = Request.ServerVariables("PATH_INFO") & "?" & Request.ServerVariables("QUERY_STRING") +end if + +function countRecords( rsToCount ) + numRecs = 0 + + do until rsToCount.eof + numRecs = numRecs + 1 + + rsToCount.movenext + loop + + rsToCount.close ' just to make sure nobody + ' tries to operate on the recordset, + ' which has already reached eof + + countRecords = numRecs +end function + +function unique( rs, sortColumn ) ' return unique instances of text in sortColumn within rs + dim sorted() + + redim sorted(1) + dim i + i = 0 + do until rs.eof + if (not find( rs(sortColumn), sorted )) then + redim preserve sorted(i+1) + sorted(i) = rs(sortColumn) + i = i + 1 + end if + rs.MoveNext + loop + + redim preserve sorted(i-1) ' the function will add an extra blank entry to the array + + rs.Close ' close the recordset - we'll be using it again - and reset i - well be using it again, too + + unique = sorted +end function + +sub testSub( variable ) ' do nothing impressive... + dim newVar + + newVar = variable + + if ( variable = true ) + response.end + else %>else %> + +

We are writing text.

+

<%=newVar%>

+

We have written text and outputted a variable.

+ +<% end if +end sub %> diff --git a/autotests/folding/highlight.awk.fold b/autotests/folding/highlight.awk.fold new file mode 100644 index 0000000..1aeb187 --- /dev/null +++ b/autotests/folding/highlight.awk.fold @@ -0,0 +1,28 @@ +#!/usr +# AWK hl test + +# BEGIN and END are also matched as patterns +BEGIN { + p = 0; +} + +/some pattern/ { + p++; +} + +# / inside brackets is not considered end of expression +# a loose division operator (/) is not mismatched as a pattern. +$1 =~ /[^abc/]def/ || b == 3 / 5 { + + gsub ( FILENAME ); + +} + +# TODO and FIXME also work in comments in Awk. + +# Also backslash in patterns works. +/\/usr\/bin\/awk/ { print "This is me"; } + +END { + print p; +} diff --git a/autotests/folding/highlight.bib.fold b/autotests/folding/highlight.bib.fold new file mode 100644 index 0000000..9d521ee --- /dev/null +++ b/autotests/folding/highlight.bib.fold @@ -0,0 +1,31 @@ +% test file for kate's bibtex syntax highlighting + +@Article{artikel, +author = {Me}, +title = {Something}, +journal = {JHEP}, +year = {2003}, +} + +@Book + +{ + +boek, +author = "Someone", +title = "Something", +journal = "Nucl. Phys. B", +year = "2003", +} + +This is ignored by BibTeX, no special highlighting +%This is not a comment, it is just ignored (thanks to the people in #latex) :) + +@string{test="lange string die ik niet vaak opnieuw wil intikken"} + +@PhdThesis{thesis, +author = {Me}, +title = {Dunno}, +school = {ITFA}, +year = {2005, hopefully}, +} diff --git a/autotests/folding/highlight.cmake.fold b/autotests/folding/highlight.cmake.fold new file mode 100644 index 0000000..67b67d4 --- /dev/null +++ b/autotests/folding/highlight.cmake.fold @@ -0,0 +1,49 @@ +#this CMakeLists.txt doesn't do anything useful, but it shoudl demonstrate the cmake syntax highlighting +#Alexander Neundorf + +#ok this is a comment +#and another line +#a built-in command, it's bold black +ADD_DEFINITIONS(-Wall -Wctor-dtor-privacy -Woverloaded-virtual -Wno-long-long -pipe -fno-builtin -fno-exceptions) + +#and another function +INCLUDE_DIRECTORIES( +#comments are also highlighted inside function parameters +#variables are Qt::blue +${CMAKE_CURRENT_SOURCE_DIR}/../../lib/qt4/include/Qt +) + +# BEGIN defining a macro +MACRO(ECOS_ADD_EXECUTABLE _exe_NAME ) + +#special parameters are italic, see the STATIC in the next line +ADD_LIBRARY(${_exe_NAME} STATIC ${ARGN}) +#but not in the following line ? + ADD_LIBRARY(${_exe_NAME} STATIC ${ARGN}) +# it seems the kate highlighting file could need some love, Alex + + +#another command with a bunch of variables and special parameters + ADD_CUSTOM_COMMAND( + TARGET ${_exe_NAME} + PRE_LINK + COMMAND ${CMAKE_C_COMPILER} + ARGS -o ${_exe_NAME} +$\(${_exe_NAME}_SRC_OBJS\) -nostdlib -nostartfiles -Lecos/install/lib -Ttarget.ld + ) + +#add the created files to the make_clean_files + SET(ECOS_ADD_MAKE_CLEAN_FILES ${ECOS_ADD_MAKE_CLEAN_FILES};${_exe_NAME};) +#and another command... + SET_DIRECTORY_PROPERTIES( + PROPERTIES + ADDITIONAL_MAKE_CLEAN_FILES "${ECOS_ADD_MAKE_CLEAN_FILES}" + ) +ENDMACRO(ECOS_ADD_EXECUTABLE) +# END of macro + +#calling a self-defined function, variables are also Qt::blue here +ECOS_ADD_EXECUTABLE(${PROJECT_NAME} ${the_sources} ${qt4_moc_SRCS}) + + + diff --git a/autotests/folding/highlight.css.fold b/autotests/folding/highlight.css.fold new file mode 100644 index 0000000..f808543 --- /dev/null +++ b/autotests/folding/highlight.css.fold @@ -0,0 +1,49 @@ +/** + * This is a pseudo CSS file to test Kate's CSS syntax highlighting. + */ + +@import url("othersheet.css") screen, tv; + +body { + font-size: 15pt; + font-family: Verdana, Helvetica, "Bitstream Vera Sans", sans-serif; + margin-top: 0px; /* yet another comment */ + margin-bottom: 0px; + // this is no comment, it's just broken! + margin-left: 0px; + margin-right: 0px; +} + +.something +{ + margin-right: 0px; + color: #cdd; + color: #AAFE04; + color: rgb(10%,30%,43%); + background: maroon; +} + +a:hover { +} + +#header, +p.intro:first-letter, +p:lang(nl), +img[align="right"] +{ + border: 1px solid Qt::red !important; + -moz-border-radius: 15px; /* unknown properties render italic */ +} + +@media print { + + #header + { + display: none; + } + +} + +/* +TODO: add more tests, e.g. media +*/ diff --git a/autotests/folding/highlight.d.fold b/autotests/folding/highlight.d.fold new file mode 100644 index 0000000..44bcb09 --- /dev/null +++ b/autotests/folding/highlight.d.fold @@ -0,0 +1,195 @@ +/******** +* Highlight testing module. +* +* Do not attempt to run this! +***********/ +module highlighttest; +import X = null; + +/++ Pragma directives. DDoc + DDoc embedded items. Special Tokens. ++ ++ --- ++ // comment ++ #line 12 "hightlighttest.d" /* block comment */ ++ #line __LINE__ __FILE__ /++ embedded block comment +/ ++ ++ pragma /* */ (msg, "what?"); ++ pragma(/++ +/ lib, "insane.a"); ++ pragma(D_Custom_Extension, "custom data"); ++ --- ++/ + +/// version condition +version = X; +version (X) ; +version(linux) {} + +/// linkage +extern + (C) {} +extern : +; +extern (Windows) {} + +/// alias & typedef +alias int.min minint; +typedef int myint; + +int main(char[][] args) { + /// statements + if (1) {} + else {} + with (N) {x = B} + + /// attributes + auto x = 1; + static if (true) {} + void (in X, out Y) {} // NOTE: using in like this is rare, more common to use as an expression and no way to tell apart? + + /// deprecated + deprecated void fct (); + + /// types + void a; + ushort u; + int[uint] AA; + class C; + enum N : int { A = 5, B } + typeof(u) u2; + + /// expressions + x = cast(int) 55; + void* p = null; + p = cast(void*) new int; + x = 1 in AA; // NOTE: a THIRD use of in. How to detect?? + assert (true); + + /// libsymbols + string s = ""; + throw new Exception; + TypeInfo ti = typeid(int); + + /// tests + debug {} + debug (2) {} + debug (DSymb) {} + unittest {} + + /// scope (as attribute and as statement) + scope struct S; + scope (exit) {} + scope + (success) {} // NOTE: rules cannot match across new-lines + scope (failure) {} + + /// Properties + x = int.min; + s = (5-3).stringof; + + /// strings + s = r"raw string"; + s = x"00FF"; + s = \n \a; + s = \u1234; + s = \U12345678; + s = \& ; + char c = 'a'; + s = "abc 012 \" \n \x12 \u1234 \U12345678"; + s = `BQString '"`; + + /// region markers + //BEGIN x + //END x + + /// DDoc + /******* + * DDoc + * + * Section: + * New section. + * $(I italic) + *******/ + /+++++++ + + DDoc + + /+ + + +/ + +++++++/ + + // comments + // FIXME NOTE + /* comment */ + /+ comment /+ nested comment +/ +/ + + /// brace folding + { + } + + /** normal text + * --- + * .x; + * .. + * ... + * .... + * ..... + * _._ + * _e1 + * --- + */ + + /// float and int literals + int i; + real r; + ireal ir; + r = .0; + r = 0f; + ir = 0e0i; + ir = 0.fi; + r = 0.0e0; + r = 0xF.Fp0; + r = 0x_._p0_; + i = 5; + i = -1; + i = 0b10; + i = 0070; + i = 00; + i = 0xF0; + + /// ranges + int[] A; + i = A[1]; + A = A[0..$]; + A = A[0..0]; + A = A[0..length]; + + /// labels + label: + goto label; + + /// function, delegate + creal function () fp = function creal() { return 0f+0fi; }; + void delegate (in int i, lazy int b) dg = delegate void (int, int) {} + + /// in, out, body + // NOTE: highlighting in & out as statements here could be difficult + float F () + in {} + out (result) {} + body {} + + /// try, catch, finally + try { + throw new Exception("oh no... "); + } catch (Exception e) { + } finally { + } + + /// mixin + mixin("return false;").stringof; + + /// templates + macro; // what does this do? + template Tp (T) { + Tp t; + } + Tp!(int) y; +} diff --git a/autotests/folding/highlight.do.fold b/autotests/folding/highlight.do.fold new file mode 100644 index 0000000..83ae062 --- /dev/null +++ b/autotests/folding/highlight.do.fold @@ -0,0 +1,89 @@ +/* Test file for kate's stata syntax highlighting +*/ +*! version 1.2.0 2mar2003 E. Leuven +program define spellsplit + version 7 + syntax [anything], spell(varlist min=2 max=2) [ by(varlist)] + tokenize `spell' + local date0 `1' + local date1 `2' + local f0 : format `date0' + local f1 : format `date1' + + /* set default statistic */ + local current "mean" + + gettoken left anything : anything, match(prns) + while "`left'"!="" { + if "`prns'"!="" { + if !inlist("`left'","mean","sum") { + di as error "Statistic `left' not supported" + exit 198 + } + local current "`left'" + } + else { + local `current'vars ``current'vars' `left' + } + gettoken left anything : anything, match(prns) + } + if ("`meanvars'"!="") { + confirm var `meanvars' + unab meanvars : `meanvars' + } + if ("`sumvars'"!="") { + confirm var `sumvars' + unab sumvars : `sumvars' + } + + quietly { + g _count = 1 + local xvars `meanvars' `sumvars' _count + + /* create dummy by-var if no by option is specified */ + if "`by'"=="" { + tempvar by + g byte `by' = 1 + } + tempvar `xvars' `by' + + /* create negative for subtraction when spell ends */ + cap foreach v of varlist `xvars' { + g double ``v'' = -`v' + local txvars `txvars' ``v'' + } + cap foreach v of varlist `by' { + g double ``v'' = `v' + local txvars `txvars' ``v'' + } + + stack `date0' `xvars' `by' `date1' `txvars', into(`date0' `xvars' `by') clear + + /* calculate totals per date */ + cap foreach v of varlist `xvars' { + egen double ``v'' = sum(`v'), by(`by' `date0') + } + + /* unique dates only */ + by `by' `date0', sort: keep if _n==1 + + /* calculate totals (+ when spell starts - when ends) */ + sort `by' + cap foreach v of varlist `xvars' { + by `by': replace `v' = sum(``v'') + } + by `by': g `date1' = `date0'[_n + 1] + + drop if `date0'>`date1' + drop _stack + drop if _count==0 + order `by' `date0' `date1' `xvars' + format `date0' `f0' + format `date1' `f1' + + cap for var `meanvars': replace X = X/_count + + compress + } + +end diff --git a/autotests/folding/highlight.dox.fold b/autotests/folding/highlight.dox.fold new file mode 100644 index 0000000..ad907ab --- /dev/null +++ b/autotests/folding/highlight.dox.fold @@ -0,0 +1,227 @@ +This is a pseudo doxygen file to test Kate's doxyge syntax highlighting. + +Normal text, no HL. +=================== +a multiline comment may begin with a /*! */, too. That should work, +because it is the same "entrance rule". + +popping tests: +/** multiline */ end of doxygen HL mode +/*! multiline */ end of doxygen HL mode +//! singleline, where */ should be ignored! still doxygen HL mode +/// singleline, where */ should be ignored! still doxygen HL mode +///< singleline, where */ should be ignored! still doxygen HL mode +begin and end immediately: +/********/ actually no doxygen comment - used for "info boxes" :) +/**/ <-- it really works --- end of doxygen HL mode +/*!*/ end of doxygen HL mode + + +/** \code rest of line is normal comment HL */ end of doxygen HL mode +/** \code rest of line is normal comment HL + * comment HL mode + */ end of doxygen HL mode + + +/** \file aword rest of line is normal comment HL */ end of doxygen HL mode +/** \file */aword <-- pop! no doxygen HL mode +/** \file aword rest of line is normal comment HL + * comment HL mode + */ end of doxygen HL mode + + +/** \brief A short description */ end of doxygen HL mode +/** \brief */A <-- pop! end of doxygen HL mode +/** \brief A short description + * comment HL mode + */ end of doxygen HL mode + + +/** \page aword rest of line is string */ end of doxygen HL mode +/** \page */aword <-- pop! end of doxygen HL mode +/** \page aword rest of line is string + * comment HL mode + */ end of doxygen HL mode + + +/** \image aword aword rest of line is normal HL */ end of doxygen HL mode +/** \image aword */aword <-- pop! end of doxygen HL mode +/** \image */aword aword <-- pop! end of doxygen HL mode +/** \image aword aword rest of line is normal HL + * comment HL mode + */ end of doxygen HL mode + +Tests for HTML tags in doxygen HL mode: +======================================= +/** */ end of doxygen HL mode +/** */> end of doxygen HL mode +/** */'> end of doxygen HL mode +/** */b'> end of doxygen HL mode +/** */lubb'> end of doxygen HL mode +/** */blubb'> end of doxygen HL mode +/** */'blubb'> end of doxygen HL mode +/** */='blubb'> end of doxygen HL mode +/** */f='blubb'> end of doxygen HL mode +/** */href='blubb'> end of doxygen HL mode +/** */ end of doxygen HL mode +/** */> end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** */"blubb"> end of doxygen HL mode +/** */="blubb"> end of doxygen HL mode +/** */ref="blubb"> end of doxygen HL mode +/** */href="blubb"> end of doxygen HL mode +/** */ href="blubb"> end of doxygen HL mode +/** <*/a href="blubb"> end of doxygen HL mode + +//! */ stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! */ stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! <*/a href="blubb"> stay in doygen HL mode +//! stay in doygen HL +/** \code rest of line is normal comment HL */ end of doxygen HL mode +/** \code rest of */> end of doxygen HL mode +/** \code rest of */'> end of doxygen HL mode +/** \code rest of */blubb'> end of doxygen HL mode +/** \code rest of */'blubb'> end of doxygen HL mode +/** \code rest of end of doxygen HL mode +/** \code rest */"blubb"> of end of doxygen HL mode +/** \code rest */ref="blubb"> of end of doxygen HL mode +/** \code rest <*/a href="blubb"> of end of doxygen HL mode +/** \code rest of line is normal comment HL + * comment HL mode text + */ end of doxygen HL mode + + +/** \file aword rest of line is normal comment HL */ end of doxygen HL mode +/** \file awo*/rd end of doxygen HL mode +/** \file awo*/gnored_here>rd end of doxygen HL mode +/** \file awo<*/html_should_be_ignored_here>rd end of doxygen HL mode +/** \file a*/word end of doxygen HL mode +/** \file aword rest of line is normal comment HL + * comment HL mode + */ end of doxygen HL mode + + +/** \brief A short of description */ end of doxygen HL mode +/** \brief A short of */> end of doxygen HL mode +/** \brief A short of */blubb'> end of doxygen HL mode +/** \brief A short of */'blubb'> end of doxygen HL mode +/** \brief A short of */='blubb'> end of doxygen HL mode +/** \brief A short of */href='blubb'> end of doxygen HL mode +/** \brief A short of <*//a href='blubb'> end of doxygen HL mode +/** \brief A short */> of end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short */"blubb"> of end of doxygen HL mode +/** \brief A short */="blubb"> of end of doxygen HL mode +/** \brief A short */ref="blubb"> of end of doxygen HL mode +/** \brief A short of description + * comment HL mode + */ end of doxygen HL mode + + +/** \page aword A short of description */ end of doxygen HL mode +/** \page aword A short of */> end of doxygen HL mode +/** \page aword A short of */blubb'> end of doxygen HL mode +/** \page aword A short of */'blubb'> end of doxygen HL mode +/** \page aword A short of */='blubb'> end of doxygen HL mode +/** \page aword A short of */href='blubb'> end of doxygen HL mode +/** \page aword A short of <*//a href='blubb'> end of doxygen HL mode +/** \page aword A short */> of end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short */"blubb"> of end of doxygen HL mode +/** \page aword A short */="blubb"> of end of doxygen HL mode +/** \page aword A short */ref="blubb"> of end of doxygen HL mode +/** \page aword A short <*/a href="blubb"> of end of doxygen HL mode +/** \page aword A shor*/t of end of doxygen HL mode +/** \page awor*/d A short of end of doxygen HL mode +/** \page */aword A short of end of doxygen HL mode +/** \page aword A short of description + * comment HL mode + */ end of doxygen HL mode + + +/** \image aword aword rest of line is normal HL */ end of doxygen HL mode +/** \image aword aword rest of line is*/ end of doxygen HL mode +/** \image aword aword*/ end of doxygen HL mode +/** \image aword aw*/ord end of doxygen HL mode +/** \image aword */aword end of doxygen HL mode +/** \image aword*/ end of doxygen HL mode +/** \image awo*/rd end of doxygen HL mode +/** \image */aword end of doxygen HL mode +/** \ima*/ge end of doxygen HL mode +/** \image aword aword rest of line is normal HL + * comment HL mode + */ end of doxygen HL mode + +Some further tests for singlelinecomments (* / should not pop!) +=============================================================== +/// a singlelinecommment blubb blubb */. stay in doxygen HL mode +/// \code a singlelinecommment blubb b*/lubb. stay in doxygen HL mode +/// \code*/ a singlelinecommment blubb blubb. stay in doxygen HL mode +/// \code a singlelinecommment blubb blubb +/// \brief a descriptive text (string) stay in doxygen HL mode +/// \brief a descriptive text (string)*/ description should go on here +/// \brief a descriptive text */(string) description should go on here +/// \brief */a descriptive text (string) description should go on here +/// \ref aword a descriptive text (string) */ description should go on here +/// \ref aword a descriptive text (str*/ing) description should go on here +/// \ref aword a des*/criptive text (string) description should go on here +/// \ref aword*/ a descriptive text (string) description should go on here +/// \ref aw*/ord a descriptive text (string) description should go on here +/// \ref */aword a descriptive text (string) description should go on here + +HTML comment tests: +=================== +//! \ref word descriptive text (string) +normal HL mode. +//! \ref w descriptive text (string) +/** \ref word descriptive text (string) +normal HL mode. +/** \ref w + * normal doxygen HL mode. + */ + + +And final tests for a word: a single char: +=========================================== + +//! \ref word descriptive text (string) +//! \ref w descriptive text (string) + + +//! \image word1 word2 b descriptive text (string) +//! \image a word b descriptive text (string) + + +//! \brief A b c d e description should go on here + + +//! \file word rest of line is normal comment HL +//! \file a word rest of line is normal comment HL + +no doxygen HL mode here. +== END OF TESTFILE == diff --git a/autotests/folding/highlight.erl.fold b/autotests/folding/highlight.erl.fold new file mode 100644 index 0000000..5b485cb --- /dev/null +++ b/autotests/folding/highlight.erl.fold @@ -0,0 +1,68 @@ +% testing for the erlang syntax highlighter +% NOTE alerts work in comments to TODO ! + +% pragmas (show as keywords) +-module +-export +-define +-undef +-ifdef +-ifndef +-else +-endif +-include +-include_lib + +% key words +after begin case catch cond end fun if let of query receive all_true some_true + +% operators +div rem or xor bor bxor bsl bsr and band not bnot ++ - * / == /= =:= =/= < =< > >= ++ -- = ! <- + +% separators (show as functions) +( ) { } [ ] . : | || ; , ? -> # + +% functions - predefined (part of erlang module) - show as functions +abs accept alarm apply atom_to_list binary_to_list binary_to_term check_process_code +concat_binary date delete_module disconnect_node element erase exit float float_to_list +garbage_collect get get_keys group_leader halt hd integer_to_list is_alive is_atom is_binary +is_boolean is_float is_function is_integer is_list is_number is_pid is_port is_process_alive +is_record is_reference is_tuple length link list_to_atom list_to_binary list_to_float list_to_integer +list_to_pid list_to_tuple load_module loaded localtime make_ref module_loaded node nodes now +open_port pid_to_list port_close port_command port_connect port_control ports pre_loaded process_flag +process_info processes purge_module put register registered round self setelement size +spawn spawn_link spawn_opt split_binary statistics term_to_binary throw time tl trunc tuple_to_list +unlink unregister whereis + +% functions - inferred +module:function +function() + +% atoms (show as "char") +% begin with underscore, lowercase, contain numbers letters and @ - or anything between '' +middle_underscore +abc ab4d a@cd8 a@ +'And this is (\012) an atom \' Atoo' Variable 'atom again' + +% variables (begin with capital letter or underscore, contain numbers, letters and @) +_leadingUnderscore AbdD@ B45@c + +% this is a string +"a string sits between \" double quotes" atom "more string" + +% integers (decimal) +1. 234 $A + +% integers (specified base) +2#10101 34#567 + +% float +12.23 12.9e-67 12.8E+89 33.34e89 + +% and finally some real code, so we can see what it looks like... +-module(codetest). % everything is in a module +-export([fac/1]). % name and number of arguments - need this to be called outside of the module + +fac(N) when N > 0 -> N * fac(N-1); +fac(N) when N == 0 -> 1. diff --git a/autotests/folding/highlight.exu.fold b/autotests/folding/highlight.exu.fold new file mode 100644 index 0000000..84f561f --- /dev/null +++ b/autotests/folding/highlight.exu.fold @@ -0,0 +1,97 @@ +-- Test file for Kate's Euphoria syntax highlighting/code folding. +-- BEGIN region marker test + +-- code here + +-- END region marker test + +-- The N Queens Problem: +-- Place N Queens on an NxN chess board +-- such that they don't threaten each other. +constant N = 8 -- try some other sizes +constant ROW = 1, COLUMN = 2 +constant TRUE = 1, FALSE = 0 +type square(sequence x) +-- a square on the board + return length(x) = 2 +end type +type row(integer x) +-- a row on the board + return x >= 1 and x <= N +end type + +function threat(square q1, square q2) +-- do two queens threaten each other? + if q1[COLUMN] = q2[COLUMN] then + return TRUE + elsif q1[ROW] - q1[COLUMN] = q2[ROW] - q2[COLUMN] then + return TRUE + elsif q1[ROW] + q1[COLUMN] = q2[ROW] + q2[COLUMN] then + return TRUE + elsif q1[ROW] = q2[ROW] then + return TRUE + else + return FALSE + end if +end function + +function conflict(square q, sequence queens) +-- Would square p cause a conflict with other queens on board so far? + for i = 1 to length(queens) do + if threat(q, queens[i]) then + return TRUE + end if + end for + return FALSE +end function + +integer soln +soln = 0 -- solution number + +procedure print_board(sequence queens) +-- print a solution, showing the Queens on the board + integer k + position(1, 1) + printf(1, "Solution #%d\n\n ", soln) + for c = 'a' to 'a' + N - 1 do + printf(1, "%2s", c) + end for + puts(1, "\n") + for r = 1 to N do + printf(1, "%2d ", r) + for c = 1 to N do + if find({r,c}, queens) then + puts(1, "Q ") + else + puts(1, ". ") + end if + end for + puts(1, "\n") + end for + puts(1, "\nPress Enter. (q to quit) ") + while TRUE do + k = get_key() + if k = 'q' then + abort(0) + elsif k != -1 then + exit + end if + end while +end procedure + +procedure place_queen(sequence queens) +-- place queens on a NxN chess board +-- (recursive procedure) + row r -- only need to consider one row for each queen + if length(queens) = N then + soln += 1 + print_board(queens) + return + end if + r = length(queens)+1 + for c = 1 to N do + if not conflict({r,c}, queens) then + place_queen(append(queens, {r,c})) + end if + end for +end procedure diff --git a/autotests/folding/highlight.f90.fold b/autotests/folding/highlight.f90.fold new file mode 100644 index 0000000..2ea0f76 --- /dev/null +++ b/autotests/folding/highlight.f90.fold @@ -0,0 +1,181 @@ +! This file is an example to test the syntax highlighting file F.xml +! (for fortran 90 and F) + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! THIS IS AN EXAMPLE OF A MODULE ! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +module module_example + + ! use 'implicit none' when you want all variables to be declared + implicit none + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! PUBLICS AND PRIVATES + + ! In fortran 90 you can define your own operator + public :: operator(.norm.) + public :: operator(+) ! <-- you can also overload the usual operators + public :: factorial + public :: example_fn + + private :: point3d_add + private :: point3d_norm + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! USER-DEFINED TYPES... + + ! This is a definition to use in declarations of real variables, + ! parameters, etc. + integer, parameter, public :: kr = selected_real_kind(10) + + ! This is a user-defined type + type, public :: point3d + real(kind=kr) :: x, y, z + end type point3d + + ! This type is useless: it is only an example of type definition! + type, public :: example_type + complex(kind=kr) :: c ! <-- a complex number (two reals of kind kr)! + real, dimension(-10:10) :: & ! <-- this line does not end here! + r1, r2 ! <-- this is the final part of the previous line + real, pointer, dimension(:) :: pointer_to_array_of_real + real, dimension(:), pointer :: array_of_pointer_to_real + end type example_type + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! INTERFACES... + + ! Interface for the norm of a 3-D vector + interface operator(.norm.) + module procedure point3d_norm + end interface + + ! Interface for the operator '+' + interface operator(+) + module procedure point3d_add + end interface + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! SOME DECLARATIONS... + + ! A real number can be declared with the following line: + real(kind=kr) :: real_var1 + ! But if you are not interested on the precision of floating point numbers, + ! you can use simply: + real :: real_var2 + + ! An array can be declared in two ways: + real(kind=kr), dimension(1:10, -4:5), private :: a, b, c + real(kind=kr), private :: d(1:10, -4:5) + + ! This is a string with fixed lenght + character(len=10) :: str_var + + ! This is an allocatable array, which can be a target of a pointer + type(example_type), private, dimension(:), allocatable, target :: & + many_examples + +! Fortran 90 hasn't got its own preprocessor, it uses the C preprocessor! +#ifdef XXX +c <-- this is a comment in the old fortran 77 style (fixed form) +c This is a free form file, so we shouldn't use this kind of comments! +c But fortran 90 still understands fixed form, when parsing sources with +c the *.f extension. + c ! <-- this 'c' shouldn't be highlighted as a comment! +#endif + +contains + + + ! The sum of two points + pure function point3d_add(a, b) result(rs) + type(point3d) :: rs + type(point3d), intent(in) :: a, b + rs%x = a%x + b%x + rs%y = a%y + b%y + rs%z = a%z + b%z + end function point3d_add + + + ! The norm of a point + pure function point3d_norm(a) result(rs) + real(kind=kr) :: rs + type(point3d), intent(in) :: a + rs = sqrt(a%x * a%x + a%y * a%y + a%z * a%z) + end function point3d_norm + + + ! A simple recursive function + recursive function factorial(i) result (rs) + integer :: rs + integer, intent(in) :: i + if ( i <= 1 ) then + rs = 1 + elseelse + rs = i * factorial(i - 1) + end if + end function factorial + + + ! This is a useless function + subroutine example_fn(int_arg, real_arg, str_arg) + integer, intent(in) :: int_arg + real(kind=kr), intent(out) :: real_arg + character(len=*), intent(in) :: str_arg + + type(example_type), pointer :: p + integer :: n, i, j + logical :: flag + + flag = .true. ! .true. is not an operator! + if ( flag .and. flag ) then ! .and. is a pre-defined operator + print *, "blabla" + end if + + ! Examples of inquiry functions: allocated, lbound, ubound. + if ( .not. allocated(many_examples) ) then + allocate( many_examples(10) ) + end if + print *, "Lower bound = ", lbound(many_examples, 1) + print *, "Upper bound = ", ubound(many_examples, 1) + + p => many_examples(5) ! <-- p is a pointer + + ! A strange way to calculate i*i: add the first i odd numbers + i = 6 + j = 0 + do n = 1, i + j = j + (2*n - 1) + end do + print *, "i*i = ", i*i, j + + real_arg = real(j) ! <-- here the highlighting is not very good: + ! it is unable to distinguish between this and a definition like: + ! real(kind=kr) :: a + deallocate( many_examples ) + end subroutine example_fn + +end module module_example + + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! THIS IS THE MAIN PROGRAM ! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +program example + use module_example + + ! this is another example of use of the 'implicit' keyword + implicit double precision (a-h,o-z) + + real(kind=kr) :: var_out + + type(point3d) :: & + a = point3d(0.0_kr, 1.0_kr, 2.0_kr), & + b = point3d(4.0_kr, 5.0_kr, 6.0_kr) + + print *, "a + b = ", .norm. (a + b) + print *, "factorial of 5 = ", factorial(5) + + call example_fn(1, var_out, "hello!") + +end program example diff --git a/autotests/folding/highlight.glsl.fold b/autotests/folding/highlight.glsl.fold new file mode 100644 index 0000000..53df4f1 --- /dev/null +++ b/autotests/folding/highlight.glsl.fold @@ -0,0 +1,62 @@ +// This is a test file for the Katepart GLSL Syntax Highlighting. + +normal text +// this is a single-line comment +normal text +/* this +is a multi-line +comment */ +normal text + +some_symbol.some_member; +some_symbol.some_member_function(); +some_function(); + +// this is a function +void main() +{ + float f = 1.4e3; // decimal float literal + int i1 = 2884; // decimal int literal + int i2 = 0x44; // hex int literal + int i3 = 0456; // octal int literal +} + +// this is a structure +struct some_struct +{ + vec3 some_member_vector; +}; + +# this is +#preprocessor code + +// all keywords +break continue do for while +if else +true false +discard return +struct + +// all basic types +float int void bool +mat2 mat3 mat4 +vec2 vec3 vec4 +ivec2 ivec3 ivec4 +bvec2 bvec3 bvec4 +sampler1D sampler2D sampler3D +samplerCube sampler1DShadow sampler1DShadow + +// all type qualifiers +attribute const uniform varying +in out inout + +// attensions: +// FIXME +// TODO +// BUG + +// some of the std functions +radians degrees sin cos tan asin acos atan + +// some of the std variables +gl_Position gl_PointSize gl_ClipVertex diff --git a/autotests/folding/highlight.hs.fold b/autotests/folding/highlight.hs.fold new file mode 100644 index 0000000..4aa90e2 --- /dev/null +++ b/autotests/folding/highlight.hs.fold @@ -0,0 +1,124 @@ +-- test file for Haskell syntax highlighting in KDE's Kate + +-- The test file for literate Haskell can be easily created like this: +-- cat highlight.hs | sed -e "s|^|> |" -e "s|> -- ||" -e "s|^> $||" > highlight.lhs +-- You only have to manually edit the multi-line comment below. + +-- this is a single-line comment + +{- this is a multi-line comment + +Things like "a string" or a 'c' character shouldn't be highlighted in here. + +-- I could even start a new +-- one-line comment. + +-} + +-- a data definition + +data Tree a = Br (Tree a) (Tree a) | Leaf a | Nil deriving (Show, Eq) + + +-- function definition, "funnyfunction::", "Integer", "Int", "Bool" should be highlighted + +funnyfunction::(Tree a)=>[a]->Integer->Int->Bool + + +-- strings and chars +-- first line of function definitions (type declaration) should be highlighted + +strangefunction::Int->String +strangefunction 1 = "hello" +strangefunction 2 = "what's up" +strangefunction 3 = (strangefunction 1) ++ ", " ++ (strangefunction 2) +strangefunction 4 = 'a':'b':'c':'"':[] -- will return "abc" +strangefunction 5 = '\n':[] +strangefunction 6 = '\invalidhaskell':[] + +-- function name including the single quote character +-- and infix operator (`div`) + +justtesting'::Int->Int +justtesting' 2 = 2+1 +justtesting' 9 = 7 `div` 2 + +-- same definition as above, slightly different function name and a couple more whitespaces + +justtesting'' :: Int -> Int +justtesting'' 2 = 3 +justtesting'' 9 = 3 + 9 - 9 + +-- the following lines are copied out of Haskell's "Prelude.hs" + +infixl 7 *, /, `quot`, `rem`, `div`, `mod`, :%, % + + +-- everything highlighted except the "a" + +class Bounded a where + minBound, maxBound :: a + +class (Num a, Ord a) => Real a where + toRational :: a -> Rational + +-- finally, some keyword lists + +-- keywords + +case, class, data, deriving, do, else, if, in, infixl, infixr, instance, let, module, of, primitive, +then, type, where + +-- infix operators + +quot, rem, div, mod, elem, notElem, seq + +-- this stuff is not handled yet + +!!, %, &&, $!, $, *, **, -,., /=, <, <=, =<<, ==, >, >=, >>, >>=, ^, ^^, ++, || + +-- functions + +FilePath, IOError, abs, acos, acosh, all, and, any, appendFile, +approxRational, asTypeOf, asin, asinh, atan, atan2, atanh, basicIORun, +break, catch, ceiling, chr, compare, concat, concatMap, const, cos, cosh, +curry, cycle, decodeFloat, denominator, digitToInt, div, divMod, drop, +dropWhile, either, elem, encodeFloat, enumFrom, enumFromThen, +enumFromThenTo, enumFromTo, error, even, exp, exponent, fail, filter, flip, +floatDigits, floatRadix, floatRange, floor, fmap, foldl, foldl1, foldr, +foldr1, fromDouble, fromEnum, fromInt, fromInteger, fromIntegral, +fromRational, fst, gcd, getChar, getContents, getLine, head, id, inRange, +index, init, intToDigit, interact, ioError, isAlpha, isAlphaNum, isAscii, +isControl, isDenormalized, isDigit, isHexDigit, isIEEE, isInfinite, isLower, +isNaN, isNegativeZero, isOctDigit, isPrint, isSpace, isUpper, iterate, last, +lcm, length, lex, lexDigits, lexLitChar, lines, log, logBase, lookup, map, +mapM, mapM_, max, maxBound, maximum, maybe, min, minBound, minimum, mod, +negate, not, notElem, null, numerator, odd, or, ord, otherwise, pi, pred, +primExitWith, print, product, properFraction, putChar, putStr, putStrLn, +quot, quotRem, range, rangeSize, read, readDec, readFile, readFloat, +readHex, readIO, readInt, readList, readLitChar, readLn, readOct, readParen, +readSigned, reads, readsPrec, realToFrac, recip, rem, repeat, replicate, +return, reverse, round, scaleFloat, scanl, scanl1, scanr, scanr1, seq, +sequence, sequence_, show, showChar, showInt, showList, showLitChar, +showParen, showSigned, showString, shows, showsPrec, significand, signum, +sin, sinh, snd, span, splitAt, sqrt, subtract, succ, sum, tail, take, +either, elem, encodeFloat, enumFrom, enumFromThen, enumFromThenTo, +enumFromTo, error, even, exp, exponent, fail, filter, flip, floatDigits, +floatRadix, floatRange, floor, fmap, takeWhile, tan, tanh, threadToIOResult, +toEnum, toInt, toInteger, toLower, toRational, toUpper, truncate, uncurry, +undefined, unlines, until, unwords, unzip, unzip3, userError, words, +writeFile, zip, zip3, zipWith, zipWith3 + +-- type constructors + +Bool, Char, Double, Either, Float, IO, Integer, Int, Maybe, Ordering, Rational, Ratio, ReadS, +ShowS, String + +-- classes + +Bounded, Enum, Eq, Floating, Fractional, Functor, Integral, Ix, Monad, Num, Ord, Read, RealFloat, +RealFrac, Real, Show + +-- data constructors + +EQ, False, GT, Just, LT, Left, Nothing, Right, True diff --git a/autotests/folding/highlight.js.fold b/autotests/folding/highlight.js.fold new file mode 100644 index 0000000..00524a0 --- /dev/null +++ b/autotests/folding/highlight.js.fold @@ -0,0 +1,134 @@ +/* test.js - test for javascript.xml syntax file */ +// Note: this script will not, and is not supposed to, comile in any js engine. + +/* + NOTE: The words "todo", "fixme" and "note" should be rendered in a different style + within comments, match should be caseless (to test for regexp insensitive attribute). + The regex used for this rule is */ + String = /\b(?:fixme|todo|note)\b/ + /* Thus, for example "Notebook" is not caught by + this rule. (the "?:" in the subpattern is there to avoid the regex engine wasting time + saving a backref, which is not used for anything. I do not know if the overhead of parsing + that is greater than the time saved by not capturing the text...) + The rule for catching these words is placed in a context "Comment common", which is used + by both comment contexts (single line, multiline) using the new "IncludeRules" item. +*/ + +// test if regex support works - nice with new fallthrough prop in context:) +somestring.replace( /dooh/ , "bah!"); +re=/foo/ig; // hehe + +somestring.search( + /^foo\w+\s\d{0,15}$/ + ); + + re = + /dooh/; + +// This is supposedly legal: +re = somebool ? /foo/ : /bar/; + +// NOTE - Special case: an empty regex, not a comment. +// The rule uses a positive lookahead assertion to catch it: "//(?=;)". +re = //; +re = /a|b/; + +/* + Tests for the regex parser. + It will parse classes, quanitfiers, special characters and regex operaters, + as specified in the netscape documentation for javascript. + Regexps are only parsed in their clean form, as the RegExp(string) constructor + is using a quoted string. + TODO: Find out if more regex feats should be supported. + Consider using more itemDatas - assertion, quantifier are options. +*/ + +re = /^text\s+\d+\s*$/; +re = /a pattern with caret \(^\) in it/; +re = /(\d{0,4})\D/; +re = /[a-zA-Z_]+/; +re = /[^\d^]+/; +re = /\s+?\w+\.$/; +re = /\/\//; +re = /a|b/; + +// a test if #pop back from a comment will work +re = /*/foo/*/ /bar/; +// ^ POP +// ^ we got back after pop in comment, if there is regexp attribs here :-) + +/* + Some tests if the fallthrough works. + The fallthrough happens if a regexp is not found in a possible (!) position, + which is after "search(" or "replace(" or "=" or "?" or ":" in version 0.1 of the xml file +*/ + +var foo = 'bar'; +// ^ fallthrough! + + +somestring.replace( new RegExp("\\b\\w+\\b"), "word: $1"); +// ^ fallthrough expected. ("new" whould be bold) + + +something.method = + function ( a, b, c ) { /* ... */ } +// ^ fallthrough ?! + +something.other = +function ( d, e, f ) { /* ... */ } +// fallthrough expected at col 0 ("function" should be bold) + +var ary = new Array(5); +// ^ fallthrough ? (if keyword is correctly rendered) + +var b = a ? 1 : 0; +// ^ ^ fallthroughs. numbers must be rendered correctly. + +var c = d ? true : false; + +var conditinalstring = b ? + "something" : + "something else"; +// guess... + + +/* + Normal program flow... +*/ + +if (something) + dostuff(); +else + dont(); + + return; + +try { bla() } catch (e) { alert("ERROR! : " + e) } + +for (int i=0; i < j; i++) + document.write("i is" + i + "
"); + +while (something) +{ + block(); + picky: + if (!1) + break; + else + continue; +} + +with (a) { + do { + stuff( b ); // a.b if it exists + } while (itmakessense); +} + +switch (i) { + case 0: + f(); + break; + default: + break; +} diff --git a/autotests/folding/highlight.jsp.fold b/autotests/folding/highlight.jsp.fold new file mode 100644 index 0000000..b938095 --- /dev/null +++ b/autotests/folding/highlight.jsp.fold @@ -0,0 +1,170 @@ +<%-- + This page won't actually work, as it is simply designed to display jsp syntax highlighting. +--%> +<%@ page info="A Page to Test Kate Jsp Syntax Highlighting" language="java" errorPage="/test-error-page.jsp"%> +<%@ include file="/include/myglobalvars.jsp"%> --%> +<%@ page import="java.util.*, + java.io.*, + java.math.*" %> +<%@ taglib uri="/WEB-INF/lib/si_taglib.tld" prefix="si"%> + + +<% + // We can decipher our expected parameters here. + String parm1 = noNull(request.getParameter(PARAMETER_1)).trim(); + String parm2 = noNull(request.getParameter(PARAMETER_2)).trim(); + String parm3 = noNull(request.getParameter(PARAMETER_3)).trim(); + String parm4 = noNull(request.getParameter(PARAMETER_4)).trim(); + String parm5 = noNull(request.getParameter(PARAMETER_5)).trim(); + + // A sample collection of Integers to display some code folding. + List intList = getIntList(10); + + +%> + + A Sample Jsp + + + + + <%-- The top label table. --%> + + + + +
The following parameters were detected:
+ + <%-- Display the parameters which might have been passed in. --%> + + <%-- Label; Actual Parameter String; Value Detected --%> + + + + + + + <%-- Label; Actual Parameter String; Value Detected --%> + + + + + + + <%-- Label; Actual Parameter String; Value Detected --%> + + + + + + + <%-- Label; Actual Parameter String; Value Detected --%> + + + + + + + <%-- Label; Actual Parameter String; Value Detected --%> + + + + + +
PARAMETER_1<%=PARAMETER_1%>"<%=parm1%>"
PARAMETER_2<%=PARAMETER_2%>"<%=parm2%>"
PARAMETER_3<%=PARAMETER_3%>"<%=parm3%>"
PARAMETER_4<%=PARAMETER_4%>"<%=parm4%>"
PARAMETER_5<%=PARAMETER_5%>"<%=parm5%>"
+ +

+ + <%-- Display our list of random Integers (shows code folding). --%> + +<% + if (intList != null && intList.size() > 0) { +%> + +<% + Iterator intListIt = intList.iterator(); + while (intListIt.hasNext()) { + Integer i = (Integer) intListIt.next(); +%> + +<% + } + } else { +%> + +<% + } +%> +
Here are the elements of intList...
<%=i.toString()%>
Oooops, we forgot to initialize intList!
+ +

+ + <%-- We can call javascript functions. --%> + + + + + + +
Test our javascript...
+ +

+ <%-- If we actually had defined a tag library. --%> + + +
+ + + + +
+ +

+ <%-- Expression language. --%> + + + + + + +
myParam's value: ""
+ + +<%! + /* A place for class variables and functions... */ + + // Define some sample parameter names that this page might understand. + private static final String PARAMETER_1 = "p1"; + private static final String PARAMETER_2 = "p2"; + private static final String PARAMETER_3 = "p3"; + private static final String PARAMETER_4 = "p4"; + private static final String PARAMETER_5 = "p5"; + + // Returns str trimmed, or an empty string if str is null. + private static String noNull(String str) { + String retStr; + if (str == null) + retStr = ""; + else + retStr = str.trim(); + + return retStr; + } + + // Returns a list of Integers with listSize elements. + private static List getIntList(int listSize) { + ArrayList retList = new ArrayList(listSize); + for (int i = 0; i < listSize; i++) + retList.add(new Integer( (int) (Math.random() * 100) )); + + return retList; + } +%> diff --git a/autotests/folding/highlight.lex.fold b/autotests/folding/highlight.lex.fold new file mode 100644 index 0000000..5e9d693 --- /dev/null +++ b/autotests/folding/highlight.lex.fold @@ -0,0 +1,82 @@ +/* This test file tests kates Lex/Flex highlighting */ + +%option c++ +%option yyclass="KateTester" +%option yylineno + + /* This is a C(++) comment */ + +/* This one is a lex comment ! */ + +%{ +#include +#include "realparser.hpp" +using namespace std; +%} + +/* Some definitions */ +DIGIT [0-9] +LETTER [_a-zA-Z] + +%%%% + + /* Comment *shall be indented here* */ +[ \t\n\r]+ + + /* Note: there is a bad } just here vvv */ +\/\*([^\*]|\*[^/])*\*\/ { foo(a, b, c); } } + + /* A start condition scope... */ +{ + "a" { + + /* C mode ! */ + return 0; +} + + "b" %{ + + /* C mode, too ! */ + return 0; +%} + + "c" return 0; // C++ comment +} + + /* Big rule */ +\"([^"\\]|\\.)*\" { + + yylval.string_val = new char[strlen(yytext) + 1]; + int j = 0, i = 1; + + while (yytext[i] != '"') + if (yytext[i] != '\\') + yylval.string_val[j++] = yytext[i++]; + else + switch (yytext[i + 1]) + { + case 'n': + yylval.string_val[j++] = '\n'; i += 2; + break; + default: + yylval.string_val[j++] << yytext[i + 1], i += 2; + } + + yylval.string_val[j] = 0; + return TOK_STRING; + +} + + /* Dot (match all) */ +. {return yylval.int_val = yytext[0];} + +%%%% + +// Here is pure C(++) +#include + +int main(void) +{ + std::cout << "Hello, World\n"; + return 0; +} diff --git a/autotests/folding/highlight.lhs.fold b/autotests/folding/highlight.lhs.fold new file mode 100644 index 0000000..9dc52e5 --- /dev/null +++ b/autotests/folding/highlight.lhs.fold @@ -0,0 +1,124 @@ +test file for Haskell syntax highlighting in KDE's Kate + +The test file for literate Haskell can be easily created like this: + cat highlight.hs | sed -e "s|^|> |" -e "s|> -- ||" -e "s|^> $||" > highlight.lhs +You only have to manually edit the multi-line comment below. + +this is a single-line comment + +{- this is a multi-line comment + +Things like "a string" or a 'c' character shouldn't be highlighted in here. + +I could even start a new +one-line comment. + +-} + +a data definition + +> data Tree a = Br (Tree a) (Tree a) | Leaf a | Nil deriving (Show, Eq) + + +function definition, "funnyfunction::", "Integer", "Int", "Bool" should be highlighted + +> funnyfunction::(Tree a)=>[a]->Integer->Int->Bool + + +strings and chars +first line of function definitions (type declaration) should be highlighted + +> strangefunction::Int->String +> strangefunction 1 = "hello" +> strangefunction 2 = "what's up" +> strangefunction 3 = (strangefunction 1) ++ ", " ++ (strangefunction 2) +> strangefunction 4 = 'a':'b':'c':'"':[] -- will return "abc" +> strangefunction 5 = '\n':[] +> strangefunction 6 = '\invalidhaskell':[] + +function name including the single quote character +and infix operator (`div`) + +> justtesting'::Int->Int +> justtesting' 2 = 2+1 +> justtesting' 9 = 7 `div` 2 + +same definition as above, slightly different function name and a couple more whitespaces + +> justtesting'' :: Int -> Int +> justtesting'' 2 = 3 +> justtesting'' 9 = 3 + 9 - 9 + +the following lines are copied out of Haskell's "Prelude.hs" + +> infixl 7 *, /, `quot`, `rem`, `div`, `mod`, :%, % + + +everything highlighted except the "a" + +> class Bounded a where +> minBound, maxBound :: a + +> class (Num a, Ord a) => Real a where +> toRational :: a -> Rational + +finally, some keyword lists + +keywords + +> case, class, data, deriving, do, else, if, in, infixl, infixr, instance, let, module, of, primitive, +> then, type, where + +infix operators + +> quot, rem, div, mod, elem, notElem, seq + +this stuff is not handled yet + +> !!, %, &&, $!, $, *, **, -,., /=, <, <=, =<<, ==, >, >=, >>, >>=, ^, ^^, ++, || + +functions + +> FilePath, IOError, abs, acos, acosh, all, and, any, appendFile, +> approxRational, asTypeOf, asin, asinh, atan, atan2, atanh, basicIORun, +> break, catch, ceiling, chr, compare, concat, concatMap, const, cos, cosh, +> curry, cycle, decodeFloat, denominator, digitToInt, div, divMod, drop, +> dropWhile, either, elem, encodeFloat, enumFrom, enumFromThen, +> enumFromThenTo, enumFromTo, error, even, exp, exponent, fail, filter, flip, +> floatDigits, floatRadix, floatRange, floor, fmap, foldl, foldl1, foldr, +> foldr1, fromDouble, fromEnum, fromInt, fromInteger, fromIntegral, +> fromRational, fst, gcd, getChar, getContents, getLine, head, id, inRange, +> index, init, intToDigit, interact, ioError, isAlpha, isAlphaNum, isAscii, +> isControl, isDenormalized, isDigit, isHexDigit, isIEEE, isInfinite, isLower, +> isNaN, isNegativeZero, isOctDigit, isPrint, isSpace, isUpper, iterate, last, +> lcm, length, lex, lexDigits, lexLitChar, lines, log, logBase, lookup, map, +> mapM, mapM_, max, maxBound, maximum, maybe, min, minBound, minimum, mod, +> negate, not, notElem, null, numerator, odd, or, ord, otherwise, pi, pred, +> primExitWith, print, product, properFraction, putChar, putStr, putStrLn, +> quot, quotRem, range, rangeSize, read, readDec, readFile, readFloat, +> readHex, readIO, readInt, readList, readLitChar, readLn, readOct, readParen, +> readSigned, reads, readsPrec, realToFrac, recip, rem, repeat, replicate, +> return, reverse, round, scaleFloat, scanl, scanl1, scanr, scanr1, seq, +> sequence, sequence_, show, showChar, showInt, showList, showLitChar, +> showParen, showSigned, showString, shows, showsPrec, significand, signum, +> sin, sinh, snd, span, splitAt, sqrt, subtract, succ, sum, tail, take, +> either, elem, encodeFloat, enumFrom, enumFromThen, enumFromThenTo, +> enumFromTo, error, even, exp, exponent, fail, filter, flip, floatDigits, +> floatRadix, floatRange, floor, fmap, takeWhile, tan, tanh, threadToIOResult, +> toEnum, toInt, toInteger, toLower, toRational, toUpper, truncate, uncurry, +> undefined, unlines, until, unwords, unzip, unzip3, userError, words, +> writeFile, zip, zip3, zipWith, zipWith3 + +type constructors + +> Bool, Char, Double, Either, Float, IO, Integer, Int, Maybe, Ordering, Rational, Ratio, ReadS, +> ShowS, String + +classes + +> Bounded, Enum, Eq, Floating, Fractional, Functor, Integral, Ix, Monad, Num, Ord, Read, RealFloat, +> RealFrac, Real, Show + +data constructors + +> EQ, False, GT, Just, LT, Left, Nothing, Right, True diff --git a/autotests/folding/highlight.lisp.fold b/autotests/folding/highlight.lisp.fold new file mode 100644 index 0000000..5b6bf55 --- /dev/null +++ b/autotests/folding/highlight.lisp.fold @@ -0,0 +1,36 @@ +;; This test file tests kates common lisp highlighting +#| +multilinecomment :) +|# + +;BEGIN region marker + +;END end + +(defun bin-search (obj vec) + (let ((len (length vec))) + (and (not (zerop len)) + (finder obj vec 0 (- len 1))))) + +(defun parse-date (str) + (let ((toks (tokens str #'constituent 0))) + (list (parse-integer (first toks)) + (parse-month (second toks)) + (parse-integer (third toks))))) + +(defconstant month-names + #("jan" "feb" "mar" "apr" "may" "jun" + "jul" "aug" "sep" "oct" "nov" "dec")) + +(defstruct buf + vec (start -1) (used -1) (new -1) (end -1)) + +(defparameter *words* (make-hash-table :size 10000)) + +(defmacro while (test &rest body) + `(do () + ((not ,test)) + ,@body)) + +(define-modify-macro append1f (val) + (lambda (lst val) (append lst (list val)))) diff --git a/autotests/folding/highlight.ly.fold b/autotests/folding/highlight.ly.fold new file mode 100644 index 0000000..a7e787b --- /dev/null +++ b/autotests/folding/highlight.ly.fold @@ -0,0 +1,114 @@ +% This is a file to test the Lilypond highlighting features of Katepart. +% This is NOT a valid lilypond file, because it also shows the +% highlighting of some invalid lilypond constructs! +% This is a line comment. + +%{ +this is a block comment, that can occur inside a line, or across +multiple lines. +%} + +\header { + title = "Katepart Lilypond syntax highlighting test file" + composer = %{"Wilbert Berendsen"%} "Anonymus" + poet = "The KDE team" + opus = "1" + copyright = "Share and enjoy!" +} + +\paper { + #(set-paper-size "a4") % a hash introduces scheme + indent = 0 % recognize variable names inside \paper, \layout etc. + between-system-space = 3\mm +} + +\layout { + \context { + \Score + \remove Bar_number_engraver % recognize engraver names + \remove "Bar_number_engraver" % also when quoted! + } +} + +% { and << block are folded +\score { + \new StaffGroup << + \new ChordNames \chordmode { c2sus4/f g2/d c1 } + \new Staff \new Voice ="mel" { + \key f \major + \time 4/4 + \partial 4 + \set Staff.instrumentName = "Bla." + \once \override Staff.NoteHead #'color = #red + % dynamics, articulations and markup + c8\p d\< e-. f-> g a\f c-5\markup {Hoi} + \notemode { c d e f } + \repeat volta 2 { + % complex durations are highlighted: + g4*2/3 + } + \times 2/3 {e8 f g} + % there is some error checking: + % often made mistake to have octavemarks after the duration: + c2' + % invalid durations are caught: + g3 + } + \context Lyrics \lyricsto "mel" { + \set fontSize = #1 + this is a line of ly -- rics. + with4 dur -- a -- tions.2. + % errors like forgetting spaces are found: + space-- flight %{i.s.o.%} space -- flight + space at end for -- got -- ten as well.} + + \new DrumStaff \drummode { hihat4 bassdrum8 } + \new FiguredBass \figuremode { + <5 4>8 <6-> + } + >> + \midi { + \context { + \Score + tempoWholesPerMinute = #(ly:make-moment 60 2) + } + } +} + +av = #(define-music-function (parser location voice) +(string?) +; scheme comments are recognized in scheme +; Lilypond inside scheme works as well: +#{ + \set associatedVoice = $voice +#}) + + + + +% inside scheme some elements are highlighted: +#(define (naturalise-pitch p) + (let* ((o (ly:pitch-octave p)) + (a (* 4 (ly:pitch-alteration p))) + (n (ly:pitch-notename p))) + (bla 'ArticulationEvent 'ChoirStaff) + (cond + ((> a 2) (set! a (- a 4)) (set! n (+ n 1))) + ((< a -2) (set! a (+ a 4)) (set! n (- n 1)))) + + (if (< n 0) (begin (set! o (- o 1)) (set! n (+ n 7)))) + (if (> n 6) (begin (set! o (+ o 1)) (set! n (- n 7)))) + + (ly:make-pitch o n (/ a 4)))) + +% markup is also highlighted +\markup { + \line { + text test Voice Staff % note Lilypond keywords are not highlighted here + } + \score { \relative c' { 2( d) } } + \italic bla + \override #'(baseline-skip . 2) { + \underline blu + } +} diff --git a/autotests/folding/highlight.m.fold b/autotests/folding/highlight.m.fold new file mode 100644 index 0000000..302659f --- /dev/null +++ b/autotests/folding/highlight.m.fold @@ -0,0 +1,61 @@ +%%===================================================== +% MATLAB test code for Kate/Kwrite syntax highlighting +% kate: hl Matlab +%%===================================================== + +% Numbers _____________________________________________ +5, 5.5, .1, 0.1, 0.4e5, 1.2e-5, 5i, 5.3i, 6j, .345+3i +5', 5.5', .1', 0.1', 0.4e5', 1.2e-5', 5i', 5.3i', 6j', .345+3i' + +% Operators ___________________________________________ +% relational operators +'asdf'~=4, c<=4, d>=4, ab, a==b, b||c, b&&c +% elementwise arithmetic operators +a.^b, a.*b a./b, 1:4:5 +% single-character binary arithmetic +a+3, a-3, a*2, a^3, a/3, a\3, a|b, a&b +% unary operators +a = ~g; g = @sfdgdsf(sdfsd,345); g.' + 1i.' - ('asdf').' +% separators and delimiter +(asd),[sadf];{asdf},;;,;;;() +% continuation +a = 1+ ... + 2; + +% Strings and adjoint _________________________________ +% incomplete strings +'string +'str'' +'str''ing +% complete strings +'string' % simple string +'''' % string containing ' +'str''ing' % one string containing ' +'string' 'string' % two strings +'asdf' 'asdf''' variable % two strings and a variable +'asdf''asdf'' fsgdfg' + (asdf)' - 'asdf'.' + []''''.';'' +'sadf'.' % string transpose +% adjoint +{'asdf'}' + 1 +('asdf')' + 1 +['asdf']' + 1 +'' var''' % empty string, var with >1 adjoints +[5]'*{5}'*('asd')'.'+(5)'*6'*asdf'*asdf'.' % many adjoints +A'*B + 1 % adjoint +A.'*B + 1 % transpose +A.'.'*B + 1 % double transpose +A'.' + 1 % adjoint, then transpose +A.'' % transpose, then adjoint + +% System command ______________________________________ +!hostname +!cp * /tmp + +% Reserved keywords ___________________________________ +function, persistent, global +switch, case, otherwise +if, else, elseif +try, catch +for, while, break, continue +end, return +function, FUNCTION, Function % case sensitive! diff --git a/autotests/folding/highlight.mac.fold b/autotests/folding/highlight.mac.fold new file mode 100644 index 0000000..ad7ee63 --- /dev/null +++ b/autotests/folding/highlight.mac.fold @@ -0,0 +1,145 @@ +/* +------------------------------------------------------------------------ +Efficient Galois Fields in Maxima + +by Alasdair McAndrew +and later extended by Fabrizio Caruso and Jacopo Daurizio + +it is distribuited together with gf_roots by Jacopo Daurizio + +Authors: + +Fabrizio Caruso (optimizations, testing) +Jacopo D'Aurizio (optimizations, modular roots) +Alasdair McAndrew (original version of the package, pohlig-helman log, etc... ) +------------------------------------------------------------------------*/ + +/* Released under terms of the GNU General Public License, version 2, + * by permission of the authors to Robert Dodier circa 2007-12-02. + */ + +/* Defines a flag for dealing with large fields. If it is set to "false", +then lookup tables are used for exponentiation and logarithms. Otherwise +other algorithms are used */ + +define_variable(largefield,true,bool)$ +define_variable(gf_char,0,integer)$ +define_variable(gf_exp,0,integer)$ +define_variable(gf_order,0,integer)$ +define_variable (gf_one, 'gf_one, any_check)$ +define_variable (gf_prim, 'gf_prim, any_check)$ +define_variable (gf_irr, 'gf_irr, any_check)$ +define_variable (gf_list, 'gf_list, any_check)$ +define_variable (gen_powers, 'gf_list, any_check)$ +remvalue(x,z,gf_char,gf_exp,gf_irr,pg,gp,lg,gf_prim,gf_one,gf_order,gf_list,gen_powers)$ + + +/* --------------------------------------------------------------------------------------------- */ +/* Settings */ + +GF_VERBOSE:false; /* Verbosity */ +GF_WARNING: true; /* Warnings */ +GF_IRREDUCIBILITY_CHECK:false; /* Irreducibility test for the minimal polynomial of the extension */ + +/* +------------------------------------------------------------------------------------------------ */ + + +/* It defines a new current field with gf_char=b, min. pol.= p of deg= e*/ +gf_set([ars]):=block([gj,m,i,j,dg], + if length(ars)=1 then + ( + gf_setp(ars[1]), + return(true) + ) + else + ( + if length(ars)=2 then + ( + if numberp(ars[2]) then + ( + if ars[2]=0 and GF_WARNING then + ( + print("WARNING: the irreducible is zero! We assume GF(",ars[1],")"), + gf_setp(ars[1]), + return(true) + ) + else + ( + error("ERROR: you tried to extend with a non-zero constant!"), + return(false) + ) + ) + else + ( + dg:hipow(ars[2],x), + + if dg=1 then + gf_setp(ars[1]), + gf_irr:ars[2], + gf_exp:dg, + return(true) + ) + ) + else + ( + gf_exp:ars[2], + if gf_exp=1 then + ( + gf_setp(ars[1]), + gf_irr:rat(ars[3]), + return(true) + ), + gf_irr:rat(ars[3]) + ) + ), + + gf_char:ars[1], + gf_one:rat(1,x), + gf_order:gf_char^gf_exp-1, + + m:makelist(coeff(gf_irr,x,i),i,0,gf_exp), + gf_list:[[first(m),0]],j:1, + for i:2 thru gf_exp+1 do if m[i]=0 then j:j+1 else ( gf_list:endcons([m[i],j],gf_list), j:1 ), + + if not(primep(gf_char)) then error("ERROR: Gf_Char must be a prime number.") + else + modulus:gf_char, + if GF_IRREDUCIBILITY_CHECK and + hipow(args(factor(ars[3]))[1],x)#hipow(rat(ars[3]),x) then + error("ERROR: Polynomial is not irreducible"), + + if not(largefield) then + ( + pg:mkpowers(), + lg:mklogs() + ) + else + ( + if GF_VERBOSE then + print("finding a primitive element..."), + + gf_prim:rat(gf_findprim(),x), + if GF_VERBOSE then + print("...primitive element found.") + + ), + modulus:false, /* it resets the modulus */ + return(true) + + )$ + + +/* Prints out information about the field */ +gf_info():=block( + print("Prime gf_char value: ",gf_char), + print("Exponent: ", gf_exp), + print("Multiplicative order: ",gf_order), + print("Irreducible polynomial: ",gf_irr), + print("Primitive element: ",gf_prim), + if (largefield) then + print("Largefield flag is true; powers and logarithms not computed.") + else + print("Largefield flag is false; powers and logarithms computed."), + disp() +)$ diff --git a/autotests/folding/highlight.mup.fold b/autotests/folding/highlight.mup.fold new file mode 100644 index 0000000..e9afd19 --- /dev/null +++ b/autotests/folding/highlight.mup.fold @@ -0,0 +1,103 @@ +// This is a MUP highlighting test. +// Mup is a shareware music publisher from www.arkkra.com + +// contexts +score +music +staff 1 +voice 1 3 + +top +top2 +bottom +bottom2 +grids + +headshapes + + +header +footer +header2 +footer2 + +// parameters and values +score + units = cm; + key = 3#minor + key = 3# minor + rehstyle=circled + + + + +mussym above all: 1 "ferm" ; + +define NAME +// this is a macro definition, these are collapsable +@ + +ifdef NAME +// this is conditionally "compiled" +endif + +ifndef NAME +// this is conditionally "compiled" when the macro has not been defined +else +// else clause +endif + + +// Various Tests + +// tablature +1: e ^f; f; b ^c5; c#5; +bar + +1: d+^e+ g^a; e+a; g ^/; c ^/ c+^/; +bar + +// cross-staff stems +1: 1e+g+c++; +2: cc+; ee+; g with g+ above; with c+c++ above; +bar + +1: 2+4ceg;4; // tie implied by added time values + +// slurs +1: 2f a c+; dbd+; +bar +1: 2fac+ slur; dbd+; +bar + +// alternation +1: 2c alt 2; 2c+;2g; +bar + +// bar to draw if repeatstart happens to be on new line +(dblbar) repeatstart +1: [up]8f bm with staff below;a;4s ebm;4s bm with staff below;8b;[len 11]d ebm; +2: 4s bm with staff above;8a;b ebm;[down;len 14]b bm with staff above;d;4s ebm; +bar + +// locations +3: 2cf; [=h] egc+; +1: [cue; with >; =_ch] fa; + + +roll up 1 1 to 1 2: 2; 4; +roll down 1 1 to 1 2: 2; 4; + +lyrics above 1,3 ; below 2,4 ; between 5&6 : "<1. >Hi, hi"; + +title "page \% of \#" + +// shaped whole rests +1: 4mr; // use a quarter rest symbol +1: 1/4mr; // use a quadruple whole rest symbol +2: 2.. mr; // use a double-dotted half rest + +// tuplets +1: {4f; g;}3num,4.+2. +bar + diff --git a/autotests/folding/highlight.pb.fold b/autotests/folding/highlight.pb.fold new file mode 100644 index 0000000..aad9803 --- /dev/null +++ b/autotests/folding/highlight.pb.fold @@ -0,0 +1,87 @@ +; This is a test file for kate's PureBasic highlighting. + +; BMP2x Converter by Sven Langenkamp + +UseJPEGImageEncoder() +UsePNGImageEncoder() + +Declare Convert(JPEG) + +Enumeration 1 + #JPEG + #PNG +EndEnumeration + +; BEGIN section + + +; END + +Global Count +Global file.s +Global filename.s +Global fileext.s +Global OutputFormat +Global JPEGQuality + +Count = 0 +OutputFormat = 1 +JPEGQuality = -1 + +; MAIN PROGRAM------------------------------------------------------------------ + +;Request Options +PrintN("Output Format") +PrintN(" [1] JPEG") +PrintN(" [2] PNG") +Print ("> ") +OutputFormat = Int(Input()) + +Select OutputFormat + Case #JPEG: + fileext = ".jpg" + ;Request JPEG Quality + PrintN("") + PrintN("JPEG Quality") + PrintN(" [0-10]") + Print ("> ") + JPEGQuality = Int(Input()) + + Case #PNG: + fileext = ".png" +EndSelect + +;Convert all BMP files in the current directory +ExamineDirectory(0, "", "*.bmp") +While NextDirectoryEntry() + file = DirectoryEntryName() + filename = GetFilePart(file) + + If LoadImage(0, file) + Select OutputFormat + Case #JPEG: + Convert(JPEGQuality) + + Case #PNG: + Convert(-1) + EndSelect + Count = Count +1 + EndIf + +Wend + +PrintN(Str(Count) + " files converted") +CloseConsole() + +; PROCUDURES-------------------------------------------------------------------- + +Procedure Convert(JPEG) + Shared filename, fileext + + If JPEG > -1 + SaveImage(0, filename + fileext, #PB_ImagePlugin_JPEG, JPEG) + Else + SaveImage(0, filename + fileext, #PB_ImagePlugin_PNG) + EndIf + PrintN(file + " converted to " + filename + fileext) +EndProcedure diff --git a/autotests/folding/highlight.php.fold b/autotests/folding/highlight.php.fold new file mode 100644 index 0000000..a77104d --- /dev/null +++ b/autotests/folding/highlight.php.fold @@ -0,0 +1,23 @@ +/*
This is a pseudo PHP file to test Kate's PHP syntax highlighting. */ +# TODO: this is incomplete, add more syntax examples! +# this is also a comment. +// Even this is a comment +function test($varname) { + return "bla"; # this is also a comment +} + +?> + + + + + test"; ?> + + +<< +This is the $string inside the variable (which seems to be rendered as a string) +It works well, I think. +DOOH +?> diff --git a/autotests/folding/highlight.pike.fold b/autotests/folding/highlight.pike.fold new file mode 100644 index 0000000..5c65bae --- /dev/null +++ b/autotests/folding/highlight.pike.fold @@ -0,0 +1,24 @@ +#! /bin/env pike + +/* This file is a syntax highlight test for Kate. + * FIXME: Improve it to contain more (and more unusual) syntax examples. + */ + + +#define PIKE_ON_THE_WEB /* Is this address correct? */ "http://pike.ida.liu.se/" + + +int main(int argc, array(string) args) +{ + // Write funny things with Pike :) + write(`+("Command line arguments (%d of them): ", @map(args, `+, " ")) + "\n", argc); + + write("\nVisit Pike site at %s\n\n", PIKE_ON_THE_WEB); + + for (int i = 1; i <= 3; i++) + write(":" + ")" * i + " "); + + write("\n" + ({"Bye", "bye"}) * "-" + "!\n"); + + return 0; +} diff --git a/autotests/folding/highlight.pl.fold b/autotests/folding/highlight.pl.fold new file mode 100644 index 0000000..8e7ac74 --- /dev/null +++ b/autotests/folding/highlight.pl.fold @@ -0,0 +1,44 @@ +#!/usr/bin/perl -w +# This is a pseudo Perl file to test Kate's Perl syntax highlighting. +# TODO: this is incomplete, add more syntax examples! + +sub prg($) +{ + my $var = shift; + + $var =~ s/bla/foo/igs;/foo/igs; + $var =~ s!bla!foo!igs;!foo!igs; + $var =~ s#bla#foo#igs;#foo#igs; + $var =~ tr/a-z/A-Z/; + ($match) = ($var =~ m/(.*?)/igs); + + $test = 2/453453.21; + $test /= 2; + + print qq~d fsd fsdf sdfl sd~ + + $" = '/'; + + $foo = <<__EOF; +d ahfdklf klsdfl sdf sd +fsd sdf sdfsdlkf sd +__EOF + + $x = "dasds"; + + next if( $match eq "two" ); + next if( $match =~ /go/i ); + + @array = (1,2,3); # a comment + @array = qw(apple foo bar); + push(@array, 4); + %hash = (red => 'rot', + blue => 'blau'); + print keys(%hash); +} + +sub blah { +} + +&blah; +prg("test"); diff --git a/autotests/folding/highlight.pov.fold b/autotests/folding/highlight.pov.fold new file mode 100644 index 0000000..01e848c --- /dev/null +++ b/autotests/folding/highlight.pov.fold @@ -0,0 +1,76 @@ +//BEGIN TEST +// test scene for POV-Ray syntax highlighting + +/* test comment */ + +/* nested /* comments */ do not work */ + +#version 3.5; +//END +global_settings { assumed_gamma 1.0 } + +// ---------------------------------------- + +camera { + location <5.0, -12.0, 2.0> + up z sky z + look_at <0.0, 0.0, 0.5> + angle 40 +} + +sky_sphere { + pigment { + gradient z + color_map { + [0.0 rgb <0.6,0.7,1.0>] + [0.2 rgb <0.2,0.3,0.9>] + } + } +} + +light_source { + <3, 1, 2>*1000 + color rgb <2.2, 1.8, 1.5> +} + +// ---------------------------------------- + +#declare TEST=0; + +#ifdef (TEST) + plane { + z, 0 + texture { + pigment { + checker + color rgb 1, color rgb 0 + } + } + } +#end + +#macro Sphere(Pos, Radius) + sphere { + , Radius + texture { + pigment { color rgb 1 } + finish{ + diffuse 0.3 + ambient 0.0 + specular 0.6 + reflection 0.8 + } + } + } +#end + +#local Cnt=0; +#local Seed=seed(0); + +#while (Cnt<10000) + Sphere( + -100+*200, + 0.3+pow(rand(Seed),2)*0.7 + ) + #local Cnt=Cnt+1; +#end diff --git a/autotests/folding/highlight.prg.fold b/autotests/folding/highlight.prg.fold new file mode 100644 index 0000000..9f03189 --- /dev/null +++ b/autotests/folding/highlight.prg.fold @@ -0,0 +1,71 @@ +// Test file to test kate's clipper highlighting +// kate: hl Clipper; + +//BEGIN INCLUDES +#include +#include "logo.ch" + +#define PRGVERSION "0.0.1" +//END + +//BEGIN CODE +static ws, win +static driver := getDriver() +/* a multiline + comment +*/ + +function main( formName ) + local form + local fileName + + if empty(formName) + ?? "Usage: ./form_ui &\n" + CANCEL + elseelse + fileName := formName + endif + ws := UIWorkSpace() + + form := UIForm( fileName ) + win := form:parseFile() +// ?? valtype(win),chr(10) + if win == NIL + CANCEL + endif + win:show() + + ws:run() + ws:quit() +return 0 + +/* Setting dialog */ +function settingsDialog() + ?? "TODO: Settings dialog&\n" +return + +/* About dialog */ +function aboutDialog() + local dlg := UIWindow("About", win, "aboutDlg", .F.) + local hl, lside, t, bb, bD + + hl := UIHBox(,4,8) + lside := UIVBox() + lside:add(UIImage(eas_logo_mini,.T.)) + hl:add(lside,.F.,.F.) + dlg:userSpace:add(hl,.T.,.T.) + t := UIVBox() + hl:add(t,.T.,.T.) + + t:add(UILabel("License: GPL version 2 or later")) + bb := UIButtonBar() + t:add(bb) + bD := UIButton(win, "&Close", {|o,e| dlg:close() } ) + bb:add( bD ) + + dlg:setFocus(bD) + dlg:setDefault(bD) + dlg:setPlacement( .T. ) + dlg:show() +return +//END diff --git a/autotests/folding/highlight.qml.fold b/autotests/folding/highlight.qml.fold new file mode 100644 index 0000000..2494d70 --- /dev/null +++ b/autotests/folding/highlight.qml.fold @@ -0,0 +1,59 @@ +import Qt 4.6 + +// some random qml snippets stolen from the qt docs + +Rectangle { + important: true + propertyAsdf: + id: container + signalA: bla + property string label + signal clicked + radius: 5; border.color: "black" + color: mouse.pressed ? "steelblue" : "lightsteelblue" + gradient: Gradient { + GradientStop { position: mouse.pressed ? 1.0 : 0.0; color: "steelblue" } + GradientStop { position: mouse.pressed ? 0.0 : 1.0; color: "lightsteelblue" } + } + MouseRegion { id: mouse; anchors.fill: parent; onClicked: container.clicked() } + Text { anchors.fill: parent; text: container.label; anchors.centerIn: parent } +} + +Rectangle { + Script { + function calculateMyHeight() { + return Math.max(otherItem.height, thirdItem.height); + } + } + + anchors.centerIn: parent + width: Math.min(otherItem.width, 10) + height: calculateMyHeight() + color: { if (width > 10) "blue"; else "red" } +} + +Rectangle { + default property color innerColor: "black" + property color innerColor: "black" + property alias text: textElement.text + property alias aliasXYZ: testElement.text + signal bar + signal bar(var blah, string yxcv) + width: 240; height: 320; + width: 100; height: 30; source: "images/toolbutton.sci" + ListView { + anchors.fill: parent + model: contactModel + delegate: Component { + Text { + text: modelData.firstName + " " + modelData.lastName + } + } + } +} + +Item { + function say(text) { + console.log("You said " + text); + } +} diff --git a/autotests/folding/highlight.rb.fold b/autotests/folding/highlight.rb.fold new file mode 100644 index 0000000..8ae2980 --- /dev/null +++ b/autotests/folding/highlight.rb.fold @@ -0,0 +1,551 @@ +# This file is a testcase for the highlighting of Ruby code +# It's not executable code, but a collection of code snippets +# + +require 'Config' +require 'DO/Clients' +require 'DO/DBClients' + + def CGI::escapeElement(string, *elements) + elements = elements[0] if elements[0].kind_of?(Array) + unless elements.empty? + string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/ni) do + CGI::escapeHTML($&) + end + elseelse + string + end + end + +case inputLine + when "debug" + dumpDebugInfo + dumpSymbols + when /p\s+(\w+)/ + dumpVariable($1) + when "quit", "exit" + exit + elseelse + print "Illegal command: #{inputLine}" +end + + +kind = case year #hi there + when 1850..1889 then "Blues" + when 1890..1909 then "Ragtime" + when 1910..1929 then "New Orleans Jazz" + when 1930..1939 then "Swing" + when 1940..1950 then "Bebop" + else "Jazz"else "Jazz" + end + + # URL-encode a string. + # url_encoded_string = CGI::escape("'Stop!' said Fred") + # # => "%27Stop%21%27+said+Fred" + def CGI::escape(string) + string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do + '%' + $1.unpack('H2' * $1.size).join('%').upcase + end.tr(' ', '+') + end + + +# Class ClientManager +# +# definition : Import, store and export the various data used by the application. +# This class is the sole interface between the application and the underlying database. + +mon, day, year = $1, $2, $3 if /(\d\d)-(\d\d)-(\d\d)/ +puts "a = #{a}" if fDebug +print total unless total == 0 + +while gets + next if /^#/ # Skip comments + parseLine unless /^$/ # Don't parse empty lines +end + +if artist == "John Coltrane" #hi there + artist = "'Trane" #hi there +end unless nicknames == "no" #hi there + +handle = if aSong.artist == "Gillespie" then #hi there + "Dizzy" + elsif aSong.artist == "Parker" thenelsif aSong.artist == "Parker" then + "Bird" + else #hi thereelse #hi there + "unknown" + end + +if aSong.artist == "Gillespie" then handle = "Dizzy" +elsif aSong.artist == "Parker" then handle = "Bird"elsif aSong.artist == "Parker" then handle = "Bird" +else handle = "unknown"else handle = "unknown" +end #hi there + +if aSong.artist == "Gillespie" then + handle = "Dizzy" +elsif aSong.artist == "Parker" thenelsif aSong.artist == "Parker" then + handle = "Bird" +elseelse + handle = "unknown" +end + +if aSong.artist == "Gillespie" + handle = "Dizzy" +elsif aSong.artist == "Parker"elsif aSong.artist == "Parker" + handle = "Bird" +elseelse + handle = "unknown" +end + + case line + when /title=(.*)/ + puts "Title is #$1" + when /track=(.*)/ + puts "Track is #$1" + when /artist=(.*)/ + puts "Artist is #$1" +end + +case shape + when Square, Rectangle + # ... + when Circle + # ... + when Triangle + # ... + elseelse + # ... +end + + +until playList.duration > 60 #hi there + playList.add(songList.pop) +end + +3.times do + print "Ho! " +end + +loop { + # block ... +} + +songList.each do |aSong| + aSong.play +end + +for aSong in songList + aSong.play +end + +for i in ['fee', 'fi', 'fo', 'fum'] + print i, " " +end +for i in 1..3 + print i, " " +end +for i in File.open("ordinal").find_all { |l| l =~ /d$/} + print i.chomp, " " +end + +class Periods + def each + yield "Classical" + yield "Jazz" + yield "Rock" + end +end + + +periods = Periods.new +for genre in periods + print genre, " " +end + +while gets + next if /^\s*#/ # skip comments + break if /^END/ # stop at end + # substitute stuff in backticks and try again + redo if gsub!(/`(.*?)`/) { eval($1) } + # process line ... +end + +i=0 +loop do + i += 1 + next if i < 3 + print i + break if i > 4 +end + +for i in 1..100 + print "Now at #{i}. Restart? " + retry if gets =~ /^y/i +end + +def doUntil(cond) + yield + retry unless cond +end + +i = 0 +doUntil(i > 3) { + print i, " " + i += 1 +} + +def system_call + # ... code which throws SystemCallError +rescue SystemCallErrorrescue SystemCallError + $stderr.print "IO failed: " + $! + opFile.close + File.delete(opName) + raise +end + +class ClientManager + + # constructor + def initialize(dbase) + @dbClient = DBClient.new(dbase) + @clients = Clients.new + end + + def prout(a, b, xy="jj") 24 end + ############################################################### + # + # CLIENTS SECTION + # + ############################################################### + + # update the clients object by retrieving the related data from the database + # returns the number of clients + def refreshClients + @clients.clean + unless @sqlQuery.nil? then + @sqlQuery.selectClient.each do |row| + @clients.addClient(row[0],row[1],row[2],row[3],row[4],row[5], row[6], row[7], row[8]) + end + elseelse + puts "SqlQuery wasn't created : cannot read data from database" + end + return @clients.length + end + + # insert a client in the database and refreshes the local clients object + # we assume that none of the arguments is null + # we assume that the client, identified by raison_sociale doesn't already exists + def addClient(raison_sociale, division, departement, adresse, cp, ville, nom_contact, tel_contact) + id = "0" + unless @sqlQuery.nil? then + id = @sqlQuery.insertClient(raison_sociale, division, departement, adresse, cp, ville, nom_contact,tel_contact) + elseelse + puts "SqlQuery wasn't created : database update cannot be performed" + end + @clients.addClient(id, raison_sociale, division, departement, adresse, cp, ville, nom_contact, tel_contact) # synchronize local object with DB + end + + # deletes a client from the database and updates the local Clients object accordingly + def delClient(nomclient_brut) + raison_sociale, div, dep = Clients.getIdentifiers(nomclient_brut) + listeContratsExp, listeContratsSup, listeContratsProd, listePropositionsExp, listePropositionsSup = [] + + listeContratsExp = @contratsExpertise.getContratsFromClient(nomclient_brut) + listeContratsSup = @contratsSupport.getContratsFromClient(nomclient_brut) + listeContratsProd = @contratsProduits.getContratsFromClient(nomclient_brut) + listePropositionsExp = @propositionsExpertise.getPropositionsFromClient(nomclient_brut) + listePropositionsSup = @propositionsSupport.getPropositionsFromClient(nomclient_brut) + + unless @sqlQuery.nil? then + @sqlQuery.deleteClient(raison_sociale, div, dep) + + @sqlQuery.deleteContracts(Config::EXPERTISE,listeContratsExp) + @sqlQuery.deleteContracts(Config::SUPPORT,listeContratsSup) + @sqlQuery.deleteContracts(Config::PRODUIT,listeContratsProd) + @sqlQuery.deletePropositions(Config::EXPERTISE,listePropositionsExp) + @sqlQuery.deletePropositions(Config::SUPPORT,listePropositionsSup) + elseelse + puts "SqlQuery wasn't created : database update cannot be performed" + end + @clients.delClient(raison_sociale,div,dep) + + @contratsExpertise.deleteContracts(listeContratsExp) + @contratsSupport.deleteContracts(listeContratsSup) + @contratsProduits.deleteContracts(listeContratsProd) + @propositionsExpertise.deletePropositions(listePropositionsExp) + @propositionsSupport.deletePropositions(listePropositionsSup) + end +end + + # Mixin module for HTML version 3 generation methods. + module Html3 # :nodoc: + + # The DOCTYPE declaration for this version of HTML + def doctype + %|| + end + + # Initialise the HTML generation methods for this version. + def element_init + extend TagMaker + methods = "" + # - - + for element in %w[ A TT I B U STRIKE BIG SMALL SUB SUP EM STRONG + DFN CODE SAMP KBD VAR CITE FONT ADDRESS DIV center MAP + APPLET PRE XMP LISTING DL OL UL DIR MENU SELECT table TITLE + STYLE SCRIPT H1 H2 H3 H4 H5 H6 TEXTAREA FORM BLOCKQUOTE + CAPTION ] + methods += <<-BEGIN + nn_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + + # - O EMPTY + for element in %w[ IMG BASE BASEFONT BR AREA LINK PARAM HR INPUT + ISINDEX META ] + methods += <<-BEGIN + nOE_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + + # O O or - O + for element in %w[ HTML HEAD BODY P PLAINTEXT DT DD LI OPTION tr + th td ] + methods += <<-BEGIN + nO_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + eval(methods) + end + + end + +# following snippet from Webrick's log.rb +# notice the erronous handling of the query method is_a? +def format(arg) + str = if arg.is_a?(Exception) + "#{arg.class}: #{arg.message}\n\t" << + arg.backtrace.join("\n\t") << "\n" + elsif arg.respond_to?(:to_str)elsif arg.respond_to?(:to_str) + arg.to_str + elseelse + arg.inspect + end +end + +# following snippet from Webrick's httputils.rb +# Splitting regexps on several lines might be bad form, +# but not illegal in Ruby. +# This should probably be supported in the highlighting +def split_header_value(str) + str.scan(/((?:"(?:\\.|[^"])+?"|[^",]+)+) + (?:,\s*|\Z)/xn).collect{|v| v[0] } +end + +# snippet from Net::Telnet +string.gsub(/#{IAC}( + [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]| + [#{DO}#{DONT}#{WILL}#{WONT}] + [#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]| + #{SB}[^#{IAC}]*#{IAC}#{SE} + )/xno) + +# following snippet from Webrick's httpresponse.rb +# the HEREDOC is not recognized as such +@body << <<-_end_of_html_ + + + #{HTMLUtils::escape(@reason_phrase)} + +

#{HTMLUtils::escape(@reason_phrase)}

+ #{HTMLUtils::escape(ex.message)} +
+_end_of_html_ + + +# snippet from Webrick's httpproxy.rb +# here we should make sure that the symbol definition ':' doesn't override +# the module operator '::' +Net::HTTP::version_1_2 if RUBY_VERSION < "1.7" + +# snippet from Webrick's cookie.rb +# the beginning of the regexp is erronously highlighted like an operator +key, val = x.split(/=/,2) + +# the following are division operators +# it's a bit tricky to keep the operator apart from the regexp +result = 8 / 4 +result /= divisor + +# 2008-06-01 regexp and division operator syntax has been fixed: +result = 8/4 # division +result = 8/foo # division +result = /8/ # regexp +result = 8//4/ # division and regexp + +10/10 # division +10/ 10 # division +10 /10 # division +10 / 10 # division + +foo/10 # division +foo/ 10 # division +foo /10/ # regexp +foo / 10 # division + +foo/10/10 # both division +total/count/2 # both division +total/(count/2) # both division + +@foo/10 # division +@foo /10 # division + +"hello"/10 # division +"hello" / 10 # division + +/regexp//10 # division +/regexp/ / 10 # division + +Math::PI/10 # division +Math::foo /rx/ # regexp + +# 2008-06-05 similar fix for modulo operator: + +10%4 # modulo +10 %4 # modulo +10% 4 # modulo +10 % 4 # modulo + +foo%4 # modulo +# foo %4 # illegal %string +foo% 4 # modulo +foo % 4 # modulo + +foo % (4) # modulo + +foo %(4) # %string +foo %q(4) # %string +foo %Q(4) # %string +foo %%4% # %string + +foo = %|blah| # GDL input +foo % %|blah| # modulo and GDL + +# mix in any way you want +result = 10//regexp//20/foo//regexp//20 + +# test cases for general delimited input +# quoted strings +%Q|this is a string| +%Q{this is a string} +%Q(this is a string) +%Q> +%Q[this is a string] + +%|also a string| +%{also a string} +%(also a string) +%> +%[also a string] + +# apostrophed strings +%q|apostrophed| +%q{apostrophed} +%q(apostrophed) +%q> +%q[apostrophed] + +# regular expressions +%r{expression} +%r(expression) +%r> +%r[expression] +%r|expression| + +# shell commands +%x{ls -l} +%x(ls -l) +%x> +%x[ls -l] + +# sometimes it's useful to have the command on multiple lines +%x{ls -l | +grep test } + +# alternative syntax +`ls -l` +`echo ' '` + +# token array +%w{one two three} +%w(one two three) +%w> +%w[one two three] + +# snippet from Net::IMAP +# I object to putting String, Integer and Array into kernel methods. +# While these classes are builtin in Ruby, this is an implementation detail +# that should not be exposed to the user. +# If we want to handle all std-lib classes, fine. But then they should be in their +# own std-lib keyword category. + +def send_data(data) + case data + when nil + put_string("NIL") + when String + send_string_data(data) + when Integer + send_number_data(data) + when Array + send_list_data(data) + when Time + send_time_data(data) + when Symbol + send_symbol_data(data) + elseelse + data.send_data(self) + end +end + +# snippet from Net::POP +# class names can have numbers in them as long as they don't begin with numbers +# Ruby doesn't internally really make much of a difference between a class name and a constant + +# class aliases + POP = POP3 + POPSession = POP3 + POP3Session = POP3 + +# "member access" +POP::Session.COUNT.attribute.calc_with(2){ |arg| puts arg } + +# snippet from Net::SMTP +# This breaks the code folding. I think we would need to +# handle the '\' that continues the statement to the next line +# in some way to make these kind of things not break something. +raise ArgumentError, 'both user and secret are required'\ + unless user and secret + +# string escapes must detect escaping the escape char +str = "\\" +str = "\\\\" +# this is not part of the string +%x{echo \\\}\\} # prints \}\ +# this is not part of the command + +# these are all symbols +:abc +:abc! +:abc? +:abc= +:[] +:[]= +:@abc +:@@abc +:$abc diff --git a/autotests/folding/highlight.scheme.fold b/autotests/folding/highlight.scheme.fold new file mode 100644 index 0000000..c42b22f --- /dev/null +++ b/autotests/folding/highlight.scheme.fold @@ -0,0 +1,186 @@ +; This is a test file to test kates scheme highlighting +; This is a comment + +;; Another comment, usually used. +;BEGIN region marker +;; a vektor +#(1 2 3 4 5) +;END region marker +;; this represents integer 28 (FIXME: does not work perfectly atm!) +28 028 #e28 #i28 ;; Normal, normal, exact, inexact +#b11100 #o34 #d28 #x1c ;; Bin, okt, dec, hex +#oe34 #eo34 ;; combined. + +;; char. +(#\y #\space) ;; list: `y' space. +(#\ #\\ #\)) ;; list of spaces, backslash and`)'. +#\newline ;; a newline-char +#\NewLine ;; another one :) + +"Hello, world" ;; a string + +"hoho, what do you +want to do ;; this is NO comment +with that?" + +;; R5RS definiert diese beiden. +"Das ist \"in Anführungszeichen\" und mit \\ Backslash." + +(let ((x (+ 1 2)) (y "blah")) ;; `let' highlighting. + (and (number? x) ;; `and' highlighting. + (string? y))) + +(let* ((x 2) (y (+ x 1))) ;; `let*' too. + (or (negative? x) ;; `or' anyways. + (negative? y))) + +(do ((vec (make-vector 5)) ;; `do' you may guess! + (i 0 (+ i 1))) + ((= i 5) vec) + (vector-set! vec i i)) + +(quasiquote ((+ 1 2) (unquote (+ 1 2)))) +;; same as: `((+ 1 2) ,(+ 1 2)) + +;; see above. +(quasiquote ((+ 1 2) (unquote-splicing (list 1 2 3)))) +;; same as: `((+ 1 2) ,@(+ 1 2)) + +;; not necessary. +(quote ()) + +(cond ((string? x) (string->symbol x)) ;; `cond' highlighting. + ((symbol? x) => (lambda (x) x)) ;; `=>' highlighting. + (else ;; `else' highlighting. + (error "Blah"))) + +(case x ;; `case' highlighting. + ((#t) 'true) ((#f) 'false) + ((()) 'null) + ((0) 'zero)) + +;; highlight `let-syntax' and `syntax-rules' . +(let-syntax ((when (syntax-rules () + ((when test stmt1 stmt2 ...) + ;; hl `begin' . + (if test (begin stmt1 stmt2 ...)))))) + (let ((if #t)) ;; here`if' is actually no keyword. + (when if (set! if 'now)) ;; nor here. + if)) + +(letrec-syntax ...) ;; hl `letrec-syntax'. + +(define-syntax when + (syntax-rules () + ((when test stmt1 stmt2 ...) + (if test (begin stmt1 stmt2 ...)))))) + +;; variable definitions. +(define natural-numbers ;; hl `define' and the var name + ;; endless stream of all natual numbers. + (letrec ((next-cell ;; hl `letrec'. + (lambda (x) ;; hl `lambda'. + ;; hl `delay' . + (cons x (delay (next-cell (+ x 1))))))) + (next-cell 0))) + +;; a procedure with unusual but allowed name. +(define 1+ + (lambda (x) + (+ x 1))) + +;; a predicate +(define between? + (lambda (x y z) + (if (and (>= x y) (<= x z)) + #t ;; True + #f))) ;; False. + +;; imperative procedure +(define set-something! + (lambda (required-argument another-one . all-remaining-args) + (set-car! another-one (lambda all-args + (set-cdr! required-argument + (append all-remaining-args + all-args)))))) + +(define compose + (lambda (f g) + (lambda (x) + (f (g x))))) + +;; syntactical sugar for procedure-definitions. +(define (compose f g) + (lambda (x) + (f (g x)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; NOW: Guile extensions ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; procedure-generator. +(define ((compose f g) x) + (f (g x))) + +;; scheme doesn't say, which chars may be in variables... +;; At least: Guile accepts umlauts +(define-private (timetr??? sprache) ;; hl `define-private'. + (list-dialekt? sprache)) + +(define-public x #t) ;; hl `define-public'. +(define-module (foo bar)) ;; hl `define-module'. +(define-macro (neither . exprs) ;; hl `define-macro'. + `(and ,@(map (lambda (x) `(not ,x)) exprs))) + +(defmacro neither exprs ;; `defmacro' as well. + `(and ,@(map (lambda (x) `(not ,x)) exprs))) + +;; hl, but I really don't know what this is supposed to do :-) +(define-syntax-macro ...) + +;; hl GOOPS-`defines' +(define-method (foo bar (baz ) qux) ...) +(define-class ...) +(define-generic foo) +(define-accessor bar) + +;; Keywords! +(blah #:foo 33 #:bar 44) + +;; another convention for symbols: +#{foo}# + +#{a +few +lines}# + +#{4711}# + +;; more chars. +#\nul #\nl #\esc #\bs #\bel #\syn #\ack #\sp ;; etc, utc, itc, oops (this is boring) + +#! + guile block-comment. +!# + +;; now, a bit hairy: +#! comment !# +still comment!!! +!# +'now-no-comment-anymore + +;; more precise: +#! comment !# +still comment +!# still comment! +!# +'now-no-comment-anymore + +(while (> foo 10) ;; Highlight `while'. + (set! foo (- foo 1)) + (catch #t ;; Highlight `catch'. + (lambda () (display foo)) + (lambda (key . args) + (if (eq? key 'system-error) + (break) ;; Highlight `break'. + (continue))))) ;; Highlight `continue'. diff --git a/autotests/folding/highlight.sh.fold b/autotests/folding/highlight.sh.fold new file mode 100644 index 0000000..9f81112 --- /dev/null +++ b/autotests/folding/highlight.sh.fold @@ -0,0 +1,207 @@ +#! /bin/sh +# This is a test script for the Katepart Bash Syntax Highlighting by +# Wilbert Berendsen. This is not runnable !!! + + +# The highlighting recognizes basic types of input, and has a few special cases that +# are all in FindCommands. The main objective is to create really proper nesting of +# (multiline) strings, variables, expressions, etc. + + + +# ============== Tests: =============== + +# basic types: +echo 'single quoted string' +echo "double quoted string" +echo $'string with esc\apes\x0din it' +echo $"string meant to be translated" + + +# comments: +# this is a comment +#this too +echo this is#nt a comment +dcop kate EditInterface#1 #this is + + +# brace expansion +mv my_file.{JPG,jpg} + + +# special characters are escaped: +echo \(output\) \&\| \> \< \" \' \* + + +# variable substitution: +echo $filename.ext +echo $filename_ext +echo ${filename}_ext +echo text${array[$subscript]}.text +echo text${array["string"]}.text +echo ${!prefix*} +echo ${!redir} +echo short are $_, $$, $?, ${@}, etc. +echo ${variable/a/d} +echo ${1:-default} + + +# expression subst: +echo $(( cd << ed + 1 )) + + +# command subst: +echo $(ls -l) +echo `cat myfile` + + +# file subst: +echo $(<$filename) +echo $( my_file.txt 2>&1 + + +# All substitutions also work in strings: +echo "subst ${in}side string" 'not $inside this ofcourse' +echo "The result is $(( $a + $b )). Thanks!" +echo "Your homedir contains `ls $HOME |wc -l` files." + + +# Escapes in strings: +p="String \` with \$ escapes \" "; + + +# keywords are black, builtins dark purple and common commands lighter purple +set +exit +login + + +# Other colorings: +error() { + cat /usr/bin/lesspipe.sh + runscript >& redir.bak + exec 3>&4 +} + + +# do - done make code blocks +while [ $p -lt $q ] +do + chown 0644 $file.$p +done + + +# braces as well +run_prog | sort -u | +{ + echo Header + while read a b d + do + echo $a/$b/$c + done + echo Footer +} + + +# Any constructions can be nested: +echo "A long string with $( + if [ $count -gt 100 ] ; then + echo "much" + else + echo "not much" + fi ) substitutions." ; + + +# Even the case construct is correctly folded: +test -f blaat && +( do_something + case $p in + *bak) + do_bak $p + ;; + *) + dont_bak $p + ;; + esac +) # despite the extra parentheses in the case construction. + + +# variable assignments: +DIR=/dev +p=`ls` +LC_ALL="nl" dcop 'kate*' +_VAR=val +ARR=(this is an array) +ARR2=([this]=too [and]="this too") +usage="$0 -- version $VERSION +Multiple lines of output +can be possible." +ANSWER=yes # here 'yes' isn't highlighed as command + + +# Some commands expect variable names, these are colored correctly: +export PATH=/my/bin:$PATH BLAAT +export A B D +local p=3 x y='\' +read x y z <<< $hallo +unset B +declare -a VAR1 VAR2 && exit +declare less a && b + +# options are recoqnized: +zip -f=file.zip +./configure --destdir=/usr +make destdir=/usr/ + + +# [[ and [ correctly need spaces to be regarded as structure, +# otherwise they are patterns (currently treated as normal text) +if [ "$p" == "" ] ; then + ls /usr/bin/[a-z]* +elif [[ $p == 0 ]] ; then + ls /usr/share/$p +fi + +# Fixed: +ls a[ab]* # dont try to interprete as assignment with subscript (fixed) +a[ab] +a[ab]=sa + + +# Here documents are difficult to catch: +cat > myfile << __EOF__ +You're right, this is definitely no bash code +But ls more $parameters should be expanded. +__EOF__ + + +# quoted: +cat << "EOF" | egrep "this" >&4 # the rest of the line is still considered bash source +You're right, this is definitely no bash code +But ls more $parameters should be expanded. :-> +EOF + + +# indented: +if true +then + cat <<- EOF + Indented text with a $dollar or \$two + EOF +elif [ -d $file ]; then + cat <<- "EOF" + Indented text without a $dollar + EOF +fi + + +case 1 in +2) echo xxx; +;; +1) echo yyy; +esacesac + +ls #should be outside of case 1 folding block diff --git a/autotests/folding/highlight.spec.fold b/autotests/folding/highlight.spec.fold new file mode 100644 index 0000000..6ed00cf --- /dev/null +++ b/autotests/folding/highlight.spec.fold @@ -0,0 +1,212 @@ +# Test file for rpmspec.xml + +# Comments start with a # in column="0": + +# Some comment + +# When they don't start in column="0", that they are recognized as comments, but with an alert: + # This is a bad comment. +# RPM spec says clear that comments must start at the begin of the line. However, in practice +# the RPM software is more permissive, depending on the context. But for our syntax highlighting, +# we give, while recognizing the as comment, at least a little alert. Comments should not contain +# the character % (which is marked as warning), but 2 of them are okay: %%. TODO is higlighted. + +# A spec file starts with "Normal" context. Here, you can specify values for some tags: +Name: kradioripper-unstable # Note that here in no comment possible! +Name: name only _one_ word allowed +Name: %macro no further syntax check after macro! +# Some tags support only _one_ word as value +Version: 0.4test5 up-from-the-space-this-is-an-error +# Some tag can have parameters: Any char in paranthesis: +Summary: Recorder for internet radios (based on Streamripper) +Summary(de.UTF-8): Aufnahmeprogramm für Internetradios (basiert auf Streamripper) +# requiere free text: +License: License 1 2 3 +# requiere a well defines value: +Requires( / ( = ): Some, value() +# new type "switch" accepts: yes, no, 0, 1 +AutoReq: yes +AutoReq: yes invalid +AutoReq: %macro no further syntax check after macro! +AutoReq: no +AutoReq: 0 +AutoReq: 1 +# requiere a number: +Epoch: 123123 +Epoch: 123123 invalid +Epoch: %macro no further syntax check afer macro! +# If tags are used that are not known, they are not highlighted: +Invalidtag: Some value +Invalid content in this section (only tags are allowed) + +# You can use conditions in specs (highlighted with region markers): +%if 0%{?mandriva_version} +# numbers and strings are distingished: string: +%if lsdksfj +# number: +%if 23472398 +# string: +%if lksdjfsl72939 +# invalid: +%if 92437lsdkfjdsl +# valid: +%if "lsdfj %ksdf(sdfs) 3489" +Release: %mkrel 1.2 +%else %else +Release: 0 +%endif +# requiere a well defined value: +%ifos fixed_value +# You must use these special macros (%%if etc.) always at the start of the line - if not, +# that's bad but not an arror. You must also always use the specified form. Everything else is an +# error: + %if +something %if +%{if} +%if(some options) +# However, this are different macros and therefore correct: +%ifx +%{ifx} +%ifx(some options) + +# the \ is escaped in the line. At the end of the line it escapes the line break: +echo This is \" a text \\ and here\ +it continues. + +%define name value +%define invalid_näme value +%define macroname multi\ +line content with references like %0 %* %# %{-f} %{-f*} %1 %2 and so on +%global name value +%global invalid_näme value +%undefine name +%undefine name too-many-parameters + +# This special comment is treated and highlighted like a tag: +# norootforbuild +# It can't have parameters, so every following non-whitespace character is not good: +# norootforbuild DONT WRITE ANYTHING HERE! +# wrong spacing is also recognized: +# norootforbuild +# and also an indeet is not fine for norootforbuild: + # norootforbuild + +# This following "Conflicts" tag will be removed by set-version.sh, +# if it is a "kradioripper" release (and not a "kradioripper-unstable" release)... +Conflicts: kradioripper + + +%description +# Here, a new section starts. It contains a value for the RPM field "description" and is therefor +# colored like values: +A KDE program for ripping internet radios. Based on StreamRipper. + + +# A section start can have parameters: +%description -l de.UTF-8 +Ein KDE-Aufnahmeprogramm für Internetradios. Basiert auf StreamRipper. + +# These sections starts are errors: + %description not at the first line +%{description} wrong form +%description(no options allowed, only parameters!) + + +%prep +# This starts a section that defines the commands to prepare the build. +# q means quit. n sets the directory: +%setup -q -n kradioripper +echo Test +# Macros can have different forms: Valid: +%abc +%abcÄndOfMacro +%abc(def)EndOfMacro +%{abc}EndOfMacro +%{something but no single %}EndOfMacro +%{abc:def}EndOfMacro +%(abc) +# Invalid: +%ÄInvalidChar +% +%) +%} +# You can use macros inside of macro calls: Fine: +%{something %but no %{sin%(fine)gle} }EndOfMacro +# Bad: +%{No closing paranthesis (No syntax highlightig for this error available) + + +%build +cmake ./ -DCMAKE_INSTALL_PREFIX=%{_prefix} +%__make %{?jobs:-j %jobs} + + +%install +%if 0%{?suse_version} +%makeinstall +%suse_update_desktop_file kradioripper +%endif +%if 0%{?fedora_version} || 0%{?rhel_version} || 0%{?centos_version} +make install DESTDIR=%{buildroot} +desktop-file-install --delete-original --vendor fedora --dir=%{buildroot}/%{_datadir}/applications/kde4 %{buildroot}/%{_datadir}/applications/kde4/kradioripper.desktop +%endif +%if 0%{?mandriva_version} +%makeinstall_std +%endif + + +%clean +rm -rf "%{buildroot}" + + +%files +%defattr(-,root,root) +%if 0%{?fedora_version} || 0%{?rhel_version} || 0%{?centos_version} +%{_datadir}/applications/kde4/fedora-kradioripper.desktop +%else %else +%{_datadir}/applications/kde4/kradioripper.desktop +%endif +%{_bindir}/kradioripper +%{_datadir}/locale/*/LC_MESSAGES/kradioripper.mo +%if 0%{?mandriva_version} +# TODO The %%doc macro is actually broken for mandriva 2009 in build service... +%dir %{_datadir}/apps/kradioripper +%{_datadir}/apps/kradioripper/* +%else %else +%doc COPYING LICENSE LICENSE.GPL2 LICENSE.GPL3 NEWS WARRANTY +%dir %{_datadir}/kde4/apps/kradioripper +%{_datadir}/kde4/apps/kradioripper/* +%endif + + +%changelog +* Sun May 04 2008 email@email.com +- some text +- some text + in two lines +- some text + in two lines + + with subtext + - and more subtext + in two lines +* Tue Apr 24 2007 Name +- text + * When the star isn't at column 0, than it doesn't indicate + a new date +* Wen Sep 08 2003 Wrong weekday +* Mon Mai 08 2003 Wrong month +* Mon Sep 0 2003 bad day +* Mon Sep 8 2003 good day +* Mon Sep 08 2003 good day +* Mon Sep 32 2003 bad day +* Mon Sep 08 03 bad year +* Mon Sep 08 2003 Name +# When using macros, the error check is disabled: +* %myDataMacro Title of the entry +- Text + - can + - be + - indeeded + - without + - problems + diff --git a/autotests/folding/highlight.t2t.fold b/autotests/folding/highlight.t2t.fold new file mode 100644 index 0000000..428f204 --- /dev/null +++ b/autotests/folding/highlight.t2t.fold @@ -0,0 +1,90 @@ +txt2tags sample + + +%!--includeconf: config.t2t +% disabled here because there is no external file +%!preproc: 'JUST A TEST' ' ' +%!postproc: '(?i)()' ' shots\1' + +%!--include: menu.t2t + += Title 1 == Title 1 = + + +== My Subtitle 1 ==[some definition]== My Subtitle 1 ==[some definition] + +Some examples: + +- A paragraph with **bold**, //italic// and --strike--. +- You can even __underline your docs__! + +- And use **//bold and italic//** +- or //**italic and bold**// + +Here is a nice pic: [img/t2tpowered.png]. + +- And a [link to a cool website http://txt2tags.sf.net]! + +- A table : + + || Name | Age | Gender | + | John | 33 | Male | + | Mary | 19 | Female | + + +``` A verbatim line + +And it's working for ``special code`` like this. + +``` +Unfortunately I can't color this verbatim content yet. +``` + + +== My Subtitle 2 ==== My Subtitle 2 == + + +Lorem ipsum etc +Lorem ipsum etc Lorem ipsum etc + +- Test d'écriture avec des accents à la française. Ça marche ou pas ? + +== My Subtitle 3 ==== My Subtitle 3 == + + +Lorem ipsum etc +Lorem ipsum etc + +Here is a direct link: http://kde.org + + +- Another boring part... + + + +=== My Subsubtitle 1 ====== My Subsubtitle 1 === + +//It's a level 3 header// + +- list 1 +- list 2 + - list 2b +- list 3 + + +=== My Subsubtitle 2 ====== My Subsubtitle 2 === + +//It's another level 3 header// + ++ ordered list 1 ++ list 2 + + list 2B + + list 2C ++ list 3 + + +== My Subtitle 4 ==== My Subtitle 4 == + +nothing to say here... + diff --git a/autotests/folding/highlight.tcl.fold b/autotests/folding/highlight.tcl.fold new file mode 100644 index 0000000..7b6264c --- /dev/null +++ b/autotests/folding/highlight.tcl.fold @@ -0,0 +1,50 @@ +# tcl syntax highlighting sample script for Kate +# +# author: JM. Philippe 15/03/04 + +# escaped characters +set String \{ +set String \{ +set String \" +set String " \" " +set String " \{ " + +#comments and not comments +# is comments +;#is comments + # is comments +#

is html comment

+puts ok; # is comments +set String [string map { {»is not comments}} $String] +set String \#not_a_comment + +# blocks +proc test {arg1 {arg2 {}} {arg3 {fr fq r}}} { + if {1} {; #comments + set String \{; # not a block start + } +} + +proc test args { + set String \}; # not a block end +} + +# BEGIN - collapsable comments +# blablabla +# END + +# strings +set String "feqr feqr $gqer gqe" +set String "feqr +feqr \" $gqer \ +gqe +" +set String {feqr +feqr \{ $gqer \ +gqe +} + +# variables +set b+1 [incr b] +set {incr-b} ${b+1} +puts ${incr-b} diff --git a/autotests/folding/highlight.tex.fold b/autotests/folding/highlight.tex.fold new file mode 100644 index 0000000..015b4cc --- /dev/null +++ b/autotests/folding/highlight.tex.fold @@ -0,0 +1,73 @@ +% LaTeX test file for kate's syntax highlighting and code folding + +\ordinaryLaTeXcommandwithoption[10pt,a4paper]{article} +% BEGIN region +%comment, this is all ok % $ +\%no comments please +\\%comment +% END of region + +\newcommand{\nohighlighting} + +\section{normal} + +\ref{blue} +\pageref{blue} +\cite{blue} + +\begin{environmentshavespecialcolors} +normal +\end{environmentshavespecialcolors} + +$equations are green, \commands somewhat darker$ +normal +$$equations are green, \commands somewhat darker$$ +normal +\( +\frac{1}{2} +\begin{test} +\end{test} +\) +normal +\[ +%comment +displaymath +\] +normal +\begin{equation} +green\darkergreen +\begin{test} +\test +\end{test} +\end{equation} + +\begin{equation*} +green\darkergreen +%comment +\begin{test} +\test +\end{test} +\%no comment +\end{equation*} + +\{ %this should be comment + +\verb%this shouldn't be%and this should be normal text + +\begin{verbatim} +text inside a verbatim environment is also treated special $ %, +you can even put a \begin{verbatim} inside +\end{verbatim} + +normal + +\begin{Verbatim} +&@@#^%&^#$ +\end{Verbatim} + + +\begin{Verbatim*} +@*&^#@*(^#(*@& +\end{Verbatim*} + +normal diff --git a/autotests/folding/highlight.wrl.fold b/autotests/folding/highlight.wrl.fold new file mode 100644 index 0000000..c800b08 --- /dev/null +++ b/autotests/folding/highlight.wrl.fold @@ -0,0 +1,41 @@ +#VRML V2.0 utf8 +# +# VRML highlighting test for Kate's syntax highlighting +# + +# Keywords +DEF, EXTERNPROTO, FALSE, IS, NULL, PROTO, ROUTE, TO, TRUE, USE, eventIn, +eventOut, exposedField, field + +# Data types +MFColor, MFFloat, MFInt32, MFNode. MFRotation, MFString, MFTime, MFVec2f, +MFVec3f, SFBool, SFColor, SFFloat, SFImage, SFInt32, SFNode, SFRotation, +SFString, SFTime, SFVec2f, SFVec3f + +# Predefined nodes +Anchor, Appearance, AudioClip, Background, Billboard, Box, Collision, Color, +ColorInterpolator, Cone, Coordinate, CoordinateInterpolator, Cylinder, +CylinderSensor, DirectionalLight, ElevationGrid, Extrusion, Fog, FontStyle, +Group, ImageTexture, IndexedFaceSet, IndexedLineSet, Inline, LOD, Material, +MovieTexture, NavigationInfo, Normal, NormalInterpolator, OrientationInterpolator, +PixelTexture, PlaneSensor, PointLight, PointSet, PositionInterpolator, +ProximitySensor, ScalarInterpolator, Script, Shape, Sound, Sphere, SphereSensor, +SpotLight, Switch, Text, TextureCoordinate, TextureTransform, TimeSensor, +TouchSensor, Transform, Viewpoint, VisibilitySensor, WorldInfo + +# Some real VRML constructs to see if highlighting of int, float etc. works +NavigationInfo { + avatarSize [0.25, 1.6, 0.75] + headlight TRUE + speed 1 + type ["WALK", "ANY"] + visibilityLimit 0.0 +} + +# some further testing for strings: linefeeds are allowed within strings +Text { + string ["some special in-string characters: \" \\ + some more text in the next line + and yet another line"] +} + diff --git a/autotests/folding/highlight.xml.fold b/autotests/folding/highlight.xml.fold new file mode 100644 index 0000000..b120aea --- /dev/null +++ b/autotests/folding/highlight.xml.fold @@ -0,0 +1,67 @@ + version="1.0" encoding="UTF-8"?> +language SYSTEM "language.dtd"> + + + +This is a pseudo XML file to test Kate's XML syntax highlighting. + +Doctype: + HTML PUBLIC "-//SOME_DOCTYPE 0.01//EN" SYSTEM "foobar.dtd"> + +Processing instruction: + processing instruction ?> + +Comments: + + + +Comment inside element: + attr="foobar">content> + +Markup inside comment: + + +Empty element: + /> + /> + +Simple element plus content: + >some content> + attr="foobar">some + content> + +Namespace for elements and attributes: + >content> + ns:attr="content content">content> + +Elements containing allowed characters: + foo="test"/> + foo="test"/> + +Elements containing allowed start characters: + <:element foo="test"/> + <_element foo="test"/> + +Single quotes (the same as double quotes): + attr='content   content'>content> + +Allowed Whitespace: + attr = "test" > + content> + +Entities: +   + å + å + å + И + 水 + attr="foo   å & bar"/> + +Illegal XML, should not be highlighted: + <0foobar> -- no digit as first character + <-foo> -- no dash as first character diff --git a/autotests/folding/highlight.xsl.fold b/autotests/folding/highlight.xsl.fold new file mode 100644 index 0000000..feea15b --- /dev/null +++ b/autotests/folding/highlight.xsl.fold @@ -0,0 +1,109 @@ + version="1.0" encoding="iso-8859-15"?> + + + + + + + + +Linux at Home Links + + + + <xsl:value-of select="h:a/h:strong"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:value-of select="normalize-space($title)"/> + + + + + + + + + diff --git a/autotests/folding/highlight.y.fold b/autotests/folding/highlight.y.fold new file mode 100644 index 0000000..2b121a9 --- /dev/null +++ b/autotests/folding/highlight.y.fold @@ -0,0 +1,54 @@ +/* Yacc / Bison hl test file. + * It won't compile :-) Sure ! + */ + +%{ + +#include +using namespace std; + +extern KateParser *parser; + +%} + +%locations + +%union { + int int_val; + double double_val; + bool bool_val; + char *string_val; + char *ident_val; + struct var *v; + void *ptr; +} + +%token TOK_NOT_EQUAL "!=" +%token TOK_LESSER_E "<=" +%token TOK_GREATER_E ">=" +%token TOK_EQUAL_2 "==" + +%type type type_proc + +%%%% + +prog: KW_PROGRAM ident { parser->start($2); } prog_beg_glob_decl instructions { parser->endproc(0); } dev_procedures KW_ENDP ; + +number: integer_number + | TOK_DOUBLE + { + $$ = new var; + $$->type = KW_REEL; + $$->cl = var::LITTERAL; + $$->real = $1; + }; + +%%%% + +#include + +int main(void) +{ + puts("Hello, World!"); + return 0; +} diff --git a/autotests/folding/highlight_lpc.c.fold b/autotests/folding/highlight_lpc.c.fold new file mode 100644 index 0000000..350ce06 --- /dev/null +++ b/autotests/folding/highlight_lpc.c.fold @@ -0,0 +1,64 @@ +// NOTE: This is a test file for kate's LPC syntax highlighting. + +// This is a Single-Line Comment +/* This is a Multi- + Line Comment */ + +// This again is a Single-Line Comment which should end here /* + +// And this is an evil single line comment \ + which should include this and the next line because of the \ + Do not use this style at home, kids. +// BEGIN region marker + +// END of region marker + +private void create() +{ +// Some Preprocessor stuff: +#define SOME_STUFF if(foo("bar")) \ + { \ + bar("foo"); \ + } // Preprocessor, Keyword, Preprocessor-String, Multiline + + // Some closures: + #'create; + #'?!; + + + /* Some other Data Types: */ + + int i = 1; // Integer. + float b = 2.34; // Float. + int c = 0b001; // Binary + int e = 0x019Beef; // Hexadecimal + int f = 0o2345; // Octal + string a = "Wheee"; // String + string x = "Wheee\ + heee"; // Multi-Line String, again, don't use this. + + + + /* Some keywords: */ + if(1) + { + switch(2) + { + case 3: + 4; + break; + } + } + + else + { + return 0; + } +} + +/* +WARNING: If the above function is part of a multi-line comment, + it's buggy. The WARNING: itself should be a comment-keyword. + That's not actually part of the language, but simply used + to highlight important stuff inside comments like TODO: etc. +*/ diff --git a/autotests/folding/highlight_ocaml.ml.fold b/autotests/folding/highlight_ocaml.ml.fold new file mode 100644 index 0000000..2403ed1 --- /dev/null +++ b/autotests/folding/highlight_ocaml.ml.fold @@ -0,0 +1,105 @@ +(* ocaml test file -- a big stew of Objective Caml syntax to use to + test Kate's syntax highlighting. This will not run! :-) *) + +(* First a little piece of real OCaml that should look right: *) + + #load "basic";; + (* Return a default value for a BASIC variable given its identifer. *) + let default_value (ident : string) : basic_value = + assert (String.length ident > 0); + match ident.[String.length ident - 1] with + | '$' -> Str "" + | '%' -> Int 0 + | '!' -> Flt 0.0 + | _ -> Flt 0.0 + ;; + +(* Directives: *) +#load "pa_o";; + #load "pa_o";; +object # meth ;; (* not a directive - a method call *) +object + # meth ;; (* not a directive - a method call *) + +(* OCaml keywords: *) +and as assert asr (* etc. there so many... *) + +(* Additional OCaml Revised Syntax keywords: *) +(* These are in a seperate category so they can be coloured to look + like identifiers when ordinary OCaml syntax is being used: *) +declare where value + +(* There's no way to reliably highlight all OCaml type expressions, + (they can be very complex) so just the built-in type names are highlighted.*) +exn lazy_t format unit int real char string ref array bool list option + + +let integers : int list = [ + 123456789; (* decimal *) + -0xabcedf0123456789; (* hexadecimal *) + 0xABCDEF0123456789; (* hexadecimal *) + -0o1234567; (* octal *) + 0b01001010101010; (* binary *) + -0Xabcedf0123456789; (* hexadecimal *) + 0XABCDEF0123456789; (* hexadecimal *) + -0O1234567; (* octal *) + 0B01001010101010; (* binary *) + -123_456_789; (* Underscores are allowed in numeric constants. *) + 0x_abce_df01_2345_6789; + -0o12_34_567; + 0b_0100_1010_1010_1101; +];; + +let floats : real list = [ + 12345.6789; + -1.23456789e4; (* All variations of the exponent form *) + 1.23456789e+4; + -1.23456789e-4; + 1.23456789E-4; + -1.23456789E+4; + 12_345.6789; (* Underscores are allowed in numeric constants. *) + -1.23_456_789e+4; + 12_345.6789; +];; + +let characters : char list = [ + 'a'; + ' '; + '�'; + '\n'; '\r'; '\t'; '\b'; (* Control characters. Only these four: not the full C-language range. *) + '\000'; '\128'; (* Decimal character codes. These are always 3 digits. *) + '\x02'; '\xff'; '\xFF'; (* Hexadecimal character codes. These are always 3 digits. *) + '\\'; '\''; '\"'; '"' (* Quote character escapes. *) +];; + +(* Quotes used to mark constants in parsers should + not be confused with character constant quotes. + "Ticks" at the end of identifiers should + not be confused with character constant quotes. *) +let basic_identifier = + parser + [< ''F'; ''N'; name = s >] -> ID (s, 'f') + | [< name = s' >] -> ID (s','i') +;; + +let strings : string list = [ + ""; (* Empty string *) + "a"; " "; "�"; "ab"; + "A\nB"; "A\rB"; "A\tB"; "A\bB"; (* Control characters. Only these four: not the full C-language range. *) + "A\000B"; "A\128B"; (* Decimal character codes. These are always 3 digits. *) + "A\x02B"; "A\xffB"; "A\xFFB"; (* Hexadecimal character codes. These are always 3 digits. *) + "A\\B"; "A\'B"; "A'B"; "A\"B"; (* Quote character escapes. *) + "A multiline\ + string"; +]; + +let camlp4_quotations = [ + <> ; + <:QUOTE> ; + <:QU�T�> ; + << A quote with an escape: \>> (end-quote symbol) >> ; + << A quote with an escape: \<< (plain start quote-symbol) >> ; + << A quote with an escape: \<:Trouv�< (labelled start-quote symbol) >> ; +];; + +(* end *) diff --git a/autotests/folding/highlight_octave.m.fold b/autotests/folding/highlight_octave.m.fold new file mode 100644 index 0000000..ee3fdbd --- /dev/null +++ b/autotests/folding/highlight_octave.m.fold @@ -0,0 +1,74 @@ +##===================================================== +% Octave test code for Kate/Kwrite syntax highlighting +% (shamelessly copied from Matlab's, since the two +% are very similar) +% kate: hl Octave; +##===================================================== + +% Numbers _____________________________________________ +5, 5.5, .1, 0.1, 0.4e5, 1.2e-5, 5i, 5.3i, 6j, .345+3i +5', 5.5', .1', 0.1', 0.4e5', 1.2e-5', 5i', 5.3i', 6j', .345+3i' + +% Operators ___________________________________________ +% relational operators +'asdf'~=4, c<=4, d>=4, ab, a==b, b||c, b&&c +% elementwise arithmetic operators +a.^b, a.*b a./b, 1:4:5 +% single-character binary arithmetic +a+3, a-3, a*2, a^3, a/3, a\3, a|b, a&b +% unary operators +a = ~g; g = @sfdgdsf(sdfsd,345); g.' + 1i.' - ('asdf').' +% separators and delimiter +(asd),[sadf];{asdf},;;,;;;() +% continuation +a = 1+ ... + 2; + +% Strings and adjoint _________________________________ +% incomplete strings +'string +'str'' +'str''ing +'str''\' +% complete strings +'string' % simple string +'''' '\'' % strings containing ' +'str''ing' % one string containing ' +'string' 'string' % two strings +'asdf' "asdf""" variable % two strings and a variable +'asdf''asdf'' fsgdfg' + (asdf)' - 'asdf'.' + []''''.';'' +'sadf'.' % string transpose +% adjoint +{'asdf'}' + 1 +('asdf')' + 1 +['asdf']' + 1 +'' var''' % empty string, var with >1 adjoints +[5]'*{5}'*('asd')'.'+(5)'*6'*asdf'*asdf'.' % many adjoints +A'*B + 1 % adjoint +A.'*B + 1 % transpose +A.'.'*B + 1 % double transpose +A'.' + 1 % adjoint, then transpose +A.'' % transpose, then adjoint + +% System command ______________________________________ +!hostname +!cp * /tmp + +% Reserved keywords ___________________________________ +function, persistent, global +endfunction + +switch, case, otherwise +endswitch + +if, else, elseif +endif + +try, end_try_catch +for, while, break, continue +endfor + +endwhile +return +function, FUNCTION, Function % case sensitive! +endfunction diff --git a/autotests/folding/learnelixir.exs.fold b/autotests/folding/learnelixir.exs.fold new file mode 100644 index 0000000..1f51bd1 --- /dev/null +++ b/autotests/folding/learnelixir.exs.fold @@ -0,0 +1,397 @@ +# Original: https://learnxinyminutes.com/docs/elixir/ + +# Single line comments start with a number symbol. + +# There's no multi-line comment, +# but you can stack multiple comments. + +# To use the elixir shell use the `iex` command. +# Compile your modules with the `elixirc` command. + +# Both should be in your path if you installed elixir correctly. + +## --------------------------- +## -- Basic types +## --------------------------- + +# There are numbers +3 # integer +0x1F # integer +3.0 # float + +# Atoms, that are literals, a constant with name. They start with `:`. +:hello # atom + +# Tuples that are stored contiguously in memory. +{1,2,3} # tuple + +# We can access a tuple element with the `elem` function: +elem({1, 2, 3}, 0) #=> 1 + +# Lists that are implemented as linked lists. +[1,2,3] # list + +# We can access the head and tail of a list as follows: +[head | tail] = [1,2,3] +head #=> 1 +tail #=> [2,3] + +# In elixir, just like in Erlang, the `=` denotes pattern matching and +# not an assignment. +# +# This means that the left-hand side (pattern) is matched against a +# right-hand side. +# +# This is how the above example of accessing the head and tail of a list works. + +# A pattern match will error when the sides don't match, in this example +# the tuples have different sizes. +# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2} + +# There are also binaries +<<1,2,3>> # binary + +# Strings and char lists +"hello" # string +'hello' # char list + +# Multi-line strings +""" +I'm a multi-line +string. +""" +#=> "I'm a multi-line\nstring.\n" + +# Strings are all encoded in UTF-8: +"héllò" #=> "héllò" + +# Strings are really just binaries, and char lists are just lists. +<> #=> "abc" +[?a, ?b, ?c] #=> 'abc' + +# `?a` in elixir returns the ASCII integer for the letter `a` +?a #=> 97 + +# To concatenate lists use `++`, for binaries use `<>` +[1,2,3] ++ [4,5] #=> [1,2,3,4,5] +'hello ' ++ 'world' #=> 'hello world' + +<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>> +"hello " <> "world" #=> "hello world" + +# Ranges are represented as `start..end` (both inclusive) +1..10 #=> 1..10 +lower..upper = 1..10 # Can use pattern matching on ranges as well +[lower, upper] #=> [1, 10] + +## --------------------------- +## -- Operators +## --------------------------- + +# Some math +1 + 1 #=> 2 +10 - 5 #=> 5 +5 * 2 #=> 10 +10 / 2 #=> 5.0 + +# In elixir the operator `/` always returns a float. + +# To do integer division use `div` +div(10, 2) #=> 5 + +# To get the division remainder use `rem` +rem(10, 3) #=> 1 + +# There are also boolean operators: `or`, `and` and `not`. +# These operators expect a boolean as their first argument. +true and true #=> true +false or true #=> true +# 1 and true #=> ** (ArgumentError) argument error + +# Elixir also provides `||`, `&&` and `!` which accept arguments of any type. +# All values except `false` and `nil` will evaluate to true. +1 || true #=> 1 +false && 1 #=> false +nil && 20 #=> nil +!true #=> false + +# For comparisons we have: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` and `>` +1 == 1 #=> true +1 != 1 #=> false +1 < 2 #=> true + +# `===` and `!==` are more strict when comparing integers and floats: +1 == 1.0 #=> true +1 === 1.0 #=> false + +# We can also compare two different data types: +1 < :hello #=> true + +# The overall sorting order is defined below: +# number < atom < reference < functions < port < pid < tuple < list < bit string + +# To quote Joe Armstrong on this: "The actual order is not important, +# but that a total ordering is well defined is important." + +## --------------------------- +## -- Control Flow +## --------------------------- + +# `if` expression +if false do + "This will never be seen" +else + "This will" +end + +# There's also `unless` +unless true do + "This will never be seen" +else + "This will" +end + +# Remember pattern matching? Many control-flow structures in elixir rely on it. + +# `case` allows us to compare a value against many patterns: +case {:one, :two} do + {:four, :five} -> + "This won't match" + {:one, x} -> + "This will match and bind `x` to `:two`" + _ -> + "This will match any value" +end + +# It's common to bind the value to `_` if we don't need it. +# For example, if only the head of a list matters to us: +[head | _] = [1,2,3] +head #=> 1 + +# For better readability we can do the following: +[head | _tail] = [:a, :b, :c] +head #=> :a + +# `cond` lets us check for many conditions at the same time. +# Use `cond` instead of nesting many `if` expressions. +cond do + 1 + 1 == 3 -> + "I will never be seen" + 2 * 5 == 12 -> + "Me neither" + 1 + 2 == 3 -> + "But I will" +end + +# It is common to set the last condition equal to `true`, which will always match. +cond do + 1 + 1 == 3 -> + "I will never be seen" + 2 * 5 == 12 -> + "Me neither" + true -> + "But I will (this is essentially an else)" +end + +# `try/catch` is used to catch values that are thrown, it also supports an +# `after` clause that is invoked whether or not a value is caught. +try do + throw(:hello) +catch + message -> "Got #{message}." +after + IO.puts("I'm the after clause.") +end +#=> I'm the after clause +# "Got :hello" + +## --------------------------- +## -- Modules and Functions +## --------------------------- + +# Anonymous functions (notice the dot) +square = fn(x) -> x * x end +square.(5) #=> 25 + +# They also accept many clauses and guards. +# Guards let you fine tune pattern matching, +# they are indicated by the `when` keyword: +f = fn + x, y when x > 0 -> x + y + x, y -> x * y +end + +f.(1, 3) #=> 4 +f.(-1, 3) #=> -3 + +# Elixir also provides many built-in functions. +# These are available in the current scope. +is_number(10) #=> true +is_list("hello") #=> false +elem({1,2,3}, 0) #=> 1 + +# You can group several functions into a module. Inside a module use `def` +# to define your functions. +defmodule Math do + def sum(a, b) do + a + b + end + + def square(x) do + x * x + end +end + +Math.sum(1, 2) #=> 3 +Math.square(3) #=> 9 + +# To compile our simple Math module save it as `math.ex` and use `elixirc` +# in your terminal: elixirc math.ex + +# Inside a module we can define functions with `def` and private functions with `defp`. +# A function defined with `def` is available to be invoked from other modules, +# a private function can only be invoked locally. +defmodule PrivateMath do + def sum(a, b) do + do_sum(a, b) + end + + defp do_sum(a, b) do + a + b + end +end + +PrivateMath.sum(1, 2) #=> 3 +# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError) + +# Function declarations also support guards and multiple clauses: +defmodule Geometry do + def area({:rectangle, w, h}) do + w * h + end + + def area({:circle, r}) when is_number(r) do + 3.14 * r * r + end +end + +Geometry.area({:rectangle, 2, 3}) #=> 6 +Geometry.area({:circle, 3}) #=> 28.25999999999999801048 +# Geometry.area({:circle, "not_a_number"}) +#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 + +# Due to immutability, recursion is a big part of elixir +defmodule Recursion do + def sum_list([head | tail], acc) do + sum_list(tail, acc + head) + end + + def sum_list([], acc) do + acc + end +end + +Recursion.sum_list([1,2,3], 0) #=> 6 + +# Elixir modules support attributes, there are built-in attributes and you +# may also add custom ones. +defmodule MyMod do + @moduledoc """ + This is a built-in attribute on a example module. + """ + + @my_data 100 # This is a custom attribute. + IO.inspect(@my_data) #=> 100 +end + +## --------------------------- +## -- Structs and Exceptions +## --------------------------- + +# Structs are extensions on top of maps that bring default values, +# compile-time guarantees and polymorphism into Elixir. +defmodule Person do + defstruct name: nil, age: 0, height: 0 +end + +joe_info = %Person{ name: "Joe", age: 30, height: 180 } +#=> %Person{age: 30, height: 180, name: "Joe"} + +# Access the value of name +joe_info.name #=> "Joe" + +# Update the value of age +older_joe_info = %{ joe_info | age: 31 } +#=> %Person{age: 31, height: 180, name: "Joe"} + +# The `try` block with the `rescue` keyword is used to handle exceptions +try do + raise "some error" +rescue + RuntimeError -> "rescued a runtime error" + _error -> "this will rescue any error" +end +#=> "rescued a runtime error" + +# All exceptions have a message +try do + raise "some error" +rescue + x in [RuntimeError] -> + x.message +end +#=> "some error" + +## --------------------------- +## -- Concurrency +## --------------------------- + +# Elixir relies on the actor model for concurrency. All we need to write +# concurrent programs in elixir are three primitives: spawning processes, +# sending messages and receiving messages. + +# To start a new process we use the `spawn` function, which takes a function +# as argument. +f = fn -> 2 * 2 end #=> #Function +spawn(f) #=> #PID<0.40.0> + +# `spawn` returns a pid (process identifier), you can use this pid to send +# messages to the process. To do message passing we use the `send` operator. +# For all of this to be useful we need to be able to receive messages. This is +# achieved with the `receive` mechanism: + +# The `receive do` block is used to listen for messages and process +# them when they are received. A `receive do` block will only +# process one received message. In order to process multiple +# messages, a function with a `receive do` block must recursively +# call itself to get into the `receive do` block again. + +defmodule Geometry do + def area_loop do + receive do + {:rectangle, w, h} -> + IO.puts("Area = #{w * h}") + area_loop() + {:circle, r} -> + IO.puts("Area = #{3.14 * r * r}") + area_loop() + end + end +end + +# Compile the module and create a process that evaluates `area_loop` in the shell +pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0> +# Alternatively +pid = spawn(Geometry, :area_loop, []) + +# Send a message to `pid` that will match a pattern in the receive statement +send pid, {:rectangle, 2, 3} +#=> Area = 6 +# {:rectangle,2,3} + +send pid, {:circle, 2} +#=> Area = 12.56000000000000049738 +# {:circle,2} + +# The shell is also a process, you can use `self` to get the current pid +self() #=> #PID<0.27.0> diff --git a/autotests/folding/light52_muldiv.vhdl.fold b/autotests/folding/light52_muldiv.vhdl.fold new file mode 100644 index 0000000..c5d461e --- /dev/null +++ b/autotests/folding/light52_muldiv.vhdl.fold @@ -0,0 +1,239 @@ +-------------------------------------------------------------------------------- +-- light52_muldiv.vhdl -- Simple multiplier/divider module. +-------------------------------------------------------------------------------- +-- The 8051 mul and div instructions are both unsigned and operands are 8 bit. +-- +-- This module implements the division as a sequential state machine which takes +-- 8 cycles to complete. +-- The multiplier can be implemented as sequential or as combinational, in which +-- case it will use a DSP block in those architectures that support it. +-- No attempt has been made to make this module generic or reusable. +-- +-- If you want a combinational multiplier but don't want to waste a DSP block +-- in this module, you need to modify this file adding whatever synthesis +-- pragmas your tool of choice needs. +-- +-- Note that unlike the division state machine, the combinational product logic +-- is always operating: when SEQUENTIAL_MULTIPLIER=true, prod_out equals +-- data_a * data_b with a latency of 1 clock cycle, and mul_ready is hardwired +-- to '1'. +-- +-- FIXME explain division algorithm. +-------------------------------------------------------------------------------- +-- GENERICS: +-- +-- SEQUENTIAL_MULTIPLIER -- Sequential vs. combinational multiplier. +-- When true, a sequential implementation will be used for the multiplier, +-- which will usually save a lot of logic or a dedicated multiplier. +-- When false, a combinational registered multiplier will be used. +-- +-------------------------------------------------------------------------------- +-- INTERFACE SIGNALS: +-- +-- clk : Clock, active rising edge. +-- reset : Synchronous reset. Clears only the control registers not +-- visible to the programmer -- not the output registers. +-- +-- data_a : Numerator input, should be connected to the ACC register. +-- data_b : Denominator input, should be connected to the B register. +-- start : Assert for 1 cycle to start the division state machine +-- (and the product if SEQUENTIAL_MULTIPLIER=true); +-- +-- prod_out : Product output, valid only when mul_ready='1'. +-- quot_out : Quotient output, valid only when div_ready='1'. +-- rem_out : Remainder output, valid only when div_ready='1'. +-- div_ov_out : Division overflow flag, valid only when div_ready='1'. +-- mul_ov_out : Product overflow flag, valid only when mul_ready='1'. +-- +-- mul_ready : Asserted permanently if SEQUENTIAL_MULTIPLIER=false. +-- div_ready : Deasserted the cycle after start is asserted. +-- Asserted when the division has completed. +-- +-------------------------------------------------------------------------------- +-- Copyright (C) 2012 Jose A. Ruiz +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source 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 Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.light52_pkg.all; +use work.light52_ucode_pkg.all; + +entity light52_muldiv is + generic ( + SEQUENTIAL_MULTIPLIER : boolean := false + ); + port( + clk : in std_logic; + reset : in std_logic; + + data_a : in t_byte; + data_b : in t_byte; + start : in std_logic; + + prod_out : out t_word; + quot_out : out t_byte; + rem_out : out t_byte; + div_ov_out : out std_logic; + mul_ov_out : out std_logic; + + mul_ready : out std_logic; + div_ready : out std_logic + ); +end entity light52_muldiv; + +architecture sequential of light52_muldiv is + +signal bit_ctr : integer range 0 to 8; + +signal b_shift_reg : t_word; + +signal den_ge_256 : std_logic; +signal num_ge_den : std_logic; +signal sub_num : std_logic; + +signal denominator : t_byte; +signal rem_reg : t_byte; +signal quot_reg : t_byte; +signal prod_reg : t_word; +signal ready : std_logic; + +signal load_regs : std_logic; + +begin + +-- Control logic --------------------------------------------------------------- + +control_counter: process(clk) +begin + if clk'event and clk='1' then + if reset='1' then + bit_ctr <= 8; + else + if load_regs='1' then + bit_ctr <= 0; + elsif bit_ctr /= 8 then + bit_ctr <= bit_ctr + 1; + end if; + end if; + end if; +end process control_counter; + +-- Internal signal ready is asserted after 8 cycles. +-- The sequential multiplier will use this signal too, IF it takes 8 cycles. + +ready <= '1' when bit_ctr >= 8 else '0'; + + +---- Divider logic ------------------------------------------------------------- + +-- What we do is a simple base-2 'shift-and-subtract' algorithm that takes +-- 8 cycles to complete. We can get away with this because we deal with unsigned +-- numbers only. + +divider_registers: process(clk) +begin + if clk'event and clk='1' then + -- denominator shift register + if load_regs='1' then + b_shift_reg <= "0" & data_b & "0000000"; + -- Division overflow can be determined upon loading B reg data. + -- OV will be raised only on div-by-zero. + if data_b=X"00" then + div_ov_out <= '1'; + else + div_ov_out <= '0'; + end if; + else + b_shift_reg <= "0" & b_shift_reg(b_shift_reg'high downto 1); + end if; + + -- numerator register + if load_regs='1' then + rem_reg <= data_a; + elsif bit_ctr/=8 and sub_num='1' then + rem_reg <= rem_reg - denominator; + end if; + + --- quotient register + if load_regs='1' then + quot_reg <= (others => '0'); + elsif bit_ctr/=8 then + quot_reg <= quot_reg(quot_reg'high-1 downto 0) & sub_num; + end if; + + load_regs <= start; + end if; +end process divider_registers; + +denominator <= b_shift_reg(7 downto 0); + +-- The 16-bit comparison between b_shift_reg (denominator) and the zero-extended +-- rem_reg (numerator) can be simplified by splitting it in 2: +-- If the shifted denominator high byte is not zero, it is >=256... +den_ge_256 <= '1' when b_shift_reg(15 downto 8) /= X"00" else '0'; +-- ...otherwise we need to compare the low bytes. +num_ge_den <= '1' when rem_reg >= denominator else '0'; +sub_num <= '1' when den_ge_256='0' and num_ge_den='1' else '0'; + + +quot_out <= quot_reg; +prod_out <= prod_reg; +rem_out <= rem_reg; + +div_ready <= ready; + +---- Multiplier logic ---------------------------------------------------------- + +---- Combinational multiplier ----------------------------- +multiplier_combinational: if not SEQUENTIAL_MULTIPLIER generate + +registered_combinational_multiplier:process(clk) +begin + if clk'event and clk='1' then + prod_reg <= data_a * data_b; -- t_byte is unsigned + end if; +end process registered_combinational_multiplier; + +-- The multiplier output is valid in the cycle after the operands are loaded, +-- so by the time MUL is executed it's already done. +mul_ready <= '1'; + +mul_ov_out <= '1' when prod_reg(15 downto 8)/=X"00" else '0'; +prod_out <= prod_reg; + +end generate multiplier_combinational; + +---- Sequential multiplier -------------------------------- +multiplier_sequential: if SEQUENTIAL_MULTIPLIER generate + +assert false +report "Sequential multiplier implementation not done yet."& + " Use combinational implementation." +severity failure; + +end generate multiplier_sequential; + +end sequential; diff --git a/autotests/folding/light52_tb.vhdl.fold b/autotests/folding/light52_tb.vhdl.fold new file mode 100644 index 0000000..44fdcff --- /dev/null +++ b/autotests/folding/light52_tb.vhdl.fold @@ -0,0 +1,180 @@ +-------------------------------------------------------------------------------- +-- light52_tb.vhdl -- +-------------------------------------------------------------------------------- +-- This test bench simulates the execution of some program (whose object code +-- is in package obj_code_pkg, in the form of a memory init constant) and logs +-- the execution to a text file called 'hw_sim_log.txt' (light52_tb_pkg.vhdl). +-- +-- This test bench does no actual tests on the core. Instead, the simulation log +-- is meant to be matched against the simulation log produced by running the +-- same program on the software simulator B51 (also included with this project). +-- +-- This will catch errors in the implementation of the CPU if the simulated +-- program has anough coverage -- the opcode tester is meant to cover all CPU +-- opcodes in many (not all) of their corner cases. +-- This scheme will not help in catching errors in the peripheral modules, +-- mainly because the current version of B51 does not simulate them. +-- +-------------------------------------------------------------------------------- +-- Copyright (C) 2012 Jose A. Ruiz +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source 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 Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-------------------------------------------------------------------------------- + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use std.textio.all; + +use work.light52_pkg.all; +use work.obj_code_pkg.all; +use work.light52_tb_pkg.all; +use work.txt_util.all; + +entity light52_tb is +generic (BCD : boolean := true); +end; + + +architecture testbench of light52_tb is + +-------------------------------------------------------------------------------- +-- Simulation parameters +-- FIXME these should be in parameter package + +-- Simulated clock period is the same as the usual target, the DE-1 board +constant T : time := 20 ns; -- 50MHz +constant SIMULATION_LENGTH : integer := 400000; + +-------------------------------------------------------------------------------- +-- MPU interface + +signal clk : std_logic := '0'; +signal reset : std_logic := '1'; + +signal p0_out : std_logic_vector(7 downto 0); +signal p1_out : std_logic_vector(7 downto 0); +signal p2_in : std_logic_vector(7 downto 0); +signal p3_in : std_logic_vector(7 downto 0); + +signal external_irq : std_logic_vector(7 downto 0); + +signal txd, rxd : std_logic; + +-------------------------------------------------------------------------------- +-- Logging signals & simulation control + +-- Asserted high to disable the clock and terminate the simulation. +signal done : std_logic := '0'; + +-- Log file +file log_file: TEXT open write_mode is "hw_sim_log.txt"; +-- Console output log file +file con_file: TEXT open write_mode is "hw_sim_console_log.txt"; +-- Info record needed by the logging fuctions +signal log_info : t_log_info; + +begin + +---- UUT instantiation --------------------------------------------------------- + +uut: entity work.light52_mcu + generic map ( + IMPLEMENT_BCD_INSTRUCTIONS => BCD, + CODE_ROM_SIZE => work.obj_code_pkg.XCODE_SIZE, + XDATA_RAM_SIZE => work.obj_code_pkg.XDATA_SIZE, + OBJ_CODE => work.obj_code_pkg.object_code + ) + port map ( + clk => clk, + reset => reset, + + txd => txd, + rxd => rxd, + + external_irq => external_irq, + + p0_out => p0_out, + p1_out => p1_out, + p2_in => p2_in, + p3_in => p3_in + ); + + -- UART is looped back in the test bench. + rxd <= txd; + + -- I/O ports are looped back and otherwise unused. + p2_in <= p0_out; + p3_in <= p1_out; + + -- External IRQ inputs are tied to port P1 for test purposes + external_irq <= p1_out; + + ---- Master clock: free running clock used as main module clock ------------ + run_master_clock: process(done, clk) + begin + if done = '0' then + clk <= not clk after T/2; + end if; + end process run_master_clock; + + + ---- Main simulation process: reset MCU and wait for fixed period ---------- + + drive_uut: process + begin + -- Leave reset asserted for a few clock cycles... + reset <= '1'; + wait for T*4; + reset <= '0'; + + -- ...and wait for the test to hit a termination condition (evaluated by + -- function log_cpu_activity) or to just timeout. + wait for T*SIMULATION_LENGTH; + + -- If we arrive here, the simulation timed out (termination conditions + -- trigger a failed assertion). + -- So print a timeout message and quit. + print("TB timed out."); + done <= '1'; + wait; + + end process drive_uut; + + + -- Logging process: launch logger functions -------------------------------- + log_execution: process + begin + -- Log cpu activity until done='1'. + log_cpu_activity(clk, reset, done, "/uut", + log_info, work.obj_code_pkg.XCODE_SIZE, "log_info", + X"0000", log_file, con_file); + + -- Flush console log file when finished. + log_flush_console(log_info, con_file); + + wait; + end process log_execution; + +end architecture testbench; diff --git a/autotests/folding/meson.build.fold b/autotests/folding/meson.build.fold new file mode 100644 index 0000000..f20c35b --- /dev/null +++ b/autotests/folding/meson.build.fold @@ -0,0 +1,21 @@ +# Unit test for Meson syntax highlight. License: LGPL +project('projectname', 'cpp') + + + +sourcefiles = ['a.cpp', 'b.cpp'] + +foreach sourcefile : sourcefiles + message('this is a source file: ' + sourcefile) +endforeach + +x=1 +if x+1 == 2 and x-1 == 0 + message('I can work in this universe!') +endif + +subprojectresult = subproject('mysubprojectdir') + +mysharedlib = shared_library('libraryname', sourcefiles, linkwith: subprojectresult.staticlib) + +executable('myprogram', ['test.cpp'], linkwith: mysharedlib) diff --git a/autotests/folding/or1200_dc_fsm.v.fold b/autotests/folding/or1200_dc_fsm.v.fold new file mode 100644 index 0000000..c54fbe7 --- /dev/null +++ b/autotests/folding/or1200_dc_fsm.v.fold @@ -0,0 +1,563 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// OR1200's DC FSM //// +//// //// +//// This file is part of the OpenRISC 1200 project //// +//// http://opencores.org/project,or1k //// +//// //// +//// Description //// +//// Data cache state machine //// +//// //// +//// To Do: //// +//// - Test error during line read or write //// +//// //// +//// Author(s): //// +//// - Damjan Lampret, lampret@opencores.org //// +//// - Julius Baxter, julius@opencores.org //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000, 2010 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// $Log: or1200_dc_fsm.v,v $ +// Revision 2.0 2010/06/30 11:00:00 ORSoC +// Minor update: +// Bugs fixed. +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on +`include "or1200_defines.v" + +`define OR1200_DCFSM_IDLE 3'd0 +`define OR1200_DCFSM_CLOADSTORE 3'd1 +`define OR1200_DCFSM_LOOP2 3'd2 +`define OR1200_DCFSM_LOOP3 3'd3 +`define OR1200_DCFSM_LOOP4 3'd4 +`define OR1200_DCFSM_FLUSH5 3'd5 +`define OR1200_DCFSM_INV6 3'd6 +`define OR1200_DCFSM_WAITSPRCS7 3'd7 + + + +// +// Data cache FSM for cache line of 16 bytes (4x singleword) +// + +module or1200_dc_fsm + ( + // Clock and reset + clk, rst, + + // Internal i/f to top level DC + dc_en, dcqmem_cycstb_i, dcqmem_ci_i, dcqmem_we_i, dcqmem_sel_i, + tagcomp_miss, biudata_valid, biudata_error, lsu_addr, + dcram_we, biu_read, biu_write, biu_do_sel, dcram_di_sel, first_hit_ack, + first_miss_ack, first_miss_err, burst, tag_we, tag_valid, dc_addr, + dc_no_writethrough, tag_dirty, dirty, tag, tag_v, dc_block_flush, + dc_block_writeback, spr_dat_i, mtspr_dc_done, spr_cswe + ); + + // + // I/O + // + input clk; + input rst; + input dc_en; + input dcqmem_cycstb_i; + input dcqmem_ci_i; + input dcqmem_we_i; + input [3:0] dcqmem_sel_i; + input tagcomp_miss; + input biudata_valid; + input biudata_error; + input [31:0] lsu_addr; + output [3:0] dcram_we; + output biu_read; + output biu_write; + output dcram_di_sel; + output biu_do_sel; + output first_hit_ack; + output first_miss_ack; + output first_miss_err; + output burst; + output tag_we; + output tag_valid; + output [31:0] dc_addr; + input dc_no_writethrough; + output tag_dirty; + input dirty; + input [`OR1200_DCTAG_W-2:0] tag; + input tag_v; + input dc_block_flush; + input dc_block_writeback; + input [31:0] spr_dat_i; + output mtspr_dc_done; + input spr_cswe; + + + // + // Internal wires and regs + // + reg [31:0] addr_r; + reg [2:0] state; + reg [`OR1200_DCLS-1:0] cnt; + reg hitmiss_eval; + reg store; + reg load; + reg cache_inhibit; + reg cache_miss; + reg cache_dirty_needs_writeback; + reg did_early_load_ack; + reg cache_spr_block_flush; + reg cache_spr_block_writeback; + reg cache_wb; + wire load_hit_ack; + wire load_miss_ack; + wire load_inhibit_ack; + wire store_hit_ack; + wire store_hit_writethrough_ack; + wire store_miss_writethrough_ack; + wire store_inhibit_ack; + wire store_miss_ack; + wire dcram_we_after_line_load; + wire dcram_we_during_line_load; + wire tagram_we_end_of_loadstore_loop; + wire tagram_dirty_bit_set; + wire writethrough; + wire cache_inhibit_with_eval; + wire [(`OR1200_DCLS-1)-2:0] next_addr_word; + + // + // Cache inhibit + // + + // Indicates whether cache is inhibited, during hitmiss_eval and after + assign cache_inhibit_with_eval = (hitmiss_eval & dcqmem_ci_i) | + (!hitmiss_eval & cache_inhibit); + + // + // Generate of DCRAM write enables + // + + // WE when non-writethrough, and had to wait for a line to load. + assign dcram_we_after_line_load = (state == `OR1200_DCFSM_LOOP3) & + dcqmem_we_i & !cache_dirty_needs_writeback & + !did_early_load_ack; + + // WE when receiving the data cache line + assign dcram_we_during_line_load = (state == `OR1200_DCFSM_LOOP2) & load & + biudata_valid; + + assign dcram_we =(// Write when hit - make sure it is only when hit - could + // maybe be doing write through and don't want to corrupt + // cache lines corresponding to the writethrough addr_r. + ({4{store_hit_ack | store_hit_writethrough_ack}} | + // Write after load of line + {4{dcram_we_after_line_load}}) & + dcqmem_sel_i ) | + // Write during load + {4{dcram_we_during_line_load}}; + + // + // Tag RAM signals + // + + // WE to tag RAM when we finish loading a line. + assign tagram_we_end_of_loadstore_loop = ((state==`OR1200_DCFSM_LOOP2) & + biudata_valid & !(|cnt)); + +`ifndef OR1200_DC_WRITETHROUGH + // No writethrough, so mark a line dirty whenever we write to it + assign tagram_dirty_bit_set = store_hit_ack | store_miss_ack; + + // Generate done signal for MTSPR instructions that may block execution + assign mtspr_dc_done = // Either DC disabled or we're not selected, or + !dc_en | !spr_cswe | + // Requested address not valid or writeback and !dirty + ((state==`OR1200_DCFSM_FLUSH5) & + (!tag_v | (cache_spr_block_writeback & !dirty))) | + // Writeback or flush is finished + ((state==`OR1200_DCFSM_LOOP3) & + (cache_spr_block_flush | cache_spr_block_writeback))| + // Invalidate of clean line finished + ((state==`OR1200_DCFSM_INV6) & cache_spr_block_flush); + + +`else + `ifdef OR1200_DC_NOSTACKWRITETHROUGH + // For dirty bit setting when having writethrough but not for stack + assign tagram_dirty_bit_set = store_hit_ack | store_miss_ack; + `else + // Lines will never be dirty if always writethrough + assign tagram_dirty_bit_set = 0; + `endif + + assign mtspr_dc_done = 1'b1; + +`endif + + assign tag_dirty = tagram_dirty_bit_set; + + // WE to tag RAM + assign tag_we = tagram_we_end_of_loadstore_loop | + tagram_dirty_bit_set | (state == `OR1200_DCFSM_INV6); + + + // Valid bit + // Set valid when end of line load, or marking dirty (is still valid) + assign tag_valid = ( tagram_we_end_of_loadstore_loop & + (load | (store & cache_spr_block_writeback)) ) | + tagram_dirty_bit_set; + + + + // + // BIU read and write + // + + assign biu_read = // Bus read request when: + // 1) Have a miss and not dirty or a load with inhibit + ((state == `OR1200_DCFSM_CLOADSTORE) & + (((hitmiss_eval & tagcomp_miss & !dirty & + !(store & writethrough)) | + (load & cache_inhibit_with_eval)) & dcqmem_cycstb_i)) | + // 2) In the loop and loading + ((state == `OR1200_DCFSM_LOOP2) & load); + + + assign biu_write = // Bus write request when: + // 1) Have a miss and dirty or store with inhibit + ((state == `OR1200_DCFSM_CLOADSTORE) & + (((hitmiss_eval & tagcomp_miss & dirty) | + (store & writethrough)) | + (store & cache_inhibit_with_eval)) & dcqmem_cycstb_i) | + // 2) In the loop and storing + ((state == `OR1200_DCFSM_LOOP2) & store); + + // + // Select for data to actual cache RAM (from LSU or BIU) + // + // Data to DCRAM - from external bus when loading (from IU when store) + assign dcram_di_sel = load; + // Data to external bus - always from IU except in case of bursting back + // the line to memory. (1 selects DCRAM) + assign biu_do_sel = (state == `OR1200_DCFSM_LOOP2) & store; + + // 3-bit wire for calculating next word of burst write, depending on + // line size of data cache. + assign next_addr_word = addr_r[`OR1200_DCLS-1:2] + 1; + + // Address to cache RAM (tag address also derived from this) + assign dc_addr = + // First check if we've got a block flush or WB op + ((dc_block_flush & !cache_spr_block_flush) | + (dc_block_writeback & !cache_spr_block_writeback)) ? + spr_dat_i : + (state==`OR1200_DCFSM_FLUSH5) ? addr_r: + // If no SPR action, then always put out address from LSU + (state==`OR1200_DCFSM_IDLE | hitmiss_eval) ? lsu_addr : + // Next, if in writeback loop, when ACKed must immediately + // output next word address (the RAM address takes a cycle + // to increment, but it's needed immediately for burst) + // otherwise, output our registered address. + (state==`OR1200_DCFSM_LOOP2 & biudata_valid & store ) ? + {addr_r[31:`OR1200_DCLS], next_addr_word, 2'b00} : addr_r; + +`ifdef OR1200_DC_WRITETHROUGH + `ifdef OR1200_DC_NOSTACKWRITETHROUGH + assign writethrough = !dc_no_writethrough; + `else + assign writethrough = 1; + `endif +`else + assign writethrough = 0; +`endif + + // + // ACK generation for LSU + // + + // ACK for when it's a cache hit + assign first_hit_ack = load_hit_ack | store_hit_ack | + store_hit_writethrough_ack | + store_miss_writethrough_ack | + store_inhibit_ack | store_miss_ack ; + + // ACK for when it's a cache miss - load only, is used in MUX for data back + // LSU straight off external data bus. In + // this was is also used for cache inhibit + // loads. + // first_hit_ack takes precedence over first_miss_ack + assign first_miss_ack = ~first_hit_ack & (load_miss_ack | load_inhibit_ack); + + // ACK cache hit on load + assign load_hit_ack = (state == `OR1200_DCFSM_CLOADSTORE) & + hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i & load; + + // ACK cache hit on store, no writethrough + assign store_hit_ack = (state == `OR1200_DCFSM_CLOADSTORE) & + hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i & + store & !writethrough; + + // ACK cache hit on store with writethrough + assign store_hit_writethrough_ack = (state == `OR1200_DCFSM_CLOADSTORE) & + !cache_miss & !cache_inhibit & + store & writethrough & biudata_valid; + + // ACK cache miss on store with writethrough + assign store_miss_writethrough_ack = (state == `OR1200_DCFSM_CLOADSTORE) & + cache_miss & !cache_inhibit & + store & writethrough & biudata_valid; + + // ACK store when cacheinhibit + assign store_inhibit_ack = (state == `OR1200_DCFSM_CLOADSTORE) & + store & cache_inhibit & biudata_valid; + + + // Get the _early_ ack on first ACK back from wishbone during load only + // Condition is that we're in the loop - that it's the first ack we get (can + // tell from value of cnt), and we're loading a line to read from it (not + // loading to write to it, in the case of a write without writethrough.) + assign load_miss_ack = ((state== `OR1200_DCFSM_LOOP2) & load & + (cnt==((1 << `OR1200_DCLS) - 4)) & biudata_valid & + !(dcqmem_we_i & !writethrough)); + + assign load_inhibit_ack = (state == `OR1200_DCFSM_CLOADSTORE) & + load & cache_inhibit & biudata_valid; + + // This will be case of write through disabled, and had to load a line. + assign store_miss_ack = dcram_we_after_line_load; + + assign first_miss_err = biudata_error & dcqmem_cycstb_i; + + // Signal burst when in the load/store loop. We will always try to burst. + assign burst = (state == `OR1200_DCFSM_LOOP2); + + // + // Main DC FSM + // + always @(posedge clk or `OR1200_RST_EVENT rst) begin + if (rst == `OR1200_RST_VALUE) begin + state <= `OR1200_DCFSM_IDLE; + addr_r <= 32'd0; + hitmiss_eval <= 1'b0; + store <= 1'b0; + load <= 1'b0; + cnt <= `OR1200_DCLS'd0; + cache_miss <= 1'b0; + cache_dirty_needs_writeback <= 1'b0; + cache_inhibit <= 1'b0; + did_early_load_ack <= 1'b0; + cache_spr_block_flush <= 1'b0; + cache_spr_block_writeback <= 1'b0; + end + else + case (state) // synopsys parallel_case + + `OR1200_DCFSM_IDLE : begin + if (dc_en & (dc_block_flush | dc_block_writeback)) + begin + cache_spr_block_flush <= dc_block_flush; + cache_spr_block_writeback <= dc_block_writeback; + hitmiss_eval <= 1'b1; + state <= `OR1200_DCFSM_FLUSH5; + addr_r <= spr_dat_i; + end + else if (dc_en & dcqmem_cycstb_i) + begin + state <= `OR1200_DCFSM_CLOADSTORE; + hitmiss_eval <= 1'b1; + store <= dcqmem_we_i; + load <= !dcqmem_we_i; + end + + + end // case: `OR1200_DCFSM_IDLE + + `OR1200_DCFSM_CLOADSTORE: begin + hitmiss_eval <= 1'b0; + if (hitmiss_eval) begin + cache_inhibit <= dcqmem_ci_i; // Check for cache inhibit here + cache_miss <= tagcomp_miss; + cache_dirty_needs_writeback <= dirty; + addr_r <= lsu_addr; + end + + // Evaluate any cache line load/stores in first cycle: + // + if (hitmiss_eval & tagcomp_miss & !(store & writethrough) & + !dcqmem_ci_i) + begin + // Miss - first either: + // 1) write back dirty line + if (dirty) begin + // Address for writeback + addr_r <= {tag, lsu_addr[`OR1200_DCINDXH:2],2'd0}; + load <= 1'b0; + store <= 1'b1; +`ifdef OR1200_VERBOSE + $display("%t: dcache miss and dirty", $time); +`endif + end + // 2) load requested line + else begin + addr_r <= lsu_addr; + load <= 1'b1; + store <= 1'b0; + end // else: !if(dirty) + state <= `OR1200_DCFSM_LOOP2; + // Set the counter for the burst accesses + cnt <= ((1 << `OR1200_DCLS) - 4); + end + else if (// Strobe goes low + !dcqmem_cycstb_i | + // Cycle finishes + (!hitmiss_eval & (biudata_valid | biudata_error)) | + // Cache hit in first cycle.... + (hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i & + // .. and you're not doing a writethrough store.. + !(store & writethrough))) begin + state <= `OR1200_DCFSM_IDLE; + load <= 1'b0; + store <= 1'b0; + cache_inhibit <= 1'b0; + cache_dirty_needs_writeback <= 1'b0; + end + end // case: `OR1200_DCFSM_CLOADSTORE + + `OR1200_DCFSM_LOOP2 : begin // loop/abort + if (!dc_en| biudata_error) begin + state <= `OR1200_DCFSM_IDLE; + load <= 1'b0; + store <= 1'b0; + cnt <= `OR1200_DCLS'd0; + end + if (biudata_valid & (|cnt)) begin + cnt <= cnt - 4; + addr_r[`OR1200_DCLS-1:2] <= addr_r[`OR1200_DCLS-1:2] + 1; + end + else if (biudata_valid & !(|cnt)) begin + state <= `OR1200_DCFSM_LOOP3; + addr_r <= lsu_addr; + load <= 1'b0; + store <= 1'b0; + end + + // Track if we did an early ack during a load + if (load_miss_ack) + did_early_load_ack <= 1'b1; + + + end // case: `OR1200_DCFSM_LOOP2 + + `OR1200_DCFSM_LOOP3: begin // figure out next step + if (cache_dirty_needs_writeback) begin + // Just did store of the dirty line so now load new one + load <= 1'b1; + // Set the counter for the burst accesses + cnt <= ((1 << `OR1200_DCLS) - 4); + // Address of line to be loaded + addr_r <= lsu_addr; + cache_dirty_needs_writeback <= 1'b0; + state <= `OR1200_DCFSM_LOOP2; + end // if (cache_dirty_needs_writeback) + else if (cache_spr_block_flush | cache_spr_block_writeback) begin + // Just wrote back the line to memory, we're finished. + cache_spr_block_flush <= 1'b0; + cache_spr_block_writeback <= 1'b0; + state <= `OR1200_DCFSM_WAITSPRCS7; + end + else begin + // Just loaded a new line, finish up + did_early_load_ack <= 1'b0; + state <= `OR1200_DCFSM_LOOP4; + end + end // case: `OR1200_DCFSM_LOOP3 + + `OR1200_DCFSM_LOOP4: begin + state <= `OR1200_DCFSM_IDLE; + end + + `OR1200_DCFSM_FLUSH5: begin + hitmiss_eval <= 1'b0; + if (hitmiss_eval & !tag_v) + begin + // Not even cached, just ignore + cache_spr_block_flush <= 1'b0; + cache_spr_block_writeback <= 1'b0; + state <= `OR1200_DCFSM_WAITSPRCS7; + end + else if (hitmiss_eval & tag_v) + begin + // Tag is valid - what do we do? + if ((cache_spr_block_flush | cache_spr_block_writeback) & + dirty) begin + // Need to writeback + // Address for writeback (spr_dat_i has already changed so + // use line number from addr_r) + addr_r <= {tag, addr_r[`OR1200_DCINDXH:2],2'd0}; + load <= 1'b0; + store <= 1'b1; +`ifdef OR1200_VERBOSE + $display("%t: block flush: dirty block", $time); +`endif + state <= `OR1200_DCFSM_LOOP2; + // Set the counter for the burst accesses + cnt <= ((1 << `OR1200_DCLS) - 4); + end + else if (cache_spr_block_flush & !dirty) + begin + // Line not dirty, just need to invalidate + state <= `OR1200_DCFSM_INV6; + end // else: !if(dirty) + else if (cache_spr_block_writeback & !dirty) + begin + // Nothing to do - line is valid but not dirty + cache_spr_block_writeback <= 1'b0; + state <= `OR1200_DCFSM_WAITSPRCS7; + end + end // if (hitmiss_eval & tag_v) + end + `OR1200_DCFSM_INV6: begin + cache_spr_block_flush <= 1'b0; + // Wait until SPR CS goes low before going back to idle + if (!spr_cswe) + state <= `OR1200_DCFSM_IDLE; + end + `OR1200_DCFSM_WAITSPRCS7: begin + // Wait until SPR CS goes low before going back to idle + if (!spr_cswe) + state <= `OR1200_DCFSM_IDLE; + end + + endcase // case (state) + + end // always @ (posedge clk or `OR1200_RST_EVENT rst) + + +endmodule diff --git a/autotests/folding/or1200_du.v.fold b/autotests/folding/or1200_du.v.fold new file mode 100644 index 0000000..97a6319 --- /dev/null +++ b/autotests/folding/or1200_du.v.fold @@ -0,0 +1,1803 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// OR1200's Debug Unit //// +//// //// +//// This file is part of the OpenRISC 1200 project //// +//// http://www.opencores.org/project,or1k //// +//// //// +//// Description //// +//// Basic OR1200 debug unit. //// +//// //// +//// To Do: //// +//// - make it smaller and faster //// +//// //// +//// Author(s): //// +//// - Damjan Lampret, lampret@opencores.org //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// +// $Log: or1200_du.v,v $ +// Revision 2.0 2010/06/30 11:00:00 ORSoC +// Minor update: +// Bugs fixed. + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on +`include "or1200_defines.v" + +// +// Debug unit +// + +module or1200_du( + // RISC Internal Interface + clk, rst, + dcpu_cycstb_i, dcpu_we_i, dcpu_adr_i, dcpu_dat_lsu, + dcpu_dat_dc, icpu_cycstb_i, + ex_freeze, branch_op, ex_insn, id_pc, + spr_dat_npc, rf_dataw, + du_dsr, du_dmr1, du_stall, du_addr, du_dat_i, du_dat_o, + du_read, du_write, du_except_stop, du_hwbkpt, du_flush_pipe, + spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o, + + // External Debug Interface + dbg_stall_i, dbg_ewt_i, dbg_lss_o, dbg_is_o, dbg_wp_o, dbg_bp_o, + dbg_stb_i, dbg_we_i, dbg_adr_i, dbg_dat_i, dbg_dat_o, dbg_ack_o +); + +parameter dw = `OR1200_OPERAND_WIDTH; +parameter aw = `OR1200_OPERAND_WIDTH; + +// +// I/O +// + +// +// RISC Internal Interface +// +input clk; // Clock +input rst; // Reset +input dcpu_cycstb_i; // LSU status +input dcpu_we_i; // LSU status +input [31:0] dcpu_adr_i; // LSU addr +input [31:0] dcpu_dat_lsu; // LSU store data +input [31:0] dcpu_dat_dc; // LSU load data +input [`OR1200_FETCHOP_WIDTH-1:0] icpu_cycstb_i; // IFETCH unit status +input ex_freeze; // EX stage freeze +input [`OR1200_BRANCHOP_WIDTH-1:0] branch_op; // Branch op +input [dw-1:0] ex_insn; // EX insn +input [31:0] id_pc; // insn fetch EA +input [31:0] spr_dat_npc; // Next PC (for trace) +input [31:0] rf_dataw; // ALU result (for trace) +output [`OR1200_DU_DSR_WIDTH-1:0] du_dsr; // DSR +output [24: 0] du_dmr1; +output du_stall; // Debug Unit Stall +output [aw-1:0] du_addr; // Debug Unit Address +input [dw-1:0] du_dat_i; // Debug Unit Data In +output [dw-1:0] du_dat_o; // Debug Unit Data Out +output du_read; // Debug Unit Read Enable +output du_write; // Debug Unit Write Enable +input [13:0] du_except_stop; // Exception masked by DSR +output du_hwbkpt; // Cause trap exception (HW Breakpoints) +output du_flush_pipe; // Cause pipeline flush and pc<-npc +input spr_cs; // SPR Chip Select +input spr_write; // SPR Read/Write +input [aw-1:0] spr_addr; // SPR Address +input [dw-1:0] spr_dat_i; // SPR Data Input +output [dw-1:0] spr_dat_o; // SPR Data Output + +// +// External Debug Interface +// +input dbg_stall_i; // External Stall Input +input dbg_ewt_i; // External Watchpoint Trigger Input +output [3:0] dbg_lss_o; // External Load/Store Unit Status +output [1:0] dbg_is_o; // External Insn Fetch Status +output [10:0] dbg_wp_o; // Watchpoints Outputs +output dbg_bp_o; // Breakpoint Output +input dbg_stb_i; // External Address/Data Strobe +input dbg_we_i; // External Write Enable +input [aw-1:0] dbg_adr_i; // External Address Input +input [dw-1:0] dbg_dat_i; // External Data Input +output [dw-1:0] dbg_dat_o; // External Data Output +output dbg_ack_o; // External Data Acknowledge (not WB compatible) +reg [dw-1:0] dbg_dat_o; // External Data Output +reg dbg_ack_o; // External Data Acknowledge (not WB compatible) + + +// +// Some connections go directly from the CPU through DU to Debug I/F +// +`ifdef OR1200_DU_STATUS_UNIMPLEMENTED +assign dbg_lss_o = 4'b0000; + +reg [1:0] dbg_is_o; +// +// Show insn activity (temp, must be removed) +// +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dbg_is_o <= 2'b00; + else if (!ex_freeze & ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16])) + dbg_is_o <= ~dbg_is_o; +`ifdef UNUSED +assign dbg_is_o = 2'b00; +`endif +`else +assign dbg_lss_o = dcpu_cycstb_i ? {dcpu_we_i, 3'b000} : 4'b0000; +assign dbg_is_o = {1'b0, icpu_cycstb_i}; +`endif +assign dbg_wp_o = 11'b000_0000_0000; + +// +// Some connections go directly from Debug I/F through DU to the CPU +// +assign du_stall = dbg_stall_i; +assign du_addr = dbg_adr_i; +assign du_dat_o = dbg_dat_i; +assign du_read = dbg_stb_i && !dbg_we_i; +assign du_write = dbg_stb_i && dbg_we_i; + +// +// After a sw breakpoint, the replaced instruction need to be executed. +// We flush the entire pipeline and set the pc to the current address +// to execute the restored address. +// + +reg du_flush_pipe_r; +reg dbg_stall_i_r; + +assign du_flush_pipe = du_flush_pipe_r; + +// +// Register du_flush_pipe +// +always @(posedge clk or `OR1200_RST_EVENT rst) begin + if (rst == `OR1200_RST_VALUE) begin + du_flush_pipe_r <= 1'b0; + end + else begin + du_flush_pipe_r <= (dbg_stall_i_r && !dbg_stall_i && |du_except_stop); + end +end + +// +// Detect dbg_stall falling edge +// +always @(posedge clk or `OR1200_RST_EVENT rst) begin + if (rst == `OR1200_RST_VALUE) begin + dbg_stall_i_r <= 1'b0; + end + else begin + dbg_stall_i_r <= dbg_stall_i; + end +end + +reg dbg_ack; +// +// Generate acknowledge -- just delay stb signal +// +always @(posedge clk or `OR1200_RST_EVENT rst) begin + if (rst == `OR1200_RST_VALUE) begin + dbg_ack <= 1'b0; + dbg_ack_o <= 1'b0; + end + else begin + dbg_ack <= dbg_stb_i; // valid when du_dat_i + dbg_ack_o <= dbg_ack & dbg_stb_i; // valid when dbg_dat_o + end +end + +// +// Register data output +// +always @(posedge clk) + dbg_dat_o <= du_dat_i; + +`ifdef OR1200_DU_IMPLEMENTED + +// +// Debug Mode Register 1 +// +`ifdef OR1200_DU_DMR1 +reg [24:0] dmr1; // DMR1 implemented +`else +wire [24:0] dmr1; // DMR1 not implemented +`endif +assign du_dmr1 = dmr1; + +// +// Debug Mode Register 2 +// +`ifdef OR1200_DU_DMR2 +reg [23:0] dmr2; // DMR2 implemented +`else +wire [23:0] dmr2; // DMR2 not implemented +`endif + +// +// Debug Stop Register +// +`ifdef OR1200_DU_DSR +reg [`OR1200_DU_DSR_WIDTH-1:0] dsr; // DSR implemented +`else +wire [`OR1200_DU_DSR_WIDTH-1:0] dsr; // DSR not implemented +`endif + +// +// Debug Reason Register +// +`ifdef OR1200_DU_DRR +reg [13:0] drr; // DRR implemented +`else +wire [13:0] drr; // DRR not implemented +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR0 +reg [31:0] dvr0; +`else +wire [31:0] dvr0; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR1 +reg [31:0] dvr1; +`else +wire [31:0] dvr1; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR2 +reg [31:0] dvr2; +`else +wire [31:0] dvr2; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR3 +reg [31:0] dvr3; +`else +wire [31:0] dvr3; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR4 +reg [31:0] dvr4; +`else +wire [31:0] dvr4; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR5 +reg [31:0] dvr5; +`else +wire [31:0] dvr5; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR6 +reg [31:0] dvr6; +`else +wire [31:0] dvr6; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR7 +reg [31:0] dvr7; +`else +wire [31:0] dvr7; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR0 +reg [7:0] dcr0; +`else +wire [7:0] dcr0; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR1 +reg [7:0] dcr1; +`else +wire [7:0] dcr1; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR2 +reg [7:0] dcr2; +`else +wire [7:0] dcr2; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR3 +reg [7:0] dcr3; +`else +wire [7:0] dcr3; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR4 +reg [7:0] dcr4; +`else +wire [7:0] dcr4; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR5 +reg [7:0] dcr5; +`else +wire [7:0] dcr5; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR6 +reg [7:0] dcr6; +`else +wire [7:0] dcr6; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR7 +reg [7:0] dcr7; +`else +wire [7:0] dcr7; +`endif + +// +// Debug Watchpoint Counter Register 0 +// +`ifdef OR1200_DU_DWCR0 +reg [31:0] dwcr0; +`else +wire [31:0] dwcr0; +`endif + +// +// Debug Watchpoint Counter Register 1 +// +`ifdef OR1200_DU_DWCR1 +reg [31:0] dwcr1; +`else +wire [31:0] dwcr1; +`endif + +// +// Internal wires +// +wire dmr1_sel; // DMR1 select +wire dmr2_sel; // DMR2 select +wire dsr_sel; // DSR select +wire drr_sel; // DRR select +wire dvr0_sel, + dvr1_sel, + dvr2_sel, + dvr3_sel, + dvr4_sel, + dvr5_sel, + dvr6_sel, + dvr7_sel; // DVR selects +wire dcr0_sel, + dcr1_sel, + dcr2_sel, + dcr3_sel, + dcr4_sel, + dcr5_sel, + dcr6_sel, + dcr7_sel; // DCR selects +wire dwcr0_sel, + dwcr1_sel; // DWCR selects +reg dbg_bp_r; +reg ex_freeze_q; +`ifdef OR1200_DU_HWBKPTS +reg [31:0] match_cond0_ct; +reg [31:0] match_cond1_ct; +reg [31:0] match_cond2_ct; +reg [31:0] match_cond3_ct; +reg [31:0] match_cond4_ct; +reg [31:0] match_cond5_ct; +reg [31:0] match_cond6_ct; +reg [31:0] match_cond7_ct; +reg match_cond0_stb; +reg match_cond1_stb; +reg match_cond2_stb; +reg match_cond3_stb; +reg match_cond4_stb; +reg match_cond5_stb; +reg match_cond6_stb; +reg match_cond7_stb; +reg match0; +reg match1; +reg match2; +reg match3; +reg match4; +reg match5; +reg match6; +reg match7; +reg wpcntr0_match; +reg wpcntr1_match; +reg incr_wpcntr0; +reg incr_wpcntr1; +reg [10:0] wp; +`endif +wire du_hwbkpt; +reg du_hwbkpt_hold; +`ifdef OR1200_DU_READREGS +reg [31:0] spr_dat_o; +`endif +reg [13:0] except_stop; // Exceptions that stop because of DSR +`ifdef OR1200_DU_TB_IMPLEMENTED +wire tb_enw; +reg [7:0] tb_wadr; +reg [31:0] tb_timstmp; +`endif +wire [31:0] tbia_dat_o; +wire [31:0] tbim_dat_o; +wire [31:0] tbar_dat_o; +wire [31:0] tbts_dat_o; + +// +// DU registers address decoder +// +`ifdef OR1200_DU_DMR1 +assign dmr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DMR1)); +`endif +`ifdef OR1200_DU_DMR2 +assign dmr2_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DMR2)); +`endif +`ifdef OR1200_DU_DSR +assign dsr_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DSR)); +`endif +`ifdef OR1200_DU_DRR +assign drr_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DRR)); +`endif +`ifdef OR1200_DU_DVR0 +assign dvr0_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR0)); +`endif +`ifdef OR1200_DU_DVR1 +assign dvr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR1)); +`endif +`ifdef OR1200_DU_DVR2 +assign dvr2_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR2)); +`endif +`ifdef OR1200_DU_DVR3 +assign dvr3_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR3)); +`endif +`ifdef OR1200_DU_DVR4 +assign dvr4_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR4)); +`endif +`ifdef OR1200_DU_DVR5 +assign dvr5_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR5)); +`endif +`ifdef OR1200_DU_DVR6 +assign dvr6_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR6)); +`endif +`ifdef OR1200_DU_DVR7 +assign dvr7_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR7)); +`endif +`ifdef OR1200_DU_DCR0 +assign dcr0_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR0)); +`endif +`ifdef OR1200_DU_DCR1 +assign dcr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR1)); +`endif +`ifdef OR1200_DU_DCR2 +assign dcr2_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR2)); +`endif +`ifdef OR1200_DU_DCR3 +assign dcr3_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR3)); +`endif +`ifdef OR1200_DU_DCR4 +assign dcr4_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR4)); +`endif +`ifdef OR1200_DU_DCR5 +assign dcr5_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR5)); +`endif +`ifdef OR1200_DU_DCR6 +assign dcr6_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR6)); +`endif +`ifdef OR1200_DU_DCR7 +assign dcr7_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR7)); +`endif +`ifdef OR1200_DU_DWCR0 +assign dwcr0_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DWCR0)); +`endif +`ifdef OR1200_DU_DWCR1 +assign dwcr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DWCR1)); +`endif + +// Track previous ex_freeze to detect when signals are updated +always @(posedge clk) + ex_freeze_q <= ex_freeze; + +// +// Decode started exception +// +// du_except_stop comes from or1200_except +// +always @(du_except_stop or ex_freeze_q) begin + except_stop = 14'b00_0000_0000_0000; + casez (du_except_stop) + 14'b1?_????_????_????: + except_stop[`OR1200_DU_DRR_TTE] = 1'b1; + 14'b01_????_????_????: begin + except_stop[`OR1200_DU_DRR_IE] = 1'b1; + end + 14'b00_1???_????_????: begin + except_stop[`OR1200_DU_DRR_IME] = 1'b1; + end + 14'b00_01??_????_????: + except_stop[`OR1200_DU_DRR_IPFE] = 1'b1; + 14'b00_001?_????_????: begin + except_stop[`OR1200_DU_DRR_BUSEE] = 1'b1; + end + 14'b00_0001_????_????: + except_stop[`OR1200_DU_DRR_IIE] = 1'b1; + 14'b00_0000_1???_????: begin + except_stop[`OR1200_DU_DRR_AE] = 1'b1; + end + 14'b00_0000_01??_????: begin + except_stop[`OR1200_DU_DRR_DME] = 1'b1; + end + 14'b00_0000_001?_????: + except_stop[`OR1200_DU_DRR_DPFE] = 1'b1; + 14'b00_0000_0001_????: + except_stop[`OR1200_DU_DRR_BUSEE] = 1'b1; + 14'b00_0000_0000_1???: begin + except_stop[`OR1200_DU_DRR_RE] = 1'b1; + end + 14'b00_0000_0000_01??: begin + except_stop[`OR1200_DU_DRR_TE] = 1'b1 & ~ex_freeze_q; + end + 14'b00_0000_0000_001?: begin + except_stop[`OR1200_DU_DRR_FPE] = 1'b1; + end + 14'b00_0000_0000_0001: + except_stop[`OR1200_DU_DRR_SCE] = 1'b1 & ~ex_freeze_q; + default: + except_stop = 14'b00_0000_0000_0000; + endcase // casez (du_except_stop) +end + +// +// dbg_bp_o is registered +// +assign dbg_bp_o = dbg_bp_r; + +// +// Breakpoint activation register +// +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dbg_bp_r <= 1'b0; + else if (!ex_freeze) + dbg_bp_r <= |except_stop +`ifdef OR1200_DU_DMR1_ST + | ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]) & dmr1[`OR1200_DU_DMR1_ST] +`endif +`ifdef OR1200_DU_DMR1_BT + | (branch_op != `OR1200_BRANCHOP_NOP) & (branch_op != `OR1200_BRANCHOP_RFE) & dmr1[`OR1200_DU_DMR1_BT] +`endif + ; + else + dbg_bp_r <= |except_stop; + +// +// Write to DMR1 +// +`ifdef OR1200_DU_DMR1 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dmr1 <= 25'h000_0000; + else if (dmr1_sel && spr_write) +`ifdef OR1200_DU_HWBKPTS + dmr1 <= spr_dat_i[24:0]; +`else + dmr1 <= {1'b0, spr_dat_i[23:22], 22'h00_0000}; +`endif +`else +assign dmr1 = 25'h000_0000; +`endif + +// +// Write to DMR2 +// +`ifdef OR1200_DU_DMR2 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dmr2 <= 24'h00_0000; + else if (dmr2_sel && spr_write) + dmr2 <= spr_dat_i[23:0]; +`else +assign dmr2 = 24'h00_0000; +`endif + +// +// Write to DSR +// +`ifdef OR1200_DU_DSR +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dsr <= {`OR1200_DU_DSR_WIDTH{1'b0}}; + else if (dsr_sel && spr_write) + dsr <= spr_dat_i[`OR1200_DU_DSR_WIDTH-1:0]; +`else +assign dsr = {`OR1200_DU_DSR_WIDTH{1'b0}}; +`endif + +// +// Write to DRR +// +`ifdef OR1200_DU_DRR +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + drr <= 14'b0; + else if (drr_sel && spr_write) + drr <= spr_dat_i[13:0]; + else + drr <= drr | except_stop; +`else +assign drr = 14'b0; +`endif + +// +// Write to DVR0 +// +`ifdef OR1200_DU_DVR0 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr0 <= 32'h0000_0000; + else if (dvr0_sel && spr_write) + dvr0 <= spr_dat_i[31:0]; +`else +assign dvr0 = 32'h0000_0000; +`endif + +// +// Write to DVR1 +// +`ifdef OR1200_DU_DVR1 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr1 <= 32'h0000_0000; + else if (dvr1_sel && spr_write) + dvr1 <= spr_dat_i[31:0]; +`else +assign dvr1 = 32'h0000_0000; +`endif + +// +// Write to DVR2 +// +`ifdef OR1200_DU_DVR2 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr2 <= 32'h0000_0000; + else if (dvr2_sel && spr_write) + dvr2 <= spr_dat_i[31:0]; +`else +assign dvr2 = 32'h0000_0000; +`endif + +// +// Write to DVR3 +// +`ifdef OR1200_DU_DVR3 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr3 <= 32'h0000_0000; + else if (dvr3_sel && spr_write) + dvr3 <= spr_dat_i[31:0]; +`else +assign dvr3 = 32'h0000_0000; +`endif + +// +// Write to DVR4 +// +`ifdef OR1200_DU_DVR4 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr4 <= 32'h0000_0000; + else if (dvr4_sel && spr_write) + dvr4 <= spr_dat_i[31:0]; +`else +assign dvr4 = 32'h0000_0000; +`endif + +// +// Write to DVR5 +// +`ifdef OR1200_DU_DVR5 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr5 <= 32'h0000_0000; + else if (dvr5_sel && spr_write) + dvr5 <= spr_dat_i[31:0]; +`else +assign dvr5 = 32'h0000_0000; +`endif + +// +// Write to DVR6 +// +`ifdef OR1200_DU_DVR6 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr6 <= 32'h0000_0000; + else if (dvr6_sel && spr_write) + dvr6 <= spr_dat_i[31:0]; +`else +assign dvr6 = 32'h0000_0000; +`endif + +// +// Write to DVR7 +// +`ifdef OR1200_DU_DVR7 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr7 <= 32'h0000_0000; + else if (dvr7_sel && spr_write) + dvr7 <= spr_dat_i[31:0]; +`else +assign dvr7 = 32'h0000_0000; +`endif + +// +// Write to DCR0 +// +`ifdef OR1200_DU_DCR0 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr0 <= 8'h00; + else if (dcr0_sel && spr_write) + dcr0 <= spr_dat_i[7:0]; +`else +assign dcr0 = 8'h00; +`endif + +// +// Write to DCR1 +// +`ifdef OR1200_DU_DCR1 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr1 <= 8'h00; + else if (dcr1_sel && spr_write) + dcr1 <= spr_dat_i[7:0]; +`else +assign dcr1 = 8'h00; +`endif + +// +// Write to DCR2 +// +`ifdef OR1200_DU_DCR2 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr2 <= 8'h00; + else if (dcr2_sel && spr_write) + dcr2 <= spr_dat_i[7:0]; +`else +assign dcr2 = 8'h00; +`endif + +// +// Write to DCR3 +// +`ifdef OR1200_DU_DCR3 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr3 <= 8'h00; + else if (dcr3_sel && spr_write) + dcr3 <= spr_dat_i[7:0]; +`else +assign dcr3 = 8'h00; +`endif + +// +// Write to DCR4 +// +`ifdef OR1200_DU_DCR4 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr4 <= 8'h00; + else if (dcr4_sel && spr_write) + dcr4 <= spr_dat_i[7:0]; +`else +assign dcr4 = 8'h00; +`endif + +// +// Write to DCR5 +// +`ifdef OR1200_DU_DCR5 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr5 <= 8'h00; + else if (dcr5_sel && spr_write) + dcr5 <= spr_dat_i[7:0]; +`else +assign dcr5 = 8'h00; +`endif + +// +// Write to DCR6 +// +`ifdef OR1200_DU_DCR6 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr6 <= 8'h00; + else if (dcr6_sel && spr_write) + dcr6 <= spr_dat_i[7:0]; +`else +assign dcr6 = 8'h00; +`endif + +// +// Write to DCR7 +// +`ifdef OR1200_DU_DCR7 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr7 <= 8'h00; + else if (dcr7_sel && spr_write) + dcr7 <= spr_dat_i[7:0]; +`else +assign dcr7 = 8'h00; +`endif + +// +// Write to DWCR0 +// +`ifdef OR1200_DU_DWCR0 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dwcr0 <= 32'h0000_0000; + else if (dwcr0_sel && spr_write) + dwcr0 <= spr_dat_i[31:0]; + else if (incr_wpcntr0) + dwcr0[`OR1200_DU_DWCR_COUNT] <= dwcr0[`OR1200_DU_DWCR_COUNT] + 16'h0001; +`else +assign dwcr0 = 32'h0000_0000; +`endif + +// +// Write to DWCR1 +// +`ifdef OR1200_DU_DWCR1 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dwcr1 <= 32'h0000_0000; + else if (dwcr1_sel && spr_write) + dwcr1 <= spr_dat_i[31:0]; + else if (incr_wpcntr1) + dwcr1[`OR1200_DU_DWCR_COUNT] <= dwcr1[`OR1200_DU_DWCR_COUNT] + 16'h0001; +`else +assign dwcr1 = 32'h0000_0000; +`endif + +// +// Read DU registers +// +`ifdef OR1200_DU_READREGS +always @(spr_addr or dsr or drr or dmr1 or dmr2 + or dvr0 or dvr1 or dvr2 or dvr3 or dvr4 + or dvr5 or dvr6 or dvr7 + or dcr0 or dcr1 or dcr2 or dcr3 or dcr4 + or dcr5 or dcr6 or dcr7 + or dwcr0 or dwcr1 +`ifdef OR1200_DU_TB_IMPLEMENTED + or tb_wadr or tbia_dat_o or tbim_dat_o + or tbar_dat_o or tbts_dat_o +`endif + ) + casez (spr_addr[`OR1200_DUOFS_BITS]) // synopsys parallel_case +`ifdef OR1200_DU_DVR0 + `OR1200_DU_DVR0: + spr_dat_o = dvr0; +`endif +`ifdef OR1200_DU_DVR1 + `OR1200_DU_DVR1: + spr_dat_o = dvr1; +`endif +`ifdef OR1200_DU_DVR2 + `OR1200_DU_DVR2: + spr_dat_o = dvr2; +`endif +`ifdef OR1200_DU_DVR3 + `OR1200_DU_DVR3: + spr_dat_o = dvr3; +`endif +`ifdef OR1200_DU_DVR4 + `OR1200_DU_DVR4: + spr_dat_o = dvr4; +`endif +`ifdef OR1200_DU_DVR5 + `OR1200_DU_DVR5: + spr_dat_o = dvr5; +`endif +`ifdef OR1200_DU_DVR6 + `OR1200_DU_DVR6: + spr_dat_o = dvr6; +`endif +`ifdef OR1200_DU_DVR7 + `OR1200_DU_DVR7: + spr_dat_o = dvr7; +`endif +`ifdef OR1200_DU_DCR0 + `OR1200_DU_DCR0: + spr_dat_o = {24'h00_0000, dcr0}; +`endif +`ifdef OR1200_DU_DCR1 + `OR1200_DU_DCR1: + spr_dat_o = {24'h00_0000, dcr1}; +`endif +`ifdef OR1200_DU_DCR2 + `OR1200_DU_DCR2: + spr_dat_o = {24'h00_0000, dcr2}; +`endif +`ifdef OR1200_DU_DCR3 + `OR1200_DU_DCR3: + spr_dat_o = {24'h00_0000, dcr3}; +`endif +`ifdef OR1200_DU_DCR4 + `OR1200_DU_DCR4: + spr_dat_o = {24'h00_0000, dcr4}; +`endif +`ifdef OR1200_DU_DCR5 + `OR1200_DU_DCR5: + spr_dat_o = {24'h00_0000, dcr5}; +`endif +`ifdef OR1200_DU_DCR6 + `OR1200_DU_DCR6: + spr_dat_o = {24'h00_0000, dcr6}; +`endif +`ifdef OR1200_DU_DCR7 + `OR1200_DU_DCR7: + spr_dat_o = {24'h00_0000, dcr7}; +`endif +`ifdef OR1200_DU_DMR1 + `OR1200_DU_DMR1: + spr_dat_o = {7'h00, dmr1}; +`endif +`ifdef OR1200_DU_DMR2 + `OR1200_DU_DMR2: + spr_dat_o = {8'h00, dmr2}; +`endif +`ifdef OR1200_DU_DWCR0 + `OR1200_DU_DWCR0: + spr_dat_o = dwcr0; +`endif +`ifdef OR1200_DU_DWCR1 + `OR1200_DU_DWCR1: + spr_dat_o = dwcr1; +`endif +`ifdef OR1200_DU_DSR + `OR1200_DU_DSR: + spr_dat_o = {18'b0, dsr}; +`endif +`ifdef OR1200_DU_DRR + `OR1200_DU_DRR: + spr_dat_o = {18'b0, drr}; +`endif +`ifdef OR1200_DU_TB_IMPLEMENTED + `OR1200_DU_TBADR: + spr_dat_o = {24'h000000, tb_wadr}; + `OR1200_DU_TBIA: + spr_dat_o = tbia_dat_o; + `OR1200_DU_TBIM: + spr_dat_o = tbim_dat_o; + `OR1200_DU_TBAR: + spr_dat_o = tbar_dat_o; + `OR1200_DU_TBTS: + spr_dat_o = tbts_dat_o; +`endif + default: + spr_dat_o = 32'h0000_0000; + endcase +`endif + +// +// DSR alias +// +assign du_dsr = dsr; + +`ifdef OR1200_DU_HWBKPTS + +// +// Compare To What (Match Condition 0) +// +always @(dcr0 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr0[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond0_ct = id_pc; // insn fetch EA + 3'b010: match_cond0_ct = dcpu_adr_i; // load EA + 3'b011: match_cond0_ct = dcpu_adr_i; // store EA + 3'b100: match_cond0_ct = dcpu_dat_dc; // load data + 3'b101: match_cond0_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond0_ct = dcpu_adr_i; // load/store EA + default:match_cond0_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 0) +// +always @(dcr0 or dcpu_cycstb_i) + case (dcr0[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond0_stb = 1'b0; //comparison disabled + 3'b001: match_cond0_stb = 1'b1; // insn fetch EA + default:match_cond0_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 0 +// +always @(match_cond0_stb or dcr0 or dvr0 or match_cond0_ct) + casex ({match_cond0_stb, dcr0[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match0 = 1'b0; + 4'b1_001: match0 = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} == + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_010: match0 = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} < + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_011: match0 = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} <= + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_100: match0 = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} > + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_101: match0 = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} >= + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_110: match0 = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} != + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + endcase + +// +// Watchpoint 0 +// +always @(dmr1 or match0) + case (dmr1[`OR1200_DU_DMR1_CW0]) + 2'b00: wp[0] = match0; + 2'b01: wp[0] = match0; + 2'b10: wp[0] = match0; + 2'b11: wp[0] = 1'b0; + endcase + +// +// Compare To What (Match Condition 1) +// +always @(dcr1 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr1[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond1_ct = id_pc; // insn fetch EA + 3'b010: match_cond1_ct = dcpu_adr_i; // load EA + 3'b011: match_cond1_ct = dcpu_adr_i; // store EA + 3'b100: match_cond1_ct = dcpu_dat_dc; // load data + 3'b101: match_cond1_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond1_ct = dcpu_adr_i; // load/store EA + default:match_cond1_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 1) +// +always @(dcr1 or dcpu_cycstb_i) + case (dcr1[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond1_stb = 1'b0; //comparison disabled + 3'b001: match_cond1_stb = 1'b1; // insn fetch EA + default:match_cond1_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 1 +// +always @(match_cond1_stb or dcr1 or dvr1 or match_cond1_ct) + casex ({match_cond1_stb, dcr1[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match1 = 1'b0; + 4'b1_001: match1 = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} == + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_010: match1 = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} < + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_011: match1 = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} <= + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_100: match1 = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} > + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_101: match1 = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} >= + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_110: match1 = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} != + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + endcase + +// +// Watchpoint 1 +// +always @(dmr1 or match1 or wp) + case (dmr1[`OR1200_DU_DMR1_CW1]) + 2'b00: wp[1] = match1; + 2'b01: wp[1] = match1 & wp[0]; + 2'b10: wp[1] = match1 | wp[0]; + 2'b11: wp[1] = 1'b0; + endcase + +// +// Compare To What (Match Condition 2) +// +always @(dcr2 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr2[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond2_ct = id_pc; // insn fetch EA + 3'b010: match_cond2_ct = dcpu_adr_i; // load EA + 3'b011: match_cond2_ct = dcpu_adr_i; // store EA + 3'b100: match_cond2_ct = dcpu_dat_dc; // load data + 3'b101: match_cond2_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond2_ct = dcpu_adr_i; // load/store EA + default:match_cond2_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 2) +// +always @(dcr2 or dcpu_cycstb_i) + case (dcr2[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond2_stb = 1'b0; //comparison disabled + 3'b001: match_cond2_stb = 1'b1; // insn fetch EA + default:match_cond2_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 2 +// +always @(match_cond2_stb or dcr2 or dvr2 or match_cond2_ct) + casex ({match_cond2_stb, dcr2[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match2 = 1'b0; + 4'b1_001: match2 = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} == + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_010: match2 = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} < + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_011: match2 = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} <= + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_100: match2 = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} > + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_101: match2 = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} >= + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_110: match2 = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} != + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + endcase + +// +// Watchpoint 2 +// +always @(dmr1 or match2 or wp) + case (dmr1[`OR1200_DU_DMR1_CW2]) + 2'b00: wp[2] = match2; + 2'b01: wp[2] = match2 & wp[1]; + 2'b10: wp[2] = match2 | wp[1]; + 2'b11: wp[2] = 1'b0; + endcase + +// +// Compare To What (Match Condition 3) +// +always @(dcr3 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr3[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond3_ct = id_pc; // insn fetch EA + 3'b010: match_cond3_ct = dcpu_adr_i; // load EA + 3'b011: match_cond3_ct = dcpu_adr_i; // store EA + 3'b100: match_cond3_ct = dcpu_dat_dc; // load data + 3'b101: match_cond3_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond3_ct = dcpu_adr_i; // load/store EA + default:match_cond3_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 3) +// +always @(dcr3 or dcpu_cycstb_i) + case (dcr3[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond3_stb = 1'b0; //comparison disabled + 3'b001: match_cond3_stb = 1'b1; // insn fetch EA + default:match_cond3_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 3 +// +always @(match_cond3_stb or dcr3 or dvr3 or match_cond3_ct) + casex ({match_cond3_stb, dcr3[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match3 = 1'b0; + 4'b1_001: match3 = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} == + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_010: match3 = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} < + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_011: match3 = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} <= + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_100: match3 = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} > + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_101: match3 = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} >= + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_110: match3 = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} != + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + endcase + +// +// Watchpoint 3 +// +always @(dmr1 or match3 or wp) + case (dmr1[`OR1200_DU_DMR1_CW3]) + 2'b00: wp[3] = match3; + 2'b01: wp[3] = match3 & wp[2]; + 2'b10: wp[3] = match3 | wp[2]; + 2'b11: wp[3] = 1'b0; + endcase + +// +// Compare To What (Match Condition 4) +// +always @(dcr4 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr4[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond4_ct = id_pc; // insn fetch EA + 3'b010: match_cond4_ct = dcpu_adr_i; // load EA + 3'b011: match_cond4_ct = dcpu_adr_i; // store EA + 3'b100: match_cond4_ct = dcpu_dat_dc; // load data + 3'b101: match_cond4_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond4_ct = dcpu_adr_i; // load/store EA + default:match_cond4_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 4) +// +always @(dcr4 or dcpu_cycstb_i) + case (dcr4[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond4_stb = 1'b0; //comparison disabled + 3'b001: match_cond4_stb = 1'b1; // insn fetch EA + default:match_cond4_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 4 +// +always @(match_cond4_stb or dcr4 or dvr4 or match_cond4_ct) + casex ({match_cond4_stb, dcr4[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match4 = 1'b0; + 4'b1_001: match4 = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} == + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_010: match4 = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} < + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_011: match4 = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} <= + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_100: match4 = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} > + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_101: match4 = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} >= + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_110: match4 = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} != + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + endcase + +// +// Watchpoint 4 +// +always @(dmr1 or match4 or wp) + case (dmr1[`OR1200_DU_DMR1_CW4]) + 2'b00: wp[4] = match4; + 2'b01: wp[4] = match4 & wp[3]; + 2'b10: wp[4] = match4 | wp[3]; + 2'b11: wp[4] = 1'b0; + endcase + +// +// Compare To What (Match Condition 5) +// +always @(dcr5 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr5[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond5_ct = id_pc; // insn fetch EA + 3'b010: match_cond5_ct = dcpu_adr_i; // load EA + 3'b011: match_cond5_ct = dcpu_adr_i; // store EA + 3'b100: match_cond5_ct = dcpu_dat_dc; // load data + 3'b101: match_cond5_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond5_ct = dcpu_adr_i; // load/store EA + default:match_cond5_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 5) +// +always @(dcr5 or dcpu_cycstb_i) + case (dcr5[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond5_stb = 1'b0; //comparison disabled + 3'b001: match_cond5_stb = 1'b1; // insn fetch EA + default:match_cond5_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 5 +// +always @(match_cond5_stb or dcr5 or dvr5 or match_cond5_ct) + casex ({match_cond5_stb, dcr5[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match5 = 1'b0; + 4'b1_001: match5 = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} == + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_010: match5 = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} < + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_011: match5 = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} <= + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_100: match5 = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} > + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_101: match5 = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} >= + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_110: match5 = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} != + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + endcase + +// +// Watchpoint 5 +// +always @(dmr1 or match5 or wp) + case (dmr1[`OR1200_DU_DMR1_CW5]) + 2'b00: wp[5] = match5; + 2'b01: wp[5] = match5 & wp[4]; + 2'b10: wp[5] = match5 | wp[4]; + 2'b11: wp[5] = 1'b0; + endcase + +// +// Compare To What (Match Condition 6) +// +always @(dcr6 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr6[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond6_ct = id_pc; // insn fetch EA + 3'b010: match_cond6_ct = dcpu_adr_i; // load EA + 3'b011: match_cond6_ct = dcpu_adr_i; // store EA + 3'b100: match_cond6_ct = dcpu_dat_dc; // load data + 3'b101: match_cond6_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond6_ct = dcpu_adr_i; // load/store EA + default:match_cond6_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 6) +// +always @(dcr6 or dcpu_cycstb_i) + case (dcr6[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond6_stb = 1'b0; //comparison disabled + 3'b001: match_cond6_stb = 1'b1; // insn fetch EA + default:match_cond6_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 6 +// +always @(match_cond6_stb or dcr6 or dvr6 or match_cond6_ct) + casex ({match_cond6_stb, dcr6[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match6 = 1'b0; + 4'b1_001: match6 = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} == + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_010: match6 = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} < + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_011: match6 = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} <= + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_100: match6 = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} > + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_101: match6 = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} >= + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_110: match6 = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} != + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + endcase + +// +// Watchpoint 6 +// +always @(dmr1 or match6 or wp) + case (dmr1[`OR1200_DU_DMR1_CW6]) + 2'b00: wp[6] = match6; + 2'b01: wp[6] = match6 & wp[5]; + 2'b10: wp[6] = match6 | wp[5]; + 2'b11: wp[6] = 1'b0; + endcase + +// +// Compare To What (Match Condition 7) +// +always @(dcr7 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr7[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond7_ct = id_pc; // insn fetch EA + 3'b010: match_cond7_ct = dcpu_adr_i; // load EA + 3'b011: match_cond7_ct = dcpu_adr_i; // store EA + 3'b100: match_cond7_ct = dcpu_dat_dc; // load data + 3'b101: match_cond7_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond7_ct = dcpu_adr_i; // load/store EA + default:match_cond7_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 7) +// +always @(dcr7 or dcpu_cycstb_i) + case (dcr7[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond7_stb = 1'b0; //comparison disabled + 3'b001: match_cond7_stb = 1'b1; // insn fetch EA + default:match_cond7_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 7 +// +always @(match_cond7_stb or dcr7 or dvr7 or match_cond7_ct) + casex ({match_cond7_stb, dcr7[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match7 = 1'b0; + 4'b1_001: match7 = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} == + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_010: match7 = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} < + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_011: match7 = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} <= + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_100: match7 = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} > + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_101: match7 = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} >= + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_110: match7 = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} != + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + endcase + +// +// Watchpoint 7 +// +always @(dmr1 or match7 or wp) + case (dmr1[`OR1200_DU_DMR1_CW7]) + 2'b00: wp[7] = match7; + 2'b01: wp[7] = match7 & wp[6]; + 2'b10: wp[7] = match7 | wp[6]; + 2'b11: wp[7] = 1'b0; + endcase + +// +// Increment Watchpoint Counter 0 +// +always @(wp or dmr2) + if (dmr2[`OR1200_DU_DMR2_WCE0]) + incr_wpcntr0 = |(wp & ~dmr2[`OR1200_DU_DMR2_AWTC]); + else + incr_wpcntr0 = 1'b0; + +// +// Match Condition Watchpoint Counter 0 +// +always @(dwcr0) + if (dwcr0[`OR1200_DU_DWCR_MATCH] == dwcr0[`OR1200_DU_DWCR_COUNT]) + wpcntr0_match = 1'b1; + else + wpcntr0_match = 1'b0; + + +// +// Watchpoint 8 +// +always @(dmr1 or wpcntr0_match or wp) + case (dmr1[`OR1200_DU_DMR1_CW8]) + 2'b00: wp[8] = wpcntr0_match; + 2'b01: wp[8] = wpcntr0_match & wp[7]; + 2'b10: wp[8] = wpcntr0_match | wp[7]; + 2'b11: wp[8] = 1'b0; + endcase + + +// +// Increment Watchpoint Counter 1 +// +always @(wp or dmr2) + if (dmr2[`OR1200_DU_DMR2_WCE1]) + incr_wpcntr1 = |(wp & dmr2[`OR1200_DU_DMR2_AWTC]); + else + incr_wpcntr1 = 1'b0; + +// +// Match Condition Watchpoint Counter 1 +// +always @(dwcr1) + if (dwcr1[`OR1200_DU_DWCR_MATCH] == dwcr1[`OR1200_DU_DWCR_COUNT]) + wpcntr1_match = 1'b1; + else + wpcntr1_match = 1'b0; + +// +// Watchpoint 9 +// +always @(dmr1 or wpcntr1_match or wp) + case (dmr1[`OR1200_DU_DMR1_CW9]) + 2'b00: wp[9] = wpcntr1_match; + 2'b01: wp[9] = wpcntr1_match & wp[8]; + 2'b10: wp[9] = wpcntr1_match | wp[8]; + 2'b11: wp[9] = 1'b0; + endcase + +// +// Watchpoint 10 +// +always @(dmr1 or dbg_ewt_i or wp) + case (dmr1[`OR1200_DU_DMR1_CW10]) + 2'b00: wp[10] = dbg_ewt_i; + 2'b01: wp[10] = dbg_ewt_i & wp[9]; + 2'b10: wp[10] = dbg_ewt_i | wp[9]; + 2'b11: wp[10] = 1'b0; + endcase + +`endif + +// +// Watchpoints can cause trap exception +// +`ifdef OR1200_DU_HWBKPTS +assign du_hwbkpt = |(wp & dmr2[`OR1200_DU_DMR2_WGB]) | du_hwbkpt_hold | (dbg_bp_r & ~dsr[`OR1200_DU_DSR_TE]); +`else +assign du_hwbkpt = 1'b0; +`endif + +// Hold du_hwbkpt if ex_freeze is active in order to cause trap exception +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + du_hwbkpt_hold <= 1'b0; + else if (du_hwbkpt & ex_freeze) + du_hwbkpt_hold <= 1'b1; + else if (!ex_freeze) + du_hwbkpt_hold <= 1'b0; + +`ifdef OR1200_DU_TB_IMPLEMENTED +// +// Simple trace buffer +// (right now hardcoded for Xilinx Virtex FPGAs) +// +// Stores last 256 instruction addresses, instruction +// machine words and ALU results +// + +// +// Trace buffer write enable +// +assign tb_enw = ~ex_freeze & ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]); + +// +// Trace buffer write address pointer +// +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + tb_wadr <= 8'h00; + else if (tb_enw) + tb_wadr <= tb_wadr + 8'd1; + +// +// Free running counter (time stamp) +// +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + tb_timstmp <= 32'h00000000; + else if (!dbg_bp_r) + tb_timstmp <= tb_timstmp + 32'd1; + +// +// Trace buffer RAMs +// + +or1200_dpram_256x32 tbia_ram( + .clk_a(clk), + .rst_a(1'b0), + .addr_a(spr_addr[7:0]), + .ce_a(1'b1), + .oe_a(1'b1), + .do_a(tbia_dat_o), + + .clk_b(clk), + .rst_b(1'b0), + .addr_b(tb_wadr), + .di_b(spr_dat_npc), + .ce_b(1'b1), + .we_b(tb_enw) + +); + +or1200_dpram_256x32 tbim_ram( + .clk_a(clk), + .rst_a(1'b0), + .addr_a(spr_addr[7:0]), + .ce_a(1'b1), + .oe_a(1'b1), + .do_a(tbim_dat_o), + + .clk_b(clk), + .rst_b(1'b0), + .addr_b(tb_wadr), + .di_b(ex_insn), + .ce_b(1'b1), + .we_b(tb_enw) +); + +or1200_dpram_256x32 tbar_ram( + .clk_a(clk), + .rst_a(1'b0), + .addr_a(spr_addr[7:0]), + .ce_a(1'b1), + .oe_a(1'b1), + .do_a(tbar_dat_o), + + .clk_b(clk), + .rst_b(1'b0), + .addr_b(tb_wadr), + .di_b(rf_dataw), + .ce_b(1'b1), + .we_b(tb_enw) +); + +or1200_dpram_256x32 tbts_ram( + .clk_a(clk), + .rst_a(1'b0), + .addr_a(spr_addr[7:0]), + .ce_a(1'b1), + .oe_a(1'b1), + .do_a(tbts_dat_o), + + .clk_b(clk), + .rst_b(1'b0), + .addr_b(tb_wadr), + .di_b(tb_timstmp), + .ce_b(1'b1), + .we_b(tb_enw) +); + +`else + +assign tbia_dat_o = 32'h0000_0000; +assign tbim_dat_o = 32'h0000_0000; +assign tbar_dat_o = 32'h0000_0000; +assign tbts_dat_o = 32'h0000_0000; + +`endif // OR1200_DU_TB_IMPLEMENTED + +`else // OR1200_DU_IMPLEMENTED + +// +// When DU is not implemented, drive all outputs as would when DU is disabled +// +assign dbg_bp_o = 1'b0; +assign du_dsr = {`OR1200_DU_DSR_WIDTH{1'b0}}; +assign du_dmr1 = {25{1'b0}}; +assign du_hwbkpt = 1'b0; + +// +// Read DU registers +// +`ifdef OR1200_DU_READREGS +assign spr_dat_o = 32'h0000_0000; +`ifdef OR1200_DU_UNUSED_ZERO +`endif +`endif + +`endif + +endmodule diff --git a/autotests/folding/preprocessor-bug363280.c.fold b/autotests/folding/preprocessor-bug363280.c.fold new file mode 100644 index 0000000..bf559fb --- /dev/null +++ b/autotests/folding/preprocessor-bug363280.c.fold @@ -0,0 +1,8 @@ +#if 1 +int x; // variable shall not be grey +#endif +#if defined (A) +int y; // variable shall not be grey +#elif defined (B) +int z; // variable shall not be grey +#endif diff --git a/autotests/folding/preprocessor-bug363280.cpp.fold b/autotests/folding/preprocessor-bug363280.cpp.fold new file mode 100644 index 0000000..3430631 --- /dev/null +++ b/autotests/folding/preprocessor-bug363280.cpp.fold @@ -0,0 +1,8 @@ +#if 1 +int x; // variable shall not be grey +#endif +#if defined (A) +int y; // variable shall not be grey +#elif defined (B) +int z; // variable shall not be grey +#endif diff --git a/autotests/folding/review128925-1.css.fold b/autotests/folding/review128925-1.css.fold new file mode 100644 index 0000000..4fa6ba6 --- /dev/null +++ b/autotests/folding/review128925-1.css.fold @@ -0,0 +1,112 @@ +/* + * CSS Syntax Highlight Sample File (Standard) + * + * This file contains most CSS syntax, CSS3 properties, @media, @font-face and + * @keyframes annotations. + * + * @author Guo Yunhe guoyunhebrave@gmail.com + * @date 2016-09-16 + */ + +/* + * Block comment + * + * Alert keywords: + * TODO BUG FIXME + */ + +@charset "UTF-8"; + +@import url("components/button.css"); + + +/* Properties */ + +html, body { + font-family: "Droid Sans", Arial, sans-serif; + font-size: 11pt; + line-height: 1.5em; + max-width: calc(100% - 300px); + background: #fff000; + text-shadow: 0 0 2px rgba(0, 0, 0, 0.3); + box-sizing: border-box; +} + + +/* Selectors */ + +blockquote { + margin: 0; +} + +header #logo { + width: 100px; +} + +div#footer .link { + color: blue; +} + +sidebar #subscribe .subscribe_form input[type="text"] { + font-size: 20px; +} + +sidebar #subscribe .subscribe_form:nth-child(2n + 1):hover input[class*="small-"] { + font-weight: bold; +} + + +/* Media Queries */ + +@media print { + .container { + width: 100%; + } +} + +@media screen and (min-width: 768px) { + .container { + width: 600px; + } +} + +@media screen and (min-width: 768px) and (max-width: 960px) { + .container { + width: 720px; + } +} + + +/* Fontface */ + +@font-face { + font-family: MyHelvetica; + src: local("Helvetica Neue Bold"), + local("HelveticaNeue-Bold"), + url(MgOpenModernaBold.ttf); + font-weight: bold; +} + +/* Animation (Keyframes) */ + +@keyframes slidein { + from { + margin-left: 100%; + width: 300%; + } + + to { + margin-left: 0%; + width: 100%; + } +} + + +/* Region markers */ + +/*BEGIN Comment */ + + + +/*END Comment */ + diff --git a/autotests/folding/review128925-1.scss.fold b/autotests/folding/review128925-1.scss.fold new file mode 100644 index 0000000..9bd366c --- /dev/null +++ b/autotests/folding/review128925-1.scss.fold @@ -0,0 +1,211 @@ +/* + * SCSS Syntax Highlight Sample File (Standard) + * + * This file contains most SCSS syntax, CSS3 properties, advanced code structure. + * It is NOT a valid SCSS file that can be compiled by SCSS preprocessors. + * + * @author Guo Yunhe guoyunhebrave@gmail.com + * @date 2016-09-15 + */ + +/* + * Block comment + * + * Alert keywords: + * TODO BUG FIXME + */ + +@charset "UTF-8"; + +@import "mixins/button"; + +// Variable define + +$image-path: "../../static/images"; +$default-text-color: #333 !default; // Default can be overrided +$default-font-size: 16px !default; +$default-font-family: Roboto, "Droid Sans", sans-serif; +$default-font-weight: 400; +$default-line-height: $default-font-size * 1.8; +$shadow-transparence: 0.25; +$box-shadow: 0 0 3px rgba(0,0,0,$shadow-transparence); +$page-width: 100rem; // kabab-case +$gapOfArticle: 20px; // camelCase +$body_background_color: white; // snake_case + +// Mixins + +@mixin border-radius($radius) { + -webkit-border-radius: $radius; + -moz-border-radius: $radius; + -ms-border-radius: $radius; + border-radius: $radius; +} + +.box { @include border-radius(10px); } + +// Nesting + +#home-page { + + header { + width: 80%; + margin: 0 auto; + + .cover { + @include border-radius(20px); + max-width: 100%; + + &:hover { + background: #ffffff; + } + + .like-button { + font-size: $default-font-size * 0.8; + + @media (max-width: 300px) and (min-width: 200px) { + font-size: $default-font-size * 0.8; + + .icon { + width: 20px; + height: 20px; + } + } + + @media print { + display: none; + } + } + } + } +} + +// Extend and inheritance + +.message { + border: $border-light; + background-color: #f0f0f0; +} + +.message-danger { + @extend .message; +} + + +// Control structures + +@mixin does-parent-exist { + @if & { + &:hover { + color: red; + } + } @else { + a { + color: red; + } + } +} + + +// Operators + +.container { width: 100%; } + +article[role="main"] { + float: left; + width: 600px / 960px * 100%; +} + +aside[role="complementary"] { + float: right; + width: 300px / 960px * 100%; +} + + +// Functions - see http://sass-lang.com/documentation/Sass/Script/Functions.html + +$color1: hsl(120deg, 100%, 50%); +$color2: rgb($red, $green, blue($color1)); +$color3: mix($color1, $color2, [$weight]); + + +// Properties + +html, body { + font-family: "Droid Sans", Arial, sans-serif; + font-size: 11pt; + line-height: 1.5em; + max-width: 300px + $page-width - $gap / 2; + background: $bg_color; + text-shadow: 0 0 2px rgba(0,0,0, $transparence); + box-sizing: border-box; +} + + +// Selectors + +blockquote { + margin: 0; +} + +header #logo { + width: 100px; +} + +div#footer .link { + color: blue; +} + +sidebar #subscribe .subscribe_form input[type="text"] { + font-size: 20px; +} + +sidebar #subscribe .subscribe_form:nth-child(2n + 1):hover input[class*="small-"] { + font-weight: bold; +} + + +// Media Queries + +@media print { + .container { + width: 100%; + } +} + +@media screen and (min-width: 768px) { + .container { + width: 600px; + } +} + +@media screen and (min-width: 768px) and (max-width: 960px) { + .container { + width: 720px; + } +} + + +// Fontface + +@font-face { + font-family: MyHelvetica; + src: local("Helvetica Neue Bold"), + local("HelveticaNeue-Bold"), + url(MgOpenModernaBold.ttf); + font-weight: bold; +} + +// Animation (Keyframes) + +@keyframes slidein { + from { + margin-left: 100%; + width: 300%; + } + + to { + margin-left: 0%; + width: 100%; + } +} diff --git a/autotests/folding/review128925-2.css.fold b/autotests/folding/review128925-2.css.fold new file mode 100644 index 0000000..c1473a3 --- /dev/null +++ b/autotests/folding/review128925-2.css.fold @@ -0,0 +1,62 @@ +/* + * CSS Syntax Highlight Sample File (Complex) + * + * This file contains complex CSS syntax that can test unexpected situations. + * + * @author Guo Yunhe guoyunhebrave@gmail.com + * @date 2016-09-16 + */ + + +/* Comments with special content */ + +/* + * .class-selector #id "string" 'comment' // comment {} [] () /* comment + * TODO BUG DEBUG + * body { + * margin: 0 !important; + * } + */ + +/* Comments in special positions */ + +header/* comment here */.active /* comment here */ { + /* comment here */ color : /* comment here */ blue/* comment here */; + font-family: Arial /* comment here */, + "Droid Sans", /* comment here */ + sans-serif/* comment here */; +} + +@media screen /* comment here */ and (max-width: 300px /* comment here */) /* comment here */ {/* comment here */} + + +/* Strings with special content */ + +@import url("{} $variable /* comment */"); + + +/* Without extra breaklines and spaces */ + +pre.primary:hover.large:nth-child(2n-1){font-size:17px;font-family:"Noto Sans";-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.3)} + + +/* With unnecessary breaklines and spaces */ + +blockquote .ref + { + flex : 0 1 30%; + flex-wrap : wrap; + } + +@media screen and (orientation: landscape) { + .sidebar { + width: 500px; } } + + +/* Special selectors: HTML5 allows user defined tags */ + +header { + flex { + width: 300px; + } +} diff --git a/autotests/folding/review128925-2.scss.fold b/autotests/folding/review128925-2.scss.fold new file mode 100644 index 0000000..826707c --- /dev/null +++ b/autotests/folding/review128925-2.scss.fold @@ -0,0 +1,81 @@ +/* + * SCSS Syntax Highlight Sample File (Complex) + * + * This file contains complex SCSS syntax that can test unexpected situations. + * It is NOT a valid SCSS file that can be compiled by SCSS preprocessors. + * + * @author Guo Yunhe guoyunhebrave@gmail.com + * @date 2016-09-16 + */ + + +// Comments with special content + +// .class-selector #id "string" 'comment' // comment {} [] () /* comment */ text + +/* + * .class-selector #id "string" 'comment' // comment {} [] () /* comment + * TODO BUG DEBUG + * body { + * margin: 0 !important; + * } + */ + +// Comments in special positions + +$color: black /* comment here */; + +header/* comment here */.active /* comment here */ { + /* comment here */ color : /* comment here */ blue/* comment here */; + font-family: Arial /* comment here */, + "Droid Sans", /* comment here */ + sans-serif/* comment here */; +} + +@media screen /* comment here */ and (max-width: 300px /* comment here */) /* comment here */ {/* comment here */} + + +// Strings with special content + +@import "{} $variable /* comment */"; +@import "{}"; + +// Without extra breaklines and spaces + +pre.primary:hover.large:nth-child(2n-1){font-size:$default-font-size;font-family:"Noto Sans";-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.3)} + +// With unnecessary breaklines and spaces + +blockquote .ref + { + flex : 0 1 30%; + flex-wrap : wrap; + } + +.sidebar { + width: 300px; } + @media screen and (orientation: landscape) { + .sidebar { + width: 500px; } } + +// Variable interpolation: #{} + +$name: foo; +$attr: border; +p.#{$name} { + #{$attr}-color: blue; +} + +p { + $font-size: 12px; + $line-height: 30px; + font: #{$font-size}/#{$line-height}; +} + +// Special selectors: HTML5 allows user defined tags + +header { + flex { + width: 300px; + } +} diff --git a/autotests/folding/review128935.html.fold b/autotests/folding/review128935.html.fold new file mode 100644 index 0000000..9a5887a --- /dev/null +++ b/autotests/folding/review128935.html.fold @@ -0,0 +1,164 @@ + + +html> + + + + + +HTML Syntax Highlight Sample File (Standard) + + + src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous">> + + + + + + +> + This is a div. This is a span + > + This is a div. + > +> + +

+ This is a paragraph. +

+ +

This is heading 1

+

This is heading 2

+

This is heading 3

+

This is heading 4

+
This is heading 5
+
This is heading 6
+ +
This is a link + +
+ +This is an image + +
+ +> +
  • List item
  • +
  • List item
  • +
  • List item
  • +
  • List item
  • +
  • List item
  • +
    > + +> +
  • List item
  • +
  • List item
  • +
  • List item
  • +
  • List item
  • +
  • List item
  • +
    > + +> + + Table head + Table head + Table head + + + Table head + Table head + Table head + +> + +
    + + + +
    + +> + >This is a header.> + + >This is a nav.> + + > +

    This is an article.

    +

    This is an article.

    +
    > + + > +

    This is an aside.

    +
    > + + >> + +
    > + + + + + + Just For Fun: The Story of an Accidental Revolutionary + Linus Torvalds + + A humorous autobiography of Linus Torvalds, the creator of the Linux + kernel, co-written with David Diamond. The book primarily theorizes + the Law of Linus that all evolution contributed by humanity starts + for survival, sustains socially and entertains at last. As well as + this the book explains Torvalds' view of himself, the free software + movement and the development of Linux. + + + + + + +
    +
    +
    +

    + + + +> + THIS IS A DIV. +

    THIS IS A PARAGRAPH.

    +

    THIS IS A HEADING.

    +
    > + + + +Magic button + +This is an image + + + + + + + + id=name class=a-sweet-block data-counter=175>This is a div.> + + + + diff --git a/autotests/folding/test.bash.fold b/autotests/folding/test.bash.fold new file mode 100644 index 0000000..579e214 --- /dev/null +++ b/autotests/folding/test.bash.fold @@ -0,0 +1,6 @@ +#!/bin/bash + +for i in `ls tests/auto/output/*.html`; do + refFile=`echo $i | sed -e s,build,src, | sed -e s,output,reference, | sed -e s,.html,.ref.html,` + cp -v $i $refFile +done diff --git a/autotests/folding/test.bb.fold b/autotests/folding/test.bb.fold new file mode 100644 index 0000000..98d9089 --- /dev/null +++ b/autotests/folding/test.bb.fold @@ -0,0 +1,34 @@ +# syntax test file for Bitbake receipes + +SUMMARY = "GammaRay Qt introspection probe" +HOMEPAGE = "http://www.kdab.com/gammaray" + +LICENSE = "GPLv2" +LIC_FILES_CHKSUM = "file://LICENSE.GPL.txt;md5=2abfe5daa817fd4346b6d55293941415" + +inherit cmake_qt5 + +SRC_URI = "git://github.com/KDAB/GammaRay;branch=master" + +SRCREV = "139e003174f48b0c883fc6c200ef2efb7467bff1" +PV = "2.4.0+git${SRCPV}" + +DEPENDS = "qtdeclarative" + +S = "${WORKDIR}/git" + +EXTRA_OECMAKE += " -DGAMMARAY_BUILD_UI=OFF" + +FILES_${PN}-dev += " \ + /usr/lib/cmake/* \ + /usr/mkspecs/modules/* \ +" +FILES_${PN}-dbg += " \ + /usr/lib/.debug/* \ + /usr/lib/gammaray/*/*/.debug \ + /usr/lib/gammaray/*/*/styles/.debug \ +" + +# error: unterinated string +VAR *= "abc + this is wrong diff --git a/autotests/folding/test.c.fold b/autotests/folding/test.c.fold new file mode 100644 index 0000000..7b43b2d --- /dev/null +++ b/autotests/folding/test.c.fold @@ -0,0 +1,56 @@ +#include +#include "stdint.h" + +#define SOME_VAR 1 +#ifdef SOME_VAR + +#define MULTILINE_MACRO one \ +two \ +three + +static uint64_t intWithSuffix = 42ull; +static int octNum = 07232; +static int invalidOctNum = 09231; +static uint64_t hexNum = 0xDEADBEEF42; +static uint64_t invalidHexNum = 0xGLDFKG; +static char binNum = 0b0101010; + +static double d1 = 42.; +static double d2 = .42; +static double d3 = 42.3e1; +static double d4 = .2e-12; +static double d5 = 32.e+12; +static float floatQualifier = 23.123f; + +static const char c1 = 'c'; +static const char c2 = '\n'; +static const char c2a = '\120'; // octal +static const char c2b = '\x1f'; // hex +static const char c2c = '\''; +static const char c2d = '\\'; +static const char* c3 = "string"; +static const char* c4 = "\"string\n\t\012\x12\""; +static const char* c5 = "multiline \ + string"; + +//BEGIN region +// TODO comment FIXME comment ### comment +//END region + +#wrong + +/** + * Doxygen + * @param p1 text + * \brief bold text + * \dot + * a -> b + * \enddot + * + * \verbatim + * + * \endverbatim + * text + */ + +#endif diff --git a/autotests/folding/test.cmake.fold b/autotests/folding/test.cmake.fold new file mode 100644 index 0000000..5c543cb --- /dev/null +++ b/autotests/folding/test.cmake.fold @@ -0,0 +1,31 @@ +# comment + +#[[.rst: +MyModule +-------- + +bla bla +#]] + +#.rst: +# ATTENTION +# alternative doc comment +# + +#[=====[.rst: + +3rd form + +]=====] + +set(CMAKE_AUTOMOC ON) +if (POLICY CMP042) + target_link_libraries(myTaget SHARED Qt5::Core) +else()else() + add_executable(myTaget ${some_var}) +endif() + +macro(my_macro arg1) + foreach(arg ${ARGN}) + endforeach() +endmacro() diff --git a/autotests/folding/test.css.fold b/autotests/folding/test.css.fold new file mode 100644 index 0000000..0edd45b --- /dev/null +++ b/autotests/folding/test.css.fold @@ -0,0 +1,18 @@ +h1 { + text-color: "red"; +} + +/* PHP code, invalid in CSS context */ +for() + + + +h2 { + text-weight: bold; +} + diff --git a/autotests/folding/test.desktop.fold b/autotests/folding/test.desktop.fold new file mode 100644 index 0000000..77db817 --- /dev/null +++ b/autotests/folding/test.desktop.fold @@ -0,0 +1,19 @@ +# test file for .dekstop syntax highlighting +[Desktop Entry][Desktop Entry] +GenericName=Text Editor +GenericName[ar]=محرّر نصوص +Name=KWrite +Name[ar]=كاتبك +Comment=KDE Text Editor +Comment[ar]=محرّر نصوص لكدي +MimeType=text/plain; +Exec=kwrite %U +StartupNotify=true +Icon=kwrite +X-DocPath=kwrite/index.html +Type=Application +Terminal=false +InitialPreference=8 +X-DBUS-StartupType=Multi +X-DBUS-ServiceName=org.kde.kwrite +Categories=Qt;KDE;Utility;TextEditor; diff --git a/autotests/folding/test.diff.fold b/autotests/folding/test.diff.fold new file mode 100644 index 0000000..95ef591 --- /dev/null +++ b/autotests/folding/test.diff.fold @@ -0,0 +1,48 @@ +commit 2b16665838c8afeaa0f065cafc747438de35876b +Author: Volker Krause +Date: Sat Oct 8 13:31:51 2016 +0200 + + Implement dynamic DetectChar rules + + Needed for Perl highlighting. + +diff --git a/src/lib/rule.cpp b/src/lib/rule.cpp +index f588985..c4c3b92 100644 +--- a/src/lib/rule.cpp ++++ b/src/lib/rule.cpp +@@ -308,12 +308,22 @@ bool DetectChar::doLoad(QXmlStreamReader& reader) + if (s.isEmpty()) + return false; + m_char = s.at(0); ++ if (isDynamic()) { ++ m_captureIndex = m_char.digitValue(); ++ } + return true; + } + + MatchResult DetectChar::doMatch(const QString& text, int offset, const QStringList &captures) + { +- Q_UNUSED(captures); // TODO ++ if (isDynamic()) { ++ if (captures.size() <= m_captureIndex || captures.at(m_captureIndex).isEmpty()) ++ return offset; ++ if (text.at(offset) == captures.at(m_captureIndex).at(0)) ++ return offset + 1; ++ return offset; ++ } ++ + if (text.at(offset) == m_char) + return offset + 1; + return offset; +diff --git a/src/lib/rule_p.h b/src/lib/rule_p.hdiff --git a/src/lib/rule_p.h b/src/lib/rule_p.hdiff --git a/src/lib/rule_p.h b/src/lib/rule_p.h +index d8862ae..d9cedbf 100644 +--- a/src/lib/rule_p.h ++++ b/src/lib/rule_p.h +@@ -103,6 +103,7 @@ protected: + + private: + QChar m_char; ++ int m_captureIndex; + }; + + class Detect2Char : public Rule diff --git a/autotests/folding/test.eml.fold b/autotests/folding/test.eml.fold new file mode 100644 index 0000000..373a421 --- /dev/null +++ b/autotests/folding/test.eml.fold @@ -0,0 +1,94 @@ +Return-Path: +X-Sieve: CMU Sieve 2.3 +X-Virus-Scanned: amavisd-new at site +Authentication-Results: linux.site (amavisd-new); dkim=pass (1024-bit key) + header.d=kde.org +Received: from postbox.kde.org (localhost.localdomain [127.0.0.1]) + by postbox.kde.org (Postfix) with ESMTP id 3167DB6E75; + Wed, 5 Oct 2016 20:21:47 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=kde.org; s=default; + t=1475698907; bh=6i+3UfR6HLC54wVtp5SF4sVWvQn63jzu9vD2zJal/kY=; + h=From:To:Subject:Date:Reply-To:List-Id:List-Unsubscribe:List-Post: + List-Help:List-Subscribe:From; + b=M5nfHbmJe/4DPuidrJ901dUzX3FmpVpyUrPM961Or9bKrMO+z9gaTUwbfPR74Rq8B + Rv66yf3ZaDuRZxv/ARPzpr8qnDTtf13WRFZ/ySdqqqQJKeBqCAd7/wbR0kHhypvpwe + z4nY6+bNnjvFelPXR56o16b+/Ib2GTYJ9hwiG97U= +X-Original-To: kwrite-devel@kde.org +Delivered-To: kwrite-devel@localhost.kde.org +Received-SPF: Neutral (access neither permitted nor denied) identity=mailfrom; + client-ip=85.214.234.26; helo=h2265959.stratoserver.net; + envelope-from=vkrause@kde.org; receiver=kwrite-devel@kde.org +From: Volker Krause +To: kwrite-devel@kde.org +Subject: Highlighting semantics: line end context switches when popping back + into previous line context stack +Date: Wed, 05 Oct 2016 22:19:17 +0200 +Message-ID: <2420385.jiZKTgWtgY@vkpc5> +Organization: KDE +User-Agent: KMail/4.14.10 (Linux/4.1.13-5-default; KDE/4.14.16; x86_64; + git-91275a7; 2015-12-13) +MIME-Version: 1.0 +Content-Type: multipart/signed; boundary="nextPart1575059.2yRQ5x6HOo"; + micalg="pgp-sha1"; protocol="application/pgp-signature" +X-BeenThere: kwrite-devel@kde.org +X-Mailman-Version: 2.1.16 +Precedence: list +Reply-To: kwrite-devel@kde.org +List-Id: Kate/KWrite Mailing List +List-Unsubscribe: , + +List-Post: +List-Help: +List-Subscribe: , + +Errors-To: kwrite-devel-bounces@kde.org +Sender: "KWrite-Devel" + + +--nextPart1575059.2yRQ5x6HOo +Content-Transfer-Encoding: 7Bit +Content-Type: text/plain; charset="us-ascii" + +Hi, + +when trying to add the unit test for the new Praat highlighting to +KF5::SyntaxHighlighting it turned out that the output doesn't match at all +that of Kate. We managed to trace this back to the following rather surprising +(and apparently undocumented) behavior in Kate: + +When a context switch (anywhere in a line) pops more contexts than were on the +stack when starting the line, it executes line end context switches of the +previous line contexts. + +| | | | | | The corresponding code is in KateHighlighting::generateContextStack(), +| | > | > KF5::SyntaxHighlighting doesn't do this (yet), Praat is apparently the first +> | > format we have tests for that uses this behavior. + +> Does anyone remember why we do this, or happens to know which highlighting +> files besides Praat rely on this? + +> > Archeology can trace this back to the dark CVS ages even, one reference +> > Dominik has dug up is a 10 year old SVN commit +> > (https://quickgit.kde.org/?p=kdelibs.git&a=commit&h=90ef47f582277745f727d89f05f72f1e1705fdc4 +> >), where Christoph claims to understand what this code does ;) + +> > > As this is highly unexpected and hard to reason about behavior, Dominik and I +> > > > were wondering if we can possibly drop this, and rather fix affected +> > > > > highlighting files instead? + +Regards, +Volker +--nextPart1575059.2yRQ5x6HOo +Content-Type: application/pgp-signature; name="signature.asc" +Content-Description: This is a digitally signed message part. +Content-Transfer-Encoding: 7Bit + +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iD8DBQBX9WBIf5bM1k0S0kcRAireAJ4lCWa08Y5yU1ezIvKVCAfnkhcUbACgou0O +X4c+lkPI0tti59KV1vetaeU= +=VqDS +-----END PGP SIGNATURE----- + +--nextPart1575059.2yRQ5x6HOo-- diff --git a/autotests/folding/test.frag.fold b/autotests/folding/test.frag.fold new file mode 100644 index 0000000..a6a7bc1 --- /dev/null +++ b/autotests/folding/test.frag.fold @@ -0,0 +1,26 @@ +#version 330 core + +// single line comment + +/* single line commonet */ + +/* + multi line comment + */ + +in ColorFormat { + vec3 color; +} fs_in; + +out vec4 fragColor; + +vec3 fun(const in vec3 foo) { + foo[2] = foo.x; + + return foo; +} + +void main() +{ + fragColor = vec4( fs_in.color, 1.0 ); +} diff --git a/autotests/folding/test.htm.fold b/autotests/folding/test.htm.fold new file mode 100644 index 0000000..277e11a --- /dev/null +++ b/autotests/folding/test.htm.fold @@ -0,0 +1,17 @@ +HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> + + + This is a title + > + /* comment */ + #xyz { color: red; } + h1 { font: "Comic Sans"; } + > + + +

    Hello world!

    + + > + document.body.appendChild(document.createTextNode('Hello World!')); // comment + > + diff --git a/autotests/folding/test.ijs.fold b/autotests/folding/test.ijs.fold new file mode 100644 index 0000000..7ff269b --- /dev/null +++ b/autotests/folding/test.ijs.fold @@ -0,0 +1,61 @@ +Comment +NB. This is a single line comment, check regions overlapping priority: 1 2.3 +/ &. 'quoted text' +NB.( +NB. This is a foldable multi line comment +NB.) + +String literal +'' +'''' +'This is quoted text' +'And this '' and this NB. and this' 'Yet another quoted text' + +Numeric literal +12 34.56 _7.89 1e2 1.2e3 _. _ __ 123j_456 2b111.111 1r23 123456x 1.2e3j4.5e6 _j_ __j_ _.j_. _j3p4j_. + +Parenthesis +( ) + +Adverb +~ / \ /. \. } b. f. M. t. t: + +Conjuction +^: . .. .: : :. :: ;. !. !: " ` `: @ @. @: & &. &: &.: d. D. D: H. L: S: T. + +Control +assert. break. case. catch. catchd. catcht. continue. do. else. elseif. end. fcase. for. for_abc. goto_abc. if. label_abc. return. select. throw. try. while. whilst. + +Copula +a =: 123 +(a) =: 123 +(a;b;c) =: 123 +'a b c' =: 123 +'a b c' =. '123' +'`a b c' =. '123' +'a' =: 123 +('a';'b';'c') =: 123 + +Explicit argument +x y m n u v x. y. m. n. u. v. + +Noun +a. a: + +Verb += < <. <: > >. >: _: + +. +: * *. *: - -. -: % %. %: ^ ^. $ $. $: ~. ~: | |. |: , ,. ,: ; ;: # #. #: ! /: \: [ [: ] { {. {: {:: }. }: ". ": ? ?. A. C. e. E. i. i: I. j. L. o. p. p.. p: q: r. s: u: x: _9: _8: _7: _6: _5: _4: _3: _2: _1: 0: 1: 2: 3: 4: 5: 6: 7: 8: 9: + +Combined +for_abc. i. 5 do. 55 return. end. +a=. b =: 123 +/ # i. 10 +123 'qwerty' +a_b =: '123' [ c__d =. 4 : 0 NB. foldable definition begins + x +/ y +) +e__12 =: define NB. foldable definition begins + if. x do. NB. inner foldable region begins + y=. y + x NB. comment after code + x +/ y + else. NB. inner foldable region begins + y +/ y + end. +) diff --git a/autotests/folding/test.js.fold b/autotests/folding/test.js.fold new file mode 100644 index 0000000..b2cd6f0 --- /dev/null +++ b/autotests/folding/test.js.fold @@ -0,0 +1,8 @@ +/* comment */ + +function fun() +{ + var boo = { 'key': [ 1, 2.0, 3.0e1, 004, 0x5 ] }; +} + +class MyClass; // reserved keywords diff --git a/autotests/folding/test.json.fold b/autotests/folding/test.json.fold new file mode 100644 index 0000000..622ad42 --- /dev/null +++ b/autotests/folding/test.json.fold @@ -0,0 +1,13 @@ +{ + "float": 3.1415, + "int": 123, + "string": "\a \"b' \n", + "array": [ 1, 2, 3 ], + "object": { + "mult-line": "so this folds" + }, + "folded array": [ + 1, 2, 3 + ] + "error key": "due to missing comma" +} diff --git a/autotests/folding/test.markdown.fold b/autotests/folding/test.markdown.fold new file mode 100644 index 0000000..b8b4a9d --- /dev/null +++ b/autotests/folding/test.markdown.fold @@ -0,0 +1,39 @@ +# H1 + +## H2 + +### H3 + +Multi-line paragraph bla bla bla +bla bla bla. + +Intentional line break +via two spaces at line. + +Formats: _italic_, **bold**, `monospace`, ~~strikeout~~ + +Bullet list: + +* item1 +* item2 + +Numbered list: + +1. item 1 +2. item 2 + +[link](http://kde.org) + + code 1 + code 2 + +normal text + +> block quote _italic_ +> more block quote + +normal text + +Title: some text + +normal text diff --git a/autotests/folding/test.mss.fold b/autotests/folding/test.mss.fold new file mode 100644 index 0000000..49e0b97 --- /dev/null +++ b/autotests/folding/test.mss.fold @@ -0,0 +1,215 @@ +/* kate: hl CartoCSS + This file contains some content coming from + https://github.com/gravitystorm/openstreetmap-carto + with CC0 license. This file is just for testing + katepart highlighting engine. + */ + +#world { +// this syntax +polygon-opacity: 50%; + +// is equivalent to +polygon-opacity: 0.5; +} + +@admin-boundaries: #ac46ac; + +/* For performance reasons, the admin border layers are split into three groups +for low, middle and high zoom levels. +For each zoomlevel, all borders come from a single attachment, to handle +overlapping borders correctly. +*/ + +#admin-low-zoom[zoom < 11], // test +#admin-mid-zoom[zoom >= 11][zoom < 13], +#admin-high-zoom[zoom >= 13] { + [admin_level = '2'], + [admin_level = '3'] { + [zoom >= 4] { + background/line-color: white; + background/line-width: 0.6; + line-color: @admin-boundaries; + line-width: 0.6; + } + [zoom >= 7] { + background/line-width: 2; + line-width: 2; + } + [zoom >= 10] { + [admin_level = '2'] { + background/line-width: 6; + line-width: 6; + } + [admin_level = '3'] { + background/line-width: 5; + line-width: 5; + line-dasharray: 4,2; + line-clip: false; + } + } + } + [admin_level = '4'] { + [zoom >= 4] { + background/line-color: white; + background/line-width: 0.6; + line-color: @admin-boundaries; + line-width: 0.6; + line-dasharray: 4,3; + line-clip: false; + } + [zoom >= 7] { + background/line-width: 1; + line-width: 1; + } + [zoom >= 11] { + background/line-width: 3; + line-width: 3; + } + } + /* + The following code prevents admin boundaries from being rendered on top of + each other. Comp-op works on the entire attachment, not on the individual + border. Therefore, this code generates an attachment containing a set of + @admin-boundaries/white dashed lines (of which only the top one is visible), + and with `comp-op: darken` the white part is ignored, while the + @admin-boundaries colored part is rendered (as long as the background is not + darker than @admin-boundaries). + The SQL has `ORDER BY admin_level`, so the boundary with the lowest + admin_level is rendered on top, and therefore the only visible boundary. + */ + opacity: 0.4; + comp-op: darken; +} + +#admin-mid-zoom[zoom >= 11][zoom < 13], +#admin-high-zoom[zoom >= 13] { + [admin_level = '5'][zoom >= 11] { + background/line-color: white; + background/line-width: 2; + line-color: @admin-boundaries; + line-width: 2; + line-dasharray: 6,3,2,3,2,3; + line-clip: false; + } + [admin_level = '6'][zoom >= 11] { + background/line-color: white; + background/line-width: 2; + line-color: @admin-boundaries; + line-width: 2; + line-dasharray: 6,3,2,3; + line-clip: false; + } + [admin_level = '7'], + [admin_level = '8'] { + [zoom >= 12] { + background/line-color: white; + background/line-width: 1.5; + line-color: @admin-boundaries; + line-width: 1.5; + line-dasharray: 5,2; + line-clip: false; + } + } + opacity: 0.5; + comp-op: darken; +} + +#admin-high-zoom[zoom >= 13] { + [admin_level = '9'], + [admin_level = '10'] { + [zoom >= 13] { + background/line-color: white; + background/line-width: 2; + line-color: @admin-boundaries; + line-width: 2; + line-dasharray: 2,3; + line-clip: false; + } + } + opacity: 0.5; + comp-op: darken; +} + + + +#nature-reserve-boundaries { + [way_pixels > 100][zoom >= 7] { + [zoom < 10] { + ::fill { + opacity: 0.05; + polygon-fill: green; + } + } + a/line-width: 1; + a/line-offset: -0.5; + a/line-color: green; + a/line-opacity: 0.15; + a/line-join: round; + a/line-cap: round; + b/line-width: 2; + b/line-offset: -1; + b/line-color: green; + b/line-opacity: 0.15; + b/line-join: round; + b/line-cap: round; + [zoom >= 10] { + a/line-width: 2; + a/line-offset: -1; + b/line-width: 4; + b/line-offset: -2; + } + [zoom >= 14] { + b/line-width: 6; + b/line-offset: -3; + } + } +} + +#building-text { +[zoom >= 14][way_pixels > 3000], +[zoom >= 17] { +text-name: "[name]"; +text-size: 11; +text-fill: #444; +text-face-name: @book-fonts; +text-halo-radius: 1; +text-wrap-width: 20; +text-halo-fill: rgba(255,255,255,0.5); +text-placement: interior; +} +} + +@marina-text: #576ddf; // also swimming_pool +@landcover-face-name: @oblique-fonts; +@standard-wrap-width: 30; + +.points { + [feature = 'tourism_alpine_hut'][zoom >= 13] { + point-file: url('symbols/alpinehut.p.16.png'); + point-placement: interior; + } + } + + [feature = 'highway_bus_stop'] { + [zoom >= 16] { + marker-file: url('symbols/square.svg'); + marker-fill: @transportation-icon; + marker-placement: interior; + marker-width: 6; + } + [zoom >= 17] { + marker-file: url('symbols/bus_stop.p.12.png'); + marker-width: 12; + } + } + +[feature = 'highway_primary'] { +[zoom >= 7][zoom < 12] { +line-width: 0.5; +line-color: @primary-fill; +[zoom >= 9] { line-width: 1.2; } +[zoom >= 10] { line-width: 2; } +[zoom >= 11] { line-width: .5; } +} +} diff --git a/autotests/folding/test.py.fold b/autotests/folding/test.py.fold new file mode 100644 index 0000000..ae0b98a --- /dev/null +++ b/autotests/folding/test.py.fold @@ -0,0 +1,28 @@ +# comment with ALERT + +''' multiline + comment + ### + ''' + +def func(x): + """ API docs """ + if x == 42: + func() + c1 = {} + c2 = { + 2.4, + 0x42 + } + a1 = [] + a2 = [ + "a", 032, ( + )] + else: + print("""multi + line + string""") + print("single \ + continued line ") + print('single line') + return float(len(a2)) diff --git a/autotests/folding/test.qml.fold b/autotests/folding/test.qml.fold new file mode 100644 index 0000000..316ff65 --- /dev/null +++ b/autotests/folding/test.qml.fold @@ -0,0 +1,23 @@ +/* + * multi line comment + */ + +// single line comment + +import QtQuick 2.0 + +Rectangle { + property real myNumProp: 0.1e12; + property alias sub.color; + signal mySignal(int arg1, string arg2) + color: "lightsteelblue" + width: 320 + height: width/2 + + Rectangle { + id: sub + width: 0x10 + height: 007 + objectName: 'single quote' + } +} diff --git a/autotests/folding/test.sql.fold b/autotests/folding/test.sql.fold new file mode 100644 index 0000000..c7a5f3b --- /dev/null +++ b/autotests/folding/test.sql.fold @@ -0,0 +1,6 @@ +-- comment + +CREATE TABLE stuff COLUMNS(col1 INT, col2 Varchar); +SELECT * FROM stuff WHERE id = 'string'; +select * from stuff where id < 0.42; +Select col1, col2 From stuff Where stuff.col1 IS NOT NuLL; diff --git a/autotests/folding/test.tex.fold b/autotests/folding/test.tex.fold new file mode 100644 index 0000000..8da60c9 --- /dev/null +++ b/autotests/folding/test.tex.fold @@ -0,0 +1,5 @@ +% commet + +text \texttt{more text} + +\verb!verbatim text! normal text diff --git a/autotests/folding/test_syntax.sql.fold b/autotests/folding/test_syntax.sql.fold new file mode 100644 index 0000000..62db7f0 --- /dev/null +++ b/autotests/folding/test_syntax.sql.fold @@ -0,0 +1,41 @@ +-- kate: hl SQL (Oracle) +-- test case shipped with highlighting in bugzilla, LGPL + +begin + q'{adfasdf'sadfasdf j}'{' hkjhkhkjhkjh khlkhklj'fghdfghdfgh'hkjh'jkhkh'a' + Q'(asldflahsl;'dkjfhklsdfh)' + q'[asdasd;'asdasd'a]sd'asd'asasd]';11111111[1']; asdasdasdasd'errrrrrrrrrrrrrr-p + + q'agdfgsdfgfhfghjfgh'f'f'sdfg'sdfg'dfg#a' dafdfadasfasdf; + + Q'#gdfgsdfgsdfgsdfgsdfg#' afgasasdfasdfasfasdfasdfasdfasdfsdf + + if sldfjsdj then + case + when 1=1 then + aslfjsldkfj; + when 2=2 then + asdfg; + else + null; + end case; + + if sdfjh then + for i in 1 .. 2 + LOOP + dbms_output.put_line(q';ololo;'); + END Loop; + + while true + loop + dbms_output.put_line('1111'); + end loop; + end if; + ksjfklasjd; + fklj; + elsif + sdklfjsdklfj; + else + sdfdfsdf; + end if; +end; diff --git a/autotests/foldingtest.cpp b/autotests/foldingtest.cpp new file mode 100644 index 0000000..ab07c96 --- /dev/null +++ b/autotests/foldingtest.cpp @@ -0,0 +1,186 @@ +/* + Copyright (C) 2016 Volker Krause + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "test-config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace KSyntaxHighlighting; + +class FoldingHighlighter : public AbstractHighlighter +{ +public: + void highlightFile(const QString &inFileName, const QString &outFileName) + { + QFile outFile(outFileName); + if (!outFile.open(QFile::WriteOnly | QFile::Truncate)) { + qWarning() << "Failed to open output file" << outFileName << ":" << outFile.errorString(); + return; + } + m_out.setDevice(&outFile); + m_out.setCodec("UTF-8"); + + QFile f(inFileName); + if (!f.open(QFile::ReadOnly)) { + qWarning() << "Failed to open input file" << inFileName << ":" << f.errorString(); + return; + } + + QTextStream in(&f); + in.setCodec("UTF-8"); + State state; + bool indentationFoldEnabled = definition().indentationBasedFoldingEnabled(); + if (indentationFoldEnabled) + m_out << ""; + while (!in.atEnd()) { + const auto currentLine = in.readLine(); + state = highlightLine(currentLine, state); + + if (indentationFoldEnabled != state.indentationBasedFoldingEnabled()) { + indentationFoldEnabled = state.indentationBasedFoldingEnabled(); + if (indentationFoldEnabled) + m_out << ""; + else + m_out << ""; + } + + int offset = 0; + foreach (const auto &fold, m_folds) { + m_out << currentLine.mid(offset, fold.offset - offset); + if (fold.region.type() == FoldingRegion::Begin) + m_out << ""; + else + m_out << ""; + m_out << currentLine.mid(fold.offset, fold.length); + if (fold.region.type() == FoldingRegion::Begin) + m_out << ""; + else + m_out << ""; + offset = fold.offset + fold.length; + } + m_out << currentLine.mid(offset) << '\n'; + m_folds.clear(); + } + + m_out.flush(); + } + +protected: + void applyFormat(int offset, int length, const Format &format) Q_DECL_OVERRIDE + { + Q_UNUSED(offset); + Q_UNUSED(length); + Q_UNUSED(format); + } + + void applyFolding(int offset, int length, FoldingRegion region) Q_DECL_OVERRIDE + { + Q_ASSERT(region.isValid()); + m_folds.push_back({offset, length, region}); + } + +private: + QTextStream m_out; + struct Fold { int offset; int length; FoldingRegion region; }; + QVector m_folds; +}; + + +class FoldingTest : public QObject +{ + Q_OBJECT +public: + explicit FoldingTest(QObject *parent = Q_NULLPTR) : QObject(parent) {} +private: + +private Q_SLOTS: + void initTestCase() + { + QStandardPaths::enableTestMode(true); + } + + void testFolding_data() + { + QTest::addColumn("inFile"); + QTest::addColumn("outFile"); + QTest::addColumn("refFile"); + QTest::addColumn("syntax"); + + QDir dir(QStringLiteral(TESTSRCDIR "/input")); + foreach (const auto &fileName, dir.entryList(QDir::Files | QDir::NoSymLinks | QDir::Readable, QDir::Name)) { + const auto inFile = dir.absoluteFilePath(fileName); + if (inFile.endsWith(QLatin1String(".syntax"))) + continue; + + QString syntax; + QFile syntaxOverride(inFile + QStringLiteral(".syntax")); + if (syntaxOverride.exists() && syntaxOverride.open(QFile::ReadOnly)) + syntax = QString::fromUtf8(syntaxOverride.readAll()).trimmed(); + + QTest::newRow(fileName.toUtf8().constData()) << inFile + << (QStringLiteral(TESTBUILDDIR "/folding.out/") + fileName + QStringLiteral(".fold")) + << (QStringLiteral(TESTSRCDIR "/folding/") + fileName + QStringLiteral(".fold")) + << syntax; + } + + QDir().mkpath(QStringLiteral(TESTBUILDDIR "/folding.out/")); + } + + void testFolding() + { + QFETCH(QString, inFile); + QFETCH(QString, outFile); + QFETCH(QString, refFile); + QFETCH(QString, syntax); + + Repository m_repo; + + auto def = m_repo.definitionForFileName(inFile); + if (!syntax.isEmpty()) + def = m_repo.definitionForName(syntax); + + FoldingHighlighter highlighter; + + QVERIFY(def.isValid()); + highlighter.setDefinition(def); + highlighter.highlightFile(inFile, outFile); + + auto args = QStringList() << QStringLiteral("-u") << refFile << outFile; + QProcess proc; + proc.setProcessChannelMode(QProcess::ForwardedChannels); + proc.start(QStringLiteral("diff"), args); + QVERIFY(proc.waitForFinished()); + QCOMPARE(proc.exitCode(), 0); + } + +}; + +QTEST_GUILESS_MAIN(FoldingTest) + +#include "foldingtest.moc" diff --git a/autotests/highlighter_benchmark.cpp b/autotests/highlighter_benchmark.cpp new file mode 100644 index 0000000..e4ec321 --- /dev/null +++ b/autotests/highlighter_benchmark.cpp @@ -0,0 +1,102 @@ +/* + Copyright (C) 2016 Volker Krause + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "test-config.h" + +#include +#include +#include +#include + +#include +#include + +using namespace KSyntaxHighlighting; + +class NullHighlighter : public AbstractHighlighter +{ +public: + void highlightFile(const QString &inFileName) + { + QFile f(inFileName); + if (!f.open(QFile::ReadOnly)) { + qWarning() << "Failed to open input file" << inFileName << ":" << f.errorString(); + return; + } + + QTextStream in(&f); + State state; + while (!in.atEnd()) + state = highlightLine(in.readLine(), state); + } + +protected: + void applyFormat(int, int, const Format&) Q_DECL_OVERRIDE {} +}; + +class HighlighterBenchmark : public QObject +{ + Q_OBJECT +public: + explicit HighlighterBenchmark(QObject *parent = Q_NULLPTR) : QObject(parent), m_repo(Q_NULLPTR) {} + +private: + Repository *m_repo; + +private Q_SLOTS: + void initTestCase() + { + m_repo = new Repository; + } + + void cleanupTestCase() + { + delete m_repo; + m_repo = Q_NULLPTR; + } + + void benchmarkHighlight_data() + { + QTest::addColumn("inFile"); + QTest::addColumn("syntax"); + + QTest::newRow("mimedb") << QStringLiteral(":/qt-project.org/qmime/freedesktop.org.xml") << QStringLiteral("XML"); + } + + void benchmarkHighlight() + { + QFETCH(QString, inFile); + QFETCH(QString, syntax); + QVERIFY(m_repo); + + NullHighlighter highlighter; + auto def = m_repo->definitionForFileName(inFile); + if (!syntax.isEmpty()) + def = m_repo->definitionForName(syntax); + QVERIFY(def.isValid()); + highlighter.setDefinition(def); + QBENCHMARK { + highlighter.highlightFile(inFile); + } + } + +}; + +QTEST_GUILESS_MAIN(HighlighterBenchmark) + +#include "highlighter_benchmark.moc" + diff --git a/autotests/html/Dockerfile.html b/autotests/html/Dockerfile.html new file mode 100644 index 0000000..ef324f6 --- /dev/null +++ b/autotests/html/Dockerfile.html @@ -0,0 +1,26 @@ + + + +Dockerfile + +
    +# LGPLv2+ example file
    +
    +# This is a comment
    +FROM ubuntu:14.04
    +MAINTAINER James Turnbull <james@example.com> # comment
    +ENV REFRESHED_AT 2014-06-01
    +
    +RUN apt-get -yqq update
    +RUN apt-get install -yqq software-properties-common python-software-properties
    +RUN add-apt-repository ppa:chris-lea/redis-server
    +RUN apt-get -yqq update
    +RUN apt-get -yqq install redis-server redis-tools
    +RUN apt-get -yqq update # comment
    +
    +VOLUME [ "/var/lib/redis", "/var/log/redis/" ]
    +
    +EXPOSE 6379
    +
    +CMD []
    +
    diff --git a/autotests/html/Kconfig.html b/autotests/html/Kconfig.html new file mode 100644 index 0000000..ab4ca14 --- /dev/null +++ b/autotests/html/Kconfig.html @@ -0,0 +1,22 @@ + + + +Kconfig + +
    +This is wrong but should not crash ] ) } !
    +
    +# comment
    +
    +config BR2_PACKAGE_GAMMARAY
    +        bool "gammaray"
    +        depends on BR2_PACKAGE_QT5
    +        help
    +          GammaRay Qt introspection probe.
    +          second line of help, with correct indentation
    +         third line underindented and thus wrong
    +        default 'true'
    +
    +menu myMenu
    +endmenu
    +
    diff --git a/autotests/html/Makefile.html b/autotests/html/Makefile.html new file mode 100644 index 0000000..4d81c81 --- /dev/null +++ b/autotests/html/Makefile.html @@ -0,0 +1,32 @@ + + + +Makefile + +
    +# comment
    +
    +include Makefile.in
    +
    +.PHONY: all
    +
    +all: target
    +
    +foo = bar $(var) \
    +    $(baz) quux
    +
    +ifeq ($(CC),gcc)
    +    bla=$(call func,param1,param2)
    +else
    +    libs=$(normal_libs)
    +endif
    +
    +target1:
    +        error
    +
    +target2: bla.cpp $@
    +	$(CC) bla.c -o bla.o
    +	$(CC) bla.o $< \
    +	    -o bla.exe
    +	@echo "hello"
    +
    diff --git a/autotests/html/basic.markdown.html b/autotests/html/basic.markdown.html new file mode 100644 index 0000000..8ee1f19 --- /dev/null +++ b/autotests/html/basic.markdown.html @@ -0,0 +1,13 @@ + + + +basic.markdown + +
    +normal
    +
    +* item1
    +still part of item
    +
    +normal text again
    +
    diff --git a/autotests/html/basic.xml.html b/autotests/html/basic.xml.html new file mode 100644 index 0000000..770b081 --- /dev/null +++ b/autotests/html/basic.xml.html @@ -0,0 +1,11 @@ + + + +basic.xml + +
    +<?xml version="1.0" encoding="UTF-8"?>
    +<element attr1="a1">
    +    <sub-element/>
    +</element>
    +
    diff --git a/autotests/html/complex.xml.html b/autotests/html/complex.xml.html new file mode 100644 index 0000000..117029d --- /dev/null +++ b/autotests/html/complex.xml.html @@ -0,0 +1,20 @@ + + + +complex.xml + +
    +<?xml version="1.0" encoding="UTF-8"?>
    +<!DOCTYPE language SYSTEM "language.dtd"
    +[
    +    <!-- comment line 1
    +         comment line 2 -->
    +    <!ENTITY name    "(?![0-9])[\w_:][\w.:_-]*">
    +    <!ENTITY entref  "&amp;(#[0-9]+|#[xX][0-9A-Fa-f]+|&name;);">
    +]>
    +<element attr1="a1" attr2="2.03" attr3="&entity;">
    +    <sub-element/>
    +</element>
    +
    +<wrong<very wrong>>
    +
    diff --git a/autotests/html/cube.obj.html b/autotests/html/cube.obj.html new file mode 100644 index 0000000..6ecd1df --- /dev/null +++ b/autotests/html/cube.obj.html @@ -0,0 +1,40 @@ + + + +cube.obj + +
    +# cube.obj
    +#
    +
    +g cube
    +
    +v  0.0  0.0  0.0
    +v  0.0  0.0  1.0
    +v  0.0  1.0  0.0
    +v  0.0  1.0  1.0
    +v  1.0  0.0  0.0
    +v  1.0  0.0  1.0
    +v  1.0  1.0  0.0
    +v  1.0  1.0  1.0
    +
    +vn  0.0  0.0  1.0
    +vn  0.0  0.0 -1.0
    +vn  0.0  1.0  0.0
    +vn  0.0 -1.0  0.0
    +vn  1.0  0.0  0.0
    +vn -1.0  0.0  0.0
    +
    +f  1//2  7//2  5//2
    +f  1//2  3//2  7//2
    +f  1//6  4//6  3//6
    +f  1//6  2//6  4//6
    +f  3//3  8//3  7//3
    +f  3//3  4//3  8//3
    +f  5//5  7//5  8//5
    +f  5//5  8//5  6//5
    +f  1//4  5//4  6//4
    +f  1//4  6//4  2//4
    +f  2//1  6//1  8//1
    +f  2//1  8//1  4//1
    +
    diff --git a/autotests/html/cube.ply.html b/autotests/html/cube.ply.html new file mode 100644 index 0000000..39d9102 --- /dev/null +++ b/autotests/html/cube.ply.html @@ -0,0 +1,33 @@ + + + +cube.ply + +
    +error before header
    +
    +ply
    +format ascii 1.0
    +comment TODO this is a comment
    +element vertex 8
    +property float x
    +property float y
    +property float z
    +element face 6
    +property list uint int vertex_indices
    +end_header
    +-1 -1 -1
    +1 -1 -1
    +1 1 -1
    +-1 1 -1
    +-1 -1 1
    +1 -1 1
    +1 1 1
    +-1 1 1
    +4 0 1 2 3
    +4 5 4 7 6
    +4 6 2 1 5
    +4 3 7 4 0
    +4 7 3 2 6
    +4 5 1 0 4
    +
    diff --git a/autotests/html/cube.stl.html b/autotests/html/cube.stl.html new file mode 100644 index 0000000..0a23eab --- /dev/null +++ b/autotests/html/cube.stl.html @@ -0,0 +1,37 @@ + + + +cube.stl + +
    +solid cube_corner
    +    facet normal 0.0 -1.0 0.0
    +        outer loop
    +            vertex 0.0 0.0 0.0
    +            vertex 1.0 0.0 0.0
    +            vertex 0.0 0.0 1.0
    +        endloop
    +    endfacet
    +    facet normal 0.0 0.0 -1.0
    +        outer loop
    +            vertex 0.0 0.0 0.0
    +            vertex 0.0 1.0 0.0
    +            vertex 1.0 0.0 0.0
    +        endloop
    +    endfacet
    +    facet normal -1.0 0.0 0.0
    +        outer loop
    +            vertex 0.0 0.0 0.0
    +            vertex 0.0 0.0 1.0
    +            vertex 0.0 1.0 0.0
    +        endloop
    +    endfacet
    +    facet normal 0.577 0.577 0.577
    +        outer loop
    +            vertex 1.0 0.0 0.0
    +            vertex 0.0 1.0 0.0
    +            vertex 0.0 0.0 1.0
    +        endloop
    +    endfacet
    +endsolid
    +
    diff --git a/autotests/html/example.rmd.html b/autotests/html/example.rmd.html new file mode 100644 index 0000000..9d7b639 --- /dev/null +++ b/autotests/html/example.rmd.html @@ -0,0 +1,46 @@ + + + +example.rmd + +
    +---
    +title: "test"
    +author: "me"
    +date: "07.10.2014"
    +output: html_document
    +---
    +
    +This is a simple test document. It shows syntax highlighting switches between YAML (above), R blocks
    +```{r, echo=FALSE}
    +for (i in 1:10) {
    +  if(i>=10) print(i)
    +}
    +# two blank lines below
    +
    +sessionInfo()
    +```
    +
    +LaTeX equations,
    +$$
    +h_{i}(t \mid q,C) = h_{0}(t) e^{\beta_{1}quality_{i} + \beta_{2}C_{iq}}
    +$$
    +
    +and Markdown. A [link](http://example.com) in Markdown.
    +
    +Inline `r y <- 5 + x - sin(3)` R code.
    +Inline `y <- 5 + x - sin(3)` code.
    +
    +
    + Heading
    + =======
    + 
    + Sub-heading
    + -----------
    + A list of editors:
    +   * kate
    +   * vim
    +   * emacs
    +
    +*italic*, **bold**, `monospace`
    +
    diff --git a/autotests/html/firstNonSpace.c.html b/autotests/html/firstNonSpace.c.html new file mode 100644 index 0000000..55e02dd --- /dev/null +++ b/autotests/html/firstNonSpace.c.html @@ -0,0 +1,14 @@ + + + +firstNonSpace.c + +
    +#define 1
    + #define 2
    +  #define 3
    +   #define 4
    +    #define 5
    +	#define tab
    +
    +
    diff --git a/autotests/html/folding.cpp.html b/autotests/html/folding.cpp.html new file mode 100644 index 0000000..d20112c --- /dev/null +++ b/autotests/html/folding.cpp.html @@ -0,0 +1,22 @@ + + + +folding.cpp + +
    +/**
    + * multi-line comment
    + */
    +
    +/* comment */
    +{ { } {
    +//BEGIN
    +}
    +//END
    +}
    +
    +#if 0
    +#elif 1
    +#else
    +#endif
    +
    diff --git a/autotests/html/git-rebase.html b/autotests/html/git-rebase.html new file mode 100644 index 0000000..17d6da9 --- /dev/null +++ b/autotests/html/git-rebase.html @@ -0,0 +1,39 @@ + + + +git-rebase + +
    +pick 318aceb Add test for Makefile highlighting
    +p 4c7182a Add first batch of test files resurrected from Kate 4.6
    +r 6f7d8a7 Sync xml files with KTextEditor
    +reword 8f0dbdc Add another batch of resurrected tests from Kate 4.6
    +e 828de45 Add some more resurrected tests from Kate 4.6
    +edit 6aa6264 Add simple coverage information for syntax definition tests
    +s 63df253 Add more syntax highlighting tests from Kate 4.6
    +squash 3e7771f Add three more tests recovered from Kate 4.6
    +f 5c7fd91 Add Kate 4.6 ASP syntax test
    +fixup 7a777ff Implement case-sensitive overrides for keyword rules
    +exec 2b16665 Implement dynamic DetectChar rules
    +drop dd808dc Quote captured strings we replace in regular expressions
    +x 0b703a3 Add a few more tests from the Kate 4.6 test suite
    +
    +# Rebase a27a854..0b703a3 onto a27a854 (13 command(s))
    +#
    +# Commands:
    +# p, pick = use commit
    +# r, reword = use commit, but edit the commit message
    +# e, edit = use commit, but stop for amending
    +# s, squash = use commit, but meld into previous commit
    +# f, fixup = like "squash", but discard this commit's log message
    +# x, exec = run command (the rest of the line) using shell
    +# d, drop = remove commit
    +#
    +# These lines can be re-ordered; they are executed from top to bottom.
    +#
    +# If you remove a line here THAT COMMIT WILL BE LOST.
    +#
    +# However, if you remove everything, the rebase will be aborted.
    +#
    +# Note that empty commits are commented out
    +
    diff --git a/autotests/html/hello.exs.html b/autotests/html/hello.exs.html new file mode 100644 index 0000000..43d76a5 --- /dev/null +++ b/autotests/html/hello.exs.html @@ -0,0 +1,18 @@ + + + +hello.exs + +
    +parent = self()
    +
    +# Spawns an Elixir process (not an operating system one!)
    +spawn_link(fn ->
    +  send parent, {:msg, "hello world"}
    +end)
    +
    +# Block until the message is received
    +receive do
    +  {:msg, contents} -> IO.puts contents
    +end
    +
    diff --git a/autotests/html/highlight.ahdl.html b/autotests/html/highlight.ahdl.html new file mode 100644 index 0000000..b833298 --- /dev/null +++ b/autotests/html/highlight.ahdl.html @@ -0,0 +1,50 @@ + + + +highlight.ahdl + +
    +-- Test file for kate's syntax highlighting
    +Title "Test file";
    +
    +-- BEGIN region (a region marker region) :)
    +
    +% multiline comment
    +goes on here %
    +
    +-- END
    +
    +FUNCTION FCT (Clk, Key) RETURNS (pulse);
    +
    +SUBDESIGN CDCLOCK2
    +(
    +in           : INPUT;  -- go in
    +out[3..0]    : OUTPUT; -- come out
    +)
    +
    +VARIABLE
    +start        : soft;
    +usec[3..0]   : node;
    +
    +BEGIN
    +
    +in = FCT(clock, some_key);  -- senseless code
    +
    +-- comment
    +blubb = (blobb[] == H"3ff"); 
    +
    +IF in THEN asdf
    +-- folde me
    +END IF; 
    +
    +TABLE
    +-- missing code
    +END TABLE
    +
    +
    +END;
    +
    +-- hex, octal, binary
    +H"0" => B"1000000";
    +O"01234567";
    +
    diff --git a/autotests/html/highlight.asm-avr.html b/autotests/html/highlight.asm-avr.html new file mode 100644 index 0000000..867894e --- /dev/null +++ b/autotests/html/highlight.asm-avr.html @@ -0,0 +1,82 @@ + + + +highlight.asm-avr + +
    +;********************************************************************
    +;* LED flasher: LED will flash with a X on/off ratio at PD6
    +;*
    +;* NOTE: delay depends in the value of X, 1 is fast, 255 is slow
    +;*
    +;* No copyright ©1998 RES® * FREEWARE *
    +;*
    +;* NOTE: Connect a low current LED with a 1k resistor in serie from 
    +;*	 Vdd to pin 11 of the MCU. (Or a normal LED with a 330ohm)
    +;*									   
    +;* RES® can be reached by email: digitalaudio@mail.com		   
    +;* or visit the website: http://home.wanadoo.nl/electro1/avr
    +;*
    +;* Version           :1.0 					   
    +;* Date		     :12/26/98
    +;* Author	     :Rob's ElectroSoft®
    +;* Target MCU        :AT90S1200-12PI@4MHz					   
    +;********************************************************************
    +
    +.include "1200def.inc"
    +
    +	rjmp	RESET		;reset handle
    +
    +
    +;* Long delay 
    +
    +;* Register variables
    +
    +	.def  T1      = r1
    +	.def  T2      = r2
    +	.def  temp    = r19
    +
    +;* Code
    +	    
    +longDelay:      
    +	clr   T1		;T1 used as delay 2nd count
    +	clr   T2		;T2 used as delay 3d count
    +delay_1:    
    +	dec   T2
    +	brne  delay_1            
    +	dec   T1
    +	brne  delay_1           
    +	dec   temp		;temp must be preset as 
    +	brne  delay_1		; delay master count
    +	ret                     
    +
    +
    +;* Resets the data direction register D
    +
    +;* Defines
    +
    +	.equ  led   = 6		;LED at PD6
    +
    +;* Code
    +
    +RESET:
    +	sbi   DDRD, led		;connect LED to PORTD pin 6
    +	    
    +
    +;* Main program
    +
    +;* This part will let the LED go on and off by X
    +
    +;* Register variables
    +
    +	.equ  X   =  10 	;enter delaytime X
    +
    +flash: 
    +	sbi   PORTD, led	;LED on
    +	ldi   temp, X		;X sec delay           
    +	rcall longDelay             
    +	cbi   PORTD, led	;LED off            
    +	ldi   temp, X		;X sec delay
    +	rcall longDelay
    +	rjmp  flash		;another run
    +
    diff --git a/autotests/html/highlight.asm-nasm.html b/autotests/html/highlight.asm-nasm.html new file mode 100644 index 0000000..6ae4028 --- /dev/null +++ b/autotests/html/highlight.asm-nasm.html @@ -0,0 +1,34 @@ + + + +highlight.asm-nasm + +
    +; Example file for nasm.xml kate syntax file
    +; compile with `nasm example.asm -f elf -o example.o`
    +; and link with 'gcc example.o -o example`
    +; Public domain
    +; kate: hl Intel x86 (NASM);
    +
    +section .data
    +
    +hello dd 'Hello World', 0x0A, 0h
    +printf_param dd '%s', 0q
    +
    +section .text
    +
    +extern printf
    +
    +global main
    +main:
    +	push ebp
    +	mov ebp, esp
    +	
    +	push hello
    +	push printf_param
    +	call printf
    +	
    +	mov eax, 0b
    +	leave
    +	ret
    +
    diff --git a/autotests/html/highlight.asp.html b/autotests/html/highlight.asp.html new file mode 100644 index 0000000..85a1bba --- /dev/null +++ b/autotests/html/highlight.asp.html @@ -0,0 +1,65 @@ + + + +highlight.asp + +
    +<% 'kate: hl ASP;
    +if ( instr(request.servervariables("PATH_INFO"),"login.asp") <= 0 and instr(request.servervariables("PATH_INFO"),"inset") <= 0 and instr(request.servervariables("PATH_INFO"),"Data") <= 0 and instr(request.servervariables("PATH_INFO"),"dropDown") <= 0 ) then
    +	Session("originalRequestedPage") = Request.ServerVariables("PATH_INFO") & "?" & Request.ServerVariables("QUERY_STRING")
    +end if
    +
    +function countRecords( rsToCount )
    +	numRecs = 0
    +
    +	do until rsToCount.eof
    +		numRecs = numRecs + 1
    +
    +		rsToCount.movenext
    +	loop
    +
    +	rsToCount.close ' just to make sure nobody
    +		' tries to operate on the recordset,
    +		' which has already reached eof
    +
    +	countRecords = numRecs
    +end function
    +
    +function unique( rs, sortColumn ) ' return unique instances of text in sortColumn within rs
    +	dim sorted()
    +
    +	redim sorted(1)
    +	dim i
    +	i = 0
    +	do until rs.eof
    +		if (not find( rs(sortColumn), sorted )) then
    +			redim preserve sorted(i+1)
    +			sorted(i) = rs(sortColumn)
    +		 	i = i + 1
    +		end if
    +		rs.MoveNext
    +	loop
    +
    +	redim preserve sorted(i-1) ' the function will add an extra blank entry to the array
    +
    +	rs.Close 	' close the recordset - we'll be using it again - and reset i - well be using it again, too
    +
    +	unique = sorted
    +end function
    +
    +sub testSub( variable ) ' do nothing impressive...
    +	dim newVar
    +
    +	newVar = variable
    +
    +	if ( variable = true )
    +		response.end
    +	else %>
    +
    +<p>We are writing text.</p>
    +<p class="stuff"><%=newVar%></p>
    +<p>We have written text and outputted a variable.</p>
    +
    +<% 	end if
    +end sub %>
    +
    diff --git a/autotests/html/highlight.awk.html b/autotests/html/highlight.awk.html new file mode 100644 index 0000000..594a2d6 --- /dev/null +++ b/autotests/html/highlight.awk.html @@ -0,0 +1,35 @@ + + + +highlight.awk + +
    +#!/usr
    +# AWK hl test
    +
    +# BEGIN and END are also matched as patterns
    +BEGIN {
    +	p = 0;
    +}
    +
    +/some pattern/ {
    +	p++;
    +}
    +
    +# / inside brackets is not considered end of expression
    +# a loose division operator (/) is not mismatched as a pattern.
    +$1 =~ /[^abc/]def/ || b == 3 / 5 {
    +
    +	gsub ( FILENAME );
    +
    +}
    +
    +# TODO and FIXME also work in comments in Awk.
    +
    +# Also backslash in patterns works.
    +/\/usr\/bin\/awk/ { print "This is me"; }
    +
    +END {
    +	print p;
    +}
    +
    diff --git a/autotests/html/highlight.bib.html b/autotests/html/highlight.bib.html new file mode 100644 index 0000000..48cc672 --- /dev/null +++ b/autotests/html/highlight.bib.html @@ -0,0 +1,38 @@ + + + +highlight.bib + +
    +% test file for kate's bibtex syntax highlighting
    +
    +@Article{artikel,
    +author = {Me},
    +title = {Something},
    +journal = {JHEP},
    +year = {2003},
    +}
    +
    +@Book
    +
    +{
    +
    +boek,
    +author = "Someone",
    +title = "Something",
    +journal = "Nucl. Phys. B",
    +year = "2003",
    +}
    +
    +This is ignored by BibTeX, no special highlighting
    +%This is not a comment, it is just ignored (thanks to the people in #latex) :)
    +
    +@string{test="lange string die ik niet vaak opnieuw wil intikken"}
    +
    +@PhdThesis{thesis,
    +author = {Me},
    +title = {Dunno},
    +school = {ITFA},
    +year = {2005, hopefully},
    +}
    +
    diff --git a/autotests/html/highlight.cmake.html b/autotests/html/highlight.cmake.html new file mode 100644 index 0000000..3d69f8b --- /dev/null +++ b/autotests/html/highlight.cmake.html @@ -0,0 +1,56 @@ + + + +highlight.cmake + +
    +#this CMakeLists.txt doesn't do anything useful, but it shoudl demonstrate the cmake syntax highlighting
    +#Alexander Neundorf <neundorf@kde.org>
    +
    +#ok this is a comment
    +#and another line
    +#a built-in command, it's bold black
    +ADD_DEFINITIONS(-Wall -Wctor-dtor-privacy -Woverloaded-virtual -Wno-long-long -pipe -fno-builtin -fno-exceptions)
    +
    +#and another function
    +INCLUDE_DIRECTORIES(
    +#comments are also highlighted inside function parameters
    +#variables are Qt::blue
    +${CMAKE_CURRENT_SOURCE_DIR}/../../lib/qt4/include/Qt  
    +)
    +
    +# BEGIN defining a macro
    +MACRO(ECOS_ADD_EXECUTABLE _exe_NAME )
    +
    +#special parameters are italic, see the STATIC in the next line
    +ADD_LIBRARY(${_exe_NAME} STATIC ${ARGN})
    +#but not in the following line ?
    +  ADD_LIBRARY(${_exe_NAME} STATIC ${ARGN})
    +# it seems the kate highlighting file could need some love, Alex
    +
    +
    +#another command with a bunch of variables and special parameters   
    +   ADD_CUSTOM_COMMAND(
    +      TARGET ${_exe_NAME} 
    +      PRE_LINK 
    +      COMMAND ${CMAKE_C_COMPILER} 
    +      ARGS -o ${_exe_NAME} 
    +$\(${_exe_NAME}_SRC_OBJS\) -nostdlib  -nostartfiles -Lecos/install/lib -Ttarget.ld
    +   )
    +
    +#add the created files to the make_clean_files
    +   SET(ECOS_ADD_MAKE_CLEAN_FILES ${ECOS_ADD_MAKE_CLEAN_FILES};${_exe_NAME};)
    +#and another command...   
    +   SET_DIRECTORY_PROPERTIES( 
    +      PROPERTIES
    +      ADDITIONAL_MAKE_CLEAN_FILES "${ECOS_ADD_MAKE_CLEAN_FILES}"
    +   )
    +ENDMACRO(ECOS_ADD_EXECUTABLE)
    +# END of macro
    +
    +#calling a self-defined function, variables are also Qt::blue here
    +ECOS_ADD_EXECUTABLE(${PROJECT_NAME} ${the_sources} ${qt4_moc_SRCS})
    +
    +
    +
    +
    diff --git a/autotests/html/highlight.css.html b/autotests/html/highlight.css.html new file mode 100644 index 0000000..7dcb4ab --- /dev/null +++ b/autotests/html/highlight.css.html @@ -0,0 +1,56 @@ + + + +highlight.css + +
    +/**
    + * This is a pseudo CSS file to test Kate's CSS syntax highlighting.
    + */
    +
    +@import url("othersheet.css") screen, tv;
    +
    +body {
    +	font-size: 15pt;
    +	font-family: Verdana, Helvetica, "Bitstream Vera Sans", sans-serif;
    +	margin-top: 0px;			/* yet another comment */
    +	margin-bottom: 0px;
    +	// this is no comment, it's just broken!
    +	margin-left: 0px;
    +	margin-right: 0px;
    +}
    +
    +.something
    +{
    +	margin-right: 0px;
    +	color: #cdd;
    +	color: #AAFE04;
    +	color: rgb(10%,30%,43%);
    +	background: maroon;
    +}
    +
    +a:hover {
    +}
    +
    +#header,
    +p.intro:first-letter,
    +p:lang(nl),
    +img[align="right"]
    +{
    +	border: 1px solid Qt::red !important;
    +	-moz-border-radius: 15px; /* unknown properties render italic */
    +}
    +
    +@media print {
    +
    +	#header
    +	{
    +		display: none;
    +	}
    +
    +}
    +
    +/*
    +TODO: add more tests, e.g. media
    +*/
    +
    diff --git a/autotests/html/highlight.d.html b/autotests/html/highlight.d.html new file mode 100644 index 0000000..5e97d7b --- /dev/null +++ b/autotests/html/highlight.d.html @@ -0,0 +1,202 @@ + + + +highlight.d + +
    +/********
    +* Highlight testing module.
    +*
    +* Do not attempt to run this!
    +***********/
    +module highlighttest;
    +import X = null;
    +
    +/++ Pragma directives. DDoc + DDoc embedded items. Special Tokens.
    ++
    ++ ---
    ++ // comment
    ++ #line 12 "hightlighttest.d"	/* block comment */
    ++ #line __LINE__ __FILE__	/++ embedded block comment +/
    ++
    ++ pragma /* */ (msg, "what?");
    ++ pragma(/++ +/ lib, "insane.a");
    ++ pragma(D_Custom_Extension, "custom data");
    ++ ---
    ++/
    +
    +/// version condition
    +version = X;
    +version (X) ;
    +version(linux) {}
    +
    +/// linkage
    +extern
    +    (C) {}
    +extern :
    +;
    +extern (Windows) {}
    +
    +/// alias & typedef
    +alias int.min minint;
    +typedef int myint;
    +
    +int main(char[][] args) {
    +    /// statements
    +    if (1) {}
    +    else {}
    +    with (N) {x = B}
    +    
    +    /// attributes
    +    auto x = 1;
    +    static if (true) {}
    +    void (in X, out Y) {}	// NOTE: using in like this is rare, more common to use as an expression and no way to tell apart?
    +    
    +    /// deprecated
    +    deprecated void fct ();
    +    
    +    /// types
    +    void a;
    +    ushort u;
    +    int[uint] AA;
    +    class C;
    +    enum N : int { A = 5, B }
    +    typeof(u) u2;
    +    
    +    /// expressions
    +    x = cast(int) 55;
    +    void* p = null;
    +    p = cast(void*) new int;
    +    x = 1 in AA;	// NOTE: a THIRD use of in. How to detect??
    +    assert (true);
    +        
    +    /// libsymbols
    +    string s = "";
    +    throw new Exception;
    +    TypeInfo ti = typeid(int);
    +    
    +    /// tests
    +    debug {}
    +    debug (2) {}
    +    debug (DSymb) {}
    +    unittest {}
    +    
    +    /// scope (as attribute and as statement)
    +    scope struct S;
    +    scope (exit) {}
    +    scope 
    +     (success) {}	// NOTE: rules cannot match across new-lines
    +    scope (failure) {}
    +    
    +    /// Properties
    +    x = int.min;
    +    s = (5-3).stringof;
    +    
    +    /// strings
    +    s = r"raw string";
    +    s = x"00FF";
    +    s = \n \a;
    +    s = \u1234;
    +    s = \U12345678;
    +    s = \&amp; ;
    +    char c = 'a';
    +    s = "abc 012 \" \n \x12 \u1234 \U12345678";
    +    s = `BQString '"`;
    +    
    +    /// region markers
    +    //BEGIN x
    +    //END x
    +    
    +    /// DDoc
    +    /*******
    +    * DDoc
    +    *
    +    * Section:
    +    * New section.
    +    * $(I italic)
    +    *******/
    +    /+++++++
    +    + DDoc
    +    + /+
    +    + +/
    +    +++++++/
    +    
    +    // comments
    +    // FIXME NOTE
    +    /* comment */
    +    /+ comment /+ nested comment +/ +/
    +    
    +    /// brace folding
    +    {
    +    }
    +    
    +    /** normal text
    +    * ---
    +    * .x;
    +    * ..
    +    * ...
    +    * ....
    +    * .....
    +    * _._
    +    * _e1
    +    * ---
    +    */
    +    
    +    /// float and int literals
    +    int i;
    +    real r;
    +    ireal ir;
    +    r = .0;
    +    r = 0f;
    +    ir = 0e0i;
    +    ir = 0.fi;
    +    r = 0.0e0;
    +    r = 0xF.Fp0;
    +    r = 0x_._p0_;
    +    i = 5;
    +    i = -1;
    +    i = 0b10;
    +    i = 0070;
    +    i = 00;
    +    i = 0xF0;
    +    
    +    /// ranges
    +    int[] A;
    +    i = A[1];
    +    A = A[0..$];
    +    A = A[0..0];
    +    A = A[0..length];
    +    
    +    /// labels
    +    label:
    +    goto label;
    +    
    +    /// function, delegate
    +    creal function () fp = function creal() { return 0f+0fi; };
    +    void delegate (in int i, lazy int b) dg = delegate void (int, int) {}
    +    
    +    /// in, out, body
    +    // NOTE: highlighting in & out as statements here could be difficult
    +    float F ()
    +    in {}
    +    out (result) {}
    +    body {}
    +    
    +    /// try, catch, finally
    +    try {
    +        throw new Exception("oh no... ");
    +    } catch (Exception e) {
    +    } finally {
    +    }
    +    
    +    /// mixin
    +    mixin("return false;").stringof;
    +    
    +    /// templates
    +    macro; // what does this do?
    +    template Tp (T) {
    +        Tp t;
    +    }
    +    Tp!(int) y;
    +}
    +
    diff --git a/autotests/html/highlight.do.html b/autotests/html/highlight.do.html new file mode 100644 index 0000000..40ac67d --- /dev/null +++ b/autotests/html/highlight.do.html @@ -0,0 +1,96 @@ + + + +highlight.do + +
    +/* Test file for kate's stata syntax highlighting
    +*/
    +*! version 1.2.0 2mar2003 E. Leuven
    +program define spellsplit
    +        version 7
    +        syntax [anything], spell(varlist min=2 max=2) [ by(varlist)]
    +        tokenize `spell'
    +        local date0 `1'
    +        local date1 `2'
    +        local f0 : format `date0'
    +        local f1 : format `date1'
    +
    +        /* set default statistic */
    +        local current "mean"
    +
    +        gettoken left anything : anything, match(prns)
    +        while "`left'"!="" {
    +                if "`prns'"!="" {
    +                        if !inlist("`left'","mean","sum") {
    +                                di as error "Statistic `left' not supported"
    +                                exit 198
    +                        }
    +                        local current "`left'"
    +                }
    +                else {
    +                        local `current'vars  ``current'vars' `left'
    +                }
    +                gettoken left anything : anything, match(prns)
    +        }
    +        if ("`meanvars'"!="") {
    +                confirm var `meanvars'
    +                unab meanvars : `meanvars'
    +        }
    +        if ("`sumvars'"!="") {
    +                confirm var `sumvars'
    +                unab sumvars : `sumvars'
    +        }
    +
    +        quietly {
    +                g _count = 1
    +                local xvars `meanvars' `sumvars' _count
    +
    +                /* create dummy by-var if no by option is specified */
    +                if "`by'"=="" {
    +                        tempvar by
    +                        g byte `by' = 1
    +                }
    +                tempvar `xvars' `by'
    +
    +                /* create negative for subtraction when spell ends */
    +                cap foreach v of varlist `xvars' {
    +                        g double ``v'' = -`v'
    +                        local txvars `txvars' ``v''
    +                }
    +                cap foreach v of varlist `by' {
    +                        g double ``v'' = `v'
    +                        local txvars `txvars' ``v''
    +                }
    +
    +                stack `date0' `xvars' `by' `date1' `txvars', into(`date0' `xvars' `by') clear
    +
    +                /* calculate totals per date */
    +                cap foreach v of varlist `xvars' {
    +                        egen double ``v'' = sum(`v'), by(`by' `date0')
    +                }
    +
    +                /* unique dates only */
    +                by `by' `date0', sort: keep if _n==1
    +
    +                /* calculate totals (+ when spell starts - when ends) */
    +                sort `by'
    +                cap foreach v of varlist `xvars' {
    +                        by `by': replace `v' = sum(``v'')
    +                }
    +                by `by': g `date1' = `date0'[_n + 1]
    +
    +                drop if `date0'>`date1'
    +                drop _stack
    +                drop if _count==0
    +                order `by' `date0' `date1' `xvars'
    +                format `date0' `f0'
    +                format `date1' `f1'
    +
    +                cap for var `meanvars': replace X = X/_count
    +
    +                compress
    +        }
    +
    +end
    +
    diff --git a/autotests/html/highlight.dox.html b/autotests/html/highlight.dox.html new file mode 100644 index 0000000..7eeae66 --- /dev/null +++ b/autotests/html/highlight.dox.html @@ -0,0 +1,234 @@ + + + +highlight.dox + +
    +This is a pseudo doxygen file to test Kate's doxyge syntax highlighting.
    +
    +Normal text, no HL.
    +===================
    +a multiline comment may begin with a /*! */, too. That should work,
    +because it is the same "entrance rule".
    +
    +popping tests:
    +/** multiline */ end of doxygen HL mode
    +/*! multiline */ end of doxygen HL mode
    +//! singleline, where */ should be ignored! still doxygen HL mode
    +/// singleline, where */ should be ignored! still doxygen HL mode
    +///< singleline, where */ should be ignored! still doxygen HL mode
    +begin and end immediately:
    +/********/ actually no doxygen comment - used for "info boxes" :)
    +/**/ <-- it really works --- end of doxygen HL mode
    +/*!*/ end of doxygen HL mode
    +
    +<tag> <normal comment HL>
    +/** \code rest of line is normal comment HL */ end of doxygen HL mode
    +/** \code rest of line is normal comment HL
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +<tag> <word> <normal comment HL>
    +/** \file aword rest of line is normal comment HL */ end of doxygen HL mode
    +/** \file */aword <-- pop! no doxygen HL mode
    +/** \file aword rest of line is normal comment HL
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +<tag> <rest of line is string>
    +/** \brief A short description */ end of doxygen HL mode
    +/** \brief */A <-- pop! end of doxygen HL mode
    +/** \brief A short description 
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +<tag> <word> <rest of line is string>
    +/** \page aword rest of line is string */ end of doxygen HL mode
    +/** \page */aword <-- pop! end of doxygen HL mode
    +/** \page aword rest of line is string 
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +<tag> <word> <word> <normal comment HL>
    +/** \image aword aword rest of line is normal HL */ end of doxygen HL mode
    +/** \image aword */aword <-- pop! end of doxygen HL mode
    +/** \image */aword aword <-- pop! end of doxygen HL mode
    +/** \image aword aword rest of line is normal HL
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +Tests for HTML tags in doxygen HL mode:
    +=======================================
    +/** <a href="blubb" href='blubb'> */ end of doxygen HL mode
    +/** <a href="blubb" href='blubb'*/> end of doxygen HL mode
    +/** <a href="blubb" href='blubb*/'> end of doxygen HL mode
    +/** <a href="blubb" href='blub*/b'> end of doxygen HL mode
    +/** <a href="blubb" href='b*/lubb'> end of doxygen HL mode
    +/** <a href="blubb" href='*/blubb'> end of doxygen HL mode
    +/** <a href="blubb" href=*/'blubb'> end of doxygen HL mode
    +/** <a href="blubb" href*/='blubb'> end of doxygen HL mode
    +/** <a href="blubb" hre*/f='blubb'> end of doxygen HL mode
    +/** <a href="blubb" */href='blubb'> end of doxygen HL mode
    +/** <a href="blubb"> */ end of doxygen HL mode
    +/** <a href="blubb"*/> end of doxygen HL mode
    +/** <a href="blubb*/"> end of doxygen HL mode
    +/** <a href="blub*/b"> end of doxygen HL mode
    +/** <a href="*/blubb"> end of doxygen HL mode
    +/** <a href=*/"blubb"> end of doxygen HL mode
    +/** <a href*/="blubb"> end of doxygen HL mode
    +/** <a h*/ref="blubb"> end of doxygen HL mode
    +/** <a */href="blubb"> end of doxygen HL mode
    +/** <a*/ href="blubb"> end of doxygen HL mode
    +/** <*/a href="blubb"> end of doxygen HL mode
    +
    +//! <a href="blubb" href='blubb'> */ stay in doygen HL mode
    +//! <a href="blubb" href='blubb'*/> stay in doygen HL mode
    +//! <a href="blubb" href='blubb*/'> stay in doygen HL mode
    +//! <a href="blubb" href='blu*/bb'> stay in doygen HL mode
    +//! <a href="blubb" href='*/blubb'> stay in doygen HL mode
    +//! <a href="blubb" href=*/'blubb'> stay in doygen HL mode
    +//! <a href="blubb"> */ stay in doygen HL mode
    +//! <a href="blubb"*/> stay in doygen HL mode
    +//! <a href="blubb*/"> stay in doygen HL mode
    +//! <a href="blub*/b"> stay in doygen HL mode
    +//! <a href="*/blubb"> stay in doygen HL mode
    +//! <a href=*/"blubb"> stay in doygen HL mode
    +//! <a href*/="blubb"> stay in doygen HL mode
    +//! <a h*/ref="blubb"> stay in doygen HL mode
    +//! <a */href="blubb"> stay in doygen HL mode
    +//! <a*/ href="blubb"> stay in doygen HL mode
    +//! <*/a href="blubb">  stay in doygen HL mode
    +//! <a href="blubb">  stay in doygen HL <mode
    +here should be normal HL mode (no doxygen!)
    +
    +Tests for HTML tags in doxygen HL mode with tags:
    +=================================================
    +<tag> <normal comment HL>
    +/** \code rest <a href="blubb"> of </a href='blubb'> line is normal comment HL */ end of doxygen HL mode
    +/** \code rest <a href="blubb"> of </a href='blubb'*/> end of doxygen HL mode
    +/** \code rest <a href="blubb"> of </a href='blubb*/'> end of doxygen HL mode
    +/** \code rest <a href="blubb"> of </a href='*/blubb'> end of doxygen HL mode
    +/** \code rest <a href="blubb"> of </a href=*/'blubb'> end of doxygen HL mode
    +/** \code rest <a href="blubb*/"> of </a href=*/'blubb'> end of doxygen HL mode
    +/** \code rest <a href=*/"blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \code rest <a h*/ref="blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \code rest <*/a href="blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \code rest of line is normal comment HL
    + * comment HL mode <html> text </html>
    + */ end of doxygen HL mode
    +
    +<tag> <word> <normal comment HL>
    +/** \file awo<html_should_be_ignored_here>rd rest of line is normal comment HL */ end of doxygen HL mode
    +/** \file awo<html_should_be_ignored_here>*/rd end of doxygen HL mode
    +/** \file awo<html_should_be_i*/gnored_here>rd end of doxygen HL mode
    +/** \file awo<*/html_should_be_ignored_here>rd end of doxygen HL mode
    +/** \file a*/wo<html_should_be_ignored_here>rd end of doxygen HL mode
    +/** \file aword rest of line is normal co<code>mment HL
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +<tag> <rest of line is string>
    +/** \brief A short <a href="blubb"> of </a href='blubb'> description */ end of doxygen HL mode
    +/** \brief A short <a href="blubb"> of </a href='blubb'*/> end of doxygen HL mode
    +/** \brief A short <a href="blubb"> of </a href='*/blubb'> end of doxygen HL mode
    +/** \brief A short <a href="blubb"> of </a href=*/'blubb'> end of doxygen HL mode
    +/** \brief A short <a href="blubb"> of </a href*/='blubb'> end of doxygen HL mode
    +/** \brief A short <a href="blubb"> of </a */href='blubb'> end of doxygen HL mode
    +/** \brief A short <a href="blubb"> of <*//a href='blubb'> end of doxygen HL mode
    +/** \brief A short <a href="blubb"*/> of </a href='blubb'> end of doxygen HL mode
    +/** \brief A short <a href="blubb*/"> of </a href='blubb'> end of doxygen HL mode
    +/** \brief A short <a href="*/blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \brief A short <a href=*/"blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \brief A short <a href*/="blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \brief A short <a h*/ref="blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \brief A short <a href="blubb"> of </a href='blubb'> description 
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +<tag> <word> <rest of line is string>
    +/** \page aword A short <a href="blubb"> of </a href='blubb'> description */ end of doxygen HL mode
    +/** \page aword A short <a href="blubb"> of </a href='blubb'*/> end of doxygen HL mode
    +/** \page aword A short <a href="blubb"> of </a href='*/blubb'> end of doxygen HL mode
    +/** \page aword A short <a href="blubb"> of </a href=*/'blubb'> end of doxygen HL mode
    +/** \page aword A short <a href="blubb"> of </a href*/='blubb'> end of doxygen HL mode
    +/** \page aword A short <a href="blubb"> of </a */href='blubb'> end of doxygen HL mode
    +/** \page aword A short <a href="blubb"> of <*//a href='blubb'> end of doxygen HL mode
    +/** \page aword A short <a href="blubb"*/> of </a href='blubb'> end of doxygen HL mode
    +/** \page aword A short <a href="blubb*/"> of </a href='blubb'> end of doxygen HL mode
    +/** \page aword A short <a href="*/blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \page aword A short <a href=*/"blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \page aword A short <a href*/="blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \page aword A short <a h*/ref="blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \page aword A short <*/a href="blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \page aword A shor*/t <a href="blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \page awor*/d A short <a href="blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \page */aword A short <a href="blubb"> of </a href='blubb'> end of doxygen HL mode
    +/** \page aword A short <a href="blubb"> of </a href='blubb'> description 
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +<tag> <word> <word> <rest of line is string>
    +/** \image aword aword rest of line is normal HL */ end of doxygen HL mode
    +/** \image aword aword rest of line is*/ end of doxygen HL mode
    +/** \image aword aword*/ end of doxygen HL mode
    +/** \image aword aw*/ord end of doxygen HL mode
    +/** \image aword */aword end of doxygen HL mode
    +/** \image aword*/ end of doxygen HL mode
    +/** \image awo*/rd end of doxygen HL mode
    +/** \image */aword end of doxygen HL mode
    +/** \ima*/ge end of doxygen HL mode
    +/** \image aword aword rest of line is normal HL
    + * comment HL mode
    + */ end of doxygen HL mode
    + 
    +Some further tests for singlelinecomments (* / should not pop!)
    +===============================================================
    +/// a singlelinecommment blubb blubb  */. stay in doxygen HL mode
    +/// \code a singlelinecommment blubb b*/lubb. stay in doxygen HL mode
    +/// \code*/ a singlelinecommment blubb blubb. stay in doxygen HL mode
    +/// \code a singlelinecommment blubb blubb
    +/// \brief a descriptive text (string) stay in doxygen HL mode
    +/// \brief a descriptive text (string)*/ description should go on here
    +/// \brief a descriptive text */(string) description should go on here
    +/// \brief */a descriptive text (string) description should go on here
    +/// \ref aword a descriptive text (string) */ description should go on here
    +/// \ref aword a descriptive text (str*/ing) description should go on here
    +/// \ref aword a des*/criptive text (string) description should go on here
    +/// \ref aword*/ a descriptive text (string) description should go on here
    +/// \ref aw*/ord a descriptive text (string) description should go on here
    +/// \ref */aword a descriptive text (string) description should go on here
    +
    +HTML comment tests:
    +===================
    +//! \ref word de<!--*/ -->scriptive text (string)
    +normal HL mode.
    +//! \ref w descriptive text (string)
    +/** \ref word de<!--*/ -->scriptive text (string)
    +normal HL mode.
    +/** \ref w <!--
    + * HTML comments
    + * -->
    + * normal doxygen HL mode.
    + */
    +
    +
    +And final tests for a word: a single char:
    +===========================================
    +<tag> <word> <rest of line as string>
    +//! \ref word descriptive text (string)
    +//! \ref w descriptive text (string)
    +
    +<tag> <word> <word> <rest is normal HL>
    +//! \image word1 word2 b descriptive text (string)
    +//! \image a word b descriptive text (string)
    +
    +<tag> <rest of line is string>
    +//! \brief A b c d e description should go on here
    +
    +<tag> <word> <rest of line is normal doxygen HL mode>
    +//! \file word rest of line is normal comment HL
    +//! \file a word rest of line is normal comment HL
    +
    +no doxygen HL mode here.
    +== END OF TESTFILE ==
    +
    diff --git a/autotests/html/highlight.erl.html b/autotests/html/highlight.erl.html new file mode 100644 index 0000000..8424c84 --- /dev/null +++ b/autotests/html/highlight.erl.html @@ -0,0 +1,75 @@ + + + +highlight.erl + +
    +% testing for the erlang syntax highlighter
    +% NOTE alerts work in comments to TODO !
    +
    +% pragmas (show as keywords)
    +-module
    +-export
    +-define
    +-undef
    +-ifdef
    +-ifndef
    +-else
    +-endif
    +-include
    +-include_lib
    +
    +% key words
    +after begin case catch cond  end fun if let of query receive all_true some_true 
    +
    +% operators
    +div rem or xor bor bxor bsl bsr and band not bnot
    ++ - * / == /= =:= =/= < =< > >= ++ -- = ! <-
    +
    +% separators (show as functions)
    +( ) { } [ ] . : | || ; , ? -> #
    +
    +% functions - predefined (part of erlang module) - show as functions
    +abs accept alarm apply atom_to_list binary_to_list binary_to_term check_process_code
    +concat_binary date delete_module disconnect_node element erase exit float float_to_list
    +garbage_collect get get_keys group_leader halt hd integer_to_list is_alive is_atom is_binary
    +is_boolean is_float is_function is_integer is_list is_number is_pid is_port is_process_alive
    +is_record is_reference is_tuple length link list_to_atom list_to_binary list_to_float list_to_integer
    +list_to_pid list_to_tuple load_module loaded localtime make_ref module_loaded node nodes now
    +open_port pid_to_list port_close port_command port_connect port_control ports pre_loaded process_flag
    +process_info processes purge_module put register registered round self setelement size
    +spawn spawn_link spawn_opt split_binary statistics term_to_binary throw time tl trunc tuple_to_list
    +unlink unregister whereis
    +
    +% functions - inferred
    +module:function
    +function()
    +
    +% atoms (show as "char")
    +% begin with underscore, lowercase, contain numbers letters and @ - or anything between ''
    +middle_underscore
    +abc ab4d a@cd8 a@
    +'And this is (\012) an atom \' Atoo' Variable 'atom again' 
    +
    +% variables (begin with capital letter or underscore, contain numbers, letters and @)
    +_leadingUnderscore AbdD@ B45@c
    +
    +% this is a string 
    +"a string sits between \" double quotes" atom "more string"
    +
    +% integers (decimal)
    +1. 234 $A
    +
    +% integers (specified base)
    +2#10101 34#567
    +
    +% float
    +12.23 12.9e-67 12.8E+89 33.34e89
    +
    +% and finally some real code, so we can see what it looks like...
    +-module(codetest).			% everything is in a module
    +-export([fac/1]).		% name and number of arguments - need this to be called outside of the module
    +
    +fac(N) when N > 0  -> N * fac(N-1);
    +fac(N) when N == 0 -> 1.
    +
    diff --git a/autotests/html/highlight.exu.html b/autotests/html/highlight.exu.html new file mode 100644 index 0000000..5631898 --- /dev/null +++ b/autotests/html/highlight.exu.html @@ -0,0 +1,104 @@ + + + +highlight.exu + +
    +-- Test file for Kate's Euphoria syntax highlighting/code folding.
    +-- BEGIN region marker test
    +
    +-- code here
    +
    +-- END region marker test
    +
    +-- The N Queens Problem:
    +-- Place N Queens on an NxN chess board
    +-- such that they don't threaten each other.
    +constant N = 8 -- try some other sizes
    +constant ROW = 1, COLUMN = 2
    +constant TRUE = 1, FALSE = 0
    +type square(sequence x)
    +-- a square on the board
    +    return length(x) = 2
    +end type
    +type row(integer x)
    +-- a row on the board
    +    return x >= 1 and x <= N
    +end type
    +
    +function threat(square q1, square q2)
    +-- do two queens threaten each other?
    +    if q1[COLUMN] = q2[COLUMN] then
    + return TRUE
    +    elsif q1[ROW] - q1[COLUMN] = q2[ROW] - q2[COLUMN] then
    + return TRUE
    +    elsif q1[ROW] + q1[COLUMN] = q2[ROW] + q2[COLUMN] then
    + return TRUE
    +    elsif q1[ROW] = q2[ROW] then
    + return TRUE
    +    else
    + return FALSE
    +    end if
    +end function
    +
    +function conflict(square q, sequence queens)
    +-- Would square p cause a conflict with other queens on board so far?
    +    for i = 1 to length(queens) do
    + if threat(q, queens[i]) then
    +     return TRUE
    + end if
    +    end for
    +    return FALSE
    +end function
    +
    +integer soln
    +soln = 0 -- solution number
    +
    +procedure print_board(sequence queens)
    +-- print a solution, showing the Queens on the board
    +    integer k
    +    position(1, 1)
    +    printf(1, "Solution #%d\n\n  ", soln)
    +    for c = 'a' to 'a' + N - 1 do
    + printf(1, "%2s", c)
    +    end for
    +    puts(1, "\n")
    +    for r = 1 to N do
    + printf(1, "%2d ", r)
    + for c = 1 to N do
    +     if find({r,c}, queens) then
    +  puts(1, "Q ")
    +     else
    +  puts(1, ". ")
    +     end if
    + end for
    + puts(1, "\n")
    +    end for
    +    puts(1, "\nPress Enter. (q to quit) ")
    +    while TRUE do
    + k = get_key()
    + if k = 'q' then
    +     abort(0)
    + elsif k != -1 then
    +     exit
    + end if
    +    end while
    +end procedure
    +
    +procedure place_queen(sequence queens)
    +-- place queens on a NxN chess board
    +-- (recursive procedure)
    +    row r -- only need to consider one row for each queen
    +    if length(queens) = N then
    + soln += 1
    + print_board(queens)
    + return
    +    end if
    +    r = length(queens)+1
    +    for c = 1 to N do
    + if not conflict({r,c}, queens) then
    +     place_queen(append(queens, {r,c}))
    + end if
    +    end for
    +end procedure
    +
    diff --git a/autotests/html/highlight.f90.html b/autotests/html/highlight.f90.html new file mode 100644 index 0000000..897b853 --- /dev/null +++ b/autotests/html/highlight.f90.html @@ -0,0 +1,188 @@ + + + +highlight.f90 + +
    +! This file is an example to test the syntax highlighting file F.xml
    +! (for fortran 90 and F)
    +
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +!                      THIS IS AN EXAMPLE OF A MODULE                          !
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +module module_example
    +
    +  ! use 'implicit none' when you want all variables to be declared  
    +  implicit none
    +
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +! PUBLICS AND PRIVATES
    +
    +  ! In fortran 90 you can define your own operator
    +  public :: operator(.norm.)
    +  public :: operator(+) ! <-- you can also overload the usual operators
    +  public :: factorial
    +  public :: example_fn
    +
    +  private :: point3d_add
    +  private :: point3d_norm
    +
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +! USER-DEFINED TYPES...
    +
    +  ! This is a definition to use in declarations of real variables,
    +  ! parameters, etc.
    +  integer, parameter, public :: kr = selected_real_kind(10)
    +
    +  ! This is a user-defined type
    +  type, public :: point3d 
    +    real(kind=kr) :: x, y, z
    +  end type point3d
    +
    +  ! This type is useless: it is only an example of type definition!
    +  type, public :: example_type
    +    complex(kind=kr)            :: c ! <-- a complex number (two reals of kind kr)!
    +    real, dimension(-10:10)     :: & ! <-- this line does not end here!
    +      r1, r2 ! <-- this is the final part of the previous line
    +    real, pointer, dimension(:) :: pointer_to_array_of_real
    +    real, dimension(:), pointer :: array_of_pointer_to_real
    +  end type example_type
    +  
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +! INTERFACES...
    +
    +  ! Interface for the norm of a 3-D vector
    +  interface operator(.norm.)
    +    module procedure point3d_norm
    +  end interface
    +
    +  ! Interface for the operator '+'
    +  interface operator(+)
    +    module procedure point3d_add
    +  end interface
    +
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +! SOME DECLARATIONS...
    +
    +  ! A real number can be declared with the following line:
    +  real(kind=kr) :: real_var1
    +  ! But if you are not interested on the precision of floating point numbers,
    +  ! you can use simply:
    +  real :: real_var2
    +
    +  ! An array can be declared in two ways:
    +  real(kind=kr), dimension(1:10, -4:5), private :: a, b, c
    +  real(kind=kr), private :: d(1:10, -4:5)
    +
    +  ! This is a string with fixed lenght
    +  character(len=10) :: str_var
    +
    +  ! This is an allocatable array, which can be a target of a pointer
    +  type(example_type), private, dimension(:), allocatable, target :: &
    +   many_examples
    +
    +! Fortran 90 hasn't got its own preprocessor, it uses the C preprocessor!
    +#ifdef XXX
    +c <-- this is a comment in the old fortran 77 style (fixed form)
    +c This is a free form file, so we shouldn't use this kind of comments!
    +c But fortran 90 still understands fixed form, when parsing sources with
    +c the *.f extension.
    + c ! <-- this 'c' shouldn't be highlighted as a comment!
    +#endif
    +
    +contains
    +
    +
    +  ! The sum of two points
    +  pure function point3d_add(a, b) result(rs)
    +    type(point3d) :: rs
    +    type(point3d), intent(in) :: a, b
    +    rs%x = a%x + b%x
    +    rs%y = a%y + b%y
    +    rs%z = a%z + b%z
    +  end function point3d_add
    +
    +
    +  ! The norm of a point
    +  pure function point3d_norm(a) result(rs)
    +    real(kind=kr) :: rs
    +    type(point3d), intent(in) :: a
    +    rs = sqrt(a%x * a%x + a%y * a%y + a%z * a%z)    
    +  end function point3d_norm
    +
    +
    +  ! A simple recursive function
    +  recursive function factorial(i) result (rs)
    +    integer :: rs
    +    integer, intent(in) :: i
    +    if ( i <= 1 ) then
    +      rs = 1
    +    else
    +      rs = i * factorial(i - 1)
    +    end if
    +  end function factorial
    +
    +
    +  ! This is a useless function
    +  subroutine example_fn(int_arg, real_arg, str_arg)
    +    integer, intent(in) :: int_arg
    +    real(kind=kr), intent(out) :: real_arg
    +    character(len=*), intent(in) :: str_arg
    +
    +    type(example_type), pointer :: p
    +    integer :: n, i, j
    +    logical :: flag
    +
    +    flag = .true. ! .true. is not an operator!
    +    if ( flag .and. flag ) then ! .and. is a pre-defined operator
    +      print *, "blabla"
    +    end if
    +
    +    ! Examples of inquiry functions: allocated, lbound, ubound.
    +    if ( .not. allocated(many_examples) ) then
    +      allocate( many_examples(10) )
    +    end if
    +    print *, "Lower bound = ", lbound(many_examples, 1)
    +    print *, "Upper bound = ", ubound(many_examples, 1)
    +
    +    p => many_examples(5) ! <-- p is a pointer
    +
    +    ! A strange way to calculate i*i: add the first i odd numbers
    +    i = 6
    +    j = 0
    +    do n = 1, i
    +      j = j + (2*n - 1)
    +    end do 
    +    print *, "i*i = ", i*i, j
    +
    +    real_arg = real(j) ! <-- here the highlighting is not very good:
    +    ! it is unable to distinguish between this and a definition like:
    +    !  real(kind=kr) :: a
    +    deallocate( many_examples )
    +  end subroutine example_fn
    +
    +end module module_example
    +
    +
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +!                         THIS IS THE MAIN PROGRAM                             !
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +program example
    +  use module_example
    +
    +  ! this is another example of use of the 'implicit' keyword
    +  implicit double precision (a-h,o-z)
    +
    +  real(kind=kr) :: var_out
    +
    +  type(point3d) :: &
    +   a = point3d(0.0_kr, 1.0_kr, 2.0_kr), &
    +   b = point3d(4.0_kr, 5.0_kr, 6.0_kr)
    +
    +  print *, "a + b = ", .norm. (a + b)
    +  print *, "factorial of 5 = ", factorial(5)
    +
    +  call example_fn(1, var_out, "hello!")
    +
    +end program example
    +
    diff --git a/autotests/html/highlight.glsl.html b/autotests/html/highlight.glsl.html new file mode 100644 index 0000000..bb22782 --- /dev/null +++ b/autotests/html/highlight.glsl.html @@ -0,0 +1,69 @@ + + + +highlight.glsl + +
    +// This is a test file for the Katepart GLSL Syntax Highlighting.
    +
    +normal text
    +// this is a single-line comment
    +normal text
    +/* this
    +is a multi-line 
    +comment */
    +normal text
    +
    +some_symbol.some_member;
    +some_symbol.some_member_function();
    +some_function();
    +
    +// this is a function
    +void main()
    +{
    +	float f = 1.4e3; // decimal float literal
    +	int i1 = 2884;   // decimal int literal
    +	int i2 = 0x44;   // hex int literal
    +	int i3 = 0456;   // octal int literal
    +}
    +
    +// this is a structure
    +struct some_struct
    +{
    +	vec3 some_member_vector;
    +};
    +
    +# this is 
    +#preprocessor code
    +
    +// all keywords
    +break continue do for while
    +if else
    +true false
    +discard return
    +struct
    +
    +// all basic types
    +float int void bool
    +mat2 mat3 mat4
    +vec2 vec3 vec4
    +ivec2 ivec3 ivec4
    +bvec2 bvec3 bvec4
    +sampler1D sampler2D sampler3D
    +samplerCube sampler1DShadow sampler1DShadow
    +
    +// all type qualifiers
    +attribute const uniform varying
    +in out inout
    +
    +// attensions:
    +// FIXME
    +// TODO
    +// BUG
    +
    +// some of the std functions
    +radians degrees sin cos tan asin acos atan
    +
    +// some of the std variables
    +gl_Position gl_PointSize gl_ClipVertex
    +
    diff --git a/autotests/html/highlight.hs.html b/autotests/html/highlight.hs.html new file mode 100644 index 0000000..0551dc0 --- /dev/null +++ b/autotests/html/highlight.hs.html @@ -0,0 +1,131 @@ + + + +highlight.hs + +
    +-- test file for Haskell syntax highlighting in KDE's Kate
    +
    +-- The test file for literate Haskell can be easily created like this:
    +--  cat highlight.hs | sed -e "s|^|> |" -e "s|> -- ||" -e "s|^> $||" > highlight.lhs
    +-- You only have to manually edit the multi-line comment below.
    +
    +-- this is a single-line comment
    +
    +{- this is a multi-line comment
    +
    +Things like "a string" or a 'c' character shouldn't be highlighted in here.
    +
    +-- I could even start a new
    +-- one-line comment.
    +
    +-}
    +
    +-- a data definition
    +
    +data Tree a = Br (Tree a) (Tree a) | Leaf a | Nil deriving (Show, Eq)
    +
    +
    +-- function definition, "funnyfunction::", "Integer", "Int", "Bool" should be highlighted
    +
    +funnyfunction::(Tree a)=>[a]->Integer->Int->Bool
    +
    +
    +-- strings and chars
    +-- first line of function definitions (type declaration) should be highlighted
    +
    +strangefunction::Int->String
    +strangefunction 1 = "hello"
    +strangefunction 2 = "what's up"
    +strangefunction 3 = (strangefunction 1) ++ ", " ++ (strangefunction 2)
    +strangefunction 4 = 'a':'b':'c':'"':[] -- will return "abc"
    +strangefunction 5 = '\n':[]
    +strangefunction 6 = '\invalidhaskell':[]
    +
    +-- function name including the single quote character
    +-- and infix operator (`div`)
    +
    +justtesting'::Int->Int
    +justtesting' 2 = 2+1
    +justtesting' 9 = 7 `div` 2
    +
    +-- same definition as above, slightly different function name and a couple more whitespaces
    +
    +justtesting''	::	Int -> Int
    +justtesting''   2 = 3
    +justtesting''	9	=   3 + 9 - 9
    +
    +-- the following lines are copied out of Haskell's "Prelude.hs"
    +
    +infixl 7  *, /, `quot`, `rem`, `div`, `mod`, :%, %
    +
    +
    +-- everything highlighted except the "a"
    +
    +class Bounded a where
    +    minBound, maxBound :: a
    +
    +class (Num a, Ord a) => Real a where
    +    toRational     :: a -> Rational
    +
    +-- finally, some keyword lists
    +
    +-- keywords
    +
    +case, class, data, deriving, do, else, if, in, infixl, infixr, instance, let, module, of, primitive,
    +then, type, where
    +
    +-- infix operators
    +
    +quot, rem, div, mod, elem, notElem, seq
    +
    +-- this stuff is not handled yet
    +
    +!!, %, &&, $!, $, *, **, -,., /=, <, <=, =<<, ==, >, >=, >>, >>=, ^, ^^, ++, ||
    +
    +-- functions
    +
    +FilePath, IOError, abs, acos, acosh, all, and, any, appendFile,
    +approxRational, asTypeOf, asin, asinh, atan, atan2, atanh, basicIORun,
    +break, catch, ceiling, chr, compare, concat, concatMap, const, cos, cosh,
    +curry, cycle, decodeFloat, denominator, digitToInt, div, divMod, drop,
    +dropWhile, either, elem, encodeFloat, enumFrom, enumFromThen,
    +enumFromThenTo, enumFromTo, error, even, exp, exponent, fail, filter, flip,
    +floatDigits, floatRadix, floatRange, floor, fmap, foldl, foldl1, foldr,
    +foldr1, fromDouble, fromEnum, fromInt, fromInteger, fromIntegral,
    +fromRational, fst, gcd, getChar, getContents, getLine, head, id, inRange,
    +index, init, intToDigit, interact, ioError, isAlpha, isAlphaNum, isAscii,
    +isControl, isDenormalized, isDigit, isHexDigit, isIEEE, isInfinite, isLower,
    +isNaN, isNegativeZero, isOctDigit, isPrint, isSpace, isUpper, iterate, last,
    +lcm, length, lex, lexDigits, lexLitChar, lines, log, logBase, lookup, map,
    +mapM, mapM_, max, maxBound, maximum, maybe, min, minBound, minimum, mod,
    +negate, not, notElem, null, numerator, odd, or, ord, otherwise, pi, pred,
    +primExitWith, print, product, properFraction, putChar, putStr, putStrLn,
    +quot, quotRem, range, rangeSize, read, readDec, readFile, readFloat,
    +readHex, readIO, readInt, readList, readLitChar, readLn, readOct, readParen,
    +readSigned, reads, readsPrec, realToFrac, recip, rem, repeat, replicate,
    +return, reverse, round, scaleFloat, scanl, scanl1, scanr, scanr1, seq,
    +sequence, sequence_, show, showChar, showInt, showList, showLitChar,
    +showParen, showSigned, showString, shows, showsPrec, significand, signum,
    +sin, sinh, snd, span, splitAt, sqrt, subtract, succ, sum, tail, take,
    +either, elem, encodeFloat, enumFrom, enumFromThen, enumFromThenTo,
    +enumFromTo, error, even, exp, exponent, fail, filter, flip, floatDigits,
    +floatRadix, floatRange, floor, fmap, takeWhile, tan, tanh, threadToIOResult,
    +toEnum, toInt, toInteger, toLower, toRational, toUpper, truncate, uncurry,
    +undefined, unlines, until, unwords, unzip, unzip3, userError, words,
    +writeFile, zip, zip3, zipWith, zipWith3
    +
    +-- type constructors
    +
    +Bool, Char, Double, Either, Float, IO, Integer, Int, Maybe, Ordering, Rational, Ratio, ReadS,
    +ShowS, String
    +
    +-- classes
    +
    +Bounded, Enum, Eq, Floating, Fractional, Functor, Integral, Ix, Monad, Num, Ord, Read, RealFloat,
    +RealFrac, Real, Show
    +
    +-- data constructors
    +
    +EQ, False, GT, Just, LT, Left, Nothing, Right, True
    +
    diff --git a/autotests/html/highlight.js.html b/autotests/html/highlight.js.html new file mode 100644 index 0000000..20d75d5 --- /dev/null +++ b/autotests/html/highlight.js.html @@ -0,0 +1,141 @@ + + + +highlight.js + +
    +/* test.js - test for javascript.xml syntax file */
    +// Note: this script will not, and is not supposed to, comile in any js engine.
    +
    +/* 
    +   NOTE: The words "todo", "fixme" and "note" should be rendered in a different style
    +   within comments, match should be caseless (to test for regexp insensitive attribute).
    +   The regex used for this rule is */
    +   String = /\b(?:fixme|todo|note)\b/
    +   /* Thus,  for example "Notebook" is not caught by
    +   this rule. (the "?:" in the subpattern is there to avoid the regex engine wasting time
    +   saving a backref, which is not used for anything. I do not know if the overhead of parsing
    +   that is greater than the time saved by not capturing the text...)
    +   The rule for catching these words is placed in a context "Comment common", which is used
    +   by both comment contexts (single line, multiline) using the new "IncludeRules" item.
    +*/
    +
    +// test if regex support works - nice with new fallthrough prop in context:)
    +somestring.replace( /dooh/ , "bah!");
    +re=/foo/ig; // hehe
    +
    +somestring.search(
    +       /^foo\w+\s\d{0,15}$/
    +                  );
    +
    +        re =
    +        /dooh/;
    +
    +// This is supposedly legal:
    +re = somebool ? /foo/ : /bar/;
    +
    +// NOTE - Special case: an empty regex, not a comment.
    +// The rule uses a positive lookahead assertion to catch it: "//(?=;)".
    +re = //;
    +re = /a|b/;
    +
    +/*
    +   Tests for the regex parser.
    +   It will parse classes, quanitfiers, special characters and regex operaters,
    +   as specified in the netscape documentation for javascript.
    +   Regexps are only parsed in their clean form, as the RegExp(string) constructor
    +   is using a quoted string.
    +   TODO: Find out if more regex feats should be supported.
    +         Consider using more itemDatas - assertion, quantifier are options.
    +*/
    +
    +re = /^text\s+\d+\s*$/;
    +re = /a pattern with caret \(^\) in it/;
    +re = /(\d{0,4})\D/;
    +re = /[a-zA-Z_]+/;
    +re = /[^\d^]+/;
    +re = /\s+?\w+\.$/;
    +re = /\/\//;
    +re = /a|b/;
    +
    +// a test if #pop back from a comment will work
    +re = /*/foo/*/ /bar/;
    +//           ^ POP
    +//             ^ we got back after pop in comment, if there is regexp attribs here :-)
    +
    +/*
    +   Some tests if the fallthrough works.
    +   The fallthrough happens if a regexp is not found in a possible (!) position,
    +   which is after "search(" or "replace(" or "=" or "?" or ":" in version 0.1 of the xml file
    +*/
    +
    +var foo = 'bar';
    +//        ^ fallthrough!
    +
    +
    +somestring.replace( new RegExp("\\b\\w+\\b"), "word: $1");
    +//                  ^ fallthrough expected. ("new" whould be bold)
    +
    +
    +something.method =
    +    function ( a, b, c ) { /* ... */ }
    +//  ^ fallthrough ?!
    +
    +something.other =
    +function ( d, e, f ) { /* ... */ }
    +// fallthrough expected at col 0 ("function" should be bold)
    +
    +var ary = new Array(5);
    +//        ^ fallthrough ? (if keyword is correctly rendered)
    +
    +var b = a ? 1 : 0;
    +//          ^   ^ fallthroughs. numbers must be rendered correctly.
    +
    +var c = d ? true : false;
    +
    +var conditinalstring = b ?
    +  "something" :
    +  "something else";
    +// guess...
    +
    +
    +/*
    +   Normal program flow...
    +*/
    +
    +if (something)
    +  dostuff();
    +else
    +  dont();
    +
    +  return;
    +
    +try { bla() } catch (e) { alert("ERROR! : " + e) }
    +
    +for (int i=0; i < j; i++)
    +  document.write("i is" + i + "<br>");
    +
    +while (something)
    +{
    +  block();
    +  picky:
    +    if (!1)
    +      break;
    +    else
    +      continue;
    +}
    +
    +with (a) {
    +  do {
    +    stuff( b ); // a.b if it exists
    +  } while (itmakessense);
    +}
    +
    +switch (i) {
    +  case 0:
    +  f();
    +  break;
    +  default:
    +  break;
    +}
    +
    diff --git a/autotests/html/highlight.jsp.html b/autotests/html/highlight.jsp.html new file mode 100644 index 0000000..919297f --- /dev/null +++ b/autotests/html/highlight.jsp.html @@ -0,0 +1,177 @@ + + + +highlight.jsp + +
    +<%--
    +  This page won't actually work, as it is simply designed to display jsp syntax highlighting.
    +--%>
    +<%@ page info="A Page to Test Kate Jsp Syntax Highlighting" language="java" errorPage="/test-error-page.jsp"%>
    +<%@ include file="/include/myglobalvars.jsp"%> --%>
    +<%@ page import="java.util.*,
    +                 java.io.*,
    +                 java.math.*" %>
    +<%@ taglib uri="/WEB-INF/lib/si_taglib.tld" prefix="si"%>
    +<jsp:useBean id="aPageBean" scope="page" class="my.package.MyPageBean"/>
    +<jsp:useBean id="aRequestBean" scope="request" class="my.package.MyRequestBean"/>
    +<%
    +  // We can decipher our expected parameters here.
    +  String parm1 = noNull(request.getParameter(PARAMETER_1)).trim();
    +  String parm2 = noNull(request.getParameter(PARAMETER_2)).trim();
    +  String parm3 = noNull(request.getParameter(PARAMETER_3)).trim();
    +  String parm4 = noNull(request.getParameter(PARAMETER_4)).trim();
    +  String parm5 = noNull(request.getParameter(PARAMETER_5)).trim();
    +
    +  // A sample collection of Integers to display some code folding.
    +  List intList = getIntList(10);
    +
    +
    +%>
    +<html>
    +  <title>A Sample Jsp</title>
    +  <head>
    +  <script language="javascript"><!--
    +    function doAlert1() {
    +      alert("This is the first javascript example.");
    +    }
    +
    +    function doAlert2() {
    +      alert("This is the second javascript example.");
    +    }
    +  //--></script>
    +  </head>
    +  <body>
    +    <%-- The top label table. --%>
    +    <table width="400" cellpadding="0" cellspacing="0" border="0">
    +      <tr>
    +        <td><font size="3"><b>The following parameters were detected:</b></font></td>
    +      </tr>
    +    </table>
    +
    +    <%-- Display the parameters which might have been passed in. --%>
    +    <table width="400" cellpadding="0" cellspacing="0" border="0">
    +      <%-- Label; Actual Parameter String; Value Detected --%>
    +      <tr>
    +        <td><b>PARAMETER_1</b></td>
    +        <td align="center"><%=PARAMETER_1%></td>
    +        <td align="right">&quot;<%=parm1%>&quot;</td>
    +      </tr>
    +
    +      <%-- Label; Actual Parameter String; Value Detected --%>
    +      <tr>
    +        <td><b>PARAMETER_2</b></td>
    +        <td align="center"><%=PARAMETER_2%></td>
    +        <td align="right">&quot;<%=parm2%>&quot;</td>
    +      </tr>
    +
    +      <%-- Label; Actual Parameter String; Value Detected --%>
    +      <tr>
    +        <td><b>PARAMETER_3</b></td>
    +        <td align="center"><%=PARAMETER_3%></td>
    +        <td align="right">&quot;<%=parm3%>&quot;</td>
    +      </tr>
    +
    +      <%-- Label; Actual Parameter String; Value Detected --%>
    +      <tr>
    +        <td><b>PARAMETER_4</b></td>
    +        <td align="center"><%=PARAMETER_4%></td>
    +        <td align="right">&quot;<%=parm4%>&quot;</td>
    +      </tr>
    +
    +      <%-- Label; Actual Parameter String; Value Detected --%>
    +      <tr>
    +        <td><b>PARAMETER_5</b></td>
    +        <td align="center"><%=PARAMETER_5%></td>
    +        <td align="right">&quot;<%=parm5%>&quot;</td>
    +      </tr>
    +    </table>
    +
    +    <br><br>
    +
    +    <%-- Display our list of random Integers (shows code folding). --%>
    +    <table width="400" cellpadding="0" cellspacing="0" border="0">
    +<%
    +  if (intList != null && intList.size() > 0) {
    +%>
    +      <tr><td><b>Here are the elements of intList...</b></td></tr>
    +<%
    +    Iterator intListIt = intList.iterator();
    +    while (intListIt.hasNext()) {
    +      Integer i = (Integer) intListIt.next();
    +%>
    +      <tr><td><%=i.toString()%></td></tr>
    +<%
    +    }
    +  } else {
    +%>
    +      <tr><td><font color="blue"><b><i>Oooops, we forgot to initialize intList!</i></b></font></td></tr>
    +<%
    +  }
    +%>
    +    </table>
    +
    +    <br><br>
    +
    +    <%-- We can call javascript functions. --%>
    +    <table width="400" cellpadding="0" cellspacing="0" border="0">
    +      <tr><td colspan="2"><b>Test our javascript...</b></td></tr>
    +      <tr>
    +        <td><input type="button" name="button1" value="Alert 1" onmouseup="javascript:doAlert1()"></td>
    +        <td><input type="button" name="button2" value="Alert 2" onmouseup="javascript:doAlert2()"></td>
    +      </tr>
    +    </table>
    +
    +    <br><br>
    +    <%-- If we actually had defined a tag library. --%>
    +    <table width="400" cellpadding="0" cellspacing="0" border="0">
    +      <tr><td>
    +      <my:SampleTag prop1="first" prop2="third">
    +        <my:SampleTagChild nameProp="value1"/>
    +        <my:SampleTagChild nameProp="value2"/>
    +      </my:SampleTag>
    +      </td></tr>
    +    </table>
    +
    +    <br><br>
    +    <%-- Expression language. --%>
    +    <table width="400" cellpadding="0" cellspacing="0" border="0">
    +      <c:if test="${!empty param.aParam}">
    +        <c:set var="myParam" scope="session" value="${param.aParam}"/>
    +      </c:if>
    +
    +      <tr><td>myParam's value: &quot;<c:out value="${myParam}" default=="Default"/>&quot;</td></tr>
    +    </table>
    +  </body>
    +</html>
    +<%!
    +  /* A place for class variables and functions... */
    +
    +  // Define some sample parameter names that this page might understand.
    +  private static final String PARAMETER_1            = "p1";
    +  private static final String PARAMETER_2            = "p2";
    +  private static final String PARAMETER_3            = "p3";
    +  private static final String PARAMETER_4            = "p4";
    +  private static final String PARAMETER_5            = "p5";
    +
    +  // Returns str trimmed, or an empty string if str is null.
    +  private static String noNull(String str) {
    +    String retStr;
    +    if (str == null)
    +      retStr = "";
    +    else
    +      retStr = str.trim();
    +
    +    return retStr;
    +  }
    +
    +  // Returns a list of Integers with listSize elements.
    +  private static List getIntList(int listSize) {
    +    ArrayList retList = new ArrayList(listSize);
    +    for (int i = 0; i < listSize; i++)
    +      retList.add(new Integer( (int) (Math.random() * 100) ));
    +
    +    return retList;
    +  }
    +%>
    +
    diff --git a/autotests/html/highlight.lex.html b/autotests/html/highlight.lex.html new file mode 100644 index 0000000..7838c6d --- /dev/null +++ b/autotests/html/highlight.lex.html @@ -0,0 +1,89 @@ + + + +highlight.lex + +
    +/* This test file tests kates Lex/Flex highlighting */
    +
    +%option c++
    +%option yyclass="KateTester"
    +%option yylineno
    +
    + /* This is a C(++) comment */
    +
    +/* This one is a lex comment ! */
    +
    +%{
    +#include <iostream>
    +#include "realparser.hpp"
    +using namespace std;
    +%}
    +
    +/* Some definitions */
    +DIGIT    [0-9]
    +LETTER   [_a-zA-Z]
    +
    +%%
    +
    + /* Comment *shall be indented here* */
    +[ \t\n\r]+          
    +
    + /* Note: there is a bad } just here     vvv */
    +\/\*([^\*]|\*[^/])*\*\/ { foo(a, b, c); } }
    +
    + /* A start condition scope... */
    +<ESC>{
    +  "a" {
    +  
    +  /* C mode ! */
    +  return 0;
    +}
    +
    +  "b" %{
    +  
    +  /* C mode, too ! */
    +  return 0;
    +%}
    +  
    +  "c" return 0; // C++ comment
    +}
    +
    + /* Big rule */
    +\"([^"\\]|\\.)*\" {
    +
    +   yylval.string_val = new char[strlen(yytext) + 1];
    +   int j = 0, i = 1;
    +   
    +   while (yytext[i] != '"')
    +      if (yytext[i] != '\\')
    +         yylval.string_val[j++] = yytext[i++];
    +      else
    +         switch (yytext[i + 1])
    +         {
    +         case 'n':
    +            yylval.string_val[j++] = '\n'; i += 2;
    +            break;
    +         default:
    +            yylval.string_val[j++] << yytext[i + 1], i += 2;
    +         }
    +    
    +    yylval.string_val[j] = 0;   
    +    return TOK_STRING;
    +
    +}
    +
    + /* Dot (match all) */
    +.             {return yylval.int_val = yytext[0];}
    +
    +%%
    +
    +// Here is pure C(++)
    +#include <iostream>
    +
    +int main(void)
    +{
    +  std::cout << "Hello, World\n";
    +  return 0;
    +}
    +
    diff --git a/autotests/html/highlight.lhs.html b/autotests/html/highlight.lhs.html new file mode 100644 index 0000000..2c7d38c --- /dev/null +++ b/autotests/html/highlight.lhs.html @@ -0,0 +1,131 @@ + + + +highlight.lhs + +
    +test file for Haskell syntax highlighting in KDE's Kate
    +
    +The test file for literate Haskell can be easily created like this:
    + cat highlight.hs | sed -e "s|^|> |" -e "s|> -- ||" -e "s|^> $||" > highlight.lhs
    +You only have to manually edit the multi-line comment below.
    +
    +this is a single-line comment
    +
    +{- this is a multi-line comment
    +
    +Things like "a string" or a 'c' character shouldn't be highlighted in here.
    +
    +I could even start a new
    +one-line comment.
    +
    +-}
    +
    +a data definition
    +
    +> data Tree a = Br (Tree a) (Tree a) | Leaf a | Nil deriving (Show, Eq)
    +
    +
    +function definition, "funnyfunction::", "Integer", "Int", "Bool" should be highlighted
    +
    +> funnyfunction::(Tree a)=>[a]->Integer->Int->Bool
    +
    +
    +strings and chars
    +first line of function definitions (type declaration) should be highlighted
    +
    +> strangefunction::Int->String
    +> strangefunction 1 = "hello"
    +> strangefunction 2 = "what's up"
    +> strangefunction 3 = (strangefunction 1) ++ ", " ++ (strangefunction 2)
    +> strangefunction 4 = 'a':'b':'c':'"':[] -- will return "abc"
    +> strangefunction 5 = '\n':[]
    +> strangefunction 6 = '\invalidhaskell':[]
    +
    +function name including the single quote character
    +and infix operator (`div`)
    +
    +> justtesting'::Int->Int
    +> justtesting' 2 = 2+1
    +> justtesting' 9 = 7 `div` 2
    +
    +same definition as above, slightly different function name and a couple more whitespaces
    +
    +> justtesting''	::	Int -> Int
    +> justtesting''   2 = 3
    +> justtesting''	9	=   3 + 9 - 9
    +
    +the following lines are copied out of Haskell's "Prelude.hs"
    +
    +> infixl 7  *, /, `quot`, `rem`, `div`, `mod`, :%, %
    +
    +
    +everything highlighted except the "a"
    +
    +> class Bounded a where
    +>     minBound, maxBound :: a
    +
    +> class (Num a, Ord a) => Real a where
    +>     toRational     :: a -> Rational
    +
    +finally, some keyword lists
    +
    +keywords
    +
    +> case, class, data, deriving, do, else, if, in, infixl, infixr, instance, let, module, of, primitive,
    +> then, type, where
    +
    +infix operators
    +
    +> quot, rem, div, mod, elem, notElem, seq
    +
    +this stuff is not handled yet
    +
    +> !!, %, &&, $!, $, *, **, -,., /=, <, <=, =<<, ==, >, >=, >>, >>=, ^, ^^, ++, ||
    +
    +functions
    +
    +> FilePath, IOError, abs, acos, acosh, all, and, any, appendFile,
    +> approxRational, asTypeOf, asin, asinh, atan, atan2, atanh, basicIORun,
    +> break, catch, ceiling, chr, compare, concat, concatMap, const, cos, cosh,
    +> curry, cycle, decodeFloat, denominator, digitToInt, div, divMod, drop,
    +> dropWhile, either, elem, encodeFloat, enumFrom, enumFromThen,
    +> enumFromThenTo, enumFromTo, error, even, exp, exponent, fail, filter, flip,
    +> floatDigits, floatRadix, floatRange, floor, fmap, foldl, foldl1, foldr,
    +> foldr1, fromDouble, fromEnum, fromInt, fromInteger, fromIntegral,
    +> fromRational, fst, gcd, getChar, getContents, getLine, head, id, inRange,
    +> index, init, intToDigit, interact, ioError, isAlpha, isAlphaNum, isAscii,
    +> isControl, isDenormalized, isDigit, isHexDigit, isIEEE, isInfinite, isLower,
    +> isNaN, isNegativeZero, isOctDigit, isPrint, isSpace, isUpper, iterate, last,
    +> lcm, length, lex, lexDigits, lexLitChar, lines, log, logBase, lookup, map,
    +> mapM, mapM_, max, maxBound, maximum, maybe, min, minBound, minimum, mod,
    +> negate, not, notElem, null, numerator, odd, or, ord, otherwise, pi, pred,
    +> primExitWith, print, product, properFraction, putChar, putStr, putStrLn,
    +> quot, quotRem, range, rangeSize, read, readDec, readFile, readFloat,
    +> readHex, readIO, readInt, readList, readLitChar, readLn, readOct, readParen,
    +> readSigned, reads, readsPrec, realToFrac, recip, rem, repeat, replicate,
    +> return, reverse, round, scaleFloat, scanl, scanl1, scanr, scanr1, seq,
    +> sequence, sequence_, show, showChar, showInt, showList, showLitChar,
    +> showParen, showSigned, showString, shows, showsPrec, significand, signum,
    +> sin, sinh, snd, span, splitAt, sqrt, subtract, succ, sum, tail, take,
    +> either, elem, encodeFloat, enumFrom, enumFromThen, enumFromThenTo,
    +> enumFromTo, error, even, exp, exponent, fail, filter, flip, floatDigits,
    +> floatRadix, floatRange, floor, fmap, takeWhile, tan, tanh, threadToIOResult,
    +> toEnum, toInt, toInteger, toLower, toRational, toUpper, truncate, uncurry,
    +> undefined, unlines, until, unwords, unzip, unzip3, userError, words,
    +> writeFile, zip, zip3, zipWith, zipWith3
    +
    +type constructors
    +
    +> Bool, Char, Double, Either, Float, IO, Integer, Int, Maybe, Ordering, Rational, Ratio, ReadS,
    +> ShowS, String
    +
    +classes
    +
    +> Bounded, Enum, Eq, Floating, Fractional, Functor, Integral, Ix, Monad, Num, Ord, Read, RealFloat,
    +> RealFrac, Real, Show
    +
    +data constructors
    +
    +> EQ, False, GT, Just, LT, Left, Nothing, Right, True
    +
    diff --git a/autotests/html/highlight.lisp.html b/autotests/html/highlight.lisp.html new file mode 100644 index 0000000..6d59f6b --- /dev/null +++ b/autotests/html/highlight.lisp.html @@ -0,0 +1,43 @@ + + + +highlight.lisp + +
    +;; This test file tests kates common lisp highlighting
    +#|
    +multilinecomment :)
    +|#
    +
    +;BEGIN region marker
    +
    +;END end
    +
    +(defun bin-search (obj vec)
    +  (let ((len (length vec)))
    +    (and (not (zerop len))
    +         (finder obj vec 0 (- len 1)))))
    +
    +(defun parse-date (str)
    +  (let ((toks (tokens str #'constituent 0)))
    +    (list (parse-integer (first toks))
    +          (parse-month   (second toks))
    +          (parse-integer (third toks)))))
    +
    +(defconstant month-names
    +  #("jan" "feb" "mar" "apr" "may" "jun"
    +    "jul" "aug" "sep" "oct" "nov" "dec"))
    +
    +(defstruct buf
    +  vec (start -1) (used -1) (new -1) (end -1))
    +
    +(defparameter *words* (make-hash-table :size 10000))
    +
    +(defmacro while (test &rest body)
    +  `(do ()
    +       ((not ,test))
    +     ,@body))
    +
    +(define-modify-macro append1f (val)
    +  (lambda (lst val) (append lst (list val))))
    +
    diff --git a/autotests/html/highlight.ly.html b/autotests/html/highlight.ly.html new file mode 100644 index 0000000..3eafd4b --- /dev/null +++ b/autotests/html/highlight.ly.html @@ -0,0 +1,121 @@ + + + +highlight.ly + +
    +% This is a file to test the Lilypond highlighting features of Katepart.
    +% This is NOT a valid lilypond file, because it also shows the
    +% highlighting of some invalid lilypond constructs!
    +% This is a line comment.
    +
    +%{
    +this is a block comment, that can occur inside a line, or across
    +multiple lines.
    +%}
    +
    +\header {
    +  title = "Katepart Lilypond syntax highlighting test file"
    +  composer = %{"Wilbert Berendsen"%} "Anonymus"
    +  poet = "The KDE team"
    +  opus = "1"
    +  copyright = "Share and enjoy!"
    +}
    +
    +\paper {
    +  #(set-paper-size "a4")  % a hash introduces scheme
    +  indent = 0              % recognize variable names inside \paper, \layout etc.
    +  between-system-space = 3\mm
    +}
    +
    +\layout {
    +  \context {
    +    \Score
    +    \remove Bar_number_engraver   % recognize engraver names
    +    \remove "Bar_number_engraver" % also when quoted!
    +  }
    +}
    +
    +% { and << block are folded
    +\score {
    +  \new StaffGroup <<
    +    \new ChordNames \chordmode { c2sus4/f g2/d c1 }
    +    \new Staff \new Voice ="mel" {
    +      \key f \major
    +      \time 4/4
    +      \partial 4
    +      \set Staff.instrumentName = "Bla."
    +      \once \override Staff.NoteHead #'color = #red
    +      % dynamics, articulations and markup
    +      c8\p d\< e-. f-> g a\f c-5\markup {Hoi}
    +      \notemode { c d e f }
    +      \repeat volta 2 {
    +        % complex durations are highlighted:
    +        g4*2/3
    +      }
    +      \times 2/3 {e8 f g}
    +      % there is some error checking:
    +      % often made mistake to have octavemarks after the duration:
    +      c2'
    +      % invalid durations are caught:
    +      g3
    +    }
    +    \context Lyrics \lyricsto "mel" {
    +      \set fontSize = #1
    +      this is a line of ly -- rics.
    +      with4 dur -- a -- tions.2.
    +      % errors like forgetting spaces are found:
    +      space-- flight %{i.s.o.%} space -- flight
    +      space at end for -- got -- ten as well.}
    +    
    +    \new DrumStaff \drummode { hihat4 bassdrum8 }
    +    \new FiguredBass \figuremode {
    +      <5 4>8 <6->
    +    }
    +  >>
    +  \midi {
    +    \context {
    +      \Score
    +      tempoWholesPerMinute = #(ly:make-moment 60 2)
    +    }
    +  }
    +}
    +
    +av = #(define-music-function (parser location voice)
    +(string?)
    +; scheme comments are recognized in scheme
    +; Lilypond inside scheme works as well:
    +#{
    +  \set associatedVoice = $voice
    +#})
    +
    +
    +
    +      
    +% inside scheme some elements are highlighted:    
    +#(define  (naturalise-pitch p)
    +  (let* ((o (ly:pitch-octave p))
    +         (a (* 4 (ly:pitch-alteration p))) 
    +         (n (ly:pitch-notename p)))
    +         (bla 'ArticulationEvent 'ChoirStaff)
    +    (cond
    +     ((> a 2) (set! a (- a 4)) (set! n (+ n 1)))
    +     ((< a -2) (set! a (+ a 4)) (set! n (- n 1))))
    +
    +    (if (< n 0) (begin (set!  o (- o 1)) (set! n (+ n 7))))
    +    (if (> n 6) (begin (set!  o (+ o 1)) (set! n (- n 7))))
    +
    +    (ly:make-pitch o n (/ a 4))))
    +
    +% markup is also highlighted
    +\markup {
    +  \line {
    +    text test Voice Staff % note Lilypond keywords are not highlighted here
    +  }
    +  \score { \relative c' { <ceg>2( d) } }
    +  \italic bla
    +  \override #'(baseline-skip . 2) {
    +    \underline blu
    +  }
    +}
    +
    diff --git a/autotests/html/highlight.m.html b/autotests/html/highlight.m.html new file mode 100644 index 0000000..3296705 --- /dev/null +++ b/autotests/html/highlight.m.html @@ -0,0 +1,68 @@ + + + +highlight.m + +
    +%%=====================================================
    +% MATLAB test code for Kate/Kwrite syntax highlighting
    +% kate: hl Matlab
    +%%=====================================================
    +
    +% Numbers _____________________________________________
    +5, 5.5, .1, 0.1, 0.4e5, 1.2e-5, 5i, 5.3i, 6j, .345+3i
    +5', 5.5', .1', 0.1', 0.4e5', 1.2e-5', 5i', 5.3i', 6j', .345+3i'
    +
    +% Operators ___________________________________________
    +% relational operators
    +'asdf'~=4, c<=4, d>=4, a<b, a>b, a==b, b||c, b&&c
    +% elementwise arithmetic operators
    +a.^b, a.*b a./b, 1:4:5
    +% single-character binary arithmetic
    +a+3, a-3, a*2, a^3, a/3, a\3, a|b, a&b
    +% unary operators
    +a = ~g; g = @sfdgdsf(sdfsd,345); g.' + 1i.' - ('asdf').'
    +% separators and delimiter
    +(asd),[sadf];{asdf},;;,;;;()
    +% continuation
    +a = 1+ ...
    +  2;
    +
    +% Strings and adjoint _________________________________
    +% incomplete strings
    +'string
    +'str''
    +'str''ing
    +% complete strings
    +'string' % simple string
    +'''' % string containing '
    +'str''ing' % one string containing '
    +'string' 'string'  % two strings
    +'asdf'  'asdf''' variable  % two strings and a variable
    +'asdf''asdf''   fsgdfg' + (asdf)' - 'asdf'.' + []''''.';''
    +'sadf'.' % string transpose
    +% adjoint
    +{'asdf'}' + 1
    +('asdf')' + 1
    +['asdf']' + 1
    +'' var''' % empty string, var with >1 adjoints
    +[5]'*{5}'*('asd')'.'+(5)'*6'*asdf'*asdf'.'  % many adjoints
    +A'*B + 1      % adjoint
    +A.'*B + 1     % transpose
    +A.'.'*B + 1   % double transpose
    +A'.' + 1      % adjoint, then transpose
    +A.''          % transpose, then adjoint
    +
    +% System command ______________________________________
    +!hostname
    +!cp * /tmp
    +
    +% Reserved keywords ___________________________________
    +function, persistent, global
    +switch, case, otherwise
    +if, else, elseif
    +try, catch
    +for, while, break, continue
    +end, return
    +function, FUNCTION, Function  % case sensitive!
    +
    diff --git a/autotests/html/highlight.mac.html b/autotests/html/highlight.mac.html new file mode 100644 index 0000000..62a6068 --- /dev/null +++ b/autotests/html/highlight.mac.html @@ -0,0 +1,152 @@ + + + +highlight.mac + +
    +/*
    +------------------------------------------------------------------------
    +Efficient Galois Fields in Maxima
    +
    +by Alasdair McAndrew
    +and later extended by Fabrizio Caruso and Jacopo Daurizio
    +
    +it is distribuited together with gf_roots by Jacopo Daurizio
    +
    +Authors:
    +
    +Fabrizio Caruso   (optimizations, testing)
    +Jacopo D'Aurizio   (optimizations, modular roots)
    +Alasdair McAndrew (original version of the package, pohlig-helman log, etc... )
    +------------------------------------------------------------------------*/
    +
    +/* Released under terms of the GNU General Public License, version 2,
    + * by permission of the authors to Robert Dodier circa 2007-12-02.
    + */
    +
    +/* Defines a flag for dealing with large fields.  If it is set to "false",
    +then lookup tables are used for exponentiation and logarithms.  Otherwise
    +other algorithms are used */
    +
    +define_variable(largefield,true,bool)$
    +define_variable(gf_char,0,integer)$
    +define_variable(gf_exp,0,integer)$
    +define_variable(gf_order,0,integer)$
    +define_variable (gf_one, 'gf_one, any_check)$
    +define_variable (gf_prim, 'gf_prim, any_check)$
    +define_variable (gf_irr, 'gf_irr, any_check)$
    +define_variable (gf_list, 'gf_list, any_check)$
    +define_variable (gen_powers, 'gf_list, any_check)$
    +remvalue(x,z,gf_char,gf_exp,gf_irr,pg,gp,lg,gf_prim,gf_one,gf_order,gf_list,gen_powers)$
    +
    +
    +/* --------------------------------------------------------------------------------------------- */
    +/* Settings */
    +
    +GF_VERBOSE:false; /* Verbosity */
    +GF_WARNING: true; /* Warnings */
    +GF_IRREDUCIBILITY_CHECK:false;   /* Irreducibility test for the minimal polynomial of the extension */
    +
    +/*
    +------------------------------------------------------------------------------------------------ */
    +
    +
    +/* It defines a new current field with gf_char=b, min. pol.= p of deg= e*/
    +gf_set([ars]):=block([gj,m,i,j,dg],
    +  if length(ars)=1 then
    +    (
    +    gf_setp(ars[1]),
    +    return(true)
    +    )
    +  else
    +    (
    +    if length(ars)=2 then
    +       (
    +       if numberp(ars[2]) then
    +         (
    +         if ars[2]=0 and GF_WARNING then
    +           (
    +           print("WARNING: the irreducible is zero! We assume GF(",ars[1],")"),
    +           gf_setp(ars[1]),
    +           return(true)
    +           )
    +         else
    +           (
    +           error("ERROR: you tried to extend with a non-zero constant!"),
    +           return(false)
    +           )
    +         )
    +       else
    +         (
    +         dg:hipow(ars[2],x),
    +
    +         if dg=1 then
    +           gf_setp(ars[1]),
    +         gf_irr:ars[2],
    +         gf_exp:dg,
    +         return(true)
    +         )
    +       )
    +    else
    +       (
    +       gf_exp:ars[2],
    +       if gf_exp=1 then
    +          (
    +          gf_setp(ars[1]),
    +          gf_irr:rat(ars[3]),
    +          return(true)
    +          ),
    +       gf_irr:rat(ars[3])
    +       )
    +    ),
    +
    +  gf_char:ars[1],
    +  gf_one:rat(1,x),
    +  gf_order:gf_char^gf_exp-1,
    +
    +  m:makelist(coeff(gf_irr,x,i),i,0,gf_exp),
    +  gf_list:[[first(m),0]],j:1,
    +  for i:2 thru gf_exp+1 do if m[i]=0 then j:j+1 else ( gf_list:endcons([m[i],j],gf_list), j:1 ),
    +
    +  if not(primep(gf_char)) then error("ERROR: Gf_Char must be a prime number.")
    +    else
    +      modulus:gf_char,
    +  if GF_IRREDUCIBILITY_CHECK and
    +       hipow(args(factor(ars[3]))[1],x)#hipow(rat(ars[3]),x) then
    +      error("ERROR: Polynomial is not irreducible"),
    +
    +  if not(largefield) then
    +     (
    +     pg:mkpowers(),
    +     lg:mklogs()
    +     )
    +  else
    +     (
    +     if GF_VERBOSE then
    +       print("finding a primitive element..."),
    +
    +     gf_prim:rat(gf_findprim(),x),
    +     if GF_VERBOSE then
    +     print("...primitive element found.")
    +
    +     ),
    +  modulus:false, /* it resets the modulus */
    +  return(true)
    +
    +  )$
    +
    +
    +/* Prints out information about the field */
    +gf_info():=block(
    +  print("Prime gf_char value: ",gf_char),
    +  print("Exponent: ", gf_exp),
    +  print("Multiplicative order: ",gf_order),
    +  print("Irreducible polynomial: ",gf_irr),
    +  print("Primitive element: ",gf_prim),
    +  if (largefield) then
    +    print("Largefield flag is true; powers and logarithms not computed.")
    +    else
    +    print("Largefield flag is false; powers and logarithms computed."),
    +  disp()
    +)$
    +
    diff --git a/autotests/html/highlight.mup.html b/autotests/html/highlight.mup.html new file mode 100644 index 0000000..48c6a3b --- /dev/null +++ b/autotests/html/highlight.mup.html @@ -0,0 +1,110 @@ + + + +highlight.mup + +
    +// This is a MUP highlighting test.
    +// Mup is a shareware music publisher from www.arkkra.com
    +
    +// contexts
    +score
    +music
    +staff 1
    +voice 1 3
    +
    +top
    +top2
    +bottom
    +bottom2
    +grids
    +
    +headshapes
    +
    +
    +header
    +footer
    +header2
    +footer2
    +
    +// parameters and values
    +score
    +	units = cm;
    +	key = 3#minor
    +	key = 3# minor
    +	rehstyle=circled 
    +
    +
    +
    +
    +mussym above all: 1 "ferm" ;
    +
    +define NAME
    +// this is a macro definition, these are collapsable
    +@
    +
    +ifdef NAME
    +// this is conditionally "compiled"
    +endif
    +
    +ifndef NAME
    +// this is conditionally "compiled" when the macro has not been defined
    +else
    +// else clause
    +endif
    +
    +
    +// Various Tests 
    +
    +// tablature
    +1: e ^f; f; b ^c5; c#5;
    +bar
    +
    +1: d+^e+ g^a; e+a; g ^/; c ^/ c+^/;
    +bar
    +
    +// cross-staff stems
    +1: 1e+g+c++;
    +2: cc+; ee+; g with g+ above; with c+c++ above;
    +bar
    +
    +1: 2+4ceg;4;    // tie implied by added time values
    +
    +// slurs
    +1: 2f<d> a<b> c+<d+>; dbd+;
    +bar
    +1: 2fac+ slur; dbd+;
    +bar
    +
    +// alternation
    +1: 2c alt 2; 2c+;2g;
    +bar
    +
    +// bar to draw if repeatstart happens to be on new line
    +(dblbar) repeatstart
    +1: [up]8f bm with staff below;a;4s ebm;4s bm with staff below;8b;[len 11]d ebm;
    +2: 4s bm with staff above;8a;b ebm;[down;len 14]b bm with staff above;d;4s ebm;
    +bar
    +
    +// locations
    +3: 2cf; [=h] egc+;
    +1: [cue; with >; =_ch] fa;
    +
    +
    +roll up 1 1 to 1 2: 2; 4;
    +roll down 1 1 to 1 2: 2; 4;
    +
    +lyrics above 1,3 ; below 2,4 ; between 5&6 : "<1.  >Hi, hi";
    +
    +title "page \% of \#"
    +
    +// shaped whole rests
    +1:	4mr;   // use a quarter rest symbol
    +1:	1/4mr;  // use a quadruple whole rest symbol
    +2:	2.. mr;  // use a double-dotted half rest
    +
    +// tuplets
    +1: {4f; g;}3num,4.+2.
    +bar
    +
    +
    diff --git a/autotests/html/highlight.pb.html b/autotests/html/highlight.pb.html new file mode 100644 index 0000000..09a3ee8 --- /dev/null +++ b/autotests/html/highlight.pb.html @@ -0,0 +1,94 @@ + + + +highlight.pb + +
    +; This is a test file for kate's PureBasic highlighting.
    +
    +; BMP2x Converter by Sven Langenkamp
    +
    +UseJPEGImageEncoder()
    +UsePNGImageEncoder()
    +
    +Declare Convert(JPEG)
    +
    +Enumeration 1
    +    #JPEG
    +    #PNG
    +EndEnumeration
    +
    +; BEGIN section
    +
    +
    +; END
    +
    +Global Count
    +Global file.s
    +Global filename.s
    +Global fileext.s
    +Global OutputFormat
    +Global JPEGQuality
    +
    +Count        = 0
    +OutputFormat = 1
    +JPEGQuality  = -1
    +
    +; MAIN PROGRAM------------------------------------------------------------------
    +
    +;Request Options
    +PrintN("Output Format")
    +PrintN("  [1] JPEG")
    +PrintN("  [2] PNG")
    +Print ("> ")
    +OutputFormat = Int(Input())
    +
    +Select OutputFormat
    +    Case #JPEG:
    +        fileext = ".jpg"
    +        ;Request JPEG Quality
    +        PrintN("")
    +        PrintN("JPEG Quality")
    +        PrintN("  [0-10]")
    +        Print ("> ")
    +        JPEGQuality = Int(Input())
    +    
    +    Case #PNG:
    +        fileext = ".png"
    +EndSelect
    +
    +;Convert all BMP files in the current directory
    +ExamineDirectory(0, "", "*.bmp")
    +While NextDirectoryEntry()   
    +    file     = DirectoryEntryName()
    +    filename = GetFilePart(file)
    +    
    +    If LoadImage(0, file)
    +        Select OutputFormat
    +	    Case #JPEG:
    +	      Convert(JPEGQuality)
    +	      
    +	    Case #PNG:
    +	        Convert(-1)
    +	EndSelect
    +	Count = Count +1
    +    EndIf
    +    
    +Wend
    +
    +PrintN(Str(Count) + " files converted")
    +CloseConsole()
    +
    +; PROCUDURES--------------------------------------------------------------------
    +
    +Procedure Convert(JPEG)
    +    Shared filename, fileext
    +    
    +    If JPEG > -1
    +        SaveImage(0, filename + fileext, #PB_ImagePlugin_JPEG, JPEG)
    +    Else
    +        SaveImage(0, filename + fileext, #PB_ImagePlugin_PNG)    
    +    EndIf
    +    PrintN(file + " converted to " + filename + fileext)
    +EndProcedure
    +
    diff --git a/autotests/html/highlight.php.html b/autotests/html/highlight.php.html new file mode 100644 index 0000000..56c772a --- /dev/null +++ b/autotests/html/highlight.php.html @@ -0,0 +1,30 @@ + + + +highlight.php + +
    +<?
    +/* This is a pseudo PHP file to test Kate's PHP syntax highlighting. */
    +# TODO: this is incomplete, add more syntax examples!
    +# this is also a comment.
    +// Even this is a comment
    +function test($varname) {
    +	return "bla";	# this is also a comment
    +}
    +
    +?>
    +
    +<?php echo("hello test"); ?>
    +
    +<html>
    +	<? print "<title>test</title>"; ?>
    +</html>
    +
    +<?php
    +$var = <<<DOOH
    +This is the $string inside the variable (which seems to be rendered as a string)
    +It works well, I think.
    +DOOH
    +?>
    +
    diff --git a/autotests/html/highlight.pike.html b/autotests/html/highlight.pike.html new file mode 100644 index 0000000..7f63985 --- /dev/null +++ b/autotests/html/highlight.pike.html @@ -0,0 +1,31 @@ + + + +highlight.pike + +
    +#! /bin/env pike
    +
    +/* This file is a syntax highlight test for Kate.
    + * FIXME: Improve it to contain more (and more unusual) syntax examples.
    + */
    +
    +
    +#define PIKE_ON_THE_WEB  /* Is this address correct? */  "http://pike.ida.liu.se/"
    +
    +
    +int main(int argc, array(string) args)
    +{
    +  // Write funny things with Pike :)
    +  write(`+("Command line arguments (%d of them): ", @map(args, `+, " ")) + "\n", argc);
    +                             
    +  write("\nVisit Pike site at %s\n\n", PIKE_ON_THE_WEB);
    +
    +  for (int i = 1; i <= 3; i++)
    +    write(":" + ")" * i + "   ");
    +
    +  write("\n" + ({"Bye", "bye"}) * "-" + "!\n");
    +
    +  return 0;
    +}
    +
    diff --git a/autotests/html/highlight.pl.html b/autotests/html/highlight.pl.html new file mode 100644 index 0000000..b72018a --- /dev/null +++ b/autotests/html/highlight.pl.html @@ -0,0 +1,51 @@ + + + +highlight.pl + +
    +#!/usr/bin/perl -w
    +# This is a pseudo Perl file to test Kate's Perl syntax highlighting.
    +# TODO: this is incomplete, add more syntax examples!
    +
    +sub prg($)
    +{
    +	my $var = shift;
    +
    +	$var =~ s/bla/foo/igs;
    +	$var =~ s!bla!foo!igs;
    +	$var =~ s#bla#foo#igs;
    +	$var =~ tr/a-z/A-Z/;
    +	($match) = ($var =~ m/(.*?)/igs);
    +
    +	$test = 2/453453.21;
    +	$test /= 2;
    +
    +	print qq~d fsd fsdf sdfl sd~
    +	
    +	$" = '/';
    +	
    +	$foo = <<__EOF;
    +d ahfdklf klsdfl sdf sd
    +fsd sdf sdfsdlkf sd
    +__EOF
    +
    +	$x = "dasds";
    +
    +	next if( $match eq "two" );
    +	next if( $match =~ /go/i );
    +
    +	@array = (1,2,3);		# a comment
    +	@array = qw(apple foo bar);
    +	push(@array, 4);
    +	%hash = (red => 'rot',
    +		blue => 'blau');
    +	print keys(%hash);
    +}
    +
    +sub blah {
    +}
    +
    +&blah;
    +prg("test");
    +
    diff --git a/autotests/html/highlight.pov.html b/autotests/html/highlight.pov.html new file mode 100644 index 0000000..e566558 --- /dev/null +++ b/autotests/html/highlight.pov.html @@ -0,0 +1,83 @@ + + + +highlight.pov + +
    +//BEGIN TEST
    +// test scene for POV-Ray syntax highlighting
    +
    +/* test comment */
    +
    +/* nested /* comments */ do not work */
    +
    +#version 3.5;
    +//END
    +global_settings { assumed_gamma 1.0 }
    +
    +// ----------------------------------------
    +
    +camera {
    +  location  <5.0, -12.0, 2.0>
    +  up z sky z
    +  look_at   <0.0, 0.0, 0.5> 
    +  angle 40
    +}
    +
    +sky_sphere {
    +  pigment {
    +    gradient z
    +    color_map {
    +      [0.0 rgb <0.6,0.7,1.0>]
    +      [0.2 rgb <0.2,0.3,0.9>]
    +    }
    +  }
    +}
    +
    +light_source {
    +  <3, 1, 2>*1000
    +  color rgb <2.2, 1.8, 1.5>
    +}   
    +
    +// ----------------------------------------
    +
    +#declare TEST=0;
    +
    +#ifdef (TEST)
    +  plane {
    +    z, 0
    +    texture {
    +      pigment {
    +        checker
    +        color rgb 1, color rgb 0
    +      }
    +    }
    +  }
    +#end
    +
    +#macro Sphere(Pos, Radius)
    +  sphere {
    +    <Pos.x, Pos.y, Radius*1.3>, Radius
    +    texture {
    +      pigment { color rgb 1 }
    +      finish{
    +        diffuse 0.3
    +        ambient 0.0
    +        specular 0.6
    +        reflection 0.8
    +      }
    +    }
    +  }
    +#end
    +
    +#local Cnt=0;
    +#local Seed=seed(0);
    +
    +#while (Cnt<10000)
    +  Sphere(
    +    -100+<rand(Seed), rand(Seed)>*200, 
    +    0.3+pow(rand(Seed),2)*0.7
    +  )  
    +  #local Cnt=Cnt+1;
    +#end
    +
    diff --git a/autotests/html/highlight.prg.html b/autotests/html/highlight.prg.html new file mode 100644 index 0000000..cc6f18a --- /dev/null +++ b/autotests/html/highlight.prg.html @@ -0,0 +1,78 @@ + + + +highlight.prg + +
    +// Test file to test kate's clipper highlighting
    +// kate: hl Clipper;
    +
    +//BEGIN INCLUDES
    +#include <clip-ui.ch>
    +#include "logo.ch"
    +
    +#define PRGVERSION	"0.0.1"
    +//END
    +
    +//BEGIN CODE
    +static ws, win
    +static driver := getDriver()
    +/* a multiline
    +     comment
    +*/
    +
    +function main( formName )
    +	local form
    +	local fileName
    +
    +	if empty(formName)
    +		?? "Usage: ./form_ui <form.xfl>&\n"
    +		CANCEL
    +	else
    +		fileName := formName
    +	endif
    +	ws  := UIWorkSpace()
    +
    +	form := UIForm( fileName )
    +	win  := form:parseFile()
    +//	?? valtype(win),chr(10)
    +	if win == NIL
    +		CANCEL
    +	endif
    +	win:show()
    +
    +	ws:run()
    +	ws:quit()
    +return 0
    +
    +/* Setting dialog */
    +function settingsDialog()
    +	?? "TODO: Settings dialog&\n"
    +return
    +
    +/* About dialog */
    +function aboutDialog()
    +	local dlg := UIWindow("About", win, "aboutDlg", .F.)
    +	local hl, lside, t, bb, bD
    +
    +	hl  := UIHBox(,4,8)
    +	lside := UIVBox()
    +	lside:add(UIImage(eas_logo_mini,.T.))
    +	hl:add(lside,.F.,.F.)
    +	dlg:userSpace:add(hl,.T.,.T.)
    +	t   := UIVBox()
    +	hl:add(t,.T.,.T.)
    +
    +	t:add(UILabel("License: GPL version 2 or later"))
    +	bb  := UIButtonBar()
    +	t:add(bb)
    +	bD := UIButton(win, "&Close", {|o,e| dlg:close() } )
    +	bb:add( bD )
    +
    +	dlg:setFocus(bD)
    +	dlg:setDefault(bD)
    +	dlg:setPlacement( .T. )
    +	dlg:show()
    +return
    +//END
    +
    diff --git a/autotests/html/highlight.qml.html b/autotests/html/highlight.qml.html new file mode 100644 index 0000000..e74d91c --- /dev/null +++ b/autotests/html/highlight.qml.html @@ -0,0 +1,66 @@ + + + +highlight.qml + +
    +import Qt 4.6
    +
    +// some random qml snippets stolen from the qt docs
    +
    +Rectangle {
    +    important: true
    +    propertyAsdf:
    +    id: container
    +    signalA: bla
    +    property string label
    +    signal clicked
    +    radius: 5; border.color: "black"
    +    color: mouse.pressed ? "steelblue" : "lightsteelblue"
    +    gradient: Gradient {
    +            GradientStop { position: mouse.pressed ? 1.0 : 0.0; color: "steelblue" }
    +            GradientStop { position: mouse.pressed ? 0.0 : 1.0; color: "lightsteelblue" }
    +    }
    +    MouseRegion { id: mouse; anchors.fill: parent; onClicked: container.clicked() }
    +    Text { anchors.fill: parent; text: container.label; anchors.centerIn: parent }
    +}
    +
    +Rectangle {
    +    Script {
    +        function calculateMyHeight() {
    +            return Math.max(otherItem.height, thirdItem.height);
    +        }
    +    }
    +
    +    anchors.centerIn: parent
    +    width: Math.min(otherItem.width, 10)
    +    height: calculateMyHeight()
    +    color: { if (width > 10) "blue"; else "red" }
    +}
    +
    +Rectangle {
    +    default property color innerColor: "black"
    +    property color innerColor: "black"
    +    property alias text: textElement.text
    +    property alias aliasXYZ: testElement.text
    +    signal bar
    +    signal bar(var blah, string yxcv)
    +    width: 240; height: 320;
    +    width: 100; height: 30; source: "images/toolbutton.sci"
    +    ListView {
    +        anchors.fill: parent
    +        model: contactModel
    +        delegate: Component {
    +            Text {
    +                text: modelData.firstName + " " + modelData.lastName
    +            }
    +        }
    +    }
    +}
    +
    +Item {
    +    function say(text) {
    +        console.log("You said " + text);
    +    }
    +}
    +
    diff --git a/autotests/html/highlight.rb.html b/autotests/html/highlight.rb.html new file mode 100644 index 0000000..8e2bb99 --- /dev/null +++ b/autotests/html/highlight.rb.html @@ -0,0 +1,558 @@ + + + +highlight.rb + +
    +# This file is a testcase for the highlighting of Ruby code
    +# It's not executable code, but a collection of code snippets
    +#
    +
    +require 'Config'
    +require 'DO/Clients'
    +require 'DO/DBClients'
    +
    +  def CGI::escapeElement(string, *elements)
    +    elements = elements[0] if elements[0].kind_of?(Array)
    +    unless elements.empty?
    +      string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/ni) do
    +        CGI::escapeHTML($&)
    +      end
    +    else
    +      string
    +    end
    +  end
    +
    +case inputLine
    +  when "debug"
    +    dumpDebugInfo
    +    dumpSymbols
    +  when /p\s+(\w+)/
    +    dumpVariable($1)
    +  when "quit", "exit"
    +    exit
    +  else
    +    print "Illegal command: #{inputLine}"
    +end
    +
    +
    +kind = case year #hi there
    +         when 1850..1889 then "Blues"
    +         when 1890..1909 then "Ragtime"
    +         when 1910..1929 then "New Orleans Jazz"
    +         when 1930..1939 then "Swing"
    +         when 1940..1950 then "Bebop"
    +         else                 "Jazz"
    +       end
    +
    +  # URL-encode a string.
    +  #   url_encoded_string = CGI::escape("'Stop!' said Fred")
    +  #      # => "%27Stop%21%27+said+Fred"
    +  def CGI::escape(string)
    +    string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do
    +      '%' + $1.unpack('H2' * $1.size).join('%').upcase
    +    end.tr(' ', '+')
    +  end
    +
    +
    +# Class ClientManager
    +#
    +# definition : Import, store and export the various data used by the application.
    +# This class is the sole interface between the application and the underlying database.
    +
    +mon, day, year = $1, $2, $3 if /(\d\d)-(\d\d)-(\d\d)/
    +puts "a = #{a}" if fDebug
    +print total unless total == 0
    +
    +while gets
    +  next if /^#/            # Skip comments
    +  parseLine unless /^$/   # Don't parse empty lines
    +end
    +
    +if artist == "John Coltrane" #hi there
    +  artist = "'Trane" #hi there
    +end unless nicknames == "no" #hi there
    +
    +handle = if aSong.artist == "Gillespie" then #hi there
    +           "Dizzy"
    +         elsif aSong.artist == "Parker" then
    +           "Bird"
    +         else #hi there
    +           "unknown"
    +         end
    +
    +if aSong.artist == "Gillespie" then  handle = "Dizzy"
    +elsif aSong.artist == "Parker" then  handle = "Bird"
    +else  handle = "unknown"
    +end #hi there
    +
    +if aSong.artist == "Gillespie" then
    +  handle = "Dizzy"
    +elsif aSong.artist == "Parker" then
    +  handle = "Bird"
    +else
    +  handle = "unknown"
    +end
    +
    +if aSong.artist == "Gillespie"
    +  handle = "Dizzy"
    +elsif aSong.artist == "Parker"
    +  handle = "Bird"
    +else
    +  handle = "unknown"
    +end
    +
    + case line
    +  when /title=(.*)/
    +    puts "Title is #$1"
    +  when /track=(.*)/
    +    puts "Track is #$1"
    +  when /artist=(.*)/
    +    puts "Artist is #$1"
    +end
    +
    +case shape
    +  when Square, Rectangle
    +    # ...
    +  when Circle
    +    # ...
    +  when Triangle
    +    # ...
    +  else
    +    # ...
    +end 
    +
    +
    +until playList.duration > 60 #hi there
    +  playList.add(songList.pop)
    +end
    +
    +3.times do
    +  print "Ho! "
    +end
    +
    +loop {
    +  # block ...
    +}
    +
    +songList.each do |aSong|
    +  aSong.play
    +end
    +
    +for aSong in songList
    +  aSong.play
    +end
    +
    +for i in ['fee', 'fi', 'fo', 'fum']
    +  print i, " "
    +end
    +for i in 1..3
    +  print i, " "
    +end
    +for i in File.open("ordinal").find_all { |l| l =~ /d$/}
    +  print i.chomp, " "
    +end
    +
    +class Periods
    +  def each
    +    yield "Classical"
    +    yield "Jazz"
    +    yield "Rock"
    +  end
    +end
    +
    +
    +periods = Periods.new
    +for genre in periods
    +  print genre, " "
    +end
    +
    +while gets
    +  next if /^\s*#/   # skip comments
    +  break if /^END/   # stop at end
    +                    # substitute stuff in backticks and try again
    +  redo if gsub!(/`(.*?)`/) { eval($1) }
    +  # process line ...
    +end
    +
    +i=0
    +loop do
    +  i += 1
    +  next if i < 3
    +  print i
    +  break if i > 4
    +end
    +
    +for i in 1..100
    +  print "Now at #{i}. Restart? "
    +  retry if gets =~ /^y/i
    +end
    +
    +def doUntil(cond)
    +  yield
    +  retry unless cond
    +end
    +
    +i = 0
    +doUntil(i > 3) {
    +  print i, " "
    +  i += 1
    +}
    +
    +def system_call
    +	# ... code which throws SystemCallError
    +rescue SystemCallError
    +	$stderr.print "IO failed: " + $!
    +	opFile.close
    +	File.delete(opName)
    +	raise
    +end
    +
    +class ClientManager
    +	
    +	# constructor
    +	def initialize(dbase)
    +		@dbClient = DBClient.new(dbase)
    +		@clients = Clients.new
    +	end
    +	
    +	def prout(a, b, xy="jj") 24 end 
    +	###############################################################
    +	#
    +	# CLIENTS SECTION
    +	#
    +	###############################################################
    +	
    +	# update the clients object by retrieving the related data from the database
    +	# returns the number of clients
    +	def refreshClients
    +		@clients.clean
    +		unless @sqlQuery.nil? then
    +			@sqlQuery.selectClient.each do |row|
    +				@clients.addClient(row[0],row[1],row[2],row[3],row[4],row[5], row[6], row[7], row[8])
    +			end
    +		else
    +			puts "SqlQuery wasn't created : cannot read data from database"
    +		end
    +		return @clients.length
    +	end
    +	
    +	# insert a client in the database and refreshes the local clients object
    +	# we assume that none of the arguments is null
    +	# we assume that the client, identified by raison_sociale doesn't already exists
    +	def addClient(raison_sociale, division, departement, adresse, cp, ville, nom_contact, tel_contact)
    +		id = "0"
    +		unless @sqlQuery.nil? then
    +			id = @sqlQuery.insertClient(raison_sociale, division, departement, adresse, cp, ville, nom_contact,tel_contact)
    +		else
    +			puts "SqlQuery wasn't created : database update cannot be performed"
    +		end
    +		@clients.addClient(id, raison_sociale, division, departement, adresse, cp, ville, nom_contact, tel_contact) # synchronize local object with DB
    +	end
    +	
    +	# deletes a client from the database and updates the local Clients object accordingly
    +	def delClient(nomclient_brut)
    +		raison_sociale, div, dep = Clients.getIdentifiers(nomclient_brut)
    +		listeContratsExp, listeContratsSup, listeContratsProd, listePropositionsExp, listePropositionsSup = []
    +
    +		listeContratsExp = @contratsExpertise.getContratsFromClient(nomclient_brut)
    +		listeContratsSup = @contratsSupport.getContratsFromClient(nomclient_brut)
    +		listeContratsProd = @contratsProduits.getContratsFromClient(nomclient_brut)
    +		listePropositionsExp = @propositionsExpertise.getPropositionsFromClient(nomclient_brut)
    +		listePropositionsSup = @propositionsSupport.getPropositionsFromClient(nomclient_brut)
    +		
    +		unless @sqlQuery.nil? then
    +			@sqlQuery.deleteClient(raison_sociale, div, dep)
    +			
    +			@sqlQuery.deleteContracts(Config::EXPERTISE,listeContratsExp) 
    +			@sqlQuery.deleteContracts(Config::SUPPORT,listeContratsSup)
    +			@sqlQuery.deleteContracts(Config::PRODUIT,listeContratsProd)
    +			@sqlQuery.deletePropositions(Config::EXPERTISE,listePropositionsExp)
    +			@sqlQuery.deletePropositions(Config::SUPPORT,listePropositionsSup)
    +		else
    +			puts "SqlQuery wasn't created : database update cannot be performed"
    +		end
    +		@clients.delClient(raison_sociale,div,dep)
    +	
    +		@contratsExpertise.deleteContracts(listeContratsExp)
    +		@contratsSupport.deleteContracts(listeContratsSup)
    +		@contratsProduits.deleteContracts(listeContratsProd)
    +		@propositionsExpertise.deletePropositions(listePropositionsExp)
    +		@propositionsSupport.deletePropositions(listePropositionsSup)
    +	end
    +end
    +
    +  # Mixin module for HTML version 3 generation methods.
    +  module Html3 # :nodoc:
    +
    +    # The DOCTYPE declaration for this version of HTML
    +    def doctype
    +      %|<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">|
    +    end
    +
    +    # Initialise the HTML generation methods for this version.
    +    def element_init
    +      extend TagMaker
    +      methods = ""
    +      # - -
    +      for element in %w[ A TT I B U STRIKE BIG SMALL SUB SUP EM STRONG
    +          DFN CODE SAMP KBD VAR CITE FONT ADDRESS DIV center MAP
    +          APPLET PRE XMP LISTING DL OL UL DIR MENU SELECT table TITLE
    +          STYLE SCRIPT H1 H2 H3 H4 H5 H6 TEXTAREA FORM BLOCKQUOTE
    +          CAPTION ]
    +        methods += <<-BEGIN + nn_element_def(element) + <<-END
    +          def #{element.downcase}(attributes = {})
    +        BEGIN
    +          end
    +        END
    +      end
    +
    +      # - O EMPTY
    +      for element in %w[ IMG BASE BASEFONT BR AREA LINK PARAM HR INPUT
    +          ISINDEX META ]
    +        methods += <<-BEGIN + nOE_element_def(element) + <<-END
    +          def #{element.downcase}(attributes = {})
    +        BEGIN
    +          end
    +        END
    +      end
    +
    +      # O O or - O
    +      for element in %w[ HTML HEAD BODY P PLAINTEXT DT DD LI OPTION tr
    +          th td ]
    +        methods += <<-BEGIN + nO_element_def(element) + <<-END
    +          def #{element.downcase}(attributes = {})
    +        BEGIN
    +          end
    +        END
    +      end
    +      eval(methods)
    +    end
    +
    +  end
    +
    +# following snippet from Webrick's log.rb
    +# notice the erronous handling of the query method is_a?
    +def format(arg)
    +     str = if arg.is_a?(Exception)
    +        "#{arg.class}: #{arg.message}\n\t" <<
    +        arg.backtrace.join("\n\t") << "\n"
    +      elsif arg.respond_to?(:to_str)
    +        arg.to_str
    +      else
    +        arg.inspect
    +      end
    +end
    +
    +# following snippet from Webrick's httputils.rb
    +# Splitting regexps on several lines might be bad form,
    +# but not illegal in Ruby. 
    +# This should probably be supported in the highlighting
    +def split_header_value(str)
    +      str.scan(/((?:"(?:\\.|[^"])+?"|[^",]+)+)
    +                (?:,\s*|\Z)/xn).collect{|v| v[0] }
    +end
    +
    +# snippet from Net::Telnet
    +string.gsub(/#{IAC}(
    +                   [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]|
    +                   [#{DO}#{DONT}#{WILL}#{WONT}]
    +                     [#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]|
    +                   #{SB}[^#{IAC}]*#{IAC}#{SE}
    +                 )/xno)
    +
    +# following snippet from Webrick's httpresponse.rb
    +# the HEREDOC is not recognized as such
    +@body << <<-_end_of_html_
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
    +<HTML>
    +  <HEAD><TITLE>#{HTMLUtils::escape(@reason_phrase)}</TITLE></HEAD>
    +  <BODY>
    +    <H1>#{HTMLUtils::escape(@reason_phrase)}</H1>
    +    #{HTMLUtils::escape(ex.message)}
    +    <HR>
    +_end_of_html_
    +
    +
    +# snippet from Webrick's httpproxy.rb
    +# here we should make sure that the symbol definition ':' doesn't override
    +# the module operator '::'
    +Net::HTTP::version_1_2 if RUBY_VERSION < "1.7"
    +
    +# snippet from Webrick's cookie.rb
    +# the beginning of the regexp is erronously highlighted like an operator
    +key, val = x.split(/=/,2)
    +
    +# the following are division operators
    +# it's a bit tricky to keep the operator apart from the regexp
    +result = 8 / 4
    +result /= divisor
    +
    +# 2008-06-01 regexp and division operator syntax has been fixed:
    +result = 8/4    # division
    +result = 8/foo  # division
    +result = /8/    # regexp
    +result = 8//4/  # division and regexp
    +
    +10/10           # division
    +10/ 10          # division
    +10 /10          # division
    +10 / 10         # division
    +
    +foo/10          # division
    +foo/ 10         # division
    +foo /10/        # regexp
    +foo / 10        # division
    +
    +foo/10/10       # both division
    +total/count/2   # both division
    +total/(count/2) # both division
    +
    +@foo/10         # division
    +@foo /10        # division
    +
    +"hello"/10      # division
    +"hello" / 10    # division
    +
    +/regexp//10     # division
    +/regexp/ / 10   # division
    +
    +Math::PI/10     # division
    +Math::foo /rx/  # regexp
    +
    +# 2008-06-05 similar fix for modulo operator:
    +
    +10%4            # modulo
    +10 %4           # modulo
    +10% 4           # modulo
    +10 % 4          # modulo
    +
    +foo%4           # modulo
    +# foo %4          # illegal %string
    +foo% 4          # modulo
    +foo % 4         # modulo
    +
    +foo % (4)       # modulo
    +
    +foo %(4)        # %string
    +foo %q(4)       # %string
    +foo %Q(4)       # %string
    +foo %%4%        # %string
    +
    +foo = %|blah|   # GDL input
    +foo % %|blah|   # modulo and GDL
    +
    +# mix in any way you want
    +result = 10//regexp//20/foo//regexp//20
    +
    +# test cases for general delimited input
    +# quoted strings
    +%Q|this is a string|
    +%Q{this is a string}
    +%Q(this is a string)
    +%Q<this is a string>
    +%Q[this is a string]
    +
    +%|also a string|
    +%{also a string}
    +%(also a string)
    +%<also a string>
    +%[also a string]
    +
    +# apostrophed strings
    +%q|apostrophed|
    +%q{apostrophed}
    +%q(apostrophed)
    +%q<apostrophed>
    +%q[apostrophed]
    +
    +# regular expressions
    +%r{expression}
    +%r(expression)
    +%r<expression>
    +%r[expression]
    +%r|expression|
    +
    +# shell commands
    +%x{ls -l}
    +%x(ls -l)
    +%x<ls -l>
    +%x[ls -l]
    +
    +# sometimes it's useful to have the command on multiple lines
    +%x{ls -l |
    +grep test }
    +
    +# alternative syntax
    +`ls -l`
    +`echo ' '`
    +
    +# token array
    +%w{one two three}
    +%w(one two three)
    +%w<one two three>
    +%w[one two three]
    +
    +# snippet from Net::IMAP
    +# I object to putting String, Integer and Array into kernel methods.
    +# While these classes are builtin in Ruby, this is an implementation detail
    +# that should not be exposed to the user.
    +# If we want to handle all std-lib classes, fine. But then they should be in their
    +# own std-lib keyword category.
    +
    +def send_data(data)
    +      case data
    +      when nil
    +        put_string("NIL")
    +      when String
    +        send_string_data(data)
    +      when Integer
    +        send_number_data(data)
    +      when Array
    +        send_list_data(data)
    +      when Time
    +        send_time_data(data)
    +      when Symbol
    +        send_symbol_data(data)
    +      else
    +        data.send_data(self)
    +      end
    +end
    +
    +# snippet from Net::POP
    +# class names can have numbers in them as long as they don't begin with numbers
    +# Ruby doesn't internally really make much of a difference between a class name and a constant
    +
    +# class aliases
    +  POP = POP3
    +  POPSession  = POP3
    +  POP3Session = POP3
    +
    +# "member access"
    +POP::Session.COUNT.attribute.calc_with(2){ |arg| puts arg }
    +
    +# snippet from Net::SMTP
    +# This breaks the code folding. I think we would need to
    +# handle the '\' that continues the statement to the next line
    +# in some way to make these kind of things not break something.
    +raise ArgumentError, 'both user and secret are required'\
    +                      unless user and secret
    + 
    +# string escapes must detect escaping the escape char
    +str = "\\"
    +str = "\\\\"
    +# this is not part of the string
    +%x{echo \\\}\\}	# prints \}\
    +# this is not part of the command
    +
    +# these are all symbols
    +:abc
    +:abc!
    +:abc?
    +:abc=
    +:[]
    +:[]=
    +:@abc
    +:@@abc
    +:$abc
    +
    diff --git a/autotests/html/highlight.scheme.html b/autotests/html/highlight.scheme.html new file mode 100644 index 0000000..e83b790 --- /dev/null +++ b/autotests/html/highlight.scheme.html @@ -0,0 +1,193 @@ + + + +highlight.scheme + +
    +; This is a test file to test kates scheme highlighting
    +; This is a comment
    +
    +;; Another comment, usually used.
    +;BEGIN region marker
    +;; a vektor
    +#(1 2 3 4 5)
    +;END region marker
    +;; this represents integer 28 (FIXME: does not work perfectly atm!)
    +28 028 #e28 #i28       ;; Normal, normal, exact, inexact
    +#b11100 #o34 #d28 #x1c ;; Bin, okt, dec, hex
    +#oe34 #eo34            ;; combined.
    +
    +;; char.
    +(#\y #\space) ;; list: `y' space.
    +(#\  #\\ #\)) ;; list of spaces, backslash and`)'.
    +#\newline     ;; a newline-char
    +#\NewLine     ;; another one :)
    +
    +"Hello, world" ;; a string
    +
    +"hoho, what do you
    +want to do  ;; this is NO comment
    +with that?"
    +
    +;; R5RS definiert diese beiden.
    +"Das ist \"in Anführungszeichen\" und mit \\ Backslash."
    +
    +(let ((x (+ 1 2)) (y "blah")) ;; `let' highlighting.
    +  (and (number? x)            ;; `and' highlighting.
    +       (string? y)))
    +
    +(let* ((x 2) (y (+ x 1))) ;; `let*' too.
    +  (or (negative? x)       ;; `or' anyways.
    +      (negative? y)))
    +
    +(do ((vec (make-vector 5)) ;; `do' you may guess!
    +     (i 0 (+ i 1)))
    +    ((= i 5) vec)
    +  (vector-set! vec i i))
    +
    +(quasiquote ((+ 1 2) (unquote (+ 1 2))))
    +;; same as: `((+ 1 2) ,(+ 1 2))
    +
    +;; see above.
    +(quasiquote ((+ 1 2) (unquote-splicing (list 1 2 3))))
    +;; same as: `((+ 1 2) ,@(+ 1 2))
    +
    +;; not necessary.
    +(quote ())
    +
    +(cond ((string? x) (string->symbol x)) ;; `cond' highlighting.
    +      ((symbol? x) => (lambda (x) x))  ;; `=>' highlighting.
    +      (else ;; `else' highlighting.
    +       (error "Blah")))
    +
    +(case x ;; `case' highlighting.
    +  ((#t) 'true) ((#f) 'false)
    +  ((()) 'null)
    +  ((0) 'zero))
    +
    +;; highlight `let-syntax' and `syntax-rules' .
    +(let-syntax ((when (syntax-rules ()
    +                     ((when test stmt1 stmt2 ...)
    +                      ;; hl `begin' .
    +                      (if test (begin stmt1 stmt2 ...))))))
    +  (let ((if #t)) ;; here`if' is actually no keyword.
    +    (when if (set! if 'now)) ;; nor here.
    +    if))
    +
    +(letrec-syntax ...) ;; hl `letrec-syntax'.
    +
    +(define-syntax when
    +  (syntax-rules ()
    +    ((when test stmt1 stmt2 ...)
    +     (if test (begin stmt1 stmt2 ...))))))
    +
    +;; variable definitions.
    +(define natural-numbers ;; hl `define' and the var name
    +  ;; endless stream of all natual numbers.
    +  (letrec ((next-cell    ;; hl `letrec'.
    +            (lambda (x)  ;; hl `lambda'.
    +              ;; hl `delay' .
    +              (cons x (delay (next-cell (+ x 1)))))))
    +    (next-cell 0)))
    +
    +;; a procedure with unusual but allowed name.
    +(define 1+
    +  (lambda (x)
    +    (+ x 1)))
    +
    +;; a predicate
    +(define between?
    +  (lambda (x y z)
    +    (if (and (>= x y) (<= x z))
    +        #t ;; True
    +      #f))) ;; False.
    +
    +;; imperative procedure
    +(define set-something!
    +  (lambda (required-argument another-one . all-remaining-args)
    +    (set-car! another-one (lambda all-args
    +                            (set-cdr! required-argument
    +                                      (append all-remaining-args
    +                                              all-args))))))
    +
    +(define compose
    +  (lambda (f g)
    +    (lambda (x)
    +      (f (g x)))))
    +
    +;; syntactical sugar for procedure-definitions.
    +(define (compose f g)
    +  (lambda (x)
    +    (f (g x))))
    +
    +;;;;;;;;;;;;;;;;;;;;;;;;;;;
    +;; NOW: Guile extensions ;;
    +;;;;;;;;;;;;;;;;;;;;;;;;;;;
    +
    +;; procedure-generator.
    +(define ((compose f g) x)
    +  (f (g x)))
    +
    +;; scheme doesn't say, which chars may be in variables...
    +;; At least: Guile accepts umlauts
    +(define-private (timetr??? sprache) ;; hl `define-private'.
    +  (list-dialekt? sprache))
    +
    +(define-public x #t)  ;; hl `define-public'.
    +(define-module (foo bar)) ;; hl `define-module'.
    +(define-macro (neither . exprs) ;; hl `define-macro'.
    +  `(and ,@(map (lambda (x) `(not ,x)) exprs)))
    +
    +(defmacro neither exprs ;; `defmacro' as well.
    +  `(and ,@(map (lambda (x) `(not ,x)) exprs)))
    +
    +;; hl, but I really don't know what this is supposed to do :-)
    +(define-syntax-macro ...)
    +
    +;; hl GOOPS-`defines'
    +(define-method (foo bar (baz <vector>) qux) ...)
    +(define-class <foo> ...)
    +(define-generic foo)
    +(define-accessor bar)
    +
    +;; Keywords!
    +(blah #:foo 33 #:bar 44)
    +
    +;; another convention for symbols:
    +#{foo}#
    +
    +#{a
    +few
    +lines}#
    +
    +#{4711}#
    +
    +;; more chars.
    +#\nul #\nl #\esc #\bs #\bel #\syn #\ack #\sp ;; etc, utc, itc, oops (this is boring)
    +
    +#!
    + guile block-comment.
    +!#
    +
    +;; now, a bit hairy:
    +#! comment !#
    +still comment!!!
    +!#
    +'now-no-comment-anymore
    +
    +;; more precise:
    +#! comment !#
    +still comment
    +!# still comment!
    +!#
    +'now-no-comment-anymore
    +
    +(while (> foo 10) ;; Highlight `while'.
    +  (set! foo (- foo 1))
    +  (catch #t ;; Highlight `catch'.
    +    (lambda () (display foo))
    +    (lambda (key . args)
    +      (if (eq? key 'system-error)
    +          (break) ;; Highlight `break'.
    +        (continue))))) ;; Highlight `continue'.
    +
    diff --git a/autotests/html/highlight.sh.html b/autotests/html/highlight.sh.html new file mode 100644 index 0000000..b661a14 --- /dev/null +++ b/autotests/html/highlight.sh.html @@ -0,0 +1,214 @@ + + + +highlight.sh + +
    +#! /bin/sh
    +# This is a test script for the Katepart Bash Syntax Highlighting by
    +#	Wilbert Berendsen.  This is not runnable !!!
    +
    +
    +# The highlighting recognizes basic types of input, and has a few special cases that
    +# are all in FindCommands.  The main objective is to create really proper nesting of
    +# (multiline) strings, variables, expressions, etc.
    +
    +
    +
    +# ============== Tests: ===============
    +
    +# basic types:
    +echo 'single quoted string'
    +echo "double quoted string"
    +echo $'string with esc\apes\x0din it'
    +echo $"string meant to be translated"
    +
    +
    +# comments:
    +# this is a comment
    +#this too
    +echo this is#nt a comment
    +dcop kate EditInterface#1 #this is
    +
    +
    +# brace expansion
    +mv my_file.{JPG,jpg}
    +
    +
    +# special characters are escaped:
    +echo \(output\) \&\| \> \< \" \' \*
    +
    +
    +# variable substitution:
    +echo $filename.ext
    +echo $filename_ext
    +echo ${filename}_ext
    +echo text${array[$subscript]}.text
    +echo text${array["string"]}.text
    +echo ${!prefix*}
    +echo ${!redir}
    +echo short are $_, $$, $?, ${@}, etc.
    +echo ${variable/a/d}
    +echo ${1:-default}
    +
    +
    +# expression subst:
    +echo $(( cd << ed + 1 ))
    +
    +
    +# command subst:
    +echo $(ls -l)
    +echo `cat myfile`
    +
    +
    +# file subst:
    +echo $(<$filename)
    +echo $(</path/to/myfile)
    +
    +# process subst:
    +sort <(show_labels) | sed 's/a/bg' > my_file.txt 2>&1
    +
    +
    +# All substitutions also work in strings:
    +echo "subst ${in}side string"  'not $inside this ofcourse'
    +echo "The result is $(( $a + $b )). Thanks!"
    +echo "Your homedir contains `ls $HOME |wc -l` files."
    +
    +
    +# Escapes in strings:
    +p="String \` with \$ escapes \" ";
    +
    +
    +# keywords are black, builtins dark purple and common commands lighter purple
    +set
    +exit
    +login
    +
    +
    +# Other colorings:
    +error() {
    +	cat /usr/bin/lesspipe.sh
    +	runscript >& redir.bak
    +	exec 3>&4
    +}
    +
    +
    +# do - done make code blocks
    +while [ $p -lt $q ] 
    +do
    +	chown 0644 $file.$p
    +done
    +
    +
    +# braces as well
    +run_prog | sort -u |
    +{
    +	echo Header
    +	while read a b d
    +	do
    +		echo $a/$b/$c
    +	done
    +	echo Footer
    +}
    +
    +
    +# Any constructions can be nested:
    +echo "A long string with $(
    +	if [ $count -gt 100 ] ; then
    +		echo "much"
    +	else
    +		echo "not much"
    +	fi ) substitutions." ;
    +
    +
    +# Even the case construct is correctly folded:
    +test -f blaat &&
    +(	do_something
    +	case $p in
    +		*bak)
    +			do_bak $p
    +			;;
    +		*)
    +			dont_bak $p
    +			;;
    +	esac
    +) # despite the extra parentheses in the case construction.
    +
    +
    +# variable assignments:
    +DIR=/dev
    +p=`ls`
    +LC_ALL="nl" dcop 'kate*'
    +_VAR=val
    +ARR=(this is an array)
    +ARR2=([this]=too [and]="this too")
    +usage="$0 -- version $VERSION
    +Multiple lines of output
    +can be possible."
    +ANSWER=yes	# here 'yes' isn't highlighed as command
    +
    +
    +# Some commands expect variable names, these are colored correctly:
    +export PATH=/my/bin:$PATH BLAAT
    +export A B D
    +local p=3  x  y='\'
    +read x y z <<< $hallo
    +unset B
    +declare -a VAR1 VAR2 && exit
    +declare less a && b 
    +
    +# options are recoqnized:
    +zip -f=file.zip
    +./configure  --destdir=/usr
    +make  destdir=/usr/
    +
    +
    +# [[ and [ correctly need spaces to be regarded as structure,
    +# otherwise they are patterns (currently treated as normal text)
    +if [ "$p" == "" ] ; then
    +	ls /usr/bin/[a-z]*
    +elif [[ $p == 0 ]] ; then
    +	ls /usr/share/$p
    +fi
    +
    +# Fixed:
    +ls a[ab]*		# dont try to interprete as assignment with subscript (fixed)
    +a[ab]
    +a[ab]=sa
    +
    +
    +# Here documents are difficult to catch:
    +cat > myfile << __EOF__
    +You're right, this is definitely no bash code
    +But ls more $parameters should be expanded.
    +__EOF__
    +
    +
    +# quoted:
    +cat << "EOF" | egrep "this" >&4   # the rest of the line is still considered bash source
    +You're right, this is definitely no bash code
    +But ls more $parameters should be expanded. :->
    +EOF
    +
    +
    +# indented:
    +if true
    +then
    +	cat <<- EOF
    +		Indented text with a $dollar or \$two
    +	EOF
    +elif [ -d $file ]; then
    +	cat <<- "EOF"
    +		Indented text without a $dollar
    +	EOF
    +fi
    +
    +
    +case 1 in 
    +2) echo xxx;
    +;;
    +1) echo yyy;
    +esac
    +
    +ls #should be outside of case 1 folding block
    +
    diff --git a/autotests/html/highlight.spec.html b/autotests/html/highlight.spec.html new file mode 100644 index 0000000..459655b --- /dev/null +++ b/autotests/html/highlight.spec.html @@ -0,0 +1,219 @@ + + + +highlight.spec + +
    +# Test file for rpmspec.xml
    +
    +# Comments start with a # in column="0":
    +
    +# Some comment
    +
    +# When they don't start in column="0", that they are recognized as comments, but with an alert:
    + # This is a bad comment.
    +# RPM spec says clear that comments must start at the begin of the line. However, in practice
    +# the RPM software is more permissive, depending on the context. But for our syntax highlighting,
    +# we give, while recognizing the as comment, at least a little alert. Comments should not contain
    +# the character % (which is marked as warning), but 2 of them are okay: %%. TODO is higlighted.
    +
    +# A spec file starts with "Normal" context. Here, you can specify values for some tags:
    +Name:                kradioripper-unstable # Note that here in no comment possible!
    +Name:                name only _one_ word allowed
    +Name:                %macro no further syntax check after macro!
    +# Some tags support only _one_ word as value
    +Version:             0.4test5 up-from-the-space-this-is-an-error
    +# Some tag can have parameters: Any char in paranthesis:
    +Summary:             Recorder for internet radios (based on Streamripper)  
    +Summary(de.UTF-8):   Aufnahmeprogramm für Internetradios (basiert auf Streamripper)
    +# requiere free text:
    +License:             License 1 2 3
    +# requiere a well defines value:
    +Requires( / (  = ):  Some, value()
    +# new type "switch" accepts: yes, no, 0, 1
    +AutoReq: yes
    +AutoReq: yes invalid
    +AutoReq: %macro no further syntax check after macro!
    +AutoReq: no
    +AutoReq: 0
    +AutoReq: 1
    +# requiere a number:
    +Epoch:               123123
    +Epoch:               123123 invalid
    +Epoch:               %macro no further syntax check afer macro!
    +# If tags are used that are not known, they are not highlighted:
    +Invalidtag:          Some value
    +Invalid content in this section (only tags are allowed)
    +  
    +# You can use conditions in specs (highlighted with region markers):
    +%if 0%{?mandriva_version}  
    +# numbers and strings are distingished: string:
    +%if lsdksfj
    +# number:
    +%if 23472398
    +# string:
    +%if lksdjfsl72939
    +# invalid:
    +%if 92437lsdkfjdsl
    +# valid:
    +%if "lsdfj %ksdf(sdfs) 3489"
    +Release:             %mkrel 1.2
    +%else  
    +Release:             0  
    +%endif  
    +# requiere a well defined value:
    +%ifos fixed_value
    +# You must use these special macros (%%if etc.) always at the start of the line - if not,
    +# that's bad but not an arror. You must also always use the specified form. Everything else is an
    +# error:
    + %if
    +something %if
    +%{if}
    +%if(some options)
    +# However, this are different macros and therefore correct:
    +%ifx
    +%{ifx}
    +%ifx(some options)
    +
    +# the \ is escaped in the line. At the end of the line it escapes the line break:
    +echo This is \" a text \\ and here\
    +it continues.
    +
    +%define name value
    +%define invalid_näme value
    +%define macroname multi\
    +line content with references like %0 %* %# %{-f} %{-f*} %1 %2 and so on
    +%global name value
    +%global invalid_näme value
    +%undefine name
    +%undefine name too-many-parameters
    +
    +# This special comment is treated and highlighted like a tag:
    +# norootforbuild  
    +# It can't have parameters, so every following non-whitespace character is not good:
    +# norootforbuild  DONT WRITE ANYTHING HERE!
    +# wrong spacing is also recognized:
    +#  norootforbuild
    +# and also an indeet is not fine for norootforbuild:
    + # norootforbuild
    +  
    +# This following "Conflicts" tag will be removed by set-version.sh,  
    +# if it is a "kradioripper" release (and not a "kradioripper-unstable" release)...  
    +Conflicts:           kradioripper  
    +  
    +  
    +%description  
    +# Here, a new section starts. It contains a value for the RPM field "description" and is therefor
    +# colored like values:
    +A KDE program for ripping internet radios. Based on StreamRipper.  
    +  
    +  
    +# A section start can have parameters:
    +%description -l de.UTF-8  
    +Ein KDE-Aufnahmeprogramm für Internetradios. Basiert auf StreamRipper.   
    +  
    +# These sections starts are errors:
    + %description not at the first line
    +%{description} wrong form
    +%description(no options allowed, only parameters!)
    +  
    +  
    +%prep  
    +# This starts a section that defines the commands to prepare the build.
    +# q means quit. n sets the directory:  
    +%setup -q -n kradioripper  
    +echo Test
    +# Macros can have different forms: Valid:
    +%abc
    +%abcÄndOfMacro
    +%abc(def)EndOfMacro
    +%{abc}EndOfMacro
    +%{something but no single %}EndOfMacro
    +%{abc:def}EndOfMacro
    +%(abc)
    +# Invalid:
    +%ÄInvalidChar
    +%
    +%)
    +%}
    +# You can use macros inside of macro calls: Fine:
    +%{something %but no %{sin%(fine)gle} }EndOfMacro
    +# Bad:
    +%{No closing paranthesis (No syntax highlightig for this error available)
    +  
    +  
    +%build  
    +cmake ./ -DCMAKE_INSTALL_PREFIX=%{_prefix}  
    +%__make %{?jobs:-j %jobs}  
    +  
    +  
    +%install  
    +%if 0%{?suse_version}  
    +%makeinstall  
    +%suse_update_desktop_file kradioripper  
    +%endif  
    +%if 0%{?fedora_version} || 0%{?rhel_version} || 0%{?centos_version}  
    +make install DESTDIR=%{buildroot}  
    +desktop-file-install --delete-original --vendor fedora --dir=%{buildroot}/%{_datadir}/applications/kde4 %{buildroot}/%{_datadir}/applications/kde4/kradioripper.desktop  
    +%endif  
    +%if 0%{?mandriva_version}  
    +%makeinstall_std  
    +%endif  
    +  
    +  
    +%clean  
    +rm -rf "%{buildroot}"  
    +  
    +  
    +%files  
    +%defattr(-,root,root)  
    +%if 0%{?fedora_version} || 0%{?rhel_version} || 0%{?centos_version}  
    +%{_datadir}/applications/kde4/fedora-kradioripper.desktop  
    +%else  
    +%{_datadir}/applications/kde4/kradioripper.desktop  
    +%endif  
    +%{_bindir}/kradioripper  
    +%{_datadir}/locale/*/LC_MESSAGES/kradioripper.mo  
    +%if 0%{?mandriva_version}  
    +# TODO The %%doc macro is actually broken for mandriva 2009 in build service...
    +%dir %{_datadir}/apps/kradioripper  
    +%{_datadir}/apps/kradioripper/*  
    +%else  
    +%doc COPYING LICENSE LICENSE.GPL2 LICENSE.GPL3 NEWS WARRANTY  
    +%dir %{_datadir}/kde4/apps/kradioripper  
    +%{_datadir}/kde4/apps/kradioripper/*  
    +%endif  
    +  
    +  
    +%changelog  
    +* Sun May 04 2008 email@email.com
    +- some text
    +- some text
    +  in two lines
    +- some text
    +  in two lines
    +  + with subtext
    +  - and more subtext
    +  in two lines
    +* Tue Apr 24 2007 Name
    +- text
    +  * When the star isn't at column 0, than it doesn't indicate
    +  a new date
    +* Wen Sep 08 2003 Wrong weekday
    +* Mon Mai 08 2003 Wrong month
    +* Mon Sep 0 2003 bad day
    +* Mon Sep 8 2003 good day
    +* Mon Sep 08 2003 good day
    +* Mon Sep 32 2003 bad day
    +* Mon Sep 08 03 bad year
    +* Mon Sep 08 2003 Name
    +# When using macros, the error check is disabled:
    +* %myDataMacro Title of the entry
    +- Text
    +    - can
    +        - be
    +        - indeeded
    +        - without
    +    - problems
    +
    +
    diff --git a/autotests/html/highlight.t2t.html b/autotests/html/highlight.t2t.html new file mode 100644 index 0000000..044837e --- /dev/null +++ b/autotests/html/highlight.t2t.html @@ -0,0 +1,97 @@ + + + +highlight.t2t + +
    +txt2tags sample
    +
    +
    +%!--includeconf: config.t2t
    +% disabled here because there is no external file
    +%!preproc: 'JUST A TEST'    ' '
    +%!postproc: '(?i)(<body)'   '\1 id="shots"'
    +%!postproc: '(?i)(</title>)'    ' shots\1'
    +
    +%!--include: menu.t2t
    +
    += Title 1 =
    +
    +
    +== My Subtitle 1 ==[some definition]
    +
    +Some examples:
    +
    +- A paragraph with **bold**, //italic// and --strike--.
    +- You can even __underline your docs__!
    +
    +- And use **//bold and italic//** 
    +- or //**italic and bold**// 
    +
    +Here is a nice pic: [img/t2tpowered.png].
    +
    +- And a [link to a cool website http://txt2tags.sf.net]!
    +
    +- A table : 
    +
    +  || Name | Age  |  Gender |
    +  | John |  33  |    Male |
    +  | Mary |  19  |  Female |
    +  
    +
    +``` A verbatim line
    +
    +And it's working for ``special code`` like this.
    +
    +```
    +Unfortunately I can't color this verbatim content yet.
    +```
    +
    +
    +== My Subtitle 2 ==
    +
    +
    +Lorem ipsum etc
    +Lorem ipsum etc Lorem ipsum etc
    +
    +- Test d'écriture avec des accents à la française. Ça marche ou pas ?
    +
    +== My Subtitle 3 ==
    +
    +
    +Lorem ipsum etc
    +Lorem ipsum etc
    +
    +Here is a direct link: http://kde.org
    +
    +
    +- Another boring part...
    +
    +
    +
    +=== My Subsubtitle 1 ===
    +
    +//It's a level 3 header// 
    +
    +- list 1
    +- list 2
    + - list 2b
    +- list 3
    +
    +
    +=== My Subsubtitle 2 ===
    +
    +//It's another level 3 header// 
    +
    ++ ordered list 1
    ++ list 2
    + + list 2B
    + + list 2C
    ++ list 3
    +
    +
    +== My Subtitle 4 ==
    +
    +nothing to say here...
    +
    +
    diff --git a/autotests/html/highlight.tcl.html b/autotests/html/highlight.tcl.html new file mode 100644 index 0000000..cda9499 --- /dev/null +++ b/autotests/html/highlight.tcl.html @@ -0,0 +1,57 @@ + + + +highlight.tcl + +
    +# tcl syntax highlighting sample script for Kate
    +#
    +# author: JM. Philippe 15/03/04
    +
    +# escaped characters
    +set String \{
    +set String \{
    +set String \"
    +set String " \" "
    +set String " \{ "
    +
    +#comments and not comments
    +# is comments
    +;#is comments
    +	# is comments
    +# <h1> is html comment </h1>
    +puts ok;	# is comments
    +set String [string map {</a> {<span>&#187;is not comments</span></a>}} $String]
    +set String \#not_a_comment
    +
    +# blocks
    +proc test {arg1 {arg2 {}} {arg3 {fr fq r}}} {
    +	if {1} {;	#comments
    +		set String \{;	# not a block start
    +	}
    +}
    +
    +proc test args {
    +	set String \};	# not a block end
    +}
    +
    +# BEGIN - collapsable comments
    +# blablabla
    +# END
    +
    +# strings
    +set String "feqr feqr $gqer gqe"
    +set String "feqr
    +feqr \" $gqer \
    +gqe
    +"
    +set String {feqr
    +feqr \{ $gqer \
    +gqe
    +}
    +
    +# variables
    +set b+1 [incr b]
    +set {incr-b} ${b+1}
    +puts ${incr-b}
    +
    diff --git a/autotests/html/highlight.tex.html b/autotests/html/highlight.tex.html new file mode 100644 index 0000000..52e20be --- /dev/null +++ b/autotests/html/highlight.tex.html @@ -0,0 +1,80 @@ + + + +highlight.tex + +
    +% LaTeX test file for kate's syntax highlighting and code folding
    +
    +\ordinaryLaTeXcommandwithoption[10pt,a4paper]{article}
    +% BEGIN region
    +%comment, this is all ok % $ 
    +\%no comments please
    +\\%comment
    +% END of region
    +
    +\newcommand{\nohighlighting}
    +
    +\section{normal}
    +
    +\ref{blue}
    +\pageref{blue}
    +\cite{blue}
    +
    +\begin{environmentshavespecialcolors}
    +normal
    +\end{environmentshavespecialcolors}
    +
    +$equations are green, \commands somewhat darker$
    +normal
    +$$equations are green, \commands somewhat darker$$
    +normal
    +\( 
    +\frac{1}{2}
    +\begin{test}
    +\end{test}
    +\)
    +normal
    +\[
    +%comment 
    +displaymath 
    +\]
    +normal
    +\begin{equation}
    +green\darkergreen
    +\begin{test}
    +\test
    +\end{test}
    +\end{equation}
    +
    +\begin{equation*}
    +green\darkergreen
    +%comment
    +\begin{test}
    +\test
    +\end{test}
    +\%no comment
    +\end{equation*}
    +
    +\{     %this should be comment
    +
    +\verb%this shouldn't be%and this should be normal text
    +
    +\begin{verbatim}
    +text inside a verbatim environment is also treated special $ %,
    +you can even put a \begin{verbatim} inside
    +\end{verbatim}
    +
    +normal
    +
    +\begin{Verbatim}
    +&@@#^%&^#$
    +\end{Verbatim}
    +
    +
    +\begin{Verbatim*}
    +@*&^#@*(^#(*@&
    +\end{Verbatim*}
    +
    +normal
    +
    diff --git a/autotests/html/highlight.wrl.html b/autotests/html/highlight.wrl.html new file mode 100644 index 0000000..4ddc08f --- /dev/null +++ b/autotests/html/highlight.wrl.html @@ -0,0 +1,48 @@ + + + +highlight.wrl + +
    +#VRML V2.0 utf8
    +#
    +# VRML highlighting test for Kate's syntax highlighting
    +#
    +
    +# Keywords
    +DEF, EXTERNPROTO, FALSE, IS, NULL, PROTO, ROUTE, TO, TRUE, USE, eventIn,
    +eventOut, exposedField, field
    +
    +# Data types
    +MFColor, MFFloat, MFInt32, MFNode. MFRotation, MFString, MFTime, MFVec2f,
    +MFVec3f, SFBool, SFColor, SFFloat, SFImage, SFInt32, SFNode, SFRotation,
    +SFString, SFTime, SFVec2f, SFVec3f
    +
    +# Predefined nodes
    +Anchor, Appearance, AudioClip, Background, Billboard, Box, Collision, Color,
    +ColorInterpolator, Cone, Coordinate, CoordinateInterpolator, Cylinder, 
    +CylinderSensor, DirectionalLight, ElevationGrid, Extrusion, Fog, FontStyle,
    +Group, ImageTexture, IndexedFaceSet, IndexedLineSet, Inline, LOD, Material,
    +MovieTexture, NavigationInfo, Normal, NormalInterpolator, OrientationInterpolator,
    +PixelTexture, PlaneSensor, PointLight, PointSet, PositionInterpolator,
    +ProximitySensor, ScalarInterpolator, Script, Shape, Sound, Sphere, SphereSensor,
    +SpotLight, Switch, Text, TextureCoordinate, TextureTransform, TimeSensor,
    +TouchSensor, Transform, Viewpoint, VisibilitySensor, WorldInfo
    +
    +# Some real VRML constructs to see if highlighting of int, float etc. works
    +NavigationInfo { 
    +	avatarSize      [0.25, 1.6, 0.75]
    +	headlight       TRUE
    +	speed           1
    +	type            ["WALK", "ANY"]
    +	visibilityLimit 0.0
    +}
    +
    +# some further testing for strings: linefeeds are allowed within strings
    +Text { 
    +	string ["some special in-string characters: \" \\
    +	        some more text in the next line
    +	        and yet another line"]
    +}
    +
    +
    diff --git a/autotests/html/highlight.xml.html b/autotests/html/highlight.xml.html new file mode 100644 index 0000000..cccbe3b --- /dev/null +++ b/autotests/html/highlight.xml.html @@ -0,0 +1,74 @@ + + + +highlight.xml + +
    +<?xml version="1.0" encoding="UTF-8"?>
    +<!DOCTYPE language SYSTEM "language.dtd">
    +<!-- we need this tags or this is no valid file -->
    +
    +
    +This is a pseudo XML file to test Kate's XML syntax highlighting.
    +
    +Doctype:
    +	<!DOCTYPE HTML PUBLIC "-//SOME_DOCTYPE 0.01//EN" SYSTEM "foobar.dtd">
    +
    +Processing instruction:
    +	<?php processing instruction ?>
    +
    +Comments:
    +	<!-- a comment -->
    +	<!-- another comment,
    +	using more than one line -->
    +
    +Comment inside element:
    +	<element attr="foobar">content<!-- comment --></element>
    +
    +Markup inside comment:
    +	<!--
    +	This is a comment!
    +	<element inside_comment />
    +	-->
    +
    +Empty element:
    +	<empty/>
    +	<empty  />
    +
    +Simple element plus content:
    +	<element>some content</element>
    +	<element attr="foobar">some
    +		content</element>
    +
    +Namespace for elements and attributes:
    +	<ns:element>content</ns:element>
    +	<element ns:attr="content content">content</element>
    +
    +Elements containing allowed characters:
    +	<element-dash foo="test"/>
    +	<element.dot foo="test"/>
    +
    +Elements containing allowed start characters:
    +	<:element foo="test"/>
    +	<_element foo="test"/>
    +
    +Single quotes (the same as double quotes):
    +	<element attr='content &nbsp; content'>content</element>
    +
    +Allowed Whitespace:
    +	<element     attr   =   "test"  >
    +		content</element>
    +
    +Entities:
    +	&nbsp;
    +	&#229;
    +	&#xE5;
    +	&#Xe5;
    +	&#1048;
    +	&#x6C34;
    +	<element attr="foo &nbsp; &#229; &amp; bar"/>
    +
    +Illegal XML, should not be highlighted:
    +	<0foobar> -- no digit as first character
    +	<-foo> -- no dash as first character
    +
    diff --git a/autotests/html/highlight.xsl.html b/autotests/html/highlight.xsl.html new file mode 100644 index 0000000..44208fb --- /dev/null +++ b/autotests/html/highlight.xsl.html @@ -0,0 +1,116 @@ + + + +highlight.xsl + +
    +<?xml version="1.0" encoding="iso-8859-15"?>
    +
    +<!--
    +	This file is freely distributable, created by Wilbert Berendsen (wbsoft@xs4all.nl)
    +
    +	This is just a simple XSLT file that converts some HTML pages to a XBEL bookmarklist.
    +	It is included here to test the new XSLT highlighting by Peter Lammich.
    +	
    +	TODO: add better test file.
    +-->
    +
    +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    +xmlns:h="http://www.w3.org/1999/xhtml">
    +<xsl:output method="xml" encoding="iso-8859-15" indent="yes"
    + doctype-public="+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
    + doctype-system="http://www.python.org/topics/xml/dtds/xbel-1.0.dtd"
    +/>
    +
    +<!-- main -->
    +<xsl:template match="/">
    +<xbel><folder><title>Linux at Home Links</title>
    +<xsl:for-each select="//*[@id='maincontents']//h:li">
    +  <xsl:variable name="f" select="document(h:a/@href)/h:html"/>
    +  <folder>
    +  <title><xsl:value-of select="h:a/h:strong"/></title>
    +  <desc><xsl:value-of select="normalize-space(h:a/text())"/></desc>
    +  <xsl:for-each select="$f//h:div[@id='maincontents']">
    +  <xsl:call-template name="getbookmarks"/>
    +  </xsl:for-each>
    +  
    +  </folder>
    +</xsl:for-each>
    +</folder></xbel>
    +</xsl:template>
    +<!-- end of main -->
    +
    +<!-- get bookmarks from a page -->
    +<xsl:template name="getbookmarks">
    +
    +<xsl:choose>
    +  <!-- harvest links from p or li elements -->
    +  <xsl:when test="self::h:li or self::h:p">
    +    <xsl:variable name="t" select="normalize-space()"/>
    +    <xsl:for-each select=".//h:a[1]">
    +      <xsl:call-template name="bookmark">
    +        <xsl:with-param name="desc" select="$t"/>
    +      </xsl:call-template>
    +    </xsl:for-each>
    +    <xsl:for-each select=".//h:a[position()!=1]">
    +      <xsl:call-template name="bookmark"/>
    +    </xsl:for-each>
    +  </xsl:when>
    +
    +
    +  <xsl:otherwise>
    +    <xsl:for-each select="*">
    +      <xsl:call-template name="getbookmarks"/>
    +    </xsl:for-each>
    +  </xsl:otherwise>
    +
    +</xsl:choose>
    +
    +</xsl:template>
    +
    +
    +<xsl:template name="bookmark">
    +  <xsl:param name="href" select="@href"/>
    +  <xsl:param name="desc" select="''"/>
    +  <xsl:param name="title" select="normalize-space()"/>
    +
    +  <xsl:variable name="realdesc">
    +    <xsl:choose>
    +      <xsl:when test="starts-with($desc,$title)">
    +        <xsl:choose>
    +          <xsl:when test="starts-with(translate(substring-after($desc,$title),',.;','...'),'.')">
    +            <xsl:value-of select="substring($desc,string-length($title) + 2)"/>
    +          </xsl:when>
    +          <xsl:otherwise>
    +            <xsl:value-of select="substring-after($desc,$title)"/>
    +          </xsl:otherwise>
    +        </xsl:choose>
    +      </xsl:when>
    +      <xsl:otherwise>
    +        <xsl:value-of select="$desc"/>
    +      </xsl:otherwise>
    +    </xsl:choose>
    +  </xsl:variable>
    +  
    +  <bookmark>
    +    <xsl:attribute name="href">
    +      <xsl:choose>
    +        <xsl:when test="starts-with($href,'http://') or starts-with($href,'ftp://') or starts-with($href,'mailto:')">
    +          <xsl:value-of select="$href"/>
    +        </xsl:when>
    +        <xsl:otherwise>
    +          <xsl:value-of select="concat('http://www.xs4all.nl/~wbsoft/linux/links/',$href)"/>
    +        </xsl:otherwise>
    +      </xsl:choose>
    +    </xsl:attribute>
    +    <title><xsl:value-of select="normalize-space($title)"/></title>
    +    <xsl:if test="normalize-space($realdesc) != ''">
    +      <desc><xsl:value-of select="normalize-space($realdesc)"/></desc>
    +    </xsl:if>
    +  </bookmark>
    +</xsl:template>
    +
    +
    +
    +</xsl:stylesheet>
    +
    diff --git a/autotests/html/highlight.y.html b/autotests/html/highlight.y.html new file mode 100644 index 0000000..0527699 --- /dev/null +++ b/autotests/html/highlight.y.html @@ -0,0 +1,61 @@ + + + +highlight.y + +
    +/* Yacc / Bison hl test file.
    + * It won't compile :-) Sure !
    + */
    +
    +%{
    +
    +#include <iostream>
    +using namespace std;
    +
    +extern KateParser *parser;
    +
    +%}
    +
    +%locations
    +
    +%union { 
    +   int int_val;
    +   double double_val;
    +   bool bool_val;
    +   char *string_val;
    +   char *ident_val;
    +   struct var *v;
    +   void *ptr;
    +}
    +
    +%token <int_val>      TOK_NOT_EQUAL  "!="
    +%token <int_val>      TOK_LESSER_E   "<="
    +%token <int_val>      TOK_GREATER_E  ">="
    +%token <int_val>      TOK_EQUAL_2    "=="
    +
    +%type <int_val>       type type_proc
    +
    +%%
    +
    +prog:                 KW_PROGRAM ident { parser->start($2); } prog_beg_glob_decl instructions { parser->endproc(0); } dev_procedures KW_ENDP ;
    +
    +number:               integer_number
    +                      | TOK_DOUBLE
    +                      {
    +                         $$ = new var;
    +                         $$->type = KW_REEL;
    +                         $$->cl = var::LITTERAL;
    +                         $$->real = $<int_val>1;
    +                      };
    +
    +%%
    +
    +#include <stdio.h>
    +
    +int main(void)
    +{
    +  puts("Hello, World!");
    +  return 0;
    +}
    +
    diff --git a/autotests/html/highlight_lpc.c.html b/autotests/html/highlight_lpc.c.html new file mode 100644 index 0000000..2ac3653 --- /dev/null +++ b/autotests/html/highlight_lpc.c.html @@ -0,0 +1,71 @@ + + + +highlight_lpc.c + +
    +// NOTE: This is a test file for kate's LPC syntax highlighting.
    +
    +// This is a Single-Line Comment
    +/* This is a Multi-
    +                   Line Comment */
    +
    +// This again is a Single-Line Comment which should end here /*
    +
    +// And this is an evil single line comment \
    +   which should include this and the next line because of the \
    +   Do not use this style at home, kids.
    +// BEGIN region marker
    +
    +// END of region marker
    +
    +private void create()
    +{
    +// Some Preprocessor stuff:
    +#define SOME_STUFF if(foo("bar")) \
    +                   { \
    +                       bar("foo"); \
    +                   } // Preprocessor, Keyword, Preprocessor-String, Multiline
    +
    +    // Some closures:
    +    #'create;
    +    #'?!;
    +
    +
    +    /* Some other Data Types: */
    +
    +    int i = 1;            // Integer.
    +    float b = 2.34;       // Float.
    +    int c = 0b001;        // Binary
    +    int e = 0x019Beef;    // Hexadecimal
    +    int f = 0o2345;       // Octal
    +    string a = "Wheee";   // String
    +    string x = "Wheee\
    +     heee";               // Multi-Line String, again, don't use this.
    +
    +
    +
    +    /* Some keywords: */
    +    if(1)
    +    {
    +        switch(2)
    +        {
    +            case 3:
    +                4;
    +                break;
    +        }
    +    }
    +
    +    else
    +    {
    +        return 0;
    +    }
    +}
    +
    +/*
    +WARNING: If the above function is part of a multi-line comment,
    +         it's buggy. The WARNING: itself should be a comment-keyword.
    +         That's not actually part of the language, but simply used
    +         to highlight important stuff inside comments like TODO: etc.
    +*/
    +
    diff --git a/autotests/html/highlight_ocaml.ml.html b/autotests/html/highlight_ocaml.ml.html new file mode 100644 index 0000000..0e85e63 --- /dev/null +++ b/autotests/html/highlight_ocaml.ml.html @@ -0,0 +1,112 @@ + + + +highlight_ocaml.ml + +
    +(* ocaml test file -- a big stew of Objective Caml syntax to use to
    +   test Kate's syntax highlighting. This will not run! :-) *)
    +
    +(* First a little piece of real OCaml that should look right: *)
    +
    +    #load "basic";;
    +    (* Return a default value for a BASIC variable given its identifer. *)
    +    let default_value (ident : string) : basic_value =
    +       assert (String.length ident > 0);
    +       match ident.[String.length ident - 1] with
    +       | '$' -> Str ""
    +       | '%' -> Int 0
    +       | '!' -> Flt 0.0
    +       | _   -> Flt 0.0
    +    ;;
    +
    +(* Directives: *)
    +#load "pa_o";;
    +  #load "pa_o";;
    +object # meth ;;  (* not a directive - a method call *)
    +object
    +   # meth ;;  (* not a directive - a method call *)
    +
    +(* OCaml keywords: *)
    +and as assert asr (* etc. there so many... *)
    +
    +(* Additional OCaml Revised Syntax keywords: *)
    +(* These are in a seperate category so they can be coloured to look
    +   like identifiers when ordinary OCaml syntax is being used: *)
    +declare where value
    +
    +(* There's no way to reliably highlight all OCaml type expressions,
    +   (they can be very complex) so just the built-in type names are highlighted.*)
    +exn lazy_t format unit int real char string ref array bool list option
    +
    +
    +let integers : int list = [
    +    123456789;              (* decimal *)
    +    -0xabcedf0123456789;    (* hexadecimal *)
    +    0xABCDEF0123456789;     (* hexadecimal *)
    +    -0o1234567;             (* octal *)
    +    0b01001010101010;       (* binary *)
    +    -0Xabcedf0123456789;    (* hexadecimal *)
    +    0XABCDEF0123456789;     (* hexadecimal *)
    +    -0O1234567;             (* octal *)
    +    0B01001010101010;       (* binary *)
    +    -123_456_789;           (* Underscores are allowed in numeric constants. *)
    +    0x_abce_df01_2345_6789;
    +    -0o12_34_567;
    +    0b_0100_1010_1010_1101;
    +];;
    +
    +let floats : real list = [
    +    12345.6789;
    +    -1.23456789e4;      (* All variations of the exponent form *)
    +    1.23456789e+4;
    +    -1.23456789e-4;
    +    1.23456789E-4;
    +    -1.23456789E+4;
    +    12_345.6789;       (* Underscores are allowed in numeric constants. *)
    +    -1.23_456_789e+4;
    +    12_345.6789;
    +];;
    +
    +let characters : char list = [
    +    'a';
    +    ' ';
    +    '�';
    +    '\n'; '\r'; '\t'; '\b';    (* Control characters. Only these four: not the full C-language range. *)
    +    '\000'; '\128';            (* Decimal character codes. These are always 3 digits. *)
    +    '\x02'; '\xff'; '\xFF';    (* Hexadecimal character codes. These are always 3 digits. *)
    +    '\\'; '\''; '\"'; '"'      (* Quote character escapes. *)
    +];;
    +
    +(* Quotes used to mark constants in parsers should
    +   not be confused with character constant quotes.
    +   "Ticks" at the end of identifiers should
    +   not be confused with character constant quotes.  *)
    +let basic_identifier =
    +  parser
    +      [< ''F'; ''N'; name = s >] -> ID (s, 'f')
    +    | [< name = s' >] -> ID (s','i')
    +;;
    +
    +let strings : string list = [
    +    ""; (* Empty string *)
    +    "a"; " ";  "�";   "ab";
    +    "A\nB"; "A\rB"; "A\tB"; "A\bB";  (* Control characters. Only these four: not the full C-language range. *)
    +    "A\000B"; "A\128B";              (* Decimal character codes. These are always 3 digits. *)
    +    "A\x02B"; "A\xffB"; "A\xFFB";    (* Hexadecimal character codes. These are always 3 digits. *)
    +    "A\\B"; "A\'B"; "A'B";  "A\"B";  (* Quote character escapes. *)
    +    "A multiline\
    +    string";
    +];
    +
    +let camlp4_quotations = [
    +    <<A Camlp4 source code quotation.>> ;
    +    <:QUOTE<A labelled Camlp4 source code quotation.>> ;
    +    <:QU�T�<A labelled Camlp4 source code quotation. (Latin-1 identifier.)>> ;
    +    << A quote with an escape: \>> (end-quote symbol) >> ;
    +    << A quote with an escape: \<< (plain start quote-symbol) >> ;
    +    << A quote with an escape: \<:Trouv�< (labelled start-quote symbol) >> ;
    +];;
    +
    +(* end *)
    +
    diff --git a/autotests/html/highlight_octave.m.html b/autotests/html/highlight_octave.m.html new file mode 100644 index 0000000..25d8cd8 --- /dev/null +++ b/autotests/html/highlight_octave.m.html @@ -0,0 +1,81 @@ + + + +highlight_octave.m + +
    +##=====================================================
    +% Octave test code for Kate/Kwrite syntax highlighting
    +% (shamelessly copied from Matlab's, since the two
    +%  are very similar)
    +% kate: hl Octave;
    +##=====================================================
    +
    +% Numbers _____________________________________________
    +5, 5.5, .1, 0.1, 0.4e5, 1.2e-5, 5i, 5.3i, 6j, .345+3i
    +5', 5.5', .1', 0.1', 0.4e5', 1.2e-5', 5i', 5.3i', 6j', .345+3i'
    +
    +% Operators ___________________________________________
    +% relational operators
    +'asdf'~=4, c<=4, d>=4, a<b, a>b, a==b, b||c, b&&c
    +% elementwise arithmetic operators
    +a.^b, a.*b a./b, 1:4:5
    +% single-character binary arithmetic
    +a+3, a-3, a*2, a^3, a/3, a\3, a|b, a&b
    +% unary operators
    +a = ~g; g = @sfdgdsf(sdfsd,345); g.' + 1i.' - ('asdf').'
    +% separators and delimiter
    +(asd),[sadf];{asdf},;;,;;;()
    +% continuation
    +a = 1+ ...
    +  2;
    +
    +% Strings and adjoint _________________________________
    +% incomplete strings
    +'string
    +'str''
    +'str''ing
    +'str''\'
    +% complete strings
    +'string' % simple string
    +'''' '\'' % strings containing '
    +'str''ing' % one string containing '
    +'string' 'string'  % two strings
    +'asdf'  "asdf""" variable  % two strings and a variable
    +'asdf''asdf''   fsgdfg' + (asdf)' - 'asdf'.' + []''''.';''
    +'sadf'.' % string transpose
    +% adjoint
    +{'asdf'}' + 1
    +('asdf')' + 1
    +['asdf']' + 1
    +'' var''' % empty string, var with >1 adjoints
    +[5]'*{5}'*('asd')'.'+(5)'*6'*asdf'*asdf'.'  % many adjoints
    +A'*B + 1      % adjoint
    +A.'*B + 1     % transpose
    +A.'.'*B + 1   % double transpose
    +A'.' + 1      % adjoint, then transpose
    +A.''          % transpose, then adjoint
    +
    +% System command ______________________________________
    +!hostname
    +!cp * /tmp
    +
    +% Reserved keywords ___________________________________
    +function, persistent, global
    +endfunction
    +
    +switch, case, otherwise
    +endswitch
    +
    +if, else, elseif
    +endif
    +
    +try, end_try_catch
    +for, while, break, continue
    +endfor
    +
    +endwhile
    +return
    +function, FUNCTION, Function  % case sensitive!
    +endfunction
    +
    diff --git a/autotests/html/learnelixir.exs.html b/autotests/html/learnelixir.exs.html new file mode 100644 index 0000000..9c0a390 --- /dev/null +++ b/autotests/html/learnelixir.exs.html @@ -0,0 +1,404 @@ + + + +learnelixir.exs + +
    +# Original: https://learnxinyminutes.com/docs/elixir/
    +
    +# Single line comments start with a number symbol.
    +
    +# There's no multi-line comment,
    +# but you can stack multiple comments.
    +
    +# To use the elixir shell use the `iex` command.
    +# Compile your modules with the `elixirc` command.
    +
    +# Both should be in your path if you installed elixir correctly.
    +
    +## ---------------------------
    +## -- Basic types
    +## ---------------------------
    +
    +# There are numbers
    +3    # integer
    +0x1F # integer
    +3.0  # float
    +
    +# Atoms, that are literals, a constant with name. They start with `:`.
    +:hello # atom
    +
    +# Tuples that are stored contiguously in memory.
    +{1,2,3} # tuple
    +
    +# We can access a tuple element with the `elem` function:
    +elem({1, 2, 3}, 0) #=> 1
    +
    +# Lists that are implemented as linked lists.
    +[1,2,3] # list
    +
    +# We can access the head and tail of a list as follows:
    +[head | tail] = [1,2,3]
    +head #=> 1
    +tail #=> [2,3]
    +
    +# In elixir, just like in Erlang, the `=` denotes pattern matching and
    +# not an assignment.
    +#
    +# This means that the left-hand side (pattern) is matched against a
    +# right-hand side.
    +#
    +# This is how the above example of accessing the head and tail of a list works.
    +
    +# A pattern match will error when the sides don't match, in this example
    +# the tuples have different sizes.
    +# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
    +
    +# There are also binaries
    +<<1,2,3>> # binary
    +
    +# Strings and char lists
    +"hello" # string
    +'hello' # char list
    +
    +# Multi-line strings
    +"""
    +I'm a multi-line
    +string.
    +"""
    +#=> "I'm a multi-line\nstring.\n"
    +
    +# Strings are all encoded in UTF-8:
    +"héllò" #=> "héllò"
    +
    +# Strings are really just binaries, and char lists are just lists.
    +<<?a, ?b, ?c>> #=> "abc"
    +[?a, ?b, ?c]   #=> 'abc'
    +
    +# `?a` in elixir returns the ASCII integer for the letter `a`
    +?a #=> 97
    +
    +# To concatenate lists use `++`, for binaries use `<>`
    +[1,2,3] ++ [4,5]     #=> [1,2,3,4,5]
    +'hello ' ++ 'world'  #=> 'hello world'
    +
    +<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
    +"hello " <> "world"  #=> "hello world"
    +
    +# Ranges are represented as `start..end` (both inclusive)
    +1..10 #=> 1..10
    +lower..upper = 1..10 # Can use pattern matching on ranges as well
    +[lower, upper] #=> [1, 10]
    +
    +## ---------------------------
    +## -- Operators
    +## ---------------------------
    +
    +# Some math
    +1 + 1  #=> 2
    +10 - 5 #=> 5
    +5 * 2  #=> 10
    +10 / 2 #=> 5.0
    +
    +# In elixir the operator `/` always returns a float.
    +
    +# To do integer division use `div`
    +div(10, 2) #=> 5
    +
    +# To get the division remainder use `rem`
    +rem(10, 3) #=> 1
    +
    +# There are also boolean operators: `or`, `and` and `not`.
    +# These operators expect a boolean as their first argument.
    +true and true #=> true
    +false or true #=> true
    +# 1 and true    #=> ** (ArgumentError) argument error
    +
    +# Elixir also provides `||`, `&&` and `!` which accept arguments of any type.
    +# All values except `false` and `nil` will evaluate to true.
    +1 || true  #=> 1
    +false && 1 #=> false
    +nil && 20  #=> nil
    +!true #=> false
    +
    +# For comparisons we have: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` and `>`
    +1 == 1 #=> true
    +1 != 1 #=> false
    +1 < 2  #=> true
    +
    +# `===` and `!==` are more strict when comparing integers and floats:
    +1 == 1.0  #=> true
    +1 === 1.0 #=> false
    +
    +# We can also compare two different data types:
    +1 < :hello #=> true
    +
    +# The overall sorting order is defined below:
    +# number < atom < reference < functions < port < pid < tuple < list < bit string
    +
    +# To quote Joe Armstrong on this: "The actual order is not important,
    +# but that a total ordering is well defined is important."
    +
    +## ---------------------------
    +## -- Control Flow
    +## ---------------------------
    +
    +# `if` expression
    +if false do
    +  "This will never be seen"
    +else
    +  "This will"
    +end
    +
    +# There's also `unless`
    +unless true do
    +  "This will never be seen"
    +else
    +  "This will"
    +end
    +
    +# Remember pattern matching? Many control-flow structures in elixir rely on it.
    +
    +# `case` allows us to compare a value against many patterns:
    +case {:one, :two} do
    +  {:four, :five} ->
    +    "This won't match"
    +  {:one, x} ->
    +    "This will match and bind `x` to `:two`"
    +  _ ->
    +    "This will match any value"
    +end
    +
    +# It's common to bind the value to `_` if we don't need it.
    +# For example, if only the head of a list matters to us:
    +[head | _] = [1,2,3]
    +head #=> 1
    +
    +# For better readability we can do the following:
    +[head | _tail] = [:a, :b, :c]
    +head #=> :a
    +
    +# `cond` lets us check for many conditions at the same time.
    +# Use `cond` instead of nesting many `if` expressions.
    +cond do
    +  1 + 1 == 3 ->
    +    "I will never be seen"
    +  2 * 5 == 12 ->
    +    "Me neither"
    +  1 + 2 == 3 ->
    +    "But I will"
    +end
    +
    +# It is common to set the last condition equal to `true`, which will always match.
    +cond do
    +  1 + 1 == 3 ->
    +    "I will never be seen"
    +  2 * 5 == 12 ->
    +    "Me neither"
    +  true ->
    +    "But I will (this is essentially an else)"
    +end
    +
    +# `try/catch` is used to catch values that are thrown, it also supports an
    +# `after` clause that is invoked whether or not a value is caught.
    +try do
    +  throw(:hello)
    +catch
    +  message -> "Got #{message}."
    +after
    +  IO.puts("I'm the after clause.")
    +end
    +#=> I'm the after clause
    +# "Got :hello"
    +
    +## ---------------------------
    +## -- Modules and Functions
    +## ---------------------------
    +
    +# Anonymous functions (notice the dot)
    +square = fn(x) -> x * x end
    +square.(5) #=> 25
    +
    +# They also accept many clauses and guards.
    +# Guards let you fine tune pattern matching,
    +# they are indicated by the `when` keyword:
    +f = fn
    +  x, y when x > 0 -> x + y
    +  x, y -> x * y
    +end
    +
    +f.(1, 3)  #=> 4
    +f.(-1, 3) #=> -3
    +
    +# Elixir also provides many built-in functions.
    +# These are available in the current scope.
    +is_number(10)    #=> true
    +is_list("hello") #=> false
    +elem({1,2,3}, 0) #=> 1
    +
    +# You can group several functions into a module. Inside a module use `def`
    +# to define your functions.
    +defmodule Math do
    +  def sum(a, b) do
    +    a + b
    +  end
    +
    +  def square(x) do
    +    x * x
    +  end
    +end
    +
    +Math.sum(1, 2)  #=> 3
    +Math.square(3) #=> 9
    +
    +# To compile our simple Math module save it as `math.ex` and use `elixirc`
    +# in your terminal: elixirc math.ex
    +
    +# Inside a module we can define functions with `def` and private functions with `defp`.
    +# A function defined with `def` is available to be invoked from other modules,
    +# a private function can only be invoked locally.
    +defmodule PrivateMath do
    +  def sum(a, b) do
    +    do_sum(a, b)
    +  end
    +
    +  defp do_sum(a, b) do
    +    a + b
    +  end
    +end
    +
    +PrivateMath.sum(1, 2)    #=> 3
    +# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
    +
    +# Function declarations also support guards and multiple clauses:
    +defmodule Geometry do
    +  def area({:rectangle, w, h}) do
    +    w * h
    +  end
    +
    +  def area({:circle, r}) when is_number(r) do
    +    3.14 * r * r
    +  end
    +end
    +
    +Geometry.area({:rectangle, 2, 3}) #=> 6
    +Geometry.area({:circle, 3})       #=> 28.25999999999999801048
    +# Geometry.area({:circle, "not_a_number"})
    +#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1
    +
    +# Due to immutability, recursion is a big part of elixir
    +defmodule Recursion do
    +  def sum_list([head | tail], acc) do
    +    sum_list(tail, acc + head)
    +  end
    +
    +  def sum_list([], acc) do
    +    acc
    +  end
    +end
    +
    +Recursion.sum_list([1,2,3], 0) #=> 6
    +
    +# Elixir modules support attributes, there are built-in attributes and you
    +# may also add custom ones.
    +defmodule MyMod do
    +  @moduledoc """
    +  This is a built-in attribute on a example module.
    +  """
    +
    +  @my_data 100 # This is a custom attribute.
    +  IO.inspect(@my_data) #=> 100
    +end
    +
    +## ---------------------------
    +## -- Structs and Exceptions
    +## ---------------------------
    +
    +# Structs are extensions on top of maps that bring default values,
    +# compile-time guarantees and polymorphism into Elixir.
    +defmodule Person do
    +  defstruct name: nil, age: 0, height: 0
    +end
    +
    +joe_info = %Person{ name: "Joe", age: 30, height: 180 }
    +#=> %Person{age: 30, height: 180, name: "Joe"}
    +
    +# Access the value of name
    +joe_info.name #=> "Joe"
    +
    +# Update the value of age
    +older_joe_info = %{ joe_info | age: 31 }
    +#=> %Person{age: 31, height: 180, name: "Joe"}
    +
    +# The `try` block with the `rescue` keyword is used to handle exceptions
    +try do
    +  raise "some error"
    +rescue
    +  RuntimeError -> "rescued a runtime error"
    +  _error -> "this will rescue any error"
    +end
    +#=> "rescued a runtime error"
    +
    +# All exceptions have a message
    +try do
    +  raise "some error"
    +rescue
    +  x in [RuntimeError] ->
    +    x.message
    +end
    +#=> "some error"
    +
    +## ---------------------------
    +## -- Concurrency
    +## ---------------------------
    +
    +# Elixir relies on the actor model for concurrency. All we need to write
    +# concurrent programs in elixir are three primitives: spawning processes,
    +# sending messages and receiving messages.
    +
    +# To start a new process we use the `spawn` function, which takes a function
    +# as argument.
    +f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
    +spawn(f) #=> #PID<0.40.0>
    +
    +# `spawn` returns a pid (process identifier), you can use this pid to send
    +# messages to the process. To do message passing we use the `send` operator.
    +# For all of this to be useful we need to be able to receive messages. This is
    +# achieved with the `receive` mechanism:
    +
    +# The `receive do` block is used to listen for messages and process
    +# them when they are received. A `receive do` block will only
    +# process one received message. In order to process multiple
    +# messages, a function with a `receive do` block must recursively
    +# call itself to get into the `receive do` block again.
    +
    +defmodule Geometry do
    +  def area_loop do
    +    receive do
    +      {:rectangle, w, h} ->
    +        IO.puts("Area = #{w * h}")
    +        area_loop()
    +      {:circle, r} ->
    +        IO.puts("Area = #{3.14 * r * r}")
    +        area_loop()
    +    end
    +  end
    +end
    +
    +# Compile the module and create a process that evaluates `area_loop` in the shell
    +pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
    +# Alternatively
    +pid = spawn(Geometry, :area_loop, [])
    +
    +# Send a message to `pid` that will match a pattern in the receive statement
    +send pid, {:rectangle, 2, 3}
    +#=> Area = 6
    +#   {:rectangle,2,3}
    +
    +send pid, {:circle, 2}
    +#=> Area = 12.56000000000000049738
    +#   {:circle,2}
    +
    +# The shell is also a process, you can use `self` to get the current pid
    +self() #=> #PID<0.27.0>
    +
    diff --git a/autotests/html/light52_muldiv.vhdl.html b/autotests/html/light52_muldiv.vhdl.html new file mode 100644 index 0000000..e5e27d3 --- /dev/null +++ b/autotests/html/light52_muldiv.vhdl.html @@ -0,0 +1,246 @@ + + + +light52_muldiv.vhdl + +
    +--------------------------------------------------------------------------------
    +-- light52_muldiv.vhdl -- Simple multiplier/divider module.
    +--------------------------------------------------------------------------------
    +-- The 8051 mul and div instructions are both unsigned and operands are 8 bit.
    +--
    +-- This module implements the division as a sequential state machine which takes
    +-- 8 cycles to complete. 
    +-- The multiplier can be implemented as sequential or as combinational, in which
    +-- case it will use a DSP block in those architectures that support it.
    +-- No attempt has been made to make this module generic or reusable.
    +--
    +-- If you want a combinational multiplier but don't want to waste a DSP block 
    +-- in this module, you need to modify this file adding whatever synthesis 
    +-- pragmas your tool of choice needs.
    +--
    +-- Note that unlike the division state machine, the combinational product logic
    +-- is always operating: when SEQUENTIAL_MULTIPLIER=true, prod_out equals 
    +-- data_a * data_b with a latency of 1 clock cycle, and mul_ready is hardwired
    +-- to '1'.
    +--
    +-- FIXME explain division algorithm.
    +--------------------------------------------------------------------------------
    +-- GENERICS:
    +-- 
    +-- SEQUENTIAL_MULTIPLIER        -- Sequential vs. combinational multiplier.
    +--  When true, a sequential implementation will be used for the multiplier, 
    +--  which will usually save a lot of logic or a dedicated multiplier.
    +--  When false, a combinational registered multiplier will be used.
    +--
    +--------------------------------------------------------------------------------
    +-- INTERFACE SIGNALS:
    +--
    +-- clk :            Clock, active rising edge.
    +-- reset :          Synchronous reset. Clears only the control registers not
    +--                  visible to the programmer -- not the output registers.
    +-- 
    +-- data_a :         Numerator input, should be connected to the ACC register.
    +-- data_b :         Denominator input, should be connected to the B register.
    +-- start :          Assert for 1 cycle to start the division state machine
    +--                  (and the product if SEQUENTIAL_MULTIPLIER=true);
    +-- 
    +-- prod_out :       Product output, valid only when mul_ready='1'.
    +-- quot_out :       Quotient output, valid only when div_ready='1'.
    +-- rem_out :        Remainder output, valid only when div_ready='1'.
    +-- div_ov_out :     Division overflow flag, valid only when div_ready='1'.
    +-- mul_ov_out :     Product overflow flag, valid only when mul_ready='1'.
    +-- 
    +-- mul_ready :      Asserted permanently if SEQUENTIAL_MULTIPLIER=false.
    +-- div_ready :      Deasserted the cycle after start is asserted.
    +--                  Asserted when the division has completed.
    +--
    +--------------------------------------------------------------------------------
    +-- Copyright (C) 2012 Jose A. Ruiz
    +--                                                              
    +-- This source file may be used and distributed without         
    +-- restriction provided that this copyright statement is not    
    +-- removed from the file and that any derivative work contains  
    +-- the original copyright notice and the associated disclaimer. 
    +--                                                              
    +-- This source file is free software; you can redistribute it   
    +-- and/or modify it under the terms of the GNU Lesser General   
    +-- Public License as published by the Free Software Foundation; 
    +-- either version 2.1 of the License, or (at your option) any   
    +-- later version.                                               
    +--                                                              
    +-- This source 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 Lesser General Public License for more 
    +-- details.                                                     
    +--                                                              
    +-- You should have received a copy of the GNU Lesser General    
    +-- Public License along with this source; if not, download it   
    +-- from http://www.opencores.org/lgpl.shtml
    +--------------------------------------------------------------------------------
    +
    +library ieee;
    +use ieee.std_logic_1164.all;
    +use ieee.numeric_std.all;
    +
    +use work.light52_pkg.all;
    +use work.light52_ucode_pkg.all;
    +
    +entity light52_muldiv is
    +    generic (
    +        SEQUENTIAL_MULTIPLIER : boolean := false
    +    );
    +    port(
    +        clk :                   in std_logic;
    +        reset :                 in std_logic;
    +        
    +        data_a :                in t_byte;
    +        data_b :                in t_byte;
    +        start :                 in std_logic;
    +        
    +        prod_out :              out t_word;
    +        quot_out :              out t_byte;
    +        rem_out :               out t_byte;
    +        div_ov_out :            out std_logic;
    +        mul_ov_out :            out std_logic;
    +        
    +        mul_ready :             out std_logic;
    +        div_ready :             out std_logic
    +    );
    +end entity light52_muldiv;
    +
    +architecture sequential of light52_muldiv is
    +
    +signal bit_ctr :            integer range 0 to 8;
    +
    +signal b_shift_reg :        t_word;
    +
    +signal den_ge_256 :         std_logic;
    +signal num_ge_den :         std_logic;
    +signal sub_num :            std_logic;
    +
    +signal denominator :        t_byte;
    +signal rem_reg :            t_byte;
    +signal quot_reg :           t_byte;
    +signal prod_reg :           t_word;
    +signal ready :              std_logic;
    +
    +signal load_regs :          std_logic;
    +
    +begin
    +
    +-- Control logic ---------------------------------------------------------------
    +
    +control_counter: process(clk)
    +begin
    +    if clk'event and clk='1' then
    +        if reset='1' then
    +            bit_ctr <= 8;
    +        else
    +            if load_regs='1' then
    +                bit_ctr <= 0;
    +            elsif bit_ctr /= 8 then
    +                bit_ctr <= bit_ctr + 1;
    +            end if;
    +        end if;
    +    end if;
    +end process control_counter;
    +
    +-- Internal signal ready is asserted after 8 cycles.
    +-- The sequential multiplier will use this signal too, IF it takes 8 cycles.
    +
    +ready <= '1' when bit_ctr >= 8 else '0';
    +
    +
    +---- Divider logic -------------------------------------------------------------
    +
    +-- What we do is a simple base-2 'shift-and-subtract' algorithm that takes
    +-- 8 cycles to complete. We can get away with this because we deal with unsigned
    +-- numbers only.
    +
    +divider_registers: process(clk)
    +begin
    +    if clk'event and clk='1' then
    +        -- denominator shift register
    +        if load_regs='1' then
    +            b_shift_reg <= "0" & data_b & "0000000";
    +            -- Division overflow can be determined upon loading B reg data.
    +            -- OV will be raised only on div-by-zero.
    +            if data_b=X"00" then
    +                div_ov_out <= '1';
    +            else
    +                div_ov_out <= '0';
    +            end if;
    +        else
    +            b_shift_reg <= "0" & b_shift_reg(b_shift_reg'high downto 1);
    +        end if;
    +        
    +        -- numerator register
    +        if load_regs='1' then 
    +            rem_reg <= data_a;
    +        elsif bit_ctr/=8 and sub_num='1' then 
    +            rem_reg <= rem_reg - denominator;
    +        end if;
    +
    +        --- quotient register
    +        if load_regs='1' then
    +            quot_reg <= (others => '0');
    +        elsif bit_ctr/=8 then
    +            quot_reg <= quot_reg(quot_reg'high-1 downto 0) & sub_num;
    +        end if;
    +        
    +        load_regs <= start;
    +    end if;
    +end process divider_registers;
    +
    +denominator <= b_shift_reg(7 downto 0);
    +
    +-- The 16-bit comparison between b_shift_reg (denominator) and the zero-extended 
    +-- rem_reg (numerator) can be simplified by splitting it in 2: 
    +-- If the shifted denominator high byte is not zero, it is >=256...
    +den_ge_256 <= '1' when b_shift_reg(15 downto 8) /= X"00" else '0';
    +-- ...otherwise we need to compare the low bytes.
    +num_ge_den <= '1' when rem_reg >= denominator else '0';
    +sub_num <= '1' when den_ge_256='0' and num_ge_den='1' else '0';
    +
    +
    +quot_out <= quot_reg;
    +prod_out <= prod_reg;
    +rem_out <= rem_reg;
    +
    +div_ready <= ready;
    +
    +---- Multiplier logic ----------------------------------------------------------
    +
    +---- Combinational multiplier -----------------------------
    +multiplier_combinational: if not SEQUENTIAL_MULTIPLIER generate
    +
    +registered_combinational_multiplier:process(clk)
    +begin
    +    if clk'event and clk='1' then
    +        prod_reg <= data_a * data_b; -- t_byte is unsigned
    +    end if;
    +end process registered_combinational_multiplier;
    +
    +-- The multiplier output is valid in the cycle after the operands are loaded,
    +-- so by the time MUL is executed it's already done.
    +mul_ready <= '1';
    +
    +mul_ov_out <= '1' when prod_reg(15 downto 8)/=X"00" else '0';
    +prod_out <= prod_reg;
    +
    +end generate multiplier_combinational;
    +
    +---- Sequential multiplier --------------------------------
    +multiplier_sequential: if SEQUENTIAL_MULTIPLIER generate
    +
    +assert false
    +report "Sequential multiplier implementation not done yet."&
    +       " Use combinational implementation."
    +severity failure;
    +
    +end generate multiplier_sequential;
    +
    +end sequential;
    +
    diff --git a/autotests/html/light52_tb.vhdl.html b/autotests/html/light52_tb.vhdl.html new file mode 100644 index 0000000..3b9649c --- /dev/null +++ b/autotests/html/light52_tb.vhdl.html @@ -0,0 +1,187 @@ + + + +light52_tb.vhdl + +
    +--------------------------------------------------------------------------------
    +-- light52_tb.vhdl -- 
    +--------------------------------------------------------------------------------
    +-- This test bench simulates the execution of some program (whose object code
    +-- is in package obj_code_pkg, in the form of a memory init constant) and logs
    +-- the execution to a text file called 'hw_sim_log.txt' (light52_tb_pkg.vhdl).
    +--
    +-- This test bench does no actual tests on the core. Instead, the simulation log
    +-- is meant to be matched against the simulation log produced by running the 
    +-- same program on the software simulator B51 (also included with this project).
    +-- 
    +-- This will catch errors in the implementation of the CPU if the simulated
    +-- program has anough coverage -- the opcode tester is meant to cover all CPU
    +-- opcodes in many (not all) of their corner cases.
    +-- This scheme will not help in catching errors in the peripheral modules, 
    +-- mainly because the current version of B51 does not simulate them.
    +--
    +--------------------------------------------------------------------------------
    +-- Copyright (C) 2012 Jose A. Ruiz
    +--                                                              
    +-- This source file may be used and distributed without         
    +-- restriction provided that this copyright statement is not    
    +-- removed from the file and that any derivative work contains  
    +-- the original copyright notice and the associated disclaimer. 
    +--                                                              
    +-- This source file is free software; you can redistribute it   
    +-- and/or modify it under the terms of the GNU Lesser General   
    +-- Public License as published by the Free Software Foundation; 
    +-- either version 2.1 of the License, or (at your option) any   
    +-- later version.                                               
    +--                                                              
    +-- This source 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 Lesser General Public License for more 
    +-- details.                                                     
    +--                                                              
    +-- You should have received a copy of the GNU Lesser General    
    +-- Public License along with this source; if not, download it   
    +-- from http://www.opencores.org/lgpl.shtml
    +--------------------------------------------------------------------------------
    +
    +
    +library ieee;
    +use ieee.std_logic_1164.all;
    +use ieee.std_logic_arith.all;
    +use ieee.std_logic_unsigned.all;
    +use std.textio.all;
    +
    +use work.light52_pkg.all;
    +use work.obj_code_pkg.all;
    +use work.light52_tb_pkg.all;
    +use work.txt_util.all;
    +
    +entity light52_tb is
    +generic (BCD : boolean := true);
    +end;
    +
    +
    +architecture testbench of light52_tb is
    +
    +--------------------------------------------------------------------------------
    +-- Simulation parameters
    +-- FIXME these should be in parameter package
    +
    +-- Simulated clock period is the same as the usual target, the DE-1 board
    +constant T : time := 20 ns; -- 50MHz
    +constant SIMULATION_LENGTH : integer := 400000;
    +
    +--------------------------------------------------------------------------------
    +-- MPU interface 
    +
    +signal clk :                std_logic := '0';
    +signal reset :              std_logic := '1';
    +
    +signal p0_out :             std_logic_vector(7 downto 0);
    +signal p1_out :             std_logic_vector(7 downto 0);
    +signal p2_in :              std_logic_vector(7 downto 0);
    +signal p3_in :              std_logic_vector(7 downto 0);
    +
    +signal external_irq :       std_logic_vector(7 downto 0);
    +
    +signal txd, rxd :           std_logic;
    +
    +--------------------------------------------------------------------------------
    +-- Logging signals & simulation control 
    +
    +-- Asserted high to disable the clock and terminate the simulation.
    +signal done :               std_logic := '0';
    +
    +-- Log file
    +file log_file: TEXT open write_mode is "hw_sim_log.txt";
    +-- Console output log file
    +file con_file: TEXT open write_mode is "hw_sim_console_log.txt";
    +-- Info record needed by the logging fuctions
    +signal log_info :           t_log_info;
    +
    +begin
    +
    +---- UUT instantiation ---------------------------------------------------------
    +
    +uut: entity work.light52_mcu
    +    generic map (
    +        IMPLEMENT_BCD_INSTRUCTIONS => BCD,
    +        CODE_ROM_SIZE =>    work.obj_code_pkg.XCODE_SIZE,
    +        XDATA_RAM_SIZE =>   work.obj_code_pkg.XDATA_SIZE,
    +        OBJ_CODE =>         work.obj_code_pkg.object_code
    +    )
    +    port map (
    +        clk             => clk,
    +        reset           => reset,
    +        
    +        txd             => txd,
    +        rxd             => rxd,
    +        
    +        external_irq    => external_irq,
    +                
    +        p0_out          => p0_out,
    +        p1_out          => p1_out,
    +        p2_in           => p2_in,
    +        p3_in           => p3_in
    +    );
    +    
    +    -- UART is looped back in the test bench.
    +    rxd <= txd;
    +    
    +    -- I/O ports are looped back and otherwise unused.
    +    p2_in <= p0_out;
    +    p3_in <= p1_out;
    +    
    +    -- External IRQ inputs are tied to port P1 for test purposes
    +    external_irq <= p1_out;
    +
    +    ---- Master clock: free running clock used as main module clock ------------
    +    run_master_clock: process(done, clk)
    +    begin
    +        if done = '0' then
    +            clk <= not clk after T/2;
    +        end if;
    +    end process run_master_clock;
    +
    +
    +    ---- Main simulation process: reset MCU and wait for fixed period ----------
    +
    +    drive_uut: process
    +    begin
    +        -- Leave reset asserted for a few clock cycles...
    +        reset <= '1';
    +        wait for T*4;
    +        reset <= '0';
    +        
    +        -- ...and wait for the test to hit a termination condition (evaluated by
    +        -- function log_cpu_activity) or to just timeout.
    +        wait for T*SIMULATION_LENGTH;
    +
    +        -- If we arrive here, the simulation timed out (termination conditions
    +        -- trigger a failed assertion).
    +        -- So print a timeout message and quit.
    +        print("TB timed out.");
    +        done <= '1';
    +        wait;
    +        
    +    end process drive_uut;
    +
    +
    +    -- Logging process: launch logger functions --------------------------------
    +    log_execution: process
    +    begin
    +        -- Log cpu activity until done='1'.
    +        log_cpu_activity(clk, reset, done, "/uut",
    +                         log_info, work.obj_code_pkg.XCODE_SIZE, "log_info", 
    +                         X"0000", log_file, con_file);
    +        
    +        -- Flush console log file when finished.
    +        log_flush_console(log_info, con_file);
    +        
    +        wait;
    +    end process log_execution;
    +
    +end architecture testbench;
    +
    diff --git a/autotests/html/meson.build.html b/autotests/html/meson.build.html new file mode 100644 index 0000000..66e7942 --- /dev/null +++ b/autotests/html/meson.build.html @@ -0,0 +1,28 @@ + + + +meson.build + +
    +# Unit test for Meson syntax highlight. License: LGPL
    +project('projectname', 'cpp')
    +
    +
    +
    +sourcefiles = ['a.cpp', 'b.cpp']
    +
    +foreach sourcefile : sourcefiles
    +    message('this is a source file: ' + sourcefile)
    +endforeach
    +
    +x=1
    +if x+1 == 2 and x-1 == 0
    +    message('I can work in this universe!')
    +endif
    +
    +subprojectresult = subproject('mysubprojectdir')
    +
    +mysharedlib = shared_library('libraryname', sourcefiles, linkwith: subprojectresult.staticlib)
    +
    +executable('myprogram', ['test.cpp'], linkwith: mysharedlib)
    +
    diff --git a/autotests/html/or1200_dc_fsm.v.html b/autotests/html/or1200_dc_fsm.v.html new file mode 100644 index 0000000..7f26b75 --- /dev/null +++ b/autotests/html/or1200_dc_fsm.v.html @@ -0,0 +1,570 @@ + + + +or1200_dc_fsm.v + +
    +//////////////////////////////////////////////////////////////////////
    +////                                                              ////
    +////  OR1200's DC FSM                                             ////
    +////                                                              ////
    +////  This file is part of the OpenRISC 1200 project              ////
    +////  http://opencores.org/project,or1k                           ////
    +////                                                              ////
    +////  Description                                                 ////
    +////  Data cache state machine                                    ////
    +////                                                              ////
    +////  To Do:                                                      ////
    +////   - Test error during line read or write                     ////
    +////                                                              ////
    +////  Author(s):                                                  ////
    +////      - Damjan Lampret, lampret@opencores.org                 ////
    +////      - Julius Baxter, julius@opencores.org                   ////
    +////                                                              ////
    +//////////////////////////////////////////////////////////////////////
    +////                                                              ////
    +//// Copyright (C) 2000, 2010 Authors and OPENCORES.ORG           ////
    +////                                                              ////
    +//// This source file may be used and distributed without         ////
    +//// restriction provided that this copyright statement is not    ////
    +//// removed from the file and that any derivative work contains  ////
    +//// the original copyright notice and the associated disclaimer. ////
    +////                                                              ////
    +//// This source file is free software; you can redistribute it   ////
    +//// and/or modify it under the terms of the GNU Lesser General   ////
    +//// Public License as published by the Free Software Foundation; ////
    +//// either version 2.1 of the License, or (at your option) any   ////
    +//// later version.                                               ////
    +////                                                              ////
    +//// This source 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 Lesser General Public License for more ////
    +//// details.                                                     ////
    +////                                                              ////
    +//// You should have received a copy of the GNU Lesser General    ////
    +//// Public License along with this source; if not, download it   ////
    +//// from http://www.opencores.org/lgpl.shtml                     ////
    +////                                                              ////
    +//////////////////////////////////////////////////////////////////////
    +//
    +// $Log: or1200_dc_fsm.v,v $
    +// Revision 2.0  2010/06/30 11:00:00  ORSoC
    +// Minor update: 
    +// Bugs fixed. 
    +//
    +
    +// synopsys translate_off
    +`include "timescale.v"
    +// synopsys translate_on
    +`include "or1200_defines.v"
    +
    +`define OR1200_DCFSM_IDLE	3'd0
    +`define OR1200_DCFSM_CLOADSTORE	3'd1
    +`define OR1200_DCFSM_LOOP2	3'd2
    +`define OR1200_DCFSM_LOOP3	3'd3
    +`define OR1200_DCFSM_LOOP4	3'd4
    +`define OR1200_DCFSM_FLUSH5	3'd5
    +`define OR1200_DCFSM_INV6	3'd6
    +`define OR1200_DCFSM_WAITSPRCS7	3'd7
    +
    +
    +
    +//
    +// Data cache FSM for cache line of 16 bytes (4x singleword)
    +//
    +
    +module or1200_dc_fsm
    +  (
    +   // Clock and reset
    +   clk, rst,
    +   
    +   // Internal i/f to top level DC
    +   dc_en, dcqmem_cycstb_i, dcqmem_ci_i, dcqmem_we_i, dcqmem_sel_i,
    +   tagcomp_miss, biudata_valid, biudata_error, lsu_addr,
    +   dcram_we, biu_read, biu_write, biu_do_sel, dcram_di_sel, first_hit_ack, 
    +   first_miss_ack, first_miss_err, burst, tag_we, tag_valid, dc_addr, 
    +   dc_no_writethrough, tag_dirty, dirty, tag, tag_v, dc_block_flush, 
    +   dc_block_writeback, spr_dat_i, mtspr_dc_done, spr_cswe
    +   );
    +
    +   //
    +   // I/O
    +   //
    +   input				clk;
    +   input				rst;
    +   input				dc_en;
    +   input				dcqmem_cycstb_i;
    +   input				dcqmem_ci_i;
    +   input				dcqmem_we_i;
    +   input [3:0] 				dcqmem_sel_i;
    +   input				tagcomp_miss;
    +   input				biudata_valid;
    +   input				biudata_error;
    +   input [31:0] 			lsu_addr;
    +   output [3:0] 			dcram_we;
    +   output				biu_read;
    +   output				biu_write;
    +   output 				dcram_di_sel;
    +   output 				biu_do_sel;
    +   output				first_hit_ack;
    +   output				first_miss_ack;
    +   output				first_miss_err;
    +   output				burst;
    +   output				tag_we;
    +   output 				tag_valid;
    +   output [31:0] 			dc_addr;
    +   input 				dc_no_writethrough;
    +   output 				tag_dirty;
    +   input 				dirty;
    +   input [`OR1200_DCTAG_W-2:0] 		tag;
    +   input 				tag_v;   
    +   input 				dc_block_flush;
    +   input 				dc_block_writeback;
    +   input [31:0] 			spr_dat_i;
    +   output 				mtspr_dc_done;
    +   input 				spr_cswe;
    +   
    +   
    +   //
    +   // Internal wires and regs
    +   //
    +   reg [31:0] 				addr_r;
    +   reg [2:0] 				state;
    +   reg [`OR1200_DCLS-1:0] 		cnt;
    +   reg 					hitmiss_eval;
    +   reg 					store;
    +   reg 					load;
    +   reg 					cache_inhibit;
    +   reg 					cache_miss;
    +   reg 					cache_dirty_needs_writeback;
    +   reg                                  did_early_load_ack;
    +   reg 					cache_spr_block_flush;
    +   reg 					cache_spr_block_writeback;
    +   reg 					cache_wb;   
    +   wire 				load_hit_ack;
    +   wire 				load_miss_ack;
    +   wire 				load_inhibit_ack;   
    +   wire 				store_hit_ack;
    +   wire 				store_hit_writethrough_ack;   
    +   wire 				store_miss_writethrough_ack;   
    +   wire 				store_inhibit_ack;
    +   wire 				store_miss_ack;
    +   wire 				dcram_we_after_line_load;
    +   wire 				dcram_we_during_line_load;
    +   wire 				tagram_we_end_of_loadstore_loop;
    +   wire 				tagram_dirty_bit_set;   
    +   wire 				writethrough;
    +   wire 				cache_inhibit_with_eval;
    +   wire [(`OR1200_DCLS-1)-2:0]		next_addr_word;
    +
    +   //
    +   // Cache inhibit
    +   //
    +   
    +   // Indicates whether cache is inhibited, during hitmiss_eval and after
    +   assign cache_inhibit_with_eval = (hitmiss_eval & dcqmem_ci_i) |
    +				    (!hitmiss_eval & cache_inhibit);
    +   
    +   //
    +   // Generate of DCRAM write enables
    +   //
    +
    +   // WE when non-writethrough, and had to wait for a line to load.
    +   assign dcram_we_after_line_load = (state == `OR1200_DCFSM_LOOP3) &
    +				    dcqmem_we_i & !cache_dirty_needs_writeback &
    +				     !did_early_load_ack;
    +
    +   // WE when receiving the data cache line
    +   assign dcram_we_during_line_load = (state == `OR1200_DCFSM_LOOP2) & load & 
    +				      biudata_valid;   
    +   
    +   assign dcram_we =(// Write when hit - make sure it is only when hit - could
    +		     // maybe be doing write through and don't want to corrupt
    +		     // cache lines corresponding to the writethrough addr_r.
    +		     ({4{store_hit_ack | store_hit_writethrough_ack}} |
    +		     // Write after load of line
    +		     {4{dcram_we_after_line_load}}) & 
    +		     dcqmem_sel_i		 ) |
    +		    // Write during load
    +		    {4{dcram_we_during_line_load}};
    +
    +   //
    +   // Tag RAM signals
    +   //
    +   
    +   // WE to tag RAM when we finish loading a line.
    +   assign tagram_we_end_of_loadstore_loop = ((state==`OR1200_DCFSM_LOOP2) & 
    +					     biudata_valid & !(|cnt));
    +   
    +`ifndef OR1200_DC_WRITETHROUGH
    +   // No writethrough, so mark a line dirty whenever we write to it
    +   assign tagram_dirty_bit_set = store_hit_ack | store_miss_ack;
    +
    +   // Generate done signal for MTSPR instructions that may block execution
    +   assign mtspr_dc_done = // Either DC disabled or we're not selected, or
    +			  !dc_en | !spr_cswe |
    +			  // Requested address not valid or writeback and !dirty
    +			  ((state==`OR1200_DCFSM_FLUSH5) & 
    +			   (!tag_v | (cache_spr_block_writeback & !dirty))) |
    +			  // Writeback or flush is finished
    +			  ((state==`OR1200_DCFSM_LOOP3) & 
    +			   (cache_spr_block_flush | cache_spr_block_writeback))|
    +			  // Invalidate of clean line finished
    +			  ((state==`OR1200_DCFSM_INV6) & cache_spr_block_flush);
    +   
    +   
    +`else
    + `ifdef OR1200_DC_NOSTACKWRITETHROUGH   
    +   // For dirty bit setting when having writethrough but not for stack
    +   assign tagram_dirty_bit_set = store_hit_ack | store_miss_ack;
    + `else
    +   // Lines will never be dirty if always writethrough
    +   assign tagram_dirty_bit_set = 0;
    + `endif
    +   
    +   assign mtspr_dc_done = 1'b1;
    +   
    +`endif
    +
    +   assign tag_dirty = tagram_dirty_bit_set;
    +   
    +   // WE to tag RAM
    +   assign tag_we = tagram_we_end_of_loadstore_loop |		    
    +                    tagram_dirty_bit_set | (state == `OR1200_DCFSM_INV6);
    +   
    +
    +   // Valid bit
    +   // Set valid when end of line load, or marking dirty (is still valid)
    +   assign tag_valid = ( tagram_we_end_of_loadstore_loop & 
    +			(load | (store & cache_spr_block_writeback)) ) |
    +		      tagram_dirty_bit_set;
    +
    +
    +   
    +   //
    +   // BIU read and write
    +   //
    +
    +   assign biu_read = // Bus read request when:
    +		     // 1) Have a miss and not dirty or a load with inhibit
    +		     ((state == `OR1200_DCFSM_CLOADSTORE) &
    +		      (((hitmiss_eval & tagcomp_miss & !dirty & 
    +			 !(store & writethrough)) | 
    +			(load & cache_inhibit_with_eval)) & dcqmem_cycstb_i)) |
    +		     // 2) In the loop and loading
    +		     ((state == `OR1200_DCFSM_LOOP2) & load);
    +   
    +
    +   assign biu_write = // Bus write request when:
    +		      // 1) Have a miss and dirty or store with inhibit
    +		      ((state == `OR1200_DCFSM_CLOADSTORE) & 
    +		       (((hitmiss_eval & tagcomp_miss & dirty) | 
    +			 (store & writethrough)) | 
    +			(store & cache_inhibit_with_eval)) & dcqmem_cycstb_i) |
    +		      // 2) In the loop and storing
    +		      ((state == `OR1200_DCFSM_LOOP2) & store);
    +   
    +   //
    +   // Select for data to actual cache RAM (from LSU or BIU)
    +   //
    +   // Data to DCRAM - from external bus when loading (from IU when store)
    +   assign dcram_di_sel = load;
    +   // Data to external bus - always from IU except in case of bursting back
    +   //                        the line to memory. (1 selects DCRAM)
    +   assign biu_do_sel = (state == `OR1200_DCFSM_LOOP2) & store;
    +
    +   // 3-bit wire for calculating next word of burst write, depending on
    +   // line size of data cache.
    +   assign next_addr_word =  addr_r[`OR1200_DCLS-1:2] + 1;
    +   
    +   // Address to cache RAM (tag address also derived from this)   
    +   assign dc_addr =
    +		   // First check if we've got a block flush or WB op
    +		   ((dc_block_flush & !cache_spr_block_flush) | 
    +		   (dc_block_writeback & !cache_spr_block_writeback)) ? 
    +		   spr_dat_i :
    +		   (state==`OR1200_DCFSM_FLUSH5) ? addr_r:
    +		    // If no SPR action, then always put out address from LSU
    +		    (state==`OR1200_DCFSM_IDLE | hitmiss_eval) ? lsu_addr :
    +		    // Next, if in writeback loop, when ACKed must immediately
    +		    // output next word address (the RAM address takes a cycle
    +		    // to increment, but it's needed immediately for burst)
    +		    // otherwise, output our registered address.
    +		    (state==`OR1200_DCFSM_LOOP2 & biudata_valid & store ) ? 
    +		    {addr_r[31:`OR1200_DCLS], next_addr_word, 2'b00} : addr_r;
    +   
    +`ifdef OR1200_DC_WRITETHROUGH
    + `ifdef OR1200_DC_NOSTACKWRITETHROUGH   
    +   assign writethrough = !dc_no_writethrough;
    + `else
    +   assign writethrough = 1;
    + `endif
    +`else
    +   assign writethrough = 0;
    +`endif
    +   
    +   //
    +   // ACK generation for LSU
    +   //
    +   
    +   // ACK for when it's a cache hit
    +   assign first_hit_ack = load_hit_ack | store_hit_ack | 
    +			  store_hit_writethrough_ack | 
    +			  store_miss_writethrough_ack |
    +			  store_inhibit_ack | store_miss_ack ;
    +
    +   // ACK for when it's a cache miss - load only, is used in MUX for data back
    +   //                                  LSU straight off external data bus. In
    +   //                                  this was is also used for cache inhibit
    +   //                                  loads.
    +   // first_hit_ack takes precedence over first_miss_ack
    +   assign first_miss_ack = ~first_hit_ack & (load_miss_ack | load_inhibit_ack);
    +   
    +   // ACK cache hit on load
    +   assign load_hit_ack = (state == `OR1200_DCFSM_CLOADSTORE) & 
    +			 hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i & load;
    +   
    +   // ACK cache hit on store, no writethrough
    +   assign store_hit_ack = (state == `OR1200_DCFSM_CLOADSTORE) & 
    +			  hitmiss_eval  & !tagcomp_miss & !dcqmem_ci_i &
    +			  store & !writethrough;
    +   
    +   // ACK cache hit on store with writethrough
    +   assign store_hit_writethrough_ack = (state == `OR1200_DCFSM_CLOADSTORE) & 
    +				       !cache_miss & !cache_inhibit &
    +				       store & writethrough & biudata_valid;
    +   
    +   // ACK cache miss on store with writethrough
    +   assign store_miss_writethrough_ack = (state == `OR1200_DCFSM_CLOADSTORE) & 
    +					cache_miss & !cache_inhibit &
    +					store & writethrough & biudata_valid;
    +      
    +   // ACK store when cacheinhibit
    +   assign store_inhibit_ack = (state == `OR1200_DCFSM_CLOADSTORE) &
    +			      store & cache_inhibit & biudata_valid;
    +   
    +   
    +   // Get the _early_ ack on first ACK back from wishbone during load only
    +   // Condition is that we're in the loop - that it's the first ack we get (can
    +   // tell from value of cnt), and we're loading a line to read from it (not
    +   // loading to write to it, in the case of a write without writethrough.)
    +   assign load_miss_ack =  ((state== `OR1200_DCFSM_LOOP2) & load &
    +			    (cnt==((1 << `OR1200_DCLS) - 4)) & biudata_valid & 
    +			    !(dcqmem_we_i & !writethrough));
    +   
    +   assign load_inhibit_ack = (state == `OR1200_DCFSM_CLOADSTORE) &
    +			     load & cache_inhibit & biudata_valid;   
    +   
    +   // This will be case of write through disabled, and had to load a line.
    +   assign store_miss_ack = dcram_we_after_line_load;
    +            
    +   assign first_miss_err = biudata_error & dcqmem_cycstb_i;
    +
    +   // Signal burst when in the load/store loop. We will always try to burst.
    +   assign burst = (state == `OR1200_DCFSM_LOOP2);
    +
    +   //
    +   // Main DC FSM
    +   //
    +   always @(posedge clk or `OR1200_RST_EVENT rst) begin
    +      if (rst == `OR1200_RST_VALUE) begin
    +	 state <=  `OR1200_DCFSM_IDLE;
    +	 addr_r <=  32'd0;
    +	 hitmiss_eval <=  1'b0;
    +	 store <=  1'b0;
    +	 load <=  1'b0;
    +	 cnt <=  `OR1200_DCLS'd0;
    +         cache_miss <=  1'b0;
    +	 cache_dirty_needs_writeback <= 1'b0;
    +	 cache_inhibit <=  1'b0;
    +	 did_early_load_ack <= 1'b0;
    +	 cache_spr_block_flush <= 1'b0;
    +	 cache_spr_block_writeback <= 1'b0;
    +      end
    +      else
    +	case (state)	// synopsys parallel_case
    +	  
    +          `OR1200_DCFSM_IDLE : begin
    +	     if (dc_en & (dc_block_flush | dc_block_writeback))
    +	       begin
    +		  cache_spr_block_flush <= dc_block_flush;
    +		  cache_spr_block_writeback <= dc_block_writeback;
    +		  hitmiss_eval <= 1'b1;
    +		  state <= `OR1200_DCFSM_FLUSH5;
    +		  addr_r <=  spr_dat_i;
    +	       end
    +	     else if (dc_en & dcqmem_cycstb_i)
    +	       begin
    +		  state <= `OR1200_DCFSM_CLOADSTORE;
    +		  hitmiss_eval <=  1'b1;
    +		  store <=  dcqmem_we_i;
    +		  load <=  !dcqmem_we_i;
    +	       end
    +	     
    +	     
    +          end // case: `OR1200_DCFSM_IDLE
    +	  
    +          `OR1200_DCFSM_CLOADSTORE: begin
    +	     hitmiss_eval <=  1'b0;
    +	     if (hitmiss_eval) begin
    +                cache_inhibit <=  dcqmem_ci_i; // Check for cache inhibit here
    +                cache_miss <=  tagcomp_miss;
    +		cache_dirty_needs_writeback <= dirty;
    +		addr_r <=  lsu_addr;
    +             end
    +
    +	     // Evaluate any cache line load/stores in first cycle:
    +			     //
    +	     if (hitmiss_eval & tagcomp_miss & !(store & writethrough) &
    +		 !dcqmem_ci_i)
    +	       begin
    +		  // Miss - first either:
    +		  //  1) write back dirty line 
    +		  if (dirty) begin
    +		     // Address for writeback
    +		     addr_r <=  {tag, lsu_addr[`OR1200_DCINDXH:2],2'd0};
    +		     load <= 1'b0;
    +		     store <= 1'b1;
    +`ifdef OR1200_VERBOSE		     
    +		     $display("%t: dcache miss and dirty", $time);
    +`endif
    +		  end
    +		  //  2) load requested line
    +		  else begin
    +		     addr_r <=  lsu_addr;
    +		     load <= 1'b1;
    +		     store <= 1'b0;
    +		  end // else: !if(dirty)
    +		  state <= `OR1200_DCFSM_LOOP2;		  
    +		  // Set the counter for the burst accesses
    +		  cnt <=  ((1 << `OR1200_DCLS) - 4);
    +	       end
    +             else if (// Strobe goes low
    +		      !dcqmem_cycstb_i |
    +		      // Cycle finishes
    +		      (!hitmiss_eval & (biudata_valid | biudata_error)) |
    +		      // Cache hit in first cycle....
    +		      (hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i &
    +		      // .. and you're not doing a writethrough store..
    +		      !(store & writethrough))) begin
    +                state <=  `OR1200_DCFSM_IDLE;
    +                load <=  1'b0;
    +		store <= 1'b0;
    +		cache_inhibit <= 1'b0;
    +		cache_dirty_needs_writeback <= 1'b0;
    +             end	     
    +          end // case: `OR1200_DCFSM_CLOADSTORE	  
    +	  
    +          `OR1200_DCFSM_LOOP2 : begin // loop/abort	     
    +             if (!dc_en| biudata_error) begin
    +                state <=  `OR1200_DCFSM_IDLE;
    +                load <=  1'b0;
    +		store <= 1'b0;
    +		cnt <= `OR1200_DCLS'd0;
    +             end
    +             if (biudata_valid & (|cnt)) begin
    +                cnt <=  cnt - 4;
    +                addr_r[`OR1200_DCLS-1:2] <=  addr_r[`OR1200_DCLS-1:2] + 1;
    +             end
    +	     else if (biudata_valid & !(|cnt)) begin
    +		state <= `OR1200_DCFSM_LOOP3;
    +		addr_r <=  lsu_addr;
    +		load <= 1'b0;
    +		store <= 1'b0;
    +	     end
    +
    +	     // Track if we did an early ack during a load
    +	     if (load_miss_ack)
    +	       did_early_load_ack <= 1'b1;
    +	     
    +
    +          end // case: `OR1200_DCFSM_LOOP2
    +	  
    +	  `OR1200_DCFSM_LOOP3: begin // figure out next step
    +	     if (cache_dirty_needs_writeback) begin
    +		// Just did store of the dirty line so now load new one
    +		load <= 1'b1;
    +		// Set the counter for the burst accesses
    +		cnt <=  ((1 << `OR1200_DCLS) - 4);
    +		// Address of line to be loaded
    +		addr_r <=  lsu_addr;
    +		cache_dirty_needs_writeback <= 1'b0;
    +		state <= `OR1200_DCFSM_LOOP2;
    +	     end // if (cache_dirty_needs_writeback)
    +	     else if (cache_spr_block_flush | cache_spr_block_writeback) begin
    +		// Just wrote back the line to memory, we're finished.
    +		cache_spr_block_flush <= 1'b0;
    +		cache_spr_block_writeback <= 1'b0;
    +		state <= `OR1200_DCFSM_WAITSPRCS7;
    +	     end
    +	     else begin
    +		// Just loaded a new line, finish up
    +		did_early_load_ack <= 1'b0;
    +		state <= `OR1200_DCFSM_LOOP4;
    +	     end
    +	  end // case: `OR1200_DCFSM_LOOP3
    +
    +	  `OR1200_DCFSM_LOOP4: begin
    +	     state <=  `OR1200_DCFSM_IDLE;
    +	  end
    +
    +	  `OR1200_DCFSM_FLUSH5: begin
    +	     hitmiss_eval <= 1'b0;
    +	     if (hitmiss_eval & !tag_v)
    +	       begin
    +		  // Not even cached, just ignore
    +		  cache_spr_block_flush <= 1'b0;
    +		  cache_spr_block_writeback <= 1'b0;
    +		  state <=  `OR1200_DCFSM_WAITSPRCS7;
    +	       end
    +	     else if (hitmiss_eval & tag_v)
    +	       begin
    +		  // Tag is valid - what do we do?
    +		  if ((cache_spr_block_flush | cache_spr_block_writeback) & 
    +		      dirty) begin
    +		     // Need to writeback
    +		     // Address for writeback (spr_dat_i has already changed so
    +		     // use line number from addr_r)
    +		     addr_r <=  {tag, addr_r[`OR1200_DCINDXH:2],2'd0};
    +		     load <= 1'b0;
    +		     store <= 1'b1;
    +`ifdef OR1200_VERBOSE		     
    +		     $display("%t: block flush: dirty block", $time);
    +`endif
    +		     state <= `OR1200_DCFSM_LOOP2;		  
    +		     // Set the counter for the burst accesses
    +		     cnt <=  ((1 << `OR1200_DCLS) - 4);
    +		  end
    +		  else if (cache_spr_block_flush & !dirty)
    +		    begin
    +		       // Line not dirty, just need to invalidate
    +		       state <=  `OR1200_DCFSM_INV6;
    +		    end // else: !if(dirty)
    +		  else if (cache_spr_block_writeback & !dirty)
    +		    begin
    +		       // Nothing to do - line is valid but not dirty
    +		       cache_spr_block_writeback <= 1'b0;
    +		       state <=  `OR1200_DCFSM_WAITSPRCS7;
    +		    end
    +	  end // if (hitmiss_eval & tag_v)
    +	  end
    +	  `OR1200_DCFSM_INV6: begin
    +	     cache_spr_block_flush <= 1'b0;
    +	     // Wait until SPR CS goes low before going back to idle
    +	     if (!spr_cswe)
    +	       state <=  `OR1200_DCFSM_IDLE;
    +	  end
    +	  `OR1200_DCFSM_WAITSPRCS7: begin
    +	     // Wait until SPR CS goes low before going back to idle
    +	     if (!spr_cswe)
    +	       state <=  `OR1200_DCFSM_IDLE;
    +	  end
    +
    +	endcase // case (state)
    +      
    +   end // always @ (posedge clk or `OR1200_RST_EVENT rst)
    +   
    +
    +endmodule
    +
    diff --git a/autotests/html/or1200_du.v.html b/autotests/html/or1200_du.v.html new file mode 100644 index 0000000..daf06ab --- /dev/null +++ b/autotests/html/or1200_du.v.html @@ -0,0 +1,1810 @@ + + + +or1200_du.v + +
    +//////////////////////////////////////////////////////////////////////
    +////                                                              ////
    +////  OR1200's Debug Unit                                         ////
    +////                                                              ////
    +////  This file is part of the OpenRISC 1200 project              ////
    +////  http://www.opencores.org/project,or1k                       ////
    +////                                                              ////
    +////  Description                                                 ////
    +////  Basic OR1200 debug unit.                                    ////
    +////                                                              ////
    +////  To Do:                                                      ////
    +////   - make it smaller and faster                               ////
    +////                                                              ////
    +////  Author(s):                                                  ////
    +////      - Damjan Lampret, lampret@opencores.org                 ////
    +////                                                              ////
    +//////////////////////////////////////////////////////////////////////
    +////                                                              ////
    +//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
    +////                                                              ////
    +//// This source file may be used and distributed without         ////
    +//// restriction provided that this copyright statement is not    ////
    +//// removed from the file and that any derivative work contains  ////
    +//// the original copyright notice and the associated disclaimer. ////
    +////                                                              ////
    +//// This source file is free software; you can redistribute it   ////
    +//// and/or modify it under the terms of the GNU Lesser General   ////
    +//// Public License as published by the Free Software Foundation; ////
    +//// either version 2.1 of the License, or (at your option) any   ////
    +//// later version.                                               ////
    +////                                                              ////
    +//// This source 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 Lesser General Public License for more ////
    +//// details.                                                     ////
    +////                                                              ////
    +//// You should have received a copy of the GNU Lesser General    ////
    +//// Public License along with this source; if not, download it   ////
    +//// from http://www.opencores.org/lgpl.shtml                     ////
    +////                                                              ////
    +//////////////////////////////////////////////////////////////////////
    +//
    +//
    +// $Log: or1200_du.v,v $
    +// Revision 2.0  2010/06/30 11:00:00  ORSoC
    +// Minor update: 
    +// Bugs fixed. 
    +
    +// synopsys translate_off
    +`include "timescale.v"
    +// synopsys translate_on
    +`include "or1200_defines.v"
    +
    +//
    +// Debug unit
    +//
    +
    +module or1200_du(
    +	// RISC Internal Interface
    +	clk, rst,
    +	dcpu_cycstb_i, dcpu_we_i, dcpu_adr_i, dcpu_dat_lsu,
    +	dcpu_dat_dc, icpu_cycstb_i,
    +	ex_freeze, branch_op, ex_insn, id_pc,
    +	spr_dat_npc, rf_dataw,
    +	du_dsr, du_dmr1, du_stall, du_addr, du_dat_i, du_dat_o,
    +	du_read, du_write, du_except_stop, du_hwbkpt, du_flush_pipe,
    +	spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
    +
    +	// External Debug Interface
    +	dbg_stall_i, dbg_ewt_i,	dbg_lss_o, dbg_is_o, dbg_wp_o, dbg_bp_o,
    +	dbg_stb_i, dbg_we_i, dbg_adr_i, dbg_dat_i, dbg_dat_o, dbg_ack_o
    +);
    +
    +parameter dw = `OR1200_OPERAND_WIDTH;
    +parameter aw = `OR1200_OPERAND_WIDTH;
    +
    +//
    +// I/O
    +//
    +
    +//
    +// RISC Internal Interface
    +//
    +input				clk;		// Clock
    +input				rst;		// Reset
    +input				dcpu_cycstb_i;	// LSU status
    +input				dcpu_we_i;	// LSU status
    +input	[31:0]			dcpu_adr_i;	// LSU addr
    +input	[31:0]			dcpu_dat_lsu;	// LSU store data
    +input	[31:0]			dcpu_dat_dc;	// LSU load data
    +input	[`OR1200_FETCHOP_WIDTH-1:0]	icpu_cycstb_i;	// IFETCH unit status
    +input				ex_freeze;	// EX stage freeze
    +input	[`OR1200_BRANCHOP_WIDTH-1:0]	branch_op;	// Branch op
    +input	[dw-1:0]		ex_insn;	// EX insn
    +input	[31:0]			id_pc;		// insn fetch EA
    +input	[31:0]			spr_dat_npc;	// Next PC (for trace)
    +input	[31:0]			rf_dataw;	// ALU result (for trace)
    +output	[`OR1200_DU_DSR_WIDTH-1:0]     du_dsr;		// DSR
    +output	[24: 0]			du_dmr1;
    +output				du_stall;	// Debug Unit Stall
    +output	[aw-1:0]		du_addr;	// Debug Unit Address
    +input	[dw-1:0]		du_dat_i;	// Debug Unit Data In
    +output	[dw-1:0]		du_dat_o;	// Debug Unit Data Out
    +output				du_read;	// Debug Unit Read Enable
    +output				du_write;	// Debug Unit Write Enable
    +input	[13:0]			du_except_stop;	// Exception masked by DSR
    +output				du_hwbkpt;	// Cause trap exception (HW Breakpoints)
    +output				du_flush_pipe;	// Cause pipeline flush and pc<-npc
    +input				spr_cs;		// SPR Chip Select
    +input				spr_write;	// SPR Read/Write
    +input	[aw-1:0]		spr_addr;	// SPR Address
    +input	[dw-1:0]		spr_dat_i;	// SPR Data Input
    +output	[dw-1:0]		spr_dat_o;	// SPR Data Output
    +
    +//
    +// External Debug Interface
    +//
    +input			dbg_stall_i;	// External Stall Input
    +input			dbg_ewt_i;	// External Watchpoint Trigger Input
    +output	[3:0]		dbg_lss_o;	// External Load/Store Unit Status
    +output	[1:0]		dbg_is_o;	// External Insn Fetch Status
    +output	[10:0]		dbg_wp_o;	// Watchpoints Outputs
    +output			dbg_bp_o;	// Breakpoint Output
    +input			dbg_stb_i;      // External Address/Data Strobe
    +input			dbg_we_i;       // External Write Enable
    +input	[aw-1:0]	dbg_adr_i;	// External Address Input
    +input	[dw-1:0]	dbg_dat_i;	// External Data Input
    +output	[dw-1:0]	dbg_dat_o;	// External Data Output
    +output			dbg_ack_o;	// External Data Acknowledge (not WB compatible)
    +reg	[dw-1:0]	dbg_dat_o;	// External Data Output
    +reg			dbg_ack_o;	// External Data Acknowledge (not WB compatible)
    +
    +
    +//
    +// Some connections go directly from the CPU through DU to Debug I/F
    +//
    +`ifdef OR1200_DU_STATUS_UNIMPLEMENTED
    +assign dbg_lss_o = 4'b0000;
    +
    +reg	[1:0]			dbg_is_o;
    +//
    +// Show insn activity (temp, must be removed)
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dbg_is_o <=  2'b00;
    +	else if (!ex_freeze & ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]))
    +		dbg_is_o <=  ~dbg_is_o;
    +`ifdef UNUSED
    +assign dbg_is_o = 2'b00;
    +`endif
    +`else
    +assign dbg_lss_o = dcpu_cycstb_i ? {dcpu_we_i, 3'b000} : 4'b0000;
    +assign dbg_is_o = {1'b0, icpu_cycstb_i};
    +`endif
    +assign dbg_wp_o = 11'b000_0000_0000;
    +
    +//
    +// Some connections go directly from Debug I/F through DU to the CPU
    +//
    +assign du_stall = dbg_stall_i;
    +assign du_addr = dbg_adr_i;
    +assign du_dat_o = dbg_dat_i;
    +assign du_read = dbg_stb_i && !dbg_we_i;
    +assign du_write = dbg_stb_i && dbg_we_i;
    +
    +//
    +// After a sw breakpoint, the replaced instruction need to be executed.
    +// We flush the entire pipeline and set the pc to the current address
    +// to execute the restored address.
    +//
    +
    +reg du_flush_pipe_r;
    +reg dbg_stall_i_r;
    +
    +assign du_flush_pipe = du_flush_pipe_r;
    +
    +//
    +// Register du_flush_pipe
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst) begin
    +	if (rst == `OR1200_RST_VALUE) begin
    +		du_flush_pipe_r   <=  1'b0;
    +	end
    +	else begin
    +		du_flush_pipe_r   <=  (dbg_stall_i_r && !dbg_stall_i && |du_except_stop);
    +	end
    +end
    +
    +//
    +// Detect dbg_stall falling edge
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst) begin
    +	if (rst == `OR1200_RST_VALUE) begin
    +		dbg_stall_i_r   <=  1'b0;
    +	end
    +	else begin
    +		dbg_stall_i_r   <=  dbg_stall_i;
    +	end
    +end
    +
    +reg				dbg_ack;
    +//
    +// Generate acknowledge -- just delay stb signal
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst) begin
    +	if (rst == `OR1200_RST_VALUE) begin
    +		dbg_ack   <=  1'b0;
    +		dbg_ack_o <=  1'b0;
    +	end
    +	else begin
    +		dbg_ack   <=  dbg_stb_i;		// valid when du_dat_i 
    +		dbg_ack_o <=  dbg_ack & dbg_stb_i;	// valid when dbg_dat_o 
    +	end
    +end
    +
    +// 
    +// Register data output
    +//
    +always @(posedge clk)
    +    dbg_dat_o <=  du_dat_i;
    +
    +`ifdef OR1200_DU_IMPLEMENTED
    +
    +//
    +// Debug Mode Register 1
    +//
    +`ifdef OR1200_DU_DMR1
    +reg	[24:0]			dmr1;		// DMR1 implemented
    +`else
    +wire	[24:0]			dmr1;		// DMR1 not implemented
    +`endif
    +assign du_dmr1 = dmr1;
    +
    +//
    +// Debug Mode Register 2
    +//
    +`ifdef OR1200_DU_DMR2
    +reg	[23:0]			dmr2;		// DMR2 implemented
    +`else
    +wire	[23:0]			dmr2;		// DMR2 not implemented
    +`endif
    +
    +//
    +// Debug Stop Register
    +//
    +`ifdef OR1200_DU_DSR
    +reg	[`OR1200_DU_DSR_WIDTH-1:0]	dsr;		// DSR implemented
    +`else
    +wire	[`OR1200_DU_DSR_WIDTH-1:0]	dsr;		// DSR not implemented
    +`endif
    +
    +//
    +// Debug Reason Register
    +//
    +`ifdef OR1200_DU_DRR
    +reg	[13:0]			drr;		// DRR implemented
    +`else
    +wire	[13:0]			drr;		// DRR not implemented
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR0
    +reg	[31:0]			dvr0;
    +`else
    +wire	[31:0]			dvr0;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR1
    +reg	[31:0]			dvr1;
    +`else
    +wire	[31:0]			dvr1;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR2
    +reg	[31:0]			dvr2;
    +`else
    +wire	[31:0]			dvr2;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR3
    +reg	[31:0]			dvr3;
    +`else
    +wire	[31:0]			dvr3;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR4
    +reg	[31:0]			dvr4;
    +`else
    +wire	[31:0]			dvr4;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR5
    +reg	[31:0]			dvr5;
    +`else
    +wire	[31:0]			dvr5;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR6
    +reg	[31:0]			dvr6;
    +`else
    +wire	[31:0]			dvr6;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR7
    +reg	[31:0]			dvr7;
    +`else
    +wire	[31:0]			dvr7;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR0
    +reg	[7:0]			dcr0;
    +`else
    +wire	[7:0]			dcr0;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR1
    +reg	[7:0]			dcr1;
    +`else
    +wire	[7:0]			dcr1;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR2
    +reg	[7:0]			dcr2;
    +`else
    +wire	[7:0]			dcr2;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR3
    +reg	[7:0]			dcr3;
    +`else
    +wire	[7:0]			dcr3;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR4
    +reg	[7:0]			dcr4;
    +`else
    +wire	[7:0]			dcr4;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR5
    +reg	[7:0]			dcr5;
    +`else
    +wire	[7:0]			dcr5;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR6
    +reg	[7:0]			dcr6;
    +`else
    +wire	[7:0]			dcr6;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR7
    +reg	[7:0]			dcr7;
    +`else
    +wire	[7:0]			dcr7;
    +`endif
    +
    +//
    +// Debug Watchpoint Counter Register 0
    +//
    +`ifdef OR1200_DU_DWCR0
    +reg	[31:0]			dwcr0;
    +`else
    +wire	[31:0]			dwcr0;
    +`endif
    +
    +//
    +// Debug Watchpoint Counter Register 1
    +//
    +`ifdef OR1200_DU_DWCR1
    +reg	[31:0]			dwcr1;
    +`else
    +wire	[31:0]			dwcr1;
    +`endif
    +
    +//
    +// Internal wires
    +//
    +wire				dmr1_sel; 	// DMR1 select
    +wire				dmr2_sel; 	// DMR2 select
    +wire				dsr_sel; 	// DSR select
    +wire				drr_sel; 	// DRR select
    +wire				dvr0_sel,
    +				dvr1_sel,
    +				dvr2_sel,
    +				dvr3_sel,
    +				dvr4_sel,
    +				dvr5_sel,
    +				dvr6_sel,
    +				dvr7_sel; 	// DVR selects
    +wire				dcr0_sel,
    +				dcr1_sel,
    +				dcr2_sel,
    +				dcr3_sel,
    +				dcr4_sel,
    +				dcr5_sel,
    +				dcr6_sel,
    +				dcr7_sel; 	// DCR selects
    +wire				dwcr0_sel,
    +				dwcr1_sel; 	// DWCR selects
    +reg				dbg_bp_r;
    +reg 				ex_freeze_q;
    +`ifdef OR1200_DU_HWBKPTS
    +reg	[31:0]			match_cond0_ct;
    +reg	[31:0]			match_cond1_ct;
    +reg	[31:0]			match_cond2_ct;
    +reg	[31:0]			match_cond3_ct;
    +reg	[31:0]			match_cond4_ct;
    +reg	[31:0]			match_cond5_ct;
    +reg	[31:0]			match_cond6_ct;
    +reg	[31:0]			match_cond7_ct;
    +reg				match_cond0_stb;
    +reg				match_cond1_stb;
    +reg				match_cond2_stb;
    +reg				match_cond3_stb;
    +reg				match_cond4_stb;
    +reg				match_cond5_stb;
    +reg				match_cond6_stb;
    +reg				match_cond7_stb;
    +reg				match0;
    +reg				match1;
    +reg				match2;
    +reg				match3;
    +reg				match4;
    +reg				match5;
    +reg				match6;
    +reg				match7;
    +reg				wpcntr0_match;
    +reg				wpcntr1_match;
    +reg				incr_wpcntr0;
    +reg				incr_wpcntr1;
    +reg	[10:0]			wp;
    +`endif
    +wire				du_hwbkpt;
    +reg				du_hwbkpt_hold;
    +`ifdef OR1200_DU_READREGS
    +reg	[31:0]			spr_dat_o;
    +`endif
    +reg	[13:0]			except_stop;	// Exceptions that stop because of DSR
    +`ifdef OR1200_DU_TB_IMPLEMENTED
    +wire				tb_enw;
    +reg	[7:0]			tb_wadr;
    +reg [31:0]			tb_timstmp;
    +`endif
    +wire	[31:0]			tbia_dat_o;
    +wire	[31:0]			tbim_dat_o;
    +wire	[31:0]			tbar_dat_o;
    +wire	[31:0]			tbts_dat_o;
    +
    +//
    +// DU registers address decoder
    +//
    +`ifdef OR1200_DU_DMR1
    +assign dmr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DMR1));
    +`endif
    +`ifdef OR1200_DU_DMR2
    +assign dmr2_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DMR2));
    +`endif
    +`ifdef OR1200_DU_DSR
    +assign dsr_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DSR));
    +`endif
    +`ifdef OR1200_DU_DRR
    +assign drr_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DRR));
    +`endif
    +`ifdef OR1200_DU_DVR0
    +assign dvr0_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR0));
    +`endif
    +`ifdef OR1200_DU_DVR1
    +assign dvr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR1));
    +`endif
    +`ifdef OR1200_DU_DVR2
    +assign dvr2_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR2));
    +`endif
    +`ifdef OR1200_DU_DVR3
    +assign dvr3_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR3));
    +`endif
    +`ifdef OR1200_DU_DVR4
    +assign dvr4_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR4));
    +`endif
    +`ifdef OR1200_DU_DVR5
    +assign dvr5_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR5));
    +`endif
    +`ifdef OR1200_DU_DVR6
    +assign dvr6_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR6));
    +`endif
    +`ifdef OR1200_DU_DVR7
    +assign dvr7_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR7));
    +`endif
    +`ifdef OR1200_DU_DCR0
    +assign dcr0_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR0));
    +`endif
    +`ifdef OR1200_DU_DCR1
    +assign dcr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR1));
    +`endif
    +`ifdef OR1200_DU_DCR2
    +assign dcr2_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR2));
    +`endif
    +`ifdef OR1200_DU_DCR3
    +assign dcr3_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR3));
    +`endif
    +`ifdef OR1200_DU_DCR4
    +assign dcr4_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR4));
    +`endif
    +`ifdef OR1200_DU_DCR5
    +assign dcr5_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR5));
    +`endif
    +`ifdef OR1200_DU_DCR6
    +assign dcr6_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR6));
    +`endif
    +`ifdef OR1200_DU_DCR7
    +assign dcr7_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR7));
    +`endif
    +`ifdef OR1200_DU_DWCR0
    +assign dwcr0_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DWCR0));
    +`endif
    +`ifdef OR1200_DU_DWCR1
    +assign dwcr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DWCR1));
    +`endif
    +
    +// Track previous ex_freeze to detect when signals are updated
    +always @(posedge clk)
    +  ex_freeze_q <= ex_freeze;
    +
    +//
    +// Decode started exception
    +//
    +// du_except_stop comes from or1200_except
    +//   
    +always @(du_except_stop or ex_freeze_q) begin
    +	except_stop = 14'b00_0000_0000_0000;
    +	casez (du_except_stop)
    +	        14'b1?_????_????_????:
    +			except_stop[`OR1200_DU_DRR_TTE] = 1'b1;
    +		14'b01_????_????_????: begin
    +			except_stop[`OR1200_DU_DRR_IE] = 1'b1;
    +		end
    +		14'b00_1???_????_????: begin
    +			except_stop[`OR1200_DU_DRR_IME] = 1'b1;
    +		end
    +		14'b00_01??_????_????:
    +			except_stop[`OR1200_DU_DRR_IPFE] = 1'b1;
    +		14'b00_001?_????_????: begin
    +			except_stop[`OR1200_DU_DRR_BUSEE] = 1'b1;
    +		end
    +		14'b00_0001_????_????:
    +			except_stop[`OR1200_DU_DRR_IIE] = 1'b1;
    +		14'b00_0000_1???_????: begin
    +			except_stop[`OR1200_DU_DRR_AE] = 1'b1;
    +		end
    +		14'b00_0000_01??_????: begin
    +			except_stop[`OR1200_DU_DRR_DME] = 1'b1;
    +		end
    +		14'b00_0000_001?_????:
    +			except_stop[`OR1200_DU_DRR_DPFE] = 1'b1;
    +		14'b00_0000_0001_????:
    +			except_stop[`OR1200_DU_DRR_BUSEE] = 1'b1;
    +		14'b00_0000_0000_1???: begin
    +			except_stop[`OR1200_DU_DRR_RE] = 1'b1;
    +		end
    +		14'b00_0000_0000_01??: begin
    +			except_stop[`OR1200_DU_DRR_TE] = 1'b1 & ~ex_freeze_q;
    +		end
    +		14'b00_0000_0000_001?: begin
    +		        except_stop[`OR1200_DU_DRR_FPE] = 1'b1;
    +		end	  
    +		14'b00_0000_0000_0001:
    +			except_stop[`OR1200_DU_DRR_SCE] = 1'b1 & ~ex_freeze_q;
    +		default:
    +			except_stop = 14'b00_0000_0000_0000;
    +	endcase // casez (du_except_stop)
    +end
    +
    +//
    +// dbg_bp_o is registered
    +//
    +assign dbg_bp_o = dbg_bp_r;
    +
    +//
    +// Breakpoint activation register
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dbg_bp_r <=  1'b0;
    +	else if (!ex_freeze)
    +		dbg_bp_r <=  |except_stop
    +`ifdef OR1200_DU_DMR1_ST
    +                        | ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]) & dmr1[`OR1200_DU_DMR1_ST]
    +`endif
    +`ifdef OR1200_DU_DMR1_BT
    +                        | (branch_op != `OR1200_BRANCHOP_NOP) & (branch_op != `OR1200_BRANCHOP_RFE) & dmr1[`OR1200_DU_DMR1_BT]
    +`endif
    +			;
    +        else
    +                dbg_bp_r <=  |except_stop;
    +
    +//
    +// Write to DMR1
    +//
    +`ifdef OR1200_DU_DMR1
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dmr1 <= 25'h000_0000;
    +	else if (dmr1_sel && spr_write)
    +`ifdef OR1200_DU_HWBKPTS
    +		dmr1 <=  spr_dat_i[24:0];
    +`else
    +		dmr1 <=  {1'b0, spr_dat_i[23:22], 22'h00_0000};
    +`endif
    +`else
    +assign dmr1 = 25'h000_0000;
    +`endif
    +
    +//
    +// Write to DMR2
    +//
    +`ifdef OR1200_DU_DMR2
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dmr2 <= 24'h00_0000;
    +	else if (dmr2_sel && spr_write)
    +		dmr2 <=  spr_dat_i[23:0];
    +`else
    +assign dmr2 = 24'h00_0000;
    +`endif
    +
    +//
    +// Write to DSR
    +//
    +`ifdef OR1200_DU_DSR
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dsr <= {`OR1200_DU_DSR_WIDTH{1'b0}};
    +	else if (dsr_sel && spr_write)
    +		dsr <=  spr_dat_i[`OR1200_DU_DSR_WIDTH-1:0];
    +`else
    +assign dsr = {`OR1200_DU_DSR_WIDTH{1'b0}};
    +`endif
    +
    +//
    +// Write to DRR
    +//
    +`ifdef OR1200_DU_DRR
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		drr <= 14'b0;
    +	else if (drr_sel && spr_write)
    +		drr <=  spr_dat_i[13:0];
    +	else
    +		drr <=  drr | except_stop;
    +`else
    +assign drr = 14'b0;
    +`endif
    +
    +//
    +// Write to DVR0
    +//
    +`ifdef OR1200_DU_DVR0
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dvr0 <= 32'h0000_0000;
    +	else if (dvr0_sel && spr_write)
    +		dvr0 <=  spr_dat_i[31:0];
    +`else
    +assign dvr0 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR1
    +//
    +`ifdef OR1200_DU_DVR1
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dvr1 <= 32'h0000_0000;
    +	else if (dvr1_sel && spr_write)
    +		dvr1 <=  spr_dat_i[31:0];
    +`else
    +assign dvr1 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR2
    +//
    +`ifdef OR1200_DU_DVR2
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dvr2 <= 32'h0000_0000;
    +	else if (dvr2_sel && spr_write)
    +		dvr2 <=  spr_dat_i[31:0];
    +`else
    +assign dvr2 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR3
    +//
    +`ifdef OR1200_DU_DVR3
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dvr3 <= 32'h0000_0000;
    +	else if (dvr3_sel && spr_write)
    +		dvr3 <=  spr_dat_i[31:0];
    +`else
    +assign dvr3 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR4
    +//
    +`ifdef OR1200_DU_DVR4
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dvr4 <= 32'h0000_0000;
    +	else if (dvr4_sel && spr_write)
    +		dvr4 <=  spr_dat_i[31:0];
    +`else
    +assign dvr4 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR5
    +//
    +`ifdef OR1200_DU_DVR5
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dvr5 <= 32'h0000_0000;
    +	else if (dvr5_sel && spr_write)
    +		dvr5 <=  spr_dat_i[31:0];
    +`else
    +assign dvr5 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR6
    +//
    +`ifdef OR1200_DU_DVR6
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dvr6 <= 32'h0000_0000;
    +	else if (dvr6_sel && spr_write)
    +		dvr6 <=  spr_dat_i[31:0];
    +`else
    +assign dvr6 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR7
    +//
    +`ifdef OR1200_DU_DVR7
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dvr7 <= 32'h0000_0000;
    +	else if (dvr7_sel && spr_write)
    +		dvr7 <=  spr_dat_i[31:0];
    +`else
    +assign dvr7 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DCR0
    +//
    +`ifdef OR1200_DU_DCR0
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dcr0 <= 8'h00;
    +	else if (dcr0_sel && spr_write)
    +		dcr0 <=  spr_dat_i[7:0];
    +`else
    +assign dcr0 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR1
    +//
    +`ifdef OR1200_DU_DCR1
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dcr1 <= 8'h00;
    +	else if (dcr1_sel && spr_write)
    +		dcr1 <=  spr_dat_i[7:0];
    +`else
    +assign dcr1 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR2
    +//
    +`ifdef OR1200_DU_DCR2
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dcr2 <= 8'h00;
    +	else if (dcr2_sel && spr_write)
    +		dcr2 <=  spr_dat_i[7:0];
    +`else
    +assign dcr2 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR3
    +//
    +`ifdef OR1200_DU_DCR3
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dcr3 <= 8'h00;
    +	else if (dcr3_sel && spr_write)
    +		dcr3 <=  spr_dat_i[7:0];
    +`else
    +assign dcr3 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR4
    +//
    +`ifdef OR1200_DU_DCR4
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dcr4 <= 8'h00;
    +	else if (dcr4_sel && spr_write)
    +		dcr4 <=  spr_dat_i[7:0];
    +`else
    +assign dcr4 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR5
    +//
    +`ifdef OR1200_DU_DCR5
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dcr5 <= 8'h00;
    +	else if (dcr5_sel && spr_write)
    +		dcr5 <=  spr_dat_i[7:0];
    +`else
    +assign dcr5 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR6
    +//
    +`ifdef OR1200_DU_DCR6
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dcr6 <= 8'h00;
    +	else if (dcr6_sel && spr_write)
    +		dcr6 <=  spr_dat_i[7:0];
    +`else
    +assign dcr6 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR7
    +//
    +`ifdef OR1200_DU_DCR7
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dcr7 <= 8'h00;
    +	else if (dcr7_sel && spr_write)
    +		dcr7 <=  spr_dat_i[7:0];
    +`else
    +assign dcr7 = 8'h00;
    +`endif
    +
    +//
    +// Write to DWCR0
    +//
    +`ifdef OR1200_DU_DWCR0
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dwcr0 <= 32'h0000_0000;
    +	else if (dwcr0_sel && spr_write)
    +		dwcr0 <=  spr_dat_i[31:0];
    +	else if (incr_wpcntr0)
    +		dwcr0[`OR1200_DU_DWCR_COUNT] <=  dwcr0[`OR1200_DU_DWCR_COUNT] + 16'h0001;
    +`else
    +assign dwcr0 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DWCR1
    +//
    +`ifdef OR1200_DU_DWCR1
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		dwcr1 <= 32'h0000_0000;
    +	else if (dwcr1_sel && spr_write)
    +		dwcr1 <=  spr_dat_i[31:0];
    +	else if (incr_wpcntr1)
    +		dwcr1[`OR1200_DU_DWCR_COUNT] <=  dwcr1[`OR1200_DU_DWCR_COUNT] + 16'h0001;
    +`else
    +assign dwcr1 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Read DU registers
    +//
    +`ifdef OR1200_DU_READREGS
    +always @(spr_addr or dsr or drr or dmr1 or dmr2
    +	or dvr0 or dvr1 or dvr2 or dvr3 or dvr4
    +	or dvr5 or dvr6 or dvr7
    +	or dcr0 or dcr1 or dcr2 or dcr3 or dcr4
    +	or dcr5 or dcr6 or dcr7
    +	or dwcr0 or dwcr1
    +`ifdef OR1200_DU_TB_IMPLEMENTED
    +	or tb_wadr or tbia_dat_o or tbim_dat_o
    +	or tbar_dat_o or tbts_dat_o
    +`endif
    +	)
    +	casez (spr_addr[`OR1200_DUOFS_BITS]) // synopsys parallel_case
    +`ifdef OR1200_DU_DVR0
    +		`OR1200_DU_DVR0:
    +			spr_dat_o = dvr0;
    +`endif
    +`ifdef OR1200_DU_DVR1
    +		`OR1200_DU_DVR1:
    +			spr_dat_o = dvr1;
    +`endif
    +`ifdef OR1200_DU_DVR2
    +		`OR1200_DU_DVR2:
    +			spr_dat_o = dvr2;
    +`endif
    +`ifdef OR1200_DU_DVR3
    +		`OR1200_DU_DVR3:
    +			spr_dat_o = dvr3;
    +`endif
    +`ifdef OR1200_DU_DVR4
    +		`OR1200_DU_DVR4:
    +			spr_dat_o = dvr4;
    +`endif
    +`ifdef OR1200_DU_DVR5
    +		`OR1200_DU_DVR5:
    +			spr_dat_o = dvr5;
    +`endif
    +`ifdef OR1200_DU_DVR6
    +		`OR1200_DU_DVR6:
    +			spr_dat_o = dvr6;
    +`endif
    +`ifdef OR1200_DU_DVR7
    +		`OR1200_DU_DVR7:
    +			spr_dat_o = dvr7;
    +`endif
    +`ifdef OR1200_DU_DCR0
    +		`OR1200_DU_DCR0:
    +			spr_dat_o = {24'h00_0000, dcr0};
    +`endif
    +`ifdef OR1200_DU_DCR1
    +		`OR1200_DU_DCR1:
    +			spr_dat_o = {24'h00_0000, dcr1};
    +`endif
    +`ifdef OR1200_DU_DCR2
    +		`OR1200_DU_DCR2:
    +			spr_dat_o = {24'h00_0000, dcr2};
    +`endif
    +`ifdef OR1200_DU_DCR3
    +		`OR1200_DU_DCR3:
    +			spr_dat_o = {24'h00_0000, dcr3};
    +`endif
    +`ifdef OR1200_DU_DCR4
    +		`OR1200_DU_DCR4:
    +			spr_dat_o = {24'h00_0000, dcr4};
    +`endif
    +`ifdef OR1200_DU_DCR5
    +		`OR1200_DU_DCR5:
    +			spr_dat_o = {24'h00_0000, dcr5};
    +`endif
    +`ifdef OR1200_DU_DCR6
    +		`OR1200_DU_DCR6:
    +			spr_dat_o = {24'h00_0000, dcr6};
    +`endif
    +`ifdef OR1200_DU_DCR7
    +		`OR1200_DU_DCR7:
    +			spr_dat_o = {24'h00_0000, dcr7};
    +`endif
    +`ifdef OR1200_DU_DMR1
    +		`OR1200_DU_DMR1:
    +			spr_dat_o = {7'h00, dmr1};
    +`endif
    +`ifdef OR1200_DU_DMR2
    +		`OR1200_DU_DMR2:
    +			spr_dat_o = {8'h00, dmr2};
    +`endif
    +`ifdef OR1200_DU_DWCR0
    +		`OR1200_DU_DWCR0:
    +			spr_dat_o = dwcr0;
    +`endif
    +`ifdef OR1200_DU_DWCR1
    +		`OR1200_DU_DWCR1:
    +			spr_dat_o = dwcr1;
    +`endif
    +`ifdef OR1200_DU_DSR
    +		`OR1200_DU_DSR:
    +			spr_dat_o = {18'b0, dsr};
    +`endif
    +`ifdef OR1200_DU_DRR
    +		`OR1200_DU_DRR:
    +			spr_dat_o = {18'b0, drr};
    +`endif
    +`ifdef OR1200_DU_TB_IMPLEMENTED
    +		`OR1200_DU_TBADR:
    +			spr_dat_o = {24'h000000, tb_wadr};
    +		`OR1200_DU_TBIA:
    +			spr_dat_o = tbia_dat_o;
    +		`OR1200_DU_TBIM:
    +			spr_dat_o = tbim_dat_o;
    +		`OR1200_DU_TBAR:
    +			spr_dat_o = tbar_dat_o;
    +		`OR1200_DU_TBTS:
    +			spr_dat_o = tbts_dat_o;
    +`endif
    +		default:
    +			spr_dat_o = 32'h0000_0000;
    +	endcase
    +`endif
    +
    +//
    +// DSR alias
    +//
    +assign du_dsr = dsr;
    +
    +`ifdef OR1200_DU_HWBKPTS
    +
    +//
    +// Compare To What (Match Condition 0)
    +//
    +always @(dcr0 or id_pc or dcpu_adr_i or dcpu_dat_dc
    +	or dcpu_dat_lsu or dcpu_we_i)
    +	case (dcr0[`OR1200_DU_DCR_CT])		// synopsys parallel_case
    +		3'b001:	match_cond0_ct = id_pc;		// insn fetch EA
    +		3'b010:	match_cond0_ct = dcpu_adr_i;	// load EA
    +		3'b011:	match_cond0_ct = dcpu_adr_i;	// store EA
    +		3'b100:	match_cond0_ct = dcpu_dat_dc;	// load data
    +		3'b101:	match_cond0_ct = dcpu_dat_lsu;	// store data
    +		3'b110:	match_cond0_ct = dcpu_adr_i;	// load/store EA
    +		default:match_cond0_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    +	endcase
    +
    +//
    +// When To Compare (Match Condition 0)
    +//
    +always @(dcr0 or dcpu_cycstb_i)
    +	case (dcr0[`OR1200_DU_DCR_CT]) 		// synopsys parallel_case
    +		3'b000:	match_cond0_stb = 1'b0;		//comparison disabled
    +		3'b001:	match_cond0_stb = 1'b1;		// insn fetch EA
    +		default:match_cond0_stb = dcpu_cycstb_i; // any load/store
    +	endcase
    +
    +//
    +// Match Condition 0
    +//
    +always @(match_cond0_stb or dcr0 or dvr0 or match_cond0_ct)
    +	casex ({match_cond0_stb, dcr0[`OR1200_DU_DCR_CC]})
    +		4'b0_xxx,
    +		4'b1_000,
    +		4'b1_111: match0 = 1'b0;
    +		4'b1_001: match0 =
    +			({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} ==
    +			 {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
    +		4'b1_010: match0 = 
    +			({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} <
    +			 {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
    +		4'b1_011: match0 = 
    +			({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} <=
    +			 {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
    +		4'b1_100: match0 = 
    +			({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} >
    +			 {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
    +		4'b1_101: match0 = 
    +			({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} >=
    +			 {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
    +		4'b1_110: match0 = 
    +			({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} !=
    +			 {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
    +	endcase
    +
    +//
    +// Watchpoint 0
    +//
    +always @(dmr1 or match0)
    +	case (dmr1[`OR1200_DU_DMR1_CW0])
    +		2'b00: wp[0] = match0;
    +		2'b01: wp[0] = match0;
    +		2'b10: wp[0] = match0;
    +		2'b11: wp[0] = 1'b0;
    +	endcase
    +
    +//
    +// Compare To What (Match Condition 1)
    +//
    +always @(dcr1 or id_pc or dcpu_adr_i or dcpu_dat_dc
    +	or dcpu_dat_lsu or dcpu_we_i)
    +	case (dcr1[`OR1200_DU_DCR_CT])		// synopsys parallel_case
    +		3'b001:	match_cond1_ct = id_pc;		// insn fetch EA
    +		3'b010:	match_cond1_ct = dcpu_adr_i;	// load EA
    +		3'b011:	match_cond1_ct = dcpu_adr_i;	// store EA
    +		3'b100:	match_cond1_ct = dcpu_dat_dc;	// load data
    +		3'b101:	match_cond1_ct = dcpu_dat_lsu;	// store data
    +		3'b110:	match_cond1_ct = dcpu_adr_i;	// load/store EA
    +		default:match_cond1_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    +	endcase
    +
    +//
    +// When To Compare (Match Condition 1)
    +//
    +always @(dcr1 or dcpu_cycstb_i)
    +	case (dcr1[`OR1200_DU_DCR_CT]) 		// synopsys parallel_case
    +		3'b000:	match_cond1_stb = 1'b0;		//comparison disabled
    +		3'b001:	match_cond1_stb = 1'b1;		// insn fetch EA
    +		default:match_cond1_stb = dcpu_cycstb_i; // any load/store
    +	endcase
    +
    +//
    +// Match Condition 1
    +//
    +always @(match_cond1_stb or dcr1 or dvr1 or match_cond1_ct)
    +	casex ({match_cond1_stb, dcr1[`OR1200_DU_DCR_CC]})
    +		4'b0_xxx,
    +		4'b1_000,
    +		4'b1_111: match1 = 1'b0;
    +		4'b1_001: match1 =
    +			({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} ==
    +			 {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
    +		4'b1_010: match1 = 
    +			({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} <
    +			 {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
    +		4'b1_011: match1 = 
    +			({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} <=
    +			 {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
    +		4'b1_100: match1 = 
    +			({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} >
    +			 {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
    +		4'b1_101: match1 = 
    +			({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} >=
    +			 {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
    +		4'b1_110: match1 = 
    +			({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} !=
    +			 {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
    +	endcase
    +
    +//
    +// Watchpoint 1
    +//
    +always @(dmr1 or match1 or wp)
    +	case (dmr1[`OR1200_DU_DMR1_CW1])
    +		2'b00: wp[1] = match1;
    +		2'b01: wp[1] = match1 & wp[0];
    +		2'b10: wp[1] = match1 | wp[0];
    +		2'b11: wp[1] = 1'b0;
    +	endcase
    +
    +//
    +// Compare To What (Match Condition 2)
    +//
    +always @(dcr2 or id_pc or dcpu_adr_i or dcpu_dat_dc
    +	or dcpu_dat_lsu or dcpu_we_i)
    +	case (dcr2[`OR1200_DU_DCR_CT])		// synopsys parallel_case
    +		3'b001:	match_cond2_ct = id_pc;		// insn fetch EA
    +		3'b010:	match_cond2_ct = dcpu_adr_i;	// load EA
    +		3'b011:	match_cond2_ct = dcpu_adr_i;	// store EA
    +		3'b100:	match_cond2_ct = dcpu_dat_dc;	// load data
    +		3'b101:	match_cond2_ct = dcpu_dat_lsu;	// store data
    +		3'b110:	match_cond2_ct = dcpu_adr_i;	// load/store EA
    +		default:match_cond2_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    +	endcase
    +
    +//
    +// When To Compare (Match Condition 2)
    +//
    +always @(dcr2 or dcpu_cycstb_i)
    +	case (dcr2[`OR1200_DU_DCR_CT]) 		// synopsys parallel_case
    +		3'b000:	match_cond2_stb = 1'b0;		//comparison disabled
    +		3'b001:	match_cond2_stb = 1'b1;		// insn fetch EA
    +		default:match_cond2_stb = dcpu_cycstb_i; // any load/store
    +	endcase
    +
    +//
    +// Match Condition 2
    +//
    +always @(match_cond2_stb or dcr2 or dvr2 or match_cond2_ct)
    +	casex ({match_cond2_stb, dcr2[`OR1200_DU_DCR_CC]})
    +		4'b0_xxx,
    +		4'b1_000,
    +		4'b1_111: match2 = 1'b0;
    +		4'b1_001: match2 =
    +			({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} ==
    +			 {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
    +		4'b1_010: match2 = 
    +			({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} <
    +			 {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
    +		4'b1_011: match2 = 
    +			({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} <=
    +			 {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
    +		4'b1_100: match2 = 
    +			({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} >
    +			 {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
    +		4'b1_101: match2 = 
    +			({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} >=
    +			 {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
    +		4'b1_110: match2 = 
    +			({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} !=
    +			 {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
    +	endcase
    +
    +//
    +// Watchpoint 2
    +//
    +always @(dmr1 or match2 or wp)
    +	case (dmr1[`OR1200_DU_DMR1_CW2])
    +		2'b00: wp[2] = match2;
    +		2'b01: wp[2] = match2 & wp[1];
    +		2'b10: wp[2] = match2 | wp[1];
    +		2'b11: wp[2] = 1'b0;
    +	endcase
    +
    +//
    +// Compare To What (Match Condition 3)
    +//
    +always @(dcr3 or id_pc or dcpu_adr_i or dcpu_dat_dc
    +	or dcpu_dat_lsu or dcpu_we_i)
    +	case (dcr3[`OR1200_DU_DCR_CT])		// synopsys parallel_case
    +		3'b001:	match_cond3_ct = id_pc;		// insn fetch EA
    +		3'b010:	match_cond3_ct = dcpu_adr_i;	// load EA
    +		3'b011:	match_cond3_ct = dcpu_adr_i;	// store EA
    +		3'b100:	match_cond3_ct = dcpu_dat_dc;	// load data
    +		3'b101:	match_cond3_ct = dcpu_dat_lsu;	// store data
    +		3'b110:	match_cond3_ct = dcpu_adr_i;	// load/store EA
    +		default:match_cond3_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    +	endcase
    +
    +//
    +// When To Compare (Match Condition 3)
    +//
    +always @(dcr3 or dcpu_cycstb_i)
    +	case (dcr3[`OR1200_DU_DCR_CT]) 		// synopsys parallel_case
    +		3'b000:	match_cond3_stb = 1'b0;		//comparison disabled
    +		3'b001:	match_cond3_stb = 1'b1;		// insn fetch EA
    +		default:match_cond3_stb = dcpu_cycstb_i; // any load/store
    +	endcase
    +
    +//
    +// Match Condition 3
    +//
    +always @(match_cond3_stb or dcr3 or dvr3 or match_cond3_ct)
    +	casex ({match_cond3_stb, dcr3[`OR1200_DU_DCR_CC]})
    +		4'b0_xxx,
    +		4'b1_000,
    +		4'b1_111: match3 = 1'b0;
    +		4'b1_001: match3 =
    +			({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} ==
    +			 {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
    +		4'b1_010: match3 = 
    +			({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} <
    +			 {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
    +		4'b1_011: match3 = 
    +			({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} <=
    +			 {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
    +		4'b1_100: match3 = 
    +			({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} >
    +			 {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
    +		4'b1_101: match3 = 
    +			({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} >=
    +			 {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
    +		4'b1_110: match3 = 
    +			({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} !=
    +			 {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
    +	endcase
    +
    +//
    +// Watchpoint 3
    +//
    +always @(dmr1 or match3 or wp)
    +	case (dmr1[`OR1200_DU_DMR1_CW3])
    +		2'b00: wp[3] = match3;
    +		2'b01: wp[3] = match3 & wp[2];
    +		2'b10: wp[3] = match3 | wp[2];
    +		2'b11: wp[3] = 1'b0;
    +	endcase
    +
    +//
    +// Compare To What (Match Condition 4)
    +//
    +always @(dcr4 or id_pc or dcpu_adr_i or dcpu_dat_dc
    +	or dcpu_dat_lsu or dcpu_we_i)
    +	case (dcr4[`OR1200_DU_DCR_CT])		// synopsys parallel_case
    +		3'b001:	match_cond4_ct = id_pc;		// insn fetch EA
    +		3'b010:	match_cond4_ct = dcpu_adr_i;	// load EA
    +		3'b011:	match_cond4_ct = dcpu_adr_i;	// store EA
    +		3'b100:	match_cond4_ct = dcpu_dat_dc;	// load data
    +		3'b101:	match_cond4_ct = dcpu_dat_lsu;	// store data
    +		3'b110:	match_cond4_ct = dcpu_adr_i;	// load/store EA
    +		default:match_cond4_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    +	endcase
    +
    +//
    +// When To Compare (Match Condition 4)
    +//
    +always @(dcr4 or dcpu_cycstb_i)
    +	case (dcr4[`OR1200_DU_DCR_CT]) 		// synopsys parallel_case
    +		3'b000:	match_cond4_stb = 1'b0;		//comparison disabled
    +		3'b001:	match_cond4_stb = 1'b1;		// insn fetch EA
    +		default:match_cond4_stb = dcpu_cycstb_i; // any load/store
    +	endcase
    +
    +//
    +// Match Condition 4
    +//
    +always @(match_cond4_stb or dcr4 or dvr4 or match_cond4_ct)
    +	casex ({match_cond4_stb, dcr4[`OR1200_DU_DCR_CC]})
    +		4'b0_xxx,
    +		4'b1_000,
    +		4'b1_111: match4 = 1'b0;
    +		4'b1_001: match4 =
    +			({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} ==
    +			 {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
    +		4'b1_010: match4 = 
    +			({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} <
    +			 {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
    +		4'b1_011: match4 = 
    +			({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} <=
    +			 {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
    +		4'b1_100: match4 = 
    +			({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} >
    +			 {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
    +		4'b1_101: match4 = 
    +			({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} >=
    +			 {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
    +		4'b1_110: match4 = 
    +			({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} !=
    +			 {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
    +	endcase
    +
    +//
    +// Watchpoint 4
    +//
    +always @(dmr1 or match4 or wp)
    +	case (dmr1[`OR1200_DU_DMR1_CW4])
    +		2'b00: wp[4] = match4;
    +		2'b01: wp[4] = match4 & wp[3];
    +		2'b10: wp[4] = match4 | wp[3];
    +		2'b11: wp[4] = 1'b0;
    +	endcase
    +
    +//
    +// Compare To What (Match Condition 5)
    +//
    +always @(dcr5 or id_pc or dcpu_adr_i or dcpu_dat_dc
    +	or dcpu_dat_lsu or dcpu_we_i)
    +	case (dcr5[`OR1200_DU_DCR_CT])		// synopsys parallel_case
    +		3'b001:	match_cond5_ct = id_pc;		// insn fetch EA
    +		3'b010:	match_cond5_ct = dcpu_adr_i;	// load EA
    +		3'b011:	match_cond5_ct = dcpu_adr_i;	// store EA
    +		3'b100:	match_cond5_ct = dcpu_dat_dc;	// load data
    +		3'b101:	match_cond5_ct = dcpu_dat_lsu;	// store data
    +		3'b110:	match_cond5_ct = dcpu_adr_i;	// load/store EA
    +		default:match_cond5_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    +	endcase
    +
    +//
    +// When To Compare (Match Condition 5)
    +//
    +always @(dcr5 or dcpu_cycstb_i)
    +	case (dcr5[`OR1200_DU_DCR_CT]) 		// synopsys parallel_case
    +		3'b000:	match_cond5_stb = 1'b0;		//comparison disabled
    +		3'b001:	match_cond5_stb = 1'b1;		// insn fetch EA
    +		default:match_cond5_stb = dcpu_cycstb_i; // any load/store
    +	endcase
    +
    +//
    +// Match Condition 5
    +//
    +always @(match_cond5_stb or dcr5 or dvr5 or match_cond5_ct)
    +	casex ({match_cond5_stb, dcr5[`OR1200_DU_DCR_CC]})
    +		4'b0_xxx,
    +		4'b1_000,
    +		4'b1_111: match5 = 1'b0;
    +		4'b1_001: match5 =
    +			({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} ==
    +			 {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
    +		4'b1_010: match5 = 
    +			({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} <
    +			 {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
    +		4'b1_011: match5 = 
    +			({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} <=
    +			 {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
    +		4'b1_100: match5 = 
    +			({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} >
    +			 {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
    +		4'b1_101: match5 = 
    +			({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} >=
    +			 {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
    +		4'b1_110: match5 = 
    +			({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} !=
    +			 {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
    +	endcase
    +
    +//
    +// Watchpoint 5
    +//
    +always @(dmr1 or match5 or wp)
    +	case (dmr1[`OR1200_DU_DMR1_CW5])
    +		2'b00: wp[5] = match5;
    +		2'b01: wp[5] = match5 & wp[4];
    +		2'b10: wp[5] = match5 | wp[4];
    +		2'b11: wp[5] = 1'b0;
    +	endcase
    +
    +//
    +// Compare To What (Match Condition 6)
    +//
    +always @(dcr6 or id_pc or dcpu_adr_i or dcpu_dat_dc
    +	or dcpu_dat_lsu or dcpu_we_i)
    +	case (dcr6[`OR1200_DU_DCR_CT])		// synopsys parallel_case
    +		3'b001:	match_cond6_ct = id_pc;		// insn fetch EA
    +		3'b010:	match_cond6_ct = dcpu_adr_i;	// load EA
    +		3'b011:	match_cond6_ct = dcpu_adr_i;	// store EA
    +		3'b100:	match_cond6_ct = dcpu_dat_dc;	// load data
    +		3'b101:	match_cond6_ct = dcpu_dat_lsu;	// store data
    +		3'b110:	match_cond6_ct = dcpu_adr_i;	// load/store EA
    +		default:match_cond6_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    +	endcase
    +
    +//
    +// When To Compare (Match Condition 6)
    +//
    +always @(dcr6 or dcpu_cycstb_i)
    +	case (dcr6[`OR1200_DU_DCR_CT]) 		// synopsys parallel_case
    +		3'b000:	match_cond6_stb = 1'b0;		//comparison disabled
    +		3'b001:	match_cond6_stb = 1'b1;		// insn fetch EA
    +		default:match_cond6_stb = dcpu_cycstb_i; // any load/store
    +	endcase
    +
    +//
    +// Match Condition 6
    +//
    +always @(match_cond6_stb or dcr6 or dvr6 or match_cond6_ct)
    +	casex ({match_cond6_stb, dcr6[`OR1200_DU_DCR_CC]})
    +		4'b0_xxx,
    +		4'b1_000,
    +		4'b1_111: match6 = 1'b0;
    +		4'b1_001: match6 =
    +			({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} ==
    +			 {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
    +		4'b1_010: match6 = 
    +			({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} <
    +			 {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
    +		4'b1_011: match6 = 
    +			({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} <=
    +			 {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
    +		4'b1_100: match6 = 
    +			({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} >
    +			 {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
    +		4'b1_101: match6 = 
    +			({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} >=
    +			 {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
    +		4'b1_110: match6 = 
    +			({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} !=
    +			 {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
    +	endcase
    +
    +//
    +// Watchpoint 6
    +//
    +always @(dmr1 or match6 or wp)
    +	case (dmr1[`OR1200_DU_DMR1_CW6])
    +		2'b00: wp[6] = match6;
    +		2'b01: wp[6] = match6 & wp[5];
    +		2'b10: wp[6] = match6 | wp[5];
    +		2'b11: wp[6] = 1'b0;
    +	endcase
    +
    +//
    +// Compare To What (Match Condition 7)
    +//
    +always @(dcr7 or id_pc or dcpu_adr_i or dcpu_dat_dc
    +	or dcpu_dat_lsu or dcpu_we_i)
    +	case (dcr7[`OR1200_DU_DCR_CT])		// synopsys parallel_case
    +		3'b001:	match_cond7_ct = id_pc;		// insn fetch EA
    +		3'b010:	match_cond7_ct = dcpu_adr_i;	// load EA
    +		3'b011:	match_cond7_ct = dcpu_adr_i;	// store EA
    +		3'b100:	match_cond7_ct = dcpu_dat_dc;	// load data
    +		3'b101:	match_cond7_ct = dcpu_dat_lsu;	// store data
    +		3'b110:	match_cond7_ct = dcpu_adr_i;	// load/store EA
    +		default:match_cond7_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    +	endcase
    +
    +//
    +// When To Compare (Match Condition 7)
    +//
    +always @(dcr7 or dcpu_cycstb_i)
    +	case (dcr7[`OR1200_DU_DCR_CT]) 		// synopsys parallel_case
    +		3'b000:	match_cond7_stb = 1'b0;		//comparison disabled
    +		3'b001:	match_cond7_stb = 1'b1;		// insn fetch EA
    +		default:match_cond7_stb = dcpu_cycstb_i; // any load/store
    +	endcase
    +
    +//
    +// Match Condition 7
    +//
    +always @(match_cond7_stb or dcr7 or dvr7 or match_cond7_ct)
    +	casex ({match_cond7_stb, dcr7[`OR1200_DU_DCR_CC]})
    +		4'b0_xxx,
    +		4'b1_000,
    +		4'b1_111: match7 = 1'b0;
    +		4'b1_001: match7 =
    +			({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} ==
    +			 {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
    +		4'b1_010: match7 = 
    +			({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} <
    +			 {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
    +		4'b1_011: match7 = 
    +			({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} <=
    +			 {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
    +		4'b1_100: match7 = 
    +			({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} >
    +			 {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
    +		4'b1_101: match7 = 
    +			({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} >=
    +			 {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
    +		4'b1_110: match7 = 
    +			({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} !=
    +			 {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
    +	endcase
    +
    +//
    +// Watchpoint 7
    +//
    +always @(dmr1 or match7 or wp)
    +	case (dmr1[`OR1200_DU_DMR1_CW7])
    +		2'b00: wp[7] = match7;
    +		2'b01: wp[7] = match7 & wp[6];
    +		2'b10: wp[7] = match7 | wp[6];
    +		2'b11: wp[7] = 1'b0;
    +	endcase
    +
    +//
    +// Increment Watchpoint Counter 0
    +//
    +always @(wp or dmr2)
    +	if (dmr2[`OR1200_DU_DMR2_WCE0])
    +		incr_wpcntr0 = |(wp & ~dmr2[`OR1200_DU_DMR2_AWTC]);
    +	else
    +		incr_wpcntr0 = 1'b0;
    +
    +//
    +// Match Condition Watchpoint Counter 0
    +//
    +always @(dwcr0)
    +	if (dwcr0[`OR1200_DU_DWCR_MATCH] == dwcr0[`OR1200_DU_DWCR_COUNT])
    +		wpcntr0_match = 1'b1;
    +	else
    +		wpcntr0_match = 1'b0;
    +
    +
    +//
    +// Watchpoint 8
    +//
    +always @(dmr1 or wpcntr0_match or wp)
    +	case (dmr1[`OR1200_DU_DMR1_CW8])
    +		2'b00: wp[8] = wpcntr0_match;
    +		2'b01: wp[8] = wpcntr0_match & wp[7];
    +		2'b10: wp[8] = wpcntr0_match | wp[7];
    +		2'b11: wp[8] = 1'b0;
    +	endcase
    +
    +
    +//
    +// Increment Watchpoint Counter 1
    +//
    +always @(wp or dmr2)
    +	if (dmr2[`OR1200_DU_DMR2_WCE1])
    +		incr_wpcntr1 = |(wp & dmr2[`OR1200_DU_DMR2_AWTC]);
    +	else
    +		incr_wpcntr1 = 1'b0;
    +
    +//
    +// Match Condition Watchpoint Counter 1
    +//
    +always @(dwcr1)
    +	if (dwcr1[`OR1200_DU_DWCR_MATCH] == dwcr1[`OR1200_DU_DWCR_COUNT])
    +		wpcntr1_match = 1'b1;
    +	else
    +		wpcntr1_match = 1'b0;
    +
    +//
    +// Watchpoint 9
    +//
    +always @(dmr1 or wpcntr1_match or wp)
    +	case (dmr1[`OR1200_DU_DMR1_CW9])
    +		2'b00: wp[9] = wpcntr1_match;
    +		2'b01: wp[9] = wpcntr1_match & wp[8];
    +		2'b10: wp[9] = wpcntr1_match | wp[8];
    +		2'b11: wp[9] = 1'b0;
    +	endcase
    +
    +//
    +// Watchpoint 10
    +//
    +always @(dmr1 or dbg_ewt_i or wp)
    +	case (dmr1[`OR1200_DU_DMR1_CW10])
    +		2'b00: wp[10] = dbg_ewt_i;
    +		2'b01: wp[10] = dbg_ewt_i & wp[9];
    +		2'b10: wp[10] = dbg_ewt_i | wp[9];
    +		2'b11: wp[10] = 1'b0;
    +	endcase
    +
    +`endif
    +
    +//
    +// Watchpoints can cause trap exception
    +//
    +`ifdef OR1200_DU_HWBKPTS
    +assign du_hwbkpt = |(wp & dmr2[`OR1200_DU_DMR2_WGB]) | du_hwbkpt_hold | (dbg_bp_r & ~dsr[`OR1200_DU_DSR_TE]);
    +`else
    +assign du_hwbkpt = 1'b0;
    +`endif
    +
    +// Hold du_hwbkpt if ex_freeze is active in order to cause trap exception 
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		du_hwbkpt_hold <=  1'b0;
    +	else if (du_hwbkpt & ex_freeze)
    +		du_hwbkpt_hold <=  1'b1;
    +	else if (!ex_freeze)
    +		du_hwbkpt_hold <=  1'b0;
    +
    +`ifdef OR1200_DU_TB_IMPLEMENTED
    +//
    +// Simple trace buffer
    +// (right now hardcoded for Xilinx Virtex FPGAs)
    +//
    +// Stores last 256 instruction addresses, instruction
    +// machine words and ALU results
    +//
    +
    +//
    +// Trace buffer write enable
    +//
    +assign tb_enw = ~ex_freeze & ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]);
    +
    +//
    +// Trace buffer write address pointer
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		tb_wadr <=  8'h00;
    +	else if (tb_enw)
    +		tb_wadr <=  tb_wadr + 8'd1;
    +
    +//
    +// Free running counter (time stamp)
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    +	if (rst == `OR1200_RST_VALUE)
    +		tb_timstmp <=  32'h00000000;
    +	else if (!dbg_bp_r)
    +		tb_timstmp <=  tb_timstmp + 32'd1;
    +
    +//
    +// Trace buffer RAMs
    +//
    +
    +or1200_dpram_256x32 tbia_ram(
    +	.clk_a(clk),
    +	.rst_a(1'b0),
    +	.addr_a(spr_addr[7:0]),
    +	.ce_a(1'b1),
    +	.oe_a(1'b1),
    +	.do_a(tbia_dat_o),
    +
    +	.clk_b(clk),
    +	.rst_b(1'b0),
    +	.addr_b(tb_wadr),
    +	.di_b(spr_dat_npc),
    +	.ce_b(1'b1),
    +	.we_b(tb_enw)
    +
    +);
    +
    +or1200_dpram_256x32 tbim_ram(
    +	.clk_a(clk),
    +	.rst_a(1'b0),
    +	.addr_a(spr_addr[7:0]),
    +	.ce_a(1'b1),
    +	.oe_a(1'b1),
    +	.do_a(tbim_dat_o),
    +	
    +	.clk_b(clk),
    +	.rst_b(1'b0),
    +	.addr_b(tb_wadr),
    +	.di_b(ex_insn),
    +	.ce_b(1'b1),
    +	.we_b(tb_enw)
    +);
    +
    +or1200_dpram_256x32 tbar_ram(
    +	.clk_a(clk),
    +	.rst_a(1'b0),
    +	.addr_a(spr_addr[7:0]),
    +	.ce_a(1'b1),
    +	.oe_a(1'b1),
    +	.do_a(tbar_dat_o),
    +	
    +	.clk_b(clk),
    +	.rst_b(1'b0),
    +	.addr_b(tb_wadr),
    +	.di_b(rf_dataw),
    +	.ce_b(1'b1),
    +	.we_b(tb_enw)
    +);
    +
    +or1200_dpram_256x32 tbts_ram(
    +	.clk_a(clk),
    +	.rst_a(1'b0),
    +	.addr_a(spr_addr[7:0]),
    +	.ce_a(1'b1),
    +	.oe_a(1'b1),
    +	.do_a(tbts_dat_o),
    +
    +	.clk_b(clk),
    +	.rst_b(1'b0),
    +	.addr_b(tb_wadr),
    +	.di_b(tb_timstmp),
    +	.ce_b(1'b1),
    +	.we_b(tb_enw)
    +);
    +
    +`else
    +
    +assign tbia_dat_o = 32'h0000_0000;
    +assign tbim_dat_o = 32'h0000_0000;
    +assign tbar_dat_o = 32'h0000_0000;
    +assign tbts_dat_o = 32'h0000_0000;
    +
    +`endif	// OR1200_DU_TB_IMPLEMENTED
    +
    +`else	// OR1200_DU_IMPLEMENTED
    +
    +//
    +// When DU is not implemented, drive all outputs as would when DU is disabled
    +//
    +assign dbg_bp_o = 1'b0;
    +assign du_dsr = {`OR1200_DU_DSR_WIDTH{1'b0}};
    +assign du_dmr1 = {25{1'b0}};
    +assign du_hwbkpt = 1'b0;
    +
    +//
    +// Read DU registers
    +//
    +`ifdef OR1200_DU_READREGS
    +assign spr_dat_o = 32'h0000_0000;
    +`ifdef OR1200_DU_UNUSED_ZERO
    +`endif
    +`endif
    +
    +`endif
    +
    +endmodule
    +
    diff --git a/autotests/html/preprocessor-bug363280.c.html b/autotests/html/preprocessor-bug363280.c.html new file mode 100644 index 0000000..e7b930b --- /dev/null +++ b/autotests/html/preprocessor-bug363280.c.html @@ -0,0 +1,15 @@ + + + +preprocessor-bug363280.c + +
    +#if 1
    +int x; // variable shall not be grey
    +#endif
    +#if defined (A)
    +int y; // variable shall not be grey
    +#elif defined (B)
    +int z; // variable shall not be grey
    +#endif
    +
    diff --git a/autotests/html/preprocessor-bug363280.cpp.html b/autotests/html/preprocessor-bug363280.cpp.html new file mode 100644 index 0000000..1cdb7cc --- /dev/null +++ b/autotests/html/preprocessor-bug363280.cpp.html @@ -0,0 +1,15 @@ + + + +preprocessor-bug363280.cpp + +
    +#if 1
    +int x; // variable shall not be grey
    +#endif
    +#if defined (A)
    +int y; // variable shall not be grey
    +#elif defined (B)
    +int z; // variable shall not be grey
    +#endif
    +
    diff --git a/autotests/html/review128925-1.css.html b/autotests/html/review128925-1.css.html new file mode 100644 index 0000000..c9686d5 --- /dev/null +++ b/autotests/html/review128925-1.css.html @@ -0,0 +1,119 @@ + + + +review128925-1.css + +
    +/*
    + * CSS Syntax Highlight Sample File (Standard)
    + *
    + * This file contains most CSS syntax, CSS3 properties, @media, @font-face and
    + * @keyframes annotations.
    + *
    + * @author  Guo Yunhe guoyunhebrave@gmail.com
    + * @date    2016-09-16
    + */
    +
    +/*
    + * Block comment
    + *
    + * Alert keywords:
    + * TODO BUG FIXME
    + */
    +
    +@charset "UTF-8";
    +
    +@import url("components/button.css");
    +
    +
    +/* Properties */
    +
    +html, body {
    +    font-family: "Droid Sans", Arial, sans-serif;
    +    font-size: 11pt;
    +    line-height: 1.5em;
    +    max-width: calc(100% - 300px);
    +    background: #fff000;
    +    text-shadow: 0 0 2px rgba(0, 0, 0, 0.3);
    +    box-sizing: border-box;
    +}
    +
    +
    +/* Selectors */
    +
    +blockquote {
    +    margin: 0;
    +}
    +
    +header #logo {
    +    width: 100px;
    +}
    +
    +div#footer .link {
    +    color: blue;
    +}
    +
    +sidebar #subscribe .subscribe_form input[type="text"] {
    +    font-size: 20px;
    +}
    +
    +sidebar #subscribe .subscribe_form:nth-child(2n + 1):hover input[class*="small-"] {
    +    font-weight: bold;
    +}
    +
    +
    +/* Media Queries */
    +
    +@media print {
    +    .container {
    +        width: 100%;
    +    }
    +}
    +
    +@media screen and (min-width: 768px) {
    +    .container {
    +        width: 600px;
    +    }
    +}
    +
    +@media screen and (min-width: 768px) and (max-width: 960px) {
    +    .container {
    +        width: 720px;
    +    }
    +}
    +
    +
    +/* Fontface */
    +
    +@font-face {
    +    font-family: MyHelvetica;
    +    src: local("Helvetica Neue Bold"),
    +        local("HelveticaNeue-Bold"),
    +        url(MgOpenModernaBold.ttf);
    +    font-weight: bold;
    +}
    +
    +/* Animation (Keyframes) */
    +
    +@keyframes slidein {
    +    from {
    +        margin-left: 100%;
    +        width: 300%;
    +    }
    +
    +    to {
    +        margin-left: 0%;
    +        width: 100%;
    +    }
    +}
    +
    +
    +/* Region markers */
    +
    +/*BEGIN Comment */
    +
    +
    +
    +/*END Comment */
    +
    +
    diff --git a/autotests/html/review128925-1.scss.html b/autotests/html/review128925-1.scss.html new file mode 100644 index 0000000..35f0f19 --- /dev/null +++ b/autotests/html/review128925-1.scss.html @@ -0,0 +1,218 @@ + + + +review128925-1.scss + +
    +/*
    + * SCSS Syntax Highlight Sample File (Standard)
    + *
    + * This file contains most SCSS syntax, CSS3 properties, advanced code structure.
    + * It is NOT a valid SCSS file that can be compiled by SCSS preprocessors.
    + *
    + * @author  Guo Yunhe guoyunhebrave@gmail.com
    + * @date    2016-09-15
    + */
    +
    +/*
    + * Block comment
    + *
    + * Alert keywords:
    + * TODO BUG FIXME
    + */
    +
    +@charset "UTF-8";
    +
    +@import "mixins/button";
    +
    +// Variable define
    +
    +$image-path:            "../../static/images";
    +$default-text-color:    #333 !default; // Default can be overrided
    +$default-font-size:     16px !default;
    +$default-font-family:   Roboto, "Droid Sans", sans-serif;
    +$default-font-weight:   400;
    +$default-line-height:   $default-font-size * 1.8;
    +$shadow-transparence:   0.25;
    +$box-shadow:            0 0 3px rgba(0,0,0,$shadow-transparence);
    +$page-width:            100rem; // kabab-case
    +$gapOfArticle:          20px;   // camelCase
    +$body_background_color: white;  // snake_case
    +
    +// Mixins
    +
    +@mixin border-radius($radius) {
    +  -webkit-border-radius: $radius;
    +     -moz-border-radius: $radius;
    +      -ms-border-radius: $radius;
    +          border-radius: $radius;
    +}
    +
    +.box { @include border-radius(10px); }
    +
    +// Nesting
    +
    +#home-page {
    +
    +    header {
    +        width: 80%;
    +        margin: 0 auto;
    +
    +        .cover {
    +            @include border-radius(20px);
    +            max-width: 100%;
    +
    +            &:hover {
    +                background: #ffffff;
    +            }
    +
    +            .like-button {
    +                font-size: $default-font-size * 0.8;
    +
    +                @media (max-width: 300px) and (min-width: 200px) {
    +                    font-size: $default-font-size * 0.8;
    +
    +                    .icon {
    +                        width: 20px;
    +                        height: 20px;
    +                    }
    +                }
    +
    +                @media print {
    +                    display: none;
    +                }
    +            }
    +        }
    +    }
    +}
    +
    +// Extend and inheritance
    +
    +.message {
    +    border: $border-light;
    +    background-color: #f0f0f0;
    +}
    +
    +.message-danger {
    +    @extend .message;
    +}
    +
    +
    +// Control structures
    +
    +@mixin does-parent-exist {
    +    @if & {
    +        &:hover {
    +            color: red;
    +        }
    +    } @else {
    +        a {
    +            color: red;
    +        }
    +    }
    +}
    +
    +
    +// Operators
    +
    +.container { width: 100%; }
    +
    +article[role="main"] {
    +  float: left;
    +  width: 600px / 960px * 100%;
    +}
    +
    +aside[role="complementary"] {
    +  float: right;
    +  width: 300px / 960px * 100%;
    +}
    +
    +
    +// Functions - see http://sass-lang.com/documentation/Sass/Script/Functions.html
    +
    +$color1: hsl(120deg, 100%, 50%);
    +$color2: rgb($red, $green, blue($color1));
    +$color3: mix($color1, $color2, [$weight]);
    +
    +
    +// Properties
    +
    +html, body {
    +    font-family: "Droid Sans", Arial, sans-serif;
    +    font-size: 11pt;
    +    line-height: 1.5em;
    +    max-width: 300px + $page-width - $gap / 2;
    +    background: $bg_color;
    +    text-shadow: 0 0 2px rgba(0,0,0, $transparence);
    +    box-sizing: border-box;
    +}
    +
    +
    +// Selectors
    +
    +blockquote {
    +    margin: 0;
    +}
    +
    +header #logo {
    +    width: 100px;
    +}
    +
    +div#footer .link {
    +    color: blue;
    +}
    +
    +sidebar #subscribe .subscribe_form input[type="text"] {
    +    font-size: 20px;
    +}
    +
    +sidebar #subscribe .subscribe_form:nth-child(2n + 1):hover input[class*="small-"] {
    +    font-weight: bold;
    +}
    +
    +
    +// Media Queries
    +
    +@media print {
    +    .container {
    +        width: 100%;
    +    }
    +}
    +
    +@media screen and (min-width: 768px) {
    +    .container {
    +        width: 600px;
    +    }
    +}
    +
    +@media screen and (min-width: 768px) and (max-width: 960px) {
    +    .container {
    +        width: 720px;
    +    }
    +}
    +
    +
    +// Fontface
    +
    +@font-face {
    +    font-family: MyHelvetica;
    +    src: local("Helvetica Neue Bold"),
    +        local("HelveticaNeue-Bold"),
    +        url(MgOpenModernaBold.ttf);
    +    font-weight: bold;
    +}
    +
    +// Animation (Keyframes)
    +
    +@keyframes slidein {
    +    from {
    +        margin-left: 100%;
    +        width: 300%;
    +    }
    +
    +    to {
    +        margin-left: 0%;
    +        width: 100%;
    +    }
    +}
    +
    diff --git a/autotests/html/review128925-2.css.html b/autotests/html/review128925-2.css.html new file mode 100644 index 0000000..eb7081c --- /dev/null +++ b/autotests/html/review128925-2.css.html @@ -0,0 +1,69 @@ + + + +review128925-2.css + +
    +/*
    + * CSS Syntax Highlight Sample File (Complex)
    + *
    + * This file contains complex CSS syntax that can test unexpected situations.
    + *
    + * @author  Guo Yunhe guoyunhebrave@gmail.com
    + * @date    2016-09-16
    + */
    +
    +
    +/* Comments with special content */
    +
    +/*
    + * .class-selector #id "string" 'comment' // comment {} [] ()  /* comment
    + * TODO BUG DEBUG
    + * body {
    + *    margin: 0 !important;
    + * }
    + */
    +
    +/* Comments in special positions */
    +
    +header/* comment here */.active /* comment here */ {
    +    /* comment here */ color : /* comment here */ blue/* comment here */;
    +    font-family: Arial /* comment here */,
    +        "Droid Sans", /* comment here */
    +        sans-serif/* comment here */;
    +}
    +
    +@media screen /* comment here */ and (max-width: 300px /* comment here */) /* comment here */ {/* comment here */}
    +
    +
    +/* Strings with special content */
    +
    +@import url("{} $variable /* comment */");
    +
    +
    +/* Without extra breaklines and spaces */
    +
    +pre.primary:hover.large:nth-child(2n-1){font-size:17px;font-family:"Noto Sans";-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.3)}
    +
    +
    +/* With unnecessary breaklines and spaces */
    +
    +blockquote .ref
    +    {
    +             flex : 0 1 30%;
    +        flex-wrap : wrap;
    +    }
    +
    +@media screen and (orientation: landscape) {
    +  .sidebar {
    +    width: 500px; } }
    +
    +
    +/* Special selectors: HTML5 allows user defined tags */
    +
    +header {
    +    flex {
    +        width: 300px;
    +    }
    +}
    +
    diff --git a/autotests/html/review128925-2.scss.html b/autotests/html/review128925-2.scss.html new file mode 100644 index 0000000..9592eec --- /dev/null +++ b/autotests/html/review128925-2.scss.html @@ -0,0 +1,88 @@ + + + +review128925-2.scss + +
    +/*
    + * SCSS Syntax Highlight Sample File (Complex)
    + *
    + * This file contains complex SCSS syntax that can test unexpected situations.
    + * It is NOT a valid SCSS file that can be compiled by SCSS preprocessors.
    + *
    + * @author  Guo Yunhe guoyunhebrave@gmail.com
    + * @date    2016-09-16
    + */
    +
    +
    +// Comments with special content
    +
    +// .class-selector #id "string" 'comment' // comment {} [] () /* comment */ text
    +
    +/*
    + * .class-selector #id "string" 'comment' // comment {} [] ()  /* comment
    + * TODO BUG DEBUG
    + * body {
    + *    margin: 0 !important;
    + * }
    + */
    +
    +// Comments in special positions
    +
    +$color: black /* comment here */;
    +
    +header/* comment here */.active /* comment here */ {
    +    /* comment here */ color : /* comment here */ blue/* comment here */;
    +    font-family: Arial /* comment here */,
    +        "Droid Sans", /* comment here */
    +        sans-serif/* comment here */;
    +}
    +
    +@media screen /* comment here */ and (max-width: 300px /* comment here */) /* comment here */ {/* comment here */}
    +
    +
    +// Strings with special content
    +
    +@import "{} $variable /* comment */";
    +@import "{}";
    +
    +// Without extra breaklines and spaces
    +
    +pre.primary:hover.large:nth-child(2n-1){font-size:$default-font-size;font-family:"Noto Sans";-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.3)}
    +
    +// With unnecessary breaklines and spaces
    +
    +blockquote .ref
    +    {
    +             flex : 0 1 30%;
    +        flex-wrap : wrap;
    +    }
    +
    +.sidebar {
    +  width: 300px; }
    +  @media screen and (orientation: landscape) {
    +    .sidebar {
    +      width: 500px; } }
    +
    +// Variable interpolation: #{}
    +
    +$name: foo;
    +$attr: border;
    +p.#{$name} {
    +    #{$attr}-color: blue;
    +}
    +
    +p {
    +    $font-size: 12px;
    +    $line-height: 30px;
    +    font: #{$font-size}/#{$line-height};
    +}
    +
    +// Special selectors: HTML5 allows user defined tags
    +
    +header {
    +    flex {
    +        width: 300px;
    +    }
    +}
    +
    diff --git a/autotests/html/review128935.html.html b/autotests/html/review128935.html.html new file mode 100644 index 0000000..4e59fc3 --- /dev/null +++ b/autotests/html/review128935.html.html @@ -0,0 +1,171 @@ + + + +review128935.html + +
    +<!--
    +
    +HTML Syntax Highlight Sample File (Standard)
    +
    +- Follow HTML5 standard.
    +- Contain some valid, but not recommended syntax.
    +- Can be rendered by modern web browsers.
    +
    +@author Guo Yunhe guoyunhebrave@gmail.com
    +@date   2016-09-17
    +
    +-->
    +
    +<!DOCTYPE html>
    +
    +<html>
    +
    +<head>
    +<meta charset="utf-8">
    +<title>HTML Syntax Highlight Sample File (Standard)</title>
    +<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    +<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    +</head>
    +
    +<body>
    +
    +<!-- HTML5 defined elements -->
    +
    +<div>
    +    This is a div. <span>This is a span</span>
    +    <div>
    +        This is a div.
    +    </div>
    +</div>
    +
    +<p>
    +    This is a paragraph. <em></em>
    +</p>
    +
    +<h1>This is heading 1</h1>
    +<h2>This is heading 2</h2>
    +<h3>This is heading 3</h3>
    +<h4>This is heading 4</h4>
    +<h5>This is heading 5</h5>
    +<h6>This is heading 6</h6>
    +
    +<a href="http://www.w3schools.com">This is a link</a>
    +
    +<br>
    +
    +<img src="http://placehold.it/200x150" alt="This is an image" width="200" height="150">
    +
    +<hr>
    +
    +<ul>
    +    <li>List item</li>
    +    <li>List item</li>
    +    <li>List item</li>
    +    <li>List item</li>
    +    <li>List item</li>
    +</ul>
    +
    +<ol>
    +    <li>List item</li>
    +    <li>List item</li>
    +    <li>List item</li>
    +    <li>List item</li>
    +    <li>List item</li>
    +</ol>
    +
    +<table>
    +    <tr>
    +        <th>Table head</th>
    +        <th>Table head</th>
    +        <th>Table head</th>
    +    </tr>
    +    <tr>
    +        <td>Table head</td>
    +        <td>Table head</td>
    +        <td>Table head</td>
    +    </tr>
    +</table>
    +
    +<form>
    +    <input type="email" name="author"/>
    +    <input type="text" name="message"/>
    +    <button type="button">Send</button>
    +</form>
    +
    +<main>
    +    <header>This is a header.</header>
    +
    +    <nav>This is a nav.</nav>
    +
    +    <article>
    +        <h2>This is an article.</h2>
    +        <p>This is an article.</p>
    +    </article>
    +
    +    <aside>
    +        <h2>This is an aside.</h2>
    +    </aside>
    +
    +    <footer></footer>
    +
    +</main>
    +
    +<!-- Custom elements -->
    +
    +<booklist>
    +    <book>
    +        <booktitle>Just For Fun: The Story of an Accidental Revolutionary</booktitle>
    +        <author>Linus Torvalds</author>
    +        <description
    +            class="featured" title="Click to read full text...">
    +            A humorous autobiography of Linus Torvalds, the creator of the Linux
    +            kernel, co-written with David Diamond. The book primarily theorizes
    +            the Law of Linus that all evolution contributed by humanity starts
    +            for survival, sustains socially and entertains at last. As well as
    +            this the book explains Torvalds' view of himself, the free software
    +            movement and the development of Linux.</description>
    +    </book>
    +</booklist>
    +
    +<large-space/>
    +
    +<!-- Ends for single tag elements -->
    +<br>
    +<br/>
    +<br />
    +<br></br>
    +
    +<!-- Uppercase elements -->
    +
    +<DIV>
    +    THIS IS A DIV.
    +    <P>THIS IS A PARAGRAPH.</P>
    +    <H2>THIS IS A HEADING.</H2>
    +</DIV>
    +
    +<!-- Arrtibutes -->
    +
    +<a href="#" style="background-color:rgba(0,0,0,0.3)" title="Click me">Magic button</a>
    +
    +<img src="http://placehold.it/200x150" alt="This is an image" width="200"
    +     height="150" title="This is an image">
    +
    +<!-- Attribute without value -->
    +
    +<select>
    +    <option selected>GNU/Linux</option>
    +    <option>BSD</option>
    +    <option>Windows</option>
    +    <option>macOS</option>
    +</select>
    +
    +<!-- Attribute without quotes -->
    +
    +<div id=name class=a-sweet-block data-counter=175>This is a div.</div>
    +
    +</body>
    +
    +</html>
    +
    diff --git a/autotests/html/test.bash.html b/autotests/html/test.bash.html new file mode 100644 index 0000000..0ca6922 --- /dev/null +++ b/autotests/html/test.bash.html @@ -0,0 +1,13 @@ + + + +test.bash + +
    +#!/bin/bash
    +
    +for i in `ls tests/auto/output/*.html`; do
    +    refFile=`echo $i | sed -e s,build,src, | sed -e s,output,reference, | sed -e s,.html,.ref.html,`
    +    cp -v $i $refFile
    +done
    +
    diff --git a/autotests/html/test.bb.html b/autotests/html/test.bb.html new file mode 100644 index 0000000..9be6849 --- /dev/null +++ b/autotests/html/test.bb.html @@ -0,0 +1,41 @@ + + + +test.bb + +
    +# syntax test file for Bitbake receipes
    +
    +SUMMARY = "GammaRay Qt introspection probe"
    +HOMEPAGE = "http://www.kdab.com/gammaray"
    +
    +LICENSE = "GPLv2"
    +LIC_FILES_CHKSUM = "file://LICENSE.GPL.txt;md5=2abfe5daa817fd4346b6d55293941415"
    +
    +inherit cmake_qt5
    +
    +SRC_URI = "git://github.com/KDAB/GammaRay;branch=master"
    +
    +SRCREV = "139e003174f48b0c883fc6c200ef2efb7467bff1"
    +PV = "2.4.0+git${SRCPV}"
    +
    +DEPENDS = "qtdeclarative"
    +
    +S = "${WORKDIR}/git"
    +
    +EXTRA_OECMAKE += " -DGAMMARAY_BUILD_UI=OFF"
    +
    +FILES_${PN}-dev += " \
    +    /usr/lib/cmake/* \
    +    /usr/mkspecs/modules/* \
    +"
    +FILES_${PN}-dbg += " \
    +    /usr/lib/.debug/* \
    +    /usr/lib/gammaray/*/*/.debug \
    +    /usr/lib/gammaray/*/*/styles/.debug \
    +"
    +
    +# error: unterinated string
    +VAR *= "abc
    +  this is wrong
    +
    diff --git a/autotests/html/test.c.html b/autotests/html/test.c.html new file mode 100644 index 0000000..1492d9b --- /dev/null +++ b/autotests/html/test.c.html @@ -0,0 +1,63 @@ + + + +test.c + +
    +#include <stdio.h>
    +#include "stdint.h"
    +
    +#define SOME_VAR 1
    +#ifdef SOME_VAR
    +
    +#define MULTILINE_MACRO one \
    +two \
    +three
    +
    +static uint64_t intWithSuffix = 42ull;
    +static int octNum = 07232;
    +static int invalidOctNum = 09231;
    +static uint64_t hexNum = 0xDEADBEEF42;
    +static uint64_t invalidHexNum = 0xGLDFKG;
    +static char binNum = 0b0101010;
    +
    +static double d1 = 42.;
    +static double d2 = .42;
    +static double d3 = 42.3e1;
    +static double d4 = .2e-12;
    +static double d5 = 32.e+12;
    +static float floatQualifier = 23.123f;
    +
    +static const char c1 = 'c';
    +static const char c2 = '\n';
    +static const char c2a = '\120'; // octal
    +static const char c2b = '\x1f'; // hex
    +static const char c2c = '\'';
    +static const char c2d = '\\';
    +static const char* c3  = "string";
    +static const char* c4 = "\"string\n\t\012\x12\"";
    +static const char* c5 = "multiline \
    +    string";
    +
    +//BEGIN region
    +// TODO comment FIXME comment ### comment
    +//END region
    +
    +#wrong
    +
    +/**
    + * Doxygen
    + * @param p1 text
    + * \brief <b>bold text</b>
    + * \dot
    + * a -> b
    + * \enddot
    + *
    + * \verbatim
    + * <dummy>
    + * \endverbatim
    + * <html>text</html>
    + */
    +
    +#endif
    +
    diff --git a/autotests/html/test.cmake.html b/autotests/html/test.cmake.html new file mode 100644 index 0000000..6a33cab --- /dev/null +++ b/autotests/html/test.cmake.html @@ -0,0 +1,38 @@ + + + +test.cmake + +
    +# comment
    +
    +#[[.rst:
    +MyModule
    +--------
    +
    +bla bla
    +#]]
    +
    +#.rst:
    +# ATTENTION
    +# alternative doc comment
    +#
    +
    +#[=====[.rst:
    +
    +3rd form
    +
    +]=====]
    +
    +set(CMAKE_AUTOMOC ON)
    +if (POLICY CMP042)
    +    target_link_libraries(myTaget SHARED Qt5::Core)
    +else()
    +    add_executable(myTaget ${some_var})
    +endif()
    +
    +macro(my_macro arg1)
    +    foreach(arg ${ARGN})
    +    endforeach()
    +endmacro()
    +
    diff --git a/autotests/html/test.css.html b/autotests/html/test.css.html new file mode 100644 index 0000000..7f9409e --- /dev/null +++ b/autotests/html/test.css.html @@ -0,0 +1,25 @@ + + + +test.css + +
    +h1 {
    +    text-color: "red";
    +}
    +
    +/* PHP code, invalid in CSS context */
    +for() 
    +
    +<?php echo("hello"); 
    +
    +// valid code in PHP context
    +for()
    +
    +?>
    +
    +h2 {
    +    text-weight: bold;
    +}
    +
    +
    diff --git a/autotests/html/test.desktop.html b/autotests/html/test.desktop.html new file mode 100644 index 0000000..66cdb27 --- /dev/null +++ b/autotests/html/test.desktop.html @@ -0,0 +1,26 @@ + + + +test.desktop + +
    +# test file for .dekstop syntax highlighting
    +[Desktop Entry]
    +GenericName=Text Editor
    +GenericName[ar]=محرّر نصوص
    +Name=KWrite
    +Name[ar]=كاتبك
    +Comment=KDE Text Editor
    +Comment[ar]=محرّر نصوص لكدي
    +MimeType=text/plain;
    +Exec=kwrite %U
    +StartupNotify=true
    +Icon=kwrite
    +X-DocPath=kwrite/index.html
    +Type=Application
    +Terminal=false
    +InitialPreference=8
    +X-DBUS-StartupType=Multi
    +X-DBUS-ServiceName=org.kde.kwrite
    +Categories=Qt;KDE;Utility;TextEditor;
    +
    diff --git a/autotests/html/test.diff.html b/autotests/html/test.diff.html new file mode 100644 index 0000000..8aa506d --- /dev/null +++ b/autotests/html/test.diff.html @@ -0,0 +1,55 @@ + + + +test.diff + +
    +commit 2b16665838c8afeaa0f065cafc747438de35876b
    +Author: Volker Krause <vkrause@kde.org>
    +Date:   Sat Oct 8 13:31:51 2016 +0200
    +
    +    Implement dynamic DetectChar rules
    +    
    +    Needed for Perl highlighting.
    +
    +diff --git a/src/lib/rule.cpp b/src/lib/rule.cpp
    +index f588985..c4c3b92 100644
    +--- a/src/lib/rule.cpp
    ++++ b/src/lib/rule.cpp
    +@@ -308,12 +308,22 @@ bool DetectChar::doLoad(QXmlStreamReader& reader)
    +     if (s.isEmpty())
    +         return false;
    +     m_char = s.at(0);
    ++    if (isDynamic()) {
    ++        m_captureIndex = m_char.digitValue();
    ++    }
    +     return true;
    + }
    + 
    + MatchResult DetectChar::doMatch(const QString& text, int offset, const QStringList &captures)
    + {
    +-    Q_UNUSED(captures); // TODO
    ++    if (isDynamic()) {
    ++        if (captures.size() <= m_captureIndex || captures.at(m_captureIndex).isEmpty())
    ++            return offset;
    ++        if (text.at(offset) == captures.at(m_captureIndex).at(0))
    ++            return offset + 1;
    ++        return offset;
    ++    }
    ++
    +     if (text.at(offset) == m_char)
    +         return offset + 1;
    +     return offset;
    +diff --git a/src/lib/rule_p.h b/src/lib/rule_p.h
    +index d8862ae..d9cedbf 100644
    +--- a/src/lib/rule_p.h
    ++++ b/src/lib/rule_p.h
    +@@ -103,6 +103,7 @@ protected:
    + 
    + private:
    +     QChar m_char;
    ++    int m_captureIndex;
    + };
    + 
    + class Detect2Char : public Rule
    +
    diff --git a/autotests/html/test.eml.html b/autotests/html/test.eml.html new file mode 100644 index 0000000..0e01d43 --- /dev/null +++ b/autotests/html/test.eml.html @@ -0,0 +1,101 @@ + + + +test.eml + +
    +Return-Path: <kwrite-devel-bounces@kde.org>
    +X-Sieve: CMU Sieve 2.3
    +X-Virus-Scanned: amavisd-new at site
    +Authentication-Results: linux.site (amavisd-new); dkim=pass (1024-bit key)
    +	header.d=kde.org
    +Received: from postbox.kde.org (localhost.localdomain [127.0.0.1])
    +	by postbox.kde.org (Postfix) with ESMTP id 3167DB6E75;
    +	Wed,  5 Oct 2016 20:21:47 +0000 (UTC)
    +DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=kde.org; s=default;
    +	t=1475698907; bh=6i+3UfR6HLC54wVtp5SF4sVWvQn63jzu9vD2zJal/kY=;
    +	h=From:To:Subject:Date:Reply-To:List-Id:List-Unsubscribe:List-Post:
    +	 List-Help:List-Subscribe:From;
    +	b=M5nfHbmJe/4DPuidrJ901dUzX3FmpVpyUrPM961Or9bKrMO+z9gaTUwbfPR74Rq8B
    +	 Rv66yf3ZaDuRZxv/ARPzpr8qnDTtf13WRFZ/ySdqqqQJKeBqCAd7/wbR0kHhypvpwe
    +	 z4nY6+bNnjvFelPXR56o16b+/Ib2GTYJ9hwiG97U=
    +X-Original-To: kwrite-devel@kde.org
    +Delivered-To: kwrite-devel@localhost.kde.org
    +Received-SPF: Neutral (access neither permitted nor denied) identity=mailfrom;
    + client-ip=85.214.234.26; helo=h2265959.stratoserver.net;
    + envelope-from=vkrause@kde.org; receiver=kwrite-devel@kde.org
    +From: Volker Krause <vkrause@kde.org>
    +To: kwrite-devel@kde.org
    +Subject: Highlighting semantics: line end context switches when popping back
    + into previous line context stack
    +Date: Wed, 05 Oct 2016 22:19:17 +0200
    +Message-ID: <2420385.jiZKTgWtgY@vkpc5>
    +Organization: KDE
    +User-Agent: KMail/4.14.10 (Linux/4.1.13-5-default; KDE/4.14.16; x86_64;
    + git-91275a7; 2015-12-13)
    +MIME-Version: 1.0
    +Content-Type: multipart/signed; boundary="nextPart1575059.2yRQ5x6HOo";
    + micalg="pgp-sha1"; protocol="application/pgp-signature"
    +X-BeenThere: kwrite-devel@kde.org
    +X-Mailman-Version: 2.1.16
    +Precedence: list
    +Reply-To: kwrite-devel@kde.org
    +List-Id: Kate/KWrite Mailing List <kwrite-devel.kde.org>
    +List-Unsubscribe: <https://mail.kde.org/mailman/options/kwrite-devel>,
    + <mailto:kwrite-devel-request@kde.org?subject=unsubscribe>
    +List-Post: <mailto:kwrite-devel@kde.org>
    +List-Help: <mailto:kwrite-devel-request@kde.org?subject=help>
    +List-Subscribe: <https://mail.kde.org/mailman/listinfo/kwrite-devel>,
    + <mailto:kwrite-devel-request@kde.org?subject=subscribe>
    +Errors-To: kwrite-devel-bounces@kde.org
    +Sender: "KWrite-Devel" <kwrite-devel-bounces@kde.org>
    +
    +
    +--nextPart1575059.2yRQ5x6HOo
    +Content-Transfer-Encoding: 7Bit
    +Content-Type: text/plain; charset="us-ascii"
    +
    +Hi,
    +
    +when trying to add the unit test for the new Praat highlighting to
    +KF5::SyntaxHighlighting it turned out that the output doesn't match at all
    +that of Kate. We managed to trace this back to the following rather surprising
    +(and apparently undocumented) behavior in Kate:
    +
    +When a context switch (anywhere in a line) pops more contexts than were on the
    +stack when starting the line, it executes line end context switches of the
    +previous line contexts.
    +
    +| | | | | | The corresponding code is in KateHighlighting::generateContextStack(),
    +| | > | > KF5::SyntaxHighlighting doesn't do this (yet), Praat is apparently the first
    +> | > format we have tests for that uses this behavior.
    +
    +> Does anyone remember why we do this, or happens to know which highlighting
    +> files besides Praat rely on this?
    +
    +> > Archeology can trace this back to the dark CVS ages even, one reference
    +> > Dominik has dug up is a 10 year old SVN commit
    +> > (https://quickgit.kde.org/?p=kdelibs.git&a=commit&h=90ef47f582277745f727d89f05f72f1e1705fdc4
    +> >), where Christoph claims to understand what this code does ;)
    +
    +> > > As this is highly unexpected and hard to reason about behavior, Dominik and I
    +> > > > were wondering if we can possibly drop this, and rather fix affected
    +> > > > > highlighting files instead?
    +
    +Regards,
    +Volker
    +--nextPart1575059.2yRQ5x6HOo
    +Content-Type: application/pgp-signature; name="signature.asc"
    +Content-Description: This is a digitally signed message part.
    +Content-Transfer-Encoding: 7Bit
    +
    +-----BEGIN PGP SIGNATURE-----
    +Version: GnuPG v2
    +
    +iD8DBQBX9WBIf5bM1k0S0kcRAireAJ4lCWa08Y5yU1ezIvKVCAfnkhcUbACgou0O
    +X4c+lkPI0tti59KV1vetaeU=
    +=VqDS
    +-----END PGP SIGNATURE-----
    +
    +--nextPart1575059.2yRQ5x6HOo--
    +
    diff --git a/autotests/html/test.frag.html b/autotests/html/test.frag.html new file mode 100644 index 0000000..9ad3654 --- /dev/null +++ b/autotests/html/test.frag.html @@ -0,0 +1,33 @@ + + + +test.frag + +
    +#version 330 core
    +
    +// single line comment
    +
    +/* single line commonet */
    +
    +/*
    + multi line comment
    + */
    +
    +in ColorFormat {
    +    vec3 color;
    +} fs_in;
    +
    +out vec4 fragColor;
    +
    +vec3 fun(const in vec3 foo) {
    +    foo[2] = foo.x;
    +
    +    return foo;
    +}
    +
    +void main()
    +{
    +    fragColor = vec4( fs_in.color, 1.0 );
    +}
    +
    diff --git a/autotests/html/test.htm.html b/autotests/html/test.htm.html new file mode 100644 index 0000000..f1a1bc7 --- /dev/null +++ b/autotests/html/test.htm.html @@ -0,0 +1,24 @@ + + + +test.htm + +
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    +<html>
    +  <head>
    +    <title>This is a title</title>
    +    <style>
    +    /* comment */
    +    #xyz { color: red; }
    +    h1 { font: "Comic Sans"; }
    +    </style>
    +  </head>
    +  <body>
    +    <p id="xzy">Hello world!</p>
    +  </body>
    +  <script>
    +    document.body.appendChild(document.createTextNode('Hello World!')); // comment
    +  </script>
    +</html>
    +
    diff --git a/autotests/html/test.ijs.html b/autotests/html/test.ijs.html new file mode 100644 index 0000000..b9b91dd --- /dev/null +++ b/autotests/html/test.ijs.html @@ -0,0 +1,68 @@ + + + +test.ijs + +
    +Comment
    +NB. This is a single line comment, check regions overlapping priority: 1 2.3  +/ &. 'quoted text'
    +NB.(
    +NB. This is a foldable multi line comment
    +NB.)
    +
    +String literal
    +''
    +''''
    +'This is quoted text'
    +'And this '' and this NB. and this' 'Yet another quoted text'
    +
    +Numeric literal
    +12 34.56 _7.89 1e2 1.2e3 _. _ __ 123j_456 2b111.111 1r23 123456x 1.2e3j4.5e6 _j_ __j_ _.j_. _j3p4j_.
    +
    +Parenthesis
    +( )
    +
    +Adverb
    +~ / \ /. \. } b. f. M. t. t:
    +
    +Conjuction
    +^: . .. .: :  :. :: ;. !. !: " ` `: @ @. @: & &. &: &.: d. D. D: H. L: S: T.
    +
    +Control
    +assert. break. case. catch. catchd. catcht. continue. do. else. elseif. end. fcase. for. for_abc. goto_abc. if. label_abc. return. select. throw. try. while. whilst.
    +
    +Copula
    +a =: 123
    +(a) =: 123
    +(a;b;c) =: 123
    +'a b c' =: 123
    +'a b c' =. '123'
    +'`a b c' =. '123'
    +'a' =: 123
    +('a';'b';'c') =: 123
    +
    +Explicit argument
    +x y m n u v  x. y. m. n. u. v.
    +
    +Noun
    +a. a:
    +
    +Verb
    += < <. <: > >. >: _: + +. +: * *. *: - -. -: % %. %: ^ ^. $ $. $: ~. ~: | |. |: , ,. ,: ; ;: # #. #: ! /: \: [ [: ] { {. {: {:: }. }: ". ": ? ?. A. C. e. E. i. i: I. j. L. o. p. p.. p: q: r. s: u: x: _9: _8: _7: _6: _5: _4: _3: _2: _1: 0: 1: 2: 3: 4: 5: 6: 7: 8: 9:
    +
    +Combined
    +for_abc. i. 5 do. 55 return. end.
    +a=. b =: 123 +/ # i. 10
    +123 'qwerty'
    +a_b =: '123' [ c__d =. 4 : 0  NB. foldable definition begins
    +  x +/ y
    +)
    +e__12 =: define  NB. foldable definition begins
    +  if. x do.  NB. inner foldable region begins
    +    y=. y + x  NB. comment after code
    +    x +/ y
    +  else.  NB. inner foldable region begins
    +    y +/ y
    +  end.
    +)
    +
    diff --git a/autotests/html/test.js.html b/autotests/html/test.js.html new file mode 100644 index 0000000..3185c60 --- /dev/null +++ b/autotests/html/test.js.html @@ -0,0 +1,15 @@ + + + +test.js + +
    +/* comment */
    +
    +function fun()
    +{
    +    var boo = { 'key': [ 1, 2.0, 3.0e1, 004, 0x5 ] };
    +}
    +
    +class MyClass; // reserved keywords
    +
    diff --git a/autotests/html/test.json.html b/autotests/html/test.json.html new file mode 100644 index 0000000..1c3ec27 --- /dev/null +++ b/autotests/html/test.json.html @@ -0,0 +1,20 @@ + + + +test.json + +
    +{
    +  "float": 3.1415,
    +  "int": 123,
    +  "string": "\a \"b' \n",
    +  "array": [ 1, 2, 3 ],
    +  "object": {
    +    "mult-line": "so this folds"
    +  },
    +  "folded array": [
    +    1, 2, 3
    +  ]
    +  "error key": "due to missing comma"
    +}
    +
    diff --git a/autotests/html/test.markdown.html b/autotests/html/test.markdown.html new file mode 100644 index 0000000..06b9511 --- /dev/null +++ b/autotests/html/test.markdown.html @@ -0,0 +1,46 @@ + + + +test.markdown + +
    +# H1
    +
    +## H2
    +
    +### H3
    +
    +Multi-line paragraph bla bla bla
    +bla bla bla.
    +
    +Intentional line break  
    +via two spaces at line.
    +
    +Formats: _italic_, **bold**, `monospace`, ~~strikeout~~
    +
    +Bullet list:
    +
    +* item1
    +* item2
    +
    +Numbered list:
    +
    +1. item 1
    +2. item 2
    +
    +[link](http://kde.org)
    +
    +    code 1
    +    code 2
    +
    +normal text
    +
    +> block quote _italic_
    +> more block quote
    +
    +normal text
    +
    +Title: some text
    +
    +normal text
    +
    diff --git a/autotests/html/test.mss.html b/autotests/html/test.mss.html new file mode 100644 index 0000000..47b6292 --- /dev/null +++ b/autotests/html/test.mss.html @@ -0,0 +1,222 @@ + + + +test.mss + +
    +/* kate: hl CartoCSS
    +   This file contains some content coming from
    +   https://github.com/gravitystorm/openstreetmap-carto
    +   with CC0 license. This file is just for testing
    +   katepart highlighting engine.
    +   */
    +
    +#world {
    +// this syntax
    +polygon-opacity: 50%;
    +
    +// is equivalent to
    +polygon-opacity: 0.5;
    +}
    +
    +@admin-boundaries: #ac46ac;
    +
    +/* For performance reasons, the admin border layers are split into three groups
    +for low, middle and high zoom levels.
    +For each zoomlevel, all borders come from a single attachment, to handle
    +overlapping borders correctly.
    +*/
    +
    +#admin-low-zoom[zoom < 11],  // test
    +#admin-mid-zoom[zoom >= 11][zoom < 13],
    +#admin-high-zoom[zoom >= 13] {
    +  [admin_level = '2'],
    +  [admin_level = '3'] {
    +    [zoom >= 4] {
    +      background/line-color: white;
    +      background/line-width: 0.6;
    +      line-color: @admin-boundaries;
    +      line-width: 0.6;
    +    }
    +    [zoom >= 7] {
    +      background/line-width: 2;
    +      line-width: 2;
    +    }
    +    [zoom >= 10] {
    +      [admin_level = '2'] {
    +        background/line-width: 6;
    +        line-width: 6;
    +      }
    +      [admin_level = '3'] {
    +        background/line-width: 5;
    +        line-width: 5;
    +        line-dasharray: 4,2;
    +        line-clip: false;
    +      }
    +    }
    +  }
    +  [admin_level = '4'] {
    +    [zoom >= 4] {
    +      background/line-color: white;
    +      background/line-width: 0.6;
    +      line-color: @admin-boundaries;
    +      line-width: 0.6;
    +      line-dasharray: 4,3;
    +      line-clip: false;
    +    }
    +    [zoom >= 7] {
    +      background/line-width: 1;
    +      line-width: 1;
    +    }
    +    [zoom >= 11] {
    +      background/line-width: 3;
    +      line-width: 3;
    +    }
    +  }
    +  /*
    +  The following code prevents admin boundaries from being rendered on top of
    +  each other. Comp-op works on the entire attachment, not on the individual
    +  border. Therefore, this code generates an attachment containing a set of
    +  @admin-boundaries/white dashed lines (of which only the top one is visible),
    +  and with `comp-op: darken` the white part is ignored, while the
    +  @admin-boundaries colored part is rendered (as long as the background is not
    +  darker than @admin-boundaries).
    +  The SQL has `ORDER BY admin_level`, so the boundary with the lowest
    +  admin_level is rendered on top, and therefore the only visible boundary.
    +  */
    +  opacity: 0.4;
    +  comp-op: darken;
    +}
    +
    +#admin-mid-zoom[zoom >= 11][zoom < 13],
    +#admin-high-zoom[zoom >= 13] {
    +  [admin_level = '5'][zoom >= 11] {
    +    background/line-color: white;
    +    background/line-width: 2;
    +    line-color: @admin-boundaries;
    +    line-width: 2;
    +    line-dasharray: 6,3,2,3,2,3;
    +    line-clip: false;
    +  }
    +  [admin_level = '6'][zoom >= 11] {
    +    background/line-color: white;
    +    background/line-width: 2;
    +    line-color: @admin-boundaries;
    +    line-width: 2;
    +    line-dasharray: 6,3,2,3;
    +    line-clip: false;
    +  }
    +  [admin_level = '7'],
    +  [admin_level = '8'] {
    +    [zoom >= 12] {
    +      background/line-color: white;
    +      background/line-width: 1.5;
    +      line-color: @admin-boundaries;
    +      line-width: 1.5;
    +      line-dasharray: 5,2;
    +      line-clip: false;
    +    }
    +  }
    +  opacity: 0.5;
    +  comp-op: darken;
    +}
    +
    +#admin-high-zoom[zoom >= 13] {
    +  [admin_level = '9'],
    +  [admin_level = '10'] {
    +    [zoom >= 13] {
    +      background/line-color: white;
    +      background/line-width: 2;
    +      line-color: @admin-boundaries;
    +      line-width: 2;
    +      line-dasharray: 2,3;
    +      line-clip: false;
    +    }
    +  }
    +  opacity: 0.5;
    +  comp-op: darken;
    +}
    +
    +
    +
    +#nature-reserve-boundaries {
    +  [way_pixels > 100][zoom >= 7] {
    +    [zoom < 10] {
    +      ::fill {
    +        opacity: 0.05;
    +        polygon-fill: green;
    +      }
    +    }
    +    a/line-width: 1;
    +    a/line-offset: -0.5;
    +    a/line-color: green;
    +    a/line-opacity: 0.15;
    +    a/line-join: round;
    +    a/line-cap: round;
    +    b/line-width: 2;
    +    b/line-offset: -1;
    +    b/line-color: green;
    +    b/line-opacity: 0.15;
    +    b/line-join: round;
    +    b/line-cap: round;
    +    [zoom >= 10] {
    +      a/line-width: 2;
    +      a/line-offset: -1;
    +      b/line-width: 4;
    +      b/line-offset: -2;
    +    }
    +    [zoom >= 14] {
    +      b/line-width: 6;
    +      b/line-offset: -3;
    +    }
    +  }
    +}
    +
    +#building-text {
    +[zoom >= 14][way_pixels > 3000],
    +[zoom >= 17] {
    +text-name: "[name]";
    +text-size: 11;
    +text-fill: #444;
    +text-face-name: @book-fonts;
    +text-halo-radius: 1;
    +text-wrap-width: 20;
    +text-halo-fill: rgba(255,255,255,0.5);
    +text-placement: interior;
    +}
    +}
    +
    +@marina-text: #576ddf; // also swimming_pool
    +@landcover-face-name: @oblique-fonts;
    +@standard-wrap-width: 30;
    +
    +.points {
    +  [feature = 'tourism_alpine_hut'][zoom >= 13] {
    +    point-file: url('symbols/alpinehut.p.16.png');
    +    point-placement: interior;
    +  }
    +  }
    +
    +  [feature = 'highway_bus_stop'] {
    +    [zoom >= 16] {
    +      marker-file: url('symbols/square.svg');
    +      marker-fill: @transportation-icon;
    +      marker-placement: interior;
    +      marker-width: 6;
    +    }
    +    [zoom >= 17] {
    +      marker-file: url('symbols/bus_stop.p.12.png');
    +      marker-width: 12;
    +    }
    +  }
    +
    +[feature = 'highway_primary'] {
    +[zoom >= 7][zoom < 12] {
    +line-width: 0.5;
    +line-color: @primary-fill;
    +[zoom >= 9] { line-width: 1.2; }
    +[zoom >= 10] { line-width: 2; }
    +[zoom >= 11] { line-width: .5; }
    +}
    +}
    +
    diff --git a/autotests/html/test.py.html b/autotests/html/test.py.html new file mode 100644 index 0000000..ad953cd --- /dev/null +++ b/autotests/html/test.py.html @@ -0,0 +1,35 @@ + + + +test.py + +
    +# comment with ALERT
    +
    +''' multiline
    +    comment
    +    ###
    +    '''
    +
    +def func(x):
    +    """ API docs """
    +    if x == 42:
    +        func()
    +        c1 = {}
    +        c2 = {
    +            2.4,
    +            0x42
    +            }
    +        a1 = []
    +        a2 = [
    +            "a", 032, (
    +                )]
    +    else:
    +        print("""multi
    +            line
    +            string""")
    +        print("single \
    +                continued line ")
    +        print('single line')
    +    return float(len(a2))
    +
    diff --git a/autotests/html/test.qml.html b/autotests/html/test.qml.html new file mode 100644 index 0000000..39cc95d --- /dev/null +++ b/autotests/html/test.qml.html @@ -0,0 +1,30 @@ + + + +test.qml + +
    +/*
    + * multi line comment
    + */
    +
    +// single line comment
    +
    +import QtQuick 2.0
    +
    +Rectangle {
    +    property real myNumProp: 0.1e12;
    +    property alias sub.color;
    +    signal mySignal(int arg1, string arg2)
    +    color: "lightsteelblue"
    +    width: 320
    +    height: width/2
    +
    +    Rectangle {
    +        id: sub
    +        width: 0x10
    +        height: 007
    +        objectName: 'single quote'
    +    }
    +}
    +
    diff --git a/autotests/html/test.sql.html b/autotests/html/test.sql.html new file mode 100644 index 0000000..8d9f050 --- /dev/null +++ b/autotests/html/test.sql.html @@ -0,0 +1,13 @@ + + + +test.sql + +
    +-- comment
    +
    +CREATE TABLE stuff COLUMNS(col1 INT, col2 Varchar);
    +SELECT * FROM stuff WHERE id = 'string';
    +select * from stuff where id < 0.42;
    +Select col1, col2 From stuff Where stuff.col1 IS NOT NuLL;
    +
    diff --git a/autotests/html/test.tex.html b/autotests/html/test.tex.html new file mode 100644 index 0000000..e3ab47c --- /dev/null +++ b/autotests/html/test.tex.html @@ -0,0 +1,12 @@ + + + +test.tex + +
    +% commet
    +
    +text \texttt{more text}
    +
    +\verb!verbatim text! normal text
    +
    diff --git a/autotests/html/test_syntax.sql.html b/autotests/html/test_syntax.sql.html new file mode 100644 index 0000000..eee648a --- /dev/null +++ b/autotests/html/test_syntax.sql.html @@ -0,0 +1,48 @@ + + + +test_syntax.sql + +
    +-- kate: hl SQL (Oracle)
    +-- test case shipped with highlighting in bugzilla, LGPL
    +
    +begin
    +	q'{adfasdf'sadfasdf j}'{' hkjhkhkjhkjh khlkhklj'fghdfghdfgh'hkjh'jkhkh'a'
    +	Q'(asldflahsl;'dkjfhklsdfh)'
    +	q'[asdasd;'asdasd'a]sd'asd'asasd]';11111111[1']; asdasdasdasd'errrrrrrrrrrrrrr-p
    +
    +	q'agdfgsdfgfhfghjfgh'f'f'sdfg'sdfg'dfg#a' dafdfadasfasdf;
    +
    +	Q'#gdfgsdfgsdfgsdfgsdfg#' afgasasdfasdfasfasdfasdfasdfasdfsdf
    +
    +	if sldfjsdj then
    +		case
    +			when 1=1 then
    +				aslfjsldkfj;
    +			when 2=2 then
    +				asdfg;
    +			else
    +				null;
    +		end case;
    +		
    +		if sdfjh then
    +			for i in 1 .. 2
    +			LOOP
    +				dbms_output.put_line(q';ololo;');
    +			END Loop;
    +			
    +			while true
    +			loop
    +				dbms_output.put_line('1111');
    +			end loop;
    +		end if;
    +		ksjfklasjd;
    +		fklj;
    +	elsif
    +		sdklfjsdklfj;
    +	else
    +		sdfdfsdf;
    +	end if;
    +end;
    +
    diff --git a/autotests/htmlhighlighter_test.cpp b/autotests/htmlhighlighter_test.cpp new file mode 100644 index 0000000..34dc769 --- /dev/null +++ b/autotests/htmlhighlighter_test.cpp @@ -0,0 +1,116 @@ +/* + Copyright (C) 2016 Volker Krause + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "test-config.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace KSyntaxHighlighting; + +class HTMLHighlighterTest : public QObject +{ + Q_OBJECT +public: + explicit HTMLHighlighterTest(QObject *parent = Q_NULLPTR) : QObject(parent), m_repo(Q_NULLPTR) {} + +private: + Repository *m_repo; + +private Q_SLOTS: + void initTestCase() + { + QStandardPaths::enableTestMode(true); + m_repo = new Repository; + } + + void cleanupTestCase() + { + delete m_repo; + m_repo = Q_NULLPTR; + } + + void testHighlight_data() + { + QTest::addColumn("inFile"); + QTest::addColumn("outFile"); + QTest::addColumn("refFile"); + QTest::addColumn("syntax"); + + QDirIterator it(QStringLiteral(TESTSRCDIR "/input"), QDir::Files | QDir::NoSymLinks | QDir::Readable); + while (it.hasNext()) { + const auto inFile = it.next(); + if (inFile.endsWith(QLatin1String(".syntax"))) + continue; + + QString syntax; + QFile syntaxOverride(inFile + QStringLiteral(".syntax")); + if (syntaxOverride.exists() && syntaxOverride.open(QFile::ReadOnly)) + syntax = QString::fromUtf8(syntaxOverride.readAll()).trimmed(); + + + QTest::newRow(it.fileName().toUtf8().constData()) << inFile + << (QStringLiteral(TESTBUILDDIR "/html.output/") + it.fileName() + QStringLiteral(".html")) + << (QStringLiteral(TESTSRCDIR "/html/") + it.fileName() + QStringLiteral(".html")) + << syntax; + } + + QDir().mkpath(QStringLiteral(TESTBUILDDIR "/html.output/")); + } + + void testHighlight() + { + QFETCH(QString, inFile); + QFETCH(QString, outFile); + QFETCH(QString, refFile); + QFETCH(QString, syntax); + QVERIFY(m_repo); + + HtmlHighlighter highlighter; + highlighter.setTheme(m_repo->defaultTheme()); + QVERIFY(highlighter.theme().isValid()); + + auto def = m_repo->definitionForFileName(inFile); + if (!syntax.isEmpty()) + def = m_repo->definitionForName(syntax); + QVERIFY(def.isValid()); + highlighter.setDefinition(def); + highlighter.setOutputFile(outFile); + highlighter.highlightFile(inFile); + + auto args = QStringList() << QStringLiteral("-u") << refFile << outFile; + QProcess proc; + proc.setProcessChannelMode(QProcess::ForwardedChannels); + proc.start(QStringLiteral("diff"), args); + QVERIFY(proc.waitForFinished()); + QCOMPARE(proc.exitCode(), 0); + } + +}; + +QTEST_GUILESS_MAIN(HTMLHighlighterTest) + +#include "htmlhighlighter_test.moc" + diff --git a/autotests/input/Dockerfile b/autotests/input/Dockerfile new file mode 100644 index 0000000..95a81d3 --- /dev/null +++ b/autotests/input/Dockerfile @@ -0,0 +1,19 @@ +# LGPLv2+ example file + +# This is a comment +FROM ubuntu:14.04 +MAINTAINER James Turnbull # comment +ENV REFRESHED_AT 2014-06-01 + +RUN apt-get -yqq update +RUN apt-get install -yqq software-properties-common python-software-properties +RUN add-apt-repository ppa:chris-lea/redis-server +RUN apt-get -yqq update +RUN apt-get -yqq install redis-server redis-tools +RUN apt-get -yqq update # comment + +VOLUME [ "/var/lib/redis", "/var/log/redis/" ] + +EXPOSE 6379 + +CMD [] diff --git a/autotests/input/Kconfig b/autotests/input/Kconfig new file mode 100644 index 0000000..5ebfaf4 --- /dev/null +++ b/autotests/input/Kconfig @@ -0,0 +1,15 @@ +This is wrong but should not crash ] ) } ! + +# comment + +config BR2_PACKAGE_GAMMARAY + bool "gammaray" + depends on BR2_PACKAGE_QT5 + help + GammaRay Qt introspection probe. + second line of help, with correct indentation + third line underindented and thus wrong + default 'true' + +menu myMenu +endmenu diff --git a/autotests/input/Makefile b/autotests/input/Makefile new file mode 100644 index 0000000..1aae297 --- /dev/null +++ b/autotests/input/Makefile @@ -0,0 +1,25 @@ +# comment + +include Makefile.in + +.PHONY: all + +all: target + +foo = bar $(var) \ + $(baz) quux + +ifeq ($(CC),gcc) + bla=$(call func,param1,param2) +else + libs=$(normal_libs) +endif + +target1: + error + +target2: bla.cpp $@ + $(CC) bla.c -o bla.o + $(CC) bla.o $< \ + -o bla.exe + @echo "hello" diff --git a/autotests/input/basic.markdown b/autotests/input/basic.markdown new file mode 100644 index 0000000..f9a5bb3 --- /dev/null +++ b/autotests/input/basic.markdown @@ -0,0 +1,6 @@ +normal + +* item1 +still part of item + +normal text again diff --git a/autotests/input/basic.xml b/autotests/input/basic.xml new file mode 100644 index 0000000..20feae1 --- /dev/null +++ b/autotests/input/basic.xml @@ -0,0 +1,4 @@ + + + + diff --git a/autotests/input/complex.xml b/autotests/input/complex.xml new file mode 100644 index 0000000..d738998 --- /dev/null +++ b/autotests/input/complex.xml @@ -0,0 +1,13 @@ + + + + +]> + + + + +> diff --git a/autotests/input/cube.obj b/autotests/input/cube.obj new file mode 100644 index 0000000..ef06c98 --- /dev/null +++ b/autotests/input/cube.obj @@ -0,0 +1,33 @@ +# cube.obj +# + +g cube + +v 0.0 0.0 0.0 +v 0.0 0.0 1.0 +v 0.0 1.0 0.0 +v 0.0 1.0 1.0 +v 1.0 0.0 0.0 +v 1.0 0.0 1.0 +v 1.0 1.0 0.0 +v 1.0 1.0 1.0 + +vn 0.0 0.0 1.0 +vn 0.0 0.0 -1.0 +vn 0.0 1.0 0.0 +vn 0.0 -1.0 0.0 +vn 1.0 0.0 0.0 +vn -1.0 0.0 0.0 + +f 1//2 7//2 5//2 +f 1//2 3//2 7//2 +f 1//6 4//6 3//6 +f 1//6 2//6 4//6 +f 3//3 8//3 7//3 +f 3//3 4//3 8//3 +f 5//5 7//5 8//5 +f 5//5 8//5 6//5 +f 1//4 5//4 6//4 +f 1//4 6//4 2//4 +f 2//1 6//1 8//1 +f 2//1 8//1 4//1 diff --git a/autotests/input/cube.ply b/autotests/input/cube.ply new file mode 100644 index 0000000..08d5f89 --- /dev/null +++ b/autotests/input/cube.ply @@ -0,0 +1,26 @@ +error before header + +ply +format ascii 1.0 +comment TODO this is a comment +element vertex 8 +property float x +property float y +property float z +element face 6 +property list uint int vertex_indices +end_header +-1 -1 -1 +1 -1 -1 +1 1 -1 +-1 1 -1 +-1 -1 1 +1 -1 1 +1 1 1 +-1 1 1 +4 0 1 2 3 +4 5 4 7 6 +4 6 2 1 5 +4 3 7 4 0 +4 7 3 2 6 +4 5 1 0 4 diff --git a/autotests/input/cube.stl b/autotests/input/cube.stl new file mode 100644 index 0000000..ae74fd9 --- /dev/null +++ b/autotests/input/cube.stl @@ -0,0 +1,30 @@ +solid cube_corner + facet normal 0.0 -1.0 0.0 + outer loop + vertex 0.0 0.0 0.0 + vertex 1.0 0.0 0.0 + vertex 0.0 0.0 1.0 + endloop + endfacet + facet normal 0.0 0.0 -1.0 + outer loop + vertex 0.0 0.0 0.0 + vertex 0.0 1.0 0.0 + vertex 1.0 0.0 0.0 + endloop + endfacet + facet normal -1.0 0.0 0.0 + outer loop + vertex 0.0 0.0 0.0 + vertex 0.0 0.0 1.0 + vertex 0.0 1.0 0.0 + endloop + endfacet + facet normal 0.577 0.577 0.577 + outer loop + vertex 1.0 0.0 0.0 + vertex 0.0 1.0 0.0 + vertex 0.0 0.0 1.0 + endloop + endfacet +endsolid diff --git a/autotests/input/example.rmd b/autotests/input/example.rmd new file mode 100644 index 0000000..ef9a33e --- /dev/null +++ b/autotests/input/example.rmd @@ -0,0 +1,39 @@ +--- +title: "test" +author: "me" +date: "07.10.2014" +output: html_document +--- + +This is a simple test document. It shows syntax highlighting switches between YAML (above), R blocks +```{r, echo=FALSE} +for (i in 1:10) { + if(i>=10) print(i) +} +# two blank lines below + +sessionInfo() +``` + +LaTeX equations, +$$ +h_{i}(t \mid q,C) = h_{0}(t) e^{\beta_{1}quality_{i} + \beta_{2}C_{iq}} +$$ + +and Markdown. A [link](http://example.com) in Markdown. + +Inline `r y <- 5 + x - sin(3)` R code. +Inline `y <- 5 + x - sin(3)` code. + + + Heading + ======= + + Sub-heading + ----------- + A list of editors: + * kate + * vim + * emacs + +*italic*, **bold**, `monospace` diff --git a/autotests/input/firstNonSpace.c b/autotests/input/firstNonSpace.c new file mode 100644 index 0000000..570ba90 --- /dev/null +++ b/autotests/input/firstNonSpace.c @@ -0,0 +1,7 @@ +#define 1 + #define 2 + #define 3 + #define 4 + #define 5 + #define tab + diff --git a/autotests/input/folding.cpp b/autotests/input/folding.cpp new file mode 100644 index 0000000..9e26b3f --- /dev/null +++ b/autotests/input/folding.cpp @@ -0,0 +1,15 @@ +/** + * multi-line comment + */ + +/* comment */ +{ { } { +//BEGIN +} +//END +} + +#if 0 +#elif 1 +#else +#endif diff --git a/autotests/input/git-rebase b/autotests/input/git-rebase new file mode 100644 index 0000000..43041bb --- /dev/null +++ b/autotests/input/git-rebase @@ -0,0 +1,32 @@ +pick 318aceb Add test for Makefile highlighting +p 4c7182a Add first batch of test files resurrected from Kate 4.6 +r 6f7d8a7 Sync xml files with KTextEditor +reword 8f0dbdc Add another batch of resurrected tests from Kate 4.6 +e 828de45 Add some more resurrected tests from Kate 4.6 +edit 6aa6264 Add simple coverage information for syntax definition tests +s 63df253 Add more syntax highlighting tests from Kate 4.6 +squash 3e7771f Add three more tests recovered from Kate 4.6 +f 5c7fd91 Add Kate 4.6 ASP syntax test +fixup 7a777ff Implement case-sensitive overrides for keyword rules +exec 2b16665 Implement dynamic DetectChar rules +drop dd808dc Quote captured strings we replace in regular expressions +x 0b703a3 Add a few more tests from the Kate 4.6 test suite + +# Rebase a27a854..0b703a3 onto a27a854 (13 command(s)) +# +# Commands: +# p, pick = use commit +# r, reword = use commit, but edit the commit message +# e, edit = use commit, but stop for amending +# s, squash = use commit, but meld into previous commit +# f, fixup = like "squash", but discard this commit's log message +# x, exec = run command (the rest of the line) using shell +# d, drop = remove commit +# +# These lines can be re-ordered; they are executed from top to bottom. +# +# If you remove a line here THAT COMMIT WILL BE LOST. +# +# However, if you remove everything, the rebase will be aborted. +# +# Note that empty commits are commented out diff --git a/autotests/input/git-rebase.syntax b/autotests/input/git-rebase.syntax new file mode 100644 index 0000000..abf0034 --- /dev/null +++ b/autotests/input/git-rebase.syntax @@ -0,0 +1 @@ +Git Rebase diff --git a/autotests/input/hello.exs b/autotests/input/hello.exs new file mode 100644 index 0000000..cca72a1 --- /dev/null +++ b/autotests/input/hello.exs @@ -0,0 +1,11 @@ +parent = self() + +# Spawns an Elixir process (not an operating system one!) +spawn_link(fn -> + send parent, {:msg, "hello world"} +end) + +# Block until the message is received +receive do + {:msg, contents} -> IO.puts contents +end diff --git a/autotests/input/highlight.ahdl b/autotests/input/highlight.ahdl new file mode 100644 index 0000000..e059aa8 --- /dev/null +++ b/autotests/input/highlight.ahdl @@ -0,0 +1,43 @@ +-- Test file for kate's syntax highlighting +Title "Test file"; + +-- BEGIN region (a region marker region) :) + +% multiline comment +goes on here % + +-- END + +FUNCTION FCT (Clk, Key) RETURNS (pulse); + +SUBDESIGN CDCLOCK2 +( +in : INPUT; -- go in +out[3..0] : OUTPUT; -- come out +) + +VARIABLE +start : soft; +usec[3..0] : node; + +BEGIN + +in = FCT(clock, some_key); -- senseless code + +-- comment +blubb = (blobb[] == H"3ff"); + +IF in THEN asdf +-- folde me +END IF; + +TABLE +-- missing code +END TABLE + + +END; + +-- hex, octal, binary +H"0" => B"1000000"; +O"01234567"; \ No newline at end of file diff --git a/autotests/input/highlight.asm-avr b/autotests/input/highlight.asm-avr new file mode 100644 index 0000000..f1e0542 --- /dev/null +++ b/autotests/input/highlight.asm-avr @@ -0,0 +1,75 @@ +;******************************************************************** +;* LED flasher: LED will flash with a X on/off ratio at PD6 +;* +;* NOTE: delay depends in the value of X, 1 is fast, 255 is slow +;* +;* No copyright ©1998 RES® * FREEWARE * +;* +;* NOTE: Connect a low current LED with a 1k resistor in serie from +;* Vdd to pin 11 of the MCU. (Or a normal LED with a 330ohm) +;* +;* RES® can be reached by email: digitalaudio@mail.com +;* or visit the website: http://home.wanadoo.nl/electro1/avr +;* +;* Version :1.0 +;* Date :12/26/98 +;* Author :Rob's ElectroSoft® +;* Target MCU :AT90S1200-12PI@4MHz +;******************************************************************** + +.include "1200def.inc" + + rjmp RESET ;reset handle + + +;* Long delay + +;* Register variables + + .def T1 = r1 + .def T2 = r2 + .def temp = r19 + +;* Code + +longDelay: + clr T1 ;T1 used as delay 2nd count + clr T2 ;T2 used as delay 3d count +delay_1: + dec T2 + brne delay_1 + dec T1 + brne delay_1 + dec temp ;temp must be preset as + brne delay_1 ; delay master count + ret + + +;* Resets the data direction register D + +;* Defines + + .equ led = 6 ;LED at PD6 + +;* Code + +RESET: + sbi DDRD, led ;connect LED to PORTD pin 6 + + +;* Main program + +;* This part will let the LED go on and off by X + +;* Register variables + + .equ X = 10 ;enter delaytime X + +flash: + sbi PORTD, led ;LED on + ldi temp, X ;X sec delay + rcall longDelay + cbi PORTD, led ;LED off + ldi temp, X ;X sec delay + rcall longDelay + rjmp flash ;another run \ No newline at end of file diff --git a/autotests/input/highlight.asm-nasm b/autotests/input/highlight.asm-nasm new file mode 100644 index 0000000..a5da4d1 --- /dev/null +++ b/autotests/input/highlight.asm-nasm @@ -0,0 +1,27 @@ +; Example file for nasm.xml kate syntax file +; compile with `nasm example.asm -f elf -o example.o` +; and link with 'gcc example.o -o example` +; Public domain +; kate: hl Intel x86 (NASM); + +section .data + +hello dd 'Hello World', 0x0A, 0h +printf_param dd '%s', 0q + +section .text + +extern printf + +global main +main: + push ebp + mov ebp, esp + + push hello + push printf_param + call printf + + mov eax, 0b + leave + ret diff --git a/autotests/input/highlight.asm-nasm.syntax b/autotests/input/highlight.asm-nasm.syntax new file mode 100644 index 0000000..67140d2 --- /dev/null +++ b/autotests/input/highlight.asm-nasm.syntax @@ -0,0 +1 @@ +Intel x86 (NASM) diff --git a/autotests/input/highlight.asp b/autotests/input/highlight.asp new file mode 100644 index 0000000..07a8619 --- /dev/null +++ b/autotests/input/highlight.asp @@ -0,0 +1,58 @@ +<% 'kate: hl ASP; +if ( instr(request.servervariables("PATH_INFO"),"login.asp") <= 0 and instr(request.servervariables("PATH_INFO"),"inset") <= 0 and instr(request.servervariables("PATH_INFO"),"Data") <= 0 and instr(request.servervariables("PATH_INFO"),"dropDown") <= 0 ) then + Session("originalRequestedPage") = Request.ServerVariables("PATH_INFO") & "?" & Request.ServerVariables("QUERY_STRING") +end if + +function countRecords( rsToCount ) + numRecs = 0 + + do until rsToCount.eof + numRecs = numRecs + 1 + + rsToCount.movenext + loop + + rsToCount.close ' just to make sure nobody + ' tries to operate on the recordset, + ' which has already reached eof + + countRecords = numRecs +end function + +function unique( rs, sortColumn ) ' return unique instances of text in sortColumn within rs + dim sorted() + + redim sorted(1) + dim i + i = 0 + do until rs.eof + if (not find( rs(sortColumn), sorted )) then + redim preserve sorted(i+1) + sorted(i) = rs(sortColumn) + i = i + 1 + end if + rs.MoveNext + loop + + redim preserve sorted(i-1) ' the function will add an extra blank entry to the array + + rs.Close ' close the recordset - we'll be using it again - and reset i - well be using it again, too + + unique = sorted +end function + +sub testSub( variable ) ' do nothing impressive... + dim newVar + + newVar = variable + + if ( variable = true ) + response.end + else %> + +

    We are writing text.

    +

    <%=newVar%>

    +

    We have written text and outputted a variable.

    + +<% end if +end sub %> \ No newline at end of file diff --git a/autotests/input/highlight.awk b/autotests/input/highlight.awk new file mode 100644 index 0000000..47f10cf --- /dev/null +++ b/autotests/input/highlight.awk @@ -0,0 +1,28 @@ +#!/usr +# AWK hl test + +# BEGIN and END are also matched as patterns +BEGIN { + p = 0; +} + +/some pattern/ { + p++; +} + +# / inside brackets is not considered end of expression +# a loose division operator (/) is not mismatched as a pattern. +$1 =~ /[^abc/]def/ || b == 3 / 5 { + + gsub ( FILENAME ); + +} + +# TODO and FIXME also work in comments in Awk. + +# Also backslash in patterns works. +/\/usr\/bin\/awk/ { print "This is me"; } + +END { + print p; +} diff --git a/autotests/input/highlight.bib b/autotests/input/highlight.bib new file mode 100644 index 0000000..0ae404c --- /dev/null +++ b/autotests/input/highlight.bib @@ -0,0 +1,31 @@ +% test file for kate's bibtex syntax highlighting + +@Article{artikel, +author = {Me}, +title = {Something}, +journal = {JHEP}, +year = {2003}, +} + +@Book + +{ + +boek, +author = "Someone", +title = "Something", +journal = "Nucl. Phys. B", +year = "2003", +} + +This is ignored by BibTeX, no special highlighting +%This is not a comment, it is just ignored (thanks to the people in #latex) :) + +@string{test="lange string die ik niet vaak opnieuw wil intikken"} + +@PhdThesis{thesis, +author = {Me}, +title = {Dunno}, +school = {ITFA}, +year = {2005, hopefully}, +} diff --git a/autotests/input/highlight.cmake b/autotests/input/highlight.cmake new file mode 100644 index 0000000..02a6c8f --- /dev/null +++ b/autotests/input/highlight.cmake @@ -0,0 +1,49 @@ +#this CMakeLists.txt doesn't do anything useful, but it shoudl demonstrate the cmake syntax highlighting +#Alexander Neundorf + +#ok this is a comment +#and another line +#a built-in command, it's bold black +ADD_DEFINITIONS(-Wall -Wctor-dtor-privacy -Woverloaded-virtual -Wno-long-long -pipe -fno-builtin -fno-exceptions) + +#and another function +INCLUDE_DIRECTORIES( +#comments are also highlighted inside function parameters +#variables are Qt::blue +${CMAKE_CURRENT_SOURCE_DIR}/../../lib/qt4/include/Qt +) + +# BEGIN defining a macro +MACRO(ECOS_ADD_EXECUTABLE _exe_NAME ) + +#special parameters are italic, see the STATIC in the next line +ADD_LIBRARY(${_exe_NAME} STATIC ${ARGN}) +#but not in the following line ? + ADD_LIBRARY(${_exe_NAME} STATIC ${ARGN}) +# it seems the kate highlighting file could need some love, Alex + + +#another command with a bunch of variables and special parameters + ADD_CUSTOM_COMMAND( + TARGET ${_exe_NAME} + PRE_LINK + COMMAND ${CMAKE_C_COMPILER} + ARGS -o ${_exe_NAME} +$\(${_exe_NAME}_SRC_OBJS\) -nostdlib -nostartfiles -Lecos/install/lib -Ttarget.ld + ) + +#add the created files to the make_clean_files + SET(ECOS_ADD_MAKE_CLEAN_FILES ${ECOS_ADD_MAKE_CLEAN_FILES};${_exe_NAME};) +#and another command... + SET_DIRECTORY_PROPERTIES( + PROPERTIES + ADDITIONAL_MAKE_CLEAN_FILES "${ECOS_ADD_MAKE_CLEAN_FILES}" + ) +ENDMACRO(ECOS_ADD_EXECUTABLE) +# END of macro + +#calling a self-defined function, variables are also Qt::blue here +ECOS_ADD_EXECUTABLE(${PROJECT_NAME} ${the_sources} ${qt4_moc_SRCS}) + + + diff --git a/autotests/input/highlight.css b/autotests/input/highlight.css new file mode 100644 index 0000000..986c6c0 --- /dev/null +++ b/autotests/input/highlight.css @@ -0,0 +1,49 @@ +/** + * This is a pseudo CSS file to test Kate's CSS syntax highlighting. + */ + +@import url("othersheet.css") screen, tv; + +body { + font-size: 15pt; + font-family: Verdana, Helvetica, "Bitstream Vera Sans", sans-serif; + margin-top: 0px; /* yet another comment */ + margin-bottom: 0px; + // this is no comment, it's just broken! + margin-left: 0px; + margin-right: 0px; +} + +.something +{ + margin-right: 0px; + color: #cdd; + color: #AAFE04; + color: rgb(10%,30%,43%); + background: maroon; +} + +a:hover { +} + +#header, +p.intro:first-letter, +p:lang(nl), +img[align="right"] +{ + border: 1px solid Qt::red !important; + -moz-border-radius: 15px; /* unknown properties render italic */ +} + +@media print { + + #header + { + display: none; + } + +} + +/* +TODO: add more tests, e.g. media +*/ diff --git a/autotests/input/highlight.d b/autotests/input/highlight.d new file mode 100644 index 0000000..b3daaf6 --- /dev/null +++ b/autotests/input/highlight.d @@ -0,0 +1,195 @@ +/******** +* Highlight testing module. +* +* Do not attempt to run this! +***********/ +module highlighttest; +import X = null; + +/++ Pragma directives. DDoc + DDoc embedded items. Special Tokens. ++ ++ --- ++ // comment ++ #line 12 "hightlighttest.d" /* block comment */ ++ #line __LINE__ __FILE__ /++ embedded block comment +/ ++ ++ pragma /* */ (msg, "what?"); ++ pragma(/++ +/ lib, "insane.a"); ++ pragma(D_Custom_Extension, "custom data"); ++ --- ++/ + +/// version condition +version = X; +version (X) ; +version(linux) {} + +/// linkage +extern + (C) {} +extern : +; +extern (Windows) {} + +/// alias & typedef +alias int.min minint; +typedef int myint; + +int main(char[][] args) { + /// statements + if (1) {} + else {} + with (N) {x = B} + + /// attributes + auto x = 1; + static if (true) {} + void (in X, out Y) {} // NOTE: using in like this is rare, more common to use as an expression and no way to tell apart? + + /// deprecated + deprecated void fct (); + + /// types + void a; + ushort u; + int[uint] AA; + class C; + enum N : int { A = 5, B } + typeof(u) u2; + + /// expressions + x = cast(int) 55; + void* p = null; + p = cast(void*) new int; + x = 1 in AA; // NOTE: a THIRD use of in. How to detect?? + assert (true); + + /// libsymbols + string s = ""; + throw new Exception; + TypeInfo ti = typeid(int); + + /// tests + debug {} + debug (2) {} + debug (DSymb) {} + unittest {} + + /// scope (as attribute and as statement) + scope struct S; + scope (exit) {} + scope + (success) {} // NOTE: rules cannot match across new-lines + scope (failure) {} + + /// Properties + x = int.min; + s = (5-3).stringof; + + /// strings + s = r"raw string"; + s = x"00FF"; + s = \n \a; + s = \u1234; + s = \U12345678; + s = \& ; + char c = 'a'; + s = "abc 012 \" \n \x12 \u1234 \U12345678"; + s = `BQString '"`; + + /// region markers + //BEGIN x + //END x + + /// DDoc + /******* + * DDoc + * + * Section: + * New section. + * $(I italic) + *******/ + /+++++++ + + DDoc + + /+ + + +/ + +++++++/ + + // comments + // FIXME NOTE + /* comment */ + /+ comment /+ nested comment +/ +/ + + /// brace folding + { + } + + /** normal text + * --- + * .x; + * .. + * ... + * .... + * ..... + * _._ + * _e1 + * --- + */ + + /// float and int literals + int i; + real r; + ireal ir; + r = .0; + r = 0f; + ir = 0e0i; + ir = 0.fi; + r = 0.0e0; + r = 0xF.Fp0; + r = 0x_._p0_; + i = 5; + i = -1; + i = 0b10; + i = 0070; + i = 00; + i = 0xF0; + + /// ranges + int[] A; + i = A[1]; + A = A[0..$]; + A = A[0..0]; + A = A[0..length]; + + /// labels + label: + goto label; + + /// function, delegate + creal function () fp = function creal() { return 0f+0fi; }; + void delegate (in int i, lazy int b) dg = delegate void (int, int) {} + + /// in, out, body + // NOTE: highlighting in & out as statements here could be difficult + float F () + in {} + out (result) {} + body {} + + /// try, catch, finally + try { + throw new Exception("oh no... "); + } catch (Exception e) { + } finally { + } + + /// mixin + mixin("return false;").stringof; + + /// templates + macro; // what does this do? + template Tp (T) { + Tp t; + } + Tp!(int) y; +} diff --git a/autotests/input/highlight.do b/autotests/input/highlight.do new file mode 100644 index 0000000..0b90b16 --- /dev/null +++ b/autotests/input/highlight.do @@ -0,0 +1,89 @@ +/* Test file for kate's stata syntax highlighting +*/ +*! version 1.2.0 2mar2003 E. Leuven +program define spellsplit + version 7 + syntax [anything], spell(varlist min=2 max=2) [ by(varlist)] + tokenize `spell' + local date0 `1' + local date1 `2' + local f0 : format `date0' + local f1 : format `date1' + + /* set default statistic */ + local current "mean" + + gettoken left anything : anything, match(prns) + while "`left'"!="" { + if "`prns'"!="" { + if !inlist("`left'","mean","sum") { + di as error "Statistic `left' not supported" + exit 198 + } + local current "`left'" + } + else { + local `current'vars ``current'vars' `left' + } + gettoken left anything : anything, match(prns) + } + if ("`meanvars'"!="") { + confirm var `meanvars' + unab meanvars : `meanvars' + } + if ("`sumvars'"!="") { + confirm var `sumvars' + unab sumvars : `sumvars' + } + + quietly { + g _count = 1 + local xvars `meanvars' `sumvars' _count + + /* create dummy by-var if no by option is specified */ + if "`by'"=="" { + tempvar by + g byte `by' = 1 + } + tempvar `xvars' `by' + + /* create negative for subtraction when spell ends */ + cap foreach v of varlist `xvars' { + g double ``v'' = -`v' + local txvars `txvars' ``v'' + } + cap foreach v of varlist `by' { + g double ``v'' = `v' + local txvars `txvars' ``v'' + } + + stack `date0' `xvars' `by' `date1' `txvars', into(`date0' `xvars' `by') clear + + /* calculate totals per date */ + cap foreach v of varlist `xvars' { + egen double ``v'' = sum(`v'), by(`by' `date0') + } + + /* unique dates only */ + by `by' `date0', sort: keep if _n==1 + + /* calculate totals (+ when spell starts - when ends) */ + sort `by' + cap foreach v of varlist `xvars' { + by `by': replace `v' = sum(``v'') + } + by `by': g `date1' = `date0'[_n + 1] + + drop if `date0'>`date1' + drop _stack + drop if _count==0 + order `by' `date0' `date1' `xvars' + format `date0' `f0' + format `date1' `f1' + + cap for var `meanvars': replace X = X/_count + + compress + } + +end \ No newline at end of file diff --git a/autotests/input/highlight.dox b/autotests/input/highlight.dox new file mode 100644 index 0000000..39b404f --- /dev/null +++ b/autotests/input/highlight.dox @@ -0,0 +1,227 @@ +This is a pseudo doxygen file to test Kate's doxyge syntax highlighting. + +Normal text, no HL. +=================== +a multiline comment may begin with a /*! */, too. That should work, +because it is the same "entrance rule". + +popping tests: +/** multiline */ end of doxygen HL mode +/*! multiline */ end of doxygen HL mode +//! singleline, where */ should be ignored! still doxygen HL mode +/// singleline, where */ should be ignored! still doxygen HL mode +///< singleline, where */ should be ignored! still doxygen HL mode +begin and end immediately: +/********/ actually no doxygen comment - used for "info boxes" :) +/**/ <-- it really works --- end of doxygen HL mode +/*!*/ end of doxygen HL mode + + +/** \code rest of line is normal comment HL */ end of doxygen HL mode +/** \code rest of line is normal comment HL + * comment HL mode + */ end of doxygen HL mode + + +/** \file aword rest of line is normal comment HL */ end of doxygen HL mode +/** \file */aword <-- pop! no doxygen HL mode +/** \file aword rest of line is normal comment HL + * comment HL mode + */ end of doxygen HL mode + + +/** \brief A short description */ end of doxygen HL mode +/** \brief */A <-- pop! end of doxygen HL mode +/** \brief A short description + * comment HL mode + */ end of doxygen HL mode + + +/** \page aword rest of line is string */ end of doxygen HL mode +/** \page */aword <-- pop! end of doxygen HL mode +/** \page aword rest of line is string + * comment HL mode + */ end of doxygen HL mode + + +/** \image aword aword rest of line is normal HL */ end of doxygen HL mode +/** \image aword */aword <-- pop! end of doxygen HL mode +/** \image */aword aword <-- pop! end of doxygen HL mode +/** \image aword aword rest of line is normal HL + * comment HL mode + */ end of doxygen HL mode + +Tests for HTML tags in doxygen HL mode: +======================================= +/** */ end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** */ end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** end of doxygen HL mode +/** <*/a href="blubb"> end of doxygen HL mode + +//! */ stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! */ stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! stay in doygen HL mode +//! <*/a href="blubb"> stay in doygen HL mode +//! stay in doygen HL +/** \code rest of line is normal comment HL */ end of doxygen HL mode +/** \code rest of end of doxygen HL mode +/** \code rest of end of doxygen HL mode +/** \code rest of end of doxygen HL mode +/** \code rest of end of doxygen HL mode +/** \code rest of end of doxygen HL mode +/** \code rest of end of doxygen HL mode +/** \code rest of end of doxygen HL mode +/** \code rest <*/a href="blubb"> of end of doxygen HL mode +/** \code rest of line is normal comment HL + * comment HL mode text + */ end of doxygen HL mode + + +/** \file aword rest of line is normal comment HL */ end of doxygen HL mode +/** \file awo*/rd end of doxygen HL mode +/** \file aword end of doxygen HL mode +/** \file awo<*/html_should_be_ignored_here>rd end of doxygen HL mode +/** \file a*/word end of doxygen HL mode +/** \file aword rest of line is normal comment HL + * comment HL mode + */ end of doxygen HL mode + + +/** \brief A short of description */ end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short of <*//a href='blubb'> end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short of end of doxygen HL mode +/** \brief A short of description + * comment HL mode + */ end of doxygen HL mode + + +/** \page aword A short of description */ end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short of <*//a href='blubb'> end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short of end of doxygen HL mode +/** \page aword A short <*/a href="blubb"> of end of doxygen HL mode +/** \page aword A shor*/t of end of doxygen HL mode +/** \page awor*/d A short of end of doxygen HL mode +/** \page */aword A short of end of doxygen HL mode +/** \page aword A short of description + * comment HL mode + */ end of doxygen HL mode + + +/** \image aword aword rest of line is normal HL */ end of doxygen HL mode +/** \image aword aword rest of line is*/ end of doxygen HL mode +/** \image aword aword*/ end of doxygen HL mode +/** \image aword aw*/ord end of doxygen HL mode +/** \image aword */aword end of doxygen HL mode +/** \image aword*/ end of doxygen HL mode +/** \image awo*/rd end of doxygen HL mode +/** \image */aword end of doxygen HL mode +/** \ima*/ge end of doxygen HL mode +/** \image aword aword rest of line is normal HL + * comment HL mode + */ end of doxygen HL mode + +Some further tests for singlelinecomments (* / should not pop!) +=============================================================== +/// a singlelinecommment blubb blubb */. stay in doxygen HL mode +/// \code a singlelinecommment blubb b*/lubb. stay in doxygen HL mode +/// \code*/ a singlelinecommment blubb blubb. stay in doxygen HL mode +/// \code a singlelinecommment blubb blubb +/// \brief a descriptive text (string) stay in doxygen HL mode +/// \brief a descriptive text (string)*/ description should go on here +/// \brief a descriptive text */(string) description should go on here +/// \brief */a descriptive text (string) description should go on here +/// \ref aword a descriptive text (string) */ description should go on here +/// \ref aword a descriptive text (str*/ing) description should go on here +/// \ref aword a des*/criptive text (string) description should go on here +/// \ref aword*/ a descriptive text (string) description should go on here +/// \ref aw*/ord a descriptive text (string) description should go on here +/// \ref */aword a descriptive text (string) description should go on here + +HTML comment tests: +=================== +//! \ref word descriptive text (string) +normal HL mode. +//! \ref w descriptive text (string) +/** \ref word descriptive text (string) +normal HL mode. +/** \ref w + * normal doxygen HL mode. + */ + + +And final tests for a word: a single char: +=========================================== + +//! \ref word descriptive text (string) +//! \ref w descriptive text (string) + + +//! \image word1 word2 b descriptive text (string) +//! \image a word b descriptive text (string) + + +//! \brief A b c d e description should go on here + + +//! \file word rest of line is normal comment HL +//! \file a word rest of line is normal comment HL + +no doxygen HL mode here. +== END OF TESTFILE == \ No newline at end of file diff --git a/autotests/input/highlight.erl b/autotests/input/highlight.erl new file mode 100644 index 0000000..5b485cb --- /dev/null +++ b/autotests/input/highlight.erl @@ -0,0 +1,68 @@ +% testing for the erlang syntax highlighter +% NOTE alerts work in comments to TODO ! + +% pragmas (show as keywords) +-module +-export +-define +-undef +-ifdef +-ifndef +-else +-endif +-include +-include_lib + +% key words +after begin case catch cond end fun if let of query receive all_true some_true + +% operators +div rem or xor bor bxor bsl bsr and band not bnot ++ - * / == /= =:= =/= < =< > >= ++ -- = ! <- + +% separators (show as functions) +( ) { } [ ] . : | || ; , ? -> # + +% functions - predefined (part of erlang module) - show as functions +abs accept alarm apply atom_to_list binary_to_list binary_to_term check_process_code +concat_binary date delete_module disconnect_node element erase exit float float_to_list +garbage_collect get get_keys group_leader halt hd integer_to_list is_alive is_atom is_binary +is_boolean is_float is_function is_integer is_list is_number is_pid is_port is_process_alive +is_record is_reference is_tuple length link list_to_atom list_to_binary list_to_float list_to_integer +list_to_pid list_to_tuple load_module loaded localtime make_ref module_loaded node nodes now +open_port pid_to_list port_close port_command port_connect port_control ports pre_loaded process_flag +process_info processes purge_module put register registered round self setelement size +spawn spawn_link spawn_opt split_binary statistics term_to_binary throw time tl trunc tuple_to_list +unlink unregister whereis + +% functions - inferred +module:function +function() + +% atoms (show as "char") +% begin with underscore, lowercase, contain numbers letters and @ - or anything between '' +middle_underscore +abc ab4d a@cd8 a@ +'And this is (\012) an atom \' Atoo' Variable 'atom again' + +% variables (begin with capital letter or underscore, contain numbers, letters and @) +_leadingUnderscore AbdD@ B45@c + +% this is a string +"a string sits between \" double quotes" atom "more string" + +% integers (decimal) +1. 234 $A + +% integers (specified base) +2#10101 34#567 + +% float +12.23 12.9e-67 12.8E+89 33.34e89 + +% and finally some real code, so we can see what it looks like... +-module(codetest). % everything is in a module +-export([fac/1]). % name and number of arguments - need this to be called outside of the module + +fac(N) when N > 0 -> N * fac(N-1); +fac(N) when N == 0 -> 1. diff --git a/autotests/input/highlight.exu b/autotests/input/highlight.exu new file mode 100644 index 0000000..3651adf --- /dev/null +++ b/autotests/input/highlight.exu @@ -0,0 +1,97 @@ +-- Test file for Kate's Euphoria syntax highlighting/code folding. +-- BEGIN region marker test + +-- code here + +-- END region marker test + +-- The N Queens Problem: +-- Place N Queens on an NxN chess board +-- such that they don't threaten each other. +constant N = 8 -- try some other sizes +constant ROW = 1, COLUMN = 2 +constant TRUE = 1, FALSE = 0 +type square(sequence x) +-- a square on the board + return length(x) = 2 +end type +type row(integer x) +-- a row on the board + return x >= 1 and x <= N +end type + +function threat(square q1, square q2) +-- do two queens threaten each other? + if q1[COLUMN] = q2[COLUMN] then + return TRUE + elsif q1[ROW] - q1[COLUMN] = q2[ROW] - q2[COLUMN] then + return TRUE + elsif q1[ROW] + q1[COLUMN] = q2[ROW] + q2[COLUMN] then + return TRUE + elsif q1[ROW] = q2[ROW] then + return TRUE + else + return FALSE + end if +end function + +function conflict(square q, sequence queens) +-- Would square p cause a conflict with other queens on board so far? + for i = 1 to length(queens) do + if threat(q, queens[i]) then + return TRUE + end if + end for + return FALSE +end function + +integer soln +soln = 0 -- solution number + +procedure print_board(sequence queens) +-- print a solution, showing the Queens on the board + integer k + position(1, 1) + printf(1, "Solution #%d\n\n ", soln) + for c = 'a' to 'a' + N - 1 do + printf(1, "%2s", c) + end for + puts(1, "\n") + for r = 1 to N do + printf(1, "%2d ", r) + for c = 1 to N do + if find({r,c}, queens) then + puts(1, "Q ") + else + puts(1, ". ") + end if + end for + puts(1, "\n") + end for + puts(1, "\nPress Enter. (q to quit) ") + while TRUE do + k = get_key() + if k = 'q' then + abort(0) + elsif k != -1 then + exit + end if + end while +end procedure + +procedure place_queen(sequence queens) +-- place queens on a NxN chess board +-- (recursive procedure) + row r -- only need to consider one row for each queen + if length(queens) = N then + soln += 1 + print_board(queens) + return + end if + r = length(queens)+1 + for c = 1 to N do + if not conflict({r,c}, queens) then + place_queen(append(queens, {r,c})) + end if + end for +end procedure diff --git a/autotests/input/highlight.f90 b/autotests/input/highlight.f90 new file mode 100644 index 0000000..e2008c2 --- /dev/null +++ b/autotests/input/highlight.f90 @@ -0,0 +1,181 @@ +! This file is an example to test the syntax highlighting file F.xml +! (for fortran 90 and F) + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! THIS IS AN EXAMPLE OF A MODULE ! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +module module_example + + ! use 'implicit none' when you want all variables to be declared + implicit none + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! PUBLICS AND PRIVATES + + ! In fortran 90 you can define your own operator + public :: operator(.norm.) + public :: operator(+) ! <-- you can also overload the usual operators + public :: factorial + public :: example_fn + + private :: point3d_add + private :: point3d_norm + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! USER-DEFINED TYPES... + + ! This is a definition to use in declarations of real variables, + ! parameters, etc. + integer, parameter, public :: kr = selected_real_kind(10) + + ! This is a user-defined type + type, public :: point3d + real(kind=kr) :: x, y, z + end type point3d + + ! This type is useless: it is only an example of type definition! + type, public :: example_type + complex(kind=kr) :: c ! <-- a complex number (two reals of kind kr)! + real, dimension(-10:10) :: & ! <-- this line does not end here! + r1, r2 ! <-- this is the final part of the previous line + real, pointer, dimension(:) :: pointer_to_array_of_real + real, dimension(:), pointer :: array_of_pointer_to_real + end type example_type + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! INTERFACES... + + ! Interface for the norm of a 3-D vector + interface operator(.norm.) + module procedure point3d_norm + end interface + + ! Interface for the operator '+' + interface operator(+) + module procedure point3d_add + end interface + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! SOME DECLARATIONS... + + ! A real number can be declared with the following line: + real(kind=kr) :: real_var1 + ! But if you are not interested on the precision of floating point numbers, + ! you can use simply: + real :: real_var2 + + ! An array can be declared in two ways: + real(kind=kr), dimension(1:10, -4:5), private :: a, b, c + real(kind=kr), private :: d(1:10, -4:5) + + ! This is a string with fixed lenght + character(len=10) :: str_var + + ! This is an allocatable array, which can be a target of a pointer + type(example_type), private, dimension(:), allocatable, target :: & + many_examples + +! Fortran 90 hasn't got its own preprocessor, it uses the C preprocessor! +#ifdef XXX +c <-- this is a comment in the old fortran 77 style (fixed form) +c This is a free form file, so we shouldn't use this kind of comments! +c But fortran 90 still understands fixed form, when parsing sources with +c the *.f extension. + c ! <-- this 'c' shouldn't be highlighted as a comment! +#endif + +contains + + + ! The sum of two points + pure function point3d_add(a, b) result(rs) + type(point3d) :: rs + type(point3d), intent(in) :: a, b + rs%x = a%x + b%x + rs%y = a%y + b%y + rs%z = a%z + b%z + end function point3d_add + + + ! The norm of a point + pure function point3d_norm(a) result(rs) + real(kind=kr) :: rs + type(point3d), intent(in) :: a + rs = sqrt(a%x * a%x + a%y * a%y + a%z * a%z) + end function point3d_norm + + + ! A simple recursive function + recursive function factorial(i) result (rs) + integer :: rs + integer, intent(in) :: i + if ( i <= 1 ) then + rs = 1 + else + rs = i * factorial(i - 1) + end if + end function factorial + + + ! This is a useless function + subroutine example_fn(int_arg, real_arg, str_arg) + integer, intent(in) :: int_arg + real(kind=kr), intent(out) :: real_arg + character(len=*), intent(in) :: str_arg + + type(example_type), pointer :: p + integer :: n, i, j + logical :: flag + + flag = .true. ! .true. is not an operator! + if ( flag .and. flag ) then ! .and. is a pre-defined operator + print *, "blabla" + end if + + ! Examples of inquiry functions: allocated, lbound, ubound. + if ( .not. allocated(many_examples) ) then + allocate( many_examples(10) ) + end if + print *, "Lower bound = ", lbound(many_examples, 1) + print *, "Upper bound = ", ubound(many_examples, 1) + + p => many_examples(5) ! <-- p is a pointer + + ! A strange way to calculate i*i: add the first i odd numbers + i = 6 + j = 0 + do n = 1, i + j = j + (2*n - 1) + end do + print *, "i*i = ", i*i, j + + real_arg = real(j) ! <-- here the highlighting is not very good: + ! it is unable to distinguish between this and a definition like: + ! real(kind=kr) :: a + deallocate( many_examples ) + end subroutine example_fn + +end module module_example + + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! THIS IS THE MAIN PROGRAM ! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +program example + use module_example + + ! this is another example of use of the 'implicit' keyword + implicit double precision (a-h,o-z) + + real(kind=kr) :: var_out + + type(point3d) :: & + a = point3d(0.0_kr, 1.0_kr, 2.0_kr), & + b = point3d(4.0_kr, 5.0_kr, 6.0_kr) + + print *, "a + b = ", .norm. (a + b) + print *, "factorial of 5 = ", factorial(5) + + call example_fn(1, var_out, "hello!") + +end program example diff --git a/autotests/input/highlight.glsl b/autotests/input/highlight.glsl new file mode 100644 index 0000000..3495757 --- /dev/null +++ b/autotests/input/highlight.glsl @@ -0,0 +1,62 @@ +// This is a test file for the Katepart GLSL Syntax Highlighting. + +normal text +// this is a single-line comment +normal text +/* this +is a multi-line +comment */ +normal text + +some_symbol.some_member; +some_symbol.some_member_function(); +some_function(); + +// this is a function +void main() +{ + float f = 1.4e3; // decimal float literal + int i1 = 2884; // decimal int literal + int i2 = 0x44; // hex int literal + int i3 = 0456; // octal int literal +} + +// this is a structure +struct some_struct +{ + vec3 some_member_vector; +}; + +# this is +#preprocessor code + +// all keywords +break continue do for while +if else +true false +discard return +struct + +// all basic types +float int void bool +mat2 mat3 mat4 +vec2 vec3 vec4 +ivec2 ivec3 ivec4 +bvec2 bvec3 bvec4 +sampler1D sampler2D sampler3D +samplerCube sampler1DShadow sampler1DShadow + +// all type qualifiers +attribute const uniform varying +in out inout + +// attensions: +// FIXME +// TODO +// BUG + +// some of the std functions +radians degrees sin cos tan asin acos atan + +// some of the std variables +gl_Position gl_PointSize gl_ClipVertex diff --git a/autotests/input/highlight.hs b/autotests/input/highlight.hs new file mode 100644 index 0000000..057a3f3 --- /dev/null +++ b/autotests/input/highlight.hs @@ -0,0 +1,124 @@ +-- test file for Haskell syntax highlighting in KDE's Kate + +-- The test file for literate Haskell can be easily created like this: +-- cat highlight.hs | sed -e "s|^|> |" -e "s|> -- ||" -e "s|^> $||" > highlight.lhs +-- You only have to manually edit the multi-line comment below. + +-- this is a single-line comment + +{- this is a multi-line comment + +Things like "a string" or a 'c' character shouldn't be highlighted in here. + +-- I could even start a new +-- one-line comment. + +-} + +-- a data definition + +data Tree a = Br (Tree a) (Tree a) | Leaf a | Nil deriving (Show, Eq) + + +-- function definition, "funnyfunction::", "Integer", "Int", "Bool" should be highlighted + +funnyfunction::(Tree a)=>[a]->Integer->Int->Bool + + +-- strings and chars +-- first line of function definitions (type declaration) should be highlighted + +strangefunction::Int->String +strangefunction 1 = "hello" +strangefunction 2 = "what's up" +strangefunction 3 = (strangefunction 1) ++ ", " ++ (strangefunction 2) +strangefunction 4 = 'a':'b':'c':'"':[] -- will return "abc" +strangefunction 5 = '\n':[] +strangefunction 6 = '\invalidhaskell':[] + +-- function name including the single quote character +-- and infix operator (`div`) + +justtesting'::Int->Int +justtesting' 2 = 2+1 +justtesting' 9 = 7 `div` 2 + +-- same definition as above, slightly different function name and a couple more whitespaces + +justtesting'' :: Int -> Int +justtesting'' 2 = 3 +justtesting'' 9 = 3 + 9 - 9 + +-- the following lines are copied out of Haskell's "Prelude.hs" + +infixl 7 *, /, `quot`, `rem`, `div`, `mod`, :%, % + + +-- everything highlighted except the "a" + +class Bounded a where + minBound, maxBound :: a + +class (Num a, Ord a) => Real a where + toRational :: a -> Rational + +-- finally, some keyword lists + +-- keywords + +case, class, data, deriving, do, else, if, in, infixl, infixr, instance, let, module, of, primitive, +then, type, where + +-- infix operators + +quot, rem, div, mod, elem, notElem, seq + +-- this stuff is not handled yet + +!!, %, &&, $!, $, *, **, -,., /=, <, <=, =<<, ==, >, >=, >>, >>=, ^, ^^, ++, || + +-- functions + +FilePath, IOError, abs, acos, acosh, all, and, any, appendFile, +approxRational, asTypeOf, asin, asinh, atan, atan2, atanh, basicIORun, +break, catch, ceiling, chr, compare, concat, concatMap, const, cos, cosh, +curry, cycle, decodeFloat, denominator, digitToInt, div, divMod, drop, +dropWhile, either, elem, encodeFloat, enumFrom, enumFromThen, +enumFromThenTo, enumFromTo, error, even, exp, exponent, fail, filter, flip, +floatDigits, floatRadix, floatRange, floor, fmap, foldl, foldl1, foldr, +foldr1, fromDouble, fromEnum, fromInt, fromInteger, fromIntegral, +fromRational, fst, gcd, getChar, getContents, getLine, head, id, inRange, +index, init, intToDigit, interact, ioError, isAlpha, isAlphaNum, isAscii, +isControl, isDenormalized, isDigit, isHexDigit, isIEEE, isInfinite, isLower, +isNaN, isNegativeZero, isOctDigit, isPrint, isSpace, isUpper, iterate, last, +lcm, length, lex, lexDigits, lexLitChar, lines, log, logBase, lookup, map, +mapM, mapM_, max, maxBound, maximum, maybe, min, minBound, minimum, mod, +negate, not, notElem, null, numerator, odd, or, ord, otherwise, pi, pred, +primExitWith, print, product, properFraction, putChar, putStr, putStrLn, +quot, quotRem, range, rangeSize, read, readDec, readFile, readFloat, +readHex, readIO, readInt, readList, readLitChar, readLn, readOct, readParen, +readSigned, reads, readsPrec, realToFrac, recip, rem, repeat, replicate, +return, reverse, round, scaleFloat, scanl, scanl1, scanr, scanr1, seq, +sequence, sequence_, show, showChar, showInt, showList, showLitChar, +showParen, showSigned, showString, shows, showsPrec, significand, signum, +sin, sinh, snd, span, splitAt, sqrt, subtract, succ, sum, tail, take, +either, elem, encodeFloat, enumFrom, enumFromThen, enumFromThenTo, +enumFromTo, error, even, exp, exponent, fail, filter, flip, floatDigits, +floatRadix, floatRange, floor, fmap, takeWhile, tan, tanh, threadToIOResult, +toEnum, toInt, toInteger, toLower, toRational, toUpper, truncate, uncurry, +undefined, unlines, until, unwords, unzip, unzip3, userError, words, +writeFile, zip, zip3, zipWith, zipWith3 + +-- type constructors + +Bool, Char, Double, Either, Float, IO, Integer, Int, Maybe, Ordering, Rational, Ratio, ReadS, +ShowS, String + +-- classes + +Bounded, Enum, Eq, Floating, Fractional, Functor, Integral, Ix, Monad, Num, Ord, Read, RealFloat, +RealFrac, Real, Show + +-- data constructors + +EQ, False, GT, Just, LT, Left, Nothing, Right, True diff --git a/autotests/input/highlight.js b/autotests/input/highlight.js new file mode 100644 index 0000000..2dfe86c --- /dev/null +++ b/autotests/input/highlight.js @@ -0,0 +1,134 @@ +/* test.js - test for javascript.xml syntax file */ +// Note: this script will not, and is not supposed to, comile in any js engine. + +/* + NOTE: The words "todo", "fixme" and "note" should be rendered in a different style + within comments, match should be caseless (to test for regexp insensitive attribute). + The regex used for this rule is */ + String = /\b(?:fixme|todo|note)\b/ + /* Thus, for example "Notebook" is not caught by + this rule. (the "?:" in the subpattern is there to avoid the regex engine wasting time + saving a backref, which is not used for anything. I do not know if the overhead of parsing + that is greater than the time saved by not capturing the text...) + The rule for catching these words is placed in a context "Comment common", which is used + by both comment contexts (single line, multiline) using the new "IncludeRules" item. +*/ + +// test if regex support works - nice with new fallthrough prop in context:) +somestring.replace( /dooh/ , "bah!"); +re=/foo/ig; // hehe + +somestring.search( + /^foo\w+\s\d{0,15}$/ + ); + + re = + /dooh/; + +// This is supposedly legal: +re = somebool ? /foo/ : /bar/; + +// NOTE - Special case: an empty regex, not a comment. +// The rule uses a positive lookahead assertion to catch it: "//(?=;)". +re = //; +re = /a|b/; + +/* + Tests for the regex parser. + It will parse classes, quanitfiers, special characters and regex operaters, + as specified in the netscape documentation for javascript. + Regexps are only parsed in their clean form, as the RegExp(string) constructor + is using a quoted string. + TODO: Find out if more regex feats should be supported. + Consider using more itemDatas - assertion, quantifier are options. +*/ + +re = /^text\s+\d+\s*$/; +re = /a pattern with caret \(^\) in it/; +re = /(\d{0,4})\D/; +re = /[a-zA-Z_]+/; +re = /[^\d^]+/; +re = /\s+?\w+\.$/; +re = /\/\//; +re = /a|b/; + +// a test if #pop back from a comment will work +re = /*/foo/*/ /bar/; +// ^ POP +// ^ we got back after pop in comment, if there is regexp attribs here :-) + +/* + Some tests if the fallthrough works. + The fallthrough happens if a regexp is not found in a possible (!) position, + which is after "search(" or "replace(" or "=" or "?" or ":" in version 0.1 of the xml file +*/ + +var foo = 'bar'; +// ^ fallthrough! + + +somestring.replace( new RegExp("\\b\\w+\\b"), "word: $1"); +// ^ fallthrough expected. ("new" whould be bold) + + +something.method = + function ( a, b, c ) { /* ... */ } +// ^ fallthrough ?! + +something.other = +function ( d, e, f ) { /* ... */ } +// fallthrough expected at col 0 ("function" should be bold) + +var ary = new Array(5); +// ^ fallthrough ? (if keyword is correctly rendered) + +var b = a ? 1 : 0; +// ^ ^ fallthroughs. numbers must be rendered correctly. + +var c = d ? true : false; + +var conditinalstring = b ? + "something" : + "something else"; +// guess... + + +/* + Normal program flow... +*/ + +if (something) + dostuff(); +else + dont(); + + return; + +try { bla() } catch (e) { alert("ERROR! : " + e) } + +for (int i=0; i < j; i++) + document.write("i is" + i + "
    "); + +while (something) +{ + block(); + picky: + if (!1) + break; + else + continue; +} + +with (a) { + do { + stuff( b ); // a.b if it exists + } while (itmakessense); +} + +switch (i) { + case 0: + f(); + break; + default: + break; +} diff --git a/autotests/input/highlight.jsp b/autotests/input/highlight.jsp new file mode 100644 index 0000000..d912836 --- /dev/null +++ b/autotests/input/highlight.jsp @@ -0,0 +1,170 @@ +<%-- + This page won't actually work, as it is simply designed to display jsp syntax highlighting. +--%> +<%@ page info="A Page to Test Kate Jsp Syntax Highlighting" language="java" errorPage="/test-error-page.jsp"%> +<%@ include file="/include/myglobalvars.jsp"%> --%> +<%@ page import="java.util.*, + java.io.*, + java.math.*" %> +<%@ taglib uri="/WEB-INF/lib/si_taglib.tld" prefix="si"%> + + +<% + // We can decipher our expected parameters here. + String parm1 = noNull(request.getParameter(PARAMETER_1)).trim(); + String parm2 = noNull(request.getParameter(PARAMETER_2)).trim(); + String parm3 = noNull(request.getParameter(PARAMETER_3)).trim(); + String parm4 = noNull(request.getParameter(PARAMETER_4)).trim(); + String parm5 = noNull(request.getParameter(PARAMETER_5)).trim(); + + // A sample collection of Integers to display some code folding. + List intList = getIntList(10); + + +%> + + A Sample Jsp + + + + + <%-- The top label table. --%> + + + + +
    The following parameters were detected:
    + + <%-- Display the parameters which might have been passed in. --%> + + <%-- Label; Actual Parameter String; Value Detected --%> + + + + + + + <%-- Label; Actual Parameter String; Value Detected --%> + + + + + + + <%-- Label; Actual Parameter String; Value Detected --%> + + + + + + + <%-- Label; Actual Parameter String; Value Detected --%> + + + + + + + <%-- Label; Actual Parameter String; Value Detected --%> + + + + + +
    PARAMETER_1<%=PARAMETER_1%>"<%=parm1%>"
    PARAMETER_2<%=PARAMETER_2%>"<%=parm2%>"
    PARAMETER_3<%=PARAMETER_3%>"<%=parm3%>"
    PARAMETER_4<%=PARAMETER_4%>"<%=parm4%>"
    PARAMETER_5<%=PARAMETER_5%>"<%=parm5%>"
    + +

    + + <%-- Display our list of random Integers (shows code folding). --%> + +<% + if (intList != null && intList.size() > 0) { +%> + +<% + Iterator intListIt = intList.iterator(); + while (intListIt.hasNext()) { + Integer i = (Integer) intListIt.next(); +%> + +<% + } + } else { +%> + +<% + } +%> +
    Here are the elements of intList...
    <%=i.toString()%>
    Oooops, we forgot to initialize intList!
    + +

    + + <%-- We can call javascript functions. --%> + + + + + + +
    Test our javascript...
    + +

    + <%-- If we actually had defined a tag library. --%> + + +
    + + + + +
    + +

    + <%-- Expression language. --%> + + + + + + +
    myParam's value: ""
    + + +<%! + /* A place for class variables and functions... */ + + // Define some sample parameter names that this page might understand. + private static final String PARAMETER_1 = "p1"; + private static final String PARAMETER_2 = "p2"; + private static final String PARAMETER_3 = "p3"; + private static final String PARAMETER_4 = "p4"; + private static final String PARAMETER_5 = "p5"; + + // Returns str trimmed, or an empty string if str is null. + private static String noNull(String str) { + String retStr; + if (str == null) + retStr = ""; + else + retStr = str.trim(); + + return retStr; + } + + // Returns a list of Integers with listSize elements. + private static List getIntList(int listSize) { + ArrayList retList = new ArrayList(listSize); + for (int i = 0; i < listSize; i++) + retList.add(new Integer( (int) (Math.random() * 100) )); + + return retList; + } +%> \ No newline at end of file diff --git a/autotests/input/highlight.lex b/autotests/input/highlight.lex new file mode 100644 index 0000000..33527bd --- /dev/null +++ b/autotests/input/highlight.lex @@ -0,0 +1,82 @@ +/* This test file tests kates Lex/Flex highlighting */ + +%option c++ +%option yyclass="KateTester" +%option yylineno + + /* This is a C(++) comment */ + +/* This one is a lex comment ! */ + +%{ +#include +#include "realparser.hpp" +using namespace std; +%} + +/* Some definitions */ +DIGIT [0-9] +LETTER [_a-zA-Z] + +%% + + /* Comment *shall be indented here* */ +[ \t\n\r]+ + + /* Note: there is a bad } just here vvv */ +\/\*([^\*]|\*[^/])*\*\/ { foo(a, b, c); } } + + /* A start condition scope... */ +{ + "a" { + + /* C mode ! */ + return 0; +} + + "b" %{ + + /* C mode, too ! */ + return 0; +%} + + "c" return 0; // C++ comment +} + + /* Big rule */ +\"([^"\\]|\\.)*\" { + + yylval.string_val = new char[strlen(yytext) + 1]; + int j = 0, i = 1; + + while (yytext[i] != '"') + if (yytext[i] != '\\') + yylval.string_val[j++] = yytext[i++]; + else + switch (yytext[i + 1]) + { + case 'n': + yylval.string_val[j++] = '\n'; i += 2; + break; + default: + yylval.string_val[j++] << yytext[i + 1], i += 2; + } + + yylval.string_val[j] = 0; + return TOK_STRING; + +} + + /* Dot (match all) */ +. {return yylval.int_val = yytext[0];} + +%% + +// Here is pure C(++) +#include + +int main(void) +{ + std::cout << "Hello, World\n"; + return 0; +} diff --git a/autotests/input/highlight.lhs b/autotests/input/highlight.lhs new file mode 100644 index 0000000..9dc52e5 --- /dev/null +++ b/autotests/input/highlight.lhs @@ -0,0 +1,124 @@ +test file for Haskell syntax highlighting in KDE's Kate + +The test file for literate Haskell can be easily created like this: + cat highlight.hs | sed -e "s|^|> |" -e "s|> -- ||" -e "s|^> $||" > highlight.lhs +You only have to manually edit the multi-line comment below. + +this is a single-line comment + +{- this is a multi-line comment + +Things like "a string" or a 'c' character shouldn't be highlighted in here. + +I could even start a new +one-line comment. + +-} + +a data definition + +> data Tree a = Br (Tree a) (Tree a) | Leaf a | Nil deriving (Show, Eq) + + +function definition, "funnyfunction::", "Integer", "Int", "Bool" should be highlighted + +> funnyfunction::(Tree a)=>[a]->Integer->Int->Bool + + +strings and chars +first line of function definitions (type declaration) should be highlighted + +> strangefunction::Int->String +> strangefunction 1 = "hello" +> strangefunction 2 = "what's up" +> strangefunction 3 = (strangefunction 1) ++ ", " ++ (strangefunction 2) +> strangefunction 4 = 'a':'b':'c':'"':[] -- will return "abc" +> strangefunction 5 = '\n':[] +> strangefunction 6 = '\invalidhaskell':[] + +function name including the single quote character +and infix operator (`div`) + +> justtesting'::Int->Int +> justtesting' 2 = 2+1 +> justtesting' 9 = 7 `div` 2 + +same definition as above, slightly different function name and a couple more whitespaces + +> justtesting'' :: Int -> Int +> justtesting'' 2 = 3 +> justtesting'' 9 = 3 + 9 - 9 + +the following lines are copied out of Haskell's "Prelude.hs" + +> infixl 7 *, /, `quot`, `rem`, `div`, `mod`, :%, % + + +everything highlighted except the "a" + +> class Bounded a where +> minBound, maxBound :: a + +> class (Num a, Ord a) => Real a where +> toRational :: a -> Rational + +finally, some keyword lists + +keywords + +> case, class, data, deriving, do, else, if, in, infixl, infixr, instance, let, module, of, primitive, +> then, type, where + +infix operators + +> quot, rem, div, mod, elem, notElem, seq + +this stuff is not handled yet + +> !!, %, &&, $!, $, *, **, -,., /=, <, <=, =<<, ==, >, >=, >>, >>=, ^, ^^, ++, || + +functions + +> FilePath, IOError, abs, acos, acosh, all, and, any, appendFile, +> approxRational, asTypeOf, asin, asinh, atan, atan2, atanh, basicIORun, +> break, catch, ceiling, chr, compare, concat, concatMap, const, cos, cosh, +> curry, cycle, decodeFloat, denominator, digitToInt, div, divMod, drop, +> dropWhile, either, elem, encodeFloat, enumFrom, enumFromThen, +> enumFromThenTo, enumFromTo, error, even, exp, exponent, fail, filter, flip, +> floatDigits, floatRadix, floatRange, floor, fmap, foldl, foldl1, foldr, +> foldr1, fromDouble, fromEnum, fromInt, fromInteger, fromIntegral, +> fromRational, fst, gcd, getChar, getContents, getLine, head, id, inRange, +> index, init, intToDigit, interact, ioError, isAlpha, isAlphaNum, isAscii, +> isControl, isDenormalized, isDigit, isHexDigit, isIEEE, isInfinite, isLower, +> isNaN, isNegativeZero, isOctDigit, isPrint, isSpace, isUpper, iterate, last, +> lcm, length, lex, lexDigits, lexLitChar, lines, log, logBase, lookup, map, +> mapM, mapM_, max, maxBound, maximum, maybe, min, minBound, minimum, mod, +> negate, not, notElem, null, numerator, odd, or, ord, otherwise, pi, pred, +> primExitWith, print, product, properFraction, putChar, putStr, putStrLn, +> quot, quotRem, range, rangeSize, read, readDec, readFile, readFloat, +> readHex, readIO, readInt, readList, readLitChar, readLn, readOct, readParen, +> readSigned, reads, readsPrec, realToFrac, recip, rem, repeat, replicate, +> return, reverse, round, scaleFloat, scanl, scanl1, scanr, scanr1, seq, +> sequence, sequence_, show, showChar, showInt, showList, showLitChar, +> showParen, showSigned, showString, shows, showsPrec, significand, signum, +> sin, sinh, snd, span, splitAt, sqrt, subtract, succ, sum, tail, take, +> either, elem, encodeFloat, enumFrom, enumFromThen, enumFromThenTo, +> enumFromTo, error, even, exp, exponent, fail, filter, flip, floatDigits, +> floatRadix, floatRange, floor, fmap, takeWhile, tan, tanh, threadToIOResult, +> toEnum, toInt, toInteger, toLower, toRational, toUpper, truncate, uncurry, +> undefined, unlines, until, unwords, unzip, unzip3, userError, words, +> writeFile, zip, zip3, zipWith, zipWith3 + +type constructors + +> Bool, Char, Double, Either, Float, IO, Integer, Int, Maybe, Ordering, Rational, Ratio, ReadS, +> ShowS, String + +classes + +> Bounded, Enum, Eq, Floating, Fractional, Functor, Integral, Ix, Monad, Num, Ord, Read, RealFloat, +> RealFrac, Real, Show + +data constructors + +> EQ, False, GT, Just, LT, Left, Nothing, Right, True diff --git a/autotests/input/highlight.lisp b/autotests/input/highlight.lisp new file mode 100644 index 0000000..e86c85f --- /dev/null +++ b/autotests/input/highlight.lisp @@ -0,0 +1,36 @@ +;; This test file tests kates common lisp highlighting +#| +multilinecomment :) +|# + +;BEGIN region marker + +;END end + +(defun bin-search (obj vec) + (let ((len (length vec))) + (and (not (zerop len)) + (finder obj vec 0 (- len 1))))) + +(defun parse-date (str) + (let ((toks (tokens str #'constituent 0))) + (list (parse-integer (first toks)) + (parse-month (second toks)) + (parse-integer (third toks))))) + +(defconstant month-names + #("jan" "feb" "mar" "apr" "may" "jun" + "jul" "aug" "sep" "oct" "nov" "dec")) + +(defstruct buf + vec (start -1) (used -1) (new -1) (end -1)) + +(defparameter *words* (make-hash-table :size 10000)) + +(defmacro while (test &rest body) + `(do () + ((not ,test)) + ,@body)) + +(define-modify-macro append1f (val) + (lambda (lst val) (append lst (list val)))) diff --git a/autotests/input/highlight.ly b/autotests/input/highlight.ly new file mode 100644 index 0000000..29aa7a6 --- /dev/null +++ b/autotests/input/highlight.ly @@ -0,0 +1,114 @@ +% This is a file to test the Lilypond highlighting features of Katepart. +% This is NOT a valid lilypond file, because it also shows the +% highlighting of some invalid lilypond constructs! +% This is a line comment. + +%{ +this is a block comment, that can occur inside a line, or across +multiple lines. +%} + +\header { + title = "Katepart Lilypond syntax highlighting test file" + composer = %{"Wilbert Berendsen"%} "Anonymus" + poet = "The KDE team" + opus = "1" + copyright = "Share and enjoy!" +} + +\paper { + #(set-paper-size "a4") % a hash introduces scheme + indent = 0 % recognize variable names inside \paper, \layout etc. + between-system-space = 3\mm +} + +\layout { + \context { + \Score + \remove Bar_number_engraver % recognize engraver names + \remove "Bar_number_engraver" % also when quoted! + } +} + +% { and << block are folded +\score { + \new StaffGroup << + \new ChordNames \chordmode { c2sus4/f g2/d c1 } + \new Staff \new Voice ="mel" { + \key f \major + \time 4/4 + \partial 4 + \set Staff.instrumentName = "Bla." + \once \override Staff.NoteHead #'color = #red + % dynamics, articulations and markup + c8\p d\< e-. f-> g a\f c-5\markup {Hoi} + \notemode { c d e f } + \repeat volta 2 { + % complex durations are highlighted: + g4*2/3 + } + \times 2/3 {e8 f g} + % there is some error checking: + % often made mistake to have octavemarks after the duration: + c2' + % invalid durations are caught: + g3 + } + \context Lyrics \lyricsto "mel" { + \set fontSize = #1 + this is a line of ly -- rics. + with4 dur -- a -- tions.2. + % errors like forgetting spaces are found: + space-- flight %{i.s.o.%} space -- flight + space at end for -- got -- ten as well.} + + \new DrumStaff \drummode { hihat4 bassdrum8 } + \new FiguredBass \figuremode { + <5 4>8 <6-> + } + >> + \midi { + \context { + \Score + tempoWholesPerMinute = #(ly:make-moment 60 2) + } + } +} + +av = #(define-music-function (parser location voice) +(string?) +; scheme comments are recognized in scheme +; Lilypond inside scheme works as well: +#{ + \set associatedVoice = $voice +#}) + + + + +% inside scheme some elements are highlighted: +#(define (naturalise-pitch p) + (let* ((o (ly:pitch-octave p)) + (a (* 4 (ly:pitch-alteration p))) + (n (ly:pitch-notename p))) + (bla 'ArticulationEvent 'ChoirStaff) + (cond + ((> a 2) (set! a (- a 4)) (set! n (+ n 1))) + ((< a -2) (set! a (+ a 4)) (set! n (- n 1)))) + + (if (< n 0) (begin (set! o (- o 1)) (set! n (+ n 7)))) + (if (> n 6) (begin (set! o (+ o 1)) (set! n (- n 7)))) + + (ly:make-pitch o n (/ a 4)))) + +% markup is also highlighted +\markup { + \line { + text test Voice Staff % note Lilypond keywords are not highlighted here + } + \score { \relative c' { 2( d) } } + \italic bla + \override #'(baseline-skip . 2) { + \underline blu + } +} diff --git a/autotests/input/highlight.m b/autotests/input/highlight.m new file mode 100644 index 0000000..f240138 --- /dev/null +++ b/autotests/input/highlight.m @@ -0,0 +1,61 @@ +%%===================================================== +% MATLAB test code for Kate/Kwrite syntax highlighting +% kate: hl Matlab +%%===================================================== + +% Numbers _____________________________________________ +5, 5.5, .1, 0.1, 0.4e5, 1.2e-5, 5i, 5.3i, 6j, .345+3i +5', 5.5', .1', 0.1', 0.4e5', 1.2e-5', 5i', 5.3i', 6j', .345+3i' + +% Operators ___________________________________________ +% relational operators +'asdf'~=4, c<=4, d>=4, ab, a==b, b||c, b&&c +% elementwise arithmetic operators +a.^b, a.*b a./b, 1:4:5 +% single-character binary arithmetic +a+3, a-3, a*2, a^3, a/3, a\3, a|b, a&b +% unary operators +a = ~g; g = @sfdgdsf(sdfsd,345); g.' + 1i.' - ('asdf').' +% separators and delimiter +(asd),[sadf];{asdf},;;,;;;() +% continuation +a = 1+ ... + 2; + +% Strings and adjoint _________________________________ +% incomplete strings +'string +'str'' +'str''ing +% complete strings +'string' % simple string +'''' % string containing ' +'str''ing' % one string containing ' +'string' 'string' % two strings +'asdf' 'asdf''' variable % two strings and a variable +'asdf''asdf'' fsgdfg' + (asdf)' - 'asdf'.' + []''''.';'' +'sadf'.' % string transpose +% adjoint +{'asdf'}' + 1 +('asdf')' + 1 +['asdf']' + 1 +'' var''' % empty string, var with >1 adjoints +[5]'*{5}'*('asd')'.'+(5)'*6'*asdf'*asdf'.' % many adjoints +A'*B + 1 % adjoint +A.'*B + 1 % transpose +A.'.'*B + 1 % double transpose +A'.' + 1 % adjoint, then transpose +A.'' % transpose, then adjoint + +% System command ______________________________________ +!hostname +!cp * /tmp + +% Reserved keywords ___________________________________ +function, persistent, global +switch, case, otherwise +if, else, elseif +try, catch +for, while, break, continue +end, return +function, FUNCTION, Function % case sensitive! \ No newline at end of file diff --git a/autotests/input/highlight.m.syntax b/autotests/input/highlight.m.syntax new file mode 100644 index 0000000..d22d99a --- /dev/null +++ b/autotests/input/highlight.m.syntax @@ -0,0 +1 @@ +Matlab diff --git a/autotests/input/highlight.mac b/autotests/input/highlight.mac new file mode 100644 index 0000000..cb9da2d --- /dev/null +++ b/autotests/input/highlight.mac @@ -0,0 +1,145 @@ +/* +------------------------------------------------------------------------ +Efficient Galois Fields in Maxima + +by Alasdair McAndrew +and later extended by Fabrizio Caruso and Jacopo Daurizio + +it is distribuited together with gf_roots by Jacopo Daurizio + +Authors: + +Fabrizio Caruso (optimizations, testing) +Jacopo D'Aurizio (optimizations, modular roots) +Alasdair McAndrew (original version of the package, pohlig-helman log, etc... ) +------------------------------------------------------------------------*/ + +/* Released under terms of the GNU General Public License, version 2, + * by permission of the authors to Robert Dodier circa 2007-12-02. + */ + +/* Defines a flag for dealing with large fields. If it is set to "false", +then lookup tables are used for exponentiation and logarithms. Otherwise +other algorithms are used */ + +define_variable(largefield,true,bool)$ +define_variable(gf_char,0,integer)$ +define_variable(gf_exp,0,integer)$ +define_variable(gf_order,0,integer)$ +define_variable (gf_one, 'gf_one, any_check)$ +define_variable (gf_prim, 'gf_prim, any_check)$ +define_variable (gf_irr, 'gf_irr, any_check)$ +define_variable (gf_list, 'gf_list, any_check)$ +define_variable (gen_powers, 'gf_list, any_check)$ +remvalue(x,z,gf_char,gf_exp,gf_irr,pg,gp,lg,gf_prim,gf_one,gf_order,gf_list,gen_powers)$ + + +/* --------------------------------------------------------------------------------------------- */ +/* Settings */ + +GF_VERBOSE:false; /* Verbosity */ +GF_WARNING: true; /* Warnings */ +GF_IRREDUCIBILITY_CHECK:false; /* Irreducibility test for the minimal polynomial of the extension */ + +/* +------------------------------------------------------------------------------------------------ */ + + +/* It defines a new current field with gf_char=b, min. pol.= p of deg= e*/ +gf_set([ars]):=block([gj,m,i,j,dg], + if length(ars)=1 then + ( + gf_setp(ars[1]), + return(true) + ) + else + ( + if length(ars)=2 then + ( + if numberp(ars[2]) then + ( + if ars[2]=0 and GF_WARNING then + ( + print("WARNING: the irreducible is zero! We assume GF(",ars[1],")"), + gf_setp(ars[1]), + return(true) + ) + else + ( + error("ERROR: you tried to extend with a non-zero constant!"), + return(false) + ) + ) + else + ( + dg:hipow(ars[2],x), + + if dg=1 then + gf_setp(ars[1]), + gf_irr:ars[2], + gf_exp:dg, + return(true) + ) + ) + else + ( + gf_exp:ars[2], + if gf_exp=1 then + ( + gf_setp(ars[1]), + gf_irr:rat(ars[3]), + return(true) + ), + gf_irr:rat(ars[3]) + ) + ), + + gf_char:ars[1], + gf_one:rat(1,x), + gf_order:gf_char^gf_exp-1, + + m:makelist(coeff(gf_irr,x,i),i,0,gf_exp), + gf_list:[[first(m),0]],j:1, + for i:2 thru gf_exp+1 do if m[i]=0 then j:j+1 else ( gf_list:endcons([m[i],j],gf_list), j:1 ), + + if not(primep(gf_char)) then error("ERROR: Gf_Char must be a prime number.") + else + modulus:gf_char, + if GF_IRREDUCIBILITY_CHECK and + hipow(args(factor(ars[3]))[1],x)#hipow(rat(ars[3]),x) then + error("ERROR: Polynomial is not irreducible"), + + if not(largefield) then + ( + pg:mkpowers(), + lg:mklogs() + ) + else + ( + if GF_VERBOSE then + print("finding a primitive element..."), + + gf_prim:rat(gf_findprim(),x), + if GF_VERBOSE then + print("...primitive element found.") + + ), + modulus:false, /* it resets the modulus */ + return(true) + + )$ + + +/* Prints out information about the field */ +gf_info():=block( + print("Prime gf_char value: ",gf_char), + print("Exponent: ", gf_exp), + print("Multiplicative order: ",gf_order), + print("Irreducible polynomial: ",gf_irr), + print("Primitive element: ",gf_prim), + if (largefield) then + print("Largefield flag is true; powers and logarithms not computed.") + else + print("Largefield flag is false; powers and logarithms computed."), + disp() +)$ diff --git a/autotests/input/highlight.mup b/autotests/input/highlight.mup new file mode 100644 index 0000000..ed5a03d --- /dev/null +++ b/autotests/input/highlight.mup @@ -0,0 +1,103 @@ +// This is a MUP highlighting test. +// Mup is a shareware music publisher from www.arkkra.com + +// contexts +score +music +staff 1 +voice 1 3 + +top +top2 +bottom +bottom2 +grids + +headshapes + + +header +footer +header2 +footer2 + +// parameters and values +score + units = cm; + key = 3#minor + key = 3# minor + rehstyle=circled + + + + +mussym above all: 1 "ferm" ; + +define NAME +// this is a macro definition, these are collapsable +@ + +ifdef NAME +// this is conditionally "compiled" +endif + +ifndef NAME +// this is conditionally "compiled" when the macro has not been defined +else +// else clause +endif + + +// Various Tests + +// tablature +1: e ^f; f; b ^c5; c#5; +bar + +1: d+^e+ g^a; e+a; g ^/; c ^/ c+^/; +bar + +// cross-staff stems +1: 1e+g+c++; +2: cc+; ee+; g with g+ above; with c+c++ above; +bar + +1: 2+4ceg;4; // tie implied by added time values + +// slurs +1: 2f a c+; dbd+; +bar +1: 2fac+ slur; dbd+; +bar + +// alternation +1: 2c alt 2; 2c+;2g; +bar + +// bar to draw if repeatstart happens to be on new line +(dblbar) repeatstart +1: [up]8f bm with staff below;a;4s ebm;4s bm with staff below;8b;[len 11]d ebm; +2: 4s bm with staff above;8a;b ebm;[down;len 14]b bm with staff above;d;4s ebm; +bar + +// locations +3: 2cf; [=h] egc+; +1: [cue; with >; =_ch] fa; + + +roll up 1 1 to 1 2: 2; 4; +roll down 1 1 to 1 2: 2; 4; + +lyrics above 1,3 ; below 2,4 ; between 5&6 : "<1. >Hi, hi"; + +title "page \% of \#" + +// shaped whole rests +1: 4mr; // use a quarter rest symbol +1: 1/4mr; // use a quadruple whole rest symbol +2: 2.. mr; // use a double-dotted half rest + +// tuplets +1: {4f; g;}3num,4.+2. +bar + diff --git a/autotests/input/highlight.pb b/autotests/input/highlight.pb new file mode 100644 index 0000000..5560233 --- /dev/null +++ b/autotests/input/highlight.pb @@ -0,0 +1,87 @@ +; This is a test file for kate's PureBasic highlighting. + +; BMP2x Converter by Sven Langenkamp + +UseJPEGImageEncoder() +UsePNGImageEncoder() + +Declare Convert(JPEG) + +Enumeration 1 + #JPEG + #PNG +EndEnumeration + +; BEGIN section + + +; END + +Global Count +Global file.s +Global filename.s +Global fileext.s +Global OutputFormat +Global JPEGQuality + +Count = 0 +OutputFormat = 1 +JPEGQuality = -1 + +; MAIN PROGRAM------------------------------------------------------------------ + +;Request Options +PrintN("Output Format") +PrintN(" [1] JPEG") +PrintN(" [2] PNG") +Print ("> ") +OutputFormat = Int(Input()) + +Select OutputFormat + Case #JPEG: + fileext = ".jpg" + ;Request JPEG Quality + PrintN("") + PrintN("JPEG Quality") + PrintN(" [0-10]") + Print ("> ") + JPEGQuality = Int(Input()) + + Case #PNG: + fileext = ".png" +EndSelect + +;Convert all BMP files in the current directory +ExamineDirectory(0, "", "*.bmp") +While NextDirectoryEntry() + file = DirectoryEntryName() + filename = GetFilePart(file) + + If LoadImage(0, file) + Select OutputFormat + Case #JPEG: + Convert(JPEGQuality) + + Case #PNG: + Convert(-1) + EndSelect + Count = Count +1 + EndIf + +Wend + +PrintN(Str(Count) + " files converted") +CloseConsole() + +; PROCUDURES-------------------------------------------------------------------- + +Procedure Convert(JPEG) + Shared filename, fileext + + If JPEG > -1 + SaveImage(0, filename + fileext, #PB_ImagePlugin_JPEG, JPEG) + Else + SaveImage(0, filename + fileext, #PB_ImagePlugin_PNG) + EndIf + PrintN(file + " converted to " + filename + fileext) +EndProcedure \ No newline at end of file diff --git a/autotests/input/highlight.php b/autotests/input/highlight.php new file mode 100644 index 0000000..d604e36 --- /dev/null +++ b/autotests/input/highlight.php @@ -0,0 +1,23 @@ + + + + + + test"; ?> + + + \ No newline at end of file diff --git a/autotests/input/highlight.pike b/autotests/input/highlight.pike new file mode 100644 index 0000000..2f63144 --- /dev/null +++ b/autotests/input/highlight.pike @@ -0,0 +1,24 @@ +#! /bin/env pike + +/* This file is a syntax highlight test for Kate. + * FIXME: Improve it to contain more (and more unusual) syntax examples. + */ + + +#define PIKE_ON_THE_WEB /* Is this address correct? */ "http://pike.ida.liu.se/" + + +int main(int argc, array(string) args) +{ + // Write funny things with Pike :) + write(`+("Command line arguments (%d of them): ", @map(args, `+, " ")) + "\n", argc); + + write("\nVisit Pike site at %s\n\n", PIKE_ON_THE_WEB); + + for (int i = 1; i <= 3; i++) + write(":" + ")" * i + " "); + + write("\n" + ({"Bye", "bye"}) * "-" + "!\n"); + + return 0; +} diff --git a/autotests/input/highlight.pl b/autotests/input/highlight.pl new file mode 100644 index 0000000..991d1fe --- /dev/null +++ b/autotests/input/highlight.pl @@ -0,0 +1,44 @@ +#!/usr/bin/perl -w +# This is a pseudo Perl file to test Kate's Perl syntax highlighting. +# TODO: this is incomplete, add more syntax examples! + +sub prg($) +{ + my $var = shift; + + $var =~ s/bla/foo/igs; + $var =~ s!bla!foo!igs; + $var =~ s#bla#foo#igs; + $var =~ tr/a-z/A-Z/; + ($match) = ($var =~ m/(.*?)/igs); + + $test = 2/453453.21; + $test /= 2; + + print qq~d fsd fsdf sdfl sd~ + + $" = '/'; + + $foo = <<__EOF; +d ahfdklf klsdfl sdf sd +fsd sdf sdfsdlkf sd +__EOF + + $x = "dasds"; + + next if( $match eq "two" ); + next if( $match =~ /go/i ); + + @array = (1,2,3); # a comment + @array = qw(apple foo bar); + push(@array, 4); + %hash = (red => 'rot', + blue => 'blau'); + print keys(%hash); +} + +sub blah { +} + +&blah; +prg("test"); diff --git a/autotests/input/highlight.pov b/autotests/input/highlight.pov new file mode 100644 index 0000000..0bb3077 --- /dev/null +++ b/autotests/input/highlight.pov @@ -0,0 +1,76 @@ +//BEGIN TEST +// test scene for POV-Ray syntax highlighting + +/* test comment */ + +/* nested /* comments */ do not work */ + +#version 3.5; +//END +global_settings { assumed_gamma 1.0 } + +// ---------------------------------------- + +camera { + location <5.0, -12.0, 2.0> + up z sky z + look_at <0.0, 0.0, 0.5> + angle 40 +} + +sky_sphere { + pigment { + gradient z + color_map { + [0.0 rgb <0.6,0.7,1.0>] + [0.2 rgb <0.2,0.3,0.9>] + } + } +} + +light_source { + <3, 1, 2>*1000 + color rgb <2.2, 1.8, 1.5> +} + +// ---------------------------------------- + +#declare TEST=0; + +#ifdef (TEST) + plane { + z, 0 + texture { + pigment { + checker + color rgb 1, color rgb 0 + } + } + } +#end + +#macro Sphere(Pos, Radius) + sphere { + , Radius + texture { + pigment { color rgb 1 } + finish{ + diffuse 0.3 + ambient 0.0 + specular 0.6 + reflection 0.8 + } + } + } +#end + +#local Cnt=0; +#local Seed=seed(0); + +#while (Cnt<10000) + Sphere( + -100+*200, + 0.3+pow(rand(Seed),2)*0.7 + ) + #local Cnt=Cnt+1; +#end \ No newline at end of file diff --git a/autotests/input/highlight.prg b/autotests/input/highlight.prg new file mode 100644 index 0000000..713c605 --- /dev/null +++ b/autotests/input/highlight.prg @@ -0,0 +1,71 @@ +// Test file to test kate's clipper highlighting +// kate: hl Clipper; + +//BEGIN INCLUDES +#include +#include "logo.ch" + +#define PRGVERSION "0.0.1" +//END + +//BEGIN CODE +static ws, win +static driver := getDriver() +/* a multiline + comment +*/ + +function main( formName ) + local form + local fileName + + if empty(formName) + ?? "Usage: ./form_ui &\n" + CANCEL + else + fileName := formName + endif + ws := UIWorkSpace() + + form := UIForm( fileName ) + win := form:parseFile() +// ?? valtype(win),chr(10) + if win == NIL + CANCEL + endif + win:show() + + ws:run() + ws:quit() +return 0 + +/* Setting dialog */ +function settingsDialog() + ?? "TODO: Settings dialog&\n" +return + +/* About dialog */ +function aboutDialog() + local dlg := UIWindow("About", win, "aboutDlg", .F.) + local hl, lside, t, bb, bD + + hl := UIHBox(,4,8) + lside := UIVBox() + lside:add(UIImage(eas_logo_mini,.T.)) + hl:add(lside,.F.,.F.) + dlg:userSpace:add(hl,.T.,.T.) + t := UIVBox() + hl:add(t,.T.,.T.) + + t:add(UILabel("License: GPL version 2 or later")) + bb := UIButtonBar() + t:add(bb) + bD := UIButton(win, "&Close", {|o,e| dlg:close() } ) + bb:add( bD ) + + dlg:setFocus(bD) + dlg:setDefault(bD) + dlg:setPlacement( .T. ) + dlg:show() +return +//END \ No newline at end of file diff --git a/autotests/input/highlight.prg.syntax b/autotests/input/highlight.prg.syntax new file mode 100644 index 0000000..3355ff8 --- /dev/null +++ b/autotests/input/highlight.prg.syntax @@ -0,0 +1 @@ +Clipper diff --git a/autotests/input/highlight.qml b/autotests/input/highlight.qml new file mode 100644 index 0000000..b860512 --- /dev/null +++ b/autotests/input/highlight.qml @@ -0,0 +1,59 @@ +import Qt 4.6 + +// some random qml snippets stolen from the qt docs + +Rectangle { + important: true + propertyAsdf: + id: container + signalA: bla + property string label + signal clicked + radius: 5; border.color: "black" + color: mouse.pressed ? "steelblue" : "lightsteelblue" + gradient: Gradient { + GradientStop { position: mouse.pressed ? 1.0 : 0.0; color: "steelblue" } + GradientStop { position: mouse.pressed ? 0.0 : 1.0; color: "lightsteelblue" } + } + MouseRegion { id: mouse; anchors.fill: parent; onClicked: container.clicked() } + Text { anchors.fill: parent; text: container.label; anchors.centerIn: parent } +} + +Rectangle { + Script { + function calculateMyHeight() { + return Math.max(otherItem.height, thirdItem.height); + } + } + + anchors.centerIn: parent + width: Math.min(otherItem.width, 10) + height: calculateMyHeight() + color: { if (width > 10) "blue"; else "red" } +} + +Rectangle { + default property color innerColor: "black" + property color innerColor: "black" + property alias text: textElement.text + property alias aliasXYZ: testElement.text + signal bar + signal bar(var blah, string yxcv) + width: 240; height: 320; + width: 100; height: 30; source: "images/toolbutton.sci" + ListView { + anchors.fill: parent + model: contactModel + delegate: Component { + Text { + text: modelData.firstName + " " + modelData.lastName + } + } + } +} + +Item { + function say(text) { + console.log("You said " + text); + } +} diff --git a/autotests/input/highlight.rb b/autotests/input/highlight.rb new file mode 100644 index 0000000..2e52e5f --- /dev/null +++ b/autotests/input/highlight.rb @@ -0,0 +1,551 @@ +# This file is a testcase for the highlighting of Ruby code +# It's not executable code, but a collection of code snippets +# + +require 'Config' +require 'DO/Clients' +require 'DO/DBClients' + + def CGI::escapeElement(string, *elements) + elements = elements[0] if elements[0].kind_of?(Array) + unless elements.empty? + string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/ni) do + CGI::escapeHTML($&) + end + else + string + end + end + +case inputLine + when "debug" + dumpDebugInfo + dumpSymbols + when /p\s+(\w+)/ + dumpVariable($1) + when "quit", "exit" + exit + else + print "Illegal command: #{inputLine}" +end + + +kind = case year #hi there + when 1850..1889 then "Blues" + when 1890..1909 then "Ragtime" + when 1910..1929 then "New Orleans Jazz" + when 1930..1939 then "Swing" + when 1940..1950 then "Bebop" + else "Jazz" + end + + # URL-encode a string. + # url_encoded_string = CGI::escape("'Stop!' said Fred") + # # => "%27Stop%21%27+said+Fred" + def CGI::escape(string) + string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do + '%' + $1.unpack('H2' * $1.size).join('%').upcase + end.tr(' ', '+') + end + + +# Class ClientManager +# +# definition : Import, store and export the various data used by the application. +# This class is the sole interface between the application and the underlying database. + +mon, day, year = $1, $2, $3 if /(\d\d)-(\d\d)-(\d\d)/ +puts "a = #{a}" if fDebug +print total unless total == 0 + +while gets + next if /^#/ # Skip comments + parseLine unless /^$/ # Don't parse empty lines +end + +if artist == "John Coltrane" #hi there + artist = "'Trane" #hi there +end unless nicknames == "no" #hi there + +handle = if aSong.artist == "Gillespie" then #hi there + "Dizzy" + elsif aSong.artist == "Parker" then + "Bird" + else #hi there + "unknown" + end + +if aSong.artist == "Gillespie" then handle = "Dizzy" +elsif aSong.artist == "Parker" then handle = "Bird" +else handle = "unknown" +end #hi there + +if aSong.artist == "Gillespie" then + handle = "Dizzy" +elsif aSong.artist == "Parker" then + handle = "Bird" +else + handle = "unknown" +end + +if aSong.artist == "Gillespie" + handle = "Dizzy" +elsif aSong.artist == "Parker" + handle = "Bird" +else + handle = "unknown" +end + + case line + when /title=(.*)/ + puts "Title is #$1" + when /track=(.*)/ + puts "Track is #$1" + when /artist=(.*)/ + puts "Artist is #$1" +end + +case shape + when Square, Rectangle + # ... + when Circle + # ... + when Triangle + # ... + else + # ... +end + + +until playList.duration > 60 #hi there + playList.add(songList.pop) +end + +3.times do + print "Ho! " +end + +loop { + # block ... +} + +songList.each do |aSong| + aSong.play +end + +for aSong in songList + aSong.play +end + +for i in ['fee', 'fi', 'fo', 'fum'] + print i, " " +end +for i in 1..3 + print i, " " +end +for i in File.open("ordinal").find_all { |l| l =~ /d$/} + print i.chomp, " " +end + +class Periods + def each + yield "Classical" + yield "Jazz" + yield "Rock" + end +end + + +periods = Periods.new +for genre in periods + print genre, " " +end + +while gets + next if /^\s*#/ # skip comments + break if /^END/ # stop at end + # substitute stuff in backticks and try again + redo if gsub!(/`(.*?)`/) { eval($1) } + # process line ... +end + +i=0 +loop do + i += 1 + next if i < 3 + print i + break if i > 4 +end + +for i in 1..100 + print "Now at #{i}. Restart? " + retry if gets =~ /^y/i +end + +def doUntil(cond) + yield + retry unless cond +end + +i = 0 +doUntil(i > 3) { + print i, " " + i += 1 +} + +def system_call + # ... code which throws SystemCallError +rescue SystemCallError + $stderr.print "IO failed: " + $! + opFile.close + File.delete(opName) + raise +end + +class ClientManager + + # constructor + def initialize(dbase) + @dbClient = DBClient.new(dbase) + @clients = Clients.new + end + + def prout(a, b, xy="jj") 24 end + ############################################################### + # + # CLIENTS SECTION + # + ############################################################### + + # update the clients object by retrieving the related data from the database + # returns the number of clients + def refreshClients + @clients.clean + unless @sqlQuery.nil? then + @sqlQuery.selectClient.each do |row| + @clients.addClient(row[0],row[1],row[2],row[3],row[4],row[5], row[6], row[7], row[8]) + end + else + puts "SqlQuery wasn't created : cannot read data from database" + end + return @clients.length + end + + # insert a client in the database and refreshes the local clients object + # we assume that none of the arguments is null + # we assume that the client, identified by raison_sociale doesn't already exists + def addClient(raison_sociale, division, departement, adresse, cp, ville, nom_contact, tel_contact) + id = "0" + unless @sqlQuery.nil? then + id = @sqlQuery.insertClient(raison_sociale, division, departement, adresse, cp, ville, nom_contact,tel_contact) + else + puts "SqlQuery wasn't created : database update cannot be performed" + end + @clients.addClient(id, raison_sociale, division, departement, adresse, cp, ville, nom_contact, tel_contact) # synchronize local object with DB + end + + # deletes a client from the database and updates the local Clients object accordingly + def delClient(nomclient_brut) + raison_sociale, div, dep = Clients.getIdentifiers(nomclient_brut) + listeContratsExp, listeContratsSup, listeContratsProd, listePropositionsExp, listePropositionsSup = [] + + listeContratsExp = @contratsExpertise.getContratsFromClient(nomclient_brut) + listeContratsSup = @contratsSupport.getContratsFromClient(nomclient_brut) + listeContratsProd = @contratsProduits.getContratsFromClient(nomclient_brut) + listePropositionsExp = @propositionsExpertise.getPropositionsFromClient(nomclient_brut) + listePropositionsSup = @propositionsSupport.getPropositionsFromClient(nomclient_brut) + + unless @sqlQuery.nil? then + @sqlQuery.deleteClient(raison_sociale, div, dep) + + @sqlQuery.deleteContracts(Config::EXPERTISE,listeContratsExp) + @sqlQuery.deleteContracts(Config::SUPPORT,listeContratsSup) + @sqlQuery.deleteContracts(Config::PRODUIT,listeContratsProd) + @sqlQuery.deletePropositions(Config::EXPERTISE,listePropositionsExp) + @sqlQuery.deletePropositions(Config::SUPPORT,listePropositionsSup) + else + puts "SqlQuery wasn't created : database update cannot be performed" + end + @clients.delClient(raison_sociale,div,dep) + + @contratsExpertise.deleteContracts(listeContratsExp) + @contratsSupport.deleteContracts(listeContratsSup) + @contratsProduits.deleteContracts(listeContratsProd) + @propositionsExpertise.deletePropositions(listePropositionsExp) + @propositionsSupport.deletePropositions(listePropositionsSup) + end +end + + # Mixin module for HTML version 3 generation methods. + module Html3 # :nodoc: + + # The DOCTYPE declaration for this version of HTML + def doctype + %|| + end + + # Initialise the HTML generation methods for this version. + def element_init + extend TagMaker + methods = "" + # - - + for element in %w[ A TT I B U STRIKE BIG SMALL SUB SUP EM STRONG + DFN CODE SAMP KBD VAR CITE FONT ADDRESS DIV center MAP + APPLET PRE XMP LISTING DL OL UL DIR MENU SELECT table TITLE + STYLE SCRIPT H1 H2 H3 H4 H5 H6 TEXTAREA FORM BLOCKQUOTE + CAPTION ] + methods += <<-BEGIN + nn_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + + # - O EMPTY + for element in %w[ IMG BASE BASEFONT BR AREA LINK PARAM HR INPUT + ISINDEX META ] + methods += <<-BEGIN + nOE_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + + # O O or - O + for element in %w[ HTML HEAD BODY P PLAINTEXT DT DD LI OPTION tr + th td ] + methods += <<-BEGIN + nO_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + eval(methods) + end + + end + +# following snippet from Webrick's log.rb +# notice the erronous handling of the query method is_a? +def format(arg) + str = if arg.is_a?(Exception) + "#{arg.class}: #{arg.message}\n\t" << + arg.backtrace.join("\n\t") << "\n" + elsif arg.respond_to?(:to_str) + arg.to_str + else + arg.inspect + end +end + +# following snippet from Webrick's httputils.rb +# Splitting regexps on several lines might be bad form, +# but not illegal in Ruby. +# This should probably be supported in the highlighting +def split_header_value(str) + str.scan(/((?:"(?:\\.|[^"])+?"|[^",]+)+) + (?:,\s*|\Z)/xn).collect{|v| v[0] } +end + +# snippet from Net::Telnet +string.gsub(/#{IAC}( + [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]| + [#{DO}#{DONT}#{WILL}#{WONT}] + [#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]| + #{SB}[^#{IAC}]*#{IAC}#{SE} + )/xno) + +# following snippet from Webrick's httpresponse.rb +# the HEREDOC is not recognized as such +@body << <<-_end_of_html_ + + + #{HTMLUtils::escape(@reason_phrase)} + +

    #{HTMLUtils::escape(@reason_phrase)}

    + #{HTMLUtils::escape(ex.message)} +
    +_end_of_html_ + + +# snippet from Webrick's httpproxy.rb +# here we should make sure that the symbol definition ':' doesn't override +# the module operator '::' +Net::HTTP::version_1_2 if RUBY_VERSION < "1.7" + +# snippet from Webrick's cookie.rb +# the beginning of the regexp is erronously highlighted like an operator +key, val = x.split(/=/,2) + +# the following are division operators +# it's a bit tricky to keep the operator apart from the regexp +result = 8 / 4 +result /= divisor + +# 2008-06-01 regexp and division operator syntax has been fixed: +result = 8/4 # division +result = 8/foo # division +result = /8/ # regexp +result = 8//4/ # division and regexp + +10/10 # division +10/ 10 # division +10 /10 # division +10 / 10 # division + +foo/10 # division +foo/ 10 # division +foo /10/ # regexp +foo / 10 # division + +foo/10/10 # both division +total/count/2 # both division +total/(count/2) # both division + +@foo/10 # division +@foo /10 # division + +"hello"/10 # division +"hello" / 10 # division + +/regexp//10 # division +/regexp/ / 10 # division + +Math::PI/10 # division +Math::foo /rx/ # regexp + +# 2008-06-05 similar fix for modulo operator: + +10%4 # modulo +10 %4 # modulo +10% 4 # modulo +10 % 4 # modulo + +foo%4 # modulo +# foo %4 # illegal %string +foo% 4 # modulo +foo % 4 # modulo + +foo % (4) # modulo + +foo %(4) # %string +foo %q(4) # %string +foo %Q(4) # %string +foo %%4% # %string + +foo = %|blah| # GDL input +foo % %|blah| # modulo and GDL + +# mix in any way you want +result = 10//regexp//20/foo//regexp//20 + +# test cases for general delimited input +# quoted strings +%Q|this is a string| +%Q{this is a string} +%Q(this is a string) +%Q +%Q[this is a string] + +%|also a string| +%{also a string} +%(also a string) +% +%[also a string] + +# apostrophed strings +%q|apostrophed| +%q{apostrophed} +%q(apostrophed) +%q +%q[apostrophed] + +# regular expressions +%r{expression} +%r(expression) +%r +%r[expression] +%r|expression| + +# shell commands +%x{ls -l} +%x(ls -l) +%x +%x[ls -l] + +# sometimes it's useful to have the command on multiple lines +%x{ls -l | +grep test } + +# alternative syntax +`ls -l` +`echo ' '` + +# token array +%w{one two three} +%w(one two three) +%w +%w[one two three] + +# snippet from Net::IMAP +# I object to putting String, Integer and Array into kernel methods. +# While these classes are builtin in Ruby, this is an implementation detail +# that should not be exposed to the user. +# If we want to handle all std-lib classes, fine. But then they should be in their +# own std-lib keyword category. + +def send_data(data) + case data + when nil + put_string("NIL") + when String + send_string_data(data) + when Integer + send_number_data(data) + when Array + send_list_data(data) + when Time + send_time_data(data) + when Symbol + send_symbol_data(data) + else + data.send_data(self) + end +end + +# snippet from Net::POP +# class names can have numbers in them as long as they don't begin with numbers +# Ruby doesn't internally really make much of a difference between a class name and a constant + +# class aliases + POP = POP3 + POPSession = POP3 + POP3Session = POP3 + +# "member access" +POP::Session.COUNT.attribute.calc_with(2){ |arg| puts arg } + +# snippet from Net::SMTP +# This breaks the code folding. I think we would need to +# handle the '\' that continues the statement to the next line +# in some way to make these kind of things not break something. +raise ArgumentError, 'both user and secret are required'\ + unless user and secret + +# string escapes must detect escaping the escape char +str = "\\" +str = "\\\\" +# this is not part of the string +%x{echo \\\}\\} # prints \}\ +# this is not part of the command + +# these are all symbols +:abc +:abc! +:abc? +:abc= +:[] +:[]= +:@abc +:@@abc +:$abc diff --git a/autotests/input/highlight.scheme b/autotests/input/highlight.scheme new file mode 100644 index 0000000..08c7351 --- /dev/null +++ b/autotests/input/highlight.scheme @@ -0,0 +1,186 @@ +; This is a test file to test kates scheme highlighting +; This is a comment + +;; Another comment, usually used. +;BEGIN region marker +;; a vektor +#(1 2 3 4 5) +;END region marker +;; this represents integer 28 (FIXME: does not work perfectly atm!) +28 028 #e28 #i28 ;; Normal, normal, exact, inexact +#b11100 #o34 #d28 #x1c ;; Bin, okt, dec, hex +#oe34 #eo34 ;; combined. + +;; char. +(#\y #\space) ;; list: `y' space. +(#\ #\\ #\)) ;; list of spaces, backslash and`)'. +#\newline ;; a newline-char +#\NewLine ;; another one :) + +"Hello, world" ;; a string + +"hoho, what do you +want to do ;; this is NO comment +with that?" + +;; R5RS definiert diese beiden. +"Das ist \"in Anführungszeichen\" und mit \\ Backslash." + +(let ((x (+ 1 2)) (y "blah")) ;; `let' highlighting. + (and (number? x) ;; `and' highlighting. + (string? y))) + +(let* ((x 2) (y (+ x 1))) ;; `let*' too. + (or (negative? x) ;; `or' anyways. + (negative? y))) + +(do ((vec (make-vector 5)) ;; `do' you may guess! + (i 0 (+ i 1))) + ((= i 5) vec) + (vector-set! vec i i)) + +(quasiquote ((+ 1 2) (unquote (+ 1 2)))) +;; same as: `((+ 1 2) ,(+ 1 2)) + +;; see above. +(quasiquote ((+ 1 2) (unquote-splicing (list 1 2 3)))) +;; same as: `((+ 1 2) ,@(+ 1 2)) + +;; not necessary. +(quote ()) + +(cond ((string? x) (string->symbol x)) ;; `cond' highlighting. + ((symbol? x) => (lambda (x) x)) ;; `=>' highlighting. + (else ;; `else' highlighting. + (error "Blah"))) + +(case x ;; `case' highlighting. + ((#t) 'true) ((#f) 'false) + ((()) 'null) + ((0) 'zero)) + +;; highlight `let-syntax' and `syntax-rules' . +(let-syntax ((when (syntax-rules () + ((when test stmt1 stmt2 ...) + ;; hl `begin' . + (if test (begin stmt1 stmt2 ...)))))) + (let ((if #t)) ;; here`if' is actually no keyword. + (when if (set! if 'now)) ;; nor here. + if)) + +(letrec-syntax ...) ;; hl `letrec-syntax'. + +(define-syntax when + (syntax-rules () + ((when test stmt1 stmt2 ...) + (if test (begin stmt1 stmt2 ...)))))) + +;; variable definitions. +(define natural-numbers ;; hl `define' and the var name + ;; endless stream of all natual numbers. + (letrec ((next-cell ;; hl `letrec'. + (lambda (x) ;; hl `lambda'. + ;; hl `delay' . + (cons x (delay (next-cell (+ x 1))))))) + (next-cell 0))) + +;; a procedure with unusual but allowed name. +(define 1+ + (lambda (x) + (+ x 1))) + +;; a predicate +(define between? + (lambda (x y z) + (if (and (>= x y) (<= x z)) + #t ;; True + #f))) ;; False. + +;; imperative procedure +(define set-something! + (lambda (required-argument another-one . all-remaining-args) + (set-car! another-one (lambda all-args + (set-cdr! required-argument + (append all-remaining-args + all-args)))))) + +(define compose + (lambda (f g) + (lambda (x) + (f (g x))))) + +;; syntactical sugar for procedure-definitions. +(define (compose f g) + (lambda (x) + (f (g x)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; NOW: Guile extensions ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; procedure-generator. +(define ((compose f g) x) + (f (g x))) + +;; scheme doesn't say, which chars may be in variables... +;; At least: Guile accepts umlauts +(define-private (timetr??? sprache) ;; hl `define-private'. + (list-dialekt? sprache)) + +(define-public x #t) ;; hl `define-public'. +(define-module (foo bar)) ;; hl `define-module'. +(define-macro (neither . exprs) ;; hl `define-macro'. + `(and ,@(map (lambda (x) `(not ,x)) exprs))) + +(defmacro neither exprs ;; `defmacro' as well. + `(and ,@(map (lambda (x) `(not ,x)) exprs))) + +;; hl, but I really don't know what this is supposed to do :-) +(define-syntax-macro ...) + +;; hl GOOPS-`defines' +(define-method (foo bar (baz ) qux) ...) +(define-class ...) +(define-generic foo) +(define-accessor bar) + +;; Keywords! +(blah #:foo 33 #:bar 44) + +;; another convention for symbols: +#{foo}# + +#{a +few +lines}# + +#{4711}# + +;; more chars. +#\nul #\nl #\esc #\bs #\bel #\syn #\ack #\sp ;; etc, utc, itc, oops (this is boring) + +#! + guile block-comment. +!# + +;; now, a bit hairy: +#! comment !# +still comment!!! +!# +'now-no-comment-anymore + +;; more precise: +#! comment !# +still comment +!# still comment! +!# +'now-no-comment-anymore + +(while (> foo 10) ;; Highlight `while'. + (set! foo (- foo 1)) + (catch #t ;; Highlight `catch'. + (lambda () (display foo)) + (lambda (key . args) + (if (eq? key 'system-error) + (break) ;; Highlight `break'. + (continue))))) ;; Highlight `continue'. \ No newline at end of file diff --git a/autotests/input/highlight.sh b/autotests/input/highlight.sh new file mode 100644 index 0000000..a354757 --- /dev/null +++ b/autotests/input/highlight.sh @@ -0,0 +1,207 @@ +#! /bin/sh +# This is a test script for the Katepart Bash Syntax Highlighting by +# Wilbert Berendsen. This is not runnable !!! + + +# The highlighting recognizes basic types of input, and has a few special cases that +# are all in FindCommands. The main objective is to create really proper nesting of +# (multiline) strings, variables, expressions, etc. + + + +# ============== Tests: =============== + +# basic types: +echo 'single quoted string' +echo "double quoted string" +echo $'string with esc\apes\x0din it' +echo $"string meant to be translated" + + +# comments: +# this is a comment +#this too +echo this is#nt a comment +dcop kate EditInterface#1 #this is + + +# brace expansion +mv my_file.{JPG,jpg} + + +# special characters are escaped: +echo \(output\) \&\| \> \< \" \' \* + + +# variable substitution: +echo $filename.ext +echo $filename_ext +echo ${filename}_ext +echo text${array[$subscript]}.text +echo text${array["string"]}.text +echo ${!prefix*} +echo ${!redir} +echo short are $_, $$, $?, ${@}, etc. +echo ${variable/a/d} +echo ${1:-default} + + +# expression subst: +echo $(( cd << ed + 1 )) + + +# command subst: +echo $(ls -l) +echo `cat myfile` + + +# file subst: +echo $(<$filename) +echo $( my_file.txt 2>&1 + + +# All substitutions also work in strings: +echo "subst ${in}side string" 'not $inside this ofcourse' +echo "The result is $(( $a + $b )). Thanks!" +echo "Your homedir contains `ls $HOME |wc -l` files." + + +# Escapes in strings: +p="String \` with \$ escapes \" "; + + +# keywords are black, builtins dark purple and common commands lighter purple +set +exit +login + + +# Other colorings: +error() { + cat /usr/bin/lesspipe.sh + runscript >& redir.bak + exec 3>&4 +} + + +# do - done make code blocks +while [ $p -lt $q ] +do + chown 0644 $file.$p +done + + +# braces as well +run_prog | sort -u | +{ + echo Header + while read a b d + do + echo $a/$b/$c + done + echo Footer +} + + +# Any constructions can be nested: +echo "A long string with $( + if [ $count -gt 100 ] ; then + echo "much" + else + echo "not much" + fi ) substitutions." ; + + +# Even the case construct is correctly folded: +test -f blaat && +( do_something + case $p in + *bak) + do_bak $p + ;; + *) + dont_bak $p + ;; + esac +) # despite the extra parentheses in the case construction. + + +# variable assignments: +DIR=/dev +p=`ls` +LC_ALL="nl" dcop 'kate*' +_VAR=val +ARR=(this is an array) +ARR2=([this]=too [and]="this too") +usage="$0 -- version $VERSION +Multiple lines of output +can be possible." +ANSWER=yes # here 'yes' isn't highlighed as command + + +# Some commands expect variable names, these are colored correctly: +export PATH=/my/bin:$PATH BLAAT +export A B D +local p=3 x y='\' +read x y z <<< $hallo +unset B +declare -a VAR1 VAR2 && exit +declare less a && b + +# options are recoqnized: +zip -f=file.zip +./configure --destdir=/usr +make destdir=/usr/ + + +# [[ and [ correctly need spaces to be regarded as structure, +# otherwise they are patterns (currently treated as normal text) +if [ "$p" == "" ] ; then + ls /usr/bin/[a-z]* +elif [[ $p == 0 ]] ; then + ls /usr/share/$p +fi + +# Fixed: +ls a[ab]* # dont try to interprete as assignment with subscript (fixed) +a[ab] +a[ab]=sa + + +# Here documents are difficult to catch: +cat > myfile << __EOF__ +You're right, this is definitely no bash code +But ls more $parameters should be expanded. +__EOF__ + + +# quoted: +cat << "EOF" | egrep "this" >&4 # the rest of the line is still considered bash source +You're right, this is definitely no bash code +But ls more $parameters should be expanded. :-> +EOF + + +# indented: +if true +then + cat <<- EOF + Indented text with a $dollar or \$two + EOF +elif [ -d $file ]; then + cat <<- "EOF" + Indented text without a $dollar + EOF +fi + + +case 1 in +2) echo xxx; +;; +1) echo yyy; +esac + +ls #should be outside of case 1 folding block \ No newline at end of file diff --git a/autotests/input/highlight.sh.syntax b/autotests/input/highlight.sh.syntax new file mode 100644 index 0000000..5b85af9 --- /dev/null +++ b/autotests/input/highlight.sh.syntax @@ -0,0 +1 @@ +Bash diff --git a/autotests/input/highlight.spec b/autotests/input/highlight.spec new file mode 100644 index 0000000..bc3b95b --- /dev/null +++ b/autotests/input/highlight.spec @@ -0,0 +1,212 @@ +# Test file for rpmspec.xml + +# Comments start with a # in column="0": + +# Some comment + +# When they don't start in column="0", that they are recognized as comments, but with an alert: + # This is a bad comment. +# RPM spec says clear that comments must start at the begin of the line. However, in practice +# the RPM software is more permissive, depending on the context. But for our syntax highlighting, +# we give, while recognizing the as comment, at least a little alert. Comments should not contain +# the character % (which is marked as warning), but 2 of them are okay: %%. TODO is higlighted. + +# A spec file starts with "Normal" context. Here, you can specify values for some tags: +Name: kradioripper-unstable # Note that here in no comment possible! +Name: name only _one_ word allowed +Name: %macro no further syntax check after macro! +# Some tags support only _one_ word as value +Version: 0.4test5 up-from-the-space-this-is-an-error +# Some tag can have parameters: Any char in paranthesis: +Summary: Recorder for internet radios (based on Streamripper) +Summary(de.UTF-8): Aufnahmeprogramm für Internetradios (basiert auf Streamripper) +# requiere free text: +License: License 1 2 3 +# requiere a well defines value: +Requires( / ( = ): Some, value() +# new type "switch" accepts: yes, no, 0, 1 +AutoReq: yes +AutoReq: yes invalid +AutoReq: %macro no further syntax check after macro! +AutoReq: no +AutoReq: 0 +AutoReq: 1 +# requiere a number: +Epoch: 123123 +Epoch: 123123 invalid +Epoch: %macro no further syntax check afer macro! +# If tags are used that are not known, they are not highlighted: +Invalidtag: Some value +Invalid content in this section (only tags are allowed) + +# You can use conditions in specs (highlighted with region markers): +%if 0%{?mandriva_version} +# numbers and strings are distingished: string: +%if lsdksfj +# number: +%if 23472398 +# string: +%if lksdjfsl72939 +# invalid: +%if 92437lsdkfjdsl +# valid: +%if "lsdfj %ksdf(sdfs) 3489" +Release: %mkrel 1.2 +%else +Release: 0 +%endif +# requiere a well defined value: +%ifos fixed_value +# You must use these special macros (%%if etc.) always at the start of the line - if not, +# that's bad but not an arror. You must also always use the specified form. Everything else is an +# error: + %if +something %if +%{if} +%if(some options) +# However, this are different macros and therefore correct: +%ifx +%{ifx} +%ifx(some options) + +# the \ is escaped in the line. At the end of the line it escapes the line break: +echo This is \" a text \\ and here\ +it continues. + +%define name value +%define invalid_näme value +%define macroname multi\ +line content with references like %0 %* %# %{-f} %{-f*} %1 %2 and so on +%global name value +%global invalid_näme value +%undefine name +%undefine name too-many-parameters + +# This special comment is treated and highlighted like a tag: +# norootforbuild +# It can't have parameters, so every following non-whitespace character is not good: +# norootforbuild DONT WRITE ANYTHING HERE! +# wrong spacing is also recognized: +# norootforbuild +# and also an indeet is not fine for norootforbuild: + # norootforbuild + +# This following "Conflicts" tag will be removed by set-version.sh, +# if it is a "kradioripper" release (and not a "kradioripper-unstable" release)... +Conflicts: kradioripper + + +%description +# Here, a new section starts. It contains a value for the RPM field "description" and is therefor +# colored like values: +A KDE program for ripping internet radios. Based on StreamRipper. + + +# A section start can have parameters: +%description -l de.UTF-8 +Ein KDE-Aufnahmeprogramm für Internetradios. Basiert auf StreamRipper. + +# These sections starts are errors: + %description not at the first line +%{description} wrong form +%description(no options allowed, only parameters!) + + +%prep +# This starts a section that defines the commands to prepare the build. +# q means quit. n sets the directory: +%setup -q -n kradioripper +echo Test +# Macros can have different forms: Valid: +%abc +%abcÄndOfMacro +%abc(def)EndOfMacro +%{abc}EndOfMacro +%{something but no single %}EndOfMacro +%{abc:def}EndOfMacro +%(abc) +# Invalid: +%ÄInvalidChar +% +%) +%} +# You can use macros inside of macro calls: Fine: +%{something %but no %{sin%(fine)gle} }EndOfMacro +# Bad: +%{No closing paranthesis (No syntax highlightig for this error available) + + +%build +cmake ./ -DCMAKE_INSTALL_PREFIX=%{_prefix} +%__make %{?jobs:-j %jobs} + + +%install +%if 0%{?suse_version} +%makeinstall +%suse_update_desktop_file kradioripper +%endif +%if 0%{?fedora_version} || 0%{?rhel_version} || 0%{?centos_version} +make install DESTDIR=%{buildroot} +desktop-file-install --delete-original --vendor fedora --dir=%{buildroot}/%{_datadir}/applications/kde4 %{buildroot}/%{_datadir}/applications/kde4/kradioripper.desktop +%endif +%if 0%{?mandriva_version} +%makeinstall_std +%endif + + +%clean +rm -rf "%{buildroot}" + + +%files +%defattr(-,root,root) +%if 0%{?fedora_version} || 0%{?rhel_version} || 0%{?centos_version} +%{_datadir}/applications/kde4/fedora-kradioripper.desktop +%else +%{_datadir}/applications/kde4/kradioripper.desktop +%endif +%{_bindir}/kradioripper +%{_datadir}/locale/*/LC_MESSAGES/kradioripper.mo +%if 0%{?mandriva_version} +# TODO The %%doc macro is actually broken for mandriva 2009 in build service... +%dir %{_datadir}/apps/kradioripper +%{_datadir}/apps/kradioripper/* +%else +%doc COPYING LICENSE LICENSE.GPL2 LICENSE.GPL3 NEWS WARRANTY +%dir %{_datadir}/kde4/apps/kradioripper +%{_datadir}/kde4/apps/kradioripper/* +%endif + + +%changelog +* Sun May 04 2008 email@email.com +- some text +- some text + in two lines +- some text + in two lines + + with subtext + - and more subtext + in two lines +* Tue Apr 24 2007 Name +- text + * When the star isn't at column 0, than it doesn't indicate + a new date +* Wen Sep 08 2003 Wrong weekday +* Mon Mai 08 2003 Wrong month +* Mon Sep 0 2003 bad day +* Mon Sep 8 2003 good day +* Mon Sep 08 2003 good day +* Mon Sep 32 2003 bad day +* Mon Sep 08 03 bad year +* Mon Sep 08 2003 Name +# When using macros, the error check is disabled: +* %myDataMacro Title of the entry +- Text + - can + - be + - indeeded + - without + - problems + diff --git a/autotests/input/highlight.t2t b/autotests/input/highlight.t2t new file mode 100644 index 0000000..5b5f379 --- /dev/null +++ b/autotests/input/highlight.t2t @@ -0,0 +1,90 @@ +txt2tags sample + + +%!--includeconf: config.t2t +% disabled here because there is no external file +%!preproc: 'JUST A TEST' ' ' +%!postproc: '(?i)()' ' shots\1' + +%!--include: menu.t2t + += Title 1 = + + +== My Subtitle 1 ==[some definition] + +Some examples: + +- A paragraph with **bold**, //italic// and --strike--. +- You can even __underline your docs__! + +- And use **//bold and italic//** +- or //**italic and bold**// + +Here is a nice pic: [img/t2tpowered.png]. + +- And a [link to a cool website http://txt2tags.sf.net]! + +- A table : + + || Name | Age | Gender | + | John | 33 | Male | + | Mary | 19 | Female | + + +``` A verbatim line + +And it's working for ``special code`` like this. + +``` +Unfortunately I can't color this verbatim content yet. +``` + + +== My Subtitle 2 == + + +Lorem ipsum etc +Lorem ipsum etc Lorem ipsum etc + +- Test d'écriture avec des accents à la française. Ça marche ou pas ? + +== My Subtitle 3 == + + +Lorem ipsum etc +Lorem ipsum etc + +Here is a direct link: http://kde.org + + +- Another boring part... + + + +=== My Subsubtitle 1 === + +//It's a level 3 header// + +- list 1 +- list 2 + - list 2b +- list 3 + + +=== My Subsubtitle 2 === + +//It's another level 3 header// + ++ ordered list 1 ++ list 2 + + list 2B + + list 2C ++ list 3 + + +== My Subtitle 4 == + +nothing to say here... + diff --git a/autotests/input/highlight.tcl b/autotests/input/highlight.tcl new file mode 100644 index 0000000..d6b7276 --- /dev/null +++ b/autotests/input/highlight.tcl @@ -0,0 +1,50 @@ +# tcl syntax highlighting sample script for Kate +# +# author: JM. Philippe 15/03/04 + +# escaped characters +set String \{ +set String \{ +set String \" +set String " \" " +set String " \{ " + +#comments and not comments +# is comments +;#is comments + # is comments +#

    is html comment

    +puts ok; # is comments +set String [string map { {»is not comments}} $String] +set String \#not_a_comment + +# blocks +proc test {arg1 {arg2 {}} {arg3 {fr fq r}}} { + if {1} {; #comments + set String \{; # not a block start + } +} + +proc test args { + set String \}; # not a block end +} + +# BEGIN - collapsable comments +# blablabla +# END + +# strings +set String "feqr feqr $gqer gqe" +set String "feqr +feqr \" $gqer \ +gqe +" +set String {feqr +feqr \{ $gqer \ +gqe +} + +# variables +set b+1 [incr b] +set {incr-b} ${b+1} +puts ${incr-b} diff --git a/autotests/input/highlight.tex b/autotests/input/highlight.tex new file mode 100644 index 0000000..b706f70 --- /dev/null +++ b/autotests/input/highlight.tex @@ -0,0 +1,73 @@ +% LaTeX test file for kate's syntax highlighting and code folding + +\ordinaryLaTeXcommandwithoption[10pt,a4paper]{article} +% BEGIN region +%comment, this is all ok % $ +\%no comments please +\\%comment +% END of region + +\newcommand{\nohighlighting} + +\section{normal} + +\ref{blue} +\pageref{blue} +\cite{blue} + +\begin{environmentshavespecialcolors} +normal +\end{environmentshavespecialcolors} + +$equations are green, \commands somewhat darker$ +normal +$$equations are green, \commands somewhat darker$$ +normal +\( +\frac{1}{2} +\begin{test} +\end{test} +\) +normal +\[ +%comment +displaymath +\] +normal +\begin{equation} +green\darkergreen +\begin{test} +\test +\end{test} +\end{equation} + +\begin{equation*} +green\darkergreen +%comment +\begin{test} +\test +\end{test} +\%no comment +\end{equation*} + +\{ %this should be comment + +\verb%this shouldn't be%and this should be normal text + +\begin{verbatim} +text inside a verbatim environment is also treated special $ %, +you can even put a \begin{verbatim} inside +\end{verbatim} + +normal + +\begin{Verbatim} +&@@#^%&^#$ +\end{Verbatim} + + +\begin{Verbatim*} +@*&^#@*(^#(*@& +\end{Verbatim*} + +normal \ No newline at end of file diff --git a/autotests/input/highlight.wrl b/autotests/input/highlight.wrl new file mode 100644 index 0000000..2fb4b41 --- /dev/null +++ b/autotests/input/highlight.wrl @@ -0,0 +1,41 @@ +#VRML V2.0 utf8 +# +# VRML highlighting test for Kate's syntax highlighting +# + +# Keywords +DEF, EXTERNPROTO, FALSE, IS, NULL, PROTO, ROUTE, TO, TRUE, USE, eventIn, +eventOut, exposedField, field + +# Data types +MFColor, MFFloat, MFInt32, MFNode. MFRotation, MFString, MFTime, MFVec2f, +MFVec3f, SFBool, SFColor, SFFloat, SFImage, SFInt32, SFNode, SFRotation, +SFString, SFTime, SFVec2f, SFVec3f + +# Predefined nodes +Anchor, Appearance, AudioClip, Background, Billboard, Box, Collision, Color, +ColorInterpolator, Cone, Coordinate, CoordinateInterpolator, Cylinder, +CylinderSensor, DirectionalLight, ElevationGrid, Extrusion, Fog, FontStyle, +Group, ImageTexture, IndexedFaceSet, IndexedLineSet, Inline, LOD, Material, +MovieTexture, NavigationInfo, Normal, NormalInterpolator, OrientationInterpolator, +PixelTexture, PlaneSensor, PointLight, PointSet, PositionInterpolator, +ProximitySensor, ScalarInterpolator, Script, Shape, Sound, Sphere, SphereSensor, +SpotLight, Switch, Text, TextureCoordinate, TextureTransform, TimeSensor, +TouchSensor, Transform, Viewpoint, VisibilitySensor, WorldInfo + +# Some real VRML constructs to see if highlighting of int, float etc. works +NavigationInfo { + avatarSize [0.25, 1.6, 0.75] + headlight TRUE + speed 1 + type ["WALK", "ANY"] + visibilityLimit 0.0 +} + +# some further testing for strings: linefeeds are allowed within strings +Text { + string ["some special in-string characters: \" \\ + some more text in the next line + and yet another line"] +} + diff --git a/autotests/input/highlight.xml b/autotests/input/highlight.xml new file mode 100644 index 0000000..007449c --- /dev/null +++ b/autotests/input/highlight.xml @@ -0,0 +1,67 @@ + + + + + +This is a pseudo XML file to test Kate's XML syntax highlighting. + +Doctype: + + +Processing instruction: + + +Comments: + + + +Comment inside element: + content + +Markup inside comment: + + +Empty element: + + + +Simple element plus content: + some content + some + content + +Namespace for elements and attributes: + content + content + +Elements containing allowed characters: + + + +Elements containing allowed start characters: + <:element foo="test"/> + <_element foo="test"/> + +Single quotes (the same as double quotes): + content + +Allowed Whitespace: + + content + +Entities: +   + å + å + å + И + 水 + + +Illegal XML, should not be highlighted: + <0foobar> -- no digit as first character + <-foo> -- no dash as first character diff --git a/autotests/input/highlight.xsl b/autotests/input/highlight.xsl new file mode 100644 index 0000000..f6e0efb --- /dev/null +++ b/autotests/input/highlight.xsl @@ -0,0 +1,109 @@ + + + + + + + + + +Linux at Home Links + + + + <xsl:value-of select="h:a/h:strong"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:value-of select="normalize-space($title)"/> + + + + + + + + + diff --git a/autotests/input/highlight.y b/autotests/input/highlight.y new file mode 100644 index 0000000..f7715e6 --- /dev/null +++ b/autotests/input/highlight.y @@ -0,0 +1,54 @@ +/* Yacc / Bison hl test file. + * It won't compile :-) Sure ! + */ + +%{ + +#include +using namespace std; + +extern KateParser *parser; + +%} + +%locations + +%union { + int int_val; + double double_val; + bool bool_val; + char *string_val; + char *ident_val; + struct var *v; + void *ptr; +} + +%token TOK_NOT_EQUAL "!=" +%token TOK_LESSER_E "<=" +%token TOK_GREATER_E ">=" +%token TOK_EQUAL_2 "==" + +%type type type_proc + +%% + +prog: KW_PROGRAM ident { parser->start($2); } prog_beg_glob_decl instructions { parser->endproc(0); } dev_procedures KW_ENDP ; + +number: integer_number + | TOK_DOUBLE + { + $$ = new var; + $$->type = KW_REEL; + $$->cl = var::LITTERAL; + $$->real = $1; + }; + +%% + +#include + +int main(void) +{ + puts("Hello, World!"); + return 0; +} diff --git a/autotests/input/highlight_lpc.c b/autotests/input/highlight_lpc.c new file mode 100644 index 0000000..fe5c629 --- /dev/null +++ b/autotests/input/highlight_lpc.c @@ -0,0 +1,64 @@ +// NOTE: This is a test file for kate's LPC syntax highlighting. + +// This is a Single-Line Comment +/* This is a Multi- + Line Comment */ + +// This again is a Single-Line Comment which should end here /* + +// And this is an evil single line comment \ + which should include this and the next line because of the \ + Do not use this style at home, kids. +// BEGIN region marker + +// END of region marker + +private void create() +{ +// Some Preprocessor stuff: +#define SOME_STUFF if(foo("bar")) \ + { \ + bar("foo"); \ + } // Preprocessor, Keyword, Preprocessor-String, Multiline + + // Some closures: + #'create; + #'?!; + + + /* Some other Data Types: */ + + int i = 1; // Integer. + float b = 2.34; // Float. + int c = 0b001; // Binary + int e = 0x019Beef; // Hexadecimal + int f = 0o2345; // Octal + string a = "Wheee"; // String + string x = "Wheee\ + heee"; // Multi-Line String, again, don't use this. + + + + /* Some keywords: */ + if(1) + { + switch(2) + { + case 3: + 4; + break; + } + } + + else + { + return 0; + } +} + +/* +WARNING: If the above function is part of a multi-line comment, + it's buggy. The WARNING: itself should be a comment-keyword. + That's not actually part of the language, but simply used + to highlight important stuff inside comments like TODO: etc. +*/ diff --git a/autotests/input/highlight_lpc.c.syntax b/autotests/input/highlight_lpc.c.syntax new file mode 100644 index 0000000..2016d4f --- /dev/null +++ b/autotests/input/highlight_lpc.c.syntax @@ -0,0 +1 @@ +LPC diff --git a/autotests/input/highlight_ocaml.ml b/autotests/input/highlight_ocaml.ml new file mode 100644 index 0000000..dc1717a --- /dev/null +++ b/autotests/input/highlight_ocaml.ml @@ -0,0 +1,105 @@ +(* ocaml test file -- a big stew of Objective Caml syntax to use to + test Kate's syntax highlighting. This will not run! :-) *) + +(* First a little piece of real OCaml that should look right: *) + + #load "basic";; + (* Return a default value for a BASIC variable given its identifer. *) + let default_value (ident : string) : basic_value = + assert (String.length ident > 0); + match ident.[String.length ident - 1] with + | '$' -> Str "" + | '%' -> Int 0 + | '!' -> Flt 0.0 + | _ -> Flt 0.0 + ;; + +(* Directives: *) +#load "pa_o";; + #load "pa_o";; +object # meth ;; (* not a directive - a method call *) +object + # meth ;; (* not a directive - a method call *) + +(* OCaml keywords: *) +and as assert asr (* etc. there so many... *) + +(* Additional OCaml Revised Syntax keywords: *) +(* These are in a seperate category so they can be coloured to look + like identifiers when ordinary OCaml syntax is being used: *) +declare where value + +(* There's no way to reliably highlight all OCaml type expressions, + (they can be very complex) so just the built-in type names are highlighted.*) +exn lazy_t format unit int real char string ref array bool list option + + +let integers : int list = [ + 123456789; (* decimal *) + -0xabcedf0123456789; (* hexadecimal *) + 0xABCDEF0123456789; (* hexadecimal *) + -0o1234567; (* octal *) + 0b01001010101010; (* binary *) + -0Xabcedf0123456789; (* hexadecimal *) + 0XABCDEF0123456789; (* hexadecimal *) + -0O1234567; (* octal *) + 0B01001010101010; (* binary *) + -123_456_789; (* Underscores are allowed in numeric constants. *) + 0x_abce_df01_2345_6789; + -0o12_34_567; + 0b_0100_1010_1010_1101; +];; + +let floats : real list = [ + 12345.6789; + -1.23456789e4; (* All variations of the exponent form *) + 1.23456789e+4; + -1.23456789e-4; + 1.23456789E-4; + -1.23456789E+4; + 12_345.6789; (* Underscores are allowed in numeric constants. *) + -1.23_456_789e+4; + 12_345.6789; +];; + +let characters : char list = [ + 'a'; + ' '; + 'ä'; + '\n'; '\r'; '\t'; '\b'; (* Control characters. Only these four: not the full C-language range. *) + '\000'; '\128'; (* Decimal character codes. These are always 3 digits. *) + '\x02'; '\xff'; '\xFF'; (* Hexadecimal character codes. These are always 3 digits. *) + '\\'; '\''; '\"'; '"' (* Quote character escapes. *) +];; + +(* Quotes used to mark constants in parsers should + not be confused with character constant quotes. + "Ticks" at the end of identifiers should + not be confused with character constant quotes. *) +let basic_identifier = + parser + [< ''F'; ''N'; name = s >] -> ID (s, 'f') + | [< name = s' >] -> ID (s','i') +;; + +let strings : string list = [ + ""; (* Empty string *) + "a"; " "; "ä"; "ab"; + "A\nB"; "A\rB"; "A\tB"; "A\bB"; (* Control characters. Only these four: not the full C-language range. *) + "A\000B"; "A\128B"; (* Decimal character codes. These are always 3 digits. *) + "A\x02B"; "A\xffB"; "A\xFFB"; (* Hexadecimal character codes. These are always 3 digits. *) + "A\\B"; "A\'B"; "A'B"; "A\"B"; (* Quote character escapes. *) + "A multiline\ + string"; +]; + +let camlp4_quotations = [ + <> ; + <:QUOTE> ; + <:QUÖTÈ> ; + << A quote with an escape: \>> (end-quote symbol) >> ; + << A quote with an escape: \<< (plain start quote-symbol) >> ; + << A quote with an escape: \<:Trouvé< (labelled start-quote symbol) >> ; +];; + +(* end *) diff --git a/autotests/input/highlight_octave.m b/autotests/input/highlight_octave.m new file mode 100644 index 0000000..1f96036 --- /dev/null +++ b/autotests/input/highlight_octave.m @@ -0,0 +1,74 @@ +##===================================================== +% Octave test code for Kate/Kwrite syntax highlighting +% (shamelessly copied from Matlab's, since the two +% are very similar) +% kate: hl Octave; +##===================================================== + +% Numbers _____________________________________________ +5, 5.5, .1, 0.1, 0.4e5, 1.2e-5, 5i, 5.3i, 6j, .345+3i +5', 5.5', .1', 0.1', 0.4e5', 1.2e-5', 5i', 5.3i', 6j', .345+3i' + +% Operators ___________________________________________ +% relational operators +'asdf'~=4, c<=4, d>=4, ab, a==b, b||c, b&&c +% elementwise arithmetic operators +a.^b, a.*b a./b, 1:4:5 +% single-character binary arithmetic +a+3, a-3, a*2, a^3, a/3, a\3, a|b, a&b +% unary operators +a = ~g; g = @sfdgdsf(sdfsd,345); g.' + 1i.' - ('asdf').' +% separators and delimiter +(asd),[sadf];{asdf},;;,;;;() +% continuation +a = 1+ ... + 2; + +% Strings and adjoint _________________________________ +% incomplete strings +'string +'str'' +'str''ing +'str''\' +% complete strings +'string' % simple string +'''' '\'' % strings containing ' +'str''ing' % one string containing ' +'string' 'string' % two strings +'asdf' "asdf""" variable % two strings and a variable +'asdf''asdf'' fsgdfg' + (asdf)' - 'asdf'.' + []''''.';'' +'sadf'.' % string transpose +% adjoint +{'asdf'}' + 1 +('asdf')' + 1 +['asdf']' + 1 +'' var''' % empty string, var with >1 adjoints +[5]'*{5}'*('asd')'.'+(5)'*6'*asdf'*asdf'.' % many adjoints +A'*B + 1 % adjoint +A.'*B + 1 % transpose +A.'.'*B + 1 % double transpose +A'.' + 1 % adjoint, then transpose +A.'' % transpose, then adjoint + +% System command ______________________________________ +!hostname +!cp * /tmp + +% Reserved keywords ___________________________________ +function, persistent, global +endfunction + +switch, case, otherwise +endswitch + +if, else, elseif +endif + +try, end_try_catch +for, while, break, continue +endfor + +endwhile +return +function, FUNCTION, Function % case sensitive! +endfunction \ No newline at end of file diff --git a/autotests/input/highlight_octave.m.syntax b/autotests/input/highlight_octave.m.syntax new file mode 100644 index 0000000..65d755f --- /dev/null +++ b/autotests/input/highlight_octave.m.syntax @@ -0,0 +1 @@ +Octave diff --git a/autotests/input/learnelixir.exs b/autotests/input/learnelixir.exs new file mode 100644 index 0000000..1f51bd1 --- /dev/null +++ b/autotests/input/learnelixir.exs @@ -0,0 +1,397 @@ +# Original: https://learnxinyminutes.com/docs/elixir/ + +# Single line comments start with a number symbol. + +# There's no multi-line comment, +# but you can stack multiple comments. + +# To use the elixir shell use the `iex` command. +# Compile your modules with the `elixirc` command. + +# Both should be in your path if you installed elixir correctly. + +## --------------------------- +## -- Basic types +## --------------------------- + +# There are numbers +3 # integer +0x1F # integer +3.0 # float + +# Atoms, that are literals, a constant with name. They start with `:`. +:hello # atom + +# Tuples that are stored contiguously in memory. +{1,2,3} # tuple + +# We can access a tuple element with the `elem` function: +elem({1, 2, 3}, 0) #=> 1 + +# Lists that are implemented as linked lists. +[1,2,3] # list + +# We can access the head and tail of a list as follows: +[head | tail] = [1,2,3] +head #=> 1 +tail #=> [2,3] + +# In elixir, just like in Erlang, the `=` denotes pattern matching and +# not an assignment. +# +# This means that the left-hand side (pattern) is matched against a +# right-hand side. +# +# This is how the above example of accessing the head and tail of a list works. + +# A pattern match will error when the sides don't match, in this example +# the tuples have different sizes. +# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2} + +# There are also binaries +<<1,2,3>> # binary + +# Strings and char lists +"hello" # string +'hello' # char list + +# Multi-line strings +""" +I'm a multi-line +string. +""" +#=> "I'm a multi-line\nstring.\n" + +# Strings are all encoded in UTF-8: +"héllò" #=> "héllò" + +# Strings are really just binaries, and char lists are just lists. +<> #=> "abc" +[?a, ?b, ?c] #=> 'abc' + +# `?a` in elixir returns the ASCII integer for the letter `a` +?a #=> 97 + +# To concatenate lists use `++`, for binaries use `<>` +[1,2,3] ++ [4,5] #=> [1,2,3,4,5] +'hello ' ++ 'world' #=> 'hello world' + +<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>> +"hello " <> "world" #=> "hello world" + +# Ranges are represented as `start..end` (both inclusive) +1..10 #=> 1..10 +lower..upper = 1..10 # Can use pattern matching on ranges as well +[lower, upper] #=> [1, 10] + +## --------------------------- +## -- Operators +## --------------------------- + +# Some math +1 + 1 #=> 2 +10 - 5 #=> 5 +5 * 2 #=> 10 +10 / 2 #=> 5.0 + +# In elixir the operator `/` always returns a float. + +# To do integer division use `div` +div(10, 2) #=> 5 + +# To get the division remainder use `rem` +rem(10, 3) #=> 1 + +# There are also boolean operators: `or`, `and` and `not`. +# These operators expect a boolean as their first argument. +true and true #=> true +false or true #=> true +# 1 and true #=> ** (ArgumentError) argument error + +# Elixir also provides `||`, `&&` and `!` which accept arguments of any type. +# All values except `false` and `nil` will evaluate to true. +1 || true #=> 1 +false && 1 #=> false +nil && 20 #=> nil +!true #=> false + +# For comparisons we have: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` and `>` +1 == 1 #=> true +1 != 1 #=> false +1 < 2 #=> true + +# `===` and `!==` are more strict when comparing integers and floats: +1 == 1.0 #=> true +1 === 1.0 #=> false + +# We can also compare two different data types: +1 < :hello #=> true + +# The overall sorting order is defined below: +# number < atom < reference < functions < port < pid < tuple < list < bit string + +# To quote Joe Armstrong on this: "The actual order is not important, +# but that a total ordering is well defined is important." + +## --------------------------- +## -- Control Flow +## --------------------------- + +# `if` expression +if false do + "This will never be seen" +else + "This will" +end + +# There's also `unless` +unless true do + "This will never be seen" +else + "This will" +end + +# Remember pattern matching? Many control-flow structures in elixir rely on it. + +# `case` allows us to compare a value against many patterns: +case {:one, :two} do + {:four, :five} -> + "This won't match" + {:one, x} -> + "This will match and bind `x` to `:two`" + _ -> + "This will match any value" +end + +# It's common to bind the value to `_` if we don't need it. +# For example, if only the head of a list matters to us: +[head | _] = [1,2,3] +head #=> 1 + +# For better readability we can do the following: +[head | _tail] = [:a, :b, :c] +head #=> :a + +# `cond` lets us check for many conditions at the same time. +# Use `cond` instead of nesting many `if` expressions. +cond do + 1 + 1 == 3 -> + "I will never be seen" + 2 * 5 == 12 -> + "Me neither" + 1 + 2 == 3 -> + "But I will" +end + +# It is common to set the last condition equal to `true`, which will always match. +cond do + 1 + 1 == 3 -> + "I will never be seen" + 2 * 5 == 12 -> + "Me neither" + true -> + "But I will (this is essentially an else)" +end + +# `try/catch` is used to catch values that are thrown, it also supports an +# `after` clause that is invoked whether or not a value is caught. +try do + throw(:hello) +catch + message -> "Got #{message}." +after + IO.puts("I'm the after clause.") +end +#=> I'm the after clause +# "Got :hello" + +## --------------------------- +## -- Modules and Functions +## --------------------------- + +# Anonymous functions (notice the dot) +square = fn(x) -> x * x end +square.(5) #=> 25 + +# They also accept many clauses and guards. +# Guards let you fine tune pattern matching, +# they are indicated by the `when` keyword: +f = fn + x, y when x > 0 -> x + y + x, y -> x * y +end + +f.(1, 3) #=> 4 +f.(-1, 3) #=> -3 + +# Elixir also provides many built-in functions. +# These are available in the current scope. +is_number(10) #=> true +is_list("hello") #=> false +elem({1,2,3}, 0) #=> 1 + +# You can group several functions into a module. Inside a module use `def` +# to define your functions. +defmodule Math do + def sum(a, b) do + a + b + end + + def square(x) do + x * x + end +end + +Math.sum(1, 2) #=> 3 +Math.square(3) #=> 9 + +# To compile our simple Math module save it as `math.ex` and use `elixirc` +# in your terminal: elixirc math.ex + +# Inside a module we can define functions with `def` and private functions with `defp`. +# A function defined with `def` is available to be invoked from other modules, +# a private function can only be invoked locally. +defmodule PrivateMath do + def sum(a, b) do + do_sum(a, b) + end + + defp do_sum(a, b) do + a + b + end +end + +PrivateMath.sum(1, 2) #=> 3 +# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError) + +# Function declarations also support guards and multiple clauses: +defmodule Geometry do + def area({:rectangle, w, h}) do + w * h + end + + def area({:circle, r}) when is_number(r) do + 3.14 * r * r + end +end + +Geometry.area({:rectangle, 2, 3}) #=> 6 +Geometry.area({:circle, 3}) #=> 28.25999999999999801048 +# Geometry.area({:circle, "not_a_number"}) +#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 + +# Due to immutability, recursion is a big part of elixir +defmodule Recursion do + def sum_list([head | tail], acc) do + sum_list(tail, acc + head) + end + + def sum_list([], acc) do + acc + end +end + +Recursion.sum_list([1,2,3], 0) #=> 6 + +# Elixir modules support attributes, there are built-in attributes and you +# may also add custom ones. +defmodule MyMod do + @moduledoc """ + This is a built-in attribute on a example module. + """ + + @my_data 100 # This is a custom attribute. + IO.inspect(@my_data) #=> 100 +end + +## --------------------------- +## -- Structs and Exceptions +## --------------------------- + +# Structs are extensions on top of maps that bring default values, +# compile-time guarantees and polymorphism into Elixir. +defmodule Person do + defstruct name: nil, age: 0, height: 0 +end + +joe_info = %Person{ name: "Joe", age: 30, height: 180 } +#=> %Person{age: 30, height: 180, name: "Joe"} + +# Access the value of name +joe_info.name #=> "Joe" + +# Update the value of age +older_joe_info = %{ joe_info | age: 31 } +#=> %Person{age: 31, height: 180, name: "Joe"} + +# The `try` block with the `rescue` keyword is used to handle exceptions +try do + raise "some error" +rescue + RuntimeError -> "rescued a runtime error" + _error -> "this will rescue any error" +end +#=> "rescued a runtime error" + +# All exceptions have a message +try do + raise "some error" +rescue + x in [RuntimeError] -> + x.message +end +#=> "some error" + +## --------------------------- +## -- Concurrency +## --------------------------- + +# Elixir relies on the actor model for concurrency. All we need to write +# concurrent programs in elixir are three primitives: spawning processes, +# sending messages and receiving messages. + +# To start a new process we use the `spawn` function, which takes a function +# as argument. +f = fn -> 2 * 2 end #=> #Function +spawn(f) #=> #PID<0.40.0> + +# `spawn` returns a pid (process identifier), you can use this pid to send +# messages to the process. To do message passing we use the `send` operator. +# For all of this to be useful we need to be able to receive messages. This is +# achieved with the `receive` mechanism: + +# The `receive do` block is used to listen for messages and process +# them when they are received. A `receive do` block will only +# process one received message. In order to process multiple +# messages, a function with a `receive do` block must recursively +# call itself to get into the `receive do` block again. + +defmodule Geometry do + def area_loop do + receive do + {:rectangle, w, h} -> + IO.puts("Area = #{w * h}") + area_loop() + {:circle, r} -> + IO.puts("Area = #{3.14 * r * r}") + area_loop() + end + end +end + +# Compile the module and create a process that evaluates `area_loop` in the shell +pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0> +# Alternatively +pid = spawn(Geometry, :area_loop, []) + +# Send a message to `pid` that will match a pattern in the receive statement +send pid, {:rectangle, 2, 3} +#=> Area = 6 +# {:rectangle,2,3} + +send pid, {:circle, 2} +#=> Area = 12.56000000000000049738 +# {:circle,2} + +# The shell is also a process, you can use `self` to get the current pid +self() #=> #PID<0.27.0> diff --git a/autotests/input/light52_muldiv.vhdl b/autotests/input/light52_muldiv.vhdl new file mode 100644 index 0000000..723f154 --- /dev/null +++ b/autotests/input/light52_muldiv.vhdl @@ -0,0 +1,239 @@ +-------------------------------------------------------------------------------- +-- light52_muldiv.vhdl -- Simple multiplier/divider module. +-------------------------------------------------------------------------------- +-- The 8051 mul and div instructions are both unsigned and operands are 8 bit. +-- +-- This module implements the division as a sequential state machine which takes +-- 8 cycles to complete. +-- The multiplier can be implemented as sequential or as combinational, in which +-- case it will use a DSP block in those architectures that support it. +-- No attempt has been made to make this module generic or reusable. +-- +-- If you want a combinational multiplier but don't want to waste a DSP block +-- in this module, you need to modify this file adding whatever synthesis +-- pragmas your tool of choice needs. +-- +-- Note that unlike the division state machine, the combinational product logic +-- is always operating: when SEQUENTIAL_MULTIPLIER=true, prod_out equals +-- data_a * data_b with a latency of 1 clock cycle, and mul_ready is hardwired +-- to '1'. +-- +-- FIXME explain division algorithm. +-------------------------------------------------------------------------------- +-- GENERICS: +-- +-- SEQUENTIAL_MULTIPLIER -- Sequential vs. combinational multiplier. +-- When true, a sequential implementation will be used for the multiplier, +-- which will usually save a lot of logic or a dedicated multiplier. +-- When false, a combinational registered multiplier will be used. +-- +-------------------------------------------------------------------------------- +-- INTERFACE SIGNALS: +-- +-- clk : Clock, active rising edge. +-- reset : Synchronous reset. Clears only the control registers not +-- visible to the programmer -- not the output registers. +-- +-- data_a : Numerator input, should be connected to the ACC register. +-- data_b : Denominator input, should be connected to the B register. +-- start : Assert for 1 cycle to start the division state machine +-- (and the product if SEQUENTIAL_MULTIPLIER=true); +-- +-- prod_out : Product output, valid only when mul_ready='1'. +-- quot_out : Quotient output, valid only when div_ready='1'. +-- rem_out : Remainder output, valid only when div_ready='1'. +-- div_ov_out : Division overflow flag, valid only when div_ready='1'. +-- mul_ov_out : Product overflow flag, valid only when mul_ready='1'. +-- +-- mul_ready : Asserted permanently if SEQUENTIAL_MULTIPLIER=false. +-- div_ready : Deasserted the cycle after start is asserted. +-- Asserted when the division has completed. +-- +-------------------------------------------------------------------------------- +-- Copyright (C) 2012 Jose A. Ruiz +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source 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 Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.light52_pkg.all; +use work.light52_ucode_pkg.all; + +entity light52_muldiv is + generic ( + SEQUENTIAL_MULTIPLIER : boolean := false + ); + port( + clk : in std_logic; + reset : in std_logic; + + data_a : in t_byte; + data_b : in t_byte; + start : in std_logic; + + prod_out : out t_word; + quot_out : out t_byte; + rem_out : out t_byte; + div_ov_out : out std_logic; + mul_ov_out : out std_logic; + + mul_ready : out std_logic; + div_ready : out std_logic + ); +end entity light52_muldiv; + +architecture sequential of light52_muldiv is + +signal bit_ctr : integer range 0 to 8; + +signal b_shift_reg : t_word; + +signal den_ge_256 : std_logic; +signal num_ge_den : std_logic; +signal sub_num : std_logic; + +signal denominator : t_byte; +signal rem_reg : t_byte; +signal quot_reg : t_byte; +signal prod_reg : t_word; +signal ready : std_logic; + +signal load_regs : std_logic; + +begin + +-- Control logic --------------------------------------------------------------- + +control_counter: process(clk) +begin + if clk'event and clk='1' then + if reset='1' then + bit_ctr <= 8; + else + if load_regs='1' then + bit_ctr <= 0; + elsif bit_ctr /= 8 then + bit_ctr <= bit_ctr + 1; + end if; + end if; + end if; +end process control_counter; + +-- Internal signal ready is asserted after 8 cycles. +-- The sequential multiplier will use this signal too, IF it takes 8 cycles. + +ready <= '1' when bit_ctr >= 8 else '0'; + + +---- Divider logic ------------------------------------------------------------- + +-- What we do is a simple base-2 'shift-and-subtract' algorithm that takes +-- 8 cycles to complete. We can get away with this because we deal with unsigned +-- numbers only. + +divider_registers: process(clk) +begin + if clk'event and clk='1' then + -- denominator shift register + if load_regs='1' then + b_shift_reg <= "0" & data_b & "0000000"; + -- Division overflow can be determined upon loading B reg data. + -- OV will be raised only on div-by-zero. + if data_b=X"00" then + div_ov_out <= '1'; + else + div_ov_out <= '0'; + end if; + else + b_shift_reg <= "0" & b_shift_reg(b_shift_reg'high downto 1); + end if; + + -- numerator register + if load_regs='1' then + rem_reg <= data_a; + elsif bit_ctr/=8 and sub_num='1' then + rem_reg <= rem_reg - denominator; + end if; + + --- quotient register + if load_regs='1' then + quot_reg <= (others => '0'); + elsif bit_ctr/=8 then + quot_reg <= quot_reg(quot_reg'high-1 downto 0) & sub_num; + end if; + + load_regs <= start; + end if; +end process divider_registers; + +denominator <= b_shift_reg(7 downto 0); + +-- The 16-bit comparison between b_shift_reg (denominator) and the zero-extended +-- rem_reg (numerator) can be simplified by splitting it in 2: +-- If the shifted denominator high byte is not zero, it is >=256... +den_ge_256 <= '1' when b_shift_reg(15 downto 8) /= X"00" else '0'; +-- ...otherwise we need to compare the low bytes. +num_ge_den <= '1' when rem_reg >= denominator else '0'; +sub_num <= '1' when den_ge_256='0' and num_ge_den='1' else '0'; + + +quot_out <= quot_reg; +prod_out <= prod_reg; +rem_out <= rem_reg; + +div_ready <= ready; + +---- Multiplier logic ---------------------------------------------------------- + +---- Combinational multiplier ----------------------------- +multiplier_combinational: if not SEQUENTIAL_MULTIPLIER generate + +registered_combinational_multiplier:process(clk) +begin + if clk'event and clk='1' then + prod_reg <= data_a * data_b; -- t_byte is unsigned + end if; +end process registered_combinational_multiplier; + +-- The multiplier output is valid in the cycle after the operands are loaded, +-- so by the time MUL is executed it's already done. +mul_ready <= '1'; + +mul_ov_out <= '1' when prod_reg(15 downto 8)/=X"00" else '0'; +prod_out <= prod_reg; + +end generate multiplier_combinational; + +---- Sequential multiplier -------------------------------- +multiplier_sequential: if SEQUENTIAL_MULTIPLIER generate + +assert false +report "Sequential multiplier implementation not done yet."& + " Use combinational implementation." +severity failure; + +end generate multiplier_sequential; + +end sequential; diff --git a/autotests/input/light52_tb.vhdl b/autotests/input/light52_tb.vhdl new file mode 100644 index 0000000..4905de1 --- /dev/null +++ b/autotests/input/light52_tb.vhdl @@ -0,0 +1,180 @@ +-------------------------------------------------------------------------------- +-- light52_tb.vhdl -- +-------------------------------------------------------------------------------- +-- This test bench simulates the execution of some program (whose object code +-- is in package obj_code_pkg, in the form of a memory init constant) and logs +-- the execution to a text file called 'hw_sim_log.txt' (light52_tb_pkg.vhdl). +-- +-- This test bench does no actual tests on the core. Instead, the simulation log +-- is meant to be matched against the simulation log produced by running the +-- same program on the software simulator B51 (also included with this project). +-- +-- This will catch errors in the implementation of the CPU if the simulated +-- program has anough coverage -- the opcode tester is meant to cover all CPU +-- opcodes in many (not all) of their corner cases. +-- This scheme will not help in catching errors in the peripheral modules, +-- mainly because the current version of B51 does not simulate them. +-- +-------------------------------------------------------------------------------- +-- Copyright (C) 2012 Jose A. Ruiz +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the GNU Lesser General +-- Public License as published by the Free Software Foundation; +-- either version 2.1 of the License, or (at your option) any +-- later version. +-- +-- This source 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 Lesser General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Lesser General +-- Public License along with this source; if not, download it +-- from http://www.opencores.org/lgpl.shtml +-------------------------------------------------------------------------------- + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use std.textio.all; + +use work.light52_pkg.all; +use work.obj_code_pkg.all; +use work.light52_tb_pkg.all; +use work.txt_util.all; + +entity light52_tb is +generic (BCD : boolean := true); +end; + + +architecture testbench of light52_tb is + +-------------------------------------------------------------------------------- +-- Simulation parameters +-- FIXME these should be in parameter package + +-- Simulated clock period is the same as the usual target, the DE-1 board +constant T : time := 20 ns; -- 50MHz +constant SIMULATION_LENGTH : integer := 400000; + +-------------------------------------------------------------------------------- +-- MPU interface + +signal clk : std_logic := '0'; +signal reset : std_logic := '1'; + +signal p0_out : std_logic_vector(7 downto 0); +signal p1_out : std_logic_vector(7 downto 0); +signal p2_in : std_logic_vector(7 downto 0); +signal p3_in : std_logic_vector(7 downto 0); + +signal external_irq : std_logic_vector(7 downto 0); + +signal txd, rxd : std_logic; + +-------------------------------------------------------------------------------- +-- Logging signals & simulation control + +-- Asserted high to disable the clock and terminate the simulation. +signal done : std_logic := '0'; + +-- Log file +file log_file: TEXT open write_mode is "hw_sim_log.txt"; +-- Console output log file +file con_file: TEXT open write_mode is "hw_sim_console_log.txt"; +-- Info record needed by the logging fuctions +signal log_info : t_log_info; + +begin + +---- UUT instantiation --------------------------------------------------------- + +uut: entity work.light52_mcu + generic map ( + IMPLEMENT_BCD_INSTRUCTIONS => BCD, + CODE_ROM_SIZE => work.obj_code_pkg.XCODE_SIZE, + XDATA_RAM_SIZE => work.obj_code_pkg.XDATA_SIZE, + OBJ_CODE => work.obj_code_pkg.object_code + ) + port map ( + clk => clk, + reset => reset, + + txd => txd, + rxd => rxd, + + external_irq => external_irq, + + p0_out => p0_out, + p1_out => p1_out, + p2_in => p2_in, + p3_in => p3_in + ); + + -- UART is looped back in the test bench. + rxd <= txd; + + -- I/O ports are looped back and otherwise unused. + p2_in <= p0_out; + p3_in <= p1_out; + + -- External IRQ inputs are tied to port P1 for test purposes + external_irq <= p1_out; + + ---- Master clock: free running clock used as main module clock ------------ + run_master_clock: process(done, clk) + begin + if done = '0' then + clk <= not clk after T/2; + end if; + end process run_master_clock; + + + ---- Main simulation process: reset MCU and wait for fixed period ---------- + + drive_uut: process + begin + -- Leave reset asserted for a few clock cycles... + reset <= '1'; + wait for T*4; + reset <= '0'; + + -- ...and wait for the test to hit a termination condition (evaluated by + -- function log_cpu_activity) or to just timeout. + wait for T*SIMULATION_LENGTH; + + -- If we arrive here, the simulation timed out (termination conditions + -- trigger a failed assertion). + -- So print a timeout message and quit. + print("TB timed out."); + done <= '1'; + wait; + + end process drive_uut; + + + -- Logging process: launch logger functions -------------------------------- + log_execution: process + begin + -- Log cpu activity until done='1'. + log_cpu_activity(clk, reset, done, "/uut", + log_info, work.obj_code_pkg.XCODE_SIZE, "log_info", + X"0000", log_file, con_file); + + -- Flush console log file when finished. + log_flush_console(log_info, con_file); + + wait; + end process log_execution; + +end architecture testbench; diff --git a/autotests/input/meson.build b/autotests/input/meson.build new file mode 100644 index 0000000..d6dd6e6 --- /dev/null +++ b/autotests/input/meson.build @@ -0,0 +1,21 @@ +# Unit test for Meson syntax highlight. License: LGPL +project('projectname', 'cpp') + + + +sourcefiles = ['a.cpp', 'b.cpp'] + +foreach sourcefile : sourcefiles + message('this is a source file: ' + sourcefile) +endforeach + +x=1 +if x+1 == 2 and x-1 == 0 + message('I can work in this universe!') +endif + +subprojectresult = subproject('mysubprojectdir') + +mysharedlib = shared_library('libraryname', sourcefiles, linkwith: subprojectresult.staticlib) + +executable('myprogram', ['test.cpp'], linkwith: mysharedlib) diff --git a/autotests/input/or1200_dc_fsm.v b/autotests/input/or1200_dc_fsm.v new file mode 100644 index 0000000..e3d80ec --- /dev/null +++ b/autotests/input/or1200_dc_fsm.v @@ -0,0 +1,563 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// OR1200's DC FSM //// +//// //// +//// This file is part of the OpenRISC 1200 project //// +//// http://opencores.org/project,or1k //// +//// //// +//// Description //// +//// Data cache state machine //// +//// //// +//// To Do: //// +//// - Test error during line read or write //// +//// //// +//// Author(s): //// +//// - Damjan Lampret, lampret@opencores.org //// +//// - Julius Baxter, julius@opencores.org //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000, 2010 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// $Log: or1200_dc_fsm.v,v $ +// Revision 2.0 2010/06/30 11:00:00 ORSoC +// Minor update: +// Bugs fixed. +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on +`include "or1200_defines.v" + +`define OR1200_DCFSM_IDLE 3'd0 +`define OR1200_DCFSM_CLOADSTORE 3'd1 +`define OR1200_DCFSM_LOOP2 3'd2 +`define OR1200_DCFSM_LOOP3 3'd3 +`define OR1200_DCFSM_LOOP4 3'd4 +`define OR1200_DCFSM_FLUSH5 3'd5 +`define OR1200_DCFSM_INV6 3'd6 +`define OR1200_DCFSM_WAITSPRCS7 3'd7 + + + +// +// Data cache FSM for cache line of 16 bytes (4x singleword) +// + +module or1200_dc_fsm + ( + // Clock and reset + clk, rst, + + // Internal i/f to top level DC + dc_en, dcqmem_cycstb_i, dcqmem_ci_i, dcqmem_we_i, dcqmem_sel_i, + tagcomp_miss, biudata_valid, biudata_error, lsu_addr, + dcram_we, biu_read, biu_write, biu_do_sel, dcram_di_sel, first_hit_ack, + first_miss_ack, first_miss_err, burst, tag_we, tag_valid, dc_addr, + dc_no_writethrough, tag_dirty, dirty, tag, tag_v, dc_block_flush, + dc_block_writeback, spr_dat_i, mtspr_dc_done, spr_cswe + ); + + // + // I/O + // + input clk; + input rst; + input dc_en; + input dcqmem_cycstb_i; + input dcqmem_ci_i; + input dcqmem_we_i; + input [3:0] dcqmem_sel_i; + input tagcomp_miss; + input biudata_valid; + input biudata_error; + input [31:0] lsu_addr; + output [3:0] dcram_we; + output biu_read; + output biu_write; + output dcram_di_sel; + output biu_do_sel; + output first_hit_ack; + output first_miss_ack; + output first_miss_err; + output burst; + output tag_we; + output tag_valid; + output [31:0] dc_addr; + input dc_no_writethrough; + output tag_dirty; + input dirty; + input [`OR1200_DCTAG_W-2:0] tag; + input tag_v; + input dc_block_flush; + input dc_block_writeback; + input [31:0] spr_dat_i; + output mtspr_dc_done; + input spr_cswe; + + + // + // Internal wires and regs + // + reg [31:0] addr_r; + reg [2:0] state; + reg [`OR1200_DCLS-1:0] cnt; + reg hitmiss_eval; + reg store; + reg load; + reg cache_inhibit; + reg cache_miss; + reg cache_dirty_needs_writeback; + reg did_early_load_ack; + reg cache_spr_block_flush; + reg cache_spr_block_writeback; + reg cache_wb; + wire load_hit_ack; + wire load_miss_ack; + wire load_inhibit_ack; + wire store_hit_ack; + wire store_hit_writethrough_ack; + wire store_miss_writethrough_ack; + wire store_inhibit_ack; + wire store_miss_ack; + wire dcram_we_after_line_load; + wire dcram_we_during_line_load; + wire tagram_we_end_of_loadstore_loop; + wire tagram_dirty_bit_set; + wire writethrough; + wire cache_inhibit_with_eval; + wire [(`OR1200_DCLS-1)-2:0] next_addr_word; + + // + // Cache inhibit + // + + // Indicates whether cache is inhibited, during hitmiss_eval and after + assign cache_inhibit_with_eval = (hitmiss_eval & dcqmem_ci_i) | + (!hitmiss_eval & cache_inhibit); + + // + // Generate of DCRAM write enables + // + + // WE when non-writethrough, and had to wait for a line to load. + assign dcram_we_after_line_load = (state == `OR1200_DCFSM_LOOP3) & + dcqmem_we_i & !cache_dirty_needs_writeback & + !did_early_load_ack; + + // WE when receiving the data cache line + assign dcram_we_during_line_load = (state == `OR1200_DCFSM_LOOP2) & load & + biudata_valid; + + assign dcram_we =(// Write when hit - make sure it is only when hit - could + // maybe be doing write through and don't want to corrupt + // cache lines corresponding to the writethrough addr_r. + ({4{store_hit_ack | store_hit_writethrough_ack}} | + // Write after load of line + {4{dcram_we_after_line_load}}) & + dcqmem_sel_i ) | + // Write during load + {4{dcram_we_during_line_load}}; + + // + // Tag RAM signals + // + + // WE to tag RAM when we finish loading a line. + assign tagram_we_end_of_loadstore_loop = ((state==`OR1200_DCFSM_LOOP2) & + biudata_valid & !(|cnt)); + +`ifndef OR1200_DC_WRITETHROUGH + // No writethrough, so mark a line dirty whenever we write to it + assign tagram_dirty_bit_set = store_hit_ack | store_miss_ack; + + // Generate done signal for MTSPR instructions that may block execution + assign mtspr_dc_done = // Either DC disabled or we're not selected, or + !dc_en | !spr_cswe | + // Requested address not valid or writeback and !dirty + ((state==`OR1200_DCFSM_FLUSH5) & + (!tag_v | (cache_spr_block_writeback & !dirty))) | + // Writeback or flush is finished + ((state==`OR1200_DCFSM_LOOP3) & + (cache_spr_block_flush | cache_spr_block_writeback))| + // Invalidate of clean line finished + ((state==`OR1200_DCFSM_INV6) & cache_spr_block_flush); + + +`else + `ifdef OR1200_DC_NOSTACKWRITETHROUGH + // For dirty bit setting when having writethrough but not for stack + assign tagram_dirty_bit_set = store_hit_ack | store_miss_ack; + `else + // Lines will never be dirty if always writethrough + assign tagram_dirty_bit_set = 0; + `endif + + assign mtspr_dc_done = 1'b1; + +`endif + + assign tag_dirty = tagram_dirty_bit_set; + + // WE to tag RAM + assign tag_we = tagram_we_end_of_loadstore_loop | + tagram_dirty_bit_set | (state == `OR1200_DCFSM_INV6); + + + // Valid bit + // Set valid when end of line load, or marking dirty (is still valid) + assign tag_valid = ( tagram_we_end_of_loadstore_loop & + (load | (store & cache_spr_block_writeback)) ) | + tagram_dirty_bit_set; + + + + // + // BIU read and write + // + + assign biu_read = // Bus read request when: + // 1) Have a miss and not dirty or a load with inhibit + ((state == `OR1200_DCFSM_CLOADSTORE) & + (((hitmiss_eval & tagcomp_miss & !dirty & + !(store & writethrough)) | + (load & cache_inhibit_with_eval)) & dcqmem_cycstb_i)) | + // 2) In the loop and loading + ((state == `OR1200_DCFSM_LOOP2) & load); + + + assign biu_write = // Bus write request when: + // 1) Have a miss and dirty or store with inhibit + ((state == `OR1200_DCFSM_CLOADSTORE) & + (((hitmiss_eval & tagcomp_miss & dirty) | + (store & writethrough)) | + (store & cache_inhibit_with_eval)) & dcqmem_cycstb_i) | + // 2) In the loop and storing + ((state == `OR1200_DCFSM_LOOP2) & store); + + // + // Select for data to actual cache RAM (from LSU or BIU) + // + // Data to DCRAM - from external bus when loading (from IU when store) + assign dcram_di_sel = load; + // Data to external bus - always from IU except in case of bursting back + // the line to memory. (1 selects DCRAM) + assign biu_do_sel = (state == `OR1200_DCFSM_LOOP2) & store; + + // 3-bit wire for calculating next word of burst write, depending on + // line size of data cache. + assign next_addr_word = addr_r[`OR1200_DCLS-1:2] + 1; + + // Address to cache RAM (tag address also derived from this) + assign dc_addr = + // First check if we've got a block flush or WB op + ((dc_block_flush & !cache_spr_block_flush) | + (dc_block_writeback & !cache_spr_block_writeback)) ? + spr_dat_i : + (state==`OR1200_DCFSM_FLUSH5) ? addr_r: + // If no SPR action, then always put out address from LSU + (state==`OR1200_DCFSM_IDLE | hitmiss_eval) ? lsu_addr : + // Next, if in writeback loop, when ACKed must immediately + // output next word address (the RAM address takes a cycle + // to increment, but it's needed immediately for burst) + // otherwise, output our registered address. + (state==`OR1200_DCFSM_LOOP2 & biudata_valid & store ) ? + {addr_r[31:`OR1200_DCLS], next_addr_word, 2'b00} : addr_r; + +`ifdef OR1200_DC_WRITETHROUGH + `ifdef OR1200_DC_NOSTACKWRITETHROUGH + assign writethrough = !dc_no_writethrough; + `else + assign writethrough = 1; + `endif +`else + assign writethrough = 0; +`endif + + // + // ACK generation for LSU + // + + // ACK for when it's a cache hit + assign first_hit_ack = load_hit_ack | store_hit_ack | + store_hit_writethrough_ack | + store_miss_writethrough_ack | + store_inhibit_ack | store_miss_ack ; + + // ACK for when it's a cache miss - load only, is used in MUX for data back + // LSU straight off external data bus. In + // this was is also used for cache inhibit + // loads. + // first_hit_ack takes precedence over first_miss_ack + assign first_miss_ack = ~first_hit_ack & (load_miss_ack | load_inhibit_ack); + + // ACK cache hit on load + assign load_hit_ack = (state == `OR1200_DCFSM_CLOADSTORE) & + hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i & load; + + // ACK cache hit on store, no writethrough + assign store_hit_ack = (state == `OR1200_DCFSM_CLOADSTORE) & + hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i & + store & !writethrough; + + // ACK cache hit on store with writethrough + assign store_hit_writethrough_ack = (state == `OR1200_DCFSM_CLOADSTORE) & + !cache_miss & !cache_inhibit & + store & writethrough & biudata_valid; + + // ACK cache miss on store with writethrough + assign store_miss_writethrough_ack = (state == `OR1200_DCFSM_CLOADSTORE) & + cache_miss & !cache_inhibit & + store & writethrough & biudata_valid; + + // ACK store when cacheinhibit + assign store_inhibit_ack = (state == `OR1200_DCFSM_CLOADSTORE) & + store & cache_inhibit & biudata_valid; + + + // Get the _early_ ack on first ACK back from wishbone during load only + // Condition is that we're in the loop - that it's the first ack we get (can + // tell from value of cnt), and we're loading a line to read from it (not + // loading to write to it, in the case of a write without writethrough.) + assign load_miss_ack = ((state== `OR1200_DCFSM_LOOP2) & load & + (cnt==((1 << `OR1200_DCLS) - 4)) & biudata_valid & + !(dcqmem_we_i & !writethrough)); + + assign load_inhibit_ack = (state == `OR1200_DCFSM_CLOADSTORE) & + load & cache_inhibit & biudata_valid; + + // This will be case of write through disabled, and had to load a line. + assign store_miss_ack = dcram_we_after_line_load; + + assign first_miss_err = biudata_error & dcqmem_cycstb_i; + + // Signal burst when in the load/store loop. We will always try to burst. + assign burst = (state == `OR1200_DCFSM_LOOP2); + + // + // Main DC FSM + // + always @(posedge clk or `OR1200_RST_EVENT rst) begin + if (rst == `OR1200_RST_VALUE) begin + state <= `OR1200_DCFSM_IDLE; + addr_r <= 32'd0; + hitmiss_eval <= 1'b0; + store <= 1'b0; + load <= 1'b0; + cnt <= `OR1200_DCLS'd0; + cache_miss <= 1'b0; + cache_dirty_needs_writeback <= 1'b0; + cache_inhibit <= 1'b0; + did_early_load_ack <= 1'b0; + cache_spr_block_flush <= 1'b0; + cache_spr_block_writeback <= 1'b0; + end + else + case (state) // synopsys parallel_case + + `OR1200_DCFSM_IDLE : begin + if (dc_en & (dc_block_flush | dc_block_writeback)) + begin + cache_spr_block_flush <= dc_block_flush; + cache_spr_block_writeback <= dc_block_writeback; + hitmiss_eval <= 1'b1; + state <= `OR1200_DCFSM_FLUSH5; + addr_r <= spr_dat_i; + end + else if (dc_en & dcqmem_cycstb_i) + begin + state <= `OR1200_DCFSM_CLOADSTORE; + hitmiss_eval <= 1'b1; + store <= dcqmem_we_i; + load <= !dcqmem_we_i; + end + + + end // case: `OR1200_DCFSM_IDLE + + `OR1200_DCFSM_CLOADSTORE: begin + hitmiss_eval <= 1'b0; + if (hitmiss_eval) begin + cache_inhibit <= dcqmem_ci_i; // Check for cache inhibit here + cache_miss <= tagcomp_miss; + cache_dirty_needs_writeback <= dirty; + addr_r <= lsu_addr; + end + + // Evaluate any cache line load/stores in first cycle: + // + if (hitmiss_eval & tagcomp_miss & !(store & writethrough) & + !dcqmem_ci_i) + begin + // Miss - first either: + // 1) write back dirty line + if (dirty) begin + // Address for writeback + addr_r <= {tag, lsu_addr[`OR1200_DCINDXH:2],2'd0}; + load <= 1'b0; + store <= 1'b1; +`ifdef OR1200_VERBOSE + $display("%t: dcache miss and dirty", $time); +`endif + end + // 2) load requested line + else begin + addr_r <= lsu_addr; + load <= 1'b1; + store <= 1'b0; + end // else: !if(dirty) + state <= `OR1200_DCFSM_LOOP2; + // Set the counter for the burst accesses + cnt <= ((1 << `OR1200_DCLS) - 4); + end + else if (// Strobe goes low + !dcqmem_cycstb_i | + // Cycle finishes + (!hitmiss_eval & (biudata_valid | biudata_error)) | + // Cache hit in first cycle.... + (hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i & + // .. and you're not doing a writethrough store.. + !(store & writethrough))) begin + state <= `OR1200_DCFSM_IDLE; + load <= 1'b0; + store <= 1'b0; + cache_inhibit <= 1'b0; + cache_dirty_needs_writeback <= 1'b0; + end + end // case: `OR1200_DCFSM_CLOADSTORE + + `OR1200_DCFSM_LOOP2 : begin // loop/abort + if (!dc_en| biudata_error) begin + state <= `OR1200_DCFSM_IDLE; + load <= 1'b0; + store <= 1'b0; + cnt <= `OR1200_DCLS'd0; + end + if (biudata_valid & (|cnt)) begin + cnt <= cnt - 4; + addr_r[`OR1200_DCLS-1:2] <= addr_r[`OR1200_DCLS-1:2] + 1; + end + else if (biudata_valid & !(|cnt)) begin + state <= `OR1200_DCFSM_LOOP3; + addr_r <= lsu_addr; + load <= 1'b0; + store <= 1'b0; + end + + // Track if we did an early ack during a load + if (load_miss_ack) + did_early_load_ack <= 1'b1; + + + end // case: `OR1200_DCFSM_LOOP2 + + `OR1200_DCFSM_LOOP3: begin // figure out next step + if (cache_dirty_needs_writeback) begin + // Just did store of the dirty line so now load new one + load <= 1'b1; + // Set the counter for the burst accesses + cnt <= ((1 << `OR1200_DCLS) - 4); + // Address of line to be loaded + addr_r <= lsu_addr; + cache_dirty_needs_writeback <= 1'b0; + state <= `OR1200_DCFSM_LOOP2; + end // if (cache_dirty_needs_writeback) + else if (cache_spr_block_flush | cache_spr_block_writeback) begin + // Just wrote back the line to memory, we're finished. + cache_spr_block_flush <= 1'b0; + cache_spr_block_writeback <= 1'b0; + state <= `OR1200_DCFSM_WAITSPRCS7; + end + else begin + // Just loaded a new line, finish up + did_early_load_ack <= 1'b0; + state <= `OR1200_DCFSM_LOOP4; + end + end // case: `OR1200_DCFSM_LOOP3 + + `OR1200_DCFSM_LOOP4: begin + state <= `OR1200_DCFSM_IDLE; + end + + `OR1200_DCFSM_FLUSH5: begin + hitmiss_eval <= 1'b0; + if (hitmiss_eval & !tag_v) + begin + // Not even cached, just ignore + cache_spr_block_flush <= 1'b0; + cache_spr_block_writeback <= 1'b0; + state <= `OR1200_DCFSM_WAITSPRCS7; + end + else if (hitmiss_eval & tag_v) + begin + // Tag is valid - what do we do? + if ((cache_spr_block_flush | cache_spr_block_writeback) & + dirty) begin + // Need to writeback + // Address for writeback (spr_dat_i has already changed so + // use line number from addr_r) + addr_r <= {tag, addr_r[`OR1200_DCINDXH:2],2'd0}; + load <= 1'b0; + store <= 1'b1; +`ifdef OR1200_VERBOSE + $display("%t: block flush: dirty block", $time); +`endif + state <= `OR1200_DCFSM_LOOP2; + // Set the counter for the burst accesses + cnt <= ((1 << `OR1200_DCLS) - 4); + end + else if (cache_spr_block_flush & !dirty) + begin + // Line not dirty, just need to invalidate + state <= `OR1200_DCFSM_INV6; + end // else: !if(dirty) + else if (cache_spr_block_writeback & !dirty) + begin + // Nothing to do - line is valid but not dirty + cache_spr_block_writeback <= 1'b0; + state <= `OR1200_DCFSM_WAITSPRCS7; + end + end // if (hitmiss_eval & tag_v) + end + `OR1200_DCFSM_INV6: begin + cache_spr_block_flush <= 1'b0; + // Wait until SPR CS goes low before going back to idle + if (!spr_cswe) + state <= `OR1200_DCFSM_IDLE; + end + `OR1200_DCFSM_WAITSPRCS7: begin + // Wait until SPR CS goes low before going back to idle + if (!spr_cswe) + state <= `OR1200_DCFSM_IDLE; + end + + endcase // case (state) + + end // always @ (posedge clk or `OR1200_RST_EVENT rst) + + +endmodule diff --git a/autotests/input/or1200_du.v b/autotests/input/or1200_du.v new file mode 100644 index 0000000..dbd3614 --- /dev/null +++ b/autotests/input/or1200_du.v @@ -0,0 +1,1803 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// OR1200's Debug Unit //// +//// //// +//// This file is part of the OpenRISC 1200 project //// +//// http://www.opencores.org/project,or1k //// +//// //// +//// Description //// +//// Basic OR1200 debug unit. //// +//// //// +//// To Do: //// +//// - make it smaller and faster //// +//// //// +//// Author(s): //// +//// - Damjan Lampret, lampret@opencores.org //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// +// $Log: or1200_du.v,v $ +// Revision 2.0 2010/06/30 11:00:00 ORSoC +// Minor update: +// Bugs fixed. + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on +`include "or1200_defines.v" + +// +// Debug unit +// + +module or1200_du( + // RISC Internal Interface + clk, rst, + dcpu_cycstb_i, dcpu_we_i, dcpu_adr_i, dcpu_dat_lsu, + dcpu_dat_dc, icpu_cycstb_i, + ex_freeze, branch_op, ex_insn, id_pc, + spr_dat_npc, rf_dataw, + du_dsr, du_dmr1, du_stall, du_addr, du_dat_i, du_dat_o, + du_read, du_write, du_except_stop, du_hwbkpt, du_flush_pipe, + spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o, + + // External Debug Interface + dbg_stall_i, dbg_ewt_i, dbg_lss_o, dbg_is_o, dbg_wp_o, dbg_bp_o, + dbg_stb_i, dbg_we_i, dbg_adr_i, dbg_dat_i, dbg_dat_o, dbg_ack_o +); + +parameter dw = `OR1200_OPERAND_WIDTH; +parameter aw = `OR1200_OPERAND_WIDTH; + +// +// I/O +// + +// +// RISC Internal Interface +// +input clk; // Clock +input rst; // Reset +input dcpu_cycstb_i; // LSU status +input dcpu_we_i; // LSU status +input [31:0] dcpu_adr_i; // LSU addr +input [31:0] dcpu_dat_lsu; // LSU store data +input [31:0] dcpu_dat_dc; // LSU load data +input [`OR1200_FETCHOP_WIDTH-1:0] icpu_cycstb_i; // IFETCH unit status +input ex_freeze; // EX stage freeze +input [`OR1200_BRANCHOP_WIDTH-1:0] branch_op; // Branch op +input [dw-1:0] ex_insn; // EX insn +input [31:0] id_pc; // insn fetch EA +input [31:0] spr_dat_npc; // Next PC (for trace) +input [31:0] rf_dataw; // ALU result (for trace) +output [`OR1200_DU_DSR_WIDTH-1:0] du_dsr; // DSR +output [24: 0] du_dmr1; +output du_stall; // Debug Unit Stall +output [aw-1:0] du_addr; // Debug Unit Address +input [dw-1:0] du_dat_i; // Debug Unit Data In +output [dw-1:0] du_dat_o; // Debug Unit Data Out +output du_read; // Debug Unit Read Enable +output du_write; // Debug Unit Write Enable +input [13:0] du_except_stop; // Exception masked by DSR +output du_hwbkpt; // Cause trap exception (HW Breakpoints) +output du_flush_pipe; // Cause pipeline flush and pc<-npc +input spr_cs; // SPR Chip Select +input spr_write; // SPR Read/Write +input [aw-1:0] spr_addr; // SPR Address +input [dw-1:0] spr_dat_i; // SPR Data Input +output [dw-1:0] spr_dat_o; // SPR Data Output + +// +// External Debug Interface +// +input dbg_stall_i; // External Stall Input +input dbg_ewt_i; // External Watchpoint Trigger Input +output [3:0] dbg_lss_o; // External Load/Store Unit Status +output [1:0] dbg_is_o; // External Insn Fetch Status +output [10:0] dbg_wp_o; // Watchpoints Outputs +output dbg_bp_o; // Breakpoint Output +input dbg_stb_i; // External Address/Data Strobe +input dbg_we_i; // External Write Enable +input [aw-1:0] dbg_adr_i; // External Address Input +input [dw-1:0] dbg_dat_i; // External Data Input +output [dw-1:0] dbg_dat_o; // External Data Output +output dbg_ack_o; // External Data Acknowledge (not WB compatible) +reg [dw-1:0] dbg_dat_o; // External Data Output +reg dbg_ack_o; // External Data Acknowledge (not WB compatible) + + +// +// Some connections go directly from the CPU through DU to Debug I/F +// +`ifdef OR1200_DU_STATUS_UNIMPLEMENTED +assign dbg_lss_o = 4'b0000; + +reg [1:0] dbg_is_o; +// +// Show insn activity (temp, must be removed) +// +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dbg_is_o <= 2'b00; + else if (!ex_freeze & ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16])) + dbg_is_o <= ~dbg_is_o; +`ifdef UNUSED +assign dbg_is_o = 2'b00; +`endif +`else +assign dbg_lss_o = dcpu_cycstb_i ? {dcpu_we_i, 3'b000} : 4'b0000; +assign dbg_is_o = {1'b0, icpu_cycstb_i}; +`endif +assign dbg_wp_o = 11'b000_0000_0000; + +// +// Some connections go directly from Debug I/F through DU to the CPU +// +assign du_stall = dbg_stall_i; +assign du_addr = dbg_adr_i; +assign du_dat_o = dbg_dat_i; +assign du_read = dbg_stb_i && !dbg_we_i; +assign du_write = dbg_stb_i && dbg_we_i; + +// +// After a sw breakpoint, the replaced instruction need to be executed. +// We flush the entire pipeline and set the pc to the current address +// to execute the restored address. +// + +reg du_flush_pipe_r; +reg dbg_stall_i_r; + +assign du_flush_pipe = du_flush_pipe_r; + +// +// Register du_flush_pipe +// +always @(posedge clk or `OR1200_RST_EVENT rst) begin + if (rst == `OR1200_RST_VALUE) begin + du_flush_pipe_r <= 1'b0; + end + else begin + du_flush_pipe_r <= (dbg_stall_i_r && !dbg_stall_i && |du_except_stop); + end +end + +// +// Detect dbg_stall falling edge +// +always @(posedge clk or `OR1200_RST_EVENT rst) begin + if (rst == `OR1200_RST_VALUE) begin + dbg_stall_i_r <= 1'b0; + end + else begin + dbg_stall_i_r <= dbg_stall_i; + end +end + +reg dbg_ack; +// +// Generate acknowledge -- just delay stb signal +// +always @(posedge clk or `OR1200_RST_EVENT rst) begin + if (rst == `OR1200_RST_VALUE) begin + dbg_ack <= 1'b0; + dbg_ack_o <= 1'b0; + end + else begin + dbg_ack <= dbg_stb_i; // valid when du_dat_i + dbg_ack_o <= dbg_ack & dbg_stb_i; // valid when dbg_dat_o + end +end + +// +// Register data output +// +always @(posedge clk) + dbg_dat_o <= du_dat_i; + +`ifdef OR1200_DU_IMPLEMENTED + +// +// Debug Mode Register 1 +// +`ifdef OR1200_DU_DMR1 +reg [24:0] dmr1; // DMR1 implemented +`else +wire [24:0] dmr1; // DMR1 not implemented +`endif +assign du_dmr1 = dmr1; + +// +// Debug Mode Register 2 +// +`ifdef OR1200_DU_DMR2 +reg [23:0] dmr2; // DMR2 implemented +`else +wire [23:0] dmr2; // DMR2 not implemented +`endif + +// +// Debug Stop Register +// +`ifdef OR1200_DU_DSR +reg [`OR1200_DU_DSR_WIDTH-1:0] dsr; // DSR implemented +`else +wire [`OR1200_DU_DSR_WIDTH-1:0] dsr; // DSR not implemented +`endif + +// +// Debug Reason Register +// +`ifdef OR1200_DU_DRR +reg [13:0] drr; // DRR implemented +`else +wire [13:0] drr; // DRR not implemented +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR0 +reg [31:0] dvr0; +`else +wire [31:0] dvr0; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR1 +reg [31:0] dvr1; +`else +wire [31:0] dvr1; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR2 +reg [31:0] dvr2; +`else +wire [31:0] dvr2; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR3 +reg [31:0] dvr3; +`else +wire [31:0] dvr3; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR4 +reg [31:0] dvr4; +`else +wire [31:0] dvr4; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR5 +reg [31:0] dvr5; +`else +wire [31:0] dvr5; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR6 +reg [31:0] dvr6; +`else +wire [31:0] dvr6; +`endif + +// +// Debug Value Register N +// +`ifdef OR1200_DU_DVR7 +reg [31:0] dvr7; +`else +wire [31:0] dvr7; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR0 +reg [7:0] dcr0; +`else +wire [7:0] dcr0; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR1 +reg [7:0] dcr1; +`else +wire [7:0] dcr1; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR2 +reg [7:0] dcr2; +`else +wire [7:0] dcr2; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR3 +reg [7:0] dcr3; +`else +wire [7:0] dcr3; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR4 +reg [7:0] dcr4; +`else +wire [7:0] dcr4; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR5 +reg [7:0] dcr5; +`else +wire [7:0] dcr5; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR6 +reg [7:0] dcr6; +`else +wire [7:0] dcr6; +`endif + +// +// Debug Control Register N +// +`ifdef OR1200_DU_DCR7 +reg [7:0] dcr7; +`else +wire [7:0] dcr7; +`endif + +// +// Debug Watchpoint Counter Register 0 +// +`ifdef OR1200_DU_DWCR0 +reg [31:0] dwcr0; +`else +wire [31:0] dwcr0; +`endif + +// +// Debug Watchpoint Counter Register 1 +// +`ifdef OR1200_DU_DWCR1 +reg [31:0] dwcr1; +`else +wire [31:0] dwcr1; +`endif + +// +// Internal wires +// +wire dmr1_sel; // DMR1 select +wire dmr2_sel; // DMR2 select +wire dsr_sel; // DSR select +wire drr_sel; // DRR select +wire dvr0_sel, + dvr1_sel, + dvr2_sel, + dvr3_sel, + dvr4_sel, + dvr5_sel, + dvr6_sel, + dvr7_sel; // DVR selects +wire dcr0_sel, + dcr1_sel, + dcr2_sel, + dcr3_sel, + dcr4_sel, + dcr5_sel, + dcr6_sel, + dcr7_sel; // DCR selects +wire dwcr0_sel, + dwcr1_sel; // DWCR selects +reg dbg_bp_r; +reg ex_freeze_q; +`ifdef OR1200_DU_HWBKPTS +reg [31:0] match_cond0_ct; +reg [31:0] match_cond1_ct; +reg [31:0] match_cond2_ct; +reg [31:0] match_cond3_ct; +reg [31:0] match_cond4_ct; +reg [31:0] match_cond5_ct; +reg [31:0] match_cond6_ct; +reg [31:0] match_cond7_ct; +reg match_cond0_stb; +reg match_cond1_stb; +reg match_cond2_stb; +reg match_cond3_stb; +reg match_cond4_stb; +reg match_cond5_stb; +reg match_cond6_stb; +reg match_cond7_stb; +reg match0; +reg match1; +reg match2; +reg match3; +reg match4; +reg match5; +reg match6; +reg match7; +reg wpcntr0_match; +reg wpcntr1_match; +reg incr_wpcntr0; +reg incr_wpcntr1; +reg [10:0] wp; +`endif +wire du_hwbkpt; +reg du_hwbkpt_hold; +`ifdef OR1200_DU_READREGS +reg [31:0] spr_dat_o; +`endif +reg [13:0] except_stop; // Exceptions that stop because of DSR +`ifdef OR1200_DU_TB_IMPLEMENTED +wire tb_enw; +reg [7:0] tb_wadr; +reg [31:0] tb_timstmp; +`endif +wire [31:0] tbia_dat_o; +wire [31:0] tbim_dat_o; +wire [31:0] tbar_dat_o; +wire [31:0] tbts_dat_o; + +// +// DU registers address decoder +// +`ifdef OR1200_DU_DMR1 +assign dmr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DMR1)); +`endif +`ifdef OR1200_DU_DMR2 +assign dmr2_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DMR2)); +`endif +`ifdef OR1200_DU_DSR +assign dsr_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DSR)); +`endif +`ifdef OR1200_DU_DRR +assign drr_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DRR)); +`endif +`ifdef OR1200_DU_DVR0 +assign dvr0_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR0)); +`endif +`ifdef OR1200_DU_DVR1 +assign dvr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR1)); +`endif +`ifdef OR1200_DU_DVR2 +assign dvr2_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR2)); +`endif +`ifdef OR1200_DU_DVR3 +assign dvr3_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR3)); +`endif +`ifdef OR1200_DU_DVR4 +assign dvr4_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR4)); +`endif +`ifdef OR1200_DU_DVR5 +assign dvr5_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR5)); +`endif +`ifdef OR1200_DU_DVR6 +assign dvr6_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR6)); +`endif +`ifdef OR1200_DU_DVR7 +assign dvr7_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR7)); +`endif +`ifdef OR1200_DU_DCR0 +assign dcr0_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR0)); +`endif +`ifdef OR1200_DU_DCR1 +assign dcr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR1)); +`endif +`ifdef OR1200_DU_DCR2 +assign dcr2_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR2)); +`endif +`ifdef OR1200_DU_DCR3 +assign dcr3_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR3)); +`endif +`ifdef OR1200_DU_DCR4 +assign dcr4_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR4)); +`endif +`ifdef OR1200_DU_DCR5 +assign dcr5_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR5)); +`endif +`ifdef OR1200_DU_DCR6 +assign dcr6_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR6)); +`endif +`ifdef OR1200_DU_DCR7 +assign dcr7_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR7)); +`endif +`ifdef OR1200_DU_DWCR0 +assign dwcr0_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DWCR0)); +`endif +`ifdef OR1200_DU_DWCR1 +assign dwcr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DWCR1)); +`endif + +// Track previous ex_freeze to detect when signals are updated +always @(posedge clk) + ex_freeze_q <= ex_freeze; + +// +// Decode started exception +// +// du_except_stop comes from or1200_except +// +always @(du_except_stop or ex_freeze_q) begin + except_stop = 14'b00_0000_0000_0000; + casez (du_except_stop) + 14'b1?_????_????_????: + except_stop[`OR1200_DU_DRR_TTE] = 1'b1; + 14'b01_????_????_????: begin + except_stop[`OR1200_DU_DRR_IE] = 1'b1; + end + 14'b00_1???_????_????: begin + except_stop[`OR1200_DU_DRR_IME] = 1'b1; + end + 14'b00_01??_????_????: + except_stop[`OR1200_DU_DRR_IPFE] = 1'b1; + 14'b00_001?_????_????: begin + except_stop[`OR1200_DU_DRR_BUSEE] = 1'b1; + end + 14'b00_0001_????_????: + except_stop[`OR1200_DU_DRR_IIE] = 1'b1; + 14'b00_0000_1???_????: begin + except_stop[`OR1200_DU_DRR_AE] = 1'b1; + end + 14'b00_0000_01??_????: begin + except_stop[`OR1200_DU_DRR_DME] = 1'b1; + end + 14'b00_0000_001?_????: + except_stop[`OR1200_DU_DRR_DPFE] = 1'b1; + 14'b00_0000_0001_????: + except_stop[`OR1200_DU_DRR_BUSEE] = 1'b1; + 14'b00_0000_0000_1???: begin + except_stop[`OR1200_DU_DRR_RE] = 1'b1; + end + 14'b00_0000_0000_01??: begin + except_stop[`OR1200_DU_DRR_TE] = 1'b1 & ~ex_freeze_q; + end + 14'b00_0000_0000_001?: begin + except_stop[`OR1200_DU_DRR_FPE] = 1'b1; + end + 14'b00_0000_0000_0001: + except_stop[`OR1200_DU_DRR_SCE] = 1'b1 & ~ex_freeze_q; + default: + except_stop = 14'b00_0000_0000_0000; + endcase // casez (du_except_stop) +end + +// +// dbg_bp_o is registered +// +assign dbg_bp_o = dbg_bp_r; + +// +// Breakpoint activation register +// +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dbg_bp_r <= 1'b0; + else if (!ex_freeze) + dbg_bp_r <= |except_stop +`ifdef OR1200_DU_DMR1_ST + | ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]) & dmr1[`OR1200_DU_DMR1_ST] +`endif +`ifdef OR1200_DU_DMR1_BT + | (branch_op != `OR1200_BRANCHOP_NOP) & (branch_op != `OR1200_BRANCHOP_RFE) & dmr1[`OR1200_DU_DMR1_BT] +`endif + ; + else + dbg_bp_r <= |except_stop; + +// +// Write to DMR1 +// +`ifdef OR1200_DU_DMR1 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dmr1 <= 25'h000_0000; + else if (dmr1_sel && spr_write) +`ifdef OR1200_DU_HWBKPTS + dmr1 <= spr_dat_i[24:0]; +`else + dmr1 <= {1'b0, spr_dat_i[23:22], 22'h00_0000}; +`endif +`else +assign dmr1 = 25'h000_0000; +`endif + +// +// Write to DMR2 +// +`ifdef OR1200_DU_DMR2 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dmr2 <= 24'h00_0000; + else if (dmr2_sel && spr_write) + dmr2 <= spr_dat_i[23:0]; +`else +assign dmr2 = 24'h00_0000; +`endif + +// +// Write to DSR +// +`ifdef OR1200_DU_DSR +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dsr <= {`OR1200_DU_DSR_WIDTH{1'b0}}; + else if (dsr_sel && spr_write) + dsr <= spr_dat_i[`OR1200_DU_DSR_WIDTH-1:0]; +`else +assign dsr = {`OR1200_DU_DSR_WIDTH{1'b0}}; +`endif + +// +// Write to DRR +// +`ifdef OR1200_DU_DRR +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + drr <= 14'b0; + else if (drr_sel && spr_write) + drr <= spr_dat_i[13:0]; + else + drr <= drr | except_stop; +`else +assign drr = 14'b0; +`endif + +// +// Write to DVR0 +// +`ifdef OR1200_DU_DVR0 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr0 <= 32'h0000_0000; + else if (dvr0_sel && spr_write) + dvr0 <= spr_dat_i[31:0]; +`else +assign dvr0 = 32'h0000_0000; +`endif + +// +// Write to DVR1 +// +`ifdef OR1200_DU_DVR1 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr1 <= 32'h0000_0000; + else if (dvr1_sel && spr_write) + dvr1 <= spr_dat_i[31:0]; +`else +assign dvr1 = 32'h0000_0000; +`endif + +// +// Write to DVR2 +// +`ifdef OR1200_DU_DVR2 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr2 <= 32'h0000_0000; + else if (dvr2_sel && spr_write) + dvr2 <= spr_dat_i[31:0]; +`else +assign dvr2 = 32'h0000_0000; +`endif + +// +// Write to DVR3 +// +`ifdef OR1200_DU_DVR3 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr3 <= 32'h0000_0000; + else if (dvr3_sel && spr_write) + dvr3 <= spr_dat_i[31:0]; +`else +assign dvr3 = 32'h0000_0000; +`endif + +// +// Write to DVR4 +// +`ifdef OR1200_DU_DVR4 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr4 <= 32'h0000_0000; + else if (dvr4_sel && spr_write) + dvr4 <= spr_dat_i[31:0]; +`else +assign dvr4 = 32'h0000_0000; +`endif + +// +// Write to DVR5 +// +`ifdef OR1200_DU_DVR5 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr5 <= 32'h0000_0000; + else if (dvr5_sel && spr_write) + dvr5 <= spr_dat_i[31:0]; +`else +assign dvr5 = 32'h0000_0000; +`endif + +// +// Write to DVR6 +// +`ifdef OR1200_DU_DVR6 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr6 <= 32'h0000_0000; + else if (dvr6_sel && spr_write) + dvr6 <= spr_dat_i[31:0]; +`else +assign dvr6 = 32'h0000_0000; +`endif + +// +// Write to DVR7 +// +`ifdef OR1200_DU_DVR7 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dvr7 <= 32'h0000_0000; + else if (dvr7_sel && spr_write) + dvr7 <= spr_dat_i[31:0]; +`else +assign dvr7 = 32'h0000_0000; +`endif + +// +// Write to DCR0 +// +`ifdef OR1200_DU_DCR0 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr0 <= 8'h00; + else if (dcr0_sel && spr_write) + dcr0 <= spr_dat_i[7:0]; +`else +assign dcr0 = 8'h00; +`endif + +// +// Write to DCR1 +// +`ifdef OR1200_DU_DCR1 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr1 <= 8'h00; + else if (dcr1_sel && spr_write) + dcr1 <= spr_dat_i[7:0]; +`else +assign dcr1 = 8'h00; +`endif + +// +// Write to DCR2 +// +`ifdef OR1200_DU_DCR2 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr2 <= 8'h00; + else if (dcr2_sel && spr_write) + dcr2 <= spr_dat_i[7:0]; +`else +assign dcr2 = 8'h00; +`endif + +// +// Write to DCR3 +// +`ifdef OR1200_DU_DCR3 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr3 <= 8'h00; + else if (dcr3_sel && spr_write) + dcr3 <= spr_dat_i[7:0]; +`else +assign dcr3 = 8'h00; +`endif + +// +// Write to DCR4 +// +`ifdef OR1200_DU_DCR4 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr4 <= 8'h00; + else if (dcr4_sel && spr_write) + dcr4 <= spr_dat_i[7:0]; +`else +assign dcr4 = 8'h00; +`endif + +// +// Write to DCR5 +// +`ifdef OR1200_DU_DCR5 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr5 <= 8'h00; + else if (dcr5_sel && spr_write) + dcr5 <= spr_dat_i[7:0]; +`else +assign dcr5 = 8'h00; +`endif + +// +// Write to DCR6 +// +`ifdef OR1200_DU_DCR6 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr6 <= 8'h00; + else if (dcr6_sel && spr_write) + dcr6 <= spr_dat_i[7:0]; +`else +assign dcr6 = 8'h00; +`endif + +// +// Write to DCR7 +// +`ifdef OR1200_DU_DCR7 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dcr7 <= 8'h00; + else if (dcr7_sel && spr_write) + dcr7 <= spr_dat_i[7:0]; +`else +assign dcr7 = 8'h00; +`endif + +// +// Write to DWCR0 +// +`ifdef OR1200_DU_DWCR0 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dwcr0 <= 32'h0000_0000; + else if (dwcr0_sel && spr_write) + dwcr0 <= spr_dat_i[31:0]; + else if (incr_wpcntr0) + dwcr0[`OR1200_DU_DWCR_COUNT] <= dwcr0[`OR1200_DU_DWCR_COUNT] + 16'h0001; +`else +assign dwcr0 = 32'h0000_0000; +`endif + +// +// Write to DWCR1 +// +`ifdef OR1200_DU_DWCR1 +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + dwcr1 <= 32'h0000_0000; + else if (dwcr1_sel && spr_write) + dwcr1 <= spr_dat_i[31:0]; + else if (incr_wpcntr1) + dwcr1[`OR1200_DU_DWCR_COUNT] <= dwcr1[`OR1200_DU_DWCR_COUNT] + 16'h0001; +`else +assign dwcr1 = 32'h0000_0000; +`endif + +// +// Read DU registers +// +`ifdef OR1200_DU_READREGS +always @(spr_addr or dsr or drr or dmr1 or dmr2 + or dvr0 or dvr1 or dvr2 or dvr3 or dvr4 + or dvr5 or dvr6 or dvr7 + or dcr0 or dcr1 or dcr2 or dcr3 or dcr4 + or dcr5 or dcr6 or dcr7 + or dwcr0 or dwcr1 +`ifdef OR1200_DU_TB_IMPLEMENTED + or tb_wadr or tbia_dat_o or tbim_dat_o + or tbar_dat_o or tbts_dat_o +`endif + ) + casez (spr_addr[`OR1200_DUOFS_BITS]) // synopsys parallel_case +`ifdef OR1200_DU_DVR0 + `OR1200_DU_DVR0: + spr_dat_o = dvr0; +`endif +`ifdef OR1200_DU_DVR1 + `OR1200_DU_DVR1: + spr_dat_o = dvr1; +`endif +`ifdef OR1200_DU_DVR2 + `OR1200_DU_DVR2: + spr_dat_o = dvr2; +`endif +`ifdef OR1200_DU_DVR3 + `OR1200_DU_DVR3: + spr_dat_o = dvr3; +`endif +`ifdef OR1200_DU_DVR4 + `OR1200_DU_DVR4: + spr_dat_o = dvr4; +`endif +`ifdef OR1200_DU_DVR5 + `OR1200_DU_DVR5: + spr_dat_o = dvr5; +`endif +`ifdef OR1200_DU_DVR6 + `OR1200_DU_DVR6: + spr_dat_o = dvr6; +`endif +`ifdef OR1200_DU_DVR7 + `OR1200_DU_DVR7: + spr_dat_o = dvr7; +`endif +`ifdef OR1200_DU_DCR0 + `OR1200_DU_DCR0: + spr_dat_o = {24'h00_0000, dcr0}; +`endif +`ifdef OR1200_DU_DCR1 + `OR1200_DU_DCR1: + spr_dat_o = {24'h00_0000, dcr1}; +`endif +`ifdef OR1200_DU_DCR2 + `OR1200_DU_DCR2: + spr_dat_o = {24'h00_0000, dcr2}; +`endif +`ifdef OR1200_DU_DCR3 + `OR1200_DU_DCR3: + spr_dat_o = {24'h00_0000, dcr3}; +`endif +`ifdef OR1200_DU_DCR4 + `OR1200_DU_DCR4: + spr_dat_o = {24'h00_0000, dcr4}; +`endif +`ifdef OR1200_DU_DCR5 + `OR1200_DU_DCR5: + spr_dat_o = {24'h00_0000, dcr5}; +`endif +`ifdef OR1200_DU_DCR6 + `OR1200_DU_DCR6: + spr_dat_o = {24'h00_0000, dcr6}; +`endif +`ifdef OR1200_DU_DCR7 + `OR1200_DU_DCR7: + spr_dat_o = {24'h00_0000, dcr7}; +`endif +`ifdef OR1200_DU_DMR1 + `OR1200_DU_DMR1: + spr_dat_o = {7'h00, dmr1}; +`endif +`ifdef OR1200_DU_DMR2 + `OR1200_DU_DMR2: + spr_dat_o = {8'h00, dmr2}; +`endif +`ifdef OR1200_DU_DWCR0 + `OR1200_DU_DWCR0: + spr_dat_o = dwcr0; +`endif +`ifdef OR1200_DU_DWCR1 + `OR1200_DU_DWCR1: + spr_dat_o = dwcr1; +`endif +`ifdef OR1200_DU_DSR + `OR1200_DU_DSR: + spr_dat_o = {18'b0, dsr}; +`endif +`ifdef OR1200_DU_DRR + `OR1200_DU_DRR: + spr_dat_o = {18'b0, drr}; +`endif +`ifdef OR1200_DU_TB_IMPLEMENTED + `OR1200_DU_TBADR: + spr_dat_o = {24'h000000, tb_wadr}; + `OR1200_DU_TBIA: + spr_dat_o = tbia_dat_o; + `OR1200_DU_TBIM: + spr_dat_o = tbim_dat_o; + `OR1200_DU_TBAR: + spr_dat_o = tbar_dat_o; + `OR1200_DU_TBTS: + spr_dat_o = tbts_dat_o; +`endif + default: + spr_dat_o = 32'h0000_0000; + endcase +`endif + +// +// DSR alias +// +assign du_dsr = dsr; + +`ifdef OR1200_DU_HWBKPTS + +// +// Compare To What (Match Condition 0) +// +always @(dcr0 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr0[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond0_ct = id_pc; // insn fetch EA + 3'b010: match_cond0_ct = dcpu_adr_i; // load EA + 3'b011: match_cond0_ct = dcpu_adr_i; // store EA + 3'b100: match_cond0_ct = dcpu_dat_dc; // load data + 3'b101: match_cond0_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond0_ct = dcpu_adr_i; // load/store EA + default:match_cond0_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 0) +// +always @(dcr0 or dcpu_cycstb_i) + case (dcr0[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond0_stb = 1'b0; //comparison disabled + 3'b001: match_cond0_stb = 1'b1; // insn fetch EA + default:match_cond0_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 0 +// +always @(match_cond0_stb or dcr0 or dvr0 or match_cond0_ct) + casex ({match_cond0_stb, dcr0[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match0 = 1'b0; + 4'b1_001: match0 = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} == + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_010: match0 = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} < + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_011: match0 = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} <= + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_100: match0 = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} > + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_101: match0 = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} >= + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + 4'b1_110: match0 = + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} != + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]}); + endcase + +// +// Watchpoint 0 +// +always @(dmr1 or match0) + case (dmr1[`OR1200_DU_DMR1_CW0]) + 2'b00: wp[0] = match0; + 2'b01: wp[0] = match0; + 2'b10: wp[0] = match0; + 2'b11: wp[0] = 1'b0; + endcase + +// +// Compare To What (Match Condition 1) +// +always @(dcr1 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr1[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond1_ct = id_pc; // insn fetch EA + 3'b010: match_cond1_ct = dcpu_adr_i; // load EA + 3'b011: match_cond1_ct = dcpu_adr_i; // store EA + 3'b100: match_cond1_ct = dcpu_dat_dc; // load data + 3'b101: match_cond1_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond1_ct = dcpu_adr_i; // load/store EA + default:match_cond1_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 1) +// +always @(dcr1 or dcpu_cycstb_i) + case (dcr1[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond1_stb = 1'b0; //comparison disabled + 3'b001: match_cond1_stb = 1'b1; // insn fetch EA + default:match_cond1_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 1 +// +always @(match_cond1_stb or dcr1 or dvr1 or match_cond1_ct) + casex ({match_cond1_stb, dcr1[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match1 = 1'b0; + 4'b1_001: match1 = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} == + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_010: match1 = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} < + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_011: match1 = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} <= + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_100: match1 = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} > + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_101: match1 = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} >= + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + 4'b1_110: match1 = + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} != + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]}); + endcase + +// +// Watchpoint 1 +// +always @(dmr1 or match1 or wp) + case (dmr1[`OR1200_DU_DMR1_CW1]) + 2'b00: wp[1] = match1; + 2'b01: wp[1] = match1 & wp[0]; + 2'b10: wp[1] = match1 | wp[0]; + 2'b11: wp[1] = 1'b0; + endcase + +// +// Compare To What (Match Condition 2) +// +always @(dcr2 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr2[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond2_ct = id_pc; // insn fetch EA + 3'b010: match_cond2_ct = dcpu_adr_i; // load EA + 3'b011: match_cond2_ct = dcpu_adr_i; // store EA + 3'b100: match_cond2_ct = dcpu_dat_dc; // load data + 3'b101: match_cond2_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond2_ct = dcpu_adr_i; // load/store EA + default:match_cond2_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 2) +// +always @(dcr2 or dcpu_cycstb_i) + case (dcr2[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond2_stb = 1'b0; //comparison disabled + 3'b001: match_cond2_stb = 1'b1; // insn fetch EA + default:match_cond2_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 2 +// +always @(match_cond2_stb or dcr2 or dvr2 or match_cond2_ct) + casex ({match_cond2_stb, dcr2[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match2 = 1'b0; + 4'b1_001: match2 = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} == + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_010: match2 = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} < + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_011: match2 = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} <= + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_100: match2 = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} > + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_101: match2 = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} >= + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + 4'b1_110: match2 = + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} != + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]}); + endcase + +// +// Watchpoint 2 +// +always @(dmr1 or match2 or wp) + case (dmr1[`OR1200_DU_DMR1_CW2]) + 2'b00: wp[2] = match2; + 2'b01: wp[2] = match2 & wp[1]; + 2'b10: wp[2] = match2 | wp[1]; + 2'b11: wp[2] = 1'b0; + endcase + +// +// Compare To What (Match Condition 3) +// +always @(dcr3 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr3[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond3_ct = id_pc; // insn fetch EA + 3'b010: match_cond3_ct = dcpu_adr_i; // load EA + 3'b011: match_cond3_ct = dcpu_adr_i; // store EA + 3'b100: match_cond3_ct = dcpu_dat_dc; // load data + 3'b101: match_cond3_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond3_ct = dcpu_adr_i; // load/store EA + default:match_cond3_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 3) +// +always @(dcr3 or dcpu_cycstb_i) + case (dcr3[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond3_stb = 1'b0; //comparison disabled + 3'b001: match_cond3_stb = 1'b1; // insn fetch EA + default:match_cond3_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 3 +// +always @(match_cond3_stb or dcr3 or dvr3 or match_cond3_ct) + casex ({match_cond3_stb, dcr3[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match3 = 1'b0; + 4'b1_001: match3 = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} == + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_010: match3 = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} < + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_011: match3 = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} <= + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_100: match3 = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} > + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_101: match3 = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} >= + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + 4'b1_110: match3 = + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} != + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]}); + endcase + +// +// Watchpoint 3 +// +always @(dmr1 or match3 or wp) + case (dmr1[`OR1200_DU_DMR1_CW3]) + 2'b00: wp[3] = match3; + 2'b01: wp[3] = match3 & wp[2]; + 2'b10: wp[3] = match3 | wp[2]; + 2'b11: wp[3] = 1'b0; + endcase + +// +// Compare To What (Match Condition 4) +// +always @(dcr4 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr4[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond4_ct = id_pc; // insn fetch EA + 3'b010: match_cond4_ct = dcpu_adr_i; // load EA + 3'b011: match_cond4_ct = dcpu_adr_i; // store EA + 3'b100: match_cond4_ct = dcpu_dat_dc; // load data + 3'b101: match_cond4_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond4_ct = dcpu_adr_i; // load/store EA + default:match_cond4_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 4) +// +always @(dcr4 or dcpu_cycstb_i) + case (dcr4[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond4_stb = 1'b0; //comparison disabled + 3'b001: match_cond4_stb = 1'b1; // insn fetch EA + default:match_cond4_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 4 +// +always @(match_cond4_stb or dcr4 or dvr4 or match_cond4_ct) + casex ({match_cond4_stb, dcr4[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match4 = 1'b0; + 4'b1_001: match4 = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} == + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_010: match4 = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} < + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_011: match4 = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} <= + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_100: match4 = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} > + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_101: match4 = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} >= + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + 4'b1_110: match4 = + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} != + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]}); + endcase + +// +// Watchpoint 4 +// +always @(dmr1 or match4 or wp) + case (dmr1[`OR1200_DU_DMR1_CW4]) + 2'b00: wp[4] = match4; + 2'b01: wp[4] = match4 & wp[3]; + 2'b10: wp[4] = match4 | wp[3]; + 2'b11: wp[4] = 1'b0; + endcase + +// +// Compare To What (Match Condition 5) +// +always @(dcr5 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr5[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond5_ct = id_pc; // insn fetch EA + 3'b010: match_cond5_ct = dcpu_adr_i; // load EA + 3'b011: match_cond5_ct = dcpu_adr_i; // store EA + 3'b100: match_cond5_ct = dcpu_dat_dc; // load data + 3'b101: match_cond5_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond5_ct = dcpu_adr_i; // load/store EA + default:match_cond5_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 5) +// +always @(dcr5 or dcpu_cycstb_i) + case (dcr5[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond5_stb = 1'b0; //comparison disabled + 3'b001: match_cond5_stb = 1'b1; // insn fetch EA + default:match_cond5_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 5 +// +always @(match_cond5_stb or dcr5 or dvr5 or match_cond5_ct) + casex ({match_cond5_stb, dcr5[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match5 = 1'b0; + 4'b1_001: match5 = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} == + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_010: match5 = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} < + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_011: match5 = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} <= + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_100: match5 = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} > + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_101: match5 = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} >= + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + 4'b1_110: match5 = + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} != + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]}); + endcase + +// +// Watchpoint 5 +// +always @(dmr1 or match5 or wp) + case (dmr1[`OR1200_DU_DMR1_CW5]) + 2'b00: wp[5] = match5; + 2'b01: wp[5] = match5 & wp[4]; + 2'b10: wp[5] = match5 | wp[4]; + 2'b11: wp[5] = 1'b0; + endcase + +// +// Compare To What (Match Condition 6) +// +always @(dcr6 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr6[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond6_ct = id_pc; // insn fetch EA + 3'b010: match_cond6_ct = dcpu_adr_i; // load EA + 3'b011: match_cond6_ct = dcpu_adr_i; // store EA + 3'b100: match_cond6_ct = dcpu_dat_dc; // load data + 3'b101: match_cond6_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond6_ct = dcpu_adr_i; // load/store EA + default:match_cond6_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 6) +// +always @(dcr6 or dcpu_cycstb_i) + case (dcr6[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond6_stb = 1'b0; //comparison disabled + 3'b001: match_cond6_stb = 1'b1; // insn fetch EA + default:match_cond6_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 6 +// +always @(match_cond6_stb or dcr6 or dvr6 or match_cond6_ct) + casex ({match_cond6_stb, dcr6[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match6 = 1'b0; + 4'b1_001: match6 = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} == + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_010: match6 = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} < + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_011: match6 = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} <= + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_100: match6 = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} > + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_101: match6 = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} >= + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + 4'b1_110: match6 = + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} != + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]}); + endcase + +// +// Watchpoint 6 +// +always @(dmr1 or match6 or wp) + case (dmr1[`OR1200_DU_DMR1_CW6]) + 2'b00: wp[6] = match6; + 2'b01: wp[6] = match6 & wp[5]; + 2'b10: wp[6] = match6 | wp[5]; + 2'b11: wp[6] = 1'b0; + endcase + +// +// Compare To What (Match Condition 7) +// +always @(dcr7 or id_pc or dcpu_adr_i or dcpu_dat_dc + or dcpu_dat_lsu or dcpu_we_i) + case (dcr7[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b001: match_cond7_ct = id_pc; // insn fetch EA + 3'b010: match_cond7_ct = dcpu_adr_i; // load EA + 3'b011: match_cond7_ct = dcpu_adr_i; // store EA + 3'b100: match_cond7_ct = dcpu_dat_dc; // load data + 3'b101: match_cond7_ct = dcpu_dat_lsu; // store data + 3'b110: match_cond7_ct = dcpu_adr_i; // load/store EA + default:match_cond7_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc; + endcase + +// +// When To Compare (Match Condition 7) +// +always @(dcr7 or dcpu_cycstb_i) + case (dcr7[`OR1200_DU_DCR_CT]) // synopsys parallel_case + 3'b000: match_cond7_stb = 1'b0; //comparison disabled + 3'b001: match_cond7_stb = 1'b1; // insn fetch EA + default:match_cond7_stb = dcpu_cycstb_i; // any load/store + endcase + +// +// Match Condition 7 +// +always @(match_cond7_stb or dcr7 or dvr7 or match_cond7_ct) + casex ({match_cond7_stb, dcr7[`OR1200_DU_DCR_CC]}) + 4'b0_xxx, + 4'b1_000, + 4'b1_111: match7 = 1'b0; + 4'b1_001: match7 = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} == + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_010: match7 = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} < + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_011: match7 = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} <= + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_100: match7 = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} > + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_101: match7 = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} >= + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + 4'b1_110: match7 = + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} != + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]}); + endcase + +// +// Watchpoint 7 +// +always @(dmr1 or match7 or wp) + case (dmr1[`OR1200_DU_DMR1_CW7]) + 2'b00: wp[7] = match7; + 2'b01: wp[7] = match7 & wp[6]; + 2'b10: wp[7] = match7 | wp[6]; + 2'b11: wp[7] = 1'b0; + endcase + +// +// Increment Watchpoint Counter 0 +// +always @(wp or dmr2) + if (dmr2[`OR1200_DU_DMR2_WCE0]) + incr_wpcntr0 = |(wp & ~dmr2[`OR1200_DU_DMR2_AWTC]); + else + incr_wpcntr0 = 1'b0; + +// +// Match Condition Watchpoint Counter 0 +// +always @(dwcr0) + if (dwcr0[`OR1200_DU_DWCR_MATCH] == dwcr0[`OR1200_DU_DWCR_COUNT]) + wpcntr0_match = 1'b1; + else + wpcntr0_match = 1'b0; + + +// +// Watchpoint 8 +// +always @(dmr1 or wpcntr0_match or wp) + case (dmr1[`OR1200_DU_DMR1_CW8]) + 2'b00: wp[8] = wpcntr0_match; + 2'b01: wp[8] = wpcntr0_match & wp[7]; + 2'b10: wp[8] = wpcntr0_match | wp[7]; + 2'b11: wp[8] = 1'b0; + endcase + + +// +// Increment Watchpoint Counter 1 +// +always @(wp or dmr2) + if (dmr2[`OR1200_DU_DMR2_WCE1]) + incr_wpcntr1 = |(wp & dmr2[`OR1200_DU_DMR2_AWTC]); + else + incr_wpcntr1 = 1'b0; + +// +// Match Condition Watchpoint Counter 1 +// +always @(dwcr1) + if (dwcr1[`OR1200_DU_DWCR_MATCH] == dwcr1[`OR1200_DU_DWCR_COUNT]) + wpcntr1_match = 1'b1; + else + wpcntr1_match = 1'b0; + +// +// Watchpoint 9 +// +always @(dmr1 or wpcntr1_match or wp) + case (dmr1[`OR1200_DU_DMR1_CW9]) + 2'b00: wp[9] = wpcntr1_match; + 2'b01: wp[9] = wpcntr1_match & wp[8]; + 2'b10: wp[9] = wpcntr1_match | wp[8]; + 2'b11: wp[9] = 1'b0; + endcase + +// +// Watchpoint 10 +// +always @(dmr1 or dbg_ewt_i or wp) + case (dmr1[`OR1200_DU_DMR1_CW10]) + 2'b00: wp[10] = dbg_ewt_i; + 2'b01: wp[10] = dbg_ewt_i & wp[9]; + 2'b10: wp[10] = dbg_ewt_i | wp[9]; + 2'b11: wp[10] = 1'b0; + endcase + +`endif + +// +// Watchpoints can cause trap exception +// +`ifdef OR1200_DU_HWBKPTS +assign du_hwbkpt = |(wp & dmr2[`OR1200_DU_DMR2_WGB]) | du_hwbkpt_hold | (dbg_bp_r & ~dsr[`OR1200_DU_DSR_TE]); +`else +assign du_hwbkpt = 1'b0; +`endif + +// Hold du_hwbkpt if ex_freeze is active in order to cause trap exception +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + du_hwbkpt_hold <= 1'b0; + else if (du_hwbkpt & ex_freeze) + du_hwbkpt_hold <= 1'b1; + else if (!ex_freeze) + du_hwbkpt_hold <= 1'b0; + +`ifdef OR1200_DU_TB_IMPLEMENTED +// +// Simple trace buffer +// (right now hardcoded for Xilinx Virtex FPGAs) +// +// Stores last 256 instruction addresses, instruction +// machine words and ALU results +// + +// +// Trace buffer write enable +// +assign tb_enw = ~ex_freeze & ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]); + +// +// Trace buffer write address pointer +// +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + tb_wadr <= 8'h00; + else if (tb_enw) + tb_wadr <= tb_wadr + 8'd1; + +// +// Free running counter (time stamp) +// +always @(posedge clk or `OR1200_RST_EVENT rst) + if (rst == `OR1200_RST_VALUE) + tb_timstmp <= 32'h00000000; + else if (!dbg_bp_r) + tb_timstmp <= tb_timstmp + 32'd1; + +// +// Trace buffer RAMs +// + +or1200_dpram_256x32 tbia_ram( + .clk_a(clk), + .rst_a(1'b0), + .addr_a(spr_addr[7:0]), + .ce_a(1'b1), + .oe_a(1'b1), + .do_a(tbia_dat_o), + + .clk_b(clk), + .rst_b(1'b0), + .addr_b(tb_wadr), + .di_b(spr_dat_npc), + .ce_b(1'b1), + .we_b(tb_enw) + +); + +or1200_dpram_256x32 tbim_ram( + .clk_a(clk), + .rst_a(1'b0), + .addr_a(spr_addr[7:0]), + .ce_a(1'b1), + .oe_a(1'b1), + .do_a(tbim_dat_o), + + .clk_b(clk), + .rst_b(1'b0), + .addr_b(tb_wadr), + .di_b(ex_insn), + .ce_b(1'b1), + .we_b(tb_enw) +); + +or1200_dpram_256x32 tbar_ram( + .clk_a(clk), + .rst_a(1'b0), + .addr_a(spr_addr[7:0]), + .ce_a(1'b1), + .oe_a(1'b1), + .do_a(tbar_dat_o), + + .clk_b(clk), + .rst_b(1'b0), + .addr_b(tb_wadr), + .di_b(rf_dataw), + .ce_b(1'b1), + .we_b(tb_enw) +); + +or1200_dpram_256x32 tbts_ram( + .clk_a(clk), + .rst_a(1'b0), + .addr_a(spr_addr[7:0]), + .ce_a(1'b1), + .oe_a(1'b1), + .do_a(tbts_dat_o), + + .clk_b(clk), + .rst_b(1'b0), + .addr_b(tb_wadr), + .di_b(tb_timstmp), + .ce_b(1'b1), + .we_b(tb_enw) +); + +`else + +assign tbia_dat_o = 32'h0000_0000; +assign tbim_dat_o = 32'h0000_0000; +assign tbar_dat_o = 32'h0000_0000; +assign tbts_dat_o = 32'h0000_0000; + +`endif // OR1200_DU_TB_IMPLEMENTED + +`else // OR1200_DU_IMPLEMENTED + +// +// When DU is not implemented, drive all outputs as would when DU is disabled +// +assign dbg_bp_o = 1'b0; +assign du_dsr = {`OR1200_DU_DSR_WIDTH{1'b0}}; +assign du_dmr1 = {25{1'b0}}; +assign du_hwbkpt = 1'b0; + +// +// Read DU registers +// +`ifdef OR1200_DU_READREGS +assign spr_dat_o = 32'h0000_0000; +`ifdef OR1200_DU_UNUSED_ZERO +`endif +`endif + +`endif + +endmodule diff --git a/autotests/input/preprocessor-bug363280.c b/autotests/input/preprocessor-bug363280.c new file mode 100644 index 0000000..9908bf7 --- /dev/null +++ b/autotests/input/preprocessor-bug363280.c @@ -0,0 +1,8 @@ +#if 1 +int x; // variable shall not be grey +#endif +#if defined (A) +int y; // variable shall not be grey +#elif defined (B) +int z; // variable shall not be grey +#endif diff --git a/autotests/input/preprocessor-bug363280.cpp b/autotests/input/preprocessor-bug363280.cpp new file mode 100644 index 0000000..9908bf7 --- /dev/null +++ b/autotests/input/preprocessor-bug363280.cpp @@ -0,0 +1,8 @@ +#if 1 +int x; // variable shall not be grey +#endif +#if defined (A) +int y; // variable shall not be grey +#elif defined (B) +int z; // variable shall not be grey +#endif diff --git a/autotests/input/review128925-1.css b/autotests/input/review128925-1.css new file mode 100644 index 0000000..b61b616 --- /dev/null +++ b/autotests/input/review128925-1.css @@ -0,0 +1,112 @@ +/* + * CSS Syntax Highlight Sample File (Standard) + * + * This file contains most CSS syntax, CSS3 properties, @media, @font-face and + * @keyframes annotations. + * + * @author Guo Yunhe guoyunhebrave@gmail.com + * @date 2016-09-16 + */ + +/* + * Block comment + * + * Alert keywords: + * TODO BUG FIXME + */ + +@charset "UTF-8"; + +@import url("components/button.css"); + + +/* Properties */ + +html, body { + font-family: "Droid Sans", Arial, sans-serif; + font-size: 11pt; + line-height: 1.5em; + max-width: calc(100% - 300px); + background: #fff000; + text-shadow: 0 0 2px rgba(0, 0, 0, 0.3); + box-sizing: border-box; +} + + +/* Selectors */ + +blockquote { + margin: 0; +} + +header #logo { + width: 100px; +} + +div#footer .link { + color: blue; +} + +sidebar #subscribe .subscribe_form input[type="text"] { + font-size: 20px; +} + +sidebar #subscribe .subscribe_form:nth-child(2n + 1):hover input[class*="small-"] { + font-weight: bold; +} + + +/* Media Queries */ + +@media print { + .container { + width: 100%; + } +} + +@media screen and (min-width: 768px) { + .container { + width: 600px; + } +} + +@media screen and (min-width: 768px) and (max-width: 960px) { + .container { + width: 720px; + } +} + + +/* Fontface */ + +@font-face { + font-family: MyHelvetica; + src: local("Helvetica Neue Bold"), + local("HelveticaNeue-Bold"), + url(MgOpenModernaBold.ttf); + font-weight: bold; +} + +/* Animation (Keyframes) */ + +@keyframes slidein { + from { + margin-left: 100%; + width: 300%; + } + + to { + margin-left: 0%; + width: 100%; + } +} + + +/* Region markers */ + +/*BEGIN Comment */ + + + +/*END Comment */ + diff --git a/autotests/input/review128925-1.scss b/autotests/input/review128925-1.scss new file mode 100644 index 0000000..6aa1da6 --- /dev/null +++ b/autotests/input/review128925-1.scss @@ -0,0 +1,211 @@ +/* + * SCSS Syntax Highlight Sample File (Standard) + * + * This file contains most SCSS syntax, CSS3 properties, advanced code structure. + * It is NOT a valid SCSS file that can be compiled by SCSS preprocessors. + * + * @author Guo Yunhe guoyunhebrave@gmail.com + * @date 2016-09-15 + */ + +/* + * Block comment + * + * Alert keywords: + * TODO BUG FIXME + */ + +@charset "UTF-8"; + +@import "mixins/button"; + +// Variable define + +$image-path: "../../static/images"; +$default-text-color: #333 !default; // Default can be overrided +$default-font-size: 16px !default; +$default-font-family: Roboto, "Droid Sans", sans-serif; +$default-font-weight: 400; +$default-line-height: $default-font-size * 1.8; +$shadow-transparence: 0.25; +$box-shadow: 0 0 3px rgba(0,0,0,$shadow-transparence); +$page-width: 100rem; // kabab-case +$gapOfArticle: 20px; // camelCase +$body_background_color: white; // snake_case + +// Mixins + +@mixin border-radius($radius) { + -webkit-border-radius: $radius; + -moz-border-radius: $radius; + -ms-border-radius: $radius; + border-radius: $radius; +} + +.box { @include border-radius(10px); } + +// Nesting + +#home-page { + + header { + width: 80%; + margin: 0 auto; + + .cover { + @include border-radius(20px); + max-width: 100%; + + &:hover { + background: #ffffff; + } + + .like-button { + font-size: $default-font-size * 0.8; + + @media (max-width: 300px) and (min-width: 200px) { + font-size: $default-font-size * 0.8; + + .icon { + width: 20px; + height: 20px; + } + } + + @media print { + display: none; + } + } + } + } +} + +// Extend and inheritance + +.message { + border: $border-light; + background-color: #f0f0f0; +} + +.message-danger { + @extend .message; +} + + +// Control structures + +@mixin does-parent-exist { + @if & { + &:hover { + color: red; + } + } @else { + a { + color: red; + } + } +} + + +// Operators + +.container { width: 100%; } + +article[role="main"] { + float: left; + width: 600px / 960px * 100%; +} + +aside[role="complementary"] { + float: right; + width: 300px / 960px * 100%; +} + + +// Functions - see http://sass-lang.com/documentation/Sass/Script/Functions.html + +$color1: hsl(120deg, 100%, 50%); +$color2: rgb($red, $green, blue($color1)); +$color3: mix($color1, $color2, [$weight]); + + +// Properties + +html, body { + font-family: "Droid Sans", Arial, sans-serif; + font-size: 11pt; + line-height: 1.5em; + max-width: 300px + $page-width - $gap / 2; + background: $bg_color; + text-shadow: 0 0 2px rgba(0,0,0, $transparence); + box-sizing: border-box; +} + + +// Selectors + +blockquote { + margin: 0; +} + +header #logo { + width: 100px; +} + +div#footer .link { + color: blue; +} + +sidebar #subscribe .subscribe_form input[type="text"] { + font-size: 20px; +} + +sidebar #subscribe .subscribe_form:nth-child(2n + 1):hover input[class*="small-"] { + font-weight: bold; +} + + +// Media Queries + +@media print { + .container { + width: 100%; + } +} + +@media screen and (min-width: 768px) { + .container { + width: 600px; + } +} + +@media screen and (min-width: 768px) and (max-width: 960px) { + .container { + width: 720px; + } +} + + +// Fontface + +@font-face { + font-family: MyHelvetica; + src: local("Helvetica Neue Bold"), + local("HelveticaNeue-Bold"), + url(MgOpenModernaBold.ttf); + font-weight: bold; +} + +// Animation (Keyframes) + +@keyframes slidein { + from { + margin-left: 100%; + width: 300%; + } + + to { + margin-left: 0%; + width: 100%; + } +} diff --git a/autotests/input/review128925-2.css b/autotests/input/review128925-2.css new file mode 100644 index 0000000..05c20a8 --- /dev/null +++ b/autotests/input/review128925-2.css @@ -0,0 +1,62 @@ +/* + * CSS Syntax Highlight Sample File (Complex) + * + * This file contains complex CSS syntax that can test unexpected situations. + * + * @author Guo Yunhe guoyunhebrave@gmail.com + * @date 2016-09-16 + */ + + +/* Comments with special content */ + +/* + * .class-selector #id "string" 'comment' // comment {} [] () /* comment + * TODO BUG DEBUG + * body { + * margin: 0 !important; + * } + */ + +/* Comments in special positions */ + +header/* comment here */.active /* comment here */ { + /* comment here */ color : /* comment here */ blue/* comment here */; + font-family: Arial /* comment here */, + "Droid Sans", /* comment here */ + sans-serif/* comment here */; +} + +@media screen /* comment here */ and (max-width: 300px /* comment here */) /* comment here */ {/* comment here */} + + +/* Strings with special content */ + +@import url("{} $variable /* comment */"); + + +/* Without extra breaklines and spaces */ + +pre.primary:hover.large:nth-child(2n-1){font-size:17px;font-family:"Noto Sans";-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.3)} + + +/* With unnecessary breaklines and spaces */ + +blockquote .ref + { + flex : 0 1 30%; + flex-wrap : wrap; + } + +@media screen and (orientation: landscape) { + .sidebar { + width: 500px; } } + + +/* Special selectors: HTML5 allows user defined tags */ + +header { + flex { + width: 300px; + } +} diff --git a/autotests/input/review128925-2.scss b/autotests/input/review128925-2.scss new file mode 100644 index 0000000..c71fe3b --- /dev/null +++ b/autotests/input/review128925-2.scss @@ -0,0 +1,81 @@ +/* + * SCSS Syntax Highlight Sample File (Complex) + * + * This file contains complex SCSS syntax that can test unexpected situations. + * It is NOT a valid SCSS file that can be compiled by SCSS preprocessors. + * + * @author Guo Yunhe guoyunhebrave@gmail.com + * @date 2016-09-16 + */ + + +// Comments with special content + +// .class-selector #id "string" 'comment' // comment {} [] () /* comment */ text + +/* + * .class-selector #id "string" 'comment' // comment {} [] () /* comment + * TODO BUG DEBUG + * body { + * margin: 0 !important; + * } + */ + +// Comments in special positions + +$color: black /* comment here */; + +header/* comment here */.active /* comment here */ { + /* comment here */ color : /* comment here */ blue/* comment here */; + font-family: Arial /* comment here */, + "Droid Sans", /* comment here */ + sans-serif/* comment here */; +} + +@media screen /* comment here */ and (max-width: 300px /* comment here */) /* comment here */ {/* comment here */} + + +// Strings with special content + +@import "{} $variable /* comment */"; +@import "{}"; + +// Without extra breaklines and spaces + +pre.primary:hover.large:nth-child(2n-1){font-size:$default-font-size;font-family:"Noto Sans";-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.3)} + +// With unnecessary breaklines and spaces + +blockquote .ref + { + flex : 0 1 30%; + flex-wrap : wrap; + } + +.sidebar { + width: 300px; } + @media screen and (orientation: landscape) { + .sidebar { + width: 500px; } } + +// Variable interpolation: #{} + +$name: foo; +$attr: border; +p.#{$name} { + #{$attr}-color: blue; +} + +p { + $font-size: 12px; + $line-height: 30px; + font: #{$font-size}/#{$line-height}; +} + +// Special selectors: HTML5 allows user defined tags + +header { + flex { + width: 300px; + } +} diff --git a/autotests/input/review128935.html b/autotests/input/review128935.html new file mode 100644 index 0000000..f373235 --- /dev/null +++ b/autotests/input/review128935.html @@ -0,0 +1,164 @@ + + + + + + + + +HTML Syntax Highlight Sample File (Standard) + + + + + + + + + +
    + This is a div. This is a span +
    + This is a div. +
    +
    + +

    + This is a paragraph. +

    + +

    This is heading 1

    +

    This is heading 2

    +

    This is heading 3

    +

    This is heading 4

    +
    This is heading 5
    +
    This is heading 6
    + +
    This is a link + +
    + +This is an image + +
    + +
      +
    • List item
    • +
    • List item
    • +
    • List item
    • +
    • List item
    • +
    • List item
    • +
    + +
      +
    1. List item
    2. +
    3. List item
    4. +
    5. List item
    6. +
    7. List item
    8. +
    9. List item
    10. +
    + + + + + + + + + + + + +
    Table headTable headTable head
    Table headTable headTable head
    + +
    + + + +
    + +
    +
    This is a header.
    + + + +
    +

    This is an article.

    +

    This is an article.

    +
    + + + +
    + +
    + + + + + + Just For Fun: The Story of an Accidental Revolutionary + Linus Torvalds + + A humorous autobiography of Linus Torvalds, the creator of the Linux + kernel, co-written with David Diamond. The book primarily theorizes + the Law of Linus that all evolution contributed by humanity starts + for survival, sustains socially and entertains at last. As well as + this the book explains Torvalds' view of himself, the free software + movement and the development of Linux. + + + + + + +
    +
    +
    +

    + + + +
    + THIS IS A DIV. +

    THIS IS A PARAGRAPH.

    +

    THIS IS A HEADING.

    +
    + + + +Magic button + +This is an image + + + + + + + +
    This is a div.
    + + + + diff --git a/autotests/input/test.bash b/autotests/input/test.bash new file mode 100644 index 0000000..f64255c --- /dev/null +++ b/autotests/input/test.bash @@ -0,0 +1,6 @@ +#!/bin/bash + +for i in `ls tests/auto/output/*.html`; do + refFile=`echo $i | sed -e s,build,src, | sed -e s,output,reference, | sed -e s,.html,.ref.html,` + cp -v $i $refFile +done diff --git a/autotests/input/test.bb b/autotests/input/test.bb new file mode 100644 index 0000000..98d9089 --- /dev/null +++ b/autotests/input/test.bb @@ -0,0 +1,34 @@ +# syntax test file for Bitbake receipes + +SUMMARY = "GammaRay Qt introspection probe" +HOMEPAGE = "http://www.kdab.com/gammaray" + +LICENSE = "GPLv2" +LIC_FILES_CHKSUM = "file://LICENSE.GPL.txt;md5=2abfe5daa817fd4346b6d55293941415" + +inherit cmake_qt5 + +SRC_URI = "git://github.com/KDAB/GammaRay;branch=master" + +SRCREV = "139e003174f48b0c883fc6c200ef2efb7467bff1" +PV = "2.4.0+git${SRCPV}" + +DEPENDS = "qtdeclarative" + +S = "${WORKDIR}/git" + +EXTRA_OECMAKE += " -DGAMMARAY_BUILD_UI=OFF" + +FILES_${PN}-dev += " \ + /usr/lib/cmake/* \ + /usr/mkspecs/modules/* \ +" +FILES_${PN}-dbg += " \ + /usr/lib/.debug/* \ + /usr/lib/gammaray/*/*/.debug \ + /usr/lib/gammaray/*/*/styles/.debug \ +" + +# error: unterinated string +VAR *= "abc + this is wrong diff --git a/autotests/input/test.c b/autotests/input/test.c new file mode 100644 index 0000000..b2462d7 --- /dev/null +++ b/autotests/input/test.c @@ -0,0 +1,56 @@ +#include +#include "stdint.h" + +#define SOME_VAR 1 +#ifdef SOME_VAR + +#define MULTILINE_MACRO one \ +two \ +three + +static uint64_t intWithSuffix = 42ull; +static int octNum = 07232; +static int invalidOctNum = 09231; +static uint64_t hexNum = 0xDEADBEEF42; +static uint64_t invalidHexNum = 0xGLDFKG; +static char binNum = 0b0101010; + +static double d1 = 42.; +static double d2 = .42; +static double d3 = 42.3e1; +static double d4 = .2e-12; +static double d5 = 32.e+12; +static float floatQualifier = 23.123f; + +static const char c1 = 'c'; +static const char c2 = '\n'; +static const char c2a = '\120'; // octal +static const char c2b = '\x1f'; // hex +static const char c2c = '\''; +static const char c2d = '\\'; +static const char* c3 = "string"; +static const char* c4 = "\"string\n\t\012\x12\""; +static const char* c5 = "multiline \ + string"; + +//BEGIN region +// TODO comment FIXME comment ### comment +//END region + +#wrong + +/** + * Doxygen + * @param p1 text + * \brief bold text + * \dot + * a -> b + * \enddot + * + * \verbatim + * + * \endverbatim + * text + */ + +#endif diff --git a/autotests/input/test.c.syntax b/autotests/input/test.c.syntax new file mode 100644 index 0000000..3cc58df --- /dev/null +++ b/autotests/input/test.c.syntax @@ -0,0 +1 @@ +C diff --git a/autotests/input/test.cmake b/autotests/input/test.cmake new file mode 100644 index 0000000..efc5c5c --- /dev/null +++ b/autotests/input/test.cmake @@ -0,0 +1,31 @@ +# comment + +#[[.rst: +MyModule +-------- + +bla bla +#]] + +#.rst: +# ATTENTION +# alternative doc comment +# + +#[=====[.rst: + +3rd form + +]=====] + +set(CMAKE_AUTOMOC ON) +if (POLICY CMP042) + target_link_libraries(myTaget SHARED Qt5::Core) +else() + add_executable(myTaget ${some_var}) +endif() + +macro(my_macro arg1) + foreach(arg ${ARGN}) + endforeach() +endmacro() diff --git a/autotests/input/test.css b/autotests/input/test.css new file mode 100644 index 0000000..763e2d6 --- /dev/null +++ b/autotests/input/test.css @@ -0,0 +1,18 @@ +h1 { + text-color: "red"; +} + +/* PHP code, invalid in CSS context */ +for() + + + +h2 { + text-weight: bold; +} + diff --git a/autotests/input/test.css.syntax b/autotests/input/test.css.syntax new file mode 100644 index 0000000..30599f0 --- /dev/null +++ b/autotests/input/test.css.syntax @@ -0,0 +1 @@ +CSS/PHP diff --git a/autotests/input/test.desktop b/autotests/input/test.desktop new file mode 100644 index 0000000..f3edd78 --- /dev/null +++ b/autotests/input/test.desktop @@ -0,0 +1,19 @@ +# test file for .dekstop syntax highlighting +[Desktop Entry] +GenericName=Text Editor +GenericName[ar]=محرّر نصوص +Name=KWrite +Name[ar]=كاتبك +Comment=KDE Text Editor +Comment[ar]=محرّر نصوص لكدي +MimeType=text/plain; +Exec=kwrite %U +StartupNotify=true +Icon=kwrite +X-DocPath=kwrite/index.html +Type=Application +Terminal=false +InitialPreference=8 +X-DBUS-StartupType=Multi +X-DBUS-ServiceName=org.kde.kwrite +Categories=Qt;KDE;Utility;TextEditor; diff --git a/autotests/input/test.diff b/autotests/input/test.diff new file mode 100644 index 0000000..7a6807c --- /dev/null +++ b/autotests/input/test.diff @@ -0,0 +1,48 @@ +commit 2b16665838c8afeaa0f065cafc747438de35876b +Author: Volker Krause +Date: Sat Oct 8 13:31:51 2016 +0200 + + Implement dynamic DetectChar rules + + Needed for Perl highlighting. + +diff --git a/src/lib/rule.cpp b/src/lib/rule.cpp +index f588985..c4c3b92 100644 +--- a/src/lib/rule.cpp ++++ b/src/lib/rule.cpp +@@ -308,12 +308,22 @@ bool DetectChar::doLoad(QXmlStreamReader& reader) + if (s.isEmpty()) + return false; + m_char = s.at(0); ++ if (isDynamic()) { ++ m_captureIndex = m_char.digitValue(); ++ } + return true; + } + + MatchResult DetectChar::doMatch(const QString& text, int offset, const QStringList &captures) + { +- Q_UNUSED(captures); // TODO ++ if (isDynamic()) { ++ if (captures.size() <= m_captureIndex || captures.at(m_captureIndex).isEmpty()) ++ return offset; ++ if (text.at(offset) == captures.at(m_captureIndex).at(0)) ++ return offset + 1; ++ return offset; ++ } ++ + if (text.at(offset) == m_char) + return offset + 1; + return offset; +diff --git a/src/lib/rule_p.h b/src/lib/rule_p.h +index d8862ae..d9cedbf 100644 +--- a/src/lib/rule_p.h ++++ b/src/lib/rule_p.h +@@ -103,6 +103,7 @@ protected: + + private: + QChar m_char; ++ int m_captureIndex; + }; + + class Detect2Char : public Rule diff --git a/autotests/input/test.eml b/autotests/input/test.eml new file mode 100644 index 0000000..373a421 --- /dev/null +++ b/autotests/input/test.eml @@ -0,0 +1,94 @@ +Return-Path: +X-Sieve: CMU Sieve 2.3 +X-Virus-Scanned: amavisd-new at site +Authentication-Results: linux.site (amavisd-new); dkim=pass (1024-bit key) + header.d=kde.org +Received: from postbox.kde.org (localhost.localdomain [127.0.0.1]) + by postbox.kde.org (Postfix) with ESMTP id 3167DB6E75; + Wed, 5 Oct 2016 20:21:47 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=kde.org; s=default; + t=1475698907; bh=6i+3UfR6HLC54wVtp5SF4sVWvQn63jzu9vD2zJal/kY=; + h=From:To:Subject:Date:Reply-To:List-Id:List-Unsubscribe:List-Post: + List-Help:List-Subscribe:From; + b=M5nfHbmJe/4DPuidrJ901dUzX3FmpVpyUrPM961Or9bKrMO+z9gaTUwbfPR74Rq8B + Rv66yf3ZaDuRZxv/ARPzpr8qnDTtf13WRFZ/ySdqqqQJKeBqCAd7/wbR0kHhypvpwe + z4nY6+bNnjvFelPXR56o16b+/Ib2GTYJ9hwiG97U= +X-Original-To: kwrite-devel@kde.org +Delivered-To: kwrite-devel@localhost.kde.org +Received-SPF: Neutral (access neither permitted nor denied) identity=mailfrom; + client-ip=85.214.234.26; helo=h2265959.stratoserver.net; + envelope-from=vkrause@kde.org; receiver=kwrite-devel@kde.org +From: Volker Krause +To: kwrite-devel@kde.org +Subject: Highlighting semantics: line end context switches when popping back + into previous line context stack +Date: Wed, 05 Oct 2016 22:19:17 +0200 +Message-ID: <2420385.jiZKTgWtgY@vkpc5> +Organization: KDE +User-Agent: KMail/4.14.10 (Linux/4.1.13-5-default; KDE/4.14.16; x86_64; + git-91275a7; 2015-12-13) +MIME-Version: 1.0 +Content-Type: multipart/signed; boundary="nextPart1575059.2yRQ5x6HOo"; + micalg="pgp-sha1"; protocol="application/pgp-signature" +X-BeenThere: kwrite-devel@kde.org +X-Mailman-Version: 2.1.16 +Precedence: list +Reply-To: kwrite-devel@kde.org +List-Id: Kate/KWrite Mailing List +List-Unsubscribe: , + +List-Post: +List-Help: +List-Subscribe: , + +Errors-To: kwrite-devel-bounces@kde.org +Sender: "KWrite-Devel" + + +--nextPart1575059.2yRQ5x6HOo +Content-Transfer-Encoding: 7Bit +Content-Type: text/plain; charset="us-ascii" + +Hi, + +when trying to add the unit test for the new Praat highlighting to +KF5::SyntaxHighlighting it turned out that the output doesn't match at all +that of Kate. We managed to trace this back to the following rather surprising +(and apparently undocumented) behavior in Kate: + +When a context switch (anywhere in a line) pops more contexts than were on the +stack when starting the line, it executes line end context switches of the +previous line contexts. + +| | | | | | The corresponding code is in KateHighlighting::generateContextStack(), +| | > | > KF5::SyntaxHighlighting doesn't do this (yet), Praat is apparently the first +> | > format we have tests for that uses this behavior. + +> Does anyone remember why we do this, or happens to know which highlighting +> files besides Praat rely on this? + +> > Archeology can trace this back to the dark CVS ages even, one reference +> > Dominik has dug up is a 10 year old SVN commit +> > (https://quickgit.kde.org/?p=kdelibs.git&a=commit&h=90ef47f582277745f727d89f05f72f1e1705fdc4 +> >), where Christoph claims to understand what this code does ;) + +> > > As this is highly unexpected and hard to reason about behavior, Dominik and I +> > > > were wondering if we can possibly drop this, and rather fix affected +> > > > > highlighting files instead? + +Regards, +Volker +--nextPart1575059.2yRQ5x6HOo +Content-Type: application/pgp-signature; name="signature.asc" +Content-Description: This is a digitally signed message part. +Content-Transfer-Encoding: 7Bit + +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iD8DBQBX9WBIf5bM1k0S0kcRAireAJ4lCWa08Y5yU1ezIvKVCAfnkhcUbACgou0O +X4c+lkPI0tti59KV1vetaeU= +=VqDS +-----END PGP SIGNATURE----- + +--nextPart1575059.2yRQ5x6HOo-- diff --git a/autotests/input/test.frag b/autotests/input/test.frag new file mode 100644 index 0000000..67ccc99 --- /dev/null +++ b/autotests/input/test.frag @@ -0,0 +1,26 @@ +#version 330 core + +// single line comment + +/* single line commonet */ + +/* + multi line comment + */ + +in ColorFormat { + vec3 color; +} fs_in; + +out vec4 fragColor; + +vec3 fun(const in vec3 foo) { + foo[2] = foo.x; + + return foo; +} + +void main() +{ + fragColor = vec4( fs_in.color, 1.0 ); +} diff --git a/autotests/input/test.htm b/autotests/input/test.htm new file mode 100644 index 0000000..1503ca7 --- /dev/null +++ b/autotests/input/test.htm @@ -0,0 +1,17 @@ + + + + This is a title + + + +

    Hello world!

    + + + diff --git a/autotests/input/test.htm.syntax b/autotests/input/test.htm.syntax new file mode 100644 index 0000000..f05185c --- /dev/null +++ b/autotests/input/test.htm.syntax @@ -0,0 +1 @@ +HTML diff --git a/autotests/input/test.ijs b/autotests/input/test.ijs new file mode 100644 index 0000000..9acfe4b --- /dev/null +++ b/autotests/input/test.ijs @@ -0,0 +1,61 @@ +Comment +NB. This is a single line comment, check regions overlapping priority: 1 2.3 +/ &. 'quoted text' +NB.( +NB. This is a foldable multi line comment +NB.) + +String literal +'' +'''' +'This is quoted text' +'And this '' and this NB. and this' 'Yet another quoted text' + +Numeric literal +12 34.56 _7.89 1e2 1.2e3 _. _ __ 123j_456 2b111.111 1r23 123456x 1.2e3j4.5e6 _j_ __j_ _.j_. _j3p4j_. + +Parenthesis +( ) + +Adverb +~ / \ /. \. } b. f. M. t. t: + +Conjuction +^: . .. .: : :. :: ;. !. !: " ` `: @ @. @: & &. &: &.: d. D. D: H. L: S: T. + +Control +assert. break. case. catch. catchd. catcht. continue. do. else. elseif. end. fcase. for. for_abc. goto_abc. if. label_abc. return. select. throw. try. while. whilst. + +Copula +a =: 123 +(a) =: 123 +(a;b;c) =: 123 +'a b c' =: 123 +'a b c' =. '123' +'`a b c' =. '123' +'a' =: 123 +('a';'b';'c') =: 123 + +Explicit argument +x y m n u v x. y. m. n. u. v. + +Noun +a. a: + +Verb += < <. <: > >. >: _: + +. +: * *. *: - -. -: % %. %: ^ ^. $ $. $: ~. ~: | |. |: , ,. ,: ; ;: # #. #: ! /: \: [ [: ] { {. {: {:: }. }: ". ": ? ?. A. C. e. E. i. i: I. j. L. o. p. p.. p: q: r. s: u: x: _9: _8: _7: _6: _5: _4: _3: _2: _1: 0: 1: 2: 3: 4: 5: 6: 7: 8: 9: + +Combined +for_abc. i. 5 do. 55 return. end. +a=. b =: 123 +/ # i. 10 +123 'qwerty' +a_b =: '123' [ c__d =. 4 : 0 NB. foldable definition begins + x +/ y +) +e__12 =: define NB. foldable definition begins + if. x do. NB. inner foldable region begins + y=. y + x NB. comment after code + x +/ y + else. NB. inner foldable region begins + y +/ y + end. +) diff --git a/autotests/input/test.js b/autotests/input/test.js new file mode 100644 index 0000000..6e684a1 --- /dev/null +++ b/autotests/input/test.js @@ -0,0 +1,8 @@ +/* comment */ + +function fun() +{ + var boo = { 'key': [ 1, 2.0, 3.0e1, 004, 0x5 ] }; +} + +class MyClass; // reserved keywords diff --git a/autotests/input/test.json b/autotests/input/test.json new file mode 100644 index 0000000..6c16ee6 --- /dev/null +++ b/autotests/input/test.json @@ -0,0 +1,13 @@ +{ + "float": 3.1415, + "int": 123, + "string": "\a \"b' \n", + "array": [ 1, 2, 3 ], + "object": { + "mult-line": "so this folds" + }, + "folded array": [ + 1, 2, 3 + ] + "error key": "due to missing comma" +} diff --git a/autotests/input/test.markdown b/autotests/input/test.markdown new file mode 100644 index 0000000..b8b4a9d --- /dev/null +++ b/autotests/input/test.markdown @@ -0,0 +1,39 @@ +# H1 + +## H2 + +### H3 + +Multi-line paragraph bla bla bla +bla bla bla. + +Intentional line break +via two spaces at line. + +Formats: _italic_, **bold**, `monospace`, ~~strikeout~~ + +Bullet list: + +* item1 +* item2 + +Numbered list: + +1. item 1 +2. item 2 + +[link](http://kde.org) + + code 1 + code 2 + +normal text + +> block quote _italic_ +> more block quote + +normal text + +Title: some text + +normal text diff --git a/autotests/input/test.mss b/autotests/input/test.mss new file mode 100644 index 0000000..4f742c1 --- /dev/null +++ b/autotests/input/test.mss @@ -0,0 +1,215 @@ +/* kate: hl CartoCSS + This file contains some content coming from + https://github.com/gravitystorm/openstreetmap-carto + with CC0 license. This file is just for testing + katepart highlighting engine. + */ + +#world { +// this syntax +polygon-opacity: 50%; + +// is equivalent to +polygon-opacity: 0.5; +} + +@admin-boundaries: #ac46ac; + +/* For performance reasons, the admin border layers are split into three groups +for low, middle and high zoom levels. +For each zoomlevel, all borders come from a single attachment, to handle +overlapping borders correctly. +*/ + +#admin-low-zoom[zoom < 11], // test +#admin-mid-zoom[zoom >= 11][zoom < 13], +#admin-high-zoom[zoom >= 13] { + [admin_level = '2'], + [admin_level = '3'] { + [zoom >= 4] { + background/line-color: white; + background/line-width: 0.6; + line-color: @admin-boundaries; + line-width: 0.6; + } + [zoom >= 7] { + background/line-width: 2; + line-width: 2; + } + [zoom >= 10] { + [admin_level = '2'] { + background/line-width: 6; + line-width: 6; + } + [admin_level = '3'] { + background/line-width: 5; + line-width: 5; + line-dasharray: 4,2; + line-clip: false; + } + } + } + [admin_level = '4'] { + [zoom >= 4] { + background/line-color: white; + background/line-width: 0.6; + line-color: @admin-boundaries; + line-width: 0.6; + line-dasharray: 4,3; + line-clip: false; + } + [zoom >= 7] { + background/line-width: 1; + line-width: 1; + } + [zoom >= 11] { + background/line-width: 3; + line-width: 3; + } + } + /* + The following code prevents admin boundaries from being rendered on top of + each other. Comp-op works on the entire attachment, not on the individual + border. Therefore, this code generates an attachment containing a set of + @admin-boundaries/white dashed lines (of which only the top one is visible), + and with `comp-op: darken` the white part is ignored, while the + @admin-boundaries colored part is rendered (as long as the background is not + darker than @admin-boundaries). + The SQL has `ORDER BY admin_level`, so the boundary with the lowest + admin_level is rendered on top, and therefore the only visible boundary. + */ + opacity: 0.4; + comp-op: darken; +} + +#admin-mid-zoom[zoom >= 11][zoom < 13], +#admin-high-zoom[zoom >= 13] { + [admin_level = '5'][zoom >= 11] { + background/line-color: white; + background/line-width: 2; + line-color: @admin-boundaries; + line-width: 2; + line-dasharray: 6,3,2,3,2,3; + line-clip: false; + } + [admin_level = '6'][zoom >= 11] { + background/line-color: white; + background/line-width: 2; + line-color: @admin-boundaries; + line-width: 2; + line-dasharray: 6,3,2,3; + line-clip: false; + } + [admin_level = '7'], + [admin_level = '8'] { + [zoom >= 12] { + background/line-color: white; + background/line-width: 1.5; + line-color: @admin-boundaries; + line-width: 1.5; + line-dasharray: 5,2; + line-clip: false; + } + } + opacity: 0.5; + comp-op: darken; +} + +#admin-high-zoom[zoom >= 13] { + [admin_level = '9'], + [admin_level = '10'] { + [zoom >= 13] { + background/line-color: white; + background/line-width: 2; + line-color: @admin-boundaries; + line-width: 2; + line-dasharray: 2,3; + line-clip: false; + } + } + opacity: 0.5; + comp-op: darken; +} + + + +#nature-reserve-boundaries { + [way_pixels > 100][zoom >= 7] { + [zoom < 10] { + ::fill { + opacity: 0.05; + polygon-fill: green; + } + } + a/line-width: 1; + a/line-offset: -0.5; + a/line-color: green; + a/line-opacity: 0.15; + a/line-join: round; + a/line-cap: round; + b/line-width: 2; + b/line-offset: -1; + b/line-color: green; + b/line-opacity: 0.15; + b/line-join: round; + b/line-cap: round; + [zoom >= 10] { + a/line-width: 2; + a/line-offset: -1; + b/line-width: 4; + b/line-offset: -2; + } + [zoom >= 14] { + b/line-width: 6; + b/line-offset: -3; + } + } +} + +#building-text { +[zoom >= 14][way_pixels > 3000], +[zoom >= 17] { +text-name: "[name]"; +text-size: 11; +text-fill: #444; +text-face-name: @book-fonts; +text-halo-radius: 1; +text-wrap-width: 20; +text-halo-fill: rgba(255,255,255,0.5); +text-placement: interior; +} +} + +@marina-text: #576ddf; // also swimming_pool +@landcover-face-name: @oblique-fonts; +@standard-wrap-width: 30; + +.points { + [feature = 'tourism_alpine_hut'][zoom >= 13] { + point-file: url('symbols/alpinehut.p.16.png'); + point-placement: interior; + } + } + + [feature = 'highway_bus_stop'] { + [zoom >= 16] { + marker-file: url('symbols/square.svg'); + marker-fill: @transportation-icon; + marker-placement: interior; + marker-width: 6; + } + [zoom >= 17] { + marker-file: url('symbols/bus_stop.p.12.png'); + marker-width: 12; + } + } + +[feature = 'highway_primary'] { +[zoom >= 7][zoom < 12] { +line-width: 0.5; +line-color: @primary-fill; +[zoom >= 9] { line-width: 1.2; } +[zoom >= 10] { line-width: 2; } +[zoom >= 11] { line-width: .5; } +} +} diff --git a/autotests/input/test.py b/autotests/input/test.py new file mode 100644 index 0000000..3c0392c --- /dev/null +++ b/autotests/input/test.py @@ -0,0 +1,28 @@ +# comment with ALERT + +''' multiline + comment + ### + ''' + +def func(x): + """ API docs """ + if x == 42: + func() + c1 = {} + c2 = { + 2.4, + 0x42 + } + a1 = [] + a2 = [ + "a", 032, ( + )] + else: + print("""multi + line + string""") + print("single \ + continued line ") + print('single line') + return float(len(a2)) diff --git a/autotests/input/test.qml b/autotests/input/test.qml new file mode 100644 index 0000000..d8f7cb5 --- /dev/null +++ b/autotests/input/test.qml @@ -0,0 +1,23 @@ +/* + * multi line comment + */ + +// single line comment + +import QtQuick 2.0 + +Rectangle { + property real myNumProp: 0.1e12; + property alias sub.color; + signal mySignal(int arg1, string arg2) + color: "lightsteelblue" + width: 320 + height: width/2 + + Rectangle { + id: sub + width: 0x10 + height: 007 + objectName: 'single quote' + } +} diff --git a/autotests/input/test.sql b/autotests/input/test.sql new file mode 100644 index 0000000..c7a5f3b --- /dev/null +++ b/autotests/input/test.sql @@ -0,0 +1,6 @@ +-- comment + +CREATE TABLE stuff COLUMNS(col1 INT, col2 Varchar); +SELECT * FROM stuff WHERE id = 'string'; +select * from stuff where id < 0.42; +Select col1, col2 From stuff Where stuff.col1 IS NOT NuLL; diff --git a/autotests/input/test.sql.syntax b/autotests/input/test.sql.syntax new file mode 100644 index 0000000..b433cc9 --- /dev/null +++ b/autotests/input/test.sql.syntax @@ -0,0 +1 @@ +SQL diff --git a/autotests/input/test.tex b/autotests/input/test.tex new file mode 100644 index 0000000..8da60c9 --- /dev/null +++ b/autotests/input/test.tex @@ -0,0 +1,5 @@ +% commet + +text \texttt{more text} + +\verb!verbatim text! normal text diff --git a/autotests/input/test_syntax.sql b/autotests/input/test_syntax.sql new file mode 100644 index 0000000..a538349 --- /dev/null +++ b/autotests/input/test_syntax.sql @@ -0,0 +1,41 @@ +-- kate: hl SQL (Oracle) +-- test case shipped with highlighting in bugzilla, LGPL + +begin + q'{adfasdf'sadfasdf j}'{' hkjhkhkjhkjh khlkhklj'fghdfghdfgh'hkjh'jkhkh'a' + Q'(asldflahsl;'dkjfhklsdfh)' + q'[asdasd;'asdasd'a]sd'asd'asasd]';11111111[1']; asdasdasdasd'errrrrrrrrrrrrrr-p + + q'agdfgsdfgfhfghjfgh'f'f'sdfg'sdfg'dfg#a' dafdfadasfasdf; + + Q'#gdfgsdfgsdfgsdfgsdfg#' afgasasdfasdfasfasdfasdfasdfasdfsdf + + if sldfjsdj then + case + when 1=1 then + aslfjsldkfj; + when 2=2 then + asdfg; + else + null; + end case; + + if sdfjh then + for i in 1 .. 2 + LOOP + dbms_output.put_line(q';ololo;'); + END Loop; + + while true + loop + dbms_output.put_line('1111'); + end loop; + end if; + ksjfklasjd; + fklj; + elsif + sdklfjsdklfj; + else + sdfdfsdf; + end if; +end; \ No newline at end of file diff --git a/autotests/input/test_syntax.sql.syntax b/autotests/input/test_syntax.sql.syntax new file mode 100644 index 0000000..679c648 --- /dev/null +++ b/autotests/input/test_syntax.sql.syntax @@ -0,0 +1 @@ +SQL (Oracle) diff --git a/autotests/reference/Dockerfile.ref b/autotests/reference/Dockerfile.ref new file mode 100644 index 0000000..092aa04 --- /dev/null +++ b/autotests/reference/Dockerfile.ref @@ -0,0 +1,19 @@ +# LGPLv2+ example file
    +
    +# This is a comment
    +FROM ubuntu:14.04
    +MAINTAINER James Turnbull # comment
    +ENV REFRESHED_AT 2014-06-01
    +
    +RUN apt-get -yqq update
    +RUN apt-get install -yqq software-properties-common python-software-properties
    +RUN add-apt-repository ppa:chris-lea/redis-server
    +RUN apt-get -yqq update
    +RUN apt-get -yqq install redis-server redis-tools
    +RUN apt-get -yqq update # comment
    +
    +VOLUME [ "/var/lib/redis", "/var/log/redis/" ]
    +
    +EXPOSE 6379
    +
    +CMD []
    diff --git a/autotests/reference/Kconfig.ref b/autotests/reference/Kconfig.ref new file mode 100644 index 0000000..49709e2 --- /dev/null +++ b/autotests/reference/Kconfig.ref @@ -0,0 +1,15 @@ +This is wrong but should not crash ] ) } !
    +
    +# comment
    +
    +config BR2_PACKAGE_GAMMARAY
    + bool "gammaray"
    + depends on BR2_PACKAGE_QT5
    + help
    + GammaRay Qt introspection probe.
    + second line of help, with correct indentation
    + third line underindented and thus wrong
    + default 'true'
    +
    +menu myMenu
    +endmenu
    diff --git a/autotests/reference/Makefile.ref b/autotests/reference/Makefile.ref new file mode 100644 index 0000000..26aa6a1 --- /dev/null +++ b/autotests/reference/Makefile.ref @@ -0,0 +1,25 @@ +# comment
    +
    +include Makefile.in
    +
    +
    .PHONY:
    all
    +
    +all: target
    +
    +foo = bar $(var) \
    + $(baz) quux
    +
    +ifeq ($(CC),gcc)
    + bla=$(call func,param1,param2)
    +else
    + libs=$(normal_libs)
    +endif
    +
    +target1:
    + error
    +
    +target2: bla.cpp $@
    + $(CC) bla.c -o bla.o
    + $(CC) bla.o $< \
    + -o bla.exe
    + @echo "hello"
    diff --git a/autotests/reference/basic.markdown.ref b/autotests/reference/basic.markdown.ref new file mode 100644 index 0000000..439cb04 --- /dev/null +++ b/autotests/reference/basic.markdown.ref @@ -0,0 +1,6 @@ +normal
    +
    +* item1
    +still part of item
    +
    +normal text again
    diff --git a/autotests/reference/basic.xml.ref b/autotests/reference/basic.xml.ref new file mode 100644 index 0000000..9e61a57 --- /dev/null +++ b/autotests/reference/basic.xml.ref @@ -0,0 +1,4 @@ + version="1.0" encoding="UTF-8"?>
    + attr1="a1">
    +
    +

    diff --git a/autotests/reference/complex.xml.ref b/autotests/reference/complex.xml.ref new file mode 100644 index 0000000..7d9efa4 --- /dev/null +++ b/autotests/reference/complex.xml.ref @@ -0,0 +1,13 @@ + version="1.0" encoding="UTF-8"?>
    +language SYSTEM "language.dtd"
    +[
    +
    + name "(?![0-9])[\w_:][\w.:_-]*">
    + entref "&(#[0-9]+|#[xX][0-9A-Fa-f]+|&name;);">
    +]>
    + attr1="a1" attr2="2.03" attr3="&entity;">
    +
    +

    +
    + wrong>>
    diff --git a/autotests/reference/cube.obj.ref b/autotests/reference/cube.obj.ref new file mode 100644 index 0000000..de5d901 --- /dev/null +++ b/autotests/reference/cube.obj.ref @@ -0,0 +1,33 @@ +# cube.obj
    +#
    +
    +g cube
    +
    +v 0.0 0.0 0.0
    +v 0.0 0.0 1.0
    +v 0.0 1.0 0.0
    +v 0.0 1.0 1.0
    +v 1.0 0.0 0.0
    +v 1.0 0.0 1.0
    +v 1.0 1.0 0.0
    +v 1.0 1.0 1.0
    +
    +vn 0.0 0.0 1.0
    +vn 0.0 0.0 -1.0
    +vn 0.0 1.0 0.0
    +vn 0.0 -1.0 0.0
    +vn 1.0 0.0 0.0
    +vn -1.0 0.0 0.0
    +
    +f 1//2 7//2 5//2
    +f 1//2 3//2 7//2
    +f 1//6 4//6 3//6
    +f 1//6 2//6 4//6
    +f 3//3 8//3 7//3
    +f 3//3 4//3 8//3
    +f 5//5 7//5 8//5
    +f 5//5 8//5 6//5
    +f 1//4 5//4 6//4
    +f 1//4 6//4 2//4
    +f 2//1 6//1 8//1
    +f 2//1 8//1 4//1
    diff --git a/autotests/reference/cube.ply.ref b/autotests/reference/cube.ply.ref new file mode 100644 index 0000000..bb86921 --- /dev/null +++ b/autotests/reference/cube.ply.ref @@ -0,0 +1,26 @@ +error before header
    +
    +ply
    +format ascii 1.0
    +comment TODO this is a comment
    +element vertex 8
    +property float x
    +property float y
    +property float z
    +element face 6
    +property list uint int vertex_indices
    +end_header
    +-1 -1 -1
    +1 -1 -1
    +1 1 -1
    +-1 1 -1
    +-1 -1 1
    +1 -1 1
    +1 1 1
    +-1 1 1
    +4 0 1 2 3
    +4 5 4 7 6
    +4 6 2 1 5
    +4 3 7 4 0
    +4 7 3 2 6
    +4 5 1 0 4
    diff --git a/autotests/reference/cube.stl.ref b/autotests/reference/cube.stl.ref new file mode 100644 index 0000000..d3e273d --- /dev/null +++ b/autotests/reference/cube.stl.ref @@ -0,0 +1,30 @@ +solid cube_corner
    + facet normal 0.0 -1.0 0.0
    + outer loop
    + vertex 0.0 0.0 0.0
    + vertex 1.0 0.0 0.0
    + vertex 0.0 0.0 1.0
    + endloop
    + endfacet
    + facet normal 0.0 0.0 -1.0
    + outer loop
    + vertex 0.0 0.0 0.0
    + vertex 0.0 1.0 0.0
    + vertex 1.0 0.0 0.0
    + endloop
    + endfacet
    + facet normal -1.0 0.0 0.0
    + outer loop
    + vertex 0.0 0.0 0.0
    + vertex 0.0 0.0 1.0
    + vertex 0.0 1.0 0.0
    + endloop
    + endfacet
    + facet normal 0.577 0.577 0.577
    + outer loop
    + vertex 1.0 0.0 0.0
    + vertex 0.0 1.0 0.0
    + vertex 0.0 0.0 1.0
    + endloop
    + endfacet
    +endsolid
    diff --git a/autotests/reference/example.rmd.ref b/autotests/reference/example.rmd.ref new file mode 100644 index 0000000..da42490 --- /dev/null +++ b/autotests/reference/example.rmd.ref @@ -0,0 +1,39 @@ +---
    +title: "test"
    +author: "me"
    +date: "07.10.2014"
    +output: html_document
    +---
    +
    +This is a simple test document. It shows syntax highlighting switches between YAML (above), R blocks
    +```{r, echo=FALSE}
    +for (i in 1:10) {
    + if(i>=10) print(i)
    +}
    +# two blank lines below
    +
    +sessionInfo()
    +```
    +
    +LaTeX equations,
    +$$
    +h_{i}(t \mid q,C) = h_{0}(t) e^{\beta_{1}quality_{i} + \beta_{2}C_{iq}}
    +$$
    +
    +and Markdown. A [link](http://example.com) in Markdown.
    +
    +Inline `r y <- 5 + x - sin(3)` R code.
    +Inline `y <- 5 + x - sin(3)` code.
    +
    +
    + Heading
    + =======
    +
    + Sub-heading
    + -----------
    + A list of editors:
    + * kate
    + * vim
    + * emacs
    +
    +*italic*, **bold**, `monospace`
    diff --git a/autotests/reference/firstNonSpace.c.ref b/autotests/reference/firstNonSpace.c.ref new file mode 100644 index 0000000..cd3ed3f --- /dev/null +++ b/autotests/reference/firstNonSpace.c.ref @@ -0,0 +1,7 @@ +#define 1
    + #define 2
    + #define 3
    + #define 4
    + #define 5
    + #define tab
    +
    diff --git a/autotests/reference/folding.cpp.ref b/autotests/reference/folding.cpp.ref new file mode 100644 index 0000000..bb11920 --- /dev/null +++ b/autotests/reference/folding.cpp.ref @@ -0,0 +1,15 @@ +/**
    + * multi-line comment
    + */
    +
    +/* comment */
    +{ { } {
    +//BEGIN
    +}
    +//END
    +}
    +
    +#if 0
    +#elif 1
    +#else
    +#endif
    diff --git a/autotests/reference/git-rebase.ref b/autotests/reference/git-rebase.ref new file mode 100644 index 0000000..1f31fd0 --- /dev/null +++ b/autotests/reference/git-rebase.ref @@ -0,0 +1,32 @@ +pick 318aceb Add test for Makefile highlighting
    +p 4c7182a Add first batch of test files resurrected from Kate 4.6
    +r 6f7d8a7 Sync xml files with KTextEditor
    +reword 8f0dbdc Add another batch of resurrected tests from Kate 4.6
    +e 828de45 Add some more resurrected tests from Kate 4.6
    +edit 6aa6264 Add simple coverage information for syntax definition tests
    +s 63df253 Add more syntax highlighting tests from Kate 4.6
    +squash 3e7771f Add three more tests recovered from Kate 4.6
    +f 5c7fd91 Add Kate 4.6 ASP syntax test
    +fixup 7a777ff Implement case-sensitive overrides for keyword rules
    +exec 2b16665 Implement dynamic DetectChar rules
    +drop dd808dc Quote captured strings we replace in regular expressions
    +x 0b703a3 Add a few more tests from the Kate 4.6 test suite
    +
    +# Rebase a27a854..0b703a3 onto a27a854 (13 command(s))
    +#
    +# Commands:
    +# p, pick = use commit
    +# r, reword = use commit, but edit the commit message
    +# e, edit = use commit, but stop for amending
    +# s, squash = use commit, but meld into previous commit
    +# f, fixup = like "squash", but discard this commit's log message
    +# x, exec = run command (the rest of the line) using shell
    +# d, drop = remove commit
    +#
    +# These lines can be re-ordered; they are executed from top to bottom.
    +#
    +# If you remove a line here THAT COMMIT WILL BE LOST.
    +#
    +# However, if you remove everything, the rebase will be aborted.
    +#
    +# Note that empty commits are commented out
    diff --git a/autotests/reference/hello.exs.ref b/autotests/reference/hello.exs.ref new file mode 100644 index 0000000..1f6ce6d --- /dev/null +++ b/autotests/reference/hello.exs.ref @@ -0,0 +1,11 @@ +parent = self()
    +
    +# Spawns an Elixir process (not an operating system one!)
    +spawn_link(fn ->
    + send parent, {:msg, "hello world"}
    +end)
    +
    +# Block until the message is received
    +receive do
    + {:msg, contents} -> IO.puts contents
    +end
    diff --git a/autotests/reference/highlight.ahdl.ref b/autotests/reference/highlight.ahdl.ref new file mode 100644 index 0000000..b1ff37d --- /dev/null +++ b/autotests/reference/highlight.ahdl.ref @@ -0,0 +1,43 @@ +-- Test file for kate's syntax highlighting
    +Title "Test file";
    +
    +-- BEGIN region (a region marker region) :)
    +
    +% multiline comment
    +goes on here %
    +
    +-- END
    +
    +FUNCTION FCT (Clk, Key) RETURNS (pulse);
    +
    +SUBDESIGN CDCLOCK2
    +(
    +in : INPUT; -- go in
    +out[3..0] : OUTPUT; -- come out
    +)
    +
    +VARIABLE
    +start : soft;
    +usec[3..0] : node;
    +
    +BEGIN
    +
    +in = FCT(clock, some_key); -- senseless code
    +
    +-- comment
    +blubb = (blobb[] == H"3ff");
    +
    +IF in THEN asdf
    +-- folde me
    +END IF;
    +
    +TABLE
    +-- missing code
    +END TABLE
    +
    +
    +END;
    +
    +-- hex, octal, binary
    +H"0" => B"1000000";
    +O"01234567";
    diff --git a/autotests/reference/highlight.asm-avr.ref b/autotests/reference/highlight.asm-avr.ref new file mode 100644 index 0000000..b5f68bc --- /dev/null +++ b/autotests/reference/highlight.asm-avr.ref @@ -0,0 +1,75 @@ +;********************************************************************
    +;* LED flasher: LED will flash with a X on/off ratio at PD6
    +;*
    +;* NOTE: delay depends in the value of X, 1 is fast, 255 is slow
    +;*
    +;* No copyright ©1998 RES® * FREEWARE *
    +;*
    +;* NOTE: Connect a low current LED with a 1k resistor in serie from
    +;* Vdd to pin 11 of the MCU. (Or a normal LED with a 330ohm)
    +;*
    +;* RES® can be reached by email: digitalaudio@mail.com
    +;* or visit the website: http://home.wanadoo.nl/electro1/avr
    +;*
    +;* Version :1.0
    +;* Date :12/26/98
    +;* Author :Rob's ElectroSoft®
    +;* Target MCU :AT90S1200-12PI@4MHz
    +;********************************************************************
    +
    +.include "1200def.inc"
    +
    + rjmp RESET ;reset handle
    +
    +
    +;* Long delay
    +
    +;* Register variables
    +
    + .def T1 = r1
    + .def T2 = r2
    + .def temp = r19
    +
    +;* Code
    +
    +
    + clr T1 ;T1 used as delay 2nd count
    + clr T2 ;T2 used as delay 3d count
    +
    + dec T2
    + brne delay_1
    + dec T1
    + brne delay_1
    + dec temp ;temp must be preset as
    + brne delay_1 ; delay master count
    + ret
    +
    +
    +;* Resets the data direction register D
    +
    +;* Defines
    +
    + .equ led = 6 ;LED at PD6
    +
    +;* Code
    +
    +
    + sbi DDRD, led ;connect LED to PORTD pin 6
    +
    +
    +;* Main program
    +
    +;* This part will let the LED go on and off by X
    +
    +;* Register variables
    +
    + .equ X = 10 ;enter delaytime X
    +
    +
    + sbi PORTD, led ;LED on
    + ldi temp, X ;X sec delay
    + rcall longDelay
    + cbi PORTD, led ;LED off
    + ldi temp, X ;X sec delay
    + rcall longDelay
    + rjmp flash ;another run
    diff --git a/autotests/reference/highlight.asm-nasm.ref b/autotests/reference/highlight.asm-nasm.ref new file mode 100644 index 0000000..b1e5012 --- /dev/null +++ b/autotests/reference/highlight.asm-nasm.ref @@ -0,0 +1,27 @@ +; Example file for nasm.xml kate syntax file
    +; compile with `nasm example.asm -f elf -o example.o`
    +; and link with 'gcc example.o -o example`
    +; Public domain
    +; kate: hl Intel x86 (NASM);
    +
    +section .data
    +
    +hello dd 'Hello World', 0x0A, 0h
    +printf_param dd '%s', 0q
    +
    +section .text
    +
    +extern printf
    +
    +global main
    +
    + push ebp
    + mov ebp, esp
    +
    + push hello
    + push printf_param
    + call printf
    +
    + mov eax, 0b
    + leave
    + ret
    diff --git a/autotests/reference/highlight.asp.ref b/autotests/reference/highlight.asp.ref new file mode 100644 index 0000000..2694397 --- /dev/null +++ b/autotests/reference/highlight.asp.ref @@ -0,0 +1,58 @@ +<% 'kate: hl ASP;
    +if ( instr(request.servervariables("PATH_INFO"),"login.asp") <= 0 and instr(request.servervariables("PATH_INFO"),"inset") <= 0 and instr(request.servervariables("PATH_INFO"),"Data") <= 0 and instr(request.servervariables("PATH_INFO"),"dropDown") <= 0 ) then
    + Session("originalRequestedPage") = Request.ServerVariables("PATH_INFO") & "?" & Request.ServerVariables("QUERY_STRING")
    +end if
    +
    +function countRecords( rsToCount )
    + numRecs = 0
    +
    + do until rsToCount.eof
    + numRecs = numRecs + 1
    +
    + rsToCount.movenext
    + loop
    +
    + rsToCount.close ' just to make sure nobody
    + ' tries to operate on the recordset,
    + ' which has already reached eof
    +
    + countRecords = numRecs
    +end function
    +
    +function unique( rs, sortColumn ) ' return unique instances of text in sortColumn within rs
    + dim sorted()
    +
    + redim sorted(1)
    + dim i
    + i = 0
    + do until rs.eof
    + if (not find( rs(sortColumn), sorted )) then
    + redim preserve sorted(i+1)
    + sorted(i) = rs(sortColumn)
    + i = i + 1
    + end if
    + rs.MoveNext
    + loop
    +
    + redim preserve sorted(i-1) ' the function will add an extra blank entry to the array
    +
    + rs.Close ' close the recordset - we'll be using it again - and reset i - well be using it again, too
    +
    + unique = sorted
    +end function
    +
    +sub testSub( variable ) ' do nothing impressive...
    + dim newVar
    +
    + newVar = variable
    +
    + if ( variable = true )
    + response.end
    + else %>
    +
    +

    We are writing text.


    + class="stuff"><%=newVar%>


    +

    We have written text and outputted a variable.


    +
    +<% end if
    +end sub %>
    diff --git a/autotests/reference/highlight.awk.ref b/autotests/reference/highlight.awk.ref new file mode 100644 index 0000000..0cfac76 --- /dev/null +++ b/autotests/reference/highlight.awk.ref @@ -0,0 +1,28 @@ +#!/usr
    +# AWK hl test
    +
    +# BEGIN and END are also matched as patterns
    +BEGIN {
    + p = 0;
    +}
    +
    +/some pattern/ {
    + p++;
    +}
    +
    +# / inside brackets is not considered end of expression
    +# a loose division operator (/) is not mismatched as a pattern.
    +$1 =~ /[^abc/]def/ || b == 3 / 5 {
    +
    + gsub ( FILENAME );
    +
    +}
    +
    +# TODO and FIXME also work in comments in Awk.
    +
    +# Also backslash in patterns works.
    +/\/usr\/bin\/awk/ { print "This is me"; }
    +
    +END {
    + print p;
    +}
    diff --git a/autotests/reference/highlight.bib.ref b/autotests/reference/highlight.bib.ref new file mode 100644 index 0000000..e7ffc60 --- /dev/null +++ b/autotests/reference/highlight.bib.ref @@ -0,0 +1,31 @@ +% test file for kate's bibtex syntax highlighting
    +
    +@Article{artikel,
    +author = {Me},
    +title = {Something},
    +journal = {JHEP},
    +year = {2003},
    +}
    +
    +@Book
    +
    +{
    +
    +boek,
    +author = "Someone",
    +title = "Something",
    +journal = "Nucl. Phys. B",
    +year = "2003",
    +}
    +
    +This is ignored by BibTeX, no special highlighting
    +%This is not a comment, it is just ignored (thanks to the people in #latex) :)
    +
    +@string{test="lange string die ik niet vaak opnieuw wil intikken"}
    +
    +@PhdThesis{thesis,
    +author = {Me},
    +title = {Dunno},
    +school = {ITFA},
    +year = {2005, hopefully},
    +}
    diff --git a/autotests/reference/highlight.cmake.ref b/autotests/reference/highlight.cmake.ref new file mode 100644 index 0000000..46b3656 --- /dev/null +++ b/autotests/reference/highlight.cmake.ref @@ -0,0 +1,49 @@ +#this CMakeLists.txt doesn't do anything useful, but it shoudl demonstrate the cmake syntax highlighting
    +#Alexander Neundorf
    +
    +#ok this is a comment
    +#and another line
    +#a built-in command, it's bold black
    +ADD_DEFINITIONS(-Wall -Wctor-dtor-privacy -Woverloaded-virtual -Wno-long-long -pipe -fno-builtin -fno-exceptions)
    +
    +#and another function
    +INCLUDE_DIRECTORIES(
    +#comments are also highlighted inside function parameters
    +#variables are Qt::blue
    +${CMAKE_CURRENT_SOURCE_DIR}/../../lib/qt4/include/Qt
    +)
    +
    +# BEGIN defining a macro
    +MACRO(ECOS_ADD_EXECUTABLE _exe_NAME )
    +
    +#special parameters are italic, see the STATIC in the next line
    +ADD_LIBRARY(${_exe_NAME} STATIC ${ARGN})
    +#but not in the following line ?
    + ADD_LIBRARY(${_exe_NAME} STATIC ${ARGN})
    +# it seems the kate highlighting file could need some love, Alex
    +
    +
    +#another command with a bunch of variables and special parameters
    + ADD_CUSTOM_COMMAND(
    + TARGET ${_exe_NAME}
    + PRE_LINK
    + COMMAND ${CMAKE_C_COMPILER}
    + ARGS -o ${_exe_NAME}
    +$\(${_exe_NAME}_SRC_OBJS\) -nostdlib -nostartfiles -Lecos/install/lib -Ttarget.ld
    + )
    +
    +#add the created files to the make_clean_files
    + SET(ECOS_ADD_MAKE_CLEAN_FILES ${ECOS_ADD_MAKE_CLEAN_FILES};${_exe_NAME};)
    +#and another command...
    + SET_DIRECTORY_PROPERTIES(
    + PROPERTIES
    + ADDITIONAL_MAKE_CLEAN_FILES "${ECOS_ADD_MAKE_CLEAN_FILES}"
    + )
    +ENDMACRO(ECOS_ADD_EXECUTABLE)
    +# END of macro
    +
    +#calling a self-defined function, variables are also Qt::blue here
    +ECOS_ADD_EXECUTABLE(${PROJECT_NAME} ${the_sources} ${qt4_moc_SRCS})
    +
    +
    +
    diff --git a/autotests/reference/highlight.css.ref b/autotests/reference/highlight.css.ref new file mode 100644 index 0000000..0db2df3 --- /dev/null +++ b/autotests/reference/highlight.css.ref @@ -0,0 +1,49 @@ +/**
    + * This is a pseudo CSS file to test Kate's CSS syntax highlighting.
    + */
    +
    +@import url("othersheet.css") screen, tv;
    +
    +body {
    + font-size: 15pt;
    + font-family: Verdana, Helvetica, "Bitstream Vera Sans", sans-serif;
    + margin-top: 0px; /* yet another comment */
    + margin-bottom: 0px;
    + // this is no comment, it's just broken!
    + margin-left: 0px;
    + margin-right: 0px;
    +}
    +
    +.something
    +{
    + margin-right: 0px;
    + color: #cdd;
    + color: #AAFE04;
    + color: rgb(10%,30%,43%);
    + background: maroon;
    +}
    +
    +a:hover {
    +}
    +
    +#header,
    +p.intro:first-letter,
    +p:lang(nl),
    +img[align="right"]
    +{
    + border: 1px solid Qt::red !important;
    + -moz-border-radius: 15px; /* unknown properties render italic */
    +}
    +
    +@media print {
    +
    + #header
    + {
    + display: none;
    + }
    +
    +}
    +
    +/*
    +TODO: add more tests, e.g. media
    +*/
    diff --git a/autotests/reference/highlight.d.ref b/autotests/reference/highlight.d.ref new file mode 100644 index 0000000..55184da --- /dev/null +++ b/autotests/reference/highlight.d.ref @@ -0,0 +1,195 @@ +/********
    +* Highlight testing module.
    +*
    +* Do not attempt to run this!
    +***********/
    +module highlighttest;
    +import X = null;
    +
    +/++ Pragma directives. DDoc + DDoc embedded items. Special Tokens.
    ++
    ++ ---
    ++ // comment
    ++ #line 12 "hightlighttest.d" /* block comment */
    ++ #line __LINE__ __FILE__ /++ embedded block comment +/
    ++
    ++ pragma /* */ (msg, "what?");
    ++ pragma(/++ +/ lib, "insane.a");
    ++ pragma(D_Custom_Extension, "custom data");
    ++ ---
    ++/
    +
    +/// version condition
    +version = X;
    +version (X) ;
    +version(linux) {}
    +
    +/// linkage
    +extern
    + (C) {}
    +extern :
    +;
    +extern (Windows) {}
    +
    +/// alias & typedef
    +alias int.min minint;
    +typedef int myint;
    +
    +int main(char[][] args) {
    + /// statements
    + if (1) {}
    + else {}
    + with (N) {x = B}
    +
    + /// attributes
    + auto x = 1;
    + static if (true) {}
    + void (in X, out Y) {} // NOTE: using in like this is rare, more common to use as an expression and no way to tell apart?
    +
    + /// deprecated
    + deprecated void fct ();
    +
    + /// types
    + void a;
    + ushort u;
    + int[uint] AA;
    + class C;
    + enum N : int { A = 5, B }
    + typeof(u) u2;
    +
    + /// expressions
    + x = cast(int) 55;
    + void* p = null;
    + p = cast(void*) new int;
    + x = 1 in AA; // NOTE: a THIRD use of in. How to detect??
    + assert (true);
    +
    + /// libsymbols
    + string s = "";
    + throw new Exception;
    + TypeInfo ti = typeid(int);
    +
    + /// tests
    + debug {}
    + debug (2) {}
    + debug (DSymb) {}
    + unittest {}
    +
    + /// scope (as attribute and as statement)
    + scope struct S;
    + scope (exit) {}
    + scope
    + (success) {} // NOTE: rules cannot match across new-lines
    + scope (failure) {}
    +
    + /// Properties
    + x = int.min;
    + s = (5-3).stringof;
    +
    + /// strings
    + s = r"raw string";
    + s = x"00FF";
    + s = \n \a;
    + s = \u1234;
    + s = \U12345678;
    + s = \& ;
    + char c = 'a';
    + s = "abc 012 \" \n \x12 \u1234 \U12345678";
    + s = `BQString '"`;
    +
    + /// region markers
    + //BEGIN x
    + //END x
    +
    + /// DDoc
    + /*******
    + * DDoc
    + *
    + * Section:
    + * New section.
    + * $(I italic)
    + *******/
    + /+++++++
    + + DDoc
    + + /+
    + + +/
    + +++++++/
    +
    + // comments
    + // FIXME NOTE
    + /* comment */
    + /+ comment /+ nested comment +/ +/
    +
    + /// brace folding
    + {
    + }
    +
    + /** normal text
    + * ---
    + * .x;
    + * ..
    + * ...
    + * ....
    + * .....
    + * _._
    + * _e1
    + * ---
    + */
    +
    + /// float and int literals
    + int i;
    + real r;
    + ireal ir;
    + r = .0;
    + r = 0f;
    + ir = 0e0i;
    + ir = 0.fi;
    + r = 0.0e0;
    + r = 0xF.Fp0;
    + r = 0x_._p0_;
    + i = 5;
    + i = -1;
    + i = 0b10;
    + i = 0070;
    + i = 00;
    + i = 0xF0;
    +
    + /// ranges
    + int[] A;
    + i = A[1];
    + A = A[0..$];
    + A = A[0..0];
    + A = A[0..length];
    +
    + /// labels
    + label:
    + goto label;
    +
    + /// function, delegate
    + creal function () fp = function creal() { return 0f+0fi; };
    + void delegate (in int i, lazy int b) dg = delegate void (int, int) {}
    +
    + /// in, out, body
    + // NOTE: highlighting in & out as statements here could be difficult
    + float F ()
    + in {}
    + out (result) {}
    + body {}
    +
    + /// try, catch, finally
    + try {
    + throw new Exception("oh no... ");
    + } catch (Exception e) {
    + } finally {
    + }
    +
    + /// mixin
    + mixin("return false;").stringof;
    +
    + /// templates
    + ; // what does this do?
    + Tp (T) {
    + Tp t;
    + }
    + Tp!(int) y;
    +}
    diff --git a/autotests/reference/highlight.do.ref b/autotests/reference/highlight.do.ref new file mode 100644 index 0000000..3b3c1f3 --- /dev/null +++ b/autotests/reference/highlight.do.ref @@ -0,0 +1,89 @@ +/* Test file for kate's stata syntax highlighting
    +*/
    +*! version 1.2.0 2mar2003 E. Leuven
    +program define spellsplit
    + version 7
    + syntax [anything], spell(varlist min=2 max=2) [ by(varlist)]
    + tokenize `spell'
    + local date0 `1'
    + local date1 `2'
    + local f0 : format `date0'
    + local f1 : format `date1'
    +
    + /* set default statistic */
    + local current "mean"
    +
    + gettoken left anything : anything, match(prns)
    + while "`left'"!="" {
    + if "`prns'"!="" {
    + if !inlist("`left'","mean","sum") {
    + di as error "Statistic `left' not supported"
    + exit 198
    + }
    + local current "`left'"
    + }
    + else {
    + local `current'vars ``current'vars' `left'
    + }
    + gettoken left anything : anything, match(prns)
    + }
    + if ("`meanvars'"!="") {
    + confirm var `meanvars'
    + unab meanvars : `meanvars'
    + }
    + if ("`sumvars'"!="") {
    + confirm var `sumvars'
    + unab sumvars : `sumvars'
    + }
    +
    + quietly {
    + g _count = 1
    + local xvars `meanvars' `sumvars' _count
    +
    + /* create dummy by-var if no by option is specified */
    + if "`by'"=="" {
    + tempvar by
    + g byte `by' = 1
    + }
    + tempvar `xvars' `by'
    +
    + /* create negative for subtraction when spell ends */
    + cap foreach v of varlist `xvars' {
    + g double ``v'' = -`v'
    + local txvars `txvars' ``v''
    + }
    + cap foreach v of varlist `by' {
    + g double ``v'' = `v'
    + local txvars `txvars' ``v''
    + }
    +
    + stack `date0' `xvars' `by' `date1' `txvars', into(`date0' `xvars' `by') clear
    +
    + /* calculate totals per date */
    + cap foreach v of varlist `xvars' {
    + egen double ``v'' = sum(`v'), by(`by' `date0')
    + }
    +
    + /* unique dates only */
    + by `by' `date0', sort: keep if _n==1
    +
    + /* calculate totals (+ when spell starts - when ends) */
    + sort `by'
    + cap foreach v of varlist `xvars' {
    + by `by': replace `v' = sum(``v'')
    + }
    + by `by': g `date1' = `date0'[_n + 1]
    +
    + drop if `date0'>`date1'
    + drop _stack
    + drop if _count==0
    + order `by' `date0' `date1' `xvars'
    + format `date0' `f0'
    + format `date1' `f1'
    +
    + cap for var `meanvars': replace X = X/_count
    +
    + compress
    + }
    +
    +end
    diff --git a/autotests/reference/highlight.dox.ref b/autotests/reference/highlight.dox.ref new file mode 100644 index 0000000..6a5485e --- /dev/null +++ b/autotests/reference/highlight.dox.ref @@ -0,0 +1,227 @@ +This is a pseudo doxygen file to test Kate's doxyge syntax highlighting.
    +
    +Normal text, no HL.
    +===================
    +a multiline comment may begin with a /*! */, too. That should work,
    +because it is the same "entrance rule".
    +
    +popping tests:
    +/** multiline */ end of doxygen HL mode
    +/*! multiline */ end of doxygen HL mode
    +//! singleline, where */ should be ignored! still doxygen HL mode
    +/// singleline, where */ should be ignored! still doxygen HL mode
    +///< singleline, where */ should be ignored! still doxygen HL mode
    +begin and end immediately:
    +/********/ actually no doxygen comment - used for "info boxes" :)
    +/**/ <-- it really works --- end of doxygen HL mode
    +/*!*/ end of doxygen HL mode
    +
    +
    +/** \code rest of line is normal comment HL */ end of doxygen HL mode
    +/** \code rest of line is normal comment HL
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +
    +/** \file aword rest of line is normal comment HL */ end of doxygen HL mode
    +/** \file */aword <-- pop! no doxygen HL mode
    +/** \file aword rest of line is normal comment HL
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +
    +/** \brief A short description */ end of doxygen HL mode
    +/** \brief */A <-- pop! end of doxygen HL mode
    +/** \brief A short description
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +
    +/** \page aword rest of line is string */ end of doxygen HL mode
    +/** \page */aword <-- pop! end of doxygen HL mode
    +/** \page aword rest of line is string
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +
    +/** \image aword aword rest of line is normal HL */ end of doxygen HL mode
    +/** \image aword */aword <-- pop! end of doxygen HL mode
    +/** \image */aword aword <-- pop! end of doxygen HL mode
    +/** \image aword aword rest of line is normal HL
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +Tests for HTML tags in doxygen HL mode:
    +=======================================
    +/** href="blubb" href='blubb'> */ end of doxygen HL mode
    +/** href="blubb" href='blubb'*/> end of doxygen HL mode
    +/** href="blubb" href='blubb*/'> end of doxygen HL mode
    +/** href="blubb" href='blub*/b'> end of doxygen HL mode
    +/** href="blubb" href='b*/lubb'> end of doxygen HL mode
    +/** href="blubb" href='*/blubb'> end of doxygen HL mode
    +/** href="blubb" href=*/'blubb'> end of doxygen HL mode
    +/** href="blubb" href*/='blubb'> end of doxygen HL mode
    +/** href="blubb" hre*/f='blubb'> end of doxygen HL mode
    +/** href="blubb" */href='blubb'> end of doxygen HL mode
    +/** href="blubb"> */ end of doxygen HL mode
    +/** href="blubb"*/> end of doxygen HL mode
    +/** href="blubb*/"> end of doxygen HL mode
    +/** href="blub*/b"> end of doxygen HL mode
    +/** href="*/blubb"> end of doxygen HL mode
    +/** href=*/"blubb"> end of doxygen HL mode
    +/** href*/="blubb"> end of doxygen HL mode
    +/** h*/ref="blubb"> end of doxygen HL mode
    +/** */href="blubb"> end of doxygen HL mode
    +/** */ href="blubb"> end of doxygen HL mode
    +/** <*/a href="blubb"> end of doxygen HL mode
    +
    +//! href="blubb" href='blubb'> */ stay in doygen HL mode
    +//! href="blubb" href='blubb'*/> stay in doygen HL mode
    +//! href="blubb" href='blubb*/'> stay in doygen HL mode
    +//! href="blubb" href='blu*/bb'> stay in doygen HL mode
    +//! href="blubb" href='*/blubb'> stay in doygen HL mode
    +//! href="blubb" href=*/'blubb'> stay in doygen HL mode
    +//! href="blubb"> */ stay in doygen HL mode
    +//! href="blubb"*/> stay in doygen HL mode
    +//! href="blubb*/"> stay in doygen HL mode
    +//! href="blub*/b"> stay in doygen HL mode
    +//! href="*/blubb"> stay in doygen HL mode
    +//! href=*/"blubb"> stay in doygen HL mode
    +//! href*/="blubb"> stay in doygen HL mode
    +//! h*/ref="blubb"> stay in doygen HL mode
    +//! */href="blubb"> stay in doygen HL mode
    +//! */ href="blubb"> stay in doygen HL mode
    +//! <*/a href="blubb"> stay in doygen HL mode
    +//! href="blubb"> stay in doygen HL
    +here should be normal HL mode (no doxygen!)
    +
    +Tests for HTML tags in doxygen HL mode with tags:
    +=================================================
    +
    +/** \code rest of line is normal comment HL */ end of doxygen HL mode
    +/** \code rest of */> end of doxygen HL mode
    +/** \code rest of end of doxygen HL mode

    +/** \code rest of end of doxygen HL mode

    +/** \code rest of */'blubb'> end of doxygen HL mode
    +/** \code rest of end of doxygen HL mode

    +/** \code rest */"blubb"> of end of doxygen HL mode

    +/** \code rest */ref="blubb"> of end of doxygen HL mode

    +/** \code rest <*/a href="blubb"> of end of doxygen HL mode
    +/** \code rest of line is normal comment HL
    + * comment HL mode text
    + */ end of doxygen HL mode
    +
    +
    +/** \file aword rest of line is normal comment HL */ end of doxygen HL mode
    +/** \file awo*/rd end of doxygen HL mode
    +/** \file awo*/gnored_here>rd end of doxygen HL mode
    +/** \file awo<*/html_should_be_ignored_here>rd end of doxygen HL mode
    +/** \file a*/word end of doxygen HL mode
    +/** \file aword rest of line is normal comment HL
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +
    +/** \brief A short href="blubb"> of href='blubb'> description */ end of doxygen HL mode
    +/** \brief A short href="blubb"> of href='blubb'*/> end of doxygen HL mode
    +/** \brief A short href="blubb"> of href='*/blubb'> end of doxygen HL mode
    +/** \brief A short href="blubb"> of href=*/'blubb'> end of doxygen HL mode
    +/** \brief A short href="blubb"> of href*/='blubb'> end of doxygen HL mode
    +/** \brief A short href="blubb"> of */href='blubb'> end of doxygen HL mode
    +/** \brief A short href="blubb"> of <*//a href='blubb'> end of doxygen HL mode
    +/** \brief A short href="blubb"*/> of end of doxygen HL mode
    +/** \brief A short href="blubb*/"> of end of doxygen HL mode
    +/** \brief A short href="*/blubb"> of end of doxygen HL mode
    +/** \brief A short href=*/"blubb"> of end of doxygen HL mode
    +/** \brief A short href*/="blubb"> of end of doxygen HL mode
    +/** \brief A short h*/ref="blubb"> of end of doxygen HL mode
    +/** \brief A short href="blubb"> of href='blubb'> description
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +
    +/** \page aword A short href="blubb"> of href='blubb'> description */ end of doxygen HL mode
    +/** \page aword A short href="blubb"> of href='blubb'*/> end of doxygen HL mode
    +/** \page aword A short href="blubb"> of href='*/blubb'> end of doxygen HL mode
    +/** \page aword A short href="blubb"> of href=*/'blubb'> end of doxygen HL mode
    +/** \page aword A short href="blubb"> of href*/='blubb'> end of doxygen HL mode
    +/** \page aword A short href="blubb"> of */href='blubb'> end of doxygen HL mode
    +/** \page aword A short href="blubb"> of <*//a href='blubb'> end of doxygen HL mode
    +/** \page aword A short href="blubb"*/> of end of doxygen HL mode
    +/** \page aword A short href="blubb*/"> of end of doxygen HL mode
    +/** \page aword A short href="*/blubb"> of end of doxygen HL mode
    +/** \page aword A short href=*/"blubb"> of end of doxygen HL mode
    +/** \page aword A short href*/="blubb"> of end of doxygen HL mode
    +/** \page aword A short h*/ref="blubb"> of end of doxygen HL mode
    +/** \page aword A short <*/a href="blubb"> of end of doxygen HL mode
    +/** \page aword A shor*/t of end of doxygen HL mode
    +/** \page awor*/d A short of end of doxygen HL mode
    +/** \page */aword A short of end of doxygen HL mode
    +/** \page aword A short href="blubb"> of href='blubb'> description
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +
    +/** \image aword aword rest of line is normal HL */ end of doxygen HL mode
    +/** \image aword aword rest of line is*/ end of doxygen HL mode
    +/** \image aword aword*/ end of doxygen HL mode
    +/** \image aword aw*/ord end of doxygen HL mode
    +/** \image aword */aword end of doxygen HL mode
    +/** \image aword*/ end of doxygen HL mode
    +/** \image awo*/rd end of doxygen HL mode
    +/** \image */aword end of doxygen HL mode
    +/** \ima*/ge end of doxygen HL mode
    +/** \image aword aword rest of line is normal HL
    + * comment HL mode
    + */ end of doxygen HL mode
    +
    +Some further tests for singlelinecomments (* / should not pop!)
    +===============================================================
    +/// a singlelinecommment blubb blubb */. stay in doxygen HL mode
    +/// \code a singlelinecommment blubb b*/lubb. stay in doxygen HL mode
    +/// \code*/ a singlelinecommment blubb blubb. stay in doxygen HL mode
    +/// \code a singlelinecommment blubb blubb
    +/// \brief a descriptive text (string) stay in doxygen HL mode
    +/// \brief a descriptive text (string)*/ description should go on here
    +/// \brief a descriptive text */(string) description should go on here
    +/// \brief */a descriptive text (string) description should go on here
    +/// \ref aword a descriptive text (string) */ description should go on here
    +/// \ref aword a descriptive text (str*/ing) description should go on here
    +/// \ref aword a des*/criptive text (string) description should go on here
    +/// \ref aword*/ a descriptive text (string) description should go on here
    +/// \ref aw*/ord a descriptive text (string) description should go on here
    +/// \ref */aword a descriptive text (string) description should go on here
    +
    +HTML comment tests:
    +===================
    +//! \ref word descriptive text (string)
    +normal HL mode.
    +//! \ref w descriptive text (string)
    +/** \ref word descriptive text (string)

    +normal HL mode.
    +/** \ref w
    + * normal doxygen HL mode.
    + */
    +
    +
    +And final tests for a word: a single char:
    +===========================================
    +
    +//! \ref word descriptive text (string)
    +//! \ref w descriptive text (string)
    +
    +
    +//! \image word1 word2 b descriptive text (string)
    +//! \image a word b descriptive text (string)
    +
    +
    +//! \brief A b c d e description should go on here
    +
    +
    +//! \file word rest of line is normal comment HL
    +//! \file a word rest of line is normal comment HL
    +
    +no doxygen HL mode here.
    +== END OF TESTFILE ==
    diff --git a/autotests/reference/highlight.erl.ref b/autotests/reference/highlight.erl.ref new file mode 100644 index 0000000..6fc4243 --- /dev/null +++ b/autotests/reference/highlight.erl.ref @@ -0,0 +1,68 @@ +% testing for the erlang syntax highlighter
    +% NOTE alerts work in comments to TODO !
    +
    +% pragmas (show as keywords)
    +-module
    +-export
    +-define
    +-undef
    +-ifdef
    +-ifndef
    +-else
    +-endif
    +-include
    +-include_lib
    +
    +% key words
    +after begin case catch cond end fun if let of query receive all_true some_true
    +
    +% operators
    +div rem or xor bor bxor bsl bsr and band not bnot
    ++ - * / == /= =:= =/= < =< > >= ++ -- = ! <-
    +
    +% separators (show as functions)
    +( ) { } [ ] . : | || ; , ? -> #
    +
    +% functions - predefined (part of erlang module) - show as functions
    +abs accept alarm apply atom_to_list binary_to_list binary_to_term check_process_code
    +concat_binary date delete_module disconnect_node element erase exit float float_to_list
    +garbage_collect get get_keys group_leader halt hd integer_to_list is_alive is_atom is_binary
    +is_boolean is_float is_function is_integer is_list is_number is_pid is_port is_process_alive
    +is_record is_reference is_tuple length link list_to_atom list_to_binary list_to_float list_to_integer
    +list_to_pid list_to_tuple load_module loaded localtime make_ref module_loaded node nodes now
    +open_port pid_to_list port_close port_command port_connect port_control ports pre_loaded process_flag
    +process_info processes purge_module put register registered round self setelement size
    +spawn spawn_link spawn_opt split_binary statistics term_to_binary throw time tl trunc tuple_to_list
    +unlink unregister whereis
    +
    +% functions - inferred
    +module:function
    +function()
    +
    +% atoms (show as "char")
    +% begin with underscore, lowercase, contain numbers letters and @ - or anything between ''
    +middle_underscore
    +abc ab4d a@cd8 a@
    +'And this is (\012) an atom \' Atoo' Variable 'atom again'
    +
    +% variables (begin with capital letter or underscore, contain numbers, letters and @)
    +_leadingUnderscore AbdD@ B45@c
    +
    +% this is a string
    +"a string sits between \" double quotes" atom "more string"
    +
    +% integers (decimal)
    +1. 234 $A
    +
    +% integers (specified base)
    +2#10101 34#567
    +
    +% float
    +12.23 12.9e-67 12.8E+89 33.34e89
    +
    +% and finally some real code, so we can see what it looks like...
    +-module(codetest). % everything is in a module
    +-export([fac/1]). % name and number of arguments - need this to be called outside of the module
    +
    +fac(N) when N > 0 -> N * fac(N-1);
    +fac(N) when N == 0 -> 1.
    diff --git a/autotests/reference/highlight.exu.ref b/autotests/reference/highlight.exu.ref new file mode 100644 index 0000000..9330549 --- /dev/null +++ b/autotests/reference/highlight.exu.ref @@ -0,0 +1,97 @@ +-- Test file for Kate's Euphoria syntax highlighting/code folding.
    +-- BEGIN region marker test
    +
    +-- code here
    +
    +-- END region marker test
    +
    +-- The N Queens Problem:
    +-- Place N Queens on an NxN chess board
    +-- such that they don't threaten each other.
    +constant N = 8 -- try some other sizes
    +constant ROW = 1, COLUMN = 2
    +constant TRUE = 1, FALSE = 0
    +type square(sequence x)
    +-- a square on the board
    + return length(x) = 2
    +end type
    +type row(integer x)
    +-- a row on the board
    + return x >= 1 and x <= N
    +end type
    +
    +function threat(square q1, square q2)
    +-- do two queens threaten each other?
    + if q1[COLUMN] = q2[COLUMN] then
    + return TRUE
    + elsif q1[ROW] - q1[COLUMN] = q2[ROW] - q2[COLUMN] then
    + return TRUE
    + elsif q1[ROW] + q1[COLUMN] = q2[ROW] + q2[COLUMN] then
    + return TRUE
    + elsif q1[ROW] = q2[ROW] then
    + return TRUE
    + else
    + return FALSE
    + end if
    +end function
    +
    +function conflict(square q, sequence queens)
    +-- Would square p cause a conflict with other queens on board so far?
    + for i = 1 to length(queens) do
    + if threat(q, queens[i]) then
    + return TRUE
    + end if
    + end for
    + return FALSE
    +end function
    +
    +integer soln
    +soln = 0 -- solution number
    +
    +procedure print_board(sequence queens)
    +-- print a solution, showing the Queens on the board
    + integer k
    + position(1, 1)
    + printf(1, "Solution #%d\n\n ", soln)
    + for c = 'a' to 'a' + N - 1 do
    + printf(1, "%2s", c)
    + end for
    + puts(1, "\n")
    + for r = 1 to N do
    + printf(1, "%2d ", r)
    + for c = 1 to N do
    + if find({r,c}, queens) then
    + puts(1, "Q ")
    + else
    + puts(1, ". ")
    + end if
    + end for
    + puts(1, "\n")
    + end for
    + puts(1, "\nPress Enter. (q to quit) ")
    + while TRUE do
    + k = get_key()
    + if k = 'q' then
    + abort(0)
    + elsif k != -1 then
    + exit
    + end if
    + end while
    +end procedure
    +
    +procedure place_queen(sequence queens)
    +-- place queens on a NxN chess board
    +-- (recursive procedure)
    + row r -- only need to consider one row for each queen
    + if length(queens) = N then
    + soln += 1
    + print_board(queens)
    + return
    + end if
    + r = length(queens)+1
    + for c = 1 to N do
    + if not conflict({r,c}, queens) then
    + place_queen(append(queens, {r,c}))
    + end if
    + end for
    +end procedure
    diff --git a/autotests/reference/highlight.f90.ref b/autotests/reference/highlight.f90.ref new file mode 100644 index 0000000..280360b --- /dev/null +++ b/autotests/reference/highlight.f90.ref @@ -0,0 +1,181 @@ +! This file is an example to test the syntax highlighting file F.xml
    +! (for fortran 90 and F)
    +
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +! THIS IS AN EXAMPLE OF A MODULE !
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +module module_example
    +
    + ! use 'implicit none' when you want all variables to be declared
    + implicit none
    +
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +! PUBLICS AND PRIVATES
    +
    + ! In fortran 90 you can define your own operator
    + public :: operator(.norm.)
    + public :: operator(+) ! <-- you can also overload the usual operators
    + public :: factorial
    + public :: example_fn
    +
    + private :: point3d_add
    + private :: point3d_norm
    +
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +! USER-DEFINED TYPES...
    +
    + ! This is a definition to use in declarations of real variables,
    + ! parameters, etc.
    + integer, parameter, public :: kr = selected_real_kind(10)
    +
    + ! This is a user-defined type
    + type, public :: point3d
    + real(kind=kr) :: x, y, z
    + end type point3d
    +
    + ! This type is useless: it is only an example of type definition!
    + type, public :: example_type
    + complex(kind=kr) :: c ! <-- a complex number (two reals of kind kr)!
    + real, dimension(-10:10) :: & ! <-- this line does not end here!
    + r1, r2 ! <-- this is the final part of the previous line
    + real, pointer, dimension(:) :: pointer_to_array_of_real
    + real, dimension(:), pointer :: array_of_pointer_to_real
    + end type example_type
    +
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +! INTERFACES...
    +
    + ! Interface for the norm of a 3-D vector
    + interface operator(.norm.)
    + module procedure point3d_norm
    + end interface
    +
    + ! Interface for the operator '+'
    + interface operator(+)
    + module procedure point3d_add
    + end interface
    +
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +! SOME DECLARATIONS...
    +
    + ! A real number can be declared with the following line:
    + real(kind=kr) :: real_var1
    + ! But if you are not interested on the precision of floating point numbers,
    + ! you can use simply:
    + real :: real_var2
    +
    + ! An array can be declared in two ways:
    + real(kind=kr), dimension(1:10, -4:5), private :: a, b, c
    + real(kind=kr), private :: d(1:10, -4:5)
    +
    + ! This is a string with fixed lenght
    + character(len=10) :: str_var
    +
    + ! This is an allocatable array, which can be a target of a pointer
    + type(example_type), private, dimension(:), allocatable, target :: &
    + many_examples
    +
    +! Fortran 90 hasn't got its own preprocessor, it uses the C preprocessor!
    +#ifdef XXX
    +c <-- this is a comment in the old fortran 77 style (fixed form)
    +c This is a free form file, so we shouldn't use this kind of comments!
    +c But fortran 90 still understands fixed form, when parsing sources with
    +c the *.f extension.
    + c ! <-- this 'c' shouldn't be highlighted as a comment!
    +#endif
    +
    +contains
    +
    +
    + ! The sum of two points
    + pure function point3d_add(a, b) result(rs)
    + type(point3d) :: rs
    + type(point3d), intent(in) :: a, b
    + rs%x = a%x + b%x
    + rs%y = a%y + b%y
    + rs%z = a%z + b%z
    + end function point3d_add
    +
    +
    + ! The norm of a point
    + pure function point3d_norm(a) result(rs)
    + real(kind=kr) :: rs
    + type(point3d), intent(in) :: a
    + rs = sqrt(a%x * a%x + a%y * a%y + a%z * a%z)
    + end function point3d_norm
    +
    +
    + ! A simple recursive function
    + recursive function factorial(i) result (rs)
    + integer :: rs
    + integer, intent(in) :: i
    + if ( i <= 1 ) then
    + rs = 1
    + else
    + rs = i * factorial(i - 1)
    + end if
    + end function factorial
    +
    +
    + ! This is a useless function
    + subroutine example_fn(int_arg, real_arg, str_arg)
    + integer, intent(in) :: int_arg
    + real(kind=kr), intent(out) :: real_arg
    + character(len=*), intent(in) :: str_arg
    +
    + type(example_type), pointer :: p
    + integer :: n, i, j
    + logical :: flag
    +
    + flag = .true. ! .true. is not an operator!
    + if ( flag .and. flag ) then ! .and. is a pre-defined operator
    + print *, "blabla"
    + end if
    +
    + ! Examples of inquiry functions: allocated, lbound, ubound.
    + if ( .not. allocated(many_examples) ) then
    + allocate( many_examples(10) )
    + end if
    + print *, "Lower bound = ", lbound(many_examples, 1)
    + print *, "Upper bound = ", ubound(many_examples, 1)
    +
    + p => many_examples(5) ! <-- p is a pointer
    +
    + ! A strange way to calculate i*i: add the first i odd numbers
    + i = 6
    + j = 0
    + do n = 1, i
    + j = j + (2*n - 1)
    + end do
    + print *, "i*i = ", i*i, j
    +
    + real_arg = real(j) ! <-- here the highlighting is not very good:
    + ! it is unable to distinguish between this and a definition like:
    + ! real(kind=kr) :: a
    + deallocate( many_examples )
    + end subroutine example_fn
    +
    +end module module_example
    +
    +
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +! THIS IS THE MAIN PROGRAM !
    +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    +program example
    + use module_example
    +
    + ! this is another example of use of the 'implicit' keyword
    + implicit double precision (a-h,o-z)
    +
    + real(kind=kr) :: var_out
    +
    + type(point3d) :: &
    + a = point3d(0.0_kr, 1.0_kr, 2.0_kr), &
    + b = point3d(4.0_kr, 5.0_kr, 6.0_kr)
    +
    + print *, "a + b = ", .norm. (a + b)
    + print *, "factorial of 5 = ", factorial(5)
    +
    + call example_fn(1, var_out, "hello!")
    +
    +end program example
    diff --git a/autotests/reference/highlight.glsl.ref b/autotests/reference/highlight.glsl.ref new file mode 100644 index 0000000..e68474f --- /dev/null +++ b/autotests/reference/highlight.glsl.ref @@ -0,0 +1,62 @@ +// This is a test file for the Katepart GLSL Syntax Highlighting.
    +
    +normal text
    +// this is a single-line comment
    +normal text
    +/* this
    +is a multi-line
    +comment */
    +normal text
    +
    +some_symbol.some_member;
    +some_symbol.some_member_function();
    +some_function();
    +
    +// this is a function
    +void main()
    +{
    + float f = 1.4e3; // decimal float literal
    + int i1 = 2884; // decimal int literal
    + int i2 = 0x44; // hex int literal
    + int i3 = 0456; // octal int literal
    +}
    +
    +// this is a structure
    +struct some_struct
    +{
    + vec3 some_member_vector;
    +};
    +
    +# this is
    +#preprocessor code
    +
    +// all keywords
    +break continue do for while
    +if else
    +true false
    +discard return
    +struct
    +
    +// all basic types
    +float int void bool
    +mat2 mat3 mat4
    +vec2 vec3 vec4
    +ivec2 ivec3 ivec4
    +bvec2 bvec3 bvec4
    +sampler1D sampler2D sampler3D
    +samplerCube sampler1DShadow sampler1DShadow
    +
    +// all type qualifiers
    +attribute const uniform varying
    +in out inout
    +
    +// attensions:
    +// FIXME
    +// TODO
    +// BUG
    +
    +// some of the std functions
    +radians degrees sin cos tan asin acos atan
    +
    +// some of the std variables
    +gl_Position gl_PointSize gl_ClipVertex
    diff --git a/autotests/reference/highlight.hs.ref b/autotests/reference/highlight.hs.ref new file mode 100644 index 0000000..2de2d2d --- /dev/null +++ b/autotests/reference/highlight.hs.ref @@ -0,0 +1,124 @@ +-- test file for Haskell syntax highlighting in KDE's Kate
    +
    +-- The test file for literate Haskell can be easily created like this:
    +-- cat highlight.hs | sed -e "s|^|> |" -e "s|> -- ||" -e "s|^> $||" > highlight.lhs
    +-- You only have to manually edit the multi-line comment below.
    +
    +-- this is a single-line comment
    +
    +{- this is a multi-line comment
    +
    +Things like "a string" or a 'c' character shouldn't be highlighted in here.
    +
    +-- I could even start a new
    +-- one-line comment.
    +
    +-}
    +
    +-- a data definition
    +
    +data Tree a = Br (Tree a) (Tree a) | Leaf a | Nil deriving (Show, Eq)
    +
    +
    +-- function definition, "funnyfunction::", "Integer", "Int", "Bool" should be highlighted
    +
    +funnyfunction::(Tree a)=>[a]->Integer->Int->Bool
    +
    +
    +-- strings and chars
    +-- first line of function definitions (type declaration) should be highlighted
    +
    +strangefunction::Int->String
    +strangefunction 1 = "hello"
    +strangefunction 2 = "what's up"
    +strangefunction 3 = (strangefunction 1) ++ ", " ++ (strangefunction 2)
    +strangefunction 4 = 'a':'b':'c':'"':[] -- will return "abc"
    +strangefunction 5 = '\n':[]
    +strangefunction 6 = '\invalidhaskell':[]
    +
    +-- function name including the single quote character
    +-- and infix operator (`div`)
    +
    +justtesting'::Int->Int
    +justtesting' 2 = 2+1
    +justtesting' 9 = 7 `div` 2
    +
    +-- same definition as above, slightly different function name and a couple more whitespaces
    +
    +justtesting'' :: Int -> Int
    +justtesting'' 2 = 3
    +justtesting'' 9 = 3 + 9 - 9
    +
    +-- the following lines are copied out of Haskell's "Prelude.hs"
    +
    +infixl 7 *, /, `quot`, `rem`, `div`, `mod`, :%, %
    +
    +
    +-- everything highlighted except the "a"
    +
    +class Bounded a where
    + minBound, maxBound :: a
    +
    +class (Num a, Ord a) => Real a where
    + toRational :: a -> Rational
    +
    +-- finally, some keyword lists
    +
    +-- keywords
    +
    +case, class, data, deriving, do, else, if, in, infixl, infixr, instance, let, module, of, primitive,
    +then, type, where
    +
    +-- infix operators
    +
    +quot, rem, div, mod, elem, notElem, seq
    +
    +-- this stuff is not handled yet
    +
    +!!, %, &&, $!, $, *, **, -,., /=, <, <=, =<<, ==, >, >=, >>, >>=, ^, ^^, ++, ||
    +
    +-- functions
    +
    +FilePath, IOError, abs, acos, acosh, all, and, any, appendFile,
    +approxRational, asTypeOf, asin, asinh, atan, atan2, atanh, basicIORun,
    +break, catch, ceiling, chr, compare, concat, concatMap, const, cos, cosh,
    +curry, cycle, decodeFloat, denominator, digitToInt, div, divMod, drop,
    +dropWhile, either, elem, encodeFloat, enumFrom, enumFromThen,
    +enumFromThenTo, enumFromTo, error, even, exp, exponent, fail, filter, flip,
    +floatDigits, floatRadix, floatRange, floor, fmap, foldl, foldl1, foldr,
    +foldr1, fromDouble, fromEnum, fromInt, fromInteger, fromIntegral,
    +fromRational, fst, gcd, getChar, getContents, getLine, head, id, inRange,
    +index, init, intToDigit, interact, ioError, isAlpha, isAlphaNum, isAscii,
    +isControl, isDenormalized, isDigit, isHexDigit, isIEEE, isInfinite, isLower,
    +isNaN, isNegativeZero, isOctDigit, isPrint, isSpace, isUpper, iterate, last,
    +lcm, length, lex, lexDigits, lexLitChar, lines, log, logBase, lookup, map,
    +mapM, mapM_, max, maxBound, maximum, maybe, min, minBound, minimum, mod,
    +negate, not, notElem, null, numerator, odd, or, ord, otherwise, pi, pred,
    +primExitWith, print, product, properFraction, putChar, putStr, putStrLn,
    +quot, quotRem, range, rangeSize, read, readDec, readFile, readFloat,
    +readHex, readIO, readInt, readList, readLitChar, readLn, readOct, readParen,
    +readSigned, reads, readsPrec, realToFrac, recip, rem, repeat, replicate,
    +return, reverse, round, scaleFloat, scanl, scanl1, scanr, scanr1, seq,
    +sequence, sequence_, show, showChar, showInt, showList, showLitChar,
    +showParen, showSigned, showString, shows, showsPrec, significand, signum,
    +sin, sinh, snd, span, splitAt, sqrt, subtract, succ, sum, tail, take,
    +either, elem, encodeFloat, enumFrom, enumFromThen, enumFromThenTo,
    +enumFromTo, error, even, exp, exponent, fail, filter, flip, floatDigits,
    +floatRadix, floatRange, floor, fmap, takeWhile, tan, tanh, threadToIOResult,
    +toEnum, toInt, toInteger, toLower, toRational, toUpper, truncate, uncurry,
    +undefined, unlines, until, unwords, unzip, unzip3, userError, words,
    +writeFile, zip, zip3, zipWith, zipWith3
    +
    +-- type constructors
    +
    +Bool, Char, Double, Either, Float, IO, Integer, Int, Maybe, Ordering, Rational, Ratio, ReadS,
    +ShowS, String
    +
    +-- classes
    +
    +Bounded, Enum, Eq, Floating, Fractional, Functor, Integral, Ix, Monad, Num, Ord, Read, RealFloat,
    +RealFrac, Real, Show
    +
    +-- data constructors
    +
    +EQ, False, GT, Just, LT, Left, Nothing, Right, True
    diff --git a/autotests/reference/highlight.js.ref b/autotests/reference/highlight.js.ref new file mode 100644 index 0000000..f9eb32e --- /dev/null +++ b/autotests/reference/highlight.js.ref @@ -0,0 +1,134 @@ +/* test.js - test for javascript.xml syntax file */
    +// Note: this script will not, and is not supposed to, comile in any js engine.
    +
    +/*
    + NOTE: The words "todo", "fixme" and "note" should be rendered in a different style
    + within comments, match should be caseless (to test for regexp insensitive attribute).
    + The regex used for this rule is */
    + String = /\b(?:fixme|todo|note)\b/
    + /* Thus, for example "Notebook" is not caught by
    + this rule. (the "?:" in the subpattern is there to avoid the regex engine wasting time
    + saving a backref, which is not used for anything. I do not know if the overhead of parsing
    + that is greater than the time saved by not capturing the text...)
    + The rule for catching these words is placed in a context "Comment common", which is used
    + by both comment contexts (single line, multiline) using the new "IncludeRules" item.
    +*/
    +
    +// test if regex support works - nice with new fallthrough prop in context:)
    +somestring.replace( /dooh/ , "bah!");
    +re=/foo/ig; // hehe
    +
    +somestring.search(
    + /^foo\w+\s\d{0,15}$/
    + );
    +
    + re =
    + /dooh/;
    +
    +// This is supposedly legal:
    +re = somebool ? /foo/ : /bar/;
    +
    +// NOTE - Special case: an empty regex, not a comment.
    +// The rule uses a positive lookahead assertion to catch it: "//(?=;)".
    +re = //;
    +re = /a|b/;
    +
    +/*
    + Tests for the regex parser.
    + It will parse classes, quanitfiers, special characters and regex operaters,
    + as specified in the netscape documentation for javascript.
    + Regexps are only parsed in their clean form, as the RegExp(string) constructor
    + is using a quoted string.
    + TODO: Find out if more regex feats should be supported.
    + Consider using more itemDatas - assertion, quantifier are options.
    +*/
    +
    +re = /^text\s+\d+\s*$/;
    +re = /a pattern with caret \(^\) in it/;
    +re = /(\d{0,4})\D/;
    +re = /[a-zA-Z_]+/;
    +re = /[^\d^]+/;
    +re = /\s+?\w+\.$/;
    +re = /\/\//;
    +re = /a|b/;
    +
    +// a test if #pop back from a comment will work
    +re = /*/foo/*/ /bar/;
    +// ^ POP
    +// ^ we got back after pop in comment, if there is regexp attribs here :-)
    +
    +/*
    + Some tests if the fallthrough works.
    + The fallthrough happens if a regexp is not found in a possible (!) position,
    + which is after "search(" or "replace(" or "=" or "?" or ":" in version 0.1 of the xml file
    +*/
    +
    +var foo = 'bar';
    +// ^ fallthrough!
    +
    +
    +somestring.replace( new RegExp("\\b\\w+\\b"), "word: $1");
    +// ^ fallthrough expected. ("new" whould be bold)
    +
    +
    +something.method =
    + function ( a, b, c ) { /* ... */ }
    +// ^ fallthrough ?!
    +
    +something.other =
    +function ( d, e, f ) { /* ... */ }
    +// fallthrough expected at col 0 ("function" should be bold)
    +
    +var ary = new Array(5);
    +// ^ fallthrough ? (if keyword is correctly rendered)
    +
    +var b = a ? 1 : 0;
    +// ^ ^ fallthroughs. numbers must be rendered correctly.
    +
    +var c = d ? true : false;
    +
    +var conditinalstring = b ?
    + "something" :
    + "something else";
    +// guess...
    +
    +
    +/*
    + Normal program flow...
    +*/
    +
    +if (something)
    + dostuff();
    +else
    + dont();
    +
    + return;
    +
    +try { bla() } catch (e) { alert("ERROR! : " + e) }
    +
    +for (int i=0; i < j; i++)
    + document.write("i is" + i + "
    "
    );
    +
    +while (something)
    +{
    + block();
    + picky:
    + if (!1)
    + break;
    + else
    + continue;
    +}
    +
    +with (a) {
    + do {
    + stuff( b ); // a.b if it exists
    + } while (itmakessense);
    +}
    +
    +switch (i) {
    + case 0:
    + f();
    + break;
    + default:
    + break;
    +}
    diff --git a/autotests/reference/highlight.jsp.ref b/autotests/reference/highlight.jsp.ref new file mode 100644 index 0000000..3eb1795 --- /dev/null +++ b/autotests/reference/highlight.jsp.ref @@ -0,0 +1,170 @@ +<%--
    + This page won't actually work, as it is simply designed to display jsp syntax highlighting.
    +--%>
    +<%@ page info="A Page to Test Kate Jsp Syntax Highlighting" language="java" errorPage="/test-error-page.jsp"%>
    +<%@ include file="/include/myglobalvars.jsp"%> --%>
    +<%@ page import="java.util.*,
    + java.io.*,
    + java.math.*" %>
    +<%@ taglib uri="/WEB-INF/lib/si_taglib.tld" prefix="si"%>
    + id="aPageBean" scope="page" class="my.package.MyPageBean"/>
    + id="aRequestBean" scope="request" class="my.package.MyRequestBean"/>
    +<%
    + // We can decipher our expected parameters here.
    + String parm1 = noNull(request.getParameter(PARAMETER_1)).trim();
    + String parm2 = noNull(request.getParameter(PARAMETER_2)).trim();
    + String parm3 = noNull(request.getParameter(PARAMETER_3)).trim();
    + String parm4 = noNull(request.getParameter(PARAMETER_4)).trim();
    + String parm5 = noNull(request.getParameter(PARAMETER_5)).trim();
    +
    + // A sample collection of Integers to display some code folding.
    + List intList = getIntList(10);
    +
    +
    +%>
    +
    + A Sample Jsp
    +
    + language="javascript">
    +
    +
    + <%-- The top label table. --%>
    + width="400" cellpadding="0" cellspacing="0" border="0">
    +
    + size="3">The following parameters were detected:
    +
    +
    +
    + <%-- Display the parameters which might have been passed in. --%>
    + width="400" cellpadding="0" cellspacing="0" border="0">
    + <%-- Label; Actual Parameter String; Value Detected --%>
    +
    + PARAMETER_1
    + align="center"><%=PARAMETER_1%>
    + align="right">"<%=parm1%>"
    +
    +
    + <%-- Label; Actual Parameter String; Value Detected --%>
    +
    + PARAMETER_2
    + align="center"><%=PARAMETER_2%>
    + align="right">"<%=parm2%>"
    +
    +
    + <%-- Label; Actual Parameter String; Value Detected --%>
    +
    + PARAMETER_3
    + align="center"><%=PARAMETER_3%>
    + align="right">"<%=parm3%>"
    +
    +
    + <%-- Label; Actual Parameter String; Value Detected --%>
    +
    + PARAMETER_4
    + align="center"><%=PARAMETER_4%>
    + align="right">"<%=parm4%>"
    +
    +
    + <%-- Label; Actual Parameter String; Value Detected --%>
    +
    + PARAMETER_5
    + align="center"><%=PARAMETER_5%>
    + align="right">"<%=parm5%>"
    +
    +
    +
    +


    +
    + <%-- Display our list of random Integers (shows code folding). --%>
    + width="400" cellpadding="0" cellspacing="0" border="0">
    +<%
    + if (intList != null && intList.size() > 0) {
    +%>
    + Here are the elements of intList...
    +<%
    + Iterator intListIt = intList.iterator();
    + while (intListIt.hasNext()) {
    + Integer i = (Integer) intListIt.next();
    +%>
    + <%=i.toString()%>
    +<%
    + }
    + } else {
    +%>
    + color="blue">Oooops, we forgot to initialize intList!
    +<%
    + }
    +%>
    +
    +
    +


    +
    + <%-- We can call javascript functions. --%>
    + width="400" cellpadding="0" cellspacing="0" border="0">
    + colspan="2">Test our javascript...
    +
    + type="button" name="button1" value="Alert 1" onmouseup="javascript:doAlert1()">
    + type="button" name="button2" value="Alert 2" onmouseup="javascript:doAlert2()">
    +
    +
    +
    +


    + <%-- If we actually had defined a tag library. --%>
    + width="400" cellpadding="0" cellspacing="0" border="0">
    +
    + prop1="first" prop2="third">
    + nameProp="value1"/>
    + nameProp="value2"/>
    +
    +
    +
    +
    +


    + <%-- Expression language. --%>
    + width="400" cellpadding="0" cellspacing="0" border="0">
    + test="${!empty param.aParam}">
    + var="myParam" scope="session" value="${param.aParam}"/>
    +
    +
    + myParam's value: " value="${myParam}" default=="Default"/>"
    +
    +
    +
    +<%!
    + /* A place for class variables and functions... */
    +
    + // Define some sample parameter names that this page might understand.
    + private static final String PARAMETER_1 = "p1";
    + private static final String PARAMETER_2 = "p2";
    + private static final String PARAMETER_3 = "p3";
    + private static final String PARAMETER_4 = "p4";
    + private static final String PARAMETER_5 = "p5";
    +
    + // Returns str trimmed, or an empty string if str is null.
    + private static String noNull(String str) {
    + String retStr;
    + if (str == null)
    + retStr = "";
    + else
    + retStr = str.trim();
    +
    + return retStr;
    + }
    +
    + // Returns a list of Integers with listSize elements.
    + private static List getIntList(int listSize) {
    + ArrayList retList = new ArrayList(listSize);
    + for (int i = 0; i < listSize; i++)
    + retList.add(new Integer( (int) (Math.random() * 100) ));
    +
    + return retList;
    + }
    +%>
    diff --git a/autotests/reference/highlight.lex.ref b/autotests/reference/highlight.lex.ref new file mode 100644 index 0000000..141a5da --- /dev/null +++ b/autotests/reference/highlight.lex.ref @@ -0,0 +1,82 @@ +/* This test file tests kates Lex/Flex highlighting */
    +
    +%option c++
    +%option yyclass="KateTester"
    +%option yylineno
    +
    + /* This is a C(++) comment */
    +
    +/* This one is a lex comment ! */
    +
    +%{
    +#include
    +#include "realparser.hpp"
    +using namespace std;
    +%}
    +
    +/* Some definitions */
    +DIGIT [0-9]
    +LETTER [_a-zA-Z]
    +
    +%%
    +
    + /* Comment *shall be indented here* */
    +[ \t\n\r]+
    +
    + /* Note: there is a bad } just here vvv */
    +\/\*([^\*]|\*[^/])*\*\/ { foo(a, b, c); } }
    +
    + /* A start condition scope... */
    +{
    + "a" {
    +
    + /* C mode ! */
    + return 0;
    +}
    +
    + "b" %{
    +
    + /* C mode, too ! */
    + return 0;
    +%}
    +
    + "c" return 0; // C++ comment
    +}
    +
    + /* Big rule */
    +\"([^"\\]|\\.)*\" {
    +
    + yylval.string_val = new char[strlen(yytext) + 1];
    + int j = 0, i = 1;
    +
    + while (yytext[i] != '"')
    + if (yytext[i] != '\\')
    + yylval.string_val[j++] = yytext[i++];
    + else
    + switch (yytext[i + 1])
    + {
    + case 'n':
    + yylval.string_val[j++] = '\n'; i += 2;
    + break;
    + default:
    + yylval.string_val[j++] << yytext[i + 1], i += 2;
    + }
    +
    + yylval.string_val[j] = 0;
    + return TOK_STRING;
    +
    +}
    +
    + /* Dot (match all) */
    +. {return yylval.int_val = yytext[0];}
    +
    +%%
    +
    +// Here is pure C(++)
    +#include
    +
    +int main(void)
    +{
    + std::cout << "Hello, World\n";
    + return 0;
    +}
    diff --git a/autotests/reference/highlight.lhs.ref b/autotests/reference/highlight.lhs.ref new file mode 100644 index 0000000..5fb1ae0 --- /dev/null +++ b/autotests/reference/highlight.lhs.ref @@ -0,0 +1,124 @@ +test file for Haskell syntax highlighting in KDE's Kate
    +
    +The test file for literate Haskell can be easily created like this:
    + cat highlight.hs | sed -e "s|^|> |" -e "s|> -- ||" -e "s|^> $||" > highlight.lhs
    +You only have to manually edit the multi-line comment below.
    +
    +this is a single-line comment
    +
    +{- this is a multi-line comment
    +
    +Things like "a string" or a 'c' character shouldn't be highlighted in here.
    +
    +I could even start a new
    +one-line comment.
    +
    +-}
    +
    +a data definition
    +
    +> data Tree a = Br (Tree a) (Tree a) | Leaf a | Nil deriving (Show, Eq)
    +
    +
    +function definition, "funnyfunction::", "Integer", "Int", "Bool" should be highlighted
    +
    +> funnyfunction::(Tree a)=>[a]->Integer->Int->Bool
    +
    +
    +strings and chars
    +first line of function definitions (type declaration) should be highlighted
    +
    +> strangefunction::Int->String
    +> strangefunction 1 = "hello"
    +> strangefunction 2 = "what's up"
    +> strangefunction 3 = (strangefunction 1) ++ ", " ++ (strangefunction 2)
    +> strangefunction 4 = 'a':'b':'c':'"':[] -- will return "abc"
    +> strangefunction 5 = '\n':[]
    +> strangefunction 6 = '\invalidhaskell':[]
    +
    +function name including the single quote character
    +and infix operator (`div`)
    +
    +> justtesting'::Int->Int
    +> justtesting' 2 = 2+1
    +> justtesting' 9 = 7 `div` 2
    +
    +same definition as above, slightly different function name and a couple more whitespaces
    +
    +> justtesting'' :: Int -> Int
    +> justtesting'' 2 = 3
    +> justtesting'' 9 = 3 + 9 - 9
    +
    +the following lines are copied out of Haskell's "Prelude.hs"
    +
    +> infixl 7 *, /, `quot`, `rem`, `div`, `mod`, :%, %
    +
    +
    +everything highlighted except the "a"
    +
    +> class Bounded a where
    +> minBound, maxBound :: a
    +
    +> class (Num a, Ord a) => Real a where
    +> toRational :: a -> Rational
    +
    +finally, some keyword lists
    +
    +keywords
    +
    +> case, class, data, deriving, do, else, if, in, infixl, infixr, instance, let, module, of, primitive,
    +> then, type, where
    +
    +infix operators
    +
    +> quot, rem, div, mod, elem, notElem, seq
    +
    +this stuff is not handled yet
    +
    +> !!, %, &&, $!, $, *, **, -,., /=, <, <=, =<<, ==, >, >=, >>, >>=, ^, ^^, ++, ||
    +
    +functions
    +
    +> FilePath, IOError, abs, acos, acosh, all, and, any, appendFile,
    +> approxRational, asTypeOf, asin, asinh, atan, atan2, atanh, basicIORun,
    +> break, catch, ceiling, chr, compare, concat, concatMap, const, cos, cosh,
    +> curry, cycle, decodeFloat, denominator, digitToInt, div, divMod, drop,
    +> dropWhile, either, elem, encodeFloat, enumFrom, enumFromThen,
    +> enumFromThenTo, enumFromTo, error, even, exp, exponent, fail, filter, flip,
    +> floatDigits, floatRadix, floatRange, floor, fmap, foldl, foldl1, foldr,
    +> foldr1, fromDouble, fromEnum, fromInt, fromInteger, fromIntegral,
    +> fromRational, fst, gcd, getChar, getContents, getLine, head, id, inRange,
    +> index, init, intToDigit, interact, ioError, isAlpha, isAlphaNum, isAscii,
    +> isControl, isDenormalized, isDigit, isHexDigit, isIEEE, isInfinite, isLower,
    +> isNaN, isNegativeZero, isOctDigit, isPrint, isSpace, isUpper, iterate, last,
    +> lcm, length, lex, lexDigits, lexLitChar, lines, log, logBase, lookup, map,
    +> mapM, mapM_, max, maxBound, maximum, maybe, min, minBound, minimum, mod,
    +> negate, not, notElem, null, numerator, odd, or, ord, otherwise, pi, pred,
    +> primExitWith, print, product, properFraction, putChar, putStr, putStrLn,
    +> quot, quotRem, range, rangeSize, read, readDec, readFile, readFloat,
    +> readHex, readIO, readInt, readList, readLitChar, readLn, readOct, readParen,
    +> readSigned, reads, readsPrec, realToFrac, recip, rem, repeat, replicate,
    +> return, reverse, round, scaleFloat, scanl, scanl1, scanr, scanr1, seq,
    +> sequence, sequence_, show, showChar, showInt, showList, showLitChar,
    +> showParen, showSigned, showString, shows, showsPrec, significand, signum,
    +> sin, sinh, snd, span, splitAt, sqrt, subtract, succ, sum, tail, take,
    +> either, elem, encodeFloat, enumFrom, enumFromThen, enumFromThenTo,
    +> enumFromTo, error, even, exp, exponent, fail, filter, flip, floatDigits,
    +> floatRadix, floatRange, floor, fmap, takeWhile, tan, tanh, threadToIOResult,
    +> toEnum, toInt, toInteger, toLower, toRational, toUpper, truncate, uncurry,
    +> undefined, unlines, until, unwords, unzip, unzip3, userError, words,
    +> writeFile, zip, zip3, zipWith, zipWith3
    +
    +type constructors
    +
    +> Bool, Char, Double, Either, Float, IO, Integer, Int, Maybe, Ordering, Rational, Ratio, ReadS,
    +> ShowS, String
    +
    +classes
    +
    +> Bounded, Enum, Eq, Floating, Fractional, Functor, Integral, Ix, Monad, Num, Ord, Read, RealFloat,
    +> RealFrac, Real, Show
    +
    +data constructors
    +
    +> EQ, False, GT, Just, LT, Left, Nothing, Right, True
    diff --git a/autotests/reference/highlight.lisp.ref b/autotests/reference/highlight.lisp.ref new file mode 100644 index 0000000..ac7a07f --- /dev/null +++ b/autotests/reference/highlight.lisp.ref @@ -0,0 +1,36 @@ +;; This test file tests kates common lisp highlighting
    +#|
    +multilinecomment :)
    +|#
    +
    +;BEGIN region marker
    +
    +;END end
    +
    +(defun bin-search (obj vec)
    + (let ((len (length vec)))
    + (and (not (zerop len))
    + (finder obj vec 0 (- len 1)))))
    +
    +(defun parse-date (str)
    + (let ((toks (tokens str #'constituent 0)))
    + (list (parse-integer (first toks))
    + (parse-month (second toks))
    + (parse-integer (third toks)))))
    +
    +(defconstant month-names
    + #("jan" "feb" "mar" "apr" "may" "jun"
    + "jul" "aug" "sep" "oct" "nov" "dec"))
    +
    +(defstruct buf
    + vec (start -1) (used -1) (new -1) (end -1))
    +
    +(defparameter *words* (make-hash-table :size 10000))
    +
    +(defmacro while (test &rest body)
    + `(do ()
    + ((not ,test))
    + ,@body))
    +
    +(define-modify-macro append1f (val)
    + (lambda (lst val) (append lst (list val))))
    diff --git a/autotests/reference/highlight.ly.ref b/autotests/reference/highlight.ly.ref new file mode 100644 index 0000000..c96f643 --- /dev/null +++ b/autotests/reference/highlight.ly.ref @@ -0,0 +1,114 @@ +% This is a file to test the Lilypond highlighting features of Katepart.
    +% This is NOT a valid lilypond file, because it also shows the
    +% highlighting of some invalid lilypond constructs!
    +% This is a line comment.
    +
    +%{
    +this is a block comment, that can occur inside a line, or across
    +multiple lines.
    +%}
    +
    +\header {
    + title = "Katepart Lilypond syntax highlighting test file"
    + composer = %{"Wilbert Berendsen"%} "Anonymus"
    + poet = "The KDE team"
    + opus = "1"
    + copyright = "Share and enjoy!"
    +}
    +
    +\paper {
    + #(set-paper-size "a4") % a hash introduces scheme
    + indent = 0 % recognize variable names inside \paper, \layout etc.
    + between-system-space = 3\mm
    +}
    +
    +\layout {
    + \context {
    + \Score
    + \remove Bar_number_engraver % recognize engraver names
    + \remove "Bar_number_engraver" % also when quoted!
    + }
    +}
    +
    +% { and << block are folded
    +\score {
    + \new StaffGroup <<
    + \new ChordNames \chordmode { c2sus4/f g2/d c1 }
    + \new Staff \new Voice ="mel" {
    + \key f \major
    + \time 4/4
    + \partial 4
    + \set Staff.instrumentName = "Bla."
    + \once \override Staff.NoteHead #'color = #red
    + % dynamics, articulations and markup
    + c8\p d\< e-. f-> g a\f c-5\markup {Hoi}
    + \notemode { c d e f }
    + \repeat volta 2 {
    + % complex durations are highlighted:
    + g4*2/3
    + }
    + \times 2/3 {e8 f g}
    + % there is some error checking:
    + % often made mistake to have octavemarks after the duration:
    + c2'
    + % invalid durations are caught:
    + g3
    + }
    + \context Lyrics \lyricsto "mel" {
    + \set fontSize = #1
    + this is a line of ly -- rics.
    + with4 dur -- a -- tions.2.
    + % errors like forgetting spaces are found:
    + space-- flight %{i.s.o.%} space -- flight
    + space at end for -- got -- ten as well.}
    +
    + \new DrumStaff \drummode { hihat4 bassdrum8 }
    + \new FiguredBass \figuremode {
    + <5 4>8 <6->
    + }
    + >>
    + \midi {
    + \context {
    + \Score
    + tempoWholesPerMinute = #(ly:make-moment 60 2)
    + }
    + }
    +}
    +
    +av = #(define-music-function (parser location voice)
    +(string?)
    +; scheme comments are recognized in scheme
    +; Lilypond inside scheme works as well:
    +#{
    + \set associatedVoice = $voice
    +#})
    +
    +
    +
    +
    +% inside scheme some elements are highlighted:
    +#(define (naturalise-pitch p)
    + (let* ((o (ly:pitch-octave p))
    + (a (* 4 (ly:pitch-alteration p)))
    + (n (ly:pitch-notename p)))
    + (bla 'ArticulationEvent 'ChoirStaff)
    + (cond
    + ((> a 2) (set! a (- a 4)) (set! n (+ n 1)))
    + ((< a -2) (set! a (+ a 4)) (set! n (- n 1))))
    +
    + (if (< n 0) (begin (set! o (- o 1)) (set! n (+ n 7))))
    + (if (> n 6) (begin (set! o (+ o 1)) (set! n (- n 7))))
    +
    + (ly:make-pitch o n (/ a 4))))
    +
    +% markup is also highlighted
    +\markup {
    + \line {
    + text test Voice Staff % note Lilypond keywords are not highlighted here
    + }
    + \score { \relative c' { <ceg>2( d) } }
    + \italic bla
    + \override #'(baseline-skip . 2) {
    + \underline blu
    + }
    +}
    diff --git a/autotests/reference/highlight.m.ref b/autotests/reference/highlight.m.ref new file mode 100644 index 0000000..53e4f52 --- /dev/null +++ b/autotests/reference/highlight.m.ref @@ -0,0 +1,61 @@ +%%=====================================================
    +% MATLAB test code for Kate/Kwrite syntax highlighting
    +% kate: hl Matlab
    +%%=====================================================
    +
    +% Numbers _____________________________________________
    +5, 5.5, .1, 0.1, 0.4e5, 1.2e-5, 5i, 5.3i, 6j, .345+3i
    +5', 5.5', .1', 0.1', 0.4e5', 1.2e-5', 5i', 5.3i', 6j', .345+3i'
    +
    +% Operators ___________________________________________
    +% relational operators
    +'asdf'~=4, c<=4, d>=4, a<b, a>b, a==b, b||c, b&&c
    +% elementwise arithmetic operators
    +a.^b, a.*b a./b, 1:4:5
    +% single-character binary arithmetic
    +a+3, a-3, a*2, a^3, a/3, a\3, a|b, a&b
    +% unary operators
    +a = ~g; g = @sfdgdsf(sdfsd,345); g.' + 1i.' - ('asdf').'
    +% separators and delimiter
    +(asd),[sadf];{asdf},;;,;;;()
    +% continuation
    +a = 1+ ...
    + 2;
    +
    +% Strings and adjoint _________________________________
    +% incomplete strings
    +'string
    +'str''
    +'str''ing
    +% complete strings
    +'string' % simple string
    +'''' % string containing '
    +'str''ing' % one string containing '
    +'string' 'string' % two strings
    +'asdf' 'asdf''' variable % two strings and a variable
    +'asdf''asdf'' fsgdfg' + (asdf)' - 'asdf'.' + []''''.';''
    +'sadf'.' % string transpose
    +% adjoint
    +{'asdf'}' + 1
    +('asdf')' + 1
    +['asdf']' + 1
    +'' var''' % empty string, var with >1 adjoints
    +[5]'*{5}'*('asd')'.'+(5)'*6'*asdf'*asdf'.' % many adjoints
    +A'*B + 1 % adjoint
    +A.'*B + 1 % transpose
    +A.'.'*B + 1 % double transpose
    +A'.' + 1 % adjoint, then transpose
    +A.'' % transpose, then adjoint
    +
    +% System command ______________________________________
    +!hostname
    +!cp * /tmp
    +
    +% Reserved keywords ___________________________________
    +function, persistent, global
    +switch, case, otherwise
    +if, else, elseif
    +try, catch
    +for, while, break, continue
    +end, return
    +function, FUNCTION, Function % case sensitive!
    diff --git a/autotests/reference/highlight.mac.ref b/autotests/reference/highlight.mac.ref new file mode 100644 index 0000000..c8582c6 --- /dev/null +++ b/autotests/reference/highlight.mac.ref @@ -0,0 +1,145 @@ +/*
    +------------------------------------------------------------------------
    +Efficient Galois Fields in Maxima
    +
    +by Alasdair McAndrew
    +and later extended by Fabrizio Caruso and Jacopo Daurizio
    +
    +it is distribuited together with gf_roots by Jacopo Daurizio
    +
    +Authors:
    +
    +Fabrizio Caruso (optimizations, testing)
    +Jacopo D'Aurizio (optimizations, modular roots)
    +Alasdair McAndrew (original version of the package, pohlig-helman log, etc... )
    +------------------------------------------------------------------------*/
    +
    +/* Released under terms of the GNU General Public License, version 2,
    + * by permission of the authors to Robert Dodier circa 2007-12-02.
    + */
    +
    +/* Defines a flag for dealing with large fields. If it is set to "false",
    +then lookup tables are used for exponentiation and logarithms. Otherwise
    +other algorithms are used */
    +
    +define_variable(,true,)$
    +define_variable(,0,)$
    +define_variable(,0,)$
    +define_variable(,0,)$
    +define_variable (, ', )$
    +define_variable (, ', )$
    +define_variable (, ', )$
    +define_variable (, ', )$
    +define_variable (, ', )$
    +remvalue(,,,,,,,,,,,,)$
    +
    +
    +/* --------------------------------------------------------------------------------------------- */
    +/* Settings */
    +
    +:false; /* Verbosity */
    +: true; /* Warnings */
    +:false; /* Irreducibility test for the minimal polynomial of the extension */
    +
    +/*
    +------------------------------------------------------------------------------------------------ */
    +
    +
    +/* It defines a new current field with gf_char=b, min. pol.= p of deg= e*/
    +([]):=block([,,,,],
    + if length()=1 then
    + (
    + ([1]),
    + return(true)
    + )
    + else
    + (
    + if length()=2 then
    + (
    + if numberp([2]) then
    + (
    + if [2]=0 and then
    + (
    + print("WARNING: the irreducible is zero! We assume GF(",[1],")"),
    + ([1]),
    + return(true)
    + )
    + else
    + (
    + error("ERROR: you tried to extend with a non-zero constant!"),
    + return(false)
    + )
    + )
    + else
    + (
    + :hipow([2],),
    +
    + if =1 then
    + ([1]),
    + :[2],
    + :,
    + return(true)
    + )
    + )
    + else
    + (
    + :[2],
    + if =1 then
    + (
    + ([1]),
    + :rat([3]),
    + return(true)
    + ),
    + :rat([3])
    + )
    + ),
    +
    + :[1],
    + :rat(1,),
    + :^-1,
    +
    + :makelist(coeff(,,),,0,),
    + :[[first(),0]],:1,
    + for :2 thru +1 do if []=0 then :+1 else ( :endcons([[],],), :1 ),
    +
    + if not(primep()) then error("ERROR: Gf_Char must be a prime number.")
    + else
    + modulus:,
    + if and
    + hipow(args(factor([3]))[1],)#hipow(rat([3]),) then
    + error("ERROR: Polynomial is not irreducible"),
    +
    + if not() then
    + (
    + :(),
    + :()
    + )
    + else
    + (
    + if then
    + print("finding a primitive element..."),
    +
    + :rat((),),
    + if then
    + print("...primitive element found.")
    +
    + ),
    + modulus:false, /* it resets the modulus */
    + return(true)
    +
    + )$
    +
    +
    +/* Prints out information about the field */
    +():=block(
    + print("Prime gf_char value: ",),
    + print("Exponent: ", ),
    + print("Multiplicative order: ",),
    + print("Irreducible polynomial: ",),
    + print("Primitive element: ",),
    + if () then
    + print("Largefield flag is true; powers and logarithms not computed.")
    + else
    + print("Largefield flag is false; powers and logarithms computed."),
    + disp()
    +)$
    diff --git a/autotests/reference/highlight.mup.ref b/autotests/reference/highlight.mup.ref new file mode 100644 index 0000000..f48c01b --- /dev/null +++ b/autotests/reference/highlight.mup.ref @@ -0,0 +1,103 @@ +// This is a MUP highlighting test.
    +// Mup is a shareware music publisher from www.arkkra.com
    +
    +// contexts
    +score
    +music
    +staff 1
    +voice 1 3
    +
    +top
    +top2
    +bottom
    +bottom2
    +grids
    +
    +headshapes
    +
    +
    +header
    +footer
    +header2
    +footer2
    +
    +// parameters and values
    +score
    + units = cm;
    + key = 3#minor
    + key = 3# minor
    + rehstyle=circled
    +
    +
    +
    +
    +mussym above all: 1 "ferm" ;
    +
    +define NAME
    +// this is a macro definition, these are collapsable
    +@
    +
    +ifdef NAME
    +// this is conditionally "compiled"
    +endif
    +
    +ifndef NAME
    +// this is conditionally "compiled" when the macro has not been defined
    +else
    +// else clause
    +endif
    +
    +
    +// Various Tests
    +
    +// tablature
    +1: e ^f; f; b ^c5; c#5;
    +bar
    +
    +1: d+^e+ g^a; e+a; g ^/; c ^/ c+^/;
    +bar
    +
    +// cross-staff stems
    +1: 1e+g+c++;
    +2: cc+; ee+; g with g+ above; with c+c++ above;
    +bar
    +
    +1: 2+4ceg;4; // tie implied by added time values
    +
    +// slurs
    +1: 2f a c+; dbd+;
    +bar
    +1: 2fac+ slur; dbd+;
    +bar
    +
    +// alternation
    +1: 2c alt 2; 2c+;2g;
    +bar
    +
    +// bar to draw if repeatstart happens to be on new line
    +(dblbar) repeatstart
    +1: [up]8f bm with staff below;a;4s ebm;4s bm with staff below;8b;[len 11]d ebm;
    +2: 4s bm with staff above;8a;b ebm;[down;len 14]b bm with staff above;d;4s ebm;
    +bar
    +
    +// locations
    +3: 2cf; [=h] egc+;
    +1: [cue; with >; =_ch] fa;
    +
    +
    +roll up 1 1 to 1 2: 2; 4;
    +roll down 1 1 to 1 2: 2; 4;
    +
    +lyrics above 1,3 ; below 2,4 ; between 5&6 : "<1. >Hi, hi";
    +
    +title "page \% of \#"
    +
    +// shaped whole rests
    +1: 4mr; // use a quarter rest symbol
    +1: 1/4mr; // use a quadruple whole rest symbol
    +2: 2.. mr; // use a double-dotted half rest
    +
    +// tuplets
    +1: {4f; g;}3num,4.+2.
    +bar
    +
    diff --git a/autotests/reference/highlight.pb.ref b/autotests/reference/highlight.pb.ref new file mode 100644 index 0000000..ef260d5 --- /dev/null +++ b/autotests/reference/highlight.pb.ref @@ -0,0 +1,87 @@ +; This is a test file for kate's PureBasic highlighting.
    +
    +; BMP2x Converter by Sven Langenkamp
    +
    +UseJPEGImageEncoder()
    +UsePNGImageEncoder()
    +
    +Declare Convert(JPEG)
    +
    +Enumeration 1
    + #JPEG
    + #PNG
    +EndEnumeration
    +
    +; BEGIN section
    +
    +
    +; END
    +
    +Global Count
    +Global file.s
    +Global filename.s
    +Global fileext.s
    +Global OutputFormat
    +Global JPEGQuality
    +
    +Count = 0
    +OutputFormat = 1
    +JPEGQuality = -1
    +
    +; MAIN PROGRAM------------------------------------------------------------------
    +
    +;Request Options
    +PrintN("Output Format")
    +PrintN(" [1] JPEG")
    +PrintN(" [2] PNG")
    +Print ("> ")
    +OutputFormat = Int(Input())
    +
    +Select OutputFormat
    + Case #JPEG:
    + fileext = ".jpg"
    + ;Request JPEG Quality
    + PrintN("")
    + PrintN("JPEG Quality")
    + PrintN(" [0-10]")
    + Print ("> ")
    + JPEGQuality = Int(Input())
    +
    + Case #PNG:
    + fileext = ".png"
    +EndSelect
    +
    +;Convert all BMP files in the current directory
    +ExamineDirectory(0, "", "*.bmp")
    +While NextDirectoryEntry()
    + file = DirectoryEntryName()
    + filename = GetFilePart(file)
    +
    + If LoadImage(0, file)
    + Select OutputFormat
    + Case #JPEG:
    + Convert(JPEGQuality)
    +
    + Case #PNG:
    + Convert(-1)
    + EndSelect
    + Count = Count +1
    + EndIf
    +
    +Wend
    +
    +PrintN(Str(Count) + " files converted")
    +CloseConsole()
    +
    +; PROCUDURES--------------------------------------------------------------------
    +
    +Procedure Convert(JPEG)
    + Shared filename, fileext
    +
    + If JPEG > -1
    + SaveImage(0, filename + fileext, #PB_ImagePlugin_JPEG, JPEG)
    + Else
    + SaveImage(0, filename + fileext, #PB_ImagePlugin_PNG)
    + EndIf
    + PrintN(file + " converted to " + filename + fileext)
    +EndProcedure
    diff --git a/autotests/reference/highlight.php.ref b/autotests/reference/highlight.php.ref new file mode 100644 index 0000000..3faab58 --- /dev/null +++ b/autotests/reference/highlight.php.ref @@ -0,0 +1,23 @@ +
    +/* This is a pseudo PHP file to test Kate's PHP syntax highlighting. */
    +# TODO: this is incomplete, add more syntax examples!
    +# this is also a comment.
    +// Even this is a comment
    +function test($varname) {
    + return "bla"; # this is also a comment
    +}
    +
    +?>
    +
    + echo("hello test"); ?>
    +
    +
    + print "test"; ?>
    +
    +
    +
    +$var = <<
    +This is the $string inside the variable (which seems to be rendered as a string)
    +It works well, I think.
    +DOOH
    +?>
    diff --git a/autotests/reference/highlight.pike.ref b/autotests/reference/highlight.pike.ref new file mode 100644 index 0000000..2b220f3 --- /dev/null +++ b/autotests/reference/highlight.pike.ref @@ -0,0 +1,24 @@ +#! /bin/env pike
    +
    +/* This file is a syntax highlight test for Kate.
    + * FIXME: Improve it to contain more (and more unusual) syntax examples.
    + */
    +
    +
    +#define PIKE_ON_THE_WEB /* Is this address correct? */ "http://pike.ida.liu.se/"
    +
    +
    +int main(int argc, array(string) args)
    +{
    + // Write funny things with Pike :)
    + write(`+("Command line arguments (%d of them): ", @map(args, `+, " ")) + "\n", argc);
    +
    + write("\nVisit Pike site at %s\n\n", PIKE_ON_THE_WEB);
    +
    + for (int i = 1; i <= 3; i++)
    + write(":" + ")" * i + " ");
    +
    + write("\n" + ({"Bye", "bye"}) * "-" + "!\n");
    +
    + return 0;
    +}
    diff --git a/autotests/reference/highlight.pl.ref b/autotests/reference/highlight.pl.ref new file mode 100644 index 0000000..8c905ba --- /dev/null +++ b/autotests/reference/highlight.pl.ref @@ -0,0 +1,44 @@ +#!/usr/bin/perl -w
    +# This is a pseudo Perl file to test Kate's Perl syntax highlighting.
    +# TODO: this is incomplete, add more syntax examples!
    +
    +sub prg($)
    +{
    + my $var = shift;
    +
    + $var =~ s/bla/foo/igs;
    + $var =~ s!bla!foo!igs;
    + $var =~ s#bla#foo#igs;
    + $var =~ tr/a-z/A-Z/;
    + ($match) = ($var =~ m/(.*?)/igs);
    +
    + $test = 2/453453.21;
    + $test /= 2;
    +
    + print qq~d fsd fsdf sdfl sd~
    +
    + $" = '/';
    +
    + $foo = <<__EOF;
    +d ahfdklf klsdfl sdf sd
    +fsd sdf sdfsdlkf sd
    +__EOF
    +
    + $x = "dasds";
    +
    + next if( $match eq "two" );
    + next if( $match =~ /go/i );
    +
    + @array = (1,2,3); # a comment
    + @array = qw(apple foo bar);
    + push(@array, 4);
    + %hash = (red => 'rot',
    + blue => 'blau');
    + print keys(%hash);
    +}
    +
    +sub blah {
    +}
    +
    +&blah;
    +prg("test");
    diff --git a/autotests/reference/highlight.pov.ref b/autotests/reference/highlight.pov.ref new file mode 100644 index 0000000..efa9eb9 --- /dev/null +++ b/autotests/reference/highlight.pov.ref @@ -0,0 +1,76 @@ +//BEGIN TEST
    +// test scene for POV-Ray syntax highlighting
    +
    +/* test comment */
    +
    +/* nested /* comments */ do not work */
    +
    +#version 3.5;
    +//END
    +global_settings { assumed_gamma 1.0 }
    +
    +// ----------------------------------------
    +
    +camera {
    + location <5.0, -12.0, 2.0>
    + up z sky z
    + look_at <0.0, 0.0, 0.5>
    + angle 40
    +}
    +
    +sky_sphere {
    + pigment {
    + gradient z
    + color_map {
    + [0.0 rgb <0.6,0.7,1.0>]
    + [0.2 rgb <0.2,0.3,0.9>]
    + }
    + }
    +}
    +
    +light_source {
    + <3, 1, 2>*1000
    + color rgb <2.2, 1.8, 1.5>
    +}
    +
    +// ----------------------------------------
    +
    +#declare TEST=0;
    +
    +#ifdef (TEST)
    + plane {
    + z, 0
    + texture {
    + pigment {
    + checker
    + color rgb 1, color rgb 0
    + }
    + }
    + }
    +#end
    +
    +#macro Sphere(Pos, Radius)
    + sphere {
    + <Pos.x, Pos.y, Radius*1.3>, Radius
    + texture {
    + pigment { color rgb 1 }
    + finish{
    + diffuse 0.3
    + ambient 0.0
    + specular 0.6
    + reflection 0.8
    + }
    + }
    + }
    +#end
    +
    +#local Cnt=0;
    +#local Seed=seed(0);
    +
    +#while (Cnt<10000)
    + Sphere(
    + -100+<rand(Seed), rand(Seed)>*200,
    + 0.3+pow(rand(Seed),2)*0.7
    + )
    + #local Cnt=Cnt+1;
    +#end
    diff --git a/autotests/reference/highlight.prg.ref b/autotests/reference/highlight.prg.ref new file mode 100644 index 0000000..5d8e653 --- /dev/null +++ b/autotests/reference/highlight.prg.ref @@ -0,0 +1,71 @@ +// Test file to test kate's clipper highlighting
    +// kate: hl Clipper;
    +
    +//BEGIN INCLUDES
    +#include
    +#include "logo.ch"
    +
    +#define PRGVERSION "0.0.1"
    +//END
    +
    +//BEGIN CODE
    +static ws, win
    +static driver := getDriver()
    +/* a multiline
    + comment
    +*/
    +
    +function main( formName )
    + local form
    + local fileName
    +
    + if empty(formName)
    + ?? "Usage: ./form_ui &\n"
    + CANCEL
    + else
    + fileName := formName
    + endif
    + ws := UIWorkSpace()
    +
    + form := UIForm( fileName )
    + win := form:parseFile()
    +// ?? valtype(win),chr(10)
    + if win == NIL
    + CANCEL
    + endif
    + win:show()
    +
    + ws:run()
    + ws:quit()
    +return 0
    +
    +/* Setting dialog */
    +function settingsDialog()
    + ?? "TODO: Settings dialog&\n"
    +return
    +
    +/* About dialog */
    +function aboutDialog()
    + local dlg := UIWindow("About", win, "aboutDlg", .F.)
    + local hl, lside, t, bb, bD
    +
    + hl := UIHBox(,4,8)
    + lside := UIVBox()
    + lside:add(UIImage(eas_logo_mini,.T.))
    + hl:add(lside,.F.,.F.)
    + dlg:userSpace:add(hl,.T.,.T.)
    + t := UIVBox()
    + hl:add(t,.T.,.T.)
    +
    + t:add(UILabel("License: GPL version 2 or later"))
    + bb := UIButtonBar()
    + t:add(bb)
    + bD := UIButton(win, "&Close", {|o,e| dlg:close() } )
    + bb:add( bD )
    +
    + dlg:setFocus(bD)
    + dlg:setDefault(bD)
    + dlg:setPlacement( .T. )
    + dlg:show()
    +return
    +//END
    diff --git a/autotests/reference/highlight.qml.ref b/autotests/reference/highlight.qml.ref new file mode 100644 index 0000000..a5c073a --- /dev/null +++ b/autotests/reference/highlight.qml.ref @@ -0,0 +1,59 @@ +import Qt 4.6
    +
    +// some random qml snippets stolen from the qt docs
    +
    +Rectangle {
    + important: true
    + propertyAsdf:
    + id: container
    + signalA: bla
    + property string label
    + signal clicked
    + radius: 5; border.color: "black"
    + color: mouse.pressed ? "steelblue" : "lightsteelblue"
    + gradient: Gradient {
    + GradientStop { position: mouse.pressed ? 1.0 : 0.0; color: "steelblue" }
    + GradientStop { position: mouse.pressed ? 0.0 : 1.0; color: "lightsteelblue" }
    + }
    + MouseRegion { id: mouse; anchors.fill: parent; onClicked: container.clicked() }
    + Text { anchors.fill: parent; text: container.label; anchors.centerIn: parent }
    +}
    +
    +Rectangle {
    + Script {
    + function calculateMyHeight() {
    + return Math.max(otherItem.height, thirdItem.height);
    + }
    + }
    +
    + anchors.centerIn: parent
    + width: Math.min(otherItem.width, 10)
    + height: calculateMyHeight()
    + color: { if (width > 10) "blue"; else "red" }
    +}
    +
    +Rectangle {
    + default property color innerColor: "black"
    + property color innerColor: "black"
    + property alias text: textElement.text
    + property alias aliasXYZ: testElement.text
    + signal bar
    + signal bar(var blah, string yxcv)
    + width: 240; height: 320;
    + width: 100; height: 30; source: "images/toolbutton.sci"
    + ListView {
    + anchors.fill: parent
    + model: contactModel
    + delegate: Component {
    + Text {
    + text: modelData.firstName + " " + modelData.lastName
    + }
    + }
    + }
    +}
    +
    +Item {
    + function say(text) {
    + console.log("You said " + text);
    + }
    +}
    diff --git a/autotests/reference/highlight.rb.ref b/autotests/reference/highlight.rb.ref new file mode 100644 index 0000000..78a944d --- /dev/null +++ b/autotests/reference/highlight.rb.ref @@ -0,0 +1,551 @@ +# This file is a testcase for the highlighting of Ruby code
    +# It's not executable code, but a collection of code snippets
    +#
    +
    +require 'Config'
    +require 'DO/Clients'
    +require 'DO/DBClients'
    +
    + def CGI::escapeElement(string, *elements)
    + elements = elements[0] if elements[0].kind_of?(Array)
    + unless elements.empty?
    + string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/ni) do
    + CGI::escapeHTML($&)
    + end
    + else
    + string
    + end
    + end
    +
    +case inputLine
    + when "debug"
    + dumpDebugInfo
    + dumpSymbols
    + when /p\s+(\w+)/
    + dumpVariable($1)
    + when "quit", "exit"
    + exit
    + else
    + print "Illegal command: #{inputLine}"
    +end
    +
    +
    +kind = case year #hi there
    + when 1850..1889 then "Blues"
    + when 1890..1909 then "Ragtime"
    + when 1910..1929 then "New Orleans Jazz"
    + when 1930..1939 then "Swing"
    + when 1940..1950 then "Bebop"
    + else "Jazz"
    + end
    +
    + # URL-encode a string.
    + # url_encoded_string = CGI::escape("'Stop!' said Fred")
    + # # => "%27Stop%21%27+said+Fred"
    + def CGI::escape(string)
    + string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do
    + '%' + $1.unpack('H2' * $1.size).join('%').upcase
    + end.tr(' ', '+')
    + end
    +
    +
    +# Class ClientManager
    +#
    +# definition : Import, store and export the various data used by the application.
    +# This class is the sole interface between the application and the underlying database.
    +
    +mon, day, year = $1, $2, $3 if /(\d\d)-(\d\d)-(\d\d)/
    +puts "a = #{a}" if fDebug
    +print total unless total == 0
    +
    +while gets
    + next if /^#/ # Skip comments
    + parseLine unless /^$/ # Don't parse empty lines
    +end
    +
    +if artist == "John Coltrane" #hi there
    + artist = "'Trane" #hi there
    +end unless nicknames == "no" #hi there
    +
    +handle = if aSong.artist == "Gillespie" then #hi there
    + "Dizzy"
    + elsif aSong.artist == "Parker" then
    + "Bird"
    + else #hi there
    + "unknown"
    + end
    +
    +if aSong.artist == "Gillespie" then handle = "Dizzy"
    +elsif aSong.artist == "Parker" then handle = "Bird"
    +else handle = "unknown"
    +end #hi there
    +
    +if aSong.artist == "Gillespie" then
    + handle = "Dizzy"
    +elsif aSong.artist == "Parker" then
    + handle = "Bird"
    +else
    + handle = "unknown"
    +end
    +
    +if aSong.artist == "Gillespie"
    + handle = "Dizzy"
    +elsif aSong.artist == "Parker"
    + handle = "Bird"
    +else
    + handle = "unknown"
    +end
    +
    + case line
    + when /title=(.*)/
    + puts "Title is #$1"
    + when /track=(.*)/
    + puts "Track is #$1"
    + when /artist=(.*)/
    + puts "Artist is #$1"
    +end
    +
    +case shape
    + when Square, Rectangle
    + # ...
    + when Circle
    + # ...
    + when Triangle
    + # ...
    + else
    + # ...
    +end
    +
    +
    +until playList.duration > 60 #hi there
    + playList.add(songList.pop)
    +end
    +
    +3.times do
    + print "Ho! "
    +end
    +
    +loop {
    + # block ...
    +}
    +
    +songList.each do |aSong|
    + aSong.play
    +end
    +
    +for aSong in songList
    + aSong.play
    +end
    +
    +for i in ['fee', 'fi', 'fo', 'fum']
    + print i, " "
    +end
    +for i in 1..3
    + print i, " "
    +end
    +for i in File.open("ordinal").find_all { |l| l =~ /d$/}
    + print i.chomp, " "
    +end
    +
    +class Periods
    + def each
    + yield "Classical"
    + yield "Jazz"
    + yield "Rock"
    + end
    +end
    +
    +
    +periods = Periods.new
    +for genre in periods
    + print genre, " "
    +end
    +
    +while gets
    + next if /^\s*#/ # skip comments
    + break if /^END/ # stop at end
    + # substitute stuff in backticks and try again
    + redo if gsub!(/`(.*?)`/) { eval($1) }
    + # process line ...
    +end
    +
    +i=0
    +loop do
    + i += 1
    + next if i < 3
    + print i
    + break if i > 4
    +end
    +
    +for i in 1..100
    + print "Now at #{i}. Restart? "
    + retry if gets =~ /^y/i
    +end
    +
    +def doUntil(cond)
    + yield
    + retry unless cond
    +end
    +
    +i = 0
    +doUntil(i > 3) {
    + print i, " "
    + i += 1
    +}
    +
    +def system_call
    + # ... code which throws SystemCallError
    +rescue SystemCallError
    + $stderr.print "IO failed: " + $!
    + opFile.close
    + File.delete(opName)
    + raise
    +end
    +
    +class ClientManager
    +
    + # constructor
    + def initialize(dbase)
    + @dbClient = DBClient.new(dbase)
    + @clients = Clients.new
    + end
    +
    + def prout(a, b, xy="jj") 24 end
    + ###############################################################
    + #
    + # CLIENTS SECTION
    + #
    + ###############################################################
    +
    + # update the clients object by retrieving the related data from the database
    + # returns the number of clients
    + def refreshClients
    + @clients.clean
    + unless @sqlQuery.nil? then
    + @sqlQuery.selectClient.each do |row|
    + @clients.addClient(row[0],row[1],row[2],row[3],row[4],row[5], row[6], row[7], row[8])
    + end
    + else
    + puts "SqlQuery wasn't created : cannot read data from database"
    + end
    + return @clients.length
    + end
    +
    + # insert a client in the database and refreshes the local clients object
    + # we assume that none of the arguments is null
    + # we assume that the client, identified by raison_sociale doesn't already exists
    + def addClient(raison_sociale, division, departement, adresse, cp, ville, nom_contact, tel_contact)
    + id = "0"
    + unless @sqlQuery.nil? then
    + id = @sqlQuery.insertClient(raison_sociale, division, departement, adresse, cp, ville, nom_contact,tel_contact)
    + else
    + puts "SqlQuery wasn't created : database update cannot be performed"
    + end
    + @clients.addClient(id, raison_sociale, division, departement, adresse, cp, ville, nom_contact, tel_contact) # synchronize local object with DB
    + end
    +
    + # deletes a client from the database and updates the local Clients object accordingly
    + def delClient(nomclient_brut)
    + raison_sociale, div, dep = Clients.getIdentifiers(nomclient_brut)
    + listeContratsExp, listeContratsSup, listeContratsProd, listePropositionsExp, listePropositionsSup = []
    +
    + listeContratsExp = @contratsExpertise.getContratsFromClient(nomclient_brut)
    + listeContratsSup = @contratsSupport.getContratsFromClient(nomclient_brut)
    + listeContratsProd = @contratsProduits.getContratsFromClient(nomclient_brut)
    + listePropositionsExp = @propositionsExpertise.getPropositionsFromClient(nomclient_brut)
    + listePropositionsSup = @propositionsSupport.getPropositionsFromClient(nomclient_brut)
    +
    + unless @sqlQuery.nil? then
    + @sqlQuery.deleteClient(raison_sociale, div, dep)
    +
    + @sqlQuery.deleteContracts(Config::EXPERTISE,listeContratsExp)
    + @sqlQuery.deleteContracts(Config::SUPPORT,listeContratsSup)
    + @sqlQuery.deleteContracts(Config::PRODUIT,listeContratsProd)
    + @sqlQuery.deletePropositions(Config::EXPERTISE,listePropositionsExp)
    + @sqlQuery.deletePropositions(Config::SUPPORT,listePropositionsSup)
    + else
    + puts "SqlQuery wasn't created : database update cannot be performed"
    + end
    + @clients.delClient(raison_sociale,div,dep)
    +
    + @contratsExpertise.deleteContracts(listeContratsExp)
    + @contratsSupport.deleteContracts(listeContratsSup)
    + @contratsProduits.deleteContracts(listeContratsProd)
    + @propositionsExpertise.deletePropositions(listePropositionsExp)
    + @propositionsSupport.deletePropositions(listePropositionsSup)
    + end
    +end
    +
    + # Mixin module for HTML version 3 generation methods.
    + module Html3 # :nodoc:
    +
    + # The DOCTYPE declaration for this version of HTML
    + def doctype
    + %||
    + end
    +
    + # Initialise the HTML generation methods for this version.
    + def element_init
    + extend TagMaker
    + methods = ""
    + # - -
    + for element in %w[ A TT I B U STRIKE BIG SMALL SUB SUP EM STRONG
    + DFN CODE SAMP KBD VAR CITE FONT ADDRESS DIV center MAP
    + APPLET PRE XMP LISTING DL OL UL DIR MENU SELECT table TITLE
    + STYLE SCRIPT H1 H2 H3 H4 H5 H6 TEXTAREA FORM BLOCKQUOTE
    + CAPTION ]
    + methods += <<-BEGIN + nn_element_def(element) + <<-END
    + def #{element.downcase}(attributes = {})
    + BEGIN
    + end
    + END
    + end
    +
    + # - O EMPTY
    + for element in %w[ IMG BASE BASEFONT BR AREA LINK PARAM HR INPUT
    + ISINDEX META ]
    + methods += <<-BEGIN + nOE_element_def(element) + <<-END
    + def #{element.downcase}(attributes = {})
    + BEGIN
    + end
    + END
    + end
    +
    + # O O or - O
    + for element in %w[ HTML HEAD BODY P PLAINTEXT DT DD LI OPTION tr
    + th td ]
    + methods += <<-BEGIN + nO_element_def(element) + <<-END
    + def #{element.downcase}(attributes = {})
    + BEGIN
    + end
    + END
    + end
    + eval(methods)
    + end
    +
    + end
    +
    +# following snippet from Webrick's log.rb
    +# notice the erronous handling of the query method is_a?
    +def format(arg)
    + str = if arg.is_a?(Exception)
    + "#{arg.class}: #{arg.message}\n\t" <<
    + arg.backtrace.join("\n\t") << "\n"
    + elsif arg.respond_to?(:to_str)
    + arg.to_str
    + else
    + arg.inspect
    + end
    +end
    +
    +# following snippet from Webrick's httputils.rb
    +# Splitting regexps on several lines might be bad form,
    +# but not illegal in Ruby.
    +# This should probably be supported in the highlighting
    +def split_header_value(str)
    + str.scan(/((?:"(?:\\.|[^"])+?"|[^",]+)+)
    + (?:,\s*|\Z)/xn).collect{|v| v[0] }
    +end
    +
    +# snippet from Net::Telnet
    +string.gsub(/#{IAC}(
    + [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]|
    + [#{DO}#{DONT}#{WILL}#{WONT}]
    + [#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]|
    + #{SB}[^#{IAC}]*#{IAC}#{SE}
    + )/xno)
    +
    +# following snippet from Webrick's httpresponse.rb
    +# the HEREDOC is not recognized as such
    +@body << <<-_end_of_html_
    +
    +
    + </Here Document><Substitution>#{</Substitution><Constant>HTMLUtils</Constant><Operator>::</Operator><Message>escape</Message><Normal Text>(</Normal Text><Instance Variable>@reason_phrase</Instance Variable><Normal Text>)</Normal Text><Substitution>}</Substitution><Here Document>
    +
    +

    #{HTMLUtils::escape(@reason_phrase)}


    + #{HTMLUtils::escape(ex.message)}
    +

    +_end_of_html_
    +
    +
    +# snippet from Webrick's httpproxy.rb
    +# here we should make sure that the symbol definition ':' doesn't override
    +# the module operator '::'
    +Net::HTTP::version_1_2 if RUBY_VERSION < "1.7"
    +
    +# snippet from Webrick's cookie.rb
    +# the beginning of the regexp is erronously highlighted like an operator
    +key, val = x.split(/=/,2)
    +
    +# the following are division operators
    +# it's a bit tricky to keep the operator apart from the regexp
    +result = 8 / 4
    +result /= divisor
    +
    +# 2008-06-01 regexp and division operator syntax has been fixed:
    +result = 8/4 # division
    +result = 8/foo # division
    +result = /8/ # regexp
    +result = 8//4/ # division and regexp
    +
    +10/10 # division
    +10/ 10 # division
    +10 /10 # division
    +10 / 10 # division
    +
    +foo/10 # division
    +foo/ 10 # division
    +foo /10/ # regexp
    +foo / 10 # division
    +
    +foo/10/10 # both division
    +total/count/2 # both division
    +total/(count/2) # both division
    +
    +@foo/10 # division
    +@foo /10 # division
    +
    +"hello"/10 # division
    +"hello" / 10 # division
    +
    +/regexp//10 # division
    +/regexp/ / 10 # division
    +
    +Math::PI/10 # division
    +Math::foo /rx/ # regexp
    +
    +# 2008-06-05 similar fix for modulo operator:
    +
    +10%4 # modulo
    +10 %4 # modulo
    +10% 4 # modulo
    +10 % 4 # modulo
    +
    +foo%4 # modulo
    +# foo %4 # illegal %string
    +foo% 4 # modulo
    +foo % 4 # modulo
    +
    +foo % (4) # modulo
    +
    +foo %(4) # %string
    +foo %q(4) # %string
    +foo %Q(4) # %string
    +foo %%4% # %string
    +
    +foo = %|blah| # GDL input
    +foo % %|blah| # modulo and GDL
    +
    +# mix in any way you want
    +result = 10//regexp//20/foo//regexp//20
    +
    +# test cases for general delimited input
    +# quoted strings
    +%Q|this is a string|
    +%Q{this is a string}
    +%Q(this is a string)
    +%Q<this is a string>
    +%Q[this is a string]
    +
    +%|also a string|
    +%{also a string}
    +%(also a string)
    +%<also a string>
    +%[also a string]
    +
    +# apostrophed strings
    +%q|apostrophed|
    +%q{apostrophed}
    +%q(apostrophed)
    +%q<apostrophed>
    +%q[apostrophed]
    +
    +# regular expressions
    +%r{expression}
    +%r(expression)
    +%r<expression>
    +%r[expression]
    +%r|expression|
    +
    +# shell commands
    +%x{ls -l}
    +%x(ls -l)
    +%x<ls -l>
    +%x[ls -l]
    +
    +# sometimes it's useful to have the command on multiple lines
    +%x{ls -l |
    +grep test }
    +
    +# alternative syntax
    +`ls -l`
    +`echo ' '`
    +
    +# token array
    +%w{one two three}
    +%w(one two three)
    +%w<one two three>
    +%w[one two three]
    +
    +# snippet from Net::IMAP
    +# I object to putting String, Integer and Array into kernel methods.
    +# While these classes are builtin in Ruby, this is an implementation detail
    +# that should not be exposed to the user.
    +# If we want to handle all std-lib classes, fine. But then they should be in their
    +# own std-lib keyword category.
    +
    +def send_data(data)
    + case data
    + when nil
    + put_string("NIL")
    + when String
    + send_string_data(data)
    + when Integer
    + send_number_data(data)
    + when Array
    + send_list_data(data)
    + when Time
    + send_time_data(data)
    + when Symbol
    + send_symbol_data(data)
    + else
    + data.send_data(self)
    + end
    +end
    +
    +# snippet from Net::POP
    +# class names can have numbers in them as long as they don't begin with numbers
    +# Ruby doesn't internally really make much of a difference between a class name and a constant
    +
    +# class aliases
    + POP = POP3
    + POPSession = POP3
    + POP3Session = POP3
    +
    +# "member access"
    +POP::Session.COUNT.attribute.calc_with(2){ |arg| puts arg }
    +
    +# snippet from Net::SMTP
    +# This breaks the code folding. I think we would need to
    +# handle the '\' that continues the statement to the next line
    +# in some way to make these kind of things not break something.
    +raise ArgumentError, 'both user and secret are required'\
    + unless user and secret
    +
    +# string escapes must detect escaping the escape char
    +str = "\\"
    +str = "\\\\"
    +# this is not part of the string
    +%x{echo \\\}\\} # prints \}\
    +# this is not part of the command
    +
    +# these are all symbols
    +:abc
    +:abc!
    +:abc?
    +:abc=
    +:[]
    +:[]=
    +:@abc
    +:@@abc
    +:$abc
    diff --git a/autotests/reference/highlight.scheme.ref b/autotests/reference/highlight.scheme.ref new file mode 100644 index 0000000..bbdf831 --- /dev/null +++ b/autotests/reference/highlight.scheme.ref @@ -0,0 +1,186 @@ +; This is a test file to test kates scheme highlighting
    +; This is a comment
    +
    +;; Another comment, usually used.
    +;BEGIN region marker
    +;; a vektor
    +#(1 2 3 4 5)
    +;END region marker
    +;; this represents integer 28 (FIXME: does not work perfectly atm!)
    +28 028 #e28 #i28 ;; Normal, normal, exact, inexact
    +#b11100 #o34 #d28 #x1c ;; Bin, okt, dec, hex
    +#oe34 #eo34 ;; combined.
    +
    +;; char.
    +(#\y #\space) ;; list: `y' space.
    +(#\ #\\ #\)) ;; list of spaces, backslash and`)'.
    +#\newline ;; a newline-char
    +#\NewLine ;; another one :)
    +
    +"Hello, world" ;; a string
    +
    +"hoho, what do you
    +want to do ;; this is NO comment
    +with that?"
    +
    +;; R5RS definiert diese beiden.
    +"Das ist \"in Anführungszeichen\" und mit \\ Backslash."
    +
    +(let ((x (+ 1 2)) (y "blah")) ;; `let' highlighting.
    + (and (number? x) ;; `and' highlighting.
    + (string? y)))
    +
    +(let* ((x 2) (y (+ x 1))) ;; `let*' too.
    + (or (negative? x) ;; `or' anyways.
    + (negative? y)))
    +
    +(do ((vec (make-vector 5)) ;; `do' you may guess!
    + (i 0 (+ i 1)))
    + ((= i 5) vec)
    + (vector-set! vec i i))
    +
    +(quasiquote ((+ 1 2) (unquote (+ 1 2))))
    +;; same as: `((+ 1 2) ,(+ 1 2))
    +
    +;; see above.
    +(quasiquote ((+ 1 2) (unquote-splicing (list 1 2 3))))
    +;; same as: `((+ 1 2) ,@(+ 1 2))
    +
    +;; not necessary.
    +(quote ())
    +
    +(cond ((string? x) (string->symbol x)) ;; `cond' highlighting.
    + ((symbol? x) => (lambda (x) x)) ;; `=>' highlighting.
    + (else ;; `else' highlighting.
    + (error "Blah")))
    +
    +(case x ;; `case' highlighting.
    + ((#t) 'true) ((#f) 'false)
    + ((()) 'null)
    + ((0) 'zero))
    +
    +;; highlight `let-syntax' and `syntax-rules' .
    +(let-syntax ((when (syntax-rules ()
    + ((when test stmt1 stmt2 ...)
    + ;; hl `begin' .
    + (if test (begin stmt1 stmt2 ...))))))
    + (let ((if #t)) ;; here`if' is actually no keyword.
    + (when if (set! if 'now)) ;; nor here.
    + if))
    +
    +(letrec-syntax ...) ;; hl `letrec-syntax'.
    +
    +(define-syntax when
    + (syntax-rules ()
    + ((when test stmt1 stmt2 ...)
    + (if test (begin stmt1 stmt2 ...))))))
    +
    +;; variable definitions.
    +(define natural-numbers ;; hl `define' and the var name
    + ;; endless stream of all natual numbers.
    + (letrec ((next-cell ;; hl `letrec'.
    + (lambda (x) ;; hl `lambda'.
    + ;; hl `delay' .
    + (cons x (delay (next-cell (+ x 1)))))))
    + (next-cell 0)))
    +
    +;; a procedure with unusual but allowed name.
    +(define 1+
    + (lambda (x)
    + (+ x 1)))
    +
    +;; a predicate
    +(define between?
    + (lambda (x y z)
    + (if (and (>= x y) (<= x z))
    + #t ;; True
    + #f))) ;; False.
    +
    +;; imperative procedure
    +(define set-something!
    + (lambda (required-argument another-one . all-remaining-args)
    + (set-car! another-one (lambda all-args
    + (set-cdr! required-argument
    + (append all-remaining-args
    + all-args))))))
    +
    +(define compose
    + (lambda (f g)
    + (lambda (x)
    + (f (g x)))))
    +
    +;; syntactical sugar for procedure-definitions.
    +(define (compose f g)
    + (lambda (x)
    + (f (g x))))
    +
    +;;;;;;;;;;;;;;;;;;;;;;;;;;;
    +;; NOW: Guile extensions ;;
    +;;;;;;;;;;;;;;;;;;;;;;;;;;;
    +
    +;; procedure-generator.
    +(define ((compose f g) x)
    + (f (g x)))
    +
    +;; scheme doesn't say, which chars may be in variables...
    +;; At least: Guile accepts umlauts
    +(define-private (timetr??? sprache) ;; hl `define-private'.
    + (list-dialekt? sprache))
    +
    +(define-public x #t) ;; hl `define-public'.
    +(define-module (foo bar)) ;; hl `define-module'.
    +(define-macro (neither . exprs) ;; hl `define-macro'.
    + `(and ,@(map (lambda (x) `(not ,x)) exprs)))
    +
    +(defmacro neither exprs ;; `defmacro' as well.
    + `(and ,@(map (lambda (x) `(not ,x)) exprs)))
    +
    +;; hl, but I really don't know what this is supposed to do :-)
    +(define-syntax-macro ...)
    +
    +;; hl GOOPS-`defines'
    +(define-method (foo bar (baz ) qux) ...)
    +(define-class ...)
    +(define-generic foo)
    +(define-accessor bar)
    +
    +;; Keywords!
    +(blah #:foo 33 #:bar 44)
    +
    +;; another convention for symbols:
    +#{foo}#
    +
    +#{a
    +few
    +lines}#
    +
    +#{4711}#
    +
    +;; more chars.
    +#\nul #\nl #\esc #\bs #\bel #\syn #\ack #\sp ;; etc, utc, itc, oops (this is boring)
    +
    +#!
    + guile block-comment.
    +!#
    +
    +;; now, a bit hairy:
    +#! comment !#
    +still comment!!!
    +!#
    +'now-no-comment-anymore
    +
    +;; more precise:
    +#! comment !#
    +still comment
    +!# still comment!
    +!#
    +'now-no-comment-anymore
    +
    +(while (> foo 10) ;; Highlight `while'.
    + (set! foo (- foo 1))
    + (catch #t ;; Highlight `catch'.
    + (lambda () (display foo))
    + (lambda (key . args)
    + (if (eq? key 'system-error)
    + (break) ;; Highlight `break'.
    + (continue))))) ;; Highlight `continue'.
    diff --git a/autotests/reference/highlight.sh.ref b/autotests/reference/highlight.sh.ref new file mode 100644 index 0000000..4cbc15f --- /dev/null +++ b/autotests/reference/highlight.sh.ref @@ -0,0 +1,207 @@ +#! /bin/sh
    +# This is a test script for the Katepart Bash Syntax Highlighting by
    +# Wilbert Berendsen. This is not runnable !!!
    +
    +
    +# The highlighting recognizes basic types of input, and has a few special cases that
    +# are all in FindCommands. The main objective is to create really proper nesting of
    +# (multiline) strings, variables, expressions, etc.
    +
    +
    +
    +# ============== Tests: ===============
    +
    +# basic types:
    +echo 'single quoted string'
    +echo "double quoted string"
    +echo $'string with esc\apes\x0din it'
    +echo $"string meant to be translated"
    +
    +
    +# comments:
    +# this is a comment
    +#this too
    +echo this is#nt a comment
    +dcop kate EditInterface#1 #this is
    +
    +
    +# brace expansion
    +mv my_file.{JPG,jpg}
    +
    +
    +# special characters are escaped:
    +echo \(output\) \&\| \> \< \" \' \*
    +
    +
    +# variable substitution:
    +echo $filename.ext
    +echo $filename_ext
    +echo ${filename}_ext
    +echo text${array[$subscript]}.text
    +echo text${array["string"]}.text
    +echo ${!prefix*}
    +echo ${!redir}
    +echo short are $_, $$, $?, ${@}, etc.
    +echo ${variable/a/d}
    +echo ${1:-default}
    +
    +
    +# expression subst:
    +echo $(( cd << ed + 1 ))
    +
    +
    +# command subst:
    +echo $(ls )
    +echo `cat myfile`
    +
    +
    +# file subst:
    +echo $(<$filename)
    +echo $(</path/to/myfile)
    +
    +# process subst:
    +sort <(show_labels) | sed 's/a/bg' > my_file.txt 2>&1
    +
    +
    +# All substitutions also work in strings:
    +echo "subst ${in}side string" 'not $inside this ofcourse'
    +echo "The result is $(( $a + $b )). Thanks!"
    +echo "Your homedir contains `ls $HOME |wc ` files."
    +
    +
    +# Escapes in strings:
    +p="String \` with \$ escapes \" ";
    +
    +
    +# keywords are black, builtins dark purple and common commands lighter purple
    +set
    +exit
    +login
    +
    +
    +# Other colorings:
    +error() {
    + cat /usr/bin/lesspipe.sh
    + runscript >& redir.bak
    + exec 3>&4
    +}
    +
    +
    +# do - done make code blocks
    +while [ $p -lt $q ]
    +do
    + chown 0644 $file.$p
    +done
    +
    +
    +# braces as well
    +run_prog | sort |
    +{
    + echo Header
    + while read a b d
    + do
    + echo $a/$b/$c
    + done
    + echo Footer
    +}
    +
    +
    +# Any constructions can be nested:
    +echo "A long string with $(
    + if [ $count -gt 100 ] ; then
    + echo "much"
    + else
    + echo "not much"
    + fi ) substitutions." ;
    +
    +
    +# Even the case construct is correctly folded:
    +test blaat &&
    +( do_something
    + case $p in
    + *bak)
    + do_bak $p
    + ;;
    + *)
    + dont_bak $p
    + ;;
    + esac
    +) # despite the extra parentheses in the case construction.
    +
    +
    +# variable assignments:
    +DIR=/dev
    +p=`ls`
    +LC_ALL="nl" dcop 'kate*'
    +_VAR=val
    +ARR=(this is an array)
    +ARR2=([this]=too [and]="this too")
    +usage="$0 -- version $VERSION
    +Multiple lines of output
    +can be possible."
    +ANSWER=yes # here 'yes' isn't highlighed as command
    +
    +
    +# Some commands expect variable names, these are colored correctly:
    +export PATH=/my/bin:$PATH BLAAT
    +export A B D
    +local p=3 x y='\'
    +read x y z <<< $hallo
    +unset B
    +declare VAR1 VAR2 && exit
    +declare less a && b
    +
    +# options are recoqnized:
    +zip =file.zip
    +./configure =/usr
    +make destdir=/usr/
    +
    +
    +# [[ and [ correctly need spaces to be regarded as structure,
    +# otherwise they are patterns (currently treated as normal text)
    +if [ "$p" == "" ] ; then
    + ls /usr/bin/[a]*
    +elif [[ $p == 0 ]] ; then
    + ls /usr/share/$p
    +fi
    +
    +# Fixed:
    +ls a[ab]* # dont try to interprete as assignment with subscript (fixed)
    +a[ab]
    +a[ab]=sa
    +
    +
    +# Here documents are difficult to catch:
    +cat > myfile << __EOF__
    +You're right, this is definitely no bash code
    +But ls more $parameters should be expanded.
    +__EOF__
    +
    +
    +# quoted:
    +cat << "EOF" | egrep "this" >&4 # the rest of the line is still considered bash source
    +You're right, this is definitely no bash code
    +But ls more $parameters should be expanded. :->
    +EOF
    +
    +
    +# indented:
    +if true
    +then
    + cat <<- EOF
    + Indented text with a $dollar or \$two
    + EOF
    +elif [ -d $file ]; then
    + cat <<- "EOF"
    + Indented text without a $dollar
    + EOF
    +fi
    +
    +
    +case 1 in
    +2) echo xxx;
    +;;
    +1) echo yyy;
    +esac
    +
    +ls #should be outside of case 1 folding block
    diff --git a/autotests/reference/highlight.spec.ref b/autotests/reference/highlight.spec.ref new file mode 100644 index 0000000..da39b2c --- /dev/null +++ b/autotests/reference/highlight.spec.ref @@ -0,0 +1,212 @@ +# Test file for rpmspec.xml
    +
    +# Comments start with a # in column="0":
    +
    +# Some comment
    +
    +# When they don't start in column="0", that they are recognized as comments, but with an alert:
    + # This is a bad comment.
    +# RPM spec says clear that comments must start at the begin of the line. However, in practice
    +# the RPM software is more permissive, depending on the context. But for our syntax highlighting,
    +# we give, while recognizing the as comment, at least a little alert. Comments should not contain
    +# the character % (which is marked as warning), but 2 of them are okay: %%. TODO is higlighted.
    +
    +# A spec file starts with "Normal" context. Here, you can specify values for some tags:
    +Name: kradioripper-unstable # Note that here in no comment possible!
    +Name: name only _one_ word allowed
    +Name: %macro no further syntax check after macro!
    +# Some tags support only _one_ word as value
    +Version: 0.4test5 up-from-the-space-this-is-an-error
    +# Some tag can have parameters: Any char in paranthesis:
    +Summary: Recorder for internet radios (based on Streamripper)
    +Summary(de.UTF-8): Aufnahmeprogramm für Internetradios (basiert auf Streamripper)
    +# requiere free text:
    +License: License 1 2 3
    +# requiere a well defines value:
    +Requires( / ( = ): Some, value()
    +# new type "switch" accepts: yes, no, 0, 1
    +AutoReq: yes
    +AutoReq: yes invalid
    +AutoReq: %macro no further syntax check after macro!
    +AutoReq: no
    +AutoReq: 0
    +AutoReq: 1
    +# requiere a number:
    +Epoch: 123123
    +Epoch: 123123 invalid
    +Epoch: %macro no further syntax check afer macro!
    +# If tags are used that are not known, they are not highlighted:
    +Invalidtag: Some value
    +Invalid content in this section (only tags are allowed)
    +
    +# You can use conditions in specs (highlighted with region markers):
    +%if 0%{?mandriva_version}
    +# numbers and strings are distingished: string:
    +%if lsdksfj
    +# number:
    +%if 23472398
    +# string:
    +%if lksdjfsl72939
    +# invalid:
    +%if 92437lsdkfjdsl
    +# valid:
    +%if "lsdfj %ksdf(sdfs) 3489"
    +Release: %mkrel 1.2
    +%else
    +Release: 0
    +%endif
    +# requiere a well defined value:
    +%ifos fixed_value
    +# You must use these special macros (%%if etc.) always at the start of the line - if not,
    +# that's bad but not an arror. You must also always use the specified form. Everything else is an
    +# error:
    + %if
    +something %if
    +%{if}
    +%if(some options)
    +# However, this are different macros and therefore correct:
    +%ifx
    +%{ifx}
    +%ifx(some options)
    +
    +# the \ is escaped in the line. At the end of the line it escapes the line break:
    +echo This is \" a text \\ and here\
    +it continues.
    +
    +%define name value
    +%define invalid_näme value
    +%define macroname multi\
    +line content with references like %0 %* %# %{-f} %{-f*} %1 %2 and so on
    +%global name value
    +%global invalid_näme value
    +%undefine name
    +%undefine name too-many-parameters
    +
    +# This special comment is treated and highlighted like a tag:
    +# norootforbuild
    +# It can't have parameters, so every following non-whitespace character is not good:
    +# norootforbuild DONT WRITE ANYTHING HERE!
    +# wrong spacing is also recognized:
    +# norootforbuild
    +# and also an indeet is not fine for norootforbuild:
    + # norootforbuild
    +
    +# This following "Conflicts" tag will be removed by set-version.sh,
    +# if it is a "kradioripper" release (and not a "kradioripper-unstable" release)...
    +Conflicts: kradioripper
    +
    +
    +
    %description

    +# Here, a new section starts. It contains a value for the RPM field "description" and is therefor
    +# colored like values:
    +A KDE program for ripping internet radios. Based on StreamRipper.
    +
    +
    +# A section start can have parameters:
    +
    %description
    -l de.UTF-8
    +Ein KDE-Aufnahmeprogramm für Internetradios. Basiert auf StreamRipper.
    +
    +# These sections starts are errors:
    + %description not at the first line
    +%{description} wrong form
    +%description(no options allowed, only parameters!)
    +
    +
    +
    %prep

    +# This starts a section that defines the commands to prepare the build.
    +# q means quit. n sets the directory:
    +%setup -q -n kradioripper
    +echo Test
    +# Macros can have different forms: Valid:
    +%abc
    +%abcÄndOfMacro
    +%abc(def)EndOfMacro
    +%{abc}EndOfMacro
    +%{something but no single %}EndOfMacro
    +%{abc:def}EndOfMacro
    +%(abc)
    +# Invalid:
    +%ÄInvalidChar
    +%
    +%)
    +%}
    +# You can use macros inside of macro calls: Fine:
    +%{something %but no %{sin%(fine)gle} }EndOfMacro
    +# Bad:
    +%{No closing paranthesis (No syntax highlightig for this error available)
    +
    +
    +
    %build

    +cmake ./ -DCMAKE_INSTALL_PREFIX=%{_prefix}
    +%__make %{?jobs:-j %jobs}
    +
    +
    +
    %install

    +%if 0%{?suse_version}
    +%makeinstall
    +%suse_update_desktop_file kradioripper
    +%endif
    +%if 0%{?fedora_version} || 0%{?rhel_version} || 0%{?centos_version}
    +make install DESTDIR=%{buildroot}
    +desktop-file-install --delete-original --vendor fedora --dir=%{buildroot}/%{_datadir}/applications/kde4 %{buildroot}/%{_datadir}/applications/kde4/kradioripper.desktop
    +%endif
    +%if 0%{?mandriva_version}
    +%makeinstall_std
    +%endif
    +
    +
    +
    %clean

    +rm -rf "%{buildroot}"
    +
    +
    +
    %files

    +%defattr(-,root,root)
    +%if 0%{?fedora_version} || 0%{?rhel_version} || 0%{?centos_version}
    +%{_datadir}/applications/kde4/fedora-kradioripper.desktop
    +%else
    +%{_datadir}/applications/kde4/kradioripper.desktop
    +%endif
    +%{_bindir}/kradioripper
    +%{_datadir}/locale/*/LC_MESSAGES/kradioripper.mo
    +%if 0%{?mandriva_version}
    +# TODO The %%doc macro is actually broken for mandriva 2009 in build service...
    +%dir %{_datadir}/apps/kradioripper
    +%{_datadir}/apps/kradioripper/*
    +%else
    +%doc COPYING LICENSE LICENSE.GPL2 LICENSE.GPL3 NEWS WARRANTY
    +%dir %{_datadir}/kde4/apps/kradioripper
    +%{_datadir}/kde4/apps/kradioripper/*
    +%endif
    +
    +
    +
    %changelog

    +* Sun May 04 2008 email@email.com
    +- some text
    +- some text
    + in two lines
    +- some text
    + in two lines
    + + with subtext
    + - and more subtext
    + in two lines
    +* Tue Apr 24 2007 Name
    +- text
    + * When the star isn't at column 0, than it doesn't indicate
    + a new date
    +* Wen Sep 08 2003 Wrong weekday
    +* Mon Mai 08 2003 Wrong month
    +* Mon Sep 0 2003 bad day
    +* Mon Sep 8 2003 good day
    +* Mon Sep 08 2003 good day
    +* Mon Sep 32 2003 bad day
    +* Mon Sep 08 03 bad year
    +* Mon Sep 08 2003 Name
    +# When using macros, the error check is disabled:
    +* %myDataMacro Title of the entry
    +- Text
    + - can
    + - be
    + - indeeded
    + - without
    + - problems
    +
    diff --git a/autotests/reference/highlight.t2t.ref b/autotests/reference/highlight.t2t.ref new file mode 100644 index 0000000..60514fb --- /dev/null +++ b/autotests/reference/highlight.t2t.ref @@ -0,0 +1,90 @@ +txt2tags sample
    +
    +
    +%!--includeconf: config.t2t
    +% disabled here because there is no external file
    +%!preproc: 'JUST A TEST' ' '
    +%!postproc: '(?i)(
    +%!postproc: '(?i)()' ' shots\1'
    +
    +%!--include: menu.t2t
    +
    += Title 1 =
    +
    +
    +== My Subtitle 1 ==[some definition]
    +
    +Some examples:
    +
    +- A paragraph with **bold**, //italic// and --strike--.
    +- You can even __underline your docs__!
    +
    +- And use **//bold and italic//**
    +- or //**italic and bold**//
    +
    +Here is a nice pic: [img/t2tpowered.png].
    +
    +- And a [link to a cool website http://txt2tags.sf.net]!
    +
    +- A table :
    +
    + || Name | Age | Gender |
    + | John | 33 | Male |
    + | Mary | 19 | Female |
    +
    +
    +``` A verbatim line
    +
    +And it's working for ``special code`` like this.
    +
    +```
    +Unfortunately I can't color this verbatim content yet.
    +```
    +
    +
    +== My Subtitle 2 ==
    +
    +
    +Lorem ipsum etc
    +Lorem ipsum etc Lorem ipsum etc
    +
    +- Test d'écriture avec des accents à la française. Ça marche ou pas ?
    +
    +== My Subtitle 3 ==
    +
    +
    +Lorem ipsum etc
    +Lorem ipsum etc
    +
    +Here is a direct link: http://kde.org
    +
    +
    +- Another boring part...
    +
    +
    +
    +=== My Subsubtitle 1 ===
    +
    +//It's a level 3 header//
    +
    +- list 1
    +- list 2
    + - list 2b
    +- list 3
    +
    +
    +=== My Subsubtitle 2 ===
    +
    +//It's another level 3 header//
    +
    ++ ordered list 1
    ++ list 2
    + + list 2B
    + + list 2C
    ++ list 3
    +
    +
    +== My Subtitle 4 ==
    +
    +nothing to say here...
    +
    diff --git a/autotests/reference/highlight.tcl.ref b/autotests/reference/highlight.tcl.ref new file mode 100644 index 0000000..57e0778 --- /dev/null +++ b/autotests/reference/highlight.tcl.ref @@ -0,0 +1,50 @@ +# tcl syntax highlighting sample script for Kate
    +#
    +# author: JM. Philippe 15/03/04
    +
    +# escaped characters
    +set String \{
    +set String \{
    +set String \"
    +set String " \" "
    +set String " \{ "
    +
    +#comments and not comments
    +# is comments
    +;#is comments
    + # is comments
    +#

    is html comment


    +puts ok; # is comments
    +set String [string map { {»is not comments}} $String]
    +set String \#not_a_comment
    +
    +# blocks
    +proc test {arg1 {arg2 {}} {arg3 {fr fq r}}} {
    + if {1} {; #comments
    + set String \{; # not a block start
    + }
    +}
    +
    +proc test args {
    + set String \}; # not a block end
    +}
    +
    +# BEGIN - collapsable comments
    +# blablabla
    +# END
    +
    +# strings
    +set String "feqr feqr $gqer gqe"
    +set String "feqr
    +feqr \" $gqer \
    +gqe
    +"
    +set String {feqr
    +feqr \{ $gqer \
    +gqe
    +}
    +
    +# variables
    +set b+1 [incr b]
    +set {incr-b} ${b+1}
    +puts ${incr-b}
    diff --git a/autotests/reference/highlight.tex.ref b/autotests/reference/highlight.tex.ref new file mode 100644 index 0000000..8893ecf --- /dev/null +++ b/autotests/reference/highlight.tex.ref @@ -0,0 +1,73 @@ +% LaTeX test file for kate's syntax highlighting and code folding
    +
    +\ordinaryLaTeXcommandwithoption[10pt,a4paper]{article}
    +% BEGIN region
    +%comment, this is all ok % $
    +\%no comments please
    +\\%comment
    +% END of region
    +
    +\newcommand{\nohighlighting}
    +
    +\section{normal}
    +
    +\ref{blue}
    +\pageref{blue}
    +\cite{blue}
    +
    +\begin{environmentshavespecialcolors}
    +normal
    +\end{environmentshavespecialcolors}
    +
    +$equations are green, \commands somewhat darker$
    +normal
    +$$equations are green, \commands somewhat darker$$
    +normal
    +\(
    +\frac{1}{2}
    +\begin{test}
    +\end{test}
    +\)
    +normal
    +\[
    +%comment
    +displaymath
    +\]
    +normal
    +\begin{equation}
    +green\darkergreen
    +\begin{test}
    +\test
    +\end{test}
    +\end{equation}
    +
    +\begin{equation*}
    +green\darkergreen
    +%comment
    +\begin{test}
    +\test
    +\end{test}
    +\%no comment
    +\end{equation*}
    +
    +\{ %this should be comment
    +
    +\verb%this shouldn't be%and this should be normal text
    +
    +\begin{verbatim}
    +text inside a verbatim environment is also treated special $ %,
    +you can even put a \begin{verbatim} inside
    +\end{verbatim}
    +
    +normal
    +
    +\begin{Verbatim}
    +&@@#^%&^#$
    +\end{Verbatim}
    +
    +
    +\begin{Verbatim*}
    +@*&^#@*(^#(*@&
    +\end{Verbatim*}
    +
    +normal
    diff --git a/autotests/reference/highlight.wrl.ref b/autotests/reference/highlight.wrl.ref new file mode 100644 index 0000000..019db97 --- /dev/null +++ b/autotests/reference/highlight.wrl.ref @@ -0,0 +1,41 @@ +#VRML V2.0 utf8
    +#
    +# VRML highlighting test for Kate's syntax highlighting
    +#
    +
    +# Keywords
    +DEF, EXTERNPROTO, FALSE, IS, NULL, PROTO, ROUTE, TO, TRUE, USE, eventIn,
    +eventOut, exposedField, field
    +
    +# Data types
    +MFColor, MFFloat, MFInt32, MFNode. MFRotation, MFString, MFTime, MFVec2f,
    +MFVec3f, SFBool, SFColor, SFFloat, SFImage, SFInt32, SFNode, SFRotation,
    +SFString, SFTime, SFVec2f, SFVec3f
    +
    +# Predefined nodes
    +Anchor, Appearance, AudioClip, Background, Billboard, Box, Collision, Color,
    +ColorInterpolator, Cone, Coordinate, CoordinateInterpolator, Cylinder,
    +CylinderSensor, DirectionalLight, ElevationGrid, Extrusion, Fog, FontStyle,
    +Group, ImageTexture, IndexedFaceSet, IndexedLineSet, Inline, LOD, Material,
    +MovieTexture, NavigationInfo, Normal, NormalInterpolator, OrientationInterpolator,
    +PixelTexture, PlaneSensor, PointLight, PointSet, PositionInterpolator,
    +ProximitySensor, ScalarInterpolator, Script, Shape, Sound, Sphere, SphereSensor,
    +SpotLight, Switch, Text, TextureCoordinate, TextureTransform, TimeSensor,
    +TouchSensor, Transform, Viewpoint, VisibilitySensor, WorldInfo
    +
    +# Some real VRML constructs to see if highlighting of int, float etc. works
    +NavigationInfo {
    + avatarSize [0.25, 1.6, 0.75]
    + headlight TRUE
    + speed 1
    + type ["WALK", "ANY"]
    + visibilityLimit 0.0
    +}
    +
    +# some further testing for strings: linefeeds are allowed within strings
    +Text {
    + string ["some special in-string characters: \" \\
    + some more text in the next line
    + and yet another line"]
    +}
    +
    diff --git a/autotests/reference/highlight.xml.ref b/autotests/reference/highlight.xml.ref new file mode 100644 index 0000000..130bc63 --- /dev/null +++ b/autotests/reference/highlight.xml.ref @@ -0,0 +1,67 @@ + version="1.0" encoding="UTF-8"?>
    +language SYSTEM "language.dtd">
    +
    +
    +
    +This is a pseudo XML file to test Kate's XML syntax highlighting.
    +
    +Doctype:
    + HTML PUBLIC "-//SOME_DOCTYPE 0.01//EN" SYSTEM "foobar.dtd">
    +
    +Processing instruction:
    + processing instruction ?>
    +
    +Comments:
    +
    +
    +
    +Comment inside element:
    + attr="foobar">content
    +
    +Markup inside comment:
    +
    +
    +Empty element:
    +
    + />
    +
    +Simple element plus content:
    + some content
    + attr="foobar">some
    + content

    +
    +Namespace for elements and attributes:
    + content
    + ns:attr="content content">content
    +
    +Elements containing allowed characters:
    + foo="test"/>
    + foo="test"/>
    +
    +Elements containing allowed start characters:
    + <:element foo="test"/>
    + <_element foo="test"/>
    +
    +Single quotes (the same as double quotes):
    + attr='content   content'>content
    +
    +Allowed Whitespace:
    + attr = "test" >
    + content

    +
    +Entities:
    +  
    + å
    + å
    + å
    + И
    +
    + attr="foo   å & bar"/>
    +
    +Illegal XML, should not be highlighted:
    + <0foobar> -- no digit as first character
    + <-foo> -- no dash as first character
    diff --git a/autotests/reference/highlight.xsl.ref b/autotests/reference/highlight.xsl.ref new file mode 100644 index 0000000..5000e1e --- /dev/null +++ b/autotests/reference/highlight.xsl.ref @@ -0,0 +1,109 @@ + version="1.0" encoding="iso-8859-15"?>
    +
    +
    +
    +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    +xmlns:h="http://www.w3.org/1999/xhtml">
    +<xsl:output method="xml" encoding="iso-8859-15" indent="yes"
    + doctype-public="+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
    + doctype-system="http://www.python.org/topics/xml/dtds/xbel-1.0.dtd"
    +/>
    +
    +
    +<xsl:template match="/">
    +</Tag><Normal Text>Linux at Home Links</Normal Text><Tag>
    +<xsl:for-each select="//*[@id='maincontents']//h:li">
    + <xsl:variable name="f" select="document(h:a/@href)/h:html"/>
    +
    + <</Tag><XSLT Tag>xsl:value-of</XSLT Tag><Attribute> select=</Attribute><XPath>"h:a/h:strong"</XPath><Tag>/>
    + <xsl:value-of select="normalize-space(h:a/text())"/>
    + <xsl:for-each select="$f//h:div[@id='maincontents']">
    + <xsl:call-template name="getbookmarks"/>
    + xsl:for-each>
    +
    +
    +xsl:for-each>
    +
    +xsl:template>
    +
    +
    +
    +<xsl:template name="getbookmarks">
    +
    +<xsl:choose>
    +
    + <xsl:when test="self::h:li or self::h:p">
    + <xsl:variable name="t" select="normalize-space()"/>
    + <xsl:for-each select=".//h:a[1]">
    + <xsl:call-template name="bookmark">
    + <xsl:with-param name="desc" select="$t"/>
    + xsl:call-template>
    + xsl:for-each>
    + <xsl:for-each select=".//h:a[position()!=1]">
    + <xsl:call-template name="bookmark"/>
    + xsl:for-each>
    + xsl:when>
    +
    +
    + <xsl:otherwise>
    + <xsl:for-each select="*">
    + <xsl:call-template name="getbookmarks"/>
    + xsl:for-each>
    + xsl:otherwise>
    +
    +xsl:choose>
    +
    +xsl:template>
    +
    +
    +<xsl:template name="bookmark">
    + <xsl:param name="href" select="@href"/>
    + <xsl:param name="desc" select="''"/>
    + <xsl:param name="title" select="normalize-space()"/>
    +
    + <xsl:variable name="realdesc">
    + <xsl:choose>
    + <xsl:when test="starts-with($desc,$title)">
    + <xsl:choose>
    + <xsl:when test="starts-with(translate(substring-after($desc,$title),',.;','...'),'.')">
    + <xsl:value-of select="substring($desc,string-length($title) + 2)"/>
    + xsl:when>
    + <xsl:otherwise>
    + <xsl:value-of select="substring-after($desc,$title)"/>
    + xsl:otherwise>
    + xsl:choose>
    + xsl:when>
    + <xsl:otherwise>
    + <xsl:value-of select="$desc"/>
    + xsl:otherwise>
    + xsl:choose>
    + xsl:variable>
    +
    +
    + <xsl:attribute name="href">
    + <xsl:choose>
    + <xsl:when test="starts-with($href,'http://') or starts-with($href,'ftp://') or starts-with($href,'mailto:')">
    + <xsl:value-of select="$href"/>
    + xsl:when>
    + <xsl:otherwise>
    + <xsl:value-of select="concat('http://www.xs4all.nl/~wbsoft/linux/links/',$href)"/>
    + xsl:otherwise>
    + xsl:choose>
    + xsl:attribute>
    + <</Tag><XSLT Tag>xsl:value-of</XSLT Tag><Attribute> select=</Attribute><XPath>"</XPath><XPath/ XSLT Function>normalize-space</XPath/ XSLT Function><XPath>(</XPath><Variable>$title</Variable><XPath>)"</XPath><Tag>/>
    + <xsl:if test="normalize-space($realdesc) != ''">
    + <xsl:value-of select="normalize-space($realdesc)"/>
    + xsl:if>
    +
    +xsl:template>
    +
    +
    +
    +xsl:stylesheet>
    diff --git a/autotests/reference/highlight.y.ref b/autotests/reference/highlight.y.ref new file mode 100644 index 0000000..c553a93 --- /dev/null +++ b/autotests/reference/highlight.y.ref @@ -0,0 +1,54 @@ +/* Yacc / Bison hl test file.
    + * It won't compile :-) Sure !
    + */
    +
    +%{
    +
    +#include
    +using namespace std;
    +
    +extern KateParser *parser;
    +
    +%}
    +
    +%locations
    +
    +%union {
    + int int_val;
    + double double_val;
    + bool bool_val;
    + char *string_val;
    + char *ident_val;
    + struct var *v;
    + void *ptr;
    +}
    +
    +%token TOK_NOT_EQUAL "!="
    +%token TOK_LESSER_E "<="
    +%token TOK_GREATER_E ">="
    +%token TOK_EQUAL_2 "=="
    +
    +%type type type_proc
    +
    +%%
    +
    +prog: KW_PROGRAM ident { parser->start($2); } prog_beg_glob_decl instructions { parser->endproc(0); } dev_procedures KW_ENDP ;
    +
    +number: integer_number
    + | TOK_DOUBLE
    + {
    + $$ = new var;
    + $$->type = KW_REEL;
    + $$->cl = var::LITTERAL;
    + $$->real = $<int_val>1;
    + };
    +
    +%%
    +
    +#include
    +
    +int main(void)
    +{
    + puts("Hello, World!");
    + return 0;
    +}
    diff --git a/autotests/reference/highlight_lpc.c.ref b/autotests/reference/highlight_lpc.c.ref new file mode 100644 index 0000000..72031aa --- /dev/null +++ b/autotests/reference/highlight_lpc.c.ref @@ -0,0 +1,64 @@ +// NOTE: This is a test file for kate's LPC syntax highlighting.
    +
    +// This is a Single-Line Comment
    +/* This is a Multi-
    + Line Comment */
    +
    +// This again is a Single-Line Comment which should end here /*
    +
    +// And this is an evil single line comment \
    + which should include this and the next line because of the \
    + Do not use this style at home, kids.
    +// BEGIN region marker
    +
    +// END of region marker
    +
    +private void create()
    +{
    +// Some Preprocessor stuff:
    +#define SOME_STUFF if(foo("bar")) \
    + { \
    + bar("foo"); \
    + } // Preprocessor, Keyword, Preprocessor-String, Multiline
    +
    + // Some closures:
    + #'create;
    + #'?!;
    +
    +
    + /* Some other Data Types: */
    +
    + int i = 1; // Integer.
    + float b = 2.34; // Float.
    + int c = 0b001; // Binary
    + int e = 0x019Beef; // Hexadecimal
    + int f = 0o2345; // Octal
    + string a = "Wheee"; // String
    + string x = "Wheee\
    + heee"; // Multi-Line String, again, don't use this.
    +
    +
    +
    + /* Some keywords: */
    + if(1)
    + {
    + switch(2)
    + {
    + case 3:
    + 4;
    + break;
    + }
    + }
    +
    + else
    + {
    + return 0;
    + }
    +}
    +
    +/*
    +WARNING: If the above function is part of a multi-line comment,
    + it's buggy. The WARNING: itself should be a comment-keyword.
    + That's not actually part of the language, but simply used
    + to highlight important stuff inside comments like TODO: etc.
    +*/
    diff --git a/autotests/reference/highlight_ocaml.ml.ref b/autotests/reference/highlight_ocaml.ml.ref new file mode 100644 index 0000000..c0559f0 --- /dev/null +++ b/autotests/reference/highlight_ocaml.ml.ref @@ -0,0 +1,105 @@ +(* ocaml test file -- a big stew of Objective Caml syntax to use to
    + test Kate's syntax highlighting. This will not run! :-) *)
    +
    +(* First a little piece of real OCaml that should look right: *)
    +
    + #load "basic";;
    + (* Return a default value for a BASIC variable given its identifer. *)
    + let default_value (ident : string) : basic_value =
    + assert (String.length ident > 0);
    + match ident.[String.length ident - 1] with
    + | '$' -> Str ""
    + | '%' -> Int 0
    + | '!' -> Flt 0.0
    + | _ -> Flt 0.0
    + ;;
    +
    +(* Directives: *)
    +#load "pa_o";;
    + #load "pa_o";;
    +object # meth ;; (* not a directive - a method call *)
    +object
    + # meth ;; (* not a directive - a method call *)
    +
    +(* OCaml keywords: *)
    +and as assert asr (* etc. there so many... *)
    +
    +(* Additional OCaml Revised Syntax keywords: *)
    +(* These are in a seperate category so they can be coloured to look
    + like identifiers when ordinary OCaml syntax is being used: *)
    +declare where value
    +
    +(* There's no way to reliably highlight all OCaml type expressions,
    + (they can be very complex) so just the built-in type names are highlighted.*)
    +exn lazy_t format unit int real char string ref array bool list option
    +
    +
    +let integers : int list = [
    + 123456789; (* decimal *)
    + -0xabcedf0123456789; (* hexadecimal *)
    + 0xABCDEF0123456789; (* hexadecimal *)
    + -0o1234567; (* octal *)
    + 0b01001010101010; (* binary *)
    + -0Xabcedf0123456789; (* hexadecimal *)
    + 0XABCDEF0123456789; (* hexadecimal *)
    + -0O1234567; (* octal *)
    + 0B01001010101010; (* binary *)
    + -123_456_789; (* Underscores are allowed in numeric constants. *)
    + 0x_abce_df01_2345_6789;
    + -0o12_34_567;
    + 0b_0100_1010_1010_1101;
    +];;
    +
    +let floats : real list = [
    + 12345.6789;
    + -1.23456789e4; (* All variations of the exponent form *)
    + 1.23456789e+4;
    + -1.23456789e-4;
    + 1.23456789E-4;
    + -1.23456789E+4;
    + 12_345.6789; (* Underscores are allowed in numeric constants. *)
    + -1.23_456_789e+4;
    + 12_345.6789;
    +];;
    +
    +let characters : char list = [
    + 'a';
    + ' ';
    + '�';
    + '\n'; '\r'; '\t'; '\b'; (* Control characters. Only these four: not the full C-language range. *)
    + '\000'; '\128'; (* Decimal character codes. These are always 3 digits. *)
    + '\x02'; '\xff'; '\xFF'; (* Hexadecimal character codes. These are always 3 digits. *)
    + '\\'; '\''; '\"'; '"' (* Quote character escapes. *)
    +];;
    +
    +(* Quotes used to mark constants in parsers should
    + not be confused with character constant quotes.
    + "Ticks" at the end of identifiers should
    + not be confused with character constant quotes. *)
    +let basic_identifier =
    + parser
    + [< ''F'; ''N'; name = s >] -> ID (s, 'f')
    + | [< name = s' >] -> ID (s','i')
    +;;
    +
    +let strings : string list = [
    + ""; (* Empty string *)
    + "a"; " "; "�"; "ab";
    + "A\nB"; "A\rB"; "A\tB"; "A\bB"; (* Control characters. Only these four: not the full C-language range. *)
    + "A\000B"; "A\128B"; (* Decimal character codes. These are always 3 digits. *)
    + "A\x02B"; "A\xffB"; "A\xFFB"; (* Hexadecimal character codes. These are always 3 digits. *)
    + "A\\B"; "A\'B"; "A'B"; "A\"B"; (* Quote character escapes. *)
    + "A multiline\
    + string";
    +];
    +
    +let camlp4_quotations = [
    + <> ;
    + <:QUOTE
    > ;
    + <:QU�T�<A labelled Camlp4 source code quotation. (Latin-1 identifier.)>> ;
    + << A quote with an escape: \>> (end-quote symbol) >> ;
    + << A quote with an escape: \<< (plain start quote-symbol) >> ;
    + << A quote with an escape: \<:Trouv�< (labelled start-quote symbol) >> ;
    +];;
    +
    +(* end *)
    diff --git a/autotests/reference/highlight_octave.m.ref b/autotests/reference/highlight_octave.m.ref new file mode 100644 index 0000000..121139b --- /dev/null +++ b/autotests/reference/highlight_octave.m.ref @@ -0,0 +1,74 @@ +##=====================================================
    +% Octave test code for Kate/Kwrite syntax highlighting
    +% (shamelessly copied from Matlab's, since the two
    +% are very similar)
    +% kate: hl Octave;
    +##=====================================================
    +
    +% Numbers _____________________________________________
    +5, 5.5, .1, 0.1, 0.4e5, 1.2e-5, 5i, 5.3i, 6j, .345+3i
    +5', 5.5', .1', 0.1', 0.4e5', 1.2e-5', 5i', 5.3i', 6j', .345+3i'
    +
    +% Operators ___________________________________________
    +% relational operators
    +'asdf'~=4, c<=4, d>=4, a<b, a>b, a==b, b||c, b&&c
    +% elementwise arithmetic operators
    +a.^b, a.*b a./b, 1:4:5
    +% single-character binary arithmetic
    +a+3, a-3, a*2, a^3, a/3, a\3, a|b, a&b
    +% unary operators
    +a = ~g; g = @sfdgdsf(sdfsd,345); g.' + 1i.' - ('asdf').'
    +% separators and delimiter
    +(asd),[sadf];{asdf},;;,;;;()
    +% continuation
    +a = 1+ ...
    + 2;
    +
    +% Strings and adjoint _________________________________
    +% incomplete strings
    +'string
    +'str''
    +'str''ing
    +'str''\'
    +% complete strings
    +'string' % simple string
    +'''' '\'' % strings containing '
    +'str''ing' % one string containing '
    +'string' 'string' % two strings
    +'asdf' "asdf""" variable % two strings and a variable
    +'asdf''asdf'' fsgdfg' + (asdf)' - 'asdf'.' + []''''.';''
    +'sadf'.' % string transpose
    +% adjoint
    +{'asdf'}' + 1
    +('asdf')' + 1
    +['asdf']' + 1
    +'' var''' % empty string, var with >1 adjoints
    +[5]'*{5}'*('asd')'.'+(5)'*6'*asdf'*asdf'.' % many adjoints
    +A'*B + 1 % adjoint
    +A.'*B + 1 % transpose
    +A.'.'*B + 1 % double transpose
    +A'.' + 1 % adjoint, then transpose
    +A.'' % transpose, then adjoint
    +
    +% System command ______________________________________
    +!hostname
    +!cp * /tmp
    +
    +% Reserved keywords ___________________________________
    +function, persistent, global
    +endfunction
    +
    +switch, case, otherwise
    +endswitch
    +
    +if, else, elseif
    +endif
    +
    +try, end_try_catch
    +for, while, break, continue
    +endfor
    +
    +endwhile
    +return
    +function, FUNCTION, Function % case sensitive!
    +endfunction
    diff --git a/autotests/reference/learnelixir.exs.ref b/autotests/reference/learnelixir.exs.ref new file mode 100644 index 0000000..10a8b56 --- /dev/null +++ b/autotests/reference/learnelixir.exs.ref @@ -0,0 +1,397 @@ +# Original: https://learnxinyminutes.com/docs/elixir/
    +
    +# Single line comments start with a number symbol.
    +
    +# There's no multi-line comment,
    +# but you can stack multiple comments.
    +
    +# To use the elixir shell use the `iex` command.
    +# Compile your modules with the `elixirc` command.
    +
    +# Both should be in your path if you installed elixir correctly.
    +
    +## ---------------------------
    +## -- Basic types
    +## ---------------------------
    +
    +# There are numbers
    +3 # integer
    +0x1F # integer
    +3.0 # float
    +
    +# Atoms, that are literals, a constant with name. They start with `:`.
    +:hello # atom
    +
    +# Tuples that are stored contiguously in memory.
    +{1,2,3} # tuple
    +
    +# We can access a tuple element with the `elem` function:
    +elem({1, 2, 3}, 0) #=> 1
    +
    +# Lists that are implemented as linked lists.
    +[1,2,3] # list
    +
    +# We can access the head and tail of a list as follows:
    +[head | tail] = [1,2,3]
    +head #=> 1
    +tail #=> [2,3]
    +
    +# In elixir, just like in Erlang, the `=` denotes pattern matching and
    +# not an assignment.
    +#
    +# This means that the left-hand side (pattern) is matched against a
    +# right-hand side.
    +#
    +# This is how the above example of accessing the head and tail of a list works.
    +
    +# A pattern match will error when the sides don't match, in this example
    +# the tuples have different sizes.
    +# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
    +
    +# There are also binaries
    +<<1,2,3>> # binary
    +
    +# Strings and char lists
    +"hello" # string
    +'hello' # char list
    +
    +# Multi-line strings
    +"""
    +I'm a multi-line
    +string.
    +"""
    +#=> "I'm a multi-line\nstring.\n"
    +
    +# Strings are all encoded in UTF-8:
    +"héllò" #=> "héllò"
    +
    +# Strings are really just binaries, and char lists are just lists.
    +<<?a, ?b, ?c>> #=> "abc"
    +[?a, ?b, ?c] #=> 'abc'
    +
    +# `?a` in elixir returns the ASCII integer for the letter `a`
    +?a #=> 97
    +
    +# To concatenate lists use `++`, for binaries use `<>`
    +[1,2,3] ++ [4,5] #=> [1,2,3,4,5]
    +'hello ' ++ 'world' #=> 'hello world'
    +
    +<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
    +"hello " <> "world" #=> "hello world"
    +
    +# Ranges are represented as `start..end` (both inclusive)
    +1..10 #=> 1..10
    +lower..upper = 1..10 # Can use pattern matching on ranges as well
    +[lower, upper] #=> [1, 10]
    +
    +## ---------------------------
    +## -- Operators
    +## ---------------------------
    +
    +# Some math
    +1 + 1 #=> 2
    +10 - 5 #=> 5
    +5 * 2 #=> 10
    +10 / 2 #=> 5.0
    +
    +# In elixir the operator `/` always returns a float.
    +
    +# To do integer division use `div`
    +div(10, 2) #=> 5
    +
    +# To get the division remainder use `rem`
    +rem(10, 3) #=> 1
    +
    +# There are also boolean operators: `or`, `and` and `not`.
    +# These operators expect a boolean as their first argument.
    +true and true #=> true
    +false or true #=> true
    +# 1 and true #=> ** (ArgumentError) argument error
    +
    +# Elixir also provides `||`, `&&` and `!` which accept arguments of any type.
    +# All values except `false` and `nil` will evaluate to true.
    +1 || true #=> 1
    +false && 1 #=> false
    +nil && 20 #=> nil
    +!true #=> false
    +
    +# For comparisons we have: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` and `>`
    +1 == 1 #=> true
    +1 != 1 #=> false
    +1 < 2 #=> true
    +
    +# `===` and `!==` are more strict when comparing integers and floats:
    +1 == 1.0 #=> true
    +1 === 1.0 #=> false
    +
    +# We can also compare two different data types:
    +1 < :hello #=> true
    +
    +# The overall sorting order is defined below:
    +# number < atom < reference < functions < port < pid < tuple < list < bit string
    +
    +# To quote Joe Armstrong on this: "The actual order is not important,
    +# but that a total ordering is well defined is important."
    +
    +## ---------------------------
    +## -- Control Flow
    +## ---------------------------
    +
    +# `if` expression
    +if false do
    + "This will never be seen"
    +else
    + "This will"
    +end
    +
    +# There's also `unless`
    +unless true do
    + "This will never be seen"
    +else
    + "This will"
    +end
    +
    +# Remember pattern matching? Many control-flow structures in elixir rely on it.
    +
    +# `case` allows us to compare a value against many patterns:
    +case {:one, :two} do
    + {:four, :five} ->
    + "This won't match"
    + {:one, x} ->
    + "This will match and bind `x` to `:two`"
    + _ ->
    + "This will match any value"
    +end
    +
    +# It's common to bind the value to `_` if we don't need it.
    +# For example, if only the head of a list matters to us:
    +[head | _] = [1,2,3]
    +head #=> 1
    +
    +# For better readability we can do the following:
    +[head | _tail] = [:a, :b, :c]
    +head #=> :a
    +
    +# `cond` lets us check for many conditions at the same time.
    +# Use `cond` instead of nesting many `if` expressions.
    +cond do
    + 1 + 1 == 3 ->
    + "I will never be seen"
    + 2 * 5 == 12 ->
    + "Me neither"
    + 1 + 2 == 3 ->
    + "But I will"
    +end
    +
    +# It is common to set the last condition equal to `true`, which will always match.
    +cond do
    + 1 + 1 == 3 ->
    + "I will never be seen"
    + 2 * 5 == 12 ->
    + "Me neither"
    + true ->
    + "But I will (this is essentially an else)"
    +end
    +
    +# `try/catch` is used to catch values that are thrown, it also supports an
    +# `after` clause that is invoked whether or not a value is caught.
    +try do
    + throw(:hello)
    +catch
    + message -> "Got #{message}."
    +after
    + IO.puts("I'm the after clause.")
    +end
    +#=> I'm the after clause
    +# "Got :hello"
    +
    +## ---------------------------
    +## -- Modules and Functions
    +## ---------------------------
    +
    +# Anonymous functions (notice the dot)
    +square = fn(x) -> x * x end
    +square.(5) #=> 25
    +
    +# They also accept many clauses and guards.
    +# Guards let you fine tune pattern matching,
    +# they are indicated by the `when` keyword:
    +f = fn
    + x, y when x > 0 -> x + y
    + x, y -> x * y
    +end
    +
    +f.(1, 3) #=> 4
    +f.(-1, 3) #=> -3
    +
    +# Elixir also provides many built-in functions.
    +# These are available in the current scope.
    +is_number(10) #=> true
    +is_list("hello") #=> false
    +elem({1,2,3}, 0) #=> 1
    +
    +# You can group several functions into a module. Inside a module use `def`
    +# to define your functions.
    +defmodule Math do
    + def sum(a, b) do
    + a + b
    + end
    +
    + def square(x) do
    + x * x
    + end
    +end
    +
    +Math.sum(1, 2) #=> 3
    +Math.square(3) #=> 9
    +
    +# To compile our simple Math module save it as `math.ex` and use `elixirc`
    +# in your terminal: elixirc math.ex
    +
    +# Inside a module we can define functions with `def` and private functions with `defp`.
    +# A function defined with `def` is available to be invoked from other modules,
    +# a private function can only be invoked locally.
    +defmodule PrivateMath do
    + def sum(a, b) do
    + do_sum(a, b)
    + end
    +
    + defp do_sum(a, b) do
    + a + b
    + end
    +end
    +
    +PrivateMath.sum(1, 2) #=> 3
    +# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
    +
    +# Function declarations also support guards and multiple clauses:
    +defmodule Geometry do
    + def area({:rectangle, w, h}) do
    + w * h
    + end
    +
    + def area({:circle, r}) when is_number(r) do
    + 3.14 * r * r
    + end
    +end
    +
    +Geometry.area({:rectangle, 2, 3}) #=> 6
    +Geometry.area({:circle, 3}) #=> 28.25999999999999801048
    +# Geometry.area({:circle, "not_a_number"})
    +#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1
    +
    +# Due to immutability, recursion is a big part of elixir
    +defmodule Recursion do
    + def sum_list([head | tail], acc) do
    + sum_list(tail, acc + head)
    + end
    +
    + def sum_list([], acc) do
    + acc
    + end
    +end
    +
    +Recursion.sum_list([1,2,3], 0) #=> 6
    +
    +# Elixir modules support attributes, there are built-in attributes and you
    +# may also add custom ones.
    +defmodule MyMod do
    + @moduledoc """
    + This is a built-in attribute on a example module.
    + """
    +
    + @my_data 100 # This is a custom attribute.
    + IO.inspect(@my_data) #=> 100
    +end
    +
    +## ---------------------------
    +## -- Structs and Exceptions
    +## ---------------------------
    +
    +# Structs are extensions on top of maps that bring default values,
    +# compile-time guarantees and polymorphism into Elixir.
    +defmodule Person do
    + defstruct name: nil, age: 0, height: 0
    +end
    +
    +joe_info = %Person{ name: "Joe", age: 30, height: 180 }
    +#=> %Person{age: 30, height: 180, name: "Joe"}
    +
    +# Access the value of name
    +joe_info.name #=> "Joe"
    +
    +# Update the value of age
    +older_joe_info = %{ joe_info | age: 31 }
    +#=> %Person{age: 31, height: 180, name: "Joe"}
    +
    +# The `try` block with the `rescue` keyword is used to handle exceptions
    +try do
    + raise "some error"
    +rescue
    + RuntimeError -> "rescued a runtime error"
    + _error -> "this will rescue any error"
    +end
    +#=> "rescued a runtime error"
    +
    +# All exceptions have a message
    +try do
    + raise "some error"
    +rescue
    + x in [RuntimeError] ->
    + x.message
    +end
    +#=> "some error"
    +
    +## ---------------------------
    +## -- Concurrency
    +## ---------------------------
    +
    +# Elixir relies on the actor model for concurrency. All we need to write
    +# concurrent programs in elixir are three primitives: spawning processes,
    +# sending messages and receiving messages.
    +
    +# To start a new process we use the `spawn` function, which takes a function
    +# as argument.
    +f = fn -> 2 * 2 end #=> #Function
    +spawn(f) #=> #PID<0.40.0>
    +
    +# `spawn` returns a pid (process identifier), you can use this pid to send
    +# messages to the process. To do message passing we use the `send` operator.
    +# For all of this to be useful we need to be able to receive messages. This is
    +# achieved with the `receive` mechanism:
    +
    +# The `receive do` block is used to listen for messages and process
    +# them when they are received. A `receive do` block will only
    +# process one received message. In order to process multiple
    +# messages, a function with a `receive do` block must recursively
    +# call itself to get into the `receive do` block again.
    +
    +defmodule Geometry do
    + def area_loop do
    + receive do
    + {:rectangle, w, h} ->
    + IO.puts("Area = #{w * h}")
    + area_loop()
    + {:circle, r} ->
    + IO.puts("Area = #{3.14 * r * r}")
    + area_loop()
    + end
    + end
    +end
    +
    +# Compile the module and create a process that evaluates `area_loop` in the shell
    +pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
    +# Alternatively
    +pid = spawn(Geometry, :area_loop, [])
    +
    +# Send a message to `pid` that will match a pattern in the receive statement
    +send pid, {:rectangle, 2, 3}
    +#=> Area = 6
    +# {:rectangle,2,3}
    +
    +send pid, {:circle, 2}
    +#=> Area = 12.56000000000000049738
    +# {:circle,2}
    +
    +# The shell is also a process, you can use `self` to get the current pid
    +self() #=> #PID<0.27.0>
    diff --git a/autotests/reference/light52_muldiv.vhdl.ref b/autotests/reference/light52_muldiv.vhdl.ref new file mode 100644 index 0000000..2fec8c1 --- /dev/null +++ b/autotests/reference/light52_muldiv.vhdl.ref @@ -0,0 +1,239 @@ +--------------------------------------------------------------------------------
    +-- light52_muldiv.vhdl -- Simple multiplier/divider module.
    +--------------------------------------------------------------------------------
    +-- The 8051 mul and div instructions are both unsigned and operands are 8 bit.
    +--
    +-- This module implements the division as a sequential state machine which takes
    +-- 8 cycles to complete.
    +-- The multiplier can be implemented as sequential or as combinational, in which
    +-- case it will use a DSP block in those architectures that support it.
    +-- No attempt has been made to make this module generic or reusable.
    +--
    +-- If you want a combinational multiplier but don't want to waste a DSP block
    +-- in this module, you need to modify this file adding whatever synthesis
    +-- pragmas your tool of choice needs.
    +--
    +-- Note that unlike the division state machine, the combinational product logic
    +-- is always operating: when SEQUENTIAL_MULTIPLIER=true, prod_out equals
    +-- data_a * data_b with a latency of 1 clock cycle, and mul_ready is hardwired
    +-- to '1'.
    +--
    +-- FIXME explain division algorithm.
    +--------------------------------------------------------------------------------
    +-- GENERICS:
    +--
    +-- SEQUENTIAL_MULTIPLIER -- Sequential vs. combinational multiplier.
    +-- When true, a sequential implementation will be used for the multiplier,
    +-- which will usually save a lot of logic or a dedicated multiplier.
    +-- When false, a combinational registered multiplier will be used.
    +--
    +--------------------------------------------------------------------------------
    +-- INTERFACE SIGNALS:
    +--
    +-- clk : Clock, active rising edge.
    +-- reset : Synchronous reset. Clears only the control registers not
    +-- visible to the programmer -- not the output registers.
    +--
    +-- data_a : Numerator input, should be connected to the ACC register.
    +-- data_b : Denominator input, should be connected to the B register.
    +-- start : Assert for 1 cycle to start the division state machine
    +-- (and the product if SEQUENTIAL_MULTIPLIER=true);
    +--
    +-- prod_out : Product output, valid only when mul_ready='1'.
    +-- quot_out : Quotient output, valid only when div_ready='1'.
    +-- rem_out : Remainder output, valid only when div_ready='1'.
    +-- div_ov_out : Division overflow flag, valid only when div_ready='1'.
    +-- mul_ov_out : Product overflow flag, valid only when mul_ready='1'.
    +--
    +-- mul_ready : Asserted permanently if SEQUENTIAL_MULTIPLIER=false.
    +-- div_ready : Deasserted the cycle after start is asserted.
    +-- Asserted when the division has completed.
    +--
    +--------------------------------------------------------------------------------
    +-- Copyright (C) 2012 Jose A. Ruiz
    +--
    +-- This source file may be used and distributed without
    +-- restriction provided that this copyright statement is not
    +-- removed from the file and that any derivative work contains
    +-- the original copyright notice and the associated disclaimer.
    +--
    +-- This source file is free software; you can redistribute it
    +-- and/or modify it under the terms of the GNU Lesser General
    +-- Public License as published by the Free Software Foundation;
    +-- either version 2.1 of the License, or (at your option) any
    +-- later version.
    +--
    +-- This source 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 Lesser General Public License for more
    +-- details.
    +--
    +-- You should have received a copy of the GNU Lesser General
    +-- Public License along with this source; if not, download it
    +-- from http://www.opencores.org/lgpl.shtml
    +--------------------------------------------------------------------------------
    +
    +library ieee;
    +use ieee.std_logic_1164.all;
    +use ieee.numeric_std.all;
    +
    +use work.light52_pkg.all;
    +use work.light52_ucode_pkg.all;
    +
    +entity light52_muldiv is
    + generic (
    + SEQUENTIAL_MULTIPLIER : boolean := false
    + );
    + port(
    + clk : in std_logic;
    + reset : in std_logic;
    +
    + data_a : in t_byte;
    + data_b : in t_byte;
    + start : in std_logic;
    +
    + prod_out : out t_word;
    + quot_out : out t_byte;
    + rem_out : out t_byte;
    + div_ov_out : out std_logic;
    + mul_ov_out : out std_logic;
    +
    + mul_ready : out std_logic;
    + div_ready : out std_logic
    + );
    +end entity light52_muldiv;
    +
    +architecture sequential of light52_muldiv is
    +
    +signal bit_ctr : integer range 0 to 8;
    +
    +signal b_shift_reg : t_word;
    +
    +signal den_ge_256 : std_logic;
    +signal num_ge_den : std_logic;
    +signal sub_num : std_logic;
    +
    +signal denominator : t_byte;
    +signal rem_reg : t_byte;
    +signal quot_reg : t_byte;
    +signal prod_reg : t_word;
    +signal ready : std_logic;
    +
    +signal load_regs : std_logic;
    +
    +begin
    +
    +-- Control logic ---------------------------------------------------------------
    +
    +control_counter: process(clk)
    +begin
    + if clk'event and clk='1' then
    + if reset='1' then
    + bit_ctr <= 8;
    + else
    + if load_regs='1' then
    + bit_ctr <= 0;
    + elsif bit_ctr /= 8 then
    + bit_ctr <= bit_ctr + 1;
    + end if;
    + end if;
    + end if;
    +end process control_counter;
    +
    +-- Internal signal ready is asserted after 8 cycles.
    +-- The sequential multiplier will use this signal too, IF it takes 8 cycles.
    +
    +ready <= '1' when bit_ctr >= 8 else '0';
    +
    +
    +---- Divider logic -------------------------------------------------------------
    +
    +-- What we do is a simple base-2 'shift-and-subtract' algorithm that takes
    +-- 8 cycles to complete. We can get away with this because we deal with unsigned
    +-- numbers only.
    +
    +divider_registers: process(clk)
    +begin
    + if clk'event and clk='1' then
    + -- denominator shift register
    + if load_regs='1' then
    + b_shift_reg <= "0" & data_b & "0000000";
    + -- Division overflow can be determined upon loading B reg data.
    + -- OV will be raised only on div-by-zero.
    + if data_b=X"00" then
    + div_ov_out <= '1';
    + else
    + div_ov_out <= '0';
    + end if;
    + else
    + b_shift_reg <= "0" & b_shift_reg(b_shift_reg'high downto 1);
    + end if;
    +
    + -- numerator register
    + if load_regs='1' then
    + rem_reg <= data_a;
    + elsif bit_ctr/=8 and sub_num='1' then
    + rem_reg <= rem_reg - denominator;
    + end if;
    +
    + --- quotient register
    + if load_regs='1' then
    + quot_reg <= (others => '0');
    + elsif bit_ctr/=8 then
    + quot_reg <= quot_reg(quot_reg'high-1 downto 0) & sub_num;
    + end if;
    +
    + load_regs <= start;
    + end if;
    +end process divider_registers;
    +
    +denominator <= b_shift_reg(7 downto 0);
    +
    +-- The 16-bit comparison between b_shift_reg (denominator) and the zero-extended
    +-- rem_reg (numerator) can be simplified by splitting it in 2:
    +-- If the shifted denominator high byte is not zero, it is >=256...
    +den_ge_256 <= '1' when b_shift_reg(15 downto 8) /= X"00" else '0';
    +-- ...otherwise we need to compare the low bytes.
    +num_ge_den <= '1' when rem_reg >= denominator else '0';
    +sub_num <= '1' when den_ge_256='0' and num_ge_den='1' else '0';
    +
    +
    +quot_out <= quot_reg;
    +prod_out <= prod_reg;
    +rem_out <= rem_reg;
    +
    +div_ready <= ready;
    +
    +---- Multiplier logic ----------------------------------------------------------
    +
    +---- Combinational multiplier -----------------------------
    +multiplier_combinational: if not SEQUENTIAL_MULTIPLIER generate
    +
    +registered_combinational_multiplier:process(clk)
    +begin
    + if clk'event and clk='1' then
    + prod_reg <= data_a * data_b; -- t_byte is unsigned
    + end if;
    +end process registered_combinational_multiplier;
    +
    +-- The multiplier output is valid in the cycle after the operands are loaded,
    +-- so by the time MUL is executed it's already done.
    +mul_ready <= '1';
    +
    +mul_ov_out <= '1' when prod_reg(15 downto 8)/=X"00" else '0';
    +prod_out <= prod_reg;
    +
    +end generate multiplier_combinational;
    +
    +---- Sequential multiplier --------------------------------
    +multiplier_sequential: if SEQUENTIAL_MULTIPLIER generate
    +
    +assert false
    +report "Sequential multiplier implementation not done yet."&
    + " Use combinational implementation."
    +severity failure;
    +
    +end generate multiplier_sequential;
    +
    +end sequential;
    diff --git a/autotests/reference/light52_tb.vhdl.ref b/autotests/reference/light52_tb.vhdl.ref new file mode 100644 index 0000000..f47b919 --- /dev/null +++ b/autotests/reference/light52_tb.vhdl.ref @@ -0,0 +1,180 @@ +--------------------------------------------------------------------------------
    +-- light52_tb.vhdl --
    +--------------------------------------------------------------------------------
    +-- This test bench simulates the execution of some program (whose object code
    +-- is in package obj_code_pkg, in the form of a memory init constant) and logs
    +-- the execution to a text file called 'hw_sim_log.txt' (light52_tb_pkg.vhdl).
    +--
    +-- This test bench does no actual tests on the core. Instead, the simulation log
    +-- is meant to be matched against the simulation log produced by running the
    +-- same program on the software simulator B51 (also included with this project).
    +--
    +-- This will catch errors in the implementation of the CPU if the simulated
    +-- program has anough coverage -- the opcode tester is meant to cover all CPU
    +-- opcodes in many (not all) of their corner cases.
    +-- This scheme will not help in catching errors in the peripheral modules,
    +-- mainly because the current version of B51 does not simulate them.
    +--
    +--------------------------------------------------------------------------------
    +-- Copyright (C) 2012 Jose A. Ruiz
    +--
    +-- This source file may be used and distributed without
    +-- restriction provided that this copyright statement is not
    +-- removed from the file and that any derivative work contains
    +-- the original copyright notice and the associated disclaimer.
    +--
    +-- This source file is free software; you can redistribute it
    +-- and/or modify it under the terms of the GNU Lesser General
    +-- Public License as published by the Free Software Foundation;
    +-- either version 2.1 of the License, or (at your option) any
    +-- later version.
    +--
    +-- This source 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 Lesser General Public License for more
    +-- details.
    +--
    +-- You should have received a copy of the GNU Lesser General
    +-- Public License along with this source; if not, download it
    +-- from http://www.opencores.org/lgpl.shtml
    +--------------------------------------------------------------------------------
    +
    +
    +library ieee;
    +use ieee.std_logic_1164.all;
    +use ieee.std_logic_arith.all;
    +use ieee.std_logic_unsigned.all;
    +use std.textio.all;
    +
    +use work.light52_pkg.all;
    +use work.obj_code_pkg.all;
    +use work.light52_tb_pkg.all;
    +use work.txt_util.all;
    +
    +entity light52_tb is
    +generic (BCD : boolean := true);
    +end;
    +
    +
    +architecture testbench of light52_tb is
    +
    +--------------------------------------------------------------------------------
    +-- Simulation parameters
    +-- FIXME these should be in parameter package
    +
    +-- Simulated clock period is the same as the usual target, the DE-1 board
    +constant T : time := 20 ns; -- 50MHz
    +constant SIMULATION_LENGTH : integer := 400000;
    +
    +--------------------------------------------------------------------------------
    +-- MPU interface
    +
    +signal clk : std_logic := '0';
    +signal reset : std_logic := '1';
    +
    +signal p0_out : std_logic_vector(7 downto 0);
    +signal p1_out : std_logic_vector(7 downto 0);
    +signal p2_in : std_logic_vector(7 downto 0);
    +signal p3_in : std_logic_vector(7 downto 0);
    +
    +signal external_irq : std_logic_vector(7 downto 0);
    +
    +signal txd, rxd : std_logic;
    +
    +--------------------------------------------------------------------------------
    +-- Logging signals & simulation control
    +
    +-- Asserted high to disable the clock and terminate the simulation.
    +signal done : std_logic := '0';
    +
    +-- Log file
    +file log_file: TEXT open write_mode is "hw_sim_log.txt";
    +-- Console output log file
    +file con_file: TEXT open write_mode is "hw_sim_console_log.txt";
    +-- Info record needed by the logging fuctions
    +signal log_info : t_log_info;
    +
    +begin
    +
    +---- UUT instantiation ---------------------------------------------------------
    +
    +uut: entity work.light52_mcu
    + generic map (
    + IMPLEMENT_BCD_INSTRUCTIONS => BCD,
    + CODE_ROM_SIZE => work.obj_code_pkg.XCODE_SIZE,
    + XDATA_RAM_SIZE => work.obj_code_pkg.XDATA_SIZE,
    + OBJ_CODE => work.obj_code_pkg.object_code
    + )
    + port map (
    + clk => clk,
    + reset => reset,
    +
    + txd => txd,
    + rxd => rxd,
    +
    + external_irq => external_irq,
    +
    + p0_out => p0_out,
    + p1_out => p1_out,
    + p2_in => p2_in,
    + p3_in => p3_in
    + );
    +
    + -- UART is looped back in the test bench.
    + rxd <= txd;
    +
    + -- I/O ports are looped back and otherwise unused.
    + p2_in <= p0_out;
    + p3_in <= p1_out;
    +
    + -- External IRQ inputs are tied to port P1 for test purposes
    + external_irq <= p1_out;
    +
    + ---- Master clock: free running clock used as main module clock ------------
    + run_master_clock: process(done, clk)
    + begin
    + if done = '0' then
    + clk <= not clk after T/2;
    + end if;
    + end process run_master_clock;
    +
    +
    + ---- Main simulation process: reset MCU and wait for fixed period ----------
    +
    + drive_uut: process
    + begin
    + -- Leave reset asserted for a few clock cycles...
    + reset <= '1';
    + wait for T*4;
    + reset <= '0';
    +
    + -- ...and wait for the test to hit a termination condition (evaluated by
    + -- function log_cpu_activity) or to just timeout.
    + wait for T*SIMULATION_LENGTH;
    +
    + -- If we arrive here, the simulation timed out (termination conditions
    + -- trigger a failed assertion).
    + -- So print a timeout message and quit.
    + print("TB timed out.");
    + done <= '1';
    + wait;
    +
    + end process drive_uut;
    +
    +
    + -- Logging process: launch logger functions --------------------------------
    + log_execution: process
    + begin
    + -- Log cpu activity until done='1'.
    + log_cpu_activity(clk, reset, done, "/uut",
    + log_info, work.obj_code_pkg.XCODE_SIZE, "log_info",
    + X"0000", log_file, con_file);
    +
    + -- Flush console log file when finished.
    + log_flush_console(log_info, con_file);
    +
    + wait;
    + end process log_execution;
    +
    +end architecture testbench;
    diff --git a/autotests/reference/meson.build.ref b/autotests/reference/meson.build.ref new file mode 100644 index 0000000..ed97ead --- /dev/null +++ b/autotests/reference/meson.build.ref @@ -0,0 +1,21 @@ +# Unit test for Meson syntax highlight. License: LGPL
    +project('projectname', 'cpp')
    +
    +
    +
    +sourcefiles = ['a.cpp', 'b.cpp']
    +
    +foreach sourcefile : sourcefiles
    + message('this is a source file: ' + sourcefile)
    +endforeach
    +
    +x=1
    +if x+1 == 2 and x-1 == 0
    + message('I can work in this universe!')
    +endif
    +
    +subprojectresult = subproject('mysubprojectdir')
    +
    +mysharedlib = shared_library('libraryname', sourcefiles, linkwith: subprojectresult.staticlib)
    +
    +executable('myprogram', ['test.cpp'], linkwith: mysharedlib)
    diff --git a/autotests/reference/or1200_dc_fsm.v.ref b/autotests/reference/or1200_dc_fsm.v.ref new file mode 100644 index 0000000..04ab055 --- /dev/null +++ b/autotests/reference/or1200_dc_fsm.v.ref @@ -0,0 +1,563 @@ +//////////////////////////////////////////////////////////////////////
    +//// ////
    +//// OR1200's DC FSM ////
    +//// ////
    +//// This file is part of the OpenRISC 1200 project ////
    +//// http://opencores.org/project,or1k ////
    +//// ////
    +//// Description ////
    +//// Data cache state machine ////
    +//// ////
    +//// To Do: ////
    +//// - Test error during line read or write ////
    +//// ////
    +//// Author(s): ////
    +//// - Damjan Lampret, lampret@opencores.org ////
    +//// - Julius Baxter, julius@opencores.org ////
    +//// ////
    +//////////////////////////////////////////////////////////////////////
    +//// ////
    +//// Copyright (C) 2000, 2010 Authors and OPENCORES.ORG ////
    +//// ////
    +//// This source file may be used and distributed without ////
    +//// restriction provided that this copyright statement is not ////
    +//// removed from the file and that any derivative work contains ////
    +//// the original copyright notice and the associated disclaimer. ////
    +//// ////
    +//// This source file is free software; you can redistribute it ////
    +//// and/or modify it under the terms of the GNU Lesser General ////
    +//// Public License as published by the Free Software Foundation; ////
    +//// either version 2.1 of the License, or (at your option) any ////
    +//// later version. ////
    +//// ////
    +//// This source 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 Lesser General Public License for more ////
    +//// details. ////
    +//// ////
    +//// You should have received a copy of the GNU Lesser General ////
    +//// Public License along with this source; if not, download it ////
    +//// from http://www.opencores.org/lgpl.shtml ////
    +//// ////
    +//////////////////////////////////////////////////////////////////////
    +//
    +// $Log: or1200_dc_fsm.v,v $
    +// Revision 2.0 2010/06/30 11:00:00 ORSoC
    +// Minor update:
    +// Bugs fixed.
    +//
    +
    +// synopsys translate_off
    +`include "timescale.v"
    +// synopsys translate_on
    +`include "or1200_defines.v"
    +
    +`define OR1200_DCFSM_IDLE 3'd0
    +`define OR1200_DCFSM_CLOADSTORE 3'd1
    +`define OR1200_DCFSM_LOOP2 3'd2
    +`define OR1200_DCFSM_LOOP3 3'd3
    +`define OR1200_DCFSM_LOOP4 3'd4
    +`define OR1200_DCFSM_FLUSH5 3'd5
    +`define OR1200_DCFSM_INV6 3'd6
    +`define OR1200_DCFSM_WAITSPRCS7 3'd7
    +
    +
    +
    +//
    +// Data cache FSM for cache line of 16 bytes (4x singleword)
    +//
    +
    +module or1200_dc_fsm
    + (
    + // Clock and reset
    + clk, rst,
    +
    + // Internal i/f to top level DC
    + dc_en, dcqmem_cycstb_i, dcqmem_ci_i, dcqmem_we_i, dcqmem_sel_i,
    + tagcomp_miss, biudata_valid, biudata_error, lsu_addr,
    + dcram_we, biu_read, biu_write, biu_do_sel, dcram_di_sel, first_hit_ack,
    + first_miss_ack, first_miss_err, burst, tag_we, tag_valid, dc_addr,
    + dc_no_writethrough, tag_dirty, dirty, tag, tag_v, dc_block_flush,
    + dc_block_writeback, spr_dat_i, mtspr_dc_done, spr_cswe
    + );
    +
    + //
    + // I/O
    + //
    + input clk;
    + input rst;
    + input dc_en;
    + input dcqmem_cycstb_i;
    + input dcqmem_ci_i;
    + input dcqmem_we_i;
    + input [3:0] dcqmem_sel_i;
    + input tagcomp_miss;
    + input biudata_valid;
    + input biudata_error;
    + input [31:0] lsu_addr;
    + output [3:0] dcram_we;
    + output biu_read;
    + output biu_write;
    + output dcram_di_sel;
    + output biu_do_sel;
    + output first_hit_ack;
    + output first_miss_ack;
    + output first_miss_err;
    + output burst;
    + output tag_we;
    + output tag_valid;
    + output [31:0] dc_addr;
    + input dc_no_writethrough;
    + output tag_dirty;
    + input dirty;
    + input [`OR1200_DCTAG_W-2:0] tag;
    + input tag_v;
    + input dc_block_flush;
    + input dc_block_writeback;
    + input [31:0] spr_dat_i;
    + output mtspr_dc_done;
    + input spr_cswe;
    +
    +
    + //
    + // Internal wires and regs
    + //
    + reg [31:0] addr_r;
    + reg [2:0] state;
    + reg [`OR1200_DCLS-1:0] cnt;
    + reg hitmiss_eval;
    + reg store;
    + reg load;
    + reg cache_inhibit;
    + reg cache_miss;
    + reg cache_dirty_needs_writeback;
    + reg did_early_load_ack;
    + reg cache_spr_block_flush;
    + reg cache_spr_block_writeback;
    + reg cache_wb;
    + wire load_hit_ack;
    + wire load_miss_ack;
    + wire load_inhibit_ack;
    + wire store_hit_ack;
    + wire store_hit_writethrough_ack;
    + wire store_miss_writethrough_ack;
    + wire store_inhibit_ack;
    + wire store_miss_ack;
    + wire dcram_we_after_line_load;
    + wire dcram_we_during_line_load;
    + wire tagram_we_end_of_loadstore_loop;
    + wire tagram_dirty_bit_set;
    + wire writethrough;
    + wire cache_inhibit_with_eval;
    + wire [(`OR1200_DCLS-1)-2:0] next_addr_word;
    +
    + //
    + // Cache inhibit
    + //
    +
    + // Indicates whether cache is inhibited, during hitmiss_eval and after
    + assign cache_inhibit_with_eval = (hitmiss_eval & dcqmem_ci_i) |
    + (!hitmiss_eval & cache_inhibit);
    +
    + //
    + // Generate of DCRAM write enables
    + //
    +
    + // WE when non-writethrough, and had to wait for a line to load.
    + assign dcram_we_after_line_load = (state == `OR1200_DCFSM_LOOP3) &
    + dcqmem_we_i & !cache_dirty_needs_writeback &
    + !did_early_load_ack;
    +
    + // WE when receiving the data cache line
    + assign dcram_we_during_line_load = (state == `OR1200_DCFSM_LOOP2) & load &
    + biudata_valid;
    +
    + assign dcram_we =(// Write when hit - make sure it is only when hit - could
    + // maybe be doing write through and don't want to corrupt
    + // cache lines corresponding to the writethrough addr_r.
    + ({4{store_hit_ack | store_hit_writethrough_ack}} |
    + // Write after load of line
    + {4{dcram_we_after_line_load}}) &
    + dcqmem_sel_i ) |
    + // Write during load
    + {4{dcram_we_during_line_load}};
    +
    + //
    + // Tag RAM signals
    + //
    +
    + // WE to tag RAM when we finish loading a line.
    + assign tagram_we_end_of_loadstore_loop = ((state==`OR1200_DCFSM_LOOP2) &
    + biudata_valid & !(|cnt));
    +
    +`ifndef OR1200_DC_WRITETHROUGH
    + // No writethrough, so mark a line dirty whenever we write to it
    + assign tagram_dirty_bit_set = store_hit_ack | store_miss_ack;
    +
    + // Generate done signal for MTSPR instructions that may block execution
    + assign mtspr_dc_done = // Either DC disabled or we're not selected, or
    + !dc_en | !spr_cswe |
    + // Requested address not valid or writeback and !dirty
    + ((state==`OR1200_DCFSM_FLUSH5) &
    + (!tag_v | (cache_spr_block_writeback & !dirty))) |
    + // Writeback or flush is finished
    + ((state==`OR1200_DCFSM_LOOP3) &
    + (cache_spr_block_flush | cache_spr_block_writeback))|
    + // Invalidate of clean line finished
    + ((state==`OR1200_DCFSM_INV6) & cache_spr_block_flush);
    +
    +
    +`else
    + `ifdef OR1200_DC_NOSTACKWRITETHROUGH
    + // For dirty bit setting when having writethrough but not for stack
    + assign tagram_dirty_bit_set = store_hit_ack | store_miss_ack;
    + `else
    + // Lines will never be dirty if always writethrough
    + assign tagram_dirty_bit_set = 0;
    + `endif
    +
    + assign mtspr_dc_done = 1'b1;
    +
    +`endif
    +
    + assign tag_dirty = tagram_dirty_bit_set;
    +
    + // WE to tag RAM
    + assign tag_we = tagram_we_end_of_loadstore_loop |
    + tagram_dirty_bit_set | (state == `OR1200_DCFSM_INV6);
    +
    +
    + // Valid bit
    + // Set valid when end of line load, or marking dirty (is still valid)
    + assign tag_valid = ( tagram_we_end_of_loadstore_loop &
    + (load | (store & cache_spr_block_writeback)) ) |
    + tagram_dirty_bit_set;
    +
    +
    +
    + //
    + // BIU read and write
    + //
    +
    + assign biu_read = // Bus read request when:
    + // 1) Have a miss and not dirty or a load with inhibit
    + ((state == `OR1200_DCFSM_CLOADSTORE) &
    + (((hitmiss_eval & tagcomp_miss & !dirty &
    + !(store & writethrough)) |
    + (load & cache_inhibit_with_eval)) & dcqmem_cycstb_i)) |
    + // 2) In the loop and loading
    + ((state == `OR1200_DCFSM_LOOP2) & load);
    +
    +
    + assign biu_write = // Bus write request when:
    + // 1) Have a miss and dirty or store with inhibit
    + ((state == `OR1200_DCFSM_CLOADSTORE) &
    + (((hitmiss_eval & tagcomp_miss & dirty) |
    + (store & writethrough)) |
    + (store & cache_inhibit_with_eval)) & dcqmem_cycstb_i) |
    + // 2) In the loop and storing
    + ((state == `OR1200_DCFSM_LOOP2) & store);
    +
    + //
    + // Select for data to actual cache RAM (from LSU or BIU)
    + //
    + // Data to DCRAM - from external bus when loading (from IU when store)
    + assign dcram_di_sel = load;
    + // Data to external bus - always from IU except in case of bursting back
    + // the line to memory. (1 selects DCRAM)
    + assign biu_do_sel = (state == `OR1200_DCFSM_LOOP2) & store;
    +
    + // 3-bit wire for calculating next word of burst write, depending on
    + // line size of data cache.
    + assign next_addr_word = addr_r[`OR1200_DCLS-1:2] + 1;
    +
    + // Address to cache RAM (tag address also derived from this)
    + assign dc_addr =
    + // First check if we've got a block flush or WB op
    + ((dc_block_flush & !cache_spr_block_flush) |
    + (dc_block_writeback & !cache_spr_block_writeback)) ?
    + spr_dat_i :
    + (state==`OR1200_DCFSM_FLUSH5) ? addr_r:
    + // If no SPR action, then always put out address from LSU
    + (state==`OR1200_DCFSM_IDLE | hitmiss_eval) ? lsu_addr :
    + // Next, if in writeback loop, when ACKed must immediately
    + // output next word address (the RAM address takes a cycle
    + // to increment, but it's needed immediately for burst)
    + // otherwise, output our registered address.
    + (state==`OR1200_DCFSM_LOOP2 & biudata_valid & store ) ?
    + {addr_r[31:`OR1200_DCLS], next_addr_word, 2'b00} : addr_r;
    +
    +`ifdef OR1200_DC_WRITETHROUGH
    + `ifdef OR1200_DC_NOSTACKWRITETHROUGH
    + assign writethrough = !dc_no_writethrough;
    + `else
    + assign writethrough = 1;
    + `endif
    +`else
    + assign writethrough = 0;
    +`endif
    +
    + //
    + // ACK generation for LSU
    + //
    +
    + // ACK for when it's a cache hit
    + assign first_hit_ack = load_hit_ack | store_hit_ack |
    + store_hit_writethrough_ack |
    + store_miss_writethrough_ack |
    + store_inhibit_ack | store_miss_ack ;
    +
    + // ACK for when it's a cache miss - load only, is used in MUX for data back
    + // LSU straight off external data bus. In
    + // this was is also used for cache inhibit
    + // loads.
    + // first_hit_ack takes precedence over first_miss_ack
    + assign first_miss_ack = ~first_hit_ack & (load_miss_ack | load_inhibit_ack);
    +
    + // ACK cache hit on load
    + assign load_hit_ack = (state == `OR1200_DCFSM_CLOADSTORE) &
    + hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i & load;
    +
    + // ACK cache hit on store, no writethrough
    + assign store_hit_ack = (state == `OR1200_DCFSM_CLOADSTORE) &
    + hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i &
    + store & !writethrough;
    +
    + // ACK cache hit on store with writethrough
    + assign store_hit_writethrough_ack = (state == `OR1200_DCFSM_CLOADSTORE) &
    + !cache_miss & !cache_inhibit &
    + store & writethrough & biudata_valid;
    +
    + // ACK cache miss on store with writethrough
    + assign store_miss_writethrough_ack = (state == `OR1200_DCFSM_CLOADSTORE) &
    + cache_miss & !cache_inhibit &
    + store & writethrough & biudata_valid;
    +
    + // ACK store when cacheinhibit
    + assign store_inhibit_ack = (state == `OR1200_DCFSM_CLOADSTORE) &
    + store & cache_inhibit & biudata_valid;
    +
    +
    + // Get the _early_ ack on first ACK back from wishbone during load only
    + // Condition is that we're in the loop - that it's the first ack we get (can
    + // tell from value of cnt), and we're loading a line to read from it (not
    + // loading to write to it, in the case of a write without writethrough.)
    + assign load_miss_ack = ((state== `OR1200_DCFSM_LOOP2) & load &
    + (cnt==((1 << `OR1200_DCLS) - 4)) & biudata_valid &
    + !(dcqmem_we_i & !writethrough));
    +
    + assign load_inhibit_ack = (state == `OR1200_DCFSM_CLOADSTORE) &
    + load & cache_inhibit & biudata_valid;
    +
    + // This will be case of write through disabled, and had to load a line.
    + assign store_miss_ack = dcram_we_after_line_load;
    +
    + assign first_miss_err = biudata_error & dcqmem_cycstb_i;
    +
    + // Signal burst when in the load/store loop. We will always try to burst.
    + assign burst = (state == `OR1200_DCFSM_LOOP2);
    +
    + //
    + // Main DC FSM
    + //
    + always @(posedge clk or `OR1200_RST_EVENT rst) begin
    + if (rst == `OR1200_RST_VALUE) begin
    + state <= `OR1200_DCFSM_IDLE;
    + addr_r <= 32'd0;
    + hitmiss_eval <= 1'b0;
    + store <= 1'b0;
    + load <= 1'b0;
    + cnt <= `OR1200_DCLS'd0;
    + cache_miss <= 1'b0;
    + cache_dirty_needs_writeback <= 1'b0;
    + cache_inhibit <= 1'b0;
    + did_early_load_ack <= 1'b0;
    + cache_spr_block_flush <= 1'b0;
    + cache_spr_block_writeback <= 1'b0;
    + end
    + else
    + case (state) // synopsys parallel_case
    +
    + `OR1200_DCFSM_IDLE : begin
    + if (dc_en & (dc_block_flush | dc_block_writeback))
    + begin
    + cache_spr_block_flush <= dc_block_flush;
    + cache_spr_block_writeback <= dc_block_writeback;
    + hitmiss_eval <= 1'b1;
    + state <= `OR1200_DCFSM_FLUSH5;
    + addr_r <= spr_dat_i;
    + end
    + else if (dc_en & dcqmem_cycstb_i)
    + begin
    + state <= `OR1200_DCFSM_CLOADSTORE;
    + hitmiss_eval <= 1'b1;
    + store <= dcqmem_we_i;
    + load <= !dcqmem_we_i;
    + end
    +
    +
    + end // case: `OR1200_DCFSM_IDLE
    +
    + `OR1200_DCFSM_CLOADSTORE: begin
    + hitmiss_eval <= 1'b0;
    + if (hitmiss_eval) begin
    + cache_inhibit <= dcqmem_ci_i; // Check for cache inhibit here
    + cache_miss <= tagcomp_miss;
    + cache_dirty_needs_writeback <= dirty;
    + addr_r <= lsu_addr;
    + end
    +
    + // Evaluate any cache line load/stores in first cycle:
    + //
    + if (hitmiss_eval & tagcomp_miss & !(store & writethrough) &
    + !dcqmem_ci_i)
    + begin
    + // Miss - first either:
    + // 1) write back dirty line
    + if (dirty) begin
    + // Address for writeback
    + addr_r <= {tag, lsu_addr[`OR1200_DCINDXH:2],2'd0};
    + load <= 1'b0;
    + store <= 1'b1;
    +`ifdef OR1200_VERBOSE
    + $display("%t: dcache miss and dirty", $time);
    +`endif
    + end
    + // 2) load requested line
    + else begin
    + addr_r <= lsu_addr;
    + load <= 1'b1;
    + store <= 1'b0;
    + end // else: !if(dirty)
    + state <= `OR1200_DCFSM_LOOP2;
    + // Set the counter for the burst accesses
    + cnt <= ((1 << `OR1200_DCLS) - 4);
    + end
    + else if (// Strobe goes low
    + !dcqmem_cycstb_i |
    + // Cycle finishes
    + (!hitmiss_eval & (biudata_valid | biudata_error)) |
    + // Cache hit in first cycle....
    + (hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i &
    + // .. and you're not doing a writethrough store..
    + !(store & writethrough))) begin
    + state <= `OR1200_DCFSM_IDLE;
    + load <= 1'b0;
    + store <= 1'b0;
    + cache_inhibit <= 1'b0;
    + cache_dirty_needs_writeback <= 1'b0;
    + end
    + end // case: `OR1200_DCFSM_CLOADSTORE
    +
    + `OR1200_DCFSM_LOOP2 : begin // loop/abort
    + if (!dc_en| biudata_error) begin
    + state <= `OR1200_DCFSM_IDLE;
    + load <= 1'b0;
    + store <= 1'b0;
    + cnt <= `OR1200_DCLS'd0;
    + end
    + if (biudata_valid & (|cnt)) begin
    + cnt <= cnt - 4;
    + addr_r[`OR1200_DCLS-1:2] <= addr_r[`OR1200_DCLS-1:2] + 1;
    + end
    + else if (biudata_valid & !(|cnt)) begin
    + state <= `OR1200_DCFSM_LOOP3;
    + addr_r <= lsu_addr;
    + load <= 1'b0;
    + store <= 1'b0;
    + end
    +
    + // Track if we did an early ack during a load
    + if (load_miss_ack)
    + did_early_load_ack <= 1'b1;
    +
    +
    + end // case: `OR1200_DCFSM_LOOP2
    +
    + `OR1200_DCFSM_LOOP3: begin // figure out next step
    + if (cache_dirty_needs_writeback) begin
    + // Just did store of the dirty line so now load new one
    + load <= 1'b1;
    + // Set the counter for the burst accesses
    + cnt <= ((1 << `OR1200_DCLS) - 4);
    + // Address of line to be loaded
    + addr_r <= lsu_addr;
    + cache_dirty_needs_writeback <= 1'b0;
    + state <= `OR1200_DCFSM_LOOP2;
    + end // if (cache_dirty_needs_writeback)
    + else if (cache_spr_block_flush | cache_spr_block_writeback) begin
    + // Just wrote back the line to memory, we're finished.
    + cache_spr_block_flush <= 1'b0;
    + cache_spr_block_writeback <= 1'b0;
    + state <= `OR1200_DCFSM_WAITSPRCS7;
    + end
    + else begin
    + // Just loaded a new line, finish up
    + did_early_load_ack <= 1'b0;
    + state <= `OR1200_DCFSM_LOOP4;
    + end
    + end // case: `OR1200_DCFSM_LOOP3
    +
    + `OR1200_DCFSM_LOOP4: begin
    + state <= `OR1200_DCFSM_IDLE;
    + end
    +
    + `OR1200_DCFSM_FLUSH5: begin
    + hitmiss_eval <= 1'b0;
    + if (hitmiss_eval & !tag_v)
    + begin
    + // Not even cached, just ignore
    + cache_spr_block_flush <= 1'b0;
    + cache_spr_block_writeback <= 1'b0;
    + state <= `OR1200_DCFSM_WAITSPRCS7;
    + end
    + else if (hitmiss_eval & tag_v)
    + begin
    + // Tag is valid - what do we do?
    + if ((cache_spr_block_flush | cache_spr_block_writeback) &
    + dirty) begin
    + // Need to writeback
    + // Address for writeback (spr_dat_i has already changed so
    + // use line number from addr_r)
    + addr_r <= {tag, addr_r[`OR1200_DCINDXH:2],2'd0};
    + load <= 1'b0;
    + store <= 1'b1;
    +`ifdef OR1200_VERBOSE
    + $display("%t: block flush: dirty block", $time);
    +`endif
    + state <= `OR1200_DCFSM_LOOP2;
    + // Set the counter for the burst accesses
    + cnt <= ((1 << `OR1200_DCLS) - 4);
    + end
    + else if (cache_spr_block_flush & !dirty)
    + begin
    + // Line not dirty, just need to invalidate
    + state <= `OR1200_DCFSM_INV6;
    + end // else: !if(dirty)
    + else if (cache_spr_block_writeback & !dirty)
    + begin
    + // Nothing to do - line is valid but not dirty
    + cache_spr_block_writeback <= 1'b0;
    + state <= `OR1200_DCFSM_WAITSPRCS7;
    + end
    + end // if (hitmiss_eval & tag_v)
    + end
    + `OR1200_DCFSM_INV6: begin
    + cache_spr_block_flush <= 1'b0;
    + // Wait until SPR CS goes low before going back to idle
    + if (!spr_cswe)
    + state <= `OR1200_DCFSM_IDLE;
    + end
    + `OR1200_DCFSM_WAITSPRCS7: begin
    + // Wait until SPR CS goes low before going back to idle
    + if (!spr_cswe)
    + state <= `OR1200_DCFSM_IDLE;
    + end
    +
    + endcase // case (state)
    +
    + end // always @ (posedge clk or `OR1200_RST_EVENT rst)
    +
    +
    +endmodule
    diff --git a/autotests/reference/or1200_du.v.ref b/autotests/reference/or1200_du.v.ref new file mode 100644 index 0000000..2413c40 --- /dev/null +++ b/autotests/reference/or1200_du.v.ref @@ -0,0 +1,1803 @@ +//////////////////////////////////////////////////////////////////////
    +//// ////
    +//// OR1200's Debug Unit ////
    +//// ////
    +//// This file is part of the OpenRISC 1200 project ////
    +//// http://www.opencores.org/project,or1k ////
    +//// ////
    +//// Description ////
    +//// Basic OR1200 debug unit. ////
    +//// ////
    +//// To Do: ////
    +//// - make it smaller and faster ////
    +//// ////
    +//// Author(s): ////
    +//// - Damjan Lampret, lampret@opencores.org ////
    +//// ////
    +//////////////////////////////////////////////////////////////////////
    +//// ////
    +//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
    +//// ////
    +//// This source file may be used and distributed without ////
    +//// restriction provided that this copyright statement is not ////
    +//// removed from the file and that any derivative work contains ////
    +//// the original copyright notice and the associated disclaimer. ////
    +//// ////
    +//// This source file is free software; you can redistribute it ////
    +//// and/or modify it under the terms of the GNU Lesser General ////
    +//// Public License as published by the Free Software Foundation; ////
    +//// either version 2.1 of the License, or (at your option) any ////
    +//// later version. ////
    +//// ////
    +//// This source 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 Lesser General Public License for more ////
    +//// details. ////
    +//// ////
    +//// You should have received a copy of the GNU Lesser General ////
    +//// Public License along with this source; if not, download it ////
    +//// from http://www.opencores.org/lgpl.shtml ////
    +//// ////
    +//////////////////////////////////////////////////////////////////////
    +//
    +//
    +// $Log: or1200_du.v,v $
    +// Revision 2.0 2010/06/30 11:00:00 ORSoC
    +// Minor update:
    +// Bugs fixed.
    +
    +// synopsys translate_off
    +`include "timescale.v"
    +// synopsys translate_on
    +`include "or1200_defines.v"
    +
    +//
    +// Debug unit
    +//
    +
    +module or1200_du(
    + // RISC Internal Interface
    + clk, rst,
    + dcpu_cycstb_i, dcpu_we_i, dcpu_adr_i, dcpu_dat_lsu,
    + dcpu_dat_dc, icpu_cycstb_i,
    + ex_freeze, branch_op, ex_insn, id_pc,
    + spr_dat_npc, rf_dataw,
    + du_dsr, du_dmr1, du_stall, du_addr, du_dat_i, du_dat_o,
    + du_read, du_write, du_except_stop, du_hwbkpt, du_flush_pipe,
    + spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
    +
    + // External Debug Interface
    + dbg_stall_i, dbg_ewt_i, dbg_lss_o, dbg_is_o, dbg_wp_o, dbg_bp_o,
    + dbg_stb_i, dbg_we_i, dbg_adr_i, dbg_dat_i, dbg_dat_o, dbg_ack_o
    +);
    +
    +parameter dw = `OR1200_OPERAND_WIDTH;
    +parameter aw = `OR1200_OPERAND_WIDTH;
    +
    +//
    +// I/O
    +//
    +
    +//
    +// RISC Internal Interface
    +//
    +input clk; // Clock
    +input rst; // Reset
    +input dcpu_cycstb_i; // LSU status
    +input dcpu_we_i; // LSU status
    +input [31:0] dcpu_adr_i; // LSU addr
    +input [31:0] dcpu_dat_lsu; // LSU store data
    +input [31:0] dcpu_dat_dc; // LSU load data
    +input [`OR1200_FETCHOP_WIDTH-1:0] icpu_cycstb_i; // IFETCH unit status
    +input ex_freeze; // EX stage freeze
    +input [`OR1200_BRANCHOP_WIDTH-1:0] branch_op; // Branch op
    +input [dw-1:0] ex_insn; // EX insn
    +input [31:0] id_pc; // insn fetch EA
    +input [31:0] spr_dat_npc; // Next PC (for trace)
    +input [31:0] rf_dataw; // ALU result (for trace)
    +output [`OR1200_DU_DSR_WIDTH-1:0] du_dsr; // DSR
    +output [24: 0] du_dmr1;
    +output du_stall; // Debug Unit Stall
    +output [aw-1:0] du_addr; // Debug Unit Address
    +input [dw-1:0] du_dat_i; // Debug Unit Data In
    +output [dw-1:0] du_dat_o; // Debug Unit Data Out
    +output du_read; // Debug Unit Read Enable
    +output du_write; // Debug Unit Write Enable
    +input [13:0] du_except_stop; // Exception masked by DSR
    +output du_hwbkpt; // Cause trap exception (HW Breakpoints)
    +output du_flush_pipe; // Cause pipeline flush and pc<-npc
    +input spr_cs; // SPR Chip Select
    +input spr_write; // SPR Read/Write
    +input [aw-1:0] spr_addr; // SPR Address
    +input [dw-1:0] spr_dat_i; // SPR Data Input
    +output [dw-1:0] spr_dat_o; // SPR Data Output
    +
    +//
    +// External Debug Interface
    +//
    +input dbg_stall_i; // External Stall Input
    +input dbg_ewt_i; // External Watchpoint Trigger Input
    +output [3:0] dbg_lss_o; // External Load/Store Unit Status
    +output [1:0] dbg_is_o; // External Insn Fetch Status
    +output [10:0] dbg_wp_o; // Watchpoints Outputs
    +output dbg_bp_o; // Breakpoint Output
    +input dbg_stb_i; // External Address/Data Strobe
    +input dbg_we_i; // External Write Enable
    +input [aw-1:0] dbg_adr_i; // External Address Input
    +input [dw-1:0] dbg_dat_i; // External Data Input
    +output [dw-1:0] dbg_dat_o; // External Data Output
    +output dbg_ack_o; // External Data Acknowledge (not WB compatible)
    +reg [dw-1:0] dbg_dat_o; // External Data Output
    +reg dbg_ack_o; // External Data Acknowledge (not WB compatible)
    +
    +
    +//
    +// Some connections go directly from the CPU through DU to Debug I/F
    +//
    +`ifdef OR1200_DU_STATUS_UNIMPLEMENTED
    +assign dbg_lss_o = 4'b0000;
    +
    +reg [1:0] dbg_is_o;
    +//
    +// Show insn activity (temp, must be removed)
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dbg_is_o <= 2'b00;
    + else if (!ex_freeze & ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]))
    + dbg_is_o <= ~dbg_is_o;
    +`ifdef UNUSED
    +assign dbg_is_o = 2'b00;
    +`endif
    +`else
    +assign dbg_lss_o = dcpu_cycstb_i ? {dcpu_we_i, 3'b000} : 4'b0000;
    +assign dbg_is_o = {1'b0, icpu_cycstb_i};
    +`endif
    +assign dbg_wp_o = 11'b000_0000_0000;
    +
    +//
    +// Some connections go directly from Debug I/F through DU to the CPU
    +//
    +assign du_stall = dbg_stall_i;
    +assign du_addr = dbg_adr_i;
    +assign du_dat_o = dbg_dat_i;
    +assign du_read = dbg_stb_i && !dbg_we_i;
    +assign du_write = dbg_stb_i && dbg_we_i;
    +
    +//
    +// After a sw breakpoint, the replaced instruction need to be executed.
    +// We flush the entire pipeline and set the pc to the current address
    +// to execute the restored address.
    +//
    +
    +reg du_flush_pipe_r;
    +reg dbg_stall_i_r;
    +
    +assign du_flush_pipe = du_flush_pipe_r;
    +
    +//
    +// Register du_flush_pipe
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst) begin
    + if (rst == `OR1200_RST_VALUE) begin
    + du_flush_pipe_r <= 1'b0;
    + end
    + else begin
    + du_flush_pipe_r <= (dbg_stall_i_r && !dbg_stall_i && |du_except_stop);
    + end
    +end
    +
    +//
    +// Detect dbg_stall falling edge
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst) begin
    + if (rst == `OR1200_RST_VALUE) begin
    + dbg_stall_i_r <= 1'b0;
    + end
    + else begin
    + dbg_stall_i_r <= dbg_stall_i;
    + end
    +end
    +
    +reg dbg_ack;
    +//
    +// Generate acknowledge -- just delay stb signal
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst) begin
    + if (rst == `OR1200_RST_VALUE) begin
    + dbg_ack <= 1'b0;
    + dbg_ack_o <= 1'b0;
    + end
    + else begin
    + dbg_ack <= dbg_stb_i; // valid when du_dat_i
    + dbg_ack_o <= dbg_ack & dbg_stb_i; // valid when dbg_dat_o
    + end
    +end
    +
    +//
    +// Register data output
    +//
    +always @(posedge clk)
    + dbg_dat_o <= du_dat_i;
    +
    +`ifdef OR1200_DU_IMPLEMENTED
    +
    +//
    +// Debug Mode Register 1
    +//
    +`ifdef OR1200_DU_DMR1
    +reg [24:0] dmr1; // DMR1 implemented
    +`else
    +wire [24:0] dmr1; // DMR1 not implemented
    +`endif
    +assign du_dmr1 = dmr1;
    +
    +//
    +// Debug Mode Register 2
    +//
    +`ifdef OR1200_DU_DMR2
    +reg [23:0] dmr2; // DMR2 implemented
    +`else
    +wire [23:0] dmr2; // DMR2 not implemented
    +`endif
    +
    +//
    +// Debug Stop Register
    +//
    +`ifdef OR1200_DU_DSR
    +reg [`OR1200_DU_DSR_WIDTH-1:0] dsr; // DSR implemented
    +`else
    +wire [`OR1200_DU_DSR_WIDTH-1:0] dsr; // DSR not implemented
    +`endif
    +
    +//
    +// Debug Reason Register
    +//
    +`ifdef OR1200_DU_DRR
    +reg [13:0] drr; // DRR implemented
    +`else
    +wire [13:0] drr; // DRR not implemented
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR0
    +reg [31:0] dvr0;
    +`else
    +wire [31:0] dvr0;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR1
    +reg [31:0] dvr1;
    +`else
    +wire [31:0] dvr1;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR2
    +reg [31:0] dvr2;
    +`else
    +wire [31:0] dvr2;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR3
    +reg [31:0] dvr3;
    +`else
    +wire [31:0] dvr3;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR4
    +reg [31:0] dvr4;
    +`else
    +wire [31:0] dvr4;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR5
    +reg [31:0] dvr5;
    +`else
    +wire [31:0] dvr5;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR6
    +reg [31:0] dvr6;
    +`else
    +wire [31:0] dvr6;
    +`endif
    +
    +//
    +// Debug Value Register N
    +//
    +`ifdef OR1200_DU_DVR7
    +reg [31:0] dvr7;
    +`else
    +wire [31:0] dvr7;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR0
    +reg [7:0] dcr0;
    +`else
    +wire [7:0] dcr0;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR1
    +reg [7:0] dcr1;
    +`else
    +wire [7:0] dcr1;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR2
    +reg [7:0] dcr2;
    +`else
    +wire [7:0] dcr2;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR3
    +reg [7:0] dcr3;
    +`else
    +wire [7:0] dcr3;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR4
    +reg [7:0] dcr4;
    +`else
    +wire [7:0] dcr4;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR5
    +reg [7:0] dcr5;
    +`else
    +wire [7:0] dcr5;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR6
    +reg [7:0] dcr6;
    +`else
    +wire [7:0] dcr6;
    +`endif
    +
    +//
    +// Debug Control Register N
    +//
    +`ifdef OR1200_DU_DCR7
    +reg [7:0] dcr7;
    +`else
    +wire [7:0] dcr7;
    +`endif
    +
    +//
    +// Debug Watchpoint Counter Register 0
    +//
    +`ifdef OR1200_DU_DWCR0
    +reg [31:0] dwcr0;
    +`else
    +wire [31:0] dwcr0;
    +`endif
    +
    +//
    +// Debug Watchpoint Counter Register 1
    +//
    +`ifdef OR1200_DU_DWCR1
    +reg [31:0] dwcr1;
    +`else
    +wire [31:0] dwcr1;
    +`endif
    +
    +//
    +// Internal wires
    +//
    +wire dmr1_sel; // DMR1 select
    +wire dmr2_sel; // DMR2 select
    +wire dsr_sel; // DSR select
    +wire drr_sel; // DRR select
    +wire dvr0_sel,
    + dvr1_sel,
    + dvr2_sel,
    + dvr3_sel,
    + dvr4_sel,
    + dvr5_sel,
    + dvr6_sel,
    + dvr7_sel; // DVR selects
    +wire dcr0_sel,
    + dcr1_sel,
    + dcr2_sel,
    + dcr3_sel,
    + dcr4_sel,
    + dcr5_sel,
    + dcr6_sel,
    + dcr7_sel; // DCR selects
    +wire dwcr0_sel,
    + dwcr1_sel; // DWCR selects
    +reg dbg_bp_r;
    +reg ex_freeze_q;
    +`ifdef OR1200_DU_HWBKPTS
    +reg [31:0] match_cond0_ct;
    +reg [31:0] match_cond1_ct;
    +reg [31:0] match_cond2_ct;
    +reg [31:0] match_cond3_ct;
    +reg [31:0] match_cond4_ct;
    +reg [31:0] match_cond5_ct;
    +reg [31:0] match_cond6_ct;
    +reg [31:0] match_cond7_ct;
    +reg match_cond0_stb;
    +reg match_cond1_stb;
    +reg match_cond2_stb;
    +reg match_cond3_stb;
    +reg match_cond4_stb;
    +reg match_cond5_stb;
    +reg match_cond6_stb;
    +reg match_cond7_stb;
    +reg match0;
    +reg match1;
    +reg match2;
    +reg match3;
    +reg match4;
    +reg match5;
    +reg match6;
    +reg match7;
    +reg wpcntr0_match;
    +reg wpcntr1_match;
    +reg incr_wpcntr0;
    +reg incr_wpcntr1;
    +reg [10:0] wp;
    +`endif
    +wire du_hwbkpt;
    +reg du_hwbkpt_hold;
    +`ifdef OR1200_DU_READREGS
    +reg [31:0] spr_dat_o;
    +`endif
    +reg [13:0] except_stop; // Exceptions that stop because of DSR
    +`ifdef OR1200_DU_TB_IMPLEMENTED
    +wire tb_enw;
    +reg [7:0] tb_wadr;
    +reg [31:0] tb_timstmp;
    +`endif
    +wire [31:0] tbia_dat_o;
    +wire [31:0] tbim_dat_o;
    +wire [31:0] tbar_dat_o;
    +wire [31:0] tbts_dat_o;
    +
    +//
    +// DU registers address decoder
    +//
    +`ifdef OR1200_DU_DMR1
    +assign dmr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DMR1));
    +`endif
    +`ifdef OR1200_DU_DMR2
    +assign dmr2_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DMR2));
    +`endif
    +`ifdef OR1200_DU_DSR
    +assign dsr_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DSR));
    +`endif
    +`ifdef OR1200_DU_DRR
    +assign drr_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DRR));
    +`endif
    +`ifdef OR1200_DU_DVR0
    +assign dvr0_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR0));
    +`endif
    +`ifdef OR1200_DU_DVR1
    +assign dvr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR1));
    +`endif
    +`ifdef OR1200_DU_DVR2
    +assign dvr2_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR2));
    +`endif
    +`ifdef OR1200_DU_DVR3
    +assign dvr3_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR3));
    +`endif
    +`ifdef OR1200_DU_DVR4
    +assign dvr4_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR4));
    +`endif
    +`ifdef OR1200_DU_DVR5
    +assign dvr5_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR5));
    +`endif
    +`ifdef OR1200_DU_DVR6
    +assign dvr6_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR6));
    +`endif
    +`ifdef OR1200_DU_DVR7
    +assign dvr7_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DVR7));
    +`endif
    +`ifdef OR1200_DU_DCR0
    +assign dcr0_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR0));
    +`endif
    +`ifdef OR1200_DU_DCR1
    +assign dcr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR1));
    +`endif
    +`ifdef OR1200_DU_DCR2
    +assign dcr2_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR2));
    +`endif
    +`ifdef OR1200_DU_DCR3
    +assign dcr3_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR3));
    +`endif
    +`ifdef OR1200_DU_DCR4
    +assign dcr4_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR4));
    +`endif
    +`ifdef OR1200_DU_DCR5
    +assign dcr5_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR5));
    +`endif
    +`ifdef OR1200_DU_DCR6
    +assign dcr6_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR6));
    +`endif
    +`ifdef OR1200_DU_DCR7
    +assign dcr7_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DCR7));
    +`endif
    +`ifdef OR1200_DU_DWCR0
    +assign dwcr0_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DWCR0));
    +`endif
    +`ifdef OR1200_DU_DWCR1
    +assign dwcr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DWCR1));
    +`endif
    +
    +// Track previous ex_freeze to detect when signals are updated
    +always @(posedge clk)
    + ex_freeze_q <= ex_freeze;
    +
    +//
    +// Decode started exception
    +//
    +// du_except_stop comes from or1200_except
    +//
    +always @(du_except_stop or ex_freeze_q) begin
    + except_stop = 14'b00_0000_0000_0000;
    + casez (du_except_stop)
    + 14'b1?_????_????_????:
    + except_stop[`OR1200_DU_DRR_TTE] = 1'b1;
    + 14'b01_????_????_????: begin
    + except_stop[`OR1200_DU_DRR_IE] = 1'b1;
    + end
    + 14'b00_1???_????_????: begin
    + except_stop[`OR1200_DU_DRR_IME] = 1'b1;
    + end
    + 14'b00_01??_????_????:
    + except_stop[`OR1200_DU_DRR_IPFE] = 1'b1;
    + 14'b00_001?_????_????: begin
    + except_stop[`OR1200_DU_DRR_BUSEE] = 1'b1;
    + end
    + 14'b00_0001_????_????:
    + except_stop[`OR1200_DU_DRR_IIE] = 1'b1;
    + 14'b00_0000_1???_????: begin
    + except_stop[`OR1200_DU_DRR_AE] = 1'b1;
    + end
    + 14'b00_0000_01??_????: begin
    + except_stop[`OR1200_DU_DRR_DME] = 1'b1;
    + end
    + 14'b00_0000_001?_????:
    + except_stop[`OR1200_DU_DRR_DPFE] = 1'b1;
    + 14'b00_0000_0001_????:
    + except_stop[`OR1200_DU_DRR_BUSEE] = 1'b1;
    + 14'b00_0000_0000_1???: begin
    + except_stop[`OR1200_DU_DRR_RE] = 1'b1;
    + end
    + 14'b00_0000_0000_01??: begin
    + except_stop[`OR1200_DU_DRR_TE] = 1'b1 & ~ex_freeze_q;
    + end
    + 14'b00_0000_0000_001?: begin
    + except_stop[`OR1200_DU_DRR_FPE] = 1'b1;
    + end
    + 14'b00_0000_0000_0001:
    + except_stop[`OR1200_DU_DRR_SCE] = 1'b1 & ~ex_freeze_q;
    + default:
    + except_stop = 14'b00_0000_0000_0000;
    + endcase // casez (du_except_stop)
    +end
    +
    +//
    +// dbg_bp_o is registered
    +//
    +assign dbg_bp_o = dbg_bp_r;
    +
    +//
    +// Breakpoint activation register
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dbg_bp_r <= 1'b0;
    + else if (!ex_freeze)
    + dbg_bp_r <= |except_stop
    +`ifdef OR1200_DU_DMR1_ST
    + | ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]) & dmr1[`OR1200_DU_DMR1_ST]
    +`endif
    +`ifdef OR1200_DU_DMR1_BT
    + | (branch_op != `OR1200_BRANCHOP_NOP) & (branch_op != `OR1200_BRANCHOP_RFE) & dmr1[`OR1200_DU_DMR1_BT]
    +`endif
    + ;
    + else
    + dbg_bp_r <= |except_stop;
    +
    +//
    +// Write to DMR1
    +//
    +`ifdef OR1200_DU_DMR1
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dmr1 <= 25'h000_0000;
    + else if (dmr1_sel && spr_write)
    +`ifdef OR1200_DU_HWBKPTS
    + dmr1 <= spr_dat_i[24:0];
    +`else
    + dmr1 <= {1'b0, spr_dat_i[23:22], 22'h00_0000};
    +`endif
    +`else
    +assign dmr1 = 25'h000_0000;
    +`endif
    +
    +//
    +// Write to DMR2
    +//
    +`ifdef OR1200_DU_DMR2
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dmr2 <= 24'h00_0000;
    + else if (dmr2_sel && spr_write)
    + dmr2 <= spr_dat_i[23:0];
    +`else
    +assign dmr2 = 24'h00_0000;
    +`endif
    +
    +//
    +// Write to DSR
    +//
    +`ifdef OR1200_DU_DSR
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dsr <= {`OR1200_DU_DSR_WIDTH{1'b0}};
    + else if (dsr_sel && spr_write)
    + dsr <= spr_dat_i[`OR1200_DU_DSR_WIDTH-1:0];
    +`else
    +assign dsr = {`OR1200_DU_DSR_WIDTH{1'b0}};
    +`endif
    +
    +//
    +// Write to DRR
    +//
    +`ifdef OR1200_DU_DRR
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + drr <= 14'b0;
    + else if (drr_sel && spr_write)
    + drr <= spr_dat_i[13:0];
    + else
    + drr <= drr | except_stop;
    +`else
    +assign drr = 14'b0;
    +`endif
    +
    +//
    +// Write to DVR0
    +//
    +`ifdef OR1200_DU_DVR0
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dvr0 <= 32'h0000_0000;
    + else if (dvr0_sel && spr_write)
    + dvr0 <= spr_dat_i[31:0];
    +`else
    +assign dvr0 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR1
    +//
    +`ifdef OR1200_DU_DVR1
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dvr1 <= 32'h0000_0000;
    + else if (dvr1_sel && spr_write)
    + dvr1 <= spr_dat_i[31:0];
    +`else
    +assign dvr1 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR2
    +//
    +`ifdef OR1200_DU_DVR2
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dvr2 <= 32'h0000_0000;
    + else if (dvr2_sel && spr_write)
    + dvr2 <= spr_dat_i[31:0];
    +`else
    +assign dvr2 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR3
    +//
    +`ifdef OR1200_DU_DVR3
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dvr3 <= 32'h0000_0000;
    + else if (dvr3_sel && spr_write)
    + dvr3 <= spr_dat_i[31:0];
    +`else
    +assign dvr3 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR4
    +//
    +`ifdef OR1200_DU_DVR4
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dvr4 <= 32'h0000_0000;
    + else if (dvr4_sel && spr_write)
    + dvr4 <= spr_dat_i[31:0];
    +`else
    +assign dvr4 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR5
    +//
    +`ifdef OR1200_DU_DVR5
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dvr5 <= 32'h0000_0000;
    + else if (dvr5_sel && spr_write)
    + dvr5 <= spr_dat_i[31:0];
    +`else
    +assign dvr5 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR6
    +//
    +`ifdef OR1200_DU_DVR6
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dvr6 <= 32'h0000_0000;
    + else if (dvr6_sel && spr_write)
    + dvr6 <= spr_dat_i[31:0];
    +`else
    +assign dvr6 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DVR7
    +//
    +`ifdef OR1200_DU_DVR7
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dvr7 <= 32'h0000_0000;
    + else if (dvr7_sel && spr_write)
    + dvr7 <= spr_dat_i[31:0];
    +`else
    +assign dvr7 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DCR0
    +//
    +`ifdef OR1200_DU_DCR0
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dcr0 <= 8'h00;
    + else if (dcr0_sel && spr_write)
    + dcr0 <= spr_dat_i[7:0];
    +`else
    +assign dcr0 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR1
    +//
    +`ifdef OR1200_DU_DCR1
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dcr1 <= 8'h00;
    + else if (dcr1_sel && spr_write)
    + dcr1 <= spr_dat_i[7:0];
    +`else
    +assign dcr1 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR2
    +//
    +`ifdef OR1200_DU_DCR2
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dcr2 <= 8'h00;
    + else if (dcr2_sel && spr_write)
    + dcr2 <= spr_dat_i[7:0];
    +`else
    +assign dcr2 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR3
    +//
    +`ifdef OR1200_DU_DCR3
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dcr3 <= 8'h00;
    + else if (dcr3_sel && spr_write)
    + dcr3 <= spr_dat_i[7:0];
    +`else
    +assign dcr3 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR4
    +//
    +`ifdef OR1200_DU_DCR4
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dcr4 <= 8'h00;
    + else if (dcr4_sel && spr_write)
    + dcr4 <= spr_dat_i[7:0];
    +`else
    +assign dcr4 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR5
    +//
    +`ifdef OR1200_DU_DCR5
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dcr5 <= 8'h00;
    + else if (dcr5_sel && spr_write)
    + dcr5 <= spr_dat_i[7:0];
    +`else
    +assign dcr5 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR6
    +//
    +`ifdef OR1200_DU_DCR6
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dcr6 <= 8'h00;
    + else if (dcr6_sel && spr_write)
    + dcr6 <= spr_dat_i[7:0];
    +`else
    +assign dcr6 = 8'h00;
    +`endif
    +
    +//
    +// Write to DCR7
    +//
    +`ifdef OR1200_DU_DCR7
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dcr7 <= 8'h00;
    + else if (dcr7_sel && spr_write)
    + dcr7 <= spr_dat_i[7:0];
    +`else
    +assign dcr7 = 8'h00;
    +`endif
    +
    +//
    +// Write to DWCR0
    +//
    +`ifdef OR1200_DU_DWCR0
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dwcr0 <= 32'h0000_0000;
    + else if (dwcr0_sel && spr_write)
    + dwcr0 <= spr_dat_i[31:0];
    + else if (incr_wpcntr0)
    + dwcr0[`OR1200_DU_DWCR_COUNT] <= dwcr0[`OR1200_DU_DWCR_COUNT] + 16'h0001;
    +`else
    +assign dwcr0 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Write to DWCR1
    +//
    +`ifdef OR1200_DU_DWCR1
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + dwcr1 <= 32'h0000_0000;
    + else if (dwcr1_sel && spr_write)
    + dwcr1 <= spr_dat_i[31:0];
    + else if (incr_wpcntr1)
    + dwcr1[`OR1200_DU_DWCR_COUNT] <= dwcr1[`OR1200_DU_DWCR_COUNT] + 16'h0001;
    +`else
    +assign dwcr1 = 32'h0000_0000;
    +`endif
    +
    +//
    +// Read DU registers
    +//
    +`ifdef OR1200_DU_READREGS
    +always @(spr_addr or dsr or drr or dmr1 or dmr2
    + or dvr0 or dvr1 or dvr2 or dvr3 or dvr4
    + or dvr5 or dvr6 or dvr7
    + or dcr0 or dcr1 or dcr2 or dcr3 or dcr4
    + or dcr5 or dcr6 or dcr7
    + or dwcr0 or dwcr1
    +`ifdef OR1200_DU_TB_IMPLEMENTED
    + or tb_wadr or tbia_dat_o or tbim_dat_o
    + or tbar_dat_o or tbts_dat_o
    +`endif
    + )
    + casez (spr_addr[`OR1200_DUOFS_BITS]) // synopsys parallel_case
    +`ifdef OR1200_DU_DVR0
    + `OR1200_DU_DVR0:
    + spr_dat_o = dvr0;
    +`endif
    +`ifdef OR1200_DU_DVR1
    + `OR1200_DU_DVR1:
    + spr_dat_o = dvr1;
    +`endif
    +`ifdef OR1200_DU_DVR2
    + `OR1200_DU_DVR2:
    + spr_dat_o = dvr2;
    +`endif
    +`ifdef OR1200_DU_DVR3
    + `OR1200_DU_DVR3:
    + spr_dat_o = dvr3;
    +`endif
    +`ifdef OR1200_DU_DVR4
    + `OR1200_DU_DVR4:
    + spr_dat_o = dvr4;
    +`endif
    +`ifdef OR1200_DU_DVR5
    + `OR1200_DU_DVR5:
    + spr_dat_o = dvr5;
    +`endif
    +`ifdef OR1200_DU_DVR6
    + `OR1200_DU_DVR6:
    + spr_dat_o = dvr6;
    +`endif
    +`ifdef OR1200_DU_DVR7
    + `OR1200_DU_DVR7:
    + spr_dat_o = dvr7;
    +`endif
    +`ifdef OR1200_DU_DCR0
    + `OR1200_DU_DCR0:
    + spr_dat_o = {24'h00_0000, dcr0};
    +`endif
    +`ifdef OR1200_DU_DCR1
    + `OR1200_DU_DCR1:
    + spr_dat_o = {24'h00_0000, dcr1};
    +`endif
    +`ifdef OR1200_DU_DCR2
    + `OR1200_DU_DCR2:
    + spr_dat_o = {24'h00_0000, dcr2};
    +`endif
    +`ifdef OR1200_DU_DCR3
    + `OR1200_DU_DCR3:
    + spr_dat_o = {24'h00_0000, dcr3};
    +`endif
    +`ifdef OR1200_DU_DCR4
    + `OR1200_DU_DCR4:
    + spr_dat_o = {24'h00_0000, dcr4};
    +`endif
    +`ifdef OR1200_DU_DCR5
    + `OR1200_DU_DCR5:
    + spr_dat_o = {24'h00_0000, dcr5};
    +`endif
    +`ifdef OR1200_DU_DCR6
    + `OR1200_DU_DCR6:
    + spr_dat_o = {24'h00_0000, dcr6};
    +`endif
    +`ifdef OR1200_DU_DCR7
    + `OR1200_DU_DCR7:
    + spr_dat_o = {24'h00_0000, dcr7};
    +`endif
    +`ifdef OR1200_DU_DMR1
    + `OR1200_DU_DMR1:
    + spr_dat_o = {7'h00, dmr1};
    +`endif
    +`ifdef OR1200_DU_DMR2
    + `OR1200_DU_DMR2:
    + spr_dat_o = {8'h00, dmr2};
    +`endif
    +`ifdef OR1200_DU_DWCR0
    + `OR1200_DU_DWCR0:
    + spr_dat_o = dwcr0;
    +`endif
    +`ifdef OR1200_DU_DWCR1
    + `OR1200_DU_DWCR1:
    + spr_dat_o = dwcr1;
    +`endif
    +`ifdef OR1200_DU_DSR
    + `OR1200_DU_DSR:
    + spr_dat_o = {18'b0, dsr};
    +`endif
    +`ifdef OR1200_DU_DRR
    + `OR1200_DU_DRR:
    + spr_dat_o = {18'b0, drr};
    +`endif
    +`ifdef OR1200_DU_TB_IMPLEMENTED
    + `OR1200_DU_TBADR:
    + spr_dat_o = {24'h000000, tb_wadr};
    + `OR1200_DU_TBIA:
    + spr_dat_o = tbia_dat_o;
    + `OR1200_DU_TBIM:
    + spr_dat_o = tbim_dat_o;
    + `OR1200_DU_TBAR:
    + spr_dat_o = tbar_dat_o;
    + `OR1200_DU_TBTS:
    + spr_dat_o = tbts_dat_o;
    +`endif
    + default:
    + spr_dat_o = 32'h0000_0000;
    + endcase
    +`endif
    +
    +//
    +// DSR alias
    +//
    +assign du_dsr = dsr;
    +
    +`ifdef OR1200_DU_HWBKPTS
    +
    +//
    +// Compare To What (Match Condition 0)
    +//
    +always @(dcr0 or id_pc or dcpu_adr_i or dcpu_dat_dc
    + or dcpu_dat_lsu or dcpu_we_i)
    + case (dcr0[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b001: match_cond0_ct = id_pc; // insn fetch EA
    + 3'b010: match_cond0_ct = dcpu_adr_i; // load EA
    + 3'b011: match_cond0_ct = dcpu_adr_i; // store EA
    + 3'b100: match_cond0_ct = dcpu_dat_dc; // load data
    + 3'b101: match_cond0_ct = dcpu_dat_lsu; // store data
    + 3'b110: match_cond0_ct = dcpu_adr_i; // load/store EA
    + default:match_cond0_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    + endcase
    +
    +//
    +// When To Compare (Match Condition 0)
    +//
    +always @(dcr0 or dcpu_cycstb_i)
    + case (dcr0[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b000: match_cond0_stb = 1'b0; //comparison disabled
    + 3'b001: match_cond0_stb = 1'b1; // insn fetch EA
    + default:match_cond0_stb = dcpu_cycstb_i; // any load/store
    + endcase
    +
    +//
    +// Match Condition 0
    +//
    +always @(match_cond0_stb or dcr0 or dvr0 or match_cond0_ct)
    + casex ({match_cond0_stb, dcr0[`OR1200_DU_DCR_CC]})
    + 4'b0_xxx,
    + 4'b1_000,
    + 4'b1_111: match0 = 1'b0;
    + 4'b1_001: match0 =
    + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} ==
    + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
    + 4'b1_010: match0 =
    + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} <
    + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
    + 4'b1_011: match0 =
    + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} <=
    + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
    + 4'b1_100: match0 =
    + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} >
    + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
    + 4'b1_101: match0 =
    + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} >=
    + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
    + 4'b1_110: match0 =
    + ({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} !=
    + {(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
    + endcase
    +
    +//
    +// Watchpoint 0
    +//
    +always @(dmr1 or match0)
    + case (dmr1[`OR1200_DU_DMR1_CW0])
    + 2'b00: wp[0] = match0;
    + 2'b01: wp[0] = match0;
    + 2'b10: wp[0] = match0;
    + 2'b11: wp[0] = 1'b0;
    + endcase
    +
    +//
    +// Compare To What (Match Condition 1)
    +//
    +always @(dcr1 or id_pc or dcpu_adr_i or dcpu_dat_dc
    + or dcpu_dat_lsu or dcpu_we_i)
    + case (dcr1[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b001: match_cond1_ct = id_pc; // insn fetch EA
    + 3'b010: match_cond1_ct = dcpu_adr_i; // load EA
    + 3'b011: match_cond1_ct = dcpu_adr_i; // store EA
    + 3'b100: match_cond1_ct = dcpu_dat_dc; // load data
    + 3'b101: match_cond1_ct = dcpu_dat_lsu; // store data
    + 3'b110: match_cond1_ct = dcpu_adr_i; // load/store EA
    + default:match_cond1_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    + endcase
    +
    +//
    +// When To Compare (Match Condition 1)
    +//
    +always @(dcr1 or dcpu_cycstb_i)
    + case (dcr1[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b000: match_cond1_stb = 1'b0; //comparison disabled
    + 3'b001: match_cond1_stb = 1'b1; // insn fetch EA
    + default:match_cond1_stb = dcpu_cycstb_i; // any load/store
    + endcase
    +
    +//
    +// Match Condition 1
    +//
    +always @(match_cond1_stb or dcr1 or dvr1 or match_cond1_ct)
    + casex ({match_cond1_stb, dcr1[`OR1200_DU_DCR_CC]})
    + 4'b0_xxx,
    + 4'b1_000,
    + 4'b1_111: match1 = 1'b0;
    + 4'b1_001: match1 =
    + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} ==
    + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
    + 4'b1_010: match1 =
    + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} <
    + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
    + 4'b1_011: match1 =
    + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} <=
    + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
    + 4'b1_100: match1 =
    + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} >
    + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
    + 4'b1_101: match1 =
    + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} >=
    + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
    + 4'b1_110: match1 =
    + ({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} !=
    + {(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
    + endcase
    +
    +//
    +// Watchpoint 1
    +//
    +always @(dmr1 or match1 or wp)
    + case (dmr1[`OR1200_DU_DMR1_CW1])
    + 2'b00: wp[1] = match1;
    + 2'b01: wp[1] = match1 & wp[0];
    + 2'b10: wp[1] = match1 | wp[0];
    + 2'b11: wp[1] = 1'b0;
    + endcase
    +
    +//
    +// Compare To What (Match Condition 2)
    +//
    +always @(dcr2 or id_pc or dcpu_adr_i or dcpu_dat_dc
    + or dcpu_dat_lsu or dcpu_we_i)
    + case (dcr2[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b001: match_cond2_ct = id_pc; // insn fetch EA
    + 3'b010: match_cond2_ct = dcpu_adr_i; // load EA
    + 3'b011: match_cond2_ct = dcpu_adr_i; // store EA
    + 3'b100: match_cond2_ct = dcpu_dat_dc; // load data
    + 3'b101: match_cond2_ct = dcpu_dat_lsu; // store data
    + 3'b110: match_cond2_ct = dcpu_adr_i; // load/store EA
    + default:match_cond2_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    + endcase
    +
    +//
    +// When To Compare (Match Condition 2)
    +//
    +always @(dcr2 or dcpu_cycstb_i)
    + case (dcr2[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b000: match_cond2_stb = 1'b0; //comparison disabled
    + 3'b001: match_cond2_stb = 1'b1; // insn fetch EA
    + default:match_cond2_stb = dcpu_cycstb_i; // any load/store
    + endcase
    +
    +//
    +// Match Condition 2
    +//
    +always @(match_cond2_stb or dcr2 or dvr2 or match_cond2_ct)
    + casex ({match_cond2_stb, dcr2[`OR1200_DU_DCR_CC]})
    + 4'b0_xxx,
    + 4'b1_000,
    + 4'b1_111: match2 = 1'b0;
    + 4'b1_001: match2 =
    + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} ==
    + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
    + 4'b1_010: match2 =
    + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} <
    + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
    + 4'b1_011: match2 =
    + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} <=
    + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
    + 4'b1_100: match2 =
    + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} >
    + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
    + 4'b1_101: match2 =
    + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} >=
    + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
    + 4'b1_110: match2 =
    + ({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} !=
    + {(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
    + endcase
    +
    +//
    +// Watchpoint 2
    +//
    +always @(dmr1 or match2 or wp)
    + case (dmr1[`OR1200_DU_DMR1_CW2])
    + 2'b00: wp[2] = match2;
    + 2'b01: wp[2] = match2 & wp[1];
    + 2'b10: wp[2] = match2 | wp[1];
    + 2'b11: wp[2] = 1'b0;
    + endcase
    +
    +//
    +// Compare To What (Match Condition 3)
    +//
    +always @(dcr3 or id_pc or dcpu_adr_i or dcpu_dat_dc
    + or dcpu_dat_lsu or dcpu_we_i)
    + case (dcr3[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b001: match_cond3_ct = id_pc; // insn fetch EA
    + 3'b010: match_cond3_ct = dcpu_adr_i; // load EA
    + 3'b011: match_cond3_ct = dcpu_adr_i; // store EA
    + 3'b100: match_cond3_ct = dcpu_dat_dc; // load data
    + 3'b101: match_cond3_ct = dcpu_dat_lsu; // store data
    + 3'b110: match_cond3_ct = dcpu_adr_i; // load/store EA
    + default:match_cond3_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    + endcase
    +
    +//
    +// When To Compare (Match Condition 3)
    +//
    +always @(dcr3 or dcpu_cycstb_i)
    + case (dcr3[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b000: match_cond3_stb = 1'b0; //comparison disabled
    + 3'b001: match_cond3_stb = 1'b1; // insn fetch EA
    + default:match_cond3_stb = dcpu_cycstb_i; // any load/store
    + endcase
    +
    +//
    +// Match Condition 3
    +//
    +always @(match_cond3_stb or dcr3 or dvr3 or match_cond3_ct)
    + casex ({match_cond3_stb, dcr3[`OR1200_DU_DCR_CC]})
    + 4'b0_xxx,
    + 4'b1_000,
    + 4'b1_111: match3 = 1'b0;
    + 4'b1_001: match3 =
    + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} ==
    + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
    + 4'b1_010: match3 =
    + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} <
    + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
    + 4'b1_011: match3 =
    + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} <=
    + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
    + 4'b1_100: match3 =
    + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} >
    + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
    + 4'b1_101: match3 =
    + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} >=
    + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
    + 4'b1_110: match3 =
    + ({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} !=
    + {(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
    + endcase
    +
    +//
    +// Watchpoint 3
    +//
    +always @(dmr1 or match3 or wp)
    + case (dmr1[`OR1200_DU_DMR1_CW3])
    + 2'b00: wp[3] = match3;
    + 2'b01: wp[3] = match3 & wp[2];
    + 2'b10: wp[3] = match3 | wp[2];
    + 2'b11: wp[3] = 1'b0;
    + endcase
    +
    +//
    +// Compare To What (Match Condition 4)
    +//
    +always @(dcr4 or id_pc or dcpu_adr_i or dcpu_dat_dc
    + or dcpu_dat_lsu or dcpu_we_i)
    + case (dcr4[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b001: match_cond4_ct = id_pc; // insn fetch EA
    + 3'b010: match_cond4_ct = dcpu_adr_i; // load EA
    + 3'b011: match_cond4_ct = dcpu_adr_i; // store EA
    + 3'b100: match_cond4_ct = dcpu_dat_dc; // load data
    + 3'b101: match_cond4_ct = dcpu_dat_lsu; // store data
    + 3'b110: match_cond4_ct = dcpu_adr_i; // load/store EA
    + default:match_cond4_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    + endcase
    +
    +//
    +// When To Compare (Match Condition 4)
    +//
    +always @(dcr4 or dcpu_cycstb_i)
    + case (dcr4[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b000: match_cond4_stb = 1'b0; //comparison disabled
    + 3'b001: match_cond4_stb = 1'b1; // insn fetch EA
    + default:match_cond4_stb = dcpu_cycstb_i; // any load/store
    + endcase
    +
    +//
    +// Match Condition 4
    +//
    +always @(match_cond4_stb or dcr4 or dvr4 or match_cond4_ct)
    + casex ({match_cond4_stb, dcr4[`OR1200_DU_DCR_CC]})
    + 4'b0_xxx,
    + 4'b1_000,
    + 4'b1_111: match4 = 1'b0;
    + 4'b1_001: match4 =
    + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} ==
    + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
    + 4'b1_010: match4 =
    + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} <
    + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
    + 4'b1_011: match4 =
    + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} <=
    + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
    + 4'b1_100: match4 =
    + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} >
    + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
    + 4'b1_101: match4 =
    + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} >=
    + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
    + 4'b1_110: match4 =
    + ({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} !=
    + {(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
    + endcase
    +
    +//
    +// Watchpoint 4
    +//
    +always @(dmr1 or match4 or wp)
    + case (dmr1[`OR1200_DU_DMR1_CW4])
    + 2'b00: wp[4] = match4;
    + 2'b01: wp[4] = match4 & wp[3];
    + 2'b10: wp[4] = match4 | wp[3];
    + 2'b11: wp[4] = 1'b0;
    + endcase
    +
    +//
    +// Compare To What (Match Condition 5)
    +//
    +always @(dcr5 or id_pc or dcpu_adr_i or dcpu_dat_dc
    + or dcpu_dat_lsu or dcpu_we_i)
    + case (dcr5[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b001: match_cond5_ct = id_pc; // insn fetch EA
    + 3'b010: match_cond5_ct = dcpu_adr_i; // load EA
    + 3'b011: match_cond5_ct = dcpu_adr_i; // store EA
    + 3'b100: match_cond5_ct = dcpu_dat_dc; // load data
    + 3'b101: match_cond5_ct = dcpu_dat_lsu; // store data
    + 3'b110: match_cond5_ct = dcpu_adr_i; // load/store EA
    + default:match_cond5_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    + endcase
    +
    +//
    +// When To Compare (Match Condition 5)
    +//
    +always @(dcr5 or dcpu_cycstb_i)
    + case (dcr5[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b000: match_cond5_stb = 1'b0; //comparison disabled
    + 3'b001: match_cond5_stb = 1'b1; // insn fetch EA
    + default:match_cond5_stb = dcpu_cycstb_i; // any load/store
    + endcase
    +
    +//
    +// Match Condition 5
    +//
    +always @(match_cond5_stb or dcr5 or dvr5 or match_cond5_ct)
    + casex ({match_cond5_stb, dcr5[`OR1200_DU_DCR_CC]})
    + 4'b0_xxx,
    + 4'b1_000,
    + 4'b1_111: match5 = 1'b0;
    + 4'b1_001: match5 =
    + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} ==
    + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
    + 4'b1_010: match5 =
    + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} <
    + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
    + 4'b1_011: match5 =
    + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} <=
    + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
    + 4'b1_100: match5 =
    + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} >
    + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
    + 4'b1_101: match5 =
    + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} >=
    + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
    + 4'b1_110: match5 =
    + ({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} !=
    + {(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
    + endcase
    +
    +//
    +// Watchpoint 5
    +//
    +always @(dmr1 or match5 or wp)
    + case (dmr1[`OR1200_DU_DMR1_CW5])
    + 2'b00: wp[5] = match5;
    + 2'b01: wp[5] = match5 & wp[4];
    + 2'b10: wp[5] = match5 | wp[4];
    + 2'b11: wp[5] = 1'b0;
    + endcase
    +
    +//
    +// Compare To What (Match Condition 6)
    +//
    +always @(dcr6 or id_pc or dcpu_adr_i or dcpu_dat_dc
    + or dcpu_dat_lsu or dcpu_we_i)
    + case (dcr6[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b001: match_cond6_ct = id_pc; // insn fetch EA
    + 3'b010: match_cond6_ct = dcpu_adr_i; // load EA
    + 3'b011: match_cond6_ct = dcpu_adr_i; // store EA
    + 3'b100: match_cond6_ct = dcpu_dat_dc; // load data
    + 3'b101: match_cond6_ct = dcpu_dat_lsu; // store data
    + 3'b110: match_cond6_ct = dcpu_adr_i; // load/store EA
    + default:match_cond6_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    + endcase
    +
    +//
    +// When To Compare (Match Condition 6)
    +//
    +always @(dcr6 or dcpu_cycstb_i)
    + case (dcr6[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b000: match_cond6_stb = 1'b0; //comparison disabled
    + 3'b001: match_cond6_stb = 1'b1; // insn fetch EA
    + default:match_cond6_stb = dcpu_cycstb_i; // any load/store
    + endcase
    +
    +//
    +// Match Condition 6
    +//
    +always @(match_cond6_stb or dcr6 or dvr6 or match_cond6_ct)
    + casex ({match_cond6_stb, dcr6[`OR1200_DU_DCR_CC]})
    + 4'b0_xxx,
    + 4'b1_000,
    + 4'b1_111: match6 = 1'b0;
    + 4'b1_001: match6 =
    + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} ==
    + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
    + 4'b1_010: match6 =
    + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} <
    + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
    + 4'b1_011: match6 =
    + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} <=
    + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
    + 4'b1_100: match6 =
    + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} >
    + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
    + 4'b1_101: match6 =
    + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} >=
    + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
    + 4'b1_110: match6 =
    + ({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} !=
    + {(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
    + endcase
    +
    +//
    +// Watchpoint 6
    +//
    +always @(dmr1 or match6 or wp)
    + case (dmr1[`OR1200_DU_DMR1_CW6])
    + 2'b00: wp[6] = match6;
    + 2'b01: wp[6] = match6 & wp[5];
    + 2'b10: wp[6] = match6 | wp[5];
    + 2'b11: wp[6] = 1'b0;
    + endcase
    +
    +//
    +// Compare To What (Match Condition 7)
    +//
    +always @(dcr7 or id_pc or dcpu_adr_i or dcpu_dat_dc
    + or dcpu_dat_lsu or dcpu_we_i)
    + case (dcr7[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b001: match_cond7_ct = id_pc; // insn fetch EA
    + 3'b010: match_cond7_ct = dcpu_adr_i; // load EA
    + 3'b011: match_cond7_ct = dcpu_adr_i; // store EA
    + 3'b100: match_cond7_ct = dcpu_dat_dc; // load data
    + 3'b101: match_cond7_ct = dcpu_dat_lsu; // store data
    + 3'b110: match_cond7_ct = dcpu_adr_i; // load/store EA
    + default:match_cond7_ct = dcpu_we_i ? dcpu_dat_lsu : dcpu_dat_dc;
    + endcase
    +
    +//
    +// When To Compare (Match Condition 7)
    +//
    +always @(dcr7 or dcpu_cycstb_i)
    + case (dcr7[`OR1200_DU_DCR_CT]) // synopsys parallel_case
    + 3'b000: match_cond7_stb = 1'b0; //comparison disabled
    + 3'b001: match_cond7_stb = 1'b1; // insn fetch EA
    + default:match_cond7_stb = dcpu_cycstb_i; // any load/store
    + endcase
    +
    +//
    +// Match Condition 7
    +//
    +always @(match_cond7_stb or dcr7 or dvr7 or match_cond7_ct)
    + casex ({match_cond7_stb, dcr7[`OR1200_DU_DCR_CC]})
    + 4'b0_xxx,
    + 4'b1_000,
    + 4'b1_111: match7 = 1'b0;
    + 4'b1_001: match7 =
    + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} ==
    + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
    + 4'b1_010: match7 =
    + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} <
    + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
    + 4'b1_011: match7 =
    + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} <=
    + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
    + 4'b1_100: match7 =
    + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} >
    + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
    + 4'b1_101: match7 =
    + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} >=
    + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
    + 4'b1_110: match7 =
    + ({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} !=
    + {(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
    + endcase
    +
    +//
    +// Watchpoint 7
    +//
    +always @(dmr1 or match7 or wp)
    + case (dmr1[`OR1200_DU_DMR1_CW7])
    + 2'b00: wp[7] = match7;
    + 2'b01: wp[7] = match7 & wp[6];
    + 2'b10: wp[7] = match7 | wp[6];
    + 2'b11: wp[7] = 1'b0;
    + endcase
    +
    +//
    +// Increment Watchpoint Counter 0
    +//
    +always @(wp or dmr2)
    + if (dmr2[`OR1200_DU_DMR2_WCE0])
    + incr_wpcntr0 = |(wp & ~dmr2[`OR1200_DU_DMR2_AWTC]);
    + else
    + incr_wpcntr0 = 1'b0;
    +
    +//
    +// Match Condition Watchpoint Counter 0
    +//
    +always @(dwcr0)
    + if (dwcr0[`OR1200_DU_DWCR_MATCH] == dwcr0[`OR1200_DU_DWCR_COUNT])
    + wpcntr0_match = 1'b1;
    + else
    + wpcntr0_match = 1'b0;
    +
    +
    +//
    +// Watchpoint 8
    +//
    +always @(dmr1 or wpcntr0_match or wp)
    + case (dmr1[`OR1200_DU_DMR1_CW8])
    + 2'b00: wp[8] = wpcntr0_match;
    + 2'b01: wp[8] = wpcntr0_match & wp[7];
    + 2'b10: wp[8] = wpcntr0_match | wp[7];
    + 2'b11: wp[8] = 1'b0;
    + endcase
    +
    +
    +//
    +// Increment Watchpoint Counter 1
    +//
    +always @(wp or dmr2)
    + if (dmr2[`OR1200_DU_DMR2_WCE1])
    + incr_wpcntr1 = |(wp & dmr2[`OR1200_DU_DMR2_AWTC]);
    + else
    + incr_wpcntr1 = 1'b0;
    +
    +//
    +// Match Condition Watchpoint Counter 1
    +//
    +always @(dwcr1)
    + if (dwcr1[`OR1200_DU_DWCR_MATCH] == dwcr1[`OR1200_DU_DWCR_COUNT])
    + wpcntr1_match = 1'b1;
    + else
    + wpcntr1_match = 1'b0;
    +
    +//
    +// Watchpoint 9
    +//
    +always @(dmr1 or wpcntr1_match or wp)
    + case (dmr1[`OR1200_DU_DMR1_CW9])
    + 2'b00: wp[9] = wpcntr1_match;
    + 2'b01: wp[9] = wpcntr1_match & wp[8];
    + 2'b10: wp[9] = wpcntr1_match | wp[8];
    + 2'b11: wp[9] = 1'b0;
    + endcase
    +
    +//
    +// Watchpoint 10
    +//
    +always @(dmr1 or dbg_ewt_i or wp)
    + case (dmr1[`OR1200_DU_DMR1_CW10])
    + 2'b00: wp[10] = dbg_ewt_i;
    + 2'b01: wp[10] = dbg_ewt_i & wp[9];
    + 2'b10: wp[10] = dbg_ewt_i | wp[9];
    + 2'b11: wp[10] = 1'b0;
    + endcase
    +
    +`endif
    +
    +//
    +// Watchpoints can cause trap exception
    +//
    +`ifdef OR1200_DU_HWBKPTS
    +assign du_hwbkpt = |(wp & dmr2[`OR1200_DU_DMR2_WGB]) | du_hwbkpt_hold | (dbg_bp_r & ~dsr[`OR1200_DU_DSR_TE]);
    +`else
    +assign du_hwbkpt = 1'b0;
    +`endif
    +
    +// Hold du_hwbkpt if ex_freeze is active in order to cause trap exception
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + du_hwbkpt_hold <= 1'b0;
    + else if (du_hwbkpt & ex_freeze)
    + du_hwbkpt_hold <= 1'b1;
    + else if (!ex_freeze)
    + du_hwbkpt_hold <= 1'b0;
    +
    +`ifdef OR1200_DU_TB_IMPLEMENTED
    +//
    +// Simple trace buffer
    +// (right now hardcoded for Xilinx Virtex FPGAs)
    +//
    +// Stores last 256 instruction addresses, instruction
    +// machine words and ALU results
    +//
    +
    +//
    +// Trace buffer write enable
    +//
    +assign tb_enw = ~ex_freeze & ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]);
    +
    +//
    +// Trace buffer write address pointer
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + tb_wadr <= 8'h00;
    + else if (tb_enw)
    + tb_wadr <= tb_wadr + 8'd1;
    +
    +//
    +// Free running counter (time stamp)
    +//
    +always @(posedge clk or `OR1200_RST_EVENT rst)
    + if (rst == `OR1200_RST_VALUE)
    + tb_timstmp <= 32'h00000000;
    + else if (!dbg_bp_r)
    + tb_timstmp <= tb_timstmp + 32'd1;
    +
    +//
    +// Trace buffer RAMs
    +//
    +
    +or1200_dpram_256x32 tbia_ram(
    + .clk_a(clk),
    + .rst_a(1'b0),
    + .addr_a(spr_addr[7:0]),
    + .ce_a(1'b1),
    + .oe_a(1'b1),
    + .do_a(tbia_dat_o),
    +
    + .clk_b(clk),
    + .rst_b(1'b0),
    + .addr_b(tb_wadr),
    + .di_b(spr_dat_npc),
    + .ce_b(1'b1),
    + .we_b(tb_enw)
    +
    +);
    +
    +or1200_dpram_256x32 tbim_ram(
    + .clk_a(clk),
    + .rst_a(1'b0),
    + .addr_a(spr_addr[7:0]),
    + .ce_a(1'b1),
    + .oe_a(1'b1),
    + .do_a(tbim_dat_o),
    +
    + .clk_b(clk),
    + .rst_b(1'b0),
    + .addr_b(tb_wadr),
    + .di_b(ex_insn),
    + .ce_b(1'b1),
    + .we_b(tb_enw)
    +);
    +
    +or1200_dpram_256x32 tbar_ram(
    + .clk_a(clk),
    + .rst_a(1'b0),
    + .addr_a(spr_addr[7:0]),
    + .ce_a(1'b1),
    + .oe_a(1'b1),
    + .do_a(tbar_dat_o),
    +
    + .clk_b(clk),
    + .rst_b(1'b0),
    + .addr_b(tb_wadr),
    + .di_b(rf_dataw),
    + .ce_b(1'b1),
    + .we_b(tb_enw)
    +);
    +
    +or1200_dpram_256x32 tbts_ram(
    + .clk_a(clk),
    + .rst_a(1'b0),
    + .addr_a(spr_addr[7:0]),
    + .ce_a(1'b1),
    + .oe_a(1'b1),
    + .do_a(tbts_dat_o),
    +
    + .clk_b(clk),
    + .rst_b(1'b0),
    + .addr_b(tb_wadr),
    + .di_b(tb_timstmp),
    + .ce_b(1'b1),
    + .we_b(tb_enw)
    +);
    +
    +`else
    +
    +assign tbia_dat_o = 32'h0000_0000;
    +assign tbim_dat_o = 32'h0000_0000;
    +assign tbar_dat_o = 32'h0000_0000;
    +assign tbts_dat_o = 32'h0000_0000;
    +
    +`endif // OR1200_DU_TB_IMPLEMENTED
    +
    +`else // OR1200_DU_IMPLEMENTED
    +
    +//
    +// When DU is not implemented, drive all outputs as would when DU is disabled
    +//
    +assign dbg_bp_o = 1'b0;
    +assign du_dsr = {`OR1200_DU_DSR_WIDTH{1'b0}};
    +assign du_dmr1 = {25{1'b0}};
    +assign du_hwbkpt = 1'b0;
    +
    +//
    +// Read DU registers
    +//
    +`ifdef OR1200_DU_READREGS
    +assign spr_dat_o = 32'h0000_0000;
    +`ifdef OR1200_DU_UNUSED_ZERO
    +`endif
    +`endif
    +
    +`endif
    +
    +endmodule
    diff --git a/autotests/reference/preprocessor-bug363280.c.ref b/autotests/reference/preprocessor-bug363280.c.ref new file mode 100644 index 0000000..4c23041 --- /dev/null +++ b/autotests/reference/preprocessor-bug363280.c.ref @@ -0,0 +1,8 @@ +#if 1
    +int x; // variable shall not be grey
    +#endif
    +#if defined (A)
    +int y; // variable shall not be grey
    +#elif defined (B)
    +int z; // variable shall not be grey
    +#endif
    diff --git a/autotests/reference/preprocessor-bug363280.cpp.ref b/autotests/reference/preprocessor-bug363280.cpp.ref new file mode 100644 index 0000000..8025f16 --- /dev/null +++ b/autotests/reference/preprocessor-bug363280.cpp.ref @@ -0,0 +1,8 @@ +#if 1
    +int x; // variable shall not be grey
    +#endif
    +#if defined (A)
    +int y; // variable shall not be grey
    +#elif defined (B)
    +int z; // variable shall not be grey
    +#endif
    diff --git a/autotests/reference/review128925-1.css.ref b/autotests/reference/review128925-1.css.ref new file mode 100644 index 0000000..36b2f90 --- /dev/null +++ b/autotests/reference/review128925-1.css.ref @@ -0,0 +1,112 @@ +/*
    + * CSS Syntax Highlight Sample File (Standard)
    + *
    + * This file contains most CSS syntax, CSS3 properties, @media, @font-face and
    + * @keyframes annotations.
    + *
    + * @author Guo Yunhe guoyunhebrave@gmail.com
    + * @date 2016-09-16
    + */
    +
    +/*
    + * Block comment
    + *
    + * Alert keywords:
    + * TODO BUG FIXME
    + */
    +
    +@charset "UTF-8";
    +
    +@import url("components/button.css");
    +
    +
    +/* Properties */
    +
    +html, body {
    + font-family: "Droid Sans", Arial, sans-serif;
    + font-size: 11pt;
    + line-height: 1.5em;
    + max-width: calc(100% - 300px);
    + background: #fff000;
    + text-shadow: 0 0 2px rgba(0, 0, 0, 0.3);
    + box-sizing: border-box;
    +}
    +
    +
    +/* Selectors */
    +
    +blockquote {
    + margin: 0;
    +}
    +
    +header #logo {
    + width: 100px;
    +}
    +
    +div#footer .link {
    + color: blue;
    +}
    +
    +sidebar #subscribe .subscribe_form input[type="text"] {
    + font-size: 20px;
    +}
    +
    +sidebar #subscribe .subscribe_form:nth-child(2n + 1):hover input[class*="small-"] {
    + font-weight: bold;
    +}
    +
    +
    +/* Media Queries */
    +
    +@media print {
    + .container {
    + width: 100%;
    + }
    +}
    +
    +@media screen and (min-width: 768px) {
    + .container {
    + width: 600px;
    + }
    +}
    +
    +@media screen and (min-width: 768px) and (max-width: 960px) {
    + .container {
    + width: 720px;
    + }
    +}
    +
    +
    +/* Fontface */
    +
    +@font-face {
    + font-family: MyHelvetica;
    + src: local("Helvetica Neue Bold"),
    + local("HelveticaNeue-Bold"),
    + url(MgOpenModernaBold.ttf);
    + font-weight: bold;
    +}
    +
    +/* Animation (Keyframes) */
    +
    +@keyframes slidein {
    + from {
    + margin-left: 100%;
    + width: 300%;
    + }
    +
    + to {
    + margin-left: 0%;
    + width: 100%;
    + }
    +}
    +
    +
    +/* Region markers */
    +
    +/*BEGIN Comment */
    +
    +
    +
    +/*END Comment */
    +
    diff --git a/autotests/reference/review128925-1.scss.ref b/autotests/reference/review128925-1.scss.ref new file mode 100644 index 0000000..ef07c19 --- /dev/null +++ b/autotests/reference/review128925-1.scss.ref @@ -0,0 +1,211 @@ +/*
    + * SCSS Syntax Highlight Sample File (Standard)
    + *
    + * This file contains most SCSS syntax, CSS3 properties, advanced code structure.
    + * It is NOT a valid SCSS file that can be compiled by SCSS preprocessors.
    + *
    + * @author Guo Yunhe guoyunhebrave@gmail.com
    + * @date 2016-09-15
    + */
    +
    +/*
    + * Block comment
    + *
    + * Alert keywords:
    + * TODO BUG FIXME
    + */
    +
    +@charset "UTF-8";
    +
    +@import "mixins/button";
    +
    +// Variable define
    +
    +$image-path: "../../static/images";
    +$default-text-color: #333 !default; // Default can be overrided
    +$default-font-size: 16px !default;
    +$default-font-family: Roboto, "Droid Sans", sans-serif;
    +$default-font-weight: 400;
    +$default-line-height: $default-font-size * 1.8;
    +$shadow-transparence: 0.25;
    +$box-shadow: 0 0 3px rgba(0,0,0,$shadow-transparence);
    +$page-width: 100rem; // kabab-case
    +$gapOfArticle: 20px; // camelCase
    +$body_background_color: white; // snake_case
    +
    +// Mixins
    +
    +@mixin border-radius($radius) {
    + -webkit-border-radius: $radius;
    + -moz-border-radius: $radius;
    + -ms-border-radius: $radius;
    + border-radius: $radius;
    +}
    +
    +.box { @include border-radius(10px); }
    +
    +// Nesting
    +
    +#home-page {
    +
    + header {
    + width: 80%;
    + margin: 0 auto;
    +
    + .cover {
    + @include border-radius(20px);
    + max-width: 100%;
    +
    + &:hover {
    + background: #ffffff;
    + }
    +
    + .like-button {
    + font-size: $default-font-size * 0.8;
    +
    + @media (max-width: 300px) and (min-width: 200px) {
    + font-size: $default-font-size * 0.8;
    +
    + .icon {
    + width: 20px;
    + height: 20px;
    + }
    + }
    +
    + @media print {
    + display: none;
    + }
    + }
    + }
    + }
    +}
    +
    +// Extend and inheritance
    +
    +.message {
    + border: $border-light;
    + background-color: #f0f0f0;
    +}
    +
    +.message-danger {
    + @extend .message;
    +}
    +
    +
    +// Control structures
    +
    +@mixin does-parent-exist {
    + @if & {
    + &:hover {
    + color: red;
    + }
    + } @else {
    + a {
    + color: red;
    + }
    + }
    +}
    +
    +
    +// Operators
    +
    +.container { width: 100%; }
    +
    +article[role="main"] {
    + float: left;
    + width: 600px / 960px * 100%;
    +}
    +
    +aside[role="complementary"] {
    + float: right;
    + width: 300px / 960px * 100%;
    +}
    +
    +
    +// Functions - see http://sass-lang.com/documentation/Sass/Script/Functions.html
    +
    +$color1: hsl(120deg, 100%, 50%);
    +$color2: rgb($red, $green, blue($color1));
    +$color3: mix($color1, $color2, [$weight]);
    +
    +
    +// Properties
    +
    +html, body {
    + font-family: "Droid Sans", Arial, sans-serif;
    + font-size: 11pt;
    + line-height: 1.5em;
    + max-width: 300px + $page-width - $gap / 2;
    + background: $bg_color;
    + text-shadow: 0 0 2px rgba(0,0,0, $transparence);
    + box-sizing: border-box;
    +}
    +
    +
    +// Selectors
    +
    +blockquote {
    + margin: 0;
    +}
    +
    +header #logo {
    + width: 100px;
    +}
    +
    +div#footer .link {
    + color: blue;
    +}
    +
    +sidebar #subscribe .subscribe_form input[type="text"] {
    + font-size: 20px;
    +}
    +
    +sidebar #subscribe .subscribe_form:nth-child(2n + 1):hover input[class*="small-"] {
    + font-weight: bold;
    +}
    +
    +
    +// Media Queries
    +
    +@media print {
    + .container {
    + width: 100%;
    + }
    +}
    +
    +@media screen and (min-width: 768px) {
    + .container {
    + width: 600px;
    + }
    +}
    +
    +@media screen and (min-width: 768px) and (max-width: 960px) {
    + .container {
    + width: 720px;
    + }
    +}
    +
    +
    +// Fontface
    +
    +@font-face {
    + font-family: MyHelvetica;
    + src: local("Helvetica Neue Bold"),
    + local("HelveticaNeue-Bold"),
    + url(MgOpenModernaBold.ttf);
    + font-weight: bold;
    +}
    +
    +// Animation (Keyframes)
    +
    +@keyframes slidein {
    + from {
    + margin-left: 100%;
    + width: 300%;
    + }
    +
    + to {
    + margin-left: 0%;
    + width: 100%;
    + }
    +}
    diff --git a/autotests/reference/review128925-2.css.ref b/autotests/reference/review128925-2.css.ref new file mode 100644 index 0000000..7decf79 --- /dev/null +++ b/autotests/reference/review128925-2.css.ref @@ -0,0 +1,62 @@ +/*
    + * CSS Syntax Highlight Sample File (Complex)
    + *
    + * This file contains complex CSS syntax that can test unexpected situations.
    + *
    + * @author Guo Yunhe guoyunhebrave@gmail.com
    + * @date 2016-09-16
    + */
    +
    +
    +/* Comments with special content */
    +
    +/*
    + * .class-selector #id "string" 'comment' // comment {} [] () /* comment
    + * TODO BUG DEBUG
    + * body {
    + * margin: 0 !important;
    + * }
    + */
    +
    +/* Comments in special positions */
    +
    +header/* comment here */.active /* comment here */ {
    + /* comment here */ color : /* comment here */ blue/* comment here */;
    + font-family: Arial /* comment here */,
    + "Droid Sans", /* comment here */
    + sans-serif/* comment here */;
    +}
    +
    +@media screen /* comment here */ and (max-width: 300px /* comment here */) /* comment here */ {/* comment here */}
    +
    +
    +/* Strings with special content */
    +
    +@import url("{} $variable /* comment */");
    +
    +
    +/* Without extra breaklines and spaces */
    +
    +pre.primary:hover.large:nth-child(2n-1){font-size:17px;font-family:"Noto Sans";-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.3)}
    +
    +
    +/* With unnecessary breaklines and spaces */
    +
    +blockquote .ref
    + {
    + flex : 0 1 30%;
    + flex-wrap : wrap;
    + }
    +
    +@media screen and (orientation: landscape) {
    + .sidebar {
    + width: 500px; } }
    +
    +
    +/* Special selectors: HTML5 allows user defined tags */
    +
    +header {
    + flex {
    + width: 300px;
    + }
    +}
    diff --git a/autotests/reference/review128925-2.scss.ref b/autotests/reference/review128925-2.scss.ref new file mode 100644 index 0000000..d3a4d44 --- /dev/null +++ b/autotests/reference/review128925-2.scss.ref @@ -0,0 +1,81 @@ +/*
    + * SCSS Syntax Highlight Sample File (Complex)
    + *
    + * This file contains complex SCSS syntax that can test unexpected situations.
    + * It is NOT a valid SCSS file that can be compiled by SCSS preprocessors.
    + *
    + * @author Guo Yunhe guoyunhebrave@gmail.com
    + * @date 2016-09-16
    + */
    +
    +
    +// Comments with special content
    +
    +// .class-selector #id "string" 'comment' // comment {} [] () /* comment */ text
    +
    +/*
    + * .class-selector #id "string" 'comment' // comment {} [] () /* comment
    + * TODO BUG DEBUG
    + * body {
    + * margin: 0 !important;
    + * }
    + */
    +
    +// Comments in special positions
    +
    +$color: black /* comment here */;
    +
    +header/* comment here */.active /* comment here */ {
    + /* comment here */ color : /* comment here */ blue/* comment here */;
    + font-family: Arial /* comment here */,
    + "Droid Sans", /* comment here */
    + sans-serif/* comment here */;
    +}
    +
    +@media screen /* comment here */ and (max-width: 300px /* comment here */) /* comment here */ {/* comment here */}
    +
    +
    +// Strings with special content
    +
    +@import "{} $variable /* comment */";
    +@import "{}";
    +
    +// Without extra breaklines and spaces
    +
    +pre.primary:hover.large:nth-child(2n-1){font-size:$default-font-size;font-family:"Noto Sans";-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.3)}
    +
    +// With unnecessary breaklines and spaces
    +
    +blockquote .ref
    + {
    + flex : 0 1 30%;
    + flex-wrap : wrap;
    + }
    +
    +.sidebar {
    + width: 300px; }
    + @media screen and (orientation: landscape) {
    + .sidebar {
    + width: 500px; } }
    +
    +// Variable interpolation: #{}
    +
    +$name: foo;
    +$attr: border;
    +p.#{$name} {
    + #{$attr}-color: blue;
    +}
    +
    +p {
    + $font-size: 12px;
    + $line-height: 30px;
    + font: #{$font-size}/#{$line-height};
    +}
    +
    +// Special selectors: HTML5 allows user defined tags
    +
    +header {
    + flex {
    + width: 300px;
    + }
    +}
    diff --git a/autotests/reference/review128935.html.ref b/autotests/reference/review128935.html.ref new file mode 100644 index 0000000..b031660 --- /dev/null +++ b/autotests/reference/review128935.html.ref @@ -0,0 +1,164 @@ +
    +
    +html>
    +
    +
    +
    +
    + charset="utf-8">
    +</Element><Normal Text>HTML Syntax Highlight Sample File (Standard)</Normal Text><Element>
    + rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    + rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    + src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous">
    +
    +
    +
    +
    +
    +
    +

    + This is a div. This is a span
    +

    + This is a div.
    +

    +

    +
    +


    + This is a paragraph.
    +


    +
    +

    This is heading 1


    +

    This is heading 2


    +

    This is heading 3


    +

    This is heading 4


    +
    This is heading 5

    +
    This is heading 6

    +
    + href="http://www.w3schools.com">This is a link

    +
    +

    +
    + src="http://placehold.it/200x150" alt="This is an image" width="200" height="150">
    +
    +

    +
    +

      +
    • List item

    • +
    • List item

    • +
    • List item

    • +
    • List item

    • +
    • List item

    • +

    +
    +

      +
    1. List item

    2. +
    3. List item

    4. +
    5. List item

    6. +
    7. List item

    8. +
    9. List item

    10. +

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Table headTable headTable head
    Table headTable headTable head

    +
    +

    + type="email" name="author"/>
    + type="text" name="message"/>
    + type="button">Send
    +
    +
    +

    +
    This is a header.

    +
    +
    +
    +

    +

    This is an article.


    +

    This is an article.


    +

    +
    +
    +
    +

    +
    +

    +
    +
    +
    +
    +
    + Just For Fun: The Story of an Accidental Revolutionary
    + Linus Torvalds
    +
    + class="featured" title="Click to read full text...">
    + A humorous autobiography of Linus Torvalds, the creator of the Linux
    + kernel, co-written with David Diamond. The book primarily theorizes
    + the Law of Linus that all evolution contributed by humanity starts
    + for survival, sustains socially and entertains at last. As well as
    + this the book explains Torvalds' view of himself, the free software
    + movement and the development of Linux.
    +
    +
    +
    +
    +
    +
    +

    +

    + />
    +


    +
    +
    +
    +

    + THIS IS A DIV.
    +

    THIS IS A PARAGRAPH.


    +

    THIS IS A HEADING.


    +

    +
    +
    +
    + href="#" style="background-color:rgba(0,0,0,0.3)" title="Click me">Magic button
    +
    + src="http://placehold.it/200x150" alt="This is an image" width="200"
    + height="150" title="This is an image">
    +
    +
    +
    +
    +
    +
    +
    + id=name class=a-sweet-block data-counter=175>This is a div.
    +
    +
    +
    +
    diff --git a/autotests/reference/test.bash.ref b/autotests/reference/test.bash.ref new file mode 100644 index 0000000..146f4b3 --- /dev/null +++ b/autotests/reference/test.bash.ref @@ -0,0 +1,6 @@ +#!/bin/bash
    +
    +for i `ls tests/auto/output/*.html`; do
    + refFile=`echo $i | sed s,build,src, | sed s,output,reference, | sed s,.html,.ref.html,`
    + cp $i $refFile
    +done
    diff --git a/autotests/reference/test.bb.ref b/autotests/reference/test.bb.ref new file mode 100644 index 0000000..6755f1a --- /dev/null +++ b/autotests/reference/test.bb.ref @@ -0,0 +1,34 @@ +# syntax test file for Bitbake receipes
    +
    +SUMMARY = "GammaRay Qt introspection probe"
    +HOMEPAGE = "http://www.kdab.com/gammaray"
    +
    +LICENSE = "GPLv2"
    +LIC_FILES_CHKSUM = "file://LICENSE.GPL.txt;md5=2abfe5daa817fd4346b6d55293941415"
    +
    +inherit cmake_qt5
    +
    +SRC_URI = "git://github.com/KDAB/GammaRay;branch=master"
    +
    +SRCREV = "139e003174f48b0c883fc6c200ef2efb7467bff1"
    +PV = "2.4.0+git${SRCPV}"
    +
    +DEPENDS = "qtdeclarative"
    +
    +S = "${WORKDIR}/git"
    +
    +EXTRA_OECMAKE += " -DGAMMARAY_BUILD_UI=OFF"
    +
    +FILES_${PN}-dev += " \
    + /usr/lib/cmake/* \
    + /usr/mkspecs/modules/* \
    +"
    +FILES_${PN}-dbg += " \
    + /usr/lib/.debug/* \
    + /usr/lib/gammaray/*/*/.debug \
    + /usr/lib/gammaray/*/*/styles/.debug \
    +"
    +
    +# error: unterinated string
    +VAR *= "abc
    + this is wrong
    diff --git a/autotests/reference/test.c.ref b/autotests/reference/test.c.ref new file mode 100644 index 0000000..2922209 --- /dev/null +++ b/autotests/reference/test.c.ref @@ -0,0 +1,56 @@ +#include
    +#include "stdint.h"
    +
    +#define SOME_VAR 1
    +#ifdef SOME_VAR
    +
    +#define MULTILINE_MACRO one \
    +two \
    +three
    +
    +static uint64_t intWithSuffix = 42ull;
    +static int octNum = 07232;
    +static int invalidOctNum = 09231;
    +static uint64_t hexNum = 0xDEADBEEF42;
    +static uint64_t invalidHexNum = 0xGLDFKG;
    +static char binNum = 0b0101010;
    +
    +static double d1 = 42.;
    +static double d2 = .42;
    +static double d3 = 42.3e1;
    +static double d4 = .2e-12;
    +static double d5 = 32.e+12;
    +static float floatQualifier = 23.123f;
    +
    +static const char c1 = 'c';
    +static const char c2 = '\n';
    +static const char c2a = '\120'; // octal
    +static const char c2b = '\x1f'; // hex
    +static const char c2c = '\'';
    +static const char c2d = '\\';
    +static const char* c3 = "string";
    +static const char* c4 = "\"string\n\t\012\x12\"";
    +static const char* c5 = "multiline \
    + string";
    +
    +//BEGIN region
    +// TODO comment FIXME comment ### comment
    +//END region
    +
    +#wrong
    +
    +/**
    + * Doxygen
    + * @param p1 text
    + * \brief bold text>
    + * \dot
    + * a -> b
    + * \enddot
    + *
    + * \verbatim
    + *
    + * \endverbatim
    + * text</html>
    + */
    +
    +#endif
    diff --git a/autotests/reference/test.cmake.ref b/autotests/reference/test.cmake.ref new file mode 100644 index 0000000..e9c0a65 --- /dev/null +++ b/autotests/reference/test.cmake.ref @@ -0,0 +1,31 @@ +# comment
    +
    +#[[.rst:
    +MyModule
    +--------
    +
    +bla bla
    +#]]
    +
    +#.rst:
    +# ATTENTION
    +# alternative doc comment
    +#
    +
    +#[=====[.rst:
    +
    +3rd form
    +
    +]=====]
    +
    +set(CMAKE_AUTOMOC ON)
    +if (POLICY CMP042)
    + target_link_libraries(myTaget SHARED Qt5::Core)
    +else()
    + add_executable(myTaget ${some_var})
    +endif()
    +
    +macro(my_macro arg1)
    + foreach(arg ${ARGN})
    + endforeach()
    +endmacro()
    diff --git a/autotests/reference/test.css.ref b/autotests/reference/test.css.ref new file mode 100644 index 0000000..4d24704 --- /dev/null +++ b/autotests/reference/test.css.ref @@ -0,0 +1,18 @@ +h1 {
    + text-color: "red";
    +}
    +
    +/* PHP code, invalid in CSS context */
    +for()
    +
    + echo("hello");
    +
    +// valid code in PHP context
    +for()
    +
    +?>
    +
    +h2 {
    + text-weight: bold;
    +}
    +
    diff --git a/autotests/reference/test.desktop.ref b/autotests/reference/test.desktop.ref new file mode 100644 index 0000000..12ca73f --- /dev/null +++ b/autotests/reference/test.desktop.ref @@ -0,0 +1,19 @@ +# test file for .dekstop syntax highlighting
    +
    [Desktop Entry]

    +GenericName=Text Editor
    +GenericName[ar]=محرّر نصوص
    +Name=KWrite
    +Name[ar]=كاتبك
    +Comment=KDE Text Editor
    +Comment[ar]=محرّر نصوص لكدي
    +MimeType=text/plain;
    +Exec=kwrite %U
    +StartupNotify=true
    +Icon=kwrite
    +X-DocPath=kwrite/index.html
    +Type=Application
    +Terminal=false
    +InitialPreference=8
    +X-DBUS-StartupType=Multi
    +X-DBUS-ServiceName=org.kde.kwrite
    +Categories=Qt;KDE;Utility;TextEditor;
    diff --git a/autotests/reference/test.diff.ref b/autotests/reference/test.diff.ref new file mode 100644 index 0000000..1ddccb2 --- /dev/null +++ b/autotests/reference/test.diff.ref @@ -0,0 +1,48 @@ +commit 2b16665838c8afeaa0f065cafc747438de35876b
    +Author: Volker Krause
    +Date: Sat Oct 8 13:31:51 2016 +0200
    +
    + Implement dynamic DetectChar rules
    +
    + Needed for Perl highlighting.
    +
    +diff --git a/src/lib/rule.cpp b/src/lib/rule.cpp
    +index f588985..c4c3b92 100644
    +
    --- a/src/lib/rule.cpp

    +
    +++ b/src/lib/rule.cpp

    +
    @@ -308,12 +308,22 @@ bool DetectChar::doLoad(QXmlStreamReader& reader)

    + if (s.isEmpty())
    + return false;
    + m_char = s.at(0);
    ++ if (isDynamic()) {
    ++ m_captureIndex = m_char.digitValue();
    ++ }
    + return true;
    + }
    +
    + MatchResult DetectChar::doMatch(const QString& text, int offset, const QStringList &captures)
    + {
    +- Q_UNUSED(captures); // TODO
    ++ if (isDynamic()) {
    ++ if (captures.size() <= m_captureIndex || captures.at(m_captureIndex).isEmpty())
    ++ return offset;
    ++ if (text.at(offset) == captures.at(m_captureIndex).at(0))
    ++ return offset + 1;
    ++ return offset;
    ++ }
    ++
    + if (text.at(offset) == m_char)
    + return offset + 1;
    + return offset;
    +diff --git a/src/lib/rule_p.h b/src/lib/rule_p.h
    +index d8862ae..d9cedbf 100644
    +
    --- a/src/lib/rule_p.h

    +
    +++ b/src/lib/rule_p.h

    +
    @@ -103,6 +103,7 @@ protected:

    +
    + private:
    + QChar m_char;
    ++ int m_captureIndex;
    + };
    +
    + class Detect2Char : public Rule
    diff --git a/autotests/reference/test.eml.ref b/autotests/reference/test.eml.ref new file mode 100644 index 0000000..b7c40ad --- /dev/null +++ b/autotests/reference/test.eml.ref @@ -0,0 +1,94 @@ +Return-Path:
    +X-Sieve: CMU Sieve 2.3
    +X-Virus-Scanned: amavisd-new at site
    +Authentication-Results: linux.site (amavisd-new); dkim=pass (1024-bit key)
    + header.d=kde.org
    +Received: from postbox.kde.org (localhost.localdomain [127.0.0.1])
    + by postbox.kde.org (Postfix) with ESMTP id 3167DB6E75;
    + Wed, 5 Oct 2016 20:21:47 +0000 (UTC)
    +DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=kde.org; s=default;
    + t=1475698907; bh=6i+3UfR6HLC54wVtp5SF4sVWvQn63jzu9vD2zJal/kY=;
    + h=From:To:Subject:Date:Reply-To:List-Id:List-Unsubscribe:List-Post:
    + List-Help:List-Subscribe:From;
    + b=M5nfHbmJe/4DPuidrJ901dUzX3FmpVpyUrPM961Or9bKrMO+z9gaTUwbfPR74Rq8B
    + Rv66yf3ZaDuRZxv/ARPzpr8qnDTtf13WRFZ/ySdqqqQJKeBqCAd7/wbR0kHhypvpwe
    + z4nY6+bNnjvFelPXR56o16b+/Ib2GTYJ9hwiG97U=
    +X-Original-To: kwrite-devel@kde.org
    +Delivered-To: kwrite-devel@localhost.kde.org
    +Received-SPF: Neutral (access neither permitted nor denied) identity=mailfrom;
    + client-ip=85.214.234.26; helo=h2265959.stratoserver.net;
    + envelope-from=vkrause@kde.org; receiver=kwrite-devel@kde.org
    +From: Volker Krause
    +To: kwrite-devel@kde.org
    +Subject: Highlighting semantics: line end context switches when popping back
    + into previous line context stack
    +Date: Wed, 05 Oct 2016 22:19:17 +0200
    +Message-ID: <2420385.jiZKTgWtgY@vkpc5>
    +Organization: KDE
    +User-Agent: KMail/4.14.10 (Linux/4.1.13-5-default; KDE/4.14.16; x86_64;
    + git-91275a7; 2015-12-13)
    +MIME-Version: 1.0
    +Content-Type: multipart/signed; boundary="nextPart1575059.2yRQ5x6HOo";
    + micalg="pgp-sha1"; protocol="application/pgp-signature"
    +X-BeenThere: kwrite-devel@kde.org
    +X-Mailman-Version: 2.1.16
    +Precedence: list
    +Reply-To: kwrite-devel@kde.org
    +List-Id: Kate/KWrite Mailing List
    +List-Unsubscribe: ,
    + kwrite-devel-request@kde.org?subject=unsubscribe>
    +List-Post: kwrite-devel@kde.org>
    +List-Help: kwrite-devel-request@kde.org?subject=help>
    +List-Subscribe: ,
    + kwrite-devel-request@kde.org?subject=subscribe>
    +Errors-To: kwrite-devel-bounces@kde.org
    +Sender: "KWrite-Devel"
    +
    +
    +--nextPart1575059.2yRQ5x6HOo
    +Content-Transfer-Encoding: 7Bit
    +Content-Type: text/plain; charset="us-ascii"
    +
    +Hi,
    +
    +when trying to add the unit test for the new Praat highlighting to
    +KF5::SyntaxHighlighting it turned out that the output doesn't match at all
    +that of Kate. We managed to trace this back to the following rather surprising
    +(and apparently undocumented) behavior in Kate:
    +
    +When a context switch (anywhere in a line) pops more contexts than were on the
    +stack when starting the line, it executes line end context switches of the
    +previous line contexts.
    +
    +| | | | | | The corresponding code is in KateHighlighting::generateContextStack(),
    +| | > | > KF5::SyntaxHighlighting doesn't do this (yet), Praat is apparently the first
    +> | > format we have tests for that uses this behavior.
    +
    +> Does anyone remember why we do this, or happens to know which highlighting
    +> files besides Praat rely on this?
    +
    +> > Archeology can trace this back to the dark CVS ages even, one reference
    +> > Dominik has dug up is a 10 year old SVN commit
    +> > (https://quickgit.kde.org/?p=kdelibs.git&a=commit&h=90ef47f582277745f727d89f05f72f1e1705fdc4
    +> >), where Christoph claims to understand what this code does ;)
    +
    +> > > As this is highly unexpected and hard to reason about behavior, Dominik and I
    +> > > > were wondering if we can possibly drop this, and rather fix affected
    +> > > > > highlighting files instead?
    +
    +Regards,
    +Volker
    +--nextPart1575059.2yRQ5x6HOo
    +Content-Type: application/pgp-signature; name="signature.asc"
    +Content-Description: This is a digitally signed message part.
    +Content-Transfer-Encoding: 7Bit
    +
    +-----BEGIN PGP SIGNATURE-----
    +Version: GnuPG v2
    +
    +iD8DBQBX9WBIf5bM1k0S0kcRAireAJ4lCWa08Y5yU1ezIvKVCAfnkhcUbACgou0O
    +X4c+lkPI0tti59KV1vetaeU=
    +=VqDS
    +-----END PGP SIGNATURE-----
    +
    +--nextPart1575059.2yRQ5x6HOo--
    diff --git a/autotests/reference/test.frag.ref b/autotests/reference/test.frag.ref new file mode 100644 index 0000000..8567197 --- /dev/null +++ b/autotests/reference/test.frag.ref @@ -0,0 +1,26 @@ +#version 330 core
    +
    +// single line comment
    +
    +/* single line commonet */
    +
    +/*
    + multi line comment
    + */
    +
    +in ColorFormat {
    + vec3 color;
    +} fs_in;
    +
    +out vec4 fragColor;
    +
    +vec3 fun(const in vec3 foo) {
    + foo[2] = foo.x;
    +
    + return foo;
    +}
    +
    +void main()
    +{
    + fragColor = vec4( fs_in.color, 1.0 );
    +}
    diff --git a/autotests/reference/test.htm.ref b/autotests/reference/test.htm.ref new file mode 100644 index 0000000..7122070 --- /dev/null +++ b/autotests/reference/test.htm.ref @@ -0,0 +1,17 @@ +HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    +
    +
    + </Element><Normal Text>This is a title</Normal Text><Element>
    +
    +
    +
    + id="xzy">Hello world!


    +
    +
    +
    diff --git a/autotests/reference/test.ijs.ref b/autotests/reference/test.ijs.ref new file mode 100644 index 0000000..cb2ea99 --- /dev/null +++ b/autotests/reference/test.ijs.ref @@ -0,0 +1,61 @@ +Comment
    +NB. This is a single line comment, check regions overlapping priority: 1 2.3 +/ &. 'quoted text'
    +NB.(
    +NB. This is a foldable multi line comment
    +NB.)
    +
    +String literal
    +''
    +''''
    +'This is quoted text'
    +'And this '' and this NB. and this' 'Yet another quoted text'
    +
    +Numeric literal
    +12 34.56 _7.89 1e2 1.2e3 _. _ __ 123j_456 2b111.111 1r23 123456x 1.2e3j4.5e6 _j_ __j_ _.j_. _j3p4j_.
    +
    +Parenthesis
    +( )
    +
    +Adverb
    +~ / \ /. \. } b. f. M. t. t:
    +
    +Conjuction
    +^: . .. .: : :. :: ;. !. !: " ` `: @ @. @: & &. &: &.: d. D. D: H. L: S: T.
    +
    +Control
    +assert. break. case. catch. catchd. catcht. continue. do. else. elseif. end. fcase. for. for_abc. goto_abc. if. label_abc. return. select. throw. try. while. whilst.
    +
    +Copula
    +a =: 123
    +(a) =: 123
    +(a;b;c) =: 123
    +'a b c' =: 123
    +'a b c' =. '123'
    +'`a b c' =. '123'
    +'a' =: 123
    +('a';'b';'c') =: 123
    +
    +Explicit argument
    +x y m n u v x. y. m. n. u. v.
    +
    +Noun
    +a. a:
    +
    +Verb
    += < <. <: > >. >: _: + +. +: * *. *: - -. -: % %. %: ^ ^. $ $. $: ~. ~: | |. |: , ,. ,: ; ;: # #. #: ! /: \: [ [: ] { {. {: {:: }. }: ". ": ? ?. A. C. e. E. i. i: I. j. L. o. p. p.. p: q: r. s: u: x: _9: _8: _7: _6: _5: _4: _3: _2: _1: 0: 1: 2: 3: 4: 5: 6: 7: 8: 9:
    +
    +Combined
    +for_abc. i. 5 do. 55 return. end.
    +a=. b =: 123 +/ # i. 10
    +123 'qwerty'
    +a_b =: '123' [ c__d =. 4 : 0 NB. foldable definition begins
    + x +/ y
    +)
    +e__12 =: define NB. foldable definition begins
    + if. x do. NB. inner foldable region begins
    + y=. y + x NB. comment after code
    + x +/ y
    + else. NB. inner foldable region begins
    + y +/ y
    + end.
    +)
    diff --git a/autotests/reference/test.js.ref b/autotests/reference/test.js.ref new file mode 100644 index 0000000..4b62657 --- /dev/null +++ b/autotests/reference/test.js.ref @@ -0,0 +1,8 @@ +/* comment */
    +
    +function fun()
    +{
    + var boo = { 'key': [ 1, 2.0, 3.0e1, 004, 0x5 ] };
    +}
    +
    +class MyClass; // reserved keywords
    diff --git a/autotests/reference/test.json.ref b/autotests/reference/test.json.ref new file mode 100644 index 0000000..b7f0e52 --- /dev/null +++ b/autotests/reference/test.json.ref @@ -0,0 +1,13 @@ +{
    + "float": 3.1415,
    + "int": 123,
    + "string": "\a \"b' \n",
    + "array": [ 1, 2, 3 ],
    + "object": {
    + "mult-line": "so this folds"
    + },
    + "folded array": [
    + 1, 2, 3
    + ]
    + "error key": "due to missing comma"
    +}
    diff --git a/autotests/reference/test.markdown.ref b/autotests/reference/test.markdown.ref new file mode 100644 index 0000000..52a09d2 --- /dev/null +++ b/autotests/reference/test.markdown.ref @@ -0,0 +1,39 @@ +

    # H1


    +
    +

    ## H2


    +
    +

    ### H3


    +
    +Multi-line paragraph bla bla bla
    +bla bla bla.
    +
    +Intentional line break
    +via two spaces at line.
    +
    +Formats: _italic_, **bold**, `monospace`, ~~strikeout~~
    +
    +Bullet list:
    +
    +* item1
    +* item2
    +
    +Numbered list:
    +
    +1. item 1
    +2. item 2
    +
    +[link](http://kde.org)
    +
    + code 1
    + code 2
    +
    +normal text
    +
    +
    > block quote
    _italic_
    +
    > more block quote

    +
    +normal text
    +
    +Title: some text
    +
    +normal text
    diff --git a/autotests/reference/test.mss.ref b/autotests/reference/test.mss.ref new file mode 100644 index 0000000..a2d1efa --- /dev/null +++ b/autotests/reference/test.mss.ref @@ -0,0 +1,215 @@ +/* kate: hl CartoCSS
    + This file contains some content coming from
    + https://github.com/gravitystorm/openstreetmap-carto
    + with CC0 license. This file is just for testing
    + katepart highlighting engine.
    + */
    +
    +#world {
    +// this syntax
    +polygon-opacity: 50%;
    +
    +// is equivalent to
    +polygon-opacity: 0.5;
    +}
    +
    +@admin-boundaries: #ac46ac;
    +
    +/* For performance reasons, the admin border layers are split into three groups
    +for low, middle and high zoom levels.
    +For each zoomlevel, all borders come from a single attachment, to handle
    +overlapping borders correctly.
    +*/
    +
    +#admin-low-zoom[zoom < 11], // test
    +#admin-mid-zoom[zoom >= 11][zoom < 13],
    +#admin-high-zoom[zoom >= 13] {
    + [admin_level = '2'],
    + [admin_level = '3'] {
    + [zoom >= 4] {
    + background/line-color: white;
    + background/line-width: 0.6;
    + line-color: @admin-boundaries;
    + line-width: 0.6;
    + }
    + [zoom >= 7] {
    + background/line-width: 2;
    + line-width: 2;
    + }
    + [zoom >= 10] {
    + [admin_level = '2'] {
    + background/line-width: 6;
    + line-width: 6;
    + }
    + [admin_level = '3'] {
    + background/line-width: 5;
    + line-width: 5;
    + line-dasharray: 4,2;
    + line-clip: false;
    + }
    + }
    + }
    + [admin_level = '4'] {
    + [zoom >= 4] {
    + background/line-color: white;
    + background/line-width: 0.6;
    + line-color: @admin-boundaries;
    + line-width: 0.6;
    + line-dasharray: 4,3;
    + line-clip: false;
    + }
    + [zoom >= 7] {
    + background/line-width: 1;
    + line-width: 1;
    + }
    + [zoom >= 11] {
    + background/line-width: 3;
    + line-width: 3;
    + }
    + }
    + /*
    + The following code prevents admin boundaries from being rendered on top of
    + each other. Comp-op works on the entire attachment, not on the individual
    + border. Therefore, this code generates an attachment containing a set of
    + @admin-boundaries/white dashed lines (of which only the top one is visible),
    + and with `comp-op: darken` the white part is ignored, while the
    + @admin-boundaries colored part is rendered (as long as the background is not
    + darker than @admin-boundaries).
    + The SQL has `ORDER BY admin_level`, so the boundary with the lowest
    + admin_level is rendered on top, and therefore the only visible boundary.
    + */
    + opacity: 0.4;
    + comp-op: darken;
    +}
    +
    +#admin-mid-zoom[zoom >= 11][zoom < 13],
    +#admin-high-zoom[zoom >= 13] {
    + [admin_level = '5'][zoom >= 11] {
    + background/line-color: white;
    + background/line-width: 2;
    + line-color: @admin-boundaries;
    + line-width: 2;
    + line-dasharray: 6,3,2,3,2,3;
    + line-clip: false;
    + }
    + [admin_level = '6'][zoom >= 11] {
    + background/line-color: white;
    + background/line-width: 2;
    + line-color: @admin-boundaries;
    + line-width: 2;
    + line-dasharray: 6,3,2,3;
    + line-clip: false;
    + }
    + [admin_level = '7'],
    + [admin_level = '8'] {
    + [zoom >= 12] {
    + background/line-color: white;
    + background/line-width: 1.5;
    + line-color: @admin-boundaries;
    + line-width: 1.5;
    + line-dasharray: 5,2;
    + line-clip: false;
    + }
    + }
    + opacity: 0.5;
    + comp-op: darken;
    +}
    +
    +#admin-high-zoom[zoom >= 13] {
    + [admin_level = '9'],
    + [admin_level = '10'] {
    + [zoom >= 13] {
    + background/line-color: white;
    + background/line-width: 2;
    + line-color: @admin-boundaries;
    + line-width: 2;
    + line-dasharray: 2,3;
    + line-clip: false;
    + }
    + }
    + opacity: 0.5;
    + comp-op: darken;
    +}
    +
    +
    +
    +#nature-reserve-boundaries {
    + [way_pixels > 100][zoom >= 7] {
    + [zoom < 10] {
    + ::fill {
    + opacity: 0.05;
    + polygon-fill: green;
    + }
    + }
    + a/line-width: 1;
    + a/line-offset: -0.5;
    + a/line-color: green;
    + a/line-opacity: 0.15;
    + a/line-join: round;
    + a/line-cap: round;
    + b/line-width: 2;
    + b/line-offset: -1;
    + b/line-color: green;
    + b/line-opacity: 0.15;
    + b/line-join: round;
    + b/line-cap: round;
    + [zoom >= 10] {
    + a/line-width: 2;
    + a/line-offset: -1;
    + b/line-width: 4;
    + b/line-offset: -2;
    + }
    + [zoom >= 14] {
    + b/line-width: 6;
    + b/line-offset: -3;
    + }
    + }
    +}
    +
    +#building-text {
    +[zoom >= 14][way_pixels > 3000],
    +[zoom >= 17] {
    +text-name: "[name]";
    +text-size: 11;
    +text-fill: #444;
    +text-face-name: @book-fonts;
    +text-halo-radius: 1;
    +text-wrap-width: 20;
    +text-halo-fill: rgba(255,255,255,0.5);
    +text-placement: interior;
    +}
    +}
    +
    +@marina-text: #576ddf; // also swimming_pool
    +@landcover-face-name: @oblique-fonts;
    +@standard-wrap-width: 30;
    +
    +.points {
    + [feature = 'tourism_alpine_hut'][zoom >= 13] {
    + point-file: url('symbols/alpinehut.p.16.png');
    + point-placement: interior;
    + }
    + }
    +
    + [feature = 'highway_bus_stop'] {
    + [zoom >= 16] {
    + marker-file: url('symbols/square.svg');
    + marker-fill: @transportation-icon;
    + marker-placement: interior;
    + marker-width: 6;
    + }
    + [zoom >= 17] {
    + marker-file: url('symbols/bus_stop.p.12.png');
    + marker-width: 12;
    + }
    + }
    +
    +[feature = 'highway_primary'] {
    +[zoom >= 7][zoom < 12] {
    +line-width: 0.5;
    +line-color: @primary-fill;
    +[zoom >= 9] { line-width: 1.2; }
    +[zoom >= 10] { line-width: 2; }
    +[zoom >= 11] { line-width: .5; }
    +}
    +}
    diff --git a/autotests/reference/test.py.ref b/autotests/reference/test.py.ref new file mode 100644 index 0000000..bb85ce0 --- /dev/null +++ b/autotests/reference/test.py.ref @@ -0,0 +1,28 @@ +# comment with ALERT
    +
    +''' multiline
    + comment
    + ###
    + '''
    +
    +def func(x):
    + """ API docs """
    + if x == 42:
    + func()
    + c1 = {}
    + c2 = {
    + 2.4,
    + 0x42
    + }
    + a1 = []
    + a2 = [
    + "a", 032, (
    + )]
    + else:
    + print("""multi
    + line
    + string""")
    + print("single \
    + continued line ")
    + print('single line')
    + return float(len(a2))
    diff --git a/autotests/reference/test.qml.ref b/autotests/reference/test.qml.ref new file mode 100644 index 0000000..bb65514 --- /dev/null +++ b/autotests/reference/test.qml.ref @@ -0,0 +1,23 @@ +/*
    + * multi line comment
    + */
    +
    +// single line comment
    +
    +import QtQuick 2.0
    +
    +Rectangle {
    + property real myNumProp: 0.1e12;
    + property alias sub.color;
    + signal mySignal(int arg1, string arg2)
    + color: "lightsteelblue"
    + width: 320
    + height: width/2
    +
    + Rectangle {
    + id: sub
    + width: 0x10
    + height: 007
    + objectName: 'single quote'
    + }
    +}
    diff --git a/autotests/reference/test.sql.ref b/autotests/reference/test.sql.ref new file mode 100644 index 0000000..f4bc03f --- /dev/null +++ b/autotests/reference/test.sql.ref @@ -0,0 +1,6 @@ +-- comment
    +
    +CREATE TABLE stuff COLUMNS(col1 INT, col2 Varchar);
    +SELECT * FROM stuff WHERE id = 'string';
    +select * from stuff where id < 0.42;
    +Select col1, col2 From stuff Where stuff.col1 IS NOT NuLL;
    diff --git a/autotests/reference/test.tex.ref b/autotests/reference/test.tex.ref new file mode 100644 index 0000000..46b442c --- /dev/null +++ b/autotests/reference/test.tex.ref @@ -0,0 +1,5 @@ +% commet
    +
    +text \texttt{more text}
    +
    +\verb!verbatim text! normal text
    diff --git a/autotests/reference/test_syntax.sql.ref b/autotests/reference/test_syntax.sql.ref new file mode 100644 index 0000000..9a41ecf --- /dev/null +++ b/autotests/reference/test_syntax.sql.ref @@ -0,0 +1,41 @@ +-- kate: hl SQL (Oracle)
    +-- test case shipped with highlighting in bugzilla, LGPL
    +
    +begin
    + q'{adfasdf'sadfasdf j}'{' hkjhkhkjhkjh khlkhklj'fghdfghdfgh'hkjh'jkhkh'a'
    + Q'(asldflahsl;'dkjfhklsdfh)'
    + q'[asdasd;'asdasd'a]sd'asd'asasd]';11111111[1']; asdasdasdasd'errrrrrrrrrrrrrr-p
    +
    + q'agdfgsdfgfhfghjfgh'f'f'sdfg'sdfg'dfg#a' dafdfadasfasdf;
    +
    + Q'#gdfgsdfgsdfgsdfgsdfg#' afgasasdfasdfasfasdfasdfasdfasdfsdf
    +
    + if sldfjsdj then
    + case
    + when 1=1 then
    + aslfjsldkfj;
    + when 2=2 then
    + asdfg;
    + else
    + null;
    + end case;
    +
    + if sdfjh then
    + for i in 1 .. 2
    + LOOP
    + dbms_output.put_line(q';ololo;');
    + END Loop;
    +
    + while true
    + loop
    + dbms_output.put_line('1111');
    + end loop;
    + end if;
    + ksjfklasjd;
    + fklj;
    + elsif
    + sdklfjsdklfj;
    + else
    + sdfdfsdf;
    + end if;
    +end;
    diff --git a/autotests/repository_benchmark.cpp b/autotests/repository_benchmark.cpp new file mode 100644 index 0000000..f4cfc0f --- /dev/null +++ b/autotests/repository_benchmark.cpp @@ -0,0 +1,40 @@ +/* + Copyright (C) 2016 Volker Krause + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include + +#include +#include + +using namespace KSyntaxHighlighting; + +class RepositoryBenchmark : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void benchmarkReporitoryLoad() + { + QBENCHMARK { + Repository repo; + } + } + +}; + +QTEST_GUILESS_MAIN(RepositoryBenchmark) + +#include "repository_benchmark.moc" diff --git a/autotests/syntaxrepository_test.cpp b/autotests/syntaxrepository_test.cpp new file mode 100644 index 0000000..6e20dae --- /dev/null +++ b/autotests/syntaxrepository_test.cpp @@ -0,0 +1,185 @@ +/* + Copyright (C) 2016 Volker Krause + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace KSyntaxHighlighting { + +class NullHighlighter : public AbstractHighlighter +{ +public: + using AbstractHighlighter::highlightLine; + void applyFormat(int offset, int length, const Format &format) Q_DECL_OVERRIDE + { + Q_UNUSED(offset); + Q_UNUSED(length); + // only here to ensure we don't crash + format.isDefaultTextStyle(theme()); + format.textColor(theme()); + } +}; + +class RepositoryTest : public QObject +{ + Q_OBJECT +private: + Repository m_repo; + +private Q_SLOTS: + void initTestCase() + { + QStandardPaths::enableTestMode(true); + } + + void testDefinitionByExtension_data() + { + QTest::addColumn("fileName"); + QTest::addColumn("defName"); + + QTest::newRow("empty") << QString() << QString(); + QTest::newRow("qml") << QStringLiteral("/bla/foo.qml") << QStringLiteral("QML"); + QTest::newRow("glsl") << QStringLiteral("flat.frag") << QStringLiteral("GLSL"); + // the following ones are defined in multiple syntax definitions + QTest::newRow("c") << QStringLiteral("test.c") << QStringLiteral("C"); + QTest::newRow("c++") << QStringLiteral("test.cpp") << QStringLiteral("C++"); + QTest::newRow("markdown") << QStringLiteral("test.md") << QStringLiteral("Markdown"); + + QTest::newRow("Makefile 1") << QStringLiteral("Makefile") << QStringLiteral("Makefile"); + QTest::newRow("Makefile 2") << QStringLiteral("/some/path/to/Makefile") << QStringLiteral("Makefile"); + QTest::newRow("Makefile 3") << QStringLiteral("Makefile.am") << QStringLiteral("Makefile"); + } + + void testDefinitionByExtension() + { + QFETCH(QString, fileName); + QFETCH(QString, defName); + + auto def = m_repo.definitionForFileName(fileName); + if (defName.isEmpty()) { + QVERIFY(!def.isValid()); + } else { + QVERIFY(def.isValid()); + QCOMPARE(def.name(), defName); + } + } + + void testLoadAll() + { + foreach (const auto &def, m_repo.definitions()) { + QVERIFY(!def.name().isEmpty()); + QVERIFY(!def.translatedName().isEmpty()); + QVERIFY(!def.section().isEmpty()); + QVERIFY(!def.translatedSection().isEmpty()); + // indirectly trigger loading, as we can't reach that from public API + // if the loading fails the highlighter will produce empty states + NullHighlighter hl; + State initialState; + hl.setDefinition(def); + const auto state = hl.highlightLine(QLatin1String("This should not crash } ] ) !"), initialState); + QVERIFY(state != initialState); + } + } + + void testMetaData() + { + auto def = m_repo.definitionForName(QLatin1String("Alerts")); + QVERIFY(def.isValid()); + QVERIFY(def.extensions().isEmpty()); + QVERIFY(def.mimeTypes().isEmpty()); + QVERIFY(def.version() >= 1.11f); + QVERIFY(def.isHidden()); + QCOMPARE(def.section(), QLatin1String("Other")); + QCOMPARE(def.license(), QLatin1String("LGPL")); + QVERIFY(def.author().contains(QLatin1String("Dominik"))); + QFileInfo fi(def.filePath()); + QVERIFY(fi.isAbsolute()); + QVERIFY(def.filePath().endsWith(QLatin1String("alert.xml"))); + + def = m_repo.definitionForName(QLatin1String("C++")); + QVERIFY(def.isValid()); + QCOMPARE(def.section(), QLatin1String("Sources")); + QCOMPARE(def.indenter(), QLatin1String("cstyle")); + QCOMPARE(def.style(), QLatin1String("C++")); + QVERIFY(def.mimeTypes().contains(QLatin1String("text/x-c++hdr"))); + QVERIFY(def.extensions().contains(QLatin1String("*.h"))); + QCOMPARE(def.priority(), 9); + + def = m_repo.definitionForName(QLatin1String("Apache Configuration")); + QVERIFY(def.isValid()); + QVERIFY(def.extensions().contains(QLatin1String("httpd.conf"))); + QVERIFY(def.extensions().contains(QLatin1String(".htaccess*"))); + } + + void testGeneralMetaData() + { + auto def = m_repo.definitionForName(QLatin1String("C++")); + QVERIFY(def.isValid()); + QVERIFY(!def.indentationBasedFoldingEnabled()); + + def = m_repo.definitionForName(QLatin1String("Python")); + QVERIFY(def.isValid()); + QVERIFY(def.indentationBasedFoldingEnabled()); + QCOMPARE(def.foldingIgnoreList(), QStringList() << QLatin1String("(?:\\s+|\\s*#.*)")); + } + + void testReload() + { + auto def = m_repo.definitionForName(QLatin1String("QML")); + QVERIFY(!m_repo.definitions().isEmpty()); + QVERIFY(def.isValid()); + + NullHighlighter hl; + hl.setDefinition(def); + auto oldState = hl.highlightLine(QLatin1String("/* TODO this should not crash */"), State()); + + m_repo.reload(); + QVERIFY(!m_repo.definitions().isEmpty()); + QVERIFY(!def.isValid()); + + hl.highlightLine(QLatin1String("/* TODO this should not crash */"), State()); + hl.highlightLine(QLatin1String("/* FIXME neither should this crash */"), oldState); + QVERIFY(hl.definition().isValid()); + QCOMPARE(hl.definition().name(), QLatin1String("QML")); + } + + void testLifetime() + { + // common mistake with value-type like Repo API, make sure this doesn'T crash + NullHighlighter hl; + { + Repository repo; + hl.setDefinition(repo.definitionForName(QLatin1String("C++"))); + hl.setTheme(repo.defaultTheme()); + } + hl.highlightLine(QLatin1String("/**! @todo this should not crash .*/"), State()); + } +}; +} + +QTEST_GUILESS_MAIN(KSyntaxHighlighting::RepositoryTest) + +#include "syntaxrepository_test.moc" diff --git a/autotests/test-config.h.in b/autotests/test-config.h.in new file mode 100644 index 0000000..5d27ebd --- /dev/null +++ b/autotests/test-config.h.in @@ -0,0 +1,19 @@ +/* + Copyright (C) 2016 Volker Krause + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#define TESTSRCDIR "@CMAKE_CURRENT_SOURCE_DIR@" +#define TESTBUILDDIR "@CMAKE_CURRENT_BINARY_DIR@" diff --git a/autotests/testhighlighter.cpp b/autotests/testhighlighter.cpp new file mode 100644 index 0000000..f802381 --- /dev/null +++ b/autotests/testhighlighter.cpp @@ -0,0 +1,186 @@ +/* + Copyright (C) 2016 Volker Krause + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "test-config.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace KSyntaxHighlighting; + +class TestHighlighter : public AbstractHighlighter +{ +public: + void highlightFile(const QString &inFileName, const QString &outFileName) + { + QFile outFile(outFileName); + if (!outFile.open(QFile::WriteOnly | QFile::Truncate)) { + qWarning() << "Failed to open output file" << outFileName << ":" << outFile.errorString(); + return; + } + m_out.setDevice(&outFile); + m_out.setCodec("UTF-8"); + + QFile f(inFileName); + if (!f.open(QFile::ReadOnly)) { + qWarning() << "Failed to open input file" << inFileName << ":" << f.errorString(); + return; + } + + QTextStream in(&f); + in.setCodec("UTF-8"); + State state; + while (!in.atEnd()) { + m_currentLine = in.readLine(); + state = highlightLine(m_currentLine, state); + m_out << "
    \n"; + } + + m_out.flush(); + } + +protected: + void applyFormat(int offset, int length, const Format &format) Q_DECL_OVERRIDE + { + if (format.name().isEmpty()) + m_out << "" << m_currentLine.midRef(offset, length) << ""; + else + m_out << "<" << format.name() << ">" << m_currentLine.midRef(offset, length) << ""; + } + +private: + QTextStream m_out; + QString m_currentLine; +}; + + +class TestHighlighterTest : public QObject +{ + Q_OBJECT +public: + explicit TestHighlighterTest(QObject *parent = Q_NULLPTR) : QObject(parent), m_repo(Q_NULLPTR) {} +private: + Repository *m_repo; + QSet m_coveredDefinitions; + +private Q_SLOTS: + void initTestCase() + { + QStandardPaths::enableTestMode(true); + m_repo = new Repository; + } + + void cleanupTestCase() + { + QFile coveredList(QLatin1String(TESTBUILDDIR "/covered-definitions.txt")); + QFile uncoveredList(QLatin1String(TESTBUILDDIR "/uncovered-definition.txt")); + QVERIFY(coveredList.open(QFile::WriteOnly)); + QVERIFY(uncoveredList.open(QFile::WriteOnly)); + + int count = 0; + foreach (const auto &def, m_repo->definitions()) { + if (def.isHidden()) + continue; + ++count; + if (m_coveredDefinitions.contains(def.name())) + coveredList.write(def.name().toUtf8() + '\n'); + else + uncoveredList.write(def.name().toUtf8() + '\n'); + } + + qDebug() << "Syntax definitions with test coverage:" << ((float)m_coveredDefinitions.size() * 100.0f / (float)count) << "%"; + + delete m_repo; + m_repo = Q_NULLPTR; + } + + void testHighlight_data() + { + QTest::addColumn("inFile"); + QTest::addColumn("outFile"); + QTest::addColumn("refFile"); + QTest::addColumn("syntax"); + + QDirIterator it(QStringLiteral(TESTSRCDIR "/input"), QDir::Files | QDir::NoSymLinks | QDir::Readable); + while (it.hasNext()) { + const auto inFile = it.next(); + if (inFile.endsWith(QLatin1String(".syntax"))) + continue; + + QString syntax; + QFile syntaxOverride(inFile + QStringLiteral(".syntax")); + if (syntaxOverride.exists() && syntaxOverride.open(QFile::ReadOnly)) + syntax = QString::fromUtf8(syntaxOverride.readAll()).trimmed(); + + QTest::newRow(it.fileName().toUtf8().constData()) << inFile + << (QStringLiteral(TESTBUILDDIR "/output/") + it.fileName() + QStringLiteral(".ref")) + << (QStringLiteral(TESTSRCDIR "/reference/") + it.fileName() + QStringLiteral(".ref")) + << syntax; + } + + QDir().mkpath(QStringLiteral(TESTBUILDDIR "/output/")); + } + + void testHighlight() + { + QFETCH(QString, inFile); + QFETCH(QString, outFile); + QFETCH(QString, refFile); + QFETCH(QString, syntax); + QVERIFY(m_repo); + + auto def = m_repo->definitionForFileName(inFile); + if (!syntax.isEmpty()) + def = m_repo->definitionForName(syntax); + + TestHighlighter highlighter; + highlighter.setTheme(m_repo->defaultTheme()); + QVERIFY(highlighter.theme().isValid()); + + QVERIFY(def.isValid()); + qDebug() << "Using syntax" << def.name(); + m_coveredDefinitions.insert(def.name()); + highlighter.setDefinition(def); + highlighter.highlightFile(inFile, outFile); + + auto args = QStringList() << QStringLiteral("-u") << refFile << outFile; + QProcess proc; + proc.setProcessChannelMode(QProcess::ForwardedChannels); + proc.start(QStringLiteral("diff"), args); + QVERIFY(proc.waitForFinished()); + QCOMPARE(proc.exitCode(), 0); + } + +}; + +QTEST_GUILESS_MAIN(TestHighlighterTest) + +#include "testhighlighter.moc" + + diff --git a/autotests/theme_test.cpp b/autotests/theme_test.cpp new file mode 100644 index 0000000..cd6173c --- /dev/null +++ b/autotests/theme_test.cpp @@ -0,0 +1,177 @@ +/* + Copyright (C) 2016 Volker Krause + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 Library General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace KSyntaxHighlighting { + +class FormatCollector : public AbstractHighlighter +{ +public: + using AbstractHighlighter::highlightLine; + void applyFormat(int offset, int length, const Format &format) Q_DECL_OVERRIDE + { + Q_UNUSED(offset); + Q_UNUSED(length); + formatMap.insert(format.name(), format); + } + QHash formatMap; +}; + +class ThemeTest : public QObject +{ + Q_OBJECT +private: + Repository m_repo; + +private Q_SLOTS: + void initTestCase() + { + QStandardPaths::enableTestMode(true); + } + + void testThemes() + { + QVERIFY(!m_repo.themes().isEmpty()); + Q_FOREACH (const auto &theme, m_repo.themes()) { + QVERIFY(theme.isValid()); + QVERIFY(!theme.name().isEmpty()); + QVERIFY(!theme.filePath().isEmpty()); + QVERIFY(QFileInfo::exists(theme.filePath())); + QVERIFY(m_repo.theme(theme.name()).isValid()); + } + } + + void testFormat_data() + { + QTest::addColumn("themeName"); + QTest::newRow("default") << "Default"; + QTest::newRow("dark") << "Breeze Dark"; + QTest::newRow("print") << "Printing"; + } + + void testFormat() + { + QFETCH(QString, themeName); + + // somewhat complicated way to get proper Format objects + FormatCollector collector; + collector.setDefinition(m_repo.definitionForName(QLatin1String("QML"))); + const auto t = m_repo.theme(themeName); + QVERIFY(t.isValid()); + collector.setTheme(t); + collector.highlightLine(QLatin1String("normal + property real foo: 3.14"), State()); + + QVERIFY(collector.formatMap.size() >= 4); + qDebug() << collector.formatMap.keys(); + + // normal text + auto f = collector.formatMap.value(QLatin1String("Normal Text")); + QVERIFY(f.isValid()); + QVERIFY(f.isDefaultTextStyle(t)); + QVERIFY(!f.hasTextColor(t)); + QVERIFY(!f.hasBackgroundColor(t)); + QVERIFY(f.id() > 0); + + // visually identical to normal text + f = collector.formatMap.value(QLatin1String("Symbol")); + QVERIFY(f.isValid()); + QVERIFY(f.isDefaultTextStyle(t)); + QVERIFY(!f.hasTextColor(t)); + QVERIFY(f.id() > 0); + + // visually different to normal text + f = collector.formatMap.value(QLatin1String("Keywords")); + QVERIFY(f.isValid()); + QVERIFY(!f.isDefaultTextStyle(t)); + QVERIFY(f.isBold(t)); + QVERIFY(f.id() > 0); + + f = collector.formatMap.value(QLatin1String("Float")); + QVERIFY(f.isValid()); + QVERIFY(!f.isDefaultTextStyle(t)); + QVERIFY(f.hasTextColor(t)); + QVERIFY(f.id() > 0); + } + + void testDefaultTheme() + { + Theme t = m_repo.theme(QLatin1String("Default")); + QVERIFY(t.isValid()); + + // make sure all editor colors are properly read + QCOMPARE(t.editorColor(Theme::BackgroundColor) , QColor("#ffffff").rgb()); + QCOMPARE(t.editorColor(Theme::TextSelection) , QColor("#94caef").rgb()); + QCOMPARE(t.editorColor(Theme::CurrentLine) , QColor("#f8f7f6").rgb()); + QCOMPARE(t.editorColor(Theme::SearchHighlight) , QColor("#ffff00").rgb()); + QCOMPARE(t.editorColor(Theme::ReplaceHighlight) , QColor("#00ff00").rgb()); + QCOMPARE(t.editorColor(Theme::BracketMatching) , QColor("#ffff00").rgb()); + QCOMPARE(t.editorColor(Theme::TabMarker) , QColor("#d2d2d2").rgb()); + QCOMPARE(t.editorColor(Theme::SpellChecking) , QColor("#bf0303").rgb()); + QCOMPARE(t.editorColor(Theme::IndentationLine) , QColor("#d2d2d2").rgb()); + QCOMPARE(t.editorColor(Theme::IconBorder) , QColor("#f0f0f0").rgb()); + QCOMPARE(t.editorColor(Theme::CodeFolding) , QColor("#94caef").rgb()); + QCOMPARE(t.editorColor(Theme::LineNumbers) , QColor("#a0a0a0").rgb()); + QCOMPARE(t.editorColor(Theme::CurrentLineNumber), QColor("#1e1e1e").rgb()); + QCOMPARE(t.editorColor(Theme::WordWrapMarker) , QColor("#ededed").rgb()); + QCOMPARE(t.editorColor(Theme::ModifiedLines) , QColor("#fdbc4b").rgb()); + QCOMPARE(t.editorColor(Theme::SavedLines) , QColor("#2ecc71").rgb()); + QCOMPARE(t.editorColor(Theme::Separator) , QColor("#898887").rgb()); + QCOMPARE(t.editorColor(Theme::MarkBookmark) , QColor("#0000ff").rgb()); + QCOMPARE(t.editorColor(Theme::MarkBreakpointActive), QColor("#ff0000").rgb()); + QCOMPARE(t.editorColor(Theme::MarkBreakpointReached), QColor("#ffff00").rgb()); + QCOMPARE(t.editorColor(Theme::MarkBreakpointDisabled), QColor("#ff00ff").rgb()); + QCOMPARE(t.editorColor(Theme::MarkExecution) , QColor("#a0a0a4").rgb()); + QCOMPARE(t.editorColor(Theme::MarkWarning) , QColor("#00ff00").rgb()); + QCOMPARE(t.editorColor(Theme::MarkError) , QColor("#ff0000").rgb()); + QCOMPARE(t.editorColor(Theme::TemplateBackground), QColor("#d6d2d0").rgb()); + QCOMPARE(t.editorColor(Theme::TemplatePlaceholder), QColor("#baf8ce").rgb()); + QCOMPARE(t.editorColor(Theme::TemplateFocusedPlaceholder), QColor("#76da98").rgb()); + QCOMPARE(t.editorColor(Theme::TemplateReadOnlyPlaceholder), QColor("#f6e6e6").rgb()); + } + + void testInvalidTheme() + { + // somewhat complicated way to get proper Format objects + FormatCollector collector; + collector.setDefinition(m_repo.definitionForName(QLatin1String("QML"))); + collector.highlightLine(QLatin1String("normal + property real foo: 3.14"), State()); + + QVERIFY(collector.formatMap.size() >= 4); + auto f = collector.formatMap.value(QLatin1String("Normal Text")); + QVERIFY(f.isValid()); + QVERIFY(f.isDefaultTextStyle(Theme())); + QVERIFY(!f.hasTextColor(Theme())); + QVERIFY(!f.hasBackgroundColor(Theme())); + } +}; +} + +QTEST_GUILESS_MAIN(KSyntaxHighlighting::ThemeTest) + +#include "theme_test.moc" + diff --git a/autotests/update-reference-data.sh.in b/autotests/update-reference-data.sh.in new file mode 100755 index 0000000..1b5e45e --- /dev/null +++ b/autotests/update-reference-data.sh.in @@ -0,0 +1,5 @@ +#!/bin/sh + +cp @CMAKE_CURRENT_BINARY_DIR@/output/* @CMAKE_CURRENT_SOURCE_DIR@/reference/ +cp @CMAKE_CURRENT_BINARY_DIR@/html.output/* @CMAKE_CURRENT_SOURCE_DIR@/html/ +cp @CMAKE_CURRENT_BINARY_DIR@/folding.out/* @CMAKE_CURRENT_SOURCE_DIR@/folding/ diff --git a/autotests/wildcardmatcher_test.cpp b/autotests/wildcardmatcher_test.cpp new file mode 100644 index 0000000..5b572d8 --- /dev/null +++ b/autotests/wildcardmatcher_test.cpp @@ -0,0 +1,87 @@ +/* This file is part of the KDE libraries + Copyright (C) 2007 Sebastian Pipping + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include + +class WildcardMatcherTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void testPositiveMatch_data() + { + QTest::addColumn("str"); + QTest::addColumn("pattern"); + + QTest::newRow("*.txt") << "abc.txt" << "*.txt"; + + QTest::newRow("*Makefile* 1") << "Makefile.am" << "*Makefile*"; + QTest::newRow("*Makefile* 2") << "Makefile.am" << "Makefile*"; + + QTest::newRow("control") << "control" << "control"; + + QTest::newRow("a??d") << "abcd" << "a??d"; + + QTest::newRow("?") << "a" << "?"; + QTest::newRow("*?*") << "a" << "*?*"; + QTest::newRow("*") << "a" << "*"; + QTest::newRow("**") << "a" << "**"; + QTest::newRow("***") << "a" << "***"; + + QTest::newRow("empty 1") << "" << "*"; + QTest::newRow("empty 2") << "" << "**"; + + QTest::newRow("a*") << "ab" << "a*"; + QTest::newRow("*b") << "ab" << "*b"; + QTest::newRow("a?") << "ab" << "a?"; + QTest::newRow("?b") << "ab" << "?b"; + + QTest::newRow("a*b*c") << "aXXbXXbYYaYc" << "a*b*c"; + } + + void testPositiveMatch() + { + QFETCH(QString, str); + QFETCH(QString, pattern); + QVERIFY(KSyntaxHighlighting::WildcardMatcher::exactMatch(str, pattern)); + } + + void testNegativeMatch_data() + { + QTest::addColumn("str"); + QTest::addColumn("pattern"); + + QTest::newRow("*.cpp") << "abc.txt" << "*.cpp"; + QTest::newRow("*Makefile* 3") << "Makefile.am" << "Makefile"; + QTest::newRow("?") << "" << "?"; + } + + void testNegativeMatch() + { + QFETCH(QString, str); + QFETCH(QString, pattern); + QVERIFY(!KSyntaxHighlighting::WildcardMatcher::exactMatch(str, pattern)); + } +}; + +QTEST_GUILESS_MAIN(WildcardMatcherTest) + +#include "wildcardmatcher_test.moc" diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt new file mode 100644 index 0000000..0878237 --- /dev/null +++ b/data/CMakeLists.txt @@ -0,0 +1,51 @@ +# generate PHP definitions +macro(generate_php_syntax_definition targetFile srcFile) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${targetFile} + COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/generators/generate-php.pl < ${CMAKE_CURRENT_SOURCE_DIR}/syntax/${srcFile} > ${CMAKE_CURRENT_BINARY_DIR}/${targetFile} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/generators/generate-php.pl ${CMAKE_CURRENT_SOURCE_DIR}/syntax/${srcFile} + ) +endmacro() + +generate_php_syntax_definition(javascript-php.xml javascript.xml) +generate_php_syntax_definition(css-php.xml css.xml) +generate_php_syntax_definition(html-php.xml html.xml) + +# find all definitions +file(GLOB src_defs "${CMAKE_CURRENT_SOURCE_DIR}/syntax/*.xml") +set(defs + ${src_defs} + ${CMAKE_CURRENT_BINARY_DIR}/html-php.xml + ${CMAKE_CURRENT_BINARY_DIR}/css-php.xml + ${CMAKE_CURRENT_BINARY_DIR}/javascript-php.xml +) + +# generate the resource file +set(qrc_file ${CMAKE_CURRENT_BINARY_DIR}/syntax-data.qrc) +file(REMOVE ${qrc_file}) +file(APPEND ${qrc_file} "\n") +file(APPEND ${qrc_file} "\n") +file(APPEND ${qrc_file} "\n") +foreach(def ${defs}) + get_filename_component(def_name ${def} NAME) + file(APPEND ${qrc_file} "${def}\n") +endforeach() +file(APPEND ${qrc_file} "${CMAKE_CURRENT_BINARY_DIR}/index.katesyntax\n") +file(APPEND ${qrc_file} "\n") +file(APPEND ${qrc_file} "\n") + +# generate the index file +add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/index.katesyntax" + COMMAND katehighlightingindexer "${CMAKE_CURRENT_BINARY_DIR}/index.katesyntax" "${CMAKE_CURRENT_SOURCE_DIR}/schema/language.xsd" "${CMAKE_CURRENT_BINARY_DIR}/syntax-data.qrc" + DEPENDS ${defs} ${CMAKE_CURRENT_SOURCE_DIR}/schema/language.xsd ${CMAKE_CURRENT_BINARY_DIR}/syntax-data.qrc +) + +# generate the qrc file manually, to make dependencies on generated files work... +add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/qrc_syntax-data.cpp" + COMMAND ${Qt5Core_RCC_EXECUTABLE} --name syntax_data -o "${CMAKE_CURRENT_BINARY_DIR}/qrc_syntax-data.cpp" "${CMAKE_CURRENT_BINARY_DIR}/syntax-data.qrc" + DEPENDS ${defs} ${CMAKE_CURRENT_BINARY_DIR}/index.katesyntax +) + +# dummy static lib to make cross-folder dependencies work +add_library(SyntaxHighlightingData STATIC ${CMAKE_CURRENT_BINARY_DIR}/qrc_syntax-data.cpp) +target_link_libraries(SyntaxHighlightingData LINK_PRIVATE Qt5::Core) diff --git a/data/generators/cmake-gen.sh b/data/generators/cmake-gen.sh new file mode 100755 index 0000000..860ad63 --- /dev/null +++ b/data/generators/cmake-gen.sh @@ -0,0 +1,110 @@ +#!/bin/env bash +# Copyright 2008, 2009 Matthew Woehlke (mw_triad@users.sourceforge.net) +# Copyright 2013, Alex Turbov (i.zaufi@gmail.com) +# +# ATTENTION Since Thu Feb 26 2015 this generator is CMake 3.x only! +# Use this generator with care and merge a results with a previous cmake.xml +# to keep older CMake compatibility. +# +# NOTE CMake 3.x seem do not have any (useless) heading for --help-xxx commands. +# So, no need to strip the first line anymore. ( | sed '1d' | ) + +export LC_ALL=C + +# need cmake +CMAKE="$(type -P cmake)" +[ -x "$CMAKE" ] || exit 1 +echo "found cmake... $CMAKE" + +t=.tmp_cmake$$ + +# Get cmake version +CMAKE_VERSION="$("$CMAKE" --help | sed -n '1p')" + +count() { + wc -l $t.$1 | awk '{print $1}' +} + +# Extract before/after command list +sed -n -e '/ $t.1 +sed -e '/<\/list\s*>/ba' -e 'd' -e ':a' -e 'n;ba' cmake.xml > $t._2 +sed -n -e '/ $t.2 +sed "1,$(wc -l < $t.2)d" $t._2 | sed -e '/<\/list\s*>/ba' -e 'd' -e ':a' -e 'n;ba' > $t._3 +sed -n -e '/ $t.3 +sed "1,$(wc -l < $t.3)d" $t._3 | sed -e '/<\/list\s*>/ba' -e 'd' -e ':a' -e 'n;ba' > $t._4 +sed -n -e '/ $t.4 +sed "1,$(wc -l < $t.4)d" $t._4 | sed -e '/<\/list\s*>/ba' -e 'd' -e ':a' -e 'n;ba' > $t._5 +sed -n -e '/ $t.5 +sed "1,$(wc -l < $t.5)d" $t._5 | sed -e '/<\/context\s*>/ba' -e 'd' -e ':a' -e 'n;ba' > $t.6 + +"$CMAKE" --help-command-list | sort > $t.commands +echo "$(count commands) commands" + +extract_args() { + sed -e '/^\s\+'"$1"'(/ba' \ + -e 'd' \ + -e ':a' \ + -e '/)/{s/^.*(\(.*\)).*$/\1/p;d}' \ + -e 'N;s/\n/ /;ba' | \ + sed -e 's/[][]//g' -e 's/|\| \+/\n/g' -e 's/<[[:upper:][:digit:]_]\+>//g' -e 's/[<>]//g' | \ + sed -n '/^[[:upper:][:digit:]_]\+$/p' | \ + # NOTE Remove some false-positives: + # 0) one-letter-commands -- found from usage examples + # 1) CMP from cmake_policy will be handled individually + # 2) fix incorrect parsing of separate_arguments(): append UNIX_COMMAND + # 3) 'VAR' actually is not a part of any command! + sed -e '/^[A-Z]$/d' -e '/^CMP$/d' -e 's/\(WINDOWS_COMMAND\)/\1\nUNIX_COMMAND/' -e '/^VAR[0-9]*$/d' \ + >> $t.args +} + +while read COMMAND ; do + echo "# Getting args of '$COMMAND' command" >>$t.args + "$CMAKE" --help-command $COMMAND | extract_args $COMMAND +done < $t.commands +sed '/^#/d' $t.args | sort -u > $t.argsu +echo "$(count args) arguments, $(count argsu) unique" +"$CMAKE" --help-property-list | sed -e '/[<>]/d' | sort -u > $t.props +echo "$(count props) properties" + +# Get builtin CMake variables list +# ATTENTION CMake 3.x doesn't have "Project name" string anymore in output of this command +# ( | grep -v 'Project name' | ) +"$CMAKE" --help-variable-list > $t.all_vars +grep '^[A-Za-z_0-9]\+\s*$' $t.all_vars | sort -u > $t.vars +grep -v '^[A-Za-z_0-9]\+\s*$' $t.all_vars \ + | sed 's,,[A-Za-z_][A-Za-z_0-9]*,' \ + | sed 's,,[A-Za-z_][A-Za-z_0-9]*,' \ + | sed 's,,[A-Za-z_][A-Za-z_0-9]*,' \ + | sed 's,,[A-Za-z_][A-Za-z_0-9]*,' \ + | sed 's,,[A-Za-z_][A-Za-z_0-9]*,' \ + | sed 's,CMP,CMP[0-9]+,' \ + | sed 's,\[CMAKE_BUILD_TYPE\],[A-Za-z_][A-Za-z_0-9]*,' \ + | sort -u \ + > $t.varsrr +echo "$(count all_vars) builtin variables" + + +# Generate new .xml +{ + cat $t.1 + echo " " + sed 's!.*! & !' $t.commands + cat $t.2 + echo " " + sed 's!.*! & !' $t.argsu + cat $t.3 + echo " " + sed 's!.*! & !' $t.props + cat $t.4 + echo " " + sed 's!.*! & !' $t.vars + cat $t.5 + echo " " + sed 's!.*! !' $t.varsrr + cat $t.6 +} > cmake.xml + +rm -f $t.* +echo "Remember to update the version!" + +# kate: tab-width 4; indent-mode normal; indent-width 4; diff --git a/data/generators/generate-php.pl b/data/generators/generate-php.pl new file mode 100755 index 0000000..943c055 --- /dev/null +++ b/data/generators/generate-php.pl @@ -0,0 +1,58 @@ +#!/usr/bin/perl + +# This perl script read stdin and write on stdout. It shall be an XML language file. +# +# * If the name of the language is 'HTML', then it creates the language 'PHP (HTML)' +# which shall be used for PHP hl. +# +# * If the name of the language is something else (say '*'), it creates the language '*/PHP'. +# This new language is the same as the old one, but is able to detect PHP everywhere. +# +# This script will correctly set extensions & mimetype, and will replace +# by +# +# Generated languages need a language named 'PHP/PHP', which shall take care of PHP hl itself +# and which will be called every time something like +# License: LGPL + +my $file = ""; + +while (<>) +{ + $file .= $_; +} + +$warning = "\n\n\n"; + +$file =~ s/(?=]+name="HTML"/) +{ + $root = 1; +} + +if ($root == 1) +{ + $file =~ s/]+)name="[^"]*"/]+)section="[^"]*"/]+)extensions="[^"]*"/]+)mimetype="[^"]*"/]+)name="([^"]*)"/