# Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import os.path
import re

Import('env')

webcore = env.Dir('$CHROME_SRC_DIR/third_party/WebKit/WebCore')
webcore_posix = webcore.abspath.replace('\\', '/')

cygwin = env.Dir('$CYGWIN_DIR/bin')
cygwin_posix = cygwin.abspath.replace('\\', '/')

pending = env.Dir('$CHROME_SRC_DIR/webkit/pending')
portroot = env.Dir('$CHROME_SRC_DIR/webkit/port')
webkit_build = env.Dir('$CHROME_SRC_DIR/webkit/build')


def PosixIncludes(env, prefix, files, suffix):
  # This is basically a custom version of the _concat() function,
  # which we need because the binding script needs posix style paths,
  # even on windows, and _concat() doesn't make that easy to do...  :-(
  #
  # Note that because we're not using the RDirs function that the
  # normal _concat() call uses, this will only add the build
  # directory paths, not the paths in the underlying source directory,
  # to its list.
  posix_files = [str(env.Dir(f).abspath).replace('\\', '/') for f in files]
  combined = [prefix + f + suffix for f in posix_files]
  return ' '.join(combined)


env = env.Clone(
    WEBCORE = webcore,
    PENDING = pending,
    PORTROOT = portroot,
    WEBKIT_BUILD = webkit_build,

    BINDINGS_SCRIPTS_DIR = '$WEBKIT_DIR/port/bindings/scripts',
    BINDINGS_SCRIPT = '$BINDINGS_SCRIPTS_DIR/generate-bindings.pl',

    PERL_INCLUDE_PATH = ['$BINDINGS_SCRIPTS_DIR', 
                         '$CHROME_SRC_DIR/third_party/WebKit/WebCore/bindings/scripts'],

    FEATURE_DEFINES = [
        'ENABLE_CROSS_DOCUMENT_MESSAGING',
        'ENABLE_XSLT',
        'ENABLE_XPATH',
        'ENABLE_SVG',
        'ENABLE_SVG_ANIMATION',
        'ENABLE_SVG_AS_IMAGE',
        'ENABLE_SVG_FONTS',
        'ENABLE_SVG_FOREIGN_OBJECT',
        'ENABLE_SVG_USE',
    ],

    SVG_FLAGS = [
        'ENABLE_SVG_ANIMATION=1',
        'ENABLE_SVG_AS_IMAGE=1',
        'ENABLE_SVG_FONTS=1',
        'ENABLE_SVG_FOREIGN_OBJECT=1',
        'ENABLE_SVG_USE=1',
    ],

    BINDINGS_INCLUDE_PATH = [
        '$PENDING',
        '$WEBCORE/css',
        '$WEBCORE/dom',
        '$WEBCORE/html',
        '$WEBCORE/page',
        '$WEBCORE/svg',
        '$WEBCORE/xml',
    ],
    BINDINGS_INCLUDE_FLAG = '--include ',
    BINDINGS_INCLUDE_SUFFIX = '',
    _posix_includes = PosixIncludes,
    _BINDINGS_INCLUDE_FLAGS = '${_posix_includes(__env__, ' + \
                              'BINDINGS_INCLUDE_FLAG, ' + \
                              'BINDINGS_INCLUDE_PATH, ' + \
                              'BINDINGS_INCLUDE_SUFFIX)}',
)

env.PrependENVPath('PATH', cygwin_posix)


# When we haven't specified --verbose (aka brief_comstr), make the
# WebKit bindings building step output more brief to match the brief
# compile/link/etc. lines.
if env.GetOption('brief_comstr'):
  env.SetDefault(BINDINGSCOMSTR='________Building bindings in $TARGET')

bindings_perl_modules = env.Glob('$BINDINGS_SCRIPTS_DIR/*.pm')

def BindingsEmitter(target, source, env):
  source.append('$BINDINGS_SCRIPT')
  try:
    idl_contents = open(source[0].rfile().abspath, 'r').read()
  except EnvironmentError:
    return target, source
  idl_contents = re.sub('//[^\\n]*\\n', '', idl_contents)
  interfaces = re.findall('interface\\s*(?:\\[[^]]+\\])?\\s*'
                          '(\\w+)[^{]*[{]', idl_contents)
  new_target = []
  for i in interfaces:
    new_cpp = '$DERIVED_DIR/${BINDINGSPREFIX}' + i + '.cpp'
    new_h = '$DERIVED_DIR/${BINDINGSPREFIX}' + i + '.h'
    new_target.extend([new_cpp, new_h])
    env.Depends(new_cpp, bindings_perl_modules)
    env.Depends(new_h, bindings_perl_modules)
  return new_target, source

