├── AUTHORS ├── LICENSE ├── README.md └── fortsearch.sh /AUTHORS: -------------------------------------------------------------------------------- 1 | Dominik Zobel 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2022 Dominik Zobel. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | fortsearch 2 | ========== 3 | 4 | [fortsearch](https://github.com/d-zo/fortsearch) is a shell script to find and highlight modules, 5 | subroutines, functions, and variables from all (Fortran 90+) files in a given directory. 6 | Internally the hard work is done almost exclusively by grep and sed commands. 7 | It was created alongside work at the German Climate Computing Center in Hamburg. 8 | 9 | 10 | Installation 11 | ------------ 12 | 13 | fortsearch does not have to be installed. To run the script, simply download it and execute it like 14 | ``` 15 | bash fortsearch.sh 16 | ``` 17 | 18 | If this script proves to be useful, a good place is to store or link it as `fortsearch` 19 | with executable permissions within a `PATH` directory of the current user (sometimes `~/.local/bin/`). 20 | This allows calling it from any terminal simply by 21 | ``` 22 | fortsearch 23 | ``` 24 | 25 | 26 | Usage 27 | ----- 28 | 29 | Typically fortsearch needs some options for a meaningful run like 30 | 31 | - the path to a directory with Fortran source code files of interest (`fort-search-dir`) 32 | - What the search should focus on: 33 | - either variable names (`-var`), 34 | - function/subroutine names (`-fun`), or 35 | - module names (`-mod`) 36 | 37 | - What name to search for (`search-term`) 38 | - Optionally if only its definition should be found (`def`) or the usage of derived values from it (`outer`) 39 | 40 | In short, the command is 41 | 42 | ``` 43 | fortsearch [fort-search-dir] {-var|-fun|-mod} [def|outer] 44 | ``` 45 | 46 | 47 | Shortcomings 48 | ------------ 49 | 50 | Although fortsearch does find all regular uses of variables/functions/subroutines/modules, 51 | it does also return false positives (e.g. when the name is used within a string). 52 | Usually these can easily be spotted and can be ruled out. 53 | 54 | fortsearch does not do any macro processing. 55 | So any names generated as a result of a macro operation should not be expected to be found. 56 | 57 | Currently there should be no colons (`:`) in the filename or the highlighting will not work correctly. 58 | 59 | 60 | 61 | Contributing 62 | ------------ 63 | 64 | **Bug reports** 65 | 66 | If you found a bug, make sure you can reproduce it with the latest version of fortsearch 67 | and not part of the known shortcomings. 68 | 69 | 70 | License 71 | ------- 72 | 73 | fortsearch is released under the BSD 3-Clause "Revised" License 74 | (see also [LICENSE](https://github.com/d-zo/fortsearch/blob/master/LICENSE) file). 75 | It is provided without any warranty. 76 | -------------------------------------------------------------------------------- /fortsearch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2022 Dominik Zobel. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 9 | # 1. Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # 2. Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # 3. Neither the name of the copyright holder nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | 32 | # Either ignore matches in comments (1) or not (0) 33 | ignore_comments=1 34 | 35 | # A root directory provided here is used as a fallback if no directory 36 | # is given when this script is called 37 | FORT_BASE_ROOT="/path/to/Fortran/sources" 38 | 39 | 40 | function Usage() { 41 | echo "Usage: $0 [fort-search-dir] {-var|-fun|-mod} [def|outer]" 42 | echo " prints lines with occurences of in [fort-search-dir]" 43 | echo " (typically including Fortran source files). The output depends on" 44 | echo " whether is a variable (-var), a function/subroutine/" 45 | echo " interface (-fun) or module (-mod). A shell variable named FORT_ROOT" 46 | echo " can be used Instead of specifying [fort-search-dir]. If only the" 47 | echo " definition/creation should be found, pass \"def\" as last argument." 48 | echo " To include cases where derived types within are used (%...)," 49 | echo " pass \"outer\"" 50 | echo "" 51 | echo " Output for -var has the following flags" 52 | echo " C Creation/initialisation of variable" 53 | echo " M Memory allocation of variable" 54 | echo " = Assignment to variable" 55 | echo " . Other occurences of variable" 56 | echo "" 57 | echo " Output for -fun/-mod has the following flags" 58 | echo " C Creation/initialisation of function/subroutine/interface" 59 | echo " E End of definition" 60 | echo " . Other occurences/calls of function/subroutine/interface" 61 | exit 1 62 | } 63 | 64 | DEF_ONLY=0 65 | WITH_OUTER=0 66 | 67 | case $# in 68 | 4) if [ "$4" == "def" ]; then 69 | DEF_ONLY=1 70 | elif [ "$4" == "outer" ]; then 71 | WITH_OUTER=1 72 | else 73 | Usage 74 | fi 75 | FORT_ROOT="$1" 76 | SEARCH_TYPE="$2" 77 | SEARCH_VAR="$3";; 78 | 3) if [ "$3" == "def" ]; then 79 | DEF_ONLY=1 80 | SEARCH_TYPE="$1" 81 | SEARCH_VAR="$2" 82 | elif [ "$3" == "outer" ]; then 83 | WITH_OUTER=1 84 | SEARCH_TYPE="$1" 85 | SEARCH_VAR="$2" 86 | else 87 | FORT_ROOT="$1" 88 | SEARCH_TYPE="$2" 89 | SEARCH_VAR="$3" 90 | fi;; 91 | 2) SEARCH_TYPE="$1" 92 | SEARCH_VAR="$2";; 93 | *) Usage;; 94 | esac 95 | 96 | if [ "${SEARCH_TYPE}" != "-var" ] && [ "${SEARCH_TYPE}" != "-fun" ] && [ "${SEARCH_TYPE}" != "-mod" ]; then 97 | Usage; 98 | fi 99 | 100 | if [ -z "${FORT_ROOT}" ]; then 101 | echo "FORT_ROOT unset. Using ${FORT_BASE_ROOT}" 102 | FORT_ROOT="${FORT_BASE_ROOT}" 103 | else 104 | echo "Using FORT_ROOT=${FORT_ROOT}" 105 | fi 106 | 107 | if [ ! -d "${FORT_ROOT}" ]; then 108 | echo "FORT_ROOT not found: ${FORT_ROOT}" 109 | exit 1 110 | fi 111 | 112 | COLMARK=\\x1b[33m 113 | COLFILE=\\x1b[32m 114 | COLLINE=\\x1b[35m 115 | COLVAR=\\x1b[31m 116 | COLRESET=\\x1b[0m 117 | 118 | # Highlight typemark, file and line number as well as variable in the middle of a code line and at the end 119 | highlightinitial='s!^\(.\{2\}\)'${FORT_ROOT}'/!\1!;'\ 120 | 's!^\(.\):\([^:]\+\):\([0-9]\+\):!'${COLMARK}'\1'${COLRESET}':'${COLFILE}'\2'${COLRESET}':'${COLLINE}'\3'${COLRESET}':!;' 121 | 122 | highlightname='s!\([^A-Za-z0-9_]\+\)\('${SEARCH_VAR}'\)\([^A-Za-z0-9_]\+\)!\1'${COLVAR}'\2'${COLRESET}'\3!gi;'\ 123 | 's!\([^A-Za-z0-9_]\+\)\('${SEARCH_VAR}'\)$!\1'${COLVAR}'\2'${COLRESET}'!gi' 124 | 125 | SEARCH_START_COND='(^|[^A-Za-z0-9_])' 126 | if [ ${WITH_OUTER} -eq 1 ]; then 127 | SEARCH_END_COND='([^A-Za-z0-9_]|$)' 128 | else 129 | SEARCH_END_COND='([^A-Za-z0-9_%]|$)' 130 | fi 131 | 132 | while IFS= read line; do 133 | templine=$(echo "${line}" | sed -e 's/[^:]*:[0-9]\+:\(.*\)/\1/') 134 | # It should not matter, that "!" in strings are also regarded as comments. Otherwise adjust the following lines or use ignore_comments=0 135 | if [ 1 -eq ${ignore_comments} ]; then 136 | # Ignore full comment lines 137 | if [ "x$(echo "${templine}" | egrep -i '^[ ]*!')" != "x" ]; then 138 | continue 139 | fi 140 | # Also ignore all lines with comments where ${SEARCH_VAR} is not found before the comment character 141 | if [ "x$(echo "${templine}" | sed -e 's/^\([^!]*\).*/\1/g' | egrep -i ${SEARCH_START_COND}${SEARCH_VAR}${SEARCH_END_COND})" == "x" ]; then 142 | continue 143 | fi 144 | fi 145 | # 146 | if [ "${SEARCH_TYPE}" == "-var" ]; then 147 | # NOTE: Definitions with custom types are not recognized as "C" but "." 148 | if [ "x$(echo "${templine}" | egrep -i '(integer|real|logical|character|double|type).*[, :]+'${SEARCH_VAR}${SEARCH_END_COND})" != "x" ]; then 149 | typemark='C' 150 | elif [ "x$(echo "${templine}" | egrep -i 'allocate[ ]*\((.*%|)'${SEARCH_VAR}'[ ]*[()]+')" != "x" ]; then 151 | typemark='M' 152 | elif [ "x$(echo "${templine}" | egrep -i '(^[ ]*|.*%)'${SEARCH_VAR}'[ ]*(\([^)]*\)[ ]*|)=')" != "x" ]; then 153 | typemark='=' 154 | else 155 | typemark='.' 156 | fi 157 | elif [ "${SEARCH_TYPE}" == "-fun" ]; then 158 | if [ "x$(echo "${templine}" | egrep -i '(function|subroutine|interface)[ ]+'${SEARCH_VAR})" != "x" ]; then 159 | typemark='C' 160 | elif [ "x$(echo "${templine}" | egrep -i '^[ ]*end[ ]+(function|subroutine|interface)[ ]+'${SEARCH_VAR})" != "x" ]; then 161 | typemark='E' 162 | else 163 | typemark='.' 164 | fi 165 | else 166 | if [ "x$(echo "${templine}" | egrep -i 'module[ ]+'${SEARCH_VAR})" != "x" ]; then 167 | typemark='C' 168 | elif [ "x$(echo "${templine}" | egrep -i '^[ ]*end[ ]+module[ ]+'${SEARCH_VAR})" != "x" ]; then 169 | typemark='E' 170 | else 171 | typemark='.' 172 | fi 173 | fi 174 | if [ 1 -eq ${DEF_ONLY} ] && [ "${typemark}" != "C" ]; then 175 | continue 176 | fi 177 | initial=$(echo "${line}" | sed -e 's/\([^:]*:[0-9]\+:\).*/\1/') 178 | echo "$(echo "${typemark}:${initial}" | sed -e "${highlightinitial}")$(echo "${templine}" | sed -e "${highlightname}")" 179 | done < <(egrep -rIin ${SEARCH_START_COND}${SEARCH_VAR}${SEARCH_END_COND} ${FORT_ROOT} | sort -V) 180 | # Use version sort to keep order in regard to line numbers for matches within a given filename 181 | 182 | exit 0 183 | 184 | # If the color coding of the output should be removed (e.g. for further shell processing) 185 | # one possibility is to pass the output to "sed -e 's/\x1b\[[0-9;]*[JKmsu]//g'" first 186 | --------------------------------------------------------------------------------