bgenOutput.py :  » Language-Interface » ChinesePython » chinesepython2.1.3-0.4 » Tools » bgen » bgen » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Language Interface » ChinesePython 
ChinesePython » chinesepython2.1.3 0.4 » Tools » bgen » bgen » bgenOutput.py
"""Output primitives for the binding generator classes.

This should really be a class, but then everybody would be passing
the output object to each other.  I chose for the simpler approach
of a module with a global variable.  Use SetOutputFile() or
SetOutputFileName() to change the output file.
"""

_NeedClose = 0

def SetOutputFile(file = None, needclose = 0):
  """Call this with an open file object to make it the output file.

  Call it without arguments to close the current file (if necessary)
  and reset it to sys.stdout.
  If the second argument is true, the new file will be explicitly closed
  on a subsequence call.
  """
  global _File, _NeedClose
  if _NeedClose:
    tmp = _File
    _NeedClose = 0
    _File = None
    tmp.close()
  if file is None:
    import sys
    file = sys.stdout
  _File = file
  _NeedClose = file and needclose

def SetOutputFileName(filename = None):
  """Call this with a filename to make it the output file.
  
  Call it without arguments to close the current file (if necessary)
  and reset it to sys.stdout.
  """
  SetOutputFile()
  if filename:
    SetOutputFile(open(filename, 'w'), 1)

SetOutputFile()  # Initialize _File

_Level = 0    # Indentation level

def GetLevel():
  """"Return the current indentation level."""
  return _Level

def SetLevel(level):
  """Set the current indentation level.

  This does no type or range checking -- use at own risk.
  """
  global _Level
  _Level = level

def Output(format = "", *args):
  VaOutput(format, args)

def VaOutput(format, args):
  """Call this with a format string and and argument tuple for the format.

  A newline is always added.  Each line in the output is indented
  to the proper indentation level -- even if the result of the
  format expansion contains embedded newlines.  Exception: lines
  beginning with '#' are not indented -- these are assumed to be
  C preprprocessor lines.
  """
  text = format % args
  if _Level > 0:
    indent = '\t' * _Level
    import string
    lines = string.splitfields(text, '\n')
    for i in range(len(lines)):
      if lines[i] and lines[i][0] != '#':
        lines[i] = indent + lines[i]
    text = string.joinfields(lines, '\n')
  _File.write(text + '\n')

def IndentLevel(by = 1):
  """Increment the indentation level by one.

  When called with an argument, adds it to the indentation level.
  """
  global _Level
  if _Level+by < 0:
    raise Error, "indentation underflow (internal error)"
  _Level = _Level + by

def DedentLevel(by = 1):
  """Decrement the indentation level by one.

  When called with an argument, subtracts it from the indentation level.
  """
  IndentLevel(-by)

def OutIndent(format = "", *args):
  """Combine Output() followed by IndentLevel().
  
  If no text is given, acts like lone IndentLevel().
  """
  if format: VaOutput(format, args)
  IndentLevel()

def OutDedent(format = "", *args):
  """Combine Output() followed by DedentLevel().
  
  If no text is given, acts like loneDedentLevel().
  """
  if format: VaOutput(format, args)
  DedentLevel()

def OutLbrace(format = "", *args):
  """Like Output, but add a '{' and increase the indentation level.
  
  If no text is given a lone '{' is output.
  """
  if format:
    format = format + " {"
  else:
    format = "{"
  VaOutput(format, args)
  IndentLevel()

def OutRbrace():
  """Decrease the indentation level and output a '}' on a line by itself."""
  DedentLevel()
  Output("}")

def OutHeader(text, dash):
  """Output a header comment using a given dash character."""
  n = 64 - len(text)
  Output()
  Output("/* %s %s %s */", dash * (n/2), text, dash * (n - n/2))
  Output()

def OutHeader1(text):
  """Output a level 1 header comment (uses '=' dashes)."""
  OutHeader(text, "=")

def OutHeader2(text):
  """Output a level 2 header comment (uses '-' dashes)."""
  OutHeader(text, "-")

def Out(text):
  """Output multiline text that's internally indented.
  
  Pass this a multiline character string.  The whitespace before the
  first nonblank line of the string will be subtracted from all lines.
  The lines are then output using Output(), but without interpretation
  of formatting (if you need formatting you can do it before the call).
  Recommended use:
  
    Out('''
      int main(argc, argv)
        int argc;
        char *argv;
      {
        printf("Hello, world\\n");
        exit(0);
      }
    ''')
  
  Caveat: the indentation must be consistent -- if you use three tabs
  in the first line, (up to) three tabs are removed from following lines,
  but a line beginning with 24 spaces is not trimmed at all.  Don't use
  this as a feature.
  """
  # (Don't you love using triple quotes *inside* triple quotes? :-)
  
  import string
  lines = string.splitfields(text, '\n')
  indent = ""
  for line in lines:
    if string.strip(line):
      for c in line:
        if c not in string.whitespace:
          break
        indent = indent + c
      break
  n = len(indent)
  for line in lines:
    if line[:n] == indent:
      line = line[n:]
    else:
      for c in indent:
        if line[:1] <> c: break
        line = line[1:]
    VaOutput("%s", line)


def _test():
  """Test program.  Run when the module is run as a script."""
  OutHeader1("test bgenOutput")
  Out("""
    #include <Python.h>
    #include <stdio.h>
  
    main(argc, argv)
      int argc;
      char **argv;
    {
      int i;
  """)
  IndentLevel()
  Output("""\
/* Here are a few comment lines.
   Just to test indenting multiple lines.

   End of the comment lines. */
""")
  Output("for (i = 0; i < argc; i++)")
  OutLbrace()
  Output('printf("argv[%%d] = %%s\\n", i, argv[i]);')
  OutRbrace()
  Output("exit(0)")
  OutRbrace()
  OutHeader2("end test")

if __name__ == '__main__':
  _test()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.