Doxygen
Loading...
Searching...
No Matches
fortranscanner.h File Reference
#include "parserintf.h"
Include dependency graph for fortranscanner.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  FortranOutlineParser
 Fortran language parser using state-based lexical scanning. More...
class  FortranOutlineParserFree
class  FortranOutlineParserFixed

Functions

const char * prepassFixedForm (const char *contents, int *hasContLine, int fixedCommentAfter)
bool recognizeFixedForm (const DString &contents, FortranFormat format)
FortranFormat convertFileNameFortranParserCode (const DString &fn)

Function Documentation

◆ convertFileNameFortranParserCode()

FortranFormat convertFileNameFortranParserCode ( const DString & fn)

Definition at line 2195 of file fortranscanner.l.

2196{
2197 DString ext = getFileNameExtension(fn);
2198 DString parserName = Doxygen::parserManager->getParserName(ext);
2199
2200 if (parserName == "fortranfixed") return FortranFormat::Fixed;
2201 else if (parserName == "fortranfree") return FortranFormat::Free;
2202
2204}
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:84
static ParserManager * parserManager
Definition doxygen.h:122
DString getParserName(const DString &extension)
Gets the name of the parser associated with given extension.
Definition parserintf.h:268
DString getFileNameExtension(const DString &fn)
Definition util.cpp:4210

References Fixed, Free, getFileNameExtension(), ParserManager::getParserName(), Doxygen::parserManager, and Unknown.

Referenced by convertCppComments(), and setFileName().

◆ prepassFixedForm()

const char * prepassFixedForm ( const char * contents,
int * hasContLine,
int fixedCommentAfter )

Definition at line 1863 of file fortranscanner.l.

