Index: build.conf
===================================================================
--- build.conf (revision 109892)
+++ build.conf (working copy)
@@ -24,3 +24,31 @@
# we have a recursive makefile for the test files (for now)
# test/*.c
+
+# some stuff that needs to explicitly be added or removed from the list of
+# files built on win32. this is on top of what can be deduced by the rule
+# of using whatever is in the win32 subdir unless there isn't one, in which
+# case we just fall back to whatever's in the unix subdir.
+[win32-fixups]
+add-files =
+ file_io/unix/copy.c
+ file_io/unix/fileacc.c
+ file_io/unix/filepath_util.c
+ file_io/unix/fullrw.c
+ file_io/unix/mktemp.c
+ file_io/unix/tempdir.c
+ misc/unix/errorcodes.c
+ misc/unix/getopt.c
+ misc/unix/otherchild.c
+ misc/unix/version.c
+ mmap/unix/common.c
+ network_io/unix/inet_ntop.c
+ network_io/unix/inet_pton.c
+ network_io/unix/sockaddr.c
+
+remove-files =
+ support/unix/waitio.c
+ misc/win32/apr_app.c
+
+remove-headers =
+ include/apr.h
Property changes on: build
___________________________________________________________________
Name: svn:ignore
- Makefile
libtool.m4
ltsugar.m4
ltconfig
ltmain.sh
ltcf-c.sh
apr_rules.mk
apr_rules.out
LibD
LibR
Debug
Release
*.vcproj
*.aps
*.plg
*.dep
*.mak
+ Makefile
libtool.m4
ltsugar.m4
ltconfig
ltmain.sh
ltcf-c.sh
apr_rules.mk
apr_rules.out
LibD
LibR
Debug
Release
*.vcproj
*.aps
*.plg
*.dep
*.mak
*.pyc
Index: build/ezt.py
===================================================================
--- build/ezt.py (revision 0)
+++ build/ezt.py (revision 0)
@@ -0,0 +1,585 @@
+#!/usr/bin/env python
+"""ezt.py -- easy templating
+
+ezt templates are very similar to standard HTML files. But additionally
+they contain directives sprinkled in between. With these directives
+it is possible to generate the dynamic content from the ezt templates.
+
+These directives are enclosed in square brackets. If you are a
+C-programmer, you might be familar with the #ifdef directives of the
+C preprocessor 'cpp'. ezt provides a similar concept for HTML. Additionally
+EZT has a 'for' directive, which allows to iterate (repeat) certain
+subsections of the template according to sequence of data items
+provided by the application.
+
+The HTML rendering is performed by the method generate() of the Template
+class. Building template instances can either be done using external
+EZT files (convention: use the suffix .ezt for such files):
+
+ >>> template = Template("../templates/log.ezt")
+
+or by calling the parse() method of a template instance directly with
+a EZT template string:
+
+ >>> template = Template()
+ >>> template.parse('''
+ ... [title_string]
+ ... [title_string]
+ ... [for a_sequence] [a_sequence]
+ ... [end]
+ ... The [person] is [if-any state]in[else]out[end].
+ ...
+ ...
+ ... ''')
+
+The application should build a dictionary 'data' and pass it together
+with the output fileobject to the templates generate method:
+
+ >>> data = {'title_string' : "A Dummy Page",
+ ... 'a_sequence' : ['list item 1', 'list item 2', 'another element'],
+ ... 'person': "doctor",
+ ... 'state' : None }
+ >>> import sys
+ >>> template.generate(sys.stdout, data)
+
+ A Dummy Page
+ A Dummy Page
+ list item 1
+ list item 2
+ another element
+
+ The doctor is out.
+
+
+
+Template syntax error reporting should be improved. Currently it is
+very sparse (template line numbers would be nice):
+
+ >>> Template().parse("[if-any where] foo [else] bar [end unexpected args]")
+ Traceback (innermost last):
+ File "", line 1, in ?
+ File "ezt.py", line 220, in parse
+ self.program = self._parse(text)
+ File "ezt.py", line 275, in _parse
+ raise ArgCountSyntaxError(str(args[1:]))
+ ArgCountSyntaxError: ['unexpected', 'args']
+ >>> Template().parse("[if unmatched_end]foo[end]")
+ Traceback (innermost last):
+ File "", line 1, in ?
+ File "ezt.py", line 206, in parse
+ self.program = self._parse(text)
+ File "ezt.py", line 266, in _parse
+ raise UnmatchedEndError()
+ UnmatchedEndError
+
+
+Directives
+==========
+
+ Several directives allow the use of dotted qualified names refering to objects
+ or attributes of objects contained in the data dictionary given to the
+ .generate() method.
+
+ Simple directives
+ -----------------
+
+ [QUAL_NAME]
+
+ This directive is simply replaced by the value of identifier from the data
+ dictionary. QUAL_NAME might be a dotted qualified name refering to some
+ instance attribute of objects contained in the dats dictionary.
+ Numbers are converted to string though.
+
+ [include "filename"] or [include QUAL_NAME]
+
+ This directive is replaced by content of the named include file.
+
+ Block directives
+ ----------------
+
+ [for QUAL_NAME] ... [end]
+
+ The text within the [for ...] directive and the corresponding [end]
+ is repeated for each element in the sequence referred to by the qualified
+ name in the for directive. Within the for block this identifiers now
+ refers to the actual item indexed by this loop iteration.
+
+ [if-any QUAL_NAME [QUAL_NAME2 ...]] ... [else] ... [end]
+
+ Test if any QUAL_NAME value is not None or an empty string or list.
+ The [else] clause is optional. CAUTION: Numeric values are converted to
+ string, so if QUAL_NAME refers to a numeric value 0, the then-clause is
+ substituted!
+
+ [if-index INDEX_FROM_FOR odd] ... [else] ... [end]
+ [if-index INDEX_FROM_FOR even] ... [else] ... [end]
+ [if-index INDEX_FROM_FOR first] ... [else] ... [end]
+ [if-index INDEX_FROM_FOR last] ... [else] ... [end]
+ [if-index INDEX_FROM_FOR NUMBER] ... [else] ... [end]
+
+ These five directives work similar to [if-any], but are only useful
+ within a [for ...]-block (see above). The odd/even directives are
+ for example useful to choose different background colors for adjacent rows
+ in a table. Similar the first/last directives might be used to
+ remove certain parts (for example "Diff to previous" doesn't make sense,
+ if there is no previous).
+
+ [is QUAL_NAME STRING] ... [else] ... [end]
+ [is QUAL_NAME QUAL_NAME] ... [else] ... [end]
+
+ The [is ...] directive is similar to the other conditional directives
+ above. But it allows to compare two value references or a value reference
+ with some constant string.
+
+"""
+#
+# Copyright (C) 2001-2002 Greg Stein. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#
+# This software is maintained by Greg and is available at:
+# http://viewcvs.sourceforge.net/
+# it is also used by the following projects:
+# http://edna.sourceforge.net/
+#
+
+import string
+import re
+from types import StringType, IntType, FloatType
+import os
+
+#
+# This regular expression matches three alternatives:
+# expr: DIRECTIVE | BRACKET | COMMENT
+# DIRECTIVE: '[' ITEM (whitespace ITEM)* ']
+# ITEM: STRING | NAME
+# STRING: '"' (not-slash-or-dquote | '\' anychar)* '"'
+# NAME: (alphanum | '_' | '-' | '.')+
+# BRACKET: '[[]'
+# COMMENT: '[#' not-rbracket* ']'
+#
+# When used with the split() method, the return value will be composed of
+# non-matching text and the two paren groups (DIRECTIVE and BRACKET). Since
+# the COMMENT matches are not placed into a group, they are considered a
+# "splitting" value and simply dropped.
+#
+_item = r'(?:"(?:[^\\"]|\\.)*"|[-\w.]+)'
+_re_parse = re.compile(r'\[(%s(?: +%s)*)\]|(\[\[\])|\[#[^\]]*\]' % (_item, _item))
+
+_re_args = re.compile(r'"(?:[^\\"]|\\.)*"|[-\w.]+')
+
+# block commands and their argument counts
+_block_cmd_specs = { 'if-index':2, 'for':1, 'is':2 }
+_block_cmds = _block_cmd_specs.keys()
+
+# two regular expresssions for compressing whitespace. the first is used to
+# compress any whitespace including a newline into a single newline. the
+# second regex is used to compress runs of whitespace into a single space.
+_re_newline = re.compile('[ \t\r\f\v]*\n\\s*')
+_re_whitespace = re.compile(r'\s\s+')
+
+# this regex is used to substitute arguments into a value. we split the value,
+# replace the relevant pieces, and then put it all back together. splitting
+# will produce a list of: TEXT ( splitter TEXT )*. splitter will be '%' or
+# an integer.
+_re_subst = re.compile('%(%|[0-9]+)')
+
+class Template:
+
+ def __init__(self, fname=None, compress_whitespace=1):
+ self.compress_whitespace = compress_whitespace
+ if fname:
+ self.parse_file(fname)
+
+ def parse_file(self, fname):
+ "fname -> a string object with pathname of file containg an EZT template."
+
+ self.program = self._parse(_FileReader(fname))
+
+ def parse(self, text_or_reader):
+ """Parse the template specified by text_or_reader.
+
+ The argument should be a string containing the template, or it should
+ specify a subclass of ezt.Reader which can read templates.
+ """
+ if not isinstance(text_or_reader, Reader):
+ # assume the argument is a plain text string
+ text_or_reader = _TextReader(text_or_reader)
+ self.program = self._parse(text_or_reader)
+
+ def generate(self, fp, data):
+ ctx = _context()
+ ctx.data = data
+ ctx.for_index = { }
+ self._execute(self.program, fp, ctx)
+
+ def _parse(self, reader, for_names=None, file_args=()):
+ """text -> string object containing the HTML template.
+
+ This is a private helper function doing the real work for method parse.
+ It returns the parsed template as a 'program'. This program is a sequence
+ made out of strings or (function, argument) 2-tuples.
+
+ Note: comment directives [# ...] are automatically dropped by _re_parse.
+ """
+
+ # parse the template program into: (TEXT DIRECTIVE BRACKET)* TEXT
+ parts = _re_parse.split(reader.text)
+
+ program = [ ]
+ stack = [ ]
+ if not for_names:
+ for_names = [ ]
+
+ for i in range(len(parts)):
+ piece = parts[i]
+ which = i % 3 # discriminate between: TEXT DIRECTIVE BRACKET
+ if which == 0:
+ # TEXT. append if non-empty.
+ if piece:
+ if self.compress_whitespace:
+ piece = _re_whitespace.sub(' ', _re_newline.sub('\n', piece))
+ program.append(piece)
+ elif which == 2:
+ # BRACKET directive. append '[' if present.
+ if piece:
+ program.append('[')
+ elif piece:
+ # DIRECTIVE is present.
+ args = _re_args.findall(piece)
+ cmd = args[0]
+ if cmd == 'else':
+ if len(args) > 1:
+ raise ArgCountSyntaxError(str(args[1:]))
+ ### check: don't allow for 'for' cmd
+ idx = stack[-1][1]
+ true_section = program[idx:]
+ del program[idx:]
+ stack[-1][3] = true_section
+ elif cmd == 'end':
+ if len(args) > 1:
+ raise ArgCountSyntaxError(str(args[1:]))
+ # note: true-section may be None
+ try:
+ cmd, idx, args, true_section = stack.pop()
+ except IndexError:
+ raise UnmatchedEndError()
+ else_section = program[idx:]
+ func = getattr(self, '_cmd_' + re.sub('-', '_', cmd))
+ program[idx:] = [ (func, (args, true_section, else_section)) ]
+ if cmd == 'for':
+ for_names.pop()
+ elif cmd in _block_cmds:
+ if len(args) > _block_cmd_specs[cmd] + 1:
+ raise ArgCountSyntaxError(str(args[1:]))
+ ### this assumes arg1 is always a ref
+ args[1] = _prepare_ref(args[1], for_names, file_args)
+
+ # handle arg2 for the 'is' command
+ if cmd == 'is':
+ args[2] = _prepare_ref(args[2], for_names, file_args)
+ elif cmd == 'for':
+ for_names.append(args[1][0])
+
+ # remember the cmd, current pos, args, and a section placeholder
+ stack.append([cmd, len(program), args[1:], None])
+ elif cmd == 'include':
+ if args[1][0] == '"':
+ include_filename = args[1][1:-1]
+ f_args = [ ]
+ for arg in args[2:]:
+ f_args.append(_prepare_ref(arg, for_names, file_args))
+ program.extend(self._parse(reader.read_other(include_filename),
+ for_names,
+ f_args))
+ else:
+ if len(args) != 2:
+ raise ArgCountSyntaxError(str(args))
+ program.append((self._cmd_include,
+ (_prepare_ref(args[1], for_names, file_args),
+ reader)))
+ elif cmd == 'if-any':
+ f_args = [ ]
+ for arg in args[1:]:
+ f_args.append(_prepare_ref(arg, for_names, file_args))
+ stack.append(['if-any', len(program), f_args, None])
+ else:
+ # implied PRINT command
+ if len(args) > 1:
+ f_args = [ ]
+ for arg in args:
+ f_args.append(_prepare_ref(arg, for_names, file_args))
+ program.append((self._cmd_format, (f_args[0], f_args[1:])))
+ else:
+ program.append((self._cmd_print,
+ _prepare_ref(args[0], for_names, file_args)))
+
+ if stack:
+ ### would be nice to say which blocks...
+ raise UnclosedBlocksError()
+ return program
+
+ def _execute(self, program, fp, ctx):
+ """This private helper function takes a 'program' sequence as created
+ by the method '_parse' and executes it step by step. strings are written
+ to the file object 'fp' and functions are called.
+ """
+ for step in program:
+ if isinstance(step, StringType):
+ fp.write(step)
+ else:
+ step[0](step[1], fp, ctx)
+
+ def _cmd_print(self, valref, fp, ctx):
+ value = _get_value(valref, ctx)
+
+ # if the value has a 'read' attribute, then it is a stream: copy it
+ if hasattr(value, 'read'):
+ while 1:
+ chunk = value.read(16384)
+ if not chunk:
+ break
+ fp.write(chunk)
+ else:
+ fp.write(value)
+
+ def _cmd_format(self, (valref, args), fp, ctx):
+ fmt = _get_value(valref, ctx)
+ parts = _re_subst.split(fmt)
+ for i in range(len(parts)):
+ piece = parts[i]
+ if i%2 == 1 and piece != '%':
+ idx = int(piece)
+ if idx < len(args):
+ piece = _get_value(args[idx], ctx)
+ else:
+ piece = ''
+ fp.write(piece)
+
+ def _cmd_include(self, (valref, reader), fp, ctx):
+ fname = _get_value(valref, ctx)
+ ### note: we don't have the set of for_names to pass into this parse.
+ ### I don't think there is anything to do but document it.
+ self._execute(self._parse(reader.read_other(fname)), fp, ctx)
+
+ def _cmd_if_any(self, args, fp, ctx):
+ "If any value is a non-empty string or non-empty list, then T else F."
+ (valrefs, t_section, f_section) = args
+ value = 0
+ for valref in valrefs:
+ if _get_value(valref, ctx):
+ value = 1
+ break
+ self._do_if(value, t_section, f_section, fp, ctx)
+
+ def _cmd_if_index(self, args, fp, ctx):
+ ((valref, value), t_section, f_section) = args
+ list, idx = ctx.for_index[valref[0]]
+ if value == 'even':
+ value = idx % 2 == 0
+ elif value == 'odd':
+ value = idx % 2 == 1
+ elif value == 'first':
+ value = idx == 0
+ elif value == 'last':
+ value = idx == len(list)-1
+ else:
+ value = idx == int(value)
+ self._do_if(value, t_section, f_section, fp, ctx)
+
+ def _cmd_is(self, args, fp, ctx):
+ ((left_ref, right_ref), t_section, f_section) = args
+ value = _get_value(right_ref, ctx)
+ value = string.lower(_get_value(left_ref, ctx)) == string.lower(value)
+ self._do_if(value, t_section, f_section, fp, ctx)
+
+ def _do_if(self, value, t_section, f_section, fp, ctx):
+ if t_section is None:
+ t_section = f_section
+ f_section = None
+ if value:
+ section = t_section
+ else:
+ section = f_section
+ if section is not None:
+ self._execute(section, fp, ctx)
+
+ def _cmd_for(self, args, fp, ctx):
+ ((valref,), unused, section) = args
+ list = _get_value(valref, ctx)
+ if isinstance(list, StringType):
+ raise NeedSequenceError()
+ refname = valref[0]
+ ctx.for_index[refname] = idx = [ list, 0 ]
+ for item in list:
+ self._execute(section, fp, ctx)
+ idx[1] = idx[1] + 1
+ del ctx.for_index[refname]
+
+def boolean(value):
+ "Return a value suitable for [if-any bool_var] usage in a template."
+ if value:
+ return 'yes'
+ return None
+
+
+def _prepare_ref(refname, for_names, file_args):
+ """refname -> a string containing a dotted identifier. example:"foo.bar.bang"
+ for_names -> a list of active for sequences.
+
+ Returns a `value reference', a 3-Tupel made out of (refname, start, rest),
+ for fast access later.
+ """
+ # is the reference a string constant?
+ if refname[0] == '"':
+ return None, refname[1:-1], None
+
+ # if this is an include-argument, then just return the prepared ref
+ if refname[:3] == 'arg':
+ try:
+ idx = int(refname[3:])
+ except ValueError:
+ pass
+ else:
+ if idx < len(file_args):
+ return file_args[idx]
+
+ parts = string.split(refname, '.')
+ start = parts[0]
+ rest = parts[1:]
+ while rest and (start in for_names):
+ # check if the next part is also a "for name"
+ name = start + '.' + rest[0]
+ if name in for_names:
+ start = name
+ del rest[0]
+ else:
+ break
+ return refname, start, rest
+
+def _get_value((refname, start, rest), ctx):
+ """(refname, start, rest) -> a prepared `value reference' (see above).
+ ctx -> an execution context instance.
+
+ Does a name space lookup within the template name space. Active
+ for blocks take precedence over data dictionary members with the
+ same name.
+ """
+ if rest is None:
+ # it was a string constant
+ return start
+ if ctx.for_index.has_key(start):
+ list, idx = ctx.for_index[start]
+ ob = list[idx]
+ elif ctx.data.has_key(start):
+ ob = ctx.data[start]
+ else:
+ raise UnknownReference(refname)
+
+ # walk the rest of the dotted reference
+ for attr in rest:
+ try:
+ ob = getattr(ob, attr)
+ except AttributeError:
+ raise UnknownReference(refname)
+
+ # make sure we return a string instead of some various Python types
+ if isinstance(ob, IntType) or isinstance(ob, FloatType):
+ return str(ob)
+ if ob is None:
+ return ''
+
+ # string or a sequence
+ return ob
+
+
+class _context:
+ """A container for the execution context"""
+
+
+class Reader:
+ "Abstract class which allows EZT to detect Reader objects."
+
+class _FileReader(Reader):
+ """Reads templates from the filesystem."""
+ def __init__(self, fname):
+ self.text = open(fname, 'rb').read()
+ self._dir = os.path.dirname(fname)
+ def read_other(self, relative):
+ return _FileReader(os.path.join(self._dir, relative))
+
+class _TextReader(Reader):
+ """'Reads' a template from provided text."""
+ def __init__(self, text):
+ self.text = text
+ def read_other(self, relative):
+ raise BaseUnavailableError()
+
+
+class EZTException(Exception):
+ """Parent class of all EZT exceptions."""
+
+class ArgCountSyntaxError(EZTException):
+ """A bracket directive got the wrong number of arguments."""
+
+class UnknownReference(EZTException):
+ """The template references an object not contained in the data dictionary."""
+
+class NeedSequenceError(EZTException):
+ """The object dereferenced by the template is no sequence (tuple or list)."""
+
+class UnclosedBlocksError(EZTException):
+ """This error may be simply a missing [end]."""
+
+class UnmatchedEndError(EZTException):
+ """This error may be caused by a misspelled if directive."""
+
+class BaseUnavailableError(EZTException):
+ """Base location is unavailable, which disables includes."""
+
+
+# --- standard test environment ---
+def test_parse():
+ assert _re_parse.split('[a]') == ['', '[a]', None, '']
+ assert _re_parse.split('[a] [b]') == \
+ ['', '[a]', None, ' ', '[b]', None, '']
+ assert _re_parse.split('[a c] [b]') == \
+ ['', '[a c]', None, ' ', '[b]', None, '']
+ assert _re_parse.split('x [a] y [b] z') == \
+ ['x ', '[a]', None, ' y ', '[b]', None, ' z']
+ assert _re_parse.split('[a "b" c "d"]') == \
+ ['', '[a "b" c "d"]', None, '']
+ assert _re_parse.split(r'["a \"b[foo]" c.d f]') == \
+ ['', '["a \\"b[foo]" c.d f]', None, '']
+
+def _test(argv):
+ import doctest, ezt
+ verbose = "-v" in argv
+ return doctest.testmod(ezt, verbose=verbose)
+
+if __name__ == "__main__":
+ # invoke unit test for this module:
+ import sys
+ sys.exit(_test(sys.argv)[0])
Index: build/gen-build.py
===================================================================
--- build/gen-build.py (revision 109892)
+++ build/gen-build.py (working copy)
@@ -16,7 +16,7 @@
import glob
import re
-#import ezt
+import ezt
#
# legal platforms: aix, beos, netware, os2, os390, unix, win32
@@ -33,11 +33,15 @@
# note: MAKE_PLATFORMS is an ordered set. we want to generate unix symbols
# first, so that the later platforms can reference them.
-
def main():
parser = ConfigParser.ConfigParser()
parser.read('build.conf')
+ do_make_platforms(parser)
+
+ do_windows(parser)
+
+def do_make_platforms(parser):
headers = get_files(parser.get('options', 'headers'))
# compute the relevant headers, along with the implied includes
@@ -112,7 +116,83 @@
'\t@for d in $(BUILD_DIRS); do test -d $$d || mkdir $$d; done\n' \
'\t@echo timestamp > $@\n')
+def win32ify_paths(paths):
+ return map(lambda x: '.\\' + string.replace(x, '/', '\\'), paths)
+def do_windows(parser):
+ subdirs = []
+
+ for subdir in string.split(parser.get('options', 'platform_dirs')):
+ path = os.path.join(subdir, 'win32')
+
+ if not os.path.exists(path):
+ subdirs.append('%s/%s' % (subdir, 'unix'))
+ else:
+ subdirs.append(path)
+
+ files = get_files(parser.get('options', 'paths'))
+
+ for s in subdirs:
+ for file in get_files(s + '/*.c'):
+ files.append(file)
+
+ public_headers = []
+
+ for h in get_files(parser.get('options', 'headers')):
+ public_headers.append(h)
+
+ private_headers = get_files('include/arch/win32/*.h')
+
+ for file in get_files('include/arch/*.h'):
+ private_headers.append(file)
+
+ for file in string.split(parser.get('win32-fixups', 'add-files')):
+ files.append(file)
+
+ for file in string.split(parser.get('win32-fixups', 'remove-files')):
+ files.remove(file)
+
+ for file in string.split(parser.get('win32-fixups', 'remove-headers')):
+ public_headers.remove(file)
+
+ # sort everything so we can easily compare two versions of the dsp files
+ files.sort()
+ public_headers.sort()
+ private_headers.sort()
+
+ # finally convert to win32 style paths before writing them out
+ public_headers = win32ify_paths(public_headers)
+ private_headers = win32ify_paths(private_headers)
+ files = win32ify_paths(files)
+
+ # dump into dsp.ezt
+ data = {
+ 'project_name' : 'apr',
+ 'project_version' : '1',
+ 'source_files' : files,
+ 'public_headers' : public_headers,
+ 'private_headers' : private_headers,
+ 'output_dir' : 'LibR',
+ 'debug_output_dir' : 'LibD',
+ 'intermediate_dir' : 'LibR',
+ 'debug_intermediate_dir' : 'LibD',
+ 'is_dll' : ezt.boolean(0),
+ }
+
+ template = ezt.Template(compress_whitespace = 0)
+ template.parse_file('build/dsp.ezt')
+
+ template.generate(open('apr.dsp', 'wb'), data)
+
+ data['project_name'] = 'libapr'
+ data['output_dir'] = 'Release'
+ data['intermediate_dir'] = 'Release'
+ data['debug_output_dir'] = 'Debug'
+ data['debug_intermediate_dir'] = 'Debug'
+ data['is_dll'] = ezt.boolean(1)
+
+ template.generate(open('libapr.dsp', 'wb'), data)
+
def write_objects(f, legal_deps, h_deps, files):
dirs = { }
objects = [ ]
Index: build/dsp.ezt
===================================================================
--- build/dsp.ezt (revision 0)
+++ build/dsp.ezt (revision 0)
@@ -0,0 +1,194 @@
+# Microsoft Developer Studio Project File - Name="[project_name]" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE [if-any is_dll]"Win32 (x86) Dynamic-Link Library" 0x0102[else]"Win32 (x86) Static Library" 0x0104[end]
+
+CFG=[project_name] - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "[project_name].mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "[project_name].mak" CFG="[project_name] - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "[project_name] - Win32 Release" (based on "Win32 (x86) [if-any is_dll]Dynamic-Link[else]Static[end] Library")
+!MESSAGE "[project_name] - Win32 Debug" (based on "Win32 (x86) [if-any is_dll]Dynamic-Link[else]Static[end] Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe[if-any is_dll]
+MTL=midl.exe[end]
+RSC=rc.exe
+
+!IF "$(CFG)" == "[project_name] - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "[output_dir]"
+# PROP BASE Intermediate_Dir "[intermediate_dir]"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "[output_dir]"
+# PROP Intermediate_Dir "[intermediate_dir]"[if-any is_dll]
+# PROP Ignore_Export_Lib 0[end]
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /Zi /O2 /I "./include" /I "./include/arch" /I "./include/arch/win32" /I "./include/arch/unix" /D "NDEBUG" /D "[if-any is_dll]APR_DECLARE_EXPORT[else]APR_DECLARE_STATIC[end]" /D "WIN32" /D "_WINDOWS" /Fd"[output_dir]\[project_name]_src" /FD /c[if-any is_dll]
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"[end]
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo[if-any is_dll]
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib advapi32.lib ws2_32.lib mswsock.lib ole32.lib shell32.lib rpcrt4.lib /nologo /base:"0x6EEC0000" /subsystem:windows /dll /incremental:no /debug /machine:I386 /opt:ref
+# ADD LINK32 kernel32.lib advapi32.lib ws2_32.lib mswsock.lib ole32.lib shell32.lib rpcrt4.lib /nologo /base:"0x6EEC0000" /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/[project_name]-[project_version].dll" /opt:ref[else]
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"[output_dir]\[project_name]-[project_version].lib"[end]
+
+!ELSEIF "$(CFG)" == "[project_name] - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "[debug_output_dir]"
+# PROP BASE Intermediate_Dir "[debug_intermediate_dir]"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "[debug_output_dir]"
+# PROP Intermediate_Dir "[debug_intermediate_dir]"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c[if-any is_dll]
+# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "./include" /I "./include/arch" /I "./include/arch/win32" /I "./include/arch/unix" /D "_DEBUG" /D "APR_DECLARE_EXPORT" /D "WIN32" /D "_WINDOWS" /Fd"[debug_output_dir]\[project_name]_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"[else]
+# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "./include" /I "./include/arch" /I "./include/arch/win32" /I "./include/arch/unix" /D "_DEBUG" /D "APR_DECLARE_STATIC" /D "WIN32" /D "_WINDOWS" /Fd"[debug_output_dir]\[project_name]_src" /FD /c[end]
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo[if-any is_dll]
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib advapi32.lib ws2_32.lib mswsock.lib ole32.lib shell32.lib rpcrt4.lib /nologo /base:"0x6EEC0000" /subsystem:windows /dll /incremental:no /debug /machine:I386
+# ADD LINK32 kernel32.lib advapi32.lib ws2_32.lib mswsock.lib ole32.lib shell32.lib rpcrt4.lib /nologo /base:"0x6EEC0000" /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"[debug_output_dir]/[project_name]-[project_version].dll"[else]
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"[debug_output_dir]\[project_name]-[project_version].lib"[end]
+
+!ENDIF
+
+# Begin Target
+
+# Name "[project_name] - Win32 Release"
+# Name "[project_name] - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter ".c"
+[for source_files]# Begin Source File
+
+SOURCE=[source_files]
+# End Source File
+[end]# End Group
+# Begin Group "Private Header Files"
+
+# PROP Default_Filter ""
+[for private_headers]# Begin Source File
+
+SOURCE=[private_headers]
+# End Source File
+[end]# End Group
+# Begin Group "Public Header Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\include\apr.h.in
+# PROP Exclude_From_Build 1
+# End Source File
+# Begin Source File
+
+SOURCE=.\include\apr.hnw
+# PROP Exclude_From_Build 1
+# End Source File
+# Begin Source File
+
+SOURCE=.\include\apr.hw
+
+!IF "$(CFG)" == "[project_name] - Win32 Release"
+
+# Begin Custom Build - Creating apr.h from apr.hw
+InputPath=.\include\apr.hw
+
+".\include\apr.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ type .\include\apr.hw > .\include\apr.h
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "[project_name] - Win32 Debug"
+
+# Begin Custom Build - Creating apr.h from apr.hw
+InputPath=.\include\apr.hw
+
+".\include\apr.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ type .\include\apr.hw > .\include\apr.h
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+[for public_headers]# Begin Source File
+
+SOURCE=[public_headers]
+# End Source File
+[end]# End Group
+[if-any is_dll]# Begin Source File
+
+SOURCE=.\libapr.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\build\win32ver.awk
+
+!IF "$(CFG)" == "[project_name] - Win32 Release"
+
+# PROP Ignore_Default_Tool 1
+USERDEP__WIN32="./include/apr_version.h"
+# Begin Custom Build - Creating Version Resource
+InputPath=.\build\win32ver.awk
+
+".\libapr.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ awk -f ./build/win32ver.awk libapr.dll "Apache Portability Runtime Library" ./include/apr_version.h > .\libapr.rc
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "[project_name] - Win32 Debug"
+
+# PROP Ignore_Default_Tool 1
+USERDEP__WIN32="./include/apr_version.h"
+# Begin Custom Build - Creating Version Resource
+InputPath=.\build\win32ver.awk
+
+".\libapr.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ awk -f ./build/win32ver.awk libapr.dll "Apache Portability Runtime Library" ./include/apr_version.h > .\libapr.rc
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File[end]
+# End Target
+# End Project