- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello everybody,
is there a compiler option that can detect blank space in a variable name ? Currently, I have following code, and it works great. Except There are a lot of COMMON blocks all over the place, with variables with different name and even spaces(maybe even tabs) in it...
... SECTION TOTALE = 0.D+0 DO I = 1, NOMBRE_PASSAGE PASSAGE = SEQUENCEL (I) ONDE = TYPE_ONDE_C ( PASSAGE, ZONEENTREE ) SECTIONTOTALE = SECTIONTOTALE + AC (ONDE) ENDDO ...
How can I find and replace them ?
Thks
Renaud
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Luigi's recommendations in #7 should be followed. The only thing I can add is from experience several years ago in doing this very same thing with 13 projects with 750 files.
1) Use your favorite text processing program, AWK, PYTHON, etc. (I used TECO) to search all files for COMMON blocks and produce an output file containing the COMMON block, together with name and variables declared within. I produced this on a single line for each entry.
2) Sort the output file
3) Locate all commons with same name and identical variable lists for all instances of that name. These are likely safe to move directly into a module. I used MOD_NameThatWasUsedOnCOMMONblock. *** you should not assume that all said variables have same type - so verify. You remove from the list the entries you selected. Replace the COMMON declarations with USE MOD_... (in the appropriate place), then compile and test and verify correctness.
4) Locate all named commons with a single declaration, and do the same as in 3)
5) What you have left in the list (if any) are named commons that map the common block differently. Each instance will have to be examined carefully. Identify those where same types in same locations of the block are used with different names. In these cases you can use the => feature of USE to rename those variables. In the module you create for these commons, for each variable create a new name that is not used by any of your procedures. e.g. was_X_or_X1 Then on the USE statement point the appropriate local name to the synthetic name. Note, this is a temporary step and you can cleanup the names later. Test the program.
6) what you have left in the list of commons will take very careful steps in making any changes. Perform incrementally, testing after each change.
Note on 6), you can keep those COMMONs if need be.
Jim Dempsey
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Such spaces are only allowed in fixed-form source files.
You might be able to find the occurrences compiling the sources as if they are free-form. That will probably cause a cascade of other errors and warnings, but it is one way ;).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That will be a huge work because I have a lot of files, but if that's the only way, I'll deal with it !
Thank you Arjen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Not necessarily: you can use the /free option to compile the source files. /free instructs the compiler to regard them as free-form source. Then it is a matter of identifying the right error messages.
An alternative might be to write a small program (in any language that you find suitable) to report instances of spaces in between letters. You would have to filter out things like "subroutine mysub" and "else if", as well as literal strings.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What problem are you trying to solve? It's legal to have different named variables in the COMMON blocks in different program units, though it's an extremely poor practice. Spaces (and tabs) in variable names are also legal (in fixed-form source) but not a good idea.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to reverse-engineer an old software of ours, and yeah I'm aware it's full of very bad practices, and this one is far from being the worst. That's precisely why it needs refactoring.
For that I need to understand what data(variables) are used, and where. Then, I want to replace all COMMONs with a USE MODULE statement, meaning I have to rename COMMON variables with unique name.
SUBROUTINE A INTEGER x, y COMMON /allovertheplace/ x, y x=2*y END SUBROUTINE A SUBROUTINE B INTEGER x1, y1, z1 COMMON /allovertheplace/ x1, y1, z1 x1=y1+z1 END SUBROUTINE B
will become
SUBROUTINE A USE ALLOVERTHEPLACEMOD x=2*y END SUBROUTINE A SUBROUTINE B USE ALLOVERTHEPLACEMOD x=y+z END SUBROUTINE B MODULE ALLOVERTHEPLACEMOD USE ALLOVERTHEPLACEMOD INTEGER x, y, z END MODULE ALLOVERTHEPLACEMOD
That is maybe not a good way to work, but I have to do this step if I want to understand the whole data structure of my program.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do not hurry in doing things.
A COMMON could be used as a buffer to hold variables of very different kinds. Such a structure (which is not a bad habit but an architectural choice) cannot be replaced by a MODULE.
You have to change the code step by step: make a 1st small change and test, make a 2nd small change and test, ….
The first thing I will do is to eliminate blank spaces and tabs.
Good trip.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are two separate issues here, and I think that it would be best to handle each separately.
Blanks in variable names and keywords are legal only in fixed form source, so the code snippet that you posted in #1 is not legal. Adding six leading spaces would make that code legal, but what matters is the form of your legacy source code. I assume that it is in fixed form. I suggest that you use a capable utility to convert the source code to free form. This process will clean up the code, and get rid of the non-significant spaces (and, possibly, tabs). Tools that can assist with this transformation are ftp://ftp.numerical.rl.ac.uk/pub/MandR/convert.f90, https://jblevins.org/mirror/amiller/to_f90.f90, SPAG from https://www.polyhedron.com, the NAG Fortran compiler with the =polish option, etc.
If you have lots of common blocks, and some of those blocks appear with different variable names in different places, or, worse, if the common block items have different types in different places, you probably have to do most of the conversion by hand. SPAG can take an input text file with a substitution list of variable names and replace those variable names in a number of source files.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Luigi's recommendations in #7 should be followed. The only thing I can add is from experience several years ago in doing this very same thing with 13 projects with 750 files.
1) Use your favorite text processing program, AWK, PYTHON, etc. (I used TECO) to search all files for COMMON blocks and produce an output file containing the COMMON block, together with name and variables declared within. I produced this on a single line for each entry.
2) Sort the output file
3) Locate all commons with same name and identical variable lists for all instances of that name. These are likely safe to move directly into a module. I used MOD_NameThatWasUsedOnCOMMONblock. *** you should not assume that all said variables have same type - so verify. You remove from the list the entries you selected. Replace the COMMON declarations with USE MOD_... (in the appropriate place), then compile and test and verify correctness.
4) Locate all named commons with a single declaration, and do the same as in 3)
5) What you have left in the list (if any) are named commons that map the common block differently. Each instance will have to be examined carefully. Identify those where same types in same locations of the block are used with different names. In these cases you can use the => feature of USE to rename those variables. In the module you create for these commons, for each variable create a new name that is not used by any of your procedures. e.g. was_X_or_X1 Then on the USE statement point the appropriate local name to the synthetic name. Note, this is a temporary step and you can cleanup the names later. Test the program.
6) what you have left in the list of commons will take very careful steps in making any changes. Perform incrementally, testing after each change.
Note on 6), you can keep those COMMONs if need be.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you all for your replies, that is great advice ! I'll work step by step in order to ensure that the migration went well.
Does anyone know if there's a way to write unit tests and/or measure the code coverage of my benchmark cases with IVF on Visual Studio 2015 ?
Again, thank you very well for your expertise !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are several frameworks that you can use for unit testing - see http://fortranwiki.org/fortran/show/Unit+testing+frameworks.
I wrote one myself :) - ftnunit - see http://flibs.sf.net
As for code coverage: look in Visual Studio under Tools/Intel Compiler/Code Coverage ...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello all,
I finally found all my spaces&tabs variables, and renamed them as you advised earlier by switching to free files format. That's nicer this way too (more readable)
Then, I also moved (some of) my COMMON into a module, as public variables, and the program seems to be ok with that !
Also, Arjen, you mentionned in #11 a unit testing framework, I didn't take the time to look into it, but I definitely will !
Thanks everyone :)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page