# # This program source code file is part of KICAD, a free EDA CAD application. # # Copyright (C) 2010 Wayne Stambaugh # Copyright (C) 2010 Kicad Developers, see AUTHORS.txt for contributors. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, you may find one here: # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html # or you may search the http://www.gnu.org website for the version 2 license, # or you may write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA # # # This script converts a plain text file with a line feed separated list # of token names into the appropriate source and header files required by # the DSN lexer. See files "/common/dsnlexer.cpp" and # "/include/dsnlexer.h" for more information about how # the DSN lexer works. The token list file format requires a single token # per line. Tokens can only contain lower case letters, numbers, and # underscores. The first letter of each token must be a lower case letter. # Tokens must be unique. If any of the above criteria are not met, the # source and header files will not be generated and a build error will # occur. # # Valid tokens: a a1 foo_1 foo_bar2 # Invalid tokens: 1 A _foo bar_ foO # # Usage: # # add_custom_command( # OUTPUT ${CMAKE_BINARY_DIR}/cmp_library_base.h # COMMAND ${CMAKE_COMMAND} # -DinputFile=${CMAKE_CURRENT_SOURCE_DIR}/token_list_file # -P ${CMAKE_MODULE_PATH}/TokenList2DsnLexer.cmake # DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library.lst # ) # # Input parameters: # # inputFile - The name of the token list file. # outputPath - Optional output path to save the generated files. If not defined, # the output path is the same path as the token list file path. # set( tokens "" ) set( lineCount 0 ) set( dsnErrorMsg "DSN token file generator failure:" ) if( NOT EXISTS ${inputFile} ) message( FATAL_ERROR "${dsnErrorMsg} file ${inputFile} cannot be found." ) endif( NOT EXISTS ${inputFile} ) if( NOT EXISTS ${outputPath} ) get_filename_component( outputPath "${inputFile}" PATH ) endif( NOT EXISTS ${outputPath} ) # Separate the file name without extension from the full file path. get_filename_component( result "${inputFile}" NAME_WE ) message( STATUS "Extracted file name ${result} from path ${inputFile}" ) # Create include and source file name from the list file name. set( includeFileName "${outputPath}/${result}_base.h" ) set( sourceFileName "${outputPath}/${result}_base.cpp" ) # Create tag for generating header file. string( TOUPPER "${result}" fileNameTag ) set( headerTag "_${fileNameTag}_H_" ) set( includeFileHeader " /* * Do not modify this file it was automatically generated by the TokenList2DsnLexer CMake * script. */ #ifndef ${headerTag} #define ${headerTag} #include \"dsnlexer.h\" namespace DSN { enum DSN_T { // these first few are negative special ones for syntax, and are // inherited from DSNLEXER. T_NONE = DSN_NONE, T_COMMENT = DSN_COMMENT, T_STRING_QUOTE = DSN_STRING_QUOTE, T_QUOTE_DEF = DSN_QUOTE_DEF, T_DASH = DSN_DASH, T_SYMBOL = DSN_SYMBOL, T_NUMBER = DSN_NUMBER, T_RIGHT = DSN_RIGHT, // right bracket, ')' T_LEFT = DSN_LEFT, // left bracket, '(' T_STRING = DSN_STRING, // a quoted string, stripped of the quotes T_EOF = DSN_EOF, // special case for end of file " ) set( sourceFileHeader " /* * Do not modify this file it was automatically generated by the TokenList2DsnLexer CMake * script. * * Include this file in your lexer class to provide the keywords for you DSN lexer. */ #include \"fctsys.h\" #include \"macros.h\" #include \"${result}_base.h\" namespace DSN { #define TOKDEF(x) { #x, T_##x } const KEYWORD ${result}_keywords[] = { " ) file( STRINGS ${inputFile} tmpTokens NO_HEX_CONVERSION ) foreach( tmpToken ${tmpTokens} ) math( EXPR lineCount "${lineCount} + 1" ) string( STRIP tmpToken "${tmpToken}" ) # Ignore empty lines. if( tmpToken ) # Make sure token is valid. string( REGEX MATCH "[a-z][_0-9a-z]*[0-9a-z]$" validToken "${tmpToken}" ) if( validToken STREQUAL tmpToken ) list( APPEND tokens "${validToken}" ) else( validToken STREQUAL tmpToken ) message( FATAL_ERROR "Invalid token string \"${tmpToken}\" at line ${lineCount} in file " "<${inputFile}>." ) endif( validToken STREQUAL tmpToken ) endif( tmpToken ) endforeach( tmpToken ${tmpTokens} ) list( SORT tokens ) # Check for duplicates. list( LENGTH tokens tokensBefore ) list( REMOVE_DUPLICATES tokens ) list( LENGTH tokens tokensAfter ) if( NOT ( tokensBefore EQUAL tokensAfter ) ) message( FATAL_ERROR "Duplicate tokens found in file <${inputFile}>." ) endif( NOT ( tokensBefore EQUAL tokensAfter ) ) file( WRITE "${includeFileName}" "${includeFileHeader}" ) file( WRITE "${sourceFileName}" "${sourceFileHeader}" ) set( lineCount 1 ) foreach( token ${tokens} ) if( lineCount EQUAL 1 ) file( APPEND "${includeFileName}" " T_${token} = 0" ) else( lineCount EQUAL 1 ) file( APPEND "${includeFileName}" " T_${token}" ) endif( lineCount EQUAL 1 ) file(APPEND "${sourceFileName}" " TOKDEF( ${token} )" ) if( lineCount EQUAL tokensAfter ) file( APPEND "${includeFileName}" "\n" ) file( APPEND "${sourceFileName}" "\n" ) else( lineCount EQUAL tokensAfter ) file( APPEND "${includeFileName}" ",\n" ) file( APPEND "${sourceFileName}" ",\n" ) endif( lineCount EQUAL tokensAfter ) math( EXPR lineCount "${lineCount} + 1" ) endforeach( token ${tokens} ) file( APPEND "${includeFileName}" "}; } // End namespace DSN #endif // End ${headerTag} " ) file( APPEND "${sourceFileName}" "}; const unsigned ${result}_keyword_count = DIM( ${result}_keywords ); } // End namespace DSN " )