Hints.java
/*
** Module : Hints.java
** Abstract : Encapsulates elementary hints and corresponding XML tree.
**
** Copyright (c) 2004-2020, Golden Code Development Corporation.
**
** -#- -I- --Date-- --JPRM-- -----------------------------Description-----------------------------
** 001 NVS 20050513 @21162 Created. Initial implementation.
** 002 NVS 20050526 @21293 Cleaned the code up.
** 003 NVS 20050527 @21318 Separated XML tag into HintsTags interface.
** 004 NVS 20051003 @22928 Hints XML no longer contains creation date & time to produce
** identical files for identical input. The hints file is not created at
** all unless there is at least one hints record.
** 005 GES 20090515 @42217 Import changes.
** 006 CA 20170825 Enhanced to allow collection and reporting of preprocessor constant
** symbols.
** 007 CA 20201015 Replaced java.util.Stack with ArrayDeque (as synchronization is not required).
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.preproc;
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import com.goldencode.util.*;
import com.goldencode.p2j.*;
/**
* Keeps information about elementary hints and organizes them into the tree.
* <p>
* @author NVS
* @version 1.0.0
*/
public class Hints
implements HintsTags
{
/** output XML file name */
private String filename = null;
/** ordered list of hints */
private List list = null;
/** stack of include hints */
private Deque includes = null;
/** XML document */
private Document dom = null;
/** stack of DOM parents */
private Deque parents = null;
/** count of essential elements */
private int elementsCount = 0;
/**
* Constructor.
*
* @param filename
* hints file name or <code>null</code>
* @throws ParserConfigurationException
* Forwarded from XmlHelper.
* @throws IOException
* Forwarded from XmlHelper.
*/
public Hints(String filename)
throws ParserConfigurationException,
IOException
{
list = new LinkedList();
includes = new ArrayDeque();
parents = new ArrayDeque();
this.filename = filename;
if (filename != null)
{
dom = XmlHelper.newDocument();
Comment comment = dom.createComment("Preprocessor hints");
dom.appendChild(comment);
Element root = dom.createElement(ELEM_TAG_ROOT);
dom.appendChild(root);
Element elem = dom.createElement(ELEM_TAG_SUBROOT);
root.appendChild(elem);
parents.push(elem);
}
}
/**
* Returns the hints list.
*
* @return
* the hints list
*/
public List getHintsList()
{
return list;
}
/**
* Returns the hints stack.
*
* @return
* the hints stack
*/
public Deque getHintsStack()
{
return includes;
}
/**
* Creates the include hint element.
* Creation of this hint is done under the current parent element and then
* this element is pushed onto the parents stack to become the current
* parent.
*
* @param ih
* <code>IncludeHint</code> object to get the details from.
*/
public void createAndPushIncludeHint(IncludeHint ih)
{
Element parent = (Element)parents.peek();
Element elem = dom.createElement(ELEM_TAG_INCL);
elementsCount ++;
parent.appendChild(elem);
XmlHelper.setAttribute(elem, ATTR_TAG_FILE, ih.getFilename());
elem.setAttribute(ATTR_TAG_START_LINE, Integer.toString(
ih.getStartLine()));
elem.setAttribute(ATTR_TAG_START_COL, Integer.toString(
ih.getStartColumn()));
parents.push(elem);
}
/**
* Completes the include hint element.
* This element is popped off the parents stack.
*
* @param ih
* <code>IncludeHint</code> object to get the details from.
*/
public void popAndCompleteIncludeHint(IncludeHint ih)
{
Element elem = (Element)parents.pop();
elem.setAttribute(ATTR_TAG_END_LINE, Integer.toString(
ih.getEndLine()));
elem.setAttribute(ATTR_TAG_END_COL, Integer.toString(
ih.getEndColumn()));
}
/**
* Creates the argument hint element.
* Creation of this hint is done under the current parent element.
*
* @param ah
* <code>ArgumentHint</code> object to get the details from.
*/
public void createArgumentHint(ArgumentHint ah)
{
Element parent = (Element)parents.peek();
Element elem = dom.createElement(ELEM_TAG_ARG);
elementsCount ++;
parent.appendChild(elem);
String name = ah.getName();
if (name.startsWith("{"))
name = new String(name + "}");
XmlHelper.setAttribute(elem, ATTR_TAG_ARG_NAME, name);
elem.setAttribute(ATTR_TAG_ARG_POS, Integer.toString(ah.getPosition()));
XmlHelper.setAttribute(elem, ATTR_TAG_ARG_VAL, ah.getValue());
elem.setAttribute(ATTR_TAG_ARG_USED, ah.getUsed() ? "yes" : "no");
}
/**
* Creates the reference hint element.
* Creation of this hint is done under the current parent element.
*
* @param rh
* <code>ReferenceHint</code> object to get the details from.
*/
public void createReferenceHint(ReferenceHint rh)
{
Element parent = (Element)parents.peek();
Element elem = dom.createElement(ELEM_TAG_REF);
elementsCount ++;
parent.appendChild(elem);
String name = rh.getName();
if (name.startsWith("{"))
name = new String(name + "}");
XmlHelper.setAttribute(elem, ATTR_TAG_REF_NAME, name);
elem.setAttribute(ATTR_TAG_REF_TYPE, rh.getType());
XmlHelper.setAttribute(elem, ATTR_TAG_REF_VAL, rh.getValue());
elem.setAttribute(ATTR_TAG_REF_LINE, Integer.toString(rh.getLine()));
elem.setAttribute(ATTR_TAG_REF_COL, Integer.toString(rh.getColumn()));
}
/**
* Creates the symbol hint element.
* Creation of this hint is done under the current parent element.
*
* @param name
* the symbol's name
* @param b
* The symbol's value.
*/
public void createConstantSymbol(String name, Symbol b)
{
if (b == null || b.getValue() == null)
{
return;
}
Element parent = (Element)parents.peek();
Element elem = dom.createElement(ELEM_TAG_SYM);
elementsCount ++;
parent.appendChild(elem);
XmlHelper.setAttribute(elem, ATTR_TAG_SYM_NAME, name);
elem.setAttribute(ATTR_TAG_SYM_TYPE, b.getOriginText());
XmlHelper.setAttribute(elem, ATTR_TAG_SYM_VAL, b.getValue());
}
/**
* Saves the hints tree to the file.
*
* @throws IOException
* Forwarded from XmlHelper.
*/
public void save()
throws IOException
{
if (filename != null && elementsCount > 0)
XmlHelper.write(dom, filename);
}
}