1864{
1865 int column=0;
1866 int prevLineLength=0;
1867 int prevLineAmpOrExclIndex=-1;
1868 int skipped = 0;
1869 char prevQuote = '\0';
1870 char thisQuote = '\0';
1871 bool emptyLabel=true;
1872 bool commented=false;
1873 bool inSingle=false;
1874 bool inDouble=false;
1875 bool inBackslash=false;
1876 bool fullCommentLine=true;
1877 bool artificialComment=false;
1878 bool spaces=true;
1879 int newContentsSize = (int)strlen(contents)+3; // \000, \n (when necessary) and one spare character (to avoid reallocation)
1880 char* newContents = (char*)malloc(newContentsSize);
1881 int curLine = 1;
1882 size_t sizCont;
1883
1884 int j = -1;
1885 sizCont = strlen(contents);
1886 for(size_t i=0;i<sizCont;i++) {
1887 column++;
1888 char c = contents[i];
1889 if (artificialComment && c != '\n')
1890 {
1891 if (c == '!' && spaces)
1892 {
1893 newContents[j++] = c;
1894 artificialComment = false;
1895 spaces = false;
1896 skipped = 0;
1897 continue;
1898 }
1899 else if (c == ' ' || c == '\t') continue;
1900 else
1901 {
1902 spaces = false;
1903 skipped++;
1904 continue;
1905 }
1906 }
1907
1908 j++;
1909 if (j>=newContentsSize-3) { // check for spare characters, which may be eventually used below (by & and '! ')
1910 newContents = (char*)realloc(newContents, newContentsSize+1000);
1911 newContentsSize = newContentsSize+1000;
1912 }
1913
1914 switch(c) {
1915 case '\n':
1916 if (!fullCommentLine)
1917 {
1918 prevLineLength=column;
1919 prevLineAmpOrExclIndex=getAmpOrExclAtTheEnd(&contents[i-prevLineLength+1], prevLineLength,prevQuote);
1920 if (prevLineAmpOrExclIndex == -1) prevLineAmpOrExclIndex = column - 1;
1921 if (skipped)
1922 {
1923 prevLineAmpOrExclIndex = -1;
1924 skipped = 0;
1925 }
1926 }
1927 else
1928 {
1929 prevLineLength+=column;
1930 /* Even though a full comment line is not really a comment line it can be seen as one. An empty line is also seen as a comment line (small bonus) */
1931 if (hasContLine)
1932 {
1933 hasContLine[curLine - 1] = 1;
1934 }
1935 }
1936 artificialComment=false;
1937 spaces=true;
1938 fullCommentLine=true;
1939 column=0;
1940 emptyLabel=true;
1941 commented=false;
1942 newContents[j]=c;
1943 prevQuote = thisQuote;
1944 curLine++;
1945 break;
1946 case ' ':
1947 case '\t':
1948 newContents[j]=c;
1949 break;
1950 case '\000':
1951 if (hasContLine)
1952 {
1953 free(newContents);
1954 return nullptr;
1955 }
1956 newContents[j]='\000';
1957 newContentsSize = (int)strlen(newContents);
1958 if (newContents[newContentsSize - 1] != '\n')
1959 {
1960 // to be on the safe side
1961 newContents = (char*)realloc(newContents, newContentsSize+2);
1962 newContents[newContentsSize] = '\n';
1963 newContents[newContentsSize + 1] = '\000';
1964 }
1965 return newContents;
1966 case '"':
1967 case '\'':
1968 case '\\':
1969 if ((column <= fixedCommentAfter) && (column!=6) && !commented)
1970 {
1971 // we have some special cases in respect to strings and escaped string characters
1972 fullCommentLine=false;
1973 newContents[j]=c;
1974 if (c == '\\')
1975 {
1976 inBackslash = !inBackslash;
1977 break;
1978 }
1979 else if (c == '\'')
1980 {
1981 if (!inDouble)
1982 {
1983 inSingle = !inSingle;
1984 if (inSingle) thisQuote = c;
1985 else thisQuote = '\0';
1986 }
1987 break;
1988 }
1989 else if (c == '"')
1990 {
1991 if (!inSingle)
1992 {
1993 inDouble = !inDouble;
1994 if (inDouble) thisQuote = c;
1995 else thisQuote = '\0';
1996 }
1997 break;
1998 }
1999 }
2000 inBackslash = false;
2001 // fallthrough
2002 case '#':
2003 case 'C':
2004 case 'c':
2005 case '*':
2006 case '!':
2007 if ((column <= fixedCommentAfter) && (column!=6))
2008 {
2009 emptyLabel=false;
2010 if (column==1)
2011 {
2012 newContents[j]='!';
2013 commented = true;
2014 }
2015 else if ((c == '!') && !inDouble && !inSingle)
2016 {
2017 newContents[j]=c;
2018 commented = true;
2019 }
2020 else
2021 {
2022 if (!commented) fullCommentLine=false;
2023 newContents[j]=c;
2024 }
2025 break;
2026 }
2027 // fallthrough
2028 default:
2029 if (!commented && (column < 6) && ((c - '0') >= 0) && ((c - '0') <= 9))
2030 { // remove numbers, i.e. labels from first 5 positions.
2031 newContents[j]=' ';
2032 }
2033 else if (column==6 && emptyLabel)
2034 { // continuation
2035 if (!commented) fullCommentLine=false;
2036 if (c != '0')
2037 { // 0 not allowed as continuation character, see f95 standard paragraph 3.3.2.3
2038 newContents[j]=' ';
2039
2040 if (prevLineAmpOrExclIndex==-1)
2041 { // add & just before end of previous line
2042 /* first line is not a continuation line in code, just in snippets etc. */
2043 if (curLine != 1) insertCharacter(newContents, j+1, (j+1)-6-1, '&');
2044 j++;
2045 }
2046 else
2047 { // add & just before end of previous line comment
2048 /* first line is not a continuation line in code, just in snippets etc. */
2049 if (curLine != 1) insertCharacter(newContents, j+1, (j+1)-6-prevLineLength+prevLineAmpOrExclIndex+skipped, '&');
2050 skipped = 0;
2051 j++;
2052 }
2053 if (hasContLine)
2054 {
2055 hasContLine[curLine - 1] = 1;
2056 }
2057 }
2058 else
2059 {
2060 newContents[j]=c; // , just handle like space
2061 }
2062 prevLineLength=0;
2063 }
2064 else if ((column > fixedCommentAfter) && !commented)
2065 {
2066 // first non commented non blank character after position fixedCommentAfter
2067 if (c == '&')
2068 {
2069 newContents[j]=' ';
2070 }
2071 else if (c != '!')
2072 {
2073 // I'm not a possible start of doxygen comment
2074 newContents[j]=' ';
2075 artificialComment = true;
2076 spaces=true;
2077 skipped = 0;
2078 }
2079 else
2080 {
2081 newContents[j]=c;
2082 commented = true;
2083 }
2084 }
2085 else
2086 {
2087 if (!commented) fullCommentLine=false;
2088 newContents[j]=c;
2089 emptyLabel=false;
2090 }
2091 break;
2092 }
2093 }
2094
2095 if (hasContLine)
2096 {
2097 free(newContents);
2098 return nullptr;
2099 }
2100
2101 if (j==-1) // contents was empty
2102 {
2103 newContents = (char*)realloc(newContents, 2);
2104 newContents[0] = '\n';
2105 newContents[1] = '\000';
2106 }
2107 else if (newContents[j] == '\n') // content ended with newline
2108 {
2109 newContents = (char*)realloc(newContents, j+2);
2110 newContents[j + 1] = '\000';
2111 }
2112 else // content did not end with a newline
2113 {
2114 newContents = (char*)realloc(newContents, j+3);
2115 newContents[j + 1] = '\n';
2116 newContents[j + 2] = '\000';
2117 }
2118 return newContents;
2119}
static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch)
static void insertCharacter(char *contents, int length, int pos, char c)