env.Append(
  BUILDERS = {'Bindings': Builder(
    action = Action('$BINDINGSCOM', '$BINDINGSCOMSTR'),
    src_suffix = '.idl',
    emitter = BindingsEmitter,
  )},
)

env.Replace(
    # TODO(bradnelson): fix ugly hack with one include!
    BINDINGSCOM = '$PERL $_PERL_INCLUDE_FLAGS ' + \
                  '${SOURCES[1].posix} ' + \
                  '--defines "$FEATURE_DEFINES $BINDINGS_LANGUAGE" ' + \
                  '--generator $BINDINGS_GENERATOR_ARG ' + \
                  '$_BINDINGS_INCLUDE_FLAGS ' + \
                  '--outputdir ${TARGET.dir} ' + \
                  '${SOURCES[0].posix}',
)

if env.Bit('mac'):  # Mac OS X
  env['BINDINGSPREFIX'] = 'DOM'
  env['BINDINGS_GENERATOR_ARG'] = 'ObjC'
  env['BINDINGS_LANGUAGE'] = 'LANGUAGE_OBJECTIVE_C'
  env.Append(BINDINGS_INCLUDE_PATH = [ 'bindings/js' ])
elif False:
  env['BINDINGSPREFIX'] = 'JS'
  env['BINDINGS_GENERATOR_ARG'] = 'JS'
  env['BINDINGS_LANGUAGE'] = 'LANGUAGE_JAVASCRIPT'
  env.Append(BINDINGS_INCLUDE_PATH = [ 'bindings/js' ])
elif True:
  env['BINDINGSPREFIX'] = 'V8'
  env['BINDINGS_GENERATOR_ARG'] = 'V8'
  env['BINDINGS_LANGUAGE'] = 'LANGUAGE_JAVASCRIPT V8_BINDING'
  env.Prepend(PERL_INCLUDE_PATH = [ '$PORTROOT/bindings/scripts' ])
else:
  print 'I am not going to generate bindings for you!'


