#!/usr/bin/env python2.7
#
# Copyright 2008, Google Inc.
# 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.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# 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 COPYRIGHT
# OWNER 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.

"""pump v0.2.0 - Pretty Useful for Meta Programming.

A tool for preprocessor meta programming.  Useful for generating
repetitive boilerplate code.  Especially useful for writing C++
classes, functions, macros, and templates that need to work with
various number of arguments.

USAGE:
       pump.py SOURCE_FILE

EXAMPLES:
       pump.py foo.cc.pump
         Converts foo.cc.pump to foo.cc.

GRAMMAR:
       CODE ::= ATOMIC_CODE*
       ATOMIC_CODE ::= $var ID = EXPRESSION
           | $var ID = [[ CODE ]]
           | $range ID EXPRESSION..EXPRESSION
           | $for ID SEPARATOR [[ CODE ]]
           | $($)
           | $ID
           | $(EXPRESSION)
           | $if EXPRESSION [[ CODE ]] ELSE_BRANCH
           | [[ CODE ]]
           | RAW_CODE
       SEPARATOR ::= RAW_CODE | EMPTY
       ELSE_BRANCH ::= $else [[ CODE ]]
           | $elif EXPRESSION [[ CODE ]] ELSE_BRANCH
           | EMPTY
       EXPRESSION has Python syntax.
"""

from __future__ import print_function

import os
import re
import sys


TOKEN_TABLE = [
    (re.compile(r'\$var\s+'), '$var'),
    (re.compile(r'\$elif\s+'), '$elif'),
    (re.compile(r'\$else\s+'), '$else'),
    (re.compile(r'\$for\s+'), '$for'),
    (re.compile(r'\$if\s+'), '$if'),
    (re.compile(r'\$range\s+'), '$range'),
    (re.compile(r'\$[_A-Za-z]\w*'), '$id'),
    (re.compile(r'\$\(\$\)'), '$($)'),
    (re.compile(r'\$'), '$'),
    (re.compile(r'\[\[\n?'), '[['),
    (re.compile(r'\]\]\n?'), ']]'),
    ]


class Cursor:
  """Represents a position (line and column) in a text file."""

  def __init__(self, line=-1, column=-1):
    self.line = line
    self.column = column

  def __eq__(self, rhs):
    return self.line == rhs.line and self.column == rhs.column

  def __ne__(self, rhs):
    return not self == rhs

  def __lt__(self, rhs):
    return self.line < rhs.line or (
        self.line == rhs.line and self.column < rhs.column)

  def __le__(self, rhs):
    return self < rhs or self == rhs

  def __gt__(self, rhs):
    return rhs < self

  def __ge__(self, rhs):
    return rhs <= self

  def __str__(self):
    if self == Eof():
      return 'EOF'
    else:
      return '%s(%s)' % (self.line + 1, self.column)

  def __add__(self, offset):
    return Cursor(self.line, self.column + offset)

  def __sub__(self, offset):
    return Cursor(self.line, self.column - offset)

  def Clone(self):
    """Returns a copy of self."""

    return Cursor(self.line, self.column)


# Special cursor to indicate the end-of-file.
def Eof():
  """Returns the special cursor to denote the end-of-file."""
  return Cursor(-1, -1)


class Token:
  """Represents a token in a Pump source file."""

  def __init__(self, start=None, end=None, value=None, token_type=None):
    if start is None:
      self.start = Eof()
    else:
      self.start = start
    if end is None:
      self.end = Eof()
    else:
      self.end = end
    self.value = value
    self.token_type = token_type

  def __str__(self):
    return 'Token @%s: \'%s\' type=%s' % (
        self.start, self.value, self.token_type)

  def Clone(self):
    """Returns a copy of self."""

    return Token(self.start.Clone(), self.end.Clone(), self.value,
                 self.token_type)


def StartsWith(lines, pos, string):
  """Returns True iff the given position in lines starts with 'string'."""

  return lines[pos.line][pos.column:].startswith(string)


def FindFirstInLine(line, token_table):
  best_match_start = -1
  for (regex, token_type) in token_table:
    m = regex.search(line)
    if m:
      # We found regex in lines
      if best_match_start < 0 or m.start() < best_match_start:
        best_match_start = m.start()
        best_match_length = m.end() - m.start()
        best_match_token_type = token_type

  if best_match_start < 0:
    return None

  return (best_match_start, best_match_length, best_match_token_type)


