├── .gitattributes ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── makefile └── src ├── astyle.h ├── astyle ├── ASBeautifier.cpp ├── ASFormatter.cpp ├── ASResource.cpp └── ASStreamIterator.cpp ├── astyle_main.cpp └── compiler_defines.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.cpp text 7 | *.h text 8 | makefile text 9 | 10 | LICENSE text 11 | *.md text 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Starting simple 2 | *.o 3 | iStyle 4 | bin 5 | dep 6 | obj 7 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ---------------------- 2 | # Usage 3 | # 1. cd to current dir(where CmakeLists.txt exists); 4 | # 2. create directory build; 5 | # 3. cd to build; 6 | # 4. run command: $cmake .. 7 | # 5. run command: $make 8 | # enjoy! 9 | 10 | # ---------------------- 11 | # Using cmake-gui 12 | # 1. open cmake-gui window; 13 | # 2. click "Browse Source" and select current dir(where CmakeLists.txt exists); 14 | # 3. click "Browse Build" and select anywhere you want to put the build files; 15 | # 4. click "Configure" and select the compiler to use; 16 | # 5. click "Generate" and make files or nmake files(MSVC) will be generated in the build folder you have selected; 17 | # 6. go to your build folder or just click "Open Project"; 18 | # 7. run make or build with Microsoft Visual Studio; 19 | # enjoy! 20 | 21 | # ---------------------- 22 | # Tested on: 23 | # 1. Windows 10 with Microsoft Visual Studio 2019; 24 | # 2. Ubuntu 20.04 with gcc 10.0; 25 | 26 | cmake_minimum_required(VERSION 3.17) 27 | 28 | # ---------------------- 29 | # set cmake base info 30 | set(CMAKE_CXX_STANDARD 11) 31 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 32 | set(CMAKE_CXX_EXTENSIONS OFF) 33 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 34 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 35 | 36 | # -------------------- 37 | # Set Target Info 38 | set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "Where to install output files") 39 | set(CMAKE_DEBUG_POSTFIX d) 40 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 41 | 42 | set(PROJECT_NAME istyle) 43 | project(${PROJECT_NAME} VERSION 0.0.1 LANGUAGES CXX) 44 | 45 | set(PROJ_SRC_H "") 46 | set(PROJ_SRC_CPP "") 47 | 48 | file(GLOB_RECURSE src_h 49 | LIST_DIRECTORIES false 50 | RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/src/ 51 | "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h" 52 | "${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp" 53 | ) 54 | 55 | foreach(src ${src_h}) 56 | set(src_path_absolute ${CMAKE_CURRENT_SOURCE_DIR}/src/${src}) 57 | get_filename_component(src_path "${src}" PATH) 58 | string(REPLACE "/" "\\" src_path_msvc "${src_path}") 59 | list(APPEND PROJ_SRC_H ${src_path_absolute}) 60 | source_group("${src_path_msvc}" FILES "${src_path_absolute}") 61 | endforeach() 62 | 63 | file(GLOB_RECURSE src_cpp 64 | LIST_DIRECTORIES false 65 | RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/src/ 66 | "${CMAKE_CURRENT_SOURCE_DIR}/src/*.c" 67 | "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp" 68 | ) 69 | 70 | foreach(src ${src_cpp}) 71 | set(src_path_absolute ${CMAKE_CURRENT_SOURCE_DIR}/src/${src}) 72 | get_filename_component(src_path "${src}" PATH) 73 | string(REPLACE "/" "\\" src_path_msvc "${src_path}") 74 | list(APPEND PROJ_SRC_CPP ${src_path_absolute}) 75 | source_group("${src_path_msvc}" FILES "${src_path_absolute}") 76 | endforeach() 77 | 78 | add_executable(${PROJECT_NAME} ${PROJ_SRC_H} ${PROJ_SRC_CPP}) 79 | 80 | target_include_directories(${PROJECT_NAME} 81 | PRIVATE 82 | ${CMAKE_CURRENT_SOURCE_DIR}/src/ 83 | ) 84 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iStyle v1 # 2 | ## Fast and Free Automatic Formatter for Verilog Source Code ## 3 | ``` 4 | Created by haimag 5 | Thanks to Tal Davidson & Astyle 6 | Report bugs https://github.com/thomasrussellmurphy/istyle-verilog-formatter/issues 7 | ``` 8 | 9 | > Originally hosted at http://code.google.com/p/istyle-verilog-formatter before Google Code EOL 10 | 11 | ``` 12 | Usage: 13 | iStyle [options] Foo.v B*r.v [...] 14 | OR, use stdin/stdout 15 | iStyle [options] Foo_formatted.v 16 | 17 | When indenting a specific file, the resulting indented file RETAINS the 18 | original file-name. The original pre-indented file is renamed, with a 19 | suffix of ".orig" added to the original filename. 20 | 21 | By default, iStyle is set up to indent Verilog files, with 4 spaces per 22 | indent, a maximal indentation of 40 spaces inside continuous statements, 23 | and NO formatting. 24 | ``` 25 | ## Option's Format: ## 26 | 27 | --- 28 | 29 | ``` 30 | Long options (starting with '--') must be written one at a time. 31 | Short options (starting with '-') may be appended together. 32 | Thus, -bps4 is the same as -b -p -s4. 33 | ``` 34 | ## Predefined Styling options: ## 35 | 36 | --- 37 | 38 | ``` 39 | --style=ansi 40 | ANSI style formatting/indenting. 41 | 42 | --style=kr 43 | Kernighan&Ritchie style formatting/indenting. 44 | 45 | --style=gnu 46 | GNU style formatting/indenting. 47 | ``` 48 | ## Indentation options: ## 49 | 50 | --- 51 | 52 | ``` 53 | -s OR -s# OR --indent=spaces=# 54 | Indent using # spaces per indent. Not specifying # 55 | will result in a default of 4 spaces per indent. 56 | 57 | -t OR -t# OR --indent=tab=# 58 | Indent using tab characters, assuming that each 59 | tab is # spaces long. Not specifying # will result 60 | in a default assumption of 4 spaces per tab. 61 | 62 | -T# OR --force-indent=tab=# 63 | Indent using tab characters, assuming that each 64 | tab is # spaces long. Force tabs to be used in areas 65 | iStyle would prefer to use spaces. 66 | 67 | -B OR --indent-brackets 68 | Add extra indentation to 'begin' and 'end' block brackets. 69 | 70 | -G OR --indent-blocks 71 | Add extra indentation entire blocks (including brackets). 72 | 73 | -m# OR --min-conditional-indent=# 74 | Indent a minimal # spaces in a continuous conditional 75 | belonging to a conditional header. 76 | 77 | -M# OR --max-instatement-indent=# 78 | Indent a maximal # spaces in a continuous statement, 79 | relatively to the previous line. 80 | 81 | -E OR --fill-empty-lines 82 | Fill empty lines with the white space of their 83 | previous lines. 84 | 85 | --indent-preprocessor 86 | Indent multi-line #define statements 87 | ``` 88 | ## Formatting options: ## 89 | 90 | --- 91 | 92 | ``` 93 | -b OR --brackets=break 94 | Break brackets from pre-block code (i.e. ANSI C/C++ style). 95 | 96 | -a OR --brackets=attach 97 | Attach brackets to pre-block code (i.e. Java/K&R style). 98 | 99 | -o OR --one-line=keep-statements 100 | Don't break lines containing multiple statements into 101 | multiple single-statement lines. 102 | 103 | -O OR --one-line=keep-blocks 104 | Don't break blocks residing completely on one line 105 | 106 | -p OR --pad=oper 107 | Insert space paddings around operators only. 108 | 109 | --pad=paren 110 | Insert space paddings around parenthesies only. 111 | -l OR --pad=block 112 | Enclose one statement in a begin-end only for keyword if/else/while/for. 113 | 114 | -P OR --pad=all 115 | Insert space paddings around operators AND parenthesies. 116 | 117 | --convert-tabs 118 | Convert tabs to spaces. 119 | 120 | --break-blocks 121 | Insert empty lines around unrelated blocks, labels, ... 122 | 123 | --break-blocks=all 124 | Like --break-blocks, except also insert empty lines 125 | around closing headers (e.g. 'else', ...). 126 | 127 | --break-elseifs 128 | Break 'else if()' statements into two different lines. 129 | ``` 130 | ## Other options: ## 131 | 132 | --- 133 | 134 | ``` 135 | --suffix=#### 136 | Append the suffix #### instead of '.orig' to original filename. 137 | 138 | -n OR --suffix=none 139 | Tells Astyle not to keep backups of the original source files. 140 | WARNING: Use this option with care, as Astyle comes with NO WARRANTY... 141 | 142 | -X OR --errors-to-standard-output 143 | Print errors and help information to standard-output rather than 144 | to standard-error. 145 | 146 | -v OR --version 147 | Print version number 148 | 149 | -h OR -? OR --help 150 | Print this help message 151 | 152 | --options=#### OR --options=none 153 | Parse used the specified options file: ####, options=none, none 154 | parse options file, and not looks for parse options files 155 | ``` 156 | ## Default options file: ## 157 | 158 | --- 159 | 160 | ``` 161 | iStyle looks for a default options file in the following order: 162 | 1. The contents of the ISTYLE_OPTIONS environment 163 | variable if it exists. 164 | 2. The file called .iStylerc in the directory pointed to by the 165 | HOME environment variable ( i.e. $HOME/.iStylerc ). 166 | 3. The file called .iStylerc in the directory pointed to by the 167 | HOMEPATH environment variable ( i.e. %HOMEPATH%\.iStylerc ). 168 | If a default options file is found, the options in this file 169 | will be parsed BEFORE the command-line options. 170 | Options within the default option file may be written without 171 | the preliminary '-' or '--'. 172 | ``` 173 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------- 2 | # 3 | # File: Makefile 4 | # 5 | # Author: Stephen Brennan 6 | # 7 | # Date Created: Friday, 17 July 2015 8 | # 9 | # Description: Generic C Makefile 10 | # 11 | # This is a generic makefile, suitable for any C programming project. It comes 12 | # with several features: 13 | # - Running tests, with Valgrind. 14 | # - Generation of documentation through Doxygen. You'll need to provide a 15 | # Doxyfile. 16 | # - Code coverage reports via gcov. 17 | # - Build configurations: debug, release, and coverage. 18 | # - Automatic dependency generation, so you never need to update this file. 19 | # 20 | # To use: 21 | # 1. You should organize your project like this: 22 | # src/ 23 | # |--- code.c 24 | # |--- module-1.h 25 | # |--- module-1/code.c 26 | # \--- module-2/code.c 27 | # test/ 28 | # \--- test-code.c 29 | # inc/ 30 | # \--- public-header.h 31 | # 2. Fill out the variables labelled CONFIGURATION. 32 | # 3. Build configurations are: debug, release, coverage. Run make like this: 33 | # make CFG=configuration target 34 | # The default target is release, so you can omit it normally. 35 | # 4. Targets: 36 | # - all: makes your main project 37 | # - test: makes and runs tests 38 | # - doc: builds documentation 39 | # - cov: generates code coverage (MUST have CFG=coverage) 40 | # - clean: removes object and binary files 41 | # - clean_{doc,cov,dep}: removes documentation/coverage/dependencies 42 | # 43 | # This code is in the public domain, for anyone to use or modify in any way. 44 | # 45 | #------------------------------------------------------------------------------- 46 | 47 | # --- CONFIGURATION: Definitely change this stuff! 48 | # PROJECT_NAME - not actually used. but what's your project's name? 49 | PROJECT_NAME="iStyle Verilog Formatter" 50 | # PROJECT_TYPE - staticlib, dynamiclib, executable 51 | PROJECT_TYPE=executable 52 | # PROJECT_MAIN - filename within your source directory that contains main() 53 | PROJECT_MAIN=astyle_main.cpp 54 | # TARGET - the name you want your target to have (bin/release/[whatgoeshere]) 55 | TARGET=iStyle 56 | # TEST_TARGET - the name you want your tests to have (probably test) 57 | TEST_TARGET=test 58 | # STATIC_LIBS - path to any static libs you need. you may need to make a rule 59 | # to generate them from subprojects. 60 | STATIC_LIBS= 61 | # EXTRA_INCLUDES - folders that should also be include directories (say, for 62 | # static libs?) 63 | EXTRA_INCLUDES= 64 | 65 | # --- DIRECTORY STRUCTURE: This structure is highly recommended, but you can 66 | # change it. The most important thing is that *none* of these directories are 67 | # subdirectories of each other. They should be completely disjoint. Also, 68 | # being too creative with directories could seriously mess up gcov, which is a 69 | # finicky beast. 70 | SOURCE_DIR=src 71 | TEST_DIR=test 72 | INCLUDE_DIR=inc 73 | OBJECT_DIR=obj 74 | BINARY_DIR=bin 75 | DEPENDENCY_DIR=dep 76 | DOCUMENTATION_DIR=doc 77 | COVERAGE_DIR=cov 78 | 79 | # --- COMPILATION FLAGS: Things you may want/need to configure, but I've put 80 | # them at sane defaults. 81 | CC=g++ 82 | FLAGS=-Wall -Wextra -pedantic 83 | INC=-I$(INCLUDE_DIR) -I$(SOURCE_DIR) $(addprefix -I,$(EXTRA_INCLUDES)) 84 | CFLAGS=$(FLAGS) -std=c++03 -fPIC $(INC) -c 85 | LFLAGS=$(FLAGS) 86 | 87 | # --- BUILD CONFIGURATIONS: Feel free to get creative with these if you'd like. 88 | # The advantage here is that you can update variables (like compile flags) based 89 | # on the build configuration. 90 | CFG=release 91 | ifeq ($(CFG),debug) 92 | FLAGS += -g -DDEBUG 93 | endif 94 | ifeq ($(CFG),coverage) 95 | CFLAGS += -fprofile-arcs -ftest-coverage 96 | LFLAGS += -fprofile-arcs -lgcov 97 | endif 98 | ifneq ($(CFG),debug) 99 | ifneq ($(CFG),release) 100 | ifneq ($(CFG),coverage) 101 | $(error Bad build configuration. Choices are debug, release, coverage.) 102 | endif 103 | endif 104 | endif 105 | 106 | # --- FILENAME LISTS: (and other internal variables) You probably don't need to 107 | # mess around with this stuff, unless you have a decent understanding of 108 | # everything this Makefile does. 109 | DIR_GUARD=@mkdir -p $(@D) 110 | OBJECT_MAIN=$(OBJECT_DIR)/$(CFG)/$(SOURCE_DIR)/$(patsubst %.cpp,%.o,$(PROJECT_MAIN)) 111 | 112 | SOURCES=$(shell find $(SOURCE_DIR) -type f -name "*.cpp") 113 | OBJECTS=$(patsubst $(SOURCE_DIR)/%.cpp,$(OBJECT_DIR)/$(CFG)/$(SOURCE_DIR)/%.o,$(SOURCES)) 114 | 115 | TEST_SOURCES=$(shell find $(TEST_DIR) -type f -name "*.cpp") 116 | TEST_OBJECTS=$(patsubst $(TEST_DIR)/%.cpp,$(OBJECT_DIR)/$(CFG)/$(TEST_DIR)/%.o,$(TEST_SOURCES)) 117 | 118 | DEPENDENCIES = $(patsubst $(SOURCE_DIR)/%.cpp,$(DEPENDENCY_DIR)/$(SOURCE_DIR)/%.d,$(SOURCES)) 119 | DEPENDENCIES += $(patsubst $(TEST_DIR)/%.cpp,$(DEPENDENCY_DIR)/$(TEST_DIR)/%.d,$(TEST_SOURCES)) 120 | 121 | # --- GLOBAL TARGETS: You can probably adjust and augment these if you'd like. 122 | .PHONY: all test clean clean_all clean_cov clean_doc 123 | 124 | all: $(BINARY_DIR)/$(CFG)/$(TARGET) 125 | 126 | test: $(BINARY_DIR)/$(CFG)/$(TEST_TARGET) 127 | valgrind $(BINARY_DIR)/$(CFG)/$(TEST_TARGET) 128 | 129 | doc: $(SOURCES) $(TEST_SOURCES) Doxyfile 130 | doxygen 131 | 132 | cov: $(BINARY_DIR)/$(CFG)/$(TEST_TARGET) 133 | @if [ "$(CFG)" != "coverage" ]; then \ 134 | echo "You must run 'make CFG=coverage coverage'."; \ 135 | exit 1; \ 136 | fi 137 | rm -f coverage.info 138 | $(BINARY_DIR)/$(CFG)/$(TEST_TARGET) 139 | lcov -c -d $(OBJECT_DIR)/$(CFG) -b $(SOURCE_DIR) -o coverage.info 140 | lcov -e coverage.info "`pwd`/$(SOURCE_DIR)/*" -o coverage.info 141 | genhtml coverage.info -o $(COVERAGE_DIR) 142 | rm coverage.info 143 | 144 | clean: 145 | rm -rf $(OBJECT_DIR)/$(CFG)/* $(BINARY_DIR)/$(CFG)/* $(SOURCE_DIR)/*.gch 146 | 147 | clean_all: clean_cov clean_doc 148 | rm -rf $(OBJECT_DIR) $(BINARY_DIR) $(DEPENDENCY_DIR) $(SOURCE_DIR)/*.gch 149 | 150 | clean_docs: 151 | rm -rf $(DOCUMENTATION_DIR) 152 | 153 | clean_cov: 154 | rm -rf $(COVERAGE_DIR) 155 | 156 | # RULE TO BUILD YOUR MAIN TARGET HERE: (you may have to edit this, but it it 157 | # configurable). 158 | $(BINARY_DIR)/$(CFG)/$(TARGET): $(OBJECTS) $(STATIC_LIBS) 159 | $(DIR_GUARD) 160 | ifeq ($(PROJECT_TYPE),staticlib) 161 | ar rcs $@ $^ 162 | endif 163 | ifeq ($(PROJECT_TYPE),dynamiclib) 164 | $(CC) -shared $(LFLAGS) $^ -o $@ 165 | endif 166 | ifeq ($(PROJECT_TYPE),executable) 167 | $(CC) $(LFLAGS) $^ -o $@ 168 | endif 169 | 170 | # RULE TO BULID YOUR TEST TARGET HERE: (it's assumed that it's an executable) 171 | $(BINARY_DIR)/$(CFG)/$(TEST_TARGET): $(filter-out $(OBJECT_MAIN),$(OBJECTS)) $(TEST_OBJECTS) $(STATIC_LIBS) 172 | $(DIR_GUARD) 173 | $(CC) $(LFLAGS) $^ -o $@ 174 | 175 | # --- Generic Compilation Command 176 | $(OBJECT_DIR)/$(CFG)/%.o: %.cpp 177 | $(DIR_GUARD) 178 | $(CC) $(CFLAGS) $< -o $@ 179 | 180 | # --- Automatic Dependency Generation 181 | $(DEPENDENCY_DIR)/%.d: %.cpp 182 | $(DIR_GUARD) 183 | $(CC) $(CFLAGS) -MM $< | sed -e 's!\(.*\)\.o:!$@ $(OBJECT_DIR)/$$(CFG)/$( $@ 184 | 185 | # --- Include Generated Dependencies 186 | ifneq "$(MAKECMDGOALS)" "clean_all" 187 | -include $(DEPENDENCIES) 188 | endif 189 | -------------------------------------------------------------------------------- /src/astyle.h: -------------------------------------------------------------------------------- 1 | // $Id: astyle.h, v 1.4 2004/02/06 08:37:56 devsolar Exp $ 2 | // -------------------------------------------------------------------------- 3 | // 4 | // Copyright (c) 1998, 1999, 2000, 2001, 2002 Tal Davidson. All rights reserved. 5 | // 6 | // compiler_defines.h 7 | // by Tal Davidson (davidsont@bigfoot.com) 8 | // 9 | // This file is a part of "Artistic Style" - an indentater and reformatter 10 | // of C, C++, C# and Java source files. 11 | // 12 | // -------------------------------------------------------------------------- 13 | // 14 | // This program is free software; you can redistribute it and/or 15 | // modify it under the terms of the GNU General Public License 16 | // as published by the Free Software Foundation; either version 2 17 | // of the License, or (at your option) any later version. 18 | // 19 | // This program is distributed in the hope that it will be useful, 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | // GNU General Public License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this program; if not, write to the Free Software 26 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 27 | // 28 | // -------------------------------------------------------------------------- 29 | 30 | #ifndef ASTYLE_H 31 | #define ASTYLE_H 32 | 33 | #include "compiler_defines.h" 34 | 35 | #include 36 | #include 37 | 38 | /* The enums below ave been moved up from inside the namespace astyle, since they 39 | for some strange reason are not recognized by 'vectors' in Microsoft Visual C++ 5 40 | when they are part of a namespace!!! There was no such problem with GNU's g++ compiler. 41 | */ 42 | enum BracketMode { NONE_MODE, ATTACH_MODE, BREAK_MODE}; 43 | enum BracketType { NULL_TYPE = 0, 44 | COMMAND_TYPE = 2, 45 | 46 | SINGLE_LINE_TYPE = 8}; 47 | 48 | void error(const char *why, const char* what); 49 | 50 | #ifdef USES_NAMESPACE 51 | using namespace std; 52 | 53 | namespace astyle 54 | { 55 | #endif 56 | 57 | class ASStreamIterator 58 | { 59 | public: 60 | ASStreamIterator(std::istream *in); 61 | virtual ~ASStreamIterator(); 62 | bool hasMoreLines() const; 63 | 64 | // Read the next line from the input stream. Returns the line read, 65 | // stripped of '\r' if any. 66 | std::string nextLine(); 67 | 68 | private: 69 | std::istream * inStream; 70 | int linecount; 71 | }; 72 | 73 | class ASResource 74 | { 75 | public: 76 | static const string AS_IF, AS_ELSE; 77 | static const string AS_WHILE; 78 | static const string AS_FOR; 79 | static const string AS_SWITCH, AS_DEFAULT; 80 | 81 | static const string AS_OPEN_BRACKET, AS_CLOSE_BRACKET; 82 | static const string AS_OPEN_LINE_COMMENT, AS_OPEN_COMMENT, AS_CLOSE_COMMENT, AS_OPEN_ATTRIBUTES, AS_CLOSE_ATTRIBUTES; 83 | // process 84 | 85 | static const string PRO_CELLDEFINE, PRO_DEFAULT_NETTYPE, PRO_DEFINE, PRO_ELSE, PRO_ELSIF; 86 | 87 | static const string PRO_ENDCELLDEFINE, PRO_ENDIF, PRO_ENDPROTECT, PRO_IFDEF, PRO_IFNDEF, PRO_INCLUDE; 88 | 89 | static const string PRO_NOUNCONNECTED_DRIVE, PRO_PROTECT, PRO_RESETALL, PRO_TIMESCALE; 90 | 91 | static const string PRO_UNCONNECTED_DRIVE, PRO_UNDEF; 92 | 93 | static const string AS_ASSIGN; 94 | static const string AS_LS_ASSIGN, AS_EQUAL_EQUAL, AS_NOT_EQUAL_EQUAL; 95 | static const string AS_BITNOT_AND, AS_BITNOT_OR, AS_BITNOT_XNOR, AS_NOT_XNOR; 96 | 97 | static const string AS_EQUAL, AS_NOT_EQUAL, AS_GR_EQUAL, AS_GR_GR, AS_INDEX_ADD, AS_INDEX_MINUS; 98 | static const string AS_LS_EQUAL, AS_LS_LS, AS_AND, AS_OR; 99 | static const string AS_PAREN_PAREN, AS_BLPAREN_BLPAREN; 100 | static const string AS_PLUS, AS_MINUS, AS_MULT, AS_EXP, AS_DIV, AS_MOD, AS_GR, AS_LS; 101 | static const string AS_NOT, AS_BIT_XOR, AS_BIT_OR, AS_BIT_AND, AS_BIT_NOT; 102 | static const string AS_QUESTION, AS_COLON, AS_SEMICOLON, AS_COMMA; 103 | 104 | static const string AS_BEGIN, AS_GENERATE, AS_CASE, AS_CASEX, AS_CASEZ, AS_FUNCTION, AS_FORK, AS_TABLE, AS_TASK, AS_SPECIFY, AS_PRIMITIVE, AS_MODULE; // add verilog 105 | 106 | static const string AS_END, AS_ENDGENERATE, AS_ENDCASE, AS_ENDFUNCTION, AS_JOIN, AS_ENDTASK, AS_ENDTABLE, AS_ENDSPECIFY, AS_ENDPRIMITIVE, AS_ENDMODULE; 107 | 108 | static const string AS_INITIAL, AS_FOREVER, AS_ALWAYS, AS_REPEAT; 109 | 110 | public: 111 | 112 | static const char PREPROCESSOR_CHAR; 113 | 114 | }; 115 | 116 | class ASBeautifier : protected ASResource 117 | { 118 | public: 119 | ASBeautifier(); 120 | virtual ~ASBeautifier(); 121 | virtual void init(ASStreamIterator* iter); // pointer to dynamically created iterator. 122 | virtual void init(); 123 | virtual bool hasMoreLines() const; 124 | virtual string nextLine(); 125 | virtual string beautify(const string &line); 126 | void setTabIndentation(int length = 4, bool forceTabs = false); 127 | 128 | void setSpaceIndentation(int length = 4); 129 | void setMaxInStatementIndentLength(int max); 130 | void setMinConditionalIndentLength(int min); 131 | 132 | void setSwitchIndent(bool state); 133 | void setCaseIndent(bool state); 134 | void setBracketIndent(bool state); 135 | void setBlockIndent(bool state); 136 | void setLabelIndent(bool state); 137 | void setEmptyLineFill(bool state); 138 | void setPreprocessorIndent(bool state); 139 | 140 | protected: 141 | int getNextProgramCharDistance(const string &line, int i); 142 | bool isLegalNameChar(char ch) const; 143 | 144 | bool isInVerilogNum(const string &line, int i) const; 145 | bool isWhiteSpace(char ch) const; 146 | const string *findHeader(const string &line, int i, 147 | const vector &possibleHeaders, 148 | bool checkBoundry = true); 149 | string trim(const string &str); 150 | int indexOf(vector &container, const string *element); 151 | 152 | private: 153 | ASBeautifier(const ASBeautifier ©); 154 | void operator=(ASBeautifier&); // not to be implemented 155 | 156 | void initStatic(); 157 | void registerInStatementIndent(const string &line, int i, int spaceTabCount, 158 | int minIndent, bool updateParenStack); 159 | string preLineWS(int spaceTabCount, int tabCount); 160 | 161 | static vector headers; 162 | static vector nonParenHeaders; 163 | static vector preprocessorHeaders; 164 | 165 | static vector verilogBlockBegin; 166 | 167 | static vector verilogBlockEnd; 168 | static bool calledInitStatic; 169 | 170 | ASStreamIterator *sourceIterator; 171 | vector *waitingBeautifierStack; 172 | vector *activeBeautifierStack; 173 | vector *waitingBeautifierStackLengthStack; 174 | vector *activeBeautifierStackLengthStack; 175 | vector *headerStack; 176 | vector< vector* > *tempStacks; 177 | vector *blockParenDepthStack; 178 | 179 | vector *inStatementIndentStack; 180 | vector *inStatementIndentStackSizeStack; 181 | vector *parenIndentStack; 182 | 183 | string indentString; 184 | const string *currentHeader; 185 | const string *previousLastLineHeader; 186 | 187 | bool isInQuote; 188 | bool isInComment; 189 | int isInCase; 190 | bool isInQuestion; 191 | bool isInStatement; 192 | bool isInHeader; 193 | bool isInDefine; 194 | bool isInDefineDefinition; 195 | 196 | bool caseIndent; 197 | bool namespaceIndent; 198 | bool bracketIndent; 199 | bool blockIndent; 200 | bool labelIndent; 201 | bool preprocessorIndent; 202 | bool isInConditional; 203 | bool isMinimalConditinalIndentSet; 204 | 205 | bool shouldForceTabIndentation; 206 | int minConditionalIndent; 207 | int parenDepth; 208 | int indentLength; 209 | unsigned int leadingWhiteSpaces; 210 | int maxInStatementIndent; 211 | char quoteChar; 212 | char prevNonSpaceCh; 213 | char currentNonSpaceCh; 214 | char currentNonLegalCh; 215 | char prevNonLegalCh; 216 | int prevFinalLineSpaceTabCount; 217 | int prevFinalLineTabCount; 218 | bool emptyLineFill; 219 | bool backslashEndsPrevLine; 220 | int defineTabCount; 221 | 222 | }; 223 | 224 | class ASFormatter : public ASBeautifier 225 | { 226 | public: 227 | ASFormatter(); 228 | virtual ~ASFormatter(); 229 | virtual void init(ASStreamIterator* iter); 230 | virtual bool hasMoreLines() const; 231 | virtual string nextLine(); 232 | void setBracketFormatMode(BracketMode mode); 233 | void setOperatorPaddingMode(bool mode); 234 | void setParenthesisPaddingMode(bool mode); 235 | 236 | void setBlockPaddingMode(bool mode); 237 | void setBreakOneLineBlocksMode(bool state); 238 | void setSingleStatementsMode(bool state); 239 | void setTabSpaceConversionMode(bool state); 240 | void setBreakBlocksMode(bool state); 241 | void setBreakClosingHeaderBlocksMode(bool state); 242 | void setBreakElseIfsMode(bool state); 243 | 244 | private: 245 | void ASformatter(ASFormatter ©); // not to be imlpemented 246 | void operator=(ASFormatter&); // not to be implemented 247 | void staticInit(); 248 | bool isFormattingEnabled() const; 249 | void goForward(int i); 250 | bool getNextChar(); 251 | char peekNextChar(bool count_white_space = false) const; 252 | bool isBeforeComment() const; 253 | void trimNewLine(); 254 | BracketType getBracketType() const; 255 | bool isUrinaryMinus() const; 256 | bool isInExponent() const; 257 | bool isOneLineBlockReached() const; 258 | void appendChar(char ch, bool canBreakLine = true); 259 | void appendCurrentChar(bool canBreakLine = true); 260 | 261 | void appendBlock(bool canBreakLine = true); 262 | void appendSequence(const string &sequence, bool canBreakLine = true); 263 | void appendSpacePad(); 264 | void breakLine(); 265 | inline bool isSequenceReached(const string &sequence) const; 266 | const string *findHeader(const vector &headers, bool checkBoundry = true); 267 | 268 | static vector headers; 269 | static vector nonParenHeaders; 270 | 271 | //used for verilog 272 | static vector preprocessorHeaders; 273 | 274 | static vector preCommandHeaders; 275 | static vector operators; 276 | static vector verilogBlockBegin; 277 | 278 | static vector verilogBlockEnd; 279 | 280 | static bool calledInitStatic; 281 | 282 | ASStreamIterator *sourceIterator; 283 | vector *preBracketHeaderStack; 284 | vector *parenStack; 285 | string readyFormattedLine; 286 | string currentLine; 287 | string formattedLine; 288 | const string *currentHeader; 289 | const string *previousOperator; 290 | char currentChar; 291 | char previousChar; 292 | char previousNonWSChar; 293 | char previousCommandChar; 294 | char quoteChar; 295 | unsigned int charNum; 296 | BracketMode bracketFormatMode; 297 | 298 | bool isVirgin; 299 | bool shouldPadOperators; 300 | 301 | bool shouldPadBlocks; 302 | bool shouldPadParenthesies; 303 | bool shouldConvertTabs; 304 | bool isInLineComment; 305 | bool isInComment; 306 | bool isInPreprocessor; 307 | bool doesLineStartComment; 308 | bool isInQuote; 309 | bool isSpecialChar; 310 | bool isNonParenHeader; 311 | bool foundQuestionMark; 312 | 313 | bool isInLineBreak; 314 | bool isInClosingBracketLineBreak; 315 | bool endOfCodeReached; 316 | bool isLineReady; 317 | bool shouldBreakOneLineBlocks; 318 | bool shouldReparseCurrentChar; 319 | bool shouldBreakOneLineStatements; 320 | bool shouldBreakLineAfterComments; 321 | bool shouldBreakElseIfs; 322 | 323 | bool passedSemicolon; 324 | bool passedColon; 325 | bool isImmediatelyPostComment; 326 | 327 | bool isImmediatelyPostLineComment; 328 | 329 | // bool isImmediatelyPostEmptyBlock; 330 | 331 | bool shouldBreakBlocks; 332 | bool shouldBreakClosingHeaderBlocks; 333 | bool isPrependPostBlockEmptyLineRequested; 334 | bool isAppendPostBlockEmptyLineRequested; 335 | 336 | bool prependEmptyLine; 337 | int previousReadyFormattedLineLength; 338 | 339 | bool isInHeader; 340 | 341 | bool isImmediatelyPostHeader; 342 | 343 | bool isRealBraceCh; 344 | 345 | bool isInsert; 346 | const string *vBlockBegin; 347 | 348 | const string *vBlockEnd; 349 | 350 | }; 351 | 352 | #ifdef USES_NAMESPACE 353 | } 354 | #endif 355 | 356 | #endif // closes ASTYLE_H 357 | 358 | -------------------------------------------------------------------------------- /src/astyle/ASBeautifier.cpp: -------------------------------------------------------------------------------- 1 | // $Id: ASBeautifier.cpp,v 1.4 2004/02/06 08:37:56 devsolar Exp $ 2 | // -------------------------------------------------------------------------- 3 | // 4 | // Copyright (c) 1998,1999,2000,2001,2002 Tal Davidson. All rights reserved. 5 | // 6 | // compiler_defines.h 7 | // by Tal Davidson (davidsont@bigfoot.com) 8 | // 9 | // This file is a part of "Artistic Style" - an indentater and reformatter 10 | // of C, C++, C# and Java source files. 11 | // 12 | // -------------------------------------------------------------------------- 13 | // 14 | // This program is free software; you can redistribute it and/or 15 | // modify it under the terms of the GNU General Public License 16 | // as published by the Free Software Foundation; either version 2 17 | // of the License, or (at your option) any later version. 18 | // 19 | // This program is distributed in the hope that it will be useful, 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | // GNU General Public License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this program; if not, write to the Free Software 26 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 27 | // 28 | // -------------------------------------------------------------------------- 29 | // 30 | // Patches: 31 | // 18 March 1999 - Brian Rampel - 32 | // Fixed inverse insertion of spaces vs. tabs when in -t mode. 33 | 34 | #include "compiler_defines.h" 35 | #include "astyle.h" 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #define INIT_CONTAINER(container, value) {if ( (container) != NULL ) delete (container); (container) = (value); } 44 | #define DELETE_CONTAINER(container) {if ( (container) != NULL ) delete (container) ; } 45 | 46 | #ifdef USES_NAMESPACE 47 | using namespace std; 48 | #endif 49 | 50 | #ifdef USES_NAMESPACE 51 | namespace astyle 52 | { 53 | #endif 54 | 55 | bool ASBeautifier::calledInitStatic = false; 56 | 57 | vector ASBeautifier::headers; 58 | vector ASBeautifier::nonParenHeaders; 59 | 60 | vector ASBeautifier::verilogBlockBegin; 61 | vector ASBeautifier::verilogBlockEnd; 62 | vector ASBeautifier::preprocessorHeaders; 63 | 64 | /* 65 | * initialize the static vars 66 | */ 67 | void ASBeautifier::initStatic() 68 | { 69 | if (calledInitStatic) 70 | return; 71 | 72 | calledInitStatic = true; 73 | 74 | headers.push_back(&AS_IF); 75 | headers.push_back(&AS_ELSE); 76 | headers.push_back(&AS_FOR); 77 | headers.push_back(&AS_WHILE); 78 | headers.push_back(&AS_INITIAL); 79 | headers.push_back(&AS_FOREVER); 80 | headers.push_back(&AS_ALWAYS); 81 | headers.push_back(&AS_REPEAT); 82 | 83 | nonParenHeaders.push_back(&AS_ELSE); 84 | nonParenHeaders.push_back(&AS_INITIAL); 85 | nonParenHeaders.push_back(&AS_FOREVER); 86 | nonParenHeaders.push_back(&AS_ALWAYS); 87 | nonParenHeaders.push_back(&AS_REPEAT); 88 | 89 | verilogBlockBegin.push_back(&AS_CASE ); 90 | verilogBlockBegin.push_back(&AS_CASEX ); 91 | verilogBlockBegin.push_back(&AS_CASEZ ); 92 | verilogBlockBegin.push_back(&AS_GENERATE ); 93 | verilogBlockBegin.push_back(&AS_FUNCTION ); 94 | verilogBlockBegin.push_back(&AS_FORK ); 95 | verilogBlockBegin.push_back(&AS_TABLE ); 96 | verilogBlockBegin.push_back(&AS_TASK ); 97 | verilogBlockBegin.push_back(&AS_SPECIFY ); 98 | verilogBlockBegin.push_back(&AS_PRIMITIVE ); 99 | verilogBlockBegin.push_back(&AS_MODULE ); 100 | verilogBlockBegin.push_back(&AS_BEGIN ); 101 | 102 | verilogBlockEnd.push_back(&AS_ENDCASE ); 103 | verilogBlockEnd.push_back(&AS_ENDGENERATE ); 104 | verilogBlockEnd.push_back(&AS_ENDFUNCTION ); 105 | verilogBlockEnd.push_back(&AS_JOIN ); 106 | verilogBlockEnd.push_back(&AS_ENDTASK ); 107 | verilogBlockEnd.push_back(&AS_ENDTABLE ); 108 | verilogBlockEnd.push_back(&AS_ENDSPECIFY ); 109 | verilogBlockEnd.push_back(&AS_ENDPRIMITIVE ); 110 | verilogBlockEnd.push_back(&AS_ENDMODULE ); 111 | verilogBlockEnd.push_back(&AS_END ); 112 | 113 | preprocessorHeaders.push_back(&PRO_CELLDEFINE ); 114 | preprocessorHeaders.push_back(&PRO_DEFAULT_NETTYPE ); 115 | preprocessorHeaders.push_back(&PRO_DEFINE ); 116 | preprocessorHeaders.push_back(&PRO_ELSE ); 117 | preprocessorHeaders.push_back(&PRO_ELSIF ); 118 | preprocessorHeaders.push_back(&PRO_ENDCELLDEFINE ); 119 | preprocessorHeaders.push_back(&PRO_ENDIF ); 120 | preprocessorHeaders.push_back(&PRO_ENDPROTECT ); 121 | preprocessorHeaders.push_back(&PRO_IFDEF ); 122 | preprocessorHeaders.push_back(&PRO_IFNDEF ); 123 | preprocessorHeaders.push_back(&PRO_INCLUDE ); 124 | preprocessorHeaders.push_back(&PRO_NOUNCONNECTED_DRIVE ); 125 | preprocessorHeaders.push_back(&PRO_PROTECT ); 126 | preprocessorHeaders.push_back(&PRO_RESETALL ); 127 | preprocessorHeaders.push_back(&PRO_TIMESCALE ); 128 | preprocessorHeaders.push_back(&PRO_UNCONNECTED_DRIVE ); 129 | preprocessorHeaders.push_back(&PRO_UNDEF ); 130 | } 131 | 132 | /** 133 | * ASBeautifier's constructor 134 | */ 135 | ASBeautifier::ASBeautifier() 136 | { 137 | initStatic(); 138 | 139 | waitingBeautifierStack = NULL; 140 | activeBeautifierStack = NULL; 141 | waitingBeautifierStackLengthStack = NULL; 142 | activeBeautifierStackLengthStack = NULL; 143 | 144 | headerStack = NULL; 145 | tempStacks = NULL; 146 | blockParenDepthStack = NULL; 147 | 148 | inStatementIndentStack = NULL; 149 | inStatementIndentStackSizeStack = NULL; 150 | parenIndentStack = NULL; 151 | sourceIterator = NULL; 152 | 153 | isMinimalConditinalIndentSet = false; 154 | shouldForceTabIndentation = false; 155 | 156 | setSpaceIndentation(4); 157 | setMaxInStatementIndentLength(40); 158 | 159 | setSwitchIndent(false); 160 | 161 | setBlockIndent(false); 162 | setBracketIndent(false); 163 | 164 | setLabelIndent(false); 165 | setEmptyLineFill(false); 166 | //setCStyle(); 167 | setPreprocessorIndent(false); 168 | } 169 | 170 | ASBeautifier::ASBeautifier(const ASBeautifier &other) 171 | { 172 | waitingBeautifierStack = NULL; 173 | activeBeautifierStack = NULL; 174 | waitingBeautifierStackLengthStack = NULL; 175 | activeBeautifierStackLengthStack = NULL; 176 | 177 | headerStack = new vector; 178 | *headerStack = *other.headerStack; 179 | 180 | tempStacks = new vector< vector* >; 181 | vector< vector* >::iterator iter; 182 | for (iter = other.tempStacks->begin(); 183 | iter != other.tempStacks->end(); 184 | ++iter) 185 | { 186 | vector *newVec = new vector; 187 | *newVec = **iter; 188 | tempStacks->push_back(newVec); 189 | } 190 | blockParenDepthStack = new vector; 191 | *blockParenDepthStack = *other.blockParenDepthStack; 192 | 193 | inStatementIndentStack = new vector; 194 | *inStatementIndentStack = *other.inStatementIndentStack; 195 | 196 | inStatementIndentStackSizeStack = new vector; 197 | *inStatementIndentStackSizeStack = *other.inStatementIndentStackSizeStack; 198 | 199 | parenIndentStack = new vector; 200 | *parenIndentStack = *other.parenIndentStack; 201 | 202 | sourceIterator = other.sourceIterator; 203 | 204 | indentString = other.indentString; 205 | currentHeader = other.currentHeader; 206 | previousLastLineHeader = other.previousLastLineHeader; 207 | 208 | isInQuote = other.isInQuote; 209 | isInComment = other.isInComment; 210 | isInCase = other.isInCase; 211 | isInQuestion = other.isInQuestion; 212 | isInStatement =other. isInStatement; 213 | isInHeader = other.isInHeader; 214 | 215 | bracketIndent = other.bracketIndent; 216 | blockIndent = other.blockIndent; 217 | labelIndent = other.labelIndent; 218 | preprocessorIndent = other.preprocessorIndent; 219 | parenDepth = other.parenDepth; 220 | indentLength = other.indentLength; 221 | 222 | leadingWhiteSpaces = other.leadingWhiteSpaces; 223 | maxInStatementIndent = other.maxInStatementIndent; 224 | quoteChar = other.quoteChar; 225 | prevNonSpaceCh = other.prevNonSpaceCh; 226 | currentNonSpaceCh = other.currentNonSpaceCh; 227 | currentNonLegalCh = other.currentNonLegalCh; 228 | prevNonLegalCh = other.prevNonLegalCh; 229 | isInConditional = other.isInConditional; 230 | minConditionalIndent = other.minConditionalIndent; 231 | prevFinalLineSpaceTabCount = other.prevFinalLineSpaceTabCount; 232 | prevFinalLineTabCount = other.prevFinalLineTabCount; 233 | emptyLineFill = other.emptyLineFill; 234 | 235 | isInDefine = other.isInDefine; 236 | isInDefineDefinition = other.isInDefineDefinition; 237 | backslashEndsPrevLine = other.backslashEndsPrevLine; 238 | defineTabCount = other.defineTabCount; 239 | } 240 | 241 | /** 242 | * ASBeautifier's destructor 243 | */ 244 | ASBeautifier::~ASBeautifier() 245 | { 246 | DELETE_CONTAINER( headerStack ); 247 | DELETE_CONTAINER( tempStacks ); 248 | DELETE_CONTAINER( blockParenDepthStack ); 249 | 250 | DELETE_CONTAINER( inStatementIndentStack ); 251 | DELETE_CONTAINER( inStatementIndentStackSizeStack ); 252 | DELETE_CONTAINER( parenIndentStack ); 253 | } 254 | 255 | /** 256 | * initialize the ASBeautifier. 257 | * 258 | * init() should be called every time a ABeautifier object is to start 259 | * beautifying a NEW source file. 260 | * init() recieves a pointer to a DYNAMICALLY CREATED ASStreamIterator object 261 | * that will be used to iterate through the source code. This object will be 262 | * deleted during the ASBeautifier's destruction, and thus should not be 263 | * deleted elsewhere. 264 | * 265 | * @param iter a pointer to the DYNAMICALLY CREATED ASStreamIterator object. 266 | */ 267 | void ASBeautifier::init(ASStreamIterator *iter) 268 | { 269 | sourceIterator = iter; 270 | init(); 271 | } 272 | 273 | /** 274 | * initialize the ASBeautifier. 275 | */ 276 | void ASBeautifier::init() 277 | { 278 | INIT_CONTAINER( waitingBeautifierStack, new vector ); 279 | INIT_CONTAINER( activeBeautifierStack, new vector ); 280 | 281 | INIT_CONTAINER( waitingBeautifierStackLengthStack, new vector ); 282 | INIT_CONTAINER( activeBeautifierStackLengthStack, new vector ); 283 | 284 | INIT_CONTAINER( headerStack, new vector ); 285 | INIT_CONTAINER( tempStacks, new vector< vector* > ); 286 | tempStacks->push_back(new vector); 287 | 288 | INIT_CONTAINER( blockParenDepthStack, new vector ); 289 | 290 | INIT_CONTAINER( inStatementIndentStack, new vector ); 291 | INIT_CONTAINER( inStatementIndentStackSizeStack, new vector ); 292 | inStatementIndentStackSizeStack->push_back(0); 293 | INIT_CONTAINER( parenIndentStack, new vector ); 294 | 295 | previousLastLineHeader = NULL; 296 | 297 | isInQuote = false; 298 | isInComment = false; 299 | isInStatement = false; 300 | isInCase = 0; 301 | isInQuestion = false; 302 | isInHeader = false; 303 | 304 | isInConditional = false; 305 | parenDepth=0; 306 | 307 | leadingWhiteSpaces = 0; 308 | prevNonSpaceCh = '{'; 309 | currentNonSpaceCh = '{'; 310 | prevNonLegalCh = '{'; 311 | currentNonLegalCh = '{'; 312 | prevFinalLineSpaceTabCount = 0; 313 | prevFinalLineTabCount = 0; 314 | 315 | backslashEndsPrevLine = false; 316 | isInDefine = false; 317 | isInDefineDefinition = false; 318 | defineTabCount = 0; 319 | 320 | } 321 | 322 | /** 323 | * indent using one tab per indentation 324 | */ 325 | void ASBeautifier::setTabIndentation(int length, bool forceTabs) 326 | { 327 | indentString = "\t"; 328 | indentLength = length; 329 | shouldForceTabIndentation = forceTabs; 330 | 331 | if (!isMinimalConditinalIndentSet) 332 | minConditionalIndent = indentLength * 2; 333 | } 334 | 335 | /** 336 | * indent using a number of spaces per indentation. 337 | * 338 | * @param length number of spaces per indent. 339 | */ 340 | void ASBeautifier::setSpaceIndentation(int length) 341 | { 342 | indentString=string(length, ' '); 343 | indentLength = length; 344 | 345 | if (!isMinimalConditinalIndentSet) 346 | minConditionalIndent = indentLength * 2; 347 | } 348 | 349 | /** 350 | * set the maximum indentation between two lines in a multi-line statement. 351 | * 352 | * @param max maximum indentation length. 353 | */ 354 | void ASBeautifier::setMaxInStatementIndentLength(int max) 355 | { 356 | maxInStatementIndent = max; 357 | } 358 | 359 | /** 360 | * set the minimum indentation between two lines in a multi-line condition. 361 | * 362 | * @param min minimal indentation length. 363 | */ 364 | void ASBeautifier::setMinConditionalIndentLength(int min) 365 | { 366 | minConditionalIndent = min; 367 | isMinimalConditinalIndentSet = true; 368 | } 369 | 370 | /** 371 | * set the state of the bracket indentation option. If true, brackets will 372 | * be indented one additional indent. 373 | * 374 | * @param state state of option. 375 | */ 376 | void ASBeautifier::setBracketIndent(bool state) 377 | { 378 | bracketIndent = state; 379 | } 380 | 381 | /** 382 | * set the state of the block indentation option. If true, entire blocks 383 | * will be indented one additional indent, similar to the GNU indent style. 384 | * 385 | * @param state state of option. 386 | */ 387 | void ASBeautifier::setBlockIndent(bool state) 388 | { 389 | if (state) 390 | setBracketIndent(false); // so that we don't have both bracket and block indent 391 | blockIndent = state; 392 | } 393 | 394 | /** 395 | * set the state of the class indentation option. If true, C++ class 396 | * definitions will be indented one additional indent. 397 | * 398 | * @param state state of option. 399 | */ 400 | // void ASBeautifier::setClassIndent(bool state) 401 | // { 402 | // classIndent = state; 403 | // } 404 | 405 | /** 406 | * set the state of the switch indentation option. If true, blocks of 'switch' 407 | * statements will be indented one additional indent. 408 | * 409 | * @param state state of option. 410 | */ 411 | void ASBeautifier::setSwitchIndent(bool state) 412 | { 413 | ;//switchIndent = state; 414 | } 415 | 416 | /** 417 | * set the state of the case indentation option. If true, lines of 'case' 418 | * statements will be indented one additional indent. 419 | * 420 | * @param state state of option. 421 | */ 422 | void ASBeautifier::setCaseIndent(bool state) 423 | { 424 | ;//caseIndent = state; 425 | } 426 | 427 | /** 428 | * set the state of the label indentation option. 429 | * If true, labels will be indented one indent LESS than the 430 | * current indentation level. 431 | * If false, labels will be flushed to the left with NO 432 | * indent at all. 433 | * 434 | * @param state state of option. 435 | */ 436 | void ASBeautifier::setLabelIndent(bool state) 437 | { 438 | labelIndent = state; 439 | } 440 | 441 | /** 442 | * set the state of the preprocessor indentation option. 443 | * If true, multiline #define statements will be indented. 444 | * 445 | * @param state state of option. 446 | */ 447 | void ASBeautifier::setPreprocessorIndent(bool state) 448 | { 449 | preprocessorIndent = state; 450 | } 451 | 452 | /** 453 | * set the state of the empty line fill option. 454 | * If true, empty lines will be filled with the whitespace. 455 | * of their previous lines. 456 | * If false, these lines will remain empty. 457 | * 458 | * @param state state of option. 459 | */ 460 | void ASBeautifier::setEmptyLineFill(bool state) 461 | { 462 | emptyLineFill = state; 463 | } 464 | 465 | /** 466 | * check if there are any indented lines ready to be read by nextLine() 467 | * 468 | * @return are there any indented lines ready? 469 | */ 470 | bool ASBeautifier::hasMoreLines() const 471 | { 472 | return sourceIterator->hasMoreLines(); 473 | } 474 | 475 | /** 476 | * get the next indented line. 477 | * 478 | * @return indented line. 479 | */ 480 | string ASBeautifier::nextLine() 481 | { 482 | return beautify(sourceIterator->nextLine()); 483 | } 484 | 485 | /** 486 | * beautify a line of source code. 487 | * every line of source code in a source code file should be sent 488 | * one after the other to the beautify method. 489 | * 490 | * @return the indented line. 491 | * @param originalLine the original unindented line. 492 | */ 493 | string ASBeautifier::beautify(const string &originalLine) 494 | { 495 | string line; 496 | bool isInLineComment = false; 497 | bool lineStartsInComment = false; 498 | bool isSpecialChar = false; 499 | char ch = ' '; 500 | char prevCh; 501 | string outBuffer; // the newly idented line is bufferd here 502 | int tabCount = 0; 503 | const string *lastLineHeader = NULL; 504 | bool closingBracketReached = false; 505 | int spaceTabCount = 0; 506 | char tempCh; 507 | int headerStackSize = headerStack->size(); 508 | 509 | bool shouldIndentBrackettedLine = true; 510 | int lineOpeningBlocksNum = 0; 511 | int lineClosingBlocksNum = 0; 512 | int i; 513 | 514 | currentHeader = NULL; 515 | 516 | lineStartsInComment = isInComment; 517 | 518 | //+ renqh 519 | const string *vBlockBegin; 520 | const string *vBlockEnd; 521 | 522 | vBlockBegin = NULL; 523 | vBlockEnd = NULL; 524 | 525 | // handle and remove white spaces around the line: 526 | // If not in comment, first find out size of white space before line, 527 | // so that possible comments starting in the line continue in 528 | // relation to the preliminary white-space. 529 | if (!isInComment) 530 | { 531 | leadingWhiteSpaces = 0; 532 | while (leadingWhiteSpacesinit(); 586 | //defineBeautifier->isInDefineDefinition = true; 587 | //defineBeautifier->beautify(""); 588 | activeBeautifierStack->push_back(defineBeautifier); 589 | } 590 | else 591 | { 592 | // the is the cloned beautifier that is in charge of indenting the #define. 593 | isInDefine = true; 594 | } 595 | } 596 | else if (preproc.COMPARE(0, 2, string("if")) == 0) 597 | { 598 | // push a new beautifier into the stack 599 | waitingBeautifierStackLengthStack->push_back(waitingBeautifierStack->size()); 600 | activeBeautifierStackLengthStack->push_back(activeBeautifierStack->size()); 601 | waitingBeautifierStack->push_back(new ASBeautifier(*this)); 602 | } 603 | else if (preproc.COMPARE(0, 4/*2*/, string("else")) == 0) 604 | { 605 | if (!waitingBeautifierStack->empty()) 606 | { 607 | // MOVE current waiting beautifier to active stack. 608 | activeBeautifierStack->push_back(waitingBeautifierStack->back()); 609 | waitingBeautifierStack->pop_back(); 610 | } 611 | } 612 | 613 | else if (preproc.COMPARE(0, 5, string("endif")) == 0) 614 | { 615 | unsigned int stackLength; 616 | ASBeautifier *beautifier; 617 | 618 | if (!waitingBeautifierStackLengthStack->empty()) 619 | { 620 | stackLength = waitingBeautifierStackLengthStack->back(); 621 | waitingBeautifierStackLengthStack->pop_back(); 622 | while (waitingBeautifierStack->size() > stackLength) 623 | { 624 | beautifier = waitingBeautifierStack->back(); 625 | waitingBeautifierStack->pop_back(); 626 | delete beautifier; 627 | } 628 | } 629 | 630 | if (!activeBeautifierStackLengthStack->empty()) 631 | { 632 | stackLength = activeBeautifierStackLengthStack->back(); 633 | activeBeautifierStackLengthStack->pop_back(); 634 | while (activeBeautifierStack->size() > stackLength) 635 | { 636 | beautifier = activeBeautifierStack->back(); 637 | activeBeautifierStack->pop_back(); 638 | delete beautifier; 639 | } 640 | } 641 | } 642 | } 643 | 644 | // check if the last char is a backslash 645 | if(line.length() > 0) 646 | backslashEndsPrevLine = (line[line.length() - 1] == '\\'); 647 | else 648 | backslashEndsPrevLine = false; 649 | 650 | // check if this line ends a multi-line #define 651 | // if so, use the #define's cloned beautifier for the line's indentation 652 | // and then remove it from the active beautifier stack and delete it. 653 | if (!backslashEndsPrevLine && isInDefineDefinition && !isInDefine) 654 | { 655 | string beautifiedLine; 656 | ASBeautifier *defineBeautifier; 657 | 658 | isInDefineDefinition = false; 659 | defineBeautifier = activeBeautifierStack->back(); 660 | activeBeautifierStack->pop_back(); 661 | 662 | beautifiedLine = defineBeautifier->beautify(line); 663 | delete defineBeautifier; 664 | return beautifiedLine; 665 | } 666 | 667 | // unless this is a multi-line #define, return this precompiler line as is. 668 | 669 | if (!isInDefine && !isInDefineDefinition ) 670 | return originalLine; 671 | } 672 | 673 | // if there exists any worker beautifier in the activeBeautifierStack, 674 | // then use it instead of me to indent the current line. 675 | if (!isInDefine && activeBeautifierStack != NULL && !activeBeautifierStack->empty()) 676 | { 677 | return activeBeautifierStack->back()->beautify(line); 678 | } 679 | 680 | // calculate preliminary indentation based on data from past lines 681 | if (!inStatementIndentStack->empty()) 682 | spaceTabCount = inStatementIndentStack->back(); 683 | 684 | for (i=0; i0 && (*headerStack)[i-1] != &AS_OPEN_BRACKET 687 | && (*headerStack)[i] == &AS_OPEN_BRACKET))) 688 | ++tabCount; 689 | } 690 | 691 | if (isInConditional) 692 | { 693 | --tabCount; 694 | } 695 | 696 | // parse characters in the current line. 697 | bool isFirstLoop = true ; 698 | int iLength = line.length(); 699 | for (i=0; isubstr(1)); 788 | i = i+ vBlockEnd->length()-1; 789 | ch = '}'; 790 | if(vBlockEnd==&AS_ENDCASE) 791 | isInCase--; 792 | } 793 | else if(vBlockBegin != NULL) 794 | { 795 | outBuffer.append(vBlockBegin->substr(1)); 796 | i = i+ vBlockBegin->length()-1; 797 | ch = '{'; 798 | if(vBlockBegin==&AS_CASE || vBlockBegin==&AS_CASEZ ||vBlockBegin==&AS_CASEX ) 799 | isInCase++; 800 | } 801 | 802 | //renqh 803 | 804 | prevNonSpaceCh = currentNonSpaceCh; 805 | currentNonSpaceCh = ch; 806 | if (!isLegalNameChar(ch) && ch != ',' && ch != ';' ) 807 | { 808 | prevNonLegalCh = currentNonLegalCh; 809 | currentNonLegalCh = ch; 810 | } 811 | if (isInHeader) 812 | { 813 | isInHeader = false; 814 | currentHeader = headerStack->back(); 815 | } 816 | else 817 | currentHeader = NULL; 818 | 819 | // handle parenthesies 820 | if (ch == '(' || ch == '[' || ch == ')' || ch == ']') 821 | { 822 | if (ch == '(' || ch == '[') 823 | { 824 | parenDepth++; 825 | 826 | inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size()); 827 | 828 | if (currentHeader != NULL) 829 | registerInStatementIndent(line, i, spaceTabCount, minConditionalIndent/*indentLength*2*/, true); 830 | else 831 | registerInStatementIndent(line, i, spaceTabCount, 0, true); 832 | } 833 | else if (ch == ')' || ch == ']') 834 | { 835 | parenDepth--; 836 | if (parenDepth == 0) 837 | { 838 | 839 | ch = ' '; 840 | isInConditional = false; 841 | } 842 | 843 | if (!inStatementIndentStackSizeStack->empty()) 844 | { 845 | unsigned int previousIndentStackSize = inStatementIndentStackSizeStack->back(); 846 | inStatementIndentStackSizeStack->pop_back(); 847 | while (previousIndentStackSize < inStatementIndentStack->size()) 848 | inStatementIndentStack->pop_back(); 849 | 850 | if (!parenIndentStack->empty()) 851 | { 852 | int poppedIndent = parenIndentStack->back(); 853 | parenIndentStack->pop_back(); 854 | 855 | if (i == 0||isFirstLoop) 856 | spaceTabCount = poppedIndent; 857 | } 858 | } 859 | } 860 | continue; 861 | } 862 | 863 | if (ch == '{') 864 | { 865 | // this bracket is a block opener... 866 | ++lineOpeningBlocksNum; 867 | 868 | blockParenDepthStack->push_back(parenDepth); 869 | inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size()); 870 | 871 | parenDepth = 0; 872 | isInStatement = false; 873 | 874 | tempStacks->push_back(new vector); 875 | headerStack->push_back(&AS_OPEN_BRACKET); 876 | lastLineHeader = &AS_OPEN_BRACKET; // <------ 877 | continue; 878 | } 879 | 880 | //check if a header has been reached 881 | if (prevCh == ' ') 882 | { 883 | const string *newHeader = findHeader(line, i, headers); 884 | if (newHeader != NULL) 885 | { 886 | // if we reached here, then this is a header... 887 | isInHeader = true; 888 | 889 | vector *lastTempStack; 890 | if (tempStacks->empty()) 891 | lastTempStack = NULL; 892 | else 893 | lastTempStack = tempStacks->back(); 894 | 895 | // take care of the special case: 'else if (...)' 896 | if (newHeader == &AS_IF && lastLineHeader == &AS_ELSE) 897 | { 898 | headerStack->pop_back(); 899 | } 900 | // take care of 'else' 901 | else if (newHeader == &AS_ELSE) 902 | { 903 | if (lastTempStack != NULL) 904 | { 905 | int indexOfIf = indexOf(*lastTempStack, &AS_IF); // <--- 906 | if (indexOfIf != -1) 907 | { 908 | // recreate the header list in headerStack up to the previous 'if' 909 | // from the temporary snapshot stored in lastTempStack. 910 | int restackSize = lastTempStack->size() - indexOfIf - 1; 911 | for (int r=0; rpush_back(lastTempStack->back()); 914 | lastTempStack->pop_back(); 915 | } 916 | if (!closingBracketReached) 917 | tabCount += restackSize; 918 | } 919 | } 920 | } 921 | 922 | headerStack->push_back(newHeader); 923 | if (indexOf(nonParenHeaders, newHeader) == -1) 924 | { 925 | isInConditional = true; 926 | } 927 | lastLineHeader = newHeader; 928 | 929 | outBuffer.append(newHeader->substr(1)); 930 | i += newHeader->length() - 1; 931 | continue; 932 | } 933 | } 934 | 935 | if (ch == '?') 936 | isInQuestion = true; 937 | 938 | // special handling of 'case' statements 939 | if (ch == ':') 940 | { 941 | // found a '[10:0] [`para:0] #(1:2:3) 942 | if (parenDepth!=0 || prevNonSpaceCh== '}'|| prevNonSpaceCh == '{') 943 | {} 944 | else 945 | { 946 | currentNonSpaceCh = ';'; // so that brackets after the ':' will appear as block-openers 947 | if (isInCase>0 ) 948 | { 949 | //ch = ';' ; 950 | isInHeader = true; 951 | headerStack->push_back(&AS_CASE); 952 | lastLineHeader = &AS_CASE; 953 | } 954 | else if (isInQuestion) 955 | { 956 | isInQuestion = false; 957 | } 958 | else //if(!isInStatement) // is in a label (e.g. 'label1:') 959 | { 960 | if (labelIndent) 961 | --tabCount; // unindent label by one indent 962 | else 963 | tabCount = 0; // completely flush indent to left 964 | } 965 | } 966 | } 967 | 968 | if ((ch == ';' || (parenDepth>0 && ch == ',')) && !inStatementIndentStackSizeStack->empty()) 969 | while (inStatementIndentStackSizeStack->back() + (parenDepth>0 ? 1 : 0) < inStatementIndentStack->size()) 970 | inStatementIndentStack->pop_back(); 971 | 972 | // handle ends of statements 973 | if ( (ch == ';' && parenDepth == 0) || ch == '}'/* || (ch == ',' && parenDepth == 0)*/) 974 | { 975 | isInQuestion = false; 976 | if (ch == '}') 977 | { 978 | // this bracket is block closer... 979 | ++lineClosingBlocksNum; 980 | 981 | if(!inStatementIndentStackSizeStack->empty()) 982 | inStatementIndentStackSizeStack->pop_back(); 983 | 984 | if (!blockParenDepthStack->empty()) 985 | { 986 | parenDepth = blockParenDepthStack->back(); 987 | blockParenDepthStack->pop_back(); 988 | 989 | } 990 | 991 | closingBracketReached = true; 992 | int headerPlace = indexOf(*headerStack, &AS_OPEN_BRACKET); // <--- 993 | if (headerPlace != -1) 994 | { 995 | const string *popped = headerStack->back(); 996 | while (popped != &AS_OPEN_BRACKET) 997 | { 998 | headerStack->pop_back(); 999 | popped = headerStack->back(); 1000 | } 1001 | headerStack->pop_back(); 1002 | 1003 | if (!tempStacks->empty()) 1004 | { 1005 | vector *temp = tempStacks->back(); 1006 | tempStacks->pop_back(); 1007 | delete temp; 1008 | } 1009 | } 1010 | 1011 | ch = ' '; // needed due to cases such as '}else{', so that headers ('else' tn tih case) will be identified... 1012 | } 1013 | 1014 | /* 1015 | * Create a temporary snapshot of the current block's header-list in the 1016 | * uppermost inner stack in tempStacks, and clear the headerStack up to 1017 | * the begining of the block. 1018 | * Thus, the next future statement will think it comes one indent past 1019 | * the block's '{' unless it specifically checks for a companion-header 1020 | * (such as a previous 'if' for an 'else' header) within the tempStacks, 1021 | * and recreates the temporary snapshot by manipulating the tempStacks. 1022 | */ 1023 | if (!tempStacks->back()->empty()) 1024 | while (!tempStacks->back()->empty()) 1025 | tempStacks->back()->pop_back(); 1026 | while (!headerStack->empty() && headerStack->back() != &AS_OPEN_BRACKET) 1027 | { 1028 | tempStacks->back()->push_back(headerStack->back()); 1029 | headerStack->pop_back(); 1030 | } 1031 | 1032 | if (ch == ';') 1033 | isInStatement=false; 1034 | continue; 1035 | } 1036 | // Handle mult line assign 1037 | if (!isInStatement && i==0 && parenDepth == 0 && isInCase==0) 1038 | { 1039 | int pos =0; 1040 | while (pos < iLength) 1041 | { 1042 | if( !isLegalNameChar(line[pos]) ) 1043 | break; 1044 | ++pos; 1045 | } 1046 | if (pos >= iLength) 1047 | pos--; 1048 | while (pos < iLength) 1049 | { 1050 | if( !isWhiteSpace(line[pos]) ) 1051 | break; 1052 | ++pos; 1053 | } 1054 | if (pos >= iLength) 1055 | pos--; 1056 | 1057 | registerInStatementIndent(string(line.c_str()+pos), 0, spaceTabCount, pos, false); 1058 | isInStatement = true; 1059 | } 1060 | } 1061 | 1062 | // indent #define lines with one less tab 1063 | //if (isInDefine) 1064 | // tabCount -= defineTabCount-1; 1065 | 1066 | vBlockBegin = findHeader(outBuffer, 0, verilogBlockBegin); 1067 | vBlockEnd = findHeader(outBuffer, 0, verilogBlockEnd); 1068 | 1069 | if (!lineStartsInComment 1070 | && !blockIndent 1071 | && outBuffer.length()>0 1072 | && ( vBlockBegin!=NULL) 1073 | && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum == lineClosingBlocksNum) 1074 | && !(headerStack->size() > 1 && (*headerStack)[headerStack->size()-2] == &AS_OPEN_BRACKET) 1075 | && shouldIndentBrackettedLine) 1076 | --tabCount; 1077 | 1078 | else if (!lineStartsInComment 1079 | && outBuffer.length()>0 1080 | && ( vBlockEnd!=NULL) 1081 | && shouldIndentBrackettedLine ) 1082 | --tabCount; 1083 | 1084 | // correctly indent one-line-blocks... 1085 | else if (!lineStartsInComment 1086 | && outBuffer.length()>0 1087 | && lineOpeningBlocksNum > 0 1088 | && lineOpeningBlocksNum == lineClosingBlocksNum 1089 | && previousLastLineHeader != NULL 1090 | && previousLastLineHeader != &AS_OPEN_BRACKET) 1091 | tabCount -= 1; //lineOpeningBlocksNum - (blockIndent ? 1 : 0); 1092 | 1093 | if (tabCount < 0) 1094 | tabCount = 0; 1095 | 1096 | // take care of extra bracket indentatation option... 1097 | if (bracketIndent && outBuffer.length()>0 && shouldIndentBrackettedLine) 1098 | if (vBlockEnd!=NULL||vBlockBegin!=NULL) 1099 | tabCount++; 1100 | 1101 | if (isInDefine) 1102 | { 1103 | if (outBuffer[0] == PREPROCESSOR_CHAR) 1104 | { 1105 | string preproc = trim(string(outBuffer.c_str() + 1)); 1106 | if (preproc.COMPARE(0, 6, string("define")) == 0) 1107 | { 1108 | if (!inStatementIndentStack->empty() 1109 | && inStatementIndentStack->back() > 0) 1110 | { 1111 | defineTabCount = tabCount; 1112 | } 1113 | else 1114 | { 1115 | defineTabCount = tabCount - 1; 1116 | tabCount--; 1117 | } 1118 | } 1119 | } 1120 | 1121 | tabCount -= defineTabCount; 1122 | } 1123 | 1124 | if (tabCount < 0) 1125 | tabCount = 0; 1126 | 1127 | // finally, insert indentations into begining of line 1128 | 1129 | prevFinalLineSpaceTabCount = spaceTabCount; 1130 | prevFinalLineTabCount = tabCount; 1131 | 1132 | if (shouldForceTabIndentation) 1133 | { 1134 | tabCount += spaceTabCount / indentLength; 1135 | spaceTabCount = spaceTabCount % indentLength; 1136 | } 1137 | 1138 | outBuffer = preLineWS(spaceTabCount,tabCount) + outBuffer; 1139 | 1140 | if (lastLineHeader != NULL) 1141 | previousLastLineHeader = lastLineHeader; 1142 | 1143 | return outBuffer; 1144 | } 1145 | 1146 | string ASBeautifier::preLineWS(int spaceTabCount, int tabCount) 1147 | { 1148 | string ws; 1149 | 1150 | for (int i=0; i 0) 1154 | ws += string(" "); 1155 | 1156 | return ws; 1157 | } 1158 | 1159 | /** 1160 | * register an in-statement indent. 1161 | */ 1162 | void ASBeautifier::registerInStatementIndent(const string &line, int i, int spaceTabCount, 1163 | int minIndent, bool updateParenStack) 1164 | { 1165 | int inStatementIndent; 1166 | int remainingCharNum = line.length() - i; 1167 | int nextNonWSChar = 1; 1168 | 1169 | nextNonWSChar = getNextProgramCharDistance(line, i); 1170 | 1171 | // if indent is around the last char in the line, indent instead 2 spaces from the previous indent 1172 | if (nextNonWSChar == remainingCharNum) 1173 | { 1174 | int previousIndent = spaceTabCount; 1175 | if (!inStatementIndentStack->empty()) 1176 | previousIndent = inStatementIndentStack->back(); 1177 | 1178 | inStatementIndentStack->push_back(/*2*/ indentLength + previousIndent ); 1179 | if (updateParenStack) 1180 | parenIndentStack->push_back( previousIndent ); 1181 | return; 1182 | } 1183 | 1184 | if (updateParenStack) 1185 | parenIndentStack->push_back(i+spaceTabCount); 1186 | 1187 | inStatementIndent = i + nextNonWSChar + spaceTabCount; 1188 | 1189 | if (i + nextNonWSChar < minIndent) 1190 | inStatementIndent = minIndent + spaceTabCount; 1191 | 1192 | if (i + nextNonWSChar > maxInStatementIndent) 1193 | inStatementIndent = indentLength*2 + spaceTabCount; 1194 | 1195 | if (!inStatementIndentStack->empty() && 1196 | inStatementIndent < inStatementIndentStack->back()) 1197 | inStatementIndent = inStatementIndentStack->back(); 1198 | 1199 | inStatementIndentStack->push_back(inStatementIndent); 1200 | } 1201 | 1202 | /** 1203 | * get distance to the next non-white sspace, non-comment character in the line. 1204 | * if no such character exists, return the length remaining to the end of the line. 1205 | */ 1206 | int ASBeautifier::getNextProgramCharDistance(const string &line, int i) 1207 | { 1208 | bool inComment = false; 1209 | int remainingCharNum = line.length() - i; 1210 | int charDistance = 1; 1211 | int ch; 1212 | 1213 | for (charDistance = 1; charDistance < remainingCharNum; charDistance++) 1214 | { 1215 | ch = line[i + charDistance]; 1216 | if (inComment) 1217 | { 1218 | if (line.COMPARE(i + charDistance, 2, AS_CLOSE_COMMENT) == 0) 1219 | { 1220 | charDistance++; 1221 | inComment = false; 1222 | } 1223 | continue; 1224 | } 1225 | else if (isWhiteSpace(ch)) 1226 | continue; 1227 | else if (ch == '/') 1228 | { 1229 | if (line.COMPARE(i + charDistance, 2, AS_OPEN_LINE_COMMENT) == 0) 1230 | return remainingCharNum; 1231 | else if (line.COMPARE(i + charDistance, 2, AS_OPEN_COMMENT) == 0) 1232 | { 1233 | charDistance++; 1234 | inComment = true; 1235 | } 1236 | } 1237 | else 1238 | return charDistance; 1239 | } 1240 | 1241 | return charDistance; 1242 | } 1243 | 1244 | /** 1245 | * check if a specific character can be used in a legal variable/method/class name 1246 | * 1247 | * @return legality of the char. 1248 | * @param ch the character to be checked. 1249 | */ 1250 | bool ASBeautifier::isLegalNameChar(char ch) const 1251 | { 1252 | return (isalnum(ch) //(ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || (ch>='0' && ch<='9') || 1253 | || ch=='.' || ch=='_' || ( ch=='$') || (ch=='`')); 1254 | } 1255 | /** 1256 | * check the char '?' is a verilog number 1257 | * 1258 | * @return is a number 1259 | * @param i '?' in the position in string line 1260 | */ 1261 | 1262 | bool ASBeautifier::isInVerilogNum(const string &line,int i) const 1263 | { 1264 | bool isNum = false; 1265 | char ch = line[i]; 1266 | int pos =i; 1267 | while(pos>=0 && !isWhiteSpace(ch)) 1268 | { 1269 | if(ch== '0' || ch=='1'||ch =='x' ||ch =='X'|| 1270 | ch =='z' ||ch =='Z'||ch =='_'||ch =='?' ) 1271 | { 1272 | pos--; 1273 | ch= line[pos]; 1274 | continue; 1275 | } 1276 | if( (ch=='b' ||ch =='B') && (pos >0 &&line[pos-1]=='\'')) 1277 | isNum = true; 1278 | break; 1279 | } 1280 | return isNum; 1281 | } 1282 | 1283 | /** 1284 | * check if a specific line position contains a header, out of several possible headers. 1285 | * 1286 | * @return a pointer to the found header. if no header was found then return NULL. 1287 | */ 1288 | const string *ASBeautifier::findHeader(const string &line, int i, const vector &possibleHeaders, bool checkBoundry) 1289 | { 1290 | int maxHeaders = possibleHeaders.size(); 1291 | const string *header = NULL; 1292 | int p; 1293 | 1294 | for (p=0; p < maxHeaders; p++) 1295 | { 1296 | header = possibleHeaders[p]; 1297 | 1298 | if (line.COMPARE(i, header->length(), *header) == 0) 1299 | { 1300 | // check that this is a header and not a part of a longer word 1301 | // (e.g. not at its begining, not at its middle...) 1302 | 1303 | int lineLength = line.length(); 1304 | int headerEnd = i + header->length(); 1305 | char startCh = (*header)[0]; // first char of header 1306 | char endCh = 0; // char just after header 1307 | char prevCh = 0; // char just before header 1308 | 1309 | if (headerEnd < lineLength) 1310 | { 1311 | endCh = line[headerEnd]; 1312 | } 1313 | if (i > 0) 1314 | { 1315 | prevCh = line[i-1]; 1316 | } 1317 | 1318 | if (!checkBoundry) 1319 | { 1320 | return header; 1321 | } 1322 | else if (prevCh != 0 1323 | && isLegalNameChar(startCh) 1324 | && isLegalNameChar(prevCh)) 1325 | { 1326 | continue; 1327 | } 1328 | else if (headerEnd >= lineLength 1329 | || !isLegalNameChar(startCh) 1330 | || !isLegalNameChar(endCh)) 1331 | { 1332 | return header; 1333 | } 1334 | else 1335 | { 1336 | continue; 1337 | } 1338 | } 1339 | } 1340 | 1341 | return NULL; 1342 | } 1343 | 1344 | /** 1345 | * check if a specific character can be used in a legal variable/method/class name 1346 | * 1347 | * @return legality of the char. 1348 | * @param ch the character to be checked. 1349 | */ 1350 | bool ASBeautifier::isWhiteSpace(char ch) const 1351 | { 1352 | return (ch == ' ' || ch == '\t'); 1353 | } 1354 | 1355 | /** 1356 | * find the index number of a string element in a container of strings 1357 | * 1358 | * @return the index number of element in the ocntainer. -1 if element not found. 1359 | * @param container a vector of strings. 1360 | * @param element the element to find . 1361 | */ 1362 | int ASBeautifier::indexOf(vector &container, const string *element) 1363 | { 1364 | vector::const_iterator where; 1365 | 1366 | where= find(container.begin(), container.end(), element); 1367 | if (where == container.end()) 1368 | return -1; 1369 | else 1370 | return where - container.begin(); 1371 | } 1372 | 1373 | /** 1374 | * trim removes the white space surrounding a line. 1375 | * 1376 | * @return the trimmed line. 1377 | * @param str the line to trim. 1378 | */ 1379 | string ASBeautifier::trim(const string &str) 1380 | { 1381 | 1382 | int start = 0; 1383 | int end = str.length() - 1; 1384 | 1385 | while (start < end && isWhiteSpace(str[start])) 1386 | start++; 1387 | 1388 | while (start <= end && isWhiteSpace(str[end])) 1389 | end--; 1390 | 1391 | string returnStr(str, start, end+1-start); 1392 | return returnStr; 1393 | } 1394 | 1395 | #ifdef USES_NAMESPACE 1396 | } 1397 | #endif 1398 | 1399 | -------------------------------------------------------------------------------- /src/astyle/ASFormatter.cpp: -------------------------------------------------------------------------------- 1 | // $Id: ASFormatter.cpp,v 1.3 2004/02/06 08:12:00 devsolar Exp $ 2 | // -------------------------------------------------------------------------- 3 | // 4 | // Copyright (c) 1998,1999,2000,2001,2002 Tal Davidson. All rights reserved. 5 | // 6 | // compiler_defines.h 7 | // by Tal Davidson (davidsont@bigfoot.com) 8 | // 9 | // This file is a part of "Artistic Style" - an indentater and reformatter 10 | // of C, C++, C# and Java source files. 11 | // 12 | // -------------------------------------------------------------------------- 13 | // 14 | // This program is free software; you can redistribute it and/or 15 | // modify it under the terms of the GNU General Public License 16 | // as published by the Free Software Foundation; either version 2 17 | // of the License, or (at your option) any later version. 18 | // 19 | // This program is distributed in the hope that it will be useful, 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | // GNU General Public License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this program; if not, write to the Free Software 26 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 27 | // 28 | // -------------------------------------------------------------------------- 29 | // Patches: 30 | // 26 November 1998 - Richard Bullington - 31 | // A correction of line-breaking in headers following '}', 32 | // was created using a variation of a patch by Richard Bullington. 33 | 34 | #include "compiler_defines.h" 35 | #include "astyle.h" 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #define INIT_CONTAINER(container, value) {if ( (container) != NULL ) delete (container); (container) = (value); } 44 | #define DELETE_CONTAINER(container) {if ( (container) != NULL ) delete (container) ; } 45 | #define IS_A(a,b) ( ((a) & (b)) == (b)) 46 | #ifdef USES_NAMESPACE 47 | using namespace std; 48 | 49 | namespace astyle 50 | { 51 | #endif 52 | 53 | bool ASFormatter::calledInitStatic = false; 54 | vector ASFormatter::headers; 55 | vector ASFormatter::nonParenHeaders; 56 | vector ASFormatter::preprocessorHeaders; 57 | vector ASFormatter::operators; 58 | vector ASFormatter::verilogBlockBegin; 59 | vector ASFormatter::verilogBlockEnd; 60 | 61 | /** 62 | * Constructor of ASFormatter 63 | */ 64 | ASFormatter::ASFormatter() 65 | { 66 | staticInit(); 67 | 68 | preBracketHeaderStack = NULL; 69 | parenStack = NULL; 70 | 71 | sourceIterator = NULL; 72 | bracketFormatMode = NONE_MODE; 73 | shouldPadOperators = false; 74 | shouldPadParenthesies = false; 75 | shouldPadBlocks = false; 76 | shouldBreakOneLineBlocks = true; 77 | shouldBreakOneLineStatements = true; 78 | shouldConvertTabs = false; 79 | shouldBreakBlocks = false; 80 | shouldBreakClosingHeaderBlocks = false; 81 | shouldBreakElseIfs = false; 82 | } 83 | 84 | /** 85 | * Destructor of ASFormatter 86 | */ 87 | ASFormatter::~ASFormatter() 88 | { 89 | DELETE_CONTAINER( preBracketHeaderStack ); 90 | } 91 | 92 | /** 93 | * initialization of static data of ASFormatter. 94 | */ 95 | void ASFormatter::staticInit() 96 | { 97 | if (calledInitStatic) 98 | return; 99 | 100 | calledInitStatic = true; 101 | 102 | headers.push_back(&AS_IF); 103 | headers.push_back(&AS_ELSE); 104 | headers.push_back(&AS_WHILE); 105 | headers.push_back(&AS_FOR); 106 | headers.push_back(&AS_CASE); 107 | headers.push_back(&AS_CASEZ); 108 | headers.push_back(&AS_CASEX); 109 | 110 | headers.push_back(&AS_INITIAL); 111 | headers.push_back(&AS_FOREVER); 112 | 113 | headers.push_back(&AS_ENDCASE ); 114 | 115 | headers.push_back(&AS_ENDTASK ); 116 | headers.push_back(&AS_ENDPRIMITIVE ); 117 | headers.push_back(&AS_ENDMODULE ); 118 | headers.push_back(&AS_ENDGENERATE ); 119 | headers.push_back(&AS_ENDFUNCTION ); 120 | 121 | nonParenHeaders.push_back(&AS_INITIAL); 122 | nonParenHeaders.push_back(&AS_ELSE); 123 | nonParenHeaders.push_back(&AS_FOREVER); 124 | 125 | nonParenHeaders.push_back(&AS_ENDCASE ); 126 | nonParenHeaders.push_back(&AS_ENDTASK ); 127 | nonParenHeaders.push_back(&AS_ENDPRIMITIVE ); 128 | nonParenHeaders.push_back(&AS_ENDMODULE ); 129 | nonParenHeaders.push_back(&AS_ENDGENERATE ); 130 | nonParenHeaders.push_back(&AS_ENDFUNCTION ); 131 | 132 | //add by renqh 133 | preprocessorHeaders.push_back(&PRO_CELLDEFINE ); 134 | preprocessorHeaders.push_back(&PRO_DEFAULT_NETTYPE ); 135 | preprocessorHeaders.push_back(&PRO_DEFINE ); 136 | preprocessorHeaders.push_back(&AS_ELSE); 137 | preprocessorHeaders.push_back(&PRO_ENDCELLDEFINE ); 138 | preprocessorHeaders.push_back(&PRO_ENDIF ); 139 | preprocessorHeaders.push_back(&PRO_IFDEF ); 140 | preprocessorHeaders.push_back(&PRO_INCLUDE ); 141 | preprocessorHeaders.push_back(&PRO_NOUNCONNECTED_DRIVE ); 142 | preprocessorHeaders.push_back(&PRO_RESETALL ); 143 | preprocessorHeaders.push_back(&PRO_TIMESCALE ); 144 | preprocessorHeaders.push_back(&PRO_UNCONNECTED_DRIVE ); 145 | preprocessorHeaders.push_back(&PRO_UNDEF ); 146 | 147 | operators.push_back(&AS_EQUAL_EQUAL); 148 | operators.push_back(&AS_NOT_EQUAL_EQUAL); 149 | operators.push_back(&AS_BITNOT_AND ); 150 | operators.push_back(&AS_BITNOT_OR ); 151 | operators.push_back(&AS_BITNOT_XNOR ); 152 | operators.push_back(&AS_NOT_XNOR ); 153 | 154 | operators.push_back(&AS_EQUAL); 155 | operators.push_back(&AS_NOT_EQUAL); 156 | operators.push_back(&AS_GR_EQUAL); 157 | operators.push_back(&AS_INDEX_ADD); 158 | operators.push_back(&AS_INDEX_MINUS); 159 | 160 | operators.push_back(&AS_GR_GR); 161 | operators.push_back(&AS_LS_EQUAL); 162 | 163 | operators.push_back(&AS_LS_LS); 164 | 165 | operators.push_back(&AS_AND); 166 | operators.push_back(&AS_OR); 167 | 168 | operators.push_back(&AS_EXP); 169 | operators.push_back(&AS_PLUS); 170 | operators.push_back(&AS_MINUS); 171 | operators.push_back(&AS_MULT); 172 | operators.push_back(&AS_DIV); 173 | operators.push_back(&AS_MOD); 174 | operators.push_back(&AS_QUESTION); 175 | operators.push_back(&AS_COLON); 176 | operators.push_back(&AS_ASSIGN); 177 | operators.push_back(&AS_LS); 178 | operators.push_back(&AS_GR); 179 | operators.push_back(&AS_NOT); 180 | operators.push_back(&AS_BIT_OR); 181 | operators.push_back(&AS_BIT_AND); 182 | operators.push_back(&AS_BIT_NOT); 183 | operators.push_back(&AS_BIT_XOR); 184 | 185 | operators.push_back(&AS_COMMA); 186 | 187 | verilogBlockBegin.push_back(&AS_FORK ); 188 | verilogBlockBegin.push_back(&AS_TABLE ); 189 | verilogBlockBegin.push_back(&AS_SPECIFY ); 190 | verilogBlockBegin.push_back(&AS_BEGIN ); 191 | 192 | verilogBlockEnd.push_back(&AS_JOIN ); 193 | verilogBlockEnd.push_back(&AS_ENDTABLE ); 194 | verilogBlockEnd.push_back(&AS_ENDSPECIFY ); 195 | verilogBlockEnd.push_back(&AS_END ); 196 | } 197 | 198 | /** 199 | * initialize the ASFormatter. 200 | * 201 | * init() should be called every time a ASFormatter object is to start 202 | * formatting a NEW source file. 203 | * init() recieves a pointer to a DYNAMICALLY CREATED ASStreamIterator object 204 | * that will be used to iterate through the source code. This object will be 205 | * deleted during the ASFormatter's destruction, and thus should not be 206 | * deleted elsewhere. 207 | * 208 | * @param iter a pointer to the DYNAMICALLY CREATED ASStreamIterator object. 209 | */ 210 | void ASFormatter::init(ASStreamIterator *si) 211 | { 212 | ASBeautifier::init(si); 213 | sourceIterator = si; 214 | 215 | INIT_CONTAINER( preBracketHeaderStack, new vector ); 216 | INIT_CONTAINER( parenStack, new vector ); 217 | parenStack->push_back(0); 218 | 219 | currentHeader = NULL; 220 | currentLine = string(""); 221 | formattedLine = ""; 222 | currentChar = ' '; 223 | previousCommandChar = ' '; 224 | previousNonWSChar = ' '; 225 | quoteChar = '"'; 226 | charNum = 0; 227 | previousOperator = NULL; 228 | 229 | isVirgin = true; 230 | isInLineComment = false; 231 | isInComment = false; 232 | isInPreprocessor = false; 233 | doesLineStartComment = false; 234 | isInQuote = false; 235 | isSpecialChar = false; 236 | isNonParenHeader = true; 237 | 238 | foundQuestionMark = false; 239 | isInLineBreak = false; 240 | endOfCodeReached = false; 241 | isLineReady = false; 242 | 243 | shouldReparseCurrentChar = false; 244 | passedSemicolon = false; 245 | passedColon = false; 246 | shouldBreakLineAfterComments = false; 247 | isImmediatelyPostComment = false; 248 | isImmediatelyPostLineComment = false; 249 | 250 | isPrependPostBlockEmptyLineRequested = false; 251 | isAppendPostBlockEmptyLineRequested = false; 252 | prependEmptyLine = false; 253 | 254 | previousReadyFormattedLineLength = 0; 255 | isImmediatelyPostHeader = false; 256 | isInHeader = false; 257 | isRealBraceCh = false; 258 | isInsert = false; 259 | 260 | vBlockBegin = NULL; 261 | vBlockEnd = NULL; 262 | 263 | } 264 | 265 | /** 266 | * get the next formatted line. 267 | * 268 | * @return formatted line. 269 | */ 270 | 271 | string ASFormatter::nextLine() 272 | { 273 | const string *newHeader; 274 | bool isCharImmediatelyPostComment = false; 275 | bool isPreviousCharPostComment = false; 276 | bool isCharImmediatelyPostLineComment = false; 277 | bool isInVirginLine = isVirgin; 278 | bool isCharImmediatelyPostOpenBlock = false; 279 | bool isCharImmediatelyPostCloseBlock = false; 280 | bool isCharImmediatelyPostTemplate = false; 281 | 282 | if (!isFormattingEnabled()) 283 | return ASBeautifier::nextLine(); 284 | 285 | while (!isLineReady) 286 | { 287 | isRealBraceCh = false ; 288 | 289 | vBlockBegin = NULL; 290 | vBlockEnd = NULL; 291 | 292 | if (shouldReparseCurrentChar) 293 | { 294 | shouldReparseCurrentChar = false; 295 | 296 | } 297 | else if (!getNextChar()) 298 | { 299 | breakLine(); 300 | return beautify(readyFormattedLine); 301 | } 302 | else // stuff to do when reading a new character... 303 | { 304 | // make sure that a virgin '{' at the begining ofthe file will be treated as a block... 305 | if (isInVirginLine && currentChar == '{') 306 | previousCommandChar = '{'; 307 | isPreviousCharPostComment = isCharImmediatelyPostComment; 308 | isCharImmediatelyPostComment = false; 309 | isCharImmediatelyPostTemplate = false; 310 | } 311 | 312 | if (isInLineComment) 313 | { 314 | appendCurrentChar(); 315 | 316 | // explicitely break a line when a line comment's end is found. 317 | if ( (charNum+1 ) == currentLine.length() ) 318 | { 319 | isInLineBreak = true; 320 | isInLineComment = false; 321 | isImmediatelyPostLineComment = true; 322 | currentChar = 0; //make sure it is a neutral char. 323 | } 324 | continue; 325 | } 326 | else if (isInComment) 327 | { 328 | if (isSequenceReached(AS_CLOSE_COMMENT)) 329 | { 330 | isInComment = false; 331 | isImmediatelyPostComment = true; 332 | appendSequence(AS_CLOSE_COMMENT); 333 | goForward(1); 334 | } 335 | else 336 | appendCurrentChar(); 337 | 338 | continue; 339 | } 340 | // not in line comment or comment 341 | else if (isInQuote) 342 | { 343 | if (isSpecialChar) 344 | { 345 | isSpecialChar = false; 346 | appendCurrentChar(); 347 | } 348 | else if (currentChar == '\\') 349 | { 350 | isSpecialChar = true; 351 | appendCurrentChar(); 352 | } 353 | else if (quoteChar == currentChar) 354 | { 355 | isInQuote = false; 356 | appendCurrentChar(); 357 | } 358 | else 359 | { 360 | appendCurrentChar(); 361 | } 362 | continue; 363 | } 364 | 365 | // handle white space - needed to simplify the rest. 366 | if (isWhiteSpace(currentChar) || isInPreprocessor) 367 | { 368 | ////// DEVEL: if (isLegalNameChar(previousChar) && isLegalNameChar(peekNextChar())) 369 | appendCurrentChar(); 370 | continue; 371 | } 372 | 373 | /* not in MIDDLE of quote or comment or white-space of any type ... */ 374 | if (isSequenceReached(AS_OPEN_LINE_COMMENT)) 375 | { 376 | isInLineComment = true; 377 | if (shouldPadOperators) 378 | appendSpacePad(); 379 | appendSequence(AS_OPEN_LINE_COMMENT); 380 | goForward(1); 381 | continue; 382 | } 383 | else if (isSequenceReached(AS_OPEN_COMMENT)) 384 | { 385 | isInComment = true; 386 | if (shouldPadOperators) 387 | appendSpacePad(); 388 | appendSequence(AS_OPEN_COMMENT); 389 | goForward(1); 390 | continue; 391 | } 392 | else if (currentChar == '"' ) 393 | { 394 | isInQuote = true; 395 | quoteChar = currentChar; 396 | ////if (shouldPadOperators) // BUGFIX: these two lines removed. seem to be unneeded, and interfere with L" 397 | ////appendSpacePad(); // BUFFIX: TODO make sure the removal of these lines doesn't reopen old bugs... 398 | appendCurrentChar(); 399 | continue; 400 | } 401 | 402 | /* not in quote or comment or white-space of any type ... */ 403 | 404 | // check if in preprocessor 405 | // ** isInPreprocessor will be automatically reset at the begining 406 | // of a new line in getnextChar() 407 | if (currentChar == PREPROCESSOR_CHAR && ( findHeader(preprocessorHeaders)!=NULL)) 408 | isInPreprocessor = true; 409 | 410 | if (isInPreprocessor) 411 | { 412 | appendCurrentChar(); 413 | continue; 414 | } 415 | 416 | /* not in preprocessor ... */ 417 | if (isImmediatelyPostComment) 418 | { 419 | isImmediatelyPostComment = false; 420 | isCharImmediatelyPostComment = true; 421 | } 422 | 423 | if (isImmediatelyPostLineComment) 424 | { 425 | isImmediatelyPostLineComment = false; 426 | isCharImmediatelyPostLineComment = true; 427 | } 428 | 429 | if (shouldBreakLineAfterComments) 430 | { 431 | shouldBreakLineAfterComments = false; 432 | shouldReparseCurrentChar = true; 433 | breakLine(); 434 | continue; 435 | } 436 | 437 | // reset isImmediatelyPostHeader information 438 | if (isImmediatelyPostHeader) 439 | { 440 | isImmediatelyPostHeader = false; 441 | 442 | // Make sure headers are broken from their succeeding blocks 443 | // (e.g. 444 | // if (isFoo) DoBar(); 445 | // should become 446 | // if (isFoo) 447 | // DoBar; 448 | // ) 449 | // But treat else if() as a special case which should not be broken! 450 | if (shouldBreakOneLineStatements) 451 | { 452 | // if may break 'else if()'s, then simply break the line 453 | if (shouldBreakElseIfs) 454 | isInLineBreak = true; 455 | else 456 | { 457 | // make sure 'else if()'s are not broken. 458 | bool isInElseIf = false; 459 | const string *upcomingHeader; 460 | 461 | upcomingHeader = findHeader(headers); 462 | if (currentHeader == &AS_ELSE && upcomingHeader == &AS_IF) 463 | isInElseIf = true; 464 | 465 | if (!isInElseIf) 466 | isInLineBreak = true; ////BUGFIX: SHOULD NOT BE breakLine() !!! 467 | 468 | // add by renqh, insert 'begin' , changed ' if(1) a; ' to ' if(1) begin a; 469 | if(shouldPadBlocks && !isInElseIf ) 470 | { 471 | vBlockBegin = findHeader(verilogBlockBegin); 472 | if ( vBlockBegin == NULL && 473 | (currentHeader == &AS_IF || currentHeader == &AS_ELSE 474 | || currentHeader == &AS_FOR || currentHeader == &AS_WHILE) 475 | ) 476 | { 477 | currentChar='b' ; 478 | string str1 = "begin "; 479 | currentLine.insert(charNum, str1);; 480 | 481 | isInsert = true; 482 | } 483 | } 484 | } 485 | } 486 | } 487 | 488 | if (passedSemicolon) 489 | { 490 | passedSemicolon = false; 491 | if (parenStack->back() == 0) 492 | { 493 | shouldReparseCurrentChar = true; 494 | isInLineBreak = true; 495 | continue; 496 | } 497 | } 498 | 499 | if (passedColon) 500 | { 501 | passedColon = false; 502 | if (parenStack->back() == 0) 503 | { 504 | shouldReparseCurrentChar = true; 505 | isInLineBreak = true; 506 | continue; 507 | } 508 | } 509 | 510 | if (isSequenceReached(AS_OPEN_ATTRIBUTES)) 511 | { 512 | appendSequence(AS_OPEN_ATTRIBUTES); 513 | if (shouldPadOperators) 514 | appendSpacePad(); 515 | goForward(1); 516 | continue; 517 | } 518 | else if (isSequenceReached(AS_CLOSE_ATTRIBUTES)) 519 | { 520 | if (shouldPadOperators) 521 | appendSpacePad(); 522 | appendSequence(AS_CLOSE_ATTRIBUTES); 523 | appendSpacePad(); 524 | goForward(1); 525 | continue; 526 | } 527 | //handle verilogBlock + 528 | 529 | if (currentChar == '{' ) 530 | { 531 | isRealBraceCh = true ; 532 | currentChar = '['; 533 | } 534 | else if(currentChar == '}' ) 535 | { 536 | isRealBraceCh = true ; 537 | currentChar = ']'; 538 | } 539 | else if (bracketFormatMode != NONE_MODE) 540 | { 541 | if(currentChar=='e' || currentChar=='j' ) // join end endtable endspecify 542 | { 543 | vBlockEnd = findHeader(verilogBlockEnd); 544 | if (vBlockEnd ) 545 | { 546 | currentChar = '}'; 547 | charNum =charNum + (vBlockEnd->length() - 1); 548 | } 549 | } 550 | else if((currentChar=='f' || currentChar=='t' || currentChar=='s' ||currentChar=='b' ))// fork table specify begin 551 | { 552 | vBlockBegin = findHeader(verilogBlockBegin); 553 | if (vBlockBegin ) 554 | { 555 | currentChar = '{'; 556 | charNum =charNum + (vBlockBegin->length() - 1); 557 | } 558 | } 559 | } 560 | //handle verilogBlock - 561 | 562 | // handle parenthesies 563 | // 564 | if (currentChar == '(' || currentChar == '[' ) 565 | { 566 | parenStack->back()++; 567 | } 568 | else if (currentChar == ')' || currentChar == ']' ) 569 | { 570 | parenStack->back()--; 571 | 572 | // check if this parenthesis closes a header, e.g. if (...), while (...) 573 | if (isInHeader && parenStack->back() == 0) 574 | { 575 | isInHeader = false; 576 | isImmediatelyPostHeader = true; 577 | } 578 | } 579 | 580 | // handle brackets 581 | // 582 | if (currentChar == '{') 583 | { 584 | parenStack->push_back(0); 585 | preBracketHeaderStack->push_back(currentHeader); 586 | currentHeader = NULL; 587 | } 588 | else if (currentChar == '}') 589 | { 590 | if (!parenStack->empty()) 591 | { 592 | parenStack->pop_back(); 593 | } 594 | // if a request has been made to append a post block empty line, 595 | // but the block exists immediately before a closing bracket, 596 | // then there is not need for the post block empty line. 597 | // 598 | isAppendPostBlockEmptyLineRequested = false; 599 | 600 | if (!preBracketHeaderStack->empty()) 601 | { 602 | currentHeader = preBracketHeaderStack->back(); 603 | preBracketHeaderStack->pop_back(); 604 | } 605 | else 606 | currentHeader = NULL; 607 | } 608 | 609 | //{ 610 | if (bracketFormatMode != NONE_MODE) 611 | { 612 | if (currentChar == '{') 613 | { 614 | if ( bracketFormatMode == ATTACH_MODE 615 | && !isCharImmediatelyPostLineComment ) 616 | { 617 | appendSpacePad(); 618 | if (!isCharImmediatelyPostComment // do not attach '{' to lines that end with /**/ comments. 619 | && previousCommandChar != '{' 620 | && previousCommandChar != '}' 621 | && previousCommandChar != ';') // '}' , ';' chars added for proper handling of '{' immediately after a '}' or ';' 622 | appendBlock(false); 623 | else 624 | appendBlock(true); 625 | continue; 626 | } 627 | else if (bracketFormatMode == BREAK_MODE) 628 | { 629 | if ( shouldBreakOneLineBlocks ) 630 | breakLine(); 631 | appendBlock(); 632 | continue; 633 | } 634 | appendBlock(true); 635 | continue; 636 | } 637 | else if (currentChar == '}') 638 | { 639 | if(shouldBreakOneLineBlocks ) 640 | { 641 | breakLine(); 642 | appendBlock(); 643 | } 644 | else 645 | { 646 | if (!isCharImmediatelyPostComment) 647 | isInLineBreak = false; 648 | appendBlock(); 649 | if (shouldBreakOneLineBlocks ) 650 | shouldBreakLineAfterComments = true; 651 | } 652 | 653 | if (shouldBreakBlocks) 654 | { 655 | isAppendPostBlockEmptyLineRequested =true; 656 | } 657 | 658 | continue; 659 | } 660 | } 661 | //} 662 | 663 | if ( ( (previousCommandChar == '{' ) 664 | || (previousCommandChar == '}' 665 | && !isPreviousCharPostComment // <-- Fixes wrongly appended newlines after '}' immediately after comments... 10/9/1999 666 | && peekNextChar() != ' ')) 667 | && (shouldBreakOneLineBlocks ) ) 668 | { 669 | isCharImmediatelyPostOpenBlock = (previousCommandChar == '{'); 670 | isCharImmediatelyPostCloseBlock = (previousCommandChar == '}'); 671 | 672 | previousCommandChar = ' '; 673 | isInLineBreak = true; //<---- 674 | } 675 | 676 | //{ 677 | if ( (newHeader = findHeader(headers)) != NULL) 678 | { 679 | const string *previousHeader; 680 | 681 | previousHeader = currentHeader; 682 | currentHeader = newHeader; 683 | 684 | // check if the found header is non-paren header 685 | isNonParenHeader = ( find(nonParenHeaders.begin(), nonParenHeaders.end(), 686 | newHeader) != nonParenHeaders.end() ); 687 | appendSequence(*currentHeader); 688 | goForward(currentHeader->length() - 1); 689 | // if padding is on, and a paren-header is found 690 | // then add a space pad after it. 691 | if (shouldPadOperators && !isNonParenHeader) 692 | appendSpacePad(); 693 | 694 | // Signal that a header has been reached 695 | // *** But treat a closing while() (as in do...while) 696 | // as if it where NOT a header since a closing while() 697 | // should never have a block after it! 698 | 699 | isInHeader = true; 700 | if (isNonParenHeader) 701 | { 702 | isImmediatelyPostHeader = true; 703 | isInHeader = false; 704 | } 705 | 706 | if (currentHeader == &AS_IF && previousHeader == &AS_ELSE) 707 | isInLineBreak = false; 708 | 709 | if (shouldBreakBlocks) 710 | { 711 | if (previousHeader == NULL 712 | && !isCharImmediatelyPostOpenBlock 713 | ) 714 | { 715 | isPrependPostBlockEmptyLineRequested = true; 716 | } 717 | 718 | if (currentHeader == &AS_ELSE 719 | || isCharImmediatelyPostLineComment 720 | || isCharImmediatelyPostComment 721 | ) 722 | { 723 | isPrependPostBlockEmptyLineRequested = false; 724 | } 725 | 726 | if (shouldBreakClosingHeaderBlocks 727 | && isCharImmediatelyPostCloseBlock) 728 | { 729 | isPrependPostBlockEmptyLineRequested = true; 730 | } 731 | } 732 | 733 | continue; 734 | } 735 | 736 | //} 737 | 738 | if (previousNonWSChar == '}' || currentChar == ';') 739 | { 740 | if (shouldBreakOneLineStatements && currentChar == ';' 741 | && (shouldBreakOneLineBlocks )) 742 | { 743 | passedSemicolon = true; 744 | 745 | if(isInsert) 746 | { 747 | isInsert = false; 748 | string str1 = " end "; 749 | currentLine.insert(charNum+1, str1); 750 | } 751 | } 752 | 753 | if (currentChar != ';') 754 | currentHeader = NULL; //DEVEL: is this ok? 755 | 756 | foundQuestionMark = false; 757 | 758 | } 759 | 760 | if(currentChar == ':' ) 761 | { 762 | if( previousNonWSChar == '}'|| previousNonWSChar == '{') 763 | { 764 | isInLineBreak = false; 765 | appendCurrentChar(); 766 | if (shouldBreakOneLineBlocks ) 767 | shouldBreakLineAfterComments = true; 768 | isInLineComment = true ; // begin : lable 769 | continue; 770 | } 771 | else if (shouldBreakOneLineStatements 772 | && previousNonWSChar != '}' 773 | && previousNonWSChar != '{' 774 | && !foundQuestionMark // not in a ... ? ... : ... sequence 775 | && previousCommandChar != ')' // not immediately after closing paren of a method header, e.g. ASFormatter::ASFormatter(...) : ASBeautifier(...) 776 | ) 777 | { 778 | passedColon = true; 779 | } 780 | } 781 | 782 | if (currentChar == '?') 783 | { 784 | if(!isInVerilogNum(currentLine,charNum)) 785 | foundQuestionMark = true; 786 | } 787 | 788 | if (shouldPadOperators) 789 | { 790 | if ((newHeader = findHeader(operators)) != NULL) 791 | { 792 | bool shouldPad = ( newHeader != &AS_PAREN_PAREN 793 | && newHeader != &AS_BLPAREN_BLPAREN 794 | && newHeader != &AS_NOT 795 | && newHeader != &AS_BIT_NOT 796 | && newHeader != &AS_BITNOT_AND 797 | && newHeader != &AS_BITNOT_OR 798 | && newHeader != &AS_NOT_XNOR 799 | && newHeader != &AS_BITNOT_XNOR 800 | && !(newHeader == &AS_MINUS && isInExponent()) 801 | && !(newHeader == &AS_PLUS && isInExponent()) 802 | && !( ( isCharImmediatelyPostTemplate) 803 | && (newHeader == &AS_LS || newHeader == &AS_GR)) 804 | ); 805 | 806 | // pad before operator 807 | if (shouldPad 808 | && !(newHeader == &AS_COLON && !foundQuestionMark) 809 | && newHeader != &AS_SEMICOLON 810 | && newHeader != &AS_COMMA) 811 | appendSpacePad(); 812 | appendSequence(*newHeader); 813 | goForward(newHeader->length() - 1); 814 | 815 | // since this block handles '()' and '[]', 816 | // the parenStack must be updated here accordingly! 817 | if (newHeader == &AS_PAREN_PAREN 818 | || newHeader == &AS_BLPAREN_BLPAREN) 819 | parenStack->back()--; 820 | 821 | currentChar = (*newHeader)[newHeader->length() - 1]; 822 | // pad after operator 823 | // but do not pad after a '-' that is a urinary-minus. 824 | if ( shouldPad && !(newHeader == &AS_MINUS && isUrinaryMinus()) ) 825 | appendSpacePad(); 826 | 827 | previousOperator = newHeader; 828 | continue; 829 | } 830 | } 831 | if (shouldPadParenthesies) 832 | { 833 | if (currentChar == '(' || currentChar == '[' ) 834 | { 835 | char peekedChar = peekNextChar(); 836 | 837 | appendCurrentChar(); 838 | if (!(currentChar == '(' && peekedChar == ')') 839 | && !(currentChar == '[' && peekedChar == ']')) 840 | appendSpacePad(); 841 | continue; 842 | } 843 | else if (currentChar == ')' || currentChar == ']') 844 | { 845 | char peekedChar = peekNextChar(); 846 | 847 | if (!(previousChar == '(' && currentChar == ')') 848 | && !(previousChar == '[' && currentChar == ']')) 849 | appendSpacePad(); 850 | 851 | appendCurrentChar(); 852 | 853 | if (peekedChar != ';' && peekedChar != ',' && peekedChar != '.' 854 | && !(currentChar == ']' && peekedChar == '[')) 855 | appendSpacePad(); 856 | continue; 857 | } 858 | } 859 | 860 | appendCurrentChar(); 861 | } 862 | 863 | // return a beautified (i.e. correctly indented) line. 864 | 865 | string beautifiedLine; 866 | int readyFormattedLineLength = trim(readyFormattedLine).length(); 867 | 868 | if (prependEmptyLine 869 | && readyFormattedLineLength > 0 870 | && previousReadyFormattedLineLength > 0) 871 | { 872 | isLineReady = true; // signal that a readyFormattedLine is still waiting 873 | beautifiedLine = beautify(""); 874 | } 875 | else 876 | { 877 | isLineReady = false; 878 | beautifiedLine = beautify(readyFormattedLine); 879 | } 880 | 881 | prependEmptyLine = false; 882 | previousReadyFormattedLineLength = readyFormattedLineLength; 883 | 884 | return beautifiedLine; 885 | 886 | } 887 | 888 | /** 889 | * check if there are any indented lines ready to be read by nextLine() 890 | * 891 | * @return are there any indented lines ready? 892 | */ 893 | bool ASFormatter::hasMoreLines() const 894 | { 895 | if (!isFormattingEnabled()) 896 | return ASBeautifier::hasMoreLines(); 897 | else 898 | return !endOfCodeReached; 899 | } 900 | 901 | /** 902 | * check if formatting options are enabled, in addition to indentation. 903 | * 904 | * @return are formatting options enabled? 905 | */ 906 | bool ASFormatter::isFormattingEnabled() const 907 | { 908 | return (bracketFormatMode != NONE_MODE 909 | || shouldPadOperators 910 | || shouldConvertTabs); 911 | } 912 | 913 | /** 914 | * set the bracket formatting mode. 915 | * options: 916 | * astyle::NONE_MODE no formatting of brackets. 917 | * astyle::ATTACH_MODE Java, K&R style bracket placement. 918 | * astyle::BREAK_MODE ANSI C/C++ style bracket placement. 919 | * 920 | * @param mode the bracket formatting mode. 921 | */ 922 | void ASFormatter::setBracketFormatMode(BracketMode mode) 923 | { 924 | bracketFormatMode = mode; 925 | } 926 | 927 | /** 928 | * set 'else if()' breaking mode 929 | * options: 930 | * true 'else' headers will be broken from their succeeding 'if' headers. 931 | * false 'else' headers will be attached to their succeeding 'if' headers. 932 | * 933 | * @param mode the 'else if()' breaking mode. 934 | */ 935 | void ASFormatter::setBreakElseIfsMode(bool state) 936 | { 937 | shouldBreakElseIfs = state; 938 | } 939 | 940 | /** 941 | * set operator padding mode. 942 | * options: 943 | * true statement operators will be padded with spaces around them. 944 | * false statement operators will not be padded. 945 | * 946 | * @param mode the padding mode. 947 | */ 948 | void ASFormatter::setOperatorPaddingMode(bool state) 949 | { 950 | shouldPadOperators = state; 951 | } 952 | 953 | /** 954 | * set parentheies padding mode. 955 | * options: 956 | * true statement parenthesies will be padded with spaces around them. 957 | * false statement parenthesies will not be padded. 958 | * 959 | * @param mode the padding mode. 960 | */ 961 | void ASFormatter::setParenthesisPaddingMode(bool state) 962 | { 963 | shouldPadParenthesies = state; 964 | } 965 | //Enclose one statement in a begin-end only for keyword if/else/while/for 966 | void ASFormatter::setBlockPaddingMode(bool state) 967 | { 968 | shouldPadBlocks = state; 969 | } 970 | 971 | /** 972 | * set option to break/not break one-line blocks 973 | * 974 | * @param state true = break, false = don't break. 975 | */ 976 | void ASFormatter::setBreakOneLineBlocksMode(bool state) 977 | { 978 | shouldBreakOneLineBlocks = state; 979 | } 980 | 981 | /** 982 | * set option to break/not break lines consisting of multiple statements. 983 | * 984 | * @param state true = break, false = don't break. 985 | */ 986 | void ASFormatter::setSingleStatementsMode(bool state) 987 | { 988 | shouldBreakOneLineStatements = state; 989 | } 990 | 991 | /** 992 | * set option to convert tabs to spaces. 993 | * 994 | * @param state true = convert, false = don't convert. 995 | */ 996 | void ASFormatter::setTabSpaceConversionMode(bool state) 997 | { 998 | shouldConvertTabs = state; 999 | } 1000 | 1001 | /** 1002 | * set option to break unrelated blocks of code with empty lines. 1003 | * 1004 | * @param state true = convert, false = don't convert. 1005 | */ 1006 | void ASFormatter::setBreakBlocksMode(bool state) 1007 | { 1008 | shouldBreakBlocks = state; 1009 | } 1010 | 1011 | /** 1012 | * set option to break closing header blocks of code (such as 'else', 'catch', ...) with empty lines. 1013 | * 1014 | * @param state true = convert, false = don't convert. 1015 | */ 1016 | void ASFormatter::setBreakClosingHeaderBlocksMode(bool state) 1017 | { 1018 | shouldBreakClosingHeaderBlocks = state; 1019 | } 1020 | 1021 | /** 1022 | * check if a specific sequence exists in the current placement of the current line 1023 | * 1024 | * @return whether sequence has been reached. 1025 | * @param sequence the sequence to be checked 1026 | */ 1027 | bool ASFormatter::isSequenceReached(const string &sequence) const 1028 | { 1029 | return currentLine.COMPARE(charNum, sequence.length(), sequence) == 0; 1030 | 1031 | } 1032 | 1033 | /** 1034 | * jump over several characters. 1035 | * 1036 | * @param i the number of characters to jump over. 1037 | */ 1038 | void ASFormatter::goForward(int i) 1039 | { 1040 | while (--i >= 0) 1041 | getNextChar(); 1042 | } 1043 | 1044 | /** 1045 | * peek at the next unread character. 1046 | * 1047 | * @return the next unread character. 1048 | */ 1049 | char ASFormatter::peekNextChar(const bool count_white_space) const 1050 | { 1051 | int peekNum = charNum + 1; 1052 | int len = currentLine.length(); 1053 | char ch = ' '; 1054 | 1055 | while (peekNum < len) 1056 | { 1057 | ch = currentLine[peekNum++]; 1058 | if (count_white_space || !isWhiteSpace(ch)) 1059 | return ch; 1060 | } 1061 | 1062 | if (shouldConvertTabs && ch == '\t') 1063 | ch = ' '; 1064 | 1065 | return ch; 1066 | } 1067 | 1068 | /** 1069 | * check if current placement is before a comment or line-comment 1070 | * 1071 | * @return is before a comment or line-comment. 1072 | */ 1073 | bool ASFormatter::isBeforeComment() const 1074 | { 1075 | int peekNum = charNum + 1; 1076 | int len = currentLine.length(); 1077 | // char ch = ' '; 1078 | bool foundComment = false; 1079 | 1080 | for (peekNum = charNum + 1; 1081 | peekNum < len && isWhiteSpace(currentLine[peekNum]); 1082 | ++peekNum) 1083 | ; 1084 | 1085 | if (peekNum < len) 1086 | foundComment = ( currentLine.COMPARE(peekNum, 2, AS_OPEN_COMMENT) == 0 1087 | || currentLine.COMPARE(peekNum, 2, AS_OPEN_LINE_COMMENT) == 0 ); 1088 | 1089 | return foundComment; 1090 | } 1091 | 1092 | /** 1093 | * get the next character, increasing the current placement in the process. 1094 | * the new character is inserted into the variable currentChar. 1095 | * 1096 | * @return whether succeded to recieve the new character. 1097 | */ 1098 | bool ASFormatter::getNextChar() 1099 | { 1100 | isInLineBreak = false; 1101 | bool isAfterFormattedWhiteSpace = false; 1102 | 1103 | if (shouldPadOperators && !isInComment && !isInLineComment 1104 | && !isInQuote && !doesLineStartComment && !isInPreprocessor 1105 | && !isBeforeComment()) 1106 | { 1107 | int len = formattedLine.length(); 1108 | if (len > 0 && isWhiteSpace(formattedLine[len-1])) 1109 | isAfterFormattedWhiteSpace = true; 1110 | } 1111 | 1112 | previousChar = currentChar; 1113 | 1114 | if (!isWhiteSpace(currentChar) ) 1115 | { 1116 | previousNonWSChar = currentChar; 1117 | if (!isInComment && !isInLineComment && !isInQuote 1118 | && !isSequenceReached(AS_OPEN_COMMENT) 1119 | && !isSequenceReached(AS_OPEN_LINE_COMMENT) 1120 | ) 1121 | previousCommandChar = previousNonWSChar; 1122 | } 1123 | 1124 | unsigned int currentLineLength = currentLine.length(); 1125 | 1126 | if (charNum+1 < currentLineLength 1127 | && (!isWhiteSpace(peekNextChar()) || isInComment || isInLineComment)) 1128 | { 1129 | currentChar = currentLine[++charNum]; 1130 | if (isAfterFormattedWhiteSpace) 1131 | while (isWhiteSpace(currentChar) && charNum+1 < currentLineLength) 1132 | currentChar = currentLine[++charNum]; 1133 | 1134 | if (shouldConvertTabs && currentChar == '\t') 1135 | currentChar = ' '; 1136 | 1137 | return true; 1138 | } 1139 | else 1140 | { 1141 | if (sourceIterator->hasMoreLines()) 1142 | { 1143 | currentLine = sourceIterator->nextLine(); 1144 | if (currentLine.length() == 0) 1145 | { 1146 | /*think*/ currentLine = string(" "); 1147 | } 1148 | 1149 | // unless reading in the first line of the file, 1150 | // break a new line. 1151 | if (!isVirgin) 1152 | isInLineBreak = true; 1153 | else 1154 | isVirgin = false; 1155 | 1156 | if (isInLineComment) 1157 | isImmediatelyPostLineComment = true; 1158 | isInLineComment = false; 1159 | 1160 | trimNewLine(); 1161 | currentChar = currentLine[charNum]; 1162 | 1163 | // check if is in preprocessor right after the line break and line trimming 1164 | if (previousNonWSChar != '\\' ) 1165 | isInPreprocessor = false; 1166 | 1167 | if (shouldConvertTabs && currentChar == '\t') 1168 | currentChar = ' '; 1169 | 1170 | return true; 1171 | } 1172 | else 1173 | { 1174 | endOfCodeReached = true; 1175 | return false; 1176 | } 1177 | } 1178 | } 1179 | 1180 | /** 1181 | * jump over the leading white space in the current line, 1182 | * IF the line does not begin a comment or is in a preprocessor definition. 1183 | */ 1184 | void ASFormatter::trimNewLine() 1185 | { 1186 | unsigned int len = currentLine.length(); 1187 | charNum = 0; 1188 | 1189 | if (isInComment || isInPreprocessor) 1190 | return; 1191 | 1192 | while (isWhiteSpace(currentLine[charNum]) && charNum+1 < len) 1193 | ++charNum; 1194 | 1195 | doesLineStartComment = false; 1196 | if (isSequenceReached(string("/*"))) 1197 | { 1198 | charNum = 0; 1199 | doesLineStartComment = true; 1200 | } 1201 | } 1202 | 1203 | /** 1204 | * append a character to the current formatted line. 1205 | * Unless disabled (via canBreakLine == false), first check if a 1206 | * line-break has been registered, and if so break the 1207 | * formatted line, and only then append the character into 1208 | * the next formatted line. 1209 | * 1210 | * @param ch the character to append. 1211 | * @param canBreakLine if true, a registered line-break 1212 | */ 1213 | void ASFormatter::appendChar(char ch, bool canBreakLine) 1214 | { 1215 | if (canBreakLine && isInLineBreak) 1216 | breakLine(); 1217 | formattedLine.append(1, ch); 1218 | } 1219 | 1220 | /** 1221 | * append the CURRENT character (curentChar)to the current 1222 | * formatted line. Unless disabled (via canBreakLine == false), 1223 | * first check if a line-break has been registered, and if so 1224 | * break the formatted line, and only then append the character 1225 | * into the next formatted line. 1226 | * 1227 | * @param canBreakLine if true, a registered line-break 1228 | */ 1229 | void ASFormatter::appendCurrentChar(bool canBreakLine) 1230 | { 1231 | char tmpCh; 1232 | tmpCh = currentChar; 1233 | 1234 | if(isRealBraceCh) 1235 | { 1236 | if(currentChar == '[') 1237 | tmpCh = '{'; 1238 | else if (currentChar == ']') 1239 | tmpCh = '}'; 1240 | isRealBraceCh = false ; 1241 | } 1242 | 1243 | appendChar(tmpCh, canBreakLine); 1244 | } 1245 | 1246 | // append block begin end 1247 | void ASFormatter::appendBlock(bool canBreakLine) 1248 | { 1249 | if (vBlockBegin!=NULL) 1250 | { 1251 | appendSequence(*vBlockBegin,canBreakLine); 1252 | vBlockBegin =NULL; 1253 | } 1254 | else if (vBlockEnd!=NULL) 1255 | { 1256 | appendSpacePad(); 1257 | appendSequence(*vBlockEnd,canBreakLine); 1258 | vBlockEnd = NULL; 1259 | } 1260 | } 1261 | 1262 | /** 1263 | * append a string sequence to the current formatted line. 1264 | * Unless disabled (via canBreakLine == false), first check if a 1265 | * line-break has been registered, and if so break the 1266 | * formatted line, and only then append the sequence into 1267 | * the next formatted line. 1268 | * 1269 | * @param sequence the sequence to append. 1270 | * @param canBreakLine if true, a registered line-break 1271 | */ 1272 | void ASFormatter::appendSequence(const string &sequence, bool canBreakLine) 1273 | { 1274 | if (canBreakLine && isInLineBreak) 1275 | breakLine(); 1276 | formattedLine.append(sequence); 1277 | } 1278 | 1279 | /** 1280 | * append a space to the current formattedline, UNLESS the 1281 | * last character is already a white-space character. 1282 | */ 1283 | void ASFormatter::appendSpacePad() 1284 | { 1285 | int len = formattedLine.length(); 1286 | if (peekNextChar(true) != ' ' 1287 | && (len == 0 || !isWhiteSpace(formattedLine[len-1]))) 1288 | formattedLine.append(1, ' '); 1289 | } 1290 | 1291 | /** 1292 | * register a line break for the formatted line. 1293 | */ 1294 | void ASFormatter::breakLine() 1295 | { 1296 | isLineReady = true; 1297 | isInLineBreak = false; 1298 | 1299 | // queue an empty line prepend request if one exists 1300 | prependEmptyLine = isPrependPostBlockEmptyLineRequested; 1301 | 1302 | readyFormattedLine = formattedLine; 1303 | if (isAppendPostBlockEmptyLineRequested) 1304 | { 1305 | isAppendPostBlockEmptyLineRequested = false; 1306 | isPrependPostBlockEmptyLineRequested = true; 1307 | } 1308 | else 1309 | { 1310 | isPrependPostBlockEmptyLineRequested = false; 1311 | } 1312 | 1313 | formattedLine = ""; 1314 | } 1315 | 1316 | /** 1317 | * check if the currently reached open-bracket (i.e. '{') 1318 | * opens a: 1319 | * - a definition type block (such as a class or namespace), 1320 | * - a command block (such as a method block) 1321 | * - a static array 1322 | * this method takes for granted that the current character 1323 | * is an opening bracket. 1324 | * 1325 | * @return the type of the opened block. 1326 | */ 1327 | BracketType ASFormatter::getBracketType() const 1328 | { 1329 | return COMMAND_TYPE; 1330 | } 1331 | 1332 | /** 1333 | * check if the currently reached '-' character is 1334 | * a urinary minus 1335 | * this method takes for granted that the current character 1336 | * is a '-'. 1337 | * 1338 | * @return whether the current '-' is a urinary minus. 1339 | */ 1340 | bool ASFormatter::isUrinaryMinus() const 1341 | { 1342 | return ( (!isalnum(previousCommandChar)) 1343 | && previousCommandChar != '.' 1344 | && previousCommandChar != ')' 1345 | && previousCommandChar != ']' ); 1346 | } 1347 | 1348 | /** 1349 | * check if the currently reached '-' or '+' character is 1350 | * part of an exponent, i.e. 0.2E-5. 1351 | * this method takes for granted that the current character 1352 | * is a '-' or '+'. 1353 | * 1354 | * @return whether the current '-' is in an exponent. 1355 | */ 1356 | bool ASFormatter::isInExponent() const 1357 | { 1358 | int formattedLineLength = formattedLine.length(); 1359 | if (formattedLineLength >= 2) 1360 | { 1361 | char prevPrevFormattedChar = formattedLine[formattedLineLength - 2]; 1362 | char prevFormattedChar = formattedLine[formattedLineLength - 1]; 1363 | 1364 | return ( (prevFormattedChar == 'e' || prevFormattedChar == 'E') 1365 | && (prevPrevFormattedChar == '.' || isdigit(prevPrevFormattedChar)) ); 1366 | } 1367 | else 1368 | return false; 1369 | } 1370 | 1371 | /** 1372 | * check if a one-line bracket has been reached, 1373 | * i.e. if the currently reached '{' character is closed 1374 | * with a complimentry '}' elsewhere on the current line, 1375 | *. 1376 | * @return has a one-line bracket been reached? 1377 | */ 1378 | bool ASFormatter::isOneLineBlockReached() const 1379 | { 1380 | bool isInComment = false; 1381 | bool isInQuote = false; 1382 | int bracketCount = 1; 1383 | int currentLineLength = currentLine.length(); 1384 | int i = 0; 1385 | char ch = ' '; 1386 | char quoteChar = ' '; 1387 | 1388 | for (i = charNum + 1; i < currentLineLength; ++i) 1389 | { 1390 | ch = currentLine[i]; 1391 | 1392 | if (isInComment) 1393 | { 1394 | if (currentLine.COMPARE(i, 2, "*/") == 0) 1395 | { 1396 | isInComment = false; 1397 | ++i; 1398 | } 1399 | continue; 1400 | } 1401 | 1402 | if (ch == '\\') 1403 | { 1404 | ++i; 1405 | continue; 1406 | } 1407 | 1408 | if (isInQuote) 1409 | { 1410 | if (ch == quoteChar) 1411 | isInQuote = false; 1412 | continue; 1413 | } 1414 | 1415 | if (ch == '"' ) 1416 | { 1417 | isInQuote = true; 1418 | quoteChar = ch; 1419 | continue; 1420 | } 1421 | 1422 | if (currentLine.COMPARE(i, 2, "//") == 0) 1423 | break; 1424 | 1425 | if (currentLine.COMPARE(i, 2, "/*") == 0) 1426 | { 1427 | isInComment = true; 1428 | ++i; 1429 | continue; 1430 | } 1431 | 1432 | if (ch == '{') 1433 | ++bracketCount; 1434 | else if (ch == '}') 1435 | --bracketCount; 1436 | 1437 | if(bracketCount == 0) 1438 | return true; 1439 | } 1440 | 1441 | return false; 1442 | } 1443 | 1444 | /** 1445 | * check if one of a set of headers has been reached in the 1446 | * current position of the current line. 1447 | * 1448 | * @return a pointer to the found header. Or a NULL if no header has been reached. 1449 | * @param headers a vector of headers 1450 | * @param checkBoundry 1451 | */ 1452 | const string *ASFormatter::findHeader(const vector &headers, bool checkBoundry) 1453 | { 1454 | return ASBeautifier::findHeader(currentLine, charNum, headers, checkBoundry); 1455 | } 1456 | 1457 | #ifdef USES_NAMESPACE 1458 | } 1459 | #endif 1460 | 1461 | -------------------------------------------------------------------------------- /src/astyle/ASResource.cpp: -------------------------------------------------------------------------------- 1 | // $Id: ASResource.cpp,v 1.2 2004/02/04 07:35:10 devsolar Exp $ 2 | // -------------------------------------------------------------------------- 3 | // 4 | // Copyright (c) 1998,1999,2000,2001,2002 Tal Davidson. All rights reserved. 5 | // 6 | // compiler_defines.h 7 | // by Tal Davidson (davidsont@bigfoot.com) 8 | // 9 | // This file is a part of "Artistic Style" - an indentater and reformatter 10 | // of C, C++, C# and Java source files. 11 | // 12 | // -------------------------------------------------------------------------- 13 | // 14 | // This program is free software; you can redistribute it and/or 15 | // modify it under the terms of the GNU General Public License 16 | // as published by the Free Software Foundation; either version 2 17 | // of the License, or (at your option) any later version. 18 | // 19 | // This program is distributed in the hope that it will be useful, 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | // GNU General Public License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this program; if not, write to the Free Software 26 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 27 | // 28 | // -------------------------------------------------------------------------- 29 | 30 | #include "compiler_defines.h" 31 | #include "astyle.h" 32 | 33 | #include 34 | 35 | #ifdef USES_NAMESPACE 36 | using namespace std; 37 | 38 | namespace astyle 39 | { 40 | #endif 41 | 42 | const string ASResource::AS_IF = string("if"); 43 | const string ASResource::AS_ELSE = string ("else"); 44 | const string ASResource::AS_FOR = string("for"); 45 | 46 | const string ASResource::AS_WHILE = string("while"); 47 | const string ASResource::AS_SWITCH = string ("switch"); 48 | 49 | const string ASResource::AS_DEFAULT = string("default"); 50 | 51 | const string ASResource::PRO_CELLDEFINE = string("`celldefine"); 52 | 53 | const string ASResource::PRO_DEFAULT_NETTYPE = string("`default_nettype"); 54 | 55 | const string ASResource::PRO_DEFINE = string("`define"); 56 | 57 | const string ASResource::PRO_ELSE = string("`else"); 58 | 59 | const string ASResource::PRO_ELSIF = string("`elsif"); 60 | 61 | const string ASResource::PRO_ENDCELLDEFINE = string("`endcelldefine"); 62 | 63 | const string ASResource::PRO_ENDIF = string("`endif"); 64 | 65 | const string ASResource::PRO_ENDPROTECT = string("`endprotect"); 66 | 67 | const string ASResource::PRO_IFDEF = string("`ifdef"); 68 | 69 | const string ASResource::PRO_IFNDEF = string("`ifndef"); 70 | 71 | const string ASResource::PRO_INCLUDE = string("`include"); 72 | 73 | const string ASResource::PRO_NOUNCONNECTED_DRIVE = string("`nounconnected_drive"); 74 | 75 | const string ASResource::PRO_PROTECT = string("`protect"); 76 | 77 | const string ASResource::PRO_RESETALL = string("`resetall"); 78 | 79 | const string ASResource::PRO_TIMESCALE = string("`timescale"); 80 | 81 | const string ASResource::PRO_UNCONNECTED_DRIVE = string("`unconnected_drive"); 82 | 83 | const string ASResource::PRO_UNDEF = string("`undef"); 84 | 85 | const string ASResource::AS_OPEN_BRACKET = string("{"); 86 | const string ASResource::AS_CLOSE_BRACKET = string("}"); 87 | const string ASResource::AS_OPEN_LINE_COMMENT = string("//"); 88 | const string ASResource::AS_OPEN_COMMENT = string("/*"); 89 | const string ASResource::AS_CLOSE_COMMENT = string("*/"); 90 | const string ASResource::AS_OPEN_ATTRIBUTES = string("(*"); 91 | const string ASResource::AS_CLOSE_ATTRIBUTES = string("*)"); 92 | 93 | const string ASResource::AS_ASSIGN = string("="); 94 | const string ASResource::AS_LS_ASSIGN = string("<="); 95 | 96 | const string ASResource::AS_EQUAL = string("=="); 97 | const string ASResource::AS_NOT_EQUAL = string("!="); 98 | const string ASResource::AS_EQUAL_EQUAL = string("==="); 99 | const string ASResource::AS_NOT_EQUAL_EQUAL = string("!=="); 100 | 101 | const string ASResource::AS_BITNOT_AND = string("~&"); 102 | const string ASResource::AS_BITNOT_OR = string("~|"); 103 | const string ASResource::AS_BITNOT_XNOR = string("~^"); 104 | const string ASResource::AS_NOT_XNOR = string("^~"); 105 | 106 | const string ASResource::AS_GR_EQUAL = string(">="); 107 | const string ASResource::AS_GR_GR = string(">>"); 108 | const string ASResource::AS_LS_EQUAL = string("<="); 109 | const string ASResource::AS_LS_LS = string("<<"); 110 | const string ASResource::AS_INDEX_ADD = string("+:"); 111 | const string ASResource::AS_INDEX_MINUS = string("-:"); 112 | 113 | const string ASResource::AS_AND = string("&&"); 114 | const string ASResource::AS_OR = string("||"); 115 | 116 | const string ASResource::AS_PAREN_PAREN = string("()"); 117 | const string ASResource::AS_BLPAREN_BLPAREN = string("[]"); 118 | 119 | const string ASResource::AS_PLUS = string("+"); 120 | const string ASResource::AS_MINUS = string("-"); 121 | const string ASResource::AS_MULT = string("*"); 122 | const string ASResource::AS_DIV = string("/"); 123 | const string ASResource::AS_MOD = string("%"); 124 | const string ASResource::AS_EXP = string("**"); 125 | 126 | const string ASResource::AS_GR = string(">"); 127 | const string ASResource::AS_LS = string("<"); 128 | const string ASResource::AS_NOT = string("!"); 129 | const string ASResource::AS_BIT_OR = string("|"); 130 | const string ASResource::AS_BIT_AND = string("&"); 131 | const string ASResource::AS_BIT_NOT = string("~"); 132 | const string ASResource::AS_BIT_XOR = string("^"); 133 | const string ASResource::AS_QUESTION = string("?"); 134 | const string ASResource::AS_COLON = string(":"); 135 | const string ASResource::AS_COMMA = string(","); 136 | const string ASResource::AS_SEMICOLON = string(";"); 137 | 138 | const string ASResource::AS_INITIAL = string("initial"); 139 | 140 | const string ASResource::AS_FOREVER = string("forever"); 141 | 142 | const string ASResource::AS_ALWAYS = string("always"); 143 | const string ASResource::AS_REPEAT = string("repeat"); 144 | 145 | const string ASResource::AS_CASE = string("case" ); 146 | const string ASResource::AS_CASEX = string("casex" ); 147 | const string ASResource::AS_CASEZ = string("casez" ); 148 | const string ASResource::AS_GENERATE = string("generate" ); 149 | const string ASResource::AS_FUNCTION = string("function" ); 150 | const string ASResource::AS_FORK = string("fork" ); 151 | const string ASResource::AS_TABLE = string("table" ); 152 | const string ASResource::AS_TASK = string("task" ); 153 | const string ASResource::AS_SPECIFY = string("specify" ); 154 | const string ASResource::AS_PRIMITIVE = string("primitive"); 155 | const string ASResource::AS_MODULE = string("module" ); 156 | const string ASResource::AS_BEGIN = string("begin" ); 157 | 158 | const string ASResource::AS_ENDCASE = string("endcase" ); 159 | const string ASResource::AS_ENDGENERATE = string("endgenerate" ); 160 | const string ASResource::AS_ENDFUNCTION = string("endfunction" ); 161 | const string ASResource::AS_JOIN = string("join" ); 162 | const string ASResource::AS_ENDTASK = string("endtask" ); 163 | const string ASResource::AS_ENDTABLE = string("endtable" ); 164 | const string ASResource::AS_ENDSPECIFY = string("endspecify" ); 165 | const string ASResource::AS_ENDPRIMITIVE = string("endprimitive" ); 166 | const string ASResource::AS_ENDMODULE = string("endmodule" ); 167 | const string ASResource::AS_END = string("end" ); 168 | 169 | const char ASResource::PREPROCESSOR_CHAR ='`'; 170 | 171 | #ifdef USES_NAMESPACE 172 | } 173 | #endif 174 | 175 | -------------------------------------------------------------------------------- /src/astyle/ASStreamIterator.cpp: -------------------------------------------------------------------------------- 1 | // $Id: ASStreamIterator.cpp,v 1.2 2004/02/06 08:15:39 devsolar Exp $ 2 | // -------------------------------------------------------------------------- 3 | // 4 | // Copyright (c) 1998,1999,2000,2001,2002 Tal Davidson. All rights reserved. 5 | // 6 | // ASStreamIterator.h 7 | // by Tal Davidson (davidsont@bigfoot.com) 8 | // 9 | // This file is a part of "Artistic Style" - an indentater and reformatter 10 | // of C, C++, C# and Java source files. 11 | // 12 | // -------------------------------------------------------------------------- 13 | // 14 | // This program is free software; you can redistribute it and/or 15 | // modify it under the terms of the GNU General Public License 16 | // as published by the Free Software Foundation; either version 2 17 | // of the License, or (at your option) any later version. 18 | // 19 | // This program is distributed in the hope that it will be useful, 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | // GNU General Public License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this program; if not, write to the Free Software 26 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 27 | // 28 | // -------------------------------------------------------------------------- 29 | 30 | #include "astyle.h" 31 | 32 | #include 33 | //~ #include 34 | 35 | 36 | #include 37 | 38 | #ifdef USES_NAMESPACE 39 | using namespace std; 40 | 41 | namespace astyle 42 | { 43 | #endif 44 | 45 | // -------------------------------------------------------------------------- 46 | // ASStreamIterator 47 | // -------------------------------------------------------------------------- 48 | 49 | ASStreamIterator::ASStreamIterator(istream *in) 50 | { 51 | inStream = in; 52 | linecount = 0; 53 | } 54 | 55 | ASStreamIterator::~ASStreamIterator() 56 | { 57 | delete inStream; 58 | } 59 | 60 | 61 | bool ASStreamIterator::hasMoreLines() const 62 | { 63 | if (*inStream) 64 | return true; 65 | else 66 | return false; 67 | } 68 | 69 | 70 | string ASStreamIterator::nextLine() 71 | { 72 | string buffer; 73 | getline(*inStream, buffer); 74 | if (inStream->fail() && !inStream->eof()) 75 | { 76 | string str; 77 | str = "Could not read line " ; 78 | error(str.c_str(), "(too long?)"); 79 | } 80 | if (!buffer.empty() && buffer[buffer.size() - 1] == '\r') 81 | { 82 | buffer.erase(buffer.size() - 1); 83 | } 84 | ++linecount; 85 | return buffer; 86 | } 87 | 88 | #ifdef USES_NAMESPACE 89 | } 90 | #endif 91 | -------------------------------------------------------------------------------- /src/astyle_main.cpp: -------------------------------------------------------------------------------- 1 | // $Id: astyle_main.cpp,v 1.9 2004/02/06 09:37:36 devsolar Exp $ 2 | // -------------------------------------------------------------------------- 3 | // 4 | // Copyright (c) 1998,1999,2000,2001,2002 Tal Davidson. All rights reserved. 5 | // 6 | // compiler_defines.h 7 | // by Tal Davidson (davidsont@bigfoot.com) 8 | // 9 | // This file is a part of "Artistic Style" - an indentater and reformatter 10 | // of C, C++, C# and Java source files. 11 | // 12 | // -------------------------------------------------------------------------- 13 | // 14 | // This program is free software; you can redistribute it and/or 15 | // modify it under the terms of the GNU General Public License 16 | // as published by the Free Software Foundation; either version 2 17 | // of the License, or (at your option) any later version. 18 | // 19 | // This program is distributed in the hope that it will be useful, 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | // GNU General Public License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this program; if not, write to the Free Software 26 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 27 | // 28 | // -------------------------------------------------------------------------- 29 | 30 | #include "compiler_defines.h" 31 | #include "astyle.h" 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | 40 | #ifdef WIN32 41 | #include 42 | #endif 43 | 44 | #define IS_PARAM_OPTION(arg,op) ((arg).length() < strlen(op) ? 0 : (arg).COMPARE(0, strlen(op), string(op))==0) 45 | #define IS_PARAM_OPTIONS(arg,a,b) (IS_PARAM_OPTION((arg),(a)) || IS_PARAM_OPTION((arg),(b))) 46 | 47 | #define GET_PARAM(arg,op) ((arg).substr(strlen(op))) 48 | #define GET_PARAMS(arg,a,b) (IS_PARAM_OPTION((arg),(a)) ? GET_PARAM((arg),(a)) : GET_PARAM((arg),(b))) 49 | 50 | 51 | #ifdef USES_NAMESPACE 52 | using namespace std; 53 | using namespace astyle; 54 | #endif 55 | 56 | // default options: 57 | ostream *_err = &cerr; 58 | string _suffix = ".orig"; 59 | 60 | const string _version = "1.23"; 61 | bool shouldBackupFile = true; 62 | 63 | // -------------------------------------------------------------------------- 64 | // Helper Functions 65 | // -------------------------------------------------------------------------- 66 | void SetColor(unsigned short ForeColor=3,unsigned short BackGroundColor=0) 67 | { 68 | #ifdef WIN32 69 | HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); 70 | SetConsoleTextAttribute(hCon,ForeColor|(BackGroundColor*16)); 71 | #endif 72 | } 73 | void error(const char *why, const char* what) 74 | { 75 | SetColor(12,0); 76 | (*_err) << why << ' ' << what <<'\n'; 77 | SetColor(7,0); 78 | exit(1); 79 | } 80 | 81 | 82 | 83 | bool parseOption(ASFormatter &formatter, const string &arg, const string &errorInfo) 84 | { 85 | if ( ( arg == "n" ) || ( arg == "suffix=none" ) ) 86 | { 87 | shouldBackupFile = false; 88 | } 89 | else if ( IS_PARAM_OPTION(arg, "suffix=") ) 90 | { 91 | string suffixParam = GET_PARAM(arg, "suffix="); 92 | if (suffixParam.length() > 0) 93 | _suffix = suffixParam; 94 | } 95 | else if ( arg == "style=ansi" ) 96 | { 97 | formatter.setBracketIndent(false); 98 | formatter.setSpaceIndentation(4); 99 | formatter.setBracketFormatMode(BREAK_MODE); 100 | formatter.setSwitchIndent(false); 101 | } 102 | else if ( arg == "style=gnu" ) 103 | { 104 | formatter.setBlockIndent(true); 105 | formatter.setSpaceIndentation(2); 106 | formatter.setBracketFormatMode(BREAK_MODE); 107 | formatter.setSwitchIndent(false); 108 | } 109 | else if ( arg == "style=kr" ) 110 | { 111 | formatter.setBracketIndent(false); 112 | formatter.setSpaceIndentation(4); 113 | formatter.setBracketFormatMode(ATTACH_MODE); 114 | formatter.setSwitchIndent(false); 115 | } 116 | else if ( IS_PARAM_OPTIONS(arg, "t", "indent=tab=") ) 117 | { 118 | int spaceNum = 4; 119 | string spaceNumParam = GET_PARAMS(arg, "t", "indent=tab="); 120 | if (spaceNumParam.length() > 0) 121 | { 122 | spaceNum = atoi(spaceNumParam.c_str()); 123 | if(spaceNum==0) 124 | { 125 | (*_err) << errorInfo << arg << endl; 126 | return false; // unknown option 127 | } 128 | } 129 | formatter.setTabIndentation(spaceNum, false); 130 | } 131 | else if ( IS_PARAM_OPTIONS(arg, "T", "force-indent=tab=") ) 132 | { 133 | int spaceNum = 4; 134 | string spaceNumParam = GET_PARAMS(arg, "T", "force-indent=tab="); 135 | if (spaceNumParam.length() > 0) 136 | { 137 | spaceNum = atoi(spaceNumParam.c_str()); 138 | if(spaceNum==0) 139 | { 140 | (*_err) << errorInfo << arg << endl; 141 | return false; // unknown option 142 | } 143 | } 144 | formatter.setTabIndentation(spaceNum, true); 145 | } 146 | else if ( IS_PARAM_OPTION(arg, "indent=tab") ) 147 | { 148 | formatter.setTabIndentation(4); 149 | } 150 | else if ( IS_PARAM_OPTIONS(arg, "s", "indent=spaces=") ) 151 | { 152 | int spaceNum = 4; 153 | string spaceNumParam = GET_PARAMS(arg, "s", "indent=spaces="); 154 | if (spaceNumParam.length() > 0) 155 | { 156 | spaceNum = atoi(spaceNumParam.c_str()); 157 | if(spaceNum==0) 158 | { 159 | (*_err) << errorInfo << arg << endl; 160 | return false; // unknown option 161 | } 162 | } 163 | formatter.setSpaceIndentation(spaceNum); 164 | } 165 | else if ( IS_PARAM_OPTION(arg, "indent=spaces") ) 166 | { 167 | formatter.setSpaceIndentation(4); 168 | } 169 | else if ( IS_PARAM_OPTIONS(arg, "M", "max-instatement-indent=") ) 170 | { 171 | int maxIndent = 40; 172 | string maxIndentParam = GET_PARAMS(arg, "M", "max-instatement-indent="); 173 | if (maxIndentParam.length() > 0) 174 | maxIndent = atoi(maxIndentParam.c_str()); 175 | if(maxIndent==0) 176 | { 177 | (*_err) << errorInfo << arg << endl; 178 | return false; // unknown option 179 | } 180 | 181 | formatter.setMaxInStatementIndentLength(maxIndent); 182 | } 183 | else if ( IS_PARAM_OPTIONS(arg, "m", "min-conditional-indent=") ) 184 | { 185 | int minIndent = 0; 186 | string minIndentParam = GET_PARAMS(arg, "m", "min-conditional-indent="); 187 | if (minIndentParam.length() > 0) 188 | { 189 | minIndent = atoi(minIndentParam.c_str()); 190 | if(minIndent==0) 191 | { 192 | (*_err) << errorInfo << arg << endl; 193 | return false; // unknown option 194 | } 195 | } 196 | formatter.setMinConditionalIndentLength(minIndent); 197 | } 198 | else if ( (arg == "B") || (arg == "indent-brackets") ) 199 | { 200 | formatter.setBracketIndent(true); 201 | } 202 | else if ( (arg == "G") || (arg == "indent-blocks") ) 203 | { 204 | formatter.setBlockIndent(true); 205 | } 206 | else if ( (arg == "b") || (arg == "brackets=break") ) 207 | { 208 | formatter.setBracketFormatMode(BREAK_MODE); 209 | } 210 | else if ( (arg == "a") || (arg == "brackets=attach") ) 211 | { 212 | formatter.setBracketFormatMode(ATTACH_MODE); 213 | } 214 | else if ( (arg == "O") || (arg == "one-line=keep-blocks") ) 215 | { 216 | formatter.setBreakOneLineBlocksMode(false); 217 | } 218 | else if ( (arg == "o") || (arg == "one-line=keep-statements") ) 219 | { 220 | formatter.setSingleStatementsMode(false); 221 | } 222 | else if ( arg == "pad=paren" ) 223 | { 224 | formatter.setParenthesisPaddingMode(true); 225 | } 226 | else if ((arg == "l") || ( arg == "pad=block" )) 227 | { 228 | formatter.setBlockPaddingMode(true); 229 | } 230 | else if ( (arg == "P") || (arg == "pad=all") ) 231 | { 232 | formatter.setOperatorPaddingMode(true); 233 | formatter.setParenthesisPaddingMode(true); 234 | formatter.setBlockPaddingMode(true); 235 | } 236 | else if ( (arg == "p") || (arg == "pad=oper") ) 237 | { 238 | formatter.setOperatorPaddingMode(true); 239 | } 240 | else if ( (arg == "E") || (arg == "fill-empty-lines") ) 241 | { 242 | formatter.setEmptyLineFill(true); 243 | } 244 | else if (arg == "indent-preprocessor") 245 | { 246 | formatter.setPreprocessorIndent(true); 247 | } 248 | else if (arg == "convert-tabs") 249 | { 250 | formatter.setTabSpaceConversionMode(true); 251 | } 252 | else if (arg == "break-blocks=all") 253 | { 254 | formatter.setBreakBlocksMode(true); 255 | formatter.setBreakClosingHeaderBlocksMode(true); 256 | } 257 | else if (arg == "break-blocks") 258 | { 259 | formatter.setBreakBlocksMode(true); 260 | } 261 | else if (arg == "break-elseifs") 262 | { 263 | formatter.setBreakElseIfsMode(true); 264 | } 265 | else if ( (arg == "X") || (arg == "errors-to-standard-output") ) 266 | { 267 | _err = &cout; 268 | } 269 | else if ( (arg == "v") || (arg == "version") ) 270 | { 271 | (*_err) << "iStyle " << _version << endl; 272 | } 273 | else 274 | { 275 | (*_err) << errorInfo << arg << endl; 276 | return false; // unknown option 277 | } 278 | return true; //o.k. 279 | } 280 | 281 | void importOptions(istream &in, vector &optionsVector) 282 | { 283 | char ch; 284 | string currentToken; 285 | 286 | while (in.peek() != istream::traits_type::eof()) 287 | { 288 | currentToken = ""; 289 | do 290 | { 291 | in.get(ch); 292 | 293 | // treat '#' as line comments 294 | if (ch == '#') 295 | { 296 | while (in.peek() != istream::traits_type::eof()) 297 | { 298 | in.get(ch); 299 | if (ch == '\n') 300 | break; 301 | } 302 | continue; 303 | } 304 | 305 | // break options on spaces, tabs or new-lines 306 | if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') 307 | break; 308 | else 309 | currentToken.append(1, ch); 310 | 311 | } 312 | while (in.peek() != istream::traits_type::eof()); 313 | 314 | if (currentToken.length() != 0) 315 | optionsVector.push_back(currentToken); 316 | } 317 | } 318 | 319 | template 320 | bool parseOptions(ASFormatter &formatter, 321 | const ITER &optionsBegin, 322 | const ITER &optionsEnd, 323 | const string &errorInfo) 324 | { 325 | ITER option; 326 | bool ok = true; 327 | string arg, subArg; 328 | 329 | for (option = optionsBegin; option != optionsEnd; ++option) 330 | { 331 | arg = *option; //string(*option); 332 | 333 | if (arg.COMPARE(0, 2, string("--")) == 0) 334 | ok &= parseOption(formatter, arg.substr(2), errorInfo); 335 | else if (arg[0] == '-') 336 | { 337 | for (unsigned int i=1; i < arg.length(); ++i) 338 | { 339 | if (isalpha(arg[i]) && i > 1) 340 | { 341 | ok &= parseOption(formatter, subArg, errorInfo); 342 | subArg = ""; 343 | } 344 | subArg.append(1, arg[i]); 345 | } 346 | ok &= parseOption(formatter, subArg, errorInfo); 347 | subArg = ""; 348 | } 349 | else 350 | { 351 | ok &= parseOption(formatter, arg, errorInfo); 352 | subArg = ""; 353 | } 354 | } 355 | 356 | return ok; 357 | } 358 | 359 | void printTitle() 360 | { 361 | cout << endl; 362 | 363 | SetColor(10,0); 364 | cout << "iStyle " << _version << endl; 365 | 366 | SetColor(2,0); 367 | cout << " Fast and Free Automatic Formatter for Verilog Source Code\n"; 368 | cout << " Created by haimag\n"; 369 | cout << " Thanks to Tal Davidson & Astyle\n"; 370 | cout << " Report bugs https://github.com/thomasrussellmurphy/istyle-verilog-formatter/issues\n"; 371 | cout << endl; 372 | SetColor(7,0); 373 | } 374 | 375 | void printHelpBase() 376 | { 377 | printTitle(); 378 | SetColor(14,0); 379 | 380 | cout << endl; 381 | cout << "Usage:\n"; 382 | cout << " iStyle [options] Foo.v B*r.v [...]\n"; 383 | cout << " OR, use stdin/stdout\n"; 384 | cout << " iStyle [options] Foo_formatted.v\n"; 385 | cout << endl; 386 | } 387 | 388 | void printHelpSimple(int isGetchar=0) 389 | { 390 | printHelpBase(); 391 | 392 | SetColor(7,0); 393 | cout << "For help on options, type 'iStyle -h'" ; 394 | 395 | if(isGetchar == 1) 396 | { 397 | cout << ", Press ENTER to exit." << endl; 398 | getchar(); 399 | } 400 | else 401 | { 402 | cout<<"."< fileNameVector; 598 | vector optionsVector; 599 | string optionsFileName = ""; 600 | string arg; 601 | bool ok = true; 602 | bool shouldPrintHelp = false; 603 | bool shouldParseOptionsFile = true; 604 | 605 | _err = &cerr; 606 | _suffix = ".orig"; 607 | 608 | // manage flags 609 | for (int i=1; i fileOptionsVector; 665 | // reading (whitespace seperated) strings from file into string vector 666 | importOptions(optionsIn, fileOptionsVector); 667 | ok = parseOptions(formatter, 668 | fileOptionsVector.begin(), 669 | fileOptionsVector.end(), 670 | string("Unknown option in default options file: ")); 671 | 672 | } 673 | 674 | optionsIn.close(); 675 | 676 | if (!ok) 677 | { 678 | printHelpSimple(); 679 | exit(1); 680 | } 681 | } 682 | } 683 | 684 | // parse options from command line 685 | 686 | ok = parseOptions(formatter, 687 | optionsVector.begin(), 688 | optionsVector.end(), 689 | string("Unknown command line option: ")); 690 | if (!ok) 691 | { 692 | printHelpSimple(); 693 | exit(1); 694 | } 695 | 696 | if (shouldPrintHelp) 697 | { 698 | printHelpFull(); 699 | exit(1); 700 | 701 | } 702 | 703 | // if no files have been given, use cin for input and cout for output 704 | if (fileNameVector.empty() ) 705 | { 706 | formatUsingStreams(formatter, &cin, &cout); 707 | } 708 | else 709 | { 710 | // Running in file-based mode, so can provide information on stdout 711 | printTitle(); 712 | 713 | // indent the given files 714 | for (unsigned int i=0; i