idl_files = [
    'bindings/v8/UndetectableHTMLCollection.idl',

    'css/Counter.idl',
    'css/CSSCharsetRule.idl',
    'css/CSSFontFaceRule.idl',
    'css/CSSImportRule.idl',
    'css/CSSMediaRule.idl',
    'css/CSSPageRule.idl',
    'css/CSSPrimitiveValue.idl',
    'css/CSSRule.idl',
    'css/CSSRuleList.idl',
    'css/CSSStyleDeclaration.idl',
    'css/CSSStyleRule.idl',
    'css/CSSStyleSheet.idl',
    'css/CSSUnknownRule.idl',
    'css/CSSValue.idl',
    'css/CSSValueList.idl',
    'css/CSSVariablesDeclaration.idl',
    'css/CSSVariablesRule.idl',
    'css/MediaList.idl',
    'css/Rect.idl',
    'css/RGBColor.idl',
    'css/StyleSheet.idl',
    'css/StyleSheetList.idl',
    'css/WebKitCSSKeyframeRule.idl',
    'css/WebKitCSSKeyframesRule.idl',
    'css/WebKitCSSMatrix.idl',
    'css/WebKitCSSTransformValue.idl',

    'dom/Attr.idl',
    'dom/CDATASection.idl',
    'dom/CharacterData.idl',
    'dom/ClientRect.idl',
    'dom/ClientRectList.idl',
    'dom/Clipboard.idl',
    'dom/Comment.idl',
    'dom/Document.idl',
    'dom/DocumentFragment.idl',
    'dom/DocumentType.idl',
    'dom/DOMCoreException.idl',
    'dom/DOMImplementation.idl',
    'dom/DOMStringList.idl',
    'dom/Element.idl',
    'dom/Entity.idl',
    'dom/EntityReference.idl',
    'dom/Event.idl',
    'dom/EventException.idl',
    'dom/EventListener.idl',
    'dom/EventTarget.idl',
    'dom/KeyboardEvent.idl',
    'dom/MessageChannel.idl',
    'dom/MessageEvent.idl',
    'dom/MessagePort.idl',
    'dom/MouseEvent.idl',
    'dom/MutationEvent.idl',
    'dom/NamedNodeMap.idl',
    'dom/Node.idl',
    'dom/NodeFilter.idl',
    'dom/NodeIterator.idl',
    'dom/NodeList.idl',
    'dom/Notation.idl',
    'dom/OverflowEvent.idl',
    'dom/ProcessingInstruction.idl',
    'dom/ProgressEvent.idl',
    'dom/Range.idl',
    'dom/RangeException.idl',
    'dom/Text.idl',
    'dom/TextEvent.idl',
    'dom/TreeWalker.idl',
    'dom/UIEvent.idl',
    'dom/WebKitAnimationEvent.idl',
    'dom/WebKitTransitionEvent.idl',
    'dom/WheelEvent.idl',

    'html/CanvasGradient.idl',
    'html/CanvasPattern.idl',
    'html/CanvasPixelArray.idl',
    'html/CanvasRenderingContext2D.idl',
    'html/File.idl',
    'html/FileList.idl',
    'html/HTMLAnchorElement.idl',
    'html/HTMLAppletElement.idl',
    'html/HTMLAreaElement.idl',
    'html/HTMLAudioElement.idl',
    'html/HTMLBaseElement.idl',
    'html/HTMLBaseFontElement.idl',
    'html/HTMLBlockquoteElement.idl',
    'html/HTMLBodyElement.idl',
    'html/HTMLBRElement.idl',
    'html/HTMLButtonElement.idl',
    'html/HTMLCanvasElement.idl',
    'html/HTMLCollection.idl',
    'html/HTMLDirectoryElement.idl',
    'html/HTMLDivElement.idl',
    'html/HTMLDListElement.idl',
    'html/HTMLDocument.idl',
    'html/HTMLElement.idl',
    'html/HTMLEmbedElement.idl',
    'html/HTMLFieldSetElement.idl',
    'html/HTMLFontElement.idl',
    'html/HTMLFormElement.idl',
    'html/HTMLFrameElement.idl',
    'html/HTMLFrameSetElement.idl',
    'html/HTMLHeadElement.idl',
    'html/HTMLHeadingElement.idl',
    'html/HTMLHRElement.idl',
    'html/HTMLHtmlElement.idl',
    'html/HTMLIFrameElement.idl',
    'html/HTMLImageElement.idl',
    'html/HTMLInputElement.idl',
    'html/HTMLIsIndexElement.idl',
    'html/HTMLLabelElement.idl',
    'html/HTMLLegendElement.idl',
    'html/HTMLLIElement.idl',
    'html/HTMLLinkElement.idl',
    'html/HTMLMapElement.idl',
    'html/HTMLMarqueeElement.idl',
    'html/HTMLMediaElement.idl',
    'html/HTMLMenuElement.idl',
    'html/HTMLMetaElement.idl',
    'html/HTMLModElement.idl',
    'html/HTMLObjectElement.idl',
    'html/HTMLOListElement.idl',
    'html/HTMLOptGroupElement.idl',
    'html/HTMLOptionElement.idl',
    'html/HTMLOptionsCollection.idl',
    'html/HTMLParagraphElement.idl',
    'html/HTMLParamElement.idl',
    'html/HTMLPreElement.idl',
    'html/HTMLQuoteElement.idl',
    'html/HTMLScriptElement.idl',
    'html/HTMLSelectElement.idl',
    'html/HTMLSourceElement.idl',
    'html/HTMLStyleElement.idl',
    'html/HTMLTableCaptionElement.idl',
    'html/HTMLTableCellElement.idl',
    'html/HTMLTableColElement.idl',
    'html/HTMLTableElement.idl',
    'html/HTMLTableRowElement.idl',
    'html/HTMLTableSectionElement.idl',
    'html/HTMLTextAreaElement.idl',
    'html/HTMLTitleElement.idl',
    'html/HTMLUListElement.idl',
    'html/HTMLVideoElement.idl',
    'html/ImageData.idl',
    'html/MediaError.idl',
    'html/TextMetrics.idl',
    'html/TimeRanges.idl',
    'html/VoidCallback.idl',

    # 'loader/appcache/DOMApplicationCache.idl',

    'page/AbstractView.idl',
    'page/BarInfo.idl',
    'page/Console.idl',
    'page/DOMSelection.idl',
    'page/DOMWindow.idl',
    'page/History.idl',
    'page/Location.idl',
    'page/Navigator.idl',
    'page/Screen.idl',
    'page/WebKitPoint.idl',
    'page/WorkerNavigator.idl',

    'inspector/InspectorController.idl',

    'plugins/MimeTypeArray.idl',
    'plugins/MimeType.idl',
    'plugins/PluginArray.idl',
    'plugins/Plugin.idl',

    'svg/ElementTimeControl.idl',
    'svg/SVGAElement.idl',
    'svg/SVGAltGlyphElement.idl',
    'svg/SVGAngle.idl',
    'svg/SVGAnimateColorElement.idl',
    'svg/SVGAnimatedAngle.idl',
    'svg/SVGAnimatedBoolean.idl',
    'svg/SVGAnimatedEnumeration.idl',
    'svg/SVGAnimatedInteger.idl',
    'svg/SVGAnimatedLength.idl',
    'svg/SVGAnimatedLengthList.idl',
    'svg/SVGAnimatedNumber.idl',
    'svg/SVGAnimatedNumberList.idl',
    'svg/SVGAnimatedPathData.idl',
    'svg/SVGAnimatedPoints.idl',
    'svg/SVGAnimatedPreserveAspectRatio.idl',
    'svg/SVGAnimatedRect.idl',
    'svg/SVGAnimatedString.idl',
    'svg/SVGAnimatedTransformList.idl',
    'svg/SVGAnimateElement.idl',
    'svg/SVGAnimateTransformElement.idl',
    'svg/SVGAnimationElement.idl',
    'svg/SVGCircleElement.idl',
    'svg/SVGClipPathElement.idl',
    'svg/SVGColor.idl',
    'svg/SVGComponentTransferFunctionElement.idl',
    'svg/SVGCursorElement.idl',
    'svg/SVGDefinitionSrcElement.idl',
    'svg/SVGDefsElement.idl',
    'svg/SVGDescElement.idl',
    'svg/SVGDocument.idl',
    'svg/SVGElement.idl',
    'svg/SVGElementInstance.idl',
    'svg/SVGElementInstanceList.idl',
    'svg/SVGEllipseElement.idl',
    'svg/SVGException.idl',
    'svg/SVGExternalResourcesRequired.idl',
    'svg/SVGFEBlendElement.idl',
    'svg/SVGFEColorMatrixElement.idl',
    'svg/SVGFEComponentTransferElement.idl',
    'svg/SVGFECompositeElement.idl',
    'svg/SVGFEDiffuseLightingElement.idl',
    'svg/SVGFEDisplacementMapElement.idl',
    'svg/SVGFEDistantLightElement.idl',
    'svg/SVGFEFloodElement.idl',
    'svg/SVGFEFuncAElement.idl',
    'svg/SVGFEFuncBElement.idl',
    'svg/SVGFEFuncGElement.idl',
    'svg/SVGFEFuncRElement.idl',
    'svg/SVGFEGaussianBlurElement.idl',
    'svg/SVGFEImageElement.idl',
    'svg/SVGFEMergeElement.idl',
    'svg/SVGFEMergeNodeElement.idl',
    'svg/SVGFEOffsetElement.idl',
    'svg/SVGFEPointLightElement.idl',
    'svg/SVGFESpecularLightingElement.idl',
    'svg/SVGFESpotLightElement.idl',
    'svg/SVGFETileElement.idl',
    'svg/SVGFETurbulenceElement.idl',
    'svg/SVGFilterElement.idl',
    'svg/SVGFilterPrimitiveStandardAttributes.idl',
    'svg/SVGFitToViewBox.idl',
    'svg/SVGFontElement.idl',
    'svg/SVGFontFaceElement.idl',
    'svg/SVGFontFaceFormatElement.idl',
    'svg/SVGFontFaceNameElement.idl',
    'svg/SVGFontFaceSrcElement.idl',
    'svg/SVGFontFaceUriElement.idl',
    'svg/SVGForeignObjectElement.idl',
    'svg/SVGGElement.idl',
    'svg/SVGGlyphElement.idl',
    'svg/SVGGradientElement.idl',
    'svg/SVGHKernElement.idl',
    'svg/SVGImageElement.idl',
    'svg/SVGLangSpace.idl',
    'svg/SVGLength.idl',
    'svg/SVGLengthList.idl',
    'svg/SVGLinearGradientElement.idl',
    'svg/SVGLineElement.idl',
    'svg/SVGLocatable.idl',
    'svg/SVGMarkerElement.idl',
    'svg/SVGMaskElement.idl',
    'svg/SVGMatrix.idl',
    'svg/SVGMetadataElement.idl',
    'svg/SVGMissingGlyphElement.idl',
    'svg/SVGNumber.idl',
    'svg/SVGNumberList.idl',
    'svg/SVGPaint.idl',
    'svg/SVGPathElement.idl',
    'svg/SVGPathSeg.idl',
    'svg/SVGPathSegArcAbs.idl',
    'svg/SVGPathSegArcRel.idl',
    'svg/SVGPathSegClosePath.idl',
    'svg/SVGPathSegCurvetoCubicAbs.idl',
    'svg/SVGPathSegCurvetoCubicRel.idl',
    'svg/SVGPathSegCurvetoCubicSmoothAbs.idl',
    'svg/SVGPathSegCurvetoCubicSmoothRel.idl',
    'svg/SVGPathSegCurvetoQuadraticAbs.idl',
    'svg/SVGPathSegCurvetoQuadraticRel.idl',
    'svg/SVGPathSegCurvetoQuadraticSmoothAbs.idl',
    'svg/SVGPathSegCurvetoQuadraticSmoothRel.idl',
    'svg/SVGPathSegLinetoAbs.idl',
    'svg/SVGPathSegLinetoHorizontalAbs.idl',
    'svg/SVGPathSegLinetoHorizontalRel.idl',
    'svg/SVGPathSegLinetoRel.idl',
    'svg/SVGPathSegLinetoVerticalAbs.idl',
    'svg/SVGPathSegLinetoVerticalRel.idl',
    'svg/SVGPathSegList.idl',
    'svg/SVGPathSegMovetoAbs.idl',
    'svg/SVGPathSegMovetoRel.idl',
    'svg/SVGPatternElement.idl',
    'svg/SVGPoint.idl',
    'svg/SVGPointList.idl',
    'svg/SVGPolygonElement.idl',
    'svg/SVGPolylineElement.idl',
    'svg/SVGPreserveAspectRatio.idl',
    'svg/SVGRadialGradientElement.idl',
    'svg/SVGRect.idl',
    'svg/SVGRectElement.idl',
    'svg/SVGRenderingIntent.idl',
    'svg/SVGScriptElement.idl',
    'svg/SVGSetElement.idl',
    'svg/SVGStopElement.idl',
    'svg/SVGStringList.idl',
    'svg/SVGStylable.idl',
    'svg/SVGStyleElement.idl',
    'svg/SVGSVGElement.idl',
    'svg/SVGSwitchElement.idl',
    'svg/SVGSymbolElement.idl',
    'svg/SVGTests.idl',
    'svg/SVGTextContentElement.idl',
    'svg/SVGTextElement.idl',
    'svg/SVGTextPathElement.idl',
    'svg/SVGTextPositioningElement.idl',
    'svg/SVGTitleElement.idl',
    'svg/SVGTransform.idl',
    'svg/SVGTransformable.idl',
    'svg/SVGTransformList.idl',
    'svg/SVGTRefElement.idl',
    'svg/SVGTSpanElement.idl',
    'svg/SVGUnitTypes.idl',
    'svg/SVGURIReference.idl',
    'svg/SVGUseElement.idl',
    'svg/SVGViewElement.idl',
    'svg/SVGViewSpec.idl',
    'svg/SVGZoomAndPan.idl',
    'svg/SVGZoomEvent.idl',

    'workers/Worker.idl',
    'workers/WorkerContext.idl',
    'workers/WorkerLocation.idl',

    'xml/DOMParser.idl',
    'xml/DOMParser.idl',
    'xml/XMLHttpRequest.idl',
    'xml/XMLHttpRequestException.idl',
    'xml/XMLHttpRequestProgressEvent.idl',
    'xml/XMLHttpRequestUpload.idl',
    'xml/XMLSerializer.idl',
    'xml/XPathEvaluator.idl',
    'xml/XPathException.idl',
    'xml/XPathExpression.idl',
    'xml/XPathNSResolver.idl',
    'xml/XPathResult.idl',
    'xml/XSLTProcessor.idl',
]