def FindFirst(lines, token_table, cursor):
  """Finds the first occurrence of any string in strings in lines."""

  start = cursor.Clone()
  cur_line_number = cursor.line
  for line in lines[start.line:]:
    if cur_line_number == start.line:
      line = line[start.column:]
    m = FindFirstInLine(line, token_table)
    if m:
      # We found a regex in line.
      (start_column, length, token_type) = m
      if cur_line_number == start.line:
        start_column += start.column
      found_start = Cursor(cur_line_number, start_column)
      found_end = found_start + length
      return MakeToken(lines, found_start, found_end, token_type)
    cur_line_number += 1
  # We failed to find str in lines
  return None


def SubString(lines, start, end):
  """Returns a substring in lines."""

  if end == Eof():
    end = Cursor(len(lines) - 1, len(lines[-1]))

  if start >= end:
    return ''

  if start.line == end.line:
    return lines[start.line][start.column:end.column]

  result_lines = ([lines[start.line][start.column:]] +
                  lines[start.line + 1:end.line] +
                  [lines[end.line][:end.column]])
  return ''.join(result_lines)


def StripMetaComments(str):
  """Strip meta comments from each line in the given string."""

  # First, completely remove lines containing nothing but a meta
  # comment, including the trailing \n.
  str = re.sub(r'^\s*\$\$.*\n', '', str)

  # Then, remove meta comments from contentful lines.
  return re.sub(r'\s*\$\$.*', '', str)


def MakeToken(lines, start, end, token_type):
  """Creates a new instance of Token."""

  return Token(start, end, SubString(lines, start, end), token_type)


def ParseToken(lines, pos, regex, token_type):
  line = lines[pos.line][pos.column:]
  m = regex.search(line)
  if m and not m.start():
    return MakeToken(lines, pos, pos + m.end(), token_type)
  else:
    print('ERROR: %s expected at %s.' % (token_type, pos))
    sys.exit(1)


ID_REGEX = re.compile(r'[_A-Za-z]\w*')
EQ_REGEX = re.compile(r'=')
REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)')
OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*')
WHITE_SPACE_REGEX = re.compile(r'\s')
DOT_DOT_REGEX = re.compile(r'\.\.')


def Skip(lines, pos, regex):
  line = lines[pos.line][pos.column:]
  m = re.search(regex, line)
  if m and not m.start():
    return pos + m.end()
  else:
    return pos


def SkipUntil(lines, pos, regex, token_type):
  line = lines[pos.line][pos.column:]
  m = re.search(regex, line)
  if m:
    return pos + m.start()
  else:
    print ('ERROR: %s expected on line %s after column %s.' %
           (token_type, pos.line + 1, pos.column))
    sys.exit(1)


def ParseExpTokenInParens(lines, pos):
  def ParseInParens(pos):
    pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX)
    pos = Skip(lines, pos, r'\(')
    pos = Parse(pos)
    pos = Skip(lines, pos, r'\)')
    return pos

  def Parse(pos):
    pos = SkipUntil(lines, pos, r'\(|\)', ')')
    if SubString(lines, pos, pos + 1) == '(':
      pos = Parse(pos + 1)
      pos = Skip(lines, pos, r'\)')
      return Parse(pos)
    else:
      return pos

  start = pos.Clone()
  pos = ParseInParens(pos)
  return MakeToken(lines, start, pos, 'exp')


def RStripNewLineFromToken(token):
  if token.value.endswith('\n'):
    return Token(token.start, token.end, token.value[:-1], token.token_type)
  else:
    return token


def TokenizeLines(lines, pos):
  while True:
    found = FindFirst(lines, TOKEN_TABLE, pos)
    if not found:
      yield MakeToken(lines, pos, Eof(), 'code')
      return

    if found.start == pos:
      prev_token = None
      prev_token_rstripped = None
    else:
      prev_token = MakeToken(lines, pos, found.start, 'code')
      prev_token_rstripped = RStripNewLineFromToken(prev_token)

    if found.token_type == '$var':
      if prev_token_rstripped:
        yield prev_token_rstripped
      yield found
      id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
      yield id_token
      pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)

      eq_token = ParseToken(lines, pos, EQ_REGEX, '=')
      yield eq_token
      pos = Skip(lines, eq_token.end, r'\s*')

      if SubString(lines, pos, pos + 2) != '[[':
        exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp')
        yield exp_token
        pos = Cursor(exp_token.end.line + 1, 0)
    elif found.token_type == '$for':
      if prev_token_rstripped:
        yield prev_token_rstripped
      yield found
      id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
      yield id_token
      pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX)
    elif found.token_type == '$range':
      if prev_token_rstripped:
        yield prev_token_rstripped
      yield found
      id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
      yield id_token
      pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)

      dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..')
      yield MakeToken(lines, pos, dots_pos, 'exp')
      yield MakeToken(lines, dots_pos, dots_pos + 2, '..')
      pos = dots_pos + 2
      new_pos = Cursor(pos.line + 1, 0)
      yield MakeToken(lines, pos, new_pos, 'exp')
      pos = new_pos
    elif found.token_type == '$':
      if prev_token:
        yield prev_token
      yield found
      exp_token = ParseExpTokenInParens(lines, found.end)
      yield exp_token
      pos = exp_token.end
    elif (found.token_type == ']]' or found.token_type == '$if' or
          found.token_type == '$elif' or found.token_type == '$else'):
      if prev_token_rstripped:
        yield prev_token_rstripped
      yield found
      pos = found.end
    else:
      if prev_token:
        yield prev_token
      yield found
      pos = found.end


