├── .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