for name in idl_files:
  env.Bindings('$WEBKIT_DIR/port/' + name)


# copy over some files
# TODO(eroman): can probably get rid of this.
i = env.Install('$SHARED_DIR', [])
env.Alias('webkit', i)

# HTML tag and attribute names
# If we add ENABLE_ flags via HTML_FLAGS, we need to pass in
# --extraDefines $HTML_FLAGS.
env.Command(['$DERIVED_DIR/HTMLNames.cpp',
             '$DERIVED_DIR/HTMLNames.h',
             '$DERIVED_DIR/HTMLElementFactory.cpp',
             '$DERIVED_DIR/HTMLElementFactory.h'],
            ['$PORT_DIR/dom/make_names.pl',
             '$PORT_DIR/html/HTMLTagNames.in',
             '$PORT_DIR/html/HTMLAttributeNames.in'],
            '$PERL $_PERL_INCLUDE_FLAGS ${SOURCES[0].posix} '
            '--tags ${SOURCES[1].posix} '
            '--attrs ${SOURCES[2].posix} '
            '--factory '
            '--wrapperFactory '
            '--outputDir $DERIVED_DIR')

env.Command(['$DERIVED_DIR/XMLNames.cpp',
             '$DERIVED_DIR/XMLNames.h'],
            ['$PORT_DIR/dom/make_names.pl',
             '$PORT_DIR/xml/xmlattrs.in'],
            '$PERL $_PERL_INCLUDE_FLAGS ${SOURCES[0].posix} '
            '--attrs ${SOURCES[1].posix} '
            '--outputDir $DERIVED_DIR')