def Tokenize(s):
  """A generator that yields the tokens in the given string."""
  if s != '':
    lines = s.splitlines(True)
    for token in TokenizeLines(lines, Cursor(0, 0)):
      yield token


class CodeNode:
  def __init__(self, atomic_code_list=None):
    self.atomic_code = atomic_code_list


class VarNode:
  def __init__(self, identifier=None, atomic_code=None):
    self.identifier = identifier
    self.atomic_code = atomic_code


class RangeNode:
  def __init__(self, identifier=None, exp1=None, exp2=None):
    self.identifier = identifier
    self.exp1 = exp1
    self.exp2 = exp2


class ForNode:
  def __init__(self, identifier=None, sep=None, code=None):
    self.identifier = identifier
    self.sep = sep
    self.code = code


class ElseNode:
  def __init__(self, else_branch=None):
    self.else_branch = else_branch


class IfNode:
  def __init__(self, exp=None, then_branch=None, else_branch=None):
    self.exp = exp
    self.then_branch = then_branch
    self.else_branch = else_branch


class RawCodeNode:
  def __init__(self, token=None):
    self.raw_code = token


class LiteralDollarNode:
  def __init__(self, token):
    self.token = token


class ExpNode:
  def __init__(self, token, python_exp):
    self.token = token
    self.python_exp = python_exp


def PopFront(a_list):
  head = a_list[0]
  a_list[:1] = []
  return head


def PushFront(a_list, elem):
  a_list[:0] = [elem]


def PopToken(a_list, token_type=None):
  token = PopFront(a_list)
  if token_type is not None and token.token_type != token_type:
    print('ERROR: %s expected at %s' % (token_type, token.start))
    print('ERROR: %s found instead' % (token,))
    sys.exit(1)

  return token


def PeekToken(a_list):
  if not a_list:
    return None

  return a_list[0]


def ParseExpNode(token):
  python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value)
  return ExpNode(token, python_exp)


def ParseElseNode(tokens):
  def Pop(token_type=None):
    return PopToken(tokens, token_type)

  next = PeekToken(tokens)
  if not next:
    return None
  if next.token_type == '$else':
    Pop('$else')
    Pop('[[')
    code_node = ParseCodeNode(tokens)
    Pop(']]')
    return code_node
  elif next.token_type == '$elif':
    Pop('$elif')
    exp = Pop('code')
    Pop('[[')
    code_node = ParseCodeNode(tokens)
    Pop(']]')
    inner_else_node = ParseElseNode(tokens)
    return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)])
  elif not next.value.strip():
    Pop('code')
    return ParseElseNode(tokens)
  else:
    return None


def ParseAtomicCodeNode(tokens):
  def Pop(token_type=None):
    return PopToken(tokens, token_type)

  head = PopFront(tokens)
  t = head.token_type
  if t == 'code':
    return RawCodeNode(head)
  elif t == '$var':
    id_token = Pop('id')
    Pop('=')
    next = PeekToken(tokens)
    if next.token_type == 'exp':
      exp_token = Pop()
      return VarNode(id_token, ParseExpNode(exp_token))
    Pop('[[')
    code_node = ParseCodeNode(tokens)
    Pop(']]')
    return VarNode(id_token, code_node)
  elif t == '$for':
    id_token = Pop('id')
    next_token = PeekToken(tokens)
    if next_token.token_type == 'code':
      sep_token = next_token
      Pop('code')
    else:
      sep_token = None
    Pop('[[')
    code_node = ParseCodeNode(tokens)
    Pop(']]')
    return ForNode(id_token, sep_token, code_node)
  elif t == '$if':
    exp_token = Pop('code')
    Pop('[[')
    code_node = ParseCodeNode(tokens)
    Pop(']]')
    else_node = ParseElseNode(tokens)
    return IfNode(ParseExpNode(exp_token), code_node, else_node)
  elif t == '$range':
    id_token = Pop('id')
    exp1_token = Pop('exp')
    Pop('..')
    exp2_token = Pop('exp')
    return RangeNode(id_token, ParseExpNode(exp1_token),
                     ParseExpNode(exp2_token))
  elif t == '$id':
    return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id'))
  elif t == '$($)':
    return LiteralDollarNode(head)
  elif t == '$':
    exp_token = Pop('exp')
    return ParseExpNode(exp_token)
  elif t == '[[':
    code_node = ParseCodeNode(tokens)
    Pop(']]')
    return code_node
  else:
    PushFront(tokens, head)
    return None


def ParseCodeNode(tokens):
  atomic_code_list = []
  while True:
    if not tokens:
      break
    atomic_code_node = ParseAtomicCodeNode(tokens)
    if atomic_code_node:
      atomic_code_list.append(atomic_code_node)
    else:
      break
  return CodeNode(atomic_code_list)


def ParseToAST(pump_src_text):
  """Convert the given Pump source text into an AST."""
  tokens = list(Tokenize(pump_src_text))
  code_node = ParseCodeNode(tokens)
  return code_node


class Env:
  def __init__(self):
    self.variables = []
    self.ranges = []

  def Clone(self):
    clone = Env()
    clone.variables = self.variables[:]
    clone.ranges = self.ranges[:]
    return clone

  def PushVariable(self, var, value):
    # If value looks like an int, store it as an int.
    try:
      int_value = int(value)
      if ('%s' % int_value) == value:
        value = int_value
    except Exception:
      pass
    self.variables[:0] = [(var, value)]

  def PopVariable(self):
    self.variables[:1] = []

  def PushRange(self, var, lower, upper):
    self.ranges[:0] = [(var, lower, upper)]

  def PopRange(self):
    self.ranges[:1] = []

  def GetValue(self, identifier):
    for (var, value) in self.variables:
      if identifier == var:
        return value

    print('ERROR: meta variable %s is undefined.' % (identifier,))
    sys.exit(1)

  def EvalExp(self, exp):
    try:
      result = eval(exp.python_exp)
    except Exception as e:  # pylint: disable=broad-except
      print('ERROR: caught exception %s: %s' % (e.__class__.__name__, e))
      print('ERROR: failed to evaluate meta expression %s at %s' %
            (exp.python_exp, exp.token.start))
      sys.exit(1)
    return result

  def GetRange(self, identifier):
    for (var, lower, upper) in self.ranges:
      if identifier == var:
        return (lower, upper)

    print('ERROR: range %s is undefined.' % (identifier,))
    sys.exit(1)


class Output:
  def __init__(self):
    self.string = ''

  def GetLastLine(self):
    index = self.string.rfind('\n')
    if index < 0:
      return ''

    return self.string[index + 1:]

  def Append(self, s):
    self.string += s


def RunAtomicCode(env, node, output):
  if isinstance(node, VarNode):
    identifier = node.identifier.value.strip()
    result = Output()
    RunAtomicCode(env.Clone(), node.atomic_code, result)
    value = result.string
    env.PushVariable(identifier, value)
  elif isinstance(node, RangeNode):
    identifier = node.identifier.value.strip()
    lower = int(env.EvalExp(node.exp1))
    upper = int(env.EvalExp(node.exp2))
    env.PushRange(identifier, lower, upper)
  elif isinstance(node, ForNode):
    identifier = node.identifier.value.strip()
    if node.sep is None:
      sep = ''
    else:
      sep = node.sep.value
    (lower, upper) = env.GetRange(identifier)
    for i in range(lower, upper + 1):
      new_env = env.Clone()
      new_env.PushVariable(identifier, i)
      RunCode(new_env, node.code, output)
      if i != upper:
        output.Append(sep)
  elif isinstance(node, RawCodeNode):
    output.Append(node.raw_code.value)
  elif isinstance(node, IfNode):
    cond = env.EvalExp(node.exp)
    if cond:
      RunCode(env.Clone(), node.then_branch, output)
    elif node.else_branch is not None:
      RunCode(env.Clone(), node.else_branch, output)
  elif isinstance(node, ExpNode):
    value = env.EvalExp(node)
    output.Append('%s' % (value,))
  elif isinstance(node, LiteralDollarNode):
    output.Append('$')
  elif isinstance(node, CodeNode):
    RunCode(env.Clone(), node, output)
  else:
    print('BAD')
    print(node)
    sys.exit(1)


def RunCode(env, code_node, output):
  for atomic_code in code_node.atomic_code:
    RunAtomicCode(env, atomic_code, output)


def IsSingleLineComment(cur_line):
  return '//' in cur_line


def IsInPreprocessorDirective(prev_lines, cur_line):
  if cur_line.lstrip().startswith('#'):
    return True
  return prev_lines and prev_lines[-1].endswith('\\')


def WrapComment(line, output):
  loc = line.find('//')
  before_comment = line[:loc].rstrip()
  if before_comment == '':
    indent = loc
  else:
    output.append(before_comment)
    indent = len(before_comment) - len(before_comment.lstrip())
  prefix = indent*' ' + '// '
  max_len = 80 - len(prefix)
  comment = line[loc + 2:].strip()
  segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != '']
  cur_line = ''
  for seg in segs:
    if len((cur_line + seg).rstrip()) < max_len:
      cur_line += seg
    else:
      if cur_line.strip() != '':
        output.append(prefix + cur_line.rstrip())
      cur_line = seg.lstrip()
  if cur_line.strip() != '':
    output.append(prefix + cur_line.strip())


def WrapCode(line, line_concat, output):
  indent = len(line) - len(line.lstrip())
  prefix = indent*' '  # Prefix of the current line
  max_len = 80 - indent - len(line_concat)  # Maximum length of the current line
  new_prefix = prefix + 4*' '  # Prefix of a continuation line
  new_max_len = max_len - 4  # Maximum length of a continuation line
  # Prefers to wrap a line after a ',' or ';'.
  segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != '']
  cur_line = ''  # The current line without leading spaces.
  for seg in segs:
    # If the line is still too long, wrap at a space.
    while cur_line == '' and len(seg.strip()) > max_len:
      seg = seg.lstrip()
      split_at = seg.rfind(' ', 0, max_len)
      output.append(prefix + seg[:split_at].strip() + line_concat)
      seg = seg[split_at + 1:]
      prefix = new_prefix
      max_len = new_max_len

    if len((cur_line + seg).rstrip()) < max_len:
      cur_line = (cur_line + seg).lstrip()
    else:
      output.append(prefix + cur_line.rstrip() + line_concat)
      prefix = new_prefix
      max_len = new_max_len
      cur_line = seg.lstrip()
  if cur_line.strip() != '':
    output.append(prefix + cur_line.strip())


def WrapPreprocessorDirective(line, output):
  WrapCode(line, ' \\', output)


def WrapPlainCode(line, output):
  WrapCode(line, '', output)


def IsMultiLineIWYUPragma(line):
  return re.search(r'/\* IWYU pragma: ', line)


def IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
  return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or
          re.match(r'^#include\s', line) or
          # Don't break IWYU pragmas, either; that causes iwyu.py problems.
          re.search(r'// IWYU pragma: ', line))


def WrapLongLine(line, output):
  line = line.rstrip()
  if len(line) <= 80:
    output.append(line)
  elif IsSingleLineComment(line):
    if IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
      # The style guide made an exception to allow long header guard lines,
      # includes and IWYU pragmas.
      output.append(line)
    else:
      WrapComment(line, output)
  elif IsInPreprocessorDirective(output, line):
    if IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
      # The style guide made an exception to allow long header guard lines,
      # includes and IWYU pragmas.
      output.append(line)
    else:
      WrapPreprocessorDirective(line, output)
  elif IsMultiLineIWYUPragma(line):
    output.append(line)
  else:
    WrapPlainCode(line, output)


def BeautifyCode(string):
  lines = string.splitlines()
  output = []
  for line in lines:
    WrapLongLine(line, output)
  output2 = [line.rstrip() for line in output]
  return '\n'.join(output2) + '\n'


def ConvertFromPumpSource(src_text):
  """Return the text generated from the given Pump source text."""
  ast = ParseToAST(StripMetaComments(src_text))
  output = Output()
  RunCode(Env(), ast, output)
  return BeautifyCode(output.string)


def main(argv):
  if len(argv) == 1:
    print(__doc__)
    sys.exit(1)

  file_path = argv[-1]
  output_str = ConvertFromPumpSource(file(file_path, 'r').read())
  if file_path.endswith('.pump'):
    output_file_path = file_path[:-5]
  else:
    output_file_path = '-'
  if output_file_path == '-':
    print(output_str,)
  else:
    output_file = file(output_file_path, 'w')
    output_file.write('// This file was GENERATED by command:\n')
    output_file.write('//     %s %s\n' %
                      (os.path.basename(__file__), os.path.basename(file_path)))
    output_file.write('// DO NOT EDIT BY HAND!!!\n\n')
    output_file.write(output_str)
    output_file.close()


if __name__ == '__main__':
  main(sys.argv)
