/** * \file * source code of ldf_parser */ #include #include #include #include #include "generic.h" #include "ldf_parser.h" #include "ldf.h" #ifdef TEST # include "protointerface_test.h" #else # include "protointerface.h" #endif #define NEXTG (parserp->grammar.nextGrammarContext) #define EXPECTT (parserp->grammar.expectedGrammarToken) #define EXPECTSV (parserp->grammar.expectedGrammarSpecialValue) #define WEAKT (parserp->grammar.weakExpectedGrammarToken) /*=================================================================== ======= TYPES AND VARS ============================================== ====================================================================*/ /** \addtogroup tokenizer */ /** \{ */ #define LDFPARSER_TOKENTYPESTRING_MAX_LEN 30 static const char LDFParser_tokenTypeStrings[][LDFPARSER_TOKENTYPESTRING_MAX_LEN + 1] = { "UNKNOWN_TOKENTYPE", "IDENTIFIER", "STRING", "NUMBER", "HEXNUMBER", "FLOAT", "COMMENT", }; /** \} */ /** \addtogroup grammar */ /** \{ */ #define GRAMMARCONTEXT_STACK_SIZE 10 #define LDFPARSER_GRAMMARCONTEXTSTRING_MAX_LEN 60 /** String representations of grammar::GrammarContext. */ static const char LDFParser_grammarContextStrings[][LDFPARSER_GRAMMARCONTEXTSTRING_MAX_LEN + 1] = { "GLOBAL", "GLOBAL_LIN_DESCRIPTION_FILE", "GLOBAL_LIN_PROTOCOL_VERSION", "GLOBAL_LIN_LANGUAGE_VERSION", "GLOBAL_LIN_SPEED", "GLOBAL_CHANNEL_NAME", "NODES definition", "NODES_ATTRIBUTES", "SIGNALS", "DIAGNOSTIC_SIGNALS", "FRAMES", "DIAGNOSTIC_FRAMES", "SPORADIC_FRAMES", "EVENTTRIGGERED_FRAMES", "SIGNAL_ENCODING_TYPES", "SIGNAL_REPRESENTATION", "COMPOSITE_NODES", "SCHEDULE_TABLES", "SIGNAL_GROUPS", "DYNAMIC_FRAMES", "NODES_MASTERDEF", "NODES_SLAVESDEF", "NODE_ATTRIBUTE_DEF", "NODEATTRIBUTEDEF_LIN_PROTOCOL", "NODEATTRIBUTEDEF_CONFIGURED_NAD", "NODEATTRIBUTEDEF_INITIAL_NAD", "NODEATTRIBUTEDEF_PRODUCT_ID", "NODEATTRIBUTEDEF_RESPONSE_ERROR", "NODEATTRIBUTEDEF_CONFIGURABLE_FRAMES", "NODEATTRIBUTEDEF_FAULT_STATE_SIGNALS", "NODEATTRIBUTEDEF_P2_MIN", "NODEATTRIBUTEDEF_ST_MIN", "NODEATTRIBUTEDEF_N_AS_TIMEOUT", "NODEATTRIBUTEDEF_N_CR_TIMEOUT", "NODEATTRIBUTEDEF_CONFIGURABLEFRAMESDEF_v2.0", "NODEATTRIBUTEDEF_CONFIGURABLEFRAMESDEF_v2.1", "SIGNALDEF", "SIGNALDEF_INITVALUES", "DIAGNOSTIC_SIGNALDEF", "FRAMEDEF", "FRAMEDEF_INCLUDEDSIGNALS", "DIAGNOSTICFRAMEDEF", "DIAGNOSTICFRAMEDEF_INCLUDEDSIGNALS", "SPORADICFRAMEDEF", "EVENTTRIGGEREDFRAMEDEF", "SIGNALENCODINGTYPE_DEF", "SIGNALENCODINGTYPEDEF_LOGICAL_VALUE", "SIGNALENCODINGTYPEDEF_PHYSICAL_VALUE", "SIGNALENCODINGTYPEDEF_BCD_VALUE", "SIGNALENCODINGTYPEDEF_ASCII_VALUE", "SIGNALREPRESENTATION_DEF", "COMPOSITENODE_CONFIGURATION", "COMPOSITENODE_DEF", }; #define LDFPARSER_GRAMMARTOKEN_MAX_LEN 15 /** String representations of grammar::GrammarToken. */ static const char LDFParser_grammarTokenStrings[][LDFPARSER_GRAMMARTOKEN_MAX_LEN + 1] = { "UNKNOWN TOKEN", "{", "}", ":", ";", ",", "=", "kbps", "ms", "identifier", "string", "number", "hexnumber", "float", }; /** Maximal length of defined identifiers. */ #define LDFPARSER_IDENTIFIER_MAX_LEN 30 /** Maximal length of temporary buffers which compare identifiers. */ #define LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN (LDFPARSER_IDENTIFIER_MAX_LEN + 20) /** Definition of global identifiers. */ static const char LDFParser_identifiersGlobal[][LDFPARSER_IDENTIFIER_MAX_LEN + 1] = { "LIN_description_file", "LIN_protocol_version", "LIN_language_version", "LIN_speed", "Channel_name", "Nodes", "Node_attributes", "Signals", "Diagnostic_signals", "Frames", "Diagnostic_frames", "Sporadic_frames", "Event_triggered_frames", "Signal_encoding_types", "Signal_representation", "composite", "Schedule_tables", "Signal_groups", "dynamic_frames", "", }; /** Definition of nodeAttributesDef identifiers. */ static const char LDFParser_identifiersNodeAttributesDef[][LDFPARSER_IDENTIFIER_MAX_LEN + 1] = { "LIN_protocol", "configured_NAD", "initial_NAD", "product_id", "response_error", "configurable_frames", "fault_state_signals", "P2_min", "ST_min", "N_As_timeout", "N_Cr_timeout", "", }; /** Definition of signalEncodingTypeDef identifiers. */ static const char LDFParser_identifiersSignalEncodingTypeDef[][LDFPARSER_IDENTIFIER_MAX_LEN + 1] = { "logical_value", "physical_value", "bcd_value", "ascii_value", "", }; /** \} */ /** \addtogroup ldf_parser*/ /** \{ */ #define LDFPARSER_ERRORSTRINGS_MAX 80 /** String representations of state of ldf_parser \ref LDFParser_state.*/ static const char LDFParser_stateStrings[][LDFPARSER_ERRORSTRINGS_MAX + 1] = { "everything ok.", "disabled.", "ERROR: wrong input file '%s'! (missing \"LIN_description_file;\"?)", "ERROR: Can't open file '%s'!", "ERROR: reading file '%s' failed!", "EOF reached ('%s').", "ERROR: EOF while inside token ('%s')!", "%s", /*LDFPARSER_ERROR_BUFFER_TOKENIZER*/ "%s", /*LDFPARSER_ERROR_STACK_GRAMMARCONTEXT*/ "ERROR: memory exhausted! Building LDF data failed!", }; #define POSTPARSE_EVENTTRIGGEREDFRAMES_BUFFER_INIT_SIZE 20 /** \} */ /*====================================================== ======== FUNCTIONS ===================================== ======================================================*/ /** \addtogroup tokenizer */ /** \{ */ /** Callback function which will be called by BufferVector::bufferVector_fillExtern(). */ static int LDFParser_tokenBufferFillCB(void *contextp, void *destp, size_t *nElementsp) { LDFParser *parserp = (LDFParser*) contextp; *nElementsp = fread(destp, sizeof(char), *nElementsp, parserp->filehandle); if (ferror(parserp->filehandle)) { parserp->parserState = LDFPARSER_ERROR_FILEREAD; return FALSE; } if (*nElementsp == 0) { parserp->parserState = LDFPARSER_ERROR_EOF; return FALSE; } return TRUE; } /** Fill up the buffer to its maximum. If buffer is already filled completely, it is assumed that the buffer is too small and it will be enlarged. */ static int LDFParser_tokenReadFile(LDFParser *parserp) { BufferVector *bufferp = &parserp->tokenizer.buffer; if (bufferVector_isFull(bufferp)) { if (bufferVector_enlarge(bufferp, 0) == FALSE) { parserp->parserState = LDFPARSER_ERROR_BUFFER_TOKENIZER; return FALSE; } } else bufferVector_reorder(bufferp); return bufferVector_fillExtern(bufferp, parserp, LDFParser_tokenBufferFillCB); } /** Returns the character at position \a pos after the beginning of the current token or EOF if end of file of LDFParser::filehandle is detected. The character is read from buffer. If the buffer does not contain anymore characters, LDFParser_tokenReadFile() is called to fill the buffer. */ static int LDFParser_tokenCharGet(LDFParser *parserp, size_t pos) { const char *cp = NULL; while ((cp = bufferVector_getElementRefConst(&parserp->tokenizer.buffer, pos)) == NULL) { if (LDFParser_tokenReadFile(parserp) == FALSE) return EOF; } return *cp; } /** Searches for the next token and sets all corresponding variables in struct Tokenizer. */ static int LDFParser_tokenFindNext(LDFParser *parserp) { struct Tokenizer *tokp = &parserp->tokenizer; struct BufferVector *bufferp = &tokp->buffer; int c; int tokenEndFoundf = FALSE, floatDotf = FALSE; enum {COMMENT_MULTILINE, COMMENT_SINGLELINE} commentType = 0; int whiteSpacesWidth = 0; /*skip old token if not used till now*/ bufferVector_skip(bufferp, tokp->nextTokenOffset); tokp->nextTokenOffset = 0; tokp->nettoTokenOffset = 0; /*skip white spaces*/ do { c = LDFParser_tokenCharGet(parserp, whiteSpacesWidth); tokp->actSourceColumn++; if (c == '\n') { tokp->actSourceLine++; tokp->actSourceColumn = 1; } else if (c == EOF) return FALSE; whiteSpacesWidth++; } while (isspace(c)); /*"unget" last char*/ bufferVector_skip(bufferp, whiteSpacesWidth - 1); tokp->actSourceColumn--; tokp->tokenSourceLine = tokp->actSourceLine; tokp->tokenSourceColumn = tokp->actSourceColumn; tokp->tokenType = TOKENTYPE_UNKNOWN; do { if ( (c = LDFParser_tokenCharGet(parserp, tokp->nextTokenOffset)) == EOF ) { parserp->parserState = LDFPARSER_ERROR_EOF_INSIDE_TOKEN; return FALSE; } else tokp->actSourceColumn++; tokp->nextTokenOffset++; /*set possibleTokenTypes*/ if (tokp->nextTokenOffset == 1) { if (c == '"' ) tokp->tokenType |= TOKENTYPE_STRING; else if (isdigit(c) || c == '-' || c == '.') { tokp->tokenType |= TOKENTYPE_NUMBER | TOKENTYPE_FLOAT; if (c == '0') tokp->tokenType |= TOKENTYPE_HEXNUMBER; } else if (c == '/') tokp->tokenType |= TOKENTYPE_COMMENT | TOKENTYPE_IDENT; else if (strchr("{}:;,=", c)) { tokp->tokenType = TOKENTYPE_IDENT; tokenEndFoundf = TRUE; tokp->nettoTokenOffset = 0; tokp->nettoTokenSize = tokp->nextTokenOffset; } else { tokp->tokenType |= TOKENTYPE_IDENT; if (c == '.') tokp->tokenType |= TOKENTYPE_FLOAT; } } else if (tokp->nextTokenOffset == 2) { if (tokp->tokenType & TOKENTYPE_HEXNUMBER) { if (c != 'x' && c != 'X') tokp->tokenType &= ~TOKENTYPE_HEXNUMBER; } if (tokp->tokenType & TOKENTYPE_COMMENT) { if (c == '*') { commentType = COMMENT_MULTILINE; tokp->tokenType = TOKENTYPE_COMMENT; } else if (c =='/') { commentType = COMMENT_SINGLELINE; tokp->tokenType = TOKENTYPE_COMMENT; } else tokp->tokenType &= ~TOKENTYPE_COMMENT; } } /*search for end of token*/ if (tokenEndFoundf == FALSE) { if (tokp->tokenType & TOKENTYPE_STRING) { if (c == '"' && tokp->nextTokenOffset > 1) { tokp->tokenType = TOKENTYPE_STRING; tokenEndFoundf = TRUE; tokp->nettoTokenOffset = 1; tokp->nettoTokenSize = tokp->nextTokenOffset - 2; } } else if (tokp->tokenType & TOKENTYPE_COMMENT) { if ((commentType == COMMENT_SINGLELINE && c == '\n') || (commentType == COMMENT_MULTILINE && tokp->nextTokenOffset >= 4 && c == '/' && LDFParser_tokenCharGet(parserp, tokp->nextTokenOffset - 2) == '*')) { tokp->tokenType = TOKENTYPE_COMMENT; tokenEndFoundf = TRUE; tokp->nettoTokenOffset = 2; if (commentType == COMMENT_MULTILINE) tokp->nettoTokenSize = tokp->nextTokenOffset - 4; else { tokp->nettoTokenSize = tokp->nextTokenOffset - 3; tokp->nextTokenOffset--; tokp->actSourceColumn--; } } } else if (tokp->tokenType == TOKENTYPE_UNKNOWN || tokp->tokenType & (TOKENTYPE_IDENT | TOKENTYPE_NUMBER | TOKENTYPE_HEXNUMBER | TOKENTYPE_FLOAT) ) { if ( strchr("{}:;,=", c) != NULL || isspace(c)) { tokenEndFoundf = TRUE; tokp->nettoTokenOffset = 0; tokp->nextTokenOffset--; tokp->actSourceColumn--; tokp->nettoTokenSize = tokp->nextTokenOffset; } /*beginning comment, even directly after token*/ else if ((c == '/' || c == '*') && LDFParser_tokenCharGet(parserp, tokp->nextTokenOffset - 2) == '/') { tokenEndFoundf = TRUE; tokp->nettoTokenOffset = 0; tokp->nextTokenOffset -= 2; tokp->actSourceColumn -= 2; tokp->nettoTokenSize = tokp->nextTokenOffset; } } } /*look for not allowed characters for current tokenType, but only if end was not found yet!*/ if (tokenEndFoundf == FALSE) { if (c == '\n') { tokp->actSourceLine++; tokp->actSourceColumn = 1; } if (tokp->tokenType & TOKENTYPE_NUMBER && tokp->nextTokenOffset > 1 && isdigit(c) == 0) tokp->tokenType &= ~TOKENTYPE_NUMBER; if (tokp->tokenType & TOKENTYPE_HEXNUMBER && tokp->nextTokenOffset > 2 && isxdigit(c) == 0) tokp->tokenType &= ~TOKENTYPE_HEXNUMBER; if (tokp->tokenType & TOKENTYPE_FLOAT) { if (c == '.' && floatDotf == FALSE) floatDotf = TRUE; else if ((isdigit(c) == 0 && tokp->nextTokenOffset > 1) || c == '.') tokp->tokenType &= ~TOKENTYPE_FLOAT; } } } while (tokenEndFoundf == FALSE); return TRUE; } static int LDFParser_tokenGetAsCString(LDFParser *parserp, char *dst, size_t maxLen) { int len = 0; if (parserp->tokenizer.nettoTokenSize > maxLen) len = maxLen; else len = parserp->tokenizer.nettoTokenSize; dst[len] = '\0'; bufferVector_getElementsCopy(&parserp->tokenizer.buffer, dst, parserp->tokenizer.nettoTokenOffset, len); return len; } static void LDFParser_messagehlp_tokenGetAsFixLenString(LDFParser *parserp, char *dst, size_t maxLen) { int len; len = LDFParser_tokenGetAsCString(parserp, dst, maxLen); if (parserp->tokenizer.nettoTokenSize > maxLen) { dst[maxLen - 1] = '.'; dst[maxLen - 2] = '.'; dst[maxLen - 3] = '.'; } /*replace newlines with ETX to supress newline outputs*/ for (; len>0; len--) { if (dst[len - 1] == '\n') dst[len - 1] = 3; } } static int LDFParser_tokenGetAsFloat(LDFParser *parserp, double *dst) { struct Tokenizer *tokp = &parserp->tokenizer; char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; int okf = TRUE; okf = (okf && tokp->tokenType & TOKENTYPE_FLOAT); if (okf) LDFParser_tokenGetAsCString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); okf = (okf && sscanf(tokenString, "%lf", dst) == 1); return okf; } static int LDFParser_tokenGetAsNumber(LDFParser *parserp, int *dst) { struct Tokenizer *tokp = &parserp->tokenizer; char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; int okf = FALSE; LDFParser_tokenGetAsCString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); if (tokp->tokenType & TOKENTYPE_NUMBER) okf = (sscanf(tokenString, "%d", dst) == 1); else if (tokp->tokenType & TOKENTYPE_HEXNUMBER) okf = (sscanf(tokenString, "%x", dst) == 1); else okf = FALSE; return okf; } /** \} */ /** \addtogroup grammar */ /** \{ */ static void LDFParser_message_sourceLocation(LDFParser *parserp) { protoInterface_printf(parserp->protoInterfacep, "(%s, %3u.%02u)", parserp->filename, parserp->tokenizer.tokenSourceLine, parserp->tokenizer.tokenSourceColumn); } static void LDFParser_message_contextError(LDFParser *parserp) { char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1] = ""; enum GrammarContext actGrammarContext = GRAMMARCONTEXT_GLOBAL; int tmpeExpectedGrammarToken = parserp->grammar.expectedGrammarToken; int tmpActGrammarToken = parserp->grammar.actGrammarToken; //int tmpWeakExpectedGrammarToken = parserp->grammar.weakExpectedGrammarToken; int nGramarTokens = 0; LDFParser_message_sourceLocation(parserp); if (parserp->grammar.expectedGrammarToken != GRAMMARTOKEN_NOTOKEN) { protoInterface_printf(parserp->protoInterfacep, " ERROR: expected token"); if (tmpeExpectedGrammarToken == GRAMMARTOKEN_NOTOKEN) protoInterface_printf(parserp->protoInterfacep, " '%s'", LDFParser_grammarTokenStrings[0]); else { nGramarTokens = 1; while(tmpeExpectedGrammarToken) { if (tmpeExpectedGrammarToken & 1) { protoInterface_printf(parserp->protoInterfacep, " '%s'", LDFParser_grammarTokenStrings[nGramarTokens]); if (tmpeExpectedGrammarToken >> 1) protoInterface_printf(parserp->protoInterfacep, ","); } tmpeExpectedGrammarToken >>= 1; nGramarTokens++; } } /*does not work anymore because weakExpectedGrammarToken is resetet in LDFParser_grammarCheck()*/ /*if (tmpWeakExpectedGrammarToken != GRAMMARTOKEN_NOTOKEN) { nGramarTokens = 1; while (tmpWeakExpectedGrammarToken) { if (tmpWeakExpectedGrammarToken & 1) protoInterface_printf(parserp->protoInterfacep, ", '%s'", LDFParser_grammarTokenStrings[nGramarTokens]); tmpWeakExpectedGrammarToken >>= 1; nGramarTokens++; } }*/ protoInterface_printf(parserp->protoInterfacep, " in '%s' context, but found", LDFParser_grammarContextStrings[parserp->grammar.nextGrammarContext]); } else { stackInt_get(&parserp->grammar.grammarContext, &actGrammarContext, 0); protoInterface_printf(parserp->protoInterfacep, " ERROR: expected '%s' context, but found", LDFParser_grammarContextStrings[actGrammarContext]); } if (tmpActGrammarToken == GRAMMARTOKEN_NOTOKEN) protoInterface_printf(parserp->protoInterfacep, " '%s'", LDFParser_grammarTokenStrings[0]); else { nGramarTokens = 1; while (tmpActGrammarToken) { if (tmpActGrammarToken & 1) { protoInterface_printf(parserp->protoInterfacep, " '%s'", LDFParser_grammarTokenStrings[nGramarTokens]); if (tmpActGrammarToken >> 1) protoInterface_printf(parserp->protoInterfacep, ","); } tmpActGrammarToken >>= 1; nGramarTokens++; } } if (parserp->grammar.actGrammarToken == GRAMMARTOKEN_NOTOKEN || parserp->grammar.actGrammarToken & (GRAMMARTOKEN_IDENT | GRAMMARTOKEN_STRING | GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER | GRAMMARTOKEN_FLOAT)) { LDFParser_messagehlp_tokenGetAsFixLenString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); protoInterface_printf(parserp->protoInterfacep, " '%s'", tokenString); } protoInterface_printf(parserp->protoInterfacep, "!\n"); } static void LDFParser_message_skipTokens(LDFParser *parserp) { struct Tokenizer *tokp = &parserp->tokenizer; char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; enum GrammarContext newGrammarContext; stackInt_get(&parserp->grammar.grammarContext, &newGrammarContext, 0); LDFParser_messagehlp_tokenGetAsFixLenString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); LDFParser_message_sourceLocation(parserp); protoInterface_printf(parserp->protoInterfacep, " INFO: tokens skipped till token '%s', context is now '%s'.\n", tokenString, LDFParser_grammarContextStrings[newGrammarContext]); } static void LDFParser_message_wrongFormatVersionString(LDFParser *parserp) { char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; LDFParser_messagehlp_tokenGetAsFixLenString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); LDFParser_message_sourceLocation(parserp); protoInterface_printf(parserp->protoInterfacep, " ERROR: string '%s' has wrong format! \"00.01\" to \"99.99\" expected.\n", tokenString); } static void LDFParser_message_nodeNameAlreadyExist(LDFParser *parserp) { char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; LDFParser_messagehlp_tokenGetAsFixLenString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); LDFParser_message_sourceLocation(parserp); protoInterface_printf(parserp->protoInterfacep, "WARNING: node '%s' already exist in namespace for nodes => skipped!\n", tokenString); } static void LDFParser_message_nodeNameAlreadyDefined(LDFParser *parserp) { char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; LDFParser_messagehlp_tokenGetAsFixLenString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); LDFParser_message_sourceLocation(parserp); protoInterface_printf(parserp->protoInterfacep, "WARNING: node '%s' is already defined => skipped!\n", tokenString); } static void LDFParser_message_nodeNameAlreadyDefinedAs(LDFParser *parserp, const char *asWhatStringp) { char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; LDFParser_messagehlp_tokenGetAsFixLenString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); LDFParser_message_sourceLocation(parserp); protoInterface_printf(parserp->protoInterfacep, "WARNING: node '%s' is already defined as a %s node => skipped!\n", tokenString, asWhatStringp); } static void LDFParser_message_signalNameNotExist(LDFParser *parserp) { char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; LDFParser_messagehlp_tokenGetAsFixLenString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); LDFParser_message_sourceLocation(parserp); protoInterface_printf(parserp->protoInterfacep, " WARNING: signal '%s' does NOT exist in namespace for signals => skipped!\n", tokenString); } static void LDFParser_message_signalNameAlreadyDefined(LDFParser *parserp) { char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; LDFParser_messagehlp_tokenGetAsFixLenString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); LDFParser_message_sourceLocation(parserp); protoInterface_printf(parserp->protoInterfacep, " WARNING: signal '%s' is already defined => skipped!\n", tokenString); } static void LDFParser_message_signalEncodingTypeNameAlreadyExist(LDFParser *parserp) { char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; LDFParser_messagehlp_tokenGetAsFixLenString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); LDFParser_message_sourceLocation(parserp); protoInterface_printf(parserp->protoInterfacep, " WARNING: signal encoding type '%s' is already defined => skipped!\n", tokenString); } static void LDFParser_message_frameNameAlreadyExist(LDFParser *parserp) { char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; LDFParser_messagehlp_tokenGetAsFixLenString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); LDFParser_message_sourceLocation(parserp); protoInterface_printf(parserp->protoInterfacep, " WARNING: frame '%s' already exist in namespace for frames => skipped!\n", tokenString); } static void LDFParser_message_versionsWarning(LDFParser *parserp, const char *versionString) { char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; LDFParser_messagehlp_tokenGetAsFixLenString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); LDFParser_message_sourceLocation(parserp); protoInterface_printf(parserp->protoInterfacep, " WARNING: token '%s' is a feature not allowed in lin protocol versions prior to '%s'!\n", tokenString, versionString); } static void LDFParser_message_overflowWarning(LDFParser *parserp, int bitSize) { char tokenString[LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN + 1]; LDFParser_messagehlp_tokenGetAsFixLenString(parserp, tokenString, LDFPARSER_IDENTIFIER_BUFFERS_MAX_LEN); LDFParser_message_sourceLocation(parserp); protoInterface_printf(parserp->protoInterfacep, " WARNING: token '%s' overflows, only %d bit values are allowed!\n", tokenString, bitSize); } static void LDFParser_message_slaveNodeNotValid(LDFstruct *ldfp, const char *identp) { protoInterface_printf(ldfp->protoInterfacep, "ERROR: slave node '%s' is not properly defined!\n", identp); } static void LDFParser_message_frameNotValid(LDFstruct *ldfp, const char *identp) { protoInterface_printf(ldfp->protoInterfacep, "ERROR: frame '%s' is not properly defined!\n", identp); } static void LDFParser_message_signalNotValid(LDFstruct *ldfp, const char *identp) { protoInterface_printf(ldfp->protoInterfacep, "ERROR: signal '%s' is not properly defined!\n", identp); } static void LDFParser_message_signalEncodingTypeNotValid(LDFstruct *ldfp, const char *identp) { protoInterface_printf(ldfp->protoInterfacep, "ERROR: singal encoding type '%s' is not properly defined!\n", identp); } static void LDFParser_message_FrameSignalWrongPublisher(LDFstruct *ldfp, const char *frameIdentp, const char *signalIdentp, const char *publisherFramep, const char *publisherSignalp) { protoInterface_printf(ldfp->protoInterfacep, "ERROR: publisher of frame '%s' and signal '%s' don't match: ('%s' != '%s')!\n", frameIdentp, signalIdentp, publisherFramep, publisherSignalp); } static void LDFParser_message_eventframePropertiesNotMatch(LDFstruct *ldfp, const char *eventFrameIdentp, const char *frameIdentp) { protoInterface_printf(ldfp->protoInterfacep, "ERROR: frame '%s' can't be added to event triggered frame '%s'. Either length or checksum type does NOT match!\n", frameIdentp, eventFrameIdentp); } static void LDFParser_message_compositeConfigurationNotFound(LDFstruct *ldfp, const char *compositeConfigurationNamep) { protoInterface_printf(ldfp->protoInterfacep, "WARNING: declared composite configuration name '%s' could not be found in LDF!\n", compositeConfigurationNamep); } /** Searches in \a identifierArray for the characters pointed by \a identp with length \a identLen. * \returns FALSE if identifier could not be found. \returns index + 1 if identifier was found. */ static int LDFParser_grammarhlp_checkIsIdent(const char *identp, size_t identLen, const char identifierArray[][LDFPARSER_IDENTIFIER_MAX_LEN + 1]) { int n=0; while (identifierArray[n][0] != '\0') { if (identLen == strlen(identifierArray[n]) && memcmp(identifierArray[n], identp, identLen) == 0) return n + 1; n++; } return FALSE; } static int LDFParser_grammarhlp_versionStringInterprete(const char *versionString, unsigned char *majorp, unsigned char *minorp) { int n; unsigned int tmpMajor, tmpMinor; n = sscanf(versionString, "%u.%u", &tmpMajor, &tmpMinor); if (n == 2 && tmpMajor >= 0 && tmpMajor <= 99 && tmpMinor >= 0 && tmpMinor <= 99 && (tmpMajor + tmpMinor != 0)) { *majorp = tmpMajor; *minorp = tmpMinor; return TRUE; } return FALSE; } static void LDFParser_grammarhlp_setToLowerVersion(unsigned char *refMajorp, unsigned char *refMinorp, unsigned char nextMajor, unsigned char nextMinor) { if (nextMajor < *refMajorp || (nextMajor == *refMajorp && nextMinor < *refMinorp)) { *refMajorp = nextMajor; *refMinorp = nextMinor; } } /** Checks the grammatically correctness of current token and store relevant data in struct LDFParser::actLDFp. */ static int LDFParser_grammarCheck(LDFParser *parserp) { struct Tokenizer *tokp = &parserp->tokenizer; struct Grammar *grammarp = &parserp->grammar; struct StackInt *grammarContextp = &grammarp->grammarContext; LDFstruct *ldfp = parserp->actLDFp; const char* cp = NULL; enum GrammarContext actGrammarContext = GRAMMARCONTEXT_GLOBAL; enum GrammarToken actGrammarToken = GRAMMARTOKEN_NOTOKEN; int n; grammarp->grammarState = GRAMMAR_OK; /*ignore comments*/ if (tokp->tokenType == TOKENTYPE_COMMENT) return TRUE; cp = bufferVector_getElementsRefConst(&tokp->buffer, tokp->nettoTokenOffset, tokp->nettoTokenSize); stackInt_get(grammarContextp, &actGrammarContext, 0); /*detect different grammatically tokens (convert tokenizer tokens to grammar tokens)*/ if (tokp->tokenType & TOKENTYPE_IDENT) { if (tokp->nettoTokenSize == 1) { switch (*cp) { case ('{') : actGrammarToken = GRAMMARTOKEN_OPENBRACE; break; case ('}') : actGrammarToken = GRAMMARTOKEN_CLOSEBRACE; break; case (':') : actGrammarToken = GRAMMARTOKEN_COLON; break; case (';') : actGrammarToken = GRAMMARTOKEN_SEMICOLON; break; case (',') : actGrammarToken = GRAMMARTOKEN_COMMA; break; case ('=') : actGrammarToken = GRAMMARTOKEN_EQUALSIGN; break; default : actGrammarToken = GRAMMARTOKEN_IDENT; break; } } else if (tokp->nettoTokenSize == 4 && memcmp(cp, "kbps", 4) == 0) actGrammarToken = GRAMMARTOKEN_KBPS; else if (tokp->nettoTokenSize == 2 && memcmp(cp, "ms", 2) == 0) actGrammarToken = GRAMMARTOKEN_MS; else actGrammarToken = GRAMMARTOKEN_IDENT; } if (tokp->tokenType & TOKENTYPE_STRING) actGrammarToken |= GRAMMARTOKEN_STRING; if (tokp->tokenType & TOKENTYPE_NUMBER) actGrammarToken |= GRAMMARTOKEN_NUMBER; if (tokp->tokenType & TOKENTYPE_HEXNUMBER) actGrammarToken |= GRAMMARTOKEN_HEXNUMBER; if (tokp->tokenType & TOKENTYPE_FLOAT) actGrammarToken |= GRAMMARTOKEN_FLOAT; /* -- end-- detect different grammatically tokens*/ grammarp->actGrammarToken = actGrammarToken; /*check for tokens that have not to appear *yet*, but do change context if they appear*/ if (grammarp->weakExpectedGrammarToken != GRAMMARTOKEN_NOTOKEN) { enum GrammarToken tmpWeakExpectedGrammarToken = grammarp->weakExpectedGrammarToken; grammarp->weakExpectedGrammarToken = GRAMMARTOKEN_NOTOKEN; if (tmpWeakExpectedGrammarToken & GRAMMARTOKEN_CLOSEBRACE && actGrammarToken & GRAMMARTOKEN_CLOSEBRACE) { if (grammarp->nOpenBraces > 0) { grammarp->nOpenBraces--; stackInt_pop(grammarContextp, &NEXTG); if (grammarp->nOpenBraces > 0) grammarp->weakExpectedGrammarToken = GRAMMARTOKEN_CLOSEBRACE; } switch (actGrammarContext) { /*accept init value array of signal definition*/ case (GRAMMARCONTEXT_SIGNALDEF) : ((struct LIN_SignalDef*) grammarp->ldfContextp[0])->byteArrayf = TRUE; EXPECTT = GRAMMARTOKEN_COMMA; EXPECTSV = 2; break; /*accept node attributes definition*/ case (GRAMMARCONTEXT_NODEATTRIBUTEDEF) : ((struct LIN_SlaveNodeAttributesDef*) grammarp->ldfContextp[0])->slaveNodeValid = SLAVENODEDEF_NODEVALID; break; /*accept (diagnostic) frame definition*/ case (GRAMMARCONTEXT_FRAMEDEF) : case (GRAMMARCONTEXT_DIAGNOSTICFRAMEDEF) : ((struct LIN_FrameDef*) grammarp->ldfContextp[0])->frameValidf = TRUE; break; /*accept signal encoding type definition*/ case (GRAMMARCONTEXT_SIGNALENCODINGTYPE_DEF) : ((struct LIN_SignalEncodingType*) grammarp->ldfContextp[0])->signalEncodingTypeValidf = TRUE; break; /*accept this composite node configuration*/ case (GRAMMARCONTEXT_COMPOSITENODE_CONFIGURATION) : grammarp->compositeNodeConfigurationf = TRUE; grammarp->expectedGrammarToken = GRAMMARTOKEN_NOTOKEN; break; } return TRUE; } } /*support ldf language version 2.0 with different syntax for GRAMMARCONTEXT_NODEATTRIBUTEDEF_LIN_PROTOCOL*/ if (grammarp->expectedGrammarToken & GRAMMARTOKEN_FLOAT && actGrammarToken & GRAMMARTOKEN_FLOAT && grammarp->nextGrammarContext == GRAMMARCONTEXT_NODEATTRIBUTEDEF_LIN_PROTOCOL) { grammarp->expectedGrammarToken = GRAMMARTOKEN_STRING; actGrammarToken = GRAMMARTOKEN_STRING; } /*branch A*/ /*check grammatically token that have to be there (multiply types are allowed, the first mathing one which are allowed after all checks so far is accepted).*/ if (grammarp->expectedGrammarToken != GRAMMARTOKEN_NOTOKEN) { if (grammarp->expectedGrammarToken & GRAMMARTOKEN_OPENBRACE && actGrammarToken & GRAMMARTOKEN_OPENBRACE) { /*only if ldf version < 2.1 and framesize (optional) was not defined*/ if (NEXTG == GRAMMARCONTEXT_FRAMEDEF && EXPECTSV == 2) { struct LIN_FrameDef *frameDefp = (struct LIN_FrameDef*) grammarp->ldfContextp[0]; struct LIN_FrameID *frameIDp = bufferVector_getElementRef(&frameDefp->frameIDs, 0); switch (frameIDp->id & 0x30) { case 0x00 : case 0x10 : frameDefp->frameSize = 2; break; case 0x20 : frameDefp->frameSize = 4; break; case 0x30 : frameDefp->frameSize = 8; break; } EXPECTSV = 3; } stackInt_push(grammarContextp, grammarp->nextGrammarContext); grammarp->nOpenBraces++; grammarp->expectedGrammarToken = GRAMMARTOKEN_NOTOKEN; grammarp->weakExpectedGrammarToken = GRAMMARTOKEN_CLOSEBRACE; return TRUE; } if (grammarp->expectedGrammarToken & GRAMMARTOKEN_COLON && actGrammarToken & GRAMMARTOKEN_COLON) { switch (grammarp->nextGrammarContext) { /*colon after "Master" or "Slave" of node definition*/ case (GRAMMARCONTEXT_NODES_MASTERDEF) : case (GRAMMARCONTEXT_NODES_SLAVESDEF) : /*colon after signal encoding type name of signal representation definition*/ case (GRAMMARCONTEXT_SIGNALREPRESENTATION_DEF) : /*colon after sporadic frame name of sproadic frame definition*/ case (GRAMMARCONTEXT_SPORADICFRAMEDEF) : EXPECTT = GRAMMARTOKEN_IDENT; return TRUE; break; /*colon after event triggeref frame name of event triggered frame definition*/ case (GRAMMARCONTEXT_EVENTTRIGGEREDFRAMEDEF) : /*if language version smaller than 2.1 => syntax is different => no schedule table identifier*/ if (ldfp->languageVersionMajor < 2 || ldfp->languageVersionMajor <= 2 && ldfp->languageVersionMinor < 1) { EXPECTT = GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER; EXPECTSV = 1; } /*next should be schedule table identifier*/ else EXPECTT = GRAMMARTOKEN_IDENT; return TRUE; break; /*colon after identifier of (diganostic) signal or frame definition*/ case (GRAMMARCONTEXT_SIGNALDEF) : case (GRAMMARCONTEXT_DIAGNOSTICSIGNALDEF) : case (GRAMMARCONTEXT_FRAMEDEF) : case (GRAMMARCONTEXT_DIAGNOSTICFRAMEDEF) : EXPECTT = GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER; return TRUE; break; } } if (grammarp->expectedGrammarToken & GRAMMARTOKEN_SEMICOLON && actGrammarToken & GRAMMARTOKEN_SEMICOLON) { ECHOPRINTS(expression accepted, LDFParser_grammarContextStrings[grammarp->nextGrammarContext]); ECHOPRINTS(file, parserp->filename); ECHOPRINTD(line, tokp->tokenSourceLine); ECHONL; switch (grammarp->nextGrammarContext) { /*accept "LIN_descrptionFile;" - command*/ case (GRAMMARCONTEXT_GLOBAL_LIN_DESCRIPTION_FILE) : grammarp->linDescriptionFilef = TRUE; break; /*accept event triggered frame definition*/ case (GRAMMARCONTEXT_EVENTTRIGGEREDFRAMEDEF) : ((struct LIN_FrameDef*) grammarp->ldfContextp[0])->frameValidf = TRUE; break; /*accept (diagnostic) signal definition*/ case (GRAMMARCONTEXT_SIGNALDEF) : case (GRAMMARCONTEXT_DIAGNOSTICSIGNALDEF) : ((struct LIN_SignalDef*) grammarp->ldfContextp[0])->signalValid |= SIGNALDEFINTION_SIGNALVALID; break; /*accept bcd value definition of signal encoding type*/ case (GRAMMARCONTEXT_SIGNALENCODINGTYPEDEF_BCD_VALUE) : ((struct SignalEncodingData*) grammarp->ldfContextp[1])->encodingType = SIGNALENCODING_BCDVALUE; break; /*accept ascii value defintion of signal encoding type*/ case (GRAMMARCONTEXT_SIGNALENCODINGTYPEDEF_ASCII_VALUE) : ((struct SignalEncodingData*) grammarp->ldfContextp[1])->encodingType = SIGNALENCODING_ASCIIVALUE; break; } grammarp->expectedGrammarToken = GRAMMARTOKEN_NOTOKEN; if (grammarp->nOpenBraces > 0) grammarp->weakExpectedGrammarToken = GRAMMARTOKEN_CLOSEBRACE; return TRUE; } if (grammarp->expectedGrammarToken & GRAMMARTOKEN_COMMA && actGrammarToken & GRAMMARTOKEN_COMMA) { switch (grammarp->nextGrammarContext) { case (GRAMMARCONTEXT_NODES_MASTERDEF) : /*comma after master node name or timebase*/ if (EXPECTSV == 1 || EXPECTSV == 2) { EXPECTT = GRAMMARTOKEN_FLOAT; return TRUE; } break; /*comma after slave node identifier in slave nodes defintion*/ case (GRAMMARCONTEXT_NODES_SLAVESDEF) : /*comma after signal identifier of sinal representation definition*/ case (GRAMMARCONTEXT_SIGNALREPRESENTATION_DEF) : /*comma after frame identifier of sporadic frame definition*/ case (GRAMMARCONTEXT_SPORADICFRAMEDEF) : EXPECTT = GRAMMARTOKEN_IDENT; return TRUE; break; /*comma after supplier_id, function_id*/ case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_PRODUCT_ID) : /*comma after init values within init values array of signal definition*/ case (GRAMMARCONTEXT_SIGNALDEF_INITVALUES) : /*commma after signal identifier of included_signals in (diagnostic) frame definition*/ case (GRAMMARCONTEXT_FRAMEDEF_INCLUDEDSIGNALS) : case (GRAMMARCONTEXT_DIAGNOSTICFRAMEDEF_INCLUDEDSIGNALS) : EXPECTT = GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER; return TRUE; break; case (GRAMMARCONTEXT_SIGNALDEF) : /*comma after signal size in signal defintion*/ if (EXPECTSV == 1) EXPECTT = GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER | GRAMMARTOKEN_OPENBRACE; /*comma after init_value and publisher of signal definition*/ else if (EXPECTSV == 2 || EXPECTSV == 3) EXPECTT = GRAMMARTOKEN_IDENT; return TRUE; break; /*comma after signal size in diagnostic signal defintion*/ case (GRAMMARCONTEXT_DIAGNOSTICSIGNALDEF) : EXPECTT = GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER; return TRUE; break; case (GRAMMARCONTEXT_FRAMEDEF) : /*comma after frame id of frame definition*/ if (EXPECTSV == 1) EXPECTT = GRAMMARTOKEN_IDENT; /*comma after publisher of frame definition*/ else if (EXPECTSV == 2) EXPECTT = GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER; return TRUE; break; case (GRAMMARCONTEXT_EVENTTRIGGEREDFRAMEDEF) : /*comma after schedule table of event triggered frame definition*/ if (EXPECTSV == 1) EXPECTT = GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER; /*comma after frame_id or frame identifier of event triggered frame definition*/ else if (EXPECTSV == 2 || EXPECTSV == 3) EXPECTT = GRAMMARTOKEN_IDENT; return TRUE; break; case (GRAMMARCONTEXT_SIGNALENCODINGTYPEDEF_LOGICAL_VALUE) : /*comma after type of encoding of signal encoding type logical value*/ if (EXPECTSV == 0) EXPECTT = GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER; /*comma after signalValue of encoding of signal encoding type logical value*/ else if (EXPECTSV == 1) EXPECTT = GRAMMARTOKEN_STRING; return TRUE; break; case (GRAMMARCONTEXT_SIGNALENCODINGTYPEDEF_PHYSICAL_VALUE) : /*comma after type AND minValue of encoding of signal encoding type physical value*/ if (EXPECTSV == 0 || EXPECTSV == 1) EXPECTT = GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER; /*comma after maxValue AND scale of encoding of signal encoding type physical value*/ else if (EXPECTSV == 2 || EXPECTSV == 3) EXPECTT = GRAMMARTOKEN_FLOAT; /*comma after offset of encoding of signal encoding type physical value*/ else if (EXPECTSV == 4) EXPECTT = GRAMMARTOKEN_STRING; return TRUE; break; /*comma after logical slave node of composite defintion*/ case (GRAMMARCONTEXT_COMPOSITENODE_DEF) : EXPECTT = GRAMMARTOKEN_NOTOKEN; return TRUE; } } if (grammarp->expectedGrammarToken & GRAMMARTOKEN_EQUALSIGN && actGrammarToken & GRAMMARTOKEN_EQUALSIGN) { switch (grammarp->nextGrammarContext) { case (GRAMMARCONTEXT_GLOBAL_LIN_PROTOCOL_VERSION) : case (GRAMMARCONTEXT_GLOBAL_LIN_LANGUAGE_VERSION) : case (GRAMMARCONTEXT_GLOBAL_CHANNEL_NAME) : grammarp->expectedGrammarToken = GRAMMARTOKEN_STRING; break; case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_LIN_PROTOCOL) : /*if language version smaller than 2.1 => syntax is different*/ if (ldfp->languageVersionMajor < 2 || ldfp->languageVersionMajor <= 2 && ldfp->languageVersionMinor < 1) EXPECTT = GRAMMARTOKEN_FLOAT; else EXPECTT = GRAMMARTOKEN_STRING; break; case (GRAMMARCONTEXT_GLOBAL_LIN_SPEED) : grammarp->expectedGrammarToken = GRAMMARTOKEN_FLOAT; break; case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_CONFIGURED_NAD) : case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_INITIAL_NAD) : case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_CONFIGURABLEFRAMESDEF_v20) : EXPECTT = GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER; break; case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_PRODUCT_ID) : EXPECTT = GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER; EXPECTSV = 0; break; case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_RESPONSE_ERROR) : EXPECTT = GRAMMARTOKEN_IDENT; break; } return TRUE; } if (grammarp->expectedGrammarToken & GRAMMARTOKEN_KBPS && actGrammarToken & GRAMMARTOKEN_KBPS) { /*only case is GRAMMARCONTEXT_GLOBAL_LIN_SPEED*/ grammarp->expectedGrammarToken = GRAMMARTOKEN_SEMICOLON; return TRUE; } if (grammarp->expectedGrammarToken & GRAMMARTOKEN_MS && actGrammarToken & GRAMMARTOKEN_MS) { switch (grammarp->nextGrammarContext) { /*ms token after timebaseof master node definition*/ case (GRAMMARCONTEXT_NODES_MASTERDEF) : if (EXPECTSV == 1) { EXPECTT = GRAMMARTOKEN_COMMA; EXPECTSV++; return TRUE; } /*ms token after jitter of master node definition*/ else if (EXPECTSV == 2) { EXPECTT = GRAMMARTOKEN_SEMICOLON; EXPECTSV++; return TRUE; } break; } } if (grammarp->expectedGrammarToken & GRAMMARTOKEN_IDENT && actGrammarToken & GRAMMARTOKEN_IDENT) { switch (grammarp->nextGrammarContext) { /*master node identifier of master node definition*/ case (GRAMMARCONTEXT_NODES_MASTERDEF) : if (EXPECTSV == 0) { LDFParser_tokenGetAsCString(parserp, ldfp->nodes.masterNodeIdent, MAX_STRING_LEN); EXPECTT = GRAMMARTOKEN_COMMA; EXPECTSV = 1; return TRUE; } break; /*slave node identifiers of slave defintion*/ case (GRAMMARCONTEXT_NODES_SLAVESDEF) : { char tmpString[MAX_STRING_LEN + 1]; size_t pos; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_nodeIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } EXPECTT = GRAMMARTOKEN_COMMA | GRAMMARTOKEN_SEMICOLON; return TRUE; } break; /*signal identifier of response error of node attributes definition*/ case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_RESPONSE_ERROR) : { char tmpString[MAX_STRING_LEN + 1]; struct LIN_SignalDef *signalDefp = NULL; size_t pos; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_signalIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } ((struct LIN_SlaveNodeAttributesDef*) (grammarp->ldfContextp[0]))->responseErrorSignalPos = pos; EXPECTT = GRAMMARTOKEN_SEMICOLON; return TRUE; } break; case (GRAMMARCONTEXT_SIGNALDEF) : { char tmpString[MAX_STRING_LEN + 1]; struct LIN_SignalDef *signalDefp = (struct LIN_SignalDef*) grammarp->ldfContextp[0]; struct LIN_SlaveNodeAttributesDef *slaveNodeDefp = NULL; size_t pos, *subscriberp = NULL; /*node identifier of publisher of signal definition*/ if (EXPECTSV == 2) { LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_nodeIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } pos = LDF_nodeGetPhysicalNode(ldfp, pos); signalDefp->publisherIdentPos = pos; EXPECTT = GRAMMARTOKEN_COMMA | GRAMMARTOKEN_SEMICOLON; EXPECTSV = 3; } /*node identifier of subscriber of signal definition*/ else if (EXPECTSV == 3) { LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); subscriberp = bufferVector_appendEmptyElements(&signalDefp->subscriberNodes, 1); if (subscriberp == NULL || FALSE == LDF_nodeIdentFindCreate(ldfp, tmpString, subscriberp)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } *subscriberp = LDF_nodeGetPhysicalNode(ldfp, *subscriberp); EXPECTT = GRAMMARTOKEN_SEMICOLON | GRAMMARTOKEN_COMMA; } return TRUE; } break; case (GRAMMARCONTEXT_FRAMEDEF) : { char tmpString[MAX_STRING_LEN + 1]; size_t pos; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); /*frame published by node ...*/ if (EXPECTSV == 1) { /*error because data is important to calculate checksum type*/ if (FALSE == LDF_nodeIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } pos = LDF_nodeGetPhysicalNode(ldfp, pos); ((struct LIN_FrameDef*) grammarp->ldfContextp[0])->publisherIdentPos = pos; EXPECTT = GRAMMARTOKEN_COMMA; /*if language version smaller than 2.1 => syntax is different => frameSize is optional*/ if (ldfp->languageVersionMajor < 2 || ldfp->languageVersionMajor <= 2 && ldfp->languageVersionMinor < 1) EXPECTT |= GRAMMARTOKEN_OPENBRACE; } EXPECTSV++; return TRUE; } break; /*sprodic frame name in dproadic frame definition*/ case (GRAMMARCONTEXT_SPORADICFRAMEDEF) : { char tmpString[MAX_STRING_LEN + 1]; size_t pos; struct LIN_FrameDef *frameDefp = NULL; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_frameIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } frameDefp = LDF_frameDef_getRef(ldfp, pos); frameDefp->frameType = FRAMETYPE_SPORADIC; EXPECTT = GRAMMARTOKEN_COMMA | GRAMMARTOKEN_SEMICOLON; return TRUE; } break; case (GRAMMARCONTEXT_EVENTTRIGGEREDFRAMEDEF) : /*schedule table of event triggered frame definition*/ if (EXPECTSV == 0) { /*skip schedule table name, not needed*/ EXPECTT = GRAMMARTOKEN_COMMA; EXPECTSV = 1; } /*frame identifier of event triggered frame definition*/ else if (EXPECTSV == 2 || EXPECTSV == 3) { char tmpString[MAX_STRING_LEN + 1]; size_t pos; struct LIN_FrameDef *eventframeDefp = (struct LIN_FrameDef*) grammarp->ldfContextp[0]; union LIN_IncludedData *includedDatap = NULL; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_frameIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } /*add frame to event triggered frames*/ includedDatap = (union LIN_IncludedData*) bufferVector_appendEmptyElements(&eventframeDefp->includedData, 1); if (includedDatap == NULL || FALSE == LDF_includedFrameEntry_init(ldfp, &includedDatap->includedFrame)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } includedDatap->includedFrame.frameIdentPos = pos; EXPECTT = GRAMMARTOKEN_COMMA | GRAMMARTOKEN_SEMICOLON; } return TRUE; break; /*signal name of signal representation defintion (signal encoding type stored in EXPECTSV)*/ case (GRAMMARCONTEXT_SIGNALREPRESENTATION_DEF) : { char tmpString[MAX_STRING_LEN + 1]; size_t pos; struct LIN_SignalDef *signalDefp = NULL; int okf = TRUE; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_signalIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } signalDefp = LDF_signalDef_getRef(ldfp, pos); signalDefp->signalValid |= SIGNALDEFINTION_ENCODINGVALID; signalDefp->signalEncodingTypePos = EXPECTSV; EXPECTT = GRAMMARTOKEN_COMMA | GRAMMARTOKEN_SEMICOLON; return TRUE; } break; case (GRAMMARCONTEXT_COMPOSITENODE_CONFIGURATION) : /*composite configuration identifier*/ if (actGrammarToken & GRAMMARTOKEN_IDENT) { char tmpString[MAX_STRING_LEN + 1]; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); /*skip if it is not the correct configuration name*/ if (strncmp(tmpString, ldfp->compositeConfigurationNamep, MAX_STRING_LEN + 1) != 0) { grammarp->grammarState = GRAMMAR_SKIP_BLOCK_SILENT; return FALSE; } EXPECTT = GRAMMARTOKEN_OPENBRACE; return TRUE; } break; } } if (grammarp->expectedGrammarToken & GRAMMARTOKEN_STRING && actGrammarToken & GRAMMARTOKEN_STRING) { switch (grammarp->nextGrammarContext) { case (GRAMMARCONTEXT_GLOBAL_LIN_PROTOCOL_VERSION) : case (GRAMMARCONTEXT_GLOBAL_LIN_LANGUAGE_VERSION) : case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_LIN_PROTOCOL) : { unsigned char major, minor; char versionString[6]; int versionStringOkf = FALSE; if (tokp->nettoTokenSize < 6) { bufferVector_getElementsCopy(&tokp->buffer, versionString, tokp->nettoTokenOffset, tokp->nettoTokenSize); versionString[tokp->nettoTokenSize] = '\0'; versionStringOkf = LDFParser_grammarhlp_versionStringInterprete(versionString, &major, &minor); } if (versionStringOkf == FALSE) { grammarp->grammarState = GRAMMAR_ERROR_VERSIONSTRING; METAMESSAGE(return FALSE); } else { /*copy to LDFstruct*/ switch (grammarp->nextGrammarContext) { case (GRAMMARCONTEXT_GLOBAL_LIN_PROTOCOL_VERSION) : ldfp->protocolVersionMajor = major; ldfp->protocolVersionMinor = minor; break; case (GRAMMARCONTEXT_GLOBAL_LIN_LANGUAGE_VERSION) : ldfp->languageVersionMajor = major; ldfp->languageVersionMinor = minor; break; case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_LIN_PROTOCOL) : ((struct LIN_SlaveNodeAttributesDef*) (grammarp->ldfContextp[0]))->linProtocolVersionMajor = major; ((struct LIN_SlaveNodeAttributesDef*) (grammarp->ldfContextp[0]))->linProtocolVersionMinor = minor; break; } grammarp->expectedGrammarToken = GRAMMARTOKEN_SEMICOLON; return TRUE; } } break; case (GRAMMARCONTEXT_GLOBAL_CHANNEL_NAME) : LDFParser_tokenGetAsCString(parserp, ldfp->postfixChannelName, MAX_STRING_LEN); grammarp->expectedGrammarToken = GRAMMARTOKEN_SEMICOLON; return TRUE; break; case (GRAMMARCONTEXT_SIGNALENCODINGTYPEDEF_LOGICAL_VALUE) : { struct SignalEncodingData *encodingDatap = (struct SignalEncodingData*) grammarp->ldfContextp[1]; LDFParser_tokenGetAsCString(parserp, encodingDatap->encodingData.logic.textInfo, MAX_STRING_LEN); grammarp->expectedGrammarToken = GRAMMARTOKEN_SEMICOLON; return TRUE; } break; case (GRAMMARCONTEXT_SIGNALENCODINGTYPEDEF_PHYSICAL_VALUE) : { struct SignalEncodingData *encodingDatap = (struct SignalEncodingData*) grammarp->ldfContextp[1]; LDFParser_tokenGetAsCString(parserp, encodingDatap->encodingData.range.textInfo, MAX_STRING_LEN); grammarp->expectedGrammarToken = GRAMMARTOKEN_SEMICOLON; return TRUE; } break; } } if ( (grammarp->expectedGrammarToken & GRAMMARTOKEN_NUMBER && actGrammarToken & GRAMMARTOKEN_NUMBER) || (grammarp->expectedGrammarToken & GRAMMARTOKEN_HEXNUMBER && actGrammarToken & GRAMMARTOKEN_HEXNUMBER) ) { switch (grammarp->nextGrammarContext) { int tmpInt; case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_CONFIGURED_NAD) : { struct ConfiguredNAD *configuredNADp = NULL; LDFParser_tokenGetAsNumber(parserp, &tmpInt); if (tmpInt > UCHAR_MAX || tmpInt < SCHAR_MIN) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(char) * 8)); if (FALSE == LDF_configuredNAD_append(ldfp, (struct LIN_SlaveNodeAttributesDef*) (grammarp->ldfContextp[0]), (unsigned char) tmpInt, 0)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } /*initNAD was not set yet*/ if (EXPECTSV == 0) ((struct LIN_SlaveNodeAttributesDef*) (grammarp->ldfContextp[0]))->initNAD = (unsigned char) tmpInt; EXPECTT = GRAMMARTOKEN_SEMICOLON; return TRUE; } break; case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_INITIAL_NAD) : LDFParser_tokenGetAsNumber(parserp, &tmpInt); if (tmpInt > UCHAR_MAX || tmpInt < SCHAR_MIN) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(char) * 8)); ((struct LIN_SlaveNodeAttributesDef*) (grammarp->ldfContextp[0]))->initNAD = (unsigned char) tmpInt; EXPECTSV = 1; EXPECTT = GRAMMARTOKEN_SEMICOLON; return TRUE; break; case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_PRODUCT_ID) : LDFParser_tokenGetAsNumber(parserp, &tmpInt); if (EXPECTSV == 0) { if (tmpInt > USHRT_MAX || tmpInt < SHRT_MIN) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(short) * 8)); ((struct LIN_SlaveNodeAttributesDef*) (grammarp->ldfContextp[0]))->supplierID = (unsigned short) tmpInt; EXPECTT = GRAMMARTOKEN_COMMA; } else if (EXPECTSV == 1) { if (tmpInt > USHRT_MAX || tmpInt < SHRT_MIN) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(short) * 8)); ((struct LIN_SlaveNodeAttributesDef*) (grammarp->ldfContextp[0]))->functionID = (unsigned short) tmpInt; EXPECTT = GRAMMARTOKEN_COMMA | GRAMMARTOKEN_SEMICOLON; } else if (EXPECTSV == 2) { if (tmpInt > UCHAR_MAX || tmpInt < SCHAR_MIN) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(char) * 8)); ((struct LIN_SlaveNodeAttributesDef*) (grammarp->ldfContextp[0]))->variantID = (unsigned char) tmpInt; EXPECTT = GRAMMARTOKEN_SEMICOLON; } EXPECTSV++; return TRUE; break; case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_CONFIGURABLEFRAMESDEF_v20) : LDFParser_tokenGetAsNumber(parserp, &tmpInt); if (tmpInt > USHRT_MAX || tmpInt < SHRT_MIN) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(short) * 8)); ((struct ConfiguredFrame*) (grammarp->ldfContextp[1]))->messageID = (unsigned short) tmpInt; EXPECTT = GRAMMARTOKEN_SEMICOLON; return TRUE; break; case (GRAMMARCONTEXT_SIGNALDEF) : case (GRAMMARCONTEXT_DIAGNOSTICSIGNALDEF) : LDFParser_tokenGetAsNumber(parserp, &tmpInt); /*signal size in bits of (diagnostic) signal definition*/ if (EXPECTSV == 0) { if (tmpInt > UCHAR_MAX || tmpInt < SCHAR_MIN) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(char) * 8)); ((struct LIN_SignalDef*) (grammarp->ldfContextp[0]))->sizeBits = (unsigned char) tmpInt; EXPECTT = GRAMMARTOKEN_COMMA; } /*init_value_scalar of (diagnostic) signal, ignore for proto*/ else if (EXPECTSV == 1) { if (grammarp->nextGrammarContext == GRAMMARCONTEXT_SIGNALDEF) EXPECTT = GRAMMARTOKEN_COMMA; else EXPECTT = GRAMMARTOKEN_SEMICOLON; } EXPECTSV++; return TRUE; break; case (GRAMMARCONTEXT_SIGNALDEF_INITVALUES) : EXPECTT = GRAMMARTOKEN_COMMA; WEAKT = GRAMMARTOKEN_CLOSEBRACE; return TRUE; break; case (GRAMMARCONTEXT_FRAMEDEF) : case (GRAMMARCONTEXT_DIAGNOSTICFRAMEDEF) : { struct LIN_FrameDef *frameDefp = (struct LIN_FrameDef*) grammarp->ldfContextp[0]; LDFParser_tokenGetAsNumber(parserp, &tmpInt); /*frame_id of (diagnostic) frame definition*/ if (EXPECTSV == 0) { if (tmpInt >= FRAMEID_MAX_NR || tmpInt < 0) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(char) * 6)); if (FALSE == LDF_frameID_append(ldfp, frameDefp, (unsigned char) (tmpInt & LIN_PID_ID_MASK), 0)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } if (grammarp->nextGrammarContext == GRAMMARCONTEXT_FRAMEDEF) EXPECTT = GRAMMARTOKEN_COMMA; else { EXPECTT = GRAMMARTOKEN_OPENBRACE; frameDefp->frameSize = DATABYTES_NUMBER_DIAGNOSTICFRAME; } EXPECTSV = 1; } /*frame_size of frame definition*/ else if (EXPECTSV == 2) { if (tmpInt > UCHAR_MAX || tmpInt < SCHAR_MIN) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(char) * 8)); frameDefp->frameSize = (unsigned char) tmpInt; EXPECTT = GRAMMARTOKEN_OPENBRACE; EXPECTSV = 3; } return TRUE; } break; /*signal offset in frame in current (diagnsotic) frame defintion*/ case (GRAMMARCONTEXT_FRAMEDEF_INCLUDEDSIGNALS) : case (GRAMMARCONTEXT_DIAGNOSTICFRAMEDEF_INCLUDEDSIGNALS) : LDFParser_tokenGetAsNumber(parserp, &tmpInt); if (tmpInt > UCHAR_MAX || tmpInt < SCHAR_MIN) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(char) * 8)); ((struct LIN_IncludedSignal*) (grammarp->ldfContextp[1]))->signalOffset = (unsigned char) tmpInt; EXPECTT = GRAMMARTOKEN_SEMICOLON; return TRUE; break; /*frame_id of event triggered frame definition*/ case (GRAMMARCONTEXT_EVENTTRIGGEREDFRAMEDEF) : { struct LIN_FrameDef *frameDefp = (struct LIN_FrameDef*) grammarp->ldfContextp[0]; LDFParser_tokenGetAsNumber(parserp, &tmpInt); if (tmpInt >= FRAMEID_MAX_NR || tmpInt < 0) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(char) * 6)); if (FALSE == LDF_frameID_append(ldfp, frameDefp, (unsigned char) (tmpInt & LIN_PID_ID_MASK), 0)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } EXPECTT = GRAMMARTOKEN_COMMA | GRAMMARTOKEN_SEMICOLON; EXPECTSV = 2; return TRUE; } break; /*signal value of signal encoding type logical value*/ case (GRAMMARCONTEXT_SIGNALENCODINGTYPEDEF_LOGICAL_VALUE) : { struct SignalEncodingData *encodingDatap = (struct SignalEncodingData*) grammarp->ldfContextp[1]; LDFParser_tokenGetAsNumber(parserp, &tmpInt); encodingDatap->encodingType = SIGNALENCODING_LOGICVALUE; encodingDatap->encodingData.logic.textInfo[0] = '\0'; encodingDatap->encodingData.logic.signalValue = (unsigned short) tmpInt; if (tmpInt > USHRT_MAX || tmpInt < SHRT_MIN) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(short) * 8)); EXPECTT = GRAMMARTOKEN_COMMA | GRAMMARTOKEN_SEMICOLON; EXPECTSV = 1; return TRUE; } break; /*min value of signal encoding type logical value*/ case (GRAMMARCONTEXT_SIGNALENCODINGTYPEDEF_PHYSICAL_VALUE) : { struct SignalEncodingData *encodingDatap = (struct SignalEncodingData*) grammarp->ldfContextp[1]; LDFParser_tokenGetAsNumber(parserp, &tmpInt); if (EXPECTSV == 0) { encodingDatap->encodingType = SIGNALENCODING_PHYSICALRANGE; encodingDatap->encodingData.range.maxValue = 0; encodingDatap->encodingData.range.scale = 0; encodingDatap->encodingData.range.offset = 0; encodingDatap->encodingData.range.textInfo[0] = '\0'; encodingDatap->encodingData.range.minValue = (unsigned short) tmpInt; if (tmpInt > USHRT_MAX || tmpInt < SHRT_MIN) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(short) * 8)); EXPECTT = GRAMMARTOKEN_COMMA; } else if (EXPECTSV == 1) { encodingDatap->encodingData.range.maxValue = (unsigned short) tmpInt; if (tmpInt > USHRT_MAX || tmpInt < SHRT_MIN) METAMESSAGE(LDFParser_message_overflowWarning(parserp, sizeof(short) * 8)); EXPECTT = GRAMMARTOKEN_COMMA; } EXPECTSV++; return TRUE; } break; } } if (grammarp->expectedGrammarToken & GRAMMARTOKEN_FLOAT && actGrammarToken & GRAMMARTOKEN_FLOAT) { switch (grammarp->nextGrammarContext) { case (GRAMMARCONTEXT_GLOBAL_LIN_SPEED) : LDFParser_tokenGetAsFloat(parserp, &ldfp->speed); grammarp->expectedGrammarToken = GRAMMARTOKEN_KBPS; return TRUE; break; case (GRAMMARCONTEXT_NODES_MASTERDEF) : if (EXPECTSV == 1) { LDFParser_tokenGetAsFloat(parserp, &ldfp->nodes.timebase); EXPECTT = GRAMMARTOKEN_MS; } else if (EXPECTSV == 2) { LDFParser_tokenGetAsFloat(parserp, &ldfp->nodes.jitter); EXPECTT = GRAMMARTOKEN_MS; } return TRUE; break; case (GRAMMARCONTEXT_SIGNALENCODINGTYPEDEF_PHYSICAL_VALUE) : { struct SignalEncodingData *encodingDatap = (struct SignalEncodingData*) grammarp->ldfContextp[1]; /*scale value of signal encoding type physical value*/ if (EXPECTSV == 2) { LDFParser_tokenGetAsFloat(parserp, &encodingDatap->encodingData.range.scale); EXPECTT = GRAMMARTOKEN_COMMA; } /*offset value of signal encoding type physical value*/ else if (EXPECTSV == 3) { LDFParser_tokenGetAsFloat(parserp, &encodingDatap->encodingData.range.offset); EXPECTT = GRAMMARTOKEN_COMMA | GRAMMARTOKEN_SEMICOLON; } EXPECTSV++; return TRUE; } break; } } } /*branch B*/ /*change grammatically context if needed*/ else { switch (actGrammarContext) { case (GRAMMARCONTEXT_GLOBAL) : if (actGrammarToken & GRAMMARTOKEN_IDENT) { n = LDFParser_grammarhlp_checkIsIdent(cp, tokp->nettoTokenSize, LDFParser_identifiersGlobal); if (n) { if (n == GRAMMARCONTEXT_GLOBAL_LIN_DESCRIPTION_FILE - GRAMMARCONTEXT_GLOBAL) EXPECTT = GRAMMARTOKEN_SEMICOLON; else { if (grammarp->linDescriptionFilef == FALSE) { parserp->parserState = LDFPARSER_ERROR_WRONGINPUTFILE; METAMESSAGE(return FALSE); } if (n < GRAMMARCONTEXT_GLOBAL_NODES - GRAMMARCONTEXT_GLOBAL) EXPECTT = GRAMMARTOKEN_EQUALSIGN; else EXPECTT = GRAMMARTOKEN_OPENBRACE; } NEXTG = GRAMMARCONTEXT_GLOBAL + n; /*skip not needed parts in ldf*/ if (NEXTG >= GRAMMARCONTEXT_GLOBAL_SCHEDULE_TABLES || (NEXTG == GRAMMARCONTEXT_GLOBAL_COMPOSITE_NODES && ldfp->compositeConfigurationNamep == NULL)) { grammarp->grammarState = GRAMMAR_SKIP_BLOCK_SILENT; return FALSE; } return TRUE; } } break; case (GRAMMARCONTEXT_GLOBAL_NODES) : if (actGrammarToken & GRAMMARTOKEN_IDENT) { if (tokp->nettoTokenSize == 6 && memcmp(cp, "Master", 6) == 0) { grammarp->nextGrammarContext = GRAMMARCONTEXT_NODES_MASTERDEF; grammarp->expectedGrammarToken = GRAMMARTOKEN_COLON; EXPECTSV = 0; return TRUE; } else if (tokp->nettoTokenSize == 6 && memcmp(cp, "Slaves", 6) == 0) { grammarp->nextGrammarContext = GRAMMARCONTEXT_NODES_SLAVESDEF; grammarp->expectedGrammarToken = GRAMMARTOKEN_COLON; return TRUE; } } break; case (GRAMMARCONTEXT_GLOBAL_NODES_ATTRIBUTES) : case (GRAMMARCONTEXT_COMPOSITENODE_CONFIGURATION) : /*slave node/composite node identifier*/ if (actGrammarToken & GRAMMARTOKEN_IDENT) { size_t pos; char nodeIdent[MAX_STRING_LEN + 1]; struct LIN_SlaveNodeAttributesDef *slaveNodeAttributesDefp = NULL; LDFParser_tokenGetAsCString(parserp, nodeIdent, MAX_STRING_LEN); if (FALSE == LDF_nodeIdentFindCreate(ldfp, nodeIdent, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } slaveNodeAttributesDefp = LDF_slaveNodeAttributesDef_getRef(ldfp, pos); if(actGrammarContext == GRAMMARCONTEXT_GLOBAL_NODES_ATTRIBUTES) { if (slaveNodeAttributesDefp->slaveNodeValid == SLAVENODEDEF_NODEVALID) { METAMESSAGE(LDFParser_message_nodeNameAlreadyDefined(parserp)); grammarp->grammarState = GRAMMAR_SKIP_BLOCK_ERROR; return FALSE; } else if (slaveNodeAttributesDefp->slaveNodeValid == SLAVENODEDEF_LOGICALNODE) { METAMESSAGE(LDFParser_message_nodeNameAlreadyDefinedAs(parserp, "logical")); grammarp->grammarState = GRAMMAR_SKIP_BLOCK_ERROR; return FALSE; } } grammarp->ldfContextp[0] = slaveNodeAttributesDefp; if (actGrammarContext == GRAMMARCONTEXT_GLOBAL_NODES_ATTRIBUTES) NEXTG = GRAMMARCONTEXT_NODEATTRIBUTEDEF; else { NEXTG = GRAMMARCONTEXT_COMPOSITENODE_DEF; EXPECTSV = pos; } grammarp->expectedGrammarToken = GRAMMARTOKEN_OPENBRACE; return TRUE; } break; case (GRAMMARCONTEXT_NODEATTRIBUTEDEF) : n = LDFParser_grammarhlp_checkIsIdent(cp, tokp->nettoTokenSize, LDFParser_identifiersNodeAttributesDef); if (n) { struct LIN_SlaveNodeAttributesDef *slaveNodeAttributesDefp = (struct LIN_SlaveNodeAttributesDef*) grammarp->ldfContextp[0]; NEXTG = GRAMMARCONTEXT_NODEATTRIBUTEDEF + n; /*skip node needed parts of node attribute definition*/ if (NEXTG >= GRAMMARCONTEXT_NODEATTRIBUTEDEF_PRODUCT_ID && slaveNodeAttributesDefp->linProtocolVersionMajor < 2) METAMESSAGE(LDFParser_message_versionsWarning(parserp, "2.0")); if (NEXTG >= GRAMMARCONTEXT_NODEATTRIBUTEDEF_FAULT_STATE_SIGNALS) { grammarp->grammarState = GRAMMAR_SKIP_BLOCK_SILENT; return FALSE; } else if (NEXTG == GRAMMARCONTEXT_NODEATTRIBUTEDEF_CONFIGURABLE_FRAMES) { if (slaveNodeAttributesDefp->linProtocolVersionMajor > 2 || slaveNodeAttributesDefp->linProtocolVersionMajor == 2 && slaveNodeAttributesDefp->linProtocolVersionMinor > 0) NEXTG = GRAMMARCONTEXT_NODEATTRIBUTEDEF_CONFIGURABLEFRAMESDEF_v21; else NEXTG = GRAMMARCONTEXT_NODEATTRIBUTEDEF_CONFIGURABLEFRAMESDEF_v20; EXPECTT = GRAMMARTOKEN_OPENBRACE; } else { EXPECTT = GRAMMARTOKEN_EQUALSIGN; EXPECTSV = 0; /*used to detect if initNAD was set*/ } return TRUE; } break; case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_CONFIGURABLEFRAMESDEF_v20) : case (GRAMMARCONTEXT_NODEATTRIBUTEDEF_CONFIGURABLEFRAMESDEF_v21) : if (actGrammarToken & GRAMMARTOKEN_IDENT) { struct LIN_SlaveNodeAttributesDef *slaveNodeAttributesDefp = (struct LIN_SlaveNodeAttributesDef*) grammarp->ldfContextp[0]; struct ConfiguredFrame *configuredFramep = NULL; char tmpString[MAX_STRING_LEN + 1]; struct LIN_SignalDef *signalDefp = NULL; size_t pos; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_frameIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } configuredFramep = (struct ConfiguredFrame*) bufferVector_appendEmptyElements(&slaveNodeAttributesDefp->configuredFrames, 1); if (configuredFramep == NULL) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } configuredFramep->frameIdentPos = pos; if (actGrammarContext == GRAMMARCONTEXT_NODEATTRIBUTEDEF_CONFIGURABLEFRAMESDEF_v21) EXPECTT = GRAMMARTOKEN_SEMICOLON; else { grammarp->ldfContextp[1] = configuredFramep; EXPECTT = GRAMMARTOKEN_EQUALSIGN; } return TRUE; } break; case (GRAMMARCONTEXT_GLOBAL_SIGNALS) : case (GRAMMARCONTEXT_GLOBAL_DIAGNOSTIC_SIGNALS): if (actGrammarToken & GRAMMARTOKEN_IDENT) { char tmpString[MAX_STRING_LEN + 1]; struct LIN_SignalDef *signalDefp = NULL; size_t pos; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_signalIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } signalDefp = LDF_signalDef_getRef(ldfp, pos); if (signalDefp->signalValid & SIGNALDEFINTION_SIGNALVALID) { METAMESSAGE(LDFParser_message_signalNameAlreadyDefined(parserp)); grammarp->grammarState = GRAMMAR_SKIP_BLOCK_ERROR; return FALSE; } if (actGrammarContext == GRAMMARCONTEXT_GLOBAL_SIGNALS) NEXTG = GRAMMARCONTEXT_SIGNALDEF; else NEXTG = GRAMMARCONTEXT_DIAGNOSTICSIGNALDEF; EXPECTT = GRAMMARTOKEN_COLON; EXPECTSV = 0; grammarp->ldfContextp[0] = signalDefp; return TRUE; } break; case (GRAMMARCONTEXT_SIGNALDEF) : /*init value array of signal definition, ignore init values for proto*/ if (actGrammarToken & (GRAMMARTOKEN_NUMBER | GRAMMARTOKEN_HEXNUMBER)) { NEXTG = GRAMMARCONTEXT_SIGNALDEF_INITVALUES; EXPECTT = GRAMMARTOKEN_COMMA; WEAKT = GRAMMARTOKEN_CLOSEBRACE; return TRUE; } break; case (GRAMMARCONTEXT_GLOBAL_FRAMES) : case (GRAMMARCONTEXT_GLOBAL_DIAGNOSTIC_FRAMES) : case (GRAMMARCONTEXT_GLOBAL_EVENTTRIGGERED_FRAMES) : /*ident of frame (unconditional or event triggered) which should be defined*/ if (actGrammarToken & GRAMMARTOKEN_IDENT) { char tmpString[MAX_STRING_LEN + 1]; struct LIN_FrameDef *frameDefp = NULL; size_t pos; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_frameIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } frameDefp = LDF_frameDef_getRef(ldfp, pos); if (frameDefp->frameValidf) { METAMESSAGE(LDFParser_message_frameNameAlreadyExist(parserp)); grammarp->grammarState = GRAMMAR_SKIP_BLOCK_ERROR; return FALSE; } if (actGrammarContext == GRAMMARCONTEXT_GLOBAL_FRAMES) { frameDefp->checksumType = CHECKSUMTYPE_ENHANCED; frameDefp->frameType = FRAMTEYPE_UNCONDITIONAL; NEXTG = GRAMMARCONTEXT_FRAMEDEF; } else if (actGrammarContext == GRAMMARCONTEXT_GLOBAL_DIAGNOSTIC_FRAMES) { frameDefp->checksumType = CHECKSUMTYPE_CLASSIC; frameDefp->frameType = FRAMETYPE_DIAGNOSTIC; NEXTG = GRAMMARCONTEXT_DIAGNOSTICFRAMEDEF; } else { frameDefp->frameType = FRAMETYPE_EVENTTRIGGERED; NEXTG = GRAMMARCONTEXT_EVENTTRIGGEREDFRAMEDEF; } EXPECTT = GRAMMARTOKEN_COLON; EXPECTSV = 0; grammarp->ldfContextp[0] = frameDefp; return TRUE; } break; case (GRAMMARCONTEXT_FRAMEDEF) : case (GRAMMARCONTEXT_DIAGNOSTICFRAMEDEF) : /*signal name of included (diagnostic) signal in (diagnostic) frame*/ if (actGrammarToken & GRAMMARTOKEN_IDENT) { char tmpString[MAX_STRING_LEN + 1]; struct LIN_FrameDef *frameDefp = (struct LIN_FrameDef*) grammarp->ldfContextp[0]; const char *publisherSignalp = NULL, *publisherFramep = NULL; union LIN_IncludedData *includedDatap = NULL; size_t pos; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_signalIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } includedDatap = bufferVector_appendEmptyElements(&frameDefp->includedData, 1); if (includedDatap == NULL || FALSE == LDF_includedSignalEntry_init(ldfp, &includedDatap->includedSignal)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } includedDatap->includedSignal.signalIdentPos = pos; grammarp->ldfContextp[1] = &includedDatap->includedSignal; if (actGrammarContext == GRAMMARCONTEXT_FRAMEDEF) NEXTG = GRAMMARCONTEXT_FRAMEDEF_INCLUDEDSIGNALS; else NEXTG = GRAMMARCONTEXT_DIAGNOSTICFRAMEDEF_INCLUDEDSIGNALS; EXPECTT = GRAMMARTOKEN_COMMA; return TRUE; } break; case (GRAMMARCONTEXT_GLOBAL_SPORADIC_FRAMES) : /*sporadic frame identifier*/ if (actGrammarToken & GRAMMARTOKEN_IDENT) { /*skip sporadic frame identifier, don't need it for proto*/ EXPECTT = GRAMMARTOKEN_COLON; NEXTG = GRAMMARCONTEXT_SPORADICFRAMEDEF; return TRUE; } break; /*signal encoding type identifier of signal encoding type definition*/ case (GRAMMARCONTEXT_GLOBAL_SIGNAL_ENCODING_TYPES) : if (actGrammarToken & GRAMMARTOKEN_IDENT) { struct LIN_SignalEncodingType *encodingTypep = NULL; char tmpString[MAX_STRING_LEN + 1]; size_t pos; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_signalEncodingTypeIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } encodingTypep = LDF_signalEncodingTypeDef_getRef(ldfp, pos); grammarp->ldfContextp[0] = encodingTypep; NEXTG = GRAMMARCONTEXT_SIGNALENCODINGTYPE_DEF; EXPECTT = GRAMMARTOKEN_OPENBRACE; return TRUE; } break; case (GRAMMARCONTEXT_SIGNALENCODINGTYPE_DEF) : if (actGrammarToken & GRAMMARTOKEN_IDENT) { struct LIN_SignalEncodingType *encodingTypep = (struct LIN_SignalEncodingType*) grammarp->ldfContextp[0]; struct SignalEncodingData *encodingDatap = NULL; n = LDFParser_grammarhlp_checkIsIdent(cp, tokp->nettoTokenSize, LDFParser_identifiersSignalEncodingTypeDef); if (n) { if (n < GRAMMARCONTEXT_SIGNALENCODINGTYPEDEF_BCD_VALUE - GRAMMARCONTEXT_SIGNALENCODINGTYPE_DEF) EXPECTT = GRAMMARTOKEN_COMMA; else EXPECTT = GRAMMARTOKEN_SEMICOLON; encodingDatap = bufferVector_appendEmptyElements(&encodingTypep->signalEncodingData, 1); if (encodingDatap == NULL || FALSE == LDF_encodingDataEntry_init(ldfp, encodingDatap)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } grammarp->ldfContextp[1] = encodingDatap; NEXTG = GRAMMARCONTEXT_SIGNALENCODINGTYPE_DEF + n; EXPECTSV = 0; return TRUE; } } break; case (GRAMMARCONTEXT_GLOBAL_SIGNAL_REPRESENTATION) : /*signal representation identifier*/ if (actGrammarToken & GRAMMARTOKEN_IDENT) { char tmpString[MAX_STRING_LEN + 1]; size_t pos; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_signalEncodingTypeIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } EXPECTSV = pos; EXPECTT = GRAMMARTOKEN_COLON; NEXTG = GRAMMARCONTEXT_SIGNALREPRESENTATION_DEF; return TRUE; } break; case (GRAMMARCONTEXT_GLOBAL_COMPOSITE_NODES) : /*composite configuration keyword*/ if (actGrammarToken & GRAMMARTOKEN_IDENT) { char tmpString[MAX_STRING_LEN + 1]; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (strncmp(tmpString, "configuration", MAX_STRING_LEN + 1) != 0) return FALSE; NEXTG = GRAMMARCONTEXT_COMPOSITENODE_CONFIGURATION; EXPECTT = GRAMMARTOKEN_IDENT; return TRUE; } break; case (GRAMMARCONTEXT_COMPOSITENODE_DEF) : /*logical node identifier*/ if (actGrammarToken & GRAMMARTOKEN_IDENT) { char tmpString[MAX_STRING_LEN + 1]; size_t pos = 0; struct LIN_SlaveNodeAttributesDef *slaveNodeAttributesDefp = NULL; LDFParser_tokenGetAsCString(parserp, tmpString, MAX_STRING_LEN); if (FALSE == LDF_nodeIdentFindCreate(ldfp, tmpString, &pos)) { parserp->parserState = LDFPARSER_ERROR_LDF; METAMESSAGE(return FALSE); } slaveNodeAttributesDefp = LDF_slaveNodeAttributesDef_getRef(ldfp, pos); if (slaveNodeAttributesDefp->slaveNodeValid != SLAVENODEDEF_INVALID) METAMESSAGE(LDFParser_message_nodeNameAlreadyDefinedAs(parserp, "physical")); else { slaveNodeAttributesDefp->slaveNodeValid = SLAVENODEDEF_LOGICALNODE; slaveNodeAttributesDefp->compositeNodePos = EXPECTSV; } NEXTG = GRAMMARCONTEXT_COMPOSITENODE_DEF; /*if language version smaller than 2.1 => syntax is different => semicolon before right brace*/ if (ldfp->languageVersionMajor < 2 || ldfp->languageVersionMajor <= 2 && ldfp->languageVersionMinor < 1) { EXPECTT = GRAMMARTOKEN_COMMA; WEAKT = GRAMMARTOKEN_CLOSEBRACE; } else EXPECTT = GRAMMARTOKEN_COMMA | GRAMMARTOKEN_SEMICOLON; return TRUE; } break; } } grammarp->grammarState = GRAMMAR_ERROR_CONTEXT; METAMESSAGE(return FALSE); } static int LDFParser_grammarSkipTokensTillHook(LDFParser *parserp) { struct Tokenizer *tokp = &parserp->tokenizer; struct Grammar *grammarp = &parserp->grammar; const char *cp = NULL; unsigned int braceLevel = 0; parserp->grammar.expectedGrammarToken = GRAMMARTOKEN_NOTOKEN; do { /*search for '{', '}' or ';' at the correct level (of open braces), all of nettoTokenSize == 1*/ if (tokp->tokenType & TOKENTYPE_IDENT && tokp->nettoTokenSize == 1) { /*cp can't be NULL because of successful LDFParser_tokenFindNext() in LDFParser_parse()*/ cp = bufferVector_getElementRefConst(&tokp->buffer, tokp->nettoTokenOffset); if (*cp == '{') braceLevel++; else if (*cp == '}') { if (braceLevel == 0) { if (grammarp->nOpenBraces > 0) { grammarp->nOpenBraces--; stackInt_pop(&grammarp->grammarContext, &NEXTG); if (grammarp->nOpenBraces > 0) grammarp->weakExpectedGrammarToken = GRAMMARTOKEN_CLOSEBRACE; } return TRUE; } else if (braceLevel == 1) { if (grammarp->nOpenBraces > 0) WEAKT = GRAMMARTOKEN_CLOSEBRACE; return TRUE; } braceLevel--; } else if (*cp == ';' && braceLevel == 0) { if (grammarp->nOpenBraces > 0) WEAKT = GRAMMARTOKEN_CLOSEBRACE; return TRUE; } } } while (LDFParser_tokenFindNext(parserp)); return FALSE; } /** \} */ /** \addtogroup ldf_parser */ /** \{ */ int LDFParser_init(LDFParser *parserp, struct ProtoInterface *protoInterfacep, const char *filename, size_t buffer_initSize) { int okf = TRUE; parserp->protoInterfacep = protoInterfacep; parserp->parserState = LDFPARSER_OK; strncpy(parserp->filename, filename, FILENAME_MAX + 1); parserp->filename[FILENAME_MAX] = '\0'; if (okf) { parserp->filehandle = fopen(filename, "r"); okf = (parserp->filehandle != NULL); if (okf == FALSE) parserp->parserState = LDFPARSER_ERROR_FILEOPEN; } parserp->actLDFp = NULL; parserp->grammar.grammarState = GRAMMAR_OK; parserp->grammar.nextGrammarContext = GRAMMARCONTEXT_GLOBAL; parserp->grammar.expectedGrammarToken = GRAMMARTOKEN_NOTOKEN; parserp->grammar.expectedGrammarSpecialValue = 0; parserp->grammar.ldfContextp[0] = NULL; parserp->grammar.ldfContextp[1] = NULL; parserp->grammar.weakExpectedGrammarToken = GRAMMARTOKEN_NOTOKEN; parserp->grammar.nOpenBraces = 0; parserp->grammar.linDescriptionFilef = FALSE; parserp->grammar.compositeNodeConfigurationf = FALSE; if (okf) { okf = stackInt_init(&parserp->grammar.grammarContext, GRAMMARCONTEXT_STACK_SIZE, protoInterfacep); if (okf) okf = stackInt_push(&parserp->grammar.grammarContext, GRAMMARCONTEXT_GLOBAL); else parserp->parserState = LDFPARSER_ERROR_STACK_GRAMMARCONTEXT; } if (bufferVector_init(&parserp->tokenizer.buffer, sizeof(char), buffer_initSize, protoInterfacep) == FALSE) { parserp->parserState = LDFPARSER_ERROR_BUFFER_TOKENIZER; okf = FALSE; } parserp->tokenizer.nettoTokenSize = 0; parserp->tokenizer.nettoTokenOffset = 0; parserp->tokenizer.tokenType = TOKENTYPE_UNKNOWN; parserp->tokenizer.actSourceLine = 1; parserp->tokenizer.actSourceColumn = 1; parserp->tokenizer.tokenSourceLine = 0; parserp->tokenizer.tokenSourceColumn = 0; parserp->tokenizer.nextTokenOffset = 0; return okf; } void LDFParser_destroy(LDFParser *parserp) { parserp->protoInterfacep = NULL; parserp->parserState = LDFPARSER_DISABLED; if (parserp->filehandle) { fclose(parserp->filehandle); parserp->filehandle = NULL; } parserp->filename[0] = '\0'; parserp->actLDFp = NULL; parserp->grammar.grammarState = GRAMMAR_OK; parserp->grammar.nextGrammarContext = GRAMMARCONTEXT_GLOBAL; parserp->grammar.expectedGrammarToken = GRAMMARTOKEN_NOTOKEN; parserp->grammar.expectedGrammarSpecialValue = 0; parserp->grammar.ldfContextp[0] = NULL; parserp->grammar.ldfContextp[1] = NULL; parserp->grammar.weakExpectedGrammarToken = GRAMMARTOKEN_NOTOKEN; parserp->grammar.nOpenBraces = 0; parserp->grammar.linDescriptionFilef = FALSE; parserp->grammar.compositeNodeConfigurationf = FALSE; stackInt_destroy(&parserp->grammar.grammarContext); bufferVector_destroy(&parserp->tokenizer.buffer); parserp->tokenizer.nettoTokenSize = 0; parserp->tokenizer.nettoTokenOffset = 0; parserp->tokenizer.tokenType = TOKENTYPE_UNKNOWN; parserp->tokenizer.actSourceLine = 0; parserp->tokenizer.actSourceColumn = 0; parserp->tokenizer.tokenSourceLine = 0; parserp->tokenizer.tokenSourceColumn = 0; parserp->tokenizer.nextTokenOffset = 0; } static int LDFParser_postParseJobs(LDFstruct *ldfp, struct Grammar *grammarp) { struct LIN_SlaveNodeAttributesDef *slaveNodeAttributesDefp = NULL; struct LIN_FrameDef *frameDefp = NULL, *eventtriggeredFrameDefp = NULL; struct LIN_SignalDef *signalDefp = NULL; struct LIN_SignalEncodingType *signalEncodingTypep = NULL; size_t pos; StackInt eventtriggeredFrames; /*take for granted that sizeof(struct LIN_FrameDef*) == sizeof(int)*/ if (FALSE == stackInt_init(&eventtriggeredFrames, POSTPARSE_EVENTTRIGGEREDFRAMES_BUFFER_INIT_SIZE, ldfp->protoInterfacep)) return FALSE; /*check if all slave nodes, frames, signals and signal encodings are valid*/ pos = 1; /*masternode is pos==0 => first slave node is pos==1*/ while (slaveNodeAttributesDefp = LDF_slaveNodeAttributesDef_getRef(ldfp, pos)) { struct LIN_SlaveNodeAttributesDef *compositeNodeAttributesDefp = slaveNodeAttributesDefp; while (compositeNodeAttributesDefp->slaveNodeValid == SLAVENODEDEF_LOGICALNODE) compositeNodeAttributesDefp = LDF_slaveNodeAttributesDef_getRef(ldfp, compositeNodeAttributesDefp->compositeNodePos); if (compositeNodeAttributesDefp->slaveNodeValid == SLAVENODEDEF_INVALID) METAMESSAGE(LDFParser_message_slaveNodeNotValid(ldfp, slaveNodeAttributesDefp->nodeIdent)); pos++; } pos = 0; while (frameDefp = LDF_frameDef_getRef(ldfp, pos)) { if (frameDefp->frameValidf == FALSE) METAMESSAGE(LDFParser_message_frameNotValid(ldfp, frameDefp->frameIdent)); /*process event triggered frames later, after all other frames are processed*/ else if (frameDefp->frameType == FRAMETYPE_EVENTTRIGGERED) { if (FALSE == stackInt_push(&eventtriggeredFrames, pos)) return FALSE; } /*decide which checksum type and compare publisher of frame and included signals*/ else if (frameDefp->frameType == FRAMTEYPE_UNCONDITIONAL || frameDefp->frameType == FRAMETYPE_SPORADIC) { size_t nSubscribedSignal = 0, nSubscribersNode = 0; size_t *subscriberNodePosp = NULL; union LIN_IncludedData *includedDatap = NULL; nSubscribedSignal = 0; while (includedDatap = bufferVector_getElementRef(&frameDefp->includedData, nSubscribedSignal)) { signalDefp = LDF_signalDef_getRef(ldfp, includedDatap->includedSignal.signalIdentPos); if (signalDefp->signalValid & SIGNALDEFINTION_SIGNALVALID) { /*compare publisher of frame and signal*/ if (frameDefp->publisherIdentPos != signalDefp->publisherIdentPos) METAMESSAGE(LDFParser_message_FrameSignalWrongPublisher(ldfp, frameDefp->frameIdent, signalDefp->signalIdent, LDF_nodeIdentGet(ldfp, frameDefp->publisherIdentPos), LDF_nodeIdentGet(ldfp, signalDefp->publisherIdentPos))); /*only check version of node (to decide which checksum type) if not already classic type*/ else if (frameDefp->checksumType != CHECKSUMTYPE_CLASSIC) { /*get all subscriber nodes*/ nSubscribersNode = 0; while (subscriberNodePosp = bufferVector_getElementRef(&signalDefp->subscriberNodes, nSubscribersNode)) { /*subscriber is master node*/ if (*subscriberNodePosp == 0) { if (ldfp->protocolVersionMajor < 2) { frameDefp->checksumType = CHECKSUMTYPE_CLASSIC; break; } } /*subscriber is slave node*/ else { slaveNodeAttributesDefp = LDF_slaveNodeAttributesDef_getRef(ldfp, *subscriberNodePosp); if (slaveNodeAttributesDefp->slaveNodeValid == SLAVENODEDEF_NODEVALID) { if (slaveNodeAttributesDefp->linProtocolVersionMajor < 2) { frameDefp->checksumType = CHECKSUMTYPE_CLASSIC; break; } } } nSubscribersNode++; } } } nSubscribedSignal++; } } pos++; } /*decide checksum and frameSize of event triggered frames*/ while (stackInt_pop(&eventtriggeredFrames, &pos)) { union LIN_IncludedData *includedDatap = NULL; int frameSize = 0, checksumType = CHECKSUMTYPE_NOTDEFINED; eventtriggeredFrameDefp = LDF_frameDef_getRef(ldfp, pos); pos = 0; while (includedDatap = bufferVector_getElementRef(&eventtriggeredFrameDefp->includedData, pos)) { frameDefp = LDF_frameDef_getRef(ldfp, includedDatap->includedFrame.frameIdentPos); if (pos == 0) { frameSize = frameDefp->frameSize; checksumType = frameDefp->checksumType; } else if (frameSize != frameDefp->frameSize || checksumType != frameDefp->checksumType) METAMESSAGE(LDFParser_message_eventframePropertiesNotMatch(ldfp, eventtriggeredFrameDefp->frameIdent, frameDefp->frameIdent)); pos++; } eventtriggeredFrameDefp->frameSize = (unsigned char) frameSize; eventtriggeredFrameDefp->checksumType = (unsigned char) checksumType; } pos = 0; while (signalDefp = LDF_signalDef_getRef(ldfp, pos)) { if ((signalDefp->signalValid & SIGNALDEFINTION_SIGNALVALID) == 0) METAMESSAGE(LDFParser_message_signalNotValid(ldfp, signalDefp->signalIdent)); pos++; } pos = 0; while (signalEncodingTypep = LDF_signalEncodingTypeDef_getRef(ldfp, pos)) { if (signalEncodingTypep->signalEncodingTypeValidf == FALSE) METAMESSAGE(LDFParser_message_signalEncodingTypeNotValid(ldfp, signalEncodingTypep->encodingIdent)); pos++; } if (grammarp->compositeNodeConfigurationf == FALSE && ldfp->compositeConfigurationNamep != NULL) METAMESSAGE(LDFParser_message_compositeConfigurationNotFound(ldfp, ldfp->compositeConfigurationNamep)); return TRUE; } int LDFParser_parse(LDFParser *parserp, LDFstruct *ldfp) { int startTagf = FALSE; parserp->actLDFp = ldfp; while (LDFParser_tokenFindNext(parserp)) { if (LDFParser_grammarCheck(parserp) == FALSE) { /*other errors*/ if (parserp->parserState != LDFPARSER_OK) return FALSE; /*syntax error*/ else if (parserp->grammar.grammarState == GRAMMAR_ERROR_CONTEXT) { LDFParser_message_contextError(parserp); if (LDFParser_grammarSkipTokensTillHook(parserp)) LDFParser_message_skipTokens(parserp); } else if (parserp->grammar.grammarState == GRAMMAR_ERROR_VERSIONSTRING) { LDFParser_message_wrongFormatVersionString(parserp); if (LDFParser_grammarSkipTokensTillHook(parserp)) LDFParser_message_skipTokens(parserp); } else if (parserp->grammar.grammarState == GRAMMAR_SKIP_BLOCK_ERROR) { if (LDFParser_grammarSkipTokensTillHook(parserp)) LDFParser_message_skipTokens(parserp); } else if (parserp->grammar.grammarState == GRAMMAR_SKIP_BLOCK_SILENT) LDFParser_grammarSkipTokensTillHook(parserp); } } if (parserp->parserState == LDFPARSER_OK || parserp->parserState == LDFPARSER_ERROR_EOF) { if (FALSE == LDFParser_postParseJobs(ldfp, &parserp->grammar)) { parserp->parserState = LDFPARSER_ERROR_LDF; return FALSE; } return TRUE; } else return FALSE; } void LDFParser_message_printState(LDFParser *parserp) { const char *furtherStringp = NULL; protoInterface_printf(parserp->protoInterfacep, "LDFParser: "); switch (parserp->parserState) { case LDFPARSER_ERROR_WRONGINPUTFILE : case LDFPARSER_ERROR_FILEOPEN : case LDFPARSER_ERROR_FILEREAD : case LDFPARSER_ERROR_EOF : case LDFPARSER_ERROR_EOF_INSIDE_TOKEN : protoInterface_printf(parserp->protoInterfacep, LDFParser_stateStrings[parserp->parserState], parserp->filename); break; case LDFPARSER_ERROR_BUFFER_TOKENIZER : case LDFPARSER_ERROR_STACK_GRAMMARCONTEXT : if (parserp->parserState == LDFPARSER_ERROR_BUFFER_TOKENIZER) furtherStringp = bufferVector_getStateString(&parserp->tokenizer.buffer); else if (parserp->parserState == LDFPARSER_ERROR_STACK_GRAMMARCONTEXT) furtherStringp = stackInt_getStateString(&parserp->grammar.grammarContext); protoInterface_printf(parserp->protoInterfacep, LDFParser_stateStrings[parserp->parserState], furtherStringp); break; default : protoInterface_printf(parserp->protoInterfacep, LDFParser_stateStrings[parserp->parserState]); break; } protoInterface_flush(parserp->protoInterfacep); } /** \} */ /*=================================================================== ======= DEBUG ======================================================= ====================================================================*/ int LDFParser_DEBUG_dumpBuffer(LDFParser *parserp, FILE *outStream) { BufferVector *bufferp = &parserp->tokenizer.buffer; const char *charp = NULL; size_t size; size = bufferVector_getActSize(bufferp); charp = bufferVector_getElementsRefConst(bufferp, 0, size); if (charp) { fwrite(charp, 1, size, outStream); bufferVector_skip(bufferp, size); return TRUE; } else { fprintf(outStream, "BUFFER ERROR!\n"); return FALSE; } } int LDFParser_DEBUG_dumpTokenzierTokens(LDFParser *parserp) { int x, n; BufferVector *bufferp = &parserp->tokenizer.buffer; const char *cp = NULL; while (LDFParser_tokenFindNext(parserp)) { LDFParser_message_sourceLocation(parserp); x = parserp->tokenizer.tokenType; if (x == 0) fprintf(stderr, " '%s'", LDFParser_tokenTypeStrings[0]); else { n = 1; while (x) { if (x & 0x1) { fprintf(stderr, " '%s'", LDFParser_tokenTypeStrings[n]); if ((x >> 1) & 1) fprintf(stderr, ","); } n++; x >>= 1; } } cp = bufferVector_getElementsRefConst(bufferp, 0, parserp->tokenizer.nextTokenOffset); if (cp) { fprintf(stderr, " token found: '"); fwrite(cp, sizeof(char), parserp->tokenizer.nextTokenOffset, stderr); fprintf(stderr, "'\n"); } else fprintf(stderr, " token error: nextTokenOffset = %u, actBufferSize = %u\n", parserp->tokenizer.nextTokenOffset, bufferVector_getActSize(bufferp)); } if (parserp->parserState == LDFPARSER_ERROR_EOF || parserp->parserState == LDFPARSER_OK) return TRUE; else return FALSE; } int LDFParser_DEBUG_dumpGrammarTokens(LDFParser *parserp) { int x, n; BufferVector *bufferp = &parserp->tokenizer.buffer; const char *cp = NULL; LDFstruct ldf; if (LDF_init(&ldf, parserp->protoInterfacep, NULL) == FALSE) return FALSE; parserp->actLDFp = &ldf; while (LDFParser_tokenFindNext(parserp)) { LDFParser_grammarCheck(parserp); LDFParser_message_sourceLocation(parserp); x = parserp->grammar.actGrammarToken; if (x == 0) fprintf(stderr, " '%s'", LDFParser_grammarTokenStrings[0]); else { n = 1; while (x) { if (x & 0x1) { fprintf(stderr, " '%s'", LDFParser_grammarTokenStrings[n]); if ((x >> 1) & 1) fprintf(stderr, ","); } n++; x >>= 1; } } cp = bufferVector_getElementsRefConst(bufferp, 0, parserp->tokenizer.nextTokenOffset); if (cp) { fprintf(stderr, " token found: '"); fwrite(cp, sizeof(char), parserp->tokenizer.nextTokenOffset, stderr); fprintf(stderr, "'\n"); } else fprintf(stderr, " token error: nextTokenOffset = %u, actBufferSize = %u\n", parserp->tokenizer.nextTokenOffset, bufferVector_getActSize(bufferp)); } if (parserp->parserState == LDFPARSER_ERROR_EOF || parserp->parserState == LDFPARSER_OK) return TRUE; else return FALSE; }