env.Command(['$DERIVED_DIR/SVGElementFactory.cpp',
             '$DERIVED_DIR/SVGElementFactory.h',
             '$DERIVED_DIR/SVGNames.cpp',
             '$DERIVED_DIR/SVGNames.h'],
            ['$PORT_DIR/dom/make_names.pl',
             '$PORT_DIR/svg/svgtags.in',
             '$PORT_DIR/svg/svgattrs.in'],
            '$PERL $_PERL_INCLUDE_FLAGS ${SOURCES[0].posix} '
            '--tags ${SOURCES[1].posix} '
            '--attrs ${SOURCES[2].posix} '
            '--extraDefines "$SVG_FLAGS" '
            '--factory '
            '--wrapperFactory '
            '--outputDir $DERIVED_DIR')

env.Command(['$DERIVED_DIR/XLinkNames.cpp',
             '$DERIVED_DIR/XLinkNames.h'],
            ['$PORT_DIR/dom/make_names.pl',
             '$PORT_DIR/svg/xlinkattrs.in'],
            '$PERL $_PERL_INCLUDE_FLAGS ${SOURCES[0].posix} '
            '--attrs ${SOURCES[1].posix} '
            '--outputDir $DERIVED_DIR')

# Add SVG Symbols to the WebCore exported symbols file
# TODO(bradnelson): fix this
#WebCore.exp : WebCore.base.exp WebCore.SVG.exp
#	cat $^ > $@

