/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is HTML Parser C++ Translator code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2008-2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Henri Sivonen <hsivonen@iki.fi>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package nu.validator.htmlparser.cpptranslate;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class CppTypes {
/**
* The license for the atom list written by this program.
*/
private static final String ATOM_LICENSE = "/*\n"
+ " * Copyright (c) 2008-2010 Mozilla Foundation\n"
+ " *\n"
+ " * Permission is hereby granted, free of charge, to any person obtaining a \n"
+ " * copy of this software and associated documentation files (the \"Software\"), \n"
+ " * to deal in the Software without restriction, including without limitation \n"
+ " * the rights to use, copy, modify, merge, publish, distribute, sublicense, \n"
+ " * and/or sell copies of the Software, and to permit persons to whom the \n"
+ " * Software is furnished to do so, subject to the following conditions:\n"
+ " *\n"
+ " * The above copyright notice and this permission notice shall be included in \n"
+ " * all copies or substantial portions of the Software.\n"
+ " *\n"
+ " * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR \n"
+ " * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \n"
+ " * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL \n"
+ " * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \n"
+ " * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING \n"
+ " * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER \n"
+ " * DEALINGS IN THE SOFTWARE.\n" + " */\n\n";
private static Set<String> reservedWords = new HashSet<String>();
static {
reservedWords.add("small");
reservedWords.add("for");
reservedWords.add("false");
reservedWords.add("true");
reservedWords.add("default");
reservedWords.add("class");
reservedWords.add("switch");
reservedWords.add("union");
reservedWords.add("template");
reservedWords.add("int");
reservedWords.add("char");
reservedWords.add("operator");
reservedWords.add("or");
reservedWords.add("and");
reservedWords.add("not");
reservedWords.add("xor");
reservedWords.add("unicode");
}
private static final String[] TREE_BUILDER_INCLUDES = { "nsContentUtils",
"nsIAtom", "nsHtml5AtomTable", "nsITimer", "nsString",
"nsNameSpaceManager", "nsIContent", "nsTraceRefcnt", "jArray",
"nsHtml5DocumentMode", "nsHtml5ArrayCopy", "nsHtml5Parser",
"nsHtml5Atoms", "nsHtml5TreeOperation", "nsHtml5StateSnapshot",
"nsHtml5StackNode", "nsHtml5TreeOpExecutor", "nsHtml5StreamParser",
"nsAHtml5TreeBuilderState", "nsHtml5Highlighter",
"nsHtml5PlainTextUtils", "nsHtml5ViewSourceUtils",
"mozilla/Likely", "nsIContentHandle", "nsHtml5OplessBuilder" };
private static final String[] TOKENIZER_INCLUDES = { "nsIAtom",
"nsHtml5AtomTable", "nsString", "nsIContent", "nsTraceRefcnt",
"jArray", "nsHtml5DocumentMode", "nsHtml5ArrayCopy",
"nsHtml5NamedCharacters", "nsHtml5NamedCharactersAccel",
"nsHtml5Atoms", "nsAHtml5TreeBuilderState", "nsHtml5Macros",
"nsHtml5Highlighter", "nsHtml5TokenizerLoopPolicies" };
private static final String[] INCLUDES = { "nsIAtom", "nsHtml5AtomTable",
"nsString", "nsNameSpaceManager", "nsIContent", "nsTraceRefcnt",
"jArray", "nsHtml5ArrayCopy", "nsAHtml5TreeBuilderState",
"nsHtml5Atoms", "nsHtml5ByteReadable", "nsIUnicodeDecoder",
"nsHtml5Macros", "nsIContentHandle" };
private static final String[] OTHER_DECLATIONS = {};
private static final String[] TREE_BUILDER_OTHER_DECLATIONS = {};
private static final String[] NAMED_CHARACTERS_INCLUDES = { "jArray",
"nscore", "nsDebug", "prlog", "mozilla/ArrayUtils" };
private static final String[] FORWARD_DECLARATIONS = { "nsHtml5StreamParser" };
private static final String[] CLASSES_THAT_NEED_SUPPLEMENT = {
"MetaScanner", "Tokenizer", "TreeBuilder", "UTF16Buffer", };
private static final String[] STATE_LOOP_POLICIES = {
"nsHtml5ViewSourcePolicy", "nsHtml5SilentPolicy" };
private final Map<String, String> atomMap = new HashMap<String, String>();
private final Writer atomWriter;
public CppTypes(File atomList) {
if (atomList == null) {
atomWriter = null;
} else {
try {
atomWriter = new OutputStreamWriter(new FileOutputStream(
atomList), "utf-8");
atomWriter.write(ATOM_LICENSE);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public void finished() {
try {
if (atomWriter != null) {
atomWriter.flush();
atomWriter.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public String classPrefix() {
return "nsHtml5";
}
public String booleanType() {
return "bool";
}
public String byteType() {
return "int8_t";
}
public String charType() {
return "char16_t";
}
/**
* Only used for named characters.
*
* @return
*/
public String unsignedShortType() {
return "uint16_t";
}
public String intType() {
return "int32_t";
}
public String stringType() {
return "nsString*";
}
public String localType() {
return "nsIAtom*";
}
public String prefixType() {
return "nsIAtom*";
}
public String nsUriType() {
return "int32_t";
}
public String falseLiteral() {
return "false";
}
public String trueLiteral() {
return "true";
}
public String nullLiteral() {
return "nullptr";
}
public String encodingDeclarationHandlerType() {
return "nsHtml5StreamParser*";
}
public String nodeType() {
return "nsIContentHandle*";
}
public String xhtmlNamespaceLiteral() {
return "kNameSpaceID_XHTML";
}
public String svgNamespaceLiteral() {
return "kNameSpaceID_SVG";
}
public String xmlnsNamespaceLiteral() {
return "kNameSpaceID_XMLNS";
}
public String xmlNamespaceLiteral() {
return "kNameSpaceID_XML";
}
public String noNamespaceLiteral() {
return "kNameSpaceID_None";
}
public String xlinkNamespaceLiteral() {
return "kNameSpaceID_XLink";
}
public String mathmlNamespaceLiteral() {
return "kNameSpaceID_MathML";
}
public String arrayTemplate() {
return "jArray";
}
public String autoArrayTemplate() {
return "autoJArray";
}
public String localForLiteral(String literal) {
String atom = atomMap.get(literal);
if (atom == null) {
atom = createAtomName(literal);
atomMap.put(literal, atom);
if (atomWriter != null) {
try {
atomWriter.write("HTML5_ATOM(" + atom + ", \"" + literal
+ "\")\n");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
return "nsHtml5Atoms::" + atom;
}
private String createAtomName(String literal) {
String candidate = literal.replaceAll("[^a-zA-Z0-9_]", "_");
if ("".equals(candidate)) {
candidate = "emptystring";
}
while (atomMap.values().contains(candidate)
|| reservedWords.contains(candidate)) {
candidate = candidate + '_';
}
return candidate;
}
public String stringForLiteral(String literal) {
return '"' + literal + '"';
}
public String staticArrayTemplate() {
return "staticJArray";
}
public String newArrayCreator() {
return "newJArray";
}
public String[] boilerplateIncludes(String javaClass) {
if ("TreeBuilder".equals(javaClass)) {
return TREE_BUILDER_INCLUDES;
} else if ("Tokenizer".equals(javaClass)) {
return TOKENIZER_INCLUDES;
} else {
return INCLUDES;
}
}
public String[] boilerplateDeclarations(String javaClass) {
if ("TreeBuilder".equals(javaClass)) {
return TREE_BUILDER_OTHER_DECLATIONS;
} else {
return OTHER_DECLATIONS;
}
}
public String[] namedCharactersIncludes() {
return NAMED_CHARACTERS_INCLUDES;
}
public String[] boilerplateForwardDeclarations() {
return FORWARD_DECLARATIONS;
}
public String documentModeHandlerType() {
return "nsHtml5TreeBuilder*";
}
public String documentModeType() {
return "nsHtml5DocumentMode";
}
public String arrayCopy() {
return "nsHtml5ArrayCopy::arraycopy";
}
public String maxInteger() {
return "INT32_MAX";
}
public String constructorBoilerplate(String className) {
return "MOZ_COUNT_CTOR(" + className + ");";
}
public String destructorBoilderplate(String className) {
return "MOZ_COUNT_DTOR(" + className + ");";
}
public String literalType() {
return "const char*";
}
public boolean hasSupplement(String javaClass) {
return Arrays.binarySearch(CLASSES_THAT_NEED_SUPPLEMENT, javaClass) > -1;
}
public String internerType() {
return "nsHtml5AtomTable*";
}
public String treeBuilderStateInterface() {
return "nsAHtml5TreeBuilderState";
}
public String treeBuilderStateType() {
return "nsAHtml5TreeBuilderState*";
}
public String arrayLengthMacro() {
return "MOZ_ARRAY_LENGTH";
}
public String staticAssert() {
return "PR_STATIC_ASSERT";
}
public String abortIfFalse() {
return "NS_ABORT_IF_FALSE";
}
public String continueMacro() {
return "NS_HTML5_CONTINUE";
}
public String breakMacro() {
return "NS_HTML5_BREAK";
}
public String characterNameType() {
return "nsHtml5CharacterName&";
}
public String characterNameTypeDeclaration() {
return "nsHtml5CharacterName";
}
public String transition() {
return "P::transition";
}
public String tokenizerErrorCondition() {
return "P::reportErrors";
}
public String firstTransitionArg() {
return "mViewSource";
}
public String errorHandler() {
return "MOZ_UNLIKELY(mViewSource)";
}
public String completedCharacterReference() {
return "P::completedNamedCharacterReference(mViewSource)";
}
public String[] stateLoopPolicies() {
return STATE_LOOP_POLICIES;
}
public String assertionMacro() {
return "MOZ_ASSERT";
}
}