ArduinoComments.java
/*******************************************************************************
* jArduino: Arduino C++ Code Generation From Java
* Copyright 2020 Tony Washer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package net.sourceforge.jarduino.message;
import java.util.HashMap;
import java.util.Map;
import net.sourceforge.jarduino.ArduinoException;
import net.sourceforge.jarduino.message.ArduinoParser.ArduinoParserException;
/**
* Comments.
*/
public class ArduinoComments {
/**
* The Marker.
*/
static final String MARKER = "CM_";
/**
* The map of comments.
*/
private Map<ArduinoNamedObject, String> theComments;
/**
* Constructor.
*/
ArduinoComments() {
theComments = new HashMap<>();
}
/**
* Obtain the comment for an object (if any).
* @param pObject the object
* @return the comment (or null)
*/
public String getCommentForObject(final ArduinoNamedObject pObject) {
return theComments.get(pObject);
}
/**
* Store the comment for an object.
* @param pObject the object
* @param pComment the comment
*/
void storeCommentForObject(final ArduinoNamedObject pObject,
final String pComment) {
theComments.put(pObject, pComment);
}
/**
* parse the comment definition.
* @param pSystem the system
* @param pCommentDef the comment definition
* @throws ArduinoException on error
*/
public static void parseComment(final ArduinoSystem pSystem,
final String pCommentDef) throws ArduinoException {
/* Marker is first token in header */
final String myMarker = ArduinoParser.nextToken(pCommentDef);
String myDef = ArduinoParser.stripToken(pCommentDef, myMarker);
if (!myMarker.equals(MARKER)) {
throw new ArduinoException("Invalid marker", pCommentDef);
}
/* Split out id/comment */
final int myIndex = myDef.indexOf(ArduinoChar.QUOTE);
if (myIndex == -1) {
throw new ArduinoException("Missing " + ArduinoChar.QUOTE + " separator", pCommentDef);
}
String myId = myDef.substring(0, myIndex);
myDef = myDef.substring(myIndex);
/* Check that the end character is semicolon */
final int myLen = myDef.length();
if (myDef.length() == 0 || myDef.charAt(myLen - 1) != ArduinoChar.SEMICOLON) {
throw new ArduinoException("Missing terminator", pCommentDef);
}
myDef = myDef.substring(0, myLen - 1);
/* Protect against exceptions */
try {
/* Comments is final token */
final String myComment = ArduinoParser.nextQuotedToken(myDef);
/* The next tokens are the object type and id */
final String myType = ArduinoParser.nextToken(myId);
myId = ArduinoParser.stripToken(myId, myType);
/* Determine the target for the comment */
final ArduinoNamedObject myTarget = determineTarget(pSystem, myType, myId);
/* Store the comment */
pSystem.storeCommentForObject(myTarget, myComment);
/* Handle parser exceptions */
} catch (ArduinoParserException e) {
throw new ArduinoException(e.getMessage() + ArduinoChar.COLON + e.getDetail(), pCommentDef);
}
}
/**
* Obtain the target.
* @param pSystem the system
* @param pType the target type
* @param pId the target id
* @return the object
* @throws ArduinoParserException on error
*/
private static ArduinoNamedObject determineTarget(final ArduinoSystem pSystem,
final String pType,
final String pId) throws ArduinoParserException {
/* If this is a system */
if (pType.length() == 0) {
return pSystem;
}
/* If this is a node */
if (pType.equals(ArduinoNode.MARKER)) {
return pSystem.findNodeByName(pId);
}
/* MsgId is the next token */
final String myId = ArduinoParser.nextToken(pId);
final String mySignal = ArduinoParser.stripToken(pId, myId);
final ArduinoMessage myMessage = pSystem.findMessageById(myId);
/* If this is a message */
if (pType.equals(ArduinoMessage.MARKER)) {
return myMessage;
}
/* If this is a signal */
if (pType.equals(ArduinoSignal.MARKER)) {
return myMessage.findSignalByName(mySignal);
}
/* Unrecognised marker */
throw new ArduinoParserException("Invalid comment type", pType);
}
}