def cat_files(target, source, env):
  fout = open(str(target[0]), "w")
  for src in source:
    fin = open(str(src))
    fout.writelines(fin.readlines())
    fin.close()
  fout.close()

env.Command(['$DERIVED_DIR/UserAgentStyleSheets.h',
             '$DERIVED_DIR/UserAgentStyleSheetsData.cpp'],
            ['$PORT_DIR/css/make-css-file-arrays.pl',
             '$PORT_DIR/css/view-source.css',
             '$PORT_DIR/css/svg.css',
             '$PORT_DIR/css/html4.css',
             '$PORT_DIR/css/quirks.css',
             '$PORT_DIR/css/themeWin.css',
             '$PORT_DIR/css/themeWinQuirks.css'],
            '$PERL ${SOURCES[0].posix} ${TARGETS.posix} ${SOURCES[1:].posix}')

def create_h_wrapper(target, source, env):
  """
  Create a *.h file by surrounding the contents of a
  yacc-generated *.hpp with a #ifndef-#define-#endif guard.
  """
  t = str(target[1])
  fp = open(t, 'w')
  define = os.path.splitext(os.path.split(t)[1])[0]
  fp.write('#ifndef %s_h\n' % define)
  fp.write('#define %s_h\n' % define)
  fp.write(open(t + 'pp', 'r').read())
  fp.write('#endif // %s_h\n' % define)