References getAmpOrExclAtTheEnd(), and insertCharacter().

Referenced by checkContLines(), and parseMain().

◆ recognizeFixedForm()

bool recognizeFixedForm ( const DString & contents,
FortranFormat format )

Definition at line 2142 of file fortranscanner.l.

2143{
2144 int column=0;
2145 bool skipLine=false;
2146
2147 if (format == FortranFormat::Fixed) return true;
2148 if (format == FortranFormat::Free) return false;
2149
2150 int tabSize=Config_getInt(TAB_SIZE);
2151 size_t sizCont = contents.length();
2152 for (size_t i=0;i<sizCont;i++)
2153 {
2154 column++;
2155
2156 switch(contents.at(i))
2157 {
2158 case '\n':
2159 column=0;
2160 skipLine=false;
2161 break;
2162 case '\t':
2163 column += tabSize-1;
2164 break;
2165 case ' ':
2166 break;
2167 case '\000':
2168 return false;
2169 case '#':
2170 skipLine=true;
2171 break;
2172 case 'C':
2173 case 'c':
2174 if (column==1)
2175 {
2176 return !keyWordsFortranC(contents.data()+i);
2177 }
2178 // fallthrough
2179 case '*':
2180 if (column==1) return true;
2181 if (skipLine) break;
2182 return false;
2183 case '!':
2184 if (column!=6) skipLine=true;
2185 break;
2186 default:
2187 if (skipLine) break;
2188 if (column>=7) return true;
2189 return false;
2190 }
2191 }
2192 return false;
2193}
char & at(size_t i)
Returns a reference to the character at index i.
Definition dstring.h:686
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition dstring.h:157
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:151
#define Config_getInt(name)
Definition config.h:34
static bool keyWordsFortranC(const char *contents)

References DString::at(), Config_getInt, DString::data(), Fixed, Free, keyWordsFortranC(), and DString::length().

Referenced by convertCppComments(), FortranCodeParser::parseCode(), parseMain(), and setFileName().