#!/usr/bin/env python3
# Copyright (C) 2011 by Bogdan Popa <popa.bogdanp@gmail.com>
# 
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
"""Run a Python expression on every line of standard input.
"""
import re

from argparse import ArgumentParser
from sys import exit, stdin

def decorate_function(function, *args):
    """'Decorates' a function by taking its return value and returning
    the group of that return value if it is a MatchObject. If it's not a
    MatchObject then it returns that value."""
    result = function(*args)
    if result is not None:
        try: return result.group()
        except AttributeError: return result
    return ''

f = lambda *a: decorate_function(re.findall, *a)
m = lambda *a: decorate_function(re.match, *a)
s = lambda *a: decorate_function(re.search, *a)
S = lambda *a: decorate_function(re.sub, *a)

def evaluate(arguments):
    expression = ' '.join(arguments.expression)
    for module in arguments.modules.split(','):
        if module: globals()[module] = __import__(module)
    for i, L in enumerate(stdin):
        result = str(eval(expression))
        if arguments.print_lines:
            print(result.rstrip('\n'))
    return 0

def parse_arguments():
    parser = ArgumentParser(description=__doc__)
    parser.add_argument('expression', metavar='E', type=str, nargs='*', default=['L'],
                        help='the expression to be evaluated on every line')
    parser.add_argument('-m', '--modules', type=str, nargs='?', default='',
                        help='a comma-separated list of modules to be imported')
    parser.add_argument('-n', '--no-print', dest='print_lines',
                        action='store_const', const=False, default=True,
                        help="don't print the evaluated expression for every line")
    return parser.parse_args()

if __name__ == '__main__':
    exit(evaluate(parse_arguments()))