# TODO(sgk):  make this a real pseudo-Builder
def BuildYacc(env, dir, name, file):
  yacc_env = env.Clone()
  yacc_env['YACC'] = env.Detect('bison') or 'yacc'
  yacc_env.Command(['$DERIVED_DIR/%s.cpp' % file,
                    '$DERIVED_DIR/%s.h'   % file],
                   ['$PORT_DIR/%s/%s.y' % (dir, file)],
                   ['$YACC -d -p %s ${SOURCES[0].posix} ' % name +
                      '-o ${TARGET.posix}',
                    Action(create_h_wrapper),
                    Delete('${TARGETS[1]}pp')])

BuildYacc(env, 'xml', 'xpathyy', 'XPathGrammar')
BuildYacc(env, 'css', 'cssyy',   'CSSGrammar')

# TODO(bradnelson): need to add in error checking

env.Command('$PORT_DIR/SVGCSSValueKeywords.in',
            '$PORT_DIR/css/SVGCSSValueKeywords.in',
            '$PERL -ne "print lc" $SOURCES > $TARGET')

env.Command('$PORT_DIR/CSSValueKeywords.in',
            ['$PORT_DIR/css/CSSValueKeywords.in',
             '$PORT_DIR/css/SVGCSSValueKeywords.in'],
            '$PERL -ne "print lc" $SOURCES > $TARGET')

env.Command('$PORT_DIR/CSSPropertyNames.in',
            ['$PORT_DIR/css/CSSPropertyNames.in',
             '$PORT_DIR/css/SVGCSSPropertyNames.in'],
            '$PERL -ne "print lc" $SOURCES > $TARGET')

env.Command(['$DERIVED_DIR/CSSValueKeywords.c',
             '$DERIVED_DIR/CSSValueKeywords.h'],
            ['$PORT_DIR/css/makevalues.pl',
             '$PORT_DIR/CSSValueKeywords.in'],
            ['cd ${SOURCES[1].dir} && $PERL ${str(SOURCES[0].abspath).replace("\\\\", "/")}',
             Move('${TARGETS[0]}', '${SOURCES[1].dir}/${TARGETS[0].file}'),
             Move('${TARGETS[1]}', '${SOURCES[1].dir}/${TARGETS[1].file}'),
            ])

env.Command(['$DERIVED_DIR/CSSPropertyNames.cpp',
             '$DERIVED_DIR/CSSPropertyNames.h'],
            ['$PORT_DIR/css/makeprop.pl',
             '$PORT_DIR/CSSPropertyNames.in'],
            ['cd ${SOURCES[1].dir} && $PERL ${str(SOURCES[0].abspath).replace("\\\\", "/")}',
             Move('${TARGETS[0]}', '${SOURCES[1].dir}/${TARGETS[0].file}'),
             Move('${TARGETS[1]}', '${SOURCES[1].dir}/${TARGETS[1].file}'),
            ])


# DOCTYPE strings
env.Command('$DERIVED_DIR/DocTypeStrings.cpp',
            '$PORT_DIR/html/DocTypeStrings.gperf',
            'gperf -CEot -L ANSI-C -k "*" -N findDoctypeEntry -F ' + \
            ',PubIDInfo::eAlmostStandards,PubIDInfo::eAlmostStandards ' + \
            '$SOURCE > $TARGET')

# color names
env.Command('$DERIVED_DIR/ColorData.c',
            '$PORT_DIR/platform/ColorData.gperf',
            'gperf -CDEot -L ANSI-C -k "*" -N findColor -D -s 2 ' + \
            '$SOURCE > $TARGET')

# HTML entity names
env.Command('$DERIVED_DIR/HTMLEntityNames.c',
            '$PORT_DIR/html/HTMLEntityNames.gperf',
            'gperf -a -L ANSI-C -C -G -c -o -t -k "*" -N findEntity ' + \
            '-D -s 2 $SOURCE > $TARGET')

# CSS tokenizer
env.Command('$DERIVED_DIR/tokenizer.cpp',
            ['$PORT_DIR/css/tokenizer.flex',
             '$PORT_DIR/css/maketokenizer'],
            'flex --nowarn -t $SOURCE | perl ${SOURCES[1]} > $